// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 HiSilicon Limited. */
#include <asm/page.h>
#include <linux/acpi.h>
#include <linux/bitmap.h>
#include <linux/dma-mapping.h>
#include <linux/idr.h>
#include <linux/io.h>
#include <linux/irqreturn.h>
#include <linux/log2.h>
#include <linux/pm_runtime.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uacce.h>
#include <linux/uaccess.h>
#include <uapi/misc/uacce/hisi_qm.h>
#include <linux/hisi_acc_qm.h>
#include "qm_common.h"

/* eq/aeq irq enable */
#define QM_VF_AEQ_INT_SOURCE		0x0
#define QM_VF_AEQ_INT_MASK		0x4
#define QM_VF_EQ_INT_SOURCE		0x8
#define QM_VF_EQ_INT_MASK		0xc

#define QM_IRQ_VECTOR_MASK		GENMASK(15, 0)
#define QM_IRQ_TYPE_MASK		GENMASK(15, 0)
#define QM_IRQ_TYPE_SHIFT		16
#define QM_ABN_IRQ_TYPE_MASK		GENMASK(7, 0)

/* mailbox */
#define QM_MB_PING_ALL_VFS		0xffff
#define QM_MB_STATUS_MASK		GENMASK(12, 9)

/* sqc shift */
#define QM_SQ_HOP_NUM_SHIFT		0
#define QM_SQ_PAGE_SIZE_SHIFT		4
#define QM_SQ_BUF_SIZE_SHIFT		8
#define QM_SQ_SQE_SIZE_SHIFT		12
#define QM_SQ_PRIORITY_SHIFT		0
#define QM_SQ_ORDERS_SHIFT		4
#define QM_SQ_TYPE_SHIFT		8
#define QM_QC_PASID_ENABLE		0x1
#define QM_QC_PASID_ENABLE_SHIFT	7

#define QM_SQ_TYPE_MASK			GENMASK(3, 0)
#define QM_SQ_TAIL_IDX(sqc)		((le16_to_cpu((sqc).w11) >> 6) & 0x1)

/* cqc shift */
#define QM_CQ_HOP_NUM_SHIFT		0
#define QM_CQ_PAGE_SIZE_SHIFT		4
#define QM_CQ_BUF_SIZE_SHIFT		8
#define QM_CQ_CQE_SIZE_SHIFT		12
#define QM_CQ_PHASE_SHIFT		0
#define QM_CQ_FLAG_SHIFT		1

#define QM_CQE_PHASE(cqe)		(le16_to_cpu((cqe)->w7) & 0x1)
#define QM_QC_CQE_SIZE			4
#define QM_CQ_TAIL_IDX(cqc)		((le16_to_cpu((cqc).w11) >> 6) & 0x1)

/* eqc shift */
#define QM_EQE_AEQE_SIZE		(2UL << 12)
#define QM_EQC_PHASE_SHIFT		16

#define QM_EQE_PHASE(eqe)		((le32_to_cpu((eqe)->dw0) >> 16) & 0x1)
#define QM_EQE_CQN_MASK			GENMASK(15, 0)

#define QM_AEQE_PHASE(aeqe)		((le32_to_cpu((aeqe)->dw0) >> 16) & 0x1)
#define QM_AEQE_TYPE_SHIFT		17
#define QM_AEQE_TYPE_MASK		0xf
#define QM_AEQE_CQN_MASK		GENMASK(15, 0)
#define QM_CQ_OVERFLOW			0
#define QM_EQ_OVERFLOW			1
#define QM_CQE_ERROR			2

#define QM_XQ_DEPTH_SHIFT		16
#define QM_XQ_DEPTH_MASK		GENMASK(15, 0)

#define QM_DOORBELL_CMD_SQ		0
#define QM_DOORBELL_CMD_CQ		1
#define QM_DOORBELL_CMD_EQ		2
#define QM_DOORBELL_CMD_AEQ		3

#define QM_DOORBELL_BASE_V1		0x340
#define QM_DB_CMD_SHIFT_V1		16
#define QM_DB_INDEX_SHIFT_V1		32
#define QM_DB_PRIORITY_SHIFT_V1		48
#define QM_PAGE_SIZE			0x0034
#define QM_QP_DB_INTERVAL		0x10000
#define QM_DB_TIMEOUT_CFG		0x100074
#define QM_DB_TIMEOUT_SET		0x1fffff

#define QM_MEM_START_INIT		0x100040
#define QM_MEM_INIT_DONE		0x100044
#define QM_VFT_CFG_RDY			0x10006c
#define QM_VFT_CFG_OP_WR		0x100058
#define QM_VFT_CFG_TYPE			0x10005c
#define QM_VFT_CFG			0x100060
#define QM_VFT_CFG_OP_ENABLE		0x100054
#define QM_PM_CTRL			0x100148
#define QM_IDLE_DISABLE			BIT(9)

#define QM_SUB_VERSION_ID		0x210

#define QM_VFT_CFG_DATA_L		0x100064
#define QM_VFT_CFG_DATA_H		0x100068
#define QM_SQC_VFT_BUF_SIZE		(7ULL << 8)
#define QM_SQC_VFT_SQC_SIZE		(5ULL << 12)
#define QM_SQC_VFT_INDEX_NUMBER		(1ULL << 16)
#define QM_SQC_VFT_START_SQN_SHIFT	28
#define QM_SQC_VFT_VALID		(1ULL << 44)
#define QM_SQC_VFT_SQN_SHIFT		45
#define QM_CQC_VFT_BUF_SIZE		(7ULL << 8)
#define QM_CQC_VFT_SQC_SIZE		(5ULL << 12)
#define QM_CQC_VFT_INDEX_NUMBER		(1ULL << 16)
#define QM_CQC_VFT_VALID		(1ULL << 28)

#define QM_SQC_VFT_BASE_SHIFT_V2	28
#define QM_SQC_VFT_BASE_MASK_V2		GENMASK(15, 0)
#define QM_SQC_VFT_NUM_SHIFT_V2		45
#define QM_SQC_VFT_NUM_MASK_V2		GENMASK(9, 0)
#define QM_MAX_QC_TYPE                  2

#define QM_ABNORMAL_INT_SOURCE		0x100000
#define QM_ABNORMAL_INT_MASK		0x100004
#define QM_ABNORMAL_INT_MASK_VALUE	0x7fff
#define QM_ABNORMAL_INT_STATUS		0x100008
#define QM_ABNORMAL_INT_SET		0x10000c
#define QM_ABNORMAL_INF00		0x100010
#define QM_FIFO_OVERFLOW_TYPE		0xc0
#define QM_FIFO_OVERFLOW_TYPE_SHIFT	6
#define QM_FIFO_OVERFLOW_VF		0x3f
#define QM_FIFO_OVERFLOW_QP_SHIFT	16
#define QM_ABNORMAL_INF01		0x100014
#define QM_DB_TIMEOUT_TYPE		0xc0
#define QM_DB_TIMEOUT_TYPE_SHIFT	6
#define QM_DB_TIMEOUT_VF		0x3f
#define QM_DB_TIMEOUT_QP_SHIFT		16
#define QM_ABNORMAL_INF02		0x100018
#define QM_AXI_POISON_ERR		BIT(22)
#define QM_RAS_CE_ENABLE		0x1000ec
#define QM_RAS_FE_ENABLE		0x1000f0
#define QM_RAS_NFE_ENABLE		0x1000f4
#define QM_RAS_CE_THRESHOLD		0x1000f8
#define QM_RAS_CE_TIMES_PER_IRQ		1
#define QM_OOO_SHUTDOWN_SEL		0x1040f8
#define QM_AXI_RRESP_ERR		BIT(0)
#define QM_ECC_MBIT			BIT(2)
#define QM_DB_TIMEOUT			BIT(10)
#define QM_OF_FIFO_OF			BIT(11)

#define QM_RESET_WAIT_TIMEOUT		400
#define QM_PEH_VENDOR_ID		0x1000d8
#define ACC_VENDOR_ID_VALUE		0x5a5a
#define QM_PEH_DFX_INFO0		0x1000fc
#define QM_PEH_DFX_INFO1		0x100100
#define QM_PEH_DFX_MASK			(BIT(0) | BIT(2))
#define QM_PEH_MSI_FINISH_MASK		GENMASK(19, 16)
#define ACC_PEH_SRIOV_CTRL_VF_MSE_SHIFT	3
#define ACC_PEH_MSI_DISABLE		GENMASK(31, 0)
#define ACC_MASTER_GLOBAL_CTRL_SHUTDOWN	0x1
#define ACC_MASTER_TRANS_RETURN_RW	3
#define ACC_MASTER_TRANS_RETURN		0x300150
#define ACC_MASTER_GLOBAL_CTRL		0x300000
#define ACC_AM_CFG_PORT_WR_EN		0x30001c
#define QM_RAS_NFE_MBIT_DISABLE		~QM_ECC_MBIT
#define ACC_AM_ROB_ECC_INT_STS		0x300104
#define ACC_ROB_ECC_ERR_MULTPL		BIT(1)
#define QM_MSI_CAP_ENABLE		BIT(16)

/* interfunction communication */
#define QM_IFC_READY_STATUS		0x100128
#define QM_IFC_INT_SET_P		0x100130
#define QM_IFC_INT_CFG			0x100134
#define QM_IFC_INT_SOURCE_P		0x100138
#define QM_IFC_INT_SOURCE_V		0x0020
#define QM_IFC_INT_MASK			0x0024
#define QM_IFC_INT_STATUS		0x0028
#define QM_IFC_INT_SET_V		0x002C
#define QM_PF2VF_PF_W			0x104700
#define QM_VF2PF_PF_R			0x104800
#define QM_VF2PF_VF_W			0x320
#define QM_PF2VF_VF_R			0x380
#define QM_IFC_SEND_ALL_VFS		GENMASK(6, 0)
#define QM_IFC_INT_SOURCE_CLR		GENMASK(63, 0)
#define QM_IFC_INT_SOURCE_MASK		BIT(0)
#define QM_IFC_INT_DISABLE		BIT(0)
#define QM_IFC_INT_STATUS_MASK		BIT(0)
#define QM_IFC_INT_SET_MASK		BIT(0)
#define QM_WAIT_DST_ACK			10
#define QM_MAX_PF_WAIT_COUNT		10
#define QM_MAX_VF_WAIT_COUNT		40
#define QM_VF_RESET_WAIT_US		20000
#define QM_VF_RESET_WAIT_CNT		3000
#define QM_VF2PF_REG_SIZE		4
#define QM_IFC_CMD_MASK			GENMASK(31, 0)
#define QM_IFC_DATA_SHIFT		32
#define QM_VF_RESET_WAIT_TIMEOUT_US    \
	(QM_VF_RESET_WAIT_US * QM_VF_RESET_WAIT_CNT)

#define POLL_PERIOD			10
#define POLL_TIMEOUT			1000
#define WAIT_PERIOD_US_MAX		200
#define WAIT_PERIOD_US_MIN		100
#define MAX_WAIT_COUNTS			1000
#define QM_CACHE_WB_START		0x204
#define QM_CACHE_WB_DONE		0x208
#define QM_FUNC_CAPS_REG		0x3100
#define QM_CAPBILITY_VERSION		GENMASK(7, 0)

#define PCI_BAR_2			2
#define PCI_BAR_4			4
#define QMC_ALIGN(sz)			ALIGN(sz, 32)

#define QM_DBG_READ_LEN		256
#define QM_PCI_COMMAND_INVALID		~0
#define QM_RESET_STOP_TX_OFFSET		1
#define QM_RESET_STOP_RX_OFFSET		2

#define WAIT_PERIOD			20
#define REMOVE_WAIT_DELAY		10

#define QM_QOS_PARAM_NUM		2
#define QM_QOS_MAX_VAL			1000
#define QM_QOS_RATE			100
#define QM_QOS_EXPAND_RATE		1000
#define QM_SHAPER_CIR_B_MASK		GENMASK(7, 0)
#define QM_SHAPER_CIR_U_MASK		GENMASK(10, 8)
#define QM_SHAPER_CIR_S_MASK		GENMASK(14, 11)
#define QM_SHAPER_FACTOR_CIR_U_SHIFT	8
#define QM_SHAPER_FACTOR_CIR_S_SHIFT	11
#define QM_SHAPER_FACTOR_CBS_B_SHIFT	15
#define QM_SHAPER_FACTOR_CBS_S_SHIFT	19
#define QM_SHAPER_CBS_B			1
#define QM_SHAPER_VFT_OFFSET		6
#define QM_QOS_MIN_ERROR_RATE		5
#define QM_SHAPER_MIN_CBS_S		8
#define QM_QOS_TICK			0x300U
#define QM_QOS_DIVISOR_CLK		0x1f40U
#define QM_QOS_MAX_CIR_B		200
#define QM_QOS_MIN_CIR_B		100
#define QM_QOS_MAX_CIR_U		6
#define QM_AUTOSUSPEND_DELAY		3000

 /* abnormal status value for stopping queue */
#define QM_STOP_QUEUE_FAIL		1
#define	QM_DUMP_SQC_FAIL		3
#define	QM_DUMP_CQC_FAIL		4
#define	QM_FINISH_WAIT			5

#define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \
	(((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \
	((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \
	((buf_sz) << QM_CQ_BUF_SIZE_SHIFT) | \
	((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT))

#define QM_MK_CQC_DW3_V2(cqe_sz, cq_depth) \
	((((u32)cq_depth) - 1) | ((cqe_sz) << QM_CQ_CQE_SIZE_SHIFT))

#define QM_MK_SQC_W13(priority, orders, alg_type) \
	(((priority) << QM_SQ_PRIORITY_SHIFT) | \
	((orders) << QM_SQ_ORDERS_SHIFT) | \
	(((alg_type) & QM_SQ_TYPE_MASK) << QM_SQ_TYPE_SHIFT))

#define QM_MK_SQC_DW3_V1(hop_num, pg_sz, buf_sz, sqe_sz) \
	(((hop_num) << QM_SQ_HOP_NUM_SHIFT) | \
	((pg_sz) << QM_SQ_PAGE_SIZE_SHIFT) | \
	((buf_sz) << QM_SQ_BUF_SIZE_SHIFT) | \
	((u32)ilog2(sqe_sz) << QM_SQ_SQE_SIZE_SHIFT))

#define QM_MK_SQC_DW3_V2(sqe_sz, sq_depth) \
	((((u32)sq_depth) - 1) | ((u32)ilog2(sqe_sz) << QM_SQ_SQE_SIZE_SHIFT))

enum vft_type {
	SQC_VFT = 0,
	CQC_VFT,
	SHAPER_VFT,
};

enum qm_alg_type {
	ALG_TYPE_0,
	ALG_TYPE_1,
};

enum qm_ifc_cmd {
	QM_PF_FLR_PREPARE = 0x01,
	QM_PF_SRST_PREPARE,
	QM_PF_RESET_DONE,
	QM_VF_PREPARE_DONE,
	QM_VF_PREPARE_FAIL,
	QM_VF_START_DONE,
	QM_VF_START_FAIL,
	QM_PF_SET_QOS,
	QM_VF_GET_QOS,
};

enum qm_basic_type {
	QM_TOTAL_QP_NUM_CAP = 0x0,
	QM_FUNC_MAX_QP_CAP,
	QM_XEQ_DEPTH_CAP,
	QM_QP_DEPTH_CAP,
	QM_EQ_IRQ_TYPE_CAP,
	QM_AEQ_IRQ_TYPE_CAP,
	QM_ABN_IRQ_TYPE_CAP,
	QM_PF2VF_IRQ_TYPE_CAP,
	QM_PF_IRQ_NUM_CAP,
	QM_VF_IRQ_NUM_CAP,
};

enum qm_cap_table_type {
	QM_CAP_VF  = 0x0,
	QM_AEQE_NUM,
	QM_SCQE_NUM,
	QM_EQ_IRQ,
	QM_AEQ_IRQ,
	QM_ABNORMAL_IRQ,
	QM_MB_IRQ,
	MAX_IRQ_NUM,
	EXT_BAR_INDEX,
};

static const struct hisi_qm_cap_query_info qm_cap_query_info[] = {
	{QM_CAP_VF, "QM_CAP_VF                   ", 0x3100, 0x0, 0x0, 0x6F01},
	{QM_AEQE_NUM, "QM_AEQE_NUM                 ", 0x3104, 0x800, 0x4000800, 0x4000800},
	{QM_SCQE_NUM, "QM_SCQE_NUM                 ",
						0x3108, 0x4000400, 0x4000400, 0x4000400},
	{QM_EQ_IRQ, "QM_EQ_IRQ                   ", 0x310c, 0x10000, 0x10000, 0x10000},
	{QM_AEQ_IRQ, "QM_AEQ_IRQ                  ", 0x3110, 0x0, 0x10001, 0x10001},
	{QM_ABNORMAL_IRQ, "QM_ABNORMAL_IRQ             ", 0x3114, 0x0, 0x10003, 0x10003},
	{QM_MB_IRQ, "QM_MB_IRQ                   ", 0x3118, 0x0, 0x0, 0x10002},
	{MAX_IRQ_NUM, "MAX_IRQ_NUM                 ", 0x311c, 0x10001, 0x40002, 0x40003},
	{EXT_BAR_INDEX, "EXT_BAR_INDEX               ", 0x3120, 0x0, 0x0, 0x14},
};

static const struct hisi_qm_cap_info qm_cap_info_comm[] = {
	{QM_SUPPORT_DB_ISOLATION, 0x30,   0, BIT(0),  0x0, 0x0, 0x0},
	{QM_SUPPORT_FUNC_QOS,     0x3100, 0, BIT(8),  0x0, 0x0, 0x1},
	{QM_SUPPORT_STOP_QP,      0x3100, 0, BIT(9),  0x0, 0x0, 0x1},
	{QM_SUPPORT_STOP_FUNC,     0x3100, 0, BIT(10), 0x0, 0x0, 0x1},
	{QM_SUPPORT_MB_COMMAND,   0x3100, 0, BIT(11), 0x0, 0x0, 0x1},
	{QM_SUPPORT_SVA_PREFETCH, 0x3100, 0, BIT(14), 0x0, 0x0, 0x1},
	{QM_SUPPORT_DAE,          0x3100, 0, BIT(15), 0x0, 0x0, 0x0},
};

static const struct hisi_qm_cap_info qm_cap_info_pf[] = {
	{QM_SUPPORT_RPM, 0x3100, 0, BIT(13), 0x0, 0x0, 0x1},
};

static const struct hisi_qm_cap_info qm_cap_info_vf[] = {
	{QM_SUPPORT_RPM, 0x3100, 0, BIT(12), 0x0, 0x0, 0x0},
};

static const struct hisi_qm_cap_info qm_basic_info[] = {
	{QM_TOTAL_QP_NUM_CAP,   0x100158, 0,  GENMASK(10, 0), 0x1000,    0x400,     0x400},
	{QM_FUNC_MAX_QP_CAP,    0x100158, 11, GENMASK(10, 0), 0x1000,    0x400,     0x400},
	{QM_XEQ_DEPTH_CAP,      0x3104,   0,  GENMASK(31, 0), 0x800,     0x4000800, 0x4000800},
	{QM_QP_DEPTH_CAP,       0x3108,   0,  GENMASK(31, 0), 0x4000400, 0x4000400, 0x4000400},
	{QM_EQ_IRQ_TYPE_CAP,    0x310c,   0,  GENMASK(31, 0), 0x10000,   0x10000,   0x10000},
	{QM_AEQ_IRQ_TYPE_CAP,   0x3110,   0,  GENMASK(31, 0), 0x0,       0x10001,   0x10001},
	{QM_ABN_IRQ_TYPE_CAP,   0x3114,   0,  GENMASK(31, 0), 0x0,       0x10003,   0x10003},
	{QM_PF2VF_IRQ_TYPE_CAP, 0x3118,   0,  GENMASK(31, 0), 0x0,       0x0,       0x10002},
	{QM_PF_IRQ_NUM_CAP,     0x311c,   16, GENMASK(15, 0), 0x1,       0x4,       0x4},
	{QM_VF_IRQ_NUM_CAP,     0x311c,   0,  GENMASK(15, 0), 0x1,       0x2,       0x3},
};

struct qm_mailbox {
	__le16 w0;
	__le16 queue_num;
	__le32 base_l;
	__le32 base_h;
	__le32 rsvd;
};

struct qm_doorbell {
	__le16 queue_num;
	__le16 cmd;
	__le16 index;
	__le16 priority;
};

struct hisi_qm_resource {
	struct hisi_qm *qm;
	int distance;
	struct list_head list;
};

/**
 * struct qm_hw_err - Structure describing the device errors
 * @list: hardware error list
 * @timestamp: timestamp when the error occurred
 */
struct qm_hw_err {
	struct list_head list;
	unsigned long long timestamp;
};

struct hisi_qm_hw_ops {
	int (*get_vft)(struct hisi_qm *qm, u32 *base, u32 *number);
	void (*qm_db)(struct hisi_qm *qm, u16 qn,
		      u8 cmd, u16 index, u8 priority);
	int (*debug_init)(struct hisi_qm *qm);
	void (*hw_error_init)(struct hisi_qm *qm);
	void (*hw_error_uninit)(struct hisi_qm *qm);
	enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm);
	int (*set_msi)(struct hisi_qm *qm, bool set);

	/* (u64)msg = (u32)data << 32 | (enum qm_ifc_cmd)cmd */
	int (*set_ifc_begin)(struct hisi_qm *qm, enum qm_ifc_cmd cmd, u32 data, u32 fun_num);
	void (*set_ifc_end)(struct hisi_qm *qm);
	int (*get_ifc)(struct hisi_qm *qm, enum qm_ifc_cmd *cmd, u32 *data, u32 fun_num);
};

struct hisi_qm_hw_error {
	u32 int_msk;
	const char *msg;
};

static const struct hisi_qm_hw_error qm_hw_error[] = {
	{ .int_msk = BIT(0), .msg = "qm_axi_rresp" },
	{ .int_msk = BIT(1), .msg = "qm_axi_bresp" },
	{ .int_msk = BIT(2), .msg = "qm_ecc_mbit" },
	{ .int_msk = BIT(3), .msg = "qm_ecc_1bit" },
	{ .int_msk = BIT(4), .msg = "qm_acc_get_task_timeout" },
	{ .int_msk = BIT(5), .msg = "qm_acc_do_task_timeout" },
	{ .int_msk = BIT(6), .msg = "qm_acc_wb_not_ready_timeout" },
	{ .int_msk = BIT(7), .msg = "qm_sq_cq_vf_invalid" },
	{ .int_msk = BIT(8), .msg = "qm_cq_vf_invalid" },
	{ .int_msk = BIT(9), .msg = "qm_sq_vf_invalid" },
	{ .int_msk = BIT(10), .msg = "qm_db_timeout" },
	{ .int_msk = BIT(11), .msg = "qm_of_fifo_of" },
	{ .int_msk = BIT(12), .msg = "qm_db_random_invalid" },
	{ .int_msk = BIT(13), .msg = "qm_mailbox_timeout" },
	{ .int_msk = BIT(14), .msg = "qm_flr_timeout" },
};

static const char * const qm_db_timeout[] = {
	"sq", "cq", "eq", "aeq",
};

static const char * const qm_fifo_overflow[] = {
	"cq", "eq", "aeq",
};

struct qm_typical_qos_table {
	u32 start;
	u32 end;
	u32 val;
};

/* the qos step is 100 */
static struct qm_typical_qos_table shaper_cir_s[] = {
	{100, 100, 4},
	{200, 200, 3},
	{300, 500, 2},
	{600, 1000, 1},
	{1100, 100000, 0},
};

static struct qm_typical_qos_table shaper_cbs_s[] = {
	{100, 200, 9},
	{300, 500, 11},
	{600, 1000, 12},
	{1100, 10000, 16},
	{10100, 25000, 17},
	{25100, 50000, 18},
	{50100, 100000, 19}
};

static void qm_irqs_unregister(struct hisi_qm *qm);
static int qm_reset_device(struct hisi_qm *qm);
int hisi_qm_q_num_set(const char *val, const struct kernel_param *kp,
		      unsigned int device)
{
	struct pci_dev *pdev;
	u32 n, q_num;
	int ret;

	if (!val)
		return -EINVAL;

	pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI, device, NULL);
	if (!pdev) {
		q_num = min_t(u32, QM_QNUM_V1, QM_QNUM_V2);
		pr_info("No device found currently, suppose queue number is %u\n",
			q_num);
	} else {
		if (pdev->revision == QM_HW_V1)
			q_num = QM_QNUM_V1;
		else
			q_num = QM_QNUM_V2;

		pci_dev_put(pdev);
	}

	ret = kstrtou32(val, 10, &n);
	if (ret || n < QM_MIN_QNUM || n > q_num)
		return -EINVAL;

	return param_set_int(val, kp);
}
EXPORT_SYMBOL_GPL(hisi_qm_q_num_set);

static u32 qm_get_hw_error_status(struct hisi_qm *qm)
{
	return readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
}

static u32 qm_get_dev_err_status(struct hisi_qm *qm)
{
	return qm->err_ini->get_dev_hw_err_status(qm);
}

/* Check if the error causes the master ooo block */
static bool qm_check_dev_error(struct hisi_qm *qm)
{
	struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(qm->pdev));
	u32 err_status;

	if (pf_qm->fun_type == QM_HW_VF)
		return false;

	err_status = qm_get_hw_error_status(pf_qm);
	if (err_status & pf_qm->err_info.qm_shutdown_mask)
		return true;

	if (pf_qm->err_ini->dev_is_abnormal)
		return pf_qm->err_ini->dev_is_abnormal(pf_qm);

	return false;
}

static int qm_wait_reset_finish(struct hisi_qm *qm)
{
	int delay = 0;

	/* All reset requests need to be queued for processing */
	while (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
		msleep(++delay);
		if (delay > QM_RESET_WAIT_TIMEOUT)
			return -EBUSY;
	}

	return 0;
}

static int qm_reset_prepare_ready(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));

	/*
	 * PF and VF on host doesnot support resetting at the
	 * same time on Kunpeng920.
	 */
	if (qm->ver < QM_HW_V3)
		return qm_wait_reset_finish(pf_qm);

	return qm_wait_reset_finish(qm);
}

