Commit dfc0882a authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'net-hinic3-add-a-driver-for-huawei-3rd-gen-nic-sw-and-hw-initialization'

Fan Gong says:

====================
net: hinic3: Add a driver for Huawei 3rd gen NIC - sw and hw initialization

This is [3/3] part of hinic3 Ethernet driver initial submission.
With this patch hinic3 becomes a functional Ethernet driver.

The driver parts contained in this patch:
Memory allocation and initialization of the driver structures.
Management interfaces initialization.
HW capabilities probing, initialization and setup using management
interfaces.
Net device open/stop implementation and data queues initialization.
Register VID:DID in PCI id_table.
Fix netif_queue_set_napi usage.

V01: https://lore.kernel.org/netdev/cover.1756195078.git.zhuyikai1@h-partners.com
V02: https://lore.kernel.org/netdev/cover.1756378721.git.zhuyikai1@h-partners.com
V03: https://lore.kernel.org/netdev/cover.1756524443.git.zhuyikai1@h-partners.com
V04: https://lore.kernel.org/netdev/cover.1757057860.git.zhuyikai1@h-partners.com
V05: https://lore.kernel.org/netdev/cover.1757401320.git.zhuyikai1@h-partners.com
====================

Link: https://patch.msgid.link/cover.1757653621.git.zhuyikai1@h-partners.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 05c05d14 d5aeec59
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -14,10 +14,12 @@ hinic3-objs := hinic3_cmdq.o \
	       hinic3_lld.o \
	       hinic3_main.o \
	       hinic3_mbox.o \
	       hinic3_mgmt.o \
	       hinic3_netdev_ops.o \
	       hinic3_nic_cfg.o \
	       hinic3_nic_io.o \
	       hinic3_queue_common.o \
	       hinic3_rss.o \
	       hinic3_rx.o \
	       hinic3_tx.o \
	       hinic3_wq.o
+168 −0
Original line number Diff line number Diff line
@@ -8,6 +8,169 @@
#include "hinic3_hwif.h"
#include "hinic3_mbox.h"

#define HINIC3_CFG_MAX_QP  256

static void hinic3_parse_pub_res_cap(struct hinic3_hwdev *hwdev,
				     struct hinic3_dev_cap *cap,
				     const struct cfg_cmd_dev_cap *dev_cap,
				     enum hinic3_func_type type)
{
	cap->port_id = dev_cap->port_id;
	cap->supp_svcs_bitmap = dev_cap->svc_cap_en;
}

static void hinic3_parse_l2nic_res_cap(struct hinic3_hwdev *hwdev,
				       struct hinic3_dev_cap *cap,
				       const struct cfg_cmd_dev_cap *dev_cap,
				       enum hinic3_func_type type)
{
	struct hinic3_nic_service_cap *nic_svc_cap = &cap->nic_svc_cap;

	nic_svc_cap->max_sqs = min(dev_cap->nic_max_sq_id + 1,
				   HINIC3_CFG_MAX_QP);
}

static void hinic3_parse_dev_cap(struct hinic3_hwdev *hwdev,
				 const struct cfg_cmd_dev_cap *dev_cap,
				 enum hinic3_func_type type)
{
	struct hinic3_dev_cap *cap = &hwdev->cfg_mgmt->cap;

	/* Public resource */
	hinic3_parse_pub_res_cap(hwdev, cap, dev_cap, type);

	/* L2 NIC resource */
	if (hinic3_support_nic(hwdev))
		hinic3_parse_l2nic_res_cap(hwdev, cap, dev_cap, type);
}

static int get_cap_from_fw(struct hinic3_hwdev *hwdev,
			   enum hinic3_func_type type)
{
	struct mgmt_msg_params msg_params = {};
	struct cfg_cmd_dev_cap dev_cap = {};
	int err;

	dev_cap.func_id = hinic3_global_func_id(hwdev);

