// SPDX-License-Identifier: GPL-2.0-only
/*
 * Huawei HiNIC PCI Express Linux driver
 * Copyright(c) 2017 Huawei Technologies Co., Ltd
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/log2.h>
#include <linux/err.h>
#include <linux/netdevice.h>
#include <net/devlink.h>

#include "hinic_devlink.h"
#include "hinic_sriov.h"
#include "hinic_dev.h"
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_mgmt.h"
#include "hinic_hw_qp_ctxt.h"
#include "hinic_hw_qp.h"
#include "hinic_hw_io.h"
#include "hinic_hw_dev.h"

#define IO_STATUS_TIMEOUT               100
#define OUTBOUND_STATE_TIMEOUT          100
#define DB_STATE_TIMEOUT                100

#define MAX_IRQS(max_qps, num_aeqs, num_ceqs)   \
		 (2 * (max_qps) + (num_aeqs) + (num_ceqs))

#define ADDR_IN_4BYTES(addr)            ((addr) >> 2)

enum intr_type {
	INTR_MSIX_TYPE,
};

enum io_status {
	IO_STOPPED = 0,
	IO_RUNNING = 1,
};

/**
 * parse_capability - convert device capabilities to NIC capabilities
 * @hwdev: the HW device to set and convert device capabilities for
 * @dev_cap: device capabilities from FW
 *
 * Return 0 - Success, negative - Failure
 **/
static int parse_capability(struct hinic_hwdev *hwdev,
			    struct hinic_dev_cap *dev_cap)
{
	struct hinic_cap *nic_cap = &hwdev->nic_cap;
	int num_aeqs, num_ceqs, num_irqs;

	if (!HINIC_IS_VF(hwdev->hwif) && dev_cap->intr_type != INTR_MSIX_TYPE)
		return -EFAULT;

	num_aeqs = HINIC_HWIF_NUM_AEQS(hwdev->hwif);
	num_ceqs = HINIC_HWIF_NUM_CEQS(hwdev->hwif);
	num_irqs = HINIC_HWIF_NUM_IRQS(hwdev->hwif);

	/* Each QP has its own (SQ + RQ) interrupts */
	nic_cap->num_qps = (num_irqs - (num_aeqs + num_ceqs)) / 2;

	if (nic_cap->num_qps > HINIC_Q_CTXT_MAX)
		nic_cap->num_qps = HINIC_Q_CTXT_MAX;

	if (!HINIC_IS_VF(hwdev->hwif))
		nic_cap->max_qps = dev_cap->max_sqs + 1;
	else
		nic_cap->max_qps = dev_cap->max_sqs;

	if (nic_cap->num_qps > nic_cap->max_qps)
		nic_cap->num_qps = nic_cap->max_qps;

	if (!HINIC_IS_VF(hwdev->hwif)) {
		nic_cap->max_vf = dev_cap->max_vf;
		nic_cap->max_vf_qps = dev_cap->max_vf_sqs + 1;
	}

	hwdev->port_id = dev_cap->port_id;

	return 0;
}

/**
 * get_capability - get device capabilities from FW
 * @pfhwdev: the PF HW device to get capabilities for
 *
 * Return 0 - Success, negative - Failure
 **/
static int get_capability(struct hinic_pfhwdev *pfhwdev)
{
	struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_dev_cap dev_cap;
	u16 out_len;
	int err;

	out_len = sizeof(dev_cap);

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_CFGM,
				HINIC_CFG_NIC_CAP, &dev_cap, sizeof(dev_cap),
				&dev_cap, &out_len, HINIC_MGMT_MSG_SYNC);
	if (err) {
		dev_err(&pdev->dev, "Failed to get capability from FW\n");
		return err;
	}

	return parse_capability(hwdev, &dev_cap);
}

/**
 * get_dev_cap - get device capabilities
 * @hwdev: the NIC HW device to get capabilities for
 *
 * Return 0 - Success, negative - Failure
 **/
static int get_dev_cap(struct hinic_hwdev *hwdev)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_pfhwdev *pfhwdev;
	int err;

	switch (HINIC_FUNC_TYPE(hwif)) {
	case HINIC_PPF:
	case HINIC_PF:
	case HINIC_VF:
		pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
		err = get_capability(pfhwdev);
		if (err) {
			dev_err(&pdev->dev, "Failed to get capability\n");
			return err;
		}
		break;
	default:
		dev_err(&pdev->dev, "Unsupported PCI Function type\n");
		return -EINVAL;
	}

	return 0;
}

