// 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/slab.h>
#include <linux/vmalloc.h>
#include <linux/spinlock.h>
#include <linux/sizes.h>
#include <linux/atomic.h>
#include <linux/log2.h>
#include <linux/io.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <asm/byteorder.h>
#include <asm/barrier.h>

#include "hinic_common.h"
#include "hinic_hw_if.h"
#include "hinic_hw_eqs.h"
#include "hinic_hw_mgmt.h"
#include "hinic_hw_wqe.h"
#include "hinic_hw_wq.h"
#include "hinic_hw_cmdq.h"
#include "hinic_hw_io.h"
#include "hinic_hw_dev.h"

#define CMDQ_CEQE_TYPE_SHIFT                    0

#define CMDQ_CEQE_TYPE_MASK                     0x7

#define CMDQ_CEQE_GET(val, member)              \
			(((val) >> CMDQ_CEQE_##member##_SHIFT) \
			 & CMDQ_CEQE_##member##_MASK)

#define CMDQ_WQE_ERRCODE_VAL_SHIFT              20

#define CMDQ_WQE_ERRCODE_VAL_MASK               0xF

#define CMDQ_WQE_ERRCODE_GET(val, member)       \
			(((val) >> CMDQ_WQE_ERRCODE_##member##_SHIFT) \
			 & CMDQ_WQE_ERRCODE_##member##_MASK)

#define CMDQ_DB_PI_OFF(pi)              (((u16)LOWER_8_BITS(pi)) << 3)

#define CMDQ_DB_ADDR(db_base, pi)       ((db_base) + CMDQ_DB_PI_OFF(pi))

#define CMDQ_WQE_HEADER(wqe)            ((struct hinic_cmdq_header *)(wqe))

#define CMDQ_WQE_COMPLETED(ctrl_info)   \
			HINIC_CMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT)

#define FIRST_DATA_TO_WRITE_LAST        sizeof(u64)

#define CMDQ_DB_OFF                     SZ_2K

#define CMDQ_WQEBB_SIZE                 64
#define CMDQ_WQE_SIZE                   64
#define CMDQ_DEPTH                      SZ_4K

#define CMDQ_WQ_PAGE_SIZE               SZ_256K

#define WQE_LCMD_SIZE                   64
#define WQE_SCMD_SIZE                   64

#define COMPLETE_LEN                    3

#define CMDQ_TIMEOUT                    1000

#define CMDQ_PFN(addr, page_size)       ((addr) >> (ilog2(page_size)))

#define cmdq_to_cmdqs(cmdq)     container_of((cmdq) - (cmdq)->cmdq_type, \
					     struct hinic_cmdqs, cmdq[0])

#define cmdqs_to_func_to_io(cmdqs)      container_of(cmdqs, \
						     struct hinic_func_to_io, \
						     cmdqs)

enum cmdq_wqe_type {
	WQE_LCMD_TYPE = 0,
	WQE_SCMD_TYPE = 1,
};

enum completion_format {
	COMPLETE_DIRECT = 0,
	COMPLETE_SGE    = 1,
};

enum data_format {
	DATA_SGE        = 0,
	DATA_DIRECT     = 1,
};

enum bufdesc_len {
	BUFDESC_LCMD_LEN = 2,   /* 16 bytes - 2(8 byte unit) */
	BUFDESC_SCMD_LEN = 3,   /* 24 bytes - 3(8 byte unit) */
};

enum ctrl_sect_len {
	CTRL_SECT_LEN        = 1, /* 4 bytes (ctrl) - 1(8 byte unit) */
	CTRL_DIRECT_SECT_LEN = 2, /* 12 bytes (ctrl + rsvd) - 2(8 byte unit) */
};

enum cmdq_scmd_type {
	CMDQ_SET_ARM_CMD = 2,
};

enum cmdq_cmd_type {
	CMDQ_CMD_SYNC_DIRECT_RESP = 0,
	CMDQ_CMD_SYNC_SGE_RESP    = 1,
};

enum completion_request {
	NO_CEQ  = 0,
	CEQ_SET = 1,
};

/**
 * hinic_alloc_cmdq_buf - alloc buffer for sending command
 * @cmdqs: the cmdqs
 * @cmdq_buf: the buffer returned in this struct
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
			 struct hinic_cmdq_buf *cmdq_buf)
{
	struct hinic_hwif *hwif = cmdqs->hwif;
	struct pci_dev *pdev = hwif->pdev;

	cmdq_buf->buf = dma_pool_alloc(cmdqs->cmdq_buf_pool, GFP_KERNEL,
				       &cmdq_buf->dma_addr);
	if (!cmdq_buf->buf) {
		dev_err(&pdev->dev, "Failed to allocate cmd from the pool\n");
		return -ENOMEM;
	}

	return 0;
}

/**
 * hinic_free_cmdq_buf - free buffer
 * @cmdqs: the cmdqs
 * @cmdq_buf: the buffer to free that is in this struct
 **/
void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,
			 struct hinic_cmdq_buf *cmdq_buf)
{
	dma_pool_free(cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr);
}

