// 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/errno.h>
#include <linux/pci.h>
#include <linux/device.h>
#include <linux/semaphore.h>
#include <linux/completion.h>
#include <linux/slab.h>
#include <net/devlink.h>
#include <asm/barrier.h>

#include "hinic_devlink.h"
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_api_cmd.h"
#include "hinic_hw_mgmt.h"
#include "hinic_hw_dev.h"

#define SYNC_MSG_ID_MASK                0x1FF

#define SYNC_MSG_ID(pf_to_mgmt)         ((pf_to_mgmt)->sync_msg_id)

#define SYNC_MSG_ID_INC(pf_to_mgmt)     (SYNC_MSG_ID(pf_to_mgmt) = \
					((SYNC_MSG_ID(pf_to_mgmt) + 1) & \
					 SYNC_MSG_ID_MASK))

#define MSG_SZ_IS_VALID(in_size)        ((in_size) <= MAX_MSG_LEN)

#define MGMT_MSG_LEN_MIN                20
#define MGMT_MSG_LEN_STEP               16
#define MGMT_MSG_RSVD_FOR_DEV           8

#define SEGMENT_LEN                     48

#define MAX_PF_MGMT_BUF_SIZE            2048

/* Data should be SEG LEN size aligned */
#define MAX_MSG_LEN                     2016

#define MSG_NOT_RESP                    0xFFFF

#define MGMT_MSG_TIMEOUT                5000

#define SET_FUNC_PORT_MBOX_TIMEOUT	30000

#define SET_FUNC_PORT_MGMT_TIMEOUT	25000

#define UPDATE_FW_MGMT_TIMEOUT		20000

#define mgmt_to_pfhwdev(pf_mgmt)        \
		container_of(pf_mgmt, struct hinic_pfhwdev, pf_to_mgmt)

enum msg_segment_type {
	NOT_LAST_SEGMENT = 0,
	LAST_SEGMENT     = 1,
};

enum mgmt_direction_type {
	MGMT_DIRECT_SEND = 0,
	MGMT_RESP        = 1,
};

enum msg_ack_type {
	MSG_ACK         = 0,
	MSG_NO_ACK      = 1,
};

/**
 * hinic_register_mgmt_msg_cb - register msg handler for a msg from a module
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that this handler will handle its messages
 * @handle: private data for the callback
 * @callback: the handler that will handle messages
 **/
void hinic_register_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt,
				enum hinic_mod_type mod,
				void *handle,
				void (*callback)(void *handle,
						 u8 cmd, void *buf_in,
						 u16 in_size, void *buf_out,
						 u16 *out_size))
{
	struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod];

	mgmt_cb->cb = callback;
	mgmt_cb->handle = handle;
	mgmt_cb->state = HINIC_MGMT_CB_ENABLED;
}

/**
 * hinic_unregister_mgmt_msg_cb - unregister msg handler for a msg from a module
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that this handler handles its messages
 **/
void hinic_unregister_mgmt_msg_cb(struct hinic_pf_to_mgmt *pf_to_mgmt,
				  enum hinic_mod_type mod)
{
	struct hinic_mgmt_cb *mgmt_cb = &pf_to_mgmt->mgmt_cb[mod];

	mgmt_cb->state &= ~HINIC_MGMT_CB_ENABLED;

	while (mgmt_cb->state & HINIC_MGMT_CB_RUNNING)
		schedule();

	mgmt_cb->cb = NULL;
}

/**
 * prepare_header - prepare the header of the message
 * @pf_to_mgmt: PF to MGMT channel
 * @msg_len: the length of the message
 * @mod: module in the chip that will get the message
 * @ack_type: ask for response
 * @direction: the direction of the message
 * @cmd: command of the message
 * @msg_id: message id
 *
 * Return the prepared header value
 **/