static void qm_reset_bit_clear(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));

	if (qm->ver < QM_HW_V3)
		clear_bit(QM_RESETTING, &pf_qm->misc_ctl);

	clear_bit(QM_RESETTING, &qm->misc_ctl);
}

static void qm_mb_pre_init(struct qm_mailbox *mailbox, u8 cmd,
			   u64 base, u16 queue, bool op)
{
	mailbox->w0 = cpu_to_le16((cmd) |
		((op) ? 0x1 << QM_MB_OP_SHIFT : 0) |
		(0x1 << QM_MB_BUSY_SHIFT));
	mailbox->queue_num = cpu_to_le16(queue);
	mailbox->base_l = cpu_to_le32(lower_32_bits(base));
	mailbox->base_h = cpu_to_le32(upper_32_bits(base));
	mailbox->rsvd = 0;
}

/* return 0 mailbox ready, -ETIMEDOUT hardware timeout */
int hisi_qm_wait_mb_ready(struct hisi_qm *qm)
{
	u32 val;

	return readl_relaxed_poll_timeout(qm->io_base + QM_MB_CMD_SEND_BASE,
					  val, !((val >> QM_MB_BUSY_SHIFT) &
					  0x1), POLL_PERIOD, POLL_TIMEOUT);
}
EXPORT_SYMBOL_GPL(hisi_qm_wait_mb_ready);

/* 128 bit should be written to hardware at one time to trigger a mailbox */
static void qm_mb_write(struct hisi_qm *qm, const void *src)
{
	void __iomem *fun_base = qm->io_base + QM_MB_CMD_SEND_BASE;

#if IS_ENABLED(CONFIG_ARM64)
	unsigned long tmp0 = 0, tmp1 = 0;
#endif

	if (!IS_ENABLED(CONFIG_ARM64)) {
		memcpy_toio(fun_base, src, 16);
		dma_wmb();
		return;
	}

#if IS_ENABLED(CONFIG_ARM64)
	asm volatile("ldp %0, %1, %3\n"
		     "stp %0, %1, %2\n"
		     "dmb oshst\n"
		     : "=&r" (tmp0),
		       "=&r" (tmp1),
		       "+Q" (*((char __iomem *)fun_base))
		     : "Q" (*((char *)src))
		     : "memory");
#endif
}

static int qm_mb_nolock(struct hisi_qm *qm, struct qm_mailbox *mailbox)
{
	int ret;
	u32 val;

	if (unlikely(hisi_qm_wait_mb_ready(qm))) {
		dev_err(&qm->pdev->dev, "QM mailbox is busy to start!\n");
		ret = -EBUSY;
		goto mb_busy;
	}

	qm_mb_write(qm, mailbox);

	if (unlikely(hisi_qm_wait_mb_ready(qm))) {
		dev_err(&qm->pdev->dev, "QM mailbox operation timeout!\n");
		ret = -ETIMEDOUT;
		goto mb_busy;
	}

	val = readl(qm->io_base + QM_MB_CMD_SEND_BASE);
	if (val & QM_MB_STATUS_MASK) {
		dev_err(&qm->pdev->dev, "QM mailbox operation failed!\n");
		ret = -EIO;
		goto mb_busy;
	}

	return 0;

mb_busy:
	atomic64_inc(&qm->debug.dfx.mb_err_cnt);
	return ret;
}

int hisi_qm_mb(struct hisi_qm *qm, u8 cmd, dma_addr_t dma_addr, u16 queue,
	       bool op)
{
	struct qm_mailbox mailbox;
	int ret;

	qm_mb_pre_init(&mailbox, cmd, dma_addr, queue, op);

	mutex_lock(&qm->mailbox_lock);
	ret = qm_mb_nolock(qm, &mailbox);
	mutex_unlock(&qm->mailbox_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_mb);

/* op 0: set xqc information to hardware, 1: get xqc information from hardware. */
int qm_set_and_get_xqc(struct hisi_qm *qm, u8 cmd, void *xqc, u32 qp_id, bool op)
{
	struct qm_mailbox mailbox;
	dma_addr_t xqc_dma;
	void *tmp_xqc;
	size_t size;
	int ret;

	switch (cmd) {
	case QM_MB_CMD_SQC:
		size = sizeof(struct qm_sqc);
		tmp_xqc = qm->xqc_buf.sqc;
		xqc_dma = qm->xqc_buf.sqc_dma;
		break;
	case QM_MB_CMD_CQC:
		size = sizeof(struct qm_cqc);
		tmp_xqc = qm->xqc_buf.cqc;
		xqc_dma = qm->xqc_buf.cqc_dma;
		break;
	case QM_MB_CMD_EQC:
		size = sizeof(struct qm_eqc);
		tmp_xqc = qm->xqc_buf.eqc;
		xqc_dma = qm->xqc_buf.eqc_dma;
		break;
	case QM_MB_CMD_AEQC:
		size = sizeof(struct qm_aeqc);
		tmp_xqc = qm->xqc_buf.aeqc;
		xqc_dma = qm->xqc_buf.aeqc_dma;
		break;
	default:
		dev_err(&qm->pdev->dev, "unknown mailbox cmd %u\n", cmd);
		return -EINVAL;
	}

	/* Setting xqc will fail if master OOO is blocked. */
	if (qm_check_dev_error(qm)) {
		dev_err(&qm->pdev->dev, "failed to send mailbox since qm is stop!\n");
		return -EIO;
	}

	mutex_lock(&qm->mailbox_lock);
	if (!op)
		memcpy(tmp_xqc, xqc, size);

	qm_mb_pre_init(&mailbox, cmd, xqc_dma, qp_id, op);
	ret = qm_mb_nolock(qm, &mailbox);
	if (!ret && op)
		memcpy(xqc, tmp_xqc, size);

	mutex_unlock(&qm->mailbox_lock);

	return ret;
}

static void qm_db_v1(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority)
{
	u64 doorbell;

	doorbell = qn | ((u64)cmd << QM_DB_CMD_SHIFT_V1) |
		   ((u64)index << QM_DB_INDEX_SHIFT_V1)  |
		   ((u64)priority << QM_DB_PRIORITY_SHIFT_V1);

	writeq(doorbell, qm->io_base + QM_DOORBELL_BASE_V1);
}

static void qm_db_v2(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority)
{
	void __iomem *io_base = qm->io_base;
	u16 randata = 0;
	u64 doorbell;

	if (cmd == QM_DOORBELL_CMD_SQ || cmd == QM_DOORBELL_CMD_CQ)
		io_base = qm->db_io_base + (u64)qn * qm->db_interval +
			  QM_DOORBELL_SQ_CQ_BASE_V2;
	else
		io_base += QM_DOORBELL_EQ_AEQ_BASE_V2;

	doorbell = qn | ((u64)cmd << QM_DB_CMD_SHIFT_V2) |
		   ((u64)randata << QM_DB_RAND_SHIFT_V2) |
		   ((u64)index << QM_DB_INDEX_SHIFT_V2) |
		   ((u64)priority << QM_DB_PRIORITY_SHIFT_V2);

	writeq(doorbell, io_base);
}

static void qm_db(struct hisi_qm *qm, u16 qn, u8 cmd, u16 index, u8 priority)
{
	dev_dbg(&qm->pdev->dev, "QM doorbell request: qn=%u, cmd=%u, index=%u\n",
		qn, cmd, index);

	qm->ops->qm_db(qm, qn, cmd, index, priority);
}

static void qm_disable_clock_gate(struct hisi_qm *qm)
{
	u32 val;

	/* if qm enables clock gating in Kunpeng930, qos will be inaccurate. */
	if (qm->ver < QM_HW_V3)
		return;

	val = readl(qm->io_base + QM_PM_CTRL);
	val |= QM_IDLE_DISABLE;
	writel(val, qm->io_base +  QM_PM_CTRL);
}

static int qm_dev_mem_reset(struct hisi_qm *qm)
{
	u32 val;

	writel(0x1, qm->io_base + QM_MEM_START_INIT);
	return readl_relaxed_poll_timeout(qm->io_base + QM_MEM_INIT_DONE, val,
					  val & BIT(0), POLL_PERIOD,
					  POLL_TIMEOUT);
}

/**
 * hisi_qm_get_hw_info() - Get device information.
 * @qm: The qm which want to get information.
 * @info_table: Array for storing device information.
 * @index: Index in info_table.
 * @is_read: Whether read from reg, 0: not support read from reg.
 *
 * This function returns device information the caller needs.
 */
u32 hisi_qm_get_hw_info(struct hisi_qm *qm,
			const struct hisi_qm_cap_info *info_table,
			u32 index, bool is_read)
{
	u32 val;

	switch (qm->ver) {
	case QM_HW_V1:
		return info_table[index].v1_val;
	case QM_HW_V2:
		return info_table[index].v2_val;
	default:
		if (!is_read)
			return info_table[index].v3_val;

		val = readl(qm->io_base + info_table[index].offset);
		return (val >> info_table[index].shift) & info_table[index].mask;
	}
}
EXPORT_SYMBOL_GPL(hisi_qm_get_hw_info);

u32 hisi_qm_get_cap_value(struct hisi_qm *qm,
			const struct hisi_qm_cap_query_info *info_table,
			u32 index, bool is_read)
{
	u32 val;

	switch (qm->ver) {
	case QM_HW_V1:
		return info_table[index].v1_val;
	case QM_HW_V2:
		return info_table[index].v2_val;
	default:
		if (!is_read)
			return info_table[index].v3_val;

		val = readl(qm->io_base + info_table[index].offset);
		return val;
	}
}
EXPORT_SYMBOL_GPL(hisi_qm_get_cap_value);

static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits,
			     u16 *high_bits, enum qm_basic_type type)
{
	u32 depth;

	depth = hisi_qm_get_hw_info(qm, qm_basic_info, type, qm->cap_ver);
	*low_bits = depth & QM_XQ_DEPTH_MASK;
	*high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK;
}

int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs,
		     u32 dev_algs_size)
{
	struct device *dev = &qm->pdev->dev;
	char *algs, *ptr;
	int i;

	if (!qm->uacce)
		return 0;

	if (dev_algs_size >= QM_DEV_ALG_MAX_LEN) {
		dev_err(dev, "algs size %u is equal or larger than %d.\n",
			dev_algs_size, QM_DEV_ALG_MAX_LEN);
		return -EINVAL;
	}

	algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL);
	if (!algs)
		return -ENOMEM;

	for (i = 0; i < dev_algs_size; i++)
		if (alg_msk & dev_algs[i].alg_msk)
			strcat(algs, dev_algs[i].alg);

	ptr = strrchr(algs, '\n');
	if (ptr)
		*ptr = '\0';

	qm->uacce->algs = algs;

	return 0;
}
EXPORT_SYMBOL_GPL(hisi_qm_set_algs);

static u32 qm_get_irq_num(struct hisi_qm *qm)
{
	if (qm->fun_type == QM_HW_PF)
		return hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF_IRQ_NUM_CAP, qm->cap_ver);

	return hisi_qm_get_hw_info(qm, qm_basic_info, QM_VF_IRQ_NUM_CAP, qm->cap_ver);
}

static int qm_pm_get_sync(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	int ret;

	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
		return 0;

	ret = pm_runtime_resume_and_get(dev);
	if (ret < 0) {
		dev_err(dev, "failed to get_sync(%d).\n", ret);
		return ret;
	}

	return 0;
}

static void qm_pm_put_sync(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;

	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
		return;

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
}

static void qm_cq_head_update(struct hisi_qp *qp)
{
	if (qp->qp_status.cq_head == qp->cq_depth - 1) {
		qp->qp_status.cqc_phase = !qp->qp_status.cqc_phase;
		qp->qp_status.cq_head = 0;
	} else {
		qp->qp_status.cq_head++;
	}
}

static void qm_poll_req_cb(struct hisi_qp *qp)
{
	struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head;
	struct hisi_qm *qm = qp->qm;

	while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) {
		dma_rmb();
		qp->req_cb(qp, qp->sqe + qm->sqe_size *
			   le16_to_cpu(cqe->sq_head));
		qm_cq_head_update(qp);
		cqe = qp->cqe + qp->qp_status.cq_head;
		qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ,
		      qp->qp_status.cq_head, 0);
		atomic_dec(&qp->qp_status.used);

		cond_resched();
	}

	/* set c_flag */
	qm_db(qm, qp->qp_id, QM_DOORBELL_CMD_CQ, qp->qp_status.cq_head, 1);
}

static void qm_work_process(struct work_struct *work)
{
	struct hisi_qm_poll_data *poll_data =
		container_of(work, struct hisi_qm_poll_data, work);
	struct hisi_qm *qm = poll_data->qm;
	u16 eqe_num = poll_data->eqe_num;
	struct hisi_qp *qp;
	int i;

	for (i = eqe_num - 1; i >= 0; i--) {
		qp = &qm->qp_array[poll_data->qp_finish_id[i]];
		if (unlikely(atomic_read(&qp->qp_status.flags) == QP_STOP))
			continue;

		if (qp->event_cb) {
			qp->event_cb(qp);
			continue;
		}

		if (likely(qp->req_cb))
			qm_poll_req_cb(qp);
	}
}

static void qm_get_complete_eqe_num(struct hisi_qm *qm)
{
	struct qm_eqe *eqe = qm->eqe + qm->status.eq_head;
	struct hisi_qm_poll_data *poll_data = NULL;
	u16 eq_depth = qm->eq_depth;
	u16 cqn, eqe_num = 0;

	if (QM_EQE_PHASE(eqe) != qm->status.eqc_phase) {
		atomic64_inc(&qm->debug.dfx.err_irq_cnt);
		qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0);
		return;
	}

	cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK;
	if (unlikely(cqn >= qm->qp_num))
		return;
	poll_data = &qm->poll_data[cqn];

	while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) {
		cqn = le32_to_cpu(eqe->dw0) & QM_EQE_CQN_MASK;
		poll_data->qp_finish_id[eqe_num] = cqn;
		eqe_num++;

		if (qm->status.eq_head == eq_depth - 1) {
			qm->status.eqc_phase = !qm->status.eqc_phase;
			eqe = qm->eqe;
			qm->status.eq_head = 0;
		} else {
			eqe++;
			qm->status.eq_head++;
		}

		if (eqe_num == (eq_depth >> 1) - 1)
			break;
	}

	poll_data->eqe_num = eqe_num;
	queue_work(qm->wq, &poll_data->work);
	qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0);
}

static irqreturn_t qm_eq_irq(int irq, void *data)
{
	struct hisi_qm *qm = data;

	/* Get qp id of completed tasks and re-enable the interrupt */
	qm_get_complete_eqe_num(qm);

	return IRQ_HANDLED;
}

static irqreturn_t qm_mb_cmd_irq(int irq, void *data)
{
	struct hisi_qm *qm = data;
	u32 val;

	val = readl(qm->io_base + QM_IFC_INT_STATUS);
	val &= QM_IFC_INT_STATUS_MASK;
	if (!val)
		return IRQ_NONE;

	if (test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl)) {
		dev_warn(&qm->pdev->dev, "Driver is down, message cannot be processed!\n");
		return IRQ_HANDLED;
	}

	schedule_work(&qm->cmd_process);

	return IRQ_HANDLED;
}

static void qm_set_qp_disable(struct hisi_qp *qp, int offset)
{
	u32 *addr;

	if (qp->is_in_kernel)
		return;

	addr = (u32 *)(qp->qdma.va + qp->qdma.size) - offset;
	*addr = 1;

	/* make sure setup is completed */
	smp_wmb();
}

static void qm_disable_qp(struct hisi_qm *qm, u32 qp_id)
{
	struct hisi_qp *qp = &qm->qp_array[qp_id];

	qm_set_qp_disable(qp, QM_RESET_STOP_TX_OFFSET);
	hisi_qm_stop_qp(qp);
	qm_set_qp_disable(qp, QM_RESET_STOP_RX_OFFSET);
}

static void qm_reset_function(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	int ret;

	if (qm_check_dev_error(qm))
		return;

	ret = qm_reset_prepare_ready(qm);
	if (ret) {
		dev_err(dev, "reset function not ready\n");
		return;
	}

	ret = hisi_qm_stop(qm, QM_DOWN);
	if (ret) {
		dev_err(dev, "failed to stop qm when reset function\n");
		goto clear_bit;
	}

	ret = hisi_qm_start(qm);
	if (ret)
		dev_err(dev, "failed to start qm when reset function\n");

clear_bit:
	qm_reset_bit_clear(qm);
}

static irqreturn_t qm_aeq_thread(int irq, void *data)
{
	struct hisi_qm *qm = data;
	struct qm_aeqe *aeqe = qm->aeqe + qm->status.aeq_head;
	u16 aeq_depth = qm->aeq_depth;
	u32 type, qp_id;

	atomic64_inc(&qm->debug.dfx.aeq_irq_cnt);

	while (QM_AEQE_PHASE(aeqe) == qm->status.aeqc_phase) {
		type = (le32_to_cpu(aeqe->dw0) >> QM_AEQE_TYPE_SHIFT) &
			QM_AEQE_TYPE_MASK;
		qp_id = le32_to_cpu(aeqe->dw0) & QM_AEQE_CQN_MASK;

		switch (type) {
		case QM_EQ_OVERFLOW:
			dev_err(&qm->pdev->dev, "eq overflow, reset function\n");
			qm_reset_function(qm);
			return IRQ_HANDLED;
		case QM_CQ_OVERFLOW:
			dev_err(&qm->pdev->dev, "cq overflow, stop qp(%u)\n",
				qp_id);
			fallthrough;
		case QM_CQE_ERROR:
			qm_disable_qp(qm, qp_id);
			break;
		default:
			dev_err(&qm->pdev->dev, "unknown error type %u\n",
				type);
			break;
		}

		if (qm->status.aeq_head == aeq_depth - 1) {
			qm->status.aeqc_phase = !qm->status.aeqc_phase;
			aeqe = qm->aeqe;
			qm->status.aeq_head = 0;
		} else {
			aeqe++;
			qm->status.aeq_head++;
		}
	}

	qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0);

	return IRQ_HANDLED;
}

static void qm_init_qp_status(struct hisi_qp *qp)
{
	struct hisi_qp_status *qp_status = &qp->qp_status;

	qp_status->sq_tail = 0;
	qp_status->cq_head = 0;
	qp_status->cqc_phase = true;
	atomic_set(&qp_status->used, 0);
}

static void qm_init_prefetch(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	u32 page_type = 0x0;

	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
		return;

	switch (PAGE_SIZE) {
	case SZ_4K:
		page_type = 0x0;
		break;
	case SZ_16K:
		page_type = 0x1;
		break;
	case SZ_64K:
		page_type = 0x2;
		break;
	default:
		dev_err(dev, "system page size is not support: %lu, default set to 4KB",
			PAGE_SIZE);
	}

	writel(page_type, qm->io_base + QM_PAGE_SIZE);
}

/*
 * acc_shaper_para_calc() Get the IR value by the qos formula, the return value
 * is the expected qos calculated.
 * the formula:
 * IR = X Mbps if ir = 1 means IR = 100 Mbps, if ir = 10000 means = 10Gbps
 *
 *		IR_b * (2 ^ IR_u) * 8000
 * IR(Mbps) = -------------------------
 *		  Tick * (2 ^ IR_s)
 */
static u32 acc_shaper_para_calc(u64 cir_b, u64 cir_u, u64 cir_s)
{
	return ((cir_b * QM_QOS_DIVISOR_CLK) * (1 << cir_u)) /
					(QM_QOS_TICK * (1 << cir_s));
}

static u32 acc_shaper_calc_cbs_s(u32 ir)
{
	int table_size = ARRAY_SIZE(shaper_cbs_s);
	int i;

	for (i = 0; i < table_size; i++) {
		if (ir >= shaper_cbs_s[i].start && ir <= shaper_cbs_s[i].end)
			return shaper_cbs_s[i].val;
	}

	return QM_SHAPER_MIN_CBS_S;
}

static u32 acc_shaper_calc_cir_s(u32 ir)
{
	int table_size = ARRAY_SIZE(shaper_cir_s);
	int i;

	for (i = 0; i < table_size; i++) {
		if (ir >= shaper_cir_s[i].start && ir <= shaper_cir_s[i].end)
			return shaper_cir_s[i].val;
	}

	return 0;
}