static unsigned int cmdq_wqe_size_from_bdlen(enum bufdesc_len len)
{
	unsigned int wqe_size = 0;

	switch (len) {
	case BUFDESC_LCMD_LEN:
		wqe_size = WQE_LCMD_SIZE;
		break;
	case BUFDESC_SCMD_LEN:
		wqe_size = WQE_SCMD_SIZE;
		break;
	}

	return wqe_size;
}

static void cmdq_set_sge_completion(struct hinic_cmdq_completion *completion,
				    struct hinic_cmdq_buf *buf_out)
{
	struct hinic_sge_resp *sge_resp = &completion->sge_resp;

	hinic_set_sge(&sge_resp->sge, buf_out->dma_addr, buf_out->size);
}

static void cmdq_prepare_wqe_ctrl(struct hinic_cmdq_wqe *wqe, int wrapped,
				  enum hinic_cmd_ack_type ack_type,
				  enum hinic_mod_type mod, u8 cmd, u16 prod_idx,
				  enum completion_format complete_format,
				  enum data_format data_format,
				  enum bufdesc_len buf_len)
{
	struct hinic_cmdq_wqe_lcmd *wqe_lcmd;
	struct hinic_cmdq_wqe_scmd *wqe_scmd;
	enum ctrl_sect_len ctrl_len;
	struct hinic_ctrl *ctrl;
	u32 saved_data;

	if (data_format == DATA_SGE) {
		wqe_lcmd = &wqe->wqe_lcmd;

		wqe_lcmd->status.status_info = 0;
		ctrl = &wqe_lcmd->ctrl;
		ctrl_len = CTRL_SECT_LEN;
	} else {
		wqe_scmd = &wqe->direct_wqe.wqe_scmd;

		wqe_scmd->status.status_info = 0;
		ctrl = &wqe_scmd->ctrl;
		ctrl_len = CTRL_DIRECT_SECT_LEN;
	}

	ctrl->ctrl_info = HINIC_CMDQ_CTRL_SET(prod_idx, PI)             |
			  HINIC_CMDQ_CTRL_SET(cmd, CMD)                 |
			  HINIC_CMDQ_CTRL_SET(mod, MOD)                 |
			  HINIC_CMDQ_CTRL_SET(ack_type, ACK_TYPE);

	CMDQ_WQE_HEADER(wqe)->header_info =
		HINIC_CMDQ_WQE_HEADER_SET(buf_len, BUFDESC_LEN)            |
		HINIC_CMDQ_WQE_HEADER_SET(complete_format, COMPLETE_FMT)   |
		HINIC_CMDQ_WQE_HEADER_SET(data_format, DATA_FMT)           |
		HINIC_CMDQ_WQE_HEADER_SET(CEQ_SET, COMPLETE_REQ)           |
		HINIC_CMDQ_WQE_HEADER_SET(COMPLETE_LEN, COMPLETE_SECT_LEN) |
		HINIC_CMDQ_WQE_HEADER_SET(ctrl_len, CTRL_LEN)              |
		HINIC_CMDQ_WQE_HEADER_SET(wrapped, TOGGLED_WRAPPED);

	saved_data = CMDQ_WQE_HEADER(wqe)->saved_data;
	saved_data = HINIC_SAVED_DATA_CLEAR(saved_data, ARM);

	if ((cmd == CMDQ_SET_ARM_CMD) && (mod == HINIC_MOD_COMM))
		CMDQ_WQE_HEADER(wqe)->saved_data |=
						HINIC_SAVED_DATA_SET(1, ARM);
	else
		CMDQ_WQE_HEADER(wqe)->saved_data = saved_data;
}

static void cmdq_set_lcmd_bufdesc(struct hinic_cmdq_wqe_lcmd *wqe_lcmd,
				  struct hinic_cmdq_buf *buf_in)
{
	hinic_set_sge(&wqe_lcmd->buf_desc.sge, buf_in->dma_addr, buf_in->size);
}

static void cmdq_set_direct_wqe_data(struct hinic_cmdq_direct_wqe *wqe,
				     void *buf_in, u32 in_size)
{
	struct hinic_cmdq_wqe_scmd *wqe_scmd = &wqe->wqe_scmd;

	wqe_scmd->buf_desc.buf_len = in_size;
	memcpy(wqe_scmd->buf_desc.data, buf_in, in_size);
}

