Torsten Duwe 7453a1
From 673184a2a58f93f0c170d30247155b3f86ba69ee Mon Sep 17 00:00:00 2001
Torsten Duwe 7453a1
From: Marco Chiappero <marco.chiappero@intel.com>
Torsten Duwe 7453a1
Date: Thu, 16 Dec 2021 09:13:26 +0000
Torsten Duwe 7453a1
Subject: [PATCH] crypto: qat - introduce support for PFVF block messages
Torsten Duwe 7453a1
Git-commit: 673184a2a58f93f0c170d30247155b3f86ba69ee
Torsten Duwe 7453a1
Patch-mainline: v5.17-rc1
Torsten Duwe 7453a1
References: jsc#PED-1073
Torsten Duwe 7453a1
Torsten Duwe 7453a1
GEN2 devices use a single CSR for PFVF messages, which leaves up to 10 bits
Torsten Duwe 7453a1
of payload per single message. While such amount is sufficient for the
Torsten Duwe 7453a1
currently defined messages, the transfer of bigger and more complex data
Torsten Duwe 7453a1
streams from the PF to the VF requires a new mechanism that extends the
Torsten Duwe 7453a1
protocol.
Torsten Duwe 7453a1
Torsten Duwe 7453a1
This patch adds a new layer on top of the basic PFVF messaging, called
Torsten Duwe 7453a1
Block Messages, to encapsulate up to 126 bytes of data in a single
Torsten Duwe 7453a1
logical message across multiple PFVF messages of new types (SMALL,
Torsten Duwe 7453a1
MEDIUM and LARGE BLOCK), including (sub)types (BLKMSG_TYPE) to carry the
Torsten Duwe 7453a1
information about the actual Block Message.
Torsten Duwe 7453a1
Torsten Duwe 7453a1
Regardless of the size, each Block Message uses a two bytes header,
Torsten Duwe 7453a1
containing the version and size, to allow for extension while
Torsten Duwe 7453a1
maintaining compatibility. The size and the types of Block Messages are
Torsten Duwe 7453a1
defined as follow:
Torsten Duwe 7453a1
Torsten Duwe 7453a1
- small block messages:  up to 16 BLKMSG types of up to 30 bytes
Torsten Duwe 7453a1
- medium block messages: up to 8 BLKMSG types of up to 62 bytes
Torsten Duwe 7453a1
- large block messages:  up to 4 BLKMSG types of up to 126 bytes
Torsten Duwe 7453a1
Torsten Duwe 7453a1
It effectively works as reading a byte at a time from a block device and
Torsten Duwe 7453a1
for each of these new Block Messages:
Torsten Duwe 7453a1
- the requestor (always a VF) can either request a specific byte of the
Torsten Duwe 7453a1
  larger message, in order to retrieve the full message, or request the
Torsten Duwe 7453a1
  value of the CRC calculated for a specific message up to the provided
Torsten Duwe 7453a1
  size (to allow for messages to grow while maintaining forward
Torsten Duwe 7453a1
  compatibility)
Torsten Duwe 7453a1
- the responder (always the PF) will either return a single data or CRC
Torsten Duwe 7453a1
  byte, along with the indication of response type (or error).
Torsten Duwe 7453a1
Torsten Duwe 7453a1
This patch provides the basic infrastructure to perform the above
Torsten Duwe 7453a1
operations, without defining any new message.
Torsten Duwe 7453a1
Torsten Duwe 7453a1
As CRCs are required, this code now depends on the CRC8 module.
Torsten Duwe 7453a1
Torsten Duwe 7453a1
Note: as a consequence of the Block Messages design, sending multiple
Torsten Duwe 7453a1
PFVF messages in bursts, the interrupt rate limiting values on the PF are
Torsten Duwe 7453a1
increased.
Torsten Duwe 7453a1
Torsten Duwe 7453a1
Signed-off-by: Marco Chiappero <marco.chiappero@intel.com>
Torsten Duwe 7453a1
Co-developed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe 7453a1
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe 7453a1
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Torsten Duwe 7453a1
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe 7453a1
Signed-off-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe 7453a1
Torsten Duwe 7453a1
---
Torsten Duwe 7453a1
 drivers/crypto/qat/Kconfig                    |   1 +