static u64 prepare_header(struct hinic_pf_to_mgmt *pf_to_mgmt,
			  u16 msg_len, enum hinic_mod_type mod,
			  enum msg_ack_type ack_type,
			  enum mgmt_direction_type direction,
			  u16 cmd, u16 msg_id)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;

	return HINIC_MSG_HEADER_SET(msg_len, MSG_LEN)           |
	       HINIC_MSG_HEADER_SET(mod, MODULE)                |
	       HINIC_MSG_HEADER_SET(SEGMENT_LEN, SEG_LEN)       |
	       HINIC_MSG_HEADER_SET(ack_type, NO_ACK)           |
	       HINIC_MSG_HEADER_SET(0, ASYNC_MGMT_TO_PF)        |
	       HINIC_MSG_HEADER_SET(0, SEQID)                   |
	       HINIC_MSG_HEADER_SET(LAST_SEGMENT, LAST)         |
	       HINIC_MSG_HEADER_SET(direction, DIRECTION)       |
	       HINIC_MSG_HEADER_SET(cmd, CMD)                   |
	       HINIC_MSG_HEADER_SET(HINIC_HWIF_PCI_INTF(hwif), PCI_INTF) |
	       HINIC_MSG_HEADER_SET(HINIC_HWIF_PF_IDX(hwif), PF_IDX)     |
	       HINIC_MSG_HEADER_SET(msg_id, MSG_ID);
}

/**
 * prepare_mgmt_cmd - prepare the mgmt command
 * @mgmt_cmd: pointer to the command to prepare
 * @header: pointer of the header for the message
 * @msg: the data of the message
 * @msg_len: the length of the message
 **/
static void prepare_mgmt_cmd(u8 *mgmt_cmd, u64 *header, u8 *msg, u16 msg_len)
{
	memset(mgmt_cmd, 0, MGMT_MSG_RSVD_FOR_DEV);

	mgmt_cmd += MGMT_MSG_RSVD_FOR_DEV;
	memcpy(mgmt_cmd, header, sizeof(*header));

	mgmt_cmd += sizeof(*header);
	memcpy(mgmt_cmd, msg, msg_len);
}

/**
 * mgmt_msg_len - calculate the total message length
 * @msg_data_len: the length of the message data
 *
 * Return the total message length
 **/
static u16 mgmt_msg_len(u16 msg_data_len)
{
	/* RSVD + HEADER_SIZE + DATA_LEN */
	u16 msg_len = MGMT_MSG_RSVD_FOR_DEV + sizeof(u64) + msg_data_len;

	if (msg_len > MGMT_MSG_LEN_MIN)
		msg_len = MGMT_MSG_LEN_MIN +
			   ALIGN((msg_len - MGMT_MSG_LEN_MIN),
				 MGMT_MSG_LEN_STEP);
	else
		msg_len = MGMT_MSG_LEN_MIN;

	return msg_len;
}

/**
 * send_msg_to_mgmt - send message to mgmt by API CMD
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that will get the message
 * @cmd: command of the message
 * @data: the msg data
 * @data_len: the msg data length
 * @ack_type: ask for response
 * @direction: the direction of the original message
 * @resp_msg_id: msg id to response for
 *
 * Return 0 - Success, negative - Failure
 **/
static int send_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
			    enum hinic_mod_type mod, u8 cmd,
			    u8 *data, u16 data_len,
			    enum msg_ack_type ack_type,
			    enum mgmt_direction_type direction,
			    u16 resp_msg_id)
{
	struct hinic_api_cmd_chain *chain;
	u64 header;
	u16 msg_id;

	msg_id = SYNC_MSG_ID(pf_to_mgmt);

	if (direction == MGMT_RESP) {
		header = prepare_header(pf_to_mgmt, data_len, mod, ack_type,
					direction, cmd, resp_msg_id);
	} else {
		SYNC_MSG_ID_INC(pf_to_mgmt);
		header = prepare_header(pf_to_mgmt, data_len, mod, ack_type,
					direction, cmd, msg_id);
	}

	prepare_mgmt_cmd(pf_to_mgmt->sync_msg_buf, &header, data, data_len);

	chain = pf_to_mgmt->cmd_chain[HINIC_API_CMD_WRITE_TO_MGMT_CPU];
	return hinic_api_cmd_write(chain, HINIC_NODE_ID_MGMT,
				   pf_to_mgmt->sync_msg_buf,
				   mgmt_msg_len(data_len));
}

/**
 * msg_to_mgmt_sync - send sync message to mgmt
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that will get the message
 * @cmd: command of the message
 * @buf_in: the msg data
 * @in_size: the msg data length
 * @buf_out: response
 * @out_size: response length
 * @direction: the direction of the original message
 * @resp_msg_id: msg id to response for
 * @timeout: time-out period of waiting for response
 *
 * Return 0 - Success, negative - Failure
 **/