/**
 * init_msix - enable the msix and save the entries
 * @hwdev: the NIC HW device
 *
 * Return 0 - Success, negative - Failure
 **/
static int init_msix(struct hinic_hwdev *hwdev)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	int nr_irqs, num_aeqs, num_ceqs;
	int i, err;

	num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
	num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);
	nr_irqs = MAX_IRQS(HINIC_MAX_QPS, num_aeqs, num_ceqs);
	if (nr_irqs > HINIC_HWIF_NUM_IRQS(hwif))
		nr_irqs = HINIC_HWIF_NUM_IRQS(hwif);

	hwdev->msix_entries = devm_kcalloc(&pdev->dev, nr_irqs,
					   sizeof(*hwdev->msix_entries),
					   GFP_KERNEL);
	if (!hwdev->msix_entries)
		return -ENOMEM;

	for (i = 0; i < nr_irqs; i++)
		hwdev->msix_entries[i].entry = i;

	err = pci_enable_msix_exact(pdev, hwdev->msix_entries, nr_irqs);
	if (err) {
		dev_err(&pdev->dev, "Failed to enable pci msix\n");
		return err;
	}

	return 0;
}

/**
 * disable_msix - disable the msix
 * @hwdev: the NIC HW device
 **/
static void disable_msix(struct hinic_hwdev *hwdev)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;

	pci_disable_msix(pdev);
}

/**
 * hinic_port_msg_cmd - send port msg to mgmt
 * @hwdev: the NIC HW device
 * @cmd: the port command
 * @buf_in: input buffer
 * @in_size: input size
 * @buf_out: output buffer
 * @out_size: returned output size
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd,
		       void *buf_in, u16 in_size, void *buf_out, u16 *out_size)
{
	struct hinic_pfhwdev *pfhwdev;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_L2NIC, cmd,
				 buf_in, in_size, buf_out, out_size,
				 HINIC_MGMT_MSG_SYNC);
}

int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd,
			 void *buf_in, u16 in_size, void *buf_out,
			 u16 *out_size)
{
	struct hinic_pfhwdev *pfhwdev;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_HILINK, cmd,
				 buf_in, in_size, buf_out, out_size,
				 HINIC_MGMT_MSG_SYNC);
}

/**
 * init_fw_ctxt- Init Firmware tables before network mgmt and io operations
 * @hwdev: the NIC HW device
 *
 * Return 0 - Success, negative - Failure
 **/
static int init_fw_ctxt(struct hinic_hwdev *hwdev)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_cmd_fw_ctxt fw_ctxt;
	u16 out_size = sizeof(fw_ctxt);
	int err;

	fw_ctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	fw_ctxt.rx_buf_sz = HINIC_RX_BUF_SZ;

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_FWCTXT_INIT,
				 &fw_ctxt, sizeof(fw_ctxt),
				 &fw_ctxt, &out_size);
	if (err || out_size != sizeof(fw_ctxt) || fw_ctxt.status) {
		dev_err(&pdev->dev, "Failed to init FW ctxt, err: %d, status: 0x%x, out size: 0x%x\n",
			err, fw_ctxt.status, out_size);
		return -EIO;
	}

	return 0;
}

/**
 * set_hw_ioctxt - set the shape of the IO queues in FW
 * @hwdev: the NIC HW device
 * @rq_depth: rq depth
 * @sq_depth: sq depth
 *
 * Return 0 - Success, negative - Failure
 **/
static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth,
			 unsigned int rq_depth)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_cmd_hw_ioctxt hw_ioctxt;
	struct hinic_pfhwdev *pfhwdev;

	hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);

	hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT;
	hw_ioctxt.cmdq_depth = 0;

	hw_ioctxt.lro_en = 1;

	hw_ioctxt.rq_depth  = ilog2(rq_depth);

	hw_ioctxt.rx_buf_sz_idx = HINIC_RX_BUF_SZ_IDX;

	hw_ioctxt.sq_depth  = ilog2(sq_depth);

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				 HINIC_COMM_CMD_HWCTXT_SET,
				 &hw_ioctxt, sizeof(hw_ioctxt), NULL,
				 NULL, HINIC_MGMT_MSG_SYNC);
}

static int wait_for_outbound_state(struct hinic_hwdev *hwdev)
{
	enum hinic_outbound_state outbound_state;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	unsigned long end;

	end = jiffies + msecs_to_jiffies(OUTBOUND_STATE_TIMEOUT);
	do {
		outbound_state = hinic_outbound_state_get(hwif);

		if (outbound_state == HINIC_OUTBOUND_ENABLE)
			return 0;

		msleep(20);
	} while (time_before(jiffies, end));

	dev_err(&pdev->dev, "Wait for OUTBOUND - Timeout\n");
	return -EFAULT;
}

