Torsten Duwe de04ed
From 03125541ca29fda7b98bea08dfed68ae0e39b46c Mon Sep 17 00:00:00 2001
Torsten Duwe de04ed
From: Marco Chiappero <marco.chiappero@intel.com>
Torsten Duwe de04ed
Date: Thu, 16 Dec 2021 09:13:15 +0000
Torsten Duwe de04ed
Subject: [PATCH] crypto: qat - support the reset of ring pairs on PF
Torsten Duwe de04ed
Git-commit: 03125541ca29fda7b98bea08dfed68ae0e39b46c
Torsten Duwe de04ed
Patch-mainline: v5.17-rc1
Torsten Duwe de04ed
References: jsc#PED-1073
Torsten Duwe de04ed
Torsten Duwe de04ed
Add support for triggering a HW reset of a specific ring pair.
Torsten Duwe de04ed
Being a device specific feature, add it to the hw_device_data struct.
Torsten Duwe de04ed
Torsten Duwe de04ed
This feature is supported only by QAT GEN4 devices.
Torsten Duwe de04ed
Torsten Duwe de04ed
This patch is based on earlier work done by Zelin Deng.
Torsten Duwe de04ed
Torsten Duwe de04ed
Signed-off-by: Marco Chiappero <marco.chiappero@intel.com>
Torsten Duwe de04ed
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe de04ed
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe de04ed
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Torsten Duwe de04ed
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe de04ed
Signed-off-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe de04ed
Torsten Duwe de04ed
---
Torsten Duwe de04ed
 .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c    |  2 +
Torsten Duwe de04ed
 .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h    |  1 +
Torsten Duwe de04ed
 .../crypto/qat/qat_common/adf_accel_devices.h |  2 +
Torsten Duwe de04ed
 .../crypto/qat/qat_common/adf_gen4_hw_data.c  | 53 +++++++++++++++++++
Torsten Duwe de04ed
 .../crypto/qat/qat_common/adf_gen4_hw_data.h  |  9 ++++
Torsten Duwe de04ed
 5 files changed, 67 insertions(+)
Torsten Duwe de04ed
Torsten Duwe de04ed
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
Torsten Duwe de04ed
index d320c50c4561c..0d1603894af44 100644
Torsten Duwe de04ed
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
Torsten Duwe de04ed
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
Torsten Duwe de04ed
@@ -239,6 +239,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
Torsten Duwe de04ed
 	hw_data->dev_class = &adf_4xxx_class;
Torsten Duwe de04ed
 	hw_data->instance_id = adf_4xxx_class.instances++;
Torsten Duwe de04ed
 	hw_data->num_banks = ADF_4XXX_ETR_MAX_BANKS;
Torsten Duwe de04ed
+	hw_data->num_banks_per_vf = ADF_4XXX_NUM_BANKS_PER_VF;
Torsten Duwe de04ed
 	hw_data->num_rings_per_bank = ADF_4XXX_NUM_RINGS_PER_BANK;
Torsten Duwe de04ed
 	hw_data->num_accel = ADF_4XXX_MAX_ACCELERATORS;
Torsten Duwe de04ed
 	hw_data->num_engines = ADF_4XXX_MAX_ACCELENGINES;
Torsten Duwe de04ed
@@ -279,6 +280,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
Torsten Duwe de04ed
 	hw_data->pfvf_ops.enable_comms = adf_pfvf_comms_disabled;
Torsten Duwe de04ed
 	hw_data->pfvf_ops.get_vf2pf_sources = get_vf2pf_sources;
Torsten Duwe de04ed
 	hw_data->disable_iov = adf_disable_sriov;
Torsten Duwe de04ed
+	hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;
Torsten Duwe de04ed
 
Torsten Duwe de04ed
 	adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
Torsten Duwe de04ed
 }
