2021-12-16 09:11:12

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 00/24] crypto: qat - PFVF updates and improved GEN4 support

This set mainly revolves around PFVF and support for compression on GEN4
devices.

Along with misc quality improvements to the PFVF code, it includes the
following major changes:
* Improved detection of HW capabilities for both GEN2 and GEN4 devices
* PFVF protocol updates, up to version 4, which include Block Messages
and Fast ACK
* PFVF support for the GEN4 host driver
* Support for enabling and reporting the compression service on GEN4
devices
* Support for Ring Pair reset by VFs on GEN4 devices
* The refactoring of PFVF code to allow for the introduction of GEN4
support

Giovanni Cabiddu (5):
crypto: qat - get compression extended capabilities
crypto: qat - set CIPHER capability for QAT GEN2
crypto: qat - set COMPRESSION capability for QAT GEN2
crypto: qat - extend crypto capability detection for 4xxx
crypto: qat - allow detection of dc capabilities for 4xxx

Marco Chiappero (18):
crypto: qat - support the reset of ring pairs on PF
crypto: qat - add the adf_get_pmisc_base() helper function
crypto: qat - make PFVF message construction direction agnostic
crypto: qat - make PFVF send and receive direction agnostic
crypto: qat - set PFVF_MSGORIGIN just before sending
crypto: qat - abstract PFVF messages with struct pfvf_message
crypto: qat - leverage bitfield.h utils for PFVF messages
crypto: qat - leverage read_poll_timeout in PFVF send
crypto: qat - improve the ACK timings in PFVF send
crypto: qat - store the PFVF protocol version of the endpoints
crypto: qat - store the ring-to-service mapping
crypto: qat - introduce support for PFVF block messages
crypto: qat - exchange device capabilities over PFVF
crypto: qat - support fast ACKs in the PFVF protocol
crypto: qat - exchange ring-to-service mappings over PFVF
crypto: qat - config VFs based on ring-to-svc mapping
crypto: qat - add PFVF support to the GEN4 host driver
crypto: qat - add PFVF support to enable the reset of ring pairs

Tomasz Kowalik (1):
crypto: qat - add support for compression for 4xxx

drivers/crypto/qat/Kconfig | 1 +
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 145 ++++++--
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 2 +
drivers/crypto/qat/qat_4xxx/adf_drv.c | 33 ++
.../crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c | 1 +
.../qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 1 +
drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 4 -
.../crypto/qat/qat_c62x/adf_c62x_hw_data.c | 1 +
.../qat/qat_c62xvf/adf_c62xvf_hw_data.c | 1 +
drivers/crypto/qat/qat_c62xvf/adf_drv.c | 4 -
drivers/crypto/qat/qat_common/Makefile | 4 +-
.../crypto/qat/qat_common/adf_accel_devices.h | 28 +-
.../crypto/qat/qat_common/adf_accel_engine.c | 8 +-
drivers/crypto/qat/qat_common/adf_admin.c | 47 ++-
drivers/crypto/qat/qat_common/adf_cfg.c | 1 +
.../crypto/qat/qat_common/adf_cfg_common.h | 13 +
.../crypto/qat/qat_common/adf_cfg_strings.h | 3 +
.../crypto/qat/qat_common/adf_common_drv.h | 12 +
.../crypto/qat/qat_common/adf_gen2_hw_data.c | 57 ++--
.../crypto/qat/qat_common/adf_gen2_hw_data.h | 9 +
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 316 +++++++++++++-----
.../crypto/qat/qat_common/adf_gen4_hw_data.c | 62 +++-
.../crypto/qat/qat_common/adf_gen4_hw_data.h | 17 +
drivers/crypto/qat/qat_common/adf_gen4_pfvf.c | 148 ++++++++
drivers/crypto/qat/qat_common/adf_gen4_pfvf.h | 17 +
drivers/crypto/qat/qat_common/adf_init.c | 9 +-
drivers/crypto/qat/qat_common/adf_isr.c | 28 +-
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 202 +++++++++--
.../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 35 +-
.../crypto/qat/qat_common/adf_pfvf_pf_msg.h | 8 +
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 262 +++++++++++++--
.../crypto/qat/qat_common/adf_pfvf_pf_proto.h | 2 +-
.../crypto/qat/qat_common/adf_pfvf_utils.c | 65 ++++
.../crypto/qat/qat_common/adf_pfvf_utils.h | 31 ++
.../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 98 +++++-
.../crypto/qat/qat_common/adf_pfvf_vf_msg.h | 2 +
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 284 ++++++++++++++--
.../crypto/qat/qat_common/adf_pfvf_vf_proto.h | 7 +-
drivers/crypto/qat/qat_common/adf_sriov.c | 39 ++-
drivers/crypto/qat/qat_common/adf_vf_isr.c | 14 +-
.../qat/qat_common/icp_qat_fw_init_admin.h | 4 +-
drivers/crypto/qat/qat_common/icp_qat_hw.h | 13 +-
drivers/crypto/qat/qat_common/qat_crypto.c | 25 ++
drivers/crypto/qat/qat_common/qat_hal.c | 41 +--
.../qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 3 +
.../qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 1 +
drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 4 -
47 files changed, 1776 insertions(+), 336 deletions(-)
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.h
create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.c
create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.h

--
2.31.1



2021-12-16 09:11:14

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 01/24] crypto: qat - get compression extended capabilities

From: Giovanni Cabiddu <[email protected]>

Get compression extended capabilities mask from firmware through the
init/admin channel.
These capabilities are stored in the accel_dev structure and will be
communicated to VF through the PFVF channel.

Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
.../crypto/qat/qat_common/adf_accel_devices.h | 1 +
drivers/crypto/qat/qat_common/adf_admin.c | 37 +++++++++++++++++++
.../qat/qat_common/icp_qat_fw_init_admin.h | 4 +-
3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index a1809a7d1c90..2c380fa10a09 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -198,6 +198,7 @@ struct adf_hw_device_data {
u32 fuses;
u32 straps;
u32 accel_capabilities_mask;
+ u32 extended_dc_capabilities;
u32 instance_id;
u16 accel_mask;
u32 ae_mask;
diff --git a/drivers/crypto/qat/qat_common/adf_admin.c b/drivers/crypto/qat/qat_common/adf_admin.c
index 43680e178242..c381b89d548d 100644
--- a/drivers/crypto/qat/qat_common/adf_admin.c
+++ b/drivers/crypto/qat/qat_common/adf_admin.c
@@ -194,6 +194,35 @@ static int adf_set_fw_constants(struct adf_accel_dev *accel_dev)
return adf_send_admin(accel_dev, &req, &resp, ae_mask);
}

+static int adf_get_dc_capabilities(struct adf_accel_dev *accel_dev,
+ u32 *capabilities)
+{
+ struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+ struct icp_qat_fw_init_admin_resp resp;
+ struct icp_qat_fw_init_admin_req req;
+ unsigned long ae_mask;
+ unsigned long ae;
+ int ret;
+
+ /* Target only service accelerator engines */
+ ae_mask = hw_device->ae_mask & ~hw_device->admin_ae_mask;
+
+ memset(&req, 0, sizeof(req));
+ memset(&resp, 0, sizeof(resp));
+ req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET;
+
+ *capabilities = 0;
+ for_each_set_bit(ae, &ae_mask, GET_MAX_ACCELENGINES(accel_dev)) {
+ ret = adf_send_admin(accel_dev, &req, &resp, 1ULL << ae);
+ if (ret)
+ return ret;
+
+ *capabilities |= resp.extended_features;
+ }
+
+ return 0;
+}
+
/**
* adf_send_admin_init() - Function sends init message to FW
* @accel_dev: Pointer to acceleration device.
@@ -204,8 +233,16 @@ static int adf_set_fw_constants(struct adf_accel_dev *accel_dev)
*/
int adf_send_admin_init(struct adf_accel_dev *accel_dev)
{
+ u32 dc_capabilities = 0;
int ret;

+ ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities);
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev), "Cannot get dc capabilities\n");
+ return ret;
+ }
+ accel_dev->hw_device->extended_dc_capabilities = dc_capabilities;
+
ret = adf_set_fw_constants(accel_dev);
if (ret)
return ret;
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
index f05ad17fbdd6..afe59a7684ac 100644
--- a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
@@ -14,7 +14,8 @@ enum icp_qat_fw_init_admin_cmd_id {
ICP_QAT_FW_COUNTERS_GET = 5,
ICP_QAT_FW_LOOPBACK = 6,
ICP_QAT_FW_HEARTBEAT_SYNC = 7,
- ICP_QAT_FW_HEARTBEAT_GET = 8
+ ICP_QAT_FW_HEARTBEAT_GET = 8,
+ ICP_QAT_FW_COMP_CAPABILITY_GET = 9,
};

enum icp_qat_fw_init_admin_resp_status {
@@ -52,6 +53,7 @@ struct icp_qat_fw_init_admin_resp {
__u16 version_minor_num;
__u16 version_major_num;
};
+ __u32 extended_features;
};
__u64 opaque_data;
union {
--
2.31.1


2021-12-16 09:11:17

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 02/24] crypto: qat - set CIPHER capability for QAT GEN2

From: Giovanni Cabiddu <[email protected]>

Set the CIPHER capability for QAT GEN2 devices if the hardware supports
it. This is done if both the CIPHER and the AUTHENTICATION engines are
available on the device.

Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_hw_data.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
index 3b48fdaaff6d..3ea26f2f4a22 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
@@ -211,17 +211,23 @@ u32 adf_gen2_get_accel_cap(struct adf_accel_dev *accel_dev)
u32 legfuses;
u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
- ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
+ ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
+ ICP_ACCEL_CAPABILITIES_CIPHER;

/* Read accelerator capabilities mask */
pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses);

- if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE)
+ /* A set bit in legfuses means the feature is OFF in this SKU */
+ if (legfuses & ICP_ACCEL_MASK_CIPHER_SLICE) {
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ }
if (legfuses & ICP_ACCEL_MASK_PKE_SLICE)
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
- if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE)
+ if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE) {
capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ }

if ((straps | fuses) & ADF_POWERGATE_PKE)
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
--
2.31.1


2021-12-16 09:11:22

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 03/24] crypto: qat - set COMPRESSION capability for QAT GEN2

From: Giovanni Cabiddu <[email protected]>

Enhance the device capability detection for QAT GEN2 devices to detect if
a device supports the compression service.

This is done by checking both the fuse and the strap registers for c62x
and c3xxx and only the fuse register for dh895xcc.

Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_hw_data.c | 8 +++++++-
drivers/crypto/qat/qat_common/adf_gen2_hw_data.h | 1 +
drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 2 ++
3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
index 3ea26f2f4a22..688dd6f53b0b 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
@@ -212,7 +212,8 @@ u32 adf_gen2_get_accel_cap(struct adf_accel_dev *accel_dev)
u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
- ICP_ACCEL_CAPABILITIES_CIPHER;
+ ICP_ACCEL_CAPABILITIES_CIPHER |
+ ICP_ACCEL_CAPABILITIES_COMPRESSION;

/* Read accelerator capabilities mask */
pci_read_config_dword(pdev, ADF_DEVICE_LEGFUSE_OFFSET, &legfuses);
@@ -228,10 +229,15 @@ u32 adf_gen2_get_accel_cap(struct adf_accel_dev *accel_dev)
capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
}
+ if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE)
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;

if ((straps | fuses) & ADF_POWERGATE_PKE)
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;

+ if ((straps | fuses) & ADF_POWERGATE_DC)
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
+
return capabilities;
}
EXPORT_SYMBOL_GPL(adf_gen2_get_accel_cap);
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
index 448c97f740e7..7c2c17366460 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
@@ -113,6 +113,7 @@ do { \
(ADF_ARB_REG_SLOT * (index)), value)

/* Power gating */
+#define ADF_POWERGATE_DC BIT(23)
#define ADF_POWERGATE_PKE BIT(24)

/* WDT timers
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
index 27d4cab65dd8..2d18279191d7 100644
--- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
@@ -69,6 +69,8 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
if (legfuses & ICP_ACCEL_MASK_AUTH_SLICE)
capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
+ if (legfuses & ICP_ACCEL_MASK_COMPRESS_SLICE)
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;

return capabilities;
}
--
2.31.1


2021-12-16 09:11:22

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 04/24] crypto: qat - extend crypto capability detection for 4xxx

From: Giovanni Cabiddu <[email protected]>

Extended the capability detection logic for 4xxx devices.
Mask out unsupported algorithms and services based on the value read in
the fuse register.

This includes only capabilities for the crypto service.

Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 29 +++++++++++++++++--
drivers/crypto/qat/qat_common/icp_qat_hw.h | 9 +++++-
2 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index 4658b7bf76da..d320c50c4561 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -98,18 +98,41 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
u32 fusectl1;
u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CIPHER |
ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
+ ICP_ACCEL_CAPABILITIES_SHA3 |
+ ICP_ACCEL_CAPABILITIES_SHA3_EXT |
+ ICP_ACCEL_CAPABILITIES_HKDF |
+ ICP_ACCEL_CAPABILITIES_ECEDMONT |
+ ICP_ACCEL_CAPABILITIES_CHACHA_POLY |
+ ICP_ACCEL_CAPABILITIES_AESGCM_SPC |
ICP_ACCEL_CAPABILITIES_AES_V2;

/* Read accelerator capabilities mask */
pci_read_config_dword(pdev, ADF_4XXX_FUSECTL1_OFFSET, &fusectl1);

- if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE)
+ /* A set bit in fusectl1 means the feature is OFF in this SKU */
+ if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) {
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
- if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE)
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_HKDF;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ }
+ if (fusectl1 & ICP_ACCEL_4XXX_MASK_UCS_SLICE) {
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_AES_V2;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ }
+ if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) {
capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
- if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE)
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ }
+ if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) {
capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
+ capabilities &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT;
+ }

return capabilities;
}
diff --git a/drivers/crypto/qat/qat_common/icp_qat_hw.h b/drivers/crypto/qat/qat_common/icp_qat_hw.h
index e39e8a2d51a7..5770b2b2c09e 100644
--- a/drivers/crypto/qat/qat_common/icp_qat_hw.h
+++ b/drivers/crypto/qat/qat_common/icp_qat_hw.h
@@ -91,7 +91,14 @@ enum icp_qat_capabilities_mask {
ICP_ACCEL_CAPABILITIES_RAND = BIT(7),
ICP_ACCEL_CAPABILITIES_ZUC = BIT(8),
ICP_ACCEL_CAPABILITIES_SHA3 = BIT(9),
- /* Bits 10-25 are currently reserved */
+ /* Bits 10-11 are currently reserved */
+ ICP_ACCEL_CAPABILITIES_HKDF = BIT(12),
+ ICP_ACCEL_CAPABILITIES_ECEDMONT = BIT(13),
+ /* Bit 14 is currently reserved */
+ ICP_ACCEL_CAPABILITIES_SHA3_EXT = BIT(15),
+ ICP_ACCEL_CAPABILITIES_AESGCM_SPC = BIT(16),
+ ICP_ACCEL_CAPABILITIES_CHACHA_POLY = BIT(17),
+ /* Bits 18-25 are currently reserved */
ICP_ACCEL_CAPABILITIES_AES_V2 = BIT(26)
};

--
2.31.1


2021-12-16 09:11:23

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 05/24] crypto: qat - support the reset of ring pairs on PF

Add support for triggering a HW reset of a specific ring pair.
Being a device specific feature, add it to the hw_device_data struct.

This feature is supported only by QAT GEN4 devices.

This patch is based on earlier work done by Zelin Deng.

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 2 +
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 1 +
.../crypto/qat/qat_common/adf_accel_devices.h | 2 +
.../crypto/qat/qat_common/adf_gen4_hw_data.c | 53 +++++++++++++++++++
.../crypto/qat/qat_common/adf_gen4_hw_data.h | 9 ++++
5 files changed, 67 insertions(+)

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index d320c50c4561..0d1603894af4 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -239,6 +239,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->dev_class = &adf_4xxx_class;
hw_data->instance_id = adf_4xxx_class.instances++;
hw_data->num_banks = ADF_4XXX_ETR_MAX_BANKS;
+ hw_data->num_banks_per_vf = ADF_4XXX_NUM_BANKS_PER_VF;
hw_data->num_rings_per_bank = ADF_4XXX_NUM_RINGS_PER_BANK;
hw_data->num_accel = ADF_4XXX_MAX_ACCELERATORS;
hw_data->num_engines = ADF_4XXX_MAX_ACCELENGINES;
@@ -279,6 +280,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->pfvf_ops.enable_comms = adf_pfvf_comms_disabled;
hw_data->pfvf_ops.get_vf2pf_sources = get_vf2pf_sources;
hw_data->disable_iov = adf_disable_sriov;
+ hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;

adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
}
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
index 924bac6feb37..a0c67752317f 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
@@ -37,6 +37,7 @@

/* Bank and ring configuration */
#define ADF_4XXX_NUM_RINGS_PER_BANK 2
+#define ADF_4XXX_NUM_BANKS_PER_VF 4

/* Error source registers */
#define ADF_4XXX_ERRSOU0 (0x41A200)
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 2c380fa10a09..cc8b10b23145 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -186,6 +186,7 @@ struct adf_hw_device_data {
bool enable);
void (*enable_ints)(struct adf_accel_dev *accel_dev);
void (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev);
+ int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, u32 bank_nr);
void (*reset_device)(struct adf_accel_dev *accel_dev);
void (*set_msix_rttable)(struct adf_accel_dev *accel_dev);
char *(*uof_get_name)(u32 obj_num);
@@ -206,6 +207,7 @@ struct adf_hw_device_data {
u16 tx_rings_mask;
u8 tx_rx_gap;
u8 num_banks;
+ u16 num_banks_per_vf;
u8 num_rings_per_bank;
u8 num_accel;
u8 num_logical_accel;
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
index e3157df8a653..c7808ff2aba1 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2020 Intel Corporation */
+#include <linux/iopoll.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_gen4_hw_data.h"
@@ -146,3 +147,55 @@ int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev)
return 0;
}
EXPORT_SYMBOL_GPL(adf_pfvf_comms_disabled);
+
+static int reset_ring_pair(void __iomem *csr, u32 bank_number)
+{
+ u32 status;
+ int ret;
+
+ /* Write rpresetctl register BIT(0) as 1
+ * Since rpresetctl registers have no RW fields, no need to preserve
+ * values for other bits. Just write directly.
+ */
+ ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETCTL(bank_number),
+ ADF_WQM_CSR_RPRESETCTL_RESET);
+
+ /* Read rpresetsts register and wait for rp reset to complete */
+ ret = read_poll_timeout(ADF_CSR_RD, status,
+ status & ADF_WQM_CSR_RPRESETSTS_STATUS,
+ ADF_RPRESET_POLL_DELAY_US,
+ ADF_RPRESET_POLL_TIMEOUT_US, true,
+ csr, ADF_WQM_CSR_RPRESETSTS(bank_number));
+ if (!ret) {
+ /* When rp reset is done, clear rpresetsts */
+ ADF_CSR_WR(csr, ADF_WQM_CSR_RPRESETSTS(bank_number),
+ ADF_WQM_CSR_RPRESETSTS_STATUS);
+ }
+
+ return ret;
+}
+
+int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ u32 etr_bar_id = hw_data->get_etr_bar_id(hw_data);
+ void __iomem *csr;
+ int ret;
+
+ if (bank_number >= hw_data->num_banks)
+ return -EINVAL;
+
+ dev_dbg(&GET_DEV(accel_dev),
+ "ring pair reset for bank:%d\n", bank_number);
+
+ csr = (&GET_BARS(accel_dev)[etr_bar_id])->virt_addr;
+ ret = reset_ring_pair(csr, bank_number);
+ if (ret)
+ dev_err(&GET_DEV(accel_dev),
+ "ring pair reset failed (timeout)\n");
+ else
+ dev_dbg(&GET_DEV(accel_dev), "ring pair reset successful\n");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(adf_gen4_ring_pair_reset);
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
index b8fca1ff7aab..449d6a5976a9 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
@@ -106,6 +106,15 @@ do { \
#define ADF_SSMWDTPKEL_OFFSET 0x58
#define ADF_SSMWDTPKEH_OFFSET 0x60

+/* Ring reset */
+#define ADF_RPRESET_POLL_TIMEOUT_US (5 * USEC_PER_SEC)
+#define ADF_RPRESET_POLL_DELAY_US 20
+#define ADF_WQM_CSR_RPRESETCTL_RESET BIT(0)
+#define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3))
+#define ADF_WQM_CSR_RPRESETSTS_STATUS BIT(0)
+#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4)
+
void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev);
void adf_gen4_init_hw_csr_ops(struct adf_hw_csr_ops *csr_ops);
+int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number);
#endif
--
2.31.1


2021-12-16 09:11:24

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 06/24] crypto: qat - add the adf_get_pmisc_base() helper function

Add and use the new helper function adf_get_pmisc_base() where convenient.

Also:
- remove no longer shared variables
- leverage other utilities, such as GET_PFVF_OPS(), as a consequence
- consistently use the "pmisc_addr" name for the returned value of this
new helper

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_admin.c | 10 ++---
.../crypto/qat/qat_common/adf_common_drv.h | 11 +++++
.../crypto/qat/qat_common/adf_gen2_hw_data.c | 39 ++++++------------
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 24 ++++-------
.../crypto/qat/qat_common/adf_gen4_hw_data.c | 9 +---
drivers/crypto/qat/qat_common/adf_isr.c | 28 ++++---------
drivers/crypto/qat/qat_common/adf_vf_isr.c | 14 ++-----
drivers/crypto/qat/qat_common/qat_hal.c | 41 +++++--------------
8 files changed, 61 insertions(+), 115 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_admin.c b/drivers/crypto/qat/qat_common/adf_admin.c
index c381b89d548d..498eb6f690e3 100644
--- a/drivers/crypto/qat/qat_common/adf_admin.c
+++ b/drivers/crypto/qat/qat_common/adf_admin.c
@@ -255,9 +255,7 @@ int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
{
struct adf_admin_comms *admin;
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- struct adf_bar *pmisc =
- &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
- void __iomem *csr = pmisc->virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
struct admin_info admin_csrs_info;
u32 mailbox_offset, adminmsg_u, adminmsg_l;
void __iomem *mailbox;
@@ -291,13 +289,13 @@ int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
hw_data->get_admin_info(&admin_csrs_info);

mailbox_offset = admin_csrs_info.mailbox_offset;
- mailbox = csr + mailbox_offset;
+ mailbox = pmisc_addr + mailbox_offset;
adminmsg_u = admin_csrs_info.admin_msg_ur;
adminmsg_l = admin_csrs_info.admin_msg_lr;

reg_val = (u64)admin->phy_addr;
- ADF_CSR_WR(csr, adminmsg_u, upper_32_bits(reg_val));
- ADF_CSR_WR(csr, adminmsg_l, lower_32_bits(reg_val));
+ ADF_CSR_WR(pmisc_addr, adminmsg_u, upper_32_bits(reg_val));
+ ADF_CSR_WR(pmisc_addr, adminmsg_l, lower_32_bits(reg_val));

mutex_init(&admin->lock);
admin->mailbox_addr = mailbox;
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
index 2d8b72085505..5212891344a9 100644
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -243,4 +243,15 @@ static inline void adf_flush_vf_wq(struct adf_accel_dev *accel_dev)
}

#endif
+
+static inline void __iomem *adf_get_pmisc_base(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct adf_bar *pmisc;
+
+ pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
+
+ return pmisc->virt_addr;
+}
+
#endif
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
index 688dd6f53b0b..57035b7dd4b2 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2020 Intel Corporation */
+#include "adf_common_drv.h"
#include "adf_gen2_hw_data.h"
#include "icp_qat_hw.h"
#include <linux/pci.h>
@@ -25,31 +26,29 @@ EXPORT_SYMBOL_GPL(adf_gen2_get_num_aes);
void adf_gen2_enable_error_correction(struct adf_accel_dev *accel_dev)
{
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- struct adf_bar *misc_bar = &GET_BARS(accel_dev)
- [hw_data->get_misc_bar_id(hw_data)];
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
unsigned long accel_mask = hw_data->accel_mask;
unsigned long ae_mask = hw_data->ae_mask;
- void __iomem *csr = misc_bar->virt_addr;
unsigned int val, i;

/* Enable Accel Engine error detection & correction */
for_each_set_bit(i, &ae_mask, hw_data->num_engines) {
- val = ADF_CSR_RD(csr, ADF_GEN2_AE_CTX_ENABLES(i));
+ val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_AE_CTX_ENABLES(i));
val |= ADF_GEN2_ENABLE_AE_ECC_ERR;
- ADF_CSR_WR(csr, ADF_GEN2_AE_CTX_ENABLES(i), val);
- val = ADF_CSR_RD(csr, ADF_GEN2_AE_MISC_CONTROL(i));
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_AE_CTX_ENABLES(i), val);
+ val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_AE_MISC_CONTROL(i));
val |= ADF_GEN2_ENABLE_AE_ECC_PARITY_CORR;
- ADF_CSR_WR(csr, ADF_GEN2_AE_MISC_CONTROL(i), val);
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_AE_MISC_CONTROL(i), val);
}

