aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/hisilicon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/hisilicon')
-rw-r--r--drivers/crypto/hisilicon/Kconfig8
-rw-r--r--drivers/crypto/hisilicon/Makefile1
-rw-r--r--drivers/crypto/hisilicon/hpre/hpre_main.c4
-rw-r--r--drivers/crypto/hisilicon/qm.c220
-rw-r--r--drivers/crypto/hisilicon/qm.h2
-rw-r--r--drivers/crypto/hisilicon/sec2/sec.h2
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_crypto.c25
-rw-r--r--drivers/crypto/hisilicon/sec2/sec_main.c34
-rw-r--r--drivers/crypto/hisilicon/sgl.c2
-rw-r--r--drivers/crypto/hisilicon/trng/Makefile2
-rw-r--r--drivers/crypto/hisilicon/trng/trng.c334
-rw-r--r--drivers/crypto/hisilicon/zip/zip_main.c30
12 files changed, 538 insertions, 126 deletions
diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
index 9c3b3ca815e6..843192666dc3 100644
--- a/drivers/crypto/hisilicon/Kconfig
+++ b/drivers/crypto/hisilicon/Kconfig
@@ -71,3 +71,11 @@ config CRYPTO_DEV_HISI_HPRE
help
Support for HiSilicon HPRE(High Performance RSA Engine)
accelerator, which can accelerate RSA and DH algorithms.
+
+config CRYPTO_DEV_HISI_TRNG
+ tristate "Support for HISI TRNG Driver"
+ depends on ARM64 && ACPI
+ select HW_RANDOM
+ select CRYPTO_RNG
+ help
+ Support for HiSilicon TRNG Driver.
diff --git a/drivers/crypto/hisilicon/Makefile b/drivers/crypto/hisilicon/Makefile
index 7f5f74c72baa..1e89269a2e4b 100644
--- a/drivers/crypto/hisilicon/Makefile
+++ b/drivers/crypto/hisilicon/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/
obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o
hisi_qm-objs = qm.o sgl.o
obj-$(CONFIG_CRYPTO_DEV_HISI_ZIP) += zip/
+obj-$(CONFIG_CRYPTO_DEV_HISI_TRNG) += trng/
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
index a33394d91bbf..e5c991913f09 100644
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -705,9 +705,7 @@ static int hpre_debugfs_init(struct hisi_qm *qm)
qm->debug.sqe_mask_offset = HPRE_SQE_MASK_OFFSET;
qm->debug.sqe_mask_len = HPRE_SQE_MASK_LEN;
- ret = hisi_qm_debug_init(qm);
- if (ret)
- goto failed_to_create;
+ hisi_qm_debug_init(qm);
if (qm->pdev->device == HPRE_PCI_DEVICE_ID) {
ret = hpre_ctrl_debug_init(qm);
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 530f23116d7c..f21ccae0e8ea 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -473,7 +473,7 @@ static int qm_wait_mb_ready(struct hisi_qm *qm)
return readl_relaxed_poll_timeout(qm->io_base + QM_MB_CMD_SEND_BASE,
val, !((val >> QM_MB_BUSY_SHIFT) &
- 0x1), 10, 1000);
+ 0x1), POLL_PERIOD, POLL_TIMEOUT);
}
/* 128 bit should be written to hardware at one time to trigger a mailbox */
@@ -583,7 +583,8 @@ static int qm_dev_mem_reset(struct hisi_qm *qm)
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), 10, 1000);
+ val & BIT(0), POLL_PERIOD,
+ POLL_TIMEOUT);
}
static u32 qm_get_irq_num_v1(struct hisi_qm *qm)
@@ -804,7 +805,8 @@ static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type,
int ret;
ret = readl_relaxed_poll_timeout(qm->io_base + QM_VFT_CFG_RDY, val,
- val & BIT(0), 10, 1000);
+ val & BIT(0), POLL_PERIOD,
+ POLL_TIMEOUT);
if (ret)
return ret;
@@ -818,7 +820,8 @@ static int qm_set_vft_common(struct hisi_qm *qm, enum vft_type type,
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), 10, 1000);
+ val & BIT(0), POLL_PERIOD,
+ POLL_TIMEOUT);
}
/* The config should be conducted after qm_dev_mem_reset() */
@@ -929,7 +932,8 @@ static ssize_t qm_debug_read(struct file *filp, char __user *buf,
return -EINVAL;
}
mutex_unlock(&file->lock);
- ret = sprintf(tbuf, "%u\n", val);
+
+ ret = scnprintf(tbuf, QM_DBG_TMP_BUF_LEN, "%u\n", val);
return simple_read_from_buffer(buf, count, pos, tbuf, ret);
}
@@ -1517,7 +1521,7 @@ static const struct file_operations qm_cmd_fops = {
.write = qm_cmd_write,
};
-static int qm_create_debugfs_file(struct hisi_qm *qm, enum qm_debug_file index)
+static void qm_create_debugfs_file(struct hisi_qm *qm, enum qm_debug_file index)
{
struct dentry *qm_d = qm->debug.qm_d;
struct debugfs_file *file = qm->debug.files + index;
@@ -1528,8 +1532,6 @@ static int qm_create_debugfs_file(struct hisi_qm *qm, enum qm_debug_file index)
file->index = index;
mutex_init(&file->lock);
file->debug = &qm->debug;
-
- return 0;
}
static void qm_hw_error_init_v1(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe)
@@ -1733,19 +1735,15 @@ void hisi_qm_release_qp(struct hisi_qp *qp)
}
EXPORT_SYMBOL_GPL(hisi_qm_release_qp);
-static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
+static int qm_sq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
{
struct hisi_qm *qm = qp->qm;
struct device *dev = &qm->pdev->dev;
enum qm_hw_ver ver = qm->ver;
struct qm_sqc *sqc;
- struct qm_cqc *cqc;
dma_addr_t sqc_dma;
- dma_addr_t cqc_dma;
int ret;
- qm_init_qp_status(qp);
-
sqc = kzalloc(sizeof(struct qm_sqc), GFP_KERNEL);
if (!sqc)
return -ENOMEM;
@@ -1770,8 +1768,18 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
ret = qm_mb(qm, QM_MB_CMD_SQC, sqc_dma, qp_id, 0);
dma_unmap_single(dev, sqc_dma, sizeof(struct qm_sqc), DMA_TO_DEVICE);
kfree(sqc);
- if (ret)
- return ret;
+
+ return ret;
+}
+
+static int qm_cq_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
+{
+ struct hisi_qm *qm = qp->qm;
+ struct device *dev = &qm->pdev->dev;
+ enum qm_hw_ver ver = qm->ver;
+ struct qm_cqc *cqc;
+ dma_addr_t cqc_dma;
+ int ret;
cqc = kzalloc(sizeof(struct qm_cqc), GFP_KERNEL);
if (!cqc)
@@ -1785,11 +1793,12 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
INIT_QC_COMMON(cqc, qp->cqe_dma, pasid);
if (ver == QM_HW_V1) {
- cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0, 4));
+ cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0,
+ QM_QC_CQE_SIZE));
cqc->w8 = cpu_to_le16(QM_Q_DEPTH - 1);
} else {
- cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(4));
- cqc->w8 = 0;
+ cqc->dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(QM_QC_CQE_SIZE));
+ cqc->w8 = 0; /* rand_qc */
}
cqc->dw6 = cpu_to_le32(1 << QM_CQ_PHASE_SHIFT | 1 << QM_CQ_FLAG_SHIFT);
@@ -1800,6 +1809,19 @@ static int qm_qp_ctx_cfg(struct hisi_qp *qp, int qp_id, u32 pasid)
return ret;
}
+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;
@@ -1843,6 +1865,9 @@ int hisi_qm_start_qp(struct hisi_qp *qp, unsigned long arg)
EXPORT_SYMBOL_GPL(hisi_qm_start_qp);
/**
+ * qm_drain_qp() - Drain a qp.
+ * @qp: The qp we want to drain.
+ *
* Determine whether the queue is cleared by judging the tail pointers of
* sq and cq.
*/
@@ -2008,7 +2033,8 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm)
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), 10, 1000))
+ val, val & BIT(0), POLL_PERIOD,
+ POLL_TIMEOUT))
dev_err(&qm->pdev->dev, "QM writeback sqc cache fail!\n");
}
@@ -2112,7 +2138,7 @@ static void hisi_qm_uacce_stop_queue(struct uacce_queue *q)
hisi_qm_stop_qp(q->priv);
}
-static int qm_set_sqctype(struct uacce_queue *q, u16 type)
+static void qm_set_sqctype(struct uacce_queue *q, u16 type)
{
struct hisi_qm *qm = q->uacce->priv;
struct hisi_qp *qp = q->priv;
@@ -2120,8 +2146,6 @@ static int qm_set_sqctype(struct uacce_queue *q, u16 type)
down_write(&qm->qps_lock);
qp->alg_type = type;
up_write(&qm->qps_lock);
-
- return 0;
}
static long hisi_qm_uacce_ioctl(struct uacce_queue *q, unsigned int cmd,
@@ -2418,6 +2442,16 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
qm->is_frozen = false;
}
+static void hisi_qm_pci_uninit(struct hisi_qm *qm)
+{
+ struct pci_dev *pdev = qm->pdev;
+
+ pci_free_irq_vectors(pdev);
+ iounmap(qm->io_base);
+ pci_release_mem_regions(pdev);
+ pci_disable_device(pdev);
+}
+
/**
* hisi_qm_uninit() - Uninitialize qm.
* @qm: The qm needed uninit.
@@ -2436,9 +2470,6 @@ void hisi_qm_uninit(struct hisi_qm *qm)
return;
}
- uacce_remove(qm->uacce);
- qm->uacce = NULL;
-
hisi_qp_memory_uninit(qm, qm->qp_num);
idr_destroy(&qm->qp_idr);
@@ -2450,10 +2481,9 @@ void hisi_qm_uninit(struct hisi_qm *qm)
}
qm_irq_unregister(qm);
- pci_free_irq_vectors(pdev);
- iounmap(qm->io_base);
- pci_release_mem_regions(pdev);
- pci_disable_device(pdev);
+ hisi_qm_pci_uninit(qm);
+ uacce_remove(qm->uacce);
+ qm->uacce = NULL;
up_write(&qm->qps_lock);
}
@@ -2486,6 +2516,12 @@ int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number)
EXPORT_SYMBOL_GPL(hisi_qm_get_vft);
/**
+ * 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.
*
@@ -2519,14 +2555,10 @@ static int qm_eq_ctx_cfg(struct hisi_qm *qm)
{
struct device *dev = &qm->pdev->dev;
struct qm_eqc *eqc;
- struct qm_aeqc *aeqc;
dma_addr_t eqc_dma;
- dma_addr_t aeqc_dma;
int ret;
- qm_init_eq_aeq_status(qm);
-
- eqc = kzalloc(sizeof(struct qm_eqc), GFP_KERNEL);
+ eqc = kzalloc(sizeof(struct qm_eqc), GFP_KERNEL); //todo
if (!eqc)
return -ENOMEM;
eqc_dma = dma_map_single(dev, eqc, sizeof(struct qm_eqc),
@@ -2541,11 +2573,20 @@ static int qm_eq_ctx_cfg(struct hisi_qm *qm)
if (qm->ver == QM_HW_V1)
eqc->dw3 = cpu_to_le32(QM_EQE_AEQE_SIZE);
eqc->dw6 = cpu_to_le32((QM_EQ_DEPTH - 1) | (1 << QM_EQC_PHASE_SHIFT));
+
ret = qm_mb(qm, QM_MB_CMD_EQC, eqc_dma, 0, 0);
dma_unmap_single(dev, eqc_dma, sizeof(struct qm_eqc), DMA_TO_DEVICE);
kfree(eqc);
- if (ret)
- return ret;
+
+ return ret;
+}
+
+static int qm_aeq_ctx_cfg(struct hisi_qm *qm)
+{
+ struct device *dev = &qm->pdev->dev;
+ struct qm_aeqc *aeqc;
+ dma_addr_t aeqc_dma;
+ int ret;
aeqc = kzalloc(sizeof(struct qm_aeqc), GFP_KERNEL);
if (!aeqc)
@@ -2568,6 +2609,22 @@ static int qm_eq_ctx_cfg(struct hisi_qm *qm)
return ret;
}
+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;
@@ -2584,7 +2641,7 @@ static int __hisi_qm_start(struct hisi_qm *qm)
return ret;
}
- ret = qm_eq_ctx_cfg(qm);
+ ret = qm_eq_aeq_ctx_cfg(qm);
if (ret)
return ret;
@@ -2690,7 +2747,11 @@ static int qm_stop_started_qp(struct hisi_qm *qm)
return 0;
}
+
/**
+ * 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.
*/
@@ -2806,12 +2867,12 @@ DEFINE_DEBUGFS_ATTRIBUTE(qm_atomic64_ops, qm_debugfs_atomic64_get,
*
* Create qm related debugfs files.
*/
-int hisi_qm_debug_init(struct hisi_qm *qm)
+void hisi_qm_debug_init(struct hisi_qm *qm)
{
struct qm_dfx *dfx = &qm->debug.dfx;
struct dentry *qm_d;
void *data;
- int i, ret;
+ int i;
qm_d = debugfs_create_dir("qm", qm->debug.debug_root);
qm->debug.qm_d = qm_d;
@@ -2819,10 +2880,7 @@ int hisi_qm_debug_init(struct hisi_qm *qm)
/* only show this in PF */
if (qm->fun_type == QM_HW_PF)
for (i = CURRENT_Q; i < DEBUG_FILE_NUM; i++)
- if (qm_create_debugfs_file(qm, i)) {
- ret = -ENOENT;
- goto failed_to_create;
- }
+ qm_create_debugfs_file(qm, i);
debugfs_create_file("regs", 0444, qm->debug.qm_d, qm, &qm_regs_fops);
@@ -2838,12 +2896,6 @@ int hisi_qm_debug_init(struct hisi_qm *qm)
data,
&qm_atomic64_ops);
}
-
- return 0;
-
-failed_to_create:
- debugfs_remove_recursive(qm_d);
- return ret;
}
EXPORT_SYMBOL_GPL(hisi_qm_debug_init);
@@ -3273,7 +3325,7 @@ pci_ers_result_t hisi_qm_dev_err_detected(struct pci_dev *pdev,
}
EXPORT_SYMBOL_GPL(hisi_qm_dev_err_detected);
-static int qm_get_hw_error_status(struct hisi_qm *qm)
+static u32 qm_get_hw_error_status(struct hisi_qm *qm)
{
return readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
}
@@ -3572,7 +3624,7 @@ restart_fail:
return ret;
}
-static int qm_get_dev_err_status(struct hisi_qm *qm)
+static u32 qm_get_dev_err_status(struct hisi_qm *qm)
{
return qm->err_ini->get_dev_hw_err_status(qm);
}
@@ -3992,34 +4044,22 @@ void hisi_qm_alg_unregister(struct hisi_qm *qm, struct hisi_qm_list *qm_list)
}
EXPORT_SYMBOL_GPL(hisi_qm_alg_unregister);
-/**
- * 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)
+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;
- hisi_qm_pre_init(qm);
-
- ret = qm_alloc_uacce(qm);
- if (ret < 0)
- dev_warn(&pdev->dev, "fail to alloc uacce (%d)\n", ret);
-
ret = pci_enable_device_mem(pdev);
if (ret < 0) {
- dev_err(&pdev->dev, "Failed to enable device mem!\n");
- goto err_remove_uacce;
+ dev_err(dev, "Failed to enable device mem!\n");
+ return ret;
}
ret = pci_request_mem_regions(pdev, qm->dev_name);
if (ret < 0) {
- dev_err(&pdev->dev, "Failed to request mem regions!\n");
+ dev_err(dev, "Failed to request mem regions!\n");
goto err_disable_pcidev;
}
@@ -4047,9 +4087,42 @@ int hisi_qm_init(struct hisi_qm *qm)
goto err_iounmap;
}
+ return 0;
+
+err_iounmap:
+ iounmap(qm->io_base);
+err_release_mem_regions:
+ pci_release_mem_regions(pdev);
+err_disable_pcidev:
+ pci_disable_device(pdev);
+ 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;
+
+ hisi_qm_pre_init(qm);
+
+ ret = qm_alloc_uacce(qm);
+ if (ret < 0)
+ dev_warn(dev, "fail to alloc uacce (%d)\n", ret);
+
+ ret = hisi_qm_pci_init(qm);
+ if (ret)
+ goto err_remove_uacce;
+
ret = qm_irq_register(qm);
if (ret)
- goto err_free_irq_vectors;
+ goto err_pci_uninit;
if (qm->fun_type == QM_HW_VF && qm->ver != QM_HW_V1) {
/* v2 starts to support get vft by mailbox */
@@ -4072,14 +4145,8 @@ int hisi_qm_init(struct hisi_qm *qm)
err_irq_unregister:
qm_irq_unregister(qm);
-err_free_irq_vectors:
- pci_free_irq_vectors(pdev);
-err_iounmap:
- iounmap(qm->io_base);
-err_release_mem_regions:
- pci_release_mem_regions(pdev);
-err_disable_pcidev:
- pci_disable_device(pdev);
+err_pci_uninit:
+ hisi_qm_pci_uninit(qm);
err_remove_uacce:
uacce_remove(qm->uacce);
qm->uacce = NULL;
@@ -4087,7 +4154,6 @@ err_remove_uacce:
}
EXPORT_SYMBOL_GPL(hisi_qm_init);
-
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
MODULE_DESCRIPTION("HiSilicon Accelerator queue manager driver");
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
index 0420f4ce7197..8624d1288afe 100644
--- a/drivers/crypto/hisilicon/qm.h
+++ b/drivers/crypto/hisilicon/qm.h
@@ -350,7 +350,7 @@ void hisi_qm_release_qp(struct hisi_qp *qp);
int hisi_qp_send(struct hisi_qp *qp, const void *msg);
int hisi_qm_get_free_qp_num(struct hisi_qm *qm);
int hisi_qm_get_vft(struct hisi_qm *qm, u32 *base, u32 *number);
-int hisi_qm_debug_init(struct hisi_qm *qm);
+void hisi_qm_debug_init(struct hisi_qm *qm);
enum qm_hw_ver hisi_qm_get_hw_version(struct pci_dev *pdev);
void hisi_qm_debug_regs_clear(struct hisi_qm *qm);
int hisi_qm_sriov_enable(struct pci_dev *pdev, int max_vfs);
diff --git a/drivers/crypto/hisilicon/sec2/sec.h b/drivers/crypto/hisilicon/sec2/sec.h
index 037762b531e2..08491912afd5 100644
--- a/drivers/crypto/hisilicon/sec2/sec.h
+++ b/drivers/crypto/hisilicon/sec2/sec.h
@@ -109,7 +109,6 @@ struct sec_qp_ctx {
struct list_head backlog;
struct hisi_acc_sgl_pool *c_in_pool;
struct hisi_acc_sgl_pool *c_out_pool;
- atomic_t pending_reqs;
};
enum sec_alg_type {
@@ -180,7 +179,6 @@ struct sec_dev {
struct sec_debug debug;
u32 ctx_q_num;
bool iommu_used;
- unsigned long status;
};
void sec_destroy_qps(struct hisi_qp **qps, int qp_num);
diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c
index bb493423668c..2eaa516b3231 100644
--- a/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -7,7 +7,8 @@
#include <crypto/des.h>
#include <crypto/hash.h>
#include <crypto/internal/aead.h>
-#include <crypto/sha.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
#include <crypto/skcipher.h>
#include <crypto/xts.h>
#include <linux/crypto.h>
@@ -101,6 +102,7 @@ static int sec_alloc_req_id(struct sec_req *req, struct sec_qp_ctx *qp_ctx)
req->qp_ctx = qp_ctx;
qp_ctx->req_list[req_id] = req;
+
return req_id;
}
@@ -317,6 +319,7 @@ static int sec_alloc_pbuf_resource(struct device *dev, struct sec_alg_res *res)
j * SEC_PBUF_PKG + pbuf_page_offset;
}
}
+
return 0;
}
@@ -345,12 +348,12 @@ static int sec_alg_resource_alloc(struct sec_ctx *ctx,
}
return 0;
+
alloc_pbuf_fail:
if (ctx->alg_type == SEC_AEAD)
sec_free_mac_resource(dev, qp_ctx->res);
alloc_fail:
sec_free_civ_resource(dev, res);
-
return ret;
}
@@ -419,7 +422,6 @@ err_free_c_in_pool:
hisi_acc_free_sgl_pool(dev, qp_ctx->c_in_pool);
err_destroy_idr:
idr_destroy(&qp_ctx->req_idr);
-
return ret;
}
@@ -557,9 +559,9 @@ static int sec_skcipher_init(struct crypto_skcipher *tfm)
goto err_cipher_init;
return 0;
+
err_cipher_init:
sec_ctx_base_uninit(ctx);
-
return ret;
}
@@ -740,7 +742,6 @@ static void sec_cipher_pbuf_unmap(struct sec_ctx *ctx, struct sec_req *req,
if (unlikely(pbuf_length != copy_size))
dev_err(dev, "copy pbuf data to dst error!\n");
-
}
static int sec_cipher_map(struct sec_ctx *ctx, struct sec_req *req,
@@ -857,7 +858,7 @@ static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx,
struct crypto_authenc_keys *keys)
{
struct crypto_shash *hash_tfm = ctx->hash_tfm;
- int blocksize, ret;
+ int blocksize, digestsize, ret;
if (!keys->authkeylen) {
pr_err("hisi_sec2: aead auth key error!\n");
@@ -865,6 +866,7 @@ static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx,
}
blocksize = crypto_shash_blocksize(hash_tfm);
+ digestsize = crypto_shash_digestsize(hash_tfm);
if (keys->authkeylen > blocksize) {
ret = crypto_shash_tfm_digest(hash_tfm, keys->authkey,
keys->authkeylen, ctx->a_key);
@@ -872,7 +874,7 @@ static int sec_aead_auth_set_key(struct sec_auth_ctx *ctx,
pr_err("hisi_sec2: aead auth digest error!\n");
return -EINVAL;
}
- ctx->a_key_len = blocksize;
+ ctx->a_key_len = digestsize;
} else {
memcpy(ctx->a_key, keys->authkey, keys->authkeylen);
ctx->a_key_len = keys->authkeylen;
@@ -913,9 +915,9 @@ static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
}
return 0;
+
bad_key:
memzero_explicit(&keys, sizeof(struct crypto_authenc_keys));
-
return -EINVAL;
}
@@ -966,7 +968,6 @@ static int sec_request_transfer(struct sec_ctx *ctx, struct sec_req *req)
unmap_req_buf:
ctx->req_op->buf_unmap(ctx, req);
-
return ret;
}
@@ -1107,7 +1108,6 @@ static void sec_skcipher_callback(struct sec_ctx *ctx, struct sec_req *req,
atomic64_inc(&ctx->sec->debug.dfx.recv_busy_cnt);
}
-
sk_req->base.complete(&sk_req->base, err);
}
@@ -1279,7 +1279,6 @@ err_send_req:
sec_request_untransfer(ctx, req);
err_uninit_req:
sec_request_uninit(ctx, req);
-
return ret;
}
@@ -1349,7 +1348,6 @@ err_cipher_init:
sec_auth_uninit(ctx);
err_auth_init:
sec_ctx_base_uninit(ctx);
-
return ret;
}
@@ -1437,8 +1435,8 @@ static int sec_skcipher_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
}
return 0;
}
-
dev_err(dev, "skcipher algorithm error!\n");
+
return -EINVAL;
}
@@ -1554,7 +1552,6 @@ static int sec_aead_param_check(struct sec_ctx *ctx, struct sec_req *sreq)
if (unlikely(c_alg != SEC_CALG_AES)) {
dev_err(SEC_CTX_DEV(ctx), "aead crypto alg error!\n");
return -EINVAL;
-
}
if (sreq->c_req.encrypt)
sreq->c_req.c_len = req->cryptlen;
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
index 548896394c4b..b35c1c2271a3 100644
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -652,20 +652,16 @@ static int sec_debugfs_init(struct hisi_qm *qm)
sec_debugfs_root);
qm->debug.sqe_mask_offset = SEC_SQE_MASK_OFFSET;
qm->debug.sqe_mask_len = SEC_SQE_MASK_LEN;
- ret = hisi_qm_debug_init(qm);
- if (ret)
- goto failed_to_create;
+ hisi_qm_debug_init(qm);
ret = sec_debug_init(qm);
if (ret)
goto failed_to_create;
-
return 0;
failed_to_create:
debugfs_remove_recursive(sec_debugfs_root);
-
return ret;
}
@@ -683,13 +679,13 @@ static void sec_log_hw_error(struct hisi_qm *qm, u32 err_sts)
while (errs->msg) {
if (errs->int_msk & err_sts) {
dev_err(dev, "%s [error status=0x%x] found\n",
- errs->msg, errs->int_msk);
+ errs->msg, errs->int_msk);
if (SEC_CORE_INT_STATUS_M_ECC & errs->int_msk) {
err_val = readl(qm->io_base +
SEC_CORE_SRAM_ECC_ERR_INFO);
dev_err(dev, "multi ecc sram num=0x%x\n",
- SEC_ECC_NUM(err_val));
+ SEC_ECC_NUM(err_val));
}
}
errs++;
@@ -724,13 +720,13 @@ static const struct hisi_qm_err_ini sec_err_ini = {
.log_dev_hw_err = sec_log_hw_error,
.open_axi_master_ooo = sec_open_axi_master_ooo,
.err_info = {
- .ce = QM_BASE_CE,
- .nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT |
- QM_ACC_WB_NOT_READY_TIMEOUT,
- .fe = 0,
- .ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC,
- .msi_wr_port = BIT(0),
- .acpi_rst = "SRST",
+ .ce = QM_BASE_CE,
+ .nfe = QM_BASE_NFE | QM_ACC_DO_TASK_TIMEOUT |
+ QM_ACC_WB_NOT_READY_TIMEOUT,
+ .fe = 0,
+ .ecc_2bits_mask = SEC_CORE_INT_STATUS_M_ECC,
+ .msi_wr_port = BIT(0),
+ .acpi_rst = "SRST",
}
};
@@ -899,17 +895,13 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_alg_unregister:
hisi_qm_alg_unregister(qm, &sec_devices);
-
err_qm_stop:
sec_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL);
-
err_probe_uninit:
sec_probe_uninit(qm);
-
err_qm_uninit:
sec_qm_uninit(qm);
-
return ret;
}
@@ -936,9 +928,9 @@ static void sec_remove(struct pci_dev *pdev)
static const struct pci_error_handlers sec_err_handler = {
.error_detected = hisi_qm_dev_err_detected,
- .slot_reset = hisi_qm_dev_slot_reset,
- .reset_prepare = hisi_qm_reset_prepare,
- .reset_done = hisi_qm_reset_done,
+ .slot_reset = hisi_qm_dev_slot_reset,
+ .reset_prepare = hisi_qm_reset_prepare,
+ .reset_done = hisi_qm_reset_done,
};
static struct pci_driver sec_pci_driver = {
diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c
index 725a739800b0..3bff6394acaf 100644
--- a/drivers/crypto/hisilicon/sgl.c
+++ b/drivers/crypto/hisilicon/sgl.c
@@ -246,8 +246,6 @@ EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl);
* @dev: The device which hw sgl belongs to.
* @sgl: Related scatterlist.
* @hw_sgl: Virtual address of hw sgl.
- * @hw_sgl_dma: DMA address of hw sgl.
- * @pool: Pool which hw sgl is allocated in.
*
* This function unmaps allocated hw sgl.
*/
diff --git a/drivers/crypto/hisilicon/trng/Makefile b/drivers/crypto/hisilicon/trng/Makefile
new file mode 100644
index 000000000000..d909079f351c
--- /dev/null
+++ b/drivers/crypto/hisilicon/trng/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_HISI_TRNG) += hisi-trng-v2.o
+hisi-trng-v2-objs = trng.o
diff --git a/drivers/crypto/hisilicon/trng/trng.c b/drivers/crypto/hisilicon/trng/trng.c
new file mode 100644
index 000000000000..29712685498a
--- /dev/null
+++ b/drivers/crypto/hisilicon/trng/trng.c
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 HiSilicon Limited. */
+
+#include <linux/acpi.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <crypto/internal/rng.h>
+
+#define HISI_TRNG_REG 0x00F0
+#define HISI_TRNG_BYTES 4
+#define HISI_TRNG_QUALITY 512
+#define SLEEP_US 10
+#define TIMEOUT_US 10000
+#define SW_DRBG_NUM_SHIFT 2
+#define SW_DRBG_KEY_BASE 0x082C
+#define SW_DRBG_SEED(n) (SW_DRBG_KEY_BASE - ((n) << SW_DRBG_NUM_SHIFT))
+#define SW_DRBG_SEED_REGS_NUM 12
+#define SW_DRBG_SEED_SIZE 48
+#define SW_DRBG_BLOCKS 0x0830
+#define SW_DRBG_INIT 0x0834
+#define SW_DRBG_GEN 0x083c
+#define SW_DRBG_STATUS 0x0840
+#define SW_DRBG_BLOCKS_NUM 4095
+#define SW_DRBG_DATA_BASE 0x0850
+#define SW_DRBG_DATA_NUM 4
+#define SW_DRBG_DATA(n) (SW_DRBG_DATA_BASE - ((n) << SW_DRBG_NUM_SHIFT))
+#define SW_DRBG_BYTES 16
+#define SW_DRBG_ENABLE_SHIFT 12
+#define SEED_SHIFT_24 24
+#define SEED_SHIFT_16 16
+#define SEED_SHIFT_8 8
+
+struct hisi_trng_list {
+ struct mutex lock;
+ struct list_head list;
+ bool is_init;
+};
+
+struct hisi_trng {
+ void __iomem *base;
+ struct hisi_trng_list *trng_list;
+ struct list_head list;
+ struct hwrng rng;
+ bool is_used;
+ struct mutex mutex;
+};
+
+struct hisi_trng_ctx {
+ struct hisi_trng *trng;
+};
+
+static atomic_t trng_active_devs;
+static struct hisi_trng_list trng_devices;
+
+static void hisi_trng_set_seed(struct hisi_trng *trng, const u8 *seed)
+{
+ u32 val, seed_reg, i;
+
+ for (i = 0; i < SW_DRBG_SEED_SIZE;
+ i += SW_DRBG_SEED_SIZE / SW_DRBG_SEED_REGS_NUM) {
+ val = seed[i] << SEED_SHIFT_24;
+ val |= seed[i + 1UL] << SEED_SHIFT_16;
+ val |= seed[i + 2UL] << SEED_SHIFT_8;
+ val |= seed[i + 3UL];
+
+ seed_reg = (i >> SW_DRBG_NUM_SHIFT) % SW_DRBG_SEED_REGS_NUM;
+ writel(val, trng->base + SW_DRBG_SEED(seed_reg));
+ }
+}
+
+static int hisi_trng_seed(struct crypto_rng *tfm, const u8 *seed,
+ unsigned int slen)
+{
+ struct hisi_trng_ctx *ctx = crypto_rng_ctx(tfm);
+ struct hisi_trng *trng = ctx->trng;
+ u32 val = 0;
+ int ret = 0;
+
+ if (slen < SW_DRBG_SEED_SIZE) {
+ pr_err("slen(%u) is not matched with trng(%d)\n", slen,
+ SW_DRBG_SEED_SIZE);
+ return -EINVAL;
+ }
+
+ writel(0x0, trng->base + SW_DRBG_BLOCKS);
+ hisi_trng_set_seed(trng, seed);
+
+ writel(SW_DRBG_BLOCKS_NUM | (0x1 << SW_DRBG_ENABLE_SHIFT),
+ trng->base + SW_DRBG_BLOCKS);
+ writel(0x1, trng->base + SW_DRBG_INIT);
+
+ ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS,
+ val, val & BIT(0), SLEEP_US, TIMEOUT_US);
+ if (ret)
+ pr_err("fail to init trng(%d)\n", ret);
+
+ return ret;
+}
+
+static int hisi_trng_generate(struct crypto_rng *tfm, const u8 *src,
+ unsigned int slen, u8 *dstn, unsigned int dlen)
+{
+ struct hisi_trng_ctx *ctx = crypto_rng_ctx(tfm);
+ struct hisi_trng *trng = ctx->trng;
+ u32 data[SW_DRBG_DATA_NUM];
+ u32 currsize = 0;
+ u32 val = 0;
+ int ret;
+ u32 i;
+
+ if (dlen > SW_DRBG_BLOCKS_NUM * SW_DRBG_BYTES || dlen == 0) {
+ pr_err("dlen(%d) exceeds limit(%d)!\n", dlen,
+ SW_DRBG_BLOCKS_NUM * SW_DRBG_BYTES);
+ return -EINVAL;
+ }
+
+ do {
+ ret = readl_relaxed_poll_timeout(trng->base + SW_DRBG_STATUS,
+ val, val & BIT(1), SLEEP_US, TIMEOUT_US);
+ if (ret) {
+ pr_err("fail to generate random number(%d)!\n", ret);
+ break;
+ }
+
+ for (i = 0; i < SW_DRBG_DATA_NUM; i++)
+ data[i] = readl(trng->base + SW_DRBG_DATA(i));
+
+ if (dlen - currsize >= SW_DRBG_BYTES) {
+ memcpy(dstn + currsize, data, SW_DRBG_BYTES);
+ currsize += SW_DRBG_BYTES;
+ } else {
+ memcpy(dstn + currsize, data, dlen - currsize);
+ currsize = dlen;
+ }
+
+ writel(0x1, trng->base + SW_DRBG_GEN);
+ } while (currsize < dlen);
+
+ return ret;
+}
+
+static int hisi_trng_init(struct crypto_tfm *tfm)
+{
+ struct hisi_trng_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct hisi_trng *trng;
+ int ret = -EBUSY;
+
+ mutex_lock(&trng_devices.lock);
+ list_for_each_entry(trng, &trng_devices.list, list) {
+ if (!trng->is_used) {
+ trng->is_used = true;
+ ctx->trng = trng;
+ ret = 0;
+ break;
+ }
+ }
+ mutex_unlock(&trng_devices.lock);
+
+ return ret;
+}
+
+static void hisi_trng_exit(struct crypto_tfm *tfm)
+{
+ struct hisi_trng_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ mutex_lock(&trng_devices.lock);
+ ctx->trng->is_used = false;
+ mutex_unlock(&trng_devices.lock);
+}
+
+static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ struct hisi_trng *trng;
+ int currsize = 0;
+ u32 val = 0;
+ u32 ret;
+
+ trng = container_of(rng, struct hisi_trng, rng);
+
+ do {
+ ret = readl_poll_timeout(trng->base + HISI_TRNG_REG, val,
+ val, SLEEP_US, TIMEOUT_US);
+ if (ret)
+ return currsize;
+
+ if (max - currsize >= HISI_TRNG_BYTES) {
+ memcpy(buf + currsize, &val, HISI_TRNG_BYTES);
+ currsize += HISI_TRNG_BYTES;
+ if (currsize == max)
+ return currsize;
+ continue;
+ }
+
+ /* copy remaining bytes */
+ memcpy(buf + currsize, &val, max - currsize);
+ currsize = max;
+ } while (currsize < max);
+
+ return currsize;
+}
+
+static struct rng_alg hisi_trng_alg = {
+ .generate = hisi_trng_generate,
+ .seed = hisi_trng_seed,
+ .seedsize = SW_DRBG_SEED_SIZE,
+ .base = {
+ .cra_name = "stdrng",
+ .cra_driver_name = "hisi_stdrng",
+ .cra_priority = 300,
+ .cra_ctxsize = sizeof(struct hisi_trng_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = hisi_trng_init,
+ .cra_exit = hisi_trng_exit,
+ },
+};
+
+static void hisi_trng_add_to_list(struct hisi_trng *trng)
+{
+ mutex_lock(&trng_devices.lock);
+ list_add_tail(&trng->list, &trng_devices.list);
+ mutex_unlock(&trng_devices.lock);
+}
+
+static int hisi_trng_del_from_list(struct hisi_trng *trng)
+{
+ int ret = -EBUSY;
+
+ mutex_lock(&trng_devices.lock);
+ if (!trng->is_used) {
+ list_del(&trng->list);
+ ret = 0;
+ }
+ mutex_unlock(&trng_devices.lock);
+
+ return ret;
+}
+
+static int hisi_trng_probe(struct platform_device *pdev)
+{
+ struct hisi_trng *trng;
+ int ret;
+
+ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
+ if (!trng)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, trng);
+
+ trng->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(trng->base))
+ return PTR_ERR(trng->base);
+
+ trng->is_used = false;
+ if (!trng_devices.is_init) {
+ INIT_LIST_HEAD(&trng_devices.list);
+ mutex_init(&trng_devices.lock);
+ trng_devices.is_init = true;
+ }
+
+ hisi_trng_add_to_list(trng);
+ if (atomic_inc_return(&trng_active_devs) == 1) {
+ ret = crypto_register_rng(&hisi_trng_alg);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to register crypto(%d)\n", ret);
+ atomic_dec_return(&trng_active_devs);
+ goto err_remove_from_list;
+ }
+ }
+
+ trng->rng.name = pdev->name;
+ trng->rng.read = hisi_trng_read;
+ trng->rng.quality = HISI_TRNG_QUALITY;
+ ret = devm_hwrng_register(&pdev->dev, &trng->rng);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register hwrng: %d!\n", ret);
+ goto err_crypto_unregister;
+ }
+
+ return ret;
+
+err_crypto_unregister:
+ if (atomic_dec_return(&trng_active_devs) == 0)
+ crypto_unregister_rng(&hisi_trng_alg);
+
+err_remove_from_list:
+ hisi_trng_del_from_list(trng);
+ return ret;
+}
+
+static int hisi_trng_remove(struct platform_device *pdev)
+{
+ struct hisi_trng *trng = platform_get_drvdata(pdev);
+
+ /* Wait until the task is finished */
+ while (hisi_trng_del_from_list(trng))
+ ;
+
+ if (atomic_dec_return(&trng_active_devs) == 0)
+ crypto_unregister_rng(&hisi_trng_alg);
+
+ return 0;
+}
+
+static const struct acpi_device_id hisi_trng_acpi_match[] = {
+ { "HISI02B3", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(acpi, hisi_trng_acpi_match);
+
+static struct platform_driver hisi_trng_driver = {
+ .probe = hisi_trng_probe,
+ .remove = hisi_trng_remove,
+ .driver = {
+ .name = "hisi-trng-v2",
+ .acpi_match_table = ACPI_PTR(hisi_trng_acpi_match),
+ },
+};
+
+module_platform_driver(hisi_trng_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Weili Qian <qianweili@huawei.com>");
+MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com>");
+MODULE_DESCRIPTION("HiSilicon true random number generator V2 driver");
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index 4bd2c811abba..4fb5a32bf830 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -590,9 +590,7 @@ static int hisi_zip_debugfs_init(struct hisi_qm *qm)
qm->debug.sqe_mask_offset = HZIP_SQE_MASK_OFFSET;
qm->debug.sqe_mask_len = HZIP_SQE_MASK_LEN;
qm->debug.debug_root = dev_d;
- ret = hisi_qm_debug_init(qm);
- if (ret)
- goto failed_to_create;
+ hisi_qm_debug_init(qm);
if (qm->fun_type == QM_HW_PF) {
ret = hisi_zip_ctrl_debug_init(qm);
@@ -749,6 +747,8 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
+ int ret;
+
qm->pdev = pdev;
qm->ver = pdev->revision;
qm->algs = "zlib\ngzip";
@@ -774,7 +774,25 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;
}
- return hisi_qm_init(qm);
+ 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, "fail to alloc workqueue\n");
+ return -ENOMEM;
+ }
+
+ ret = hisi_qm_init(qm);
+ if (ret)
+ destroy_workqueue(qm->wq);
+
+ return ret;
+}
+
+static void hisi_zip_qm_uninit(struct hisi_qm *qm)
+{
+ hisi_qm_uninit(qm);
+ destroy_workqueue(qm->wq);
}
static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
@@ -856,7 +874,7 @@ err_dev_err_uninit:
hisi_qm_dev_err_uninit(qm);
err_qm_uninit:
- hisi_qm_uninit(qm);
+ hisi_zip_qm_uninit(qm);
return ret;
}
@@ -874,7 +892,7 @@ static void hisi_zip_remove(struct pci_dev *pdev)
hisi_zip_debugfs_exit(qm);
hisi_qm_stop(qm, QM_NORMAL);
hisi_qm_dev_err_uninit(qm);
- hisi_qm_uninit(qm);
+ hisi_zip_qm_uninit(qm);
}
static const struct pci_error_handlers hisi_zip_err_handler = {