static void cmdq_set_lcmd_wqe(struct hinic_cmdq_wqe *wqe,
			      enum cmdq_cmd_type cmd_type,
			      struct hinic_cmdq_buf *buf_in,
			      struct hinic_cmdq_buf *buf_out, int wrapped,
			      enum hinic_cmd_ack_type ack_type,
			      enum hinic_mod_type mod, u8 cmd, u16 prod_idx)
{
	struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd;
	enum completion_format complete_format;

	switch (cmd_type) {
	case CMDQ_CMD_SYNC_SGE_RESP:
		complete_format = COMPLETE_SGE;
		cmdq_set_sge_completion(&wqe_lcmd->completion, buf_out);
		break;
	case CMDQ_CMD_SYNC_DIRECT_RESP:
		complete_format = COMPLETE_DIRECT;
		wqe_lcmd->completion.direct_resp = 0;
		break;
	}

	cmdq_prepare_wqe_ctrl(wqe, wrapped, ack_type, mod, cmd,
			      prod_idx, complete_format, DATA_SGE,
			      BUFDESC_LCMD_LEN);

	cmdq_set_lcmd_bufdesc(wqe_lcmd, buf_in);
}

static void cmdq_set_direct_wqe(struct hinic_cmdq_wqe *wqe,
				enum cmdq_cmd_type cmd_type,
				void *buf_in, u16 in_size,
				struct hinic_cmdq_buf *buf_out, int wrapped,
				enum hinic_cmd_ack_type ack_type,
				enum hinic_mod_type mod, u8 cmd, u16 prod_idx)
{
	struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe;
	enum completion_format complete_format;
	struct hinic_cmdq_wqe_scmd *wqe_scmd;

	wqe_scmd = &direct_wqe->wqe_scmd;

	switch (cmd_type) {
	case CMDQ_CMD_SYNC_SGE_RESP:
		complete_format = COMPLETE_SGE;
		cmdq_set_sge_completion(&wqe_scmd->completion, buf_out);
		break;
	case CMDQ_CMD_SYNC_DIRECT_RESP:
		complete_format = COMPLETE_DIRECT;
		wqe_scmd->completion.direct_resp = 0;
		break;
	}

	cmdq_prepare_wqe_ctrl(wqe, wrapped, ack_type, mod, cmd, prod_idx,
			      complete_format, DATA_DIRECT, BUFDESC_SCMD_LEN);

	cmdq_set_direct_wqe_data(direct_wqe, buf_in, in_size);
}

static void cmdq_wqe_fill(void *dst, void *src)
{
	memcpy(dst + FIRST_DATA_TO_WRITE_LAST, src + FIRST_DATA_TO_WRITE_LAST,
	       CMDQ_WQE_SIZE - FIRST_DATA_TO_WRITE_LAST);

	wmb();          /* The first 8 bytes should be written last */

	*(u64 *)dst = *(u64 *)src;
}

static void cmdq_fill_db(u32 *db_info,
			 enum hinic_cmdq_type cmdq_type, u16 prod_idx)
{
	*db_info = HINIC_CMDQ_DB_INFO_SET(UPPER_8_BITS(prod_idx), HI_PROD_IDX) |
		   HINIC_CMDQ_DB_INFO_SET(HINIC_CTRL_PATH, PATH)               |
		   HINIC_CMDQ_DB_INFO_SET(cmdq_type, CMDQ_TYPE)                |
		   HINIC_CMDQ_DB_INFO_SET(HINIC_DB_CMDQ_TYPE, DB_TYPE);
}

static void cmdq_set_db(struct hinic_cmdq *cmdq,
			enum hinic_cmdq_type cmdq_type, u16 prod_idx)
{
	u32 db_info;

	cmdq_fill_db(&db_info, cmdq_type, prod_idx);

	/* The data that is written to HW should be in Big Endian Format */
	db_info = cpu_to_be32(db_info);

	wmb();  /* write all before the doorbell */

	writel(db_info, CMDQ_DB_ADDR(cmdq->db_base, prod_idx));
}