	mgmt_msg_params_init_default(&msg_params, &dev_cap, sizeof(dev_cap));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_CFGM,
				       CFG_CMD_GET_DEV_CAP, &msg_params);
	if (err || dev_cap.head.status) {
		dev_err(hwdev->dev,
			"Failed to get capability from FW, err: %d, status: 0x%x\n",
			err, dev_cap.head.status);
		return -EIO;
	}

	hinic3_parse_dev_cap(hwdev, &dev_cap, type);

	return 0;
}

static int hinic3_init_irq_info(struct hinic3_hwdev *hwdev)
{
	struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;
	struct hinic3_hwif *hwif = hwdev->hwif;
	u16 intr_num = hwif->attr.num_irqs;
	struct hinic3_irq_info *irq_info;
	u16 intr_needed;

	intr_needed = hwif->attr.msix_flex_en ? (hwif->attr.num_aeqs +
		      hwif->attr.num_ceqs + hwif->attr.num_sq) : intr_num;
	if (intr_needed > intr_num) {
		dev_warn(hwdev->dev, "Irq num cfg %d is less than the needed irq num %d msix_flex_en %d\n",
			 intr_num, intr_needed, hwdev->hwif->attr.msix_flex_en);
		intr_needed = intr_num;
	}

	irq_info = &cfg_mgmt->irq_info;
	irq_info->irq = kcalloc(intr_num, sizeof(struct hinic3_irq),
				GFP_KERNEL);
	if (!irq_info->irq)
		return -ENOMEM;

	irq_info->num_irq_hw = intr_needed;
	mutex_init(&irq_info->irq_mutex);

	return 0;
}

static int hinic3_init_irq_alloc_info(struct hinic3_hwdev *hwdev)
{
	struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;
	struct hinic3_irq *irq = cfg_mgmt->irq_info.irq;
	u16 nreq = cfg_mgmt->irq_info.num_irq_hw;
	struct pci_dev *pdev = hwdev->pdev;
	int actual_irq;
	u16 i;

	actual_irq = pci_alloc_irq_vectors(pdev, 2, nreq, PCI_IRQ_MSIX);
	if (actual_irq < 0) {
		dev_err(hwdev->dev, "Alloc msix entries with threshold 2 failed. actual_irq: %d\n",
			actual_irq);
		return -ENOMEM;
	}

	nreq = actual_irq;
	cfg_mgmt->irq_info.num_irq = nreq;

	for (i = 0; i < nreq; ++i) {
		irq[i].msix_entry_idx = i;
		irq[i].irq_id = pci_irq_vector(pdev, i);
		irq[i].allocated = false;
	}

	return 0;
}

int hinic3_init_cfg_mgmt(struct hinic3_hwdev *hwdev)
{
	struct hinic3_cfg_mgmt_info *cfg_mgmt;
	int err;

	cfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL);
	if (!cfg_mgmt)
		return -ENOMEM;

	hwdev->cfg_mgmt = cfg_mgmt;

	err = hinic3_init_irq_info(hwdev);
	if (err) {
		dev_err(hwdev->dev, "Failed to init hinic3_irq_mgmt_info, err: %d\n",
			err);
		goto err_free_cfg_mgmt;
	}

	err = hinic3_init_irq_alloc_info(hwdev);
	if (err) {
		dev_err(hwdev->dev, "Failed to init hinic3_irq_info, err: %d\n",
			err);
		goto err_free_irq_info;
	}

	return 0;

err_free_irq_info:
	kfree(cfg_mgmt->irq_info.irq);
	cfg_mgmt->irq_info.irq = NULL;
err_free_cfg_mgmt:
	kfree(cfg_mgmt);

	return err;
}

void hinic3_free_cfg_mgmt(struct hinic3_hwdev *hwdev)
{
	struct hinic3_cfg_mgmt_info *cfg_mgmt = hwdev->cfg_mgmt;

	pci_free_irq_vectors(hwdev->pdev);
	kfree(cfg_mgmt->irq_info.irq);
	cfg_mgmt->irq_info.irq = NULL;
	kfree(cfg_mgmt);
}