static int wait_for_db_state(struct hinic_hwdev *hwdev)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	enum hinic_db_state db_state;
	unsigned long end;

	end = jiffies + msecs_to_jiffies(DB_STATE_TIMEOUT);
	do {
		db_state = hinic_db_state_get(hwif);

		if (db_state == HINIC_DB_ENABLE)
			return 0;

		msleep(20);
	} while (time_before(jiffies, end));

	dev_err(&pdev->dev, "Wait for DB - Timeout\n");
	return -EFAULT;
}

/**
 * clear_io_resources - set the IO resources as not active in the NIC
 * @hwdev: the NIC HW device
 *
 * Return 0 - Success, negative - Failure
 **/
static int clear_io_resources(struct hinic_hwdev *hwdev)
{
	struct hinic_cmd_clear_io_res cmd_clear_io_res;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_pfhwdev *pfhwdev;
	int err;

	/* sleep 100ms to wait for firmware stopping I/O */
	msleep(100);

	cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_IO_RES_CLEAR, &cmd_clear_io_res,
				sizeof(cmd_clear_io_res), NULL, NULL,
				HINIC_MGMT_MSG_SYNC);
	if (err) {
		dev_err(&pdev->dev, "Failed to clear IO resources\n");
		return err;
	}

	return 0;
}

/**
 * set_resources_state - set the state of the resources in the NIC
 * @hwdev: the NIC HW device
 * @state: the state to set
 *
 * Return 0 - Success, negative - Failure
 **/
static int set_resources_state(struct hinic_hwdev *hwdev,
			       enum hinic_res_state state)
{
	struct hinic_cmd_set_res_state res_state;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_pfhwdev *pfhwdev;

	res_state.func_idx = HINIC_HWIF_FUNC_IDX(hwif);
	res_state.state = state;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt,
				 HINIC_MOD_COMM,
				 HINIC_COMM_CMD_RES_STATE_SET,
				 &res_state, sizeof(res_state), NULL,
				 NULL, HINIC_MGMT_MSG_SYNC);
}

/**
 * get_base_qpn - get the first qp number
 * @hwdev: the NIC HW device
 * @base_qpn: returned qp number
 *
 * Return 0 - Success, negative - Failure
 **/
static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
{
	struct hinic_cmd_base_qpn cmd_base_qpn;
	struct hinic_hwif *hwif = hwdev->hwif;
	u16 out_size = sizeof(cmd_base_qpn);
	struct pci_dev *pdev = hwif->pdev;
	int err;

	cmd_base_qpn.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_GET_GLOBAL_QPN,
				 &cmd_base_qpn, sizeof(cmd_base_qpn),
				 &cmd_base_qpn, &out_size);
	if (err || out_size != sizeof(cmd_base_qpn) || cmd_base_qpn.status) {
		dev_err(&pdev->dev, "Failed to get base qpn, err: %d, status: 0x%x, out size: 0x%x\n",
			err, cmd_base_qpn.status, out_size);
		return -EIO;
	}

	*base_qpn = cmd_base_qpn.qpn;
	return 0;
}

/**
 * hinic_hwdev_ifup - Preparing the HW for passing IO
 * @hwdev: the NIC HW device
 * @sq_depth: the send queue depth
 * @rq_depth: the receive queue depth
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth)
{
	struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
	struct hinic_cap *nic_cap = &hwdev->nic_cap;
	struct hinic_hwif *hwif = hwdev->hwif;
	int err, num_aeqs, num_ceqs, num_qps;
	struct msix_entry *ceq_msix_entries;
	struct msix_entry *sq_msix_entries;
	struct msix_entry *rq_msix_entries;
	struct pci_dev *pdev = hwif->pdev;
	u16 base_qpn;

	err = get_base_qpn(hwdev, &base_qpn);
	if (err) {
		dev_err(&pdev->dev, "Failed to get global base qp number\n");
		return err;
	}

	num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);
	num_ceqs = HINIC_HWIF_NUM_CEQS(hwif);

	ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
	func_to_io->hwdev = hwdev;
	func_to_io->sq_depth = sq_depth;
	func_to_io->rq_depth = rq_depth;
	func_to_io->global_qpn = base_qpn;

	err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
			    ceq_msix_entries);
	if (err) {
		dev_err(&pdev->dev, "Failed to init IO channel\n");
		return err;
	}

	num_qps = nic_cap->num_qps;
	sq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs];
	rq_msix_entries = &hwdev->msix_entries[num_aeqs + num_ceqs + num_qps];

	err = hinic_io_create_qps(func_to_io, base_qpn, num_qps,
				  sq_msix_entries, rq_msix_entries);
	if (err) {
		dev_err(&pdev->dev, "Failed to create QPs\n");
		goto err_create_qps;
	}

	err = wait_for_db_state(hwdev);
	if (err) {
		dev_warn(&pdev->dev, "db - disabled, try again\n");
		hinic_db_state_set(hwif, HINIC_DB_ENABLE);
	}

	err = set_hw_ioctxt(hwdev, sq_depth, rq_depth);
	if (err) {
		dev_err(&pdev->dev, "Failed to set HW IO ctxt\n");
		goto err_hw_ioctxt;
	}

	return 0;

err_hw_ioctxt:
	hinic_io_destroy_qps(func_to_io, num_qps);

err_create_qps:
	hinic_io_free(func_to_io);
	return err;
}

/**
 * hinic_hwdev_ifdown - Closing the HW for passing IO
 * @hwdev: the NIC HW device
 *
 **/