static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,
				     enum hinic_mod_type mod, u8 cmd,
				     struct hinic_cmdq_buf *buf_in,
				     u64 *resp)
{
	struct hinic_cmdq_wqe *curr_cmdq_wqe, cmdq_wqe;
	u16 curr_prod_idx, next_prod_idx;
	int errcode, wrapped, num_wqebbs;
	struct hinic_wq *wq = cmdq->wq;
	struct hinic_hw_wqe *hw_wqe;
	struct completion done;

	/* Keep doorbell index correct. bh - for tasklet(ceq). */
	spin_lock_bh(&cmdq->cmdq_lock);

	/* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow*/
	hw_wqe = hinic_get_wqe(wq, WQE_LCMD_SIZE, &curr_prod_idx);
	if (IS_ERR(hw_wqe)) {
		spin_unlock_bh(&cmdq->cmdq_lock);
		return -EBUSY;
	}

	curr_cmdq_wqe = &hw_wqe->cmdq_wqe;

	wrapped = cmdq->wrapped;

	num_wqebbs = ALIGN(WQE_LCMD_SIZE, wq->wqebb_size) / wq->wqebb_size;
	next_prod_idx = curr_prod_idx + num_wqebbs;
	if (next_prod_idx >= wq->q_depth) {
		cmdq->wrapped = !cmdq->wrapped;
		next_prod_idx -= wq->q_depth;
	}

	cmdq->errcode[curr_prod_idx] = &errcode;

	init_completion(&done);
	cmdq->done[curr_prod_idx] = &done;

	cmdq_set_lcmd_wqe(&cmdq_wqe, CMDQ_CMD_SYNC_DIRECT_RESP, buf_in, NULL,
			  wrapped, HINIC_CMD_ACK_TYPE_CMDQ, mod, cmd,
			  curr_prod_idx);

	/* The data that is written to HW should be in Big Endian Format */
	hinic_cpu_to_be32(&cmdq_wqe, WQE_LCMD_SIZE);

	/* CMDQ WQE is not shadow, therefore wqe will be written to wq */
	cmdq_wqe_fill(curr_cmdq_wqe, &cmdq_wqe);

	cmdq_set_db(cmdq, HINIC_CMDQ_SYNC, next_prod_idx);

	spin_unlock_bh(&cmdq->cmdq_lock);

	if (!wait_for_completion_timeout(&done,
					 msecs_to_jiffies(CMDQ_TIMEOUT))) {
		spin_lock_bh(&cmdq->cmdq_lock);

		if (cmdq->errcode[curr_prod_idx] == &errcode)
			cmdq->errcode[curr_prod_idx] = NULL;

		if (cmdq->done[curr_prod_idx] == &done)
			cmdq->done[curr_prod_idx] = NULL;

		spin_unlock_bh(&cmdq->cmdq_lock);

		return -ETIMEDOUT;
	}

	smp_rmb();      /* read error code after completion */

	if (resp) {
		struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &curr_cmdq_wqe->wqe_lcmd;

		*resp = cpu_to_be64(wqe_lcmd->completion.direct_resp);
	}

	if (errcode != 0)
		return -EFAULT;

	return 0;
}

static int cmdq_set_arm_bit(struct hinic_cmdq *cmdq, void *buf_in,
			    u16 in_size)
{
	struct hinic_cmdq_wqe *curr_cmdq_wqe, cmdq_wqe;
	u16 curr_prod_idx, next_prod_idx;
	struct hinic_wq *wq = cmdq->wq;
	struct hinic_hw_wqe *hw_wqe;
	int wrapped, num_wqebbs;

	/* Keep doorbell index correct */
	spin_lock(&cmdq->cmdq_lock);

	/* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow*/
	hw_wqe = hinic_get_wqe(wq, WQE_SCMD_SIZE, &curr_prod_idx);
	if (IS_ERR(hw_wqe)) {
		spin_unlock(&cmdq->cmdq_lock);
		return -EBUSY;
	}

	curr_cmdq_wqe = &hw_wqe->cmdq_wqe;

	wrapped = cmdq->wrapped;

	num_wqebbs = ALIGN(WQE_SCMD_SIZE, wq->wqebb_size) / wq->wqebb_size;
	next_prod_idx = curr_prod_idx + num_wqebbs;
	if (next_prod_idx >= wq->q_depth) {
		cmdq->wrapped = !cmdq->wrapped;
		next_prod_idx -= wq->q_depth;
	}

	cmdq_set_direct_wqe(&cmdq_wqe, CMDQ_CMD_SYNC_DIRECT_RESP, buf_in,
			    in_size, NULL, wrapped, HINIC_CMD_ACK_TYPE_CMDQ,
			    HINIC_MOD_COMM, CMDQ_SET_ARM_CMD, curr_prod_idx);

	/* The data that is written to HW should be in Big Endian Format */
	hinic_cpu_to_be32(&cmdq_wqe, WQE_SCMD_SIZE);

	/* cmdq wqe is not shadow, therefore wqe will be written to wq */
	cmdq_wqe_fill(curr_cmdq_wqe, &cmdq_wqe);

	cmdq_set_db(cmdq, HINIC_CMDQ_SYNC, next_prod_idx);

	spin_unlock(&cmdq->cmdq_lock);
	return 0;
}