Torsten Duwe 7453a1
 drivers/crypto/qat/qat_common/adf_pfvf_msg.h  |  74 +++++++
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_pf_msg.h   |   3 +
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 137 ++++++++++++
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_utils.c    |  15 ++
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_utils.h    |   3 +
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 203 +++++++++++++++++-
Torsten Duwe 7453a1
 .../crypto/qat/qat_common/adf_pfvf_vf_proto.h |   2 +
Torsten Duwe 7453a1
 drivers/crypto/qat/qat_common/adf_sriov.c     |   7 +-
Torsten Duwe 7453a1
 9 files changed, 442 insertions(+), 3 deletions(-)
Torsten Duwe 7453a1
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
Torsten Duwe 7453a1
index 77783feb62b25..4b90c0f22b03f 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/Kconfig
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/Kconfig
Torsten Duwe 7453a1
@@ -13,6 +13,7 @@ config CRYPTO_DEV_QAT
Torsten Duwe 7453a1
 	select CRYPTO_SHA512
Torsten Duwe 7453a1
 	select CRYPTO_LIB_AES
Torsten Duwe 7453a1
 	select FW_LOADER
Torsten Duwe 7453a1
+	select CRC8
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 config CRYPTO_DEV_QAT_DH895xCC
Torsten Duwe 7453a1
 	tristate "Support for Intel(R) DH895xCC"
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
Torsten Duwe 7453a1
index daee3d7ceb8c3..6abbb5e05809f 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
Torsten Duwe 7453a1
@@ -71,6 +71,7 @@ struct pfvf_message {
Torsten Duwe 7453a1
 enum pf2vf_msgtype {
Torsten Duwe 7453a1
 	ADF_PF2VF_MSGTYPE_RESTARTING		= 0x01,
Torsten Duwe 7453a1
 	ADF_PF2VF_MSGTYPE_VERSION_RESP		= 0x02,
Torsten Duwe 7453a1
+	ADF_PF2VF_MSGTYPE_BLKMSG_RESP		= 0x03,
Torsten Duwe 7453a1
 };
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 /* VF->PF messages */
Torsten Duwe 7453a1
@@ -79,6 +80,9 @@ enum vf2pf_msgtype {
Torsten Duwe 7453a1
 	ADF_VF2PF_MSGTYPE_SHUTDOWN		= 0x04,
Torsten Duwe 7453a1
 	ADF_VF2PF_MSGTYPE_VERSION_REQ		= 0x05,
Torsten Duwe 7453a1
 	ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ	= 0x06,
Torsten Duwe 7453a1
+	ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ	= 0x07,
Torsten Duwe 7453a1
+	ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ	= 0x08,
Torsten Duwe 7453a1
+	ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ	= 0x09,
Torsten Duwe 7453a1
 };
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 /* VF/PF compatibility version. */
Torsten Duwe 7453a1
@@ -97,4 +101,74 @@ enum pf2vf_compat_response {
Torsten Duwe 7453a1
 	ADF_PF2VF_VF_COMPAT_UNKNOWN		= 0x03,
Torsten Duwe 7453a1
 };
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+/* PF->VF Block Responses */
Torsten Duwe 7453a1
+#define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK		GENMASK(1, 0)
Torsten Duwe 7453a1
+#define ADF_PF2VF_BLKMSG_RESP_DATA_MASK		GENMASK(9, 2)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+enum pf2vf_blkmsg_resp_type {
Torsten Duwe 7453a1
+	ADF_PF2VF_BLKMSG_RESP_TYPE_DATA		= 0x00,
Torsten Duwe 7453a1
+	ADF_PF2VF_BLKMSG_RESP_TYPE_CRC		= 0x01,
Torsten Duwe 7453a1
+	ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR	= 0x02,
Torsten Duwe 7453a1
+};
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* PF->VF Block Error Code */
Torsten Duwe 7453a1
+enum pf2vf_blkmsg_error {
Torsten Duwe 7453a1
+	ADF_PF2VF_INVALID_BLOCK_TYPE		= 0x00,
Torsten Duwe 7453a1
+	ADF_PF2VF_INVALID_BYTE_NUM_REQ		= 0x01,
Torsten Duwe 7453a1
+	ADF_PF2VF_PAYLOAD_TRUNCATED		= 0x02,
Torsten Duwe 7453a1
+	ADF_PF2VF_UNSPECIFIED_ERROR		= 0x03,
Torsten Duwe 7453a1
+};
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* VF->PF Block Requests */
Torsten Duwe 7453a1
+#define ADF_VF2PF_LARGE_BLOCK_TYPE_MASK		GENMASK(1, 0)
Torsten Duwe 7453a1
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_MASK		GENMASK(8, 2)
Torsten Duwe 7453a1
+#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK	GENMASK(2, 0)
Torsten Duwe 7453a1
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK	GENMASK(8, 3)
Torsten Duwe 7453a1
+#define ADF_VF2PF_SMALL_BLOCK_TYPE_MASK		GENMASK(3, 0)
Torsten Duwe 7453a1
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_MASK		GENMASK(8, 4)
Torsten Duwe 7453a1
+#define ADF_VF2PF_BLOCK_CRC_REQ_MASK		BIT(9)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* PF->VF Block Request Types
Torsten Duwe 7453a1
+ *  0..15 - 32 byte message
Torsten Duwe 7453a1
+ * 16..23 - 64 byte message
Torsten Duwe 7453a1
+ * 24..27 - 128 byte message
Torsten Duwe 7453a1
+ */
Torsten Duwe 7453a1
+/* No block messages as of yet */
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \
Torsten Duwe 7453a1
+		(FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK))
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX \
Torsten Duwe 7453a1
+		(FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK) + \
Torsten Duwe 7453a1
+		ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_LARGE_BLOCK_TYPE_MAX \
Torsten Duwe 7453a1
+		(FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK) + \
Torsten Duwe 7453a1
+		ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_MAX \
Torsten Duwe 7453a1
+		FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX \
Torsten Duwe 7453a1
+		FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_MAX \
Torsten Duwe 7453a1
+		FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK)
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+struct pfvf_blkmsg_header {
Torsten Duwe 7453a1
+	u8 version;
Torsten Duwe 7453a1
+	u8 payload_size;
Torsten Duwe 7453a1
+} __packed;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_HEADER_SIZE		(sizeof(struct pfvf_blkmsg_header))
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_PAYLOAD_SIZE(blkmsg)	(sizeof(blkmsg) - \
Torsten Duwe 7453a1
+							ADF_PFVF_BLKMSG_HEADER_SIZE)
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_MSG_SIZE(blkmsg)	(ADF_PFVF_BLKMSG_HEADER_SIZE + \
Torsten Duwe 7453a1
+							(blkmsg)->hdr.payload_size)
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_MSG_MAX_SIZE		128
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* PF->VF Block message header bytes */
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_VER_BYTE		0
Torsten Duwe 7453a1
+#define ADF_PFVF_BLKMSG_LEN_BYTE		1
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 #endif /* ADF_PFVF_MSG_H */
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
Torsten Duwe 7453a1
index 187807b1ff880..5c669f1de6e4c 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
Torsten Duwe 7453a1
@@ -7,4 +7,7 @@
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
Torsten Duwe 7453a1
+					 u8 *buffer, u8 compat);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 #endif /* ADF_PFVF_PF_MSG_H */
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
Torsten Duwe 7453a1
index f461aa0a95c7e..850b5f4414a69 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
Torsten Duwe 7453a1
@@ -6,7 +6,16 @@
Torsten Duwe 7453a1
 #include "adf_accel_devices.h"