void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev)
{
	struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
	struct hinic_cap *nic_cap = &hwdev->nic_cap;

	clear_io_resources(hwdev);

	hinic_io_destroy_qps(func_to_io, nic_cap->num_qps);
	hinic_io_free(func_to_io);
}

/**
 * hinic_hwdev_cb_register - register callback handler for MGMT events
 * @hwdev: the NIC HW device
 * @cmd: the mgmt event
 * @handle: private data for the handler
 * @handler: event handler
 **/
void hinic_hwdev_cb_register(struct hinic_hwdev *hwdev,
			     enum hinic_mgmt_msg_cmd cmd, void *handle,
			     void (*handler)(void *handle, void *buf_in,
					     u16 in_size, void *buf_out,
					     u16 *out_size))
{
	struct hinic_pfhwdev *pfhwdev;
	struct hinic_nic_cb *nic_cb;
	u8 cmd_cb;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;
	nic_cb = &pfhwdev->nic_cb[cmd_cb];

	nic_cb->handler = handler;
	nic_cb->handle = handle;
	nic_cb->cb_state = HINIC_CB_ENABLED;
}

/**
 * hinic_hwdev_cb_unregister - unregister callback handler for MGMT events
 * @hwdev: the NIC HW device
 * @cmd: the mgmt event
 **/
void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev,
			       enum hinic_mgmt_msg_cmd cmd)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_pfhwdev *pfhwdev;
	struct hinic_nic_cb *nic_cb;
	u8 cmd_cb;

	if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif))
		return;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;
	nic_cb = &pfhwdev->nic_cb[cmd_cb];

	nic_cb->cb_state &= ~HINIC_CB_ENABLED;

	while (nic_cb->cb_state & HINIC_CB_RUNNING)
		schedule();

	nic_cb->handler = NULL;
}

/**
 * nic_mgmt_msg_handler - nic mgmt event handler
 * @handle: private data for the handler
 * @cmd: message command
 * @buf_in: input buffer
 * @in_size: input size
 * @buf_out: output buffer
 * @out_size: returned output size
 **/
static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
				 u16 in_size, void *buf_out, u16 *out_size)
{
	struct hinic_pfhwdev *pfhwdev = handle;
	enum hinic_cb_state cb_state;
	struct hinic_nic_cb *nic_cb;
	struct hinic_hwdev *hwdev;
	struct hinic_hwif *hwif;
	struct pci_dev *pdev;
	u8 cmd_cb;

	hwdev = &pfhwdev->hwdev;
	hwif = hwdev->hwif;
	pdev = hwif->pdev;

	if (cmd < HINIC_MGMT_MSG_CMD_BASE ||
	    cmd >= HINIC_MGMT_MSG_CMD_MAX) {
		dev_err(&pdev->dev, "unknown L2NIC event, cmd = %d\n", cmd);
		return;
	}

	cmd_cb = cmd - HINIC_MGMT_MSG_CMD_BASE;

	nic_cb = &pfhwdev->nic_cb[cmd_cb];

	cb_state = cmpxchg(&nic_cb->cb_state,
			   HINIC_CB_ENABLED,
			   HINIC_CB_ENABLED | HINIC_CB_RUNNING);

	if (cb_state == HINIC_CB_ENABLED && nic_cb->handler)
		nic_cb->handler(nic_cb->handle, buf_in,
				in_size, buf_out, out_size);
	else
		dev_err(&pdev->dev, "Unhandled NIC Event %d\n", cmd);

	nic_cb->cb_state &= ~HINIC_CB_RUNNING;
}