static int cmdq_params_valid(struct hinic_cmdq_buf *buf_in)
{
	if (buf_in->size > HINIC_CMDQ_MAX_DATA_SIZE)
		return -EINVAL;

	return 0;
}

/**
 * hinic_cmdq_direct_resp - send command with direct data as resp
 * @cmdqs: the cmdqs
 * @mod: module on the card that will handle the command
 * @cmd: the command
 * @buf_in: the buffer for the command
 * @resp: the response to return
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs,
			   enum hinic_mod_type mod, u8 cmd,
			   struct hinic_cmdq_buf *buf_in, u64 *resp)
{
	struct hinic_hwif *hwif = cmdqs->hwif;
	struct pci_dev *pdev = hwif->pdev;
	int err;

	err = cmdq_params_valid(buf_in);
	if (err) {
		dev_err(&pdev->dev, "Invalid CMDQ parameters\n");
		return err;
	}

	return cmdq_sync_cmd_direct_resp(&cmdqs->cmdq[HINIC_CMDQ_SYNC],
					 mod, cmd, buf_in, resp);
}

/**
 * hinic_set_arm_bit - set arm bit for enable interrupt again
 * @cmdqs: the cmdqs
 * @q_type: type of queue to set the arm bit for
 * @q_id: the queue number
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_set_arm_bit(struct hinic_cmdqs *cmdqs,
		      enum hinic_set_arm_qtype q_type, u32 q_id)
{
	struct hinic_cmdq *cmdq = &cmdqs->cmdq[HINIC_CMDQ_SYNC];
	struct hinic_hwif *hwif = cmdqs->hwif;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_cmdq_arm_bit arm_bit;
	int err;

	arm_bit.q_type = q_type;
	arm_bit.q_id   = q_id;

	err = cmdq_set_arm_bit(cmdq, &arm_bit, sizeof(arm_bit));
	if (err) {
		dev_err(&pdev->dev, "Failed to set arm for qid %d\n", q_id);
		return err;
	}

	return 0;
}

static void clear_wqe_complete_bit(struct hinic_cmdq *cmdq,
				   struct hinic_cmdq_wqe *wqe)
{
	u32 header_info = be32_to_cpu(CMDQ_WQE_HEADER(wqe)->header_info);
	unsigned int bufdesc_len, wqe_size;
	struct hinic_ctrl *ctrl;

	bufdesc_len = HINIC_CMDQ_WQE_HEADER_GET(header_info, BUFDESC_LEN);
	wqe_size = cmdq_wqe_size_from_bdlen(bufdesc_len);
	if (wqe_size == WQE_LCMD_SIZE) {
		struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd;

		ctrl = &wqe_lcmd->ctrl;
	} else {
		struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe;
		struct hinic_cmdq_wqe_scmd *wqe_scmd;

		wqe_scmd = &direct_wqe->wqe_scmd;
		ctrl = &wqe_scmd->ctrl;
	}

	/* clear HW busy bit */
	ctrl->ctrl_info = 0;

	wmb();  /* verify wqe is clear */
}

/**
 * cmdq_arm_ceq_handler - cmdq completion event handler for arm command
 * @cmdq: the cmdq of the arm command
 * @wqe: the wqe of the arm command
 *
 * Return 0 - Success, negative - Failure
 **/
static int cmdq_arm_ceq_handler(struct hinic_cmdq *cmdq,
				struct hinic_cmdq_wqe *wqe)
{
	struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe;
	struct hinic_cmdq_wqe_scmd *wqe_scmd;
	struct hinic_ctrl *ctrl;
	u32 ctrl_info;

	wqe_scmd = &direct_wqe->wqe_scmd;
	ctrl = &wqe_scmd->ctrl;
	ctrl_info = be32_to_cpu(ctrl->ctrl_info);

	/* HW should toggle the HW BUSY BIT */
	if (!CMDQ_WQE_COMPLETED(ctrl_info))
		return -EBUSY;

	clear_wqe_complete_bit(cmdq, wqe);

	hinic_put_wqe(cmdq->wq, WQE_SCMD_SIZE);
	return 0;
}

static void cmdq_update_errcode(struct hinic_cmdq *cmdq, u16 prod_idx,
				int errcode)
{
	if (cmdq->errcode[prod_idx])
		*cmdq->errcode[prod_idx] = errcode;
}

/**
 * cmdq_arm_ceq_handler - cmdq completion event handler for sync command
 * @cmdq: the cmdq of the command
 * @cons_idx: the consumer index to update the error code for
 * @errcode: the error code
 **/