static int msg_to_mgmt_sync(struct hinic_pf_to_mgmt *pf_to_mgmt,
			    enum hinic_mod_type mod, u8 cmd,
			    u8 *buf_in, u16 in_size,
			    u8 *buf_out, u16 *out_size,
			    enum mgmt_direction_type direction,
			    u16 resp_msg_id, u32 timeout)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_recv_msg *recv_msg;
	struct completion *recv_done;
	unsigned long timeo;
	u16 msg_id;
	int err;

	/* Lock the sync_msg_buf */
	down(&pf_to_mgmt->sync_msg_lock);

	recv_msg = &pf_to_mgmt->recv_resp_msg_from_mgmt;
	recv_done = &recv_msg->recv_done;

	if (resp_msg_id == MSG_NOT_RESP)
		msg_id = SYNC_MSG_ID(pf_to_mgmt);
	else
		msg_id = resp_msg_id;

	init_completion(recv_done);

	err = send_msg_to_mgmt(pf_to_mgmt, mod, cmd, buf_in, in_size,
			       MSG_ACK, direction, resp_msg_id);
	if (err) {
		dev_err(&pdev->dev, "Failed to send sync msg to mgmt\n");
		goto unlock_sync_msg;
	}

	timeo = msecs_to_jiffies(timeout ? timeout : MGMT_MSG_TIMEOUT);

	if (!wait_for_completion_timeout(recv_done, timeo)) {
		dev_err(&pdev->dev, "MGMT timeout, MSG id = %d\n", msg_id);
		hinic_dump_aeq_info(pf_to_mgmt->hwdev);
		err = -ETIMEDOUT;
		goto unlock_sync_msg;
	}

	smp_rmb();      /* verify reading after completion */

	if (recv_msg->msg_id != msg_id) {
		dev_err(&pdev->dev, "incorrect MSG for id = %d\n", msg_id);
		err = -EFAULT;
		goto unlock_sync_msg;
	}

	if ((buf_out) && (recv_msg->msg_len <= MAX_PF_MGMT_BUF_SIZE)) {
		memcpy(buf_out, recv_msg->msg, recv_msg->msg_len);
		*out_size = recv_msg->msg_len;
	}

unlock_sync_msg:
	up(&pf_to_mgmt->sync_msg_lock);
	return err;
}

/**
 * msg_to_mgmt_async - send message to mgmt without response
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that will get the message
 * @cmd: command of the message
 * @buf_in: the msg data
 * @in_size: the msg data length
 * @direction: the direction of the original message
 * @resp_msg_id: msg id to response for
 *
 * Return 0 - Success, negative - Failure
 **/
static int msg_to_mgmt_async(struct hinic_pf_to_mgmt *pf_to_mgmt,
			     enum hinic_mod_type mod, u8 cmd,
			     u8 *buf_in, u16 in_size,
			     enum mgmt_direction_type direction,
			     u16 resp_msg_id)
{
	int err;

	/* Lock the sync_msg_buf */
	down(&pf_to_mgmt->sync_msg_lock);

	err = send_msg_to_mgmt(pf_to_mgmt, mod, cmd, buf_in, in_size,
			       MSG_NO_ACK, direction, resp_msg_id);

	up(&pf_to_mgmt->sync_msg_lock);
	return err;
}

