Commit 7f97b714 authored by Weili Qian's avatar Weili Qian Committed by JangShui Yang
Browse files

crypto: hisilicon/qm - add stop function by hardware

maillist inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I925L9
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev.git/commit/?id=12b8ae68f50de200c038246c2496822f38b18fe2



----------------------------------------------------------------------

Hardware V3 could be able to drain function by sending mailbox
to hardware which will trigger tasks in device to be flushed out.
When the function is reset, the function can be stopped by this way.

Signed-off-by: default avatarWeili Qian <qianweili@huawei.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarJangShui Yang <yangjiangshui@h-partners.com>
parent 81a3b4cf
Loading
Loading
Loading
Loading
+32 −8
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ 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},
};
@@ -1674,6 +1675,11 @@ static int qm_ping_pf(struct hisi_qm *qm, u64 cmd)
	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);
@@ -2088,7 +2094,8 @@ static int qm_drain_qp(struct hisi_qp *qp)

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

	/*
@@ -2104,11 +2111,14 @@ static int qm_stop_qp_nolock(struct hisi_qp *qp)

	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!\n");
			dev_err(dev, "Failed to drain out data for stopping qp(%u)!\n", qp->qp_id);
	}

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

@@ -3112,16 +3122,29 @@ int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r)

	down_write(&qm->qps_lock);

	qm->status.stop_reason = r;
	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_SOFT_RESET ||
	    qm->status.stop_reason == QM_DOWN) {
	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;
			}
		}

		ret = qm_stop_started_qp(qm);
		if (ret < 0) {
			dev_err(dev, "Failed to stop started qp!\n");
@@ -3141,6 +3164,7 @@ int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r)
	}

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

err_unlock:
	up_write(&qm->qps_lock);
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#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_FLUSH_QM		0x9
#define QM_MB_CMD_SRC                   0xc
#define QM_MB_CMD_DST                   0xd

@@ -151,6 +152,7 @@ enum qm_cap_bits {
	QM_SUPPORT_DB_ISOLATION = 0x0,
	QM_SUPPORT_FUNC_QOS,
	QM_SUPPORT_STOP_QP,
	QM_SUPPORT_STOP_FUNC,
	QM_SUPPORT_MB_COMMAND,
	QM_SUPPORT_SVA_PREFETCH,
	QM_SUPPORT_RPM,