static int qm_get_shaper_para(u32 ir, struct qm_shaper_factor *factor)
{
	u32 cir_b, cir_u, cir_s, ir_calc;
	u32 error_rate;

	factor->cbs_s = acc_shaper_calc_cbs_s(ir);
	cir_s = acc_shaper_calc_cir_s(ir);

	for (cir_b = QM_QOS_MIN_CIR_B; cir_b <= QM_QOS_MAX_CIR_B; cir_b++) {
		for (cir_u = 0; cir_u <= QM_QOS_MAX_CIR_U; cir_u++) {
			ir_calc = acc_shaper_para_calc(cir_b, cir_u, cir_s);

			error_rate = QM_QOS_EXPAND_RATE * (u32)abs(ir_calc - ir) / ir;
			if (error_rate <= QM_QOS_MIN_ERROR_RATE) {
				factor->cir_b = cir_b;
				factor->cir_u = cir_u;
				factor->cir_s = cir_s;
				return 0;
			}
		}
	}

	return -EINVAL;
}

static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
			    u32 number, struct qm_shaper_factor *factor)
{
	u64 tmp = 0;

	if (number > 0) {
		switch (type) {
		case SQC_VFT:
			if (qm->ver == QM_HW_V1) {
				tmp = QM_SQC_VFT_BUF_SIZE	|
				      QM_SQC_VFT_SQC_SIZE	|
				      QM_SQC_VFT_INDEX_NUMBER	|
				      QM_SQC_VFT_VALID		|
				      (u64)base << QM_SQC_VFT_START_SQN_SHIFT;
			} else {
				tmp = (u64)base << QM_SQC_VFT_START_SQN_SHIFT |
				      QM_SQC_VFT_VALID |
				      (u64)(number - 1) << QM_SQC_VFT_SQN_SHIFT;
			}
			break;
		case CQC_VFT:
			if (qm->ver == QM_HW_V1) {
				tmp = QM_CQC_VFT_BUF_SIZE	|
				      QM_CQC_VFT_SQC_SIZE	|
				      QM_CQC_VFT_INDEX_NUMBER	|
				      QM_CQC_VFT_VALID;
			} else {
				tmp = QM_CQC_VFT_VALID;
			}
			break;
		case SHAPER_VFT:
			if (factor) {
				tmp = factor->cir_b |
				(factor->cir_u << QM_SHAPER_FACTOR_CIR_U_SHIFT) |
				(factor->cir_s << QM_SHAPER_FACTOR_CIR_S_SHIFT) |
				(QM_SHAPER_CBS_B << QM_SHAPER_FACTOR_CBS_B_SHIFT) |
				(factor->cbs_s << QM_SHAPER_FACTOR_CBS_S_SHIFT);
			}
			break;
		}
	}

	writel(lower_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_L);
	writel(upper_32_bits(tmp), qm->io_base + QM_VFT_CFG_DATA_H);
}

static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type,
			     u32 fun_num, u32 base, u32 number)
{
	struct qm_shaper_factor *factor = NULL;
	unsigned int val;
	int ret;

	if (type == SHAPER_VFT && test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
		factor = &qm->factor[fun_num];

	ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
					 val & BIT(0), POLL_PERIOD,
					 POLL_TIMEOUT);
	if (ret)
		return ret;

	writel(0x0, qm->io_base + QM_VFT_CFG_OP_WR);
	writel(type, qm->io_base + QM_VFT_CFG_TYPE);
	if (type == SHAPER_VFT)
		fun_num |= base << QM_SHAPER_VFT_OFFSET;

	writel(fun_num, qm->io_base + QM_VFT_CFG);

	qm_vft_data_cfg(qm, type, base, number, factor);

	writel(0x0, qm->io_base + QM_VFT_CFG_RDY);
	writel(0x1, qm->io_base + QM_VFT_CFG_OP_ENABLE);

	return readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
					  val & BIT(0), POLL_PERIOD,
					  POLL_TIMEOUT);
}

static int qm_shaper_init_vft(struct hisi_qm *qm, u32 fun_num)
{
	u32 qos = qm->factor[fun_num].func_qos;
	int ret, i;

	ret = qm_get_shaper_para(qos * QM_QOS_RATE, &qm->factor[fun_num]);
	if (ret) {
		dev_err(&qm->pdev->dev, "failed to calculate shaper parameter!\n");
		return ret;
	}
	writel(qm->type_rate, qm->io_base + QM_SHAPER_CFG);
	for (i = ALG_TYPE_0; i <= ALG_TYPE_1; i++) {
		/* The base number of queue reuse for different alg type */
		ret = qm_set_vft_common(qm, SHAPER_VFT, fun_num, i, 1);
		if (ret)
			return ret;
	}

	return 0;
}

/* The config should be conducted after qm_dev_mem_reset() */
static int qm_set_sqc_cqc_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
			      u32 number)
{
	int ret, i;

	for (i = SQC_VFT; i <= CQC_VFT; i++) {
		ret = qm_set_vft_common(qm, i, fun_num, base, number);
		if (ret)
			return ret;
	}

	/* init default shaper qos val */
	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
		ret = qm_shaper_init_vft(qm, fun_num);
		if (ret)
			goto back_sqc_cqc;
	}

	return 0;
back_sqc_cqc:
	for (i = SQC_VFT; i <= CQC_VFT; i++)
		qm_set_vft_common(qm, i, fun_num, 0, 0);

	return ret;
}

static int qm_get_vft_v2(struct hisi_qm *qm, u32 *base, u32 *number)
{
	u64 sqc_vft;
	int ret;

	ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_VFT_V2, 0, 0, 1);
	if (ret)
		return ret;

	sqc_vft = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) |
		  ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32);
	*base = QM_SQC_VFT_BASE_MASK_V2 & (sqc_vft >> QM_SQC_VFT_BASE_SHIFT_V2);
	*number = (QM_SQC_VFT_NUM_MASK_V2 &
		   (sqc_vft >> QM_SQC_VFT_NUM_SHIFT_V2)) + 1;

	return 0;
}

static void qm_hw_error_init_v1(struct hisi_qm *qm)
{
	writel(QM_ABNORMAL_INT_MASK_VALUE, qm->io_base + QM_ABNORMAL_INT_MASK);
}

static void qm_hw_error_cfg(struct hisi_qm *qm)
{
	struct hisi_qm_err_info *err_info = &qm->err_info;

	qm->error_mask = err_info->nfe | err_info->ce | err_info->fe;
	/* clear QM hw residual error source */
	writel(qm->error_mask, qm->io_base + QM_ABNORMAL_INT_SOURCE);

	/* configure error type */
	writel(err_info->ce, qm->io_base + QM_RAS_CE_ENABLE);
	writel(QM_RAS_CE_TIMES_PER_IRQ, qm->io_base + QM_RAS_CE_THRESHOLD);
	writel(err_info->nfe, qm->io_base + QM_RAS_NFE_ENABLE);
	writel(err_info->fe, qm->io_base + QM_RAS_FE_ENABLE);
}

static void qm_hw_error_init_v2(struct hisi_qm *qm)
{
	u32 irq_unmask;

	qm_hw_error_cfg(qm);

	irq_unmask = ~qm->error_mask;
	irq_unmask &= readl(qm->io_base + QM_ABNORMAL_INT_MASK);
	writel(irq_unmask, qm->io_base + QM_ABNORMAL_INT_MASK);
}

static void qm_hw_error_uninit_v2(struct hisi_qm *qm)
{
	u32 irq_mask = qm->error_mask;

	irq_mask |= readl(qm->io_base + QM_ABNORMAL_INT_MASK);
	writel(irq_mask, qm->io_base + QM_ABNORMAL_INT_MASK);
}

static void qm_hw_error_init_v3(struct hisi_qm *qm)
{
	u32 irq_unmask;

	qm_hw_error_cfg(qm);

	/* enable close master ooo when hardware error happened */
	writel(qm->err_info.qm_shutdown_mask, qm->io_base + QM_OOO_SHUTDOWN_SEL);

	irq_unmask = ~qm->error_mask;
	irq_unmask &= readl(qm->io_base + QM_ABNORMAL_INT_MASK);
	writel(irq_unmask, qm->io_base + QM_ABNORMAL_INT_MASK);
}

static void qm_hw_error_uninit_v3(struct hisi_qm *qm)
{
	u32 irq_mask = qm->error_mask;

	irq_mask |= readl(qm->io_base + QM_ABNORMAL_INT_MASK);
	writel(irq_mask, qm->io_base + QM_ABNORMAL_INT_MASK);

	/* disable close master ooo when hardware error happened */
	writel(0x0, qm->io_base + QM_OOO_SHUTDOWN_SEL);
}

static void qm_log_hw_error(struct hisi_qm *qm, u32 error_status)
{
	const struct hisi_qm_hw_error *err;
	struct device *dev = &qm->pdev->dev;
	u32 reg_val, type, vf_num, qp_id;
	int i;

	for (i = 0; i < ARRAY_SIZE(qm_hw_error); i++) {
		err = &qm_hw_error[i];
		if (!(err->int_msk & error_status))
			continue;

		dev_err(dev, "%s [error status=0x%x] found\n",
			err->msg, err->int_msk);

		if (err->int_msk & QM_DB_TIMEOUT) {
			reg_val = readl(qm->io_base + QM_ABNORMAL_INF01);
			type = (reg_val & QM_DB_TIMEOUT_TYPE) >>
			       QM_DB_TIMEOUT_TYPE_SHIFT;
			vf_num = reg_val & QM_DB_TIMEOUT_VF;
			qp_id = reg_val >> QM_DB_TIMEOUT_QP_SHIFT;
			dev_err(dev, "qm %s doorbell timeout in function %u qp %u\n",
				qm_db_timeout[type], vf_num, qp_id);
		} else if (err->int_msk & QM_OF_FIFO_OF) {
			reg_val = readl(qm->io_base + QM_ABNORMAL_INF00);
			type = (reg_val & QM_FIFO_OVERFLOW_TYPE) >>
			       QM_FIFO_OVERFLOW_TYPE_SHIFT;
			vf_num = reg_val & QM_FIFO_OVERFLOW_VF;
			qp_id = reg_val >> QM_FIFO_OVERFLOW_QP_SHIFT;
			if (type < ARRAY_SIZE(qm_fifo_overflow))
				dev_err(dev, "qm %s fifo overflow in function %u qp %u\n",
					qm_fifo_overflow[type], vf_num, qp_id);
			else
				dev_err(dev, "unknown error type\n");
		} else if (err->int_msk & QM_AXI_RRESP_ERR) {
			reg_val = readl(qm->io_base + QM_ABNORMAL_INF02);
			if (reg_val & QM_AXI_POISON_ERR)
				dev_err(dev, "qm axi poison error happened\n");
		}
	}
}

static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
{
	u32 error_status;

	error_status = qm_get_hw_error_status(qm);
	if (error_status & qm->error_mask) {
		if (error_status & QM_ECC_MBIT)
			qm->err_status.is_qm_ecc_mbit = true;

		qm_log_hw_error(qm, error_status);
		if (error_status & qm->err_info.qm_reset_mask) {
			/* Disable the same error reporting until device is recovered. */
			writel(qm->err_info.nfe & (~error_status),
			       qm->io_base + QM_RAS_NFE_ENABLE);
			return ACC_ERR_NEED_RESET;
		}

		/* Clear error source if not need reset. */
		writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
		writel(qm->err_info.nfe, qm->io_base + QM_RAS_NFE_ENABLE);
		writel(qm->err_info.ce, qm->io_base + QM_RAS_CE_ENABLE);
	}

	return ACC_ERR_RECOVERED;
}

static int qm_get_mb_cmd(struct hisi_qm *qm, u64 *msg, u16 fun_num)
{
	struct qm_mailbox mailbox;
	int ret;

	qm_mb_pre_init(&mailbox, QM_MB_CMD_DST, 0, fun_num, 0);
	mutex_lock(&qm->mailbox_lock);
	ret = qm_mb_nolock(qm, &mailbox);
	if (ret)
		goto err_unlock;

	*msg = readl(qm->io_base + QM_MB_CMD_DATA_ADDR_L) |
		  ((u64)readl(qm->io_base + QM_MB_CMD_DATA_ADDR_H) << 32);

err_unlock:
	mutex_unlock(&qm->mailbox_lock);
	return ret;
}

static void qm_clear_cmd_interrupt(struct hisi_qm *qm, u64 vf_mask)
{
	u32 val;

	if (qm->fun_type == QM_HW_PF)
		writeq(vf_mask, qm->io_base + QM_IFC_INT_SOURCE_P);

	val = readl(qm->io_base + QM_IFC_INT_SOURCE_V);
	val |= QM_IFC_INT_SOURCE_MASK;
	writel(val, qm->io_base + QM_IFC_INT_SOURCE_V);
}

static void qm_handle_vf_msg(struct hisi_qm *qm, u32 vf_id)
{
	struct device *dev = &qm->pdev->dev;
	enum qm_ifc_cmd cmd;
	int ret;

	ret = qm->ops->get_ifc(qm, &cmd, NULL, vf_id);
	if (ret) {
		dev_err(dev, "failed to get command from VF(%u)!\n", vf_id);
		return;
	}

	switch (cmd) {
	case QM_VF_PREPARE_FAIL:
		dev_err(dev, "failed to stop VF(%u)!\n", vf_id);
		break;
	case QM_VF_START_FAIL:
		dev_err(dev, "failed to start VF(%u)!\n", vf_id);
		break;
	case QM_VF_PREPARE_DONE:
	case QM_VF_START_DONE:
		break;
	default:
		dev_err(dev, "unsupported command(0x%x) sent by VF(%u)!\n", cmd, vf_id);
		break;
	}
}

static int qm_wait_vf_prepare_finish(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	u32 vfs_num = qm->vfs_num;
	int cnt = 0;
	int ret = 0;
	u64 val;
	u32 i;

	if (!qm->vfs_num || !test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
		return 0;

	while (true) {
		val = readq(qm->io_base + QM_IFC_INT_SOURCE_P);
		/* All VFs send command to PF, break */
		if ((val & GENMASK(vfs_num, 1)) == GENMASK(vfs_num, 1))
			break;

		if (++cnt > QM_MAX_PF_WAIT_COUNT) {
			ret = -EBUSY;
			break;
		}

		msleep(QM_WAIT_DST_ACK);
	}

	/* PF check VFs msg */
	for (i = 1; i <= vfs_num; i++) {
		if (val & BIT(i))
			qm_handle_vf_msg(qm, i);
		else
			dev_err(dev, "VF(%u) not ping PF!\n", i);
	}

	/* PF clear interrupt to ack VFs */
	qm_clear_cmd_interrupt(qm, val);

	return ret;
}

static void qm_trigger_vf_interrupt(struct hisi_qm *qm, u32 fun_num)
{
	u32 val;

	val = readl(qm->io_base + QM_IFC_INT_CFG);
	val &= ~QM_IFC_SEND_ALL_VFS;
	val |= fun_num;
	writel(val, qm->io_base + QM_IFC_INT_CFG);

	val = readl(qm->io_base + QM_IFC_INT_SET_P);
	val |= QM_IFC_INT_SET_MASK;
	writel(val, qm->io_base + QM_IFC_INT_SET_P);
}

static void qm_trigger_pf_interrupt(struct hisi_qm *qm)
{
	u32 val;

	val = readl(qm->io_base + QM_IFC_INT_SET_V);
	val |= QM_IFC_INT_SET_MASK;
	writel(val, qm->io_base + QM_IFC_INT_SET_V);
}

static int qm_ping_single_vf(struct hisi_qm *qm, enum qm_ifc_cmd cmd, u32 data, u32 fun_num)
{
	struct device *dev = &qm->pdev->dev;
	int cnt = 0;
	u64 val;
	int ret;

	ret = qm->ops->set_ifc_begin(qm, cmd, data, fun_num);
	if (ret) {
		dev_err(dev, "failed to send command to vf(%u)!\n", fun_num);
		goto err_unlock;
	}

	qm_trigger_vf_interrupt(qm, fun_num);
	while (true) {
		msleep(QM_WAIT_DST_ACK);
		val = readq(qm->io_base + QM_IFC_READY_STATUS);
		/* if VF respond, PF notifies VF successfully. */
		if (!(val & BIT(fun_num)))
			goto err_unlock;

		if (++cnt > QM_MAX_PF_WAIT_COUNT) {
			dev_err(dev, "failed to get response from VF(%u)!\n", fun_num);
			ret = -ETIMEDOUT;
			break;
		}
	}

err_unlock:
	qm->ops->set_ifc_end(qm);
	return ret;
}

static int qm_ping_all_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd)
{
	struct device *dev = &qm->pdev->dev;
	u32 vfs_num = qm->vfs_num;
	u64 val = 0;
	int cnt = 0;
	int ret;
	u32 i;

	ret = qm->ops->set_ifc_begin(qm, cmd, 0, QM_MB_PING_ALL_VFS);
	if (ret) {
		dev_err(dev, "failed to send command(0x%x) to all vfs!\n", cmd);
		qm->ops->set_ifc_end(qm);
		return ret;
	}

	qm_trigger_vf_interrupt(qm, QM_IFC_SEND_ALL_VFS);
	while (true) {
		msleep(QM_WAIT_DST_ACK);
		val = readq(qm->io_base + QM_IFC_READY_STATUS);
		/* If all VFs acked, PF notifies VFs successfully. */
		if (!(val & GENMASK(vfs_num, 1))) {
			qm->ops->set_ifc_end(qm);
			return 0;
		}

		if (++cnt > QM_MAX_PF_WAIT_COUNT)
			break;
	}

	qm->ops->set_ifc_end(qm);

	/* Check which vf respond timeout. */
	for (i = 1; i <= vfs_num; i++) {
		if (val & BIT(i))
			dev_err(dev, "failed to get response from VF(%u)!\n", i);
	}

	return -ETIMEDOUT;
}

static int qm_ping_pf(struct hisi_qm *qm, enum qm_ifc_cmd cmd)
{
	int cnt = 0;
	u32 val;
	int ret;

	ret = qm->ops->set_ifc_begin(qm, cmd, 0, 0);
	if (ret) {
		dev_err(&qm->pdev->dev, "failed to send command(0x%x) to PF!\n", cmd);
		goto unlock;
	}

	qm_trigger_pf_interrupt(qm);
	/* Waiting for PF response */
	while (true) {
		msleep(QM_WAIT_DST_ACK);
		val = readl(qm->io_base + QM_IFC_INT_SET_V);
		if (!(val & QM_IFC_INT_STATUS_MASK))
			break;

		if (++cnt > QM_MAX_VF_WAIT_COUNT) {
			ret = -ETIMEDOUT;
			break;
		}
	}

unlock:
	qm->ops->set_ifc_end(qm);

	return ret;
}

static int qm_drain_qm(struct hisi_qm *qm)
{
	return hisi_qm_mb(qm, QM_MB_CMD_FLUSH_QM, 0, 0, 0);
}

static int qm_stop_qp(struct hisi_qp *qp)
{
	return hisi_qm_mb(qp->qm, QM_MB_CMD_STOP_QP, 0, qp->qp_id, 0);
}

static int qm_set_msi(struct hisi_qm *qm, bool set)
{
	struct pci_dev *pdev = qm->pdev;

	if (set) {
		pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_MASK_64,
				       0);
	} else {
		pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_MASK_64,
				       ACC_PEH_MSI_DISABLE);
		if (qm->err_status.is_qm_ecc_mbit ||
		    qm->err_status.is_dev_ecc_mbit)
			return 0;

		mdelay(1);
		if (readl(qm->io_base + QM_PEH_DFX_INFO0))
			return -EFAULT;
	}

	return 0;
}

static void qm_wait_msi_finish(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 cmd = ~0;
	int cnt = 0;
	u32 val;
	int ret;

	while (true) {
		pci_read_config_dword(pdev, pdev->msi_cap +
				      PCI_MSI_PENDING_64, &cmd);
		if (!cmd)
			break;

		if (++cnt > MAX_WAIT_COUNTS) {
			pci_warn(pdev, "failed to empty MSI PENDING!\n");
			break;
		}

		udelay(1);
	}

	ret = readl_relaxed_poll_timeout(qm->io_base + QM_PEH_DFX_INFO0,
					 val, !(val & QM_PEH_DFX_MASK),
					 POLL_PERIOD, POLL_TIMEOUT);
	if (ret)
		pci_warn(pdev, "failed to empty PEH MSI!\n");

	ret = readl_relaxed_poll_timeout(qm->io_base + QM_PEH_DFX_INFO1,
					 val, !(val & QM_PEH_MSI_FINISH_MASK),
					 POLL_PERIOD, POLL_TIMEOUT);
	if (ret)
		pci_warn(pdev, "failed to finish MSI operation!\n");
}

static int qm_set_msi_v3(struct hisi_qm *qm, bool set)
{
	struct pci_dev *pdev = qm->pdev;
	int ret = -ETIMEDOUT;
	u32 cmd, i;

	pci_read_config_dword(pdev, pdev->msi_cap, &cmd);
	if (set)
		cmd |= QM_MSI_CAP_ENABLE;
	else
		cmd &= ~QM_MSI_CAP_ENABLE;

	pci_write_config_dword(pdev, pdev->msi_cap, cmd);
	if (set) {
		for (i = 0; i < MAX_WAIT_COUNTS; i++) {
			pci_read_config_dword(pdev, pdev->msi_cap, &cmd);
			if (cmd & QM_MSI_CAP_ENABLE)
				return 0;

			udelay(1);
		}
	} else {
		udelay(WAIT_PERIOD_US_MIN);
		qm_wait_msi_finish(qm);
		ret = 0;
	}

	return ret;
}

static int qm_set_ifc_begin_v3(struct hisi_qm *qm, enum qm_ifc_cmd cmd, u32 data, u32 fun_num)
{
	struct qm_mailbox mailbox;
	u64 msg;

	msg = cmd | (u64)data << QM_IFC_DATA_SHIFT;

	qm_mb_pre_init(&mailbox, QM_MB_CMD_SRC, msg, fun_num, 0);
	mutex_lock(&qm->mailbox_lock);
	return qm_mb_nolock(qm, &mailbox);
}

static void qm_set_ifc_end_v3(struct hisi_qm *qm)
{
	mutex_unlock(&qm->mailbox_lock);
}

static int qm_get_ifc_v3(struct hisi_qm *qm, enum qm_ifc_cmd *cmd, u32 *data, u32 fun_num)
{
	u64 msg;
	int ret;

	ret = qm_get_mb_cmd(qm, &msg, fun_num);
	if (ret)
		return ret;

	*cmd = msg & QM_IFC_CMD_MASK;

	if (data)
		*data = msg >> QM_IFC_DATA_SHIFT;

	return 0;
}

static int qm_set_ifc_begin_v4(struct hisi_qm *qm, enum qm_ifc_cmd cmd, u32 data, u32 fun_num)
{
	uintptr_t offset;
	u64 msg;

	if (qm->fun_type == QM_HW_PF)
		offset = QM_PF2VF_PF_W;
	else
		offset = QM_VF2PF_VF_W;

	msg = cmd | (u64)data << QM_IFC_DATA_SHIFT;

	mutex_lock(&qm->ifc_lock);
	writeq(msg, qm->io_base + offset);

	return 0;
}

static void qm_set_ifc_end_v4(struct hisi_qm *qm)
{
	mutex_unlock(&qm->ifc_lock);
}

static u64 qm_get_ifc_pf(struct hisi_qm *qm, u32 fun_num)
{
	uintptr_t offset;

	offset = QM_VF2PF_PF_R + QM_VF2PF_REG_SIZE * fun_num;

	return (u64)readl(qm->io_base + offset);
}

static u64 qm_get_ifc_vf(struct hisi_qm *qm)
{
	return readq(qm->io_base + QM_PF2VF_VF_R);
}