/**
 * hinic_msg_to_mgmt - send message to mgmt
 * @pf_to_mgmt: PF to MGMT channel
 * @mod: module in the chip that will get the message
 * @cmd: command of the message
 * @buf_in: the msg data
 * @in_size: the msg data length
 * @buf_out: response
 * @out_size: returned response length
 * @sync: sync msg or async msg
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
		      enum hinic_mod_type mod, u8 cmd,
		      void *buf_in, u16 in_size, void *buf_out, u16 *out_size,
		      enum hinic_mgmt_msg_type sync)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;
	struct pci_dev *pdev = hwif->pdev;
	u32 timeout = 0;

	if (sync != HINIC_MGMT_MSG_SYNC) {
		dev_err(&pdev->dev, "Invalid MGMT msg type\n");
		return -EINVAL;
	}

	if (!MSG_SZ_IS_VALID(in_size)) {
		dev_err(&pdev->dev, "Invalid MGMT msg buffer size\n");
		return -EINVAL;
	}

	if (HINIC_IS_VF(hwif)) {
		if (cmd == HINIC_PORT_CMD_SET_FUNC_STATE)
			timeout = SET_FUNC_PORT_MBOX_TIMEOUT;

		return hinic_mbox_to_pf(pf_to_mgmt->hwdev, mod, cmd, buf_in,
					in_size, buf_out, out_size, timeout);
	} else {
		if (cmd == HINIC_PORT_CMD_SET_FUNC_STATE)
			timeout = SET_FUNC_PORT_MGMT_TIMEOUT;
		else if (cmd == HINIC_PORT_CMD_UPDATE_FW)
			timeout = UPDATE_FW_MGMT_TIMEOUT;

		return msg_to_mgmt_sync(pf_to_mgmt, mod, cmd, buf_in, in_size,
				buf_out, out_size, MGMT_DIRECT_SEND,
				MSG_NOT_RESP, timeout);
	}
}

static void recv_mgmt_msg_work_handler(struct work_struct *work)
{
	struct hinic_mgmt_msg_handle_work *mgmt_work =
		container_of(work, struct hinic_mgmt_msg_handle_work, work);
	struct hinic_pf_to_mgmt *pf_to_mgmt = mgmt_work->pf_to_mgmt;
	struct pci_dev *pdev = pf_to_mgmt->hwif->pdev;
	u8 *buf_out = pf_to_mgmt->mgmt_ack_buf;
	struct hinic_mgmt_cb *mgmt_cb;
	unsigned long cb_state;
	u16 out_size = 0;

	memset(buf_out, 0, MAX_PF_MGMT_BUF_SIZE);

	if (mgmt_work->mod >= HINIC_MOD_MAX) {
		dev_err(&pdev->dev, "Unknown MGMT MSG module = %d\n",
			mgmt_work->mod);
		kfree(mgmt_work->msg);
		kfree(mgmt_work);
		return;
	}

	mgmt_cb = &pf_to_mgmt->mgmt_cb[mgmt_work->mod];

	cb_state = cmpxchg(&mgmt_cb->state,
			   HINIC_MGMT_CB_ENABLED,
			   HINIC_MGMT_CB_ENABLED | HINIC_MGMT_CB_RUNNING);

	if ((cb_state == HINIC_MGMT_CB_ENABLED) && (mgmt_cb->cb))
		mgmt_cb->cb(mgmt_cb->handle, mgmt_work->cmd,
			    mgmt_work->msg, mgmt_work->msg_len,
			    buf_out, &out_size);
	else
		dev_err(&pdev->dev, "No MGMT msg handler, mod: %d, cmd: %d\n",
			mgmt_work->mod, mgmt_work->cmd);

	mgmt_cb->state &= ~HINIC_MGMT_CB_RUNNING;

	if (!mgmt_work->async_mgmt_to_pf)
		/* MGMT sent sync msg, send the response */
		msg_to_mgmt_async(pf_to_mgmt, mgmt_work->mod, mgmt_work->cmd,
				  buf_out, out_size, MGMT_RESP,
				  mgmt_work->msg_id);

	kfree(mgmt_work->msg);
	kfree(mgmt_work);
}

/**
 * mgmt_recv_msg_handler - handler for message from mgmt cpu
 * @pf_to_mgmt: PF to MGMT channel
 * @recv_msg: received message details
 **/
static void mgmt_recv_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
				  struct hinic_recv_msg *recv_msg)
{
	struct hinic_mgmt_msg_handle_work *mgmt_work = NULL;
	struct pci_dev *pdev = pf_to_mgmt->hwif->pdev;

	mgmt_work = kzalloc(sizeof(*mgmt_work), GFP_KERNEL);
	if (!mgmt_work) {
		dev_err(&pdev->dev, "Allocate mgmt work memory failed\n");
		return;
	}

	if (recv_msg->msg_len) {
		mgmt_work->msg = kzalloc(recv_msg->msg_len, GFP_KERNEL);
		if (!mgmt_work->msg) {
			dev_err(&pdev->dev, "Allocate mgmt msg memory failed\n");
			kfree(mgmt_work);
			return;
		}
	}