static void cmdq_sync_cmd_handler(struct hinic_cmdq *cmdq, u16 cons_idx,
				  int errcode)
{
	u16 prod_idx = cons_idx;

	spin_lock(&cmdq->cmdq_lock);
	cmdq_update_errcode(cmdq, prod_idx, errcode);

	wmb();  /* write all before update for the command request */

	if (cmdq->done[prod_idx])
		complete(cmdq->done[prod_idx]);
	spin_unlock(&cmdq->cmdq_lock);
}

static int cmdq_cmd_ceq_handler(struct hinic_cmdq *cmdq, u16 ci,
				struct hinic_cmdq_wqe *cmdq_wqe)
{
	struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &cmdq_wqe->wqe_lcmd;
	struct hinic_status *status = &wqe_lcmd->status;
	struct hinic_ctrl *ctrl = &wqe_lcmd->ctrl;
	int errcode;

	if (!CMDQ_WQE_COMPLETED(be32_to_cpu(ctrl->ctrl_info)))
		return -EBUSY;

	dma_rmb();

	errcode = CMDQ_WQE_ERRCODE_GET(be32_to_cpu(status->status_info), VAL);

	cmdq_sync_cmd_handler(cmdq, ci, errcode);

	clear_wqe_complete_bit(cmdq, cmdq_wqe);
	hinic_put_wqe(cmdq->wq, WQE_LCMD_SIZE);
	return 0;
}

/**
 * cmdq_ceq_handler - cmdq completion event handler
 * @handle: private data for the handler(cmdqs)
 * @ceqe_data: ceq element data
 **/
static void cmdq_ceq_handler(void *handle, u32 ceqe_data)
{
	enum hinic_cmdq_type cmdq_type = CMDQ_CEQE_GET(ceqe_data, TYPE);
	struct hinic_cmdqs *cmdqs = (struct hinic_cmdqs *)handle;
	struct hinic_cmdq *cmdq = &cmdqs->cmdq[cmdq_type];
	struct hinic_cmdq_header *header;
	struct hinic_hw_wqe *hw_wqe;
	int err, set_arm = 0;
	u32 saved_data;
	u16 ci;

	/* Read the smallest wqe size for getting wqe size */
	while ((hw_wqe = hinic_read_wqe(cmdq->wq, WQE_SCMD_SIZE, &ci))) {
		if (IS_ERR(hw_wqe))
			break;

		header = CMDQ_WQE_HEADER(&hw_wqe->cmdq_wqe);
		saved_data = be32_to_cpu(header->saved_data);

		if (HINIC_SAVED_DATA_GET(saved_data, ARM)) {
			/* arm_bit was set until here */
			set_arm = 0;

			if (cmdq_arm_ceq_handler(cmdq, &hw_wqe->cmdq_wqe))
				break;
		} else {
			set_arm = 1;

			hw_wqe = hinic_read_wqe(cmdq->wq, WQE_LCMD_SIZE, &ci);
			if (IS_ERR(hw_wqe))
				break;

			if (cmdq_cmd_ceq_handler(cmdq, ci, &hw_wqe->cmdq_wqe))
				break;
		}
	}

	if (set_arm) {
		struct hinic_hwif *hwif = cmdqs->hwif;
		struct pci_dev *pdev = hwif->pdev;

		err = hinic_set_arm_bit(cmdqs, HINIC_SET_ARM_CMDQ, cmdq_type);
		if (err)
			dev_err(&pdev->dev, "Failed to set arm for CMDQ\n");
	}
}

/**
 * cmdq_init_queue_ctxt - init the queue ctxt of a cmdq
 * @cmdq_ctxt: cmdq ctxt to initialize
 * @cmdq: the cmdq
 * @cmdq_pages: the memory of the queue
 **/
static void cmdq_init_queue_ctxt(struct hinic_cmdq_ctxt *cmdq_ctxt,
				 struct hinic_cmdq *cmdq,
				 struct hinic_cmdq_pages *cmdq_pages)
{
	struct hinic_cmdq_ctxt_info *ctxt_info = &cmdq_ctxt->ctxt_info;
	u64 wq_first_page_paddr, cmdq_first_block_paddr, pfn;
	struct hinic_cmdqs *cmdqs = cmdq_to_cmdqs(cmdq);
	struct hinic_wq *wq = cmdq->wq;

	/* The data in the HW is in Big Endian Format */
	wq_first_page_paddr = be64_to_cpu(*wq->block_vaddr);

	pfn = CMDQ_PFN(wq_first_page_paddr, SZ_4K);