static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev,
					      u8 cmd,
					      comm_mgmt_self_msg_proc proc)
{
	u8 cmd_idx;

	cmd_idx = pfhwdev->proc.cmd_num;
	if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
		dev_err(&pfhwdev->hwdev.hwif->pdev->dev,
			"Register recv mgmt process failed, cmd: 0x%x\n", cmd);
		return;
	}

	pfhwdev->proc.info[cmd_idx].cmd = cmd;
	pfhwdev->proc.info[cmd_idx].proc = proc;
	pfhwdev->proc.cmd_num++;
}

static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev,
						u8 cmd)
{
	u8 cmd_idx;

	cmd_idx = pfhwdev->proc.cmd_num;
	if (cmd_idx >= HINIC_COMM_SELF_CMD_MAX) {
		dev_err(&pfhwdev->hwdev.hwif->pdev->dev, "Unregister recv mgmt process failed, cmd: 0x%x\n",
			cmd);
		return;
	}

	for (cmd_idx = 0; cmd_idx < HINIC_COMM_SELF_CMD_MAX; cmd_idx++) {
		if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
			pfhwdev->proc.info[cmd_idx].cmd = 0;
			pfhwdev->proc.info[cmd_idx].proc = NULL;
			pfhwdev->proc.cmd_num--;
		}
	}
}

static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in,
				  u16 in_size, void *buf_out, u16 *out_size)
{
	struct hinic_pfhwdev *pfhwdev = handle;
	u8 cmd_idx;

	for (cmd_idx = 0; cmd_idx < pfhwdev->proc.cmd_num; cmd_idx++) {
		if (cmd == pfhwdev->proc.info[cmd_idx].cmd) {
			if (!pfhwdev->proc.info[cmd_idx].proc) {
				dev_warn(&pfhwdev->hwdev.hwif->pdev->dev,
					 "PF recv mgmt comm msg handle null, cmd: 0x%x\n",
					 cmd);
			} else {
				pfhwdev->proc.info[cmd_idx].proc
					(&pfhwdev->hwdev, buf_in, in_size,
					 buf_out, out_size);
			}

			return;
		}
	}

	dev_warn(&pfhwdev->hwdev.hwif->pdev->dev, "Received unknown mgmt cpu event: 0x%x\n",
		 cmd);

	*out_size = 0;
}

/* pf fault report event */
static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size,
				   void *buf_out, u16 *out_size)
{
	struct hinic_cmd_fault_event *fault_event = buf_in;
	struct hinic_hwdev *hwdev = dev;

	if (in_size != sizeof(*fault_event)) {
		dev_err(&hwdev->hwif->pdev->dev, "Invalid fault event report, length: %d, should be %zu\n",
			in_size, sizeof(*fault_event));
		return;
	}

	if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->hw_fault_reporter))
		return;

	devlink_health_report(hwdev->devlink_dev->hw_fault_reporter,
			      "HW fatal error reported", &fault_event->event);
}

static void mgmt_watchdog_timeout_event_handler(void *dev,
						void *buf_in, u16 in_size,
						void *buf_out, u16 *out_size)
{
	struct hinic_mgmt_watchdog_info *watchdog_info = buf_in;
	struct hinic_hwdev *hwdev = dev;

	if (in_size != sizeof(*watchdog_info)) {
		dev_err(&hwdev->hwif->pdev->dev, "Invalid mgmt watchdog report, length: %d, should be %zu\n",
			in_size, sizeof(*watchdog_info));
		return;
	}

	if (!hwdev->devlink_dev || IS_ERR_OR_NULL(hwdev->devlink_dev->fw_fault_reporter))
		return;

	devlink_health_report(hwdev->devlink_dev->fw_fault_reporter,
			      "FW fatal error reported", watchdog_info);
}

/**
 * init_pfhwdev - Initialize the extended components of PF
 * @pfhwdev: the HW device for PF
 *
 * Return 0 - success, negative - failure
 **/
