diff mbox series

crypto: hisilicon/qm - add stop queue by hardware

Message ID 1617713762-52120-1-git-send-email-qianweili@huawei.com (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series crypto: hisilicon/qm - add stop queue by hardware | expand

Commit Message

Weili Qian April 6, 2021, 12:56 p.m. UTC
Kunpeng930 could be able to stop queue by writing hardware registers,
which will trigger tasks in device to be flushed out.

In order to be compatible with the kunpeng920 driver, add 'qm_hw_ops_v3' to
adapt Kunpeng930. And 'stop_qp' callback is added in 'qm_hw_ops_v3' to
write hardware registers. Call 'stop_qp' to drain the tasks in device
before releasing queue.

Signed-off-by: Weili Qian <qianweili@huawei.com>
Reviewed-by: Longfang Liu <liulongfang@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

Comments

Herbert Xu April 16, 2021, 11:29 a.m. UTC | #1
On Tue, Apr 06, 2021 at 08:56:02PM +0800, Weili Qian wrote:
> Kunpeng930 could be able to stop queue by writing hardware registers,
> which will trigger tasks in device to be flushed out.
> 
> In order to be compatible with the kunpeng920 driver, add 'qm_hw_ops_v3' to
> adapt Kunpeng930. And 'stop_qp' callback is added in 'qm_hw_ops_v3' to
> write hardware registers. Call 'stop_qp' to drain the tasks in device
> before releasing queue.
> 
> Signed-off-by: Weili Qian <qianweili@huawei.com>
> Reviewed-by: Longfang Liu <liulongfang@huawei.com>
> ---
>  drivers/crypto/hisilicon/qm.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)

Patch applied.  Thanks.
diff mbox series

Patch

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index c91e57a..05f96aa 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -38,6 +38,7 @@ 
 #define QM_MB_CMD_SQC_BT		0x4
 #define QM_MB_CMD_CQC_BT		0x5
 #define QM_MB_CMD_SQC_VFT_V2		0x6
+#define QM_MB_CMD_STOP_QP		0x8
 
 #define QM_MB_CMD_SEND_BASE		0x300
 #define QM_MB_EVENT_SHIFT		8
@@ -349,6 +350,7 @@  struct hisi_qm_hw_ops {
 	void (*hw_error_init)(struct hisi_qm *qm, u32 ce, u32 nfe, u32 fe);
 	void (*hw_error_uninit)(struct hisi_qm *qm);
 	enum acc_err_result (*hw_error_handle)(struct hisi_qm *qm);
+	int (*stop_qp)(struct hisi_qp *qp);
 };
 
 struct qm_dfx_item {
@@ -1711,6 +1713,11 @@  static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
 	return ACC_ERR_RECOVERED;
 }
 
+static int qm_stop_qp(struct hisi_qp *qp)
+{
+	return qm_mb(qp->qm, QM_MB_CMD_STOP_QP, 0, qp->qp_id, 0);
+}
+
 static const struct hisi_qm_hw_ops qm_hw_ops_v1 = {
 	.qm_db = qm_db_v1,
 	.get_irq_num = qm_get_irq_num_v1,
@@ -1726,6 +1733,16 @@  static const struct hisi_qm_hw_ops qm_hw_ops_v2 = {
 	.hw_error_handle = qm_hw_error_handle_v2,
 };
 
+static const struct hisi_qm_hw_ops qm_hw_ops_v3 = {
+	.get_vft = qm_get_vft_v2,
+	.qm_db = qm_db_v2,
+	.get_irq_num = qm_get_irq_num_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,
+	.stop_qp = qm_stop_qp,
+};
+
 static void *qm_get_avail_sqe(struct hisi_qp *qp)
 {
 	struct hisi_qp_status *qp_status = &qp->qp_status;
@@ -2005,6 +2022,14 @@  static int qm_drain_qp(struct hisi_qp *qp)
 	if (qm->err_status.is_qm_ecc_mbit || qm->err_status.is_dev_ecc_mbit)
 		return 0;
 
+	/* Kunpeng930 supports drain qp by device */
+	if (qm->ops->stop_qp) {
+		ret = qm->ops->stop_qp(qp);
+		if (ret)
+			dev_err(dev, "Failed to stop qp(%u)!\n", qp->qp_id);
+		return ret;
+	}
+
 	addr = qm_ctx_alloc(qm, size, &dma_addr);
 	if (IS_ERR(addr)) {
 		dev_err(dev, "Failed to alloc ctx for sqc and cqc!\n");
@@ -2565,8 +2590,10 @@  static void hisi_qm_pre_init(struct hisi_qm *qm)
 
 	if (qm->ver == QM_HW_V1)
 		qm->ops = &qm_hw_ops_v1;
-	else
+	else if (qm->ver == QM_HW_V2)
 		qm->ops = &qm_hw_ops_v2;
+	else
+		qm->ops = &qm_hw_ops_v3;
 
 	pci_set_drvdata(pdev, qm);
 	mutex_init(&qm->mailbox_lock);