int hinic3_alloc_irqs(struct hinic3_hwdev *hwdev, u16 num,
		      struct msix_entry *alloc_arr, u16 *act_num)
{
@@ -51,6 +214,11 @@ void hinic3_free_irq(struct hinic3_hwdev *hwdev, u32 irq_id)
	mutex_unlock(&irq_info->irq_mutex);
}

int hinic3_init_capability(struct hinic3_hwdev *hwdev)
{
	return get_cap_from_fw(hwdev, HINIC3_FUNC_TYPE_VF);
}

bool hinic3_support_nic(struct hinic3_hwdev *hwdev)
{
	return hwdev->cfg_mgmt->cap.supp_svcs_bitmap &
+4 −0
Original line number Diff line number Diff line
@@ -42,10 +42,14 @@ struct hinic3_cfg_mgmt_info {
	struct hinic3_dev_cap  cap;
};

int hinic3_init_cfg_mgmt(struct hinic3_hwdev *hwdev);
void hinic3_free_cfg_mgmt(struct hinic3_hwdev *hwdev);

int hinic3_alloc_irqs(struct hinic3_hwdev *hwdev, u16 num,
		      struct msix_entry *alloc_arr, u16 *act_num);
void hinic3_free_irq(struct hinic3_hwdev *hwdev, u32 irq_id);

int hinic3_init_capability(struct hinic3_hwdev *hwdev);
bool hinic3_support_nic(struct hinic3_hwdev *hwdev);
u16 hinic3_func_max_qnum(struct hinic3_hwdev *hwdev);
u8 hinic3_physical_port_id(struct hinic3_hwdev *hwdev);
+363 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@

#include <linux/delay.h>

#include "hinic3_cmdq.h"
#include "hinic3_hw_comm.h"
#include "hinic3_hwdev.h"
#include "hinic3_hwif.h"
@@ -61,3 +62,365 @@ int hinic3_func_reset(struct hinic3_hwdev *hwdev, u16 func_id, u64 reset_flag)

	return 0;
}

static int hinic3_comm_features_nego(struct hinic3_hwdev *hwdev, u8 opcode,
				     u64 *s_feature, u16 size)
{
	struct comm_cmd_feature_nego feature_nego = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	feature_nego.func_id = hinic3_global_func_id(hwdev);
	feature_nego.opcode = opcode;
	if (opcode == MGMT_MSG_CMD_OP_SET)
		memcpy(feature_nego.s_feature, s_feature,
		       array_size(size, sizeof(u64)));

	mgmt_msg_params_init_default(&msg_params, &feature_nego,
				     sizeof(feature_nego));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_FEATURE_NEGO, &msg_params);
	if (err || feature_nego.head.status) {
		dev_err(hwdev->dev, "Failed to negotiate feature, err: %d, status: 0x%x\n",
			err, feature_nego.head.status);
		return -EINVAL;
	}

	if (opcode == MGMT_MSG_CMD_OP_GET)
		memcpy(s_feature, feature_nego.s_feature,
		       array_size(size, sizeof(u64)));

	return 0;
}

int hinic3_get_comm_features(struct hinic3_hwdev *hwdev, u64 *s_feature,
			     u16 size)
{
	return hinic3_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_GET, s_feature,
					 size);
}

int hinic3_set_comm_features(struct hinic3_hwdev *hwdev, u64 *s_feature,
			     u16 size)
{
	return hinic3_comm_features_nego(hwdev, MGMT_MSG_CMD_OP_SET, s_feature,
					 size);
}

int hinic3_get_global_attr(struct hinic3_hwdev *hwdev,
			   struct comm_global_attr *attr)
{
	struct comm_cmd_get_glb_attr get_attr = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	mgmt_msg_params_init_default(&msg_params, &get_attr, sizeof(get_attr));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_GET_GLOBAL_ATTR, &msg_params);
	if (err || get_attr.head.status) {
		dev_err(hwdev->dev,
			"Failed to get global attribute, err: %d, status: 0x%x\n",
			err, get_attr.head.status);
		return -EIO;
	}

	memcpy(attr, &get_attr.attr, sizeof(*attr));

	return 0;
}