static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev)
{
	struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
	struct hinic_hwif *hwif = hwdev->hwif;
	struct pci_dev *pdev = hwif->pdev;
	int err;

	err = hinic_pf_to_mgmt_init(&pfhwdev->pf_to_mgmt, hwif);
	if (err) {
		dev_err(&pdev->dev, "Failed to initialize PF to MGMT channel\n");
		return err;
	}

	err = hinic_func_to_func_init(hwdev);
	if (err) {
		dev_err(&hwif->pdev->dev, "Failed to init mailbox\n");
		hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
		return err;
	}

	if (!HINIC_IS_VF(hwif)) {
		hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
					   HINIC_MOD_L2NIC, pfhwdev,
					   nic_mgmt_msg_handler);
		hinic_register_mgmt_msg_cb(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
					   pfhwdev, comm_mgmt_msg_handler);
		hinic_comm_recv_mgmt_self_cmd_reg(pfhwdev,
						  HINIC_COMM_CMD_FAULT_REPORT,
						  pf_fault_event_handler);
		hinic_comm_recv_mgmt_self_cmd_reg
			(pfhwdev, HINIC_COMM_CMD_WATCHDOG_INFO,
			 mgmt_watchdog_timeout_event_handler);
	} else {
		hinic_register_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC,
					  nic_mgmt_msg_handler);
	}

	hinic_set_pf_action(hwif, HINIC_PF_MGMT_ACTIVE);
	hinic_devlink_register(hwdev->devlink_dev);
	return 0;
}

/**
 * free_pfhwdev - Free the extended components of PF
 * @pfhwdev: the HW device for PF
 **/
static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev)
{
	struct hinic_hwdev *hwdev = &pfhwdev->hwdev;

	hinic_devlink_unregister(hwdev->devlink_dev);
	hinic_set_pf_action(hwdev->hwif, HINIC_PF_MGMT_INIT);

	if (!HINIC_IS_VF(hwdev->hwif)) {
		hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
						    HINIC_COMM_CMD_WATCHDOG_INFO);
		hinic_comm_recv_mgmt_self_cmd_unreg(pfhwdev,
						    HINIC_COMM_CMD_FAULT_REPORT);
		hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
					     HINIC_MOD_COMM);
		hinic_unregister_mgmt_msg_cb(&pfhwdev->pf_to_mgmt,
					     HINIC_MOD_L2NIC);
	} else {
		hinic_unregister_vf_mbox_cb(hwdev, HINIC_MOD_L2NIC);
	}

	hinic_func_to_func_free(hwdev);

	hinic_pf_to_mgmt_free(&pfhwdev->pf_to_mgmt);
}

static int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
{
	struct hinic_cmd_l2nic_reset l2nic_reset = {0};
	u16 out_size = sizeof(l2nic_reset);
	struct hinic_pfhwdev *pfhwdev;
	int err;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	l2nic_reset.func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	/* 0 represents standard l2nic reset flow */
	l2nic_reset.reset_flag = 0;

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_L2NIC_RESET, &l2nic_reset,
				sizeof(l2nic_reset), &l2nic_reset,
				&out_size, HINIC_MGMT_MSG_SYNC);
	if (err || !out_size || l2nic_reset.status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to reset L2NIC resources, err: %d, status: 0x%x, out_size: 0x%x\n",
			err, l2nic_reset.status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,
			    struct hinic_msix_config *interrupt_info)
{
	u16 out_size = sizeof(*interrupt_info);
	struct hinic_pfhwdev *pfhwdev;
	int err;

	if (!hwdev || !interrupt_info)
		return -EINVAL;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_MSI_CTRL_REG_RD_BY_UP,
				interrupt_info, sizeof(*interrupt_info),
				interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
	if (err || !out_size || interrupt_info->status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
			err, interrupt_info->status, out_size);
		return -EIO;
	}

	return 0;
}

int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
			    struct hinic_msix_config *interrupt_info)
{
	u16 out_size = sizeof(*interrupt_info);
	struct hinic_msix_config temp_info;
	struct hinic_pfhwdev *pfhwdev;
	int err;

	if (!hwdev)
		return -EINVAL;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	interrupt_info->func_id = HINIC_HWIF_FUNC_IDX(hwdev->hwif);

	err = hinic_get_interrupt_cfg(hwdev, &temp_info);
	if (err)
		return -EINVAL;

	interrupt_info->lli_credit_cnt = temp_info.lli_credit_cnt;
	interrupt_info->lli_timer_cnt = temp_info.lli_timer_cnt;

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_MSI_CTRL_REG_WR_BY_UP,
				interrupt_info, sizeof(*interrupt_info),
				interrupt_info, &out_size, HINIC_MGMT_MSG_SYNC);
	if (err || !out_size || interrupt_info->status) {
		dev_err(&hwdev->hwif->pdev->dev, "Failed to get interrupt config, err: %d, status: 0x%x, out size: 0x%x\n",
			err, interrupt_info->status, out_size);
		return -EIO;
	}

	return 0;
}

