DPDK patches and discussions
 help / color / mirror / Atom feed
From: Feifei Wang <wff_light@vip.163.com>
To: dev@dpdk.org
Cc: Yi Chen <chenyi221@huawei.com>,
	Xin Wang <wangxin679@h-partners.com>,
	Feifei Wang <wangfeifei40@huawei.com>
Subject: [RFC 09/18] net/hinic3: add a NIC business configuration module
Date: Fri, 18 Apr 2025 17:05:55 +0800	[thread overview]
Message-ID: <20250418090621.9638-10-wff_light@vip.163.com> (raw)
In-Reply-To: <20250418090621.9638-1-wff_light@vip.163.com>

From: Yi Chen <chenyi221@huawei.com>

The items of configurations and queries for NIC business include
MAC, VLAN, MTU, RSS and so on. These configurations and queries
are handled by mgmt module. This patch introduces related
data structures and function codes.

Signed-off-by: Yi Chen <chenyi221@huawei.com>
Reviewed-by: Xin Wang <wangxin679@h-partners.com>
Reviewed-by: Feifei Wang <wangfeifei40@huawei.com>
---
 drivers/net/hinic3/base/hinic3_nic_cfg.c | 1828 ++++++++++++++++++++++
 drivers/net/hinic3/base/hinic3_nic_cfg.h | 1527 ++++++++++++++++++
 2 files changed, 3355 insertions(+)
 create mode 100644 drivers/net/hinic3/base/hinic3_nic_cfg.c
 create mode 100644 drivers/net/hinic3/base/hinic3_nic_cfg.h

diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c b/drivers/net/hinic3/base/hinic3_nic_cfg.c
new file mode 100644
index 0000000000..b4a4edc939
--- /dev/null
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c
@@ -0,0 +1,1828 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2025 Huawei Technologies Co., Ltd
+ */
+
+#include <rte_ether.h>
+
+#include "hinic3_compat.h"
+#include "hinic3_cmd.h"
+#include "hinic3_cmdq.h"
+#include "hinic3_hw_cfg.h"
+#include "hinic3_hwdev.h"
+#include "hinic3_hwif.h"
+#include "hinic3_mbox.h"
+#include "hinic3_nic_cfg.h"
+#include "hinic3_wq.h"
+
+struct vf_msg_handler {
+	u16 cmd;
+};
+
+static const struct vf_msg_handler vf_cmd_handler[] = {
+	{
+		.cmd = HINIC3_NIC_CMD_VF_REGISTER,
+	},
+
+	{
+		.cmd = HINIC3_NIC_CMD_GET_MAC,
+	},
+
+	{
+		.cmd = HINIC3_NIC_CMD_SET_MAC,
+	},
+
+	{
+		.cmd = HINIC3_NIC_CMD_DEL_MAC,
+	},
+
+	{
+		.cmd = HINIC3_NIC_CMD_UPDATE_MAC,
+	},
+
+	{
+		.cmd = HINIC3_NIC_CMD_VF_COS,
+	},
+};
+
+static const struct vf_msg_handler vf_mag_cmd_handler[] = {
+	{
+		.cmd = MAG_CMD_GET_LINK_STATUS,
+	},
+};
+
+static int mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+				void *buf_out, u16 *out_size);
+
+/**
+ * If device is VF and command is found in a predefined list, send to PF, else
+ * send to management module.
+ *
+ * @param[in] hwdev
+ * The pointer to the hardware device structure.
+ * @param[in] cmd
+ * The command to send.
+ * @param[in] buf_in
+ * The input buffer containing the request data.
+ * @param[in] in_size
+ * The size of the input buffer.
+ * @param[out] buf_out
+ * The output buffer to receive the response data.
+ * @param[out] out_size
+ * The size of the output buffer on return.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int
+l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+		       void *buf_out, u16 *out_size)
+{
+	u32 i, cmd_cnt = ARRAY_LEN(vf_cmd_handler);
+	bool cmd_to_pf = false;
+
+	if (hinic3_func_type(hwdev) == TYPE_VF) {
+		for (i = 0; i < cmd_cnt; i++) {
+			if (cmd == vf_cmd_handler[i].cmd)
+				cmd_to_pf = true;
+		}
+	}
+
+	if (cmd_to_pf) {
+		return hinic3_mbox_to_pf(hwdev, HINIC3_MOD_L2NIC, cmd, buf_in,
+					 in_size, buf_out, out_size, 0);
+	}
+
+	return hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, cmd, buf_in,
+				       in_size, buf_out, out_size, 0);
+}
+
+/**
+ * Set CI table for a SQ.
+ *
+ * Configure the CI table with attributes like CI address, pending limit,
+ * coalescing time, and optional interrupt settings for specified SQ.
+ *
+ * @param[in] hwdev
+ * Pointer to hardware device structure.
+ * @param[in] attr
+ * Attributes to configure for CI table.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int
+hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr)
+{
+	struct hinic3_cmd_cons_idx_attr cons_idx_attr;
+	u16 out_size = sizeof(cons_idx_attr);
+	int err;
+
+	if (!hwdev || !attr)
+		return -EINVAL;
+
+	memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
+	cons_idx_attr.func_idx = hinic3_global_func_id(hwdev);
+	cons_idx_attr.dma_attr_off = attr->dma_attr_off;
+	cons_idx_attr.pending_limit = attr->pending_limit;
+	cons_idx_attr.coalescing_time = attr->coalescing_time;
+
+	if (attr->intr_en) {
+		cons_idx_attr.intr_en = attr->intr_en;
+		cons_idx_attr.intr_idx = attr->intr_idx;
+	}
+
+	cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
+	cons_idx_attr.ci_addr = attr->ci_dma_base;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SQ_CI_ATTR_SET,
+				     &cons_idx_attr, sizeof(cons_idx_attr),
+				     &cons_idx_attr, &out_size);
+	if (err || !out_size || cons_idx_attr.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set ci attribute table failed, "
+			    "err: %d, status: 0x%x, out_size: 0x%x",
+			    err, cons_idx_attr.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+#define PF_SET_VF_MAC(hwdev, status)           \
+	(hinic3_func_type(hwdev) == TYPE_VF && \
+	 (status) == HINIC3_PF_SET_VF_ALREADY)
+
+static int
+hinic3_check_mac_info(void *hwdev, u8 status, u16 vlan_id)
+{
+	if ((status && status != HINIC3_MGMT_STATUS_EXIST) ||
+	    ((vlan_id & CHECK_IPSU_15BIT) &&
+	     status == HINIC3_MGMT_STATUS_EXIST)) {
+		if (PF_SET_VF_MAC(hwdev, status))
+			return 0;
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#define VLAN_N_VID 4096
+
+int
+hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
+{
+	struct hinic3_port_mac_set mac_info;
+	u16 out_size = sizeof(mac_info);
+	int err;
+
+	if (!hwdev || !mac_addr)
+		return -EINVAL;
+
+	memset(&mac_info, 0, sizeof(mac_info));
+
+	if (vlan_id >= VLAN_N_VID) {
+		PMD_DRV_LOG(ERR, "Invalid VLAN number: %d", vlan_id);
+		return -EINVAL;
+	}
+
+	mac_info.func_id = func_id;
+	mac_info.vlan_id = vlan_id;
+	memmove(mac_info.mac, mac_addr, ETH_ALEN);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_MAC, &mac_info,
+				     sizeof(mac_info), &mac_info, &out_size);
+	if (err || !out_size ||
+	    hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+				  mac_info.vlan_id)) {
+		PMD_DRV_LOG(ERR,
+			    "Update MAC failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, mac_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+		PMD_DRV_LOG(WARNING,
+			    "PF has already set VF mac, Ignore set operation");
+		return HINIC3_PF_SET_VF_ALREADY;
+	}
+
+	if (mac_info.msg_head.status == HINIC3_MGMT_STATUS_EXIST) {
+		PMD_DRV_LOG(WARNING,
+			    "MAC is repeated. Ignore update operation");
+		return 0;
+	}
+
+	return 0;
+}
+
+int
+hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id)
+{
+	struct hinic3_port_mac_set mac_info;
+	u16 out_size = sizeof(mac_info);
+	int err;
+
+	if (!hwdev || !mac_addr)
+		return -EINVAL;
+
+	if (vlan_id >= VLAN_N_VID) {
+		PMD_DRV_LOG(ERR, "Invalid VLAN number: %d", vlan_id);
+		return -EINVAL;
+	}
+
+	memset(&mac_info, 0, sizeof(mac_info));
+	mac_info.func_id = func_id;
+	mac_info.vlan_id = vlan_id;
+	memmove(mac_info.mac, mac_addr, ETH_ALEN);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_DEL_MAC, &mac_info,
+				     sizeof(mac_info), &mac_info, &out_size);
+	if (err || !out_size ||
+	    (mac_info.msg_head.status &&
+	     !PF_SET_VF_MAC(hwdev, mac_info.msg_head.status))) {
+		PMD_DRV_LOG(ERR,
+			    "Delete MAC failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, mac_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+		PMD_DRV_LOG(WARNING,
+			"PF has already set VF mac, Ignore delete operation");
+		return HINIC3_PF_SET_VF_ALREADY;
+	}
+
+	return 0;
+}
+
+int
+hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+		  u16 func_id)
+{
+	struct hinic3_port_mac_update mac_info;
+	u16 out_size = sizeof(mac_info);
+	int err;
+
+	if (!hwdev || !old_mac || !new_mac)
+		return -EINVAL;
+
+	if (vlan_id >= VLAN_N_VID) {
+		PMD_DRV_LOG(ERR, "Invalid VLAN number: %d", vlan_id);
+		return -EINVAL;
+	}
+
+	memset(&mac_info, 0, sizeof(mac_info));
+	mac_info.func_id = func_id;
+	mac_info.vlan_id = vlan_id;
+	memcpy(mac_info.old_mac, old_mac, ETH_ALEN);
+	memcpy(mac_info.new_mac, new_mac, ETH_ALEN);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_UPDATE_MAC,
+				     &mac_info, sizeof(mac_info), &mac_info,
+				     &out_size);
+	if (err || !out_size ||
+	    hinic3_check_mac_info(hwdev, mac_info.msg_head.status,
+				  mac_info.vlan_id)) {
+		PMD_DRV_LOG(ERR,
+			    "Update MAC failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, mac_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	if (PF_SET_VF_MAC(hwdev, mac_info.msg_head.status)) {
+		PMD_DRV_LOG(WARNING,
+			"PF has already set VF MAC. Ignore update operation");
+		return HINIC3_PF_SET_VF_ALREADY;
+	}
+
+	if (mac_info.msg_head.status == HINIC3_MGMT_STATUS_EXIST) {
+		PMD_DRV_LOG(INFO, "MAC is repeated. Ignore update operation");
+		return 0;
+	}
+
+	return 0;
+}
+
+int
+hinic3_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len)
+{
+	struct hinic3_port_mac_set mac_info;
+	u16 out_size = sizeof(mac_info);
+	int err;
+
+	if (!hwdev || !mac_addr)
+		return -EINVAL;
+
+	memset(&mac_info, 0, sizeof(mac_info));
+	mac_info.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_MAC, &mac_info,
+				     sizeof(mac_info), &mac_info, &out_size);
+	if (err || !out_size || mac_info.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			"Get MAC failed, err: %d, status: 0x%x, out size: 0x%x",
+			err, mac_info.msg_head.status, out_size);
+		return -EINVAL;
+	}
+
+	memmove(mac_addr, mac_info.mac, ether_len);
+
+	return 0;
+}
+
+static int
+hinic3_config_vlan(void *hwdev, u8 opcode, u16 vlan_id, u16 func_id)
+{
+	struct hinic3_cmd_vlan_config vlan_info;
+	u16 out_size = sizeof(vlan_info);
+	int err;
+
+	memset(&vlan_info, 0, sizeof(vlan_info));
+	vlan_info.opcode = opcode;
+	vlan_info.func_id = func_id;
+	vlan_info.vlan_id = vlan_id;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_FUNC_VLAN,
+				     &vlan_info, sizeof(vlan_info), &vlan_info,
+				     &out_size);
+	if (err || !out_size || vlan_info.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			"%s vlan failed, err: %d, status: 0x%x, out size: 0x%x",
+			opcode == HINIC3_CMD_OP_ADD ? "Add" : "Delete", err,
+			vlan_info.msg_head.status, out_size);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return hinic3_config_vlan(hwdev, HINIC3_CMD_OP_ADD, vlan_id, func_id);
+}
+
+int
+hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return hinic3_config_vlan(hwdev, HINIC3_CMD_OP_DEL, vlan_id, func_id);
+}
+
+int
+hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info)
+{
+	struct hinic3_cmd_port_info port_msg;
+	u16 out_size = sizeof(port_msg);
+	int err;
+
+	if (!hwdev || !port_info)
+		return -EINVAL;
+
+	memset(&port_msg, 0, sizeof(port_msg));
+	port_msg.port_id = hinic3_physical_port_id(hwdev);
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_INFO, &port_msg,
+				   sizeof(port_msg), &port_msg, &out_size);
+	if (err || !out_size || port_msg.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Get port info failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, port_msg.msg_head.status, out_size);
+		return -EINVAL;
+	}
+
+	port_info->autoneg_cap = port_msg.autoneg_cap;
+	port_info->autoneg_state = port_msg.autoneg_state;
+	port_info->duplex = port_msg.duplex;
+	port_info->port_type = port_msg.port_type;
+	port_info->speed = port_msg.speed;
+	port_info->fec = port_msg.fec;
+
+	return 0;
+}
+
+int
+hinic3_get_link_state(void *hwdev, u8 *link_state)
+{
+	struct hinic3_cmd_link_state get_link;
+	u16 out_size = sizeof(get_link);
+	int err;
+
+	if (!hwdev || !link_state)
+		return -EINVAL;
+
+	memset(&get_link, 0, sizeof(get_link));
+	get_link.port_id = hinic3_physical_port_id(hwdev);
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_LINK_STATUS, &get_link,
+				   sizeof(get_link), &get_link, &out_size);
+	if (err || !out_size || get_link.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Get link state failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, get_link.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	*link_state = get_link.state;
+
+	return 0;
+}
+
+int
+hinic3_set_vport_enable(void *hwdev, bool enable)
+{
+	struct hinic3_vport_state en_state;
+	u16 out_size = sizeof(en_state);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&en_state, 0, sizeof(en_state));
+	en_state.func_id = hinic3_global_func_id(hwdev);
+	en_state.state = enable ? 1 : 0;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_VPORT_ENABLE,
+				     &en_state, sizeof(en_state), &en_state,
+				     &out_size);
+	if (err || !out_size || en_state.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set vport state failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, en_state.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_set_port_enable(void *hwdev, bool enable)
+{
+	struct mag_cmd_set_port_enable en_state;
+	u16 out_size = sizeof(en_state);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	if (hinic3_func_type(hwdev) == TYPE_VF)
+		return 0;
+
+	memset(&en_state, 0, sizeof(en_state));
+	en_state.function_id = hinic3_global_func_id(hwdev);
+	en_state.state = enable ? MAG_CMD_TX_ENABLE | MAG_CMD_RX_ENABLE
+				: MAG_CMD_PORT_DISABLE;
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_PORT_ENABLE, &en_state,
+				   sizeof(en_state), &en_state, &out_size);
+	if (err || !out_size || en_state.head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set port state failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, en_state.head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_flush_qps_res(void *hwdev)
+{
+	struct hinic3_cmd_clear_qp_resource sq_res;
+	u16 out_size = sizeof(sq_res);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&sq_res, 0, sizeof(sq_res));
+	sq_res.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CLEAR_QP_RESOURCE,
+				     &sq_res, sizeof(sq_res), &sq_res,
+				     &out_size);
+	if (err || !out_size || sq_res.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Clear sq resources failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, sq_res.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+/**
+ * Get or set the flow control (pause frame) settings for NIC.
+ *
+ * @param[in] hwdev
+ * Pointer to the hardware device.
+ * @param[in] opcode
+ * The operation to perform. Use `HINIC3_CMD_OP_SET` to set the pause settings
+ * and `HINIC3_CMD_OP_GET` to get them.
+ * @param[out] nic_pause
+ * Pointer to the `nic_pause_config` structure. This structure contains the flow
+ * control settings (auto-negotiation, Rx pause, and Tx pause). It is updated
+ * when getting settings. When setting, the values in this structure are used.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ * - -EIO if the operation failed.
+ */
+static int
+hinic3_cfg_hw_pause(void *hwdev, u8 opcode, struct nic_pause_config *nic_pause)
+{
+	struct hinic3_cmd_pause_config pause_info = {0};
+	u16 out_size = sizeof(pause_info);
+	int err = 0;
+
+	pause_info.port_id = hinic3_physical_port_id(hwdev);
+	pause_info.opcode = opcode;
+	if (opcode == HINIC3_CMD_OP_SET) {
+		pause_info.auto_neg = nic_pause->auto_neg;
+		pause_info.rx_pause = nic_pause->rx_pause;
+		pause_info.tx_pause = nic_pause->tx_pause;
+	}
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_PAUSE_INFO,
+				     &pause_info, sizeof(pause_info),
+				     &pause_info, &out_size);
+	if (err || !out_size || pause_info.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "%s pause info failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    opcode == HINIC3_CMD_OP_SET ? "Set" : "Get", err,
+			    pause_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	if (opcode == HINIC3_CMD_OP_GET) {
+		nic_pause->auto_neg = pause_info.auto_neg;
+		nic_pause->rx_pause = pause_info.rx_pause;
+		nic_pause->tx_pause = pause_info.tx_pause;
+	}
+
+	return 0;
+}
+
+int
+hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return hinic3_cfg_hw_pause(hwdev, HINIC3_CMD_OP_SET, &nic_pause);
+}
+
+int
+hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause)
+{
+	if (!hwdev || !nic_pause)
+		return -EINVAL;
+
+	return hinic3_cfg_hw_pause(hwdev, HINIC3_CMD_OP_GET, nic_pause);
+}
+
+int
+hinic3_get_vport_stats(void *hwdev, struct hinic3_vport_stats *stats)
+{
+	struct hinic3_port_stats_info stats_info;
+	struct hinic3_cmd_vport_stats vport_stats;
+	u16 out_size = sizeof(vport_stats);
+	int err;
+
+	if (!hwdev || !stats)
+		return -EINVAL;
+
+	memset(&stats_info, 0, sizeof(stats_info));
+	memset(&vport_stats, 0, sizeof(vport_stats));
+
+	stats_info.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_VPORT_STAT,
+				     &stats_info, sizeof(stats_info),
+				     &vport_stats, &out_size);
+	if (err || !out_size || vport_stats.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Get function stats failed, err: %d, status: 0x%x, "
+			    "out size: 0x%x",
+			    err, vport_stats.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	memcpy(stats, &vport_stats.stats, sizeof(*stats));
+
+	return 0;
+}
+
+int
+hinic3_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats)
+{
+	struct mag_cmd_get_port_stat *port_stats = NULL;
+	struct mag_cmd_port_stats_info stats_info;
+	u16 out_size = sizeof(*port_stats);
+	int err;
+
+	port_stats = rte_zmalloc("port_stats", sizeof(*port_stats), 0);
+	if (!port_stats)
+		return -ENOMEM;
+
+	memset(&stats_info, 0, sizeof(stats_info));
+	stats_info.port_id = hinic3_physical_port_id(hwdev);
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_GET_PORT_STAT, &stats_info,
+				   sizeof(stats_info), port_stats, &out_size);
+	if (err || !out_size || port_stats->head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to get port statistics, err: %d, status: "
+			    "0x%x, out size: 0x%x",
+			    err, port_stats->head.status, out_size);
+		err = -EIO;
+		goto out;
+	}
+
+	memcpy(stats, &port_stats->counter, sizeof(*stats));
+
+out:
+	rte_free(port_stats);
+
+	return err;
+}
+
+int
+hinic3_clear_vport_stats(void *hwdev)
+{
+	struct hinic3_cmd_clear_vport_stats clear_vport_stats;
+	u16 out_size = sizeof(clear_vport_stats);
+	int err;
+
+	if (!hwdev) {
+		PMD_DRV_LOG(ERR, "Hwdev is NULL");
+		return -EINVAL;
+	}
+
+	memset(&clear_vport_stats, 0, sizeof(clear_vport_stats));
+	clear_vport_stats.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev,
+		HINIC3_NIC_CMD_CLEAN_VPORT_STAT, &clear_vport_stats,
+		sizeof(clear_vport_stats), &clear_vport_stats, &out_size);
+	if (err || !out_size || clear_vport_stats.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Clear vport stats failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, clear_vport_stats.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_clear_phy_port_stats(void *hwdev)
+{
+	struct mag_cmd_port_stats_info port_stats;
+	u16 out_size = sizeof(port_stats);
+	int err;
+
+	port_stats.port_id = hinic3_physical_port_id(hwdev);
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_CLR_PORT_STAT, &port_stats,
+				   sizeof(port_stats), &port_stats, &out_size);
+	if (err || !out_size || port_stats.head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to get port statistics, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, port_stats.head.status, out_size);
+		err = -EIO;
+	}
+
+	return err;
+}
+
+static int
+hinic3_set_function_table(void *hwdev, u32 cfg_bitmap,
+			  struct hinic3_func_tbl_cfg *cfg)
+{
+	struct hinic3_cmd_set_func_tbl cmd_func_tbl;
+	u16 out_size = sizeof(cmd_func_tbl);
+	int err;
+
+	memset(&cmd_func_tbl, 0, sizeof(cmd_func_tbl));
+	cmd_func_tbl.func_id = hinic3_global_func_id(hwdev);
+	cmd_func_tbl.cfg_bitmap = cfg_bitmap;
+	cmd_func_tbl.tbl_cfg = *cfg;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_FUNC_TBL,
+				     &cmd_func_tbl, sizeof(cmd_func_tbl),
+				     &cmd_func_tbl, &out_size);
+	if (err || cmd_func_tbl.msg_head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Set func table failed, bitmap: 0x%x, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    cfg_bitmap, err, cmd_func_tbl.msg_head.status,
+			    out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int
+hinic3_init_function_table(void *hwdev, u16 rx_buff_len)
+{
+	struct hinic3_func_tbl_cfg func_tbl_cfg;
+	u32 cfg_bitmap = BIT(FUNC_CFG_INIT) | BIT(FUNC_CFG_MTU) |
+			 BIT(FUNC_CFG_RX_BUF_SIZE);
+
+	memset(&func_tbl_cfg, 0, sizeof(func_tbl_cfg));
+	func_tbl_cfg.mtu = 0x3FFF; /**< Default, max mtu */
+	func_tbl_cfg.rx_wqe_buf_size = rx_buff_len;
+
+	return hinic3_set_function_table(hwdev, cfg_bitmap, &func_tbl_cfg);
+}
+
+int
+hinic3_set_port_mtu(void *hwdev, u16 new_mtu)
+{
+	struct hinic3_func_tbl_cfg func_tbl_cfg;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	if (new_mtu < HINIC3_MIN_MTU_SIZE) {
+		PMD_DRV_LOG(ERR,
+			    "Invalid mtu size: %ubytes, mtu size < %ubytes",
+			    new_mtu, HINIC3_MIN_MTU_SIZE);
+		return -EINVAL;
+	}
+
+	if (new_mtu > HINIC3_MAX_JUMBO_FRAME_SIZE) {
+		PMD_DRV_LOG(ERR,
+			    "Invalid mtu size: %ubytes, mtu size > %ubytes",
+			    new_mtu, HINIC3_MAX_JUMBO_FRAME_SIZE);
+		return -EINVAL;
+	}
+
+	memset(&func_tbl_cfg, 0, sizeof(func_tbl_cfg));
+	func_tbl_cfg.mtu = new_mtu;
+	return hinic3_set_function_table(hwdev, BIT(FUNC_CFG_MTU),
+					 &func_tbl_cfg);
+}
+
+static int
+nic_feature_nego(void *hwdev, u8 opcode, u64 *s_feature, u16 size)
+{
+	struct hinic3_cmd_feature_nego feature_nego;
+	u16 out_size = sizeof(feature_nego);
+	int err;
+
+	if (!hwdev || !s_feature || size > MAX_FEATURE_QWORD)
+		return -EINVAL;
+
+	memset(&feature_nego, 0, sizeof(feature_nego));
+	feature_nego.func_id = hinic3_global_func_id(hwdev);
+	feature_nego.opcode = opcode;
+	if (opcode == HINIC3_CMD_OP_SET)
+		memcpy(feature_nego.s_feature, s_feature, size * sizeof(u64));
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_FEATURE_NEGO,
+				     &feature_nego, sizeof(feature_nego),
+				     &feature_nego, &out_size);
+	if (err || !out_size || feature_nego.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to negotiate nic feature, err:%d, status: "
+			    "0x%x, out_size: 0x%x",
+			    err, feature_nego.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	if (opcode == HINIC3_CMD_OP_GET)
+		memcpy(s_feature, feature_nego.s_feature, size * sizeof(u64));
+
+	return 0;
+}
+
+int
+hinic3_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size)
+{
+	return nic_feature_nego(hwdev, HINIC3_CMD_OP_GET, s_feature, size);
+}
+
+int
+hinic3_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size)
+{
+	return nic_feature_nego(hwdev, HINIC3_CMD_OP_SET, s_feature, size);
+}
+
+static int
+hinic3_vf_func_init(void *hwdev)
+{
+	struct hinic3_cmd_register_vf register_info;
+	u16 out_size = sizeof(register_info);
+	int err;
+
+	if (hinic3_func_type(hwdev) != TYPE_VF)
+		return 0;
+
+	memset(&register_info, 0, sizeof(register_info));
+	register_info.op_register = 1;
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_VF_REGISTER,
+				     &register_info, sizeof(register_info),
+				     &register_info, &out_size);
+	if (err || register_info.msg_head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Register VF failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    err, register_info.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+hinic3_vf_func_free(void *hwdev)
+{
+	struct hinic3_cmd_register_vf unregister;
+	u16 out_size = sizeof(unregister);
+	int err;
+
+	if (hinic3_func_type(hwdev) != TYPE_VF)
+		return 0;
+
+	memset(&unregister, 0, sizeof(unregister));
+	unregister.op_register = 0;
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_VF_REGISTER,
+				     &unregister, sizeof(unregister),
+				     &unregister, &out_size);
+	if (err || unregister.msg_head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Unregister VF failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    err, unregister.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int
+hinic3_init_nic_hwdev(void *hwdev)
+{
+	return hinic3_vf_func_init(hwdev);
+}
+
+void
+hinic3_free_nic_hwdev(void *hwdev)
+{
+	if (!hwdev)
+		return;
+
+	if (hinic3_func_type(hwdev) != TYPE_VF)
+		(void)hinic3_set_link_status_follow(hwdev,
+						    HINIC3_LINK_FOLLOW_DEFAULT);
+
+	hinic3_vf_func_free(hwdev);
+}
+
+int
+hinic3_set_rx_mode(void *hwdev, u32 enable)
+{
+	struct hinic3_rx_mode_config rx_mode_cfg;
+	u16 out_size = sizeof(rx_mode_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&rx_mode_cfg, 0, sizeof(rx_mode_cfg));
+	rx_mode_cfg.func_id = hinic3_global_func_id(hwdev);
+	rx_mode_cfg.rx_mode = enable;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_RX_MODE,
+				     &rx_mode_cfg, sizeof(rx_mode_cfg),
+				     &rx_mode_cfg, &out_size);
+	if (err || !out_size || rx_mode_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set rx mode failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    err, rx_mode_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+	return 0;
+}
+
+int
+hinic3_set_rx_vlan_offload(void *hwdev, u8 en)
+{
+	struct hinic3_cmd_vlan_offload vlan_cfg;
+	u16 out_size = sizeof(vlan_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&vlan_cfg, 0, sizeof(vlan_cfg));
+	vlan_cfg.func_id = hinic3_global_func_id(hwdev);
+	vlan_cfg.vlan_offload = en;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_RX_VLAN_OFFLOAD,
+				     &vlan_cfg, sizeof(vlan_cfg), &vlan_cfg,
+				     &out_size);
+	if (err || !out_size || vlan_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set rx vlan offload failed, err: %d, status: "
+			    "0x%x, out size: 0x%x",
+			    err, vlan_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+	return 0;
+}
+
+int
+hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl)
+{
+	struct hinic3_cmd_set_vlan_filter vlan_filter;
+	u16 out_size = sizeof(vlan_filter);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&vlan_filter, 0, sizeof(vlan_filter));
+	vlan_filter.func_id = hinic3_global_func_id(hwdev);
+	vlan_filter.vlan_filter_ctrl = vlan_filter_ctrl;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_VLAN_FILTER_EN,
+				     &vlan_filter, sizeof(vlan_filter),
+				     &vlan_filter, &out_size);
+	if (err || !out_size || vlan_filter.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to set vlan filter, err: %d, status: 0x%x, "
+			    "out size: 0x%x",
+			    err, vlan_filter.msg_head.status, out_size);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int
+hinic3_set_rx_lro(void *hwdev, u8 ipv4_en, u8 ipv6_en, u8 lro_max_pkt_len)
+{
+	struct hinic3_cmd_lro_config lro_cfg = {0};
+	u16 out_size = sizeof(lro_cfg);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	lro_cfg.func_id = hinic3_global_func_id(hwdev);
+	lro_cfg.opcode = HINIC3_CMD_OP_SET;
+	lro_cfg.lro_ipv4_en = ipv4_en;
+	lro_cfg.lro_ipv6_en = ipv6_en;
+	lro_cfg.lro_max_pkt_len = lro_max_pkt_len;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_RX_LRO, &lro_cfg,
+				     sizeof(lro_cfg), &lro_cfg, &out_size);
+	if (err || !out_size || lro_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set lro offload failed, err: %d, status: 0x%x, "
+			    "out size: 0x%x",
+			    err, lro_cfg.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int
+hinic3_set_rx_lro_timer(void *hwdev, u32 timer_value)
+{
+	struct hinic3_cmd_lro_timer lro_timer;
+	u16 out_size = sizeof(lro_timer);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&lro_timer, 0, sizeof(lro_timer));
+	lro_timer.opcode = HINIC3_CMD_OP_SET;
+	lro_timer.timer = timer_value;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_LRO_TIMER,
+				     &lro_timer, sizeof(lro_timer), &lro_timer,
+				     &out_size);
+	if (err || !out_size || lro_timer.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set lro timer failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    err, lro_timer.msg_head.status, out_size);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
+			u32 lro_max_pkt_len)
+{
+	u8 ipv4_en = 0, ipv6_en = 0;
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	ipv4_en = lro_en ? 1 : 0;
+	ipv6_en = lro_en ? 1 : 0;
+
+	PMD_DRV_LOG(INFO, "Set LRO max coalesce packet size to %uK",
+		    lro_max_pkt_len);
+
+	err = hinic3_set_rx_lro(hwdev, ipv4_en, ipv6_en, (u8)lro_max_pkt_len);
+	if (err)
+		return err;
+
+	/* We don't set LRO timer for VF */
+	if (hinic3_func_type(hwdev) == TYPE_VF)
+		return 0;
+
+	PMD_DRV_LOG(INFO, "Set LRO timer to %u", lro_timer);
+
+	return hinic3_set_rx_lro_timer(hwdev, lro_timer);
+}
+
+/* RSS config */
+int
+hinic3_rss_template_alloc(void *hwdev)
+{
+	struct hinic3_rss_template_mgmt template_mgmt;
+	u16 out_size = sizeof(template_mgmt);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&template_mgmt, 0, sizeof(struct hinic3_rss_template_mgmt));
+	template_mgmt.func_id = hinic3_global_func_id(hwdev);
+	template_mgmt.cmd = NIC_RSS_CMD_TEMP_ALLOC;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RSS_TEMP_MGR,
+				     &template_mgmt, sizeof(template_mgmt),
+				     &template_mgmt, &out_size);
+	if (err || !out_size || template_mgmt.msg_head.status) {
+		if (template_mgmt.msg_head.status ==
+		    HINIC3_MGMT_STATUS_TABLE_FULL) {
+			PMD_DRV_LOG(ERR, "There is no more template available");
+			return -ENOSPC;
+		}
+		PMD_DRV_LOG(ERR,
+			    "Alloc rss template failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, template_mgmt.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int
+hinic3_rss_template_free(void *hwdev)
+{
+	struct hinic3_rss_template_mgmt template_mgmt;
+	u16 out_size = sizeof(template_mgmt);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&template_mgmt, 0, sizeof(struct hinic3_rss_template_mgmt));
+	template_mgmt.func_id = hinic3_global_func_id(hwdev);
+	template_mgmt.cmd = NIC_RSS_CMD_TEMP_FREE;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RSS_TEMP_MGR,
+				     &template_mgmt, sizeof(template_mgmt),
+				     &template_mgmt, &out_size);
+	if (err || !out_size || template_mgmt.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Free rss template failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, template_mgmt.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+hinic3_rss_cfg_hash_key(void *hwdev, u8 opcode, u8 *key, u16 key_size)
+{
+	struct hinic3_cmd_rss_hash_key hash_key;
+	u16 out_size = sizeof(hash_key);
+	int err;
+
+	if (!hwdev || !key)
+		return -EINVAL;
+
+	memset(&hash_key, 0, sizeof(struct hinic3_cmd_rss_hash_key));
+	hash_key.func_id = hinic3_global_func_id(hwdev);
+	hash_key.opcode = opcode;
+	if (opcode == HINIC3_CMD_OP_SET)
+		memcpy(hash_key.key, key, key_size);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_RSS_HASH_KEY,
+				     &hash_key, sizeof(hash_key), &hash_key,
+				     &out_size);
+	if (err || !out_size || hash_key.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "%s hash key failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    opcode == HINIC3_CMD_OP_SET ? "Set" : "Get", err,
+			    hash_key.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	if (opcode == HINIC3_CMD_OP_GET)
+		memcpy(key, hash_key.key, key_size);
+
+	return 0;
+}
+
+int
+hinic3_rss_set_hash_key(void *hwdev, u8 *key, u16 key_size)
+{
+	if (!hwdev || !key)
+		return -EINVAL;
+
+	return hinic3_rss_cfg_hash_key(hwdev, HINIC3_CMD_OP_SET, key, key_size);
+}
+
+int
+hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table, u32 indir_table_size)
+{
+	struct hinic3_cmd_buf *cmd_buf = NULL;
+	u16 *indir_tbl = NULL;
+	int err;
+	u32 i;
+
+	if (!hwdev || !indir_table)
+		return -EINVAL;
+
+	cmd_buf = hinic3_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
+	err = hinic3_cmdq_detail_resp(hwdev, HINIC3_MOD_L2NIC,
+				      HINIC3_UCODE_CMD_GET_RSS_INDIR_TABLE,
+				      cmd_buf, cmd_buf, 0);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Get rss indir table failed");
+		hinic3_free_cmd_buf(cmd_buf);
+		return err;
+	}
+
+	indir_tbl = (u16 *)cmd_buf->buf;
+	for (i = 0; i < indir_table_size; i++)
+		indir_table[i] = *(indir_tbl + i);
+
+	hinic3_free_cmd_buf(cmd_buf);
+	return 0;
+}
+
+int
+hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table,
+			 u32 indir_table_size)
+{
+	struct nic_rss_indirect_tbl *indir_tbl = NULL;
+	struct hinic3_cmd_buf *cmd_buf = NULL;
+	u32 i, size;
+	u32 *temp = NULL;
+	u64 out_param = 0;
+	int err;
+
+	if (!hwdev || !indir_table)
+		return -EINVAL;
+
+	cmd_buf = hinic3_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	cmd_buf->size = sizeof(struct nic_rss_indirect_tbl);
+	indir_tbl = (struct nic_rss_indirect_tbl *)cmd_buf->buf;
+	memset(indir_tbl, 0, sizeof(*indir_tbl));
+
+	for (i = 0; i < indir_table_size; i++)
+		indir_tbl->entry[i] = (u16)(*(indir_table + i));
+
+	rte_mb();
+	size = sizeof(indir_tbl->entry) / sizeof(u32);
+	temp = (u32 *)indir_tbl->entry;
+	for (i = 0; i < size; i++)
+		temp[i] = cpu_to_be32(temp[i]);
+
+	err = hinic3_cmdq_direct_resp(hwdev, HINIC3_MOD_L2NIC,
+				      HINIC3_UCODE_CMD_SET_RSS_INDIR_TABLE,
+				      cmd_buf, &out_param, 0);
+	if (err || out_param != 0) {
+		PMD_DRV_LOG(ERR, "Set rss indir table failed");
+		err = -EFAULT;
+	}
+
+	hinic3_free_cmd_buf(cmd_buf);
+	return err;
+}
+
+static int
+hinic3_cmdq_set_rss_type(void *hwdev, struct hinic3_rss_type rss_type)
+{
+	struct nic_rss_context_tbl *ctx_tbl = NULL;
+	struct hinic3_cmd_buf *cmd_buf = NULL;
+	u32 ctx = 0;
+	u64 out_param = 0;
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	cmd_buf = hinic3_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Allocate cmd buf failed");
+		return -ENOMEM;
+	}
+
+	ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
+	       HINIC3_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
+
+	cmd_buf->size = sizeof(struct nic_rss_context_tbl);
+	ctx_tbl = (struct nic_rss_context_tbl *)cmd_buf->buf;
+	memset(ctx_tbl, 0, sizeof(*ctx_tbl));
+	rte_mb();
+	ctx_tbl->ctx = cpu_to_be32(ctx);
+
+	/* Cfg the RSS context table by command queue. */
+	err = hinic3_cmdq_direct_resp(hwdev, HINIC3_MOD_L2NIC,
+				      HINIC3_UCODE_CMD_SET_RSS_CONTEXT_TABLE,
+				      cmd_buf, &out_param, 0);
+
+	hinic3_free_cmd_buf(cmd_buf);
+
+	if (err || out_param != 0) {
+		PMD_DRV_LOG(ERR, "Cmdq set rss context table failed, err: %d",
+			    err);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int
+hinic3_mgmt_set_rss_type(void *hwdev, struct hinic3_rss_type rss_type)
+{
+	struct hinic3_rss_context_table ctx_tbl;
+	u32 ctx = 0;
+	u16 out_size = sizeof(ctx_tbl);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&ctx_tbl, 0, sizeof(ctx_tbl));
+	ctx_tbl.func_id = hinic3_global_func_id(hwdev);
+	ctx |= HINIC3_RSS_TYPE_SET(1, VALID) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv4, IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv6, IPV6) |
+	       HINIC3_RSS_TYPE_SET(rss_type.ipv6_ext, IPV6_EXT) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv4, TCP_IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv6, TCP_IPV6) |
+	       HINIC3_RSS_TYPE_SET(rss_type.tcp_ipv6_ext, TCP_IPV6_EXT) |
+	       HINIC3_RSS_TYPE_SET(rss_type.udp_ipv4, UDP_IPV4) |
+	       HINIC3_RSS_TYPE_SET(rss_type.udp_ipv6, UDP_IPV6);
+	ctx_tbl.context = ctx;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev,
+		HINIC3_NIC_CMD_SET_RSS_CTX_TBL_INTO_FUNC, &ctx_tbl,
+		sizeof(ctx_tbl), &ctx_tbl, &out_size);
+	if (ctx_tbl.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+		return HINIC3_MGMT_CMD_UNSUPPORTED;
+	} else if (err || !out_size || ctx_tbl.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Mgmt set rss context table failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, ctx_tbl.msg_head.status, out_size);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int
+hinic3_set_rss_type(void *hwdev, struct hinic3_rss_type rss_type)
+{
+	int err;
+	err = hinic3_mgmt_set_rss_type(hwdev, rss_type);
+	if (err == HINIC3_MGMT_CMD_UNSUPPORTED)
+		err = hinic3_cmdq_set_rss_type(hwdev, rss_type);
+	return err;
+}
+
+int
+hinic3_get_rss_type(void *hwdev, struct hinic3_rss_type *rss_type)
+{
+	struct hinic3_rss_context_table ctx_tbl;
+	u16 out_size = sizeof(ctx_tbl);
+	int err;
+
+	if (!hwdev || !rss_type)
+		return -EINVAL;
+
+	memset(&ctx_tbl, 0, sizeof(struct hinic3_rss_context_table));
+	ctx_tbl.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_GET_RSS_CTX_TBL,
+				     &ctx_tbl, sizeof(ctx_tbl), &ctx_tbl,
+				     &out_size);
+	if (err || !out_size || ctx_tbl.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Get hash type failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, ctx_tbl.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	rss_type->ipv4 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, IPV4);
+	rss_type->ipv6 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, IPV6);
+	rss_type->ipv6_ext = HINIC3_RSS_TYPE_GET(ctx_tbl.context, IPV6_EXT);
+	rss_type->tcp_ipv4 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV4);
+	rss_type->tcp_ipv6 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6);
+	rss_type->tcp_ipv6_ext =
+		HINIC3_RSS_TYPE_GET(ctx_tbl.context, TCP_IPV6_EXT);
+	rss_type->udp_ipv4 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV4);
+	rss_type->udp_ipv6 = HINIC3_RSS_TYPE_GET(ctx_tbl.context, UDP_IPV6);
+
+	return 0;
+}
+
+static int
+hinic3_rss_cfg_hash_engine(void *hwdev, u8 opcode, u8 *type)
+{
+	struct hinic3_cmd_rss_engine_type hash_type;
+	u16 out_size = sizeof(hash_type);
+	int err;
+
+	if (!hwdev || !type)
+		return -EINVAL;
+
+	memset(&hash_type, 0, sizeof(struct hinic3_cmd_rss_engine_type));
+	hash_type.func_id = hinic3_global_func_id(hwdev);
+	hash_type.opcode = opcode;
+	if (opcode == HINIC3_CMD_OP_SET)
+		hash_type.hash_engine = *type;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_RSS_HASH_ENGINE,
+				     &hash_type, sizeof(hash_type), &hash_type,
+				     &out_size);
+	if (err || !out_size || hash_type.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "%s hash engine failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    opcode == HINIC3_CMD_OP_SET ? "Set" : "Get", err,
+			    hash_type.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	if (opcode == HINIC3_CMD_OP_GET)
+		*type = hash_type.hash_engine;
+
+	return 0;
+}
+
+int
+hinic3_rss_get_hash_engine(void *hwdev, u8 *type)
+{
+	if (!hwdev || !type)
+		return -EINVAL;
+
+	return hinic3_rss_cfg_hash_engine(hwdev, HINIC3_CMD_OP_GET, type);
+}
+
+int
+hinic3_rss_set_hash_engine(void *hwdev, u8 type)
+{
+	if (!hwdev)
+		return -EINVAL;
+
+	return hinic3_rss_cfg_hash_engine(hwdev, HINIC3_CMD_OP_SET, &type);
+}
+
+int
+hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 tc_num, u8 *prio_tc)
+{
+	struct hinic3_cmd_rss_config rss_cfg;
+	u16 out_size = sizeof(rss_cfg);
+	int err;
+
+	/* Ucode requires number of TC should be power of 2. */
+	if (!hwdev || !prio_tc || (tc_num & (tc_num - 1)))
+		return -EINVAL;
+
+	memset(&rss_cfg, 0, sizeof(struct hinic3_cmd_rss_config));
+	rss_cfg.func_id = hinic3_global_func_id(hwdev);
+	rss_cfg.rss_en = rss_en;
+	rss_cfg.rq_priority_number = tc_num ? (u8)ilog2(tc_num) : 0;
+
+	memcpy(rss_cfg.prio_tc, prio_tc, HINIC3_DCB_UP_MAX);
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_RSS_CFG, &rss_cfg,
+				     sizeof(rss_cfg), &rss_cfg, &out_size);
+	if (err || !out_size || rss_cfg.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set rss cfg failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x",
+			    err, rss_cfg.msg_head.status, out_size);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+int
+hinic3_vf_get_default_cos(void *hwdev, u8 *cos_id)
+{
+	struct hinic3_cmd_vf_dcb_state vf_dcb;
+	u16 out_size = sizeof(vf_dcb);
+	int err;
+
+	memset(&vf_dcb, 0, sizeof(vf_dcb));
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_VF_COS, &vf_dcb,
+				     sizeof(vf_dcb), &vf_dcb, &out_size);
+	if (err || !out_size || vf_dcb.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Get VF default cos failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, vf_dcb.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	*cos_id = vf_dcb.state.default_cos;
+
+	return 0;
+}
+
+/**
+ * Set the Ethernet type filtering rule for the FDIR of a NIC.
+ *
+ * @param[in] hwdev
+ * Pointer to hardware device structure.
+ * @param[in] pkt_type
+ * Indicate the packet type.
+ * @param[in] queue_id
+ * Indicate the queue id.
+ * @param[in] en
+ * Indicate whether to add or delete an operation. 1 - add; 0 - delete.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int
+hinic3_set_fdir_ethertype_filter(void *hwdev, u8 pkt_type, u16 queue_id, u8 en)
+{
+	struct hinic3_set_fdir_ethertype_rule ethertype_cmd;
+	u16 out_size = sizeof(ethertype_cmd);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&ethertype_cmd, 0,
+	       sizeof(struct hinic3_set_fdir_ethertype_rule));
+	ethertype_cmd.func_id = hinic3_global_func_id(hwdev);
+	ethertype_cmd.pkt_type = pkt_type;
+	ethertype_cmd.pkt_type_en = en;
+	ethertype_cmd.qid = (u8)queue_id;
+
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_SET_FDIR_STATUS,
+				     &ethertype_cmd, sizeof(ethertype_cmd),
+				     &ethertype_cmd, &out_size);
+	if (err || ethertype_cmd.head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "set fdir ethertype rule failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x, func_id %d",
+			    err, ethertype_cmd.head.status, out_size,
+			    ethertype_cmd.func_id);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_add_tcam_rule(void *hwdev, struct hinic3_tcam_cfg_rule *tcam_rule,
+		     u8 tcam_rule_type)
+{
+	struct hinic3_fdir_add_rule tcam_cmd;
+	u16 out_size = sizeof(tcam_cmd);
+	int err;
+
+	if (!hwdev || !tcam_rule)
+		return -EINVAL;
+	/* Check whether the index is out of range. */
+	if (tcam_rule->index >= HINIC3_MAX_TCAM_RULES_NUM) {
+		PMD_DRV_LOG(ERR, "Tcam rules num to add is invalid");
+		return -EINVAL;
+	}
+
+	memset(&tcam_cmd, 0, sizeof(struct hinic3_fdir_add_rule));
+	tcam_cmd.func_id = hinic3_global_func_id(hwdev);
+	memcpy((void *)&tcam_cmd.rule, (void *)tcam_rule,
+	       sizeof(struct hinic3_tcam_cfg_rule));
+	tcam_cmd.type = tcam_rule_type;
+
+	/* Synchronize the information to the management module. */
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_ADD_TC_FLOW,
+				     &tcam_cmd, sizeof(tcam_cmd), &tcam_cmd,
+				     &out_size);
+	if (err || tcam_cmd.msg_head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Add tcam rule failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, tcam_cmd.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+hinic3_del_tcam_rule(void *hwdev, u32 index, u8 tcam_rule_type)
+{
+	struct hinic3_fdir_del_rule tcam_cmd;
+	u16 out_size = sizeof(tcam_cmd);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+	/* Check whether the index is out of range. */
+	if (index >= HINIC3_MAX_TCAM_RULES_NUM) {
+		PMD_DRV_LOG(ERR, "Tcam rules num to del is invalid");
+		return -EINVAL;
+	}
+
+	memset(&tcam_cmd, 0, sizeof(struct hinic3_fdir_del_rule));
+	tcam_cmd.func_id = hinic3_global_func_id(hwdev);
+	tcam_cmd.index_start = index;
+	tcam_cmd.index_num = 1;
+	tcam_cmd.type = tcam_rule_type;
+
+	/* Synchronize the information to the management module. */
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_DEL_TC_FLOW,
+				     &tcam_cmd, sizeof(tcam_cmd), &tcam_cmd,
+				     &out_size);
+	if (err || tcam_cmd.msg_head.status || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Del tcam rule failed, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, tcam_cmd.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int
+hinic3_cfg_tcam_block(void *hwdev, u8 alloc_en, u16 *index)
+{
+	struct hinic3_tcam_block tcam_block_info;
+	u16 out_size = sizeof(tcam_block_info);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+	/* Initialization TCAM block structure. */
+	memset(&tcam_block_info, 0, sizeof(struct hinic3_tcam_block));
+	tcam_block_info.func_id = hinic3_global_func_id(hwdev);
+	tcam_block_info.alloc_en = alloc_en;
+	tcam_block_info.tcam_type = HINIC3_TCAM_BLOCK_NORMAL_TYPE;
+	tcam_block_info.tcam_block_index = *index;
+
+	/* Synchronize the information to the management module. */
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_CFG_TCAM_BLOCK,
+				     &tcam_block_info, sizeof(tcam_block_info),
+				     &tcam_block_info, &out_size);
+	if (err || !out_size || tcam_block_info.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Set tcam block failed, err: %d, status: 0x%x, out "
+			    "size: 0x%x",
+			    err, tcam_block_info.msg_head.status, out_size);
+		return -EIO;
+	}
+
+	/* Update TCAM block of index. */
+	if (alloc_en)
+		*index = tcam_block_info.tcam_block_index;
+
+	return 0;
+}
+
+int
+hinic3_alloc_tcam_block(void *hwdev, u16 *index)
+{
+	return hinic3_cfg_tcam_block(hwdev, HINIC3_TCAM_BLOCK_ENABLE, index);
+}
+
+int
+hinic3_free_tcam_block(void *hwdev, u16 *index)
+{
+	return hinic3_cfg_tcam_block(hwdev, HINIC3_TCAM_BLOCK_DISABLE, index);
+}
+
+int
+hinic3_flush_tcam_rule(void *hwdev)
+{
+	struct hinic3_flush_tcam_rules tcam_flush;
+	u16 out_size = sizeof(tcam_flush);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	memset(&tcam_flush, 0, sizeof(struct hinic3_flush_tcam_rules));
+	tcam_flush.func_id = hinic3_global_func_id(hwdev);
+
+	err = l2nic_msg_to_mgmt_sync(hwdev,
+		HINIC3_NIC_CMD_FLUSH_TCAM, &tcam_flush,
+		sizeof(struct hinic3_flush_tcam_rules), &tcam_flush, &out_size);
+	if (tcam_flush.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+		err = HINIC3_MGMT_CMD_UNSUPPORTED;
+		PMD_DRV_LOG(INFO,
+			    "Firmware/uP doesn't support flush tcam fdir");
+	} else if (err || (!out_size) || tcam_flush.msg_head.status) {
+		PMD_DRV_LOG(ERR,
+			    "Flush tcam fdir rules failed, err: %d, status: "
+			    "0x%x, out size: 0x%x",
+			    err, tcam_flush.msg_head.status, out_size);
+		err = -EIO;
+	}
+
+	return err;
+}
+
+int
+hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable)
+{
+	struct hinic3_port_tcam_info port_tcam_cmd;
+	u16 out_size = sizeof(port_tcam_cmd);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+	/* Initialization information. */
+	memset(&port_tcam_cmd, 0, sizeof(port_tcam_cmd));
+	port_tcam_cmd.func_id = hinic3_global_func_id(hwdev);
+	port_tcam_cmd.tcam_enable = (u8)enable;
+
+	/* Synchronize the information to the management module. */
+	err = l2nic_msg_to_mgmt_sync(hwdev, HINIC3_NIC_CMD_ENABLE_TCAM,
+				     &port_tcam_cmd, sizeof(port_tcam_cmd),
+				     &port_tcam_cmd, &out_size);
+	if ((port_tcam_cmd.msg_head.status != HINIC3_MGMT_CMD_UNSUPPORTED &&
+	     port_tcam_cmd.msg_head.status) ||
+	    err || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Set fdir tcam filter failed, err: %d, "
+			    "status: 0x%x, out size: 0x%x, enable: 0x%x",
+			    err, port_tcam_cmd.msg_head.status, out_size,
+			    enable);
+		return -EIO;
+	}
+
+	if (port_tcam_cmd.msg_head.status == HINIC3_MGMT_CMD_UNSUPPORTED) {
+		err = HINIC3_MGMT_CMD_UNSUPPORTED;
+		PMD_DRV_LOG(WARNING,
+			    "Fw doesn't support setting fdir tcam filter");
+	}
+
+	return err;
+}
+
+int
+hinic3_set_rq_flush(void *hwdev, u16 q_id)
+{
+	struct hinic3_cmd_set_rq_flush *rq_flush_msg = NULL;
+	struct hinic3_cmd_buf *cmd_buf = NULL;
+	u64 out_param = EIO;
+	int err;
+
+	cmd_buf = hinic3_alloc_cmd_buf(hwdev);
+	if (!cmd_buf) {
+		PMD_DRV_LOG(ERR, "Failed to allocate cmd buf");
+		return -ENOMEM;
+	}
+
+	cmd_buf->size = sizeof(*rq_flush_msg);
+
+	rq_flush_msg = cmd_buf->buf;
+	rq_flush_msg->local_rq_id = q_id;
+	rte_mb();
+	rq_flush_msg->value = cpu_to_be32(rq_flush_msg->value);
+
+	err = hinic3_cmdq_direct_resp(hwdev, HINIC3_MOD_L2NIC,
+				      HINIC3_UCODE_CMD_SET_RQ_FLUSH, cmd_buf,
+				      &out_param, 0);
+	if (err || out_param != 0) {
+		PMD_DRV_LOG(ERR,
+			"Failed to set rq flush, err:%d, out_param:0x%" PRIx64,
+			err, out_param);
+		err = -EFAULT;
+	}
+
+	hinic3_free_cmd_buf(cmd_buf);
+
+	return err;
+}
+
+static int
+_mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+		      void *buf_out, u16 *out_size)
+{
+	u32 i, cmd_cnt = ARRAY_LEN(vf_mag_cmd_handler);
+
+	if (hinic3_func_type(hwdev) == TYPE_VF) {
+		for (i = 0; i < cmd_cnt; i++) {
+			if (cmd == vf_mag_cmd_handler[i].cmd)
+				return hinic3_mbox_to_pf(hwdev,
+					HINIC3_MOD_HILINK, cmd, buf_in,
+					in_size, buf_out, out_size, 0);
+		}
+	}
+
+	return hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_HILINK, cmd, buf_in,
+				       in_size, buf_out, out_size, 0);
+}
+
+static int
+mag_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+		     void *buf_out, u16 *out_size)
+{
+	return _mag_msg_to_mgmt_sync(hwdev, cmd, buf_in, in_size, buf_out,
+				     out_size);
+}
+
+int
+hinic3_set_link_status_follow(void *hwdev,
+			      enum hinic3_link_follow_status status)
+{
+	struct mag_cmd_set_link_follow follow;
+	u16 out_size = sizeof(follow);
+	int err;
+
+	if (!hwdev)
+		return -EINVAL;
+
+	if (status >= HINIC3_LINK_FOLLOW_STATUS_MAX) {
+		PMD_DRV_LOG(ERR, "Invalid link follow status: %d", status);
+		return -EINVAL;
+	}
+
+	memset(&follow, 0, sizeof(follow));
+	follow.function_id = hinic3_global_func_id(hwdev);
+	follow.follow = status;
+
+	err = mag_msg_to_mgmt_sync(hwdev, MAG_CMD_SET_LINK_FOLLOW, &follow,
+				   sizeof(follow), &follow, &out_size);
+	if ((follow.head.status != HINIC3_MGMT_CMD_UNSUPPORTED &&
+	     follow.head.status) ||
+	    err || !out_size) {
+		PMD_DRV_LOG(ERR,
+			    "Failed to set link status follow port status, "
+			    "err: %d, status: 0x%x, out size: 0x%x",
+			    err, follow.head.status, out_size);
+		return -EFAULT;
+	}
+
+	return follow.head.status;
+}
diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.h b/drivers/net/hinic3/base/hinic3_nic_cfg.h
new file mode 100644
index 0000000000..3e8e14e405
--- /dev/null
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.h
@@ -0,0 +1,1527 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2025 Huawei Technologies Co., Ltd
+ */
+
+#ifndef _HINIC3_NIC_CFG_H_
+#define _HINIC3_NIC_CFG_H_
+
+#include "hinic3_mgmt.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define OS_VF_ID_TO_HW(os_vf_id) ((os_vf_id) + 1)
+#define HW_VF_ID_TO_OS(hw_vf_id) ((hw_vf_id) - 1)
+
+#define HINIC3_VLAN_PRIORITY_SHIFT 13
+
+#define HINIC3_DCB_UP_MAX 0x8
+
+#define HINIC3_MAX_NUM_RQ 256
+
+#define HINIC3_MAX_MTU_SIZE 9600
+#define HINIC3_MIN_MTU_SIZE 256
+
+#define HINIC3_COS_NUM_MAX 8
+
+#define HINIC3_VLAN_TAG_SIZE 4
+#define HINIC3_ETH_OVERHEAD \
+	(RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + HINIC3_VLAN_TAG_SIZE * 2)
+
+#define HINIC3_MIN_FRAME_SIZE	    (HINIC3_MIN_MTU_SIZE + HINIC3_ETH_OVERHEAD)
+#define HINIC3_MAX_JUMBO_FRAME_SIZE (HINIC3_MAX_MTU_SIZE + HINIC3_ETH_OVERHEAD)
+
+#define HINIC3_MTU_TO_PKTLEN(mtu) (mtu)
+
+#define HINIC3_PKTLEN_TO_MTU(pktlen) (pktlen)
+
+#define HINIC3_PF_SET_VF_ALREADY 0x4
+#define HINIC3_MGMT_STATUS_EXIST 0x6
+#define CHECK_IPSU_15BIT	 0x8000
+
+#define HINIC3_MGMT_STATUS_TABLE_EMPTY 0xB
+#define HINIC3_MGMT_STATUS_TABLE_FULL  0xC
+
+#define HINIC3_MGMT_CMD_UNSUPPORTED 0xFF
+
+#define HINIC3_MAX_UC_MAC_ADDRS 128
+#define HINIC3_MAX_MC_MAC_ADDRS 2048
+
+#define CAP_INFO_MAX_LEN 512
+#define VENDOR_MAX_LEN	 17
+
+/* Structures for RSS config. */
+#define HINIC3_RSS_INDIR_SIZE	   256
+#define HINIC3_RSS_INDIR_CMDQ_SIZE 128
+#define HINIC3_RSS_KEY_SIZE	   40
+#define HINIC3_RSS_ENABLE	   0x01
+#define HINIC3_RSS_DISABLE	   0x00
+#define HINIC3_INVALID_QID_BASE	   0xffff
+
+#ifndef ETH_SPEED_NUM_200G
+#define ETH_SPEED_NUM_200G 200000 /**< 200 Gbps. */
+#endif
+
+struct hinic3_rss_type {
+	u8 tcp_ipv6_ext;
+	u8 ipv6_ext;
+	u8 tcp_ipv6;
+	u8 ipv6;
+	u8 tcp_ipv4;
+	u8 ipv4;
+	u8 udp_ipv6;
+	u8 udp_ipv4;
+};
+
+enum hinic3_rss_hash_type {
+	HINIC3_RSS_HASH_ENGINE_TYPE_XOR = 0,
+	HINIC3_RSS_HASH_ENGINE_TYPE_TOEP,
+	HINIC3_RSS_HASH_ENGINE_TYPE_MAX,
+};
+
+#define MAX_FEATURE_QWORD 4
+struct hinic3_cmd_feature_nego {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 opcode; /**< 1: set, 0: get. */
+	u8 rsvd;
+	u64 s_feature[MAX_FEATURE_QWORD];
+};
+
+/* Structures for port info. */
+struct nic_port_info {
+	u8 port_type;
+	u8 autoneg_cap;
+	u8 autoneg_state;
+	u8 duplex;
+	u8 speed;
+	u8 fec;
+};
+
+enum hinic3_link_status { HINIC3_LINK_DOWN = 0, HINIC3_LINK_UP };
+
+enum nic_media_type {
+	MEDIA_UNKNOWN = -1,
+	MEDIA_FIBRE = 0,
+	MEDIA_COPPER,
+	MEDIA_BACKPLANE
+};
+
+enum nic_speed_level {
+	LINK_SPEED_NOT_SET = 0,
+	LINK_SPEED_10MB,
+	LINK_SPEED_100MB,
+	LINK_SPEED_1GB,
+	LINK_SPEED_10GB,
+	LINK_SPEED_25GB,
+	LINK_SPEED_40GB,
+	LINK_SPEED_50GB,
+	LINK_SPEED_100GB,
+	LINK_SPEED_200GB,
+	LINK_SPEED_LEVELS,
+};
+
+enum hinic3_nic_event_type {
+	EVENT_NIC_LINK_DOWN,
+	EVENT_NIC_LINK_UP,
+	EVENT_NIC_PORT_MODULE_EVENT,
+	EVENT_NIC_DCB_STATE_CHANGE,
+};
+
+enum hinic3_link_port_type {
+	LINK_PORT_UNKNOWN,
+	LINK_PORT_OPTICAL_MM,
+	LINK_PORT_OPTICAL_SM,
+	LINK_PORT_PAS_COPPER,
+	LINK_PORT_ACC,
+	LINK_PORT_BASET,
+	LINK_PORT_AOC = 0x40,
+	LINK_PORT_ELECTRIC,
+	LINK_PORT_BACKBOARD_INTERFACE,
+};
+
+enum hilink_fibre_subtype {
+	FIBRE_SUBTYPE_SR = 1,
+	FIBRE_SUBTYPE_LR,
+	FIBRE_SUBTYPE_MAX,
+};
+
+enum hilink_fec_type {
+	HILINK_FEC_NOT_SET,
+	HILINK_FEC_RSFEC,
+	HILINK_FEC_BASEFEC,
+	HILINK_FEC_NOFEC,
+	HILINK_FEC_LLRSFE,
+	HILINK_FEC_MAX_TYPE,
+};
+
+enum mag_cmd_port_an {
+	PORT_AN_NOT_SET = 0,
+	PORT_CFG_AN_ON = 1,
+	PORT_CFG_AN_OFF = 2
+};
+
+enum mag_cmd_port_speed {
+	PORT_SPEED_NOT_SET = 0,
+	PORT_SPEED_10MB = 1,
+	PORT_SPEED_100MB = 2,
+	PORT_SPEED_1GB = 3,
+	PORT_SPEED_10GB = 4,
+	PORT_SPEED_25GB = 5,
+	PORT_SPEED_40GB = 6,
+	PORT_SPEED_50GB = 7,
+	PORT_SPEED_100GB = 8,
+	PORT_SPEED_200GB = 9,
+	PORT_SPEED_UNKNOWN
+};
+
+struct hinic3_sq_attr {
+	u8 dma_attr_off;
+	u8 pending_limit;
+	u8 coalescing_time;
+	u8 intr_en;
+	u16 intr_idx;
+	u32 l2nic_sqn;
+	u64 ci_dma_base;
+};
+
+struct hinic3_cmd_cons_idx_attr {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_idx;
+	u8 dma_attr_off;
+	u8 pending_limit;
+	u8 coalescing_time;
+	u8 intr_en;
+	u16 intr_idx;
+	u32 l2nic_sqn;
+	u32 rsvd;
+	u64 ci_addr;
+};
+
+struct hinic3_port_mac_set {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 vlan_id;
+	u16 rsvd1;
+	u8 mac[ETH_ALEN];
+};
+
+struct hinic3_port_mac_update {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 vlan_id;
+	u16 rsvd1;
+	u8 old_mac[ETH_ALEN];
+	u16 rsvd2;
+	u8 new_mac[ETH_ALEN];
+};
+
+struct hinic3_ppa_cfg_state_cmd {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 ppa_state;
+	u8 rsvd;
+};
+
+struct hinic3_ppa_cfg_mode_cmd {
+	struct mgmt_msg_head msg_head;
+
+	u16 rsvd0;
+	u8 ppa_mode;
+	u8 qpc_func_nums;
+	u16 base_qpc_func_id;
+	u16 rsvd1;
+};
+
+struct hinic3_ppa_cfg_flush_cmd {
+	struct mgmt_msg_head msg_head;
+
+	u16 rsvd0;
+	u8 flush_en; /**< 0: flush done, 1: in flush operation. */
+	u8 rsvd1;
+};
+
+struct hinic3_ppa_fdir_query_cmd {
+	struct mgmt_msg_head msg_head;
+
+	u32 index;
+	u32 rsvd;
+	u64 pkt_nums;
+	u64 pkt_bytes;
+};
+
+#define HINIC3_CMD_OP_ADD 1
+#define HINIC3_CMD_OP_DEL 0
+
+struct hinic3_cmd_vlan_config {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 opcode;
+	u8 rsvd1;
+	u16 vlan_id;
+	u16 rsvd2;
+};
+
+struct hinic3_cmd_set_vlan_filter {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 resvd[2];
+	/* Bit0: vlan filter en, bit1: broadcast filter en. */
+	u32 vlan_filter_ctrl;
+};
+
+struct hinic3_cmd_port_info {
+	struct mgmt_msg_head msg_head;
+
+	u8 port_id;
+	u8 rsvd1[3];
+	u8 port_type;
+	u8 autoneg_cap;
+	u8 autoneg_state;
+	u8 duplex;
+	u8 speed;
+	u8 fec;
+	u16 rsvd2;
+	u32 rsvd3[4];
+};
+
+struct hinic3_cmd_link_state {
+	struct mgmt_msg_head msg_head;
+
+	u8 port_id;
+	u8 state;
+	u16 rsvd1;
+};
+
+struct nic_pause_config {
+	u8 auto_neg;
+	u8 rx_pause;
+	u8 tx_pause;
+};
+
+struct hinic3_cmd_pause_config {
+	struct mgmt_msg_head msg_head;
+
+	u8 port_id;
+	u8 opcode;
+	u16 rsvd1;
+	u8 auto_neg;
+	u8 rx_pause;
+	u8 tx_pause;
+	u8 rsvd2[5];
+};
+
+struct hinic3_vport_state {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+	u8 state; /**< 0:disable, 1:enable. */
+	u8 rsvd2[3];
+};
+
+#define MAG_CMD_PORT_DISABLE 0x0
+#define MAG_CMD_TX_ENABLE    0x1
+#define MAG_CMD_RX_ENABLE    0x2
+/**
+ * The physical port is disable only when all pf of the port are set to down, if
+ * any pf is enable, the port is enable.
+ */
+struct mag_cmd_set_port_enable {
+	struct mgmt_msg_head head;
+	/* function_id should not more than the max support pf_id(32). */
+	u16 function_id;
+	u16 rsvd0;
+
+	/* bitmap bit0:tx_en, bit1:rx_en. */
+	u8 state;
+	u8 rsvd1[3];
+};
+
+struct mag_cmd_get_port_enable {
+	struct mgmt_msg_head head;
+
+	u8 port;
+	u8 state; /**< bitmap bit0:tx_en, bit1:rx_en. */
+	u8 rsvd0[2];
+};
+
+struct hinic3_cmd_clear_qp_resource {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+};
+
+struct hinic3_port_stats_info {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+};
+
+struct hinic3_vport_stats {
+	u64 tx_unicast_pkts_vport;
+	u64 tx_unicast_bytes_vport;
+	u64 tx_multicast_pkts_vport;
+	u64 tx_multicast_bytes_vport;
+	u64 tx_broadcast_pkts_vport;
+	u64 tx_broadcast_bytes_vport;
+
+	u64 rx_unicast_pkts_vport;
+	u64 rx_unicast_bytes_vport;
+	u64 rx_multicast_pkts_vport;
+	u64 rx_multicast_bytes_vport;
+	u64 rx_broadcast_pkts_vport;
+	u64 rx_broadcast_bytes_vport;
+
+	u64 tx_discard_vport;
+	u64 rx_discard_vport;
+	u64 tx_err_vport;
+	u64 rx_err_vport;
+};
+
+struct hinic3_cmd_vport_stats {
+	struct mgmt_msg_head msg_head;
+
+	u32 stats_size;
+	u32 rsvd1;
+	struct hinic3_vport_stats stats;
+	u64 rsvd2[6];
+};
+
+struct hinic3_phy_port_stats {
+	u64 mac_rx_total_octs_port;
+	u64 mac_tx_total_octs_port;
+	u64 mac_rx_under_frame_pkts_port;
+	u64 mac_rx_frag_pkts_port;
+	u64 mac_rx_64_oct_pkts_port;
+	u64 mac_rx_127_oct_pkts_port;
+	u64 mac_rx_255_oct_pkts_port;
+	u64 mac_rx_511_oct_pkts_port;
+	u64 mac_rx_1023_oct_pkts_port;
+	u64 mac_rx_max_oct_pkts_port;
+	u64 mac_rx_over_oct_pkts_port;
+	u64 mac_tx_64_oct_pkts_port;
+	u64 mac_tx_127_oct_pkts_port;
+	u64 mac_tx_255_oct_pkts_port;
+	u64 mac_tx_511_oct_pkts_port;
+	u64 mac_tx_1023_oct_pkts_port;
+	u64 mac_tx_max_oct_pkts_port;
+	u64 mac_tx_over_oct_pkts_port;
+	u64 mac_rx_good_pkts_port;
+	u64 mac_rx_crc_error_pkts_port;
+	u64 mac_rx_broadcast_ok_port;
+	u64 mac_rx_multicast_ok_port;
+	u64 mac_rx_mac_frame_ok_port;
+	u64 mac_rx_length_err_pkts_port;
+	u64 mac_rx_vlan_pkts_port;
+	u64 mac_rx_pause_pkts_port;
+	u64 mac_rx_unknown_mac_frame_port;
+	u64 mac_tx_good_pkts_port;
+	u64 mac_tx_broadcast_ok_port;
+	u64 mac_tx_multicast_ok_port;
+	u64 mac_tx_underrun_pkts_port;
+	u64 mac_tx_mac_frame_ok_port;
+	u64 mac_tx_vlan_pkts_port;
+	u64 mac_tx_pause_pkts_port;
+};
+
+struct mag_phy_port_stats {
+	u64 mac_tx_fragment_pkt_num;
+	u64 mac_tx_undersize_pkt_num;
+	u64 mac_tx_undermin_pkt_num;
+	u64 mac_tx_64_oct_pkt_num;
+	u64 mac_tx_65_127_oct_pkt_num;
+	u64 mac_tx_128_255_oct_pkt_num;
+	u64 mac_tx_256_511_oct_pkt_num;
+	u64 mac_tx_512_1023_oct_pkt_num;
+	u64 mac_tx_1024_1518_oct_pkt_num;
+	u64 mac_tx_1519_2047_oct_pkt_num;
+	u64 mac_tx_2048_4095_oct_pkt_num;
+	u64 mac_tx_4096_8191_oct_pkt_num;
+	u64 mac_tx_8192_9216_oct_pkt_num;
+	u64 mac_tx_9217_12287_oct_pkt_num;
+	u64 mac_tx_12288_16383_oct_pkt_num;
+	u64 mac_tx_1519_max_bad_pkt_num;
+	u64 mac_tx_1519_max_good_pkt_num;
+	u64 mac_tx_oversize_pkt_num;
+	u64 mac_tx_jabber_pkt_num;
+	u64 mac_tx_bad_pkt_num;
+	u64 mac_tx_bad_oct_num;
+	u64 mac_tx_good_pkt_num;
+	u64 mac_tx_good_oct_num;
+	u64 mac_tx_total_pkt_num;
+	u64 mac_tx_total_oct_num;
+	u64 mac_tx_uni_pkt_num;
+	u64 mac_tx_multi_pkt_num;
+	u64 mac_tx_broad_pkt_num;
+	u64 mac_tx_pause_num;
+	u64 mac_tx_pfc_pkt_num;
+	u64 mac_tx_pfc_pri0_pkt_num;
+	u64 mac_tx_pfc_pri1_pkt_num;
+	u64 mac_tx_pfc_pri2_pkt_num;
+	u64 mac_tx_pfc_pri3_pkt_num;
+	u64 mac_tx_pfc_pri4_pkt_num;
+	u64 mac_tx_pfc_pri5_pkt_num;
+	u64 mac_tx_pfc_pri6_pkt_num;
+	u64 mac_tx_pfc_pri7_pkt_num;
+	u64 mac_tx_control_pkt_num;
+	u64 mac_tx_err_all_pkt_num;
+	u64 mac_tx_from_app_good_pkt_num;
+	u64 mac_tx_from_app_bad_pkt_num;
+
+	u64 mac_rx_fragment_pkt_num;
+	u64 mac_rx_undersize_pkt_num;
+	u64 mac_rx_undermin_pkt_num;
+	u64 mac_rx_64_oct_pkt_num;
+	u64 mac_rx_65_127_oct_pkt_num;
+	u64 mac_rx_128_255_oct_pkt_num;
+	u64 mac_rx_256_511_oct_pkt_num;
+	u64 mac_rx_512_1023_oct_pkt_num;
+	u64 mac_rx_1024_1518_oct_pkt_num;
+	u64 mac_rx_1519_2047_oct_pkt_num;
+	u64 mac_rx_2048_4095_oct_pkt_num;
+	u64 mac_rx_4096_8191_oct_pkt_num;
+	u64 mac_rx_8192_9216_oct_pkt_num;
+	u64 mac_rx_9217_12287_oct_pkt_num;
+	u64 mac_rx_12288_16383_oct_pkt_num;
+	u64 mac_rx_1519_max_bad_pkt_num;
+	u64 mac_rx_1519_max_good_pkt_num;
+	u64 mac_rx_oversize_pkt_num;
+	u64 mac_rx_jabber_pkt_num;
+	u64 mac_rx_bad_pkt_num;
+	u64 mac_rx_bad_oct_num;
+	u64 mac_rx_good_pkt_num;
+	u64 mac_rx_good_oct_num;
+	u64 mac_rx_total_pkt_num;
+	u64 mac_rx_total_oct_num;
+	u64 mac_rx_uni_pkt_num;
+	u64 mac_rx_multi_pkt_num;
+	u64 mac_rx_broad_pkt_num;
+	u64 mac_rx_pause_num;
+	u64 mac_rx_pfc_pkt_num;
+	u64 mac_rx_pfc_pri0_pkt_num;
+	u64 mac_rx_pfc_pri1_pkt_num;
+	u64 mac_rx_pfc_pri2_pkt_num;
+	u64 mac_rx_pfc_pri3_pkt_num;
+	u64 mac_rx_pfc_pri4_pkt_num;
+	u64 mac_rx_pfc_pri5_pkt_num;
+	u64 mac_rx_pfc_pri6_pkt_num;
+	u64 mac_rx_pfc_pri7_pkt_num;
+	u64 mac_rx_control_pkt_num;
+	u64 mac_rx_sym_err_pkt_num;
+	u64 mac_rx_fcs_err_pkt_num;
+	u64 mac_rx_send_app_good_pkt_num;
+	u64 mac_rx_send_app_bad_pkt_num;
+	u64 mac_rx_unfilter_pkt_num;
+};
+
+struct mag_cmd_port_stats_info {
+	struct mgmt_msg_head head;
+
+	u8 port_id;
+	u8 rsvd0[3];
+};
+
+struct mag_cmd_get_port_stat {
+	struct mgmt_msg_head head;
+
+	struct mag_phy_port_stats counter;
+	u64 rsvd1[15];
+};
+
+struct param_head {
+	u8 valid_len;
+	u8 info_type;
+	u8 rsvd[2];
+};
+
+struct mag_port_link_param {
+	struct param_head head;
+
+	u8 an;
+	u8 fec;
+	u8 speed;
+	u8 rsvd0;
+
+	u32 used;
+	u32 an_fec_ability;
+	u32 an_speed_ability;
+	u32 an_pause_ability;
+};
+
+struct mag_port_wire_info {
+	struct param_head head;
+
+	u8 status;
+	u8 rsvd0[3];
+
+	u8 wire_type;
+	u8 default_fec;
+	u8 speed;
+	u8 rsvd1;
+	u32 speed_ability;
+};
+
+struct mag_port_adapt_info {
+	struct param_head head;
+
+	u32 adapt_en;
+	u32 flash_adapt;
+	u32 rsvd0[2];
+
+	u32 wire_node;
+	u32 an_en;
+	u32 speed;
+	u32 fec;
+};
+
+struct mag_port_param_info {
+	u8 parameter_cnt;
+	u8 lane_id;
+	u8 lane_num;
+	u8 rsvd0;
+
+	struct mag_port_link_param default_cfg;
+	struct mag_port_link_param bios_cfg;
+	struct mag_port_link_param tool_cfg;
+	struct mag_port_link_param final_cfg;
+
+	struct mag_port_wire_info wire_info;
+	struct mag_port_adapt_info adapt_info;
+};
+
+#define XSFP_VENDOR_NAME_LEN 16
+struct mag_cmd_event_port_info {
+	struct mgmt_msg_head head;
+
+	u8 port_id;
+	u8 event_type;
+	u8 rsvd0[2];
+
+	/* Optical Module Related. */
+	u8 vendor_name[XSFP_VENDOR_NAME_LEN];
+	u32 port_type;	   /**< fiber / copper. */
+	u32 port_sub_type; /**< sr / lr. */
+	u32 cable_length;  /**< 1 / 3 / 5 m. */
+	u8 cable_temp;	   /**< Temperature. */
+	u8 max_speed;	   /**< Max rate of optical module. */
+	u8 sfp_type;	   /**< sfp / qsfp. */
+	u8 rsvd1;
+	u32 power[4]; /**< Optical power. */
+
+	u8 an_state;
+	u8 fec;
+	u16 speed;
+
+	u8 gpio_insert; /**< 0: present, 1: absent. */
+	u8 alos;
+	u8 rx_los;
+	u8 pma_ctrl;
+
+	u32 pma_fifo_reg;
+	u32 pma_signal_ok_reg;
+	u32 pcs_64_66b_reg;
+	u32 rf_lf;
+	u8 pcs_link;
+	u8 pcs_mac_link;
+	u8 tx_enable;
+	u8 rx_enable;
+	u32 pcs_err_cnt;
+
+	u8 eq_data[38];
+	u8 rsvd2[2];
+
+	u32 his_link_machine_state;
+	u32 cur_link_machine_state;
+	u8 his_machine_state_data[128];
+	u8 cur_machine_state_data[128];
+	u8 his_machine_state_length;
+	u8 cur_machine_state_length;
+
+	struct mag_port_param_info param_info;
+	u8 rsvd3[360];
+};
+
+struct hinic3_port_stats {
+	struct mgmt_msg_head msg_head;
+
+	struct hinic3_phy_port_stats stats;
+};
+
+struct hinic3_cmd_clear_vport_stats {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd;
+};
+
+struct hinic3_cmd_clear_port_stats {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd;
+};
+
+struct hinic3_cmd_qpn {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 base_qpn;
+};
+
+enum hinic3_func_tbl_cfg_bitmap {
+	FUNC_CFG_INIT,
+	FUNC_CFG_RX_BUF_SIZE,
+	FUNC_CFG_MTU,
+};
+
+struct hinic3_func_tbl_cfg {
+	u16 rx_wqe_buf_size;
+	u16 mtu;
+	u32 rsvd[9];
+};
+
+struct hinic3_cmd_set_func_tbl {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd;
+
+	u32 cfg_bitmap;
+	struct hinic3_func_tbl_cfg tbl_cfg;
+};
+
+struct hinic3_rx_mode_config {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+	u32 rx_mode;
+};
+
+struct hinic3_cmd_vlan_offload {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 vlan_offload;
+	u8 rsvd1[5];
+};
+
+#define HINIC3_CMD_OP_GET 0
+#define HINIC3_CMD_OP_SET 1
+
+struct hinic3_cmd_lro_config {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 opcode;
+	u8 rsvd1;
+	u8 lro_ipv4_en;
+	u8 lro_ipv6_en;
+	u8 lro_max_pkt_len; /**< Unit size is 1K. */
+	u8 resv2[13];
+};
+
+struct hinic3_cmd_lro_timer {
+	struct mgmt_msg_head msg_head;
+
+	u8 opcode; /**< 1: set timer value, 0: get timer value. */
+	u8 rsvd1;
+	u16 rsvd2;
+	u32 timer;
+};
+
+struct hinic3_rss_template_mgmt {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 cmd;
+	u8 template_id;
+	u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_hash_key {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 opcode;
+	u8 rsvd1;
+	u8 key[HINIC3_RSS_KEY_SIZE];
+};
+
+struct hinic3_rss_indir_table {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+	u8 indir[HINIC3_RSS_INDIR_SIZE];
+};
+
+struct nic_rss_indirect_tbl {
+	u32 rsvd[4]; /**< Make sure that 16B beyond entry[]. */
+	u16 entry[HINIC3_RSS_INDIR_SIZE];
+};
+
+struct nic_rss_context_tbl {
+	u32 rsvd[4];
+	u32 ctx;
+};
+
+struct hinic3_rss_context_table {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd1;
+	u32 context;
+};
+
+struct hinic3_cmd_rss_engine_type {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 opcode;
+	u8 hash_engine;
+	u8 rsvd1[4];
+};
+
+struct hinic3_cmd_rss_config {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 rss_en;
+	u8 rq_priority_number;
+	u8 prio_tc[HINIC3_DCB_UP_MAX];
+	u32 rsvd1;
+};
+
+enum {
+	HINIC3_IFLA_VF_LINK_STATE_AUTO,	   /**< Link state of the uplink. */
+	HINIC3_IFLA_VF_LINK_STATE_ENABLE,  /**< Link always up. */
+	HINIC3_IFLA_VF_LINK_STATE_DISABLE, /**< Link always down. */
+};
+
+struct hinic3_dcb_state {
+	u8 dcb_on;
+	u8 default_cos;
+	u8 trust;
+	u8 rsvd1;
+	u8 up_cos[HINIC3_DCB_UP_MAX];
+	u8 dscp2cos[64];
+	u32 rsvd2[7];
+};
+
+struct hinic3_cmd_vf_dcb_state {
+	struct mgmt_msg_head msg_head;
+
+	struct hinic3_dcb_state state;
+};
+
+struct hinic3_cmd_register_vf {
+	struct mgmt_msg_head msg_head;
+
+	u8 op_register; /* 0: unregister, 1: register. */
+	u8 rsvd[39];
+};
+
+struct hinic3_tcam_result {
+	u32 qid;
+	u32 rsvd;
+};
+
+#define HINIC3_TCAM_FLOW_KEY_SIZE     44
+#define HINIC3_MAX_TCAM_RULES_NUM     4096
+#define HINIC3_TCAM_BLOCK_ENABLE      1
+#define HINIC3_TCAM_BLOCK_DISABLE     0
+#define HINIC3_TCAM_BLOCK_NORMAL_TYPE 0
+
+struct hinic3_tcam_key_x_y {
+	u8 x[HINIC3_TCAM_FLOW_KEY_SIZE];
+	u8 y[HINIC3_TCAM_FLOW_KEY_SIZE];
+};
+
+struct hinic3_tcam_cfg_rule {
+	u32 index;
+	struct hinic3_tcam_result data;
+	struct hinic3_tcam_key_x_y key;
+};
+
+/* Define the TCAM type. */
+#define TCAM_RULE_FDIR_TYPE 0
+#define TCAM_RULE_PPA_TYPE  1
+
+struct hinic3_fdir_add_rule {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 type;
+	u8 rsvd;
+	struct hinic3_tcam_cfg_rule rule;
+};
+
+struct hinic3_fdir_del_rule {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 type;
+	u8 rsvd;
+	u32 index_start;
+	u32 index_num;
+};
+
+struct hinic3_flush_tcam_rules {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u16 rsvd;
+};
+
+struct hinic3_tcam_block {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 alloc_en; /* 0: free tcam block, 1: alloc tcam block. */
+	u8 tcam_type;
+	u16 tcam_block_index;
+	u16 rsvd;
+};
+
+struct hinic3_port_tcam_info {
+	struct mgmt_msg_head msg_head;
+
+	u16 func_id;
+	u8 tcam_enable;
+	u8 rsvd1;
+	u32 rsvd2;
+};
+
+struct hinic3_set_fdir_ethertype_rule {
+	struct mgmt_msg_head head;
+
+	u16 func_id;
+	u16 rsvd1;
+	u8 pkt_type_en;
+	u8 pkt_type;
+	u8 qid;
+	u8 rsvd2;
+};
+
+struct hinic3_cmd_set_rq_flush {
+	union {
+		struct {
+			u16 global_rq_id;
+			u16 local_rq_id;
+		};
+		u32 value;
+	};
+};
+
+enum hinic3_link_follow_status {
+	HINIC3_LINK_FOLLOW_DEFAULT,
+	HINIC3_LINK_FOLLOW_PORT,
+	HINIC3_LINK_FOLLOW_SEPARATE,
+	HINIC3_LINK_FOLLOW_STATUS_MAX,
+};
+
+struct mag_cmd_set_link_follow {
+	struct mgmt_msg_head head;
+	u16 function_id;
+	u16 rsvd0;
+	u8 follow;
+	u8 rsvd1[3];
+};
+
+int l2nic_msg_to_mgmt_sync(void *hwdev, u16 cmd, void *buf_in, u16 in_size,
+			   void *buf_out, u16 *out_size);
+
+int hinic3_set_ci_table(void *hwdev, struct hinic3_sq_attr *attr);
+
+/**
+ * Update MAC address to hardware.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] old_mac
+ * Old MAC addr to delete.
+ * @param[in] new_mac
+ * New MAC addr to update.
+ * @param[in] vlan_id
+ * Vlan id.
+ * @param func_id
+ * Function index.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_update_mac(void *hwdev, u8 *old_mac, u8 *new_mac, u16 vlan_id,
+		      u16 func_id);
+
+/**
+ * Get the default mac address.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] mac_addr
+ * Mac address from hardware.
+ * @param[in] ether_len
+ * The length of mac address.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_default_mac(void *hwdev, u8 *mac_addr, int ether_len);
+
+/**
+ * Set mac address.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] mac_addr
+ * Mac address from hardware.
+ * @param[in] vlan_id
+ * Vlan id.
+ * @param[in] func_id
+ * Function index.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id);
+
+/**
+ * Delete MAC address.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] mac_addr
+ * MAC address from hardware.
+ * @param[in] vlan_id
+ * Vlan id.
+ * @param[in] func_id
+ * Function index.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_del_mac(void *hwdev, const u8 *mac_addr, u16 vlan_id, u16 func_id);
+
+/**
+ * Set function mtu.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] new_mtu
+ * MTU value.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_port_mtu(void *hwdev, u16 new_mtu);
+
+/**
+ * Set function valid status.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] enable
+ * 0: disable, 1: enable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_vport_enable(void *hwdev, bool enable);
+
+/**
+ * Set port status.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev
+ * @param[in] enable
+ * 0: disable, 1: enable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_port_enable(void *hwdev, bool enable);
+
+/**
+ * Get link state.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] link_state
+ * Link state, 0: link down, 1: link up.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_link_state(void *hwdev, u8 *link_state);
+
+/**
+ * Flush queue pairs resource in hardware.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_flush_qps_res(void *hwdev);
+
+/**
+ * Set pause info.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] nic_pause
+ * Pause info.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_pause_info(void *hwdev, struct nic_pause_config nic_pause);
+
+/**
+ * Get pause info.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] nic_pause
+ * Pause info.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_pause_info(void *hwdev, struct nic_pause_config *nic_pause);
+
+/**
+ * Get function stats.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] stats
+ * Function stats.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_vport_stats(void *hwdev, struct hinic3_vport_stats *stats);
+
+/**
+ * Get port stats.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] stats
+ * Port stats.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+
+int hinic3_get_phy_port_stats(void *hwdev, struct mag_phy_port_stats *stats);
+
+int hinic3_clear_vport_stats(void *hwdev);
+
+int hinic3_clear_phy_port_stats(void *hwdev);
+
+/**
+ * Init nic hwdev.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_init_nic_hwdev(void *hwdev);
+
+/**
+ * Free nic hwdev.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ */
+void hinic3_free_nic_hwdev(void *hwdev);
+
+/**
+ * Set function rx mode.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] enable
+ * Rx mode state, 0-disable, 1-enable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_rx_mode(void *hwdev, u32 enable);
+
+/**
+ * Set function vlan offload valid state.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] enable
+ * Rx mode state, 0-disable, 1-enable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_rx_vlan_offload(void *hwdev, u8 en);
+
+/**
+ * Set rx LRO configuration.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] lro_en
+ * LRO enable state, 0-disable, 1-enable.
+ * @param[in] lro_timer
+ * LRO aggregation timeout.
+ * @param[in] lro_max_pkt_len
+ * LRO coalesce packet size(unit size is 1K).
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_rx_lro_state(void *hwdev, u8 lro_en, u32 lro_timer,
+			    u32 lro_max_pkt_len);
+
+/**
+ * Get port info.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] port_info
+ * Port info, including autoneg, port type, duplex, speed and fec mode.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_port_info(void *hwdev, struct nic_port_info *port_info);
+
+int hinic3_init_function_table(void *hwdev, u16 rx_buff_len);
+
+/**
+ * Alloc RSS template table.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_template_alloc(void *hwdev);
+
+/**
+ * Free RSS template table.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_template_free(void *hwdev);
+
+/**
+ * Set RSS indirect table.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] indir_table
+ * RSS indirect table.
+ * @param[in] indir_table_size
+ * RSS indirect table size.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_set_indir_tbl(void *hwdev, const u32 *indir_table,
+			     u32 indir_table_size);
+
+/**
+ * Get RSS indirect table.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] indir_table
+ * RSS indirect table.
+ * @param[in] indir_table_size
+ * RSS indirect table size.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_get_indir_tbl(void *hwdev, u32 *indir_table,
+			     u32 indir_table_size);
+
+/**
+ * Set RSS type.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] rss_type
+ * RSS type, including ipv4, tcpv4, ipv6, tcpv6 and etc.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_rss_type(void *hwdev, struct hinic3_rss_type rss_type);
+
+/**
+ * Get RSS type.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] rss_type
+ * RSS type, including ipv4, tcpv4, ipv6, tcpv6 and etc.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_rss_type(void *hwdev, struct hinic3_rss_type *rss_type);
+
+/**
+ * Get RSS hash engine.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] type
+ * RSS hash engine, pmd driver only supports Toeplitz.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_get_hash_engine(void *hwdev, u8 *type);
+
+/**
+ * Set RSS hash engine.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] type
+ * RSS hash engine, pmd driver only supports Toeplitz.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_set_hash_engine(void *hwdev, u8 type);
+
+/**
+ * Set RSS configuration.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] rss_en
+ * RSS enable lag, 0-disable, 1-enable.
+ * @param[in] tc_num
+ * Number of TC.
+ * @param[in] prio_tc
+ * Priority of TC.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_cfg(void *hwdev, u8 rss_en, u8 tc_num, u8 *prio_tc);
+
+/**
+ * Set RSS hash key.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] key
+ * RSS hash key.
+ * @param[in] key_size
+ * hash key size.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_rss_set_hash_key(void *hwdev, u8 *key, u16 key_size);
+
+/**
+ * Add vlan to hardware.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] vlan_id
+ * Vlan id.
+ * @param[in] func_id
+ * Function id.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_add_vlan(void *hwdev, u16 vlan_id, u16 func_id);
+
+/**
+ * Delete vlan.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] vlan_id
+ * Vlan id.
+ * @param[in] func_id
+ * Function id.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_del_vlan(void *hwdev, u16 vlan_id, u16 func_id);
+
+/**
+ * Set vlan filter.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] vlan_filter_ctrl
+ * Vlan filter enable flag, 0-disable, 1-enable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_vlan_fliter(void *hwdev, u32 vlan_filter_ctrl);
+
+/**
+ * Get VF function default cos.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[out] cos_id
+ * Cos id.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_vf_get_default_cos(void *hwdev, u8 *cos_id);
+
+/**
+ * Add tcam rules.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] tcam_rule
+ * Tcam rule, including tcam rule index, tcam action, tcam key and etc.
+ * @param[in] tcam_rule_type
+ * Tcam rule type.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_add_tcam_rule(void *hwdev, struct hinic3_tcam_cfg_rule *tcam_rule,
+			 u8 tcam_rule_type);
+
+/**
+ * Del tcam rules.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] index
+ * Tcam rule index.
+ * @param[in] tcam_rule_type
+ * Tcam rule type.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_del_tcam_rule(void *hwdev, u32 index, u8 tcam_rule_type);
+
+/**
+ * Alloc tcam block.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] index
+ * Tcam block index.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_alloc_tcam_block(void *hwdev, u16 *index);
+
+/**
+ * Free tcam block.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] index
+ * Tcam block index.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_free_tcam_block(void *hwdev, u16 *index);
+
+/**
+ * Set fdir tcam function enable or disable.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ * @param[in] enable
+ * Tcam enable flag, 1-enable, 0-disable.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_fdir_tcam_rule_filter(void *hwdev, bool enable);
+
+/**
+ * Flush fdir tcam rule.
+ *
+ * @param[in] hwdev
+ * Device pointer to hwdev.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_flush_tcam_rule(void *hwdev);
+
+int hinic3_set_rq_flush(void *hwdev, u16 q_id);
+
+/**
+ * Get service feature HW supported.
+ *
+ * @param[in] dev
+ * Device pointer to hwdev.
+ * @param[in] size
+ * s_feature's array size.
+ * @param[out] s_feature
+ * s_feature HW supported.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_get_feature_from_hw(void *hwdev, u64 *s_feature, u16 size);
+
+/**
+ * Set service feature driver supported to hardware.
+ *
+ * @param[in] dev
+ * Device pointer to hwdev.
+ * @param[in] size
+ * s_feature's array size.
+ * @param[out] s_feature
+ * s_feature HW supported.
+ *
+ * @return
+ * 0 on success, non-zero on failure.
+ */
+int hinic3_set_feature_to_hw(void *hwdev, u64 *s_feature, u16 size);
+
+int hinic3_set_fdir_ethertype_filter(void *hwdev, u8 pkt_type, u16 queue_id,
+				     u8 en);
+
+int hinic3_set_link_status_follow(void *hwdev,
+				  enum hinic3_link_follow_status status);
+#endif /* _HINIC3_NIC_CFG_H_ */
-- 
2.47.0.windows.2


  parent reply	other threads:[~2025-04-18  9:08 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-18  9:05 [RFC 00/18] add hinic3 PMD driver Feifei Wang
2025-04-18  9:05 ` [RFC 01/18] net/hinic3: add intro doc for hinic3 Feifei Wang
2025-04-18  9:05 ` [RFC 02/18] net/hinic3: add basic header files Feifei Wang
2025-04-18  9:05 ` [RFC 03/18] net/hinic3: add hardware interfaces of BAR operation Feifei Wang
2025-04-18  9:05 ` [RFC 04/18] net/hinic3: add support for cmdq mechanism Feifei Wang
2025-04-18  9:05 ` [RFC 05/18] net/hinic3: add NIC event module Feifei Wang
2025-04-18  9:05 ` [RFC 06/18] net/hinic3: add eq mechanism function code Feifei Wang
2025-04-18  9:05 ` [RFC 07/18] net/hinic3: add mgmt module " Feifei Wang
2025-04-18  9:05 ` [RFC 08/18] net/hinic3: add module about hardware operation Feifei Wang
2025-04-18  9:05 ` Feifei Wang [this message]
2025-04-18  9:05 ` [RFC 10/18] net/hinic3: add context and work queue support Feifei Wang
2025-04-18  9:05 ` [RFC 11/18] net/hinic3: add a mailbox communication module Feifei Wang
2025-04-18  9:05 ` [RFC 12/18] net/hinic3: add device initailization Feifei Wang
2025-04-18  9:05 ` [RFC 13/18] net/hinic3: add dev ops Feifei Wang
2025-04-18  9:06 ` [RFC 14/18] net/hinic3: add Rx/Tx functions Feifei Wang
2025-04-18  9:06 ` [RFC 15/18] net/hinic3: add MML and EEPROM access feature Feifei Wang
2025-04-18  9:06 ` [RFC 16/18] net/hinic3: add RSS promiscuous ops Feifei Wang
2025-04-18  9:06 ` [RFC 17/18] net/hinic3: add FDIR flow control module Feifei Wang
2025-04-18 18:25   ` Stephen Hemminger
2025-04-18 18:27   ` Stephen Hemminger
2025-04-18 18:28   ` Stephen Hemminger
2025-04-18 18:30   ` Stephen Hemminger
2025-04-18  9:06 ` [RFC 18/18] drivers/net: add hinic3 PMD build and doc files Feifei Wang
2025-04-18 17:22   ` Stephen Hemminger
2025-04-19  2:52     ` 回复: " wangfeifei (J)
2025-04-18 18:18 ` [RFC 00/18] add hinic3 PMD driver Stephen Hemminger
2025-04-19  2:44   ` 回复: " wangfeifei (J)
2025-04-18 18:20 ` Stephen Hemminger
2025-04-18 18:32 ` Stephen Hemminger
2025-04-19  3:30   ` 回复: " wangfeifei (J)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250418090621.9638-10-wff_light@vip.163.com \
    --to=wff_light@vip.163.com \
    --cc=chenyi221@huawei.com \
    --cc=dev@dpdk.org \
    --cc=wangfeifei40@huawei.com \
    --cc=wangxin679@h-partners.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).