/* Enable shared memory error detection & correction */
for_each_set_bit(i, &accel_mask, hw_data->num_accel) {
- val = ADF_CSR_RD(csr, ADF_GEN2_UERRSSMSH(i));
+ val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_UERRSSMSH(i));
val |= ADF_GEN2_ERRSSMSH_EN;
- ADF_CSR_WR(csr, ADF_GEN2_UERRSSMSH(i), val);
- val = ADF_CSR_RD(csr, ADF_GEN2_CERRSSMSH(i));
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_UERRSSMSH(i), val);
+ val = ADF_CSR_RD(pmisc_addr, ADF_GEN2_CERRSSMSH(i));
val |= ADF_GEN2_ERRSSMSH_EN;
- ADF_CSR_WR(csr, ADF_GEN2_CERRSSMSH(i), val);
+ ADF_CSR_WR(pmisc_addr, ADF_GEN2_CERRSSMSH(i), val);
}
}
EXPORT_SYMBOL_GPL(adf_gen2_enable_error_correction);
@@ -57,15 +56,9 @@ EXPORT_SYMBOL_GPL(adf_gen2_enable_error_correction);
void adf_gen2_cfg_iov_thds(struct adf_accel_dev *accel_dev, bool enable,
int num_a_regs, int num_b_regs)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- void __iomem *pmisc_addr;
- struct adf_bar *pmisc;
- int pmisc_id, i;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
u32 reg;
-
- pmisc_id = hw_data->get_misc_bar_id(hw_data);
- pmisc = &GET_BARS(accel_dev)[pmisc_id];
- pmisc_addr = pmisc->virt_addr;
+ int i;

/* Set/Unset Valid bit in AE Thread to PCIe Function Mapping Group A */
for (i = 0; i < num_a_regs; i++) {
@@ -245,18 +238,12 @@ EXPORT_SYMBOL_GPL(adf_gen2_get_accel_cap);
void adf_gen2_set_ssm_wdtimer(struct adf_accel_dev *accel_dev)
{
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
u32 timer_val_pke = ADF_SSM_WDT_PKE_DEFAULT_VALUE;
u32 timer_val = ADF_SSM_WDT_DEFAULT_VALUE;
unsigned long accel_mask = hw_data->accel_mask;
- void __iomem *pmisc_addr;
- struct adf_bar *pmisc;
- int pmisc_id;
u32 i = 0;

- pmisc_id = hw_data->get_misc_bar_id(hw_data);
- pmisc = &GET_BARS(accel_dev)[pmisc_id];
- pmisc_addr = pmisc->virt_addr;
-
/* Configures WDT timers */
for_each_set_bit(i, &accel_mask, hw_data->num_accel) {
/* Enable WDT for sym and dc */
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 099e39808d13..5ac69ece34a8 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -75,15 +75,12 @@ static void adf_gen2_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
u8 vf_nr)
{
- struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- void __iomem *pmisc_bar_addr =
- pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr;
- u32 val, pfvf_offset, count = 0;
- u32 local_in_use_mask, local_in_use_pattern;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
u32 remote_in_use_mask, remote_in_use_pattern;
+ u32 local_in_use_mask, local_in_use_pattern;
+ u32 val, pfvf_offset, count = 0;
struct mutex *lock; /* lock preventing concurrent acces of CSR */
- unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
u32 int_bit;
int ret;

@@ -114,7 +111,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
ret = 0;

/* Check if the PFVF CSR is in use by remote function */
- val = ADF_CSR_RD(pmisc_bar_addr, pfvf_offset);
+ val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
if ((val & remote_in_use_mask) == remote_in_use_pattern) {
dev_dbg(&GET_DEV(accel_dev),
"PFVF CSR in use by remote function\n");
@@ -122,12 +119,12 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
}

/* Attempt to get ownership of the PFVF CSR */
- ADF_CSR_WR(pmisc_bar_addr, pfvf_offset, msg | int_bit);
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, msg | int_bit);

/* Wait for confirmation from remote func it received the message */
do {
msleep(ADF_PFVF_MSG_ACK_DELAY);
- val = ADF_CSR_RD(pmisc_bar_addr, pfvf_offset);
+ val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
} while ((val & int_bit) && (count++ < ADF_PFVF_MSG_ACK_MAX_RETRY));

if (val & int_bit) {
@@ -143,7 +140,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
}

/* Finished with the PFVF CSR; relinquish it and leave msg in CSR */
- ADF_CSR_WR(pmisc_bar_addr, pfvf_offset, val & ~local_in_use_mask);
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, val & ~local_in_use_mask);
out:
mutex_unlock(lock);
return ret;
@@ -160,10 +157,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,

static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev, u8 vf_nr)
{
- struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- void __iomem *pmisc_addr =
- pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
u32 pfvf_offset;
u32 msg_origin;
u32 int_bit;
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
index c7808ff2aba1..3148a62938fd 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.c
@@ -111,20 +111,13 @@ static inline void adf_gen4_unpack_ssm_wdtimer(u64 value, u32 *upper,

void adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
u64 timer_val_pke = ADF_SSM_WDT_PKE_DEFAULT_VALUE;
u64 timer_val = ADF_SSM_WDT_DEFAULT_VALUE;
u32 ssm_wdt_pke_high = 0;
u32 ssm_wdt_pke_low = 0;
u32 ssm_wdt_high = 0;
u32 ssm_wdt_low = 0;
- void __iomem *pmisc_addr;
- struct adf_bar *pmisc;
- int pmisc_id;
-
- pmisc_id = hw_data->get_misc_bar_id(hw_data);
- pmisc = &GET_BARS(accel_dev)[pmisc_id];
- pmisc_addr = pmisc->virt_addr;

/* Convert 64bit WDT timer value into 32bit values for
* mmio write to 32bit CSRs.
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c
index 522e0c10d9b9..4ca482aa69f7 100644
--- a/drivers/crypto/qat/qat_common/adf_isr.c
+++ b/drivers/crypto/qat/qat_common/adf_isr.c
@@ -57,54 +57,42 @@ static irqreturn_t adf_msix_isr_bundle(int irq, void *bank_ptr)
#ifdef CONFIG_PCI_IOV
void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- u32 misc_bar_id = hw_data->get_misc_bar_id(hw_data);
- struct adf_bar *pmisc = &GET_BARS(accel_dev)[misc_bar_id];
- void __iomem *pmisc_addr = pmisc->virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
unsigned long flags;

spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
- hw_data->pfvf_ops.enable_vf2pf_interrupts(pmisc_addr, vf_mask);
+ GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask);
spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
}

void adf_disable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- u32 misc_bar_id = hw_data->get_misc_bar_id(hw_data);
- struct adf_bar *pmisc = &GET_BARS(accel_dev)[misc_bar_id];
- void __iomem *pmisc_addr = pmisc->virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
unsigned long flags;

spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags);
- hw_data->pfvf_ops.disable_vf2pf_interrupts(pmisc_addr, vf_mask);
+ GET_PFVF_OPS(accel_dev)->disable_vf2pf_interrupts(pmisc_addr, vf_mask);
spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags);
}

static void adf_disable_vf2pf_interrupts_irq(struct adf_accel_dev *accel_dev,
u32 vf_mask)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- u32 misc_bar_id = hw_data->get_misc_bar_id(hw_data);
- struct adf_bar *pmisc = &GET_BARS(accel_dev)[misc_bar_id];
- void __iomem *pmisc_addr = pmisc->virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);

spin_lock(&accel_dev->pf.vf2pf_ints_lock);
- hw_data->pfvf_ops.disable_vf2pf_interrupts(pmisc_addr, vf_mask);
+ GET_PFVF_OPS(accel_dev)->disable_vf2pf_interrupts(pmisc_addr, vf_mask);
spin_unlock(&accel_dev->pf.vf2pf_ints_lock);
}

static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev)
{
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- int bar_id = hw_data->get_misc_bar_id(hw_data);
- struct adf_bar *pmisc = &GET_BARS(accel_dev)[bar_id];
- void __iomem *pmisc_addr = pmisc->virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
bool irq_handled = false;
unsigned long vf_mask;

/* Get the interrupt sources triggered by VFs */
- vf_mask = hw_data->pfvf_ops.get_vf2pf_sources(pmisc_addr);
+ vf_mask = GET_PFVF_OPS(accel_dev)->get_vf2pf_sources(pmisc_addr);

if (vf_mask) {
struct adf_accel_vf_info *vf_info;
diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c
index fe094178f065..86c3bd0c9c2b 100644
--- a/drivers/crypto/qat/qat_common/adf_vf_isr.c
+++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c
@@ -30,22 +30,16 @@ struct adf_vf_stop_data {

void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev)
{
- struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- void __iomem *pmisc_bar_addr =
- pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);

- ADF_CSR_WR(pmisc_bar_addr, ADF_VINTMSK_OFFSET, 0x0);
+ ADF_CSR_WR(pmisc_addr, ADF_VINTMSK_OFFSET, 0x0);
}

void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev)
{
- struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
- struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- void __iomem *pmisc_bar_addr =
- pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr;
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);

- ADF_CSR_WR(pmisc_bar_addr, ADF_VINTMSK_OFFSET, 0x2);
+ ADF_CSR_WR(pmisc_addr, ADF_VINTMSK_OFFSET, 0x2);
}
EXPORT_SYMBOL_GPL(adf_disable_pf2vf_interrupts);

diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c
index 12ca6b8764aa..4bfd8f3566f7 100644
--- a/drivers/crypto/qat/qat_common/qat_hal.c
+++ b/drivers/crypto/qat/qat_common/qat_hal.c
@@ -684,8 +684,7 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle,
{
struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev;
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
- struct adf_bar *misc_bar =
- &pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)];
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
unsigned int max_en_ae_id = 0;
struct adf_bar *sram_bar;
unsigned int csr_val = 0;
@@ -715,18 +714,12 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle,
handle->chip_info->fcu_loaded_ae_csr = FCU_AE_LOADED_4XXX;
handle->chip_info->fcu_loaded_ae_pos = 0;

- handle->hal_cap_g_ctl_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_CAP_OFFSET_4XXX);
- handle->hal_cap_ae_xfer_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_AE_OFFSET_4XXX);
- handle->hal_ep_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_EP_OFFSET_4XXX);
+ handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET_4XXX;
+ handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET_4XXX;
+ handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET_4XXX;
handle->hal_cap_ae_local_csr_addr_v =
(void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v
- + LOCAL_TO_XFER_REG_OFFSET);
+ + LOCAL_TO_XFER_REG_OFFSET);
break;
case PCI_DEVICE_ID_INTEL_QAT_C62X:
case PCI_DEVICE_ID_INTEL_QAT_C3XXX:
@@ -749,15 +742,9 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle,
handle->chip_info->fcu_dram_addr_lo = FCU_DRAM_ADDR_LO;
handle->chip_info->fcu_loaded_ae_csr = FCU_STATUS;
handle->chip_info->fcu_loaded_ae_pos = FCU_LOADED_AE_POS;
- handle->hal_cap_g_ctl_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_CAP_OFFSET);
- handle->hal_cap_ae_xfer_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_AE_OFFSET);
- handle->hal_ep_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_EP_OFFSET);
+ handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET;
+ handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET;
+ handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET;
handle->hal_cap_ae_local_csr_addr_v =
(void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v
+ LOCAL_TO_XFER_REG_OFFSET);
@@ -782,15 +769,9 @@ static int qat_hal_chip_init(struct icp_qat_fw_loader_handle *handle,
handle->chip_info->fcu_dram_addr_lo = 0;
handle->chip_info->fcu_loaded_ae_csr = 0;
handle->chip_info->fcu_loaded_ae_pos = 0;
- handle->hal_cap_g_ctl_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_CAP_OFFSET);
- handle->hal_cap_ae_xfer_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_AE_OFFSET);
- handle->hal_ep_csr_addr_v =
- (void __iomem *)((uintptr_t)misc_bar->virt_addr +
- ICP_QAT_EP_OFFSET);
+ handle->hal_cap_g_ctl_csr_addr_v = pmisc_addr + ICP_QAT_CAP_OFFSET;
+ handle->hal_cap_ae_xfer_csr_addr_v = pmisc_addr + ICP_QAT_AE_OFFSET;
+ handle->hal_ep_csr_addr_v = pmisc_addr + ICP_QAT_EP_OFFSET;
handle->hal_cap_ae_local_csr_addr_v =
(void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v
+ LOCAL_TO_XFER_REG_OFFSET);
--
2.31.1


2021-12-16 09:11:29

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 07/24] crypto: qat - make PFVF message construction direction agnostic

Currently PFVF messages are created upfront in the CSR format, that is
PF2VF messages starting from bit 0 and VF2PF from bit 16, and passed
along unmodified to the PFVF send function.

Refactor the code to allow the VF2PF messages to be built starting from
bit 0, as for the PF2VF messages. Shift the VF to PF messages just
before sending them, and refactor the send logic to handle messages
properly depending on the direction.

As a result all the messages are composed the same way regardless of
the direction.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 129 +++++++++++++-----
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 26 ++--
.../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 4 +-
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 10 +-
.../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 20 +--
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 2 +-
6 files changed, 120 insertions(+), 71 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 5ac69ece34a8..2e0b9ac27393 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -17,6 +17,14 @@
#define ADF_GEN2_PF_PF2VF_OFFSET(i) (0x3A000 + 0x280 + ((i) * 0x04))
#define ADF_GEN2_VF_PF2VF_OFFSET 0x200

+#define ADF_GEN2_CSR_IN_USE 0x6AC2
+#define ADF_GEN2_CSR_IN_USE_MASK 0xFFFE
+
+enum gen2_csr_pos {
+ ADF_GEN2_CSR_PF2VF_OFFSET = 0,
+ ADF_GEN2_CSR_VF2PF_OFFSET = 16,
+};
+
#define ADF_PFVF_MSG_ACK_DELAY 2
#define ADF_PFVF_MSG_ACK_MAX_RETRY 100

@@ -72,38 +80,81 @@ static void adf_gen2_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
}
}

+static u32 gen2_csr_get_int_bit(enum gen2_csr_pos offset)
+{
+ return ADF_PFVF_INT << offset;
+}
+
+static u32 gen2_csr_msg_to_position(u32 csr_msg, enum gen2_csr_pos offset)
+{
+ return (csr_msg & 0xFFFF) << offset;
+}
+
+static u32 gen2_csr_msg_from_position(u32 csr_val, enum gen2_csr_pos offset)
+{
+ return (csr_val >> offset) & 0xFFFF;
+}
+
+static bool gen2_csr_is_in_use(u32 msg, enum gen2_csr_pos offset)
+{
+ return ((msg >> offset) & ADF_GEN2_CSR_IN_USE_MASK) == ADF_GEN2_CSR_IN_USE;
+}
+
+static void gen2_csr_clear_in_use(u32 *msg, enum gen2_csr_pos offset)
+{
+ *msg &= ~(ADF_GEN2_CSR_IN_USE_MASK << offset);
+}
+
+static void gen2_csr_set_in_use(u32 *msg, enum gen2_csr_pos offset)
+{
+ *msg |= (ADF_GEN2_CSR_IN_USE << offset);
+}
+
+static bool is_legacy_user_pfvf_message(u32 msg)
+{
+ return !(msg & ADF_PFVF_MSGORIGIN_SYSTEM);
+}
+
static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
u8 vf_nr)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
- u32 remote_in_use_mask, remote_in_use_pattern;
- u32 local_in_use_mask, local_in_use_pattern;
- u32 val, pfvf_offset, count = 0;
+ enum gen2_csr_pos remote_offset;
+ enum gen2_csr_pos local_offset;
struct mutex *lock; /* lock preventing concurrent acces of CSR */
+ u32 pfvf_offset;
+ u32 count = 0;
u32 int_bit;
+ u32 csr_val;
int ret;

+ /* Gen2 messages, both PF->VF and VF->PF, are all 16 bits long. This
+ * allows us to build and read messages as if they where all 0 based.
+ * However, send and receive are in a single shared 32 bits register,
+ * so we need to shift and/or mask the message half before decoding
+ * it and after encoding it. Which one to shift depends on the
+ * direction.
+ */
if (accel_dev->is_vf) {
pfvf_offset = GET_PFVF_OPS(accel_dev)->get_vf2pf_offset(0);
lock = &accel_dev->vf.vf2pf_lock;
- local_in_use_mask = ADF_VF2PF_IN_USE_BY_VF_MASK;
- local_in_use_pattern = ADF_VF2PF_IN_USE_BY_VF;
- remote_in_use_mask = ADF_PF2VF_IN_USE_BY_PF_MASK;
- remote_in_use_pattern = ADF_PF2VF_IN_USE_BY_PF;
- int_bit = ADF_VF2PF_INT;
+ local_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
+ remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
} else {
pfvf_offset = GET_PFVF_OPS(accel_dev)->get_pf2vf_offset(vf_nr);
lock = &accel_dev->pf.vf_info[vf_nr].pf2vf_lock;
- local_in_use_mask = ADF_PF2VF_IN_USE_BY_PF_MASK;
- local_in_use_pattern = ADF_PF2VF_IN_USE_BY_PF;
- remote_in_use_mask = ADF_VF2PF_IN_USE_BY_VF_MASK;
- remote_in_use_pattern = ADF_VF2PF_IN_USE_BY_VF;
- int_bit = ADF_PF2VF_INT;
+ local_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
+ remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
}

- msg &= ~local_in_use_mask;
- msg |= local_in_use_pattern;
+ int_bit = gen2_csr_get_int_bit(local_offset);
+
+ /* Pre-calculate message, shifting it in place and setting
+ * the in use pattern
+ */
+ msg = gen2_csr_msg_to_position(msg, local_offset);
+ gen2_csr_set_in_use(&msg, remote_offset);

mutex_lock(lock);

@@ -111,8 +162,8 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
ret = 0;

/* Check if the PFVF CSR is in use by remote function */
- val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
- if ((val & remote_in_use_mask) == remote_in_use_pattern) {
+ csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
+ if (gen2_csr_is_in_use(csr_val, local_offset)) {
dev_dbg(&GET_DEV(accel_dev),
"PFVF CSR in use by remote function\n");
goto retry;
@@ -124,23 +175,25 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
/* Wait for confirmation from remote func it received the message */
do {
msleep(ADF_PFVF_MSG_ACK_DELAY);
- val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
- } while ((val & int_bit) && (count++ < ADF_PFVF_MSG_ACK_MAX_RETRY));
+ csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
+ } while ((csr_val & int_bit) && (count++ < ADF_PFVF_MSG_ACK_MAX_RETRY));

- if (val & int_bit) {
+ if (csr_val & int_bit) {
dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n");
- val &= ~int_bit;
+ csr_val &= ~int_bit;
ret = -EIO;
}

- if (val != msg) {
+ if (csr_val != msg) {
dev_dbg(&GET_DEV(accel_dev),
"Collision - PFVF CSR overwritten by remote function\n");
goto retry;
}

/* Finished with the PFVF CSR; relinquish it and leave msg in CSR */
- ADF_CSR_WR(pmisc_addr, pfvf_offset, val & ~local_in_use_mask);
+ gen2_csr_clear_in_use(&csr_val, remote_offset);
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
+
out:
mutex_unlock(lock);
return ret;
@@ -158,39 +211,43 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev, u8 vf_nr)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ enum gen2_csr_pos local_offset;
u32 pfvf_offset;
- u32 msg_origin;
u32 int_bit;
+ u32 csr_val;
u32 msg;

if (accel_dev->is_vf) {
pfvf_offset = GET_PFVF_OPS(accel_dev)->get_pf2vf_offset(0);
- int_bit = ADF_PF2VF_INT;
- msg_origin = ADF_PF2VF_MSGORIGIN_SYSTEM;
+ local_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
} else {
pfvf_offset = GET_PFVF_OPS(accel_dev)->get_vf2pf_offset(vf_nr);
- int_bit = ADF_VF2PF_INT;
- msg_origin = ADF_VF2PF_MSGORIGIN_SYSTEM;
+ local_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
}

+ int_bit = gen2_csr_get_int_bit(local_offset);
+
/* Read message */
- msg = ADF_CSR_RD(pmisc_addr, pfvf_offset);
- if (!(msg & int_bit)) {
+ csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
+ if (!(csr_val & int_bit)) {
dev_info(&GET_DEV(accel_dev),
- "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", msg);
+ "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", csr_val);
return 0;
}

- /* Ignore legacy non-system (non-kernel) VF2PF messages */
- if (!(msg & msg_origin)) {
+ /* Extract the message from the CSR */
+ msg = gen2_csr_msg_from_position(csr_val, local_offset);
+
+ /* Ignore legacy non-system (non-kernel) messages */
+ if (unlikely(is_legacy_user_pfvf_message(msg))) {
dev_dbg(&GET_DEV(accel_dev),
- "Ignored non-system message (0x%.8x);\n", msg);
+ "Ignored non-system message (0x%.8x);\n", csr_val);
return 0;
}

/* To ACK, clear the INT bit */
- msg &= ~int_bit;
- ADF_CSR_WR(pmisc_addr, pfvf_offset, msg);
+ csr_val &= ~int_bit;
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);

return msg;
}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index 8b476072df28..3ba88bcd0726 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -53,27 +53,19 @@
* adf_gen2_pfvf_send() in adf_pf2vf_msg.c).
*/

-/* PF->VF messages */
-#define ADF_PF2VF_INT BIT(0)
-#define ADF_PF2VF_MSGORIGIN_SYSTEM BIT(1)
-#define ADF_PF2VF_IN_USE_BY_PF 0x6AC20000
-#define ADF_PF2VF_IN_USE_BY_PF_MASK 0xFFFE0000
-#define ADF_PF2VF_MSGTYPE_MASK 0x0000003C
-#define ADF_PF2VF_MSGTYPE_SHIFT 2
+/* PFVF message common bits */
+#define ADF_PFVF_INT BIT(0)
+#define ADF_PFVF_MSGORIGIN_SYSTEM BIT(1)
+#define ADF_PFVF_MSGTYPE_SHIFT 2
+#define ADF_PFVF_MSGTYPE_MASK 0x0F

+/* PF->VF messages */
enum pf2vf_msgtype {
ADF_PF2VF_MSGTYPE_RESTARTING = 0x01,
ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02,
};