Torsten Duwe 7453a1
 #include "adf_common_drv.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_msg.h"
Torsten Duwe 7453a1
+#include "adf_pfvf_pf_msg.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_pf_proto.h"
Torsten Duwe 7453a1
+#include "adf_pfvf_utils.h"
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+typedef u8 (*pf2vf_blkmsg_data_getter_fn)(u8 const *blkmsg, u8 byte);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = {
Torsten Duwe 7453a1
+	NULL,				  /* no message type defined for value 0 */
Torsten Duwe 7453a1
+	NULL,				  /* no message type defined for value 1 */
Torsten Duwe 7453a1
+};
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 /**
Torsten Duwe 7453a1
  * adf_send_pf2vf_msg() - send PF to VF message
Torsten Duwe 7453a1
@@ -44,6 +53,128 @@ static struct pfvf_message adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u
Torsten Duwe 7453a1
 	return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
Torsten Duwe 7453a1
 }
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+static adf_pf2vf_blkmsg_provider get_blkmsg_response_provider(u8 type)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	if (type >= ARRAY_SIZE(pf2vf_blkmsg_providers))
Torsten Duwe 7453a1
+		return NULL;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	return pf2vf_blkmsg_providers[type];
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* Byte pf2vf_blkmsg_data_getter_fn callback */
Torsten Duwe 7453a1
+static u8 adf_pf2vf_blkmsg_get_byte(u8 const *blkmsg, u8 index)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	return blkmsg[index];
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/* CRC pf2vf_blkmsg_data_getter_fn callback */
Torsten Duwe 7453a1
+static u8 adf_pf2vf_blkmsg_get_crc(u8 const *blkmsg, u8 count)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	/* count is 0-based, turn it into a length */
Torsten Duwe 7453a1
+	return adf_pfvf_calc_blkmsg_crc(blkmsg, count + 1);
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+static int adf_pf2vf_blkmsg_get_data(struct adf_accel_vf_info *vf_info,
Torsten Duwe 7453a1
+				     u8 type, u8 byte, u8 max_size, u8 *data,
Torsten Duwe 7453a1
+				     pf2vf_blkmsg_data_getter_fn data_getter)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	u8 blkmsg[ADF_PFVF_BLKMSG_MSG_MAX_SIZE] = { 0 };
Torsten Duwe 7453a1
+	struct adf_accel_dev *accel_dev = vf_info->accel_dev;
Torsten Duwe 7453a1
+	adf_pf2vf_blkmsg_provider provider;
Torsten Duwe 7453a1
+	u8 msg_size;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	provider = get_blkmsg_response_provider(type);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(!provider)) {
Torsten Duwe 7453a1
+		pr_err("QAT: No registered provider for message %d\n", type);
Torsten Duwe 7453a1
+		*data = ADF_PF2VF_INVALID_BLOCK_TYPE;
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely((*provider)(accel_dev, blkmsg, vf_info->vf_compat_ver))) {
Torsten Duwe 7453a1
+		pr_err("QAT: unknown error from provider for message %d\n", type);
Torsten Duwe 7453a1
+		*data = ADF_PF2VF_UNSPECIFIED_ERROR;
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	msg_size = ADF_PFVF_BLKMSG_HEADER_SIZE + blkmsg[ADF_PFVF_BLKMSG_LEN_BYTE];
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(msg_size >= max_size)) {
Torsten Duwe 7453a1
+		pr_err("QAT: Invalid size %d provided for message type %d\n",
Torsten Duwe 7453a1
+		       msg_size, type);
Torsten Duwe 7453a1
+		*data = ADF_PF2VF_PAYLOAD_TRUNCATED;
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(byte >= msg_size)) {
Torsten Duwe 7453a1
+		pr_err("QAT: Out-of-bound byte number %d (msg size %d)\n",
Torsten Duwe 7453a1
+		       byte, msg_size);
Torsten Duwe 7453a1
+		*data = ADF_PF2VF_INVALID_BYTE_NUM_REQ;
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	*data = data_getter(blkmsg, byte);
Torsten Duwe 7453a1
+	return 0;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info,
Torsten Duwe 7453a1
+					     struct pfvf_message req)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	u8 resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR;
Torsten Duwe 7453a1
+	struct pfvf_message resp = { 0 };
Torsten Duwe 7453a1
+	u8 resp_data = 0;
Torsten Duwe 7453a1
+	u8 blk_type;
Torsten Duwe 7453a1
+	u8 blk_byte;
Torsten Duwe 7453a1
+	u8 byte_max;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	switch (req.type) {
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ:
Torsten Duwe 7453a1
+		blk_type = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, req.data)
Torsten Duwe 7453a1
+			   + ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX + 1;
Torsten Duwe 7453a1
+		blk_byte = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, req.data);
Torsten Duwe 7453a1
+		byte_max = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+		break;
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ:
Torsten Duwe 7453a1
+		blk_type = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, req.data)
Torsten Duwe 7453a1
+			   + ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1;
Torsten Duwe 7453a1
+		blk_byte = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, req.data);
Torsten Duwe 7453a1
+		byte_max = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+		break;
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
Torsten Duwe 7453a1
+		blk_type = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, req.data);
Torsten Duwe 7453a1
+		blk_byte = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, req.data);
Torsten Duwe 7453a1
+		byte_max = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+		break;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* Is this a request for CRC or data? */
Torsten Duwe 7453a1
+	if (FIELD_GET(ADF_VF2PF_BLOCK_CRC_REQ_MASK, req.data)) {
Torsten Duwe 7453a1
+		dev_dbg(&GET_DEV(vf_info->accel_dev),
Torsten Duwe 7453a1
+			"BlockMsg of type %d for CRC over %d bytes received from VF%d\n",
Torsten Duwe 7453a1
+			blk_type, blk_byte, vf_info->vf_nr);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+		if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte,
Torsten Duwe 7453a1
+					       byte_max, &resp_data,
Torsten Duwe 7453a1
+					       adf_pf2vf_blkmsg_get_crc))
Torsten Duwe 7453a1
+			resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_CRC;
Torsten Duwe 7453a1
+	} else {
Torsten Duwe 7453a1
+		dev_dbg(&GET_DEV(vf_info->accel_dev),
Torsten Duwe 7453a1
+			"BlockMsg of type %d for data byte %d received from VF%d\n",
Torsten Duwe 7453a1
+			blk_type, blk_byte, vf_info->vf_nr);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+		if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte,
Torsten Duwe 7453a1
+					       byte_max, &resp_data,
Torsten Duwe 7453a1
+					       adf_pf2vf_blkmsg_get_byte))
Torsten Duwe 7453a1
+			resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_DATA;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	resp.type = ADF_PF2VF_MSGTYPE_BLKMSG_RESP;
Torsten Duwe 7453a1
+	resp.data = FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp_type) |
Torsten Duwe 7453a1
+		    FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp_data);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	return resp;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
Torsten Duwe 7453a1
 				struct pfvf_message msg, struct pfvf_message *resp)