	ctxt_info->curr_wqe_page_pfn =
		HINIC_CMDQ_CTXT_PAGE_INFO_SET(pfn, CURR_WQE_PAGE_PFN)   |
		HINIC_CMDQ_CTXT_PAGE_INFO_SET(HINIC_CEQ_ID_CMDQ, EQ_ID) |
		HINIC_CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_ARM)               |
		HINIC_CMDQ_CTXT_PAGE_INFO_SET(1, CEQ_EN)                |
		HINIC_CMDQ_CTXT_PAGE_INFO_SET(cmdq->wrapped, WRAPPED);

	if (wq->num_q_pages != 1) {
		/* block PFN - Read Modify Write */
		cmdq_first_block_paddr = cmdq_pages->page_paddr;

		pfn = CMDQ_PFN(cmdq_first_block_paddr, wq->wq_page_size);
	}

	ctxt_info->wq_block_pfn =
		HINIC_CMDQ_CTXT_BLOCK_INFO_SET(pfn, WQ_BLOCK_PFN) |
		HINIC_CMDQ_CTXT_BLOCK_INFO_SET(atomic_read(&wq->cons_idx), CI);

	cmdq_ctxt->func_idx = HINIC_HWIF_FUNC_IDX(cmdqs->hwif);
	cmdq_ctxt->ppf_idx = HINIC_HWIF_PPF_IDX(cmdqs->hwif);
	cmdq_ctxt->cmdq_type  = cmdq->cmdq_type;
}

/**
 * init_cmdq - initialize cmdq
 * @cmdq: the cmdq
 * @wq: the wq attaced to the cmdq
 * @q_type: the cmdq type of the cmdq
 * @db_area: doorbell area for the cmdq
 *
 * Return 0 - Success, negative - Failure
 **/
static int init_cmdq(struct hinic_cmdq *cmdq, struct hinic_wq *wq,
		     enum hinic_cmdq_type q_type, void __iomem *db_area)
{
	int err;

	cmdq->wq = wq;
	cmdq->cmdq_type = q_type;
	cmdq->wrapped = 1;

	spin_lock_init(&cmdq->cmdq_lock);

	cmdq->done = vzalloc(array_size(sizeof(*cmdq->done), wq->q_depth));
	if (!cmdq->done)
		return -ENOMEM;

	cmdq->errcode = vzalloc(array_size(sizeof(*cmdq->errcode),
					   wq->q_depth));
	if (!cmdq->errcode) {
		err = -ENOMEM;
		goto err_errcode;
	}

	cmdq->db_base = db_area + CMDQ_DB_OFF;
	return 0;

err_errcode:
	vfree(cmdq->done);
	return err;
}

/**
 * free_cmdq - Free cmdq
 * @cmdq: the cmdq to free
 **/
static void free_cmdq(struct hinic_cmdq *cmdq)
{
	vfree(cmdq->errcode);
	vfree(cmdq->done);
}

/**
 * init_cmdqs_ctxt - write the cmdq ctxt to HW after init all cmdq
 * @hwdev: the NIC HW device
 * @cmdqs: cmdqs to write the ctxts for
 * &db_area: db_area for all the cmdqs
 *
 * Return 0 - Success, negative - Failure
 **/
static int init_cmdqs_ctxt(struct hinic_hwdev *hwdev,
			   struct hinic_cmdqs *cmdqs, void __iomem **db_area)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	enum hinic_cmdq_type type, cmdq_type;
	struct hinic_cmdq_ctxt *cmdq_ctxts;
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_pfhwdev *pfhwdev;
	size_t cmdq_ctxts_size;
	int err;

	cmdq_ctxts_size = HINIC_MAX_CMDQ_TYPES * sizeof(*cmdq_ctxts);
	cmdq_ctxts = devm_kzalloc(&pdev->dev, cmdq_ctxts_size, GFP_KERNEL);
	if (!cmdq_ctxts)
		return -ENOMEM;

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

	cmdq_type = HINIC_CMDQ_SYNC;
	for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
		err = init_cmdq(&cmdqs->cmdq[cmdq_type],
				&cmdqs->saved_wqs[cmdq_type], cmdq_type,
				db_area[cmdq_type]);
		if (err) {
			dev_err(&pdev->dev, "Failed to initialize cmdq\n");
			goto err_init_cmdq;
		}

		cmdq_init_queue_ctxt(&cmdq_ctxts[cmdq_type],
				     &cmdqs->cmdq[cmdq_type],
				     &cmdqs->cmdq_pages);
	}

	/* Write the CMDQ ctxts */
	cmdq_type = HINIC_CMDQ_SYNC;
	for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
		err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
					HINIC_COMM_CMD_CMDQ_CTXT_SET,
					&cmdq_ctxts[cmdq_type],
					sizeof(cmdq_ctxts[cmdq_type]),
					NULL, NULL, HINIC_MGMT_MSG_SYNC);
		if (err) {
			dev_err(&pdev->dev, "Failed to set CMDQ CTXT type = %d\n",
				cmdq_type);
			goto err_write_cmdq_ctxt;
		}
	}

	devm_kfree(&pdev->dev, cmdq_ctxts);
	return 0;