int hinic3_set_func_svc_used_state(struct hinic3_hwdev *hwdev, u16 svc_type,
				   u8 state)
{
	struct comm_cmd_set_func_svc_used_state used_state = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	used_state.func_id = hinic3_global_func_id(hwdev);
	used_state.svc_type = svc_type;
	used_state.used_state = state;

	mgmt_msg_params_init_default(&msg_params, &used_state,
				     sizeof(used_state));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_FUNC_SVC_USED_STATE,
				       &msg_params);
	if (err || used_state.head.status) {
		dev_err(hwdev->dev,
			"Failed to set func service used state, err: %d, status: 0x%x\n",
			err, used_state.head.status);
		return -EIO;
	}

	return 0;
}

int hinic3_set_dma_attr_tbl(struct hinic3_hwdev *hwdev, u8 entry_idx, u8 st,
			    u8 at, u8 ph, u8 no_snooping, u8 tph_en)
{
	struct comm_cmd_set_dma_attr dma_attr = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	dma_attr.func_id = hinic3_global_func_id(hwdev);
	dma_attr.entry_idx = entry_idx;
	dma_attr.st = st;
	dma_attr.at = at;
	dma_attr.ph = ph;
	dma_attr.no_snooping = no_snooping;
	dma_attr.tph_en = tph_en;

	mgmt_msg_params_init_default(&msg_params, &dma_attr, sizeof(dma_attr));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_DMA_ATTR, &msg_params);
	if (err || dma_attr.head.status) {
		dev_err(hwdev->dev, "Failed to set dma attr, err: %d, status: 0x%x\n",
			err, dma_attr.head.status);
		return -EIO;
	}

	return 0;
}

int hinic3_set_wq_page_size(struct hinic3_hwdev *hwdev, u16 func_idx,
			    u32 page_size)
{
	struct comm_cmd_cfg_wq_page_size page_size_info = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	page_size_info.func_id = func_idx;
	page_size_info.page_size = ilog2(page_size / HINIC3_MIN_PAGE_SIZE);
	page_size_info.opcode = MGMT_MSG_CMD_OP_SET;

	mgmt_msg_params_init_default(&msg_params, &page_size_info,
				     sizeof(page_size_info));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_CFG_PAGESIZE, &msg_params);
	if (err || page_size_info.head.status) {
		dev_err(hwdev->dev,
			"Failed to set wq page size, err: %d, status: 0x%x\n",
			err, page_size_info.head.status);
		return -EFAULT;
	}

	return 0;
}

int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth)
{
	struct comm_cmd_set_root_ctxt root_ctxt = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	root_ctxt.func_id = hinic3_global_func_id(hwdev);

	root_ctxt.set_cmdq_depth = 1;
	root_ctxt.cmdq_depth = ilog2(cmdq_depth);

	mgmt_msg_params_init_default(&msg_params, &root_ctxt,
				     sizeof(root_ctxt));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_VAT, &msg_params);
	if (err || root_ctxt.head.status) {
		dev_err(hwdev->dev,
			"Failed to set cmdq depth, err: %d, status: 0x%x\n",
			err, root_ctxt.head.status);
		return -EFAULT;
	}

	return 0;
}

#define HINIC3_WAIT_CMDQ_IDLE_TIMEOUT    5000

static enum hinic3_wait_return check_cmdq_stop_handler(void *priv_data)
{
	struct hinic3_hwdev *hwdev = priv_data;
	enum hinic3_cmdq_type cmdq_type;
	struct hinic3_cmdqs *cmdqs;

	cmdqs = hwdev->cmdqs;
	for (cmdq_type = 0; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
		if (!hinic3_cmdq_idle(&cmdqs->cmdq[cmdq_type]))
			return HINIC3_WAIT_PROCESS_WAITING;
	}