Torsten Duwe 7453a1
 {
Torsten Duwe 7453a1
@@ -106,6 +237,11 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
Torsten Duwe 7453a1
 		vf_info->init = false;
Torsten Duwe 7453a1
 		}
Torsten Duwe 7453a1
 		break;
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ:
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ:
Torsten Duwe 7453a1
+	case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
Torsten Duwe 7453a1
+		*resp = handle_blkmsg_req(vf_info, msg);
Torsten Duwe 7453a1
+		break;
Torsten Duwe 7453a1
 	default:
Torsten Duwe 7453a1
 		dev_dbg(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
 			"Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n",
Torsten Duwe 7453a1
@@ -147,6 +283,7 @@ bool adf_recv_and_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr)
Torsten Duwe 7453a1
  */
Torsten Duwe 7453a1
 int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev)
Torsten Duwe 7453a1
 {
Torsten Duwe 7453a1
+	adf_pfvf_crc_init();
Torsten Duwe 7453a1
 	spin_lock_init(&accel_dev->pf.vf2pf_ints_lock);
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 	return 0;
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.c b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
Torsten Duwe 7453a1
index 494da89e20487..c5f6d77d4bb86 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
Torsten Duwe 7453a1
@@ -1,11 +1,26 @@
Torsten Duwe 7453a1
 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
Torsten Duwe 7453a1
 /* Copyright(c) 2021 Intel Corporation */
Torsten Duwe 7453a1
+#include <linux/crc8.h>
Torsten Duwe 7453a1
 #include <linux/pci.h>
Torsten Duwe 7453a1
 #include <linux/types.h>
Torsten Duwe 7453a1
 #include "adf_accel_devices.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_msg.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_utils.h"
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+/* CRC Calculation */
Torsten Duwe 7453a1
+DECLARE_CRC8_TABLE(pfvf_crc8_table);
Torsten Duwe 7453a1
+#define ADF_PFVF_CRC8_POLYNOMIAL 0x97
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+void adf_pfvf_crc_init(void)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	crc8_populate_msb(pfvf_crc8_table, ADF_PFVF_CRC8_POLYNOMIAL);
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	return crc8(pfvf_crc8_table, buf, buf_len, CRC8_INIT_VALUE);
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 static bool set_value_on_csr_msg(struct adf_accel_dev *accel_dev, u32 *csr_msg,
Torsten Duwe 7453a1
 				 u32 value, const struct pfvf_field_format *fmt)
Torsten Duwe 7453a1
 {
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
Torsten Duwe 7453a1
index 7676fdddbe268..2be048e2287b7 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
Torsten Duwe 7453a1
@@ -10,6 +10,9 @@
Torsten Duwe 7453a1
 #define ADF_PFVF_MSG_ACK_DELAY_US	4
Torsten Duwe 7453a1
 #define ADF_PFVF_MSG_ACK_MAX_DELAY_US	(1 * USEC_PER_SEC)
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len);
Torsten Duwe 7453a1
+void adf_pfvf_crc_init(void);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 struct pfvf_field_format {
Torsten Duwe 7453a1
 	u8  offset;
Torsten Duwe 7453a1
 	u32 mask;
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
Torsten Duwe 7453a1
index 729c00c0d2549..0fdd6b9892d38 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
Torsten Duwe 7453a1
@@ -1,10 +1,13 @@
Torsten Duwe 7453a1
 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
Torsten Duwe 7453a1
 /* Copyright(c) 2015 - 2021 Intel Corporation */
Torsten Duwe 7453a1
+#include <linux/bitfield.h>
Torsten Duwe 7453a1
 #include <linux/completion.h>
Torsten Duwe 7453a1
+#include <linux/minmax.h>
Torsten Duwe 7453a1
 #include <linux/types.h>
Torsten Duwe 7453a1
 #include "adf_accel_devices.h"
Torsten Duwe 7453a1
 #include "adf_common_drv.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_msg.h"
Torsten Duwe 7453a1
+#include "adf_pfvf_utils.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_vf_msg.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_vf_proto.h"
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
@@ -94,6 +97,202 @@ int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
Torsten Duwe 7453a1
 	return 0;
Torsten Duwe 7453a1
 }
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
Torsten Duwe 7453a1
+				     u8 *type, u8 *data)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	struct pfvf_message req = { 0 };
Torsten Duwe 7453a1
+	struct pfvf_message resp = { 0 };
Torsten Duwe 7453a1
+	u8 blk_type;
Torsten Duwe 7453a1
+	u8 blk_byte;
Torsten Duwe 7453a1
+	u8 msg_type;
Torsten Duwe 7453a1
+	u8 max_data;
Torsten Duwe 7453a1
+	int err;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* Convert the block type to {small, medium, large} size category */
Torsten Duwe 7453a1
+	if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) {
Torsten Duwe 7453a1
+		msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ;
Torsten Duwe 7453a1
+		blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type);
Torsten Duwe 7453a1
+		blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data);
Torsten Duwe 7453a1
+		max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+	} else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) {
Torsten Duwe 7453a1
+		msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ;
Torsten Duwe 7453a1
+		blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK,
Torsten Duwe 7453a1
+				      *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX);
Torsten Duwe 7453a1
+		blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data);
Torsten Duwe 7453a1
+		max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+	} else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) {
Torsten Duwe 7453a1
+		msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ;
Torsten Duwe 7453a1
+		blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK,
Torsten Duwe 7453a1
+				      *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX);
Torsten Duwe 7453a1
+		blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data);
Torsten Duwe 7453a1
+		max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
Torsten Duwe 7453a1
+	} else {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type);
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* Sanity check */
Torsten Duwe 7453a1
+	if (*data > max_data) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Invalid byte %s %u for message type %u\n",
Torsten Duwe 7453a1
+			crc ? "count" : "index", *data, *type);
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* Build the block message */
Torsten Duwe 7453a1
+	req.type = msg_type;
Torsten Duwe 7453a1
+	req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	err = adf_send_vf2pf_req(accel_dev, req, &resp);
Torsten Duwe 7453a1
+	if (err)
Torsten Duwe 7453a1
+		return err;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	*type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data);
Torsten Duwe 7453a1
+	*data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	return 0;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type,
Torsten Duwe 7453a1
+				     u8 index, u8 *data)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	int ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index);
Torsten Duwe 7453a1
+	if (ret < 0)
Torsten Duwe 7453a1
+		return ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Unexpected BLKMSG response type %u, byte 0x%x\n",
Torsten Duwe 7453a1
+			type, index);
Torsten Duwe 7453a1
+		return -EFAULT;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	*data = index;
Torsten Duwe 7453a1
+	return 0;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type,
Torsten Duwe 7453a1
+				    u8 bytes, u8 *crc)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	int ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* The count of bytes refers to a length, however shift it to a 0-based
Torsten Duwe 7453a1
+	 * count to avoid overflows. Thus, a request for 0 bytes is technically
Torsten Duwe 7453a1
+	 * valid.
Torsten Duwe 7453a1
+	 */
Torsten Duwe 7453a1
+	--bytes;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes);
Torsten Duwe 7453a1
+	if (ret < 0)
Torsten Duwe 7453a1
+		return ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Unexpected CRC BLKMSG response type %u, crc 0x%x\n",
Torsten Duwe 7453a1
+			type, bytes);
Torsten Duwe 7453a1
+		return  -EFAULT;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	*crc = bytes;
Torsten Duwe 7453a1
+	return 0;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+/**
Torsten Duwe 7453a1
+ * adf_send_vf2pf_blkmsg_req() - retrieve block message
Torsten Duwe 7453a1
+ * @accel_dev:	Pointer to acceleration VF device.
Torsten Duwe 7453a1
+ * @type:	The block message type, see adf_pfvf_msg.h for allowed values
Torsten Duwe 7453a1
+ * @buffer:	input buffer where to place the received data
Torsten Duwe 7453a1
+ * @buffer_len:	buffer length as input, the amount of written bytes on output
Torsten Duwe 7453a1
+ *
Torsten Duwe 7453a1
+ * Request a message of type 'type' over the block message transport.
Torsten Duwe 7453a1
+ * This function will send the required amount block message requests and
Torsten Duwe 7453a1
+ * return the overall content back to the caller through the provided buffer.
Torsten Duwe 7453a1
+ * The buffer should be large enough to contain the requested message type,
Torsten Duwe 7453a1
+ * otherwise the response will be truncated.
Torsten Duwe 7453a1
+ *
Torsten Duwe 7453a1
+ * Return: 0 on success, error code otherwise.
Torsten Duwe 7453a1
+ */
Torsten Duwe 7453a1
+int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
Torsten Duwe 7453a1
+			      u8 *buffer, unsigned int *buffer_len)
Torsten Duwe 7453a1
+{
Torsten Duwe 7453a1
+	unsigned int index;
Torsten Duwe 7453a1
+	unsigned int msg_len;
Torsten Duwe 7453a1
+	int ret;
Torsten Duwe 7453a1
+	u8 remote_crc;
Torsten Duwe 7453a1
+	u8 local_crc;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n",
Torsten Duwe 7453a1
+			type);
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Buffer size too small for a block message\n");
Torsten Duwe 7453a1
+		return -EINVAL;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
Torsten Duwe 7453a1
+					ADF_PFVF_BLKMSG_VER_BYTE,
Torsten Duwe 7453a1
+					&buffer[ADF_PFVF_BLKMSG_VER_BYTE]);
Torsten Duwe 7453a1
+	if (unlikely(ret))
Torsten Duwe 7453a1
+		return ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Invalid version 0 received for block request %u", type);
Torsten Duwe 7453a1
+		return -EFAULT;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
Torsten Duwe 7453a1
+					ADF_PFVF_BLKMSG_LEN_BYTE,
Torsten Duwe 7453a1
+					&buffer[ADF_PFVF_BLKMSG_LEN_BYTE]);
Torsten Duwe 7453a1
+	if (unlikely(ret))
Torsten Duwe 7453a1
+		return ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"Invalid size 0 received for block request %u", type);
Torsten Duwe 7453a1
+		return -EFAULT;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* We need to pick the minimum since there is no way to request a
Torsten Duwe 7453a1
+	 * specific version. As a consequence any scenario is possible:
Torsten Duwe 7453a1
+	 * - PF has a newer (longer) version which doesn't fit in the buffer
Torsten Duwe 7453a1
+	 * - VF expects a newer (longer) version, so we must not ask for
Torsten Duwe 7453a1
+	 *   bytes in excess
Torsten Duwe 7453a1
+	 * - PF and VF share the same version, no problem
Torsten Duwe 7453a1
+	 */
Torsten Duwe 7453a1
+	msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE];
Torsten Duwe 7453a1
+	msg_len = min(*buffer_len, msg_len);
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	/* Get the payload */
Torsten Duwe 7453a1
+	for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) {
Torsten Duwe 7453a1
+		ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index,
Torsten Duwe 7453a1
+						&buffer[index]);
Torsten Duwe 7453a1
+		if (unlikely(ret))
Torsten Duwe 7453a1
+			return ret;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc);
Torsten Duwe 7453a1
+	if (unlikely(ret))
Torsten Duwe 7453a1
+		return ret;
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len);
Torsten Duwe 7453a1
+	if (unlikely(local_crc != remote_crc)) {
Torsten Duwe 7453a1
+		dev_err(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
+			"CRC error on msg type %d. Local %02X, remote %02X\n",
Torsten Duwe 7453a1
+			type, local_crc, remote_crc);
Torsten Duwe 7453a1
+		return -EIO;
Torsten Duwe 7453a1
+	}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
+	*buffer_len = msg_len;
Torsten Duwe 7453a1
+	return 0;
Torsten Duwe 7453a1
+}
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
Torsten Duwe 7453a1
 				 struct pfvf_message msg)
