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 <marco.chiappero@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Fiona Trahe <fiona.trahe@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Marco Chiappero 2021-12-16 09:13:27 +00:00 committed by Herbert Xu
parent 673184a2a5
commit 851ed498db
8 changed files with 112 additions and 4 deletions

View File

@ -203,6 +203,7 @@ struct adf_hw_device_data {
u32 straps; u32 straps;
u32 accel_capabilities_mask; u32 accel_capabilities_mask;
u32 extended_dc_capabilities; u32 extended_dc_capabilities;
u32 clock_frequency;
u32 instance_id; u32 instance_id;
u16 accel_mask; u16 accel_mask;
u32 ae_mask; u32 ae_mask;

View File

@ -87,8 +87,10 @@ enum vf2pf_msgtype {
/* VF/PF compatibility version. */ /* VF/PF compatibility version. */
enum pfvf_compatibility_version { enum pfvf_compatibility_version {
/* Reference to the current version */ /* Support for extended capabilities */
ADF_PFVF_COMPAT_THIS_VERSION = 0x01, ADF_PFVF_COMPAT_CAPABILITIES = 0x02,
/* Reference to the latest version */
ADF_PFVF_COMPAT_THIS_VERSION = 0x02,
}; };
/* PF->VF Version Response */ /* PF->VF Version Response */
@ -133,7 +135,9 @@ enum pf2vf_blkmsg_error {
* 16..23 - 64 byte message * 16..23 - 64 byte message
* 24..27 - 128 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 \ #define ADF_VF2PF_SMALL_BLOCK_TYPE_MAX \
(FIELD_MAX(ADF_VF2PF_SMALL_BLOCK_TYPE_MASK)) (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_VER_BYTE 0
#define ADF_PFVF_BLKMSG_LEN_BYTE 1 #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 */ #endif /* ADF_PFVF_MSG_H */

View File

@ -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); "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;
}

View File

@ -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, typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
u8 *buffer, u8 compat); 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 */ #endif /* ADF_PFVF_PF_MSG_H */

View File

@ -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[] = { static const adf_pf2vf_blkmsg_provider pf2vf_blkmsg_providers[] = {
NULL, /* no message type defined for value 0 */ NULL, /* no message type defined for value 0 */
NULL, /* no message type defined for value 1 */ NULL, /* no message type defined for value 1 */
adf_pf_capabilities_msg_provider, /* ADF_VF2PF_BLKMSG_REQ_CAP_SUMMARY */
}; };
/** /**

View File

@ -92,3 +92,49 @@ int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
accel_dev->vf.pf_compat_ver = pf_version; accel_dev->vf.pf_compat_ver = pf_version;
return 0; 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;
}

View File

@ -7,6 +7,7 @@
int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev); int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev);
void adf_vf2pf_notify_shutdown(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_request_version(struct adf_accel_dev *accel_dev);
int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev);
#else #else
static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) static inline int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev)
{ {

View File

@ -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 adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
{ {
int ret;
adf_pfvf_crc_init(); adf_pfvf_crc_init();
adf_enable_pf2vf_interrupts(accel_dev); 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); EXPORT_SYMBOL_GPL(adf_enable_vf2pf_comms);