/* VF->PF messages */
-#define ADF_VF2PF_INT BIT(16)
-#define ADF_VF2PF_MSGORIGIN_SYSTEM BIT(17)
-#define ADF_VF2PF_IN_USE_BY_VF 0x00006AC2
-#define ADF_VF2PF_IN_USE_BY_VF_MASK 0x0000FFFE
-#define ADF_VF2PF_MSGTYPE_MASK 0x003C0000
-#define ADF_VF2PF_MSGTYPE_SHIFT 18
-
enum vf2pf_msgtype {
ADF_VF2PF_MSGTYPE_INIT = 0x03,
ADF_VF2PF_MSGTYPE_SHUTDOWN = 0x04,
@@ -90,10 +82,10 @@ enum pfvf_compatibility_version {
/* PF->VF Version Response */
#define ADF_PF2VF_MINORVERSION_SHIFT 6
#define ADF_PF2VF_MAJORVERSION_SHIFT 10
-#define ADF_PF2VF_VERSION_RESP_VERS_MASK 0x00003FC0
#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6
-#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x0000C000
+#define ADF_PF2VF_VERSION_RESP_VERS_MASK 0xFF
#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14
+#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x03

enum pf2vf_compat_response {
ADF_PF2VF_VF_COMPATIBLE = 0x01,
@@ -102,6 +94,6 @@ enum pf2vf_compat_response {
};

/* VF->PF Compatible Version Request */
-#define ADF_VF2PF_COMPAT_VER_REQ_SHIFT 22
+#define ADF_VF2PF_COMPAT_VER_REQ_SHIFT 6

#endif /* ADF_PFVF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
index 647b82e6c4ba..4057d7d74d62 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
@@ -9,8 +9,8 @@
void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
{
struct adf_accel_vf_info *vf;
- u32 msg = (ADF_PF2VF_MSGORIGIN_SYSTEM |
- (ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PF2VF_MSGTYPE_SHIFT));
+ u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
+ (ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PFVF_MSGTYPE_SHIFT));
int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));

for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 4f20dd35fcd4..fb477eb89fef 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -42,7 +42,7 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
u32 resp = 0;

- switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) {
+ switch ((msg >> ADF_PFVF_MSGTYPE_SHIFT) & ADF_PFVF_MSGTYPE_MASK) {
case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ:
{
u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
@@ -57,9 +57,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
else
compat = ADF_PF2VF_VF_COMPAT_UNKNOWN;

- resp = ADF_PF2VF_MSGORIGIN_SYSTEM;
+ resp = ADF_PFVF_MSGORIGIN_SYSTEM;
resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
- ADF_PF2VF_MSGTYPE_SHIFT;
+ ADF_PFVF_MSGTYPE_SHIFT;
resp |= ADF_PFVF_COMPAT_THIS_VERSION <<
ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
@@ -76,9 +76,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
/* PF always newer than legacy VF */
compat = ADF_PF2VF_VF_COMPATIBLE;

- resp = ADF_PF2VF_MSGORIGIN_SYSTEM;
+ resp = ADF_PFVF_MSGORIGIN_SYSTEM;
resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
- ADF_PF2VF_MSGTYPE_SHIFT;
+ ADF_PFVF_MSGTYPE_SHIFT;
/* Set legacy major and minor version num */
resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT |
1 << ADF_PF2VF_MINORVERSION_SHIFT;
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 763581839902..c9e929651a7d 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -16,8 +16,8 @@
*/
int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{
- u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM |
- (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT));
+ u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
+ (ADF_VF2PF_MSGTYPE_INIT << ADF_PFVF_MSGTYPE_SHIFT));

if (adf_send_vf2pf_msg(accel_dev, msg)) {
dev_err(&GET_DEV(accel_dev),
@@ -39,8 +39,8 @@ EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init);
*/
void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
{
- u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM |
- (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT));
+ u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
+ (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_PFVF_MSGTYPE_SHIFT));

if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status))
if (adf_send_vf2pf_msg(accel_dev, msg))
@@ -57,8 +57,8 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
u32 resp;
int ret;

- msg = ADF_VF2PF_MSGORIGIN_SYSTEM;
- msg |= ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_VF2PF_MSGTYPE_SHIFT;
+ msg = ADF_PFVF_MSGORIGIN_SYSTEM;
+ msg |= ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_PFVF_MSGTYPE_SHIFT;
msg |= ADF_PFVF_COMPAT_THIS_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255);

@@ -69,10 +69,10 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
return ret;
}

- pf_version = (resp & ADF_PF2VF_VERSION_RESP_VERS_MASK)
- >> ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
- compat = (resp & ADF_PF2VF_VERSION_RESP_RESULT_MASK)
- >> ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
+ pf_version = (resp >> ADF_PF2VF_VERSION_RESP_VERS_SHIFT)
+ & ADF_PF2VF_VERSION_RESP_VERS_MASK;
+ compat = (resp >> ADF_PF2VF_VERSION_RESP_RESULT_SHIFT)
+ & ADF_PF2VF_VERSION_RESP_RESULT_MASK;

/* Response from PF received, check compatibility */
switch (compat) {
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index 9c7489ed122c..f8d1c7d0ec4e 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -88,7 +88,7 @@ int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, u32 msg, u32 *resp)

static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, u32 msg)
{
- switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) {
+ switch ((msg >> ADF_PFVF_MSGTYPE_SHIFT) & ADF_PFVF_MSGTYPE_MASK) {
case ADF_PF2VF_MSGTYPE_RESTARTING:
dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n");

--
2.31.1


2021-12-16 09:11:30

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 08/24] crypto: qat - make PFVF send and receive direction agnostic

Currently PF and VF share the same send and receive logic for the PFVF
protocol. However, the inner behaviour still depends on the specific
direction, requiring a test to determine the if the sender is a PF or a
VF. Moreover the vf_nr parameter is only required for PF2VF messages and
ignored for the opposite direction.

Make the GEN2 send and recv completely direction agnostic, by calculating
and determining any direction specific input in the caller instead, and
feeding the send and the receive functions with the same arguments for
both PF and VF. In order to accommodate for this change, the API of the
pfvf_ops send and recv has been modified to remove any reference to vf_nr.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
.../crypto/qat/qat_common/adf_accel_devices.h | 5 +-
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 99 +++++++++++++------
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 11 ++-
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 11 ++-
4 files changed, 89 insertions(+), 37 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index cc8b10b23145..d65d8dda8fda 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -154,8 +154,9 @@ struct adf_pfvf_ops {
u32 (*get_vf2pf_sources)(void __iomem *pmisc_addr);
void (*enable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
void (*disable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
- int (*send_msg)(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr);
- u32 (*recv_msg)(struct adf_accel_dev *accel_dev, u8 vf_nr);
+ int (*send_msg)(struct adf_accel_dev *accel_dev, u32 msg,
+ u32 pfvf_offset, struct mutex *csr_lock);
+ u32 (*recv_msg)(struct adf_accel_dev *accel_dev, u32 pfvf_offset);
};

struct adf_hw_device_data {
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 2e0b9ac27393..1e45f3230c19 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -115,15 +115,22 @@ static bool is_legacy_user_pfvf_message(u32 msg)
return !(msg & ADF_PFVF_MSGORIGIN_SYSTEM);
}

+struct pfvf_gen2_params {
+ u32 pfvf_offset;
+ struct mutex *csr_lock; /* lock preventing concurrent access of CSR */
+ enum gen2_csr_pos local_offset;
+ enum gen2_csr_pos remote_offset;
+};
+
static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
- u8 vf_nr)
+ struct pfvf_gen2_params *params)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ enum gen2_csr_pos remote_offset = params->remote_offset;
+ enum gen2_csr_pos local_offset = params->local_offset;
unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
- enum gen2_csr_pos remote_offset;
- enum gen2_csr_pos local_offset;
- struct mutex *lock; /* lock preventing concurrent acces of CSR */
- u32 pfvf_offset;
+ struct mutex *lock = params->csr_lock;
+ u32 pfvf_offset = params->pfvf_offset;
u32 count = 0;
u32 int_bit;
u32 csr_val;
@@ -136,17 +143,6 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
* it and after encoding it. Which one to shift depends on the
* direction.
*/
- if (accel_dev->is_vf) {
- pfvf_offset = GET_PFVF_OPS(accel_dev)->get_vf2pf_offset(0);
- lock = &accel_dev->vf.vf2pf_lock;
- local_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
- remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
- } else {
- pfvf_offset = GET_PFVF_OPS(accel_dev)->get_pf2vf_offset(vf_nr);
- lock = &accel_dev->pf.vf_info[vf_nr].pf2vf_lock;
- local_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
- remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
- }

int_bit = gen2_csr_get_int_bit(local_offset);

@@ -208,23 +204,16 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
}
}

-static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev, u8 vf_nr)
+static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
+ struct pfvf_gen2_params *params)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
- enum gen2_csr_pos local_offset;
- u32 pfvf_offset;
+ enum gen2_csr_pos local_offset = params->local_offset;
+ u32 pfvf_offset = params->pfvf_offset;
u32 int_bit;
u32 csr_val;
u32 msg;

- if (accel_dev->is_vf) {
- pfvf_offset = GET_PFVF_OPS(accel_dev)->get_pf2vf_offset(0);
- local_offset = ADF_GEN2_CSR_PF2VF_OFFSET;
- } else {
- pfvf_offset = GET_PFVF_OPS(accel_dev)->get_vf2pf_offset(vf_nr);
- local_offset = ADF_GEN2_CSR_VF2PF_OFFSET;
- }
-
int_bit = gen2_csr_get_int_bit(local_offset);

/* Read message */
@@ -252,6 +241,54 @@ static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev, u8 vf_nr)
return msg;
}

+static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, u32 msg,
+ u32 pfvf_offset, struct mutex *csr_lock)
+{
+ struct pfvf_gen2_params params = {
+ .csr_lock = csr_lock,
+ .pfvf_offset = pfvf_offset,
+ .local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ .remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ };
+
+ return adf_gen2_pfvf_send(accel_dev, msg, &params);
+}
+
+static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, u32 msg,
+ u32 pfvf_offset, struct mutex *csr_lock)
+{
+ struct pfvf_gen2_params params = {
+ .csr_lock = csr_lock,
+ .pfvf_offset = pfvf_offset,
+ .local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ .remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ };
+
+ return adf_gen2_pfvf_send(accel_dev, msg, &params);
+}
+
+static u32 adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev, u32 pfvf_offset)
+{
+ struct pfvf_gen2_params params = {
+ .pfvf_offset = pfvf_offset,
+ .local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ .remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ };
+
+ return adf_gen2_pfvf_recv(accel_dev, &params);
+}
+
+static u32 adf_gen2_vf2pf_recv(struct adf_accel_dev *accel_dev, u32 pfvf_offset)
+{
+ struct pfvf_gen2_params params = {
+ .pfvf_offset = pfvf_offset,
+ .local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ .remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ };
+
+ return adf_gen2_pfvf_recv(accel_dev, &params);
+}
+
void adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
{
pfvf_ops->enable_comms = adf_enable_pf2vf_comms;
@@ -260,8 +297,8 @@ void adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
pfvf_ops->get_vf2pf_sources = adf_gen2_get_vf2pf_sources;
pfvf_ops->enable_vf2pf_interrupts = adf_gen2_enable_vf2pf_interrupts;
pfvf_ops->disable_vf2pf_interrupts = adf_gen2_disable_vf2pf_interrupts;
- pfvf_ops->send_msg = adf_gen2_pfvf_send;
- pfvf_ops->recv_msg = adf_gen2_pfvf_recv;
+ pfvf_ops->send_msg = adf_gen2_pf2vf_send;
+ pfvf_ops->recv_msg = adf_gen2_vf2pf_recv;
}
EXPORT_SYMBOL_GPL(adf_gen2_init_pf_pfvf_ops);

@@ -270,7 +307,7 @@ void adf_gen2_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
pfvf_ops->enable_comms = adf_enable_vf2pf_comms;
pfvf_ops->get_pf2vf_offset = adf_gen2_vf_get_pfvf_offset;
pfvf_ops->get_vf2pf_offset = adf_gen2_vf_get_pfvf_offset;
- pfvf_ops->send_msg = adf_gen2_pfvf_send;
- pfvf_ops->recv_msg = adf_gen2_pfvf_recv;
+ pfvf_ops->send_msg = adf_gen2_vf2pf_send;
+ pfvf_ops->recv_msg = adf_gen2_pf2vf_recv;
}
EXPORT_SYMBOL_GPL(adf_gen2_init_vf_pfvf_ops);
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index fb477eb89fef..4e4daec2ae34 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -19,7 +19,11 @@
*/
int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, u32 msg)
{
- return GET_PFVF_OPS(accel_dev)->send_msg(accel_dev, msg, vf_nr);
+ struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
+ u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(vf_nr);
+
+ return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset,
+ &accel_dev->pf.vf_info[vf_nr].pf2vf_lock);
}

/**
@@ -33,7 +37,10 @@ int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, u32 msg)
*/
static u32 adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr)
{
- return GET_PFVF_OPS(accel_dev)->recv_msg(accel_dev, vf_nr);
+ struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
+ u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(vf_nr);
+
+ return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
}

static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index f8d1c7d0ec4e..56e8185a9630 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -27,7 +27,11 @@
*/
int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 msg)
{
- return GET_PFVF_OPS(accel_dev)->send_msg(accel_dev, msg, 0);
+ struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
+ u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0);
+
+ return pfvf_ops->send_msg(accel_dev, msg, pfvf_offset,
+ &accel_dev->vf.vf2pf_lock);
}

/**
@@ -40,7 +44,10 @@ int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 msg)
*/
static u32 adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
- return GET_PFVF_OPS(accel_dev)->recv_msg(accel_dev, 0);
+ struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
+ u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);
+
+ return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
}

/**
--
2.31.1


2021-12-16 09:11:34

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 09/24] crypto: qat - set PFVF_MSGORIGIN just before sending

In this implementation of the PFVF protocol every egressing message must
include the ADF_PFVF_MSGORIGIN_SYSTEM flag. However, this flag can be set
on all the outbound messages just before sending them rather than at
message build time, as currently done.

Remove the unnecessary code duplication by setting the
ADF_PFVF_MSGORIGIN_SYSTEM flag only once at send time in
adf_gen2_pfvf_send().

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 1 +
drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c | 3 +--
drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c | 2 --
drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c | 12 +++++-------
4 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 1e45f3230c19..97bef41ddc47 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -149,6 +149,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
/* Pre-calculate message, shifting it in place and setting
* the in use pattern
*/
+ msg |= ADF_PFVF_MSGORIGIN_SYSTEM;
msg = gen2_csr_msg_to_position(msg, local_offset);
gen2_csr_set_in_use(&msg, remote_offset);

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
index 4057d7d74d62..f6d05cd29a82 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
@@ -9,8 +9,7 @@
void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
{
struct adf_accel_vf_info *vf;
- u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
- (ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PFVF_MSGTYPE_SHIFT));
+ u32 msg = ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PFVF_MSGTYPE_SHIFT;
int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));

for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 4e4daec2ae34..9f4baa9b14fc 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -64,7 +64,6 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
else
compat = ADF_PF2VF_VF_COMPAT_UNKNOWN;

- resp = ADF_PFVF_MSGORIGIN_SYSTEM;
resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
ADF_PFVF_MSGTYPE_SHIFT;
resp |= ADF_PFVF_COMPAT_THIS_VERSION <<
@@ -83,7 +82,6 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
/* PF always newer than legacy VF */
compat = ADF_PF2VF_VF_COMPATIBLE;

- resp = ADF_PFVF_MSGORIGIN_SYSTEM;
resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
ADF_PFVF_MSGTYPE_SHIFT;
/* Set legacy major and minor version num */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index c9e929651a7d..0463743a8d43 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -16,8 +16,7 @@
*/
int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{
- u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
- (ADF_VF2PF_MSGTYPE_INIT << ADF_PFVF_MSGTYPE_SHIFT));
+ u32 msg = ADF_VF2PF_MSGTYPE_INIT << ADF_PFVF_MSGTYPE_SHIFT;

if (adf_send_vf2pf_msg(accel_dev, msg)) {
dev_err(&GET_DEV(accel_dev),
@@ -39,8 +38,7 @@ EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init);
*/
void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
{
- u32 msg = (ADF_PFVF_MSGORIGIN_SYSTEM |
- (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_PFVF_MSGTYPE_SHIFT));
+ u32 msg = ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_PFVF_MSGTYPE_SHIFT;

if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status))
if (adf_send_vf2pf_msg(accel_dev, msg))
@@ -57,9 +55,9 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
u32 resp;
int ret;

- msg = ADF_PFVF_MSGORIGIN_SYSTEM;
- msg |= ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_PFVF_MSGTYPE_SHIFT;
- msg |= ADF_PFVF_COMPAT_THIS_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
+ msg = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_PFVF_MSGTYPE_SHIFT |
+ ADF_PFVF_COMPAT_THIS_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
+
BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255);

ret = adf_send_vf2pf_req(accel_dev, msg, &resp);
--
2.31.1


2021-12-16 09:11:35

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 11/24] crypto: qat - leverage bitfield.h utils for PFVF messages

The PFVF protocol defines messages composed of a number of control
bitfields. Replace all the code setting and retrieving such bits
with the utilities from bitfield.h, to improve code quality and
readability.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 8 ++++----
drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c | 13 +++++++------
drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c | 7 +++----
3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index 26eb27853e83..daee3d7ceb8c 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -3,6 +3,8 @@
#ifndef ADF_PFVF_MSG_H
#define ADF_PFVF_MSG_H

+#include <linux/bits.h>
+
/*
* PF<->VF Messaging
* The PF has an array of 32-bit PF2VF registers, one for each VF. The
@@ -86,10 +88,8 @@ enum pfvf_compatibility_version {
};

/* PF->VF Version Response */
-#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 0
-#define ADF_PF2VF_VERSION_RESP_VERS_MASK 0xFF
-#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 8
-#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x03
+#define ADF_PF2VF_VERSION_RESP_VERS_MASK GENMASK(7, 0)
+#define ADF_PF2VF_VERSION_RESP_RESULT_MASK GENMASK(9, 8)

enum pf2vf_compat_response {
ADF_PF2VF_VF_COMPATIBLE = 0x01,
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index bb4d7db68579..8785b9d1df91 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2015 - 2021 Intel Corporation */
+#include <linux/bitfield.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
@@ -64,9 +65,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
compat = ADF_PF2VF_VF_COMPAT_UNKNOWN;

resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
- resp->data = ADF_PFVF_COMPAT_THIS_VERSION <<
- ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
- resp->data |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
+ resp->data = FIELD_PREP(ADF_PF2VF_VERSION_RESP_VERS_MASK,
+ ADF_PFVF_COMPAT_THIS_VERSION) |
+ FIELD_PREP(ADF_PF2VF_VERSION_RESP_RESULT_MASK, compat);
}
break;
case ADF_VF2PF_MSGTYPE_VERSION_REQ:
@@ -80,10 +81,10 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
/* PF always newer than legacy VF */
compat = ADF_PF2VF_VF_COMPATIBLE;

- resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
/* Set legacy major and minor version to the latest, 1.1 */
- resp->data |= 0x11;
- resp->data |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
+ resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
+ resp->data = FIELD_PREP(ADF_PF2VF_VERSION_RESP_VERS_MASK, 0x11) |
+ FIELD_PREP(ADF_PF2VF_VERSION_RESP_RESULT_MASK, compat);
}
break;
case ADF_VF2PF_MSGTYPE_INIT:
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 5184a77598d2..130d7b9c12ea 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2015 - 2021 Intel Corporation */
+#include <linux/bitfield.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_pfvf_msg.h"
@@ -67,10 +68,8 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
return ret;
}

- pf_version = (resp.data >> ADF_PF2VF_VERSION_RESP_VERS_SHIFT)
- & ADF_PF2VF_VERSION_RESP_VERS_MASK;
- compat = (resp.data >> ADF_PF2VF_VERSION_RESP_RESULT_SHIFT)
- & ADF_PF2VF_VERSION_RESP_RESULT_MASK;
+ pf_version = FIELD_GET(ADF_PF2VF_VERSION_RESP_VERS_MASK, resp.data);
+ compat = FIELD_GET(ADF_PF2VF_VERSION_RESP_RESULT_MASK, resp.data);

/* Response from PF received, check compatibility */
switch (compat) {
--
2.31.1


2021-12-16 09:11:35

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 10/24] crypto: qat - abstract PFVF messages with struct pfvf_message

This implementation of the PFVF protocol was designed around the GEN2
devices and its CSR format. In order to support future generations,
which come with differently sized fields, change the definition of the PFVF
message and make it abstract by means of a new pfvf_message struct. Also,
introduce some utilities to translate to and from the new message format
and the device specific CSR format.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/Makefile | 2 +-
.../crypto/qat/qat_common/adf_accel_devices.h | 8 ++-
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 60 +++++++++++++------
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 19 +++---
.../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 2 +-
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 51 +++++++---------
.../crypto/qat/qat_common/adf_pfvf_pf_proto.h | 2 +-
.../crypto/qat/qat_common/adf_pfvf_utils.c | 50 ++++++++++++++++
.../crypto/qat/qat_common/adf_pfvf_utils.h | 24 ++++++++
.../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 18 +++---
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 26 ++++----
.../crypto/qat/qat_common/adf_pfvf_vf_proto.h | 5 +-
12 files changed, 184 insertions(+), 83 deletions(-)
create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.c
create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.h

diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
index 1376504d16ff..80f6cb424753 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -19,7 +19,7 @@ intel_qat-objs := adf_cfg.o \
qat_hal.o

intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o
-intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o \
+intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \
adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \
adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \
adf_gen2_pfvf.o
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index d65d8dda8fda..d5ccefc04153 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -8,6 +8,7 @@
#include <linux/io.h>
#include <linux/ratelimit.h>
#include "adf_cfg_common.h"
+#include "adf_pfvf_msg.h"

#define ADF_DH895XCC_DEVICE_NAME "dh895xcc"
#define ADF_DH895XCCVF_DEVICE_NAME "dh895xccvf"
@@ -154,9 +155,10 @@ struct adf_pfvf_ops {
u32 (*get_vf2pf_sources)(void __iomem *pmisc_addr);
void (*enable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
void (*disable_vf2pf_interrupts)(void __iomem *pmisc_addr, u32 vf_mask);
- int (*send_msg)(struct adf_accel_dev *accel_dev, u32 msg,
+ int (*send_msg)(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
u32 pfvf_offset, struct mutex *csr_lock);
- u32 (*recv_msg)(struct adf_accel_dev *accel_dev, u32 pfvf_offset);
+ struct pfvf_message (*recv_msg)(struct adf_accel_dev *accel_dev,
+ u32 pfvf_offset);
};

struct adf_hw_device_data {
@@ -275,7 +277,7 @@ struct adf_accel_dev {
struct tasklet_struct pf2vf_bh_tasklet;
struct mutex vf2pf_lock; /* protect CSR access */
struct completion msg_received;
- u32 response; /* temp field holding pf2vf response */
+ struct pfvf_message response; /* temp field holding pf2vf response */
u8 pf_version;
} vf;
};
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 97bef41ddc47..7a927bea4ac6 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -9,6 +9,7 @@
#include "adf_pfvf_msg.h"
#include "adf_pfvf_pf_proto.h"
#include "adf_pfvf_vf_proto.h"
+#include "adf_pfvf_utils.h"

/* VF2PF interrupts */
#define ADF_GEN2_ERR_REG_VF2PF(vf_src) (((vf_src) & 0x01FFFE00) >> 9)
@@ -25,6 +26,16 @@ enum gen2_csr_pos {
ADF_GEN2_CSR_VF2PF_OFFSET = 16,
};

+#define ADF_PFVF_GEN2_MSGTYPE_SHIFT 2
+#define ADF_PFVF_GEN2_MSGTYPE_MASK 0x0F
+#define ADF_PFVF_GEN2_MSGDATA_SHIFT 6
+#define ADF_PFVF_GEN2_MSGDATA_MASK 0x3FF
+
+static const struct pfvf_csr_format csr_gen2_fmt = {
+ { ADF_PFVF_GEN2_MSGTYPE_SHIFT, ADF_PFVF_GEN2_MSGTYPE_MASK },
+ { ADF_PFVF_GEN2_MSGDATA_SHIFT, ADF_PFVF_GEN2_MSGDATA_MASK },
+};
+
#define ADF_PFVF_MSG_ACK_DELAY 2
#define ADF_PFVF_MSG_ACK_MAX_RETRY 100

@@ -122,7 +133,8 @@ struct pfvf_gen2_params {
enum gen2_csr_pos remote_offset;
};

-static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
+static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
+ struct pfvf_message msg,
struct pfvf_gen2_params *params)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
@@ -134,6 +146,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
u32 count = 0;
u32 int_bit;
u32 csr_val;
+ u32 csr_msg;
int ret;

/* Gen2 messages, both PF->VF and VF->PF, are all 16 bits long. This
@@ -146,12 +159,15 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,

int_bit = gen2_csr_get_int_bit(local_offset);

- /* Pre-calculate message, shifting it in place and setting
- * the in use pattern
+ csr_msg = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen2_fmt);
+ if (unlikely(!csr_msg))
+ return -EINVAL;
+
+ /* Prepare for CSR format, shifting the wire message in place and
+ * setting the in use pattern
*/
- msg |= ADF_PFVF_MSGORIGIN_SYSTEM;
- msg = gen2_csr_msg_to_position(msg, local_offset);
- gen2_csr_set_in_use(&msg, remote_offset);
+ csr_msg = gen2_csr_msg_to_position(csr_msg, local_offset);
+ gen2_csr_set_in_use(&csr_msg, remote_offset);

mutex_lock(lock);

@@ -167,7 +183,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
}

/* Attempt to get ownership of the PFVF CSR */
- ADF_CSR_WR(pmisc_addr, pfvf_offset, msg | int_bit);
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_msg | int_bit);

/* Wait for confirmation from remote func it received the message */
do {
@@ -181,7 +197,7 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
ret = -EIO;
}