	return HINIC3_WAIT_PROCESS_CPL;
}

static int wait_cmdq_stop(struct hinic3_hwdev *hwdev)
{
	struct hinic3_cmdqs *cmdqs = hwdev->cmdqs;
	enum hinic3_cmdq_type cmdq_type;
	int err;

	if (!(cmdqs->status & HINIC3_CMDQ_ENABLE))
		return 0;

	cmdqs->status &= ~HINIC3_CMDQ_ENABLE;
	err = hinic3_wait_for_timeout(hwdev, check_cmdq_stop_handler,
				      HINIC3_WAIT_CMDQ_IDLE_TIMEOUT,
				      USEC_PER_MSEC);

	if (err)
		goto err_reenable_cmdq;

	return 0;

err_reenable_cmdq:
	for (cmdq_type = 0; cmdq_type < cmdqs->cmdq_num; cmdq_type++) {
		if (!hinic3_cmdq_idle(&cmdqs->cmdq[cmdq_type]))
			dev_err(hwdev->dev, "Cmdq %d is busy\n", cmdq_type);
	}
	cmdqs->status |= HINIC3_CMDQ_ENABLE;

	return err;
}

int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev)
{
	struct comm_cmd_clear_resource clear_db = {};
	struct comm_cmd_clear_resource clr_res = {};
	struct hinic3_hwif *hwif = hwdev->hwif;
	struct mgmt_msg_params msg_params = {};
	int ret = 0;
	int err;

	err = wait_cmdq_stop(hwdev);
	if (err) {
		dev_warn(hwdev->dev, "CMDQ is still working, CMDQ timeout value is unreasonable\n");
		ret = err;
	}

	hinic3_toggle_doorbell(hwif, DISABLE_DOORBELL);

	clear_db.func_id = hwif->attr.func_global_idx;
	mgmt_msg_params_init_default(&msg_params, &clear_db, sizeof(clear_db));
	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_FLUSH_DOORBELL, &msg_params);
	if (err || clear_db.head.status) {
		dev_warn(hwdev->dev, "Failed to flush doorbell, err: %d, status: 0x%x\n",
			 err, clear_db.head.status);
		if (err)
			ret = err;
		else
			ret = -EFAULT;
	}

	clr_res.func_id = hwif->attr.func_global_idx;
	msg_params.buf_in = &clr_res;
	msg_params.in_size = sizeof(clr_res);
	err = hinic3_send_mbox_to_mgmt_no_ack(hwdev, MGMT_MOD_COMM,
					      COMM_CMD_START_FLUSH,
					      &msg_params);
	if (err) {
		dev_warn(hwdev->dev, "Failed to notice flush message, err: %d\n",
			 err);
		ret = err;
	}

	hinic3_toggle_doorbell(hwif, ENABLE_DOORBELL);

	err = hinic3_reinit_cmdq_ctxts(hwdev);
	if (err) {
		dev_warn(hwdev->dev, "Failed to reinit cmdq\n");
		ret = err;
	}

	return ret;
}

static int get_hw_rx_buf_size_idx(int rx_buf_sz, u16 *buf_sz_idx)
{
	/* Supported RX buffer sizes in bytes. Configured by array index. */
	static const int supported_sizes[16] = {
		[0] = 32,     [1] = 64,     [2] = 96,     [3] = 128,
		[4] = 192,    [5] = 256,    [6] = 384,    [7] = 512,
		[8] = 768,    [9] = 1024,   [10] = 1536,  [11] = 2048,
		[12] = 3072,  [13] = 4096,  [14] = 8192,  [15] = 16384,
	};
	u16 idx;

	/* Scan from biggest to smallest. Choose supported size that is equal or
	 * smaller. For smaller value HW will under-utilize posted buffers. For
	 * bigger value HW may overrun posted buffers.
	 */
	idx = ARRAY_SIZE(supported_sizes);
	while (idx > 0) {
		idx--;
		if (supported_sizes[idx] <= rx_buf_sz) {
			*buf_sz_idx = idx;
			return 0;
		}
	}

	return -EINVAL;
}