	mgmt_work->pf_to_mgmt = pf_to_mgmt;
	mgmt_work->msg_len = recv_msg->msg_len;
	memcpy(mgmt_work->msg, recv_msg->msg, recv_msg->msg_len);
	mgmt_work->msg_id = recv_msg->msg_id;
	mgmt_work->mod = recv_msg->mod;
	mgmt_work->cmd = recv_msg->cmd;
	mgmt_work->async_mgmt_to_pf = recv_msg->async_mgmt_to_pf;

	INIT_WORK(&mgmt_work->work, recv_mgmt_msg_work_handler);
	queue_work(pf_to_mgmt->workq, &mgmt_work->work);
}

/**
 * mgmt_resp_msg_handler - handler for a response message from mgmt cpu
 * @pf_to_mgmt: PF to MGMT channel
 * @recv_msg: received message details
 **/
static void mgmt_resp_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
				  struct hinic_recv_msg *recv_msg)
{
	wmb();  /* verify writing all, before reading */

	complete(&recv_msg->recv_done);
}

/**
 * recv_mgmt_msg_handler - handler for a message from mgmt cpu
 * @pf_to_mgmt: PF to MGMT channel
 * @header: the header of the message
 * @recv_msg: received message details
 **/
static void recv_mgmt_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt,
				  u64 *header, struct hinic_recv_msg *recv_msg)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;
	struct pci_dev *pdev = hwif->pdev;
	int seq_id, seg_len;
	u8 *msg_body;

	seq_id = HINIC_MSG_HEADER_GET(*header, SEQID);
	seg_len = HINIC_MSG_HEADER_GET(*header, SEG_LEN);

	if (seq_id >= (MAX_MSG_LEN / SEGMENT_LEN)) {
		dev_err(&pdev->dev, "recv big mgmt msg\n");
		return;
	}

	msg_body = (u8 *)header + sizeof(*header);
	memcpy(recv_msg->msg + seq_id * SEGMENT_LEN, msg_body, seg_len);

	if (!HINIC_MSG_HEADER_GET(*header, LAST))
		return;

	recv_msg->cmd = HINIC_MSG_HEADER_GET(*header, CMD);
	recv_msg->mod = HINIC_MSG_HEADER_GET(*header, MODULE);
	recv_msg->async_mgmt_to_pf = HINIC_MSG_HEADER_GET(*header,
							  ASYNC_MGMT_TO_PF);
	recv_msg->msg_len = HINIC_MSG_HEADER_GET(*header, MSG_LEN);
	recv_msg->msg_id = HINIC_MSG_HEADER_GET(*header, MSG_ID);

	if (HINIC_MSG_HEADER_GET(*header, DIRECTION) == MGMT_RESP)
		mgmt_resp_msg_handler(pf_to_mgmt, recv_msg);
	else
		mgmt_recv_msg_handler(pf_to_mgmt, recv_msg);
}

/**
 * mgmt_msg_aeqe_handler - handler for a mgmt message event
 * @handle: PF to MGMT channel
 * @data: the header of the message
 * @size: unused
 **/
static void mgmt_msg_aeqe_handler(void *handle, void *data, u8 size)
{
	struct hinic_pf_to_mgmt *pf_to_mgmt = handle;
	struct hinic_recv_msg *recv_msg;
	u64 *header = (u64 *)data;

	recv_msg = HINIC_MSG_HEADER_GET(*header, DIRECTION) ==
		   MGMT_DIRECT_SEND ?
		   &pf_to_mgmt->recv_msg_from_mgmt :
		   &pf_to_mgmt->recv_resp_msg_from_mgmt;

	recv_mgmt_msg_handler(pf_to_mgmt, header, recv_msg);
}

/**
 * alloc_recv_msg - allocate receive message memory
 * @pf_to_mgmt: PF to MGMT channel
 * @recv_msg: pointer that will hold the allocated data
 *
 * Return 0 - Success, negative - Failure
 **/
static int alloc_recv_msg(struct hinic_pf_to_mgmt *pf_to_mgmt,
			  struct hinic_recv_msg *recv_msg)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;
	struct pci_dev *pdev = hwif->pdev;

	recv_msg->msg = devm_kzalloc(&pdev->dev, MAX_PF_MGMT_BUF_SIZE,
				     GFP_KERNEL);
	if (!recv_msg->msg)
		return -ENOMEM;

	recv_msg->buf_out = devm_kzalloc(&pdev->dev, MAX_PF_MGMT_BUF_SIZE,
					 GFP_KERNEL);
	if (!recv_msg->buf_out)
		return -ENOMEM;

	return 0;
}