static int qm_get_ifc_v4(struct hisi_qm *qm, enum qm_ifc_cmd *cmd, u32 *data, u32 fun_num)
{
	u64 msg;

	if (qm->fun_type == QM_HW_PF)
		msg = qm_get_ifc_pf(qm, fun_num);
	else
		msg = qm_get_ifc_vf(qm);

	*cmd = msg & QM_IFC_CMD_MASK;

	if (data)
		*data = msg >> QM_IFC_DATA_SHIFT;

	return 0;
}

static const struct hisi_qm_hw_ops qm_hw_ops_v1 = {
	.qm_db = qm_db_v1,
	.hw_error_init = qm_hw_error_init_v1,
	.set_msi = qm_set_msi,
};

static const struct hisi_qm_hw_ops qm_hw_ops_v2 = {
	.get_vft = qm_get_vft_v2,
	.qm_db = qm_db_v2,
	.hw_error_init = qm_hw_error_init_v2,
	.hw_error_uninit = qm_hw_error_uninit_v2,
	.hw_error_handle = qm_hw_error_handle_v2,
	.set_msi = qm_set_msi,
};

static const struct hisi_qm_hw_ops qm_hw_ops_v3 = {
	.get_vft = qm_get_vft_v2,
	.qm_db = qm_db_v2,
	.hw_error_init = qm_hw_error_init_v3,
	.hw_error_uninit = qm_hw_error_uninit_v3,
	.hw_error_handle = qm_hw_error_handle_v2,
	.set_msi = qm_set_msi_v3,
	.set_ifc_begin = qm_set_ifc_begin_v3,
	.set_ifc_end = qm_set_ifc_end_v3,
	.get_ifc = qm_get_ifc_v3,
};

static const struct hisi_qm_hw_ops qm_hw_ops_v4 = {
	.get_vft = qm_get_vft_v2,
	.qm_db = qm_db_v2,
	.hw_error_init = qm_hw_error_init_v3,
	.hw_error_uninit = qm_hw_error_uninit_v3,
	.hw_error_handle = qm_hw_error_handle_v2,
	.set_msi = qm_set_msi_v3,
	.set_ifc_begin = qm_set_ifc_begin_v4,
	.set_ifc_end = qm_set_ifc_end_v4,
	.get_ifc = qm_get_ifc_v4,
};

static void *qm_get_avail_sqe(struct hisi_qp *qp)
{
	struct hisi_qp_status *qp_status = &qp->qp_status;
	u16 sq_tail = qp_status->sq_tail;

	if (unlikely(atomic_read(&qp->qp_status.used) == qp->sq_depth - 1))
		return NULL;

	return qp->sqe + sq_tail * qp->qm->sqe_size;
}

static void hisi_qm_unset_hw_reset(struct hisi_qp *qp)
{
	u64 *addr;

	/* Use last 64 bits of DUS to reset status. */
	addr = (u64 *)(qp->qdma.va + qp->qdma.size) - QM_RESET_STOP_TX_OFFSET;
	*addr = 0;
}

static struct hisi_qp *qm_create_qp_nolock(struct hisi_qm *qm, u8 alg_type)
{
	struct device *dev = &qm->pdev->dev;
	struct hisi_qp *qp;
	int qp_id;

	if (atomic_read(&qm->status.flags) == QM_STOP) {
		dev_info_ratelimited(dev, "failed to create qp as qm is stop!\n");
		return ERR_PTR(-EPERM);
	}

	if (qm->qp_in_used == qm->qp_num) {
		dev_info_ratelimited(dev, "All %u queues of QM are busy!\n",
				     qm->qp_num);
		atomic64_inc(&qm->debug.dfx.create_qp_err_cnt);
		return ERR_PTR(-EBUSY);
	}

	qp_id = idr_alloc_cyclic(&qm->qp_idr, NULL, 0, qm->qp_num, GFP_ATOMIC);
	if (qp_id < 0) {
		dev_info_ratelimited(dev, "All %u queues of QM are busy!\n",
				    qm->qp_num);
		atomic64_inc(&qm->debug.dfx.create_qp_err_cnt);
		return ERR_PTR(-EBUSY);
	}

	qp = &qm->qp_array[qp_id];
	hisi_qm_unset_hw_reset(qp);
	memset(qp->cqe, 0, sizeof(struct qm_cqe) * qp->cq_depth);

	qp->event_cb = NULL;
	qp->req_cb = NULL;
	qp->qp_id = qp_id;
	qp->alg_type = alg_type;
	qp->is_in_kernel = true;
	qm->qp_in_used++;

	return qp;
}

/**
 * hisi_qm_create_qp() - Create a queue pair from qm.
 * @qm: The qm we create a qp from.
 * @alg_type: Accelerator specific algorithm type in sqc.
 *
 * Return created qp, negative error code if failed.
 */
static struct hisi_qp *hisi_qm_create_qp(struct hisi_qm *qm, u8 alg_type)
{
	struct hisi_qp *qp;
	int ret;

	ret = qm_pm_get_sync(qm);
	if (ret)
		return ERR_PTR(ret);

	down_write(&qm->qps_lock);
	qp = qm_create_qp_nolock(qm, alg_type);
	up_write(&qm->qps_lock);

	if (IS_ERR(qp))
		qm_pm_put_sync(qm);

	return qp;
}

/**
 * hisi_qm_release_qp() - Release a qp back to its qm.
 * @qp: The qp we want to release.
 *
 * This function releases the resource of a qp.
 */
static void hisi_qm_release_qp(struct hisi_qp *qp)
{
	struct hisi_qm *qm = qp->qm;

	down_write(&qm->qps_lock);

	qm->qp_in_used--;
	idr_remove(&qm->qp_idr, qp->qp_id);

	up_write(&qm->qps_lock);

	qm_pm_put_sync(qm);
}

static int qm_sq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
{
	struct hisi_qm *qm = qp->qm;
	enum qm_hw_ver ver = qm->ver;
	struct qm_sqc sqc = {0};

	if (ver == QM_HW_V1) {
		sqc.dw3 = cpu_to_le32(QM_MK_SQC_DW3_V1(0, 0, 0, qm->sqe_size));
		sqc.w8 = cpu_to_le16(qp->sq_depth - 1);
	} else {
		sqc.dw3 = cpu_to_le32(QM_MK_SQC_DW3_V2(qm->sqe_size, qp->sq_depth));
		sqc.w8 = 0; /* rand_qc */
	}
	sqc.w13 = cpu_to_le16(QM_MK_SQC_W13(0, 1, qp->alg_type));
	sqc.base_l = cpu_to_le32(lower_32_bits(qp->sqe_dma));
	sqc.base_h = cpu_to_le32(upper_32_bits(qp->sqe_dma));
	sqc.cq_num = cpu_to_le16(qp_id);
	sqc.pasid = cpu_to_le16(pasid);

	if (ver >= QM_HW_V3 && qm->use_sva && !qp->is_in_kernel)
		sqc.w11 = cpu_to_le16(QM_QC_PASID_ENABLE <<
				      QM_QC_PASID_ENABLE_SHIFT);

	return qm_set_and_get_xqc(qm, QM_MB_CMD_SQC, &sqc, qp_id, 0);
}

static int qm_cq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
{
	struct hisi_qm *qm = qp->qm;
	enum qm_hw_ver ver = qm->ver;
	struct qm_cqc cqc = {0};

	if (ver == QM_HW_V1) {
		cqc.dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0, QM_QC_CQE_SIZE));
		cqc.w8 = cpu_to_le16(qp->cq_depth - 1);
	} else {
		cqc.dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(QM_QC_CQE_SIZE, qp->cq_depth));
		cqc.w8 = 0; /* rand_qc */
	}
	/*
	 * Enable request finishing interrupts defaultly.
	 * So, there will be some interrupts until disabling
	 * this.
	 */
	cqc.dw6 = cpu_to_le32(1 << QM_CQ_PHASE_SHIFT | 1 << QM_CQ_FLAG_SHIFT);
	cqc.base_l = cpu_to_le32(lower_32_bits(qp->cqe_dma));
	cqc.base_h = cpu_to_le32(upper_32_bits(qp->cqe_dma));
	cqc.pasid = cpu_to_le16(pasid);

	if (ver >= QM_HW_V3 && qm->use_sva && !qp->is_in_kernel)
		cqc.w11 = cpu_to_le16(QM_QC_PASID_ENABLE);

	return qm_set_and_get_xqc(qm, QM_MB_CMD_CQC, &cqc, qp_id, 0);
}

static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
{
	int ret;

	qm_init_qp_status(qp);

	ret = qm_sq_ctx_cfg(qp, qp_id, pasid);
	if (ret)
		return ret;

	return qm_cq_ctx_cfg(qp, qp_id, pasid);
}

static int qm_start_qp_nolock(struct hisi_qp *qp, unsigned long arg)
{
	struct hisi_qm *qm = qp->qm;
	struct device *dev = &qm->pdev->dev;
	int qp_id = qp->qp_id;
	u32 pasid = arg;
	int ret;

	if (atomic_read(&qm->status.flags) == QM_STOP) {
		dev_info_ratelimited(dev, "failed to start qp as qm is stop!\n");
		return -EPERM;
	}

	ret = qm_qp_ctx_cfg(qp, qp_id, pasid);
	if (ret)
		return ret;

	atomic_set(&qp->qp_status.flags, QP_START);
	dev_dbg(dev, "queue %d started\n", qp_id);

	return 0;
}

/**
 * hisi_qm_start_qp() - Start a qp into running.
 * @qp: The qp we want to start to run.
 * @arg: Accelerator specific argument.
 *
 * After this function, qp can receive request from user. Return 0 if
 * successful, negative error code if failed.
 */
int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
{
	struct hisi_qm *qm = qp->qm;
	int ret;

	down_write(&qm->qps_lock);
	ret = qm_start_qp_nolock(qp, arg);
	up_write(&qm->qps_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_start_qp);

/**
 * qp_stop_fail_cb() - call request cb.
 * @qp: stopped failed qp.
 *
 * Callback function should be called whether task completed or not.
 */
static void qp_stop_fail_cb(struct hisi_qp *qp)
{
	int qp_used = atomic_read(&qp->qp_status.used);
	u16 cur_tail = qp->qp_status.sq_tail;
	u16 sq_depth = qp->sq_depth;
	u16 cur_head = (cur_tail + sq_depth - qp_used) % sq_depth;
	struct hisi_qm *qm = qp->qm;
	u16 pos;
	int i;

	for (i = 0; i < qp_used; i++) {
		pos = (i + cur_head) % sq_depth;
		qp->req_cb(qp, qp->sqe + (u32)(qm->sqe_size * pos));
		atomic_dec(&qp->qp_status.used);
	}
}

static int qm_wait_qp_empty(struct hisi_qm *qm, u32 *state, u32 qp_id)
{
	struct device *dev = &qm->pdev->dev;
	struct qm_sqc sqc;
	struct qm_cqc cqc;
	int ret, i = 0;

	while (++i) {
		ret = qm_set_and_get_xqc(qm, QM_MB_CMD_SQC, &sqc, qp_id, 1);
		if (ret) {
			dev_err_ratelimited(dev, "Failed to dump sqc!\n");
			*state = QM_DUMP_SQC_FAIL;
			return ret;
		}

		ret = qm_set_and_get_xqc(qm, QM_MB_CMD_CQC, &cqc, qp_id, 1);
		if (ret) {
			dev_err_ratelimited(dev, "Failed to dump cqc!\n");
			*state = QM_DUMP_CQC_FAIL;
			return ret;
		}

		if ((sqc.tail == cqc.tail) &&
		    (QM_SQ_TAIL_IDX(sqc) == QM_CQ_TAIL_IDX(cqc)))
			break;

		if (i == MAX_WAIT_COUNTS) {
			dev_err(dev, "Fail to empty queue %u!\n", qp_id);
			*state = QM_STOP_QUEUE_FAIL;
			return -ETIMEDOUT;
		}

		usleep_range(WAIT_PERIOD_US_MIN, WAIT_PERIOD_US_MAX);
	}

	return 0;
}

/**
 * qm_drain_qp() - Drain a qp.
 * @qp: The qp we want to drain.
 *
 * If the device does not support stopping queue by sending mailbox,
 * determine whether the queue is cleared by judging the tail pointers of
 * sq and cq.
 */
static int qm_drain_qp(struct hisi_qp *qp)
{
	struct hisi_qm *qm = qp->qm;
	u32 state = 0;
	int ret;

	/* No need to judge if master OOO is blocked. */
	if (qm_check_dev_error(qm))
		return 0;

	/* HW V3 supports drain qp by device */
	if (test_bit(QM_SUPPORT_STOP_QP, &qm->caps)) {
		ret = qm_stop_qp(qp);
		if (ret) {
			dev_err(&qm->pdev->dev, "Failed to stop qp!\n");
			state = QM_STOP_QUEUE_FAIL;
			goto set_dev_state;
		}
		return ret;
	}

	ret = qm_wait_qp_empty(qm, &state, qp->qp_id);
	if (ret)
		goto set_dev_state;

	return 0;

set_dev_state:
	if (qm->debug.dev_dfx.dev_timeout)
		qm->debug.dev_dfx.dev_state = state;

	return ret;
}

static void qm_stop_qp_nolock(struct hisi_qp *qp)
{
	struct hisi_qm *qm = qp->qm;
	struct device *dev = &qm->pdev->dev;
	int ret;

	/*
	 * It is allowed to stop and release qp when reset, If the qp is
	 * stopped when reset but still want to be released then, the
	 * is_resetting flag should be set negative so that this qp will not
	 * be restarted after reset.
	 */
	if (atomic_read(&qp->qp_status.flags) != QP_START) {
		qp->is_resetting = false;
		return;
	}

	atomic_set(&qp->qp_status.flags, QP_STOP);

	/* V3 supports direct stop function when FLR prepare */
	if (qm->ver < QM_HW_V3 || qm->status.stop_reason == QM_NORMAL) {
		ret = qm_drain_qp(qp);
		if (ret)
			dev_err(dev, "Failed to drain out data for stopping qp(%u)!\n", qp->qp_id);
	}

	flush_workqueue(qm->wq);
	if (unlikely(qp->is_resetting && atomic_read(&qp->qp_status.used)))
		qp_stop_fail_cb(qp);

	dev_dbg(dev, "stop queue %u!", qp->qp_id);
}

/**
 * hisi_qm_stop_qp() - Stop a qp in qm.
 * @qp: The qp we want to stop.
 *
 * This function is reverse of hisi_qm_start_qp.
 */
void hisi_qm_stop_qp(struct hisi_qp *qp)
{
	down_write(&qp->qm->qps_lock);
	qm_stop_qp_nolock(qp);
	up_write(&qp->qm->qps_lock);
}
EXPORT_SYMBOL_GPL(hisi_qm_stop_qp);

/**
 * hisi_qp_send() - Queue up a task in the hardware queue.
 * @qp: The qp in which to put the message.
 * @msg: The message.
 *
 * This function will return -EBUSY if qp is currently full, and -EAGAIN
 * if qp related qm is resetting.
 *
 * Note: This function may run with qm_irq_thread and ACC reset at same time.
 *       It has no race with qm_irq_thread. However, during hisi_qp_send, ACC
 *       reset may happen, we have no lock here considering performance. This
 *       causes current qm_db sending fail or can not receive sended sqe. QM
 *       sync/async receive function should handle the error sqe. ACC reset
 *       done function should clear used sqe to 0.
 */
int hisi_qp_send(struct hisi_qp *qp, const void *msg)
{
	struct hisi_qp_status *qp_status = &qp->qp_status;
	u16 sq_tail = qp_status->sq_tail;
	u16 sq_tail_next = (sq_tail + 1) % qp->sq_depth;
	void *sqe = qm_get_avail_sqe(qp);

	if (unlikely(atomic_read(&qp->qp_status.flags) == QP_STOP ||
		     atomic_read(&qp->qm->status.flags) == QM_STOP ||
		     qp->is_resetting)) {
		dev_info_ratelimited(&qp->qm->pdev->dev, "QP is stopped or resetting\n");
		return -EAGAIN;
	}

	if (!sqe)
		return -EBUSY;

	memcpy(sqe, msg, qp->qm->sqe_size);

	qm_db(qp->qm, qp->qp_id, QM_DOORBELL_CMD_SQ, sq_tail_next, 0);
	atomic_inc(&qp->qp_status.used);
	qp_status->sq_tail = sq_tail_next;

	return 0;
}
EXPORT_SYMBOL_GPL(hisi_qp_send);

static void hisi_qm_cache_wb(struct hisi_qm *qm)
{
	unsigned int val;

	if (qm->ver == QM_HW_V1)
		return;

	writel(0x1, qm->io_base + QM_CACHE_WB_START);
	if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
				       val, val & BIT(0), POLL_PERIOD,
				       POLL_TIMEOUT))
		dev_err(&qm->pdev->dev, "QM writeback sqc cache fail!\n");
}

static void qm_qp_event_notifier(struct hisi_qp *qp)
{
	wake_up_interruptible(&qp->uacce_q->wait);
}

 /* This function returns free number of qp in qm. */
static int hisi_qm_get_available_instances(struct uacce_device *uacce)
{
	struct hisi_qm *qm = uacce->priv;
	int ret;

	down_read(&qm->qps_lock);
	ret = qm->qp_num - qm->qp_in_used;
	up_read(&qm->qps_lock);

	return ret;
}

static void hisi_qm_set_hw_reset(struct hisi_qm *qm, int offset)
{
	int i;

	for (i = 0; i < qm->qp_num; i++)
		qm_set_qp_disable(&qm->qp_array[i], offset);
}

static int hisi_qm_uacce_get_queue(struct uacce_device *uacce,
				   unsigned long arg,
				   struct uacce_queue *q)
{
	struct hisi_qm *qm = uacce->priv;
	struct hisi_qp *qp;
	u8 alg_type = 0;

	qp = hisi_qm_create_qp(qm, alg_type);
	if (IS_ERR(qp))
		return PTR_ERR(qp);

	q->priv = qp;
	q->uacce = uacce;
	qp->uacce_q = q;
	qp->event_cb = qm_qp_event_notifier;
	qp->pasid = arg;
	qp->is_in_kernel = false;

	return 0;
}

static void hisi_qm_uacce_put_queue(struct uacce_queue *q)
{
	struct hisi_qp *qp = q->priv;

	hisi_qm_release_qp(qp);
}

/* map sq/cq/doorbell to user space */
static int hisi_qm_uacce_mmap(struct uacce_queue *q,
			      struct vm_area_struct *vma,
			      struct uacce_qfile_region *qfr)
{
	struct hisi_qp *qp = q->priv;
	struct hisi_qm *qm = qp->qm;
	resource_size_t phys_base = qm->db_phys_base +
				    qp->qp_id * qm->db_interval;
	size_t sz = vma->vm_end - vma->vm_start;
	struct pci_dev *pdev = qm->pdev;
	struct device *dev = &pdev->dev;
	unsigned long vm_pgoff;
	int ret;

	switch (qfr->type) {
	case UACCE_QFRT_MMIO:
		if (qm->ver == QM_HW_V1) {
			if (sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR)
				return -EINVAL;
		} else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
			if (sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
			    QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE))
				return -EINVAL;
		} else {
			if (sz > qm->db_interval)
				return -EINVAL;
		}

		vm_flags_set(vma, VM_IO);

		return remap_pfn_range(vma, vma->vm_start,
				       phys_base >> PAGE_SHIFT,
				       sz, pgprot_noncached(vma->vm_page_prot));
	case UACCE_QFRT_DUS:
		if (sz != qp->qdma.size)
			return -EINVAL;

		/*
		 * dma_mmap_coherent() requires vm_pgoff as 0
		 * restore vm_pfoff to initial value for mmap()
		 */
		vm_pgoff = vma->vm_pgoff;
		vma->vm_pgoff = 0;
		ret = dma_mmap_coherent(dev, vma, qp->qdma.va,
					qp->qdma.dma, sz);
		vma->vm_pgoff = vm_pgoff;
		return ret;

	default:
		return -EINVAL;
	}
}

static int hisi_qm_uacce_start_queue(struct uacce_queue *q)
{
	struct hisi_qp *qp = q->priv;

	return hisi_qm_start_qp(qp, qp->pasid);
}

static void hisi_qm_uacce_stop_queue(struct uacce_queue *q)
{
	struct hisi_qp *qp = q->priv;
	struct hisi_qm *qm = qp->qm;
	struct qm_dev_dfx *dev_dfx = &qm->debug.dev_dfx;
	u32 i = 0;

	hisi_qm_stop_qp(qp);

	if (!dev_dfx->dev_timeout || !dev_dfx->dev_state)
		return;

	/*
	 * After the queue fails to be stopped,
	 * wait for a period of time before releasing the queue.
	 */
	while (++i) {
		msleep(WAIT_PERIOD);

		/* Since dev_timeout maybe modified, check i >= dev_timeout */
		if (i >= dev_dfx->dev_timeout) {
			dev_err(&qm->pdev->dev, "Stop q %u timeout, state %u\n",
			       qp->qp_id, dev_dfx->dev_state);
			dev_dfx->dev_state = QM_FINISH_WAIT;
			break;
		}
	}
}

static int hisi_qm_is_q_updated(struct uacce_queue *q)
{
	struct hisi_qp *qp = q->priv;
	struct qm_cqe *cqe = qp->cqe + qp->qp_status.cq_head;
	int updated = 0;

	while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) {
		/* make sure to read data from memory */
		dma_rmb();
		qm_cq_head_update(qp);
		cqe = qp->cqe + qp->qp_status.cq_head;
		updated = 1;
	}

	return updated;
}

static void qm_set_sqctype(struct uacce_queue *q, u16 type)
{
	struct hisi_qm *qm = q->uacce->priv;
	struct hisi_qp *qp = q->priv;

	down_write(&qm->qps_lock);
	qp->alg_type = type;
	up_write(&qm->qps_lock);
}

static long hisi_qm_uacce_ioctl(struct uacce_queue *q, unsigned int cmd,
				unsigned long arg)
{
	struct hisi_qp *qp = q->priv;
	struct hisi_qp_info qp_info;
	struct hisi_qp_ctx qp_ctx;

	if (cmd == UACCE_CMD_QM_SET_QP_CTX) {
		if (copy_from_user(&qp_ctx, (void __user *)arg,
				   sizeof(struct hisi_qp_ctx)))
			return -EFAULT;

		if (qp_ctx.qc_type > QM_MAX_QC_TYPE)
			return -EINVAL;

		qm_set_sqctype(q, qp_ctx.qc_type);
		qp_ctx.id = qp->qp_id;

		if (copy_to_user((void __user *)arg, &qp_ctx,
				 sizeof(struct hisi_qp_ctx)))
			return -EFAULT;

		return 0;
	} else if (cmd == UACCE_CMD_QM_SET_QP_INFO) {
		if (copy_from_user(&qp_info, (void __user *)arg,
				   sizeof(struct hisi_qp_info)))
			return -EFAULT;

		qp_info.sqe_size = qp->qm->sqe_size;
		qp_info.sq_depth = qp->sq_depth;
		qp_info.cq_depth = qp->cq_depth;

		if (copy_to_user((void __user *)arg, &qp_info,
				  sizeof(struct hisi_qp_info)))
			return -EFAULT;

		return 0;
	}

	return -EINVAL;
}