- if (csr_val != msg) {
+ if (csr_val != csr_msg) {
dev_dbg(&GET_DEV(accel_dev),
"Collision - PFVF CSR overwritten by remote function\n");
goto retry;
@@ -205,15 +221,16 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev, u32 msg,
}
}

-static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
- struct pfvf_gen2_params *params)
+static struct pfvf_message adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
+ struct pfvf_gen2_params *params)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
enum gen2_csr_pos local_offset = params->local_offset;
u32 pfvf_offset = params->pfvf_offset;
+ struct pfvf_message msg = { 0 };
u32 int_bit;
u32 csr_val;
- u32 msg;
+ u16 csr_msg;

int_bit = gen2_csr_get_int_bit(local_offset);

@@ -222,19 +239,22 @@ static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
if (!(csr_val & int_bit)) {
dev_info(&GET_DEV(accel_dev),
"Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", csr_val);
- return 0;
+ return msg;
}

/* Extract the message from the CSR */
- msg = gen2_csr_msg_from_position(csr_val, local_offset);
+ csr_msg = gen2_csr_msg_from_position(csr_val, local_offset);

/* Ignore legacy non-system (non-kernel) messages */
- if (unlikely(is_legacy_user_pfvf_message(msg))) {
+ if (unlikely(is_legacy_user_pfvf_message(csr_msg))) {
dev_dbg(&GET_DEV(accel_dev),
"Ignored non-system message (0x%.8x);\n", csr_val);
- return 0;
+ return msg;
}

+ /* Return the pfvf_message format */
+ msg = adf_pfvf_message_of(accel_dev, csr_msg, &csr_gen2_fmt);
+
/* To ACK, clear the INT bit */
csr_val &= ~int_bit;
ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
@@ -242,7 +262,7 @@ static u32 adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
return msg;
}

-static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, u32 msg,
+static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
u32 pfvf_offset, struct mutex *csr_lock)
{
struct pfvf_gen2_params params = {
@@ -255,7 +275,7 @@ static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, u32 msg,
return adf_gen2_pfvf_send(accel_dev, msg, &params);
}

-static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, u32 msg,
+static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
u32 pfvf_offset, struct mutex *csr_lock)
{
struct pfvf_gen2_params params = {
@@ -268,7 +288,8 @@ static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, u32 msg,
return adf_gen2_pfvf_send(accel_dev, msg, &params);
}

-static u32 adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev, u32 pfvf_offset)
+static struct pfvf_message adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev,
+ u32 pfvf_offset)
{
struct pfvf_gen2_params params = {
.pfvf_offset = pfvf_offset,
@@ -279,7 +300,8 @@ static u32 adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev, u32 pfvf_offset)
return adf_gen2_pfvf_recv(accel_dev, &params);
}

-static u32 adf_gen2_vf2pf_recv(struct adf_accel_dev *accel_dev, u32 pfvf_offset)
+static struct pfvf_message adf_gen2_vf2pf_recv(struct adf_accel_dev *accel_dev,
+ u32 pfvf_offset)
{
struct pfvf_gen2_params params = {
.pfvf_offset = pfvf_offset,
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index 3ba88bcd0726..26eb27853e83 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -56,8 +56,14 @@
/* PFVF message common bits */
#define ADF_PFVF_INT BIT(0)
#define ADF_PFVF_MSGORIGIN_SYSTEM BIT(1)
-#define ADF_PFVF_MSGTYPE_SHIFT 2
-#define ADF_PFVF_MSGTYPE_MASK 0x0F
+
+/* Different generations have different CSR layouts, use this struct
+ * to abstract these differences away
+ */
+struct pfvf_message {
+ u8 type;
+ u32 data;
+};

/* PF->VF messages */
enum pf2vf_msgtype {
@@ -80,11 +86,9 @@ enum pfvf_compatibility_version {
};

/* PF->VF Version Response */
-#define ADF_PF2VF_MINORVERSION_SHIFT 6
-#define ADF_PF2VF_MAJORVERSION_SHIFT 10
-#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 6
+#define ADF_PF2VF_VERSION_RESP_VERS_SHIFT 0
#define ADF_PF2VF_VERSION_RESP_VERS_MASK 0xFF
-#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 14
+#define ADF_PF2VF_VERSION_RESP_RESULT_SHIFT 8
#define ADF_PF2VF_VERSION_RESP_RESULT_MASK 0x03

enum pf2vf_compat_response {
@@ -93,7 +97,4 @@ enum pf2vf_compat_response {
ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03,
};

-/* VF->PF Compatible Version Request */
-#define ADF_VF2PF_COMPAT_VER_REQ_SHIFT 6
-
#endif /* ADF_PFVF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
index f6d05cd29a82..ad198b624098 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
@@ -9,7 +9,7 @@
void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
{
struct adf_accel_vf_info *vf;
- u32 msg = ADF_PF2VF_MSGTYPE_RESTARTING << ADF_PFVF_MSGTYPE_SHIFT;
+ struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTING };
int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));

for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 9f4baa9b14fc..bb4d7db68579 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -17,7 +17,7 @@
*
* Return: 0 on success, error code otherwise.
*/
-int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, u32 msg)
+int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, struct pfvf_message msg)
{
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(vf_nr);
@@ -35,7 +35,7 @@ int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, u32 msg)
*
* Return: a valid message on success, zero otherwise.
*/
-static u32 adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr)
+static struct pfvf_message adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr)
{
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(vf_nr);
@@ -43,16 +43,15 @@ static u32 adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr)
return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
}

-static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
- u32 msg, u32 *response)
+static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
+ struct pfvf_message msg, struct pfvf_message *resp)
{
struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
- u32 resp = 0;

- switch ((msg >> ADF_PFVF_MSGTYPE_SHIFT) & ADF_PFVF_MSGTYPE_MASK) {
+ switch (msg.type) {
case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ:
{
- u8 vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
+ u8 vf_compat_ver = msg.data;
u8 compat;

dev_dbg(&GET_DEV(accel_dev),
@@ -64,11 +63,10 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
else
compat = ADF_PF2VF_VF_COMPAT_UNKNOWN;

- resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
- ADF_PFVF_MSGTYPE_SHIFT;
- resp |= ADF_PFVF_COMPAT_THIS_VERSION <<
- ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
- resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
+ resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
+ resp->data = ADF_PFVF_COMPAT_THIS_VERSION <<
+ ADF_PF2VF_VERSION_RESP_VERS_SHIFT;
+ resp->data |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
}
break;
case ADF_VF2PF_MSGTYPE_VERSION_REQ:
@@ -82,12 +80,10 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
/* PF always newer than legacy VF */
compat = ADF_PF2VF_VF_COMPATIBLE;

- resp |= ADF_PF2VF_MSGTYPE_VERSION_RESP <<
- ADF_PFVF_MSGTYPE_SHIFT;
- /* Set legacy major and minor version num */
- resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT |
- 1 << ADF_PF2VF_MINORVERSION_SHIFT;
- resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
+ resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
+ /* Set legacy major and minor version to the latest, 1.1 */
+ resp->data |= 0x11;
+ resp->data |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT;
}
break;
case ADF_VF2PF_MSGTYPE_INIT:
@@ -105,29 +101,28 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr,
}
break;
default:
- dev_dbg(&GET_DEV(accel_dev), "Unknown message from VF%d (0x%.8x)\n",
- vf_nr, msg);
+ dev_dbg(&GET_DEV(accel_dev),
+ "Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n",
+ vf_nr, msg.type, msg.data);
return -ENOMSG;
}

- *response = resp;
-
return 0;
}

bool adf_recv_and_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr)
{
- u32 resp = 0;
- u32 msg;
+ struct pfvf_message req;
+ struct pfvf_message resp = {0};

- msg = adf_recv_vf2pf_msg(accel_dev, vf_nr);
- if (!msg)
+ req = adf_recv_vf2pf_msg(accel_dev, vf_nr);
+ if (!req.type) /* Legacy or no message */
return true;

- if (adf_handle_vf2pf_msg(accel_dev, vf_nr, msg, &resp))
+ if (adf_handle_vf2pf_msg(accel_dev, vf_nr, req, &resp))
return false;

- if (resp && adf_send_pf2vf_msg(accel_dev, vf_nr, resp))
+ if (resp.type && adf_send_pf2vf_msg(accel_dev, vf_nr, resp))
dev_err(&GET_DEV(accel_dev),
"Failed to send response to VF%d\n", vf_nr);

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.h b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.h
index 63245407bfb6..165d266d023d 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.h
@@ -6,7 +6,7 @@
#include <linux/types.h>
#include "adf_accel_devices.h"

-int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, u32 msg);
+int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, struct pfvf_message msg);

int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev);

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.c b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
new file mode 100644
index 000000000000..494da89e2048
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
+/* Copyright(c) 2021 Intel Corporation */
+#include <linux/pci.h>
+#include <linux/types.h>
+#include "adf_accel_devices.h"
+#include "adf_pfvf_msg.h"
+#include "adf_pfvf_utils.h"
+
+static bool set_value_on_csr_msg(struct adf_accel_dev *accel_dev, u32 *csr_msg,
+ u32 value, const struct pfvf_field_format *fmt)
+{
+ if (unlikely((value & fmt->mask) != value)) {
+ dev_err(&GET_DEV(accel_dev),
+ "PFVF message value 0x%X out of range, %u max allowed\n",
+ value, fmt->mask);
+ return false;
+ }
+
+ *csr_msg |= value << fmt->offset;
+
+ return true;
+}
+
+u32 adf_pfvf_csr_msg_of(struct adf_accel_dev *accel_dev,
+ struct pfvf_message msg,
+ const struct pfvf_csr_format *fmt)
+{
+ u32 csr_msg = 0;
+
+ if (!set_value_on_csr_msg(accel_dev, &csr_msg, msg.type, &fmt->type) ||
+ !set_value_on_csr_msg(accel_dev, &csr_msg, msg.data, &fmt->data))
+ return 0;
+
+ return csr_msg | ADF_PFVF_MSGORIGIN_SYSTEM;
+}
+
+struct pfvf_message adf_pfvf_message_of(struct adf_accel_dev *accel_dev, u32 csr_msg,
+ const struct pfvf_csr_format *fmt)
+{
+ struct pfvf_message msg = { 0 };
+
+ msg.type = (csr_msg >> fmt->type.offset) & fmt->type.mask;
+ msg.data = (csr_msg >> fmt->data.offset) & fmt->data.mask;
+
+ if (unlikely(!msg.type))
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid PFVF msg with no type received\n");
+
+ return msg;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
new file mode 100644
index 000000000000..7b73b5992d03
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
+/* Copyright(c) 2021 Intel Corporation */
+#ifndef ADF_PFVF_UTILS_H
+#define ADF_PFVF_UTILS_H
+
+#include <linux/types.h>
+#include "adf_pfvf_msg.h"
+
+struct pfvf_field_format {
+ u8 offset;
+ u32 mask;
+};
+
+struct pfvf_csr_format {
+ struct pfvf_field_format type;
+ struct pfvf_field_format data;
+};
+
+u32 adf_pfvf_csr_msg_of(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
+ const struct pfvf_csr_format *fmt);
+struct pfvf_message adf_pfvf_message_of(struct adf_accel_dev *accel_dev, u32 raw_msg,
+ const struct pfvf_csr_format *fmt);
+
+#endif /* ADF_PFVF_UTILS_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 0463743a8d43..5184a77598d2 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -16,7 +16,7 @@
*/
int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{
- u32 msg = ADF_VF2PF_MSGTYPE_INIT << ADF_PFVF_MSGTYPE_SHIFT;
+ struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT };

if (adf_send_vf2pf_msg(accel_dev, msg)) {
dev_err(&GET_DEV(accel_dev),
@@ -38,7 +38,7 @@ EXPORT_SYMBOL_GPL(adf_vf2pf_notify_init);
*/
void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev)
{
- u32 msg = ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_PFVF_MSGTYPE_SHIFT;
+ struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_SHUTDOWN };

if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status))
if (adf_send_vf2pf_msg(accel_dev, msg))
@@ -50,13 +50,13 @@ EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown);
int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
{
u8 pf_version;
- u32 msg = 0;
int compat;
- u32 resp;
int ret;
-
- msg = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_PFVF_MSGTYPE_SHIFT |
- ADF_PFVF_COMPAT_THIS_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT;
+ struct pfvf_message resp;
+ struct pfvf_message msg = {
+ .type = ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ,
+ .data = ADF_PFVF_COMPAT_THIS_VERSION,
+ };

BUILD_BUG_ON(ADF_PFVF_COMPAT_THIS_VERSION > 255);

@@ -67,9 +67,9 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
return ret;
}

- pf_version = (resp >> ADF_PF2VF_VERSION_RESP_VERS_SHIFT)
+ pf_version = (resp.data >> ADF_PF2VF_VERSION_RESP_VERS_SHIFT)
& ADF_PF2VF_VERSION_RESP_VERS_MASK;
- compat = (resp >> ADF_PF2VF_VERSION_RESP_RESULT_SHIFT)
+ compat = (resp.data >> ADF_PF2VF_VERSION_RESP_RESULT_SHIFT)
& ADF_PF2VF_VERSION_RESP_RESULT_MASK;

/* Response from PF received, check compatibility */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index 56e8185a9630..729c00c0d254 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -25,7 +25,7 @@
*
* Return: 0 on success, error code otherwise.
*/
-int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 msg)
+int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg)
{
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(0);
@@ -42,7 +42,7 @@ int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 msg)
*
* Return: a valid message on success, zero otherwise.
*/
-static u32 adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
+static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);
@@ -61,7 +61,8 @@ static u32 adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
*
* Return: 0 on success, error code otherwise.
*/
-int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, u32 msg, u32 *resp)
+int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
+ struct pfvf_message *resp)
{
unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT);
int ret;
@@ -88,14 +89,15 @@ int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, u32 msg, u32 *resp)
*resp = accel_dev->vf.response;

/* Once copied, set to an invalid value */
- accel_dev->vf.response = 0;
+ accel_dev->vf.response.type = 0;

return 0;
}

-static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, u32 msg)
+static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
+ struct pfvf_message msg)
{
- switch ((msg >> ADF_PFVF_MSGTYPE_SHIFT) & ADF_PFVF_MSGTYPE_MASK) {
+ switch (msg.type) {
case ADF_PF2VF_MSGTYPE_RESTARTING:
dev_dbg(&GET_DEV(accel_dev), "Restarting message received from PF\n");

@@ -103,13 +105,15 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, u32 msg)
return false;
case ADF_PF2VF_MSGTYPE_VERSION_RESP:
dev_dbg(&GET_DEV(accel_dev),
- "Response message received from PF (0x%.8x)\n", msg);
+ "Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
+ msg.type, msg.data);
accel_dev->vf.response = msg;
complete(&accel_dev->vf.msg_received);
return true;
default:
dev_err(&GET_DEV(accel_dev),
- "Unknown PF2VF message (0x%.8x) from PF\n", msg);
+ "Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n",
+ msg.type, msg.data);
}

return false;
@@ -117,12 +121,14 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev, u32 msg)

bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
{
- u32 msg;
+ struct pfvf_message msg;

msg = adf_recv_pf2vf_msg(accel_dev);
- if (msg)
+ if (msg.type) /* Invalid or no message */
return adf_handle_pf2vf_msg(accel_dev, msg);

+ /* No replies for PF->VF messages at present */
+
return true;
}

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
index 6226d4d9d520..e32d1bc3a740 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
@@ -6,8 +6,9 @@
#include <linux/types.h>
#include "adf_accel_devices.h"

-int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 msg);
-int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, u32 msg, u32 *resp);
+int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg);
+int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
+ struct pfvf_message *resp);

int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev);

--
2.31.1


2021-12-16 09:11:37

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 12/24] crypto: qat - leverage read_poll_timeout in PFVF send

Replace the polling loop, waiting for the remote end to acknowledge
the reception of the message, with the equivalent and standard
read_poll_timeout() in adf_gen2_pfvf_send().

Also, the use of the read_poll_timeout():
- implies the use of microseconds for the timings, so update the previous
values from ms to us
- allows to leverage the return value for both success and error,
removing the need for the reset of the 'ret' variable soon after the
'start' label.

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 20 ++++++++-----------
1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 7a927bea4ac6..53c2e124944d 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2021 Intel Corporation */
#include <linux/delay.h>
+#include <linux/iopoll.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
@@ -36,8 +37,8 @@ static const struct pfvf_csr_format csr_gen2_fmt = {
{ ADF_PFVF_GEN2_MSGDATA_SHIFT, ADF_PFVF_GEN2_MSGDATA_MASK },
};

-#define ADF_PFVF_MSG_ACK_DELAY 2
-#define ADF_PFVF_MSG_ACK_MAX_RETRY 100
+#define ADF_PFVF_MSG_ACK_DELAY_US 2000
+#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (ADF_PFVF_MSG_ACK_DELAY_US * 100)

#define ADF_PFVF_MSG_RETRY_DELAY 5
#define ADF_PFVF_MSG_MAX_RETRIES 3
@@ -143,7 +144,6 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
unsigned int retries = ADF_PFVF_MSG_MAX_RETRIES;
struct mutex *lock = params->csr_lock;
u32 pfvf_offset = params->pfvf_offset;
- u32 count = 0;
u32 int_bit;
u32 csr_val;
u32 csr_msg;
@@ -172,8 +172,6 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
mutex_lock(lock);

start:
- ret = 0;
-
/* Check if the PFVF CSR is in use by remote function */
csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
if (gen2_csr_is_in_use(csr_val, local_offset)) {
@@ -186,15 +184,13 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_msg | int_bit);

/* Wait for confirmation from remote func it received the message */
- do {
- msleep(ADF_PFVF_MSG_ACK_DELAY);
- csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
- } while ((csr_val & int_bit) && (count++ < ADF_PFVF_MSG_ACK_MAX_RETRY));
-
- if (csr_val & int_bit) {
+ ret = read_poll_timeout(ADF_CSR_RD, csr_val, !(csr_val & int_bit),
+ ADF_PFVF_MSG_ACK_DELAY_US,
+ ADF_PFVF_MSG_ACK_MAX_DELAY_US,
+ true, pmisc_addr, pfvf_offset);
+ if (unlikely(ret < 0)) {
dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n");
csr_val &= ~int_bit;
- ret = -EIO;
}

if (csr_val != csr_msg) {
--
2.31.1


2021-12-16 09:11:46

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 13/24] crypto: qat - improve the ACK timings in PFVF send

Review the ACK timings in adf_gen2_pfvf_send() to improve the latency
by reducing the polling interval. Also increase the timeout, for higher
tolerance in highly loaded systems, and reposition these new values to
allow for inclusion by the future GEN4 devices too.

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 3 ---
drivers/crypto/qat/qat_common/adf_pfvf_utils.h | 4 ++++
2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index 53c2e124944d..feab01ec4bbb 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -37,9 +37,6 @@ static const struct pfvf_csr_format csr_gen2_fmt = {
{ ADF_PFVF_GEN2_MSGDATA_SHIFT, ADF_PFVF_GEN2_MSGDATA_MASK },
};

-#define ADF_PFVF_MSG_ACK_DELAY_US 2000
-#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (ADF_PFVF_MSG_ACK_DELAY_US * 100)
-
#define ADF_PFVF_MSG_RETRY_DELAY 5
#define ADF_PFVF_MSG_MAX_RETRIES 3

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
index 7b73b5992d03..7676fdddbe26 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
@@ -6,6 +6,10 @@
#include <linux/types.h>
#include "adf_pfvf_msg.h"

+/* How long to wait for far side to acknowledge receipt */
+#define ADF_PFVF_MSG_ACK_DELAY_US 4
+#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (1 * USEC_PER_SEC)
+
struct pfvf_field_format {
u8 offset;
u32 mask;
--
2.31.1


2021-12-16 09:11:56

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 14/24] crypto: qat - store the PFVF protocol version of the endpoints

This patch adds an entry for storing the PFVF protocol version for both
PF and VFs. While not currently used, knowing and storing the remote
protocol version enables more complex compatibility checks and/or newer
features for compatible PFVF endpoints in the future.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_accel_devices.h | 3 ++-
drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c | 5 +++++
drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c | 2 +-
drivers/crypto/qat/qat_common/adf_sriov.c | 1 +
4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index d5ccefc04153..1fb32f3e78df 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -249,6 +249,7 @@ struct adf_accel_vf_info {
struct ratelimit_state vf2pf_ratelimit;
u32 vf_nr;
bool init;
+ u8 vf_compat_ver;
};

struct adf_accel_dev {
@@ -278,7 +279,7 @@ struct adf_accel_dev {
struct mutex vf2pf_lock; /* protect CSR access */
struct completion msg_received;
struct pfvf_message response; /* temp field holding pf2vf response */
- u8 pf_version;
+ u8 pf_compat_ver;
} vf;
};
bool is_vf;
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 8785b9d1df91..f461aa0a95c7 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -64,6 +64,8 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
else
compat = ADF_PF2VF_VF_COMPAT_UNKNOWN;

+ vf_info->vf_compat_ver = vf_compat_ver;
+
resp->type = ADF_PF2VF_MSGTYPE_VERSION_RESP;
resp->data = FIELD_PREP(ADF_PF2VF_VERSION_RESP_VERS_MASK,
ADF_PFVF_COMPAT_THIS_VERSION) |
@@ -78,6 +80,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
"Legacy VersionRequest received from VF%d to PF (vers 1.1)\n",
vf_nr);

+ /* legacy driver, VF compat_ver is 0 */
+ vf_info->vf_compat_ver = 0;
+
/* PF always newer than legacy VF */
compat = ADF_PF2VF_VF_COMPATIBLE;

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 130d7b9c12ea..307d593042f3 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -89,6 +89,6 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
return -EINVAL;
}

- accel_dev->vf.pf_version = pf_version;
+ accel_dev->vf.pf_compat_ver = pf_version;
return 0;
}
diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c
index 429990c5e0f3..6366622ff8fd 100644
--- a/drivers/crypto/qat/qat_common/adf_sriov.c
+++ b/drivers/crypto/qat/qat_common/adf_sriov.c
@@ -58,6 +58,7 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)
/* This ptr will be populated when VFs will be created */
vf_info->accel_dev = accel_dev;
vf_info->vf_nr = i;
+ vf_info->vf_compat_ver = 0;

mutex_init(&vf_info->pf2vf_lock);
ratelimit_state_init(&vf_info->vf2pf_ratelimit,
--
2.31.1


2021-12-16 09:11:56

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 15/24] crypto: qat - store the ring-to-service mapping