/**
 * alloc_msg_buf - allocate all the message buffers of PF to MGMT channel
 * @pf_to_mgmt: PF to MGMT channel
 *
 * Return 0 - Success, negative - Failure
 **/
static int alloc_msg_buf(struct hinic_pf_to_mgmt *pf_to_mgmt)
{
	struct hinic_hwif *hwif = pf_to_mgmt->hwif;
	struct pci_dev *pdev = hwif->pdev;
	int err;

	err = alloc_recv_msg(pf_to_mgmt,
			     &pf_to_mgmt->recv_msg_from_mgmt);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate recv msg\n");
		return err;
	}

	err = alloc_recv_msg(pf_to_mgmt,
			     &pf_to_mgmt->recv_resp_msg_from_mgmt);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate resp recv msg\n");
		return err;
	}

	pf_to_mgmt->sync_msg_buf = devm_kzalloc(&pdev->dev,
						MAX_PF_MGMT_BUF_SIZE,
						GFP_KERNEL);
	if (!pf_to_mgmt->sync_msg_buf)
		return -ENOMEM;

	pf_to_mgmt->mgmt_ack_buf = devm_kzalloc(&pdev->dev,
						MAX_PF_MGMT_BUF_SIZE,
						GFP_KERNEL);
	if (!pf_to_mgmt->mgmt_ack_buf)
		return -ENOMEM;

	return 0;
}

/**
 * hinic_pf_to_mgmt_init - initialize PF to MGMT channel
 * @pf_to_mgmt: PF to MGMT channel
 * @hwif: HW interface the PF to MGMT will use for accessing HW
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt,
			  struct hinic_hwif *hwif)
{
	struct hinic_pfhwdev *pfhwdev = mgmt_to_pfhwdev(pf_to_mgmt);
	struct hinic_hwdev *hwdev = &pfhwdev->hwdev;
	struct pci_dev *pdev = hwif->pdev;
	int err;

	pf_to_mgmt->hwif = hwif;
	pf_to_mgmt->hwdev = hwdev;

	if (HINIC_IS_VF(hwif))
		return 0;

	err = hinic_health_reporters_create(hwdev->devlink_dev);
	if (err)
		return err;

	sema_init(&pf_to_mgmt->sync_msg_lock, 1);
	pf_to_mgmt->workq = create_singlethread_workqueue("hinic_mgmt");
	if (!pf_to_mgmt->workq) {
		dev_err(&pdev->dev, "Failed to initialize MGMT workqueue\n");
		hinic_health_reporters_destroy(hwdev->devlink_dev);
		return -ENOMEM;
	}
	pf_to_mgmt->sync_msg_id = 0;

	err = alloc_msg_buf(pf_to_mgmt);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate msg buffers\n");
		hinic_health_reporters_destroy(hwdev->devlink_dev);
		return err;
	}

	err = hinic_api_cmd_init(pf_to_mgmt->cmd_chain, hwif);
	if (err) {
		dev_err(&pdev->dev, "Failed to initialize cmd chains\n");
		hinic_health_reporters_destroy(hwdev->devlink_dev);
		return err;
	}

	hinic_aeq_register_hw_cb(&hwdev->aeqs, HINIC_MSG_FROM_MGMT_CPU,
				 pf_to_mgmt,
				 mgmt_msg_aeqe_handler);
	return 0;
}

/**
 * hinic_pf_to_mgmt_free - free PF to MGMT channel
 * @pf_to_mgmt: PF to MGMT channel
 **/
void hinic_pf_to_mgmt_free(struct hinic_pf_to_mgmt *pf_to_mgmt)
{
	struct hinic_pfhwdev *pfhwdev = mgmt_to_pfhwdev(pf_to_mgmt);
	struct hinic_hwdev *hwdev = &pfhwdev->hwdev;

	if (HINIC_IS_VF(hwdev->hwif))
		return;

	hinic_aeq_unregister_hw_cb(&hwdev->aeqs, HINIC_MSG_FROM_MGMT_CPU);
	hinic_api_cmd_free(pf_to_mgmt->cmd_chain);
	destroy_workqueue(pf_to_mgmt->workq);
	hinic_health_reporters_destroy(hwdev->devlink_dev);
}