/**
 * qm_hw_err_isolate() - Try to set the isolation status of the uacce device
 * according to user's configuration of error threshold.
 * @qm: the uacce device
 */
static int qm_hw_err_isolate(struct hisi_qm *qm)
{
	struct qm_hw_err *err, *tmp, *hw_err;
	struct qm_err_isolate *isolate;
	u32 count = 0;

	isolate = &qm->isolate_data;

#define SECONDS_PER_HOUR	3600

	/* All the hw errs are processed by PF driver */
	if (qm->uacce->is_vf || isolate->is_isolate || !isolate->err_threshold)
		return 0;

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

	/*
	 * Time-stamp every slot AER error. Then check the AER error log when the
	 * next device AER error occurred. if the device slot AER error count exceeds
	 * the setting error threshold in one hour, the isolated state will be set
	 * to true. And the AER error logs that exceed one hour will be cleared.
	 */
	mutex_lock(&isolate->isolate_lock);
	hw_err->timestamp = jiffies;
	list_for_each_entry_safe(err, tmp, &isolate->qm_hw_errs, list) {
		if ((hw_err->timestamp - err->timestamp) / HZ >
		    SECONDS_PER_HOUR) {
			list_del(&err->list);
			kfree(err);
		} else {
			count++;
		}
	}
	list_add(&hw_err->list, &isolate->qm_hw_errs);
	mutex_unlock(&isolate->isolate_lock);

	if (count >= isolate->err_threshold)
		isolate->is_isolate = true;

	return 0;
}

static void qm_hw_err_destroy(struct hisi_qm *qm)
{
	struct qm_hw_err *err, *tmp;

	mutex_lock(&qm->isolate_data.isolate_lock);
	list_for_each_entry_safe(err, tmp, &qm->isolate_data.qm_hw_errs, list) {
		list_del(&err->list);
		kfree(err);
	}
	mutex_unlock(&qm->isolate_data.isolate_lock);
}

static enum uacce_dev_state hisi_qm_get_isolate_state(struct uacce_device *uacce)
{
	struct hisi_qm *qm = uacce->priv;
	struct hisi_qm *pf_qm;

	if (uacce->is_vf)
		pf_qm = pci_get_drvdata(pci_physfn(qm->pdev));
	else
		pf_qm = qm;

	return pf_qm->isolate_data.is_isolate ?
			UACCE_DEV_ISOLATE : UACCE_DEV_NORMAL;
}

static int hisi_qm_isolate_threshold_write(struct uacce_device *uacce, u32 num)
{
	struct hisi_qm *qm = uacce->priv;

	/* Must be set by PF */
	if (uacce->is_vf)
		return -EPERM;

	if (qm->isolate_data.is_isolate)
		return -EPERM;

	qm->isolate_data.err_threshold = num;

	/* After the policy is updated, need to reset the hardware err list */
	qm_hw_err_destroy(qm);

	return 0;
}

static u32 hisi_qm_isolate_threshold_read(struct uacce_device *uacce)
{
	struct hisi_qm *qm = uacce->priv;
	struct hisi_qm *pf_qm;

	if (uacce->is_vf) {
		pf_qm = pci_get_drvdata(pci_physfn(qm->pdev));
		return pf_qm->isolate_data.err_threshold;
	}

	return qm->isolate_data.err_threshold;
}

static const struct uacce_ops uacce_qm_ops = {
	.get_available_instances = hisi_qm_get_available_instances,
	.get_queue = hisi_qm_uacce_get_queue,
	.put_queue = hisi_qm_uacce_put_queue,
	.start_queue = hisi_qm_uacce_start_queue,
	.stop_queue = hisi_qm_uacce_stop_queue,
	.mmap = hisi_qm_uacce_mmap,
	.ioctl = hisi_qm_uacce_ioctl,
	.is_q_updated = hisi_qm_is_q_updated,
	.get_isolate_state = hisi_qm_get_isolate_state,
	.isolate_err_threshold_write = hisi_qm_isolate_threshold_write,
	.isolate_err_threshold_read = hisi_qm_isolate_threshold_read,
};

static void qm_remove_uacce(struct hisi_qm *qm)
{
	struct uacce_device *uacce = qm->uacce;

	if (qm->use_sva) {
		qm_hw_err_destroy(qm);
		uacce_remove(uacce);
		qm->uacce = NULL;
	}
}

static int qm_alloc_uacce(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct uacce_device *uacce;
	unsigned long mmio_page_nr;
	unsigned long dus_page_nr;
	u16 sq_depth, cq_depth;
	struct uacce_interface interface = {
		.flags = UACCE_DEV_SVA,
		.ops = &uacce_qm_ops,
	};
	int ret;

	ret = strscpy(interface.name, dev_driver_string(&pdev->dev),
		      sizeof(interface.name));
	if (ret < 0)
		return -ENAMETOOLONG;

	uacce = uacce_alloc(&pdev->dev, &interface);
	if (IS_ERR(uacce))
		return PTR_ERR(uacce);

	if (uacce->flags & UACCE_DEV_SVA) {
		qm->use_sva = true;
	} else {
		/* only consider sva case */
		qm_remove_uacce(qm);
		return -EINVAL;
	}

	uacce->is_vf = pdev->is_virtfn;
	uacce->priv = qm;

	if (qm->ver == QM_HW_V1)
		uacce->api_ver = HISI_QM_API_VER_BASE;
	else if (qm->ver == QM_HW_V2)
		uacce->api_ver = HISI_QM_API_VER2_BASE;
	else
		uacce->api_ver = HISI_QM_API_VER3_BASE;

	if (qm->ver == QM_HW_V1)
		mmio_page_nr = QM_DOORBELL_PAGE_NR;
	else if (!test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
		mmio_page_nr = QM_DOORBELL_PAGE_NR +
			QM_DOORBELL_SQ_CQ_BASE_V2 / PAGE_SIZE;
	else
		mmio_page_nr = qm->db_interval / PAGE_SIZE;

	qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);

	/* Add one more page for device or qp status */
	dus_page_nr = (PAGE_SIZE - 1 + qm->sqe_size * sq_depth +
		       sizeof(struct qm_cqe) * cq_depth  + PAGE_SIZE) >>
					 PAGE_SHIFT;

	uacce->qf_pg_num[UACCE_QFRT_MMIO] = mmio_page_nr;
	uacce->qf_pg_num[UACCE_QFRT_DUS]  = dus_page_nr;

	qm->uacce = uacce;
	INIT_LIST_HEAD(&qm->isolate_data.qm_hw_errs);
	mutex_init(&qm->isolate_data.isolate_lock);

	return 0;
}

/**
 * qm_frozen() - Try to froze QM to cut continuous queue request. If
 * there is user on the QM, return failure without doing anything.
 * @qm: The qm needed to be fronzen.
 *
 * This function frozes QM, then we can do SRIOV disabling.
 */
static int qm_frozen(struct hisi_qm *qm)
{
	if (test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl))
		return 0;

	down_write(&qm->qps_lock);

	if (!qm->qp_in_used) {
		qm->qp_in_used = qm->qp_num;
		up_write(&qm->qps_lock);
		set_bit(QM_DRIVER_REMOVING, &qm->misc_ctl);
		return 0;
	}

	up_write(&qm->qps_lock);

	return -EBUSY;
}

static int qm_try_frozen_vfs(struct pci_dev *pdev,
			     struct hisi_qm_list *qm_list)
{
	struct hisi_qm *qm, *vf_qm;
	struct pci_dev *dev;
	int ret = 0;

	if (!qm_list || !pdev)
		return -EINVAL;

	/* Try to frozen all the VFs as disable SRIOV */
	mutex_lock(&qm_list->lock);
	list_for_each_entry(qm, &qm_list->list, list) {
		dev = qm->pdev;
		if (dev == pdev)
			continue;
		if (pci_physfn(dev) == pdev) {
			vf_qm = pci_get_drvdata(dev);
			ret = qm_frozen(vf_qm);
			if (ret)
				goto frozen_fail;
		}
	}

frozen_fail:
	mutex_unlock(&qm_list->lock);

	return ret;
}

/**
 * hisi_qm_wait_task_finish() - Wait until the task is finished
 * when removing the driver.
 * @qm: The qm needed to wait for the task to finish.
 * @qm_list: The list of all available devices.
 */
void hisi_qm_wait_task_finish(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
{
	while (qm_frozen(qm) ||
	       ((qm->fun_type == QM_HW_PF) &&
	       qm_try_frozen_vfs(qm->pdev, qm_list))) {
		msleep(WAIT_PERIOD);
	}

	while (test_bit(QM_RST_SCHED, &qm->misc_ctl) ||
	       test_bit(QM_RESETTING, &qm->misc_ctl))
		msleep(WAIT_PERIOD);

	if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
		flush_work(&qm->cmd_process);

	udelay(REMOVE_WAIT_DELAY);
}
EXPORT_SYMBOL_GPL(hisi_qm_wait_task_finish);

static void hisi_qp_memory_uninit(struct hisi_qm *qm, int num)
{
	struct device *dev = &qm->pdev->dev;
	struct qm_dma *qdma;
	int i;

	for (i = num - 1; i >= 0; i--) {
		qdma = &qm->qp_array[i].qdma;
		dma_free_coherent(dev, qdma->size, qdma->va, qdma->dma);
		kfree(qm->poll_data[i].qp_finish_id);
	}

	kfree(qm->poll_data);
	kfree(qm->qp_array);
}

static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id,
			       u16 sq_depth, u16 cq_depth)
{
	struct device *dev = &qm->pdev->dev;
	size_t off = qm->sqe_size * sq_depth;
	struct hisi_qp *qp;
	int ret = -ENOMEM;

	qm->poll_data[id].qp_finish_id = kcalloc(qm->qp_num, sizeof(u16),
						 GFP_KERNEL);
	if (!qm->poll_data[id].qp_finish_id)
		return -ENOMEM;

	qp = &qm->qp_array[id];
	qp->qdma.va = dma_alloc_coherent(dev, dma_size, &qp->qdma.dma,
					 GFP_KERNEL);
	if (!qp->qdma.va)
		goto err_free_qp_finish_id;

	qp->sqe = qp->qdma.va;
	qp->sqe_dma = qp->qdma.dma;
	qp->cqe = qp->qdma.va + off;
	qp->cqe_dma = qp->qdma.dma + off;
	qp->qdma.size = dma_size;
	qp->sq_depth = sq_depth;
	qp->cq_depth = cq_depth;
	qp->qm = qm;
	qp->qp_id = id;

	return 0;

err_free_qp_finish_id:
	kfree(qm->poll_data[id].qp_finish_id);
	return ret;
}

static void hisi_qm_pre_init(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;

	if (qm->ver == QM_HW_V1)
		qm->ops = &qm_hw_ops_v1;
	else if (qm->ver == QM_HW_V2)
		qm->ops = &qm_hw_ops_v2;
	else if (qm->ver == QM_HW_V3)
		qm->ops = &qm_hw_ops_v3;
	else
		qm->ops = &qm_hw_ops_v4;

	pci_set_drvdata(pdev, qm);
	mutex_init(&qm->mailbox_lock);
	mutex_init(&qm->ifc_lock);
	init_rwsem(&qm->qps_lock);
	qm->qp_in_used = 0;
	if (test_bit(QM_SUPPORT_RPM, &qm->caps)) {
		if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev)))
			dev_info(&pdev->dev, "_PS0 and _PR0 are not defined");
	}
}

static void qm_cmd_uninit(struct hisi_qm *qm)
{
	u32 val;

	if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
		return;

	val = readl(qm->io_base + QM_IFC_INT_MASK);
	val |= QM_IFC_INT_DISABLE;
	writel(val, qm->io_base + QM_IFC_INT_MASK);
}

static void qm_cmd_init(struct hisi_qm *qm)
{
	u32 val;

	if (!test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
		return;

	/* Clear communication interrupt source */
	qm_clear_cmd_interrupt(qm, QM_IFC_INT_SOURCE_CLR);

	/* Enable pf to vf communication reg. */
	val = readl(qm->io_base + QM_IFC_INT_MASK);
	val &= ~QM_IFC_INT_DISABLE;
	writel(val, qm->io_base + QM_IFC_INT_MASK);
}

static void qm_put_pci_res(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;

	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
		iounmap(qm->db_io_base);

	iounmap(qm->io_base);
	pci_release_mem_regions(pdev);
}

static void hisi_qm_pci_uninit(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;

	pci_free_irq_vectors(pdev);
	qm_put_pci_res(qm);
	pci_disable_device(pdev);
}

static void hisi_qm_set_state(struct hisi_qm *qm, u8 state)
{
	if (qm->ver > QM_HW_V2 && qm->fun_type == QM_HW_VF)
		writel(state, qm->io_base + QM_VF_STATE);
}

static void hisi_qm_unint_work(struct hisi_qm *qm)
{
	destroy_workqueue(qm->wq);
}

static void hisi_qm_free_rsv_buf(struct hisi_qm *qm)
{
	struct qm_dma *xqc_dma = &qm->xqc_buf.qcdma;
	struct device *dev = &qm->pdev->dev;

	dma_free_coherent(dev, xqc_dma->size, xqc_dma->va, xqc_dma->dma);
}

static void hisi_qm_memory_uninit(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;

	hisi_qp_memory_uninit(qm, qm->qp_num);
	hisi_qm_free_rsv_buf(qm);
	if (qm->qdma.va) {
		hisi_qm_cache_wb(qm);
		dma_free_coherent(dev, qm->qdma.size,
				  qm->qdma.va, qm->qdma.dma);
	}

	idr_destroy(&qm->qp_idr);

	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
		kfree(qm->factor);
}

/**
 * hisi_qm_uninit() - Uninitialize qm.
 * @qm: The qm needed uninit.
 *
 * This function uninits qm related device resources.
 */
void hisi_qm_uninit(struct hisi_qm *qm)
{
	qm_cmd_uninit(qm);
	hisi_qm_unint_work(qm);

	down_write(&qm->qps_lock);
	hisi_qm_memory_uninit(qm);
	hisi_qm_set_state(qm, QM_NOT_READY);
	up_write(&qm->qps_lock);

	qm_remove_uacce(qm);
	qm_irqs_unregister(qm);
	hisi_qm_pci_uninit(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_uninit);

/**
 * hisi_qm_get_vft() - Get vft from a qm.
 * @qm: The qm we want to get its vft.
 * @base: The base number of queue in vft.
 * @number: The number of queues in vft.
 *
 * We can allocate multiple queues to a qm by configuring virtual function
 * table. We get related configures by this function. Normally, we call this
 * function in VF driver to get the queue information.
 *
 * qm hw v1 does not support this interface.
 */
static int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number)
{
	if (!base || !number)
		return -EINVAL;

	if (!qm->ops->get_vft) {
		dev_err(&qm->pdev->dev, "Don't support vft read!\n");
		return -EINVAL;
	}

	return qm->ops->get_vft(qm, base, number);
}

/**
 * hisi_qm_set_vft() - Set vft to a qm.
 * @qm: The qm we want to set its vft.
 * @fun_num: The function number.
 * @base: The base number of queue in vft.
 * @number: The number of queues in vft.
 *
 * This function is alway called in PF driver, it is used to assign queues
 * among PF and VFs.
 *
 * Assign queues A~B to PF: hisi_qm_set_vft(qm, 0, A, B - A + 1)
 * Assign queues A~B to VF: hisi_qm_set_vft(qm, 2, A, B - A + 1)
 * (VF function number 0x2)
 */
static int hisi_qm_set_vft(struct hisi_qm *qm, u32 fun_num, u32 base,
		    u32 number)
{
	u32 max_q_num = qm->ctrl_qp_num;

	if (base >= max_q_num || number > max_q_num ||
	    (base + number) > max_q_num)
		return -EINVAL;

	return qm_set_sqc_cqc_vft(qm, fun_num, base, number);
}

static void qm_init_eq_aeq_status(struct hisi_qm *qm)
{
	struct hisi_qm_status *status = &qm->status;

	status->eq_head = 0;
	status->aeq_head = 0;
	status->eqc_phase = true;
	status->aeqc_phase = true;
}

static void qm_enable_eq_aeq_interrupts(struct hisi_qm *qm)
{
	/* Clear eq/aeq interrupt source */
	qm_db(qm, 0, QM_DOORBELL_CMD_AEQ, qm->status.aeq_head, 0);
	qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0);

	writel(0x0, qm->io_base + QM_VF_EQ_INT_MASK);
	writel(0x0, qm->io_base + QM_VF_AEQ_INT_MASK);
}

static void qm_disable_eq_aeq_interrupts(struct hisi_qm *qm)
{
	writel(0x1, qm->io_base + QM_VF_EQ_INT_MASK);
	writel(0x1, qm->io_base + QM_VF_AEQ_INT_MASK);
}

static int qm_eq_ctx_cfg(struct hisi_qm *qm)
{
	struct qm_eqc eqc = {0};

	eqc.base_l = cpu_to_le32(lower_32_bits(qm->eqe_dma));
	eqc.base_h = cpu_to_le32(upper_32_bits(qm->eqe_dma));
	if (qm->ver == QM_HW_V1)
		eqc.dw3 = cpu_to_le32(QM_EQE_AEQE_SIZE);
	eqc.dw6 = cpu_to_le32(((u32)qm->eq_depth - 1) | (1 << QM_EQC_PHASE_SHIFT));

	return qm_set_and_get_xqc(qm, QM_MB_CMD_EQC, &eqc, 0, 0);
}

static int qm_aeq_ctx_cfg(struct hisi_qm *qm)
{
	struct qm_aeqc aeqc = {0};

	aeqc.base_l = cpu_to_le32(lower_32_bits(qm->aeqe_dma));
	aeqc.base_h = cpu_to_le32(upper_32_bits(qm->aeqe_dma));
	aeqc.dw6 = cpu_to_le32(((u32)qm->aeq_depth - 1) | (1 << QM_EQC_PHASE_SHIFT));

	return qm_set_and_get_xqc(qm, QM_MB_CMD_AEQC, &aeqc, 0, 0);
}

static int qm_eq_aeq_ctx_cfg(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	int ret;

	qm_init_eq_aeq_status(qm);

	ret = qm_eq_ctx_cfg(qm);
	if (ret) {
		dev_err(dev, "Set eqc failed!\n");
		return ret;
	}

	return qm_aeq_ctx_cfg(qm);
}

static int __hisi_qm_start(struct hisi_qm *qm)
{
	int ret;

	WARN_ON(!qm->qdma.va);

	if (qm->fun_type == QM_HW_PF) {
		ret = hisi_qm_set_vft(qm, 0, qm->qp_base, qm->qp_num);
		if (ret)
			return ret;
	}

	ret = qm_eq_aeq_ctx_cfg(qm);
	if (ret)
		return ret;

	ret = hisi_qm_mb(qm, QM_MB_CMD_SQC_BT, qm->sqc_dma, 0, 0);
	if (ret)
		return ret;

	ret = hisi_qm_mb(qm, QM_MB_CMD_CQC_BT, qm->cqc_dma, 0, 0);
	if (ret)
		return ret;

	qm_init_prefetch(qm);
	qm_enable_eq_aeq_interrupts(qm);

	return 0;
}

/**
 * hisi_qm_start() - start qm
 * @qm: The qm to be started.
 *
 * This function starts a qm, then we can allocate qp from this qm.
 */