This driver relies on either the FW (on the PF) or the PF (on the VF) to
know how crypto services and rings map to one another. Store this
information so that it can be referenced in the future at runtime for
checks or extensions.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 1 +
drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c | 1 +
.../crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 1 +
drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c | 1 +
drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c | 1 +
drivers/crypto/qat/qat_common/adf_accel_devices.h | 8 ++++++++
drivers/crypto/qat/qat_common/adf_cfg_common.h | 13 +++++++++++++
drivers/crypto/qat/qat_common/adf_gen2_hw_data.h | 8 ++++++++
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 8 ++++++++
.../crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 1 +
.../qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 1 +
11 files changed, 44 insertions(+)

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index 0d1603894af4..67cd20f443ab 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -246,6 +246,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->num_logical_accel = 1;
hw_data->tx_rx_gap = ADF_4XXX_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_4XXX_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN4_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_isr_resource_alloc;
hw_data->free_irq = adf_isr_resource_free;
hw_data->enable_error_correction = adf_enable_error_correction;
diff --git a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c
index 3987a44fa164..b941fe3713ff 100644
--- a/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c
@@ -109,6 +109,7 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_isr_resource_alloc;
hw_data->free_irq = adf_isr_resource_free;
hw_data->enable_error_correction = adf_gen2_enable_error_correction;
diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c
index 85122013534d..a9fbe57b32ae 100644
--- a/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c
+++ b/drivers/crypto/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c
@@ -67,6 +67,7 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_C3XXXIOV_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_C3XXXIOV_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_C3XXXIOV_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_vf_isr_resource_alloc;
hw_data->free_irq = adf_vf_isr_resource_free;
hw_data->enable_error_correction = adf_vf_void_noop;
diff --git a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
index a76e33d7a215..b1eac2f81faa 100644
--- a/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
+++ b/drivers/crypto/qat/qat_c62x/adf_c62x_hw_data.c
@@ -111,6 +111,7 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_C62X_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_isr_resource_alloc;
hw_data->free_irq = adf_isr_resource_free;
hw_data->enable_error_correction = adf_gen2_enable_error_correction;
diff --git a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c
index 99c56405f88f..0282038fca54 100644
--- a/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c
+++ b/drivers/crypto/qat/qat_c62xvf/adf_c62xvf_hw_data.c
@@ -67,6 +67,7 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_C62XIOV_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_C62XIOV_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_C62XIOV_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_vf_isr_resource_alloc;
hw_data->free_irq = adf_vf_isr_resource_free;
hw_data->enable_error_correction = adf_vf_void_noop;
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 1fb32f3e78df..59f06e53d316 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -208,6 +208,7 @@ struct adf_hw_device_data {
u32 ae_mask;
u32 admin_ae_mask;
u16 tx_rings_mask;
+ u16 ring_to_svc_map;
u8 tx_rx_gap;
u8 num_banks;
u16 num_banks_per_vf;
@@ -224,12 +225,19 @@ struct adf_hw_device_data {
/* CSR read macro */
#define ADF_CSR_RD(csr_base, csr_offset) __raw_readl(csr_base + csr_offset)

+#define ADF_CFG_NUM_SERVICES 4
+#define ADF_SRV_TYPE_BIT_LEN 3
+#define ADF_SRV_TYPE_MASK 0x7
+
#define GET_DEV(accel_dev) ((accel_dev)->accel_pci_dev.pci_dev->dev)
#define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars)
#define GET_HW_DATA(accel_dev) (accel_dev->hw_device)
#define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks)
#define GET_NUM_RINGS_PER_BANK(accel_dev) \
GET_HW_DATA(accel_dev)->num_rings_per_bank
+#define GET_SRV_TYPE(accel_dev, idx) \
+ (((GET_HW_DATA(accel_dev)->ring_to_svc_map) >> (ADF_SRV_TYPE_BIT_LEN * (idx))) \
+ & ADF_SRV_TYPE_MASK)
#define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines)
#define GET_CSR_OPS(accel_dev) (&(accel_dev)->hw_device->csr_ops)
#define GET_PFVF_OPS(accel_dev) (&(accel_dev)->hw_device->pfvf_ops)
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_common.h b/drivers/crypto/qat/qat_common/adf_cfg_common.h
index 4fabb70b1f18..6e5de1dab97b 100644
--- a/drivers/crypto/qat/qat_common/adf_cfg_common.h
+++ b/drivers/crypto/qat/qat_common/adf_cfg_common.h
@@ -19,6 +19,19 @@
#define ADF_MAX_DEVICES (32 * 32)
#define ADF_DEVS_ARRAY_SIZE BITS_TO_LONGS(ADF_MAX_DEVICES)

+#define ADF_CFG_SERV_RING_PAIR_0_SHIFT 0
+#define ADF_CFG_SERV_RING_PAIR_1_SHIFT 3
+#define ADF_CFG_SERV_RING_PAIR_2_SHIFT 6
+#define ADF_CFG_SERV_RING_PAIR_3_SHIFT 9
+enum adf_cfg_service_type {
+ UNUSED = 0,
+ CRYPTO,
+ COMP,
+ SYM,
+ ASYM,
+ USED
+};
+
enum adf_cfg_val_type {
ADF_DEC,
ADF_HEX,
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
index 7c2c17366460..f2e0451b11c0 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen2_hw_data.h
@@ -4,6 +4,7 @@
#define ADF_GEN2_HW_DATA_H_

#include "adf_accel_devices.h"
+#include "adf_cfg_common.h"

/* Transport access */
#define ADF_BANK_INT_SRC_SEL_MASK_0 0x4444444CUL
@@ -116,6 +117,13 @@ do { \
#define ADF_POWERGATE_DC BIT(23)
#define ADF_POWERGATE_PKE BIT(24)

+/* Default ring mapping */
+#define ADF_GEN2_DEFAULT_RING_TO_SRV_MAP \
+ (CRYPTO << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
+ CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \
+ UNUSED << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
+
/* WDT timers
*
* Timeout is in cycles. Clock speed may vary across products but this
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
index 449d6a5976a9..f0f71ca44ca3 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
@@ -4,6 +4,7 @@
#define ADF_GEN4_HW_CSR_DATA_H_

#include "adf_accel_devices.h"
+#include "adf_cfg_common.h"

/* Transport access */
#define ADF_BANK_INT_SRC_SEL_MASK 0x44UL
@@ -94,6 +95,13 @@ do { \
ADF_RING_BUNDLE_SIZE * (bank) + \
ADF_RING_CSR_RING_SRV_ARB_EN, (value))

+/* Default ring mapping */
+#define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP \
+ (ASYM << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
+ SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \
+ ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \
+ SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
+
/* WDT timers
*
* Timeout is in cycles. Clock speed may vary across products but this
diff --git a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
index 2d18279191d7..09599fe4d2f3 100644
--- a/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
+++ b/drivers/crypto/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
@@ -191,6 +191,7 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_GEN2_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_GEN2_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_isr_resource_alloc;
hw_data->free_irq = adf_isr_resource_free;
hw_data->enable_error_correction = adf_gen2_enable_error_correction;
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c
index 5489d6c02256..31c14d7e1c11 100644
--- a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c
+++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c
@@ -67,6 +67,7 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data)
hw_data->num_engines = ADF_DH895XCCIOV_MAX_ACCELENGINES;
hw_data->tx_rx_gap = ADF_DH895XCCIOV_RX_RINGS_OFFSET;
hw_data->tx_rings_mask = ADF_DH895XCCIOV_TX_RINGS_MASK;
+ hw_data->ring_to_svc_map = ADF_GEN2_DEFAULT_RING_TO_SRV_MAP;
hw_data->alloc_irq = adf_vf_isr_resource_alloc;
hw_data->free_irq = adf_vf_isr_resource_free;
hw_data->enable_error_correction = adf_vf_void_noop;
--
2.31.1


2021-12-16 09:11:57

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 18/24] crypto: qat - support fast ACKs in the PFVF protocol

The original design and current implementation of the PFVF protocol
expects the sender to both acquire and relinquish the ownership of the
shared CSR by setting and clearing the "in use" pattern on the remote
half of the register when sending a message. This happens regardless of
the acknowledgment of the reception, to guarantee changes, including
collisions, are surely detected.

However, in the case of a request that requires a response, collisions
can also be detected by the lack of a reply. This can be exploited to
speed up and simplify the above behaviour, letting the receiver both
acknowledge the message and release the CSR in a single transaction:

1) the sender can return as soon as the message has been acknowledged
2) the receiver doesn't have to wait long before acquiring ownership
of the CSR for the response message, greatly improving the overall
throughput.

Howerver, this improvement cannot be leveraged for fire-and-forget
notifications, as it would be impossible for the sender to clearly
distinguish between a collision and an ack immediately followed by a new
message.

This patch implements this optimization in a new version of the protocol
(v3), which applies the fast-ack logic only whenever possible and
guarantees backward compatibility with older versions. For requests, a
new retry loop guarantees a correct behaviour.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
.../crypto/qat/qat_common/adf_accel_devices.h | 2 +-
drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 68 ++++++++++++++++---
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 4 +-
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 3 +-
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 44 ++++++------
5 files changed, 91 insertions(+), 30 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 55e8948a8c5e..1b9d4ed03dd0 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -158,7 +158,7 @@ struct adf_pfvf_ops {
int (*send_msg)(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
u32 pfvf_offset, struct mutex *csr_lock);
struct pfvf_message (*recv_msg)(struct adf_accel_dev *accel_dev,
- u32 pfvf_offset);
+ u32 pfvf_offset, u8 compat_ver);
};

struct adf_hw_device_data {
diff --git a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
index feab01ec4bbb..1a9072aac2ca 100644
--- a/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
+++ b/drivers/crypto/qat/qat_common/adf_gen2_pfvf.c
@@ -124,11 +124,34 @@ static bool is_legacy_user_pfvf_message(u32 msg)
return !(msg & ADF_PFVF_MSGORIGIN_SYSTEM);
}

+static bool is_pf2vf_notification(u8 msg_type)
+{
+ switch (msg_type) {
+ case ADF_PF2VF_MSGTYPE_RESTARTING:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool is_vf2pf_notification(u8 msg_type)
+{
+ switch (msg_type) {
+ case ADF_VF2PF_MSGTYPE_INIT:
+ case ADF_VF2PF_MSGTYPE_SHUTDOWN:
+ return true;
+ default:
+ return false;
+ }
+}
+
struct pfvf_gen2_params {
u32 pfvf_offset;
struct mutex *csr_lock; /* lock preventing concurrent access of CSR */
enum gen2_csr_pos local_offset;
enum gen2_csr_pos remote_offset;
+ bool (*is_notification_message)(u8 msg_type);
+ u8 compat_ver;
};

static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
@@ -190,15 +213,27 @@ static int adf_gen2_pfvf_send(struct adf_accel_dev *accel_dev,
csr_val &= ~int_bit;
}

- if (csr_val != csr_msg) {
- dev_dbg(&GET_DEV(accel_dev),
- "Collision - PFVF CSR overwritten by remote function\n");
+ /* For fire-and-forget notifications, the receiver does not clear
+ * the in-use pattern. This is used to detect collisions.
+ */
+ if (params->is_notification_message(msg.type) && csr_val != csr_msg) {
+ /* Collision must have overwritten the message */
+ dev_err(&GET_DEV(accel_dev),
+ "Collision on notification - PFVF CSR overwritten by remote function\n");
goto retry;
}

- /* Finished with the PFVF CSR; relinquish it and leave msg in CSR */
- gen2_csr_clear_in_use(&csr_val, remote_offset);
- ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
+ /* If the far side did not clear the in-use pattern it is either
+ * 1) Notification - message left intact to detect collision
+ * 2) Older protocol (compatibility version < 3) on the far side
+ * where the sender is responsible for clearing the in-use
+ * pattern after the received has acknowledged receipt.
+ * In either case, clear the in-use pattern now.
+ */
+ if (gen2_csr_is_in_use(csr_val, remote_offset)) {
+ gen2_csr_clear_in_use(&csr_val, remote_offset);
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
+ }

out:
mutex_unlock(lock);
@@ -218,6 +253,7 @@ static struct pfvf_message adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
struct pfvf_gen2_params *params)
{
void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ enum gen2_csr_pos remote_offset = params->remote_offset;
enum gen2_csr_pos local_offset = params->local_offset;
u32 pfvf_offset = params->pfvf_offset;
struct pfvf_message msg = { 0 };
@@ -242,12 +278,22 @@ static struct pfvf_message adf_gen2_pfvf_recv(struct adf_accel_dev *accel_dev,
if (unlikely(is_legacy_user_pfvf_message(csr_msg))) {
dev_dbg(&GET_DEV(accel_dev),
"Ignored non-system message (0x%.8x);\n", csr_val);
+ /* Because this must be a legacy message, the far side
+ * must clear the in-use pattern, so don't do it.
+ */
return msg;
}

/* Return the pfvf_message format */
msg = adf_pfvf_message_of(accel_dev, csr_msg, &csr_gen2_fmt);

+ /* The in-use pattern is not cleared for notifications (so that
+ * it can be used for collision detection) or older implementations
+ */
+ if (params->compat_ver >= ADF_PFVF_COMPAT_FAST_ACK &&
+ !params->is_notification_message(msg.type))
+ gen2_csr_clear_in_use(&csr_val, remote_offset);
+
/* To ACK, clear the INT bit */
csr_val &= ~int_bit;
ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val);
@@ -263,6 +309,7 @@ static int adf_gen2_pf2vf_send(struct adf_accel_dev *accel_dev, struct pfvf_mess
.pfvf_offset = pfvf_offset,
.local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
.remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ .is_notification_message = is_pf2vf_notification,
};

return adf_gen2_pfvf_send(accel_dev, msg, &params);
@@ -276,30 +323,35 @@ static int adf_gen2_vf2pf_send(struct adf_accel_dev *accel_dev, struct pfvf_mess
.pfvf_offset = pfvf_offset,
.local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
.remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ .is_notification_message = is_vf2pf_notification,
};

return adf_gen2_pfvf_send(accel_dev, msg, &params);
}

static struct pfvf_message adf_gen2_pf2vf_recv(struct adf_accel_dev *accel_dev,
- u32 pfvf_offset)
+ u32 pfvf_offset, u8 compat_ver)
{
struct pfvf_gen2_params params = {
.pfvf_offset = pfvf_offset,
.local_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
.remote_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
+ .is_notification_message = is_pf2vf_notification,
+ .compat_ver = compat_ver,
};

return adf_gen2_pfvf_recv(accel_dev, &params);
}

static struct pfvf_message adf_gen2_vf2pf_recv(struct adf_accel_dev *accel_dev,
- u32 pfvf_offset)
+ u32 pfvf_offset, u8 compat_ver)
{
struct pfvf_gen2_params params = {
.pfvf_offset = pfvf_offset,
.local_offset = ADF_GEN2_CSR_VF2PF_OFFSET,
.remote_offset = ADF_GEN2_CSR_PF2VF_OFFSET,
+ .is_notification_message = is_vf2pf_notification,
+ .compat_ver = compat_ver,
};

return adf_gen2_pfvf_recv(accel_dev, &params);
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index f418dd26a742..df052194ece7 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -89,8 +89,10 @@ enum vf2pf_msgtype {
enum pfvf_compatibility_version {
/* Support for extended capabilities */
ADF_PFVF_COMPAT_CAPABILITIES = 0x02,
+ /* In-use pattern cleared by receiver */
+ ADF_PFVF_COMPAT_FAST_ACK = 0x03,
/* Reference to the latest version */
- ADF_PFVF_COMPAT_THIS_VERSION = 0x02,
+ ADF_PFVF_COMPAT_THIS_VERSION = 0x03,
};

/* PF->VF Version Response */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 1256d68c3efd..cd728d5ac9ab 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -48,10 +48,11 @@ int adf_send_pf2vf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr, struct pfvf_me
*/
static struct pfvf_message adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr)
{
+ struct adf_accel_vf_info *vf_info = &accel_dev->pf.vf_info[vf_nr];
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_vf2pf_offset(vf_nr);

- return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
+ return pfvf_ops->recv_msg(accel_dev, pfvf_offset, vf_info->vf_compat_ver);
}

static adf_pf2vf_blkmsg_provider get_blkmsg_response_provider(u8 type)
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index a85bd6dcb62a..b9a1cf5d58a9 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -15,6 +15,8 @@
#define ADF_PFVF_MSG_ACK_DELAY 2
#define ADF_PFVF_MSG_ACK_MAX_RETRY 100

+/* How often to retry if there is no response */
+#define ADF_PFVF_MSG_RESP_RETRIES 5
#define ADF_PFVF_MSG_RESP_TIMEOUT (ADF_PFVF_MSG_ACK_DELAY * \
ADF_PFVF_MSG_ACK_MAX_RETRY + \
ADF_PFVF_MSG_COLLISION_DETECT_DELAY)
@@ -50,7 +52,7 @@ static struct pfvf_message adf_recv_pf2vf_msg(struct adf_accel_dev *accel_dev)
struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev);
u32 pfvf_offset = pfvf_ops->get_pf2vf_offset(0);

- return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
+ return pfvf_ops->recv_msg(accel_dev, pfvf_offset, accel_dev->vf.pf_compat_ver);
}

/**
@@ -68,33 +70,37 @@ int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
struct pfvf_message *resp)
{
unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT);
+ unsigned int retries = ADF_PFVF_MSG_RESP_RETRIES;
int ret;

reinit_completion(&accel_dev->vf.msg_received);

/* Send request from VF to PF */
- ret = adf_send_vf2pf_msg(accel_dev, msg);
- if (ret) {
- dev_err(&GET_DEV(accel_dev),
- "Failed to send request msg to PF\n");
- return ret;
- }
+ do {
+ ret = adf_send_vf2pf_msg(accel_dev, msg);
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev),
+ "Failed to send request msg to PF\n");
+ return ret;
+ }

- /* Wait for response */
- if (!wait_for_completion_timeout(&accel_dev->vf.msg_received,
- timeout)) {
- dev_err(&GET_DEV(accel_dev),
- "PFVF request/response message timeout expired\n");
- return -EIO;
- }
+ /* Wait for response, if it times out retry */
+ ret = wait_for_completion_timeout(&accel_dev->vf.msg_received,
+ timeout);
+ if (ret) {
+ if (likely(resp))
+ *resp = accel_dev->vf.response;

- if (likely(resp))
- *resp = accel_dev->vf.response;
+ /* Once copied, set to an invalid value */
+ accel_dev->vf.response.type = 0;

- /* Once copied, set to an invalid value */
- accel_dev->vf.response.type = 0;
+ return 0;
+ }

- return 0;
+ dev_err(&GET_DEV(accel_dev), "PFVF response message timeout\n");
+ } while (--retries);
+
+ return -EIO;
}

static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
--
2.31.1


2021-12-16 09:11:58

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 17/24] crypto: qat - exchange device capabilities over PFVF

Allow the VF driver to get the supported device capabilities through PFVF,
by adding a new block message, the Capability Summary.

This messages allows to exchange the capability through masks, which
report, depending on the Capability Summary version, up to the following
information:
- algorithms and/or services that are supported by the device (e.g.
symmetric crypto, data compression, etc.)
- (extended) compression capabilities, with details about the compression
service (e.g. if compress and verify is supported by this device)
- the frequency of the device

This patch supports the latest Capabilities Summary version 3 for VFs,
but will limit support for the PF driver to version 2. This change also
increases the PFVF protocol to version 2.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
.../crypto/qat/qat_common/adf_accel_devices.h | 1 +
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 35 ++++++++++++--
.../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 18 ++++++++
.../crypto/qat/qat_common/adf_pfvf_pf_msg.h | 3 ++
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 1 +
.../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 46 +++++++++++++++++++
.../crypto/qat/qat_common/adf_pfvf_vf_msg.h | 1 +
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 11 ++++-
8 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 59f06e53d316..55e8948a8c5e 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -203,6 +203,7 @@ struct adf_hw_device_data {
u32 straps;
u32 accel_capabilities_mask;
u32 extended_dc_capabilities;
+ u32 clock_frequency;
u32 instance_id;
u16 accel_mask;
u32 ae_mask;
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index 6abbb5e05809..f418dd26a742 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -87,8 +87,10 @@ enum vf2pf_msgtype {

/* VF/PF compatibility version. */
enum pfvf_compatibility_version {
- /* Reference to the current version */
- ADF_PFVF_COMPAT_THIS_VERSION = 0x01,
+ /* Support for extended capabilities */
+ ADF_PFVF_COMPAT_CAPABILITIES = 0x02,
+ /* Reference to the latest version */
+ ADF_PFVF_COMPAT_THIS_VERSION = 0x02,
};

/* PF->VF Version Response */
@@ -133,7 +135,9 @@ enum pf2vf_blkmsg_error {
* 16..23 - 64 byte message
* 24..27 - 128 byte message
*/
-/* No block messages as of yet */
+enum vf2pf_blkmsg_req_type {
+ ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY = 0x02,
+};

#define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \
(FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK))
@@ -171,4 +175,29 @@ struct pfvf_blkmsg_header {
#define ADF_PFVF_BLKMSG_VER_BYTE 0
#define ADF_PFVF_BLKMSG_LEN_BYTE 1

+/* PF/VF Capabilities message values */
+enum blkmsg_capabilities_versions {
+ ADF_PFVF_CAPABILITIES_V1_VERSION = 0x01,
+ ADF_PFVF_CAPABILITIES_V2_VERSION = 0x02,
+ ADF_PFVF_CAPABILITIES_V3_VERSION = 0x03,
+};
+
+struct capabilities_v1 {
+ struct pfvf_blkmsg_header hdr;
+ u32 ext_dc_caps;
+} __packed;
+
+struct capabilities_v2 {
+ struct pfvf_blkmsg_header hdr;
+ u32 ext_dc_caps;
+ u32 capabilities;
+} __packed;
+
+struct capabilities_v3 {
+ struct pfvf_blkmsg_header hdr;
+ u32 ext_dc_caps;
+ u32 capabilities;
+ u32 frequency;
+} __packed;
+
#endif /* ADF_PFVF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
index ad198b624098..5732cea1c7ca 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
@@ -18,3 +18,21 @@ void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
"Failed to send restarting msg to VF%d\n", i);
}
}
+
+int adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,
+ u8 *buffer, u8 compat)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct capabilities_v2 caps_msg;
+
+ caps_msg.ext_dc_caps = hw_data->extended_dc_capabilities;
+ caps_msg.capabilities = hw_data->accel_capabilities_mask;
+
+ caps_msg.hdr.version = ADF_PFVF_CAPABILITIES_V2_VERSION;
+ caps_msg.hdr.payload_size =
+ ADF_PFVF_BLKMSG_PAYLOAD_SIZE(struct capabilities_v2);
+
+ memcpy(buffer, &caps_msg, sizeof(caps_msg));
+
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
index 5c669f1de6e4..401450bd30b0 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
@@ -10,4 +10,7 @@ void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);
typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
u8 *buffer, u8 compat);

+int adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,
+ u8 *buffer, u8 comapt);
+
#endif /* ADF_PFVF_PF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 850b5f4414a6..1256d68c3efd 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -15,6 +15,7 @@ typedef u8 (*pf2vf_blkmsg_data_getter_fn)(u8 const *blkmsg, u8 byte);
static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = {
NULL, /* no message type defined for value 0 */
NULL, /* no message type defined for value 1 */
+ adf_pf_capabilities_msg_provider, /* ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY */
};

/**
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index 307d593042f3..b08f8544991a 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -92,3 +92,49 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
accel_dev->vf.pf_compat_ver = pf_version;
return 0;
}
+
+int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct capabilities_v3 cap_msg = { { 0 }, };
+ unsigned int len = sizeof(cap_msg);
+
+ if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_CAPABILITIES)
+ /* The PF is too old to support the extended capabilities */
+ return 0;
+
+ if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY,
+ (u8 *)&cap_msg, &len)) {
+ dev_err(&GET_DEV(accel_dev),
+ "QAT: Failed to get block message response\n");
+ return -EFAULT;
+ }
+
+ switch (cap_msg.hdr.version) {
+ default:
+ /* Newer version received, handle only the know parts */
+ fallthrough;
+ case ADF_PFVF_CAPABILITIES_V3_VERSION:
+ if (likely(len >= sizeof(struct capabilities_v3)))
+ hw_data->clock_frequency = cap_msg.frequency;
+ else
+ dev_info(&GET_DEV(accel_dev), "Could not get frequency");
+ fallthrough;
+ case ADF_PFVF_CAPABILITIES_V2_VERSION:
+ if (likely(len >= sizeof(struct capabilities_v2)))
+ hw_data->accel_capabilities_mask = cap_msg.capabilities;
+ else
+ dev_info(&GET_DEV(accel_dev), "Could not get capabilities");
+ fallthrough;
+ case ADF_PFVF_CAPABILITIES_V1_VERSION:
+ if (likely(len >= sizeof(struct capabilities_v1))) {
+ hw_data->extended_dc_capabilities = cap_msg.ext_dc_caps;
+ } else {
+ dev_err(&GET_DEV(accel_dev),
+ "Capabilities message truncated to %d bytes\n", len);
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
index 5091b5b2fd8f..c1f31354c138 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
@@ -7,6 +7,7 @@
int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev);
void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev);
int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev);
+int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev);
#else
static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index 0fdd6b9892d3..a85bd6dcb62a 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -341,8 +341,17 @@ bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
*/
int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
{
+ int ret;
+
adf_pfvf_crc_init();
adf_enable_pf2vf_interrupts(accel_dev);
- return adf_vf2pf_request_version(accel_dev);
+
+ ret = adf_vf2pf_request_version(accel_dev);
+ if (ret)
+ return ret;
+
+ ret = adf_vf2pf_get_capabilities(accel_dev);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms);
--
2.31.1


2021-12-16 09:11:56

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 16/24] crypto: qat - introduce support for PFVF block messages

GEN2 devices use a single CSR for PFVF messages, which leaves up to 10 bits
of payload per single message. While such amount is sufficient for the
currently defined messages, the transfer of bigger and more complex data
streams from the PF to the VF requires a new mechanism that extends the
protocol.

This patch adds a new layer on top of the basic PFVF messaging, called
Block Messages, to encapsulate up to 126 bytes of data in a single
logical message across multiple PFVF messages of new types (SMALL,
MEDIUM and LARGE BLOCK), including (sub)types (BLKMSG_TYPE) to carry the
information about the actual Block Message.