Torsten Duwe 7453a1
 {
Torsten Duwe 7453a1
@@ -104,6 +303,7 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
Torsten Duwe 7453a1
 		adf_pf2vf_handle_pf_restarting(accel_dev);
Torsten Duwe 7453a1
 		return false;
Torsten Duwe 7453a1
 	case ADF_PF2VF_MSGTYPE_VERSION_RESP:
Torsten Duwe 7453a1
+	case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
Torsten Duwe 7453a1
 		dev_dbg(&GET_DEV(accel_dev),
Torsten Duwe 7453a1
 			"Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
Torsten Duwe 7453a1
 			msg.type, msg.data);
Torsten Duwe 7453a1
@@ -135,12 +335,13 @@ bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
Torsten Duwe 7453a1
 /**
Torsten Duwe 7453a1
  * adf_enable_vf2pf_comms() - Function enables communication from vf to pf
Torsten Duwe 7453a1
  *
Torsten Duwe 7453a1
- * @accel_dev: Pointer to acceleration device virtual function.
Torsten Duwe 7453a1
+ * @accel_dev:	Pointer to acceleration device virtual function.
Torsten Duwe 7453a1
  *
Torsten Duwe 7453a1
  * Return: 0 on success, error code otherwise.
Torsten Duwe 7453a1
  */
Torsten Duwe 7453a1
 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
Torsten Duwe 7453a1
 {
Torsten Duwe 7453a1
+	adf_pfvf_crc_init();
Torsten Duwe 7453a1
 	adf_enable_pf2vf_interrupts(accel_dev);
Torsten Duwe 7453a1
 	return adf_vf2pf_request_version(accel_dev);
Torsten Duwe 7453a1
 }
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
Torsten Duwe 7453a1
index e32d1bc3a7404..f6ee9b38c0e10 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
Torsten Duwe 7453a1
@@ -9,6 +9,8 @@
Torsten Duwe 7453a1
 int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg);