int hisi_qm_start(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	int ret = 0;

	down_write(&qm->qps_lock);

	dev_dbg(dev, "qm start with %u queue pairs\n", qm->qp_num);

	if (!qm->qp_num) {
		dev_err(dev, "qp_num should not be 0\n");
		ret = -EINVAL;
		goto err_unlock;
	}

	ret = __hisi_qm_start(qm);
	if (ret)
		goto err_unlock;

	atomic_set(&qm->status.flags, QM_WORK);
	hisi_qm_set_state(qm, QM_READY);

err_unlock:
	up_write(&qm->qps_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_start);

static int qm_restart(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	struct hisi_qp *qp;
	int ret, i;

	ret = hisi_qm_start(qm);
	if (ret < 0)
		return ret;

	down_write(&qm->qps_lock);
	for (i = 0; i < qm->qp_num; i++) {
		qp = &qm->qp_array[i];
		if (atomic_read(&qp->qp_status.flags) == QP_STOP &&
		    qp->is_resetting == true) {
			ret = qm_start_qp_nolock(qp, 0);
			if (ret < 0) {
				dev_err(dev, "Failed to start qp%d!\n", i);

				up_write(&qm->qps_lock);
				return ret;
			}
			qp->is_resetting = false;
		}
	}
	up_write(&qm->qps_lock);

	return 0;
}

/* Stop started qps in reset flow */
static void qm_stop_started_qp(struct hisi_qm *qm)
{
	struct hisi_qp *qp;
	int i;

	for (i = 0; i < qm->qp_num; i++) {
		qp = &qm->qp_array[i];
		if (atomic_read(&qp->qp_status.flags) == QP_START) {
			qp->is_resetting = true;
			qm_stop_qp_nolock(qp);
		}
	}
}

/**
 * qm_clear_queues() - Clear all queues memory in a qm.
 * @qm: The qm in which the queues will be cleared.
 *
 * This function clears all queues memory in a qm. Reset of accelerator can
 * use this to clear queues.
 */
static void qm_clear_queues(struct hisi_qm *qm)
{
	struct hisi_qp *qp;
	int i;

	for (i = 0; i < qm->qp_num; i++) {
		qp = &qm->qp_array[i];
		if (qp->is_in_kernel && qp->is_resetting)
			memset(qp->qdma.va, 0, qp->qdma.size);
	}

	memset(qm->qdma.va, 0, qm->qdma.size);
}

/**
 * hisi_qm_stop() - Stop a qm.
 * @qm: The qm which will be stopped.
 * @r: The reason to stop qm.
 *
 * This function stops qm and its qps, then qm can not accept request.
 * Related resources are not released at this state, we can use hisi_qm_start
 * to let qm start again.
 */
int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r)
{
	struct device *dev = &qm->pdev->dev;
	int ret = 0;

	down_write(&qm->qps_lock);

	if (atomic_read(&qm->status.flags) == QM_STOP)
		goto err_unlock;

	/* Stop all the request sending at first. */
	atomic_set(&qm->status.flags, QM_STOP);
	qm->status.stop_reason = r;

	if (qm->status.stop_reason != QM_NORMAL) {
		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
		/*
		 * When performing soft reset, the hardware will no longer
		 * do tasks, and the tasks in the device will be flushed
		 * out directly since the master ooo is closed.
		 */
		if (test_bit(QM_SUPPORT_STOP_FUNC, &qm->caps) &&
		    r != QM_SOFT_RESET) {
			ret = qm_drain_qm(qm);
			if (ret) {
				dev_err(dev, "failed to drain qm!\n");
				goto err_unlock;
			}
		}

		qm_stop_started_qp(qm);

		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
	}

	qm_disable_eq_aeq_interrupts(qm);
	if (qm->fun_type == QM_HW_PF) {
		ret = hisi_qm_set_vft(qm, 0, 0, 0);
		if (ret < 0) {
			dev_err(dev, "Failed to set vft!\n");
			ret = -EBUSY;
			goto err_unlock;
		}
	}

	qm_clear_queues(qm);
	qm->status.stop_reason = QM_NORMAL;

err_unlock:
	up_write(&qm->qps_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_stop);

static void qm_hw_error_init(struct hisi_qm *qm)
{
	if (!qm->ops->hw_error_init) {
		dev_err(&qm->pdev->dev, "QM doesn't support hw error handling!\n");
		return;
	}

	qm->ops->hw_error_init(qm);
}

static void qm_hw_error_uninit(struct hisi_qm *qm)
{
	if (!qm->ops->hw_error_uninit) {
		dev_err(&qm->pdev->dev, "Unexpected QM hw error uninit!\n");
		return;
	}

	qm->ops->hw_error_uninit(qm);
}

static enum acc_err_result qm_hw_error_handle(struct hisi_qm *qm)
{
	if (!qm->ops->hw_error_handle) {
		dev_err(&qm->pdev->dev, "QM doesn't support hw error report!\n");
		return ACC_ERR_NONE;
	}

	return qm->ops->hw_error_handle(qm);
}

/**
 * hisi_qm_dev_err_init() - Initialize device error configuration.
 * @qm: The qm for which we want to do error initialization.
 *
 * Initialize QM and device error related configuration.
 */
void hisi_qm_dev_err_init(struct hisi_qm *qm)
{
	if (qm->fun_type == QM_HW_VF)
		return;

	qm_hw_error_init(qm);

	if (!qm->err_ini->hw_err_enable) {
		dev_err(&qm->pdev->dev, "Device doesn't support hw error init!\n");
		return;
	}
	qm->err_ini->hw_err_enable(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_init);

/**
 * hisi_qm_dev_err_uninit() - Uninitialize device error configuration.
 * @qm: The qm for which we want to do error uninitialization.
 *
 * Uninitialize QM and device error related configuration.
 */
void hisi_qm_dev_err_uninit(struct hisi_qm *qm)
{
	if (qm->fun_type == QM_HW_VF)
		return;

	qm_hw_error_uninit(qm);

	if (!qm->err_ini->hw_err_disable) {
		dev_err(&qm->pdev->dev, "Unexpected device hw error uninit!\n");
		return;
	}
	qm->err_ini->hw_err_disable(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_uninit);

/**
 * hisi_qm_free_qps() - free multiple queue pairs.
 * @qps: The queue pairs need to be freed.
 * @qp_num: The num of queue pairs.
 */
void hisi_qm_free_qps(struct hisi_qp **qps, int qp_num)
{
	int i;

	if (!qps || qp_num <= 0)
		return;

	for (i = qp_num - 1; i >= 0; i--)
		hisi_qm_release_qp(qps[i]);
}
EXPORT_SYMBOL_GPL(hisi_qm_free_qps);

static void free_list(struct list_head *head)
{
	struct hisi_qm_resource *res, *tmp;

	list_for_each_entry_safe(res, tmp, head, list) {
		list_del(&res->list);
		kfree(res);
	}
}

static int hisi_qm_sort_devices(int node, struct list_head *head,
				struct hisi_qm_list *qm_list)
{
	struct hisi_qm_resource *res, *tmp;
	struct hisi_qm *qm;
	struct list_head *n;
	struct device *dev;
	int dev_node;

	list_for_each_entry(qm, &qm_list->list, list) {
		dev = &qm->pdev->dev;

		dev_node = dev_to_node(dev);
		if (dev_node < 0)
			dev_node = 0;

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

		res->qm = qm;
		res->distance = node_distance(dev_node, node);
		n = head;
		list_for_each_entry(tmp, head, list) {
			if (res->distance < tmp->distance) {
				n = &tmp->list;
				break;
			}
		}
		list_add_tail(&res->list, n);
	}

	return 0;
}

/**
 * hisi_qm_alloc_qps_node() - Create multiple queue pairs.
 * @qm_list: The list of all available devices.
 * @qp_num: The number of queue pairs need created.
 * @alg_type: The algorithm type.
 * @node: The numa node.
 * @qps: The queue pairs need created.
 *
 * This function will sort all available device according to numa distance.
 * Then try to create all queue pairs from one device, if all devices do
 * not meet the requirements will return error.
 */
int hisi_qm_alloc_qps_node(struct hisi_qm_list *qm_list, int qp_num,
			   u8 alg_type, int node, struct hisi_qp **qps)
{
	struct hisi_qm_resource *tmp;
	int ret = -ENODEV;
	LIST_HEAD(head);
	int i;

	if (!qps || !qm_list || qp_num <= 0)
		return -EINVAL;

	mutex_lock(&qm_list->lock);
	if (hisi_qm_sort_devices(node, &head, qm_list)) {
		mutex_unlock(&qm_list->lock);
		goto err;
	}

	list_for_each_entry(tmp, &head, list) {
		for (i = 0; i < qp_num; i++) {
			qps[i] = hisi_qm_create_qp(tmp->qm, alg_type);
			if (IS_ERR(qps[i])) {
				hisi_qm_free_qps(qps, i);
				break;
			}
		}

		if (i == qp_num) {
			ret = 0;
			break;
		}
	}

	mutex_unlock(&qm_list->lock);
	if (ret)
		pr_info("Failed to create qps, node[%d], alg[%u], qp[%d]!\n",
			node, alg_type, qp_num);

err:
	free_list(&head);
	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_alloc_qps_node);

static int qm_vf_q_assign(struct hisi_qm *qm, u32 num_vfs)
{
	u32 remain_q_num, vfs_q_num, act_q_num, q_num, i, j;
	u32 max_qp_num = qm->max_qp_num;
	u32 q_base = qm->qp_num;
	int ret;

	if (!num_vfs)
		return -EINVAL;

	vfs_q_num = qm->ctrl_qp_num - qm->qp_num;

	/* If vfs_q_num is less than num_vfs, return error. */
	if (vfs_q_num < num_vfs)
		return -EINVAL;

	q_num = vfs_q_num / num_vfs;
	remain_q_num = vfs_q_num % num_vfs;

	for (i = num_vfs; i > 0; i--) {
		/*
		 * if q_num + remain_q_num > max_qp_num in last vf, divide the
		 * remaining queues equally.
		 */
		if (i == num_vfs && q_num + remain_q_num <= max_qp_num) {
			act_q_num = q_num + remain_q_num;
			remain_q_num = 0;
		} else if (remain_q_num > 0) {
			act_q_num = q_num + 1;
			remain_q_num--;
		} else {
			act_q_num = q_num;
		}

		act_q_num = min(act_q_num, max_qp_num);
		ret = hisi_qm_set_vft(qm, i, q_base, act_q_num);
		if (ret) {
			for (j = num_vfs; j > i; j--)
				hisi_qm_set_vft(qm, j, 0, 0);
			return ret;
		}
		q_base += act_q_num;
	}

	return 0;
}

static int qm_clear_vft_config(struct hisi_qm *qm)
{
	int ret;
	u32 i;

	for (i = 1; i <= qm->vfs_num; i++) {
		ret = hisi_qm_set_vft(qm, i, 0, 0);
		if (ret)
			return ret;
	}
	qm->vfs_num = 0;

	return 0;
}

static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos)
{
	struct device *dev = &qm->pdev->dev;
	u32 ir = qos * QM_QOS_RATE;
	int ret, total_vfs, i;

	total_vfs = pci_sriov_get_totalvfs(qm->pdev);
	if (fun_index > total_vfs)
		return -EINVAL;

	qm->factor[fun_index].func_qos = qos;

	ret = qm_get_shaper_para(ir, &qm->factor[fun_index]);
	if (ret) {
		dev_err(dev, "failed to calculate shaper parameter!\n");
		return -EINVAL;
	}

	for (i = ALG_TYPE_0; i <= ALG_TYPE_1; i++) {
		/* The base number of queue reuse for different alg type */
		ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1);
		if (ret) {
			dev_err(dev, "type: %d, failed to set shaper vft!\n", i);
			return -EINVAL;
		}
	}

	return 0;
}

static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index)
{
	u64 cir_u = 0, cir_b = 0, cir_s = 0;
	u64 shaper_vft, ir_calc, ir;
	unsigned int val;
	u32 error_rate;
	int ret;

	ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
					 val & BIT(0), POLL_PERIOD,
					 POLL_TIMEOUT);
	if (ret)
		return 0;

	writel(0x1, qm->io_base + QM_VFT_CFG_OP_WR);
	writel(SHAPER_VFT, qm->io_base + QM_VFT_CFG_TYPE);
	writel(fun_index, qm->io_base + QM_VFT_CFG);

	writel(0x0, qm->io_base + QM_VFT_CFG_RDY);
	writel(0x1, qm->io_base + QM_VFT_CFG_OP_ENABLE);

	ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
					 val & BIT(0), POLL_PERIOD,
					 POLL_TIMEOUT);
	if (ret)
		return 0;

	shaper_vft = readl(qm->io_base + QM_VFT_CFG_DATA_L) |
		  ((u64)readl(qm->io_base + QM_VFT_CFG_DATA_H) << 32);

	cir_b = shaper_vft & QM_SHAPER_CIR_B_MASK;
	cir_u = shaper_vft & QM_SHAPER_CIR_U_MASK;
	cir_u = cir_u >> QM_SHAPER_FACTOR_CIR_U_SHIFT;

	cir_s = shaper_vft & QM_SHAPER_CIR_S_MASK;
	cir_s = cir_s >> QM_SHAPER_FACTOR_CIR_S_SHIFT;

	ir_calc = acc_shaper_para_calc(cir_b, cir_u, cir_s);

	ir = qm->factor[fun_index].func_qos * QM_QOS_RATE;

	error_rate = QM_QOS_EXPAND_RATE * (u32)abs(ir_calc - ir) / ir;
	if (error_rate > QM_QOS_MIN_ERROR_RATE) {
		pci_err(qm->pdev, "error_rate: %u, get function qos is error!\n", error_rate);
		return 0;
	}

	return ir;
}

static void qm_vf_get_qos(struct hisi_qm *qm, u32 fun_num)
{
	struct device *dev = &qm->pdev->dev;
	u32 qos;
	int ret;

	qos = qm_get_shaper_vft_qos(qm, fun_num);
	if (!qos) {
		dev_err(dev, "function(%u) failed to get qos by PF!\n", fun_num);
		return;
	}

	ret = qm_ping_single_vf(qm, QM_PF_SET_QOS, qos, fun_num);
	if (ret)
		dev_err(dev, "failed to send command(0x%x) to VF(%u)!\n", QM_PF_SET_QOS, fun_num);
}

static int qm_vf_read_qos(struct hisi_qm *qm)
{
	int cnt = 0;
	int ret = -EINVAL;

	/* reset mailbox qos val */
	qm->mb_qos = 0;

	/* vf ping pf to get function qos */
	ret = qm_ping_pf(qm, QM_VF_GET_QOS);
	if (ret) {
		pci_err(qm->pdev, "failed to send cmd to PF to get qos!\n");
		return ret;
	}

	while (true) {
		msleep(QM_WAIT_DST_ACK);
		if (qm->mb_qos)
			break;

		if (++cnt > QM_MAX_VF_WAIT_COUNT) {
			pci_err(qm->pdev, "PF ping VF timeout!\n");
			return  -ETIMEDOUT;
		}
	}

	return ret;
}

static ssize_t qm_algqos_read(struct file *filp, char __user *buf,
			       size_t count, loff_t *pos)
{
	struct hisi_qm *qm = filp->private_data;
	char tbuf[QM_DBG_READ_LEN];
	u32 qos_val, ir;
	int ret;

	ret = hisi_qm_get_dfx_access(qm);
	if (ret)
		return ret;

	/* Mailbox and reset cannot be operated at the same time */
	if (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
		pci_err(qm->pdev, "dev resetting, read alg qos failed!\n");
		ret = -EAGAIN;
		goto err_put_dfx_access;
	}

	if (qm->fun_type == QM_HW_PF) {
		ir = qm_get_shaper_vft_qos(qm, 0);
	} else {
		ret = qm_vf_read_qos(qm);
		if (ret)
			goto err_get_status;
		ir = qm->mb_qos;
	}

	qos_val = ir / QM_QOS_RATE;
	ret = scnprintf(tbuf, QM_DBG_READ_LEN, "%u\n", qos_val);

	ret = simple_read_from_buffer(buf, count, pos, tbuf, ret);

err_get_status:
	clear_bit(QM_RESETTING, &qm->misc_ctl);
err_put_dfx_access:
	hisi_qm_put_dfx_access(qm);
	return ret;
}

static ssize_t qm_get_qos_value(struct hisi_qm *qm, const char *buf,
			       unsigned long *val,
			       unsigned int *fun_index)
{
	const struct bus_type *bus_type = qm->pdev->dev.bus;
	char tbuf_bdf[QM_DBG_READ_LEN] = {0};
	char val_buf[QM_DBG_READ_LEN] = {0};
	struct pci_dev *pdev;
	struct device *dev;
	int ret;

	ret = sscanf(buf, "%s %s", tbuf_bdf, val_buf);
	if (ret != QM_QOS_PARAM_NUM)
		return -EINVAL;

	ret = kstrtoul(val_buf, 10, val);
	if (ret || *val == 0 || *val > QM_QOS_MAX_VAL) {
		pci_err(qm->pdev, "input qos value is error, please set 1~1000!\n");
		return -EINVAL;
	}

	dev = bus_find_device_by_name(bus_type, NULL, tbuf_bdf);
	if (!dev) {
		pci_err(qm->pdev, "input pci bdf number is error!\n");
		return -ENODEV;
	}

	pdev = container_of(dev, struct pci_dev, dev);

	*fun_index = pdev->devfn;

	return 0;
}

static ssize_t qm_algqos_write(struct file *filp, const char __user *buf,
			       size_t count, loff_t *pos)
{
	struct hisi_qm *qm = filp->private_data;
	char tbuf[QM_DBG_READ_LEN];
	unsigned int fun_index;
	unsigned long val;
	int len, ret;

	if (*pos != 0)
		return 0;

	if (count >= QM_DBG_READ_LEN)
		return -ENOSPC;

	len = simple_write_to_buffer(tbuf, QM_DBG_READ_LEN - 1, pos, buf, count);
	if (len < 0)
		return len;

	tbuf[len] = '\0';
	ret = qm_get_qos_value(qm, tbuf, &val, &fun_index);
	if (ret)
		return ret;

	/* Mailbox and reset cannot be operated at the same time */
	if (test_and_set_bit(QM_RESETTING, &qm->misc_ctl)) {
		pci_err(qm->pdev, "dev resetting, write alg qos failed!\n");
		return -EAGAIN;
	}

	ret = qm_pm_get_sync(qm);
	if (ret) {
		ret = -EINVAL;
		goto err_get_status;
	}

	ret = qm_func_shaper_enable(qm, fun_index, val);
	if (ret) {
		pci_err(qm->pdev, "failed to enable function shaper!\n");
		ret = -EINVAL;
		goto err_put_sync;
	}

	pci_info(qm->pdev, "the qos value of function%u is set to %lu.\n",
		 fun_index, val);
	ret = count;

err_put_sync:
	qm_pm_put_sync(qm);
err_get_status:
	clear_bit(QM_RESETTING, &qm->misc_ctl);
	return ret;
}

static const struct file_operations qm_algqos_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = qm_algqos_read,
	.write = qm_algqos_write,
};

/**
 * hisi_qm_set_algqos_init() - Initialize function qos debugfs files.
 * @qm: The qm for which we want to add debugfs files.
 *
 * Create function qos debugfs files, VF ping PF to get function qos.
 */
void hisi_qm_set_algqos_init(struct hisi_qm *qm)
{
	if (qm->fun_type == QM_HW_PF)
		debugfs_create_file("alg_qos", 0644, qm->debug.debug_root,
				    qm, &qm_algqos_fops);
	else if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps))
		debugfs_create_file("alg_qos", 0444, qm->debug.debug_root,
				    qm, &qm_algqos_fops);
}

static void hisi_qm_init_vf_qos(struct hisi_qm *qm, int total_func)
{
	int i;

	for (i = 1; i <= total_func; i++)
		qm->factor[i].func_qos = QM_QOS_MAX_VAL;
}

/**
 * hisi_qm_sriov_enable() - enable virtual functions
 * @pdev: the PCIe device
 * @max_vfs: the number of virtual functions to enable
 *
 * Returns the number of enabled VFs. If there are VFs enabled already or
 * max_vfs is more than the total number of device can be enabled, returns
 * failure.
 */
int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs)
{
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int pre_existing_vfs, num_vfs, total_vfs, ret;

	ret = qm_pm_get_sync(qm);
	if (ret)
		return ret;

	total_vfs = pci_sriov_get_totalvfs(pdev);
	pre_existing_vfs = pci_num_vf(pdev);
	if (pre_existing_vfs) {
		pci_err(pdev, "%d VFs already enabled. Please disable pre-enabled VFs!\n",
			pre_existing_vfs);
		goto err_put_sync;
	}

	if (max_vfs > total_vfs) {
		pci_err(pdev, "%d VFs is more than total VFs %d!\n", max_vfs, total_vfs);
		ret = -ERANGE;
		goto err_put_sync;
	}

	num_vfs = max_vfs;

	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
		hisi_qm_init_vf_qos(qm, num_vfs);

	ret = qm_vf_q_assign(qm, num_vfs);
	if (ret) {
		pci_err(pdev, "Can't assign queues for VF!\n");
		goto err_put_sync;
	}

	ret = pci_enable_sriov(pdev, num_vfs);
	if (ret) {
		pci_err(pdev, "Can't enable VF!\n");
		qm_clear_vft_config(qm);
		goto err_put_sync;
	}
	qm->vfs_num = num_vfs;

	pci_info(pdev, "VF enabled, vfs_num(=%d)!\n", num_vfs);

	return num_vfs;

err_put_sync:
	qm_pm_put_sync(qm);
	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_sriov_enable);

/**
 * hisi_qm_sriov_disable - disable virtual functions
 * @pdev: the PCI device.
 * @is_frozen: true when all the VFs are frozen.
 *
 * Return failure if there are VFs assigned already or VF is in used.
 */
int hisi_qm_sriov_disable(struct pci_dev *pdev, bool is_frozen)
{
	struct hisi_qm *qm = pci_get_drvdata(pdev);

	if (pci_vfs_assigned(pdev)) {
		pci_err(pdev, "Failed to disable VFs as VFs are assigned!\n");
		return -EPERM;
	}

	/* While VF is in used, SRIOV cannot be disabled. */
	if (!is_frozen && qm_try_frozen_vfs(pdev, qm->qm_list)) {
		pci_err(pdev, "Task is using its VF!\n");
		return -EBUSY;
	}

	pci_disable_sriov(pdev);

	qm->vfs_num = 0;
	qm_pm_put_sync(qm);

	return qm_clear_vft_config(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_sriov_disable);

/**
 * hisi_qm_sriov_configure - configure the number of VFs
 * @pdev: The PCI device
 * @num_vfs: The number of VFs need enabled
 *
 * Enable SR-IOV according to num_vfs, 0 means disable.
 */
int hisi_qm_sriov_configure(struct pci_dev *pdev, int num_vfs)
{
	if (num_vfs == 0)
		return hisi_qm_sriov_disable(pdev, false);
	else
		return hisi_qm_sriov_enable(pdev, num_vfs);
}
EXPORT_SYMBOL_GPL(hisi_qm_sriov_configure);

static enum acc_err_result qm_dev_err_handle(struct hisi_qm *qm)
{
	if (!qm->err_ini->get_err_result) {
		dev_err(&qm->pdev->dev, "Device doesn't support reset!\n");
		return ACC_ERR_NONE;
	}

	return qm->err_ini->get_err_result(qm);
}

static enum acc_err_result qm_process_dev_error(struct hisi_qm *qm)
{
	enum acc_err_result qm_ret, dev_ret;

	/* log qm error */
	qm_ret = qm_hw_error_handle(qm);

	/* log device error */
	dev_ret = qm_dev_err_handle(qm);

	return (qm_ret == ACC_ERR_NEED_RESET ||
		dev_ret == ACC_ERR_NEED_RESET) ?
		ACC_ERR_NEED_RESET : ACC_ERR_RECOVERED;
}

/**
 * hisi_qm_dev_err_detected() - Get device and qm error status then log it.
 * @pdev: The PCI device which need report error.
 * @state: The connectivity between CPU and device.
 *
 * We register this function into PCIe AER handlers, It will report device or
 * qm hardware error status when error occur.
 */
pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
					  pci_channel_state_t state)
{
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	enum acc_err_result ret;

	if (pdev->is_virtfn)
		return PCI_ERS_RESULT_NONE;

	pci_info(pdev, "PCI error detected, state(=%u)!!\n", state);
	if (state == pci_channel_io_perm_failure)
		return PCI_ERS_RESULT_DISCONNECT;

	ret = qm_process_dev_error(qm);
	if (ret == ACC_ERR_NEED_RESET)
		return PCI_ERS_RESULT_NEED_RESET;

	return PCI_ERS_RESULT_RECOVERED;
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_detected);

static int qm_check_req_recv(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;
	u32 val;

	if (qm->ver >= QM_HW_V3)
		return 0;

	writel(ACC_VENDOR_ID_VALUE, qm->io_base + QM_PEH_VENDOR_ID);
	ret = readl_relaxed_poll_timeout(qm->io_base + QM_PEH_VENDOR_ID, val,
					 (val == ACC_VENDOR_ID_VALUE),
					 POLL_PERIOD, POLL_TIMEOUT);
	if (ret) {
		dev_err(&pdev->dev, "Fails to read QM reg!\n");
		return ret;
	}

	writel(PCI_VENDOR_ID_HUAWEI, qm->io_base + QM_PEH_VENDOR_ID);
	ret = readl_relaxed_poll_timeout(qm->io_base + QM_PEH_VENDOR_ID, val,
					 (val == PCI_VENDOR_ID_HUAWEI),
					 POLL_PERIOD, POLL_TIMEOUT);
	if (ret)
		dev_err(&pdev->dev, "Fails to read QM reg in the second time!\n");

	return ret;
}

static int qm_set_pf_mse(struct hisi_qm *qm, bool set)
{
	struct pci_dev *pdev = qm->pdev;
	u16 cmd;
	int i;

	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
	if (set)
		cmd |= PCI_COMMAND_MEMORY;
	else
		cmd &= ~PCI_COMMAND_MEMORY;

	pci_write_config_word(pdev, PCI_COMMAND, cmd);
	for (i = 0; i < MAX_WAIT_COUNTS; i++) {
		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
		if (set == ((cmd & PCI_COMMAND_MEMORY) >> 1))
			return 0;

		udelay(1);
	}

	return -ETIMEDOUT;
}

static int qm_set_vf_mse(struct hisi_qm *qm, bool set)
{
	struct pci_dev *pdev = qm->pdev;
	u16 sriov_ctrl;
	int pos;
	int i;

	/*
	 * Since function qm_set_vf_mse is called only after SRIOV is enabled,
	 * pci_find_ext_capability cannot return 0, pos does not need to be
	 * checked.
	 */
	pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
	pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &sriov_ctrl);
	if (set)
		sriov_ctrl |= PCI_SRIOV_CTRL_MSE;
	else
		sriov_ctrl &= ~PCI_SRIOV_CTRL_MSE;
	pci_write_config_word(pdev, pos + PCI_SRIOV_CTRL, sriov_ctrl);

	for (i = 0; i < MAX_WAIT_COUNTS; i++) {
		pci_read_config_word(pdev, pos + PCI_SRIOV_CTRL, &sriov_ctrl);
		if (set == (sriov_ctrl & PCI_SRIOV_CTRL_MSE) >>
		    ACC_PEH_SRIOV_CTRL_VF_MSE_SHIFT)
			return 0;

		udelay(1);
	}

	return -ETIMEDOUT;
}