err_write_cmdq_ctxt:
	cmdq_type = HINIC_MAX_CMDQ_TYPES;

err_init_cmdq:
	for (type = HINIC_CMDQ_SYNC; type < cmdq_type; type++)
		free_cmdq(&cmdqs->cmdq[type]);

	devm_kfree(&pdev->dev, cmdq_ctxts);
	return err;
}

static int hinic_set_cmdq_depth(struct hinic_hwdev *hwdev, u16 cmdq_depth)
{
	struct hinic_cmd_hw_ioctxt hw_ioctxt = { 0 };
	struct hinic_pfhwdev *pfhwdev;

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

	hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwdev->hwif);
	hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);

	hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_ENABLE;
	hw_ioctxt.cmdq_depth = (u8)ilog2(cmdq_depth);

	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);
}

/**
 * hinic_init_cmdqs - init all cmdqs
 * @cmdqs: cmdqs to init
 * @hwif: HW interface for accessing cmdqs
 * @db_area: doorbell areas for all the cmdqs
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
		     void __iomem **db_area)
{
	struct hinic_func_to_io *func_to_io = cmdqs_to_func_to_io(cmdqs);
	struct pci_dev *pdev = hwif->pdev;
	struct hinic_hwdev *hwdev;
	size_t saved_wqs_size;
	u16 max_wqe_size;
	int err;

	cmdqs->hwif = hwif;
	cmdqs->cmdq_buf_pool = dma_pool_create("hinic_cmdq", &pdev->dev,
					       HINIC_CMDQ_BUF_SIZE,
					       HINIC_CMDQ_BUF_SIZE, 0);
	if (!cmdqs->cmdq_buf_pool)
		return -ENOMEM;

	saved_wqs_size = HINIC_MAX_CMDQ_TYPES * sizeof(struct hinic_wq);
	cmdqs->saved_wqs = devm_kzalloc(&pdev->dev, saved_wqs_size, GFP_KERNEL);
	if (!cmdqs->saved_wqs) {
		err = -ENOMEM;
		goto err_saved_wqs;
	}

	max_wqe_size = WQE_LCMD_SIZE;
	err = hinic_wqs_cmdq_alloc(&cmdqs->cmdq_pages, cmdqs->saved_wqs, hwif,
				   HINIC_MAX_CMDQ_TYPES, CMDQ_WQEBB_SIZE,
				   CMDQ_WQ_PAGE_SIZE, CMDQ_DEPTH, max_wqe_size);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate CMDQ wqs\n");
		goto err_cmdq_wqs;
	}

	hwdev = container_of(func_to_io, struct hinic_hwdev, func_to_io);
	err = init_cmdqs_ctxt(hwdev, cmdqs, db_area);
	if (err) {
		dev_err(&pdev->dev, "Failed to write cmdq ctxt\n");
		goto err_cmdq_ctxt;
	}

	hinic_ceq_register_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ, cmdqs,
			      cmdq_ceq_handler);

	err = hinic_set_cmdq_depth(hwdev, CMDQ_DEPTH);
	if (err) {
		dev_err(&hwif->pdev->dev, "Failed to set cmdq depth\n");
		goto err_set_cmdq_depth;
	}

	return 0;

err_set_cmdq_depth:
	hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);

err_cmdq_ctxt:
	hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
			    HINIC_MAX_CMDQ_TYPES);

err_cmdq_wqs:
	devm_kfree(&pdev->dev, cmdqs->saved_wqs);

err_saved_wqs:
	dma_pool_destroy(cmdqs->cmdq_buf_pool);
	return err;
}

/**
 * hinic_free_cmdqs - free all cmdqs
 * @cmdqs: cmdqs to free
 **/
void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs)
{
	struct hinic_func_to_io *func_to_io = cmdqs_to_func_to_io(cmdqs);
	struct hinic_hwif *hwif = cmdqs->hwif;
	struct pci_dev *pdev = hwif->pdev;
	enum hinic_cmdq_type cmdq_type;

	hinic_ceq_unregister_cb(&func_to_io->ceqs, HINIC_CEQ_CMDQ);

	cmdq_type = HINIC_CMDQ_SYNC;
	for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++)
		free_cmdq(&cmdqs->cmdq[cmdq_type]);

	hinic_wqs_cmdq_free(&cmdqs->cmdq_pages, cmdqs->saved_wqs,
			    HINIC_MAX_CMDQ_TYPES);

	devm_kfree(&pdev->dev, cmdqs->saved_wqs);

	dma_pool_destroy(cmdqs->cmdq_buf_pool);
}