Regardless of the size, each Block Message uses a two bytes header,
containing the version and size, to allow for extension while
maintaining compatibility. The size and the types of Block Messages are
defined as follow:

- small block messages: up to 16 BLKMSG types of up to 30 bytes
- medium block messages: up to 8 BLKMSG types of up to 62 bytes
- large block messages: up to 4 BLKMSG types of up to 126 bytes

It effectively works as reading a byte at a time from a block device and
for each of these new Block Messages:
- the requestor (always a VF) can either request a specific byte of the
larger message, in order to retrieve the full message, or request the
value of the CRC calculated for a specific message up to the provided
size (to allow for messages to grow while maintaining forward
compatibility)
- the responder (always the PF) will either return a single data or CRC
byte, along with the indication of response type (or error).

This patch provides the basic infrastructure to perform the above
operations, without defining any new message.

As CRCs are required, this code now depends on the CRC8 module.

Note: as a consequence of the Block Messages design, sending multiple
PFVF messages in bursts, the interrupt rate limiting values on the PF are
increased.

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/Kconfig | 1 +
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 74 +++++++
.../crypto/qat/qat_common/adf_pfvf_pf_msg.h | 3 +
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 137 ++++++++++++
.../crypto/qat/qat_common/adf_pfvf_utils.c | 15 ++
.../crypto/qat/qat_common/adf_pfvf_utils.h | 3 +
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 203 +++++++++++++++++-
.../crypto/qat/qat_common/adf_pfvf_vf_proto.h | 2 +
drivers/crypto/qat/qat_common/adf_sriov.c | 7 +-
9 files changed, 442 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
index 77783feb62b2..4b90c0f22b03 100644
--- a/drivers/crypto/qat/Kconfig
+++ b/drivers/crypto/qat/Kconfig
@@ -13,6 +13,7 @@ config CRYPTO_DEV_QAT
select CRYPTO_SHA512
select CRYPTO_LIB_AES
select FW_LOADER
+ select CRC8

config CRYPTO_DEV_QAT_DH895xCC
tristate "Support for Intel(R) DH895xCC"
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index daee3d7ceb8c..6abbb5e05809 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -71,6 +71,7 @@ struct pfvf_message {
enum pf2vf_msgtype {
ADF_PF2VF_MSGTYPE_RESTARTING = 0x01,
ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02,
+ ADF_PF2VF_MSGTYPE_BLKMSG_RESP = 0x03,
};

/* VF->PF messages */
@@ -79,6 +80,9 @@ enum vf2pf_msgtype {
ADF_VF2PF_MSGTYPE_SHUTDOWN = 0x04,
ADF_VF2PF_MSGTYPE_VERSION_REQ = 0x05,
ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ = 0x06,
+ ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ = 0x07,
+ ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ = 0x08,
+ ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ = 0x09,
};

/* VF/PF compatibility version. */
@@ -97,4 +101,74 @@ enum pf2vf_compat_response {
ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03,
};

+/* PF->VF Block Responses */
+#define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK GENMASK(1, 0)
+#define ADF_PF2VF_BLKMSG_RESP_DATA_MASK GENMASK(9, 2)
+
+enum pf2vf_blkmsg_resp_type {
+ ADF_PF2VF_BLKMSG_RESP_TYPE_DATA = 0x00,
+ ADF_PF2VF_BLKMSG_RESP_TYPE_CRC = 0x01,
+ ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR = 0x02,
+};
+
+/* PF->VF Block Error Code */
+enum pf2vf_blkmsg_error {
+ ADF_PF2VF_INVALID_BLOCK_TYPE = 0x00,
+ ADF_PF2VF_INVALID_BYTE_NUM_REQ = 0x01,
+ ADF_PF2VF_PAYLOAD_TRUNCATED = 0x02,
+ ADF_PF2VF_UNSPECIFIED_ERROR = 0x03,
+};
+
+/* VF->PF Block Requests */
+#define ADF_VF2PF_LARGE_BLOCK_TYPE_MASK GENMASK(1, 0)
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_MASK GENMASK(8, 2)
+#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK GENMASK(2, 0)
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK GENMASK(8, 3)
+#define ADF_VF2PF_SMALL_BLOCK_TYPE_MASK GENMASK(3, 0)
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_MASK GENMASK(8, 4)
+#define ADF_VF2PF_BLOCK_CRC_REQ_MASK BIT(9)
+
+/* PF->VF Block Request Types
+ * 0..15 - 32 byte message
+ * 16..23 - 64 byte message
+ * 24..27 - 128 byte message
+ */
+/* No block messages as of yet */
+
+#define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \
+ (FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK))
+
+#define ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX \
+ (FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK) + \
+ ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1)
+
+#define ADF_VF2PF_LARGE_BLOCK_TYPE_MAX \
+ (FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK) + \
+ ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX)
+
+#define ADF_VF2PF_SMALL_BLOCK_BYTE_MAX \
+ FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK)
+
+#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX \
+ FIELD_MAX(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK)
+
+#define ADF_VF2PF_LARGE_BLOCK_BYTE_MAX \
+ FIELD_MAX(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK)
+
+struct pfvf_blkmsg_header {
+ u8 version;
+ u8 payload_size;
+} __packed;
+
+#define ADF_PFVF_BLKMSG_HEADER_SIZE (sizeof(struct pfvf_blkmsg_header))
+#define ADF_PFVF_BLKMSG_PAYLOAD_SIZE(blkmsg) (sizeof(blkmsg) - \
+ ADF_PFVF_BLKMSG_HEADER_SIZE)
+#define ADF_PFVF_BLKMSG_MSG_SIZE(blkmsg) (ADF_PFVF_BLKMSG_HEADER_SIZE + \
+ (blkmsg)->hdr.payload_size)
+#define ADF_PFVF_BLKMSG_MSG_MAX_SIZE 128
+
+/* PF->VF Block message header bytes */
+#define ADF_PFVF_BLKMSG_VER_BYTE 0
+#define ADF_PFVF_BLKMSG_LEN_BYTE 1
+
#endif /* ADF_PFVF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
index 187807b1ff88..5c669f1de6e4 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
@@ -7,4 +7,7 @@

void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);

+typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
+ u8 *buffer, u8 compat);
+
#endif /* ADF_PFVF_PF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index f461aa0a95c7..850b5f4414a6 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -6,7 +6,16 @@
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_pfvf_msg.h"
+#include "adf_pfvf_pf_msg.h"
#include "adf_pfvf_pf_proto.h"
+#include "adf_pfvf_utils.h"
+
+typedef u8 (*pf2vf_blkmsg_data_getter_fn)(u8 const *blkmsg, u8 byte);
+
+static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = {
+ NULL, /* no message type defined for value 0 */
+ NULL, /* no message type defined for value 1 */
+};

/**
* adf_send_pf2vf_msg() - send PF to VF message
@@ -44,6 +53,128 @@ static struct pfvf_message adf_recv_vf2pf_msg(struct adf_accel_dev *accel_dev, u
return pfvf_ops->recv_msg(accel_dev, pfvf_offset);
}

+static adf_pf2vf_blkmsg_provider get_blkmsg_response_provider(u8 type)
+{
+ if (type >= ARRAY_SIZE(pf2vf_blkmsg_providers))
+ return NULL;
+
+ return pf2vf_blkmsg_providers[type];
+}
+
+/* Byte pf2vf_blkmsg_data_getter_fn callback */
+static u8 adf_pf2vf_blkmsg_get_byte(u8 const *blkmsg, u8 index)
+{
+ return blkmsg[index];
+}
+
+/* CRC pf2vf_blkmsg_data_getter_fn callback */
+static u8 adf_pf2vf_blkmsg_get_crc(u8 const *blkmsg, u8 count)
+{
+ /* count is 0-based, turn it into a length */
+ return adf_pfvf_calc_blkmsg_crc(blkmsg, count + 1);
+}
+
+static int adf_pf2vf_blkmsg_get_data(struct adf_accel_vf_info *vf_info,
+ u8 type, u8 byte, u8 max_size, u8 *data,
+ pf2vf_blkmsg_data_getter_fn data_getter)
+{
+ u8 blkmsg[ADF_PFVF_BLKMSG_MSG_MAX_SIZE] = { 0 };
+ struct adf_accel_dev *accel_dev = vf_info->accel_dev;
+ adf_pf2vf_blkmsg_provider provider;
+ u8 msg_size;
+
+ provider = get_blkmsg_response_provider(type);
+
+ if (unlikely(!provider)) {
+ pr_err("QAT: No registered provider for message %d\n", type);
+ *data = ADF_PF2VF_INVALID_BLOCK_TYPE;
+ return -EINVAL;
+ }
+
+ if (unlikely((*provider)(accel_dev, blkmsg, vf_info->vf_compat_ver))) {
+ pr_err("QAT: unknown error from provider for message %d\n", type);
+ *data = ADF_PF2VF_UNSPECIFIED_ERROR;
+ return -EINVAL;
+ }
+
+ msg_size = ADF_PFVF_BLKMSG_HEADER_SIZE + blkmsg[ADF_PFVF_BLKMSG_LEN_BYTE];
+
+ if (unlikely(msg_size >= max_size)) {
+ pr_err("QAT: Invalid size %d provided for message type %d\n",
+ msg_size, type);
+ *data = ADF_PF2VF_PAYLOAD_TRUNCATED;
+ return -EINVAL;
+ }
+
+ if (unlikely(byte >= msg_size)) {
+ pr_err("QAT: Out-of-bound byte number %d (msg size %d)\n",
+ byte, msg_size);
+ *data = ADF_PF2VF_INVALID_BYTE_NUM_REQ;
+ return -EINVAL;
+ }
+
+ *data = data_getter(blkmsg, byte);
+ return 0;
+}
+
+static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info,
+ struct pfvf_message req)
+{
+ u8 resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_ERROR;
+ struct pfvf_message resp = { 0 };
+ u8 resp_data = 0;
+ u8 blk_type;
+ u8 blk_byte;
+ u8 byte_max;
+
+ switch (req.type) {
+ case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ:
+ blk_type = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK, req.data)
+ + ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX + 1;
+ blk_byte = FIELD_GET(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, req.data);
+ byte_max = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
+ break;
+ case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ:
+ blk_type = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK, req.data)
+ + ADF_VF2PF_SMALL_BLOCK_TYPE_MAX + 1;
+ blk_byte = FIELD_GET(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, req.data);
+ byte_max = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
+ break;
+ case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
+ blk_type = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, req.data);
+ blk_byte = FIELD_GET(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, req.data);
+ byte_max = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
+ break;
+ }
+
+ /* Is this a request for CRC or data? */
+ if (FIELD_GET(ADF_VF2PF_BLOCK_CRC_REQ_MASK, req.data)) {
+ dev_dbg(&GET_DEV(vf_info->accel_dev),
+ "BlockMsg of type %d for CRC over %d bytes received from VF%d\n",
+ blk_type, blk_byte, vf_info->vf_nr);
+
+ if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte,
+ byte_max, &resp_data,
+ adf_pf2vf_blkmsg_get_crc))
+ resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_CRC;
+ } else {
+ dev_dbg(&GET_DEV(vf_info->accel_dev),
+ "BlockMsg of type %d for data byte %d received from VF%d\n",
+ blk_type, blk_byte, vf_info->vf_nr);
+
+ if (!adf_pf2vf_blkmsg_get_data(vf_info, blk_type, blk_byte,
+ byte_max, &resp_data,
+ adf_pf2vf_blkmsg_get_byte))
+ resp_type = ADF_PF2VF_BLKMSG_RESP_TYPE_DATA;
+ }
+
+ resp.type = ADF_PF2VF_MSGTYPE_BLKMSG_RESP;
+ resp.data = FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp_type) |
+ FIELD_PREP(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp_data);
+
+ return resp;
+}
+
static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
struct pfvf_message msg, struct pfvf_message *resp)
{
@@ -106,6 +237,11 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
vf_info->init = false;
}
break;
+ case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ:
+ case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ:
+ case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
+ *resp = handle_blkmsg_req(vf_info, msg);
+ break;
default:
dev_dbg(&GET_DEV(accel_dev),
"Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n",
@@ -147,6 +283,7 @@ bool adf_recv_and_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u32 vf_nr)
*/
int adf_enable_pf2vf_comms(struct adf_accel_dev *accel_dev)
{
+ adf_pfvf_crc_init();
spin_lock_init(&accel_dev->pf.vf2pf_ints_lock);

return 0;
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.c b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
index 494da89e2048..c5f6d77d4bb8 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.c
@@ -1,11 +1,26 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2021 Intel Corporation */
+#include <linux/crc8.h>
#include <linux/pci.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
#include "adf_pfvf_msg.h"
#include "adf_pfvf_utils.h"

+/* CRC Calculation */
+DECLARE_CRC8_TABLE(pfvf_crc8_table);
+#define ADF_PFVF_CRC8_POLYNOMIAL 0x97
+
+void adf_pfvf_crc_init(void)
+{
+ crc8_populate_msb(pfvf_crc8_table, ADF_PFVF_CRC8_POLYNOMIAL);
+}
+
+u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len)
+{
+ return crc8(pfvf_crc8_table, buf, buf_len, CRC8_INIT_VALUE);
+}
+
static bool set_value_on_csr_msg(struct adf_accel_dev *accel_dev, u32 *csr_msg,
u32 value, const struct pfvf_field_format *fmt)
{
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
index 7676fdddbe26..2be048e2287b 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_utils.h
@@ -10,6 +10,9 @@
#define ADF_PFVF_MSG_ACK_DELAY_US 4
#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (1 * USEC_PER_SEC)

+u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len);
+void adf_pfvf_crc_init(void);
+
struct pfvf_field_format {
u8 offset;
u32 mask;
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index 729c00c0d254..0fdd6b9892d3 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -1,10 +1,13 @@
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2015 - 2021 Intel Corporation */
+#include <linux/bitfield.h>
#include <linux/completion.h>
+#include <linux/minmax.h>
#include <linux/types.h>
#include "adf_accel_devices.h"
#include "adf_common_drv.h"
#include "adf_pfvf_msg.h"
+#include "adf_pfvf_utils.h"
#include "adf_pfvf_vf_msg.h"
#include "adf_pfvf_vf_proto.h"

@@ -94,6 +97,202 @@ int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
return 0;
}

+static int adf_vf2pf_blkmsg_data_req(struct adf_accel_dev *accel_dev, bool crc,
+ u8 *type, u8 *data)
+{
+ struct pfvf_message req = { 0 };
+ struct pfvf_message resp = { 0 };
+ u8 blk_type;
+ u8 blk_byte;
+ u8 msg_type;
+ u8 max_data;
+ int err;
+
+ /* Convert the block type to {small, medium, large} size category */
+ if (*type <= ADF_VF2PF_SMALL_BLOCK_TYPE_MAX) {
+ msg_type = ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ;
+ blk_type = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK, *type);
+ blk_byte = FIELD_PREP(ADF_VF2PF_SMALL_BLOCK_BYTE_MASK, *data);
+ max_data = ADF_VF2PF_SMALL_BLOCK_BYTE_MAX;
+ } else if (*type <= ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX) {
+ msg_type = ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ;
+ blk_type = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_TYPE_MASK,
+ *type - ADF_VF2PF_SMALL_BLOCK_TYPE_MAX);
+ blk_byte = FIELD_PREP(ADF_VF2PF_MEDIUM_BLOCK_BYTE_MASK, *data);
+ max_data = ADF_VF2PF_MEDIUM_BLOCK_BYTE_MAX;
+ } else if (*type <= ADF_VF2PF_LARGE_BLOCK_TYPE_MAX) {
+ msg_type = ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ;
+ blk_type = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_TYPE_MASK,
+ *type - ADF_VF2PF_MEDIUM_BLOCK_TYPE_MAX);
+ blk_byte = FIELD_PREP(ADF_VF2PF_LARGE_BLOCK_BYTE_MASK, *data);
+ max_data = ADF_VF2PF_LARGE_BLOCK_BYTE_MAX;
+ } else {
+ dev_err(&GET_DEV(accel_dev), "Invalid message type %u\n", *type);
+ return -EINVAL;
+ }
+
+ /* Sanity check */
+ if (*data > max_data) {
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid byte %s %u for message type %u\n",
+ crc ? "count" : "index", *data, *type);
+ return -EINVAL;
+ }
+
+ /* Build the block message */
+ req.type = msg_type;
+ req.data = blk_type | blk_byte | FIELD_PREP(ADF_VF2PF_BLOCK_CRC_REQ_MASK, crc);
+
+ err = adf_send_vf2pf_req(accel_dev, req, &resp);
+ if (err)
+ return err;
+
+ *type = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_TYPE_MASK, resp.data);
+ *data = FIELD_GET(ADF_PF2VF_BLKMSG_RESP_DATA_MASK, resp.data);
+
+ return 0;
+}
+
+static int adf_vf2pf_blkmsg_get_byte(struct adf_accel_dev *accel_dev, u8 type,
+ u8 index, u8 *data)
+{
+ int ret;
+
+ ret = adf_vf2pf_blkmsg_data_req(accel_dev, false, &type, &index);
+ if (ret < 0)
+ return ret;
+
+ if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_DATA)) {
+ dev_err(&GET_DEV(accel_dev),
+ "Unexpected BLKMSG response type %u, byte 0x%x\n",
+ type, index);
+ return -EFAULT;
+ }
+
+ *data = index;
+ return 0;
+}
+
+static int adf_vf2pf_blkmsg_get_crc(struct adf_accel_dev *accel_dev, u8 type,
+ u8 bytes, u8 *crc)
+{
+ int ret;
+
+ /* The count of bytes refers to a length, however shift it to a 0-based
+ * count to avoid overflows. Thus, a request for 0 bytes is technically
+ * valid.
+ */
+ --bytes;
+
+ ret = adf_vf2pf_blkmsg_data_req(accel_dev, true, &type, &bytes);
+ if (ret < 0)
+ return ret;
+
+ if (unlikely(type != ADF_PF2VF_BLKMSG_RESP_TYPE_CRC)) {
+ dev_err(&GET_DEV(accel_dev),
+ "Unexpected CRC BLKMSG response type %u, crc 0x%x\n",
+ type, bytes);
+ return -EFAULT;
+ }
+
+ *crc = bytes;
+ return 0;
+}
+
+/**
+ * adf_send_vf2pf_blkmsg_req() - retrieve block message
+ * @accel_dev: Pointer to acceleration VF device.
+ * @type: The block message type, see adf_pfvf_msg.h for allowed values
+ * @buffer: input buffer where to place the received data
+ * @buffer_len: buffer length as input, the amount of written bytes on output
+ *
+ * Request a message of type 'type' over the block message transport.
+ * This function will send the required amount block message requests and
+ * return the overall content back to the caller through the provided buffer.
+ * The buffer should be large enough to contain the requested message type,
+ * otherwise the response will be truncated.
+ *
+ * Return: 0 on success, error code otherwise.
+ */
+int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
+ u8 *buffer, unsigned int *buffer_len)
+{
+ unsigned int index;
+ unsigned int msg_len;
+ int ret;
+ u8 remote_crc;
+ u8 local_crc;
+
+ if (unlikely(type > ADF_VF2PF_LARGE_BLOCK_TYPE_MAX)) {
+ dev_err(&GET_DEV(accel_dev), "Invalid block message type %d\n",
+ type);
+ return -EINVAL;
+ }
+
+ if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) {
+ dev_err(&GET_DEV(accel_dev),
+ "Buffer size too small for a block message\n");
+ return -EINVAL;
+ }
+
+ ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
+ ADF_PFVF_BLKMSG_VER_BYTE,
+ &buffer[ADF_PFVF_BLKMSG_VER_BYTE]);
+ if (unlikely(ret))
+ return ret;
+
+ if (unlikely(!buffer[ADF_PFVF_BLKMSG_VER_BYTE])) {
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid version 0 received for block request %u", type);
+ return -EFAULT;
+ }
+
+ ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type,
+ ADF_PFVF_BLKMSG_LEN_BYTE,
+ &buffer[ADF_PFVF_BLKMSG_LEN_BYTE]);
+ if (unlikely(ret))
+ return ret;
+
+ if (unlikely(!buffer[ADF_PFVF_BLKMSG_LEN_BYTE])) {
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid size 0 received for block request %u", type);
+ return -EFAULT;
+ }
+
+ /* We need to pick the minimum since there is no way to request a
+ * specific version. As a consequence any scenario is possible:
+ * - PF has a newer (longer) version which doesn't fit in the buffer
+ * - VF expects a newer (longer) version, so we must not ask for
+ * bytes in excess
+ * - PF and VF share the same version, no problem
+ */
+ msg_len = ADF_PFVF_BLKMSG_HEADER_SIZE + buffer[ADF_PFVF_BLKMSG_LEN_BYTE];
+ msg_len = min(*buffer_len, msg_len);
+
+ /* Get the payload */
+ for (index = ADF_PFVF_BLKMSG_HEADER_SIZE; index < msg_len; index++) {
+ ret = adf_vf2pf_blkmsg_get_byte(accel_dev, type, index,
+ &buffer[index]);
+ if (unlikely(ret))
+ return ret;
+ }
+
+ ret = adf_vf2pf_blkmsg_get_crc(accel_dev, type, msg_len, &remote_crc);
+ if (unlikely(ret))
+ return ret;
+
+ local_crc = adf_pfvf_calc_blkmsg_crc(buffer, msg_len);
+ if (unlikely(local_crc != remote_crc)) {
+ dev_err(&GET_DEV(accel_dev),
+ "CRC error on msg type %d. Local %02X, remote %02X\n",
+ type, local_crc, remote_crc);
+ return -EIO;
+ }
+
+ *buffer_len = msg_len;
+ return 0;
+}
+
static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
struct pfvf_message msg)
{
@@ -104,6 +303,7 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
adf_pf2vf_handle_pf_restarting(accel_dev);
return false;
case ADF_PF2VF_MSGTYPE_VERSION_RESP:
+ case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
dev_dbg(&GET_DEV(accel_dev),
"Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
msg.type, msg.data);
@@ -135,12 +335,13 @@ bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev)
/**
* adf_enable_vf2pf_comms() - Function enables communication from vf to pf
*
- * @accel_dev: Pointer to acceleration device virtual function.
+ * @accel_dev: Pointer to acceleration device virtual function.
*
* Return: 0 on success, error code otherwise.
*/
int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
{
+ adf_pfvf_crc_init();
adf_enable_pf2vf_interrupts(accel_dev);
return adf_vf2pf_request_version(accel_dev);
}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
index e32d1bc3a740..f6ee9b38c0e1 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.h
@@ -9,6 +9,8 @@
int adf_send_vf2pf_msg(struct adf_accel_dev *accel_dev, struct pfvf_message msg);
int adf_send_vf2pf_req(struct adf_accel_dev *accel_dev, struct pfvf_message msg,
struct pfvf_message *resp);
+int adf_send_vf2pf_blkmsg_req(struct adf_accel_dev *accel_dev, u8 type,
+ u8 *buffer, unsigned int *buffer_len);

int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev);

diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c
index 6366622ff8fd..971a05d62418 100644
--- a/drivers/crypto/qat/qat_common/adf_sriov.c
+++ b/drivers/crypto/qat/qat_common/adf_sriov.c
@@ -8,6 +8,9 @@
#include "adf_cfg.h"
#include "adf_pfvf_pf_msg.h"

+#define ADF_VF2PF_RATELIMIT_INTERVAL 8
+#define ADF_VF2PF_RATELIMIT_BURST 130
+
static struct workqueue_struct *pf2vf_resp_wq;

struct adf_pf2vf_resp {
@@ -62,8 +65,8 @@ static int adf_enable_sriov(struct adf_accel_dev *accel_dev)

mutex_init(&vf_info->pf2vf_lock);
ratelimit_state_init(&vf_info->vf2pf_ratelimit,
- DEFAULT_RATELIMIT_INTERVAL,
- DEFAULT_RATELIMIT_BURST);
+ ADF_VF2PF_RATELIMIT_INTERVAL,
+ ADF_VF2PF_RATELIMIT_BURST);
}

/* Set Valid bits in AE Thread to PCIe Function Mapping */
--
2.31.1


2021-12-16 09:12:11

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 20/24] crypto: qat - config VFs based on ring-to-svc mapping

Change the configuration logic for the VF driver to leverage the
ring-to-service mappings now received via PFVF.