static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
{
	u32 nfe_enb = 0;

	/* Kunpeng930 hardware automatically close master ooo when NFE occurs */
	if (qm->ver >= QM_HW_V3)
		return;

	if (!qm->err_status.is_dev_ecc_mbit &&
	    qm->err_status.is_qm_ecc_mbit &&
	    qm->err_ini->close_axi_master_ooo) {
		qm->err_ini->close_axi_master_ooo(qm);
	} else if (qm->err_status.is_dev_ecc_mbit &&
		   !qm->err_status.is_qm_ecc_mbit &&
		   !qm->err_ini->close_axi_master_ooo) {
		nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
		writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
		       qm->io_base + QM_RAS_NFE_ENABLE);
		writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
	}
}

static int qm_vf_reset_prepare(struct hisi_qm *qm,
			       enum qm_stop_reason stop_reason)
{
	struct hisi_qm_list *qm_list = qm->qm_list;
	struct pci_dev *pdev = qm->pdev;
	struct pci_dev *virtfn;
	struct hisi_qm *vf_qm;
	int ret = 0;

	mutex_lock(&qm_list->lock);
	list_for_each_entry(vf_qm, &qm_list->list, list) {
		virtfn = vf_qm->pdev;
		if (virtfn == pdev)
			continue;

		if (pci_physfn(virtfn) == pdev) {
			/* save VFs PCIE BAR configuration */
			pci_save_state(virtfn);

			ret = hisi_qm_stop(vf_qm, stop_reason);
			if (ret)
				goto stop_fail;
		}
	}

stop_fail:
	mutex_unlock(&qm_list->lock);
	return ret;
}

static int qm_try_stop_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd,
			   enum qm_stop_reason stop_reason)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	if (!qm->vfs_num)
		return 0;

	/* Kunpeng930 supports to notify VFs to stop before PF reset */
	if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
		ret = qm_ping_all_vfs(qm, cmd);
		if (ret)
			pci_err(pdev, "failed to send command to all VFs before PF reset!\n");
	} else {
		ret = qm_vf_reset_prepare(qm, stop_reason);
		if (ret)
			pci_err(pdev, "failed to prepare reset, ret = %d.\n", ret);
	}

	return ret;
}

static int qm_controller_reset_prepare(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	if (qm->err_ini->set_priv_status) {
		ret = qm->err_ini->set_priv_status(qm);
		if (ret)
			return ret;
	}

	ret = qm_reset_prepare_ready(qm);
	if (ret) {
		pci_err(pdev, "Controller reset not ready!\n");
		return ret;
	}

	qm_dev_ecc_mbit_handle(qm);

	/* PF obtains the information of VF by querying the register. */
	qm_cmd_uninit(qm);

	/* Whether VFs stop successfully, soft reset will continue. */
	ret = qm_try_stop_vfs(qm, QM_PF_SRST_PREPARE, QM_SOFT_RESET);
	if (ret)
		pci_err(pdev, "failed to stop vfs by pf in soft reset.\n");

	ret = hisi_qm_stop(qm, QM_SOFT_RESET);
	if (ret) {
		pci_err(pdev, "Fails to stop QM!\n");
		qm_reset_bit_clear(qm);
		return ret;
	}

	if (qm->use_sva) {
		ret = qm_hw_err_isolate(qm);
		if (ret)
			pci_err(pdev, "failed to isolate hw err!\n");
	}

	ret = qm_wait_vf_prepare_finish(qm);
	if (ret)
		pci_err(pdev, "failed to stop by vfs in soft reset!\n");

	clear_bit(QM_RST_SCHED, &qm->misc_ctl);

	return 0;
}

static int qm_master_ooo_check(struct hisi_qm *qm)
{
	u32 val;
	int ret;

	/* Check the ooo register of the device before resetting the device. */
	writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
	ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
					 val, (val == ACC_MASTER_TRANS_RETURN_RW),
					 POLL_PERIOD, POLL_TIMEOUT);
	if (ret)
		pci_warn(qm->pdev, "Bus lock! Please reset system.\n");

	return ret;
}

static int qm_soft_reset_prepare(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	/* Ensure all doorbells and mailboxes received by QM */
	ret = qm_check_req_recv(qm);
	if (ret)
		return ret;

	if (qm->vfs_num) {
		ret = qm_set_vf_mse(qm, false);
		if (ret) {
			pci_err(pdev, "Fails to disable vf MSE bit.\n");
			return ret;
		}
	}

	ret = qm->ops->set_msi(qm, false);
	if (ret) {
		pci_err(pdev, "Fails to disable PEH MSI bit.\n");
		return ret;
	}

	ret = qm_master_ooo_check(qm);
	if (ret)
		return ret;

	if (qm->err_ini->close_sva_prefetch)
		qm->err_ini->close_sva_prefetch(qm);

	ret = qm_set_pf_mse(qm, false);
	if (ret)
		pci_err(pdev, "Fails to disable pf MSE bit.\n");

	return ret;
}

static int qm_reset_device(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;

	/* The reset related sub-control registers are not in PCI BAR */
	if (ACPI_HANDLE(&pdev->dev)) {
		unsigned long long value = 0;
		acpi_status s;

		s = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
					  qm->err_info.acpi_rst,
					  NULL, &value);
		if (ACPI_FAILURE(s)) {
			pci_err(pdev, "NO controller reset method!\n");
			return -EIO;
		}

		if (value) {
			pci_err(pdev, "Reset step %llu failed!\n", value);
			return -EIO;
		}

		return 0;
	}

	pci_err(pdev, "No reset method!\n");
	return -EINVAL;
}

static int qm_soft_reset(struct hisi_qm *qm)
{
	int ret;

	ret = qm_soft_reset_prepare(qm);
	if (ret)
		return ret;

	return qm_reset_device(qm);
}

static int qm_vf_reset_done(struct hisi_qm *qm)
{
	struct hisi_qm_list *qm_list = qm->qm_list;
	struct pci_dev *pdev = qm->pdev;
	struct pci_dev *virtfn;
	struct hisi_qm *vf_qm;
	int ret = 0;

	mutex_lock(&qm_list->lock);
	list_for_each_entry(vf_qm, &qm_list->list, list) {
		virtfn = vf_qm->pdev;
		if (virtfn == pdev)
			continue;

		if (pci_physfn(virtfn) == pdev) {
			/* enable VFs PCIE BAR configuration */
			pci_restore_state(virtfn);

			ret = qm_restart(vf_qm);
			if (ret)
				goto restart_fail;
		}
	}

restart_fail:
	mutex_unlock(&qm_list->lock);
	return ret;
}

static int qm_try_start_vfs(struct hisi_qm *qm, enum qm_ifc_cmd cmd)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	if (!qm->vfs_num)
		return 0;

	ret = qm_vf_q_assign(qm, qm->vfs_num);
	if (ret) {
		pci_err(pdev, "failed to assign VFs, ret = %d.\n", ret);
		return ret;
	}

	/* Kunpeng930 supports to notify VFs to start after PF reset. */
	if (test_bit(QM_SUPPORT_MB_COMMAND, &qm->caps)) {
		ret = qm_ping_all_vfs(qm, cmd);
		if (ret)
			pci_warn(pdev, "failed to send cmd to all VFs after PF reset!\n");
	} else {
		ret = qm_vf_reset_done(qm);
		if (ret)
			pci_warn(pdev, "failed to start vfs, ret = %d.\n", ret);
	}

	return ret;
}

static int qm_dev_hw_init(struct hisi_qm *qm)
{
	return qm->err_ini->hw_init(qm);
}

static void qm_restart_prepare(struct hisi_qm *qm)
{
	u32 value;

	if (qm->err_ini->open_sva_prefetch)
		qm->err_ini->open_sva_prefetch(qm);

	if (qm->ver >= QM_HW_V3)
		return;

	if (!qm->err_status.is_qm_ecc_mbit &&
	    !qm->err_status.is_dev_ecc_mbit)
		return;

	/* temporarily close the OOO port used for PEH to write out MSI */
	value = readl(qm->io_base + ACC_AM_CFG_PORT_WR_EN);
	writel(value & ~qm->err_info.msi_wr_port,
	       qm->io_base + ACC_AM_CFG_PORT_WR_EN);

	/* clear dev ecc 2bit error source if having */
	value = qm_get_dev_err_status(qm) & qm->err_info.ecc_2bits_mask;
	if (value && qm->err_ini->clear_dev_hw_err_status)
		qm->err_ini->clear_dev_hw_err_status(qm, value);

	/* clear QM ecc mbit error source */
	writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SOURCE);

	/* clear AM Reorder Buffer ecc mbit source */
	writel(ACC_ROB_ECC_ERR_MULTPL, qm->io_base + ACC_AM_ROB_ECC_INT_STS);
}

static void qm_restart_done(struct hisi_qm *qm)
{
	u32 value;

	if (qm->ver >= QM_HW_V3)
		goto clear_flags;

	if (!qm->err_status.is_qm_ecc_mbit &&
	    !qm->err_status.is_dev_ecc_mbit)
		return;

	/* open the OOO port for PEH to write out MSI */
	value = readl(qm->io_base + ACC_AM_CFG_PORT_WR_EN);
	value |= qm->err_info.msi_wr_port;
	writel(value, qm->io_base + ACC_AM_CFG_PORT_WR_EN);

clear_flags:
	qm->err_status.is_qm_ecc_mbit = false;
	qm->err_status.is_dev_ecc_mbit = false;
}

static int qm_controller_reset_done(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	ret = qm->ops->set_msi(qm, true);
	if (ret) {
		pci_err(pdev, "Fails to enable PEH MSI bit!\n");
		return ret;
	}

	ret = qm_set_pf_mse(qm, true);
	if (ret) {
		pci_err(pdev, "Fails to enable pf MSE bit!\n");
		return ret;
	}

	if (qm->vfs_num) {
		ret = qm_set_vf_mse(qm, true);
		if (ret) {
			pci_err(pdev, "Fails to enable vf MSE bit!\n");
			return ret;
		}
	}

	ret = qm_dev_hw_init(qm);
	if (ret) {
		pci_err(pdev, "Failed to init device\n");
		return ret;
	}

	qm_restart_prepare(qm);
	hisi_qm_dev_err_init(qm);
	if (qm->err_ini->open_axi_master_ooo)
		qm->err_ini->open_axi_master_ooo(qm);

	ret = qm_dev_mem_reset(qm);
	if (ret) {
		pci_err(pdev, "failed to reset device memory\n");
		return ret;
	}

	ret = qm_restart(qm);
	if (ret) {
		pci_err(pdev, "Failed to start QM!\n");
		return ret;
	}

	ret = qm_try_start_vfs(qm, QM_PF_RESET_DONE);
	if (ret)
		pci_err(pdev, "failed to start vfs by pf in soft reset.\n");

	ret = qm_wait_vf_prepare_finish(qm);
	if (ret)
		pci_err(pdev, "failed to start by vfs in soft reset!\n");

	qm_cmd_init(qm);
	qm_restart_done(qm);

	qm_reset_bit_clear(qm);

	return 0;
}

static int qm_controller_reset(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	pci_info(pdev, "Controller resetting...\n");

	ret = qm_controller_reset_prepare(qm);
	if (ret) {
		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
		clear_bit(QM_RST_SCHED, &qm->misc_ctl);
		return ret;
	}

	hisi_qm_show_last_dfx_regs(qm);
	if (qm->err_ini->show_last_dfx_regs)
		qm->err_ini->show_last_dfx_regs(qm);

	ret = qm_soft_reset(qm);
	if (ret)
		goto err_reset;

	ret = qm_controller_reset_done(qm);
	if (ret)
		goto err_reset;

	pci_info(pdev, "Controller reset complete\n");

	return 0;

err_reset:
	pci_err(pdev, "Controller reset failed (%d)\n", ret);
	qm_reset_bit_clear(qm);

	/* if resetting fails, isolate the device */
	if (qm->use_sva)
		qm->isolate_data.is_isolate = true;
	return ret;
}

/**
 * hisi_qm_dev_slot_reset() - slot reset
 * @pdev: the PCIe device
 *
 * This function offers QM relate PCIe device reset interface. Drivers which
 * use QM can use this function as slot_reset in its struct pci_error_handlers.
 */
pci_ers_result_t hisi_qm_dev_slot_reset(struct pci_dev *pdev)
{
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int ret;

	if (pdev->is_virtfn)
		return PCI_ERS_RESULT_RECOVERED;

	/* reset pcie device controller */
	ret = qm_controller_reset(qm);
	if (ret) {
		pci_err(pdev, "Controller reset failed (%d)\n", ret);
		return PCI_ERS_RESULT_DISCONNECT;
	}

	return PCI_ERS_RESULT_RECOVERED;
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_slot_reset);

void hisi_qm_reset_prepare(struct pci_dev *pdev)
{
	struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	u32 delay = 0;
	int ret;

	hisi_qm_dev_err_uninit(pf_qm);

	/*
	 * Check whether there is an ECC mbit error, If it occurs, need to
	 * wait for soft reset to fix it.
	 */
	while (qm_check_dev_error(qm)) {
		msleep(++delay);
		if (delay > QM_RESET_WAIT_TIMEOUT)
			return;
	}

	ret = qm_reset_prepare_ready(qm);
	if (ret) {
		pci_err(pdev, "FLR not ready!\n");
		return;
	}

	/* PF obtains the information of VF by querying the register. */
	if (qm->fun_type == QM_HW_PF)
		qm_cmd_uninit(qm);

	ret = qm_try_stop_vfs(qm, QM_PF_FLR_PREPARE, QM_DOWN);
	if (ret)
		pci_err(pdev, "failed to stop vfs by pf in FLR.\n");

	ret = hisi_qm_stop(qm, QM_DOWN);
	if (ret) {
		pci_err(pdev, "Failed to stop QM, ret = %d.\n", ret);
		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
		hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
		return;
	}

	ret = qm_wait_vf_prepare_finish(qm);
	if (ret)
		pci_err(pdev, "failed to stop by vfs in FLR!\n");

	pci_info(pdev, "FLR resetting...\n");
}
EXPORT_SYMBOL_GPL(hisi_qm_reset_prepare);

static bool qm_flr_reset_complete(struct pci_dev *pdev)
{
	struct pci_dev *pf_pdev = pci_physfn(pdev);
	struct hisi_qm *qm = pci_get_drvdata(pf_pdev);
	u32 id;

	pci_read_config_dword(qm->pdev, PCI_COMMAND, &id);
	if (id == QM_PCI_COMMAND_INVALID) {
		pci_err(pdev, "Device can not be used!\n");
		return false;
	}

	return true;
}

void hisi_qm_reset_done(struct pci_dev *pdev)
{
	struct hisi_qm *pf_qm = pci_get_drvdata(pci_physfn(pdev));
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int ret;

	if (qm->fun_type == QM_HW_PF) {
		ret = qm_dev_hw_init(qm);
		if (ret) {
			pci_err(pdev, "Failed to init PF, ret = %d.\n", ret);
			goto flr_done;
		}
	}

	hisi_qm_dev_err_init(pf_qm);

	ret = qm_restart(qm);
	if (ret) {
		pci_err(pdev, "Failed to start QM, ret = %d.\n", ret);
		goto flr_done;
	}

	ret = qm_try_start_vfs(qm, QM_PF_RESET_DONE);
	if (ret)
		pci_err(pdev, "failed to start vfs by pf in FLR.\n");

	ret = qm_wait_vf_prepare_finish(qm);
	if (ret)
		pci_err(pdev, "failed to start by vfs in FLR!\n");

flr_done:
	if (qm->fun_type == QM_HW_PF)
		qm_cmd_init(qm);

	if (qm_flr_reset_complete(pdev))
		pci_info(pdev, "FLR reset complete\n");

	qm_reset_bit_clear(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_reset_done);

static irqreturn_t qm_abnormal_irq(int irq, void *data)
{
	struct hisi_qm *qm = data;
	enum acc_err_result ret;

	atomic64_inc(&qm->debug.dfx.abnormal_irq_cnt);
	ret = qm_process_dev_error(qm);
	if (ret == ACC_ERR_NEED_RESET &&
	    !test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl) &&
	    !test_and_set_bit(QM_RST_SCHED, &qm->misc_ctl))
		schedule_work(&qm->rst_work);

	return IRQ_HANDLED;
}

/**
 * hisi_qm_dev_shutdown() - Shutdown device.
 * @pdev: The device will be shutdown.
 *
 * This function will stop qm when OS shutdown or rebooting.
 */
void hisi_qm_dev_shutdown(struct pci_dev *pdev)
{
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int ret;

	ret = hisi_qm_stop(qm, QM_DOWN);
	if (ret)
		dev_err(&pdev->dev, "Fail to stop qm in shutdown!\n");

	hisi_qm_cache_wb(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_shutdown);

static void hisi_qm_controller_reset(struct work_struct *rst_work)
{
	struct hisi_qm *qm = container_of(rst_work, struct hisi_qm, rst_work);
	int ret;

	ret = qm_pm_get_sync(qm);
	if (ret) {
		clear_bit(QM_RST_SCHED, &qm->misc_ctl);
		return;
	}

	/* reset pcie device controller */
	ret = qm_controller_reset(qm);
	if (ret)
		dev_err(&qm->pdev->dev, "controller reset failed (%d)\n", ret);

	qm_pm_put_sync(qm);
}

static void qm_pf_reset_vf_prepare(struct hisi_qm *qm,
				   enum qm_stop_reason stop_reason)
{
	enum qm_ifc_cmd cmd = QM_VF_PREPARE_DONE;
	struct pci_dev *pdev = qm->pdev;
	int ret;

	ret = qm_reset_prepare_ready(qm);
	if (ret) {
		dev_err(&pdev->dev, "reset prepare not ready!\n");
		atomic_set(&qm->status.flags, QM_STOP);
		cmd = QM_VF_PREPARE_FAIL;
		goto err_prepare;
	}

	ret = hisi_qm_stop(qm, stop_reason);
	if (ret) {
		dev_err(&pdev->dev, "failed to stop QM, ret = %d.\n", ret);
		atomic_set(&qm->status.flags, QM_STOP);
		cmd = QM_VF_PREPARE_FAIL;
		goto err_prepare;
	} else {
		goto out;
	}

err_prepare:
	hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET);
	hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET);
out:
	pci_save_state(pdev);
	ret = qm_ping_pf(qm, cmd);
	if (ret)
		dev_warn(&pdev->dev, "PF responds timeout in reset prepare!\n");
}

static void qm_pf_reset_vf_done(struct hisi_qm *qm)
{
	enum qm_ifc_cmd cmd = QM_VF_START_DONE;
	struct pci_dev *pdev = qm->pdev;
	int ret;

	pci_restore_state(pdev);
	ret = hisi_qm_start(qm);
	if (ret) {
		dev_err(&pdev->dev, "failed to start QM, ret = %d.\n", ret);
		cmd = QM_VF_START_FAIL;
	}

	qm_cmd_init(qm);
	ret = qm_ping_pf(qm, cmd);
	if (ret)
		dev_warn(&pdev->dev, "PF responds timeout in reset done!\n");

	qm_reset_bit_clear(qm);
}

static int qm_wait_pf_reset_finish(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	u32 val, cmd;
	int ret;

	/* Wait for reset to finish */
	ret = readl_relaxed_poll_timeout(qm->io_base + QM_IFC_INT_SOURCE_V, val,
					 val == BIT(0), QM_VF_RESET_WAIT_US,
					 QM_VF_RESET_WAIT_TIMEOUT_US);
	/* hardware completion status should be available by this time */
	if (ret) {
		dev_err(dev, "couldn't get reset done status from PF, timeout!\n");
		return -ETIMEDOUT;
	}

	/*
	 * Whether message is got successfully,
	 * VF needs to ack PF by clearing the interrupt.
	 */
	ret = qm->ops->get_ifc(qm, &cmd, NULL, 0);
	qm_clear_cmd_interrupt(qm, 0);
	if (ret) {
		dev_err(dev, "failed to get command from PF in reset done!\n");
		return ret;
	}

	if (cmd != QM_PF_RESET_DONE) {
		dev_err(dev, "the command(0x%x) is not reset done!\n", cmd);
		ret = -EINVAL;
	}

	return ret;
}

static void qm_pf_reset_vf_process(struct hisi_qm *qm,
				   enum qm_stop_reason stop_reason)
{
	struct device *dev = &qm->pdev->dev;
	int ret;

	dev_info(dev, "device reset start...\n");

	/* The message is obtained by querying the register during resetting */
	qm_cmd_uninit(qm);
	qm_pf_reset_vf_prepare(qm, stop_reason);

	ret = qm_wait_pf_reset_finish(qm);
	if (ret)
		goto err_get_status;

	qm_pf_reset_vf_done(qm);

	dev_info(dev, "device reset done.\n");

	return;

err_get_status:
	qm_cmd_init(qm);
	qm_reset_bit_clear(qm);
}

static void qm_handle_cmd_msg(struct hisi_qm *qm, u32 fun_num)
{
	struct device *dev = &qm->pdev->dev;
	enum qm_ifc_cmd cmd;
	u32 data;
	int ret;

	/*
	 * Get the msg from source by sending mailbox. Whether message is got
	 * successfully, destination needs to ack source by clearing the interrupt.
	 */
	ret = qm->ops->get_ifc(qm, &cmd, &data, fun_num);
	qm_clear_cmd_interrupt(qm, BIT(fun_num));
	if (ret) {
		dev_err(dev, "failed to get command from source!\n");
		return;
	}

	switch (cmd) {
	case QM_PF_FLR_PREPARE:
		qm_pf_reset_vf_process(qm, QM_DOWN);
		break;
	case QM_PF_SRST_PREPARE:
		qm_pf_reset_vf_process(qm, QM_SOFT_RESET);
		break;
	case QM_VF_GET_QOS:
		qm_vf_get_qos(qm, fun_num);
		break;
	case QM_PF_SET_QOS:
		qm->mb_qos = data;
		break;
	default:
		dev_err(dev, "unsupported command(0x%x) sent by function(%u)!\n", cmd, fun_num);
		break;
	}
}

static void qm_cmd_process(struct work_struct *cmd_process)
{
	struct hisi_qm *qm = container_of(cmd_process,
					struct hisi_qm, cmd_process);
	u32 vfs_num = qm->vfs_num;
	u64 val;
	u32 i;

	if (qm->fun_type == QM_HW_PF) {
		val = readq(qm->io_base + QM_IFC_INT_SOURCE_P);
		if (!val)
			return;

		for (i = 1; i <= vfs_num; i++) {
			if (val & BIT(i))
				qm_handle_cmd_msg(qm, i);
		}

		return;
	}

	qm_handle_cmd_msg(qm, 0);
}

/**
 * hisi_qm_alg_register() - Register alg to crypto.
 * @qm: The qm needs add.
 * @qm_list: The qm list.
 * @guard: Guard of qp_num.
 *
 * Register algorithm to crypto when the function is satisfy guard.
 */