/**
 * hinic_init_hwdev - Initialize the NIC HW
 * @pdev: the NIC pci device
 * @devlink: the poniter of hinic devlink
 *
 * Return initialized NIC HW device
 *
 * Initialize the NIC HW device and return a pointer to it
 **/
struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink)
{
	struct hinic_pfhwdev *pfhwdev;
	struct hinic_hwdev *hwdev;
	struct hinic_hwif *hwif;
	int err, num_aeqs;

	hwif = devm_kzalloc(&pdev->dev, sizeof(*hwif), GFP_KERNEL);
	if (!hwif)
		return ERR_PTR(-ENOMEM);

	err = hinic_init_hwif(hwif, pdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init HW interface\n");
		return ERR_PTR(err);
	}

	pfhwdev = devm_kzalloc(&pdev->dev, sizeof(*pfhwdev), GFP_KERNEL);
	if (!pfhwdev) {
		err = -ENOMEM;
		goto err_pfhwdev_alloc;
	}

	hwdev = &pfhwdev->hwdev;
	hwdev->hwif = hwif;
	hwdev->devlink_dev = devlink_priv(devlink);
	hwdev->devlink_dev->hwdev = hwdev;

	err = init_msix(hwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init msix\n");
		goto err_init_msix;
	}

	err = wait_for_outbound_state(hwdev);
	if (err) {
		dev_warn(&pdev->dev, "outbound - disabled, try again\n");
		hinic_outbound_state_set(hwif, HINIC_OUTBOUND_ENABLE);
	}

	num_aeqs = HINIC_HWIF_NUM_AEQS(hwif);

	err = hinic_aeqs_init(&hwdev->aeqs, hwif, num_aeqs,
			      HINIC_DEFAULT_AEQ_LEN, HINIC_EQ_PAGE_SIZE,
			      hwdev->msix_entries);
	if (err) {
		dev_err(&pdev->dev, "Failed to init async event queues\n");
		goto err_aeqs_init;
	}

	err = init_pfhwdev(pfhwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init PF HW device\n");
		goto err_init_pfhwdev;
	}

	err = hinic_l2nic_reset(hwdev);
	if (err)
		goto err_l2nic_reset;

	err = get_dev_cap(hwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to get device capabilities\n");
		goto err_dev_cap;
	}

	mutex_init(&hwdev->func_to_io.nic_cfg.cfg_mutex);

	err = hinic_vf_func_init(hwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init nic mbox\n");
		goto err_vf_func_init;
	}

	err = init_fw_ctxt(hwdev);
	if (err) {
		dev_err(&pdev->dev, "Failed to init function table\n");
		goto err_init_fw_ctxt;
	}

	err = set_resources_state(hwdev, HINIC_RES_ACTIVE);
	if (err) {
		dev_err(&pdev->dev, "Failed to set resources state\n");
		goto err_resources_state;
	}

	return hwdev;

err_resources_state:
err_init_fw_ctxt:
	hinic_vf_func_free(hwdev);
err_vf_func_init:
err_l2nic_reset:
err_dev_cap:
	free_pfhwdev(pfhwdev);

err_init_pfhwdev:
	hinic_aeqs_free(&hwdev->aeqs);

err_aeqs_init:
	disable_msix(hwdev);

err_init_msix:
err_pfhwdev_alloc:
	hinic_free_hwif(hwif);
	if (err > 0)
		err = -EIO;
	return ERR_PTR(err);
}

/**
 * hinic_free_hwdev - Free the NIC HW device
 * @hwdev: the NIC HW device
 **/
void hinic_free_hwdev(struct hinic_hwdev *hwdev)
{
	struct hinic_pfhwdev *pfhwdev = container_of(hwdev,
						     struct hinic_pfhwdev,
						     hwdev);

	set_resources_state(hwdev, HINIC_RES_CLEAN);

	hinic_vf_func_free(hwdev);

	free_pfhwdev(pfhwdev);

	hinic_aeqs_free(&hwdev->aeqs);

	disable_msix(hwdev);

	hinic_free_hwif(hwdev->hwif);
}

int hinic_hwdev_max_num_qps(struct hinic_hwdev *hwdev)
{
	struct hinic_cap *nic_cap = &hwdev->nic_cap;

	return nic_cap->max_qps;
}

/**
 * hinic_hwdev_num_qps - return the number QPs available for use
 * @hwdev: the NIC HW device
 *
 * Return number QPs available for use
 **/
int hinic_hwdev_num_qps(struct hinic_hwdev *hwdev)
{
	struct hinic_cap *nic_cap = &hwdev->nic_cap;

	return nic_cap->num_qps;
}