Torsten Duwe 7453a1
 int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
Torsten Duwe 7453a1
 		       struct pfvf_message *resp);
Torsten Duwe 7453a1
+int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
Torsten Duwe 7453a1
+			      u8 *buffer, unsigned int *buffer_len);
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev);
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c
Torsten Duwe 7453a1
index 6366622ff8fd1..971a05d624181 100644
Torsten Duwe 7453a1
--- a/drivers/crypto/qat/qat_common/adf_sriov.c
Torsten Duwe 7453a1
+++ b/drivers/crypto/qat/qat_common/adf_sriov.c
Torsten Duwe 7453a1
@@ -8,6 +8,9 @@
Torsten Duwe 7453a1
 #include "adf_cfg.h"
Torsten Duwe 7453a1
 #include "adf_pfvf_pf_msg.h"
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
+#define ADF_VF2PF_RATELIMIT_INTERVAL	8
Torsten Duwe 7453a1
+#define ADF_VF2PF_RATELIMIT_BURST	130
Torsten Duwe 7453a1
+
Torsten Duwe 7453a1
 static struct workqueue_struct *pf2vf_resp_wq;
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 struct adf_pf2vf_resp {
Torsten Duwe 7453a1
@@ -62,8 +65,8 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 		mutex_init(&vf_info->pf2vf_lock);
Torsten Duwe 7453a1
 		ratelimit_state_init(&vf_info->vf2pf_ratelimit,
Torsten Duwe 7453a1
-				     DEFAULT_RATELIMIT_INTERVAL,
Torsten Duwe 7453a1
-				     DEFAULT_RATELIMIT_BURST);
Torsten Duwe 7453a1
+				     ADF_VF2PF_RATELIMIT_INTERVAL,
Torsten Duwe 7453a1
+				     ADF_VF2PF_RATELIMIT_BURST);
Torsten Duwe 7453a1
 	}
Torsten Duwe 7453a1
 
Torsten Duwe 7453a1
 	/* Set Valid bits in AE Thread to PCIe Function Mapping */
Torsten Duwe 7453a1
-- 
Torsten Duwe 7453a1
2.35.3
Torsten Duwe 7453a1