From 5005327514064840c6713b793cd80c5b98afba3d Mon Sep 17 00:00:00 2001 From: Adam Guerin Date: Fri, 9 Jun 2023 17:38:22 +0100 Subject: [PATCH] crypto: qat - extend configuration for 4xxx A QAT GEN4 device can be currently configured for crypto (sym;asym) or compression (dc). This patch extends the configuration to support more variations of these services, download the correct FW images on the device and report the correct capabilities on the device based on the configured service. The device can now be configured with the following services: "sym", "asym", "dc", "sym;asym", "asym;sym", "sym;dc", "dc;sym", "asym;dc", "dc;asym". With this change, the configuration "sym", "asym", "sym;dc", "dc;sym", "asym;dc", "dc;asym" will be accessible only via userspace, i.e. the driver for those configurations will not register into the crypto framework. Support for such configurations in kernel will be enabled in a later patch. The pairs "sym;asym" and "asym;sym" result in identical device config. As do "sym;dc", "dc;sym", and "asym;dc", "dc;asym". Signed-off-by: Adam Guerin Reviewed-by: Giovanni Cabiddu Reviewed-by: Andy Shevchenko Signed-off-by: Herbert Xu --- Documentation/ABI/testing/sysfs-driver-qat | 11 ++ .../crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c | 127 +++++++++++++++++---- drivers/crypto/intel/qat/qat_4xxx/adf_drv.c | 33 ++++++ .../crypto/intel/qat/qat_common/adf_cfg_strings.h | 7 ++ drivers/crypto/intel/qat/qat_common/adf_sysfs.c | 7 ++ 5 files changed, 163 insertions(+), 22 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-driver-qat b/Documentation/ABI/testing/sysfs-driver-qat index 087842b..e6d427c 100644 --- a/Documentation/ABI/testing/sysfs-driver-qat +++ b/Documentation/ABI/testing/sysfs-driver-qat @@ -27,7 +27,18 @@ Description: (RW) Reports the current configuration of the QAT device. * sym;asym: the device is configured for running crypto services + * asym;sym: identical to sym;asym * dc: the device is configured for running compression services + * sym: the device is configured for running symmetric crypto + services + * asym: the device is configured for running asymmetric crypto + services + * asym;dc: the device is configured for running asymmetric + crypto services and compression services + * dc;asym: identical to asym;dc + * sym;dc: the device is configured for running symmetric crypto + services and compression services + * dc;sym: identical to sym;dc It is possible to set the configuration only if the device is in the `down` state (see /sys/bus/pci/devices//qat/state) diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c index ec30359..e543a9e 100644 --- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c @@ -49,10 +49,38 @@ static const struct adf_fw_config adf_fw_dc_config[] = { {0x100, ADF_FW_ADMIN_OBJ}, }; +static const struct adf_fw_config adf_fw_sym_config[] = { + {0xF0, ADF_FW_SYM_OBJ}, + {0xF, ADF_FW_SYM_OBJ}, + {0x100, ADF_FW_ADMIN_OBJ}, +}; + +static const struct adf_fw_config adf_fw_asym_config[] = { + {0xF0, ADF_FW_ASYM_OBJ}, + {0xF, ADF_FW_ASYM_OBJ}, + {0x100, ADF_FW_ADMIN_OBJ}, +}; + +static const struct adf_fw_config adf_fw_asym_dc_config[] = { + {0xF0, ADF_FW_ASYM_OBJ}, + {0xF, ADF_FW_DC_OBJ}, + {0x100, ADF_FW_ADMIN_OBJ}, +}; + +static const struct adf_fw_config adf_fw_sym_dc_config[] = { + {0xF0, ADF_FW_SYM_OBJ}, + {0xF, ADF_FW_DC_OBJ}, + {0x100, ADF_FW_ADMIN_OBJ}, +}; + static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_dc_config)); +static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_sym_config)); +static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_asym_config)); +static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_asym_dc_config)); +static_assert(ARRAY_SIZE(adf_fw_cy_config) == ARRAY_SIZE(adf_fw_sym_dc_config)); /* Worker thread to service arbiter mappings */ -static const u32 thrd_to_arb_map_cy[ADF_4XXX_MAX_ACCELENGINES] = { +static const u32 default_thrd_to_arb_map[ADF_4XXX_MAX_ACCELENGINES] = { 0x5555555, 0x5555555, 0x5555555, 0x5555555, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0xAAAAAAA, 0x0 @@ -72,12 +100,26 @@ static struct adf_hw_device_class adf_4xxx_class = { enum dev_services { SVC_CY = 0, + SVC_CY2, SVC_DC, + SVC_SYM, + SVC_ASYM, + SVC_DC_ASYM, + SVC_ASYM_DC, + SVC_DC_SYM, + SVC_SYM_DC, }; static const char *const dev_cfg_services[] = { [SVC_CY] = ADF_CFG_CY, + [SVC_CY2] = ADF_CFG_ASYM_SYM, [SVC_DC] = ADF_CFG_DC, + [SVC_SYM] = ADF_CFG_SYM, + [SVC_ASYM] = ADF_CFG_ASYM, + [SVC_DC_ASYM] = ADF_CFG_DC_ASYM, + [SVC_ASYM_DC] = ADF_CFG_ASYM_DC, + [SVC_DC_SYM] = ADF_CFG_DC_SYM, + [SVC_SYM_DC] = ADF_CFG_SYM_DC, }; static int get_service_enabled(struct adf_accel_dev *accel_dev) @@ -167,45 +209,50 @@ 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 capabilities_sym, capabilities_asym, capabilities_dc; u32 fusectl1; /* 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 | + capabilities_sym = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | 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_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_HKDF; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_HKDF; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_CIPHER; } + if (fusectl1 & ICP_ACCEL_4XXX_MASK_UCS_SLICE) { - 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; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_CHACHA_POLY; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_AESGCM_SPC; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_AES_V2; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_CIPHER; } + if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) { - 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; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_SHA3; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_SHA3_EXT; + capabilities_sym &= ~ICP_ACCEL_CAPABILITIES_CIPHER; } + + capabilities_asym = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | + ICP_ACCEL_CAPABILITIES_CIPHER | + ICP_ACCEL_CAPABILITIES_ECEDMONT; + if (fusectl1 & ICP_ACCEL_4XXX_MASK_PKE_SLICE) { - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; - capabilities_cy &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT; + capabilities_asym &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + capabilities_asym &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT; } capabilities_dc = ICP_ACCEL_CAPABILITIES_COMPRESSION | @@ -222,9 +269,20 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev) switch (get_service_enabled(accel_dev)) { case SVC_CY: - return capabilities_cy; + case SVC_CY2: + return capabilities_sym | capabilities_asym; case SVC_DC: return capabilities_dc; + case SVC_SYM: + return capabilities_sym; + case SVC_ASYM: + return capabilities_asym; + case SVC_ASYM_DC: + case SVC_DC_ASYM: + return capabilities_asym | capabilities_dc; + case SVC_SYM_DC: + case SVC_DC_SYM: + return capabilities_sym | capabilities_dc; default: return 0; } @@ -238,12 +296,10 @@ static enum dev_sku_info get_sku(struct adf_hw_device_data *self) static const u32 *adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev) { switch (get_service_enabled(accel_dev)) { - case SVC_CY: - return thrd_to_arb_map_cy; case SVC_DC: return thrd_to_arb_map_dc; default: - return NULL; + return default_thrd_to_arb_map; } } @@ -325,11 +381,26 @@ static const char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num, switch (get_service_enabled(accel_dev)) { case SVC_CY: + case SVC_CY2: id = adf_fw_cy_config[obj_num].obj; break; case SVC_DC: id = adf_fw_dc_config[obj_num].obj; break; + case SVC_SYM: + id = adf_fw_sym_config[obj_num].obj; + break; + case SVC_ASYM: + id = adf_fw_asym_config[obj_num].obj; + break; + case SVC_ASYM_DC: + case SVC_DC_ASYM: + id = adf_fw_asym_dc_config[obj_num].obj; + break; + case SVC_SYM_DC: + case SVC_DC_SYM: + id = adf_fw_sym_dc_config[obj_num].obj; + break; default: id = -EINVAL; break; @@ -362,6 +433,18 @@ static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num) return adf_fw_cy_config[obj_num].ae_mask; case SVC_DC: return adf_fw_dc_config[obj_num].ae_mask; + case SVC_CY2: + return adf_fw_cy_config[obj_num].ae_mask; + case SVC_SYM: + return adf_fw_sym_config[obj_num].ae_mask; + case SVC_ASYM: + return adf_fw_asym_config[obj_num].ae_mask; + case SVC_ASYM_DC: + case SVC_DC_ASYM: + return adf_fw_asym_dc_config[obj_num].ae_mask; + case SVC_SYM_DC: + case SVC_DC_SYM: + return adf_fw_sym_dc_config[obj_num].ae_mask; default: return 0; } diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c index 3ecc190..1a15600 100644 --- a/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c +++ b/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c @@ -25,11 +25,25 @@ MODULE_DEVICE_TABLE(pci, adf_pci_tbl); enum configs { DEV_CFG_CY = 0, DEV_CFG_DC, + DEV_CFG_SYM, + DEV_CFG_ASYM, + DEV_CFG_ASYM_SYM, + DEV_CFG_ASYM_DC, + DEV_CFG_DC_ASYM, + DEV_CFG_SYM_DC, + DEV_CFG_DC_SYM, }; static const char * const services_operations[] = { ADF_CFG_CY, ADF_CFG_DC, + ADF_CFG_SYM, + ADF_CFG_ASYM, + ADF_CFG_ASYM_SYM, + ADF_CFG_ASYM_DC, + ADF_CFG_DC_ASYM, + ADF_CFG_SYM_DC, + ADF_CFG_DC_SYM, }; static void adf_cleanup_accel(struct adf_accel_dev *accel_dev) @@ -242,6 +256,21 @@ err: return ret; } +static int adf_no_dev_config(struct adf_accel_dev *accel_dev) +{ + unsigned long val; + int ret; + + val = 0; + ret = adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_DC, + &val, ADF_DEC); + if (ret) + return ret; + + return adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_CY, + &val, ADF_DEC); +} + int adf_gen4_dev_config(struct adf_accel_dev *accel_dev) { char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; @@ -266,11 +295,15 @@ int adf_gen4_dev_config(struct adf_accel_dev *accel_dev) switch (ret) { case DEV_CFG_CY: + case DEV_CFG_ASYM_SYM: ret = adf_crypto_dev_config(accel_dev); break; case DEV_CFG_DC: ret = adf_comp_dev_config(accel_dev); break; + default: + ret = adf_no_dev_config(accel_dev); + break; } if (ret) diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h index 5d8c3bd..b6a9abe 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h +++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h @@ -25,6 +25,13 @@ #define ADF_DC "Dc" #define ADF_CFG_DC "dc" #define ADF_CFG_CY "sym;asym" +#define ADF_CFG_SYM "sym" +#define ADF_CFG_ASYM "asym" +#define ADF_CFG_ASYM_SYM "asym;sym" +#define ADF_CFG_ASYM_DC "asym;dc" +#define ADF_CFG_DC_ASYM "dc;asym" +#define ADF_CFG_SYM_DC "sym;dc" +#define ADF_CFG_DC_SYM "dc;sym" #define ADF_SERVICES_ENABLED "ServicesEnabled" #define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled" #define ADF_ETRMGR_COALESCING_ENABLED_FORMAT \ diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c index 3eb6611..b2ec923 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_sysfs.c +++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs.c @@ -78,6 +78,13 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, static const char * const services_operations[] = { ADF_CFG_CY, ADF_CFG_DC, + ADF_CFG_SYM, + ADF_CFG_ASYM, + ADF_CFG_ASYM_SYM, + ADF_CFG_ASYM_DC, + ADF_CFG_DC_ASYM, + ADF_CFG_SYM_DC, + ADF_CFG_DC_SYM, }; static ssize_t cfg_services_show(struct device *dev, struct device_attribute *attr, -- 2.7.4