int hinic3_set_root_ctxt(struct hinic3_hwdev *hwdev, u32 rq_depth, u32 sq_depth,
			 int rx_buf_sz)
{
	struct comm_cmd_set_root_ctxt root_ctxt = {};
	struct mgmt_msg_params msg_params = {};
	u16 buf_sz_idx;
	int err;

	err = get_hw_rx_buf_size_idx(rx_buf_sz, &buf_sz_idx);
	if (err)
		return err;

	root_ctxt.func_id = hinic3_global_func_id(hwdev);

	root_ctxt.set_cmdq_depth = 0;
	root_ctxt.cmdq_depth = 0;

	root_ctxt.lro_en = 1;

	root_ctxt.rq_depth  = ilog2(rq_depth);
	root_ctxt.rx_buf_sz = buf_sz_idx;
	root_ctxt.sq_depth  = ilog2(sq_depth);

	mgmt_msg_params_init_default(&msg_params, &root_ctxt,
				     sizeof(root_ctxt));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_VAT, &msg_params);
	if (err || root_ctxt.head.status) {
		dev_err(hwdev->dev,
			"Failed to set root context, err: %d, status: 0x%x\n",
			err, root_ctxt.head.status);
		return -EFAULT;
	}

	return 0;
}

int hinic3_clean_root_ctxt(struct hinic3_hwdev *hwdev)
{
	struct comm_cmd_set_root_ctxt root_ctxt = {};
	struct mgmt_msg_params msg_params = {};
	int err;

	root_ctxt.func_id = hinic3_global_func_id(hwdev);

	mgmt_msg_params_init_default(&msg_params, &root_ctxt,
				     sizeof(root_ctxt));

	err = hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM,
				       COMM_CMD_SET_VAT, &msg_params);
	if (err || root_ctxt.head.status) {
		dev_err(hwdev->dev,
			"Failed to set root context, err: %d, status: 0x%x\n",
			err, root_ctxt.head.status);
		return -EFAULT;
	}

	return 0;
}
+21 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@

struct hinic3_hwdev;

#define HINIC3_WQ_PAGE_SIZE_ORDER  8

struct hinic3_interrupt_info {
	u32 lli_set;
	u32 interrupt_coalesc_set;
@@ -23,4 +25,23 @@ int hinic3_set_interrupt_cfg_direct(struct hinic3_hwdev *hwdev,
				    const struct hinic3_interrupt_info *info);
int hinic3_func_reset(struct hinic3_hwdev *hwdev, u16 func_id, u64 reset_flag);

int hinic3_get_comm_features(struct hinic3_hwdev *hwdev, u64 *s_feature,
			     u16 size);
int hinic3_set_comm_features(struct hinic3_hwdev *hwdev, u64 *s_feature,
			     u16 size);
int hinic3_get_global_attr(struct hinic3_hwdev *hwdev,
			   struct comm_global_attr *attr);
int hinic3_set_func_svc_used_state(struct hinic3_hwdev *hwdev, u16 svc_type,
				   u8 state);
int hinic3_set_dma_attr_tbl(struct hinic3_hwdev *hwdev, u8 entry_idx, u8 st,
			    u8 at, u8 ph, u8 no_snooping, u8 tph_en);

int hinic3_set_wq_page_size(struct hinic3_hwdev *hwdev, u16 func_idx,
			    u32 page_size);
int hinic3_set_cmdq_depth(struct hinic3_hwdev *hwdev, u16 cmdq_depth);
int hinic3_func_rx_tx_flush(struct hinic3_hwdev *hwdev);
int hinic3_set_root_ctxt(struct hinic3_hwdev *hwdev, u32 rq_depth, u32 sq_depth,
			 int rx_buf_sz);
int hinic3_clean_root_ctxt(struct hinic3_hwdev *hwdev);

#endif
Loading