/**
 * hinic_hwdev_get_sq - get SQ
 * @hwdev: the NIC HW device
 * @i: the position of the SQ
 *
 * Return: the SQ in the i position
 **/
struct hinic_sq *hinic_hwdev_get_sq(struct hinic_hwdev *hwdev, int i)
{
	struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
	struct hinic_qp *qp = &func_to_io->qps[i];

	if (i >= hinic_hwdev_num_qps(hwdev))
		return NULL;

	return &qp->sq;
}

/**
 * hinic_hwdev_get_rq - get RQ
 * @hwdev: the NIC HW device
 * @i: the position of the RQ
 *
 * Return: the RQ in the i position
 **/
struct hinic_rq *hinic_hwdev_get_rq(struct hinic_hwdev *hwdev, int i)
{
	struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
	struct hinic_qp *qp = &func_to_io->qps[i];

	if (i >= hinic_hwdev_num_qps(hwdev))
		return NULL;

	return &qp->rq;
}

/**
 * hinic_hwdev_msix_cnt_set - clear message attribute counters for msix entry
 * @hwdev: the NIC HW device
 * @msix_index: msix_index
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_hwdev_msix_cnt_set(struct hinic_hwdev *hwdev, u16 msix_index)
{
	return hinic_msix_attr_cnt_clear(hwdev->hwif, msix_index);
}

/**
 * hinic_hwdev_msix_set - set message attribute for msix entry
 * @hwdev: the NIC HW device
 * @msix_index: msix_index
 * @pending_limit: the maximum pending interrupt events (unit 8)
 * @coalesc_timer: coalesc period for interrupt (unit 8 us)
 * @lli_timer_cfg: replenishing period for low latency credit (unit 8 us)
 * @lli_credit_limit: maximum credits for low latency msix messages (unit 8)
 * @resend_timer: maximum wait for resending msix (unit coalesc period)
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index,
			 u8 pending_limit, u8 coalesc_timer,
			 u8 lli_timer_cfg, u8 lli_credit_limit,
			 u8 resend_timer)
{
	return hinic_msix_attr_set(hwdev->hwif, msix_index,
				   pending_limit, coalesc_timer,
				   lli_timer_cfg, lli_credit_limit,
				   resend_timer);
}

/**
 * hinic_hwdev_hw_ci_addr_set - set cons idx addr and attributes in HW for sq
 * @hwdev: the NIC HW device
 * @sq: send queue
 * @pending_limit: the maximum pending update ci events (unit 8)
 * @coalesc_timer: coalesc period for update ci (unit 8 us)
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq,
			       u8 pending_limit, u8 coalesc_timer)
{
	struct hinic_qp *qp = container_of(sq, struct hinic_qp, sq);
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_pfhwdev *pfhwdev;
	struct hinic_cmd_hw_ci hw_ci;

	hw_ci.dma_attr_off  = 0;
	hw_ci.pending_limit = pending_limit;
	hw_ci.coalesc_timer = coalesc_timer;

	hw_ci.msix_en = 1;
	hw_ci.msix_entry_idx = sq->msix_entry;

	hw_ci.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

	hw_ci.sq_id = qp->q_id;

	hw_ci.ci_addr = ADDR_IN_4BYTES(sq->hw_ci_dma_addr);

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
	return hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt,
				 HINIC_MOD_COMM,
				 HINIC_COMM_CMD_SQ_HI_CI_SET,
				 &hw_ci, sizeof(hw_ci), NULL,
				 NULL, HINIC_MGMT_MSG_SYNC);
}

/**
 * hinic_hwdev_set_msix_state- set msix state
 * @hwdev: the NIC HW device
 * @msix_index: IRQ corresponding index number
 * @flag: msix state
 *
 **/
void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index,
				enum hinic_msix_state flag)
{
	hinic_set_msix_state(hwdev->hwif, msix_index, flag);
}

int hinic_get_board_info(struct hinic_hwdev *hwdev,
			 struct hinic_comm_board_info *board_info)
{
	u16 out_size = sizeof(*board_info);
	struct hinic_pfhwdev *pfhwdev;
	int err;

	if (!hwdev || !board_info)
		return -EINVAL;

	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
				HINIC_COMM_CMD_GET_BOARD_INFO,
				board_info, sizeof(*board_info),
				board_info, &out_size, HINIC_MGMT_MSG_SYNC);
	if (err || board_info->status || !out_size) {
		dev_err(&hwdev->hwif->pdev->dev,
			"Failed to get board info, err: %d, status: 0x%x, out size: 0x%x\n",
			err, board_info->status, out_size);
		return -EIO;
	}

	return 0;
}