int hisi_qm_alg_register(struct hisi_qm *qm, struct hisi_qm_list *qm_list, int guard)
{
	struct device *dev = &qm->pdev->dev;

	if (qm->ver <= QM_HW_V2 && qm->use_sva) {
		dev_info(dev, "HW V2 not both use uacce sva mode and hardware crypto algs.\n");
		return 0;
	}

	if (qm->qp_num < guard) {
		dev_info(dev, "qp_num is less than task need.\n");
		return 0;
	}

	return qm_list->register_to_crypto(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_alg_register);

/**
 * hisi_qm_alg_unregister() - Unregister alg from crypto.
 * @qm: The qm needs delete.
 * @qm_list: The qm list.
 * @guard: Guard of qp_num.
 *
 * Unregister algorithm from crypto when the last function is satisfy guard.
 */
void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list, int guard)
{
	if (qm->ver <= QM_HW_V2 && qm->use_sva)
		return;

	if (qm->qp_num < guard)
		return;

	qm_list->unregister_from_crypto(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_alg_unregister);

static void qm_unregister_abnormal_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;

	if (qm->fun_type == QM_HW_VF)
		return;

	val = qm->cap_tables.qm_cap_table[QM_ABNORMAL_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK))
		return;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	free_irq(pci_irq_vector(pdev, irq_vector), qm);
}

static int qm_register_abnormal_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;
	int ret;

	if (qm->fun_type == QM_HW_VF)
		return 0;

	val = qm->cap_tables.qm_cap_table[QM_ABNORMAL_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK))
		return 0;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_abnormal_irq, 0, qm->dev_name, qm);
	if (ret)
		dev_err(&qm->pdev->dev, "failed to request abnormal irq, ret = %d", ret);

	return ret;
}

static void qm_unregister_mb_cmd_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;

	val = qm->cap_tables.qm_cap_table[QM_MB_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	free_irq(pci_irq_vector(pdev, irq_vector), qm);
}

static int qm_register_mb_cmd_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;
	int ret;

	val = qm->cap_tables.qm_cap_table[QM_MB_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return 0;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_mb_cmd_irq, 0, qm->dev_name, qm);
	if (ret)
		dev_err(&pdev->dev, "failed to request function communication irq, ret = %d", ret);

	return ret;
}

static void qm_unregister_aeq_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;

	val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	free_irq(pci_irq_vector(pdev, irq_vector), qm);
}

static int qm_register_aeq_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;
	int ret;

	val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return 0;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	ret = request_threaded_irq(pci_irq_vector(pdev, irq_vector), NULL,
						   qm_aeq_thread, IRQF_ONESHOT, qm->dev_name, qm);
	if (ret)
		dev_err(&pdev->dev, "failed to request eq irq, ret = %d", ret);

	return ret;
}

static void qm_unregister_eq_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;

	val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	free_irq(pci_irq_vector(pdev, irq_vector), qm);
}

static int qm_register_eq_irq(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 irq_vector, val;
	int ret;

	val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ].cap_val;
	if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK))
		return 0;

	irq_vector = val & QM_IRQ_VECTOR_MASK;
	ret = request_irq(pci_irq_vector(pdev, irq_vector), qm_eq_irq, 0, qm->dev_name, qm);
	if (ret)
		dev_err(&pdev->dev, "failed to request eq irq, ret = %d", ret);

	return ret;
}

static void qm_irqs_unregister(struct hisi_qm *qm)
{
	qm_unregister_mb_cmd_irq(qm);
	qm_unregister_abnormal_irq(qm);
	qm_unregister_aeq_irq(qm);
	qm_unregister_eq_irq(qm);
}

static int qm_irqs_register(struct hisi_qm *qm)
{
	int ret;

	ret = qm_register_eq_irq(qm);
	if (ret)
		return ret;

	ret = qm_register_aeq_irq(qm);
	if (ret)
		goto free_eq_irq;

	ret = qm_register_abnormal_irq(qm);
	if (ret)
		goto free_aeq_irq;

	ret = qm_register_mb_cmd_irq(qm);
	if (ret)
		goto free_abnormal_irq;

	return 0;

free_abnormal_irq:
	qm_unregister_abnormal_irq(qm);
free_aeq_irq:
	qm_unregister_aeq_irq(qm);
free_eq_irq:
	qm_unregister_eq_irq(qm);
	return ret;
}

static int qm_get_qp_num(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	bool is_db_isolation;

	/* VF's qp_num assigned by PF in v2, and VF can get qp_num by vft. */
	if (qm->fun_type == QM_HW_VF) {
		if (qm->ver != QM_HW_V1)
			/* v2 starts to support get vft by mailbox */
			return hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);

		return 0;
	}

	is_db_isolation = test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps);
	qm->ctrl_qp_num = hisi_qm_get_hw_info(qm, qm_basic_info, QM_TOTAL_QP_NUM_CAP, true);
	qm->max_qp_num = hisi_qm_get_hw_info(qm, qm_basic_info,
					     QM_FUNC_MAX_QP_CAP, is_db_isolation);

	if (qm->qp_num <= qm->max_qp_num)
		return 0;

	if (test_bit(QM_MODULE_PARAM, &qm->misc_ctl)) {
		/* Check whether the set qp number is valid */
		dev_err(dev, "qp num(%u) is more than max qp num(%u)!\n",
			qm->qp_num, qm->max_qp_num);
		return -EINVAL;
	}

	dev_info(dev, "Default qp num(%u) is too big, reset it to Function's max qp num(%u)!\n",
		 qm->qp_num, qm->max_qp_num);
	qm->qp_num = qm->max_qp_num;
	qm->debug.curr_qm_qp_num = qm->qp_num;

	return 0;
}

static int qm_pre_store_caps(struct hisi_qm *qm)
{
	struct hisi_qm_cap_record *qm_cap;
	struct pci_dev *pdev = qm->pdev;
	size_t i, size;

	size = ARRAY_SIZE(qm_cap_query_info);
	qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL);
	if (!qm_cap)
		return -ENOMEM;

	for (i = 0; i < size; i++) {
		qm_cap[i].type = qm_cap_query_info[i].type;
		qm_cap[i].name = qm_cap_query_info[i].name;
		qm_cap[i].cap_val = hisi_qm_get_cap_value(qm, qm_cap_query_info,
							i, qm->cap_ver);
	}

	qm->cap_tables.qm_cap_table = qm_cap;
	qm->cap_tables.qm_cap_size = size;

	return 0;
}

static int qm_get_hw_caps(struct hisi_qm *qm)
{
	const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ?
						  qm_cap_info_pf : qm_cap_info_vf;
	u32 size = qm->fun_type == QM_HW_PF ? ARRAY_SIZE(qm_cap_info_pf) :
				   ARRAY_SIZE(qm_cap_info_vf);
	u32 val, i;

	/* Doorbell isolate register is a independent register. */
	val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, QM_SUPPORT_DB_ISOLATION, true);
	if (val)
		set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps);

	if (qm->ver >= QM_HW_V3) {
		val = readl(qm->io_base + QM_FUNC_CAPS_REG);
		qm->cap_ver = val & QM_CAPBILITY_VERSION;
	}

	/* Get PF/VF common capbility */
	for (i = 1; i < ARRAY_SIZE(qm_cap_info_comm); i++) {
		val = hisi_qm_get_hw_info(qm, qm_cap_info_comm, i, qm->cap_ver);
		if (val)
			set_bit(qm_cap_info_comm[i].type, &qm->caps);
	}

	/* Get PF/VF different capbility */
	for (i = 0; i < size; i++) {
		val = hisi_qm_get_hw_info(qm, cap_info, i, qm->cap_ver);
		if (val)
			set_bit(cap_info[i].type, &qm->caps);
	}

	/* Fetch and save the value of qm capability registers */
	return qm_pre_store_caps(qm);
}

static void qm_get_version(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	u32 sub_version_id;

	qm->ver = pdev->revision;

	if (pdev->revision == QM_HW_V3) {
		sub_version_id = readl(qm->io_base + QM_SUB_VERSION_ID);
		if (sub_version_id)
			qm->ver = sub_version_id;
	}
}

static int qm_get_pci_res(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct device *dev = &pdev->dev;
	int ret;

	ret = pci_request_mem_regions(pdev, qm->dev_name);
	if (ret < 0) {
		dev_err(dev, "Failed to request mem regions!\n");
		return ret;
	}

	qm->phys_base = pci_resource_start(pdev, PCI_BAR_2);
	qm->io_base = ioremap(qm->phys_base, pci_resource_len(pdev, PCI_BAR_2));
	if (!qm->io_base) {
		ret = -EIO;
		goto err_request_mem_regions;
	}

	qm_get_version(qm);

	ret = qm_get_hw_caps(qm);
	if (ret)
		goto err_ioremap;

	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) {
		qm->db_interval = QM_QP_DB_INTERVAL;
		qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4);
		qm->db_io_base = ioremap(qm->db_phys_base,
					 pci_resource_len(pdev, PCI_BAR_4));
		if (!qm->db_io_base) {
			ret = -EIO;
			goto err_ioremap;
		}
	} else {
		qm->db_phys_base = qm->phys_base;
		qm->db_io_base = qm->io_base;
		qm->db_interval = 0;
	}

	hisi_qm_pre_init(qm);
	ret = qm_get_qp_num(qm);
	if (ret)
		goto err_db_ioremap;

	return 0;

err_db_ioremap:
	if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps))
		iounmap(qm->db_io_base);
err_ioremap:
	iounmap(qm->io_base);
err_request_mem_regions:
	pci_release_mem_regions(pdev);
	return ret;
}

static int qm_clear_device(struct hisi_qm *qm)
{
	acpi_handle handle = ACPI_HANDLE(&qm->pdev->dev);
	int ret;

	if (qm->fun_type == QM_HW_VF)
		return 0;

	/* Device does not support reset, return */
	if (!qm->err_ini->err_info_init)
		return 0;
	qm->err_ini->err_info_init(qm);

	if (!handle)
		return 0;

	/* No reset method, return */
	if (!acpi_has_method(handle, qm->err_info.acpi_rst))
		return 0;

	ret = qm_master_ooo_check(qm);
	if (ret) {
		writel(0x0, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
		return ret;
	}

	if (qm->err_ini->set_priv_status) {
		ret = qm->err_ini->set_priv_status(qm);
		if (ret) {
			writel(0x0, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
			return ret;
		}
	}

	return qm_reset_device(qm);
}

static int hisi_qm_pci_init(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct device *dev = &pdev->dev;
	unsigned int num_vec;
	int ret;

	ret = pci_enable_device_mem(pdev);
	if (ret < 0) {
		dev_err(dev, "Failed to enable device mem!\n");
		return ret;
	}

	ret = qm_get_pci_res(qm);
	if (ret)
		goto err_disable_pcidev;

	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
	if (ret < 0)
		goto err_get_pci_res;
	pci_set_master(pdev);

	num_vec = qm_get_irq_num(qm);
	ret = pci_alloc_irq_vectors(pdev, num_vec, num_vec, PCI_IRQ_MSI);
	if (ret < 0) {
		dev_err(dev, "Failed to enable MSI vectors!\n");
		goto err_get_pci_res;
	}

	ret = qm_clear_device(qm);
	if (ret)
		goto err_free_vectors;

	return 0;

err_free_vectors:
	pci_free_irq_vectors(pdev);
err_get_pci_res:
	qm_put_pci_res(qm);
err_disable_pcidev:
	pci_disable_device(pdev);
	return ret;
}

static int hisi_qm_init_work(struct hisi_qm *qm)
{
	int i;

	for (i = 0; i < qm->qp_num; i++)
		INIT_WORK(&qm->poll_data[i].work, qm_work_process);

	if (qm->fun_type == QM_HW_PF)
		INIT_WORK(&qm->rst_work, hisi_qm_controller_reset);

	if (qm->ver > QM_HW_V2)
		INIT_WORK(&qm->cmd_process, qm_cmd_process);

	qm->wq = alloc_workqueue("%s", WQ_HIGHPRI | WQ_MEM_RECLAIM |
				 WQ_UNBOUND, num_online_cpus(),
				 pci_name(qm->pdev));
	if (!qm->wq) {
		pci_err(qm->pdev, "failed to alloc workqueue!\n");
		return -ENOMEM;
	}

	return 0;
}

static int hisi_qp_alloc_memory(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	u16 sq_depth, cq_depth;
	size_t qp_dma_size;
	int i, ret;

	qm->qp_array = kcalloc(qm->qp_num, sizeof(struct hisi_qp), GFP_KERNEL);
	if (!qm->qp_array)
		return -ENOMEM;

	qm->poll_data = kcalloc(qm->qp_num, sizeof(struct hisi_qm_poll_data), GFP_KERNEL);
	if (!qm->poll_data) {
		kfree(qm->qp_array);
		return -ENOMEM;
	}

	qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);

	/* one more page for device or qp statuses */
	qp_dma_size = qm->sqe_size * sq_depth + sizeof(struct qm_cqe) * cq_depth;
	qp_dma_size = PAGE_ALIGN(qp_dma_size) + PAGE_SIZE;
	for (i = 0; i < qm->qp_num; i++) {
		qm->poll_data[i].qm = qm;
		ret = hisi_qp_memory_init(qm, qp_dma_size, i, sq_depth, cq_depth);
		if (ret)
			goto err_init_qp_mem;

		dev_dbg(dev, "allocate qp dma buf size=%zx)\n", qp_dma_size);
	}

	return 0;
err_init_qp_mem:
	hisi_qp_memory_uninit(qm, i);

	return ret;
}

static int hisi_qm_alloc_rsv_buf(struct hisi_qm *qm)
{
	struct qm_rsv_buf *xqc_buf = &qm->xqc_buf;
	struct qm_dma *xqc_dma = &xqc_buf->qcdma;
	struct device *dev = &qm->pdev->dev;
	size_t off = 0;

#define QM_XQC_BUF_INIT(xqc_buf, type) do { \
	(xqc_buf)->type = ((xqc_buf)->qcdma.va + (off)); \
	(xqc_buf)->type##_dma = (xqc_buf)->qcdma.dma + (off); \
	off += QMC_ALIGN(sizeof(struct qm_##type)); \
} while (0)

	xqc_dma->size = QMC_ALIGN(sizeof(struct qm_eqc)) +
			QMC_ALIGN(sizeof(struct qm_aeqc)) +
			QMC_ALIGN(sizeof(struct qm_sqc)) +
			QMC_ALIGN(sizeof(struct qm_cqc));
	xqc_dma->va = dma_alloc_coherent(dev, xqc_dma->size,
					 &xqc_dma->dma, GFP_KERNEL);
	if (!xqc_dma->va)
		return -ENOMEM;

	QM_XQC_BUF_INIT(xqc_buf, eqc);
	QM_XQC_BUF_INIT(xqc_buf, aeqc);
	QM_XQC_BUF_INIT(xqc_buf, sqc);
	QM_XQC_BUF_INIT(xqc_buf, cqc);

	return 0;
}

static int hisi_qm_memory_init(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;
	int ret, total_func;
	size_t off = 0;

	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) {
		total_func = pci_sriov_get_totalvfs(qm->pdev) + 1;
		qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL);
		if (!qm->factor)
			return -ENOMEM;

		/* Only the PF value needs to be initialized */
		qm->factor[0].func_qos = QM_QOS_MAX_VAL;
	}

#define QM_INIT_BUF(qm, type, num) do { \
	(qm)->type = ((qm)->qdma.va + (off)); \
	(qm)->type##_dma = (qm)->qdma.dma + (off); \
	off += QMC_ALIGN(sizeof(struct qm_##type) * (num)); \
} while (0)

	idr_init(&qm->qp_idr);
	qm_get_xqc_depth(qm, &qm->eq_depth, &qm->aeq_depth, QM_XEQ_DEPTH_CAP);
	qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * qm->eq_depth) +
			QMC_ALIGN(sizeof(struct qm_aeqe) * qm->aeq_depth) +
			QMC_ALIGN(sizeof(struct qm_sqc) * qm->qp_num) +
			QMC_ALIGN(sizeof(struct qm_cqc) * qm->qp_num);
	qm->qdma.va = dma_alloc_coherent(dev, qm->qdma.size, &qm->qdma.dma,
					 GFP_ATOMIC);
	dev_dbg(dev, "allocate qm dma buf size=%zx)\n", qm->qdma.size);
	if (!qm->qdma.va) {
		ret = -ENOMEM;
		goto err_destroy_idr;
	}

	QM_INIT_BUF(qm, eqe, qm->eq_depth);
	QM_INIT_BUF(qm, aeqe, qm->aeq_depth);
	QM_INIT_BUF(qm, sqc, qm->qp_num);
	QM_INIT_BUF(qm, cqc, qm->qp_num);

	ret = hisi_qm_alloc_rsv_buf(qm);
	if (ret)
		goto err_free_qdma;

	ret = hisi_qp_alloc_memory(qm);
	if (ret)
		goto err_free_reserve_buf;

	return 0;

err_free_reserve_buf:
	hisi_qm_free_rsv_buf(qm);
err_free_qdma:
	dma_free_coherent(dev, qm->qdma.size, qm->qdma.va, qm->qdma.dma);
err_destroy_idr:
	idr_destroy(&qm->qp_idr);
	if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps))
		kfree(qm->factor);

	return ret;
}

/**
 * hisi_qm_init() - Initialize configures about qm.
 * @qm: The qm needing init.
 *
 * This function init qm, then we can call hisi_qm_start to put qm into work.
 */
int hisi_qm_init(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	struct device *dev = &pdev->dev;
	int ret;

	ret = hisi_qm_pci_init(qm);
	if (ret)
		return ret;

	ret = qm_irqs_register(qm);
	if (ret)
		goto err_pci_init;

	if (qm->fun_type == QM_HW_PF) {
		/* Set the doorbell timeout to QM_DB_TIMEOUT_CFG ns. */
		writel(QM_DB_TIMEOUT_SET, qm->io_base + QM_DB_TIMEOUT_CFG);
		qm_disable_clock_gate(qm);
		ret = qm_dev_mem_reset(qm);
		if (ret) {
			dev_err(dev, "failed to reset device memory\n");
			goto err_irq_register;
		}
	}

	if (qm->mode == UACCE_MODE_SVA) {
		ret = qm_alloc_uacce(qm);
		if (ret < 0)
			dev_warn(dev, "fail to alloc uacce (%d)\n", ret);
	}

	ret = hisi_qm_memory_init(qm);
	if (ret)
		goto err_alloc_uacce;

	ret = hisi_qm_init_work(qm);
	if (ret)
		goto err_free_qm_memory;

	qm_cmd_init(qm);

	return 0;

err_free_qm_memory:
	hisi_qm_memory_uninit(qm);
err_alloc_uacce:
	qm_remove_uacce(qm);
err_irq_register:
	qm_irqs_unregister(qm);
err_pci_init:
	hisi_qm_pci_uninit(qm);
	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_init);

/**
 * hisi_qm_get_dfx_access() - Try to get dfx access.
 * @qm: pointer to accelerator device.
 *
 * Try to get dfx access, then user can get message.
 *
 * If device is in suspended, return failure, otherwise
 * bump up the runtime PM usage counter.
 */
int hisi_qm_get_dfx_access(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;

	if (pm_runtime_suspended(dev)) {
		dev_info(dev, "can not read/write - device in suspended.\n");
		return -EAGAIN;
	}

	return qm_pm_get_sync(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_get_dfx_access);

/**
 * hisi_qm_put_dfx_access() - Put dfx access.
 * @qm: pointer to accelerator device.
 *
 * Put dfx access, drop runtime PM usage counter.
 */
void hisi_qm_put_dfx_access(struct hisi_qm *qm)
{
	qm_pm_put_sync(qm);
}
EXPORT_SYMBOL_GPL(hisi_qm_put_dfx_access);

/**
 * hisi_qm_pm_init() - Initialize qm runtime PM.
 * @qm: pointer to accelerator device.
 *
 * Function that initialize qm runtime PM.
 */
void hisi_qm_pm_init(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;

	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
		return;

	pm_runtime_set_autosuspend_delay(dev, QM_AUTOSUSPEND_DELAY);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_put_noidle(dev);
}
EXPORT_SYMBOL_GPL(hisi_qm_pm_init);

/**
 * hisi_qm_pm_uninit() - Uninitialize qm runtime PM.
 * @qm: pointer to accelerator device.
 *
 * Function that uninitialize qm runtime PM.
 */
void hisi_qm_pm_uninit(struct hisi_qm *qm)
{
	struct device *dev = &qm->pdev->dev;

	if (!test_bit(QM_SUPPORT_RPM, &qm->caps))
		return;

	pm_runtime_get_noresume(dev);
	pm_runtime_dont_use_autosuspend(dev);
}
EXPORT_SYMBOL_GPL(hisi_qm_pm_uninit);

static int qm_prepare_for_suspend(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	ret = qm->ops->set_msi(qm, false);
	if (ret) {
		pci_err(pdev, "failed to disable MSI before suspending!\n");
		return ret;
	}

	ret = qm_master_ooo_check(qm);
	if (ret)
		return ret;

	if (qm->err_ini->set_priv_status) {
		ret = qm->err_ini->set_priv_status(qm);
		if (ret)
			return ret;
	}

	ret = qm_set_pf_mse(qm, false);
	if (ret)
		pci_err(pdev, "failed to disable MSE before suspending!\n");

	return ret;
}

static int qm_rebuild_for_resume(struct hisi_qm *qm)
{
	struct pci_dev *pdev = qm->pdev;
	int ret;

	ret = qm_set_pf_mse(qm, true);
	if (ret) {
		pci_err(pdev, "failed to enable MSE after resuming!\n");
		return ret;
	}

	ret = qm->ops->set_msi(qm, true);
	if (ret) {
		pci_err(pdev, "failed to enable MSI after resuming!\n");
		return ret;
	}

	ret = qm_dev_hw_init(qm);
	if (ret) {
		pci_err(pdev, "failed to init device after resuming\n");
		return ret;
	}

	qm_cmd_init(qm);
	hisi_qm_dev_err_init(qm);
	/* Set the doorbell timeout to QM_DB_TIMEOUT_CFG ns. */
	writel(QM_DB_TIMEOUT_SET, qm->io_base + QM_DB_TIMEOUT_CFG);
	qm_disable_clock_gate(qm);
	ret = qm_dev_mem_reset(qm);
	if (ret)
		pci_err(pdev, "failed to reset device memory\n");

	return ret;
}

/**
 * hisi_qm_suspend() - Runtime suspend of given device.
 * @dev: device to suspend.
 *
 * Function that suspend the device.
 */
int hisi_qm_suspend(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int ret;

	pci_info(pdev, "entering suspended state\n");

	ret = hisi_qm_stop(qm, QM_NORMAL);
	if (ret) {
		pci_err(pdev, "failed to stop qm(%d)\n", ret);
		return ret;
	}

	ret = qm_prepare_for_suspend(qm);
	if (ret)
		pci_err(pdev, "failed to prepare suspended(%d)\n", ret);

	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_suspend);

/**
 * hisi_qm_resume() - Runtime resume of given device.
 * @dev: device to resume.
 *
 * Function that resume the device.
 */
int hisi_qm_resume(struct device *dev)
{
	struct pci_dev *pdev = to_pci_dev(dev);
	struct hisi_qm *qm = pci_get_drvdata(pdev);
	int ret;

	pci_info(pdev, "resuming from suspend state\n");

	ret = qm_rebuild_for_resume(qm);
	if (ret) {
		pci_err(pdev, "failed to rebuild resume(%d)\n", ret);
		return ret;
	}

	ret = hisi_qm_start(qm);
	if (ret) {
		if (qm_check_dev_error(qm)) {
			pci_info(pdev, "failed to start qm due to device error, device will be reset!\n");
			return 0;
		}

		pci_err(pdev, "failed to start qm(%d)!\n", ret);
	}

	return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_resume);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
