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

crypto: hisilicon/qm - fix the pf2vf timeout when global reset

driver inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I9CB6L


CVE: NA

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

When funcitons communicate with each other, if the mailbox operation fails,
funciton cannot obtain the message from the communication source.
If the vf does not receive the message from pf to stop function when reset,
it will cause the vf to be unavailable.

For the global reset scenario:
1. Increase the QM_DEVICE_DOWN state. Before IO operation,
check the state to avoid mailbox busy during communication.
2. When vf obtains pf message, if the mailbox fails, it is
considered to be a global reset, and stop function directly.
When pf sends reset message to vf, if the mailbox fails, it
still send interrupt event to vf.
3. Increase the response time of PF waiting for vf.

Signed-off-by: default avatarWeili Qian <qianweili@huawei.com>
Signed-off-by: default avatarJiangShui Yang <yangjiangshui@h-partners.com>
parent 80a16e23
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
@@ -187,9 +187,9 @@
#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_WAIT_DST_ACK			100
#define QM_MAX_PF_WAIT_COUNT		50
#define QM_MAX_VF_WAIT_COUNT		100
#define QM_VF_RESET_WAIT_US            20000
#define QM_VF_RESET_WAIT_CNT           3000
#define QM_VF_RESET_WAIT_TIMEOUT_US    \
@@ -1707,8 +1707,8 @@ static int qm_ping_all_vfs(struct hisi_qm *qm, u64 cmd)
	mutex_lock(&qm->mailbox_lock);
	/* PF sends command to all VFs by mailbox */
	ret = qm_mb_nolock(qm, &mailbox);
	if (ret) {
		dev_err(dev, "failed to send command to VFs!\n");
	if (ret && cmd != QM_PF_FLR_PREPARE && cmd != QM_PF_SRST_PREPARE) {
		dev_err(dev, "failed to send command to all vfs, cmd = %llu!\n", cmd);
		mutex_unlock(&qm->mailbox_lock);
		return ret;
	}
@@ -1748,8 +1748,8 @@ static int qm_ping_pf(struct hisi_qm *qm, u64 cmd)
	qm_mb_pre_init(&mailbox, QM_MB_CMD_SRC, cmd, 0, 0);
	mutex_lock(&qm->mailbox_lock);
	ret = qm_mb_nolock(qm, &mailbox);
	if (ret) {
		dev_err(&qm->pdev->dev, "failed to send command to PF!\n");
	if (ret && (cmd > QM_VF_START_FAIL || cmd < QM_VF_PREPARE_DONE)) {
		dev_err(&qm->pdev->dev, "failed to send command to PF, cmd = %llu!\n", cmd);
		goto unlock;
	}

@@ -1758,8 +1758,10 @@ static int qm_ping_pf(struct hisi_qm *qm, u64 cmd)
	while (true) {
		msleep(QM_WAIT_DST_ACK);
		val = readl(qm->io_base + QM_IFC_INT_SET_V);
		if (!(val & QM_IFC_INT_STATUS_MASK))
		if (!(val & QM_IFC_INT_STATUS_MASK)) {
			ret = 0;
			break;
		}

		if (++cnt > QM_MAX_VF_WAIT_COUNT) {
			ret = -ETIMEDOUT;
@@ -4902,9 +4904,14 @@ static void qm_handle_cmd_msg(struct hisi_qm *qm, u32 fun_num)
	ret = hisi_qm_mb_read(qm, &msg, QM_MB_CMD_DST, fun_num);
	qm_clear_cmd_interrupt(qm, BIT(fun_num));
	if (ret) {
		if (!fun_num) {
			msg = QM_PF_SRST_PREPARE;
			dev_err(dev, "failed to get response from PF, suppos it is soft reset!\n");
		} else {
			dev_err(dev, "failed to get msg from source!\n");
			return;
		}
	}

	cmd = msg & QM_MB_CMD_DATA_MASK;
	switch (cmd) {