While the driver config logic is not yet capable of supporting
configurations other than the default mapping, make sure that both VF
and PF share the same default configuration in order to work properly.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 4 ---
drivers/crypto/qat/qat_c62xvf/adf_drv.c | 4 ---
.../crypto/qat/qat_common/adf_common_drv.h | 1 +
drivers/crypto/qat/qat_common/adf_init.c | 9 ++++++-
drivers/crypto/qat/qat_common/qat_crypto.c | 25 +++++++++++++++++++
drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 4 ---
6 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c
index 0ba1d293bb81..fa18d8009f53 100644
--- a/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c
+++ b/drivers/crypto/qat/qat_c3xxxvf/adf_drv.c
@@ -173,10 +173,6 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Completion for VF2PF request/response message exchange */
init_completion(&accel_dev->vf.msg_received);

- ret = qat_crypto_dev_config(accel_dev);
- if (ret)
- goto out_err_free_reg;
-
ret = adf_dev_init(accel_dev);
if (ret)
goto out_err_dev_shutdown;
diff --git a/drivers/crypto/qat/qat_c62xvf/adf_drv.c b/drivers/crypto/qat/qat_c62xvf/adf_drv.c
index 176d8e2786f4..686ec752d0e9 100644
--- a/drivers/crypto/qat/qat_c62xvf/adf_drv.c
+++ b/drivers/crypto/qat/qat_c62xvf/adf_drv.c
@@ -173,10 +173,6 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Completion for VF2PF request/response message exchange */
init_completion(&accel_dev->vf.msg_received);

- ret = qat_crypto_dev_config(accel_dev);
- if (ret)
- goto out_err_free_reg;
-
ret = adf_dev_init(accel_dev);
if (ret)
goto out_err_dev_shutdown;
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
index 5212891344a9..76f4f96ec5eb 100644
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -114,6 +114,7 @@ void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev);
int qat_crypto_register(void);
int qat_crypto_unregister(void);
int qat_crypto_dev_config(struct adf_accel_dev *accel_dev);
+int qat_crypto_vf_dev_config(struct adf_accel_dev *accel_dev);
struct qat_crypto_instance *qat_crypto_get_instance_node(int node);
void qat_crypto_put_instance(struct qat_crypto_instance *inst);
void qat_alg_callback(void *resp);
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
index 391d82a64a93..2edc63c6b6ca 100644
--- a/drivers/crypto/qat/qat_common/adf_init.c
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -69,7 +69,8 @@ int adf_dev_init(struct adf_accel_dev *accel_dev)
return -EFAULT;
}

- if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
+ if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) &&
+ !accel_dev->is_vf) {
dev_err(&GET_DEV(accel_dev), "Device not configured\n");
return -EFAULT;
}
@@ -121,6 +122,12 @@ int adf_dev_init(struct adf_accel_dev *accel_dev)
if (ret)
return ret;

+ if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) &&
+ accel_dev->is_vf) {
+ if (qat_crypto_vf_dev_config(accel_dev))
+ return -EFAULT;
+ }
+
/*
* Subservice initialisation is divided into two stages: init and start.
* This is to facilitate any ordering dependencies between services
diff --git a/drivers/crypto/qat/qat_common/qat_crypto.c b/drivers/crypto/qat/qat_common/qat_crypto.c
index ece6776fbd53..7234c4940fae 100644
--- a/drivers/crypto/qat/qat_common/qat_crypto.c
+++ b/drivers/crypto/qat/qat_common/qat_crypto.c
@@ -8,6 +8,7 @@
#include "adf_transport_access_macros.h"
#include "adf_cfg.h"
#include "adf_cfg_strings.h"
+#include "adf_gen2_hw_data.h"
#include "qat_crypto.h"
#include "icp_qat_fw.h"

@@ -104,6 +105,30 @@ struct qat_crypto_instance *qat_crypto_get_instance_node(int node)
return inst;
}

+/**
+ * qat_crypto_vf_dev_config()
+ * create dev config required to create crypto inst.
+ *
+ * @accel_dev: Pointer to acceleration device.
+ *
+ * Function creates device configuration required to create
+ * asym, sym or, crypto instances
+ *
+ * Return: 0 on success, error code otherwise.
+ */
+int qat_crypto_vf_dev_config(struct adf_accel_dev *accel_dev)
+{
+ u16 ring_to_svc_map = GET_HW_DATA(accel_dev)->ring_to_svc_map;
+
+ if (ring_to_svc_map != ADF_GEN2_DEFAULT_RING_TO_SRV_MAP) {
+ dev_err(&GET_DEV(accel_dev),
+ "Unsupported ring/service mapping present on PF");
+ return -EFAULT;
+ }
+
+ return qat_crypto_dev_config(accel_dev);
+}
+
/**
* qat_crypto_dev_config() - create dev config required to create crypto inst.
*
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
index ee45d688b5d7..18756b2e1c91 100644
--- a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
+++ b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
@@ -173,10 +173,6 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Completion for VF2PF request/response message exchange */
init_completion(&accel_dev->vf.msg_received);

- ret = qat_crypto_dev_config(accel_dev);
- if (ret)
- goto out_err_free_reg;
-
ret = adf_dev_init(accel_dev);
if (ret)
goto out_err_dev_shutdown;
--
2.31.1


2021-12-16 09:12:13

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 19/24] crypto: qat - exchange ring-to-service mappings over PFVF

In addition to retrieving the device capabilities, a VF may also need to
retrieve the mapping of its ring pairs to crypto and or compression
services in order to work properly.

Make the VF receive the ring-to-service mappings from the PF by means of a
new REQ_RING_SVC_MAP Block Message and add the request and response
logic on VF and PF respectively. This change requires to bump the PFVF
protocol to version 4.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 15 ++++++++++-
.../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 14 ++++++++++
.../crypto/qat/qat_common/adf_pfvf_pf_msg.h | 2 ++
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 1 +
.../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 27 +++++++++++++++++++
.../crypto/qat/qat_common/adf_pfvf_vf_msg.h | 1 +
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 4 +++
7 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index df052194ece7..1d3cad7d4999 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -91,8 +91,10 @@ enum pfvf_compatibility_version {
ADF_PFVF_COMPAT_CAPABILITIES = 0x02,
/* In-use pattern cleared by receiver */
ADF_PFVF_COMPAT_FAST_ACK = 0x03,
+ /* Ring to service mapping support for non-standard mappings */
+ ADF_PFVF_COMPAT_RING_TO_SVC_MAP = 0x04,
/* Reference to the latest version */
- ADF_PFVF_COMPAT_THIS_VERSION = 0x03,
+ ADF_PFVF_COMPAT_THIS_VERSION = 0x04,
};

/* PF->VF Version Response */
@@ -139,6 +141,7 @@ enum pf2vf_blkmsg_error {
*/
enum vf2pf_blkmsg_req_type {
ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY = 0x02,
+ ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP = 0x03,
};

#define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \
@@ -202,4 +205,14 @@ struct capabilities_v3 {
u32 frequency;
} __packed;

+/* PF/VF Ring to service mapping values */
+enum blkmsg_ring_to_svc_versions {
+ ADF_PFVF_RING_TO_SVC_VERSION = 0x01,
+};
+
+struct ring_to_svc_map_v1 {
+ struct pfvf_blkmsg_header hdr;
+ u16 map;
+} __packed;
+
#endif /* ADF_PFVF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
index 5732cea1c7ca..14c069f0d71a 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.c
@@ -36,3 +36,17 @@ int adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,

return 0;
}
+
+int adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev,
+ u8 *buffer, u8 compat)
+{
+ struct ring_to_svc_map_v1 rts_map_msg;
+
+ rts_map_msg.map = accel_dev->hw_device->ring_to_svc_map;
+ rts_map_msg.hdr.version = ADF_PFVF_RING_TO_SVC_VERSION;
+ rts_map_msg.hdr.payload_size = ADF_PFVF_BLKMSG_PAYLOAD_SIZE(rts_map_msg);
+
+ memcpy(buffer, &rts_map_msg, sizeof(rts_map_msg));
+
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
index 401450bd30b0..e8982d1ac896 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_msg.h
@@ -12,5 +12,7 @@ typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,

int adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,
u8 *buffer, u8 comapt);
+int adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev,
+ u8 *buffer, u8 comapt);

#endif /* ADF_PFVF_PF_MSG_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index cd728d5ac9ab..84230aac67e6 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -16,6 +16,7 @@ static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = {
NULL, /* no message type defined for value 0 */
NULL, /* no message type defined for value 1 */
adf_pf_capabilities_msg_provider, /* ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY */
+ adf_pf_ring_to_svc_msg_provider, /* ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP */
};

/**
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
index b08f8544991a..14b222691c9c 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.c
@@ -138,3 +138,30 @@ int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev)

return 0;
}
+
+int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev)
+{
+ struct ring_to_svc_map_v1 rts_map_msg = { { 0 }, };
+ unsigned int len = sizeof(rts_map_msg);
+
+ if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_RING_TO_SVC_MAP)
+ /* Use already set default mappings */
+ return 0;
+
+ if (adf_send_vf2pf_blkmsg_req(accel_dev, ADF_VF2PF_BLKMSG_REQ_RING_SVC_MAP,
+ (u8 *)&rts_map_msg, &len)) {
+ dev_err(&GET_DEV(accel_dev),
+ "QAT: Failed to get block message response\n");
+ return -EFAULT;
+ }
+
+ if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) {
+ dev_err(&GET_DEV(accel_dev),
+ "RING_TO_SVC message truncated to %d bytes\n", len);
+ return -EFAULT;
+ }
+
+ /* Only v1 at present */
+ accel_dev->hw_device->ring_to_svc_map = rts_map_msg.map;
+ return 0;
+}
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
index c1f31354c138..71bc0e3f1d93 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_msg.h
@@ -8,6 +8,7 @@ int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev);
void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev);
int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev);
int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev);
+int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev);
#else
static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index b9a1cf5d58a9..0e4b8397cbe3 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -357,6 +357,10 @@ int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
return ret;

ret = adf_vf2pf_get_capabilities(accel_dev);
+ if (ret)
+ return ret;
+
+ ret = adf_vf2pf_get_ring_to_svc(accel_dev);

return ret;
}
--
2.31.1


2021-12-16 09:12:13

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 22/24] crypto: qat - add PFVF support to enable the reset of ring pairs

Extend support for resetting ring pairs on the device to VFs. Such
reset happens by sending a request to the PF over the PFVF protocol.

This patch defines two new PFVF messages and adds the PFVF logic for
handling the request on PF, triggering the reset, and VFs, accepting the
'success'/'error' response.

This feature is GEN4 specific.

This patch is based on earlier work done by Zelin Deng.

Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 14 +++++
.../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 52 +++++++++++++++++++
.../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 1 +
3 files changed, 67 insertions(+)

diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index f00e9e2c585b..86b0e7baa4d3 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -99,6 +99,8 @@ enum pf2vf_msgtype {
ADF_PF2VF_MSGTYPE_RESTARTING = 0x01,
ADF_PF2VF_MSGTYPE_VERSION_RESP = 0x02,
ADF_PF2VF_MSGTYPE_BLKMSG_RESP = 0x03,
+/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
+ ADF_PF2VF_MSGTYPE_RP_RESET_RESP = 0x10,
};

/* VF->PF messages */
@@ -110,6 +112,8 @@ enum vf2pf_msgtype {
ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ = 0x07,
ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ = 0x08,
ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ = 0x09,
+/* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
+ ADF_VF2PF_MSGTYPE_RP_RESET = 0x10,
};

/* VF/PF compatibility version. */
@@ -134,6 +138,16 @@ enum pf2vf_compat_response {
ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03,
};

+enum ring_reset_result {
+ RPRESET_SUCCESS = 0x01,
+ RPRESET_NOT_SUPPORTED = 0x02,
+ RPRESET_INVAL_BANK = 0x03,
+ RPRESET_TIMEOUT = 0x04,
+};
+
+#define ADF_VF2PF_RNG_RESET_RP_MASK GENMASK(1, 0)
+#define ADF_VF2PF_RNG_RESET_RSVD_MASK GENMASK(25, 2)
+
/* PF->VF Block Responses */
#define ADF_PF2VF_BLKMSG_RESP_TYPE_MASK GENMASK(1, 0)
#define ADF_PF2VF_BLKMSG_RESP_DATA_MASK GENMASK(9, 2)
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
index 84230aac67e6..588352de1ef0 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_pf_proto.c
@@ -178,6 +178,55 @@ static struct pfvf_message handle_blkmsg_req(struct adf_accel_vf_info *vf_info,
return resp;
}

+static struct pfvf_message handle_rp_reset_req(struct adf_accel_dev *accel_dev, u8 vf_nr,
+ struct pfvf_message req)
+{
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+ struct pfvf_message resp = {
+ .type = ADF_PF2VF_MSGTYPE_RP_RESET_RESP,
+ .data = RPRESET_SUCCESS
+ };
+ u32 bank_number;
+ u32 rsvd_field;
+
+ bank_number = FIELD_GET(ADF_VF2PF_RNG_RESET_RP_MASK, req.data);
+ rsvd_field = FIELD_GET(ADF_VF2PF_RNG_RESET_RSVD_MASK, req.data);
+
+ dev_dbg(&GET_DEV(accel_dev),
+ "Ring Pair Reset Message received from VF%d for bank 0x%x\n",
+ vf_nr, bank_number);
+
+ if (!hw_data->ring_pair_reset || rsvd_field) {
+ dev_dbg(&GET_DEV(accel_dev),
+ "Ring Pair Reset for VF%d is not supported\n", vf_nr);
+ resp.data = RPRESET_NOT_SUPPORTED;
+ goto out;
+ }
+
+ if (bank_number >= hw_data->num_banks_per_vf) {
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid bank number (0x%x) from VF%d for Ring Reset\n",
+ bank_number, vf_nr);
+ resp.data = RPRESET_INVAL_BANK;
+ goto out;
+ }
+
+ /* Convert the VF provided value to PF bank number */
+ bank_number = vf_nr * hw_data->num_banks_per_vf + bank_number;
+ if (hw_data->ring_pair_reset(accel_dev, bank_number)) {
+ dev_dbg(&GET_DEV(accel_dev),
+ "Ring pair reset for VF%d failure\n", vf_nr);
+ resp.data = RPRESET_TIMEOUT;
+ goto out;
+ }
+
+ dev_dbg(&GET_DEV(accel_dev),
+ "Ring pair reset for VF%d successfully\n", vf_nr);
+
+out:
+ return resp;
+}
+
static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
struct pfvf_message msg, struct pfvf_message *resp)
{
@@ -245,6 +294,9 @@ static int adf_handle_vf2pf_msg(struct adf_accel_dev *accel_dev, u8 vf_nr,
case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
*resp = handle_blkmsg_req(vf_info, msg);
break;
+ case ADF_VF2PF_MSGTYPE_RP_RESET:
+ *resp = handle_rp_reset_req(accel_dev, vf_nr, msg);
+ break;
default:
dev_dbg(&GET_DEV(accel_dev),
"Unknown message from VF%d (type 0x%.4x, data: 0x%.4x)\n",
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
index 0e4b8397cbe3..1015155b6374 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_vf_proto.c
@@ -310,6 +310,7 @@ static bool adf_handle_pf2vf_msg(struct adf_accel_dev *accel_dev,
return false;
case ADF_PF2VF_MSGTYPE_VERSION_RESP:
case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
+ case ADF_PF2VF_MSGTYPE_RP_RESET_RESP:
dev_dbg(&GET_DEV(accel_dev),
"Response Message received from PF (type 0x%.4x, data 0x%.4x)\n",
msg.type, msg.data);
--
2.31.1


2021-12-16 09:12:13

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 21/24] crypto: qat - add PFVF support to the GEN4 host driver

So far PFVF support for GEN4 devices has been kept effectively disabled
due to lack of support. This patch adds all the GEN4 specific logic to
make PFVF fully functional on PF.

Signed-off-by: Marco Chiappero <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
---
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 10 +-
drivers/crypto/qat/qat_common/Makefile | 2 +-
drivers/crypto/qat/qat_common/adf_gen4_pfvf.c | 148 ++++++++++++++++++
drivers/crypto/qat/qat_common/adf_gen4_pfvf.h | 17 ++
drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 29 +++-
5 files changed, 196 insertions(+), 10 deletions(-)
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.h

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index 67cd20f443ab..ef71aa4efd64 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -4,6 +4,7 @@
#include <adf_accel_devices.h>
#include <adf_common_drv.h>
#include <adf_gen4_hw_data.h>
+#include <adf_gen4_pfvf.h>
#include "adf_4xxx_hw_data.h"
#include "icp_qat_hw.h"

@@ -228,12 +229,6 @@ static u32 uof_get_ae_mask(u32 obj_num)
return adf_4xxx_fw_config[obj_num].ae_mask;
}

-static u32 get_vf2pf_sources(void __iomem *pmisc_addr)
-{
- /* For the moment do not report vf2pf sources */
- return 0;
-}
-
void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
{
hw_data->dev_class = &adf_4xxx_class;
@@ -278,12 +273,11 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->uof_get_ae_mask = uof_get_ae_mask;
hw_data->set_msix_rttable = set_msix_default_rttable;
hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer;
- hw_data->pfvf_ops.enable_comms = adf_pfvf_comms_disabled;
- hw_data->pfvf_ops.get_vf2pf_sources = get_vf2pf_sources;
hw_data->disable_iov = adf_disable_sriov;
hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;

adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
+ adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops);
}

void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data)
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
index 80f6cb424753..7e191a42a5c7 100644
--- a/drivers/crypto/qat/qat_common/Makefile
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -22,4 +22,4 @@ intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o
intel_qat-$(CONFIG_PCI_IOV) += adf_sriov.o adf_vf_isr.o adf_pfvf_utils.o \
adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \
adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \
- adf_gen2_pfvf.o
+ adf_gen2_pfvf.o adf_gen4_pfvf.o
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
new file mode 100644
index 000000000000..8efbedf63bc8
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
+/* Copyright(c) 2021 Intel Corporation */
+#include <linux/iopoll.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_gen4_pfvf.h"
+#include "adf_pfvf_pf_proto.h"
+#include "adf_pfvf_utils.h"
+
+#define ADF_4XXX_MAX_NUM_VFS 16
+
+#define ADF_4XXX_PF2VM_OFFSET(i) (0x40B010 + ((i) * 0x20))
+#define ADF_4XXX_VM2PF_OFFSET(i) (0x40B014 + ((i) * 0x20))
+
+/* VF2PF interrupt source registers */
+#define ADF_4XXX_VM2PF_SOU(i) (0x41A180 + ((i) * 4))
+#define ADF_4XXX_VM2PF_MSK(i) (0x41A1C0 + ((i) * 4))
+#define ADF_4XXX_VM2PF_INT_EN_MSK BIT(0)
+
+#define ADF_PFVF_GEN4_MSGTYPE_SHIFT 2
+#define ADF_PFVF_GEN4_MSGTYPE_MASK 0x3F
+#define ADF_PFVF_GEN4_MSGDATA_SHIFT 8
+#define ADF_PFVF_GEN4_MSGDATA_MASK 0xFFFFFF
+
+static const struct pfvf_csr_format csr_gen4_fmt = {
+ { ADF_PFVF_GEN4_MSGTYPE_SHIFT, ADF_PFVF_GEN4_MSGTYPE_MASK },
+ { ADF_PFVF_GEN4_MSGDATA_SHIFT, ADF_PFVF_GEN4_MSGDATA_MASK },
+};
+
+static u32 adf_gen4_pf_get_pf2vf_offset(u32 i)
+{
+ return ADF_4XXX_PF2VM_OFFSET(i);
+}
+
+static u32 adf_gen4_pf_get_vf2pf_offset(u32 i)
+{
+ return ADF_4XXX_VM2PF_OFFSET(i);
+}
+
+static u32 adf_gen4_get_vf2pf_sources(void __iomem *pmisc_addr)
+{
+ int i;
+ u32 sou, mask;
+ int num_csrs = ADF_4XXX_MAX_NUM_VFS;
+ u32 vf_mask = 0;
+
+ for (i = 0; i < num_csrs; i++) {
+ sou = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_SOU(i));
+ mask = ADF_CSR_RD(pmisc_addr, ADF_4XXX_VM2PF_MSK(i));
+ sou &= ~mask;
+ vf_mask |= sou << i;
+ }
+
+ return vf_mask;
+}
+
+static void adf_gen4_enable_vf2pf_interrupts(void __iomem *pmisc_addr,
+ u32 vf_mask)
+{
+ int num_csrs = ADF_4XXX_MAX_NUM_VFS;
+ unsigned long mask = vf_mask;
+ unsigned int val;
+ int i;
+
+ for_each_set_bit(i, &mask, num_csrs) {
+ unsigned int offset = ADF_4XXX_VM2PF_MSK(i);
+
+ val = ADF_CSR_RD(pmisc_addr, offset) & ~ADF_4XXX_VM2PF_INT_EN_MSK;
+ ADF_CSR_WR(pmisc_addr, offset, val);
+ }
+}
+
+static void adf_gen4_disable_vf2pf_interrupts(void __iomem *pmisc_addr,
+ u32 vf_mask)
+{
+ int num_csrs = ADF_4XXX_MAX_NUM_VFS;
+ unsigned long mask = vf_mask;
+ unsigned int val;
+ int i;
+
+ for_each_set_bit(i, &mask, num_csrs) {
+ unsigned int offset = ADF_4XXX_VM2PF_MSK(i);
+
+ val = ADF_CSR_RD(pmisc_addr, offset) | ADF_4XXX_VM2PF_INT_EN_MSK;
+ ADF_CSR_WR(pmisc_addr, offset, val);
+ }
+}
+
+static int adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev,
+ struct pfvf_message msg, u32 pfvf_offset,
+ struct mutex *csr_lock)
+{
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ u32 csr_val;
+ int ret;
+
+ csr_val = adf_pfvf_csr_msg_of(accel_dev, msg, &csr_gen4_fmt);
+ if (unlikely(!csr_val))
+ return -EINVAL;
+
+ mutex_lock(csr_lock);
+
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val | ADF_PFVF_INT);
+
+ /* Wait for confirmation from remote that it received the message */
+ ret = read_poll_timeout(ADF_CSR_RD, csr_val, !(csr_val & ADF_PFVF_INT),
+ ADF_PFVF_MSG_ACK_DELAY_US,
+ ADF_PFVF_MSG_ACK_MAX_DELAY_US,
+ true, pmisc_addr, pfvf_offset);
+ if (ret < 0)
+ dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n");
+
+ mutex_unlock(csr_lock);
+ return ret;
+}
+
+static struct pfvf_message adf_gen4_pfvf_recv(struct adf_accel_dev *accel_dev,
+ u32 pfvf_offset, u8 compat_ver)
+{
+ void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev);
+ u32 csr_val;
+
+ /* Read message from the CSR */
+ csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset);
+
+ /* We can now acknowledge the message reception by clearing the
+ * interrupt bit
+ */
+ ADF_CSR_WR(pmisc_addr, pfvf_offset, csr_val & ~ADF_PFVF_INT);
+
+ /* Return the pfvf_message format */
+ return adf_pfvf_message_of(accel_dev, csr_val, &csr_gen4_fmt);
+}
+
+void adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
+{
+ pfvf_ops->enable_comms = adf_enable_pf2vf_comms;
+ pfvf_ops->get_pf2vf_offset = adf_gen4_pf_get_pf2vf_offset;
+ pfvf_ops->get_vf2pf_offset = adf_gen4_pf_get_vf2pf_offset;
+ pfvf_ops->get_vf2pf_sources = adf_gen4_get_vf2pf_sources;
+ pfvf_ops->enable_vf2pf_interrupts = adf_gen4_enable_vf2pf_interrupts;
+ pfvf_ops->disable_vf2pf_interrupts = adf_gen4_disable_vf2pf_interrupts;
+ pfvf_ops->send_msg = adf_gen4_pfvf_send;
+ pfvf_ops->recv_msg = adf_gen4_pfvf_recv;
+}
+EXPORT_SYMBOL_GPL(adf_gen4_init_pf_pfvf_ops);
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pfvf.h b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.h
new file mode 100644
index 000000000000..17d1b774d4a8
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pfvf.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
+/* Copyright(c) 2021 Intel Corporation */
+#ifndef ADF_GEN4_PFVF_H
+#define ADF_GEN4_PFVF_H
+
+#include "adf_accel_devices.h"
+
+#ifdef CONFIG_PCI_IOV
+void adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops);
+#else
+static inline void adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops)
+{
+ pfvf_ops->enable_comms = adf_pfvf_comms_disabled;
+}
+#endif
+
+#endif /* ADF_GEN4_PFVF_H */
diff --git a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
index 1d3cad7d4999..f00e9e2c585b 100644
--- a/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
+++ b/drivers/crypto/qat/qat_common/adf_pfvf_msg.h
@@ -6,7 +6,8 @@
#include <linux/bits.h>