Torsten Duwe de04ed
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
Torsten Duwe de04ed
index 924bac6feb372..a0c67752317f1 100644
Torsten Duwe de04ed
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
Torsten Duwe de04ed
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
Torsten Duwe de04ed
@@ -37,6 +37,7 @@
Torsten Duwe de04ed
 
Torsten Duwe de04ed
 /* Bank and ring configuration */
Torsten Duwe de04ed
 #define ADF_4XXX_NUM_RINGS_PER_BANK	2
Torsten Duwe de04ed
+#define ADF_4XXX_NUM_BANKS_PER_VF	4
Torsten Duwe de04ed
 
Torsten Duwe de04ed
 /* Error source registers */
Torsten Duwe de04ed
 #define ADF_4XXX_ERRSOU0	(0x41A200)
Torsten Duwe de04ed
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe de04ed
index 2c380fa10a094..cc8b10b231452 100644
Torsten Duwe de04ed
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe de04ed
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe de04ed
@@ -186,6 +186,7 @@ struct adf_hw_device_data {
Torsten Duwe de04ed
 				      bool enable);
Torsten Duwe de04ed
 	void (*enable_ints)(struct adf_accel_dev *accel_dev);
Torsten Duwe de04ed
 	void (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev);
Torsten Duwe de04ed
+	int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, u32 bank_nr);
Torsten Duwe de04ed
 	void (*reset_device)(struct adf_accel_dev *accel_dev);
Torsten Duwe de04ed
 	void (*set_msix_rttable)(struct adf_accel_dev *accel_dev);
Torsten Duwe de04ed
 	char *(*uof_get_name)(u32 obj_num);
Torsten Duwe de04ed
@@ -206,6 +207,7 @@ struct adf_hw_device_data {
Torsten Duwe de04ed
 	u16 tx_rings_mask;
Torsten Duwe de04ed
 	u8 tx_rx_gap;
Torsten Duwe de04ed
 	u8 num_banks;
Torsten Duwe de04ed
+	u16 num_banks_per_vf;
Torsten Duwe de04ed
 	u8 num_rings_per_bank;
Torsten Duwe de04ed
 	u8 num_accel;
Torsten Duwe de04ed
 	u8 num_logical_accel;
Torsten Duwe de04ed
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
Torsten Duwe de04ed
index e3157df8a653f..c7808ff2aba1e 100644
Torsten Duwe de04ed
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
Torsten Duwe de04ed
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
Torsten Duwe de04ed
@@ -1,5 +1,6 @@
Torsten Duwe de04ed
 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
Torsten Duwe de04ed
 /* Copyright(c) 2020 Intel Corporation */
Torsten Duwe de04ed
+#include <linux/iopoll.h>
Torsten Duwe de04ed
 #include "adf_accel_devices.h"
Torsten Duwe de04ed
 #include "adf_common_drv.h"
Torsten Duwe de04ed
 #include "adf_gen4_hw_data.h"
Torsten Duwe de04ed
@@ -146,3 +147,55 @@ int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev)
Torsten Duwe de04ed
 	return 0;
Torsten Duwe de04ed
 }
Torsten Duwe de04ed
 EXPORT_SYMBOL_GPL(adf_pfvf_comms_disabled);
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+static int reset_ring_pair(void __iomem *csr, u32 bank_number)
Torsten Duwe de04ed
+{
Torsten Duwe de04ed
+	u32 status;
Torsten Duwe de04ed
+	int ret;
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	/* Write rpresetctl register BIT(0) as 1
Torsten Duwe de04ed
+	 * Since rpresetctl registers have no RW fields, no need to preserve
Torsten Duwe de04ed
+	 * values for other bits. Just write directly.
Torsten Duwe de04ed
+	 */
Torsten Duwe de04ed
+	ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETCTL(bank_number),
Torsten Duwe de04ed
+		   ADF_WQM_CSR_RPRESETCTL_RESET);
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	/* Read rpresetsts register and wait for rp reset to complete */
Torsten Duwe de04ed
+	ret = read_poll_timeout(ADF_CSR_RD, status,
Torsten Duwe de04ed
+				status & ADF_WQM_CSR_RPRESETSTS_STATUS,
Torsten Duwe de04ed
+				ADF_RPRESET_POLL_DELAY_US,
Torsten Duwe de04ed
+				ADF_RPRESET_POLL_TIMEOUT_US, true,
Torsten Duwe de04ed
+				csr, ADF_WQM_CSR_RPRESETSTS(bank_number));
Torsten Duwe de04ed
+	if (!ret) {
Torsten Duwe de04ed
+		/* When rp reset is done, clear rpresetsts */
Torsten Duwe de04ed
+		ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETSTS(bank_number),
Torsten Duwe de04ed
+			   ADF_WQM_CSR_RPRESETSTS_STATUS);
Torsten Duwe de04ed
+	}
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	return ret;
Torsten Duwe de04ed
+}
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number)
Torsten Duwe de04ed
+{
Torsten Duwe de04ed
+	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
Torsten Duwe de04ed
+	u32 etr_bar_id = hw_data->get_etr_bar_id(hw_data);
Torsten Duwe de04ed
+	void __iomem *csr;
Torsten Duwe de04ed
+	int ret;
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	if (bank_number >= hw_data->num_banks)
Torsten Duwe de04ed
+		return -EINVAL;
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	dev_dbg(&GET_DEV(accel_dev),
Torsten Duwe de04ed
+		"ring pair reset for bank:%d\n", bank_number);
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	csr = (&GET_BARS(accel_dev)[etr_bar_id])->virt_addr;
Torsten Duwe de04ed
+	ret = reset_ring_pair(csr, bank_number);
Torsten Duwe de04ed
+	if (ret)
Torsten Duwe de04ed
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe de04ed
+			"ring pair reset failed (timeout)\n");
Torsten Duwe de04ed
+	else
Torsten Duwe de04ed
+		dev_dbg(&GET_DEV(accel_dev), "ring pair reset successful\n");
Torsten Duwe de04ed
+
Torsten Duwe de04ed
+	return ret;
Torsten Duwe de04ed
+}
Torsten Duwe de04ed
+EXPORT_SYMBOL_GPL(adf_gen4_ring_pair_reset);
Torsten Duwe de04ed
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
Torsten Duwe de04ed
index b8fca1ff7aab0..449d6a5976a9d 100644
Torsten Duwe de04ed
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
Torsten Duwe de04ed
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
Torsten Duwe de04ed
@@ -106,6 +106,15 @@ do { \
Torsten Duwe de04ed
 #define ADF_SSMWDTPKEL_OFFSET		0x58
Torsten Duwe de04ed
 #define ADF_SSMWDTPKEH_OFFSET		0x60
Torsten Duwe de04ed
 
Torsten Duwe de04ed
+/* Ring reset */
Torsten Duwe de04ed
+#define ADF_RPRESET_POLL_TIMEOUT_US	(5 * USEC_PER_SEC)
Torsten Duwe de04ed
+#define ADF_RPRESET_POLL_DELAY_US	20
Torsten Duwe de04ed
+#define ADF_WQM_CSR_RPRESETCTL_RESET	BIT(0)
Torsten Duwe de04ed
+#define ADF_WQM_CSR_RPRESETCTL(bank)	(0x6000 + ((bank) << 3))
Torsten Duwe de04ed
+#define ADF_WQM_CSR_RPRESETSTS_STATUS	BIT(0)
Torsten Duwe de04ed
+#define ADF_WQM_CSR_RPRESETSTS(bank)	(ADF_WQM_CSR_RPRESETCTL(bank) + 4)
Torsten Duwe de04ed
+
Torsten Duwe de04ed
 void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev);
Torsten Duwe de04ed
 void adf_gen4_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops);
Torsten Duwe de04ed
+int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number);
Torsten Duwe de04ed
 #endif
Torsten Duwe de04ed
-- 
Torsten Duwe de04ed
2.35.3
Torsten Duwe de04ed