/*
- * PF<->VF Messaging
+ * PF<->VF Gen2 Messaging format
+ *
* The PF has an array of 32-bit PF2VF registers, one for each VF. The
* PF can access all these registers; each VF can access only the one
* register associated with that particular VF.
@@ -53,6 +54,32 @@
* respectively, the other 16 bits are written to first with a defined
* IN_USE_BY pattern as part of a collision control scheme (see function
* adf_gen2_pfvf_send() in adf_pf2vf_msg.c).
+ *
+ *
+ * PF<->VF Gen4 Messaging format
+ *
+ * Similarly to the gen2 messaging format, 32-bit long registers are used for
+ * communication between PF and VFs. However, each VF and PF share a pair of
+ * 32-bits register to avoid collisions: one for PV to VF messages and one
+ * for VF to PF messages.
+ *
+ * Both the Interrupt bit and the Message Origin bit retain the same position
+ * and meaning, although non-system messages are now deprecated and not
+ * expected.
+ *
+ * 31 30 9 8 7 6 5 4 3 2 1 0
+ * _______________________________________________
+ * | | | . . . | | | | | | | | | | |
+ * +-----------------------------------------------+
+ * \_____________________/ \_______________/ ^ ^
+ * ^ ^ | |
+ * | | | PF/VF Int
+ * | | Message Origin
+ * | Message Type
+ * Message-specific Data/Reserved
+ *
+ * For both formats, the message reception is acknowledged by lowering the
+ * interrupt bit on the register where the message was sent.
*/

/* PFVF message common bits */
--
2.31.1


2021-12-16 09:12:13

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 23/24] crypto: qat - allow detection of dc capabilities for 4xxx

From: Giovanni Cabiddu <[email protected]>

Add logic to allow the detection of data compression capabilities for
4xxx devices.
The capability detection logic has been refactored to separate the
crypto capabilities from the compression ones.

This patch is not updating the returned capability mask as, up to now,
4xxx devices are configured only to handle crypto operations.

Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 64 +++++++++++--------
drivers/crypto/qat/qat_common/icp_qat_hw.h | 6 +-
2 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index ef71aa4efd64..40f684103b29 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -96,46 +96,60 @@ static void set_msix_default_rttable(struct adf_accel_dev *accel_dev)
static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
{
struct pci_dev *pdev = accel_dev->accel_pci_dev.pci_dev;
+ u32 capabilities_cy, capabilities_dc;
u32 fusectl1;
- u32 capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
- ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
- ICP_ACCEL_CAPABILITIES_CIPHER |
- ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
- ICP_ACCEL_CAPABILITIES_SHA3 |
- ICP_ACCEL_CAPABILITIES_SHA3_EXT |
- ICP_ACCEL_CAPABILITIES_HKDF |
- ICP_ACCEL_CAPABILITIES_ECEDMONT |
- ICP_ACCEL_CAPABILITIES_CHACHA_POLY |
- ICP_ACCEL_CAPABILITIES_AESGCM_SPC |
- ICP_ACCEL_CAPABILITIES_AES_V2;

/* Read accelerator capabilities mask */
pci_read_config_dword(pdev, ADF_4XXX_FUSECTL1_OFFSET, &fusectl1);

+ capabilities_cy = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CIPHER |
+ ICP_ACCEL_CAPABILITIES_AUTHENTICATION |
+ ICP_ACCEL_CAPABILITIES_SHA3 |
+ ICP_ACCEL_CAPABILITIES_SHA3_EXT |
+ ICP_ACCEL_CAPABILITIES_HKDF |
+ ICP_ACCEL_CAPABILITIES_ECEDMONT |
+ ICP_ACCEL_CAPABILITIES_CHACHA_POLY |
+ ICP_ACCEL_CAPABILITIES_AESGCM_SPC |
+ ICP_ACCEL_CAPABILITIES_AES_V2;
+
/* A set bit in fusectl1 means the feature is OFF in this SKU */
if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) {
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_HKDF;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_HKDF;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
}
if (fusectl1 & ICP_ACCEL_4XXX_MASK_UCS_SLICE) {
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_AES_V2;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AES_V2;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
}
if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) {
- capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_SHA3;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER;
}
if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) {
- capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
- capabilities &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
+ capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT;
+ }
+
+ capabilities_dc = ICP_ACCEL_CAPABILITIES_COMPRESSION |
+ ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION |
+ ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION |
+ ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64;
+
+ if (fusectl1 & ICP_ACCEL_4XXX_MASK_COMPRESS_SLICE) {
+ capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION;
+ capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION;
+ capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION;
+ capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64;
}

- return capabilities;
+ return capabilities_cy;
}

static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
diff --git a/drivers/crypto/qat/qat_common/icp_qat_hw.h b/drivers/crypto/qat/qat_common/icp_qat_hw.h
index 5770b2b2c09e..433304cad2ed 100644
--- a/drivers/crypto/qat/qat_common/icp_qat_hw.h
+++ b/drivers/crypto/qat/qat_common/icp_qat_hw.h
@@ -98,7 +98,11 @@ enum icp_qat_capabilities_mask {
ICP_ACCEL_CAPABILITIES_SHA3_EXT = BIT(15),
ICP_ACCEL_CAPABILITIES_AESGCM_SPC = BIT(16),
ICP_ACCEL_CAPABILITIES_CHACHA_POLY = BIT(17),
- /* Bits 18-25 are currently reserved */
+ /* Bits 18-21 are currently reserved */
+ ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY = BIT(22),
+ ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64 = BIT(23),
+ ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION = BIT(24),
+ ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION = BIT(25),
ICP_ACCEL_CAPABILITIES_AES_V2 = BIT(26)
};

--
2.31.1


2021-12-16 09:12:14

by Marco Chiappero

[permalink] [raw]
Subject: [PATCH 24/24] crypto: qat - add support for compression for 4xxx

From: Tomasz Kowalik <[email protected]>

Add the logic required to enable the compression service for 4xxx devices.
This allows to load the compression firmware image and report
the appropriate compression capabilities.

The firmware image selection for a given device is based on the
'ServicesEnabled' key stored in the internal configuration, which is
added statically at the probe of the device according to the following
rule, by default:
- odd numbered devices assigned to compression services
- even numbered devices assigned to crypto services

In addition, restore the 'ServicesEnabled' key, if present, when SRIOV
is enabled on the device.

Signed-off-by: Tomasz Kowalik <[email protected]>
Co-developed-by: Mateuszx Potrola <[email protected]>
Signed-off-by: Mateuszx Potrola <[email protected]>
Co-developed-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Giovanni Cabiddu <[email protected]>
Signed-off-by: Marco Chiappero <[email protected]>
Reviewed-by: Fiona Trahe <[email protected]>
Reviewed-by: Marco Chiappero <[email protected]>
---
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 79 +++++++++++++++++--
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 1 +
drivers/crypto/qat/qat_4xxx/adf_drv.c | 33 ++++++++
.../crypto/qat/qat_common/adf_accel_devices.h | 4 +-
.../crypto/qat/qat_common/adf_accel_engine.c | 8 +-
drivers/crypto/qat/qat_common/adf_cfg.c | 1 +
.../crypto/qat/qat_common/adf_cfg_strings.h | 3 +
drivers/crypto/qat/qat_common/adf_sriov.c | 31 +++++++-
8 files changed, 147 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index 40f684103b29..6d10edc40aca 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -2,6 +2,7 @@
/* Copyright(c) 2020 - 2021 Intel Corporation */
#include <linux/iopoll.h>
#include <adf_accel_devices.h>
+#include <adf_cfg.h>
#include <adf_common_drv.h>
#include <adf_gen4_hw_data.h>
#include <adf_gen4_pfvf.h>
@@ -13,12 +14,18 @@ struct adf_fw_config {
char *obj_name;
};

-static struct adf_fw_config adf_4xxx_fw_config[] = {
+static struct adf_fw_config adf_4xxx_fw_cy_config[] = {
{0xF0, ADF_4XXX_SYM_OBJ},
{0xF, ADF_4XXX_ASYM_OBJ},
{0x100, ADF_4XXX_ADMIN_OBJ},
};

+static struct adf_fw_config adf_4xxx_fw_dc_config[] = {
+ {0xF0, ADF_4XXX_DC_OBJ},
+ {0xF, ADF_4XXX_DC_OBJ},
+ {0x100, ADF_4XXX_ADMIN_OBJ},
+};
+
/* Worker thread to service arbiter mappings */
static const u32 thrd_to_arb_map[ADF_4XXX_MAX_ACCELENGINES] = {
0x5555555, 0x5555555, 0x5555555, 0x5555555,
@@ -32,6 +39,39 @@ static struct adf_hw_device_class adf_4xxx_class = {
.instances = 0,
};

+enum dev_services {
+ SVC_CY = 0,
+ SVC_DC,
+};
+
+static const char *const dev_cfg_services[] = {
+ [SVC_CY] = ADF_CFG_CY,
+ [SVC_DC] = ADF_CFG_DC,
+};
+
+static int get_service_enabled(struct adf_accel_dev *accel_dev)
+{
+ char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
+ u32 ret;
+
+ ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
+ ADF_SERVICES_ENABLED, services);
+ if (ret) {
+ dev_err(&GET_DEV(accel_dev),
+ ADF_SERVICES_ENABLED " param not found\n");
+ return ret;
+ }
+
+ ret = match_string(dev_cfg_services, ARRAY_SIZE(dev_cfg_services),
+ services);
+ if (ret < 0)
+ dev_err(&GET_DEV(accel_dev),
+ "Invalid value of " ADF_SERVICES_ENABLED " param: %s\n",
+ services);
+
+ return ret;
+}
+
static u32 get_accel_mask(struct adf_hw_device_data *self)
{
return ADF_4XXX_ACCELERATORS_MASK;
@@ -149,7 +189,14 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
capabilities_dc &= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64;
}

- return capabilities_cy;
+ switch (get_service_enabled(accel_dev)) {
+ case SVC_CY:
+ return capabilities_cy;
+ case SVC_DC:
+ return capabilities_dc;
+ }
+
+ return 0;
}

static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
@@ -230,17 +277,35 @@ static int adf_init_device(struct adf_accel_dev *accel_dev)

static u32 uof_get_num_objs(void)
{
- return ARRAY_SIZE(adf_4xxx_fw_config);
+ BUILD_BUG_ON_MSG(ARRAY_SIZE(adf_4xxx_fw_cy_config) !=
+ ARRAY_SIZE(adf_4xxx_fw_dc_config),
+ "Size mismatch between adf_4xxx_fw_*_config arrays");
+
+ return ARRAY_SIZE(adf_4xxx_fw_cy_config);
}

-static char *uof_get_name(u32 obj_num)
+static char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num)
{
- return adf_4xxx_fw_config[obj_num].obj_name;
+ switch (get_service_enabled(accel_dev)) {
+ case SVC_CY:
+ return adf_4xxx_fw_cy_config[obj_num].obj_name;
+ case SVC_DC:
+ return adf_4xxx_fw_dc_config[obj_num].obj_name;
+ }
+
+ return NULL;
}

-static u32 uof_get_ae_mask(u32 obj_num)
+static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num)
{
- return adf_4xxx_fw_config[obj_num].ae_mask;
+ switch (get_service_enabled(accel_dev)) {
+ case SVC_CY:
+ return adf_4xxx_fw_cy_config[obj_num].ae_mask;
+ case SVC_DC:
+ return adf_4xxx_fw_dc_config[obj_num].ae_mask;
+ }
+
+ return 0;
}

void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
index a0c67752317f..12e4fb9b40ce 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
@@ -77,6 +77,7 @@
#define ADF_4XXX_FW "qat_4xxx.bin"
#define ADF_4XXX_MMP "qat_4xxx_mmp.bin"
#define ADF_4XXX_SYM_OBJ "qat_4xxx_sym.bin"
+#define ADF_4XXX_DC_OBJ "qat_4xxx_dc.bin"
#define ADF_4XXX_ASYM_OBJ "qat_4xxx_asym.bin"
#define ADF_4XXX_ADMIN_OBJ "qat_4xxx_admin.bin"

diff --git a/drivers/crypto/qat/qat_4xxx/adf_drv.c b/drivers/crypto/qat/qat_4xxx/adf_drv.c
index 71ef065914b2..a6c78b9c730b 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_drv.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_drv.c
@@ -29,6 +29,29 @@ static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
adf_devmgr_rm_dev(accel_dev, NULL);
}

+static int adf_cfg_dev_init(struct adf_accel_dev *accel_dev)
+{
+ const char *config;
+ int ret;
+
+ config = accel_dev->accel_id % 2 ? ADF_CFG_DC : ADF_CFG_CY;
+
+ ret = adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
+ if (ret)
+ return ret;
+
+ /* Default configuration is crypto only for even devices
+ * and compression for odd devices
+ */
+ ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,
+ ADF_SERVICES_ENABLED, config,
+ ADF_STR);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int adf_crypto_dev_config(struct adf_accel_dev *accel_dev)
{
char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
@@ -227,8 +250,18 @@ static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_err;
}

+ ret = adf_cfg_dev_init(accel_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to initialize configuration.\n");
+ goto out_err;
+ }
+
/* Get accelerator capabilities mask */
hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
+ if (!hw_data->accel_capabilities_mask) {
+ dev_err(&pdev->dev, "Failed to get capabilities mask.\n");
+ goto out_err;
+ }

/* Find and map all the device's BARS */
bar_mask = pci_select_bars(pdev, IORESOURCE_MEM) & ADF_4XXX_BAR_MASK;
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index 1b9d4ed03dd0..2d4cd7c7cf33 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -192,9 +192,9 @@ struct adf_hw_device_data {
int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, u32 bank_nr);
void (*reset_device)(struct adf_accel_dev *accel_dev);
void (*set_msix_rttable)(struct adf_accel_dev *accel_dev);
- char *(*uof_get_name)(u32 obj_num);
+ char *(*uof_get_name)(struct adf_accel_dev *accel_dev, u32 obj_num);
u32 (*uof_get_num_objs)(void);
- u32 (*uof_get_ae_mask)(u32 obj_num);
+ u32 (*uof_get_ae_mask)(struct adf_accel_dev *accel_dev, u32 obj_num);
struct adf_pfvf_ops pfvf_ops;
struct adf_hw_csr_ops csr_ops;
const char *fw_name;
diff --git a/drivers/crypto/qat/qat_common/adf_accel_engine.c b/drivers/crypto/qat/qat_common/adf_accel_engine.c
index ca4eae8cdd0b..4ce2b666929e 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_engine.c
+++ b/drivers/crypto/qat/qat_common/adf_accel_engine.c
@@ -22,8 +22,12 @@ static int adf_ae_fw_load_images(struct adf_accel_dev *accel_dev, void *fw_addr,
num_objs = hw_device->uof_get_num_objs();

for (i = 0; i < num_objs; i++) {
- obj_name = hw_device->uof_get_name(i);
- ae_mask = hw_device->uof_get_ae_mask(i);
+ obj_name = hw_device->uof_get_name(accel_dev, i);
+ ae_mask = hw_device->uof_get_ae_mask(accel_dev, i);
+ if (!obj_name || !ae_mask) {
+ dev_err(&GET_DEV(accel_dev), "Invalid UOF image\n");
+ goto out_err;
+ }

if (qat_uclo_set_cfg_ae_mask(loader, ae_mask)) {
dev_err(&GET_DEV(accel_dev),
diff --git a/drivers/crypto/qat/qat_common/adf_cfg.c b/drivers/crypto/qat/qat_common/adf_cfg.c
index 575b6f002303..b5b208cbe5a1 100644
--- a/drivers/crypto/qat/qat_common/adf_cfg.c
+++ b/drivers/crypto/qat/qat_common/adf_cfg.c
@@ -297,3 +297,4 @@ int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
up_read(&cfg->lock);
return ret;
}
+EXPORT_SYMBOL_GPL(adf_cfg_get_param_value);
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
index 09651e1f937a..655248dbf962 100644
--- a/drivers/crypto/qat/qat_common/adf_cfg_strings.h
+++ b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
@@ -22,6 +22,9 @@
#define ADF_RING_ASYM_BANK_NUM "BankAsymNumber"
#define ADF_CY "Cy"
#define ADF_DC "Dc"
+#define ADF_CFG_DC "dc"
+#define ADF_CFG_CY "sym;asym"
+#define ADF_SERVICES_ENABLED "ServicesEnabled"
#define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled"
#define ADF_ETRMGR_COALESCING_ENABLED_FORMAT \
ADF_ETRMGR_BANK "%d" ADF_ETRMGR_COALESCING_ENABLED
diff --git a/drivers/crypto/qat/qat_common/adf_sriov.c b/drivers/crypto/qat/qat_common/adf_sriov.c
index 971a05d62418..b960bca1f9d2 100644
--- a/drivers/crypto/qat/qat_common/adf_sriov.c
+++ b/drivers/crypto/qat/qat_common/adf_sriov.c
@@ -126,6 +126,32 @@ void adf_disable_sriov(struct adf_accel_dev *accel_dev)
}
EXPORT_SYMBOL_GPL(adf_disable_sriov);

+static int adf_sriov_prepare_restart(struct adf_accel_dev *accel_dev)
+{
+ char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
+ int ret;
+
+ ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
+ ADF_SERVICES_ENABLED, services);
+
+ adf_dev_stop(accel_dev);
+ adf_dev_shutdown(accel_dev);
+
+ if (!ret) {
+ ret = adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
+ if (ret)
+ return ret;
+
+ ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,
+ ADF_SERVICES_ENABLED,
+ services, ADF_STR);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* adf_sriov_configure() - Enable SRIOV for the device
* @pdev: Pointer to PCI device.
@@ -165,8 +191,9 @@ int adf_sriov_configure(struct pci_dev *pdev, int numvfs)
return -EBUSY;
}

- adf_dev_stop(accel_dev);
- adf_dev_shutdown(accel_dev);
+ ret = adf_sriov_prepare_restart(accel_dev);
+ if (ret)
+ return ret;
}

if (adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC))
--
2.31.1


2021-12-24 03:25:51

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH 00/24] crypto: qat - PFVF updates and improved GEN4 support

On Thu, Dec 16, 2021 at 09:13:10AM +0000, Marco Chiappero wrote:
> This set mainly revolves around PFVF and support for compression on GEN4
> devices.
>
> Along with misc quality improvements to the PFVF code, it includes the
> following major changes:
> * Improved detection of HW capabilities for both GEN2 and GEN4 devices
> * PFVF protocol updates, up to version 4, which include Block Messages
> and Fast ACK
> * PFVF support for the GEN4 host driver
> * Support for enabling and reporting the compression service on GEN4
> devices
> * Support for Ring Pair reset by VFs on GEN4 devices
> * The refactoring of PFVF code to allow for the introduction of GEN4
> support
>
> Giovanni Cabiddu (5):
> crypto: qat - get compression extended capabilities
> crypto: qat - set CIPHER capability for QAT GEN2
> crypto: qat - set COMPRESSION capability for QAT GEN2
> crypto: qat - extend crypto capability detection for 4xxx
> crypto: qat - allow detection of dc capabilities for 4xxx
>
> Marco Chiappero (18):
> crypto: qat - support the reset of ring pairs on PF
> crypto: qat - add the adf_get_pmisc_base() helper function
> crypto: qat - make PFVF message construction direction agnostic
> crypto: qat - make PFVF send and receive direction agnostic
> crypto: qat - set PFVF_MSGORIGIN just before sending
> crypto: qat - abstract PFVF messages with struct pfvf_message
> crypto: qat - leverage bitfield.h utils for PFVF messages
> crypto: qat - leverage read_poll_timeout in PFVF send
> crypto: qat - improve the ACK timings in PFVF send
> crypto: qat - store the PFVF protocol version of the endpoints
> crypto: qat - store the ring-to-service mapping
> crypto: qat - introduce support for PFVF block messages
> crypto: qat - exchange device capabilities over PFVF
> crypto: qat - support fast ACKs in the PFVF protocol
> crypto: qat - exchange ring-to-service mappings over PFVF
> crypto: qat - config VFs based on ring-to-svc mapping
> crypto: qat - add PFVF support to the GEN4 host driver
> crypto: qat - add PFVF support to enable the reset of ring pairs
>
> Tomasz Kowalik (1):
> crypto: qat - add support for compression for 4xxx
>
> drivers/crypto/qat/Kconfig | 1 +
> .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 145 ++++++--
> .../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 2 +
> drivers/crypto/qat/qat_4xxx/adf_drv.c | 33 ++
> .../crypto/qat/qat_c3xxx/adf_c3xxx_hw_data.c | 1 +
> .../qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c | 1 +
> drivers/crypto/qat/qat_c3xxxvf/adf_drv.c | 4 -
> .../crypto/qat/qat_c62x/adf_c62x_hw_data.c | 1 +
> .../qat/qat_c62xvf/adf_c62xvf_hw_data.c | 1 +
> drivers/crypto/qat/qat_c62xvf/adf_drv.c | 4 -
> drivers/crypto/qat/qat_common/Makefile | 4 +-
> .../crypto/qat/qat_common/adf_accel_devices.h | 28 +-
> .../crypto/qat/qat_common/adf_accel_engine.c | 8 +-
> drivers/crypto/qat/qat_common/adf_admin.c | 47 ++-
> drivers/crypto/qat/qat_common/adf_cfg.c | 1 +
> .../crypto/qat/qat_common/adf_cfg_common.h | 13 +
> .../crypto/qat/qat_common/adf_cfg_strings.h | 3 +
> .../crypto/qat/qat_common/adf_common_drv.h | 12 +
> .../crypto/qat/qat_common/adf_gen2_hw_data.c | 57 ++--
> .../crypto/qat/qat_common/adf_gen2_hw_data.h | 9 +
> drivers/crypto/qat/qat_common/adf_gen2_pfvf.c | 316 +++++++++++++-----
> .../crypto/qat/qat_common/adf_gen4_hw_data.c | 62 +++-
> .../crypto/qat/qat_common/adf_gen4_hw_data.h | 17 +
> drivers/crypto/qat/qat_common/adf_gen4_pfvf.c | 148 ++++++++
> drivers/crypto/qat/qat_common/adf_gen4_pfvf.h | 17 +
> drivers/crypto/qat/qat_common/adf_init.c | 9 +-
> drivers/crypto/qat/qat_common/adf_isr.c | 28 +-
> drivers/crypto/qat/qat_common/adf_pfvf_msg.h | 202 +++++++++--
> .../crypto/qat/qat_common/adf_pfvf_pf_msg.c | 35 +-
> .../crypto/qat/qat_common/adf_pfvf_pf_msg.h | 8 +
> .../crypto/qat/qat_common/adf_pfvf_pf_proto.c | 262 +++++++++++++--
> .../crypto/qat/qat_common/adf_pfvf_pf_proto.h | 2 +-
> .../crypto/qat/qat_common/adf_pfvf_utils.c | 65 ++++
> .../crypto/qat/qat_common/adf_pfvf_utils.h | 31 ++
> .../crypto/qat/qat_common/adf_pfvf_vf_msg.c | 98 +++++-
> .../crypto/qat/qat_common/adf_pfvf_vf_msg.h | 2 +
> .../crypto/qat/qat_common/adf_pfvf_vf_proto.c | 284 ++++++++++++++--
> .../crypto/qat/qat_common/adf_pfvf_vf_proto.h | 7 +-
> drivers/crypto/qat/qat_common/adf_sriov.c | 39 ++-
> drivers/crypto/qat/qat_common/adf_vf_isr.c | 14 +-
> .../qat/qat_common/icp_qat_fw_init_admin.h | 4 +-
> drivers/crypto/qat/qat_common/icp_qat_hw.h | 13 +-
> drivers/crypto/qat/qat_common/qat_crypto.c | 25 ++
> drivers/crypto/qat/qat_common/qat_hal.c | 41 +--
> .../qat/qat_dh895xcc/adf_dh895xcc_hw_data.c | 3 +
> .../qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 1 +
> drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 4 -
> 47 files changed, 1776 insertions(+), 336 deletions(-)
> create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.c
> create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pfvf.h
> create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.c
> create mode 100644 drivers/crypto/qat/qat_common/adf_pfvf_utils.h
>
> --
> 2.31.1

All applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt