diff --git a/share/man/man4/qat.4 b/share/man/man4/qat.4 --- a/share/man/man4/qat.4 +++ b/share/man/man4/qat.4 @@ -1,7 +1,7 @@ .\" SPDX-License-Identifier: BSD-3-Clause .\" Copyright(c) 2007-2022 Intel Corporation .\" $FreeBSD$ -.Dd September 1, 2022 +.Dd May 4, 2023 .Dt QAT 4 .Os .Sh NAME @@ -101,6 +101,61 @@ documentation mentioned above and .Sx SEE ALSO section. +.Sh SYSCTL_VARIABLES +Following variables may be used to reconfigure the QAT device.\& +For configuration persistence those variables may be set before loading the driver, either via +.Xr kenv 1 +or +.Xr loader.conf(5). +The device specific configuration options are prefixed with +.Va dev.qat.X\&. +where X is the device number. +The specific device needs to be in "down" state before changing the configuration. +.Bl -tag -width indent +.It Va state +Show current state of the device. Override the device state. Possible values: "down", "up". + +NOTE: If the symmetric services are used for device the qat_ocf driver needs to be disabled prior the device +reconfiguration. +Following variable may be used to enable/disable the QAT cryptographic framework connectivity +.Va dev.qat_ocf.0.enable\&. +Enabled by default. +.It Va cfg_services +Override the device services enabled: symmetric, asymmetric, data compression. +Possible values: "sym", "asym", "dc", "sym;dc", "asym;dc", "sym;asym". +Default services configured are "sym;asym" for even and "dc" for odd devices. +.It Va cfg_mode +Override the device mode configuration for kernel space and user space instances. +Possible values: "ks", "us", "ks;us". +Default value "ks;us". +.It Va num_user_processes +Override the number of uio user space processes that can connect to the QAT device. +Default: 2 +.El +.Pp +The following +.Xr sysctl 8 +variables are read-only: +.Bl -tag -width indent +.It Va frequency +QAT device frequency value. +.It Va mmp_version +QAT MMP Library revision number. +.It Va hw_version +QAT hardware revision number. +.It Va fw_version +QAT firmware revision number. +.It Va dev_cfg +Summary of device specific configuration. +.It Va heartbeat +QAT device heartbeat status. Value '1' indicates that the device is operational. +'0' value means that the device is not responsive. Device requires restart. +.It Va heartbeat_failed +Number of QAT heartbeat failures received. +.It Va heartbeat_sent +Number of QAT heartbeat requests sent. +.El + .Sh COMPATIBILITY The .Nm diff --git a/sys/contrib/dev/qat/qat_4xxx.bin b/sys/contrib/dev/qat/qat_4xxx.bin index baec3ad9ca32a87113fe185afc94ec264ff5fa4f..66dd803fe419c681f7fa19381e716179bd226fb0 GIT binary patch literal 665356 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 F{|&qWsqX*) literal 532308 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

q#ncN4_wqhZ#!n@H@Zz9@{q6lF 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 loRq~qM8Q>Ss{lwSkIpJ?Z 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 diff --git a/sys/dev/qat/include/adf_cfg_device.h b/sys/dev/qat/include/adf_cfg_device.h --- a/sys/dev/qat/include/adf_cfg_device.h +++ b/sys/dev/qat/include/adf_cfg_device.h @@ -13,14 +13,14 @@ #define ADF_CFG_STATIC_CONF_DC_INTER_BUF_SIZE 64 #define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ENABLED 1 #define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC 1 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DH 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DRBG 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DSA 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ECC 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_KEYGEN 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_LN 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_PRIME 0 -#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_RSA 0 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DH 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DRBG 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DSA 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ECC 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_KEYGEN 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_LN 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_PRIME 1 +#define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_RSA 1 #define ADF_CFG_STATIC_CONF_SAL_STATS_CFG_SYM 1 #define ADF_CFG_STATIC_CONF_POLL 1 #define ADF_CFG_STATIC_CONF_IRQ 0 @@ -30,6 +30,14 @@ #define ADF_CFG_STATIC_CONF_INST_NUM_DC 2 #define ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL 6 #define ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ 2 +#define ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM 2 +#define ADF_CFG_STATIC_CONF_USER_INST_NUM_CY 6 +#define ADF_CFG_STATIC_CONF_USER_INST_NUM_DC 2 +#define ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL_VF 1 +#define ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ_VF 1 +#define ADF_CFG_STATIC_CONF_INST_NUM_DC_VF 2 +#define ADF_CFG_STATIC_CONF_USER_INST_NUM_CY_VF 2 +#define ADF_CFG_STATIC_CONF_USER_INST_NUM_DC_VF 2 #define ADF_CFG_FW_STRING_TO_ID(str, acc, id) \ do { \ diff --git a/sys/dev/qat/include/adf_gen2_pfvf.h b/sys/dev/qat/include/adf_gen2_pfvf.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/adf_gen2_pfvf.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN2_PFVF_H +#define ADF_GEN2_PFVF_H + +#include +#include "adf_accel_devices.h" + +#define ADF_GEN2_ERRSOU3 (0x3A000 + 0x0C) +#define ADF_GEN2_ERRSOU5 (0x3A000 + 0xD8) +#define ADF_GEN2_ERRMSK3 (0x3A000 + 0x1C) +#define ADF_GEN2_ERRMSK5 (0x3A000 + 0xDC) + +static inline void +adf_gen2_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +static inline void +adf_gen2_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +#endif /* ADF_GEN2_PFVF_H */ diff --git a/sys/dev/qat/include/adf_gen4_pfvf.h b/sys/dev/qat/include/adf_gen4_pfvf.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/adf_gen4_pfvf.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4_PFVF_H +#define ADF_GEN4_PFVF_H + +#include "adf_accel_devices.h" + +void adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops); +static inline void +adf_gen4_init_pf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_pfvf_comms_disabled; +} + +#endif /* ADF_GEN4_PFVF_H */ diff --git a/sys/dev/qat/include/adf_gen4_timer.h b/sys/dev/qat/include/adf_gen4_timer.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/adf_gen4_timer.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4_TIMER_H_ +#define ADF_GEN4_TIMER_H_ + +struct adf_accel_dev; + +struct adf_hb_timer_data { + struct adf_accel_dev *accel_dev; + struct work_struct hb_int_timer_work; +}; + +int adf_int_timer_init(struct adf_accel_dev *accel_dev); +void adf_int_timer_exit(struct adf_accel_dev *accel_dev); + +#endif /* ADF_GEN4_TIMER_H_ */ diff --git a/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h b/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/adf_gen4vf_hw_csr_data.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_GEN4VF_HW_CSR_DATA_H_ +#define ADF_GEN4VF_HW_CSR_DATA_H_ + +#define ADF_RING_CSR_ADDR_OFFSET_GEN4VF 0x0 +#define ADF_RING_BUNDLE_SIZE_GEN4 0x2000 +#define ADF_RING_CSR_RING_HEAD 0x0C0 +#define ADF_RING_CSR_RING_TAIL 0x100 +#define ADF_RING_CSR_E_STAT 0x14C +#define ADF_RING_CSR_RING_CONFIG_GEN4 0x1000 +#define ADF_RING_CSR_RING_LBASE_GEN4 0x1040 +#define ADF_RING_CSR_RING_UBASE_GEN4 0x1080 +#define ADF_RING_CSR_INT_FLAG 0x170 +#define ADF_RING_CSR_INT_FLAG_AND_COL 0x184 +#define ADF_RING_CSR_NEXT_INT_SRCSEL 0x4 +#define ADF_RING_CSR_INT_SRCSEL 0x174 +#define ADF_RING_CSR_INT_COL_EN 0x17C +#define ADF_RING_CSR_INT_COL_CTL 0x180 +#define ADF_RING_CSR_RING_SRV_ARB_EN 0x19C +#define ADF_BANK_INT_SRC_SEL_MASK_GEN4 0x44UL +#define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000 +#define ADF_BANK_INT_FLAG_CLEAR_MASK_GEN4 0x3 +#define ADF_RINGS_PER_INT_SRCSEL_GEN4 2 + +#define BUILD_RING_BASE_ADDR_GEN4(addr, size) \ + ((((addr) >> 6) & (0xFFFFFFFFFFFFFFFFULL << (size))) << 6) +#define READ_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_HEAD + ((ring) << 2)) +#define READ_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_TAIL + ((ring) << 2)) +#define READ_CSR_E_STAT_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_E_STAT) +#define WRITE_CSR_RING_CONFIG_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_CONFIG_GEN4 + ((ring) << 2), \ + (value)) +#define WRITE_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring, value) \ + do { \ + struct resource *_csr_base_addr = csr_base_addr; \ + u32 _bank = bank; \ + u32 _ring = ring; \ + dma_addr_t _value = value; \ + u32 l_base = 0, u_base = 0; \ + l_base = (u32)((_value)&0xFFFFFFFF); \ + u_base = (u32)(((_value)&0xFFFFFFFF00000000ULL) >> 32); \ + ADF_CSR_WR((_csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (_bank)) + \ + ADF_RING_CSR_RING_LBASE_GEN4 + ((_ring) << 2), \ + l_base); \ + ADF_CSR_WR((_csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (_bank)) + \ + ADF_RING_CSR_RING_UBASE_GEN4 + ((_ring) << 2), \ + u_base); \ + } while (0) + +static inline u64 +read_base_gen4vf(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE_GEN4 * bank) + + ADF_RING_CSR_RING_LBASE_GEN4 + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE_GEN4 * bank) + + ADF_RING_CSR_RING_UBASE_GEN4 + (ring << 2)); + + addr = (u64)l_base & 0x00000000FFFFFFFFULL; + addr |= (u64)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define WRITE_CSR_INT_SRCSEL_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_WR((csr_base_addr), \ + ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank) + \ + ADF_RING_CSR_INT_SRCSEL, \ + ADF_BANK_INT_SRC_SEL_MASK_GEN4) + +#define READ_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring) \ + read_base_gen4vf((csr_base_addr), (bank), (ring)) + +#define WRITE_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_HEAD + ((ring) << 2), \ + (value)) +#define WRITE_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_TAIL + ((ring) << 2), \ + (value)) +#define WRITE_CSR_INT_FLAG_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_FLAG, \ + (value)) +#define WRITE_CSR_INT_COL_EN_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_COL_EN, \ + (value)) +#define WRITE_CSR_INT_COL_CTL_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_COL_CTL, \ + (value)) +#define WRITE_CSR_INT_FLAG_AND_COL_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_INT_FLAG_AND_COL, \ + (value)) +#define READ_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank) \ + ADF_CSR_RD((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_SRV_ARB_EN) +#define WRITE_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank, value) \ + ADF_CSR_WR((csr_base_addr), \ + (ADF_RING_CSR_ADDR_OFFSET_GEN4VF + \ + ADF_RING_BUNDLE_SIZE_GEN4 * (bank)) + \ + ADF_RING_CSR_RING_SRV_ARB_EN, \ + (value)) + +struct adf_hw_csr_info; +void gen4vf_init_hw_csr_info(struct adf_hw_csr_info *csr_info); + +#endif /* ADF_GEN4VF_HW_CSR_DATA_H_ */ diff --git a/sys/dev/qat/include/adf_pf2vf_msg.h b/sys/dev/qat/include/adf_pf2vf_msg.h deleted file mode 100644 --- a/sys/dev/qat/include/adf_pf2vf_msg.h +++ /dev/null @@ -1,182 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#ifndef ADF_PF2VF_MSG_H -#define ADF_PF2VF_MSG_H - -/* - * PF<->VF Messaging - * 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. - * - * The register functionally is split into two parts: - * The bottom half is for PF->VF messages. In particular when the first - * bit of this register (bit 0) gets set an interrupt will be triggered - * in the respective VF. - * The top half is for VF->PF messages. In particular when the first bit - * of this half of register (bit 16) gets set an interrupt will be triggered - * in the PF. - * - * The remaining bits within this register are available to encode messages. - * and implement a collision control mechanism to prevent concurrent use of - * the PF2VF register by both the PF and VF. - * - * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 - * _______________________________________________ - * | | | | | | | | | | | | | | | | | - * +-----------------------------------------------+ - * \___________________________/ \_________/ ^ ^ - * ^ ^ | | - * | | | VF2PF Int - * | | Message Origin - * | Message Type - * Message-specific Data/Reserved - * - * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - * _______________________________________________ - * | | | | | | | | | | | | | | | | | - * +-----------------------------------------------+ - * \___________________________/ \_________/ ^ ^ - * ^ ^ | | - * | | | PF2VF Int - * | | Message Origin - * | Message Type - * Message-specific Data/Reserved - * - * Message Origin (Should always be 1) - * A legacy out-of-tree QAT driver allowed for a set of messages not supported - * by this driver; these had a Msg Origin of 0 and are ignored by this driver. - * - * When a PF or VF attempts to send a message in the lower or upper 16 bits, - * respectively, the other 16 bits are written to first with a defined - * IN_USE_BY pattern as part of a collision control scheme (see adf_iov_putmsg). - */ - -/* VF/PF compatibility version. */ -/* ADF_PFVF_COMPATIBILITY_EXT_CAP: Support for extended capabilities */ -#define ADF_PFVF_COMPATIBILITY_CAPABILITIES 2 -/* ADF_PFVF_COMPATIBILITY_FAST_ACK: In-use pattern cleared by receiver */ -#define ADF_PFVF_COMPATIBILITY_FAST_ACK 3 -#define ADF_PFVF_COMPATIBILITY_RING_TO_SVC_MAP 4 -#define ADF_PFVF_COMPATIBILITY_VERSION 4 /* PF<->VF compat */ - -/* PF->VF messages */ -#define ADF_PF2VF_INT BIT(0) -#define ADF_PF2VF_MSGORIGIN_SYSTEM BIT(1) -#define ADF_PF2VF_MSGTYPE_MASK 0x0000003C -#define ADF_PF2VF_MSGTYPE_SHIFT 2 -#define ADF_PF2VF_MSGTYPE_RESTARTING 0x01 -#define ADF_PF2VF_MSGTYPE_VERSION_RESP 0x02 -#define ADF_PF2VF_MSGTYPE_BLOCK_RESP 0x03 -#define ADF_PF2VF_MSGTYPE_FATAL_ERROR 0x04 -#define ADF_PF2VF_IN_USE_BY_PF 0x6AC20000 -#define ADF_PF2VF_IN_USE_BY_PF_MASK 0xFFFE0000 - -/* PF->VF Version Response */ -#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_RESULT_SHIFT 14 -#define ADF_PF2VF_MINORVERSION_SHIFT 6 -#define ADF_PF2VF_MAJORVERSION_SHIFT 10 -#define ADF_PF2VF_VF_COMPATIBLE 1 -#define ADF_PF2VF_VF_INCOMPATIBLE 2 -#define ADF_PF2VF_VF_COMPAT_UNKNOWN 3 - -/* PF->VF Block Request Type */ -#define ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE 0 -#define ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE (ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE + 15) -#define ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE (ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE + 1) -#define ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE \ - (ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE + 7) -#define ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE (ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE + 1) -#define ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE (ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE + 3) -#define ADF_VF2PF_SMALL_PAYLOAD_SIZE 30 -#define ADF_VF2PF_MEDIUM_PAYLOAD_SIZE 62 -#define ADF_VF2PF_LARGE_PAYLOAD_SIZE 126 - -#define ADF_VF2PF_MAX_BLOCK_TYPE 3 -#define ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT 22 -#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT 24 -#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT 25 -#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT 26 -#define ADF_VF2PF_BLOCK_REQ_CRC_SHIFT 31 -#define ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_MASK 0x7F000000 -#define ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_MASK 0x7E000000 -#define ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_MASK 0x7C000000 -#define ADF_VF2PF_LARGE_BLOCK_REQ_TYPE_MASK 0xC00000 -#define ADF_VF2PF_MEDIUM_BLOCK_REQ_TYPE_MASK 0x1C00000 -#define ADF_VF2PF_SMALL_BLOCK_REQ_TYPE_MASK 0x3C00000 - -/* PF->VF Block Response Type */ -#define ADF_PF2VF_BLOCK_RESP_TYPE_DATA 0x0 -#define ADF_PF2VF_BLOCK_RESP_TYPE_CRC 0x1 -#define ADF_PF2VF_BLOCK_RESP_TYPE_ERROR 0x2 -#define ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT 6 -#define ADF_PF2VF_BLOCK_RESP_DATA_SHIFT 8 -#define ADF_PF2VF_BLOCK_RESP_TYPE_MASK 0x000000C0 -#define ADF_PF2VF_BLOCK_RESP_DATA_MASK 0x0000FF00 - -/* PF-VF block message header bytes */ -#define ADF_VF2PF_BLOCK_VERSION_BYTE 0 -#define ADF_VF2PF_BLOCK_LEN_BYTE 1 -#define ADF_VF2PF_BLOCK_DATA 2 - -/* PF->VF Block Error Code */ -#define ADF_PF2VF_INVALID_BLOCK_TYPE 0x0 -#define ADF_PF2VF_INVALID_BYTE_NUM_REQ 0x1 -#define ADF_PF2VF_PAYLOAD_TRUNCATED 0x2 -#define ADF_PF2VF_UNSPECIFIED_ERROR 0x3 - -/* VF->PF messages */ -#define ADF_VF2PF_IN_USE_BY_VF 0x00006AC2 -#define ADF_VF2PF_IN_USE_BY_VF_MASK 0x0000FFFE -#define ADF_VF2PF_INT BIT(16) -#define ADF_VF2PF_MSGORIGIN_SYSTEM BIT(17) -#define ADF_VF2PF_MSGTYPE_MASK 0x003C0000 -#define ADF_VF2PF_MSGTYPE_SHIFT 18 -#define ADF_VF2PF_MSGTYPE_INIT 0x3 -#define ADF_VF2PF_MSGTYPE_SHUTDOWN 0x4 -#define ADF_VF2PF_MSGTYPE_VERSION_REQ 0x5 -#define ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ 0x6 -#define ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ 0x7 -#define ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ 0x8 -#define ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ 0x9 -#define ADF_VF2PF_MSGTYPE_NOTIFY 0xa -#define ADF_VF2PF_MSGGENC_RESTARTING_COMPLETE 0x0 - -/* Block message types - * 0..15 - 32 byte message - * 16..23 - 64 byte message - * 24..27 - 128 byte message - * 2 - Get Capability Request message - */ -#define ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY 2 -#define ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ 0x3 - -/* VF->PF Compatible Version Request */ -#define ADF_VF2PF_COMPAT_VER_REQ_SHIFT 22 - -/* How long to wait for far side to acknowledge receipt */ -#define ADF_IOV_MSG_ACK_DELAY_US 5 -#define ADF_IOV_MSG_ACK_EXP_MAX_DELAY_US (5 * 1000) -#define ADF_IOV_MSG_ACK_DELAY_MS 5 -#define ADF_IOV_MSG_ACK_LIN_MAX_DELAY_US (2 * 1000 * 1000) -/* If CSR is busy, how long to delay before retrying */ -#define ADF_IOV_MSG_RETRY_DELAY 5 -#define ADF_IOV_MSG_MAX_RETRIES 10 -/* How long to wait for a response from the other side */ -#define ADF_IOV_MSG_RESP_TIMEOUT 100 -/* How often to retry when there is no response */ -#define ADF_IOV_MSG_RESP_RETRIES 5 - -#define ADF_IOV_RATELIMIT_INTERVAL 8 -#define ADF_IOV_RATELIMIT_BURST 130 - -/* CRC Calculation */ -#define ADF_CRC8_INIT_VALUE 0xFF -/* PF VF message byte shift */ -#define ADF_PFVF_DATA_SHIFT 8 -#define ADF_PFVF_DATA_MASK 0xFF -#endif /* ADF_IOV_MSG_H */ diff --git a/sys/dev/qat/include/adf_pfvf_vf_msg.h b/sys/dev/qat/include/adf_pfvf_vf_msg.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/adf_pfvf_vf_msg.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_VF_MSG_H +#define ADF_PFVF_VF_MSG_H + +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); + +#endif /* ADF_PFVF_VF_MSG_H */ diff --git a/sys/dev/qat/include/common/adf_accel_devices.h b/sys/dev/qat/include/common/adf_accel_devices.h --- a/sys/dev/qat/include/common/adf_accel_devices.h +++ b/sys/dev/qat/include/common/adf_accel_devices.h @@ -6,6 +6,7 @@ #include "qat_freebsd.h" #include "adf_cfg_common.h" +#include "adf_pfvf_msg.h" #define ADF_CFG_NUM_SERVICES 4 @@ -20,6 +21,7 @@ #define ADF_C4XXX_DEVICE_NAME "c4xxx" #define ADF_C4XXXVF_DEVICE_NAME "c4xxxvf" #define ADF_4XXX_DEVICE_NAME "4xxx" +#define ADF_4XXXVF_DEVICE_NAME "4xxxvf" #define ADF_DH895XCC_PCI_DEVICE_ID 0x435 #define ADF_DH895XCCIOV_PCI_DEVICE_ID 0x443 #define ADF_C62X_PCI_DEVICE_ID 0x37c8 @@ -33,13 +35,17 @@ #define ADF_C4XXX_PCI_DEVICE_ID 0x18a0 #define ADF_C4XXXIOV_PCI_DEVICE_ID 0x18a1 #define ADF_4XXX_PCI_DEVICE_ID 0x4940 +#define ADF_4XXXIOV_PCI_DEVICE_ID 0x4941 #define ADF_401XX_PCI_DEVICE_ID 0x4942 +#define ADF_401XXIOV_PCI_DEVICE_ID 0x4943 #define IS_QAT_GEN3(ID) ({ (ID == ADF_C4XXX_PCI_DEVICE_ID); }) static inline bool IS_QAT_GEN4(const unsigned int id) { - return (id == ADF_4XXX_PCI_DEVICE_ID || id == ADF_401XX_PCI_DEVICE_ID); + return (id == ADF_4XXX_PCI_DEVICE_ID || id == ADF_401XX_PCI_DEVICE_ID || + id == ADF_4XXXIOV_PCI_DEVICE_ID || + id == ADF_401XXIOV_PCI_DEVICE_ID); } #define IS_QAT_GEN3_OR_GEN4(ID) (IS_QAT_GEN3(ID) || IS_QAT_GEN4(ID)) @@ -85,7 +91,7 @@ (((ena_srv_mask) >> (ADF_SRV_TYPE_BIT_LEN * (srv))) & ADF_SRV_TYPE_MASK) #define GET_CSR_OPS(accel_dev) (&(accel_dev)->hw_device->csr_info.csr_ops) - +#define GET_PFVF_OPS(accel_dev) (&(accel_dev)->hw_device->csr_info.pfvf_ops) #define ADF_DEFAULT_RING_TO_SRV_MAP \ (CRYPTO | CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ NA << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ @@ -266,6 +272,9 @@ u32 bank, u32 ring, u32 value); + bus_addr_t (*read_csr_ring_base)(struct resource *csr_base_addr, + u32 bank, + u32 ring); void (*write_csr_ring_base)(struct resource *csr_base_addr, u32 bank, u32 ring, @@ -288,10 +297,36 @@ void (*write_csr_ring_srv_arb_en)(struct resource *csr_base_addr, u32 bank, u32 value); + u32 (*get_src_sel_mask)(void); + u32 (*get_int_col_ctl_enable_mask)(void); + u32 (*get_bank_irq_mask)(u32 irq_mask); +}; + +struct adf_cfg_device_data; +struct adf_accel_dev; +struct adf_etr_data; +struct adf_etr_ring_data; + +struct adf_pfvf_ops { + int (*enable_comms)(struct adf_accel_dev *accel_dev); + u32 (*get_pf2vf_offset)(u32 i); + u32 (*get_vf2pf_offset)(u32 i); + void (*enable_vf2pf_interrupts)(struct resource *pmisc_addr, + u32 vf_mask); + void (*disable_all_vf2pf_interrupts)(struct resource *pmisc_addr); + u32 (*disable_pending_vf2pf_interrupts)(struct resource *pmisc_addr); + 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, + u8 compat_ver); }; struct adf_hw_csr_info { struct adf_hw_csr_ops csr_ops; + struct adf_pfvf_ops pfvf_ops; u32 csr_addr_offset; u32 ring_bundle_size; u32 bank_int_flag_clear_mask; @@ -299,11 +334,6 @@ u32 arb_enable_mask; }; -struct adf_cfg_device_data; -struct adf_accel_dev; -struct adf_etr_data; -struct adf_etr_ring_data; - struct adf_hw_device_data { struct adf_hw_device_class *dev_class; uint32_t (*get_accel_mask)(struct adf_accel_dev *accel_dev); @@ -315,9 +345,6 @@ uint32_t (*get_num_accels)(struct adf_hw_device_data *self); void (*notify_and_wait_ethernet)(struct adf_accel_dev *accel_dev); bool (*get_eth_doorbell_msg)(struct adf_accel_dev *accel_dev); - uint32_t (*get_pf2vf_offset)(uint32_t i); - uint32_t (*get_vintmsk_offset)(uint32_t i); - u32 (*get_vintsou_offset)(void); void (*get_arb_info)(struct arb_info *arb_csrs_info); void (*get_admin_info)(struct admin_info *admin_csrs_info); void (*get_errsou_offset)(u32 *errsou3, u32 *errsou5); @@ -352,6 +379,8 @@ const uint32_t **cfg); int (*init_device)(struct adf_accel_dev *accel_dev); int (*get_heartbeat_status)(struct adf_accel_dev *accel_dev); + int (*int_timer_init)(struct adf_accel_dev *accel_dev); + void (*int_timer_exit)(struct adf_accel_dev *accel_dev); uint32_t (*get_ae_clock)(struct adf_hw_device_data *self); uint32_t (*get_hb_clock)(struct adf_hw_device_data *self); void (*disable_iov)(struct adf_accel_dev *accel_dev); @@ -360,8 +389,10 @@ void (*enable_ints)(struct adf_accel_dev *accel_dev); bool (*check_slice_hang)(struct adf_accel_dev *accel_dev); int (*set_ssm_wdtimer)(struct adf_accel_dev *accel_dev); - int (*enable_vf2pf_comms)(struct adf_accel_dev *accel_dev); - int (*disable_vf2pf_comms)(struct adf_accel_dev *accel_dev); + void (*enable_pf2vf_interrupt)(struct adf_accel_dev *accel_dev); + void (*disable_pf2vf_interrupt)(struct adf_accel_dev *accel_dev); + int (*interrupt_active_pf2vf)(struct adf_accel_dev *accel_dev); + int (*get_int_active_bundles)(struct adf_accel_dev *accel_dev); void (*reset_device)(struct adf_accel_dev *accel_dev); void (*reset_hw_units)(struct adf_accel_dev *accel_dev); int (*measure_clock)(struct adf_accel_dev *accel_dev); @@ -378,6 +409,11 @@ char *aeidstr); void (*remove_misc_error)(struct adf_accel_dev *accel_dev); int (*configure_accel_units)(struct adf_accel_dev *accel_dev); + int (*ring_pair_reset)(struct adf_accel_dev *accel_dev, + u32 bank_number); + void (*config_ring_irq)(struct adf_accel_dev *accel_dev, + u32 bank_number, + u16 ring_mask); uint32_t (*get_objs_num)(struct adf_accel_dev *accel_dev); const char *(*get_obj_name)(struct adf_accel_dev *accel_dev, enum adf_accel_unit_services services); @@ -411,7 +447,6 @@ uint8_t num_accel; uint8_t num_logical_accel; uint8_t num_engines; - uint8_t min_iov_compat_ver; int (*get_storage_enabled)(struct adf_accel_dev *accel_dev, uint32_t *storage_enabled); u8 query_storage_cap; @@ -419,6 +454,7 @@ u8 storage_enable; u32 extended_dc_capabilities; int (*config_device)(struct adf_accel_dev *accel_dev); + u32 asym_ae_active_thd_mask; u16 asym_rings_mask; int (*get_fw_image_type)(struct adf_accel_dev *accel_dev, enum adf_cfg_fw_image_type *fw_image_type); @@ -603,6 +639,15 @@ u8 mmp_version_patch; }; +struct adf_int_timer { + struct adf_accel_dev *accel_dev; + struct workqueue_struct *timer_irq_wq; + struct timer_list timer; + u32 timeout_val; + u32 int_cnt; + bool enabled; +}; + #define ADF_COMPAT_CHECKER_MAX 8 typedef int (*adf_iov_compat_checker_t)(struct adf_accel_dev *accel_dev, u8 vf_compat_ver); @@ -620,7 +665,9 @@ struct adf_cfg_device_data *cfg; struct adf_fw_loader_data *fw_loader; struct adf_admin_comms *admin; + struct adf_uio_control_accel *accel; struct adf_heartbeat *heartbeat; + struct adf_int_timer *int_timer; struct adf_fw_versions fw_versions; unsigned int autoreset_on_error; struct adf_fw_counters_data *fw_counters_data; @@ -648,17 +695,18 @@ int num_vfs; } pf; struct { + bool irq_enabled; struct resource *irq; void *cookie; - char *irq_name; struct task pf2vf_bh_tasklet; struct mutex vf2pf_lock; /* protect CSR access */ - int iov_msg_completion; - uint8_t compatible; - uint8_t pf_version; - u8 pf2vf_block_byte; - u8 pf2vf_block_resp_type; + struct completion msg_received; + struct pfvf_message + response; /* temp field holding pf2vf response */ + enum ring_reset_result rpreset_sts; + struct mutex rpreset_lock; /* protect rpreset_sts */ struct pfvf_stats pfvf_counters; + u8 pf_compat_ver; } vf; } u1; bool is_vf; diff --git a/sys/dev/qat/include/common/adf_cfg.h b/sys/dev/qat/include/common/adf_cfg.h --- a/sys/dev/qat/include/common/adf_cfg.h +++ b/sys/dev/qat/include/common/adf_cfg.h @@ -9,6 +9,8 @@ #include "adf_cfg_common.h" #include "adf_cfg_strings.h" +#define ADF_CFG_MAX_VAL 16 + struct adf_cfg_key_val { char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; @@ -29,6 +31,9 @@ struct list_head sec_list; struct sysctl_oid *debug; struct sx lock; + char cfg_services[ADF_CFG_MAX_VAL]; + char cfg_mode[ADF_CFG_MAX_VAL]; + u16 num_user_processes; }; struct adf_cfg_depot_list { diff --git a/sys/dev/qat/include/common/adf_cfg_common.h b/sys/dev/qat/include/common/adf_cfg_common.h --- a/sys/dev/qat/include/common/adf_cfg_common.h +++ b/sys/dev/qat/include/common/adf_cfg_common.h @@ -88,7 +88,10 @@ DEV_200XXVF, DEV_C4XXX, DEV_C4XXXVF, - DEV_4XXX + DEV_D15XX, + DEV_D15XXVF, + DEV_4XXX, + DEV_4XXXVF }; enum adf_cfg_fw_image_type { @@ -196,9 +199,23 @@ #define ADF_CFG_DEF_ASYM_MASK 0x03 #define ADF_CFG_MAX_SERVICES 4 +#define ADF_CTL_IOC_MAGIC 'a' +#define IOCTL_STATUS_ACCEL_DEV \ + _IOWR(ADF_CTL_IOC_MAGIC, 3, struct adf_dev_status_info) +#define IOCTL_RESERVE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 10, struct adf_user_reserve_ring) +#define IOCTL_RELEASE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 11, struct adf_user_reserve_ring) +#define IOCTL_ENABLE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 12, struct adf_user_reserve_ring) +#define IOCTL_DISABLE_RING \ + _IOWR(ADF_CTL_IOC_MAGIC, 13, struct adf_user_reserve_ring) +#define IOCTL_GET_NUM_DEVICES _IOR(ADF_CTL_IOC_MAGIC, 4, int32_t) #define ADF_CFG_HB_DEFAULT_VALUE 500 #define ADF_CFG_HB_COUNT_THRESHOLD 3 #define ADF_MIN_HB_TIMER_MS 100 +#define IOCTL_GET_CFG_VAL \ + _IOW(ADF_CTL_IOC_MAGIC, 5, struct adf_user_cfg_ctl_data) enum adf_device_heartbeat_status { DEV_HB_UNRESPONSIVE = 0, @@ -210,4 +227,6 @@ uint16_t device_id; enum adf_device_heartbeat_status status; }; +#define IOCTL_HEARTBEAT_ACCEL_DEV \ + _IOWR(ADF_CTL_IOC_MAGIC, 9, struct adf_dev_heartbeat_status_ctl) #endif diff --git a/sys/dev/qat/include/common/adf_cfg_strings.h b/sys/dev/qat/include/common/adf_cfg_strings.h --- a/sys/dev/qat/include/common/adf_cfg_strings.h +++ b/sys/dev/qat/include/common/adf_cfg_strings.h @@ -7,6 +7,7 @@ #define ADF_GENERAL_SEC "GENERAL" #define ADF_KERNEL_SEC "KERNEL" #define ADF_ACCEL_SEC "Accelerator" +#define ADF_SAL_SEC "SSL" #define ADF_NUM_CY "NumberCyInstances" #define ADF_NUM_DC "NumberDcInstances" #define ADF_RING_SYM_SIZE "NumConcurrentSymRequests" @@ -55,6 +56,11 @@ #define ADF_CFG_DC "dc" #define ADF_CFG_ASYM "asym" #define ADF_CFG_SYM "sym" +#define ADF_CFG_SYM_ASYM "sym;asym" +#define ADF_CFG_SYM_DC "sym;dc" +#define ADF_CFG_KERNEL_USER "ks;us" +#define ADF_CFG_KERNEL "ks" +#define ADF_CFG_USER "us" #define ADF_SERVICE_INLINE "inline" #define ADF_SERVICES_ENABLED "ServicesEnabled" #define ADF_SERVICES_SEPARATOR ";" diff --git a/sys/dev/qat/include/common/adf_cfg_sysctl.h b/sys/dev/qat/include/common/adf_cfg_sysctl.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_cfg_sysctl.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_CFG_SYSCTL_H_ +#define ADF_CFG_SYSCTL_H_ + +#include "adf_accel_devices.h" + +int adf_cfg_sysctl_add(struct adf_accel_dev *accel_dev); +void adf_cfg_sysctl_remove(struct adf_accel_dev *accel_dev); + +#endif /* ADF_CFG_SYSCTL_H_ */ diff --git a/sys/dev/qat/include/common/adf_common_drv.h b/sys/dev/qat/include/common/adf_common_drv.h --- a/sys/dev/qat/include/common/adf_common_drv.h +++ b/sys/dev/qat/include/common/adf_common_drv.h @@ -9,7 +9,10 @@ #include "icp_qat_fw_loader_handle.h" #include "icp_qat_hal.h" #include "adf_cfg_user.h" +#include "adf_uio.h" +#include "adf_uio_control.h" +#define QAT_UIO_IOC_MAGIC 'b' #define ADF_MAJOR_VERSION 0 #define ADF_MINOR_VERSION 6 #define ADF_BUILD_VERSION 0 @@ -17,6 +20,10 @@ __stringify(ADF_MAJOR_VERSION) "." __stringify( \ ADF_MINOR_VERSION) "." __stringify(ADF_BUILD_VERSION) +#define IOCTL_GET_BUNDLE_SIZE _IOR(QAT_UIO_IOC_MAGIC, 0, int32_t) +#define IOCTL_ALLOC_BUNDLE _IOW(QAT_UIO_IOC_MAGIC, 1, int) +#define IOCTL_GET_ACCEL_TYPE _IOR(QAT_UIO_IOC_MAGIC, 2, uint32_t) +#define IOCTL_ADD_MEM_FD _IOW(QAT_UIO_IOC_MAGIC, 3, int) #define ADF_STATUS_RESTARTING 0 #define ADF_STATUS_STARTING 1 #define ADF_STATUS_CONFIGURED 2 @@ -81,43 +88,7 @@ void adf_error_notifier(uintptr_t arg); int adf_init_fatal_error_wq(void); void adf_exit_fatal_error_wq(void); -int adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); -int adf_iov_notify(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr); -void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev); int adf_notify_fatal_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_uncorrectable_error(struct adf_accel_dev *accel_dev); -void adf_pf2vf_notify_heartbeat_error(struct adf_accel_dev *accel_dev); -typedef int (*adf_iov_block_provider)(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num); -int adf_iov_block_provider_register(u8 block_type, - const adf_iov_block_provider provider); -u8 adf_iov_is_block_provider_registered(u8 block_type); -int adf_iov_block_provider_unregister(u8 block_type, - const adf_iov_block_provider provider); -int adf_iov_block_get(struct adf_accel_dev *accel_dev, - u8 block_type, - u8 *block_version, - u8 *buffer, - u8 *length); -u8 adf_pfvf_crc(u8 start_crc, u8 *buf, u8 len); -int adf_iov_init_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm); -int adf_iov_shutdown_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm); -int adf_iov_register_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc); -int adf_iov_unregister_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc); -int adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_pf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev); -int adf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev); -void adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info); void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data); void adf_clean_vf_map(bool); int adf_sysctl_add_fw_versions(struct adf_accel_dev *accel_dev); @@ -125,19 +96,12 @@ int adf_ctl_dev_register(void); void adf_ctl_dev_unregister(void); -int adf_pf_vf_capabilities_init(struct adf_accel_dev *accel_dev); -int adf_pf_ext_dc_cap_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility); -int adf_pf_vf_ring_to_svc_init(struct adf_accel_dev *accel_dev); -int adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num); +int adf_register_ctl_device_driver(void); +void adf_unregister_ctl_device_driver(void); +int adf_processes_dev_register(void); +void adf_processes_dev_unregister(void); +void adf_state_init(void); +void adf_state_destroy(void); int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, struct adf_accel_dev *pf); void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev, @@ -212,6 +176,7 @@ unsigned int bank_nr, unsigned int mask); int adf_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); +void adf_update_uio_ring_arb(struct adf_uio_control_bundle *bundle); struct adf_accel_dev *adf_devmgr_get_dev_by_bdf(struct adf_pci_address *addr); struct adf_accel_dev *adf_devmgr_get_dev_by_pci_bus(u8 bus); int adf_get_vf_nr(struct adf_pci_address *vf_pci_addr, int *vf_nr); @@ -239,7 +204,7 @@ void adf_isr_resource_free(struct adf_accel_dev *accel_dev); int adf_vf_isr_resource_alloc(struct adf_accel_dev *accel_dev); void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev); - +int adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev); int qat_hal_init(struct adf_accel_dev *accel_dev); void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle); int qat_hal_start(struct icp_qat_fw_loader_handle *handle); @@ -334,13 +299,13 @@ void qat_hal_get_scs_neigh_ae(unsigned char ae, unsigned char *ae_neigh); int qat_uclo_set_cfg_ae_mask(struct icp_qat_fw_loader_handle *handle, unsigned int cfg_ae_mask); -void adf_enable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); -void adf_disable_pf2vf_interrupts(struct adf_accel_dev *accel_dev); int adf_init_vf_wq(void); void adf_exit_vf_wq(void); -void adf_flush_vf_wq(void); -int adf_vf2pf_init(struct adf_accel_dev *accel_dev); -void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev); +void adf_flush_vf_wq(struct adf_accel_dev *accel_dev); +int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev); +int adf_pf2vf_handle_pf_rp_reset(struct adf_accel_dev *accel_dev, + struct pfvf_message msg); +bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev); static inline int adf_sriov_configure(device_t *pdev, int numvfs) { diff --git a/sys/dev/qat/include/common/adf_gen2_hw_data.h b/sys/dev/qat/include/common/adf_gen2_hw_data.h --- a/sys/dev/qat/include/common/adf_gen2_hw_data.h +++ b/sys/dev/qat/include/common/adf_gen2_hw_data.h @@ -23,6 +23,7 @@ #define ADF_RING_CSR_INT_COL_CTL 0x180 #define ADF_RING_CSR_INT_FLAG_AND_COL 0x184 #define ADF_RING_CSR_INT_COL_CTL_ENABLE 0x80000000 +#define ADF_RING_CSR_ADDR_OFFSET 0x0 #define ADF_RING_BUNDLE_SIZE 0x1000 #define ADF_GEN2_RX_RINGS_OFFSET 8 #define ADF_GEN2_TX_RINGS_MASK 0xFF @@ -45,6 +46,29 @@ (ADF_RING_BUNDLE_SIZE * (bank)) + \ ADF_RING_CSR_RING_CONFIG + ((ring) << 2), \ value) + +static inline uint64_t +read_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_LBASE + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_UBASE + (ring << 2)); + + addr = (uint64_t)l_base & 0x00000000FFFFFFFFULL; + addr |= (uint64_t)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define READ_CSR_RING_BASE(csr_base_addr, bank, ring) \ + read_base(csr_base_addr, bank, ring) + #define WRITE_CSR_RING_BASE(csr_base_addr, bank, ring, value) \ do { \ u32 l_base = 0, u_base = 0; \ diff --git a/sys/dev/qat/include/common/adf_gen4_hw_data.h b/sys/dev/qat/include/common/adf_gen4_hw_data.h --- a/sys/dev/qat/include/common/adf_gen4_hw_data.h +++ b/sys/dev/qat/include/common/adf_gen4_hw_data.h @@ -23,6 +23,22 @@ #define ADF_RING_CSR_ADDR_OFFSET 0x100000 #define ADF_RING_BUNDLE_SIZE 0x2000 +/* 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) + +#define ADF_WQM_CSR_RPRESETCTL_SHIFT 0 +#define ADF_WQM_CSR_RPRESETCTL_DRAIN_SHIFT 2 +#define ADF_WQM_CSR_RPRESETCTL_MASK (BIT(3) - 1) +#define ADF_WQM_CSR_RPRESETCTL(bank) (0x6000 + ((bank) << 3)) +#define ADF_WQM_CSR_RPRESETSTS_SHIFT 0 +#define ADF_WQM_CSR_RPRESETSTS_MASK (BIT(0)) +#define ADF_WQM_CSR_RPRESETSTS(bank) (ADF_WQM_CSR_RPRESETCTL(bank) + 4) + #define BUILD_RING_BASE_ADDR(addr, size) \ ((((addr) >> 6) & (GENMASK_ULL(63, 0) << (size))) << 6) #define READ_CSR_RING_HEAD(csr_base_addr, bank, ring) \ @@ -63,6 +79,30 @@ u_base); \ } while (0) +static inline u64 +read_base_gen4(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + u32 l_base, u_base; + u64 addr; + + l_base = ADF_CSR_RD(csr_base_addr, + ADF_RING_CSR_ADDR_OFFSET + + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_LBASE + (ring << 2)); + u_base = ADF_CSR_RD(csr_base_addr, + ADF_RING_CSR_ADDR_OFFSET + + (ADF_RING_BUNDLE_SIZE * bank) + + ADF_RING_CSR_RING_UBASE + (ring << 2)); + + addr = (u64)l_base & 0x00000000FFFFFFFFULL; + addr |= (u64)u_base << 32 & 0xFFFFFFFF00000000ULL; + + return addr; +} + +#define READ_CSR_RING_BASE(csr_base_addr, bank, ring) \ + read_base_gen4((csr_base_addr), (bank), (ring)) + #define WRITE_CSR_RING_HEAD(csr_base_addr, bank, ring, value) \ ADF_CSR_WR((csr_base_addr), \ ADF_RING_CSR_ADDR_OFFSET + ADF_RING_BUNDLE_SIZE * (bank) + \ @@ -129,4 +169,5 @@ int adf_gen4_set_ssm_wdtimer(struct adf_accel_dev *accel_dev); void adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info); +int adf_gen4_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number); #endif diff --git a/sys/dev/qat/include/common/adf_pfvf_msg.h b/sys/dev/qat/include/common/adf_pfvf_msg.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_msg.h @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_MSG_H +#define ADF_PFVF_MSG_H + +/* + * 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 while each VF can access only the one + * register associated with that particular VF. + * + * The register functionally is split into two parts: + * The bottom half is for PF->VF messages. In particular when the first + * bit of this register (bit 0) gets set an interrupt will be triggered + * in the respective VF. + * The top half is for VF->PF messages. In particular when the first bit + * of this half of register (bit 16) gets set an interrupt will be triggered + * in the PF. + * + * The remaining bits within this register are available to encode messages. + * and implement a collision control mechanism to prevent concurrent use of + * the PF2VF register by both the PF and VF. + * + * 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 + * _______________________________________________ + * | | | | | | | | | | | | | | | | | + * +-----------------------------------------------+ + * \___________________________/ \_________/ ^ ^ + * ^ ^ | | + * | | | VF2PF Int + * | | Message Origin + * | Message Type + * Message-specific Data/Reserved + * + * 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + * _______________________________________________ + * | | | | | | | | | | | | | | | | | + * +-----------------------------------------------+ + * \___________________________/ \_________/ ^ ^ + * ^ ^ | | + * | | | PF2VF Int + * | | Message Origin + * | Message Type + * Message-specific Data/Reserved + * + * Message Origin (Should always be 1) + * A legacy out-of-tree QAT driver allowed for a set of messages not supported + * by this driver; these had a Msg Origin of 0 and are ignored by this driver. + * + * When a PF or VF attempts to send a message in the lower or upper 16 bits, + * 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 */ +#define ADF_PFVF_INT BIT(0) +#define ADF_PFVF_MSGORIGIN_SYSTEM BIT(1) + +/* 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 { + 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 */ +enum vf2pf_msgtype { + ADF_VF2PF_MSGTYPE_INIT = 0x03, + 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, + /* 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. */ +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, + /* 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 = 0x04, +}; + +/* PF->VF Version Response */ +#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, + ADF_PF2VF_VF_INCOMPATIBLE = 0x02, + ADF_PF2VF_VF_COMPAT_UNKNOWN = 0x03, +}; + +enum ring_reset_result { + RPRESET_SUCCESS = 0x00, + RPRESET_NOT_SUPPORTED = 0x01, + RPRESET_INVAL_BANK = 0x02, + RPRESET_TIMEOUT = 0x03, +}; + +#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) + +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 + */ +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 \ + (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 + +/* 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; + +/* 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/sys/dev/qat/include/common/adf_pfvf_utils.h b/sys/dev/qat/include/common/adf_pfvf_utils.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_utils.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_UTILS_H +#define ADF_PFVF_UTILS_H + +#include +#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) + +u8 adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len); + +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); + +static inline struct resource * +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 /* ADF_PFVF_UTILS_H */ diff --git a/sys/dev/qat/include/common/adf_pfvf_vf_proto.h b/sys/dev/qat/include/common/adf_pfvf_vf_proto.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_pfvf_vf_proto.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_PFVF_VF_PROTO_H +#define ADF_PFVF_VF_PROTO_H + +#include +#include "adf_accel_devices.h" + +#define ADF_PFVF_MSG_COLLISION_DETECT_DELAY 10 +#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) + +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); + +#endif /* ADF_PFVF_VF_PROTO_H */ diff --git a/sys/dev/qat/include/common/adf_uio.h b/sys/dev/qat/include/common/adf_uio.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_UIO_H +#define ADF_UIO_H +#include "adf_accel_devices.h" + +struct qat_uio_bundle_dev { + u8 hardware_bundle_number; + struct adf_uio_control_bundle *bundle; + struct adf_uio_control_accel *accel; +}; + +int adf_uio_register(struct adf_accel_dev *accel_dev); +void adf_uio_remove(struct adf_accel_dev *accel_dev); + +#endif /* end of include guard: ADF_UIO_H */ diff --git a/sys/dev/qat/include/common/adf_uio_cleanup.h b/sys/dev/qat/include/common/adf_uio_cleanup.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio_cleanup.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_UIO_CLEANUP_H +#define ADF_UIO_CLEANUP_H + +void adf_uio_do_cleanup_orphan(int bank, + struct adf_uio_control_accel *accel); + + +#endif diff --git a/sys/dev/qat/include/common/adf_uio_control.h b/sys/dev/qat/include/common/adf_uio_control.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/include/common/adf_uio_control.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2023 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef QAT_UIO_CONTROL_H +#define QAT_UIO_CONTROL_H +#include + +struct adf_uio_instance_rings { + unsigned int user_pid; + u16 ring_mask; + struct list_head list; +}; + +struct adf_uio_control_bundle { + uint8_t hardware_bundle_number; + bool used; + struct list_head list; + struct mutex list_lock; /* protects list struct */ + struct mutex lock; /* protects rings_used and csr_addr */ + u16 rings_used; + u32 rings_enabled; + void *csr_addr; + struct qat_uio_bundle_dev uio_priv; + vm_object_t obj; +}; + +struct adf_uio_control_accel { + struct adf_accel_dev *accel_dev; + struct cdev *cdev; + struct mtx lock; + struct adf_bar *bar; + unsigned int nb_bundles; + unsigned int num_ker_bundles; + unsigned int total_used_bundles; + unsigned int num_handles; + struct cv cleanup_ok; + /* bundle[] must be last to allow dynamic size allocation. */ + struct adf_uio_control_bundle bundle[0]; + +}; + + +#endif /* end of include guard: QAT_UIO_CONTROL_H */ diff --git a/sys/dev/qat/qat/qat_ocf.c b/sys/dev/qat/qat/qat_ocf.c --- a/sys/dev/qat/qat/qat_ocf.c +++ b/sys/dev/qat/qat/qat_ocf.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Cryptodev headers */ #include @@ -44,6 +45,8 @@ /* QAT OCF internal structures */ struct qat_ocf_softc { device_t sc_dev; + struct sysctl_oid *rc; + uint32_t enabled; int32_t cryptodev_id; struct qat_ocf_instance cyInstHandles[QAT_OCF_MAX_INSTANCES]; int32_t numCyInstances; @@ -560,17 +563,22 @@ /* Create cryptodev session */ qat_softc = device_get_softc(dev); - qat_instance = - &qat_softc->cyInstHandles[cpu_id % qat_softc->numCyInstances]; - qat_dsession = crypto_get_driver_session(cses); - if (NULL == qat_dsession) { - device_printf(dev, "Unable to create new session\n"); - return (EINVAL); - } + if (qat_softc->numCyInstances > 0) { + qat_instance = + &qat_softc + ->cyInstHandles[cpu_id % qat_softc->numCyInstances]; + qat_dsession = crypto_get_driver_session(cses); + if (NULL == qat_dsession) { + device_printf(dev, "Unable to create new session\n"); + return (EINVAL); + } - /* Add only instance at this point remaining operations moved to - * lazy session init */ - qat_dsession->qatInstance = qat_instance; + /* Add only instance at this point remaining operations moved to + * lazy session init */ + qat_dsession->qatInstance = qat_instance; + } else { + return ENXIO; + } return 0; } @@ -988,6 +996,10 @@ if (NULL == baseAddr) continue; listTemp = baseAddr->sym_services; + if (NULL == listTemp) { + listTemp = baseAddr->crypto_services; + } + while (NULL != listTemp) { cyInstHandle = SalList_getObject(listTemp); status = cpaCyInstanceGetInfo2(cyInstHandle, &info); @@ -1023,8 +1035,6 @@ &numInstances); if (CPA_STATUS_SUCCESS != status) return status; - if (0 == numInstances) - return CPA_STATUS_RESOURCE; for (i = 0; i < numInstances; i++) { struct qat_ocf_instance *qat_ocf_instance; @@ -1041,11 +1051,18 @@ continue; } + qat_ocf_instance = &qat_softc->cyInstHandles[startedInstances]; + qat_ocf_instance->cyInstHandle = cyInstHandle; + mtx_init(&qat_ocf_instance->cyInstMtx, + "Instance MTX", + NULL, + MTX_DEF); + status = cpaCySetAddressTranslation(cyInstHandle, qatVirtToPhys); if (CPA_STATUS_SUCCESS != status) { device_printf(qat_softc->sc_dev, - "unable to add virt to phys callback"); + "unable to add virt to phys callback\n"); goto fail; } @@ -1056,13 +1073,6 @@ goto fail; } - qat_ocf_instance = &qat_softc->cyInstHandles[startedInstances]; - qat_ocf_instance->cyInstHandle = cyInstHandle; - mtx_init(&qat_ocf_instance->cyInstMtx, - "Instance MTX", - NULL, - MTX_DEF); - /* Initialize cookie pool */ status = qat_ocf_cookie_pool_init(qat_ocf_instance, dev); if (CPA_STATUS_SUCCESS != status) { @@ -1085,19 +1095,16 @@ startedInstances++; continue; fail: + mtx_destroy(&qat_ocf_instance->cyInstMtx); + /* Stop instance */ status = cpaCyStopInstance(cyInstHandle); if (CPA_STATUS_SUCCESS != status) device_printf(qat_softc->sc_dev, "unable to stop the instance\n"); - continue; } qat_softc->numCyInstances = startedInstances; - /* Success if at least one instance has been set */ - if (!qat_softc->numCyInstances) - return CPA_STATUS_FAIL; - return CPA_STATUS_SUCCESS; } @@ -1114,73 +1121,146 @@ status = cpaCyStopInstance(qat_instance->cyInstHandle); if (CPA_STATUS_SUCCESS != status) { pr_err("QAT: stopping instance id: %d failed\n", i); - mtx_unlock(&qat_instance->cyInstMtx); continue; } qat_ocf_cookie_pool_deinit(qat_instance); mtx_destroy(&qat_instance->cyInstMtx); } + qat_softc->numCyInstances = 0; + return status; } static int -qat_ocf_attach(device_t dev) +qat_ocf_deinit(struct qat_ocf_softc *qat_softc) { - int status; - struct qat_ocf_softc *qat_softc; - int32_t cryptodev_id; + int status = 0; + CpaStatus cpaStatus; - qat_softc = device_get_softc(dev); - qat_softc->sc_dev = dev; + if (qat_softc->cryptodev_id >= 0) { + crypto_unregister_all(qat_softc->cryptodev_id); + qat_softc->cryptodev_id = -1; + } - cryptodev_id = crypto_get_driverid(dev, - sizeof(struct qat_ocf_dsession), - CRYPTOCAP_F_HARDWARE); - if (cryptodev_id < 0) { - device_printf(dev, "cannot initialize!\n"); - goto fail; + /* Stop QAT instances */ + cpaStatus = qat_ocf_stop_instances(qat_softc); + if (CPA_STATUS_SUCCESS != cpaStatus) { + device_printf(qat_softc->sc_dev, "unable to stop instances\n"); + status = EIO; } - qat_softc->cryptodev_id = cryptodev_id; + + return status; +} + +static int +qat_ocf_init(struct qat_ocf_softc *qat_softc) +{ + int32_t cryptodev_id; /* Starting instances for OCF */ - status = qat_ocf_start_instances(qat_softc, dev); - if (status) { - device_printf(dev, "no QAT IRQ instances available\n"); + if (qat_ocf_start_instances(qat_softc, qat_softc->sc_dev)) { + device_printf(qat_softc->sc_dev, + "unable to get QAT IRQ instances\n"); goto fail; } + /* Register only if instances available */ + if (qat_softc->numCyInstances) { + cryptodev_id = + crypto_get_driverid(qat_softc->sc_dev, + sizeof(struct qat_ocf_dsession), + CRYPTOCAP_F_HARDWARE); + if (cryptodev_id < 0) { + device_printf(qat_softc->sc_dev, + "cannot initialize!\n"); + goto fail; + } + qat_softc->cryptodev_id = cryptodev_id; + } + return 0; fail: - qat_ocf_detach(dev); + qat_ocf_deinit(qat_softc); - return (ENXIO); + return ENXIO; } -static int -qat_ocf_detach(device_t dev) +static int qat_ocf_sysctl_handle(SYSCTL_HANDLER_ARGS) { struct qat_ocf_softc *qat_softc = NULL; - CpaStatus cpaStatus; - int status = 0; + int ret = 0; + device_t dev = arg1; + u_int enabled; qat_softc = device_get_softc(dev); + enabled = qat_softc->enabled; - if (qat_softc->cryptodev_id >= 0) { - status = crypto_unregister_all(qat_softc->cryptodev_id); - if (status) - device_printf(dev, - "unable to unregister QAt backend\n"); + ret = sysctl_handle_int(oidp, &enabled, 0, req); + if (ret || !req->newptr) + return (ret); + + if (qat_softc->enabled != enabled) { + if (enabled) { + ret = qat_ocf_init(qat_softc); + + } else { + ret = qat_ocf_deinit(qat_softc); + } + + if (!ret) + qat_softc->enabled = enabled; } - /* Stop QAT instances */ - cpaStatus = qat_ocf_stop_instances(qat_softc); - if (CPA_STATUS_SUCCESS != cpaStatus) { - device_printf(dev, "unable to stop instances\n"); - status = EIO; + return ret; +} + +static int +qat_ocf_attach(device_t dev) +{ + int status; + struct qat_ocf_softc *qat_softc; + + qat_softc = device_get_softc(dev); + qat_softc->sc_dev = dev; + qat_softc->cryptodev_id = -1; + qat_softc->enabled = 1; + + qat_softc->rc = + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, + "enable", + CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, + dev, + 0, + qat_ocf_sysctl_handle, + "I", + "QAT OCF support enablement"); + + if (!qat_softc->rc) + return ENOMEM; + if (qat_softc->enabled) { + status = qat_ocf_init(qat_softc); + if (status) { + device_printf(dev, "qat_ocf init failed\n"); + goto fail; + } } - return status; + return 0; +fail: + qat_ocf_deinit(qat_softc); + + return (ENXIO); +} + +static int +qat_ocf_detach(device_t dev) +{ + struct qat_ocf_softc *qat_softc = device_get_softc(dev); + + return qat_ocf_deinit(qat_softc); } static device_method_t qat_ocf_methods[] = diff --git a/sys/dev/qat/qat_api/common/compression/dc_buffers.c b/sys/dev/qat/qat_api/common/compression/dc_buffers.c --- a/sys/dev/qat/qat_api/common/compression/dc_buffers.c +++ b/sys/dev/qat/qat_api/common/compression/dc_buffers.c @@ -172,3 +172,19 @@ return dcDeflateBoundGen2(huffType, inputSize, outputSize); } } + +CpaStatus +cpaDcLZ4CompressBound(const CpaInstanceHandle dcInstance, + Cpa32U inputSize, + Cpa32U *outputSize) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcLZ4SCompressBound(const CpaInstanceHandle dcInstance, + Cpa32U inputSize, + Cpa32U *outputSize) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_chain.c b/sys/dev/qat/qat_api/common/compression/dc_chain.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_chain.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_chain.c + * + * @ingroup Dc_Chaining + * + * @description + * Implementation of the chaining session operations. + * + *****************************************************************************/ + +/* + ******************************************************************************* + * Include public/global header files + ******************************************************************************* + */ +#include "cpa.h" + +#include "icp_qat_fw.h" +#include "icp_qat_fw_comp.h" +#include "icp_qat_hw.h" + +/* + ******************************************************************************* + * Include private header files + ******************************************************************************* + */ +#include "sal_types_compression.h" +#include "cpa_dc_chain.h" +#include "lac_session.h" +#include "dc_session.h" +#include "dc_datapath.h" +#include "dc_stats.h" +#include "lac_mem_pools.h" +#include "lac_log.h" +#include "sal_types_compression.h" +#include "lac_buffer_desc.h" +#include "sal_service_state.h" +#include "sal_qat_cmn_msg.h" +#include "lac_sym_qat_hash_defs_lookup.h" +#include "sal_string_parse.h" +#include "lac_sym.h" +#include "lac_session.h" +#include "lac_sym_qat.h" +#include "lac_sym_hash.h" +#include "lac_sym_alg_chain.h" +#include "lac_sym_auth_enc.h" + +CpaStatus +cpaDcChainGetSessionSize(CpaInstanceHandle dcInstance, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + Cpa32U *pSessionSize) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainInitSession(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + CpaDcCallbackFn callbackFn) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainRemoveSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainResetSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcChainPerformOp(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcChainOperations operation, + Cpa8U numOpDatas, + CpaDcChainOpData *pChainOpData, + CpaDcChainRqResults *pResults, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_datapath.c b/sys/dev/qat/qat_api/common/compression/dc_datapath.c --- a/sys/dev/qat/qat_api/common/compression/dc_datapath.c +++ b/sys/dev/qat/qat_api/common/compression/dc_datapath.c @@ -331,6 +331,12 @@ (ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_SET == ICP_QAT_FW_COMN_RESP_CMP_END_OF_LAST_BLK_FLAG_GET( opStatus)); + } else { + /* Check if returned data is a stored block + * in compression direction + */ + pResults->dataUncompressed = + ICP_QAT_FW_COMN_HDR_ST_BLK_FLAG_GET(hdrFlags); } /* Save the checksum for the next request */ diff --git a/sys/dev/qat/qat_api/common/compression/dc_dp.c b/sys/dev/qat/qat_api/common/compression/dc_dp.c --- a/sys/dev/qat/qat_api/common/compression/dc_dp.c +++ b/sys/dev/qat/qat_api/common/compression/dc_dp.c @@ -273,6 +273,14 @@ return cpaDcRemoveSession(dcInstance, pSessionHandle); } +CpaStatus +cpaDcDpUpdateSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pUpdateSessionData) +{ + return CPA_STATUS_UNSUPPORTED; +} + CpaStatus cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance, const CpaDcDpCallbackFn pNewCb) diff --git a/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c b/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_ns_datapath.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_ns_datapath.c + * + * @defgroup Dc_DataCompression DC Data Compression + * + * @ingroup Dc_DataCompression + * + * @description + * Implementation of the Data Compression datapath operations. + * + *****************************************************************************/ + +/* +******************************************************************************* +* Include public/global header files +******************************************************************************* +*/ +#include "cpa.h" +#include "cpa_dc.h" +#include "cpa_dc_dp.h" + +/* +******************************************************************************* +* Include private header files +******************************************************************************* +*/ +#include "dc_session.h" +#include "dc_datapath.h" +#include "sal_statistics.h" +#include "lac_common.h" +#include "lac_mem.h" +#include "lac_mem_pools.h" +#include "lac_log.h" +#include "sal_types_compression.h" +#include "dc_stats.h" +#include "lac_buffer_desc.h" +#include "lac_sal.h" +#include "lac_sync.h" +#include "sal_service_state.h" +#include "sal_qat_cmn_msg.h" +#include "dc_error_counter.h" + +CpaStatus +cpaDcNsDecompressData(CpaInstanceHandle dcInstance, + CpaDcNsSetupData *pSetupData, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcOpData *pOpData, + CpaDcRqResults *pResults, + CpaDcCallbackFn callbackFn, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcNsCompressData(CpaInstanceHandle dcInstance, + CpaDcNsSetupData *pSetupData, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcOpData *pOpData, + CpaDcRqResults *pResults, + CpaDcCallbackFn callbackFn, + void *callbackTag) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c b/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_api/common/compression/dc_ns_header_footer.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file dc_ns_header_footer.c + * + * @ingroup Dc_DataCompression + * + * @description + * Implementation of the Data Compression header and footer operations. + * + *****************************************************************************/ + +/* + ******************************************************************************* + * Include public/global header files + ******************************************************************************* + */ +#include "cpa.h" +#include "cpa_dc.h" + +/* + ******************************************************************************* + * Include private header files + ******************************************************************************* + */ +#include "dc_session.h" + +CpaStatus +cpaDcNsGenerateHeader(CpaDcNsSetupData *pSetupData, + CpaFlatBuffer *pDestBuff, + Cpa32U *count) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcNsGenerateFooter(CpaDcNsSetupData *pSetupData, + Cpa64U totalLength, + CpaFlatBuffer *pDestBuff, + CpaDcRqResults *pResults) +{ + return CPA_STATUS_UNSUPPORTED; +} diff --git a/sys/dev/qat/qat_api/common/compression/dc_session.c b/sys/dev/qat/qat_api/common/compression/dc_session.c --- a/sys/dev/qat/qat_api/common/compression/dc_session.c +++ b/sys/dev/qat/qat_api/common/compression/dc_session.c @@ -65,14 +65,13 @@ cpaDcQueryCapabilities(dcInstance, &instanceCapabilities); if ((pSessionData->compLevel < CPA_DC_L1) || - (pSessionData->compLevel > CPA_DC_L9)) { + (pSessionData->compLevel > CPA_DC_L12)) { QAT_UTILS_LOG("Invalid compLevel value\n"); return CPA_STATUS_INVALID_PARAM; } if ((pSessionData->autoSelectBestHuffmanTree < CPA_DC_ASB_DISABLED) || - (pSessionData->autoSelectBestHuffmanTree > - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS)) { + (pSessionData->autoSelectBestHuffmanTree > CPA_DC_ASB_ENABLED)) { QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n"); return CPA_STATUS_INVALID_PARAM; } @@ -869,6 +868,13 @@ disableType0EnhancedAutoSelectBest = ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST; break; + case CPA_DC_ASB_ENABLED: + if (pService->comp_device_data.asbEnableSupport == CPA_FALSE) { + autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST; + enhancedAutoSelectBest = + ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST; + } + break; default: break; } @@ -1088,6 +1094,21 @@ return status; } +CpaStatus +cpaDcResetXXHashState(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaDcUpdateSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pUpdateSessionData) +{ + return CPA_STATUS_UNSUPPORTED; +} + CpaStatus cpaDcRemoveSession(const CpaInstanceHandle dcInstance, CpaDcSessionHandle pSessionHandle) diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_session.h b/sys/dev/qat/qat_api/common/compression/include/dc_session.h --- a/sys/dev/qat/qat_api/common/compression/include/dc_session.h +++ b/sys/dev/qat/qat_api/common/compression/include/dc_session.h @@ -208,8 +208,6 @@ /**< Session direction */ CpaDcSessionState sessState; /**< Session state */ - Cpa32U deflateWindowSize; - /**< Window size */ CpaDcCompLvl compLevel; /**< Compression level */ CpaDcCallbackFn pCompressionCb; diff --git a/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c b/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c --- a/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c +++ b/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c @@ -2449,20 +2449,12 @@ { CpaStatus status = CPA_STATUS_FAIL; CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in); - CpaCyCapabilitiesInfo cyCapInfo; LAC_CHECK_INSTANCE_HANDLE(instanceHandle); SAL_CHECK_INSTANCE_TYPE(instanceHandle, (SAL_SERVICE_TYPE_CRYPTO | SAL_SERVICE_TYPE_CRYPTO_SYM)); - SAL_RUNNING_CHECK(instanceHandle); - SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo); - - if (IS_HKDF_UNSUPPORTED(cmdId, cyCapInfo.hkdfSupported)) { - LAC_LOG_ERROR("The device does not support HKDF"); - return CPA_STATUS_UNSUPPORTED; - } status = LacSymKey_CheckParamSslTls(pKeyGenOpData, hashAlgorithm, diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c --- a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c +++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c @@ -1147,8 +1147,8 @@ * build the message templates * create two content descriptors in the case we can support using SHRAM * constants and an optimised content descriptor. we have to do this in - *case of partials. 64 byte content descriptor is used in the SHRAM case - *for AES-128-HMAC-SHA1 + * case of partials. 64 byte content descriptor is used in the SHRAM + * case for AES-128-HMAC-SHA1 *-----------------------------------------------------------------------*/ if (CPA_STATUS_SUCCESS == status) { pSessionDesc->cipherSliceType = diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_compression.c b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c --- a/sys/dev/qat/qat_api/common/ctrl/sal_compression.c +++ b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c @@ -126,7 +126,7 @@ sal_compression_service_t *pCompService) { int level = 0; - + pCompService->comp_device_data.asbEnableSupport = CPA_FALSE; pCompService->comp_device_data.uniqueCompressionLevels[0] = CPA_FALSE; switch (device->deviceType) { @@ -154,6 +154,23 @@ pCompService->comp_device_data.windowSizeMask = (1 << DC_8K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); pCompService->comp_device_data.cnvnrSupported = CPA_FALSE; + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; case DEVICE_C3XXX: case DEVICE_C3XXXVF: @@ -181,6 +198,24 @@ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED; pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; + + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; case DEVICE_C62X: case DEVICE_C62XVF: @@ -209,7 +244,7 @@ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED; pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; - for (level = CPA_DC_L1; level <= CPA_DC_L9; level++) { + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { switch (level) { case CPA_DC_L1: case CPA_DC_L2: @@ -254,8 +289,28 @@ pCompService->comp_device_data.windowSizeMask = (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); pCompService->comp_device_data.cnvnrSupported = CPA_TRUE; + + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { + switch (level) { + case CPA_DC_L1: + case CPA_DC_L2: + case CPA_DC_L3: + case CPA_DC_L4: + case CPA_DC_L5: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_TRUE; + break; + default: + pCompService->comp_device_data + .uniqueCompressionLevels[level] = CPA_FALSE; + break; + } + } + pCompService->comp_device_data.numCompressionLevels = + DC_NUM_COMPRESSION_LEVELS; break; - case DEVICE_GEN4: + case DEVICE_4XXX: + case DEVICE_4XXXVF: pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE; pCompService->numInterBuffs = 0; pCompService->comp_device_data.minOutputBuffSize = @@ -277,7 +332,7 @@ pCompService->comp_device_data.windowSizeMask = (1 << DC_4K_WINDOW_SIZE | 1 << DC_8K_WINDOW_SIZE | 1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE); - for (level = CPA_DC_L1; level <= CPA_DC_L9; level++) { + for (level = CPA_DC_L1; level <= CPA_DC_L12; level++) { switch (level) { case CPA_DC_L1: case CPA_DC_L6: diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c b/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c --- a/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c +++ b/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c @@ -478,7 +478,8 @@ pInst->gen = GEN3; break; - case DEVICE_GEN4: + case DEVICE_4XXX: + case DEVICE_4XXXVF: pInst->gen = GEN4; break; @@ -719,6 +720,28 @@ return status; } +static CpaStatus +SalCtrl_ServiceError(icp_accel_dev_t *device, sal_list_t *services) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + + /* Calling error handling functions */ + sal_list_t *curr_element = services; + sal_service_t *service = NULL; + while (NULL != curr_element) { + service = (sal_service_t *)SalList_getObject(curr_element); + if (service->notification_cb) { + service->notification_cb( + service, + service->cb_tag, + CPA_INSTANCE_EVENT_FATAL_ERROR); + } + curr_element = SalList_next(curr_element); + } + + return status; +} + /* * @ingroup SalCtrl * @description @@ -1164,6 +1187,78 @@ return ret_status; } +/************************************************************************** + * @ingroup SalCtrl + * @description + * This function calls the error function on all the service instances. + * + * @context + * This function is called from the SalCtrl_ServiceEventHandler function. + * + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] device An icp_accel_dev_t* type + * @param[in] enabled_services Enabled services by user + * + **************************************************************************/ +static CpaStatus +SalCtrl_ServiceEventError(icp_accel_dev_t *device, Cpa32U enabled_services) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + CpaStatus ret_status = CPA_STATUS_SUCCESS; + sal_t *service_container = device->pSalHandle; + + if (service_container == NULL) { + QAT_UTILS_LOG("Private data is NULL\n"); + return CPA_STATUS_FATAL; + } + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO_ASYM)) { + status = SalCtrl_ServiceError(device, + service_container->asym_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO_SYM)) { + status = SalCtrl_ServiceError(device, + service_container->sym_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_CRYPTO)) { + status = + SalCtrl_ServiceError(device, + service_container->crypto_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + if (SalCtrl_IsServiceEnabled(enabled_services, + SAL_SERVICE_TYPE_COMPRESSION)) { + status = SalCtrl_ServiceError( + device, service_container->compression_services); + if (CPA_STATUS_SUCCESS != status) { + ret_status = status; + } + } + + return ret_status; +} + /************************************************************************** * @ingroup SalCtrl * @description @@ -1307,6 +1402,10 @@ } break; } + case ICP_ADF_EVENT_ERROR: { + status = SalCtrl_ServiceEventError(device, enabled_services); + break; + } default: status = CPA_STATUS_SUCCESS; break; diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c b/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_api/common/ctrl/sal_get_instances.c @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +/** + ***************************************************************************** + * @file sal_get_instances.c + * + * @defgroup SalCtrl Service Access Layer Controller + * + * @ingroup SalCtrl + * + * @description + * This file contains the main function to get SAL instances. + * + *****************************************************************************/ + +/* +******************************************************************************* +* Include public/global header files +******************************************************************************* +*/ + +/* QAT-API includes */ +#include "cpa.h" +#include "cpa_cy_common.h" +#include "cpa_cy_im.h" +#include "cpa_dc.h" + +/* ADF includes */ +#include "icp_accel_devices.h" +#include "icp_adf_accel_mgr.h" + +/* SAL includes */ +#include "lac_mem.h" +#include "lac_list.h" +#include "lac_sal_types.h" + +/** + ****************************************************************************** + * @ingroup SalCtrl + * @description + * Get either sym or asym instance number + *****************************************************************************/ +static CpaStatus +Lac_GetSingleCyNumInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + icp_accel_dev_t **pAdfInsts = NULL; + icp_accel_dev_t *dev_addr = NULL; + sal_t *base_addr = NULL; + sal_list_t *list_temp = NULL; + Cpa16U num_accel_dev = 0; + Cpa16U num_inst = 0; + Cpa16U i = 0; + Cpa32U accel_capability = 0; + char *service = NULL; + + LAC_CHECK_NULL_PARAM(pNumInstances); + *pNumInstances = 0; + + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + service = "asym"; + break; + + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + service = "sym"; + break; + + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } + + /* Get the number of accel_dev in the system */ + status = icp_amgr_getNumInstances(&num_accel_dev); + LAC_CHECK_STATUS(status); + + /* Allocate memory to store addr of accel_devs */ + pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), + M_QAT, + M_WAITOK | M_ZERO); + if (NULL == pAdfInsts) { + QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); + return CPA_STATUS_RESOURCE; + } + + num_accel_dev = 0; + status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, + pAdfInsts, + &num_accel_dev); + if (CPA_STATUS_SUCCESS != status) { + QAT_UTILS_LOG("No support for service %s\n", service); + free(pAdfInsts, M_QAT); + return status; + } + + for (i = 0; i < num_accel_dev; i++) { + dev_addr = pAdfInsts[i]; + if (NULL == dev_addr || NULL == dev_addr->pSalHandle) { + continue; + } + base_addr = dev_addr->pSalHandle; + + if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) { + list_temp = base_addr->asym_services; + } else { + list_temp = base_addr->sym_services; + } + while (NULL != list_temp) { + num_inst++; + list_temp = SalList_next(list_temp); + } + } + + *pNumInstances = num_inst; + free(pAdfInsts, M_QAT); + + return status; +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + * @description + * Get either sym or asym instance + *****************************************************************************/ +static CpaStatus +Lac_GetSingleCyInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *pInstances) +{ + CpaStatus status = CPA_STATUS_SUCCESS; + icp_accel_dev_t **pAdfInsts = NULL; + icp_accel_dev_t *dev_addr = NULL; + sal_t *base_addr = NULL; + sal_list_t *list_temp = NULL; + Cpa16U num_accel_dev = 0; + Cpa16U num_allocated_instances = 0; + Cpa16U index = 0; + Cpa16U i = 0; + Cpa32U accel_capability = 0; + char *service = NULL; + + LAC_CHECK_NULL_PARAM(pInstances); + if (0 == numInstances) { + QAT_UTILS_LOG("NumInstances is 0\n"); + return CPA_STATUS_INVALID_PARAM; + } + + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + service = "asym"; + break; + + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + accel_capability = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + service = "sym"; + break; + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } + + /* Get the number of instances */ + status = cpaGetNumInstances(accelerationServiceType, + &num_allocated_instances); + if (CPA_STATUS_SUCCESS != status) { + return status; + } + + if (numInstances > num_allocated_instances) { + QAT_UTILS_LOG("Only %d instances available\n", + num_allocated_instances); + return CPA_STATUS_RESOURCE; + } + + /* Get the number of accel devices in the system */ + status = icp_amgr_getNumInstances(&num_accel_dev); + LAC_CHECK_STATUS(status); + + /* Allocate memory to store addr of accel_devs */ + pAdfInsts = malloc(num_accel_dev * sizeof(icp_accel_dev_t *), + M_QAT, + M_WAITOK | M_ZERO); + if (NULL == pAdfInsts) { + QAT_UTILS_LOG("Failed to allocate dev instance memory\n"); + return CPA_STATUS_RESOURCE; + } + + num_accel_dev = 0; + status = icp_amgr_getAllAccelDevByCapabilities(accel_capability, + pAdfInsts, + &num_accel_dev); + if (CPA_STATUS_SUCCESS != status) { + QAT_UTILS_LOG("No support for service %s\n", service); + free(pAdfInsts, M_QAT); + return status; + } + + for (i = 0; i < num_accel_dev; i++) { + dev_addr = pAdfInsts[i]; + /* Note dev_addr cannot be NULL here as numInstances = 0 + * is not valid and if dev_addr = NULL then index = 0 (which + * is less than numInstances and status is set to _RESOURCE + * above) + */ + base_addr = dev_addr->pSalHandle; + if (NULL == base_addr) { + continue; + } + + if (CPA_ACC_SVC_TYPE_CRYPTO_ASYM == accelerationServiceType) + list_temp = base_addr->asym_services; + else + list_temp = base_addr->sym_services; + while (NULL != list_temp) { + if (index > (numInstances - 1)) + break; + + pInstances[index] = SalList_getObject(list_temp); + list_temp = SalList_next(list_temp); + index++; + } + } + free(pAdfInsts, M_QAT); + + return status; +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + *****************************************************************************/ +CpaStatus +cpaGetNumInstances(const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances) +{ + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + return Lac_GetSingleCyNumInstances(accelerationServiceType, + pNumInstances); + case CPA_ACC_SVC_TYPE_CRYPTO: + return cpaCyGetNumInstances(pNumInstances); + case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: + return cpaDcGetNumInstances(pNumInstances); + + default: + QAT_UTILS_LOG("Invalid service type\n"); + *pNumInstances = 0; + return CPA_STATUS_INVALID_PARAM; + } +} + +/** + ****************************************************************************** + * @ingroup SalCtrl + *****************************************************************************/ +CpaStatus +cpaGetInstances(const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *pInstances) +{ + switch (accelerationServiceType) { + case CPA_ACC_SVC_TYPE_CRYPTO_ASYM: + case CPA_ACC_SVC_TYPE_CRYPTO_SYM: + return Lac_GetSingleCyInstances(accelerationServiceType, + numInstances, + pInstances); + + case CPA_ACC_SVC_TYPE_CRYPTO: + return cpaCyGetInstances(numInstances, pInstances); + case CPA_ACC_SVC_TYPE_DATA_COMPRESSION: + return cpaDcGetInstances(numInstances, pInstances); + + default: + QAT_UTILS_LOG("Invalid service type\n"); + return CPA_STATUS_INVALID_PARAM; + } +} diff --git a/sys/dev/qat/qat_api/common/include/sal_types_compression.h b/sys/dev/qat/qat_api/common/include/sal_types_compression.h --- a/sys/dev/qat/qat_api/common/include/sal_types_compression.h +++ b/sys/dev/qat/qat_api/common/include/sal_types_compression.h @@ -23,7 +23,7 @@ #include "icp_adf_transport.h" #define DC_NUM_RX_RINGS (1) -#define DC_NUM_COMPRESSION_LEVELS (CPA_DC_L9) +#define DC_NUM_COMPRESSION_LEVELS (CPA_DC_L12) /** ***************************************************************************** @@ -73,6 +73,9 @@ /* Flag to indicate CompressAndVerifyAndRecover feature support */ CpaBoolean cnvnrSupported; + + /* When set, implies device supports ASB_ENABLE */ + CpaBoolean asbEnableSupport; } sal_compression_device_data_t; /** diff --git a/sys/dev/qat/qat_api/common/stubs/lac_stubs.c b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c --- a/sys/dev/qat/qat_api/common/stubs/lac_stubs.c +++ b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c @@ -29,6 +29,9 @@ #include "cpa_cy_rsa.h" #include "cpa_cy_ln.h" #include "cpa_dc.h" +#include "cpa_dc_chain.h" +#include "cpa_cy_ecsm2.h" +#include "cpa_cy_kpt.h" #include "icp_accel_devices.h" #include "icp_adf_init.h" #include "icp_adf_transport.h" @@ -283,6 +286,194 @@ return CPA_STATUS_UNSUPPORTED; } +CpaStatus +cpaCyEcGenericPointVerify(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointVerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcGenericPointVerifyOpData *pOpData, + CpaBoolean *pVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcGenericPointMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcGenericPointMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pOutX, + CpaFlatBuffer *pOutY) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2PointMultiply( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointMultiplyCbFunc pEcsm2PointMulCb, + void *pCallbackTag, + const CpaCyEcsm2PointMultiplyOpData *pEcsm2PointMulOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2GeneratorMultiply( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointMultiplyCbFunc pEcsm2GenMulCb, + void *pCallbackTag, + const CpaCyEcsm2GeneratorMultiplyOpData *pEcsm2GenMulOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2PointVerify( + const CpaInstanceHandle instanceHandle_in, + const CpaCyEcPointVerifyCbFunc pEcsm2PointVeirfyCb, + void *pCallbackTag, + const CpaCyEcsm2PointVerifyOpData *pEcsm2PointVerifyOpData, + CpaBoolean *pPointVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Sign(const CpaInstanceHandle instanceHandle_in, + const CpaCyEcsm2SignCbFunc pEcsm2SignCb, + void *pCallbackTag, + const CpaCyEcsm2SignOpData *pEcsm2SignOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Verify(const CpaInstanceHandle instanceHandle_in, + const CpaCyEcsm2VerifyCbFunc pEcsm2VerifyCb, + void *pCallbackTag, + const CpaCyEcsm2VerifyOpData *pEcsm2VerifyOpData, + CpaBoolean *pVerifyStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Encrypt(const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2EncCb, + void *pCallbackTag, + const CpaCyEcsm2EncryptOpData *pEcsm2EncOpData, + CpaCyEcsm2EncryptOutputData *pEcsm2EncOutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2Decrypt(const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2DecCb, + void *pCallbackTag, + const CpaCyEcsm2DecryptOpData *pEcsm2DecOpData, + CpaCyEcsm2DecryptOutputData *pEcsm2DecOutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2KeyExPhase1( + const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2KeyExPhase1Cb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase1OpData *pEcsm2KeyExPhase1OpData, + CpaCyEcsm2KeyExOutputData *pEcsm2KeyExPhase1OutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2KeyExPhase2( + const CpaInstanceHandle instanceHandle_in, + const CpaCyGenFlatBufCbFunc pEcsm2KeyExPhase2Cb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase2OpData *pEcsm2KeyExPhase2OpData, + CpaCyEcsm2KeyExOutputData *pEcsm2KeyExPhase2OutputData) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyEcsm2QueryStats64(const CpaInstanceHandle instanceHandle_in, + CpaCyEcsm2Stats64 *pEcsm2Stats) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptEcdsaSignRS(const CpaInstanceHandle instanceHandle, + const CpaCyEcdsaSignRSCbFunc pCb, + void *pCallbackTag, + const CpaCyKptEcdsaSignRSOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS, + CpaCyKptUnwrapContext *pKptUnwrapContext) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptRsaDecrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pRsaDecryptCb, + void *pCallbackTag, + const CpaCyKptRsaDecryptOpData *pDecryptOpData, + CpaFlatBuffer *pOutputData, + CpaCyKptUnwrapContext *pKptUnwrapContext) + +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptQueryIssuingKeys(const CpaInstanceHandle instanceHandle_in, + CpaFlatBuffer *pPublicX509IssueCert, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptQueryDeviceCredentials(const CpaInstanceHandle instanceHandle, + CpaCyKptValidationKey *pDevCredential, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptLoadKey(CpaInstanceHandle instanceHandle, + CpaCyKptLoadKey *pSWK, + CpaCyKptHandle *keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + +CpaStatus +cpaCyKptDeleteKey(CpaInstanceHandle instanceHandle, + CpaCyKptHandle keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus) +{ + return CPA_STATUS_UNSUPPORTED; +} + /* Prime */ CpaStatus cpaCyPrimeTest(const CpaInstanceHandle instanceHandle, diff --git a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h --- a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h +++ b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ + +/* --- (Automatically generated (build v. 2.7), do not modify manually) --- */ + + /** * @file icp_qat_fw_mmp.h * @defgroup icp_qat_fw_mmp ICP QAT FW MMP Processing Definitions @@ -12,3162 +16,3887 @@ * accelerate crypto assymetric applications */ + #ifndef __ICP_QAT_FW_MMP__ #define __ICP_QAT_FW_MMP__ + /************************************************************************** * Include local header files ************************************************************************** */ + #include "icp_qat_fw.h" + /************************************************************************** * Local constants ************************************************************************** */ -#define ICP_QAT_FW_PKE_INPUT_COUNT_MAX 7 +#define ICP_QAT_FW_PKE_INPUT_COUNT_MAX 7 /**< @ingroup icp_qat_fw_pke * Maximum number of input paramaters in all PKE request */ -#define ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX 5 +#define ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX 5 /**< @ingroup icp_qat_fw_pke * Maximum number of output paramaters in all PKE request */ +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p384_input_s +{ + uint64_t xp; /**< xP = affine coordinate X of point P (6 qwords)*/ + uint64_t yp; /**< yP = affine coordinate Y of point P (6 qwords)*/ + uint64_t k; /**< k = scalar (6 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p384_input_s +{ + uint64_t k; /**< k = scalar (6 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s +{ + uint64_t k; /**< k = random value, > 0 and < n (order of G for P384) + (6 qwords)*/ + uint64_t e; /**< (6 qwords)*/ + uint64_t d; /**< (6 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p256_input_s +{ + uint64_t xp; /**< xP = affine coordinate X of point P (4 qwords)*/ + uint64_t yp; /**< yP = affine coordinate Y of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p256_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s +{ + uint64_t k; /**< k = random value, > 0 and < n (order of G for P256) + (4 qwords)*/ + uint64_t e; /**< (4 qwords)*/ + uint64_t d; /**< (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC SM2 point multiply [k]G , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_ECSM2_GENERATOR_MULTIPLICATION. + */ +typedef struct icp_qat_fw_mmp_ecsm2_generator_multiplication_input_s +{ + uint64_t k; /**< k = multiplicand (4 qwords)*/ +} icp_qat_fw_mmp_ecsm2_generator_multiplication_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Initialisation sequence , * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_INIT. */ -typedef struct icp_qat_fw_mmp_init_input_s { - uint64_t z; /**< zeroed quadword (1 qwords)*/ +typedef struct icp_qat_fw_mmp_init_input_s +{ + uint64_t z; /**< zeroed quadword (1 qwords)*/ } icp_qat_fw_mmp_init_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_768. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_768. */ -typedef struct icp_qat_fw_mmp_dh_g2_768_input_s { - uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ - uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_768_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ + uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_dh_g2_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for 768-bit - * numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_768. + * Input parameter list for Diffie-Hellman Modular exponentiation for 768-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_768. */ -typedef struct icp_qat_fw_mmp_dh_768_input_s { - uint64_t g; /**< base ≥ 0 and < 2^768 (12 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ - uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_768_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^768 (12 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^768 (12 qwords)*/ + uint64_t m; /**< modulus ≥ 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_dh_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_1024. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_1024. */ -typedef struct icp_qat_fw_mmp_dh_g2_1024_input_s { - uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1024_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_dh_g2_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_1024. + * Input parameter list for Diffie-Hellman Modular exponentiation for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_1024. */ -typedef struct icp_qat_fw_mmp_dh_1024_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1024_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_dh_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_1536. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_1536. */ -typedef struct icp_qat_fw_mmp_dh_g2_1536_input_s { - uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1536_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_dh_g2_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_1536. + * Input parameter list for Diffie-Hellman Modular exponentiation for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_1536. */ -typedef struct icp_qat_fw_mmp_dh_1536_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1536_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus ≥ 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_dh_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_2048. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_2048. */ -typedef struct icp_qat_fw_mmp_dh_g2_2048_input_s { - uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_2048_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_dh_g2_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_2048. + * Input parameter list for Diffie-Hellman Modular exponentiation for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_2048. */ -typedef struct icp_qat_fw_mmp_dh_2048_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_2048_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus ≥ 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_dh_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_3072. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_3072. */ -typedef struct icp_qat_fw_mmp_dh_g2_3072_input_s { - uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_3072_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_dh_g2_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_3072. + * Input parameter list for Diffie-Hellman Modular exponentiation for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_3072. */ -typedef struct icp_qat_fw_mmp_dh_3072_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_3072_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus ≥ 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_dh_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_G2_4096. + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_G2_4096. */ -typedef struct icp_qat_fw_mmp_dh_g2_4096_input_s { - uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_4096_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_dh_g2_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Diffie-Hellman Modular exponentiation for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DH_4096. + * Input parameter list for Diffie-Hellman Modular exponentiation for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DH_4096. */ -typedef struct icp_qat_fw_mmp_dh_4096_input_s { - uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_dh_4096_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus ≥ 2^4095 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_dh_4096_input_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers , to be used when icp_qat_fw_pke_request_s::functionalityId + * is #PKE_DH_G2_8192. + */ +typedef struct icp_qat_fw_mmp_dh_g2_8192_input_s +{ + uint64_t e; /**< exponent > 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus ≥ 2^8191 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_dh_g2_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Diffie-Hellman Modular exponentiation for + * 8192-bit numbers , to be used when icp_qat_fw_pke_request_s::functionalityId + * is #PKE_DH_8192. + */ +typedef struct icp_qat_fw_mmp_dh_8192_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t e; /**< exponent > 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus ≥ 2^8191 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_dh_8192_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_512. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_512_input_s { - uint64_t - p; /**< RSA parameter, prime,  2 < p < 2^256 (4 qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2 < q < 2^256 (4 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_512. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_512_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^256 (4 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_512. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_512_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_512. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_512_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_512. */ -typedef struct icp_qat_fw_mmp_rsa_ep_512_input_s { - uint64_t m; /**< message representative, < n (8 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (8 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^256 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_512_input_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (8 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^256 (8 qwords)*/ } icp_qat_fw_mmp_rsa_ep_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 512 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_512_input_s { - uint64_t c; /**< cipher text representative, < n (8 qwords)*/ - uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^256 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_512_input_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ + uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^256 (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_512. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_512_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (4 qwords)*/ - uint64_t dq; /**< RSA private key 0 < dq < q-1 (4 qwords)*/ - uint64_t qinv; /**< RSA private key 0 < qInv < p (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_512. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_512_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^255 < p < 2^256 (4 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^255 < q < 2^256 (4 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (4 qwords)*/ + uint64_t dq; /**< RSA private key 0 < dq < q-1 (4 qwords)*/ + uint64_t qinv; /**< RSA private key 0 < qInv < p (4 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_1024. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1024_input_s { - uint64_t - p; /**< RSA parameter, prime,  2 < p < 2^512 (8 qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2 < q < 2^512 (8 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_1024_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^512 (8 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_1024. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1024_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1024_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_1024. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1024_input_s { - uint64_t m; /**< message representative, < n (16 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (16 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1024_input_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (16 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1024_input_s { - uint64_t c; /**< cipher text representative, < n (16 qwords)*/ - uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1024_input_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ + uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_1024. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1024_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (8 qwords)*/ - uint64_t dq; /**< RSA private key 0 < dq < q-1 (8 qwords)*/ - uint64_t qinv; /**< RSA private key 0 < qInv < p (8 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1024_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^511 < p < 2^512 (8 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^511 < q < 2^512 (8 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (8 qwords)*/ + uint64_t dq; /**< RSA private key 0 < dq < q-1 (8 qwords)*/ + uint64_t qinv; /**< RSA private key 0 < qInv < p (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1536 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1536_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^768 (12 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^768 (12 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_1536_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^768 (12 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1536 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1536_input_s { - uint64_t - p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^767 < q < 2^768 (12 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1536_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^767 < q < 2^768 (12 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (24 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1536 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_1536. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_1536. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1536_input_s { - uint64_t m; /**< message representative, < n (24 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ (p*q)-1 (24 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1536_input_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ (p*q)-1 (24 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1536 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_1536. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_1536. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1536_input_s { - uint64_t c; /**< cipher text representative, < n (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1536_input_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 1536 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1536_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ - uint64_t - p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t - q; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 - qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (12 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (12 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (12 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_1536_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^767 < p < 2^768 (12 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (12 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (12 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (12 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_2048_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1024 (16 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1024 (16 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_2048_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1024 (16 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_2048_input_s { - uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 - (16 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 - (16 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_2048_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 (16 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (32 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_2048. */ -typedef struct icp_qat_fw_mmp_rsa_ep_2048_input_s { - uint64_t m; /**< message representative, < n (32 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (32 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_2048_input_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (32 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_rsa_ep_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_2048. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_2048_input_s { - uint64_t c; /**< cipher text representative, < n (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_2048_input_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 2048 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_2048_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 - (16 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 - (16 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (16 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (16 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (16 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_2048_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^1023 < p < 2^1024 (16 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1023 < q < 2^1024 (16 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (16 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (16 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 3072 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_3072_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1536 (24 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1536 (24 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_3072_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^1536 (24 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 3072 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_3072_input_s { - uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 - (24 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 - (24 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_3072_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 (24 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (48 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 3072 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_3072. */ -typedef struct icp_qat_fw_mmp_rsa_ep_3072_input_s { - uint64_t m; /**< message representative, < n (48 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (48 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_3072_input_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (48 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_rsa_ep_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 3072 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_3072. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_3072_input_s { - uint64_t c; /**< cipher text representative, < n (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ - uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_3072_input_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ + uint64_t n; /**< RSA key > 0 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 3072 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_3072_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 - (24 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 - (24 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (24 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (24 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (24 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_3072_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^1535 < p < 2^1536 (24 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^1535 < q < 2^1536 (24 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (24 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (24 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (24 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 key generation first form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP1_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp1_4096_input_s { - uint64_t p; /**< RSA parameter, prime,  2 < p < 2^2048 (32 - qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2 < q < 2^2048 (32 - qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP1_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp1_4096_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2 < q < 2^2048 (32 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 key generation second form , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_KP2_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_4096_input_s { - uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 - (32 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 - (32 qwords)*/ - uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1, -  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_KP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_4096_input_s +{ + uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 (32 qwords)*/ + uint64_t e; /**< RSA public key, must be odd, ≥ 3 and ≤ (p*q)-1,  with GCD(e, p-1, q-1) = 1 (64 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 Encryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_EP_4096. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_EP_4096. */ -typedef struct icp_qat_fw_mmp_rsa_ep_4096_input_s { - uint64_t m; /**< message representative, < n (64 qwords)*/ - uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (64 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_4096_input_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (64 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_rsa_ep_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 Decryption , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP1_4096. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP1_4096. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_4096_input_s { - uint64_t c; /**< cipher text representative, < n (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ - uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_4096_input_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for RSA 4096 Decryption with CRT , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_RSA_DP2_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_dp2_4096_input_s { - uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ - uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 - (32 qwords)*/ - uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 - (32 qwords)*/ - uint64_t dp; /**< RSA private key, 0 < dp < p-1 (32 qwords)*/ - uint64_t dq; /**< RSA private key, 0 < dq < q-1 (32 qwords)*/ - uint64_t qinv; /**< RSA private key, 0 < qInv < p (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_RSA_DP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_4096_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^2047 < p < 2^2048 (32 qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^2047 < q < 2^2048 (32 qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (32 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (32 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (32 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_4096_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for GCD primality test for 192-bit numbers , + * Input parameter list for RSA 8192 Encryption , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_RSA_EP_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_8192_input_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ + uint64_t e; /**< RSA public key, ≥ 3 and ≤ n-1 (128 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 8192 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_192. + * #PKE_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_8192_input_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ + uint64_t d; /**< RSA private key (128 qwords)*/ + uint64_t n; /**< RSA key, > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for RSA 8192 Decryption with CRT , + * to be used when icp_qat_fw_pke_request_s::functionalityId is + * #PKE_RSA_DP2_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_8192_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (128 qwords)*/ + uint64_t p; /**< RSA parameter, prime,  2^4095 < p < 2^4096 (64 + qwords)*/ + uint64_t q; /**< RSA parameter, prime,  2^4095 < q < 2^4096 (64 + qwords)*/ + uint64_t dp; /**< RSA private key, 0 < dp < p-1 (64 qwords)*/ + uint64_t dq; /**< RSA private key, 0 < dq < q-1 (64 qwords)*/ + uint64_t qinv; /**< RSA private key, 0 < qInv < p (64 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_8192_input_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for GCD primality test for 192-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_192. */ -typedef struct icp_qat_fw_mmp_gcd_pt_192_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^192 (3 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_192_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^192 (3 qwords)*/ } icp_qat_fw_mmp_gcd_pt_192_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 256-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_256. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_256. */ -typedef struct icp_qat_fw_mmp_gcd_pt_256_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^256 (4 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_256_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^256 (4 qwords)*/ } icp_qat_fw_mmp_gcd_pt_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 384-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_384. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_384. */ -typedef struct icp_qat_fw_mmp_gcd_pt_384_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^384 (6 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_384_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^384 (6 qwords)*/ } icp_qat_fw_mmp_gcd_pt_384_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_512. */ -typedef struct icp_qat_fw_mmp_gcd_pt_512_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_512_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_gcd_pt_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_768. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_768. */ -typedef struct icp_qat_fw_mmp_gcd_pt_768_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_768_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_gcd_pt_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_1024. */ -typedef struct icp_qat_fw_mmp_gcd_pt_1024_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_1024_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_gcd_pt_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_1536. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_1536. */ -typedef struct icp_qat_fw_mmp_gcd_pt_1536_input_s { - uint64_t m; /**< (24 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_1536_input_s +{ + uint64_t m; /**< (24 qwords)*/ } icp_qat_fw_mmp_gcd_pt_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_2048. */ -typedef struct icp_qat_fw_mmp_gcd_pt_2048_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_2048_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_gcd_pt_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_3072. */ -typedef struct icp_qat_fw_mmp_gcd_pt_3072_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_3072_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_gcd_pt_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for GCD primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_GCD_PT_4096. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_GCD_PT_4096. */ -typedef struct icp_qat_fw_mmp_gcd_pt_4096_input_s { - uint64_t m; /**< prime candidate > 1 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_gcd_pt_4096_input_s +{ + uint64_t m; /**< prime candidate > 1 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_gcd_pt_4096_input_t; -/** + + +/** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_160. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_160. */ -typedef struct icp_qat_fw_mmp_fermat_pt_160_input_s { - uint64_t m; /**< prime candidate, 2^159 < m < 2^160 (3 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_160_input_s +{ + uint64_t m; /**< prime candidate, 2^159 < m < 2^160 (3 qwords)*/ } icp_qat_fw_mmp_fermat_pt_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_512. */ -typedef struct icp_qat_fw_mmp_fermat_pt_512_input_s { - uint64_t m; /**< prime candidate, 2^511 < m < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_512_input_s +{ + uint64_t m; /**< prime candidate, 2^511 < m < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_fermat_pt_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for <e; 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_L512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_L512. */ -typedef struct icp_qat_fw_mmp_fermat_pt_l512_input_s { - uint64_t m; /**< prime candidate, 5 < m < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_l512_input_s +{ + uint64_t m; /**< prime candidate, 5 < m < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_fermat_pt_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_768. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_768. */ -typedef struct icp_qat_fw_mmp_fermat_pt_768_input_s { - uint64_t m; /**< prime candidate, 2^767 < m < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_768_input_s +{ + uint64_t m; /**< prime candidate, 2^767 < m < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_fermat_pt_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_1024. */ -typedef struct icp_qat_fw_mmp_fermat_pt_1024_input_s { - uint64_t - m; /**< prime candidate, 2^1023 < m < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_1024_input_s +{ + uint64_t m; /**< prime candidate, 2^1023 < m < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_fermat_pt_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_1536. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_1536. */ -typedef struct icp_qat_fw_mmp_fermat_pt_1536_input_s { - uint64_t - m; /**< prime candidate, 2^1535 < m < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_1536_input_s +{ + uint64_t m; /**< prime candidate, 2^1535 < m < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_fermat_pt_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_2048. */ -typedef struct icp_qat_fw_mmp_fermat_pt_2048_input_s { - uint64_t - m; /**< prime candidate, 2^2047 < m < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_2048_input_s +{ + uint64_t m; /**< prime candidate, 2^2047 < m < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_fermat_pt_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_3072. */ -typedef struct icp_qat_fw_mmp_fermat_pt_3072_input_s { - uint64_t - m; /**< prime candidate, 2^3071 < m < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_3072_input_s +{ + uint64_t m; /**< prime candidate, 2^3071 < m < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_fermat_pt_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Fermat primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_FERMAT_PT_4096. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_FERMAT_PT_4096. */ -typedef struct icp_qat_fw_mmp_fermat_pt_4096_input_s { - uint64_t - m; /**< prime candidate, 2^4095 < m < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_fermat_pt_4096_input_s +{ + uint64_t m; /**< prime candidate, 2^4095 < m < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_fermat_pt_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Miller-Rabin primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_160. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_160. */ -typedef struct icp_qat_fw_mmp_mr_pt_160_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (3 qwords)*/ - uint64_t m; /**< prime candidate > 2^159 and < 2^160 (3 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_160_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (3 qwords)*/ + uint64_t m; /**< prime candidate > 2^159 and < 2^160 (3 qwords)*/ } icp_qat_fw_mmp_mr_pt_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Miller-Rabin primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_512. */ -typedef struct icp_qat_fw_mmp_mr_pt_512_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ - uint64_t m; /**< prime candidate > 2^511 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_512_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ + uint64_t m; /**< prime candidate > 2^511 and < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_mr_pt_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Miller-Rabin primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_768. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_768. */ -typedef struct icp_qat_fw_mmp_mr_pt_768_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (12 qwords)*/ - uint64_t m; /**< prime candidate > 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_768_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (12 qwords)*/ + uint64_t m; /**< prime candidate > 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_mr_pt_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Miller-Rabin primality test for 1024-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_1024. + * Input parameter list for Miller-Rabin primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_1024. */ -typedef struct icp_qat_fw_mmp_mr_pt_1024_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (16 qwords)*/ - uint64_t - m; /**< prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_1024_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (16 qwords)*/ + uint64_t m; /**< prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_mr_pt_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Miller-Rabin primality test for 1536-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_1536. + * Input parameter list for Miller-Rabin primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_1536. */ -typedef struct icp_qat_fw_mmp_mr_pt_1536_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (24 qwords)*/ - uint64_t - m; /**< prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_1536_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (24 qwords)*/ + uint64_t m; /**< prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_mr_pt_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Miller-Rabin primality test for 2048-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_2048. + * Input parameter list for Miller-Rabin primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_2048. */ -typedef struct icp_qat_fw_mmp_mr_pt_2048_input_s { - uint64_t x; /**< randomness > 1 and <m-1 (32 qwords)*/ - uint64_t - m; /**< prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_2048_input_s +{ + uint64_t x; /**< randomness > 1 and <m-1 (32 qwords)*/ + uint64_t m; /**< prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_mr_pt_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Miller-Rabin primality test for 3072-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_3072. + * Input parameter list for Miller-Rabin primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_3072. */ -typedef struct icp_qat_fw_mmp_mr_pt_3072_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (48 qwords)*/ - uint64_t - m; /**< prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_3072_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (48 qwords)*/ + uint64_t m; /**< prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_mr_pt_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Miller-Rabin primality test for 4096-bit numbers - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_4096. + * Input parameter list for Miller-Rabin primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_4096. */ -typedef struct icp_qat_fw_mmp_mr_pt_4096_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (64 qwords)*/ - uint64_t - m; /**< prime candidate > 2^4095 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_4096_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (64 qwords)*/ + uint64_t m; /**< prime candidate > 2^4095 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_mr_pt_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Miller-Rabin primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_MR_PT_L512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_MR_PT_L512. */ -typedef struct icp_qat_fw_mmp_mr_pt_l512_input_s { - uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ - uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_mr_pt_l512_input_s +{ + uint64_t x; /**< randomness > 1 and < m-1 (8 qwords)*/ + uint64_t m; /**< prime candidate > 1 and < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_mr_pt_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_160. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_160. */ -typedef struct icp_qat_fw_mmp_lucas_pt_160_input_s { - uint64_t - m; /**< odd prime candidate > 2^159 and < 2^160 (3 qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_160_input_s +{ + uint64_t m; /**< odd prime candidate > 2^159 and < 2^160 (3 qwords)*/ } icp_qat_fw_mmp_lucas_pt_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_512. */ -typedef struct icp_qat_fw_mmp_lucas_pt_512_input_s { - uint64_t - m; /**< odd prime candidate > 2^511 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_512_input_s +{ + uint64_t m; /**< odd prime candidate > 2^511 and < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_lucas_pt_512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_768. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_768. */ -typedef struct icp_qat_fw_mmp_lucas_pt_768_input_s { - uint64_t - m; /**< odd prime candidate > 2^767 and < 2^768 (12 qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_768_input_s +{ + uint64_t m; /**< odd prime candidate > 2^767 and < 2^768 (12 qwords)*/ } icp_qat_fw_mmp_lucas_pt_768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_1024. */ -typedef struct icp_qat_fw_mmp_lucas_pt_1024_input_s { - uint64_t m; /**< odd prime candidate > 2^1023 and < 2^1024 (16 - qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_1024_input_s +{ + uint64_t m; /**< odd prime candidate > 2^1023 and < 2^1024 (16 qwords)*/ } icp_qat_fw_mmp_lucas_pt_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_1536. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_1536. */ -typedef struct icp_qat_fw_mmp_lucas_pt_1536_input_s { - uint64_t m; /**< odd prime candidate > 2^1535 and < 2^1536 (24 - qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_1536_input_s +{ + uint64_t m; /**< odd prime candidate > 2^1535 and < 2^1536 (24 qwords)*/ } icp_qat_fw_mmp_lucas_pt_1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_2048. */ -typedef struct icp_qat_fw_mmp_lucas_pt_2048_input_s { - uint64_t m; /**< odd prime candidate > 2^2047 and < 2^2048 (32 - qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_2048_input_s +{ + uint64_t m; /**< odd prime candidate > 2^2047 and < 2^2048 (32 qwords)*/ } icp_qat_fw_mmp_lucas_pt_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_3072. */ -typedef struct icp_qat_fw_mmp_lucas_pt_3072_input_s { - uint64_t m; /**< odd prime candidate > 2^3071 and < 2^3072 (48 - qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_3072_input_s +{ + uint64_t m; /**< odd prime candidate > 2^3071 and < 2^3072 (48 qwords)*/ } icp_qat_fw_mmp_lucas_pt_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_4096. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_4096. */ -typedef struct icp_qat_fw_mmp_lucas_pt_4096_input_s { - uint64_t m; /**< odd prime candidate > 2^4096 and < 2^4096 (64 - qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_4096_input_s +{ + uint64_t m; /**< odd prime candidate > 2^4096 and < 2^4096 (64 qwords)*/ } icp_qat_fw_mmp_lucas_pt_4096_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Lucas primality test for L512-bit numbers , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_LUCAS_PT_L512. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_LUCAS_PT_L512. */ -typedef struct icp_qat_fw_mmp_lucas_pt_l512_input_s { - uint64_t m; /**< odd prime candidate > 5 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_mmp_lucas_pt_l512_input_s +{ + uint64_t m; /**< odd prime candidate > 5 and < 2^512 (8 qwords)*/ } icp_qat_fw_mmp_lucas_pt_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 512-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L512. + * Input parameter list for Modular exponentiation for numbers less than 512-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L512. */ -typedef struct icp_qat_fw_maths_modexp_l512_input_s { - uint64_t g; /**< base ≥ 0 and < 2^512 (8 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^512 (8 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^512 (8 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l512_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^512 (8 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^512 (8 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^512 (8 qwords)*/ } icp_qat_fw_maths_modexp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 1024-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L1024. + * Input parameter list for Modular exponentiation for numbers less than 1024-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L1024. */ -typedef struct icp_qat_fw_maths_modexp_l1024_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^1024 (16 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^1024 (16 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l1024_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^1024 (16 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^1024 (16 qwords)*/ } icp_qat_fw_maths_modexp_l1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 1536-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L1536. + * Input parameter list for Modular exponentiation for numbers less than 1536-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L1536. */ -typedef struct icp_qat_fw_maths_modexp_l1536_input_s { - uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^1536 (24 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^1536 (24 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l1536_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^1536 (24 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^1536 (24 qwords)*/ } icp_qat_fw_maths_modexp_l1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 2048-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L2048. + * Input parameter list for Modular exponentiation for numbers less than 2048-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L2048. */ -typedef struct icp_qat_fw_maths_modexp_l2048_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^2048 (32 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^2048 (32 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l2048_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^2048 (32 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^2048 (32 qwords)*/ } icp_qat_fw_maths_modexp_l2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 2560-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L2560. + * Input parameter list for Modular exponentiation for numbers less than 2560-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L2560. */ -typedef struct icp_qat_fw_maths_modexp_l2560_input_s { - uint64_t g; /**< base ≥ 0 and < 2^2560 (40 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^2560 (40 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^2560 (40 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l2560_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^2560 (40 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^2560 (40 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^2560 (40 qwords)*/ } icp_qat_fw_maths_modexp_l2560_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 3072-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L3072. + * Input parameter list for Modular exponentiation for numbers less than 3072-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L3072. */ -typedef struct icp_qat_fw_maths_modexp_l3072_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^3072 (48 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^3072 (48 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l3072_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^3072 (48 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^3072 (48 qwords)*/ } icp_qat_fw_maths_modexp_l3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 3584-bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L3584. + * Input parameter list for Modular exponentiation for numbers less than 3584-bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L3584. */ -typedef struct icp_qat_fw_maths_modexp_l3584_input_s { - uint64_t g; /**< base ≥ 0 and < 2^3584 (56 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^3584 (56 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^3584 (56 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l3584_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^3584 (56 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^3584 (56 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^3584 (56 qwords)*/ } icp_qat_fw_maths_modexp_l3584_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular exponentiation for numbers less than - * 4096-bit , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODEXP_L4096. + * Input parameter list for Modular exponentiation for numbers less than 4096-bit , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODEXP_L4096. */ -typedef struct icp_qat_fw_maths_modexp_l4096_input_s { - uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t e; /**< exponent ≥ 0 and < 2^4096 (64 qwords)*/ - uint64_t m; /**< modulus > 0 and < 2^4096 (64 qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l4096_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^4096 (64 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^4096 (64 qwords)*/ } icp_qat_fw_maths_modexp_l4096_input_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular exponentiation for numbers up to 8192 + * bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODEXP_L8192. + */ +typedef struct icp_qat_fw_maths_modexp_l8192_input_s +{ + uint64_t g; /**< base ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t e; /**< exponent ≥ 0 and < 2^8192 (128 qwords)*/ + uint64_t m; /**< modulus > 0 and < 2^8192 (128 qwords)*/ +} icp_qat_fw_maths_modexp_l8192_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is + * than 128 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is * #MATHS_MODINV_ODD_L128. */ -typedef struct icp_qat_fw_maths_modinv_odd_l128_input_s { - uint64_t a; /**< number > 0 and < 2^128 (2 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^128, coprime to a (2 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l128_input_s +{ + uint64_t a; /**< number > 0 and < 2^128 (2 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^128, coprime to a (2 qwords)*/ } icp_qat_fw_maths_modinv_odd_l128_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L192. + * Input parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L192. */ -typedef struct icp_qat_fw_maths_modinv_odd_l192_input_s { - uint64_t a; /**< number > 0 and < 2^192 (3 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^192, coprime to a (3 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l192_input_s +{ + uint64_t a; /**< number > 0 and < 2^192 (3 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^192, coprime to a (3 qwords)*/ } icp_qat_fw_maths_modinv_odd_l192_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L256. + * Input parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L256. */ -typedef struct icp_qat_fw_maths_modinv_odd_l256_input_s { - uint64_t a; /**< number > 0 and < 2^256 (4 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^256, coprime to a (4 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l256_input_s +{ + uint64_t a; /**< number > 0 and < 2^256 (4 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^256, coprime to a (4 qwords)*/ } icp_qat_fw_maths_modinv_odd_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L384. + * Input parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L384. */ -typedef struct icp_qat_fw_maths_modinv_odd_l384_input_s { - uint64_t a; /**< number > 0 and < 2^384 (6 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^384, coprime to a (6 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l384_input_s +{ + uint64_t a; /**< number > 0 and < 2^384 (6 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^384, coprime to a (6 qwords)*/ } icp_qat_fw_maths_modinv_odd_l384_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L512. + * Input parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L512. */ -typedef struct icp_qat_fw_maths_modinv_odd_l512_input_s { - uint64_t a; /**< number > 0 and < 2^512 (8 qwords)*/ - uint64_t - b; /**< odd modulus > 0 and < 2^512, coprime to a (8 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l512_input_s +{ + uint64_t a; /**< number > 0 and < 2^512 (8 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^512, coprime to a (8 qwords)*/ } icp_qat_fw_maths_modinv_odd_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L768. + * Input parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L768. */ -typedef struct icp_qat_fw_maths_modinv_odd_l768_input_s { - uint64_t a; /**< number > 0 and < 2^768 (12 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^768 ,coprime to a (12 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l768_input_s +{ + uint64_t a; /**< number > 0 and < 2^768 (12 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^768 ,coprime to a (12 qwords)*/ } icp_qat_fw_maths_modinv_odd_l768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L1024. + * Input parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L1024. */ -typedef struct icp_qat_fw_maths_modinv_odd_l1024_input_s { - uint64_t a; /**< number > 0 and < 2^1024 (16 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^1024, coprime to a (16 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l1024_input_s +{ + uint64_t a; /**< number > 0 and < 2^1024 (16 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^1024, coprime to a (16 qwords)*/ } icp_qat_fw_maths_modinv_odd_l1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L1536. + * Input parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L1536. */ -typedef struct icp_qat_fw_maths_modinv_odd_l1536_input_s { - uint64_t a; /**< number > 0 and < 2^1536 (24 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^1536, coprime to a (24 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l1536_input_s +{ + uint64_t a; /**< number > 0 and < 2^1536 (24 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^1536, coprime to a (24 qwords)*/ } icp_qat_fw_maths_modinv_odd_l1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L2048. + * Input parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L2048. */ -typedef struct icp_qat_fw_maths_modinv_odd_l2048_input_s { - uint64_t a; /**< number > 0 and < 2^2048 (32 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^2048, coprime to a (32 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l2048_input_s +{ + uint64_t a; /**< number > 0 and < 2^2048 (32 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^2048, coprime to a (32 qwords)*/ } icp_qat_fw_maths_modinv_odd_l2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L3072. + * Input parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L3072. */ -typedef struct icp_qat_fw_maths_modinv_odd_l3072_input_s { - uint64_t a; /**< number > 0 and < 2^3072 (48 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^3072, coprime to a (48 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l3072_input_s +{ + uint64_t a; /**< number > 0 and < 2^3072 (48 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^3072, coprime to a (48 qwords)*/ } icp_qat_fw_maths_modinv_odd_l3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_ODD_L4096. + * Input parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_ODD_L4096. */ -typedef struct icp_qat_fw_maths_modinv_odd_l4096_input_s { - uint64_t a; /**< number > 0 and < 2^4096 (64 qwords)*/ - uint64_t b; /**< odd modulus > 0 and < 2^4096, coprime to a (64 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l4096_input_s +{ + uint64_t a; /**< number > 0 and < 2^4096 (64 qwords)*/ + uint64_t b; /**< odd modulus > 0 and < 2^4096, coprime to a (64 qwords)*/ } icp_qat_fw_maths_modinv_odd_l4096_input_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_ODD_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l8192_input_s +{ + uint64_t a; /**< number > 0 and < 2^8192 (128 qwords)*/ + uint64_t + b; /**< odd modulus > 0 and < 2^8192, coprime to a (128 qwords)*/ +} icp_qat_fw_maths_modinv_odd_l8192_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is + * than 128 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is * #MATHS_MODINV_EVEN_L128. */ -typedef struct icp_qat_fw_maths_modinv_even_l128_input_s { - uint64_t a; /**< odd number > 0 and < 2^128 (2 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^128, coprime with a (2 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l128_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^128 (2 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^128, coprime with a (2 qwords)*/ } icp_qat_fw_maths_modinv_even_l128_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L192. + * Input parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L192. */ -typedef struct icp_qat_fw_maths_modinv_even_l192_input_s { - uint64_t a; /**< odd number > 0 and < 2^192 (3 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^192, coprime with a (3 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l192_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^192 (3 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^192, coprime with a (3 qwords)*/ } icp_qat_fw_maths_modinv_even_l192_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L256. + * Input parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L256. */ -typedef struct icp_qat_fw_maths_modinv_even_l256_input_s { - uint64_t a; /**< odd number > 0 and < 2^256 (4 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^256, coprime with a (4 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l256_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^256 (4 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^256, coprime with a (4 qwords)*/ } icp_qat_fw_maths_modinv_even_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L384. + * Input parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L384. */ -typedef struct icp_qat_fw_maths_modinv_even_l384_input_s { - uint64_t a; /**< odd number > 0 and < 2^384 (6 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^384, coprime with a (6 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l384_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^384 (6 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^384, coprime with a (6 qwords)*/ } icp_qat_fw_maths_modinv_even_l384_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L512. + * Input parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L512. */ -typedef struct icp_qat_fw_maths_modinv_even_l512_input_s { - uint64_t a; /**< odd number > 0 and < 2^512 (8 qwords)*/ - uint64_t - b; /**< even modulus > 0 and < 2^512, coprime with a (8 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l512_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^512 (8 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^512, coprime with a (8 qwords)*/ } icp_qat_fw_maths_modinv_even_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L768. + * Input parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L768. */ -typedef struct icp_qat_fw_maths_modinv_even_l768_input_s { - uint64_t a; /**< odd number > 0 and < 2^768 (12 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^768, coprime with a - (12 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l768_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^768 (12 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^768, coprime with a (12 qwords)*/ } icp_qat_fw_maths_modinv_even_l768_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L1024. + * Input parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L1024. */ -typedef struct icp_qat_fw_maths_modinv_even_l1024_input_s { - uint64_t a; /**< odd number > 0 and < 2^1024 (16 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^1024, coprime with a - (16 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l1024_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^1024 (16 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^1024, coprime with a (16 qwords)*/ } icp_qat_fw_maths_modinv_even_l1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L1536. + * Input parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L1536. */ -typedef struct icp_qat_fw_maths_modinv_even_l1536_input_s { - uint64_t a; /**< odd number > 0 and < 2^1536 (24 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^1536, coprime with a - (24 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l1536_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^1536 (24 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^1536, coprime with a (24 qwords)*/ } icp_qat_fw_maths_modinv_even_l1536_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L2048. + * Input parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L2048. */ -typedef struct icp_qat_fw_maths_modinv_even_l2048_input_s { - uint64_t a; /**< odd number > 0 and < 2^2048 (32 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^2048, coprime with a - (32 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l2048_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^2048 (32 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^2048, coprime with a (32 qwords)*/ } icp_qat_fw_maths_modinv_even_l2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L3072. + * Input parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L3072. */ -typedef struct icp_qat_fw_maths_modinv_even_l3072_input_s { - uint64_t a; /**< odd number > 0 and < 2^3072 (48 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^3072, coprime with a - (48 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l3072_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^3072 (48 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^3072, coprime with a (48 qwords)*/ } icp_qat_fw_maths_modinv_even_l3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_MODINV_EVEN_L4096. + * Input parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_MODINV_EVEN_L4096. */ -typedef struct icp_qat_fw_maths_modinv_even_l4096_input_s { - uint64_t a; /**< odd number > 0 and < 2^4096 (64 qwords)*/ - uint64_t b; /**< even modulus > 0 and < 2^4096, coprime with a - (64 qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l4096_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^4096 (64 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^4096, coprime with a (64 qwords)*/ } icp_qat_fw_maths_modinv_even_l4096_input_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_request_s::functionalityId is + * #MATHS_MODINV_EVEN_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l8192_input_s +{ + uint64_t a; /**< odd number > 0 and < 2^8192 (128 qwords)*/ + uint64_t b; /**< even modulus > 0 and < 2^8192, coprime with a (128 + qwords)*/ +} icp_qat_fw_maths_modinv_even_l8192_input_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_1024_160. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_1024_160. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s { - uint64_t x; /**< DSA 1024-bit randomness (16 qwords)*/ - uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s +{ + uint64_t x; /**< DSA 1024-bit randomness (16 qwords)*/ + uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_1024. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_input_s { - uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ - uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ - uint64_t h; /**< DSA 1024-bit parameter (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_input_s +{ + uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ + uint64_t q; /**< DSA 160-bit parameter (3 qwords)*/ + uint64_t h; /**< DSA 1024-bit parameter (16 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_1024. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_1024. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_input_s { - uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t - x; /**< randomly generated DSA parameter (160 bits), (3 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_input_s +{ + uint64_t p; /**< DSA 1024-bit parameter (16 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (160 bits), (3 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_1024_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_input_s { - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t p; /**< DSA parameter, (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t p; /**< DSA parameter, (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_160_input_s { - uint64_t m; /**< digest message to be signed (3 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t r; /**< DSA parameter (3 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_160_input_s +{ + uint64_t m; /**< digest message to be signed (3 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t r; /**< DSA parameter (3 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_s { - uint64_t m; /**< digest of the message to be signed (3 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ - uint64_t p; /**< DSA parameter (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_s +{ + uint64_t m; /**< digest of the message to be signed (3 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (3 qwords)*/ + uint64_t p; /**< DSA parameter (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_1024_160. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_input_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t m; /**< digest of the message (3 qwords)*/ - uint64_t p; /**< DSA parameter (16 qwords)*/ - uint64_t q; /**< DSA parameter (3 qwords)*/ - uint64_t g; /**< DSA parameter (16 qwords)*/ - uint64_t y; /**< DSA parameter (16 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_1024_160. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_input_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t m; /**< digest of the message (3 qwords)*/ + uint64_t p; /**< DSA parameter (16 qwords)*/ + uint64_t q; /**< DSA parameter (3 qwords)*/ + uint64_t g; /**< DSA parameter (16 qwords)*/ + uint64_t y; /**< DSA parameter (16 qwords)*/ } icp_qat_fw_mmp_dsa_verify_1024_160_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_2048_224. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_2048_224. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_input_s { - uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ - uint64_t q; /**< DSA 224-bit parameter (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_input_s +{ + uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ + uint64_t q; /**< DSA 224-bit parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_2048. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_input_s { - uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (224/256 bits), (4 - qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_input_s +{ + uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (224/256 bits), (4 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_224_input_s { - uint64_t m; /**< digest message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t r; /**< DSA parameter (4 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_224_input_s +{ + uint64_t m; /**< digest message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t r; /**< DSA parameter (4 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_224_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_2048_224. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_input_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t y; /**< DSA parameter (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_2048_224. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_input_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t y; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_verify_2048_224_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_2048_256. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_2048_256. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_input_s { - uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_input_s +{ + uint64_t x; /**< DSA 2048-bit randomness (32 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_2048. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_2048. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_input_s { - uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ - uint64_t h; /**< DSA 2048-bit parameter (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_input_s +{ + uint64_t p; /**< DSA 2048-bit parameter (32 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ + uint64_t h; /**< DSA 2048-bit parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_2048_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_S_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_256_input_s { - uint64_t m; /**< digest message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t r; /**< DSA parameter (4 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_S_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_s_256_input_s +{ + uint64_t m; /**< digest message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t r; /**< DSA parameter (4 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_2048_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_input_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (32 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (32 qwords)*/ - uint64_t y; /**< DSA parameter (32 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_2048_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_input_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (32 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (32 qwords)*/ + uint64_t y; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_verify_2048_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_P_3072_256. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_P_3072_256. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_input_s { - uint64_t x; /**< DSA 3072-bit randomness (48 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_input_s +{ + uint64_t x; /**< DSA 3072-bit randomness (48 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_G_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_G_3072. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_input_s { - uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ - uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ - uint64_t h; /**< DSA 3072-bit parameter (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_input_s +{ + uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ + uint64_t q; /**< DSA 256-bit parameter (4 qwords)*/ + uint64_t h; /**< DSA 3072-bit parameter (48 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_GEN_Y_3072. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_GEN_Y_3072. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_input_s { - uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t - x; /**< randomly generated DSA parameter (3072 bits), (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_input_s +{ + uint64_t p; /**< DSA 3072-bit parameter (48 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (3072 bits), (4 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_3072_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_input_s { - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter, (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_input_s +{ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter, (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_SIGN_R_S_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_s { - uint64_t m; /**< digest of the message to be signed (4 qwords)*/ - uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ - uint64_t p; /**< DSA parameter (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_SIGN_R_S_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_s +{ + uint64_t m; /**< digest of the message to be signed (4 qwords)*/ + uint64_t k; /**< randomly generated DSA parameter (4 qwords)*/ + uint64_t p; /**< DSA parameter (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t x; /**< randomly generated DSA parameter (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_DSA_VERIFY_3072_256. - */ -typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_input_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t m; /**< digest of the message (4 qwords)*/ - uint64_t p; /**< DSA parameter (48 qwords)*/ - uint64_t q; /**< DSA parameter (4 qwords)*/ - uint64_t g; /**< DSA parameter (48 qwords)*/ - uint64_t y; /**< DSA parameter (48 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_DSA_VERIFY_3072_256. + */ +typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_input_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t m; /**< digest of the message (4 qwords)*/ + uint64_t p; /**< DSA parameter (48 qwords)*/ + uint64_t q; /**< DSA parameter (4 qwords)*/ + uint64_t g; /**< DSA parameter (48 qwords)*/ + uint64_t y; /**< DSA parameter (48 qwords)*/ } icp_qat_fw_mmp_dsa_verify_3072_256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L256. + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_s { - uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) - (36 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_s +{ + uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) (36 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_s { - uint64_t - xg; /**< x coordinate of base point G of B/K-163 of B/K-233 (4 - qwords)*/ - uint64_t - yg; /**< y coordinate of base point G of B/K-163 or B/K-233 (4 - qwords)*/ - uint64_t - n; /**< order of the base point of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t - a; /**< a equation coefficient of B/K-163 of B/K-233 (4 qwords)*/ - uint64_t - b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t k; /**< random value > 0 and < n (4 qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_s +{ + uint64_t xg; /**< x coordinate of base point G of B/K-163 of B/K-233 (4 qwords)*/ + uint64_t yg; /**< y coordinate of base point G of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t n; /**< order of the base point of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-163 of B/K-233 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t k; /**< random value > 0 and < n (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Input parameter list for ECDSA Sign S for curves with n < 2^256 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_s { - uint64_t e; /**< hash of message (0 < e < 2^256) (4 qwords)*/ - uint64_t d; /**< private key (>0 and < n) (4 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (>0 and < n) (4 qwords)*/ - uint64_t k; /**< random value > 0 and < n (4 qwords)*/ - uint64_t n; /**< order of the base point G (2 < n < 2^256) (4 - qwords)*/ + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_s +{ + uint64_t e; /**< hash of message (0 < e < 2^256) (4 qwords)*/ + uint64_t d; /**< private key (>0 and < n) (4 qwords)*/ + uint64_t r; /**< ECDSA r signature value (>0 and < n) (4 qwords)*/ + uint64_t k; /**< random value > 0 and < n (4 qwords)*/ + uint64_t n; /**< order of the base point G (2 < n < 2^256) (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t; + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_s +{ + uint64_t in; /**< concatenated curve parameter (e,s,r,n,G,Q,a,b,q) (44 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_s +{ + uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) (72 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_s +{ + uint64_t xg; /**< x coordinate of verified base point (> 0 and degree(x(G)) < degree(q)) (8 qwords)*/ + uint64_t yg; /**< y coordinate of verified base point (> 0 and degree(y(G)) < degree(q)) (8 qwords)*/ + uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and < 2^512) (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < degree(q)) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(b) < degree(q)) (8 qwords)*/ + uint64_t k; /**< random value > 0 and < n (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_s +{ + uint64_t e; /**< hash of message (0 < e < 2^512) (8 qwords)*/ + uint64_t d; /**< private key (>0 and < n) (8 qwords)*/ + uint64_t r; /**< ECDSA r signature value (>0 and < n) (8 qwords)*/ + uint64_t k; /**< random value > 0 and < n (8 qwords)*/ + uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and < 2^512) (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_s +{ + uint64_t in; /**< concatenated curve parameters (e, s, r, n, xG, yG, xQ, yQ, a, b, q) (88 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_s +{ + uint64_t in; /**< concatenated input parameters (x(G), y(G), n, q, a, b, k, e, d) (81 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_s +{ + uint64_t e; /**< hash of message < 2^576 (9 qwords)*/ + uint64_t d; /**< private key (> 0 and < n) (9 qwords)*/ + uint64_t r; /**< ECDSA r signature value (> 0 and < n) (9 qwords)*/ + uint64_t k; /**< random value (> 0 and < n) (9 qwords)*/ + uint64_t n; /**< order of the base point of the curve (n < 2^576) (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Sign R for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_s +{ + uint64_t xg; /**< x coordinate of verified base point belonging to B/K-571 (9 qwords)*/ + uint64_t yg; /**< y coordinate of verified base point belonging to B/K-571 (9 qwords)*/ + uint64_t n; /**< order of the base point G (9 qwords)*/ + uint64_t q; /**< irreducible field polynomial of B/K-571 (9 qwords)*/ + uint64_t a; /**< a coefficient of curve B/K-571 (degree(a) < degree(q)) (9 qwords)*/ + uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) < degree(q)) (9 qwords)*/ + uint64_t k; /**< random value > 0 and < n (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GF2 Verify for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_s +{ + uint64_t in; /**< concatenated input (e, s, r, n, G, Q, a, b, q) (99 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_input_s +{ + uint64_t k; /**< scalar multiplier > 0 and < 2^256 (4 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < 256) (4 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(yG) < 256) (4 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ + uint64_t h; /**< cofactor of B/K-163 or B/K-233 (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l256_input_s +{ + uint64_t xq; /**< x coordinate of input point (4 qwords)*/ + uint64_t yq; /**< y coordinate of input point (4 qwords)*/ + uint64_t q; /**< field polynomial of curve, degree(q) < 256 (4 qwords)*/ + uint64_t a; /**< a equation coefficient of curve, degree(a) < 256 (4 qwords)*/ + uint64_t b; /**< b equation coefficient of curve, degree(b) < 256 (4 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_input_s +{ + uint64_t k; /**< scalar multiplier > 0 and < 2^512 (8 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < 512) (8 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(yG) < 512) (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(b) < 512) (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t h; /**< cofactor (< 2^512) (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for MATHS GF2 Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l512_input_s +{ + uint64_t xq; /**< x coordinate of input point (8 qwords)*/ + uint64_t yq; /**< y coordinate of input point (8 qwords)*/ + uint64_t q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ + uint64_t a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ + uint64_t b; /**< b equation coefficient (degree(a) < 512) (8 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_l512_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GF2 Point Multiplication for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_input_s +{ + uint64_t k; /**< scalar value > 0 and < 2^576 (9 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (degree(xG) < degree(q)) (9 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (degree(xG) < degree(q)) (9 qwords)*/ + uint64_t a; /**< a equation coefficient for B/K-571 (9 qwords)*/ + uint64_t b; /**< b equation coefficient for B/K-571 (9 qwords)*/ + uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ + uint64_t h; /**< cofactor for B/K-571 (1 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECC GF2 Point Verification for degree 571 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GF2_571. + */ +typedef struct icp_qat_fw_maths_point_verify_gf2_571_input_s +{ + uint64_t xq; /**< x coordinate of candidate public key (9 qwords)*/ + uint64_t yq; /**< y coordinate of candidate public key (9 qwords)*/ + uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ + uint64_t a; /**< a equation coefficient of B/K-571 (9 qwords)*/ + uint64_t b; /**< b equation coefficient of B/K-571 (9 qwords)*/ +} icp_qat_fw_maths_point_verify_gf2_571_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (4 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (4 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ + uint64_t k; /**< random value (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t; + + + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_s +{ + uint64_t e; /**< digest of the message to be signed (4 qwords)*/ + uint64_t d; /**< private key (4 qwords)*/ + uint64_t r; /**< DSA r signature value (4 qwords)*/ + uint64_t k; /**< random value (4 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t; + + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L256. + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_s { - uint64_t - in; /**< concatenated curve parameter (e,s,r,n,G,Q,a,b,q) (44 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t; +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (36 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L512. + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_s { - uint64_t in; /**< concatenated input parameters (G, n, q, a, b, k, e, d) - (72 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t; +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (44 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_s { - uint64_t xg; /**< x coordinate of verified base point (> 0 and - degree(x(G)) < degree(q)) (8 qwords)*/ - uint64_t yg; /**< y coordinate of verified base point (> 0 and - degree(y(G)) < degree(q)) (8 qwords)*/ - uint64_t n; /**< order of the base point G, which must be prime and a - divisor of #E and < 2^512) (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t a; /**< a equation coefficient (degree(a) < degree(q)) (8 - qwords)*/ - uint64_t b; /**< b equation coefficient (degree(b) < degree(q)) (8 - qwords)*/ - uint64_t k; /**< random value > 0 and < n (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t; + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (8 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (8 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ + uint64_t k; /**< random value (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_s { - uint64_t e; /**< hash of message (0 < e < 2^512) (8 qwords)*/ - uint64_t d; /**< private key (>0 and < n) (8 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (>0 and < n) (8 qwords)*/ - uint64_t k; /**< random value > 0 and < n (8 qwords)*/ - uint64_t n; /**< order of the base point G, which must be prime and a - divisor of #E and < 2^512) (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t; + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L512. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_s +{ + uint64_t e; /**< digest of the message to be signed (8 qwords)*/ + uint64_t d; /**< private key (8 qwords)*/ + uint64_t r; /**< DSA r signature value (8 qwords)*/ + uint64_t k; /**< random value (8 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (8 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L512. + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_s { - uint64_t - in; /**< concatenated curve parameters (e, s, r, n, xG, yG, xQ, yQ, - a, b, q) (88 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t; +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (72 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_571. + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_s { - uint64_t - in; /**< concatenated input parameters (x(G), y(G), n, q, a, b, k, - e, d) (81 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t; +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (88 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 - * , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_s { - uint64_t e; /**< hash of message < 2^576 (9 qwords)*/ - uint64_t d; /**< private key (> 0 and < n) (9 qwords)*/ - uint64_t - r; /**< ECDSA r signature value (> 0 and < n) (9 qwords)*/ - uint64_t k; /**< random value (> 0 and < n) (9 qwords)*/ - uint64_t - n; /**< order of the base point of the curve (n < 2^576) (9 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t; + * Input parameter list for ECDSA GFP Sign R , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_s +{ + uint64_t xg; /**< x coordinate of base point G, (9 qwords)*/ + uint64_t yg; /**< y coordinate of base point G, (9 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ + uint64_t k; /**< random value (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Sign R for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_571. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_s { - uint64_t xg; /**< x coordinate of verified base point belonging to - B/K-571 (9 qwords)*/ - uint64_t yg; /**< y coordinate of verified base point belonging to - B/K-571 (9 qwords)*/ - uint64_t n; /**< order of the base point G (9 qwords)*/ - uint64_t q; /**< irreducible field polynomial of B/K-571 (9 qwords)*/ - uint64_t a; /**< a coefficient of curve B/K-571 (degree(a) < - degree(q)) (9 qwords)*/ - uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) < - degree(q)) (9 qwords)*/ - uint64_t k; /**< random value > 0 and < n (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t; + * Input parameter list for ECDSA GFP Sign S , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_s +{ + uint64_t e; /**< digest of the message to be signed (9 qwords)*/ + uint64_t d; /**< private key (9 qwords)*/ + uint64_t r; /**< DSA r signature value (9 qwords)*/ + uint64_t k; /**< random value (9 qwords)*/ + uint64_t n; /**< order of the base point G, which shall be prime (9 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GF2 Verify for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_571. + * Input parameter list for ECDSA GFP Sign RS , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_521. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_s { - uint64_t in; /**< concatenated input (e, s, r, n, G, Q, a, b, q) (99 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t; +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_s +{ + uint64_t in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (81 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_input_s { - uint64_t k; /**< scalar multiplier > 0 and < 2^256 (4 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < 256) (4 - qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(yG) < 256) (4 - qwords)*/ - uint64_t - a; /**< a equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t - b; /**< b equation coefficient of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t q; /**< field polynomial of B/K-163 or B/K-233 (4 qwords)*/ - uint64_t h; /**< cofactor of B/K-163 or B/K-233 (4 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l256_input_t; + * Input parameter list for ECDSA GFP Verify , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_s +{ + uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} concatenated (99 qwords)*/ +} icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l256_input_s { - uint64_t xq; /**< x coordinate of input point (4 qwords)*/ - uint64_t yq; /**< y coordinate of input point (4 qwords)*/ - uint64_t - q; /**< field polynomial of curve, degree(q) < 256 (4 qwords)*/ - uint64_t - a; /**< a equation coefficient of curve, degree(a) < 256 (4 - qwords)*/ - uint64_t - b; /**< b equation coefficient of curve, degree(b) < 256 (4 - qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_l256_input_t; + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_input_s +{ + uint64_t k; /**< scalar multiplier (4 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (4 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t h; /**< cofactor (4 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_input_s { - uint64_t k; /**< scalar multiplier > 0 and < 2^512 (8 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < 512) (8 - qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(yG) < 512) (8 - qwords)*/ - uint64_t - a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ - uint64_t - b; /**< b equation coefficient (degree(b) < 512) (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t h; /**< cofactor (< 2^512) (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_l512_input_t; + * Input parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L256. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l256_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (4 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (4 qwords)*/ + uint64_t q; /**< modulus (4 qwords)*/ + uint64_t a; /**< a equation coefficient (4 qwords)*/ + uint64_t b; /**< b equation coefficient (4 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_l256_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l512_input_s { - uint64_t xq; /**< x coordinate of input point (8 qwords)*/ - uint64_t yq; /**< y coordinate of input point (8 qwords)*/ - uint64_t - q; /**< field polynomial of degree > 2 and < 512 (8 qwords)*/ - uint64_t - a; /**< a equation coefficient (degree(a) < 512) (8 qwords)*/ - uint64_t - b; /**< b equation coefficient (degree(a) < 512) (8 qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_l512_input_t; + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_input_s +{ + uint64_t k; /**< scalar multiplier (8 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (8 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t h; /**< cofactor (8 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GF2 Point Multiplication for curves - * B-571/K-571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_input_s { - uint64_t k; /**< scalar value > 0 and < 2^576 (9 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (degree(xG) < - degree(q)) (9 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (degree(xG) < - degree(q)) (9 qwords)*/ - uint64_t a; /**< a equation coefficient for B/K-571 (9 qwords)*/ - uint64_t b; /**< b equation coefficient for B/K-571 (9 qwords)*/ - uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ - uint64_t h; /**< cofactor for B/K-571 (1 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gf2_571_input_t; + * Input parameter list for ECC GFP Partial Point , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L512. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l512_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (8 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (8 qwords)*/ + uint64_t q; /**< modulus (8 qwords)*/ + uint64_t a; /**< a equation coefficient (8 qwords)*/ + uint64_t b; /**< b equation coefficient (8 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_l512_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GF2 Point Verification for degree 571 , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_571. - */ -typedef struct icp_qat_fw_maths_point_verify_gf2_571_input_s { - uint64_t xq; /**< x coordinate of candidate public key (9 qwords)*/ - uint64_t yq; /**< y coordinate of candidate public key (9 qwords)*/ - uint64_t q; /**< field polynomial of B/K-571 (9 qwords)*/ - uint64_t a; /**< a equation coefficient of B/K-571 (9 qwords)*/ - uint64_t b; /**< b equation coefficient of B/K-571 (9 qwords)*/ -} icp_qat_fw_maths_point_verify_gf2_571_input_t; + * Input parameter list for ECC GFP Point Multiplication , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_input_s +{ + uint64_t k; /**< scalar multiplier (9 qwords)*/ + uint64_t xg; /**< x coordinate of curve point (9 qwords)*/ + uint64_t yg; /**< y coordinate of curve point (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t h; /**< cofactor (1 qwords)*/ +} icp_qat_fw_maths_point_multiplication_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_s { - uint64_t xg; /**< x coordinate of base point G, (4 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (4 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (4 - qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ - uint64_t k; /**< random value (4 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t; + * Input parameter list for ECC GFP Partial Point Verification , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #MATHS_POINT_VERIFY_GFP_521. + */ +typedef struct icp_qat_fw_maths_point_verify_gfp_521_input_s +{ + uint64_t xq; /**< x coordinate of candidate point (9 qwords)*/ + uint64_t yq; /**< y coordinate of candidate point (9 qwords)*/ + uint64_t q; /**< modulus (9 qwords)*/ + uint64_t a; /**< a equation coefficient (9 qwords)*/ + uint64_t b; /**< b equation coefficient (9 qwords)*/ +} icp_qat_fw_maths_point_verify_gfp_521_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L256. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_s { - uint64_t e; /**< digest of the message to be signed (4 qwords)*/ - uint64_t d; /**< private key (4 qwords)*/ - uint64_t r; /**< DSA r signature value (4 qwords)*/ - uint64_t k; /**< random value (4 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (4 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t; + * Input parameter list for ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_C25519. + */ +typedef struct icp_qat_fw_point_multiplication_c25519_input_s +{ + uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_point_multiplication_c25519_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L256. + * Input parameter list for ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_C25519. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (36 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t; +typedef struct icp_qat_fw_generator_multiplication_c25519_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_generator_multiplication_c25519_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L256. + * Input parameter list for ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_ED25519. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (44 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t; +typedef struct icp_qat_fw_point_multiplication_ed25519_input_s +{ + uint64_t xp; /**< xP = Twisted Edwards affine coordinate X of point P (4 qwords)*/ + uint64_t yp; /**< yP = Twisted Edwards affine coordinate Y of point P (4 qwords)*/ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_point_multiplication_ed25519_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_s { - uint64_t xg; /**< x coordinate of base point G, (8 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (8 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (8 - qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ - uint64_t k; /**< random value (8 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t; + * Input parameter list for ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_generator_multiplication_ed25519_input_s +{ + uint64_t k; /**< k = scalar (4 qwords)*/ +} icp_qat_fw_generator_multiplication_ed25519_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L512. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_s { - uint64_t e; /**< digest of the message to be signed (8 qwords)*/ - uint64_t d; /**< private key (8 qwords)*/ - uint64_t r; /**< DSA r signature value (8 qwords)*/ - uint64_t k; /**< random value (8 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (8 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t; + * Input parameter list for ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_C448. + */ +typedef struct icp_qat_fw_point_multiplication_c448_input_s +{ + uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (8 qwords)*/ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_point_multiplication_c448_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L512. + * Input parameter list for ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_C448. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (72 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t; +typedef struct icp_qat_fw_generator_multiplication_c448_input_s +{ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_generator_multiplication_c448_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L512. + * Input parameter list for ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #POINT_MULTIPLICATION_ED448. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (88 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t; +typedef struct icp_qat_fw_point_multiplication_ed448_input_s +{ + uint64_t xp; /**< xP = Edwards affine coordinate X of point P (8 qwords)*/ + uint64_t yp; /**< yP = Edwards affine coordinate Y of point P (8 qwords)*/ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_point_multiplication_ed448_input_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_s { - uint64_t xg; /**< x coordinate of base point G, (9 qwords)*/ - uint64_t yg; /**< y coordinate of base point G, (9 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (9 - qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ - uint64_t k; /**< random value (9 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t; + * Input parameter list for ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_request_s::functionalityId is #GENERATOR_MULTIPLICATION_ED448. + */ +typedef struct icp_qat_fw_generator_multiplication_ed448_input_s +{ + uint64_t k; /**< k = scalar (8 qwords)*/ +} icp_qat_fw_generator_multiplication_ed448_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign S , + * Input parameter list for ECC P521 ECDSA Sign RS , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_521. - */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_s { - uint64_t e; /**< digest of the message to be signed (9 qwords)*/ - uint64_t d; /**< private key (9 qwords)*/ - uint64_t r; /**< DSA r signature value (9 qwords)*/ - uint64_t k; /**< random value (9 qwords)*/ - uint64_t n; /**< order of the base point G, which shall be prime (9 - qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t; + * #PKE_KPT_ECDSA_SIGN_RS_P521. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s +{ + uint64_t kpt_wrapped; /**< (42 qwords)*/ + uint64_t kpt_wrapping_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Sign RS , + * Input parameter list for ECC P384 ECDSA Sign RS , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_521. + * #PKE_KPT_ECDSA_SIGN_RS_P384. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_s { - uint64_t - in; /**< {xG, yG, n, q, a, b, k, e, d} concatenated (81 qwords)*/ -} icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t; +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s +{ + uint64_t kpt_wrapped; /**< (42 qwords)*/ + uint64_t kpt_wrapping_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECDSA GFP Verify , + * Input parameter list for ECC KPT P256 ECDSA Sign RS , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_521. + * #PKE_KPT_ECDSA_SIGN_RS_P256. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_s { - uint64_t in; /**< in = {e, s, r, n, xG, yG, xQ, yQ, a, b ,q} - concatenated (99 qwords)*/ -} icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t; +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s +{ + uint64_t kpt_wrapped; /**< (28 qwords)*/ + uint64_t key_unwrap_context; /**< unwrap context (8 qwords)*/ + uint64_t e; /**< (4 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Point Multiplication , + * Input parameter list for KPT RSA 512 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_input_s { - uint64_t k; /**< scalar multiplier (4 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (4 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t h; /**< cofactor (4 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l256_input_t; + * #PKE_KPT_RSA_DP1_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ + uint64_t kpt_wrapped; /**< (16 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_512_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Partial Point Verification , + * Input parameter list for KPT RSA 1024 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L256. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l256_input_s { - uint64_t xq; /**< x coordinate of candidate point (4 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (4 qwords)*/ - uint64_t q; /**< modulus (4 qwords)*/ - uint64_t a; /**< a equation coefficient (4 qwords)*/ - uint64_t b; /**< b equation coefficient (4 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_l256_input_t; + * #PKE_KPT_RSA_DP1_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ + uint64_t kpt_wrapped; /**< (32 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Point Multiplication , + * Input parameter list for KPT RSA 1536 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_input_s { - uint64_t k; /**< scalar multiplier (8 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (8 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t h; /**< cofactor (8 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_l512_input_t; + * #PKE_KPT_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ + uint64_t kpt_wrapped; /**< (48 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Partial Point , + * Input parameter list for KPT RSA 2048 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L512. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l512_input_s { - uint64_t xq; /**< x coordinate of candidate point (8 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (8 qwords)*/ - uint64_t q; /**< modulus (8 qwords)*/ - uint64_t a; /**< a equation coefficient (8 qwords)*/ - uint64_t b; /**< b equation coefficient (8 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_l512_input_t; + * #PKE_KPT_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ + uint64_t kpt_wrapped; /**< (64 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Point Multiplication , + * Input parameter list for KPT RSA 3072 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_input_s { - uint64_t k; /**< scalar multiplier (9 qwords)*/ - uint64_t xg; /**< x coordinate of curve point (9 qwords)*/ - uint64_t yg; /**< y coordinate of curve point (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t h; /**< cofactor (1 qwords)*/ -} icp_qat_fw_maths_point_multiplication_gfp_521_input_t; + * #PKE_KPT_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ + uint64_t kpt_wrapped; /**< (96 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC GFP Partial Point Verification , + * Input parameter list for KPT RSA 4096 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_521. - */ -typedef struct icp_qat_fw_maths_point_verify_gfp_521_input_s { - uint64_t xq; /**< x coordinate of candidate point (9 qwords)*/ - uint64_t yq; /**< y coordinate of candidate point (9 qwords)*/ - uint64_t q; /**< modulus (9 qwords)*/ - uint64_t a; /**< a equation coefficient (9 qwords)*/ - uint64_t b; /**< b equation coefficient (9 qwords)*/ -} icp_qat_fw_maths_point_verify_gfp_521_input_t; + * #PKE_KPT_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ + uint64_t kpt_wrapped; /**< (128 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC curve25519 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , + * Input parameter list for KPT RSA 8192 Decryption , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_C25519. + * #PKE_KPT_RSA_DP1_8192. */ -typedef struct icp_qat_fw_point_multiplication_c25519_input_s { - uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (4 - qwords)*/ - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_point_multiplication_c25519_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ + uint64_t kpt_wrapped; /**< (256 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC curve25519 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , + * Input parameter list for RSA 512 decryption second form , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C25519. + * #PKE_KPT_RSA_DP2_512. */ -typedef struct icp_qat_fw_generator_multiplication_c25519_input_s { - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_generator_multiplication_c25519_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (8 qwords)*/ + uint64_t kpt_wrapped; /**< (28 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_512_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC edwards25519 Variable Point Multiplication - * [k]P, as specified in RFC8032 , + * Input parameter list for RSA 1024 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_point_multiplication_ed25519_input_s { - uint64_t xp; /**< xP = Twisted Edwards affine coordinate X of point P - (4 qwords)*/ - uint64_t yp; /**< yP = Twisted Edwards affine coordinate Y of point P - (4 qwords)*/ - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_point_multiplication_ed25519_input_t; + * #PKE_KPT_RSA_DP2_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (16 qwords)*/ + uint64_t kpt_wrapped; /**< (56 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC edwards25519 Generator Point Multiplication - * [k]G, as specified in RFC8032 , + * Input parameter list for KPT RSA 1536 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED25519. + * #PKE_KPT_RSA_DP2_1536. */ -typedef struct icp_qat_fw_generator_multiplication_ed25519_input_s { - uint64_t k; /**< k = scalar (4 qwords)*/ -} icp_qat_fw_generator_multiplication_ed25519_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (24 qwords)*/ + uint64_t kpt_wrapped; /**< (84 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC curve448 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , + * Input parameter list for RSA 2048 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_C448. + * #PKE_KPT_RSA_DP2_2048. */ -typedef struct icp_qat_fw_point_multiplication_c448_input_s { - uint64_t xp; /**< xP = Montgomery affine coordinate X of point P (8 - qwords)*/ - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_point_multiplication_c448_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (32 qwords)*/ + uint64_t kpt_wrapped; /**< (112 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC curve448 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , + * Input parameter list for , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C448. + * #PKE_KPT_RSA_DP2_3072. */ -typedef struct icp_qat_fw_generator_multiplication_c448_input_s { - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_generator_multiplication_c448_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (48 qwords)*/ + uint64_t kpt_wrapped; /**< (168 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC edwards448 Variable Point Multiplication - * [k]P, as specified in RFC8032 , + * Input parameter list for RSA 4096 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #POINT_MULTIPLICATION_ED448. - */ -typedef struct icp_qat_fw_point_multiplication_ed448_input_s { - uint64_t - xp; /**< xP = Edwards affine coordinate X of point P (8 qwords)*/ - uint64_t - yp; /**< yP = Edwards affine coordinate Y of point P (8 qwords)*/ - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_point_multiplication_ed448_input_t; + * #PKE_KPT_RSA_DP2_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (64 qwords)*/ + uint64_t kpt_wrapped; /**< (224 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Input parameter list for ECC edwards448 Generator Point Multiplication - * [k]P, as specified in RFC8032 , + * Input parameter list for RSA 8192 Decryption with CRT , * to be used when icp_qat_fw_pke_request_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED448. + * #PKE_KPT_RSA_DP2_8192. */ -typedef struct icp_qat_fw_generator_multiplication_ed448_input_s { - uint64_t k; /**< k = scalar (8 qwords)*/ -} icp_qat_fw_generator_multiplication_ed448_input_t; +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s +{ + uint64_t c; /**< cipher text representative, < (p*q) (128 qwords)*/ + uint64_t kpt_wrapped; /**< (448 qwords)*/ + uint64_t kpt_unwrap_context; /**< unwrap context (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_t; /** * @ingroup icp_qat_fw_mmp * @brief * MMP input parameters */ -typedef union icp_qat_fw_mmp_input_param_u { - /** Generic parameter structure : All members of this wrapper structure - * are pointers to large integers. - */ - uint64_t flat_array[ICP_QAT_FW_PKE_INPUT_COUNT_MAX]; +typedef union icp_qat_fw_mmp_input_param_u +{ + /** Generic parameter structure : All members of this wrapper structure + * are pointers to large integers. + */ + uint64_t flat_array[ICP_QAT_FW_PKE_INPUT_COUNT_MAX]; + /** ECC P384 Variable Point Multiplication [k]P */ + + icp_qat_fw_mmp_ec_point_multiplication_p384_input_t + mmp_ec_point_multiplication_p384; + + /** ECC P384 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p384_input_t + mmp_ec_generator_multiplication_p384; + + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_t mmp_ecdsa_sign_rs_p384; + + /** ECC P256 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p256_input_t + mmp_ec_point_multiplication_p256; + + /** ECC P256 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p256_input_t + mmp_ec_generator_multiplication_p256; + + /** ECC P256 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_t mmp_ecdsa_sign_rs_p256; + + /** Initialisation sequence */ + icp_qat_fw_mmp_init_input_t mmp_init; + + /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ + icp_qat_fw_mmp_dh_g2_768_input_t mmp_dh_g2_768; + + /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ + icp_qat_fw_mmp_dh_768_input_t mmp_dh_768; + + /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ + icp_qat_fw_mmp_dh_g2_1024_input_t mmp_dh_g2_1024; + + /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ + icp_qat_fw_mmp_dh_1024_input_t mmp_dh_1024; + + /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ + icp_qat_fw_mmp_dh_g2_1536_input_t mmp_dh_g2_1536; + + /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ + icp_qat_fw_mmp_dh_1536_input_t mmp_dh_1536; + + /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ + icp_qat_fw_mmp_dh_g2_2048_input_t mmp_dh_g2_2048; + + /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ + icp_qat_fw_mmp_dh_2048_input_t mmp_dh_2048; + + /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ + icp_qat_fw_mmp_dh_g2_3072_input_t mmp_dh_g2_3072; + + /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ + icp_qat_fw_mmp_dh_3072_input_t mmp_dh_3072; + + /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ + icp_qat_fw_mmp_dh_g2_4096_input_t mmp_dh_g2_4096; + + /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ + icp_qat_fw_mmp_dh_4096_input_t mmp_dh_4096; + + /** Diffie-Hellman Modular exponentiation base 2 for 8192-bit numbers */ + icp_qat_fw_mmp_dh_g2_8192_input_t mmp_dh_g2_8192; - /** Initialisation sequence */ - icp_qat_fw_mmp_init_input_t mmp_init; + /** Diffie-Hellman Modular exponentiation for 8192-bit numbers */ + icp_qat_fw_mmp_dh_8192_input_t mmp_dh_8192; - /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ - icp_qat_fw_mmp_dh_g2_768_input_t mmp_dh_g2_768; + /** RSA 512 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_512_input_t mmp_rsa_kp1_512; - /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ - icp_qat_fw_mmp_dh_768_input_t mmp_dh_768; + /** RSA 512 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_512_input_t mmp_rsa_kp2_512; - /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ - icp_qat_fw_mmp_dh_g2_1024_input_t mmp_dh_g2_1024; + /** RSA 512 Encryption */ + icp_qat_fw_mmp_rsa_ep_512_input_t mmp_rsa_ep_512; - /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ - icp_qat_fw_mmp_dh_1024_input_t mmp_dh_1024; + /** RSA 512 Decryption */ + icp_qat_fw_mmp_rsa_dp1_512_input_t mmp_rsa_dp1_512; - /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ - icp_qat_fw_mmp_dh_g2_1536_input_t mmp_dh_g2_1536; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_512_input_t mmp_rsa_dp2_512; - /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ - icp_qat_fw_mmp_dh_1536_input_t mmp_dh_1536; + /** RSA 1024 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1024_input_t mmp_rsa_kp1_1024; - /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ - icp_qat_fw_mmp_dh_g2_2048_input_t mmp_dh_g2_2048; + /** RSA 1024 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1024_input_t mmp_rsa_kp2_1024; - /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ - icp_qat_fw_mmp_dh_2048_input_t mmp_dh_2048; + /** RSA 1024 Encryption */ + icp_qat_fw_mmp_rsa_ep_1024_input_t mmp_rsa_ep_1024; - /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ - icp_qat_fw_mmp_dh_g2_3072_input_t mmp_dh_g2_3072; + /** RSA 1024 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1024_input_t mmp_rsa_dp1_1024; - /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ - icp_qat_fw_mmp_dh_3072_input_t mmp_dh_3072; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1024_input_t mmp_rsa_dp2_1024; - /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ - icp_qat_fw_mmp_dh_g2_4096_input_t mmp_dh_g2_4096; + /** RSA 1536 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1536_input_t mmp_rsa_kp1_1536; - /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ - icp_qat_fw_mmp_dh_4096_input_t mmp_dh_4096; + /** RSA 1536 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1536_input_t mmp_rsa_kp2_1536; - /** RSA 512 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_512_input_t mmp_rsa_kp1_512; + /** RSA 1536 Encryption */ + icp_qat_fw_mmp_rsa_ep_1536_input_t mmp_rsa_ep_1536; - /** RSA 512 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_512_input_t mmp_rsa_kp2_512; + /** RSA 1536 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1536_input_t mmp_rsa_dp1_1536; - /** RSA 512 Encryption */ - icp_qat_fw_mmp_rsa_ep_512_input_t mmp_rsa_ep_512; + /** RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1536_input_t mmp_rsa_dp2_1536; - /** RSA 512 Decryption */ - icp_qat_fw_mmp_rsa_dp1_512_input_t mmp_rsa_dp1_512; + /** RSA 2048 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_2048_input_t mmp_rsa_kp1_2048; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_512_input_t mmp_rsa_dp2_512; + /** RSA 2048 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_2048_input_t mmp_rsa_kp2_2048; - /** RSA 1024 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1024_input_t mmp_rsa_kp1_1024; + /** RSA 2048 Encryption */ + icp_qat_fw_mmp_rsa_ep_2048_input_t mmp_rsa_ep_2048; - /** RSA 1024 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1024_input_t mmp_rsa_kp2_1024; + /** RSA 2048 Decryption */ + icp_qat_fw_mmp_rsa_dp1_2048_input_t mmp_rsa_dp1_2048; - /** RSA 1024 Encryption */ - icp_qat_fw_mmp_rsa_ep_1024_input_t mmp_rsa_ep_1024; + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_2048_input_t mmp_rsa_dp2_2048; - /** RSA 1024 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1024_input_t mmp_rsa_dp1_1024; + /** RSA 3072 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_3072_input_t mmp_rsa_kp1_3072; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1024_input_t mmp_rsa_dp2_1024; + /** RSA 3072 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_3072_input_t mmp_rsa_kp2_3072; - /** RSA 1536 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1536_input_t mmp_rsa_kp1_1536; + /** RSA 3072 Encryption */ + icp_qat_fw_mmp_rsa_ep_3072_input_t mmp_rsa_ep_3072; - /** RSA 1536 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1536_input_t mmp_rsa_kp2_1536; + /** RSA 3072 Decryption */ + icp_qat_fw_mmp_rsa_dp1_3072_input_t mmp_rsa_dp1_3072; - /** RSA 1536 Encryption */ - icp_qat_fw_mmp_rsa_ep_1536_input_t mmp_rsa_ep_1536; + /** RSA 3072 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_3072_input_t mmp_rsa_dp2_3072; - /** RSA 1536 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1536_input_t mmp_rsa_dp1_1536; + /** RSA 4096 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_4096_input_t mmp_rsa_kp1_4096; - /** RSA 1536 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1536_input_t mmp_rsa_dp2_1536; + /** RSA 4096 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_4096_input_t mmp_rsa_kp2_4096; - /** RSA 2048 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_2048_input_t mmp_rsa_kp1_2048; + /** RSA 4096 Encryption */ + icp_qat_fw_mmp_rsa_ep_4096_input_t mmp_rsa_ep_4096; - /** RSA 2048 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_2048_input_t mmp_rsa_kp2_2048; + /** RSA 4096 Decryption */ + icp_qat_fw_mmp_rsa_dp1_4096_input_t mmp_rsa_dp1_4096; - /** RSA 2048 Encryption */ - icp_qat_fw_mmp_rsa_ep_2048_input_t mmp_rsa_ep_2048; + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_4096_input_t mmp_rsa_dp2_4096; - /** RSA 2048 Decryption */ - icp_qat_fw_mmp_rsa_dp1_2048_input_t mmp_rsa_dp1_2048; + /** RSA 8192 Encryption */ + icp_qat_fw_mmp_rsa_ep_8192_input_t mmp_rsa_ep_8192; - /** RSA 2048 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_2048_input_t mmp_rsa_dp2_2048; + /** RSA 8192 Decryption */ + icp_qat_fw_mmp_rsa_dp1_8192_input_t mmp_rsa_dp1_8192; - /** RSA 3072 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_3072_input_t mmp_rsa_kp1_3072; + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_8192_input_t mmp_rsa_dp2_8192; - /** RSA 3072 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_3072_input_t mmp_rsa_kp2_3072; + /** GCD primality test for 192-bit numbers */ + icp_qat_fw_mmp_gcd_pt_192_input_t mmp_gcd_pt_192; - /** RSA 3072 Encryption */ - icp_qat_fw_mmp_rsa_ep_3072_input_t mmp_rsa_ep_3072; + /** GCD primality test for 256-bit numbers */ + icp_qat_fw_mmp_gcd_pt_256_input_t mmp_gcd_pt_256; - /** RSA 3072 Decryption */ - icp_qat_fw_mmp_rsa_dp1_3072_input_t mmp_rsa_dp1_3072; + /** GCD primality test for 384-bit numbers */ + icp_qat_fw_mmp_gcd_pt_384_input_t mmp_gcd_pt_384; - /** RSA 3072 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_3072_input_t mmp_rsa_dp2_3072; + /** GCD primality test for 512-bit numbers */ + icp_qat_fw_mmp_gcd_pt_512_input_t mmp_gcd_pt_512; - /** RSA 4096 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_4096_input_t mmp_rsa_kp1_4096; + /** GCD primality test for 768-bit numbers */ + icp_qat_fw_mmp_gcd_pt_768_input_t mmp_gcd_pt_768; - /** RSA 4096 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_4096_input_t mmp_rsa_kp2_4096; + /** GCD primality test for 1024-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1024_input_t mmp_gcd_pt_1024; - /** RSA 4096 Encryption */ - icp_qat_fw_mmp_rsa_ep_4096_input_t mmp_rsa_ep_4096; + /** GCD primality test for 1536-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1536_input_t mmp_gcd_pt_1536; - /** RSA 4096 Decryption */ - icp_qat_fw_mmp_rsa_dp1_4096_input_t mmp_rsa_dp1_4096; + /** GCD primality test for 2048-bit numbers */ + icp_qat_fw_mmp_gcd_pt_2048_input_t mmp_gcd_pt_2048; - /** RSA 4096 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_4096_input_t mmp_rsa_dp2_4096; + /** GCD primality test for 3072-bit numbers */ + icp_qat_fw_mmp_gcd_pt_3072_input_t mmp_gcd_pt_3072; - /** GCD primality test for 192-bit numbers */ - icp_qat_fw_mmp_gcd_pt_192_input_t mmp_gcd_pt_192; + /** GCD primality test for 4096-bit numbers */ + icp_qat_fw_mmp_gcd_pt_4096_input_t mmp_gcd_pt_4096; - /** GCD primality test for 256-bit numbers */ - icp_qat_fw_mmp_gcd_pt_256_input_t mmp_gcd_pt_256; + /** Fermat primality test for 160-bit numbers */ + icp_qat_fw_mmp_fermat_pt_160_input_t mmp_fermat_pt_160; - /** GCD primality test for 384-bit numbers */ - icp_qat_fw_mmp_gcd_pt_384_input_t mmp_gcd_pt_384; + /** Fermat primality test for 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_512_input_t mmp_fermat_pt_512; - /** GCD primality test for 512-bit numbers */ - icp_qat_fw_mmp_gcd_pt_512_input_t mmp_gcd_pt_512; + /** Fermat primality test for <e; 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_l512_input_t mmp_fermat_pt_l512; - /** GCD primality test for 768-bit numbers */ - icp_qat_fw_mmp_gcd_pt_768_input_t mmp_gcd_pt_768; + /** Fermat primality test for 768-bit numbers */ + icp_qat_fw_mmp_fermat_pt_768_input_t mmp_fermat_pt_768; - /** GCD primality test for 1024-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1024_input_t mmp_gcd_pt_1024; + /** Fermat primality test for 1024-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1024_input_t mmp_fermat_pt_1024; - /** GCD primality test for 1536-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1536_input_t mmp_gcd_pt_1536; + /** Fermat primality test for 1536-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1536_input_t mmp_fermat_pt_1536; - /** GCD primality test for 2048-bit numbers */ - icp_qat_fw_mmp_gcd_pt_2048_input_t mmp_gcd_pt_2048; + /** Fermat primality test for 2048-bit numbers */ + icp_qat_fw_mmp_fermat_pt_2048_input_t mmp_fermat_pt_2048; - /** GCD primality test for 3072-bit numbers */ - icp_qat_fw_mmp_gcd_pt_3072_input_t mmp_gcd_pt_3072; + /** Fermat primality test for 3072-bit numbers */ + icp_qat_fw_mmp_fermat_pt_3072_input_t mmp_fermat_pt_3072; - /** GCD primality test for 4096-bit numbers */ - icp_qat_fw_mmp_gcd_pt_4096_input_t mmp_gcd_pt_4096; + /** Fermat primality test for 4096-bit numbers */ + icp_qat_fw_mmp_fermat_pt_4096_input_t mmp_fermat_pt_4096; - /** Fermat primality test for 160-bit numbers */ - icp_qat_fw_mmp_fermat_pt_160_input_t mmp_fermat_pt_160; + /** Miller-Rabin primality test for 160-bit numbers */ + icp_qat_fw_mmp_mr_pt_160_input_t mmp_mr_pt_160; - /** Fermat primality test for 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_512_input_t mmp_fermat_pt_512; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_512_input_t mmp_mr_pt_512; - /** Fermat primality test for <e; 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_l512_input_t mmp_fermat_pt_l512; + /** Miller-Rabin primality test for 768-bit numbers */ + icp_qat_fw_mmp_mr_pt_768_input_t mmp_mr_pt_768; - /** Fermat primality test for 768-bit numbers */ - icp_qat_fw_mmp_fermat_pt_768_input_t mmp_fermat_pt_768; + /** Miller-Rabin primality test for 1024-bit numbers */ + icp_qat_fw_mmp_mr_pt_1024_input_t mmp_mr_pt_1024; - /** Fermat primality test for 1024-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1024_input_t mmp_fermat_pt_1024; + /** Miller-Rabin primality test for 1536-bit numbers */ + icp_qat_fw_mmp_mr_pt_1536_input_t mmp_mr_pt_1536; - /** Fermat primality test for 1536-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1536_input_t mmp_fermat_pt_1536; + /** Miller-Rabin primality test for 2048-bit numbers */ + icp_qat_fw_mmp_mr_pt_2048_input_t mmp_mr_pt_2048; - /** Fermat primality test for 2048-bit numbers */ - icp_qat_fw_mmp_fermat_pt_2048_input_t mmp_fermat_pt_2048; + /** Miller-Rabin primality test for 3072-bit numbers */ + icp_qat_fw_mmp_mr_pt_3072_input_t mmp_mr_pt_3072; - /** Fermat primality test for 3072-bit numbers */ - icp_qat_fw_mmp_fermat_pt_3072_input_t mmp_fermat_pt_3072; + /** Miller-Rabin primality test for 4096-bit numbers */ + icp_qat_fw_mmp_mr_pt_4096_input_t mmp_mr_pt_4096; - /** Fermat primality test for 4096-bit numbers */ - icp_qat_fw_mmp_fermat_pt_4096_input_t mmp_fermat_pt_4096; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_l512_input_t mmp_mr_pt_l512; - /** Miller-Rabin primality test for 160-bit numbers */ - icp_qat_fw_mmp_mr_pt_160_input_t mmp_mr_pt_160; + /** Lucas primality test for 160-bit numbers */ + icp_qat_fw_mmp_lucas_pt_160_input_t mmp_lucas_pt_160; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_512_input_t mmp_mr_pt_512; + /** Lucas primality test for 512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_512_input_t mmp_lucas_pt_512; - /** Miller-Rabin primality test for 768-bit numbers */ - icp_qat_fw_mmp_mr_pt_768_input_t mmp_mr_pt_768; + /** Lucas primality test for 768-bit numbers */ + icp_qat_fw_mmp_lucas_pt_768_input_t mmp_lucas_pt_768; - /** Miller-Rabin primality test for 1024-bit numbers */ - icp_qat_fw_mmp_mr_pt_1024_input_t mmp_mr_pt_1024; + /** Lucas primality test for 1024-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1024_input_t mmp_lucas_pt_1024; - /** Miller-Rabin primality test for 1536-bit numbers */ - icp_qat_fw_mmp_mr_pt_1536_input_t mmp_mr_pt_1536; + /** Lucas primality test for 1536-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1536_input_t mmp_lucas_pt_1536; - /** Miller-Rabin primality test for 2048-bit numbers */ - icp_qat_fw_mmp_mr_pt_2048_input_t mmp_mr_pt_2048; + /** Lucas primality test for 2048-bit numbers */ + icp_qat_fw_mmp_lucas_pt_2048_input_t mmp_lucas_pt_2048; - /** Miller-Rabin primality test for 3072-bit numbers */ - icp_qat_fw_mmp_mr_pt_3072_input_t mmp_mr_pt_3072; + /** Lucas primality test for 3072-bit numbers */ + icp_qat_fw_mmp_lucas_pt_3072_input_t mmp_lucas_pt_3072; - /** Miller-Rabin primality test for 4096-bit numbers */ - icp_qat_fw_mmp_mr_pt_4096_input_t mmp_mr_pt_4096; + /** Lucas primality test for 4096-bit numbers */ + icp_qat_fw_mmp_lucas_pt_4096_input_t mmp_lucas_pt_4096; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_l512_input_t mmp_mr_pt_l512; + /** Lucas primality test for L512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_l512_input_t mmp_lucas_pt_l512; - /** Lucas primality test for 160-bit numbers */ - icp_qat_fw_mmp_lucas_pt_160_input_t mmp_lucas_pt_160; + /** Modular exponentiation for numbers less than 512-bits */ + icp_qat_fw_maths_modexp_l512_input_t maths_modexp_l512; - /** Lucas primality test for 512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_512_input_t mmp_lucas_pt_512; + /** Modular exponentiation for numbers less than 1024-bit */ + icp_qat_fw_maths_modexp_l1024_input_t maths_modexp_l1024; - /** Lucas primality test for 768-bit numbers */ - icp_qat_fw_mmp_lucas_pt_768_input_t mmp_lucas_pt_768; + /** Modular exponentiation for numbers less than 1536-bits */ + icp_qat_fw_maths_modexp_l1536_input_t maths_modexp_l1536; - /** Lucas primality test for 1024-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1024_input_t mmp_lucas_pt_1024; + /** Modular exponentiation for numbers less than 2048-bit */ + icp_qat_fw_maths_modexp_l2048_input_t maths_modexp_l2048; - /** Lucas primality test for 1536-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1536_input_t mmp_lucas_pt_1536; + /** Modular exponentiation for numbers less than 2560-bits */ + icp_qat_fw_maths_modexp_l2560_input_t maths_modexp_l2560; - /** Lucas primality test for 2048-bit numbers */ - icp_qat_fw_mmp_lucas_pt_2048_input_t mmp_lucas_pt_2048; + /** Modular exponentiation for numbers less than 3072-bits */ + icp_qat_fw_maths_modexp_l3072_input_t maths_modexp_l3072; - /** Lucas primality test for 3072-bit numbers */ - icp_qat_fw_mmp_lucas_pt_3072_input_t mmp_lucas_pt_3072; + /** Modular exponentiation for numbers less than 3584-bits */ + icp_qat_fw_maths_modexp_l3584_input_t maths_modexp_l3584; - /** Lucas primality test for 4096-bit numbers */ - icp_qat_fw_mmp_lucas_pt_4096_input_t mmp_lucas_pt_4096; + /** Modular exponentiation for numbers less than 4096-bit */ + icp_qat_fw_maths_modexp_l4096_input_t maths_modexp_l4096; - /** Lucas primality test for L512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_l512_input_t mmp_lucas_pt_l512; + /** Modular exponentiation for numbers up to 8192 bits */ + icp_qat_fw_maths_modexp_l8192_input_t maths_modexp_l8192; - /** Modular exponentiation for numbers less than 512-bits */ - icp_qat_fw_maths_modexp_l512_input_t maths_modexp_l512; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_odd_l128_input_t maths_modinv_odd_l128; - /** Modular exponentiation for numbers less than 1024-bit */ - icp_qat_fw_maths_modexp_l1024_input_t maths_modexp_l1024; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_odd_l192_input_t maths_modinv_odd_l192; - /** Modular exponentiation for numbers less than 1536-bits */ - icp_qat_fw_maths_modexp_l1536_input_t maths_modexp_l1536; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_odd_l256_input_t maths_modinv_odd_l256; - /** Modular exponentiation for numbers less than 2048-bit */ - icp_qat_fw_maths_modexp_l2048_input_t maths_modexp_l2048; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_odd_l384_input_t maths_modinv_odd_l384; - /** Modular exponentiation for numbers less than 2560-bits */ - icp_qat_fw_maths_modexp_l2560_input_t maths_modexp_l2560; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_odd_l512_input_t maths_modinv_odd_l512; - /** Modular exponentiation for numbers less than 3072-bits */ - icp_qat_fw_maths_modexp_l3072_input_t maths_modexp_l3072; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_odd_l768_input_t maths_modinv_odd_l768; - /** Modular exponentiation for numbers less than 3584-bits */ - icp_qat_fw_maths_modexp_l3584_input_t maths_modexp_l3584; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_odd_l1024_input_t maths_modinv_odd_l1024; - /** Modular exponentiation for numbers less than 4096-bit */ - icp_qat_fw_maths_modexp_l4096_input_t maths_modexp_l4096; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_odd_l1536_input_t maths_modinv_odd_l1536; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_odd_l128_input_t maths_modinv_odd_l128; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_odd_l2048_input_t maths_modinv_odd_l2048; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_odd_l192_input_t maths_modinv_odd_l192; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_odd_l3072_input_t maths_modinv_odd_l3072; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_odd_l256_input_t maths_modinv_odd_l256; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_odd_l4096_input_t maths_modinv_odd_l4096; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_odd_l384_input_t maths_modinv_odd_l384; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_odd_l8192_input_t maths_modinv_odd_l8192; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_odd_l512_input_t maths_modinv_odd_l512; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_even_l128_input_t maths_modinv_even_l128; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_odd_l768_input_t maths_modinv_odd_l768; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_even_l192_input_t maths_modinv_even_l192; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_odd_l1024_input_t maths_modinv_odd_l1024; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_even_l256_input_t maths_modinv_even_l256; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_odd_l1536_input_t maths_modinv_odd_l1536; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_even_l384_input_t maths_modinv_even_l384; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_odd_l2048_input_t maths_modinv_odd_l2048; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_even_l512_input_t maths_modinv_even_l512; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_odd_l3072_input_t maths_modinv_odd_l3072; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_even_l768_input_t maths_modinv_even_l768; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_odd_l4096_input_t maths_modinv_odd_l4096; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_even_l1024_input_t maths_modinv_even_l1024; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_even_l128_input_t maths_modinv_even_l128; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_even_l1536_input_t maths_modinv_even_l1536; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_even_l192_input_t maths_modinv_even_l192; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_even_l2048_input_t maths_modinv_even_l2048; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_even_l256_input_t maths_modinv_even_l256; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_even_l3072_input_t maths_modinv_even_l3072; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_even_l384_input_t maths_modinv_even_l384; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_even_l4096_input_t maths_modinv_even_l4096; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_even_l512_input_t maths_modinv_even_l512; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_even_l8192_input_t maths_modinv_even_l8192; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_even_l768_input_t maths_modinv_even_l768; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t mmp_dsa_gen_p_1024_160; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_even_l1024_input_t maths_modinv_even_l1024; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_1024_input_t mmp_dsa_gen_g_1024; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_even_l1536_input_t maths_modinv_even_l1536; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_1024_input_t mmp_dsa_gen_y_1024; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_even_l2048_input_t maths_modinv_even_l2048; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t mmp_dsa_sign_r_1024_160; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_even_l3072_input_t maths_modinv_even_l3072; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_160_input_t mmp_dsa_sign_s_160; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_even_l4096_input_t maths_modinv_even_l4096; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t mmp_dsa_sign_r_s_1024_160; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_1024_160_input_t mmp_dsa_gen_p_1024_160; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_1024_160_input_t mmp_dsa_verify_1024_160; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_1024_input_t mmp_dsa_gen_g_1024; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t mmp_dsa_gen_p_2048_224; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_1024_input_t mmp_dsa_gen_y_1024; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_2048_input_t mmp_dsa_gen_y_2048; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_1024_160_input_t mmp_dsa_sign_r_1024_160; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t mmp_dsa_sign_r_2048_224; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_160_input_t mmp_dsa_sign_s_160; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_224_input_t mmp_dsa_sign_s_224; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_1024_160_input_t mmp_dsa_sign_r_s_1024_160; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t mmp_dsa_sign_r_s_2048_224; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_1024_160_input_t mmp_dsa_verify_1024_160; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_224_input_t mmp_dsa_verify_2048_224; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_224_input_t mmp_dsa_gen_p_2048_224; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t mmp_dsa_gen_p_2048_256; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_2048_input_t mmp_dsa_gen_y_2048; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_2048_input_t mmp_dsa_gen_g_2048; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_224_input_t mmp_dsa_sign_r_2048_224; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t mmp_dsa_sign_r_2048_256; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_224_input_t mmp_dsa_sign_s_224; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_256_input_t mmp_dsa_sign_s_256; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_224_input_t mmp_dsa_sign_r_s_2048_224; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t mmp_dsa_sign_r_s_2048_256; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_224_input_t mmp_dsa_verify_2048_224; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_256_input_t mmp_dsa_verify_2048_256; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_256_input_t mmp_dsa_gen_p_2048_256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t mmp_dsa_gen_p_3072_256; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_2048_input_t mmp_dsa_gen_g_2048; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_3072_input_t mmp_dsa_gen_g_3072; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_256_input_t mmp_dsa_sign_r_2048_256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_3072_input_t mmp_dsa_gen_y_3072; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_256_input_t mmp_dsa_sign_s_256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t mmp_dsa_sign_r_3072_256; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_256_input_t mmp_dsa_sign_r_s_2048_256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t mmp_dsa_sign_r_s_3072_256; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_256_input_t mmp_dsa_verify_2048_256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_3072_256_input_t mmp_dsa_verify_3072_256; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_3072_256_input_t mmp_dsa_gen_p_3072_256; + /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t mmp_ecdsa_sign_rs_gf2_l256; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_3072_input_t mmp_dsa_gen_g_3072; + /** ECDSA Sign R for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t mmp_ecdsa_sign_r_gf2_l256; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_3072_input_t mmp_dsa_gen_y_3072; + /** ECDSA Sign S for curves with n < 2^256 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t mmp_ecdsa_sign_s_gf2_l256; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_3072_256_input_t mmp_dsa_sign_r_3072_256; + /** ECDSA Verify for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t mmp_ecdsa_verify_gf2_l256; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_3072_256_input_t mmp_dsa_sign_r_s_3072_256; + /** ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t mmp_ecdsa_sign_rs_gf2_l512; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_3072_256_input_t mmp_dsa_verify_3072_256; + /** ECDSA GF2 Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t mmp_ecdsa_sign_r_gf2_l512; - /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_input_t - mmp_ecdsa_sign_rs_gf2_l256; + /** ECDSA GF2 Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t mmp_ecdsa_sign_s_gf2_l512; - /** ECDSA Sign R for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_input_t mmp_ecdsa_sign_r_gf2_l256; + /** ECDSA GF2 Verify */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t mmp_ecdsa_verify_gf2_l512; - /** ECDSA Sign S for curves with n < 2^256 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_input_t mmp_ecdsa_sign_s_gf2_l256; + /** ECDSA GF2 Sign RS for curves B-571/K-571 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t mmp_ecdsa_sign_rs_gf2_571; - /** ECDSA Verify for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l256_input_t mmp_ecdsa_verify_gf2_l256; + /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t mmp_ecdsa_sign_s_gf2_571; - /** ECDSA Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_input_t - mmp_ecdsa_sign_rs_gf2_l512; + /** ECDSA GF2 Sign R for degree 571 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t mmp_ecdsa_sign_r_gf2_571; - /** ECDSA GF2 Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_input_t mmp_ecdsa_sign_r_gf2_l512; + /** ECDSA GF2 Verify for degree 571 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t mmp_ecdsa_verify_gf2_571; - /** ECDSA GF2 Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_input_t mmp_ecdsa_sign_s_gf2_l512; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l256_input_t maths_point_multiplication_gf2_l256; - /** ECDSA GF2 Verify */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l512_input_t mmp_ecdsa_verify_gf2_l512; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l256_input_t maths_point_verify_gf2_l256; - /** ECDSA GF2 Sign RS for curves B-571/K-571 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_input_t mmp_ecdsa_sign_rs_gf2_571; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l512_input_t maths_point_multiplication_gf2_l512; - /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_input_t mmp_ecdsa_sign_s_gf2_571; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l512_input_t maths_point_verify_gf2_l512; - /** ECDSA GF2 Sign R for degree 571 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_input_t mmp_ecdsa_sign_r_gf2_571; + /** ECC GF2 Point Multiplication for curves B-571/K-571 */ + icp_qat_fw_maths_point_multiplication_gf2_571_input_t maths_point_multiplication_gf2_571; - /** ECDSA GF2 Verify for degree 571 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_571_input_t mmp_ecdsa_verify_gf2_571; + /** ECC GF2 Point Verification for degree 571 */ + icp_qat_fw_maths_point_verify_gf2_571_input_t maths_point_verify_gf2_571; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l256_input_t - maths_point_multiplication_gf2_l256; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t mmp_ecdsa_sign_r_gfp_l256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l256_input_t - maths_point_verify_gf2_l256; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t mmp_ecdsa_sign_s_gfp_l256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l512_input_t - maths_point_multiplication_gf2_l512; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t mmp_ecdsa_sign_rs_gfp_l256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l512_input_t - maths_point_verify_gf2_l512; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t mmp_ecdsa_verify_gfp_l256; - /** ECC GF2 Point Multiplication for curves B-571/K-571 */ - icp_qat_fw_maths_point_multiplication_gf2_571_input_t - maths_point_multiplication_gf2_571; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t mmp_ecdsa_sign_r_gfp_l512; - /** ECC GF2 Point Verification for degree 571 */ - icp_qat_fw_maths_point_verify_gf2_571_input_t - maths_point_verify_gf2_571; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t mmp_ecdsa_sign_s_gfp_l512; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_input_t mmp_ecdsa_sign_r_gfp_l256; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t mmp_ecdsa_sign_rs_gfp_l512; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_input_t mmp_ecdsa_sign_s_gfp_l256; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t mmp_ecdsa_verify_gfp_l512; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_input_t - mmp_ecdsa_sign_rs_gfp_l256; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t mmp_ecdsa_sign_r_gfp_521; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l256_input_t mmp_ecdsa_verify_gfp_l256; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t mmp_ecdsa_sign_s_gfp_521; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_input_t mmp_ecdsa_sign_r_gfp_l512; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t mmp_ecdsa_sign_rs_gfp_521; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_input_t mmp_ecdsa_sign_s_gfp_l512; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t mmp_ecdsa_verify_gfp_521; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_input_t - mmp_ecdsa_sign_rs_gfp_l512; + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l256_input_t maths_point_multiplication_gfp_l256; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l512_input_t mmp_ecdsa_verify_gfp_l512; + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_l256_input_t maths_point_verify_gfp_l256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_input_t mmp_ecdsa_sign_r_gfp_521; + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l512_input_t maths_point_multiplication_gfp_l512; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_input_t mmp_ecdsa_sign_s_gfp_521; + /** ECC GFP Partial Point */ + icp_qat_fw_maths_point_verify_gfp_l512_input_t maths_point_verify_gfp_l512; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_input_t mmp_ecdsa_sign_rs_gfp_521; + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_521_input_t maths_point_multiplication_gfp_521; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_521_input_t mmp_ecdsa_verify_gfp_521; + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_521_input_t maths_point_verify_gfp_521; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l256_input_t - maths_point_multiplication_gfp_l256; + /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 */ + icp_qat_fw_point_multiplication_c25519_input_t point_multiplication_c25519; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_l256_input_t - maths_point_verify_gfp_l256; + /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 */ + icp_qat_fw_generator_multiplication_c25519_input_t generator_multiplication_c25519; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l512_input_t - maths_point_multiplication_gfp_l512; + /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_point_multiplication_ed25519_input_t point_multiplication_ed25519; - /** ECC GFP Partial Point */ - icp_qat_fw_maths_point_verify_gfp_l512_input_t - maths_point_verify_gfp_l512; + /** ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 */ + icp_qat_fw_generator_multiplication_ed25519_input_t generator_multiplication_ed25519; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_521_input_t - maths_point_multiplication_gfp_521; + /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 */ + icp_qat_fw_point_multiplication_c448_input_t point_multiplication_c448; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_521_input_t - maths_point_verify_gfp_521; + /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 */ + icp_qat_fw_generator_multiplication_c448_input_t generator_multiplication_c448; - /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified - * in RFC7748 */ - icp_qat_fw_point_multiplication_c25519_input_t - point_multiplication_c25519; + /** ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_point_multiplication_ed448_input_t point_multiplication_ed448; - /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified - * in RFC7748 */ - icp_qat_fw_generator_multiplication_c25519_input_t - generator_multiplication_c25519; + /** ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 */ + icp_qat_fw_generator_multiplication_ed448_input_t generator_multiplication_ed448; - /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed25519_input_t - point_multiplication_ed25519; + /** ECC P521 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_t mmp_kpt_ecdsa_sign_rs_p521; - /** ECC edwards25519 Generator Point Multiplication [k]G, as specified - * in RFC8032 */ - icp_qat_fw_generator_multiplication_ed25519_input_t - generator_multiplication_ed25519; + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_t mmp_kpt_ecdsa_sign_rs_p384; + + /** ECC KPT P256 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_t mmp_kpt_ecdsa_sign_rs_p256; + + /** KPT RSA 512 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_512_input_t mmp_kpt_rsa_dp1_512; + + /** KPT RSA 1024 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_t mmp_kpt_rsa_dp1_1024; + + /** KPT RSA 1536 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_t mmp_kpt_rsa_dp1_1536; + + /** KPT RSA 2048 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_t mmp_kpt_rsa_dp1_2048; + + /** KPT RSA 3072 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_t mmp_kpt_rsa_dp1_3072; + + /** KPT RSA 4096 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_t mmp_kpt_rsa_dp1_4096; + + /** KPT RSA 8192 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_t mmp_kpt_rsa_dp1_8192; + + /** RSA 512 decryption second form */ + icp_qat_fw_mmp_kpt_rsa_dp2_512_input_t mmp_kpt_rsa_dp2_512; + + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_t mmp_kpt_rsa_dp2_1024; + + /** KPT RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_t mmp_kpt_rsa_dp2_1536; + + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_t mmp_kpt_rsa_dp2_2048; + + /** */ + icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_t mmp_kpt_rsa_dp2_3072; + + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_t mmp_kpt_rsa_dp2_4096; + + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_t mmp_kpt_rsa_dp2_8192; + +} icp_qat_fw_mmp_input_param_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p384_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]P (6 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]P (6 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P384. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p384_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]G (6 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]G (6 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_t; - /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in - * RFC7748 */ - icp_qat_fw_point_multiplication_c448_input_t point_multiplication_c448; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 Variable Point Multiplication [k]P , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_POINT_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_point_multiplication_p256_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]P (4 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]P (4 qwords)*/ +} icp_qat_fw_mmp_ec_point_multiplication_p256_output_t; - /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in - * RFC7748 */ - icp_qat_fw_generator_multiplication_c448_input_t - generator_multiplication_c448; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 Generator Point Multiplication [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_EC_GENERATOR_MULTIPLICATION_P256. + */ +typedef struct icp_qat_fw_mmp_ec_generator_multiplication_p256_output_s +{ + uint64_t xr; /**< xR = affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yr; /**< yR = affine coordinate Y of point [k]G (4 qwords)*/ +} icp_qat_fw_mmp_ec_generator_multiplication_p256_output_t; - /** ECC edwards448 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed448_input_t - point_multiplication_ed448; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_t; - /** ECC edwards448 Generator Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_generator_multiplication_ed448_input_t - generator_multiplication_ed448; -} icp_qat_fw_mmp_input_param_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC SM2 point multiply [k]G , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_ECSM2_GENERATOR_MULTIPLICATION. + */ +typedef struct icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s +{ + uint64_t xd; /**< xD = affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yd; /**< yD = affine coordinate Y of point [k]G (4 qwords)*/ +} icp_qat_fw_mmp_ecsm2_generator_multiplication_output_t; /** * @ingroup icp_qat_fw_mmp @@ -3175,2752 +3904,3345 @@ * Output parameter list for Initialisation sequence , * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_INIT. */ -typedef struct icp_qat_fw_mmp_init_output_s { - uint64_t zz; /**< 1'd quadword (1 qwords)*/ +typedef struct icp_qat_fw_mmp_init_output_s +{ + uint64_t zz; /**< 1'd quadword (1 qwords)*/ } icp_qat_fw_mmp_init_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_768. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_768. */ -typedef struct icp_qat_fw_mmp_dh_g2_768_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_768_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 qwords)*/ } icp_qat_fw_mmp_dh_g2_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_768. + * Output parameter list for Diffie-Hellman Modular exponentiation for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_768. */ -typedef struct icp_qat_fw_mmp_dh_768_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_768_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (12 qwords)*/ } icp_qat_fw_mmp_dh_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_1024. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_1024. */ -typedef struct icp_qat_fw_mmp_dh_g2_1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ } icp_qat_fw_mmp_dh_g2_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_1024. + * Output parameter list for Diffie-Hellman Modular exponentiation for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_1024. */ -typedef struct icp_qat_fw_mmp_dh_1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ } icp_qat_fw_mmp_dh_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_1536. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_1536. */ -typedef struct icp_qat_fw_mmp_dh_g2_1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ } icp_qat_fw_mmp_dh_g2_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_1536. + * Output parameter list for Diffie-Hellman Modular exponentiation for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_1536. */ -typedef struct icp_qat_fw_mmp_dh_1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ } icp_qat_fw_mmp_dh_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_2048. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_2048. */ -typedef struct icp_qat_fw_mmp_dh_g2_2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ } icp_qat_fw_mmp_dh_g2_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_2048. + * Output parameter list for Diffie-Hellman Modular exponentiation for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_2048. */ -typedef struct icp_qat_fw_mmp_dh_2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ } icp_qat_fw_mmp_dh_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_3072. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_3072. */ -typedef struct icp_qat_fw_mmp_dh_g2_3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ } icp_qat_fw_mmp_dh_g2_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_3072. + * Output parameter list for Diffie-Hellman Modular exponentiation for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_3072. */ -typedef struct icp_qat_fw_mmp_dh_3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ } icp_qat_fw_mmp_dh_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_G2_4096. + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_G2_4096. */ -typedef struct icp_qat_fw_mmp_dh_g2_4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_g2_4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ } icp_qat_fw_mmp_dh_g2_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Diffie-Hellman Modular exponentiation for - * 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DH_4096. + * Output parameter list for Diffie-Hellman Modular exponentiation for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DH_4096. */ -typedef struct icp_qat_fw_mmp_dh_4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ +typedef struct icp_qat_fw_mmp_dh_4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ } icp_qat_fw_mmp_dh_4096_output_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers , to be used when icp_qat_fw_pke_response_s::functionalityId + * is #PKE_DH_G2_8192. + */ +typedef struct icp_qat_fw_mmp_dh_g2_8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_mmp_dh_g2_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Diffie-Hellman Modular exponentiation for + * 8192-bit numbers , to be used when icp_qat_fw_pke_response_s::functionalityId + * is #PKE_DH_8192. + */ +typedef struct icp_qat_fw_mmp_dh_8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_mmp_dh_8192_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_512. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_512_output_s { - uint64_t n; /**< RSA key (8 qwords)*/ - uint64_t d; /**< RSA private key (first form) (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_512_output_s +{ + uint64_t n; /**< RSA key (8 qwords)*/ + uint64_t d; /**< RSA private key (first form) (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_512. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_512_output_s { - uint64_t n; /**< RSA key (8 qwords)*/ - uint64_t d; /**< RSA private key (second form) (8 qwords)*/ - uint64_t dp; /**< RSA private key (second form) (4 qwords)*/ - uint64_t dq; /**< RSA private key (second form) (4 qwords)*/ - uint64_t qinv; /**< RSA private key (second form) (4 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_512. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_512_output_s +{ + uint64_t n; /**< RSA key (8 qwords)*/ + uint64_t d; /**< RSA private key (second form) (8 qwords)*/ + uint64_t dp; /**< RSA private key (second form) (4 qwords)*/ + uint64_t dq; /**< RSA private key (second form) (4 qwords)*/ + uint64_t qinv; /**< RSA private key (second form) (4 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_512. */ -typedef struct icp_qat_fw_mmp_rsa_ep_512_output_s { - uint64_t c; /**< cipher text representative, < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_512_output_s +{ + uint64_t c; /**< cipher text representative, < n (8 qwords)*/ } icp_qat_fw_mmp_rsa_ep_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 512 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_512_output_s { - uint64_t m; /**< message representative, < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_512_output_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_512. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_512_output_s { - uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_512_output_s +{ + uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1024_output_s { - uint64_t n; /**< RSA key (16 qwords)*/ - uint64_t d; /**< RSA private key (first form) (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_1024_output_s +{ + uint64_t n; /**< RSA key (16 qwords)*/ + uint64_t d; /**< RSA private key (first form) (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_1024. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1024_output_s { - uint64_t n; /**< RSA key (16 qwords)*/ - uint64_t d; /**< RSA private key (second form) (16 qwords)*/ - uint64_t dp; /**< RSA private key (second form) (8 qwords)*/ - uint64_t dq; /**< RSA private key (second form) (8 qwords)*/ - uint64_t qinv; /**< RSA private key (second form) (8 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_1024. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1024_output_s +{ + uint64_t n; /**< RSA key (16 qwords)*/ + uint64_t d; /**< RSA private key (second form) (16 qwords)*/ + uint64_t dp; /**< RSA private key (second form) (8 qwords)*/ + uint64_t dq; /**< RSA private key (second form) (8 qwords)*/ + uint64_t qinv; /**< RSA private key (second form) (8 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_1024. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1024_output_s { - uint64_t c; /**< cipher text representative, < n (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1024_output_s +{ + uint64_t c; /**< cipher text representative, < n (16 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1024_output_s { - uint64_t m; /**< message representative, < n (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1024_output_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1024 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_1024. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1024_output_s { - uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_1024_output_s +{ + uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1536 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_1536. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_1536_output_s { - uint64_t n; /**< RSA key (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_1536_output_s +{ + uint64_t n; /**< RSA key (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1536 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_1536. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_1536_output_s { - uint64_t n; /**< RSA key (24 qwords)*/ - uint64_t d; /**< RSA private key (24 qwords)*/ - uint64_t dp; /**< RSA private key (12 qwords)*/ - uint64_t dq; /**< RSA private key (12 qwords)*/ - uint64_t qinv; /**< RSA private key (12 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_1536. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_1536_output_s +{ + uint64_t n; /**< RSA key (24 qwords)*/ + uint64_t d; /**< RSA private key (24 qwords)*/ + uint64_t dp; /**< RSA private key (12 qwords)*/ + uint64_t dq; /**< RSA private key (12 qwords)*/ + uint64_t qinv; /**< RSA private key (12 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1536 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_1536. */ -typedef struct icp_qat_fw_mmp_rsa_ep_1536_output_s { - uint64_t c; /**< cipher text representative, < n (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_1536_output_s +{ + uint64_t c; /**< cipher text representative, < n (24 qwords)*/ } icp_qat_fw_mmp_rsa_ep_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1536 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_1536. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_1536_output_s { - uint64_t m; /**< message representative, < n (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_1536_output_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 1536 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_1536. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_1536_output_s { - uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_1536_output_s +{ + uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_2048. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_2048_output_s { - uint64_t n; /**< RSA key (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_2048_output_s +{ + uint64_t n; /**< RSA key (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_2048. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_2048_output_s { - uint64_t n; /**< RSA key (32 qwords)*/ - uint64_t d; /**< RSA private key (32 qwords)*/ - uint64_t dp; /**< RSA private key (16 qwords)*/ - uint64_t dq; /**< RSA private key (16 qwords)*/ - uint64_t qinv; /**< RSA private key (16 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_2048. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_2048_output_s +{ + uint64_t n; /**< RSA key (32 qwords)*/ + uint64_t d; /**< RSA private key (32 qwords)*/ + uint64_t dp; /**< RSA private key (16 qwords)*/ + uint64_t dq; /**< RSA private key (16 qwords)*/ + uint64_t qinv; /**< RSA private key (16 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_2048. */ -typedef struct icp_qat_fw_mmp_rsa_ep_2048_output_s { - uint64_t c; /**< cipher text representative, < n (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_2048_output_s +{ + uint64_t c; /**< cipher text representative, < n (32 qwords)*/ } icp_qat_fw_mmp_rsa_ep_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_2048. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_2048_output_s { - uint64_t m; /**< message representative, < n (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_2048_output_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 2048 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_2048. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_2048_output_s { - uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_2048_output_s +{ + uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 3072 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_3072. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_3072_output_s { - uint64_t n; /**< RSA key (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_3072_output_s +{ + uint64_t n; /**< RSA key (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 3072 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_3072. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_3072_output_s { - uint64_t n; /**< RSA key (48 qwords)*/ - uint64_t d; /**< RSA private key (48 qwords)*/ - uint64_t dp; /**< RSA private key (24 qwords)*/ - uint64_t dq; /**< RSA private key (24 qwords)*/ - uint64_t qinv; /**< RSA private key (24 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_3072. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_3072_output_s +{ + uint64_t n; /**< RSA key (48 qwords)*/ + uint64_t d; /**< RSA private key (48 qwords)*/ + uint64_t dp; /**< RSA private key (24 qwords)*/ + uint64_t dq; /**< RSA private key (24 qwords)*/ + uint64_t qinv; /**< RSA private key (24 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 3072 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_3072. */ -typedef struct icp_qat_fw_mmp_rsa_ep_3072_output_s { - uint64_t c; /**< cipher text representative, < n (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_3072_output_s +{ + uint64_t c; /**< cipher text representative, < n (48 qwords)*/ } icp_qat_fw_mmp_rsa_ep_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 3072 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_3072. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_3072_output_s { - uint64_t m; /**< message representative, < n (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_3072_output_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 3072 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_3072. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_3072_output_s { - uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_3072_output_s +{ + uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 key generation first form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP1_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP1_4096. */ -typedef struct icp_qat_fw_mmp_rsa_kp1_4096_output_s { - uint64_t n; /**< RSA key (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_kp1_4096_output_s +{ + uint64_t n; /**< RSA key (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ } icp_qat_fw_mmp_rsa_kp1_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 key generation second form , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_KP2_4096. - */ -typedef struct icp_qat_fw_mmp_rsa_kp2_4096_output_s { - uint64_t n; /**< RSA key (64 qwords)*/ - uint64_t d; /**< RSA private key (64 qwords)*/ - uint64_t dp; /**< RSA private key (32 qwords)*/ - uint64_t dq; /**< RSA private key (32 qwords)*/ - uint64_t qinv; /**< RSA private key (32 qwords)*/ + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_KP2_4096. + */ +typedef struct icp_qat_fw_mmp_rsa_kp2_4096_output_s +{ + uint64_t n; /**< RSA key (64 qwords)*/ + uint64_t d; /**< RSA private key (64 qwords)*/ + uint64_t dp; /**< RSA private key (32 qwords)*/ + uint64_t dq; /**< RSA private key (32 qwords)*/ + uint64_t qinv; /**< RSA private key (32 qwords)*/ } icp_qat_fw_mmp_rsa_kp2_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 Encryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_EP_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_EP_4096. */ -typedef struct icp_qat_fw_mmp_rsa_ep_4096_output_s { - uint64_t c; /**< cipher text representative, < n (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_ep_4096_output_s +{ + uint64_t c; /**< cipher text representative, < n (64 qwords)*/ } icp_qat_fw_mmp_rsa_ep_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 Decryption , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP1_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP1_4096. */ -typedef struct icp_qat_fw_mmp_rsa_dp1_4096_output_s { - uint64_t m; /**< message representative, < n (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp1_4096_output_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ } icp_qat_fw_mmp_rsa_dp1_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for RSA 4096 Decryption with CRT , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_RSA_DP2_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_RSA_DP2_4096. */ -typedef struct icp_qat_fw_mmp_rsa_dp2_4096_output_s { - uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ +typedef struct icp_qat_fw_mmp_rsa_dp2_4096_output_s +{ + uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ } icp_qat_fw_mmp_rsa_dp2_4096_output_t; /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for GCD primality test for 192-bit numbers , + * Output parameter list for RSA 8192 Encryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_RSA_EP_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_ep_8192_output_s +{ + uint64_t c; /**< cipher text representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_rsa_ep_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp1_8192_output_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp1_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Decryption with CRT , * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_192. + * #PKE_RSA_DP2_8192. + */ +typedef struct icp_qat_fw_mmp_rsa_dp2_8192_output_s +{ + uint64_t m; /**< message representative, < (p*q) (128 qwords)*/ +} icp_qat_fw_mmp_rsa_dp2_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for GCD primality test for 192-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_192. */ -typedef struct icp_qat_fw_mmp_gcd_pt_192_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_192_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_192_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 256-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_256. */ -typedef struct icp_qat_fw_mmp_gcd_pt_256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_256_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 384-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_384. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_384. */ -typedef struct icp_qat_fw_mmp_gcd_pt_384_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_384_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_384_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_512. */ -typedef struct icp_qat_fw_mmp_gcd_pt_512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_768. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_768. */ -typedef struct icp_qat_fw_mmp_gcd_pt_768_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_768_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_1024. */ -typedef struct icp_qat_fw_mmp_gcd_pt_1024_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_1024_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_1536. */ -typedef struct icp_qat_fw_mmp_gcd_pt_1536_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_1536_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_2048. */ -typedef struct icp_qat_fw_mmp_gcd_pt_2048_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_2048_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_3072. */ -typedef struct icp_qat_fw_mmp_gcd_pt_3072_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_3072_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for GCD primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_GCD_PT_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_GCD_PT_4096. */ -typedef struct icp_qat_fw_mmp_gcd_pt_4096_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_gcd_pt_4096_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_gcd_pt_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_160. */ -typedef struct icp_qat_fw_mmp_fermat_pt_160_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_160_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_512. */ -typedef struct icp_qat_fw_mmp_fermat_pt_512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Fermat primality test for <e; 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_L512. + * Output parameter list for Fermat primality test for <e; 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_L512. */ -typedef struct icp_qat_fw_mmp_fermat_pt_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_768. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_768. */ -typedef struct icp_qat_fw_mmp_fermat_pt_768_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_768_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_1024. */ -typedef struct icp_qat_fw_mmp_fermat_pt_1024_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_1024_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_1536. */ -typedef struct icp_qat_fw_mmp_fermat_pt_1536_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_1536_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_2048. */ -typedef struct icp_qat_fw_mmp_fermat_pt_2048_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_2048_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_3072. */ -typedef struct icp_qat_fw_mmp_fermat_pt_3072_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_3072_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Fermat primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_FERMAT_PT_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_FERMAT_PT_4096. */ -typedef struct icp_qat_fw_mmp_fermat_pt_4096_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_fermat_pt_4096_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_fermat_pt_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 160-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_160. + * Output parameter list for Miller-Rabin primality test for 160-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_160. */ -typedef struct icp_qat_fw_mmp_mr_pt_160_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_160_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_512. + * Output parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_512. */ -typedef struct icp_qat_fw_mmp_mr_pt_512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 768-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_768. + * Output parameter list for Miller-Rabin primality test for 768-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_768. */ -typedef struct icp_qat_fw_mmp_mr_pt_768_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_768_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 1024-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_1024. + * Output parameter list for Miller-Rabin primality test for 1024-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_1024. */ -typedef struct icp_qat_fw_mmp_mr_pt_1024_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_1024_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 1536-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_1536. + * Output parameter list for Miller-Rabin primality test for 1536-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_1536. */ -typedef struct icp_qat_fw_mmp_mr_pt_1536_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_1536_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 2048-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_2048. + * Output parameter list for Miller-Rabin primality test for 2048-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_2048. */ -typedef struct icp_qat_fw_mmp_mr_pt_2048_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_2048_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 3072-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_3072. + * Output parameter list for Miller-Rabin primality test for 3072-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_3072. */ -typedef struct icp_qat_fw_mmp_mr_pt_3072_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_3072_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 4096-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_4096. + * Output parameter list for Miller-Rabin primality test for 4096-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_4096. */ -typedef struct icp_qat_fw_mmp_mr_pt_4096_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_4096_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Miller-Rabin primality test for 512-bit numbers - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_MR_PT_L512. + * Output parameter list for Miller-Rabin primality test for 512-bit numbers , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_MR_PT_L512. */ -typedef struct icp_qat_fw_mmp_mr_pt_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_mr_pt_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_mr_pt_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 160-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_160. */ -typedef struct icp_qat_fw_mmp_lucas_pt_160_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_160_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_512. */ -typedef struct icp_qat_fw_mmp_lucas_pt_512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 768-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_768. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_768. */ -typedef struct icp_qat_fw_mmp_lucas_pt_768_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_768_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 1024-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_1024. */ -typedef struct icp_qat_fw_mmp_lucas_pt_1024_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_1024_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 1536-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_1536. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_1536. */ -typedef struct icp_qat_fw_mmp_lucas_pt_1536_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_1536_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 2048-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_2048. */ -typedef struct icp_qat_fw_mmp_lucas_pt_2048_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_2048_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 3072-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_3072. */ -typedef struct icp_qat_fw_mmp_lucas_pt_3072_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_3072_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for 4096-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_4096. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_4096. */ -typedef struct icp_qat_fw_mmp_lucas_pt_4096_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_4096_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_4096_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Lucas primality test for L512-bit numbers , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_LUCAS_PT_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_LUCAS_PT_L512. */ -typedef struct icp_qat_fw_mmp_lucas_pt_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_lucas_pt_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_lucas_pt_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 512-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L512. + * Output parameter list for Modular exponentiation for numbers less than 512-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L512. */ -typedef struct icp_qat_fw_maths_modexp_l512_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (8 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l512_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (8 qwords)*/ } icp_qat_fw_maths_modexp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 1024-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L1024. + * Output parameter list for Modular exponentiation for numbers less than 1024-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L1024. */ -typedef struct icp_qat_fw_maths_modexp_l1024_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l1024_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (16 qwords)*/ } icp_qat_fw_maths_modexp_l1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 1536-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L1536. + * Output parameter list for Modular exponentiation for numbers less than 1536-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L1536. */ -typedef struct icp_qat_fw_maths_modexp_l1536_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l1536_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (24 qwords)*/ } icp_qat_fw_maths_modexp_l1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 2048-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L2048. + * Output parameter list for Modular exponentiation for numbers less than 2048-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L2048. */ -typedef struct icp_qat_fw_maths_modexp_l2048_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l2048_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (32 qwords)*/ } icp_qat_fw_maths_modexp_l2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 2560-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L2560. + * Output parameter list for Modular exponentiation for numbers less than 2560-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L2560. */ -typedef struct icp_qat_fw_maths_modexp_l2560_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (40 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l2560_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (40 qwords)*/ } icp_qat_fw_maths_modexp_l2560_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 3072-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L3072. + * Output parameter list for Modular exponentiation for numbers less than 3072-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L3072. */ -typedef struct icp_qat_fw_maths_modexp_l3072_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l3072_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (48 qwords)*/ } icp_qat_fw_maths_modexp_l3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 3584-bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L3584. + * Output parameter list for Modular exponentiation for numbers less than 3584-bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L3584. */ -typedef struct icp_qat_fw_maths_modexp_l3584_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (56 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l3584_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (56 qwords)*/ } icp_qat_fw_maths_modexp_l3584_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular exponentiation for numbers less than - * 4096-bit , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODEXP_L4096. + * Output parameter list for Modular exponentiation for numbers less than 4096-bit , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODEXP_L4096. */ -typedef struct icp_qat_fw_maths_modexp_l4096_output_s { - uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 - qwords)*/ +typedef struct icp_qat_fw_maths_modexp_l4096_output_s +{ + uint64_t r; /**< modular exponentiation result ≥ 0 and < m (64 qwords)*/ } icp_qat_fw_maths_modexp_l4096_output_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular exponentiation for numbers up to 8192 + * bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODEXP_L8192. + */ +typedef struct icp_qat_fw_maths_modexp_l8192_output_s +{ + uint64_t + r; /**< modular exponentiation result ≥ 0 and < m (128 qwords)*/ +} icp_qat_fw_maths_modexp_l8192_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is + * than 128 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is * #MATHS_MODINV_ODD_L128. */ -typedef struct icp_qat_fw_maths_modinv_odd_l128_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (2 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l128_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (2 qwords)*/ } icp_qat_fw_maths_modinv_odd_l128_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L192. + * Output parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L192. */ -typedef struct icp_qat_fw_maths_modinv_odd_l192_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (3 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (3 qwords)*/ } icp_qat_fw_maths_modinv_odd_l192_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L256. + * Output parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L256. */ -typedef struct icp_qat_fw_maths_modinv_odd_l256_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (4 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l256_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (4 qwords)*/ } icp_qat_fw_maths_modinv_odd_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L384. + * Output parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L384. */ -typedef struct icp_qat_fw_maths_modinv_odd_l384_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (6 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l384_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (6 qwords)*/ } icp_qat_fw_maths_modinv_odd_l384_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L512. + * Output parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L512. */ -typedef struct icp_qat_fw_maths_modinv_odd_l512_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (8 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l512_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (8 qwords)*/ } icp_qat_fw_maths_modinv_odd_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L768. + * Output parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L768. */ -typedef struct icp_qat_fw_maths_modinv_odd_l768_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (12 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l768_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (12 qwords)*/ } icp_qat_fw_maths_modinv_odd_l768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L1024. + * Output parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L1024. */ -typedef struct icp_qat_fw_maths_modinv_odd_l1024_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (16 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l1024_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (16 qwords)*/ } icp_qat_fw_maths_modinv_odd_l1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L1536. + * Output parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L1536. */ -typedef struct icp_qat_fw_maths_modinv_odd_l1536_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (24 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l1536_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (24 qwords)*/ } icp_qat_fw_maths_modinv_odd_l1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L2048. + * Output parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L2048. */ -typedef struct icp_qat_fw_maths_modinv_odd_l2048_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (32 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l2048_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (32 qwords)*/ } icp_qat_fw_maths_modinv_odd_l2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L3072. + * Output parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L3072. */ -typedef struct icp_qat_fw_maths_modinv_odd_l3072_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (48 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l3072_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (48 qwords)*/ } icp_qat_fw_maths_modinv_odd_l3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_ODD_L4096. + * Output parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_ODD_L4096. */ -typedef struct icp_qat_fw_maths_modinv_odd_l4096_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (64 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_odd_l4096_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (64 qwords)*/ } icp_qat_fw_maths_modinv_odd_l4096_output_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_ODD_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_odd_l8192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (128 + qwords)*/ +} icp_qat_fw_maths_modinv_odd_l8192_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for Modular multiplicative inverse for numbers less - * than 128 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is + * than 128 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is * #MATHS_MODINV_EVEN_L128. */ -typedef struct icp_qat_fw_maths_modinv_even_l128_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (2 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l128_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (2 qwords)*/ } icp_qat_fw_maths_modinv_even_l128_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 192 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L192. + * Output parameter list for Modular multiplicative inverse for numbers less than 192 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L192. */ -typedef struct icp_qat_fw_maths_modinv_even_l192_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (3 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (3 qwords)*/ } icp_qat_fw_maths_modinv_even_l192_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 256 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L256. + * Output parameter list for Modular multiplicative inverse for numbers less than 256 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L256. */ -typedef struct icp_qat_fw_maths_modinv_even_l256_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (4 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l256_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (4 qwords)*/ } icp_qat_fw_maths_modinv_even_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 384 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L384. + * Output parameter list for Modular multiplicative inverse for numbers less than 384 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L384. */ -typedef struct icp_qat_fw_maths_modinv_even_l384_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (6 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l384_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (6 qwords)*/ } icp_qat_fw_maths_modinv_even_l384_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 512 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L512. + * Output parameter list for Modular multiplicative inverse for numbers less than 512 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L512. */ -typedef struct icp_qat_fw_maths_modinv_even_l512_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (8 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l512_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (8 qwords)*/ } icp_qat_fw_maths_modinv_even_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 768 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L768. + * Output parameter list for Modular multiplicative inverse for numbers less than 768 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L768. */ -typedef struct icp_qat_fw_maths_modinv_even_l768_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (12 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l768_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (12 qwords)*/ } icp_qat_fw_maths_modinv_even_l768_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1024 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L1024. + * Output parameter list for Modular multiplicative inverse for numbers less than 1024 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L1024. */ -typedef struct icp_qat_fw_maths_modinv_even_l1024_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (16 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l1024_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (16 qwords)*/ } icp_qat_fw_maths_modinv_even_l1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 1536 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L1536. + * Output parameter list for Modular multiplicative inverse for numbers less than 1536 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L1536. */ -typedef struct icp_qat_fw_maths_modinv_even_l1536_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (24 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l1536_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (24 qwords)*/ } icp_qat_fw_maths_modinv_even_l1536_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 2048 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L2048. + * Output parameter list for Modular multiplicative inverse for numbers less than 2048 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L2048. */ -typedef struct icp_qat_fw_maths_modinv_even_l2048_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (32 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l2048_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (32 qwords)*/ } icp_qat_fw_maths_modinv_even_l2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 3072 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L3072. + * Output parameter list for Modular multiplicative inverse for numbers less than 3072 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L3072. */ -typedef struct icp_qat_fw_maths_modinv_even_l3072_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (48 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l3072_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (48 qwords)*/ } icp_qat_fw_maths_modinv_even_l3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for Modular multiplicative inverse for numbers less - * than 4096 bits , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_MODINV_EVEN_L4096. + * Output parameter list for Modular multiplicative inverse for numbers less than 4096 bits , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_MODINV_EVEN_L4096. */ -typedef struct icp_qat_fw_maths_modinv_even_l4096_output_s { - uint64_t - c; /**< modular multiplicative inverse of a, > 0 and < b (64 - qwords)*/ +typedef struct icp_qat_fw_maths_modinv_even_l4096_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (64 qwords)*/ } icp_qat_fw_maths_modinv_even_l4096_output_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for Modular multiplicative inverse for numbers up to + * 8192 bits , to be used when icp_qat_fw_pke_response_s::functionalityId is + * #MATHS_MODINV_EVEN_L8192. + */ +typedef struct icp_qat_fw_maths_modinv_even_l8192_output_s +{ + uint64_t c; /**< modular multiplicative inverse of a, > 0 and < b (128 + qwords)*/ +} icp_qat_fw_maths_modinv_even_l8192_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_1024_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_1024_160. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_output_s { - uint64_t p; /**< candidate for DSA parameter p (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_1024_160_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (16 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_1024. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_output_s { - uint64_t g; /**< DSA parameter (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_1024_output_s +{ + uint64_t g; /**< DSA parameter (16 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_1024. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_1024. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_output_s { - uint64_t y; /**< DSA parameter (16 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_1024_output_s +{ + uint64_t y; /**< DSA parameter (16 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_1024_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_1024_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_1024_160. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_output_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_1024_160_output_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_160. */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_160_output_s { - uint64_t s; /**< s DSA 160-bits signature (3 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_s_160_output_s +{ + uint64_t s; /**< s DSA 160-bits signature (3 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_1024_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_1024_160. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_s { - uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ - uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_s +{ + uint64_t r; /**< DSA 160-bits signature (3 qwords)*/ + uint64_t s; /**< DSA 160-bits signature (3 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_1024_160. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_1024_160. */ -typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_dsa_verify_1024_160_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_dsa_verify_1024_160_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_2048_224. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_2048_224. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_output_s { - uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_224_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_2048. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_output_s { - uint64_t y; /**< DSA parameter (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_2048_output_s +{ + uint64_t y; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_224. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_2048_224. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_output_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_224_output_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_224. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_224. */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_224_output_s { - uint64_t s; /**< s DSA 224-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_s_224_output_s +{ + uint64_t s; /**< s DSA 224-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_224_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_224. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_224. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_s { - uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_s +{ + uint64_t r; /**< DSA 224-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 224-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_2048_224. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_2048_224. */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_224_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_dsa_verify_2048_224_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_2048_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_2048_256. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_output_s { - uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_2048_256_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (32 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_2048. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_2048. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_output_s { - uint64_t g; /**< DSA parameter (32 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_2048_output_s +{ + uint64_t g; /**< DSA parameter (32 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_2048_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_2048_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_2048_256. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_2048_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_S_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_S_256. */ -typedef struct icp_qat_fw_mmp_dsa_sign_s_256_output_s { - uint64_t s; /**< s DSA 256-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_s_256_output_s +{ + uint64_t s; /**< s DSA 256-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_s_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_2048_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_2048_256. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_2048_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_2048_256. */ -typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_dsa_verify_2048_256_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_dsa_verify_2048_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA parameter generation P , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_P_3072_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_P_3072_256. */ -typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_output_s { - uint64_t p; /**< candidate for DSA parameter p (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_p_3072_256_output_s +{ + uint64_t p; /**< candidate for DSA parameter p (48 qwords)*/ } icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation G , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_G_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_G_3072. */ -typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_output_s { - uint64_t g; /**< DSA parameter (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_g_3072_output_s +{ + uint64_t g; /**< DSA parameter (48 qwords)*/ } icp_qat_fw_mmp_dsa_gen_g_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA key generation Y , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_GEN_Y_3072. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_GEN_Y_3072. */ -typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_output_s { - uint64_t y; /**< DSA parameter (48 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_gen_y_3072_output_s +{ + uint64_t y; /**< DSA parameter (48 qwords)*/ } icp_qat_fw_mmp_dsa_gen_y_3072_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_3072_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_3072_256. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_3072_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Sign R S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_SIGN_R_S_3072_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_SIGN_R_S_3072_256. */ -typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_s { - uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ - uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_s +{ + uint64_t r; /**< DSA 256-bits signature (4 qwords)*/ + uint64_t s; /**< DSA 256-bits signature (4 qwords)*/ } icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for DSA Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_DSA_VERIFY_3072_256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_DSA_VERIFY_3072_256. */ -typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_dsa_verify_3072_256_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_dsa_verify_3072_256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA Sign RS for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ - uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ + uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA Sign R for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA Sign S for curves with n < 2^256 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA Verify for curves B/K-163 and B/K-233 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_s { - uint64_t r; /**< (8 qwords)*/ - uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s - > 0 and < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_s +{ + uint64_t r; /**< (8 qwords)*/ + uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s > 0 and < n (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Sign RS for curves B-571/K-571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GF2_571. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GF2_571. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_s { - uint64_t r; /**< (9 qwords)*/ - uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s - > 0 and < n (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_s +{ + uint64_t r; /**< (9 qwords)*/ + uint64_t s; /**< ECDSA signature r > 0 and < n ECDSA signature s > 0 and < n (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 - * , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GF2_571. + * Output parameter list for ECDSA GF2 Sign S for curves with deg(q) < 576 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GF2_571. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_s { - uint64_t s; /**< ECDSA signature s > 0 and < n (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_s +{ + uint64_t s; /**< ECDSA signature s > 0 and < n (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Sign R for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GF2_571. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GF2_571. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_s { - uint64_t r; /**< ECDSA signature r > 0 and < n (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_s +{ + uint64_t r; /**< ECDSA signature r > 0 and < n (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GF2 Verify for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GF2_571. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GF2_571. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L256. */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_output_s { - uint64_t xk; /**< x coordinate of resultant point (< degree(q)) (4 - qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (< degree(q)) (4 - qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (< degree(q)) (4 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (< degree(q)) (4 qwords)*/ } icp_qat_fw_maths_point_multiplication_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L256. */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l256_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gf2_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for MATHS GF2 Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_L512. */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_output_s { - uint64_t xk; /**< x coordinate of resultant point (< q) (8 qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (< q) (8 qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (< q) (8 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (< q) (8 qwords)*/ } icp_qat_fw_maths_point_multiplication_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for MATHS GF2 Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_L512. */ -typedef struct icp_qat_fw_maths_point_verify_gf2_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gf2_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gf2_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC GF2 Point Multiplication for curves - * B-571/K-571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GF2_571. + * Output parameter list for ECC GF2 Point Multiplication for curves B-571/K-571 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GF2_571. */ -typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_output_s { - uint64_t xk; /**< x coordinate of resultant point (degree < - degree(q)) (9 qwords)*/ - uint64_t yk; /**< y coordinate of resultant point (degree < - degree(q)) (9 qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gf2_571_output_s +{ + uint64_t xk; /**< x coordinate of resultant point (degree < degree(q)) (9 qwords)*/ + uint64_t yk; /**< y coordinate of resultant point (degree < degree(q)) (9 qwords)*/ } icp_qat_fw_maths_point_multiplication_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GF2 Point Verification for degree 571 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GF2_571. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GF2_571. */ -typedef struct icp_qat_fw_maths_point_verify_gf2_571_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gf2_571_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gf2_571_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_s { - uint64_t r; /**< ECDSA signature (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_s +{ + uint64_t r; /**< ECDSA signature (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_s { - uint64_t s; /**< ECDSA signature s (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_s +{ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_s { - uint64_t r; /**< ECDSA signature r (4 qwords)*/ - uint64_t s; /**< ECDSA signature s (4 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L256. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_s { - uint64_t r; /**< ECDSA signature (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_s +{ + uint64_t r; /**< ECDSA signature (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_s { - uint64_t s; /**< ECDSA signature s (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_s +{ + uint64_t s; /**< ECDSA signature s (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_s { - uint64_t r; /**< ECDSA signature r (8 qwords)*/ - uint64_t s; /**< ECDSA signature s (8 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_s +{ + uint64_t r; /**< ECDSA signature r (8 qwords)*/ + uint64_t s; /**< ECDSA signature s (8 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_L512. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign R , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_R_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_R_GFP_521. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_s { - uint64_t r; /**< ECDSA signature (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_s +{ + uint64_t r; /**< ECDSA signature (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign S , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_S_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_S_GFP_521. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_s { - uint64_t s; /**< ECDSA signature s (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_s +{ + uint64_t s; /**< ECDSA signature s (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Sign RS , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_SIGN_RS_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_SIGN_RS_GFP_521. */ -typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_s { - uint64_t r; /**< ECDSA signature r (9 qwords)*/ - uint64_t s; /**< ECDSA signature s (9 qwords)*/ +typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_s +{ + uint64_t r; /**< ECDSA signature r (9 qwords)*/ + uint64_t s; /**< ECDSA signature s (9 qwords)*/ } icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECDSA GFP Verify , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #PKE_ECDSA_VERIFY_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #PKE_ECDSA_VERIFY_GFP_521. */ -typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_s +{ + /* no output parameters */ } icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L256. */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (4 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (4 qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l256_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (4 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (4 qwords)*/ } icp_qat_fw_maths_point_multiplication_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L256. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L256. */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l256_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l256_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gfp_l256_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_L512. */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (8 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (8 qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_l512_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (8 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (8 qwords)*/ } icp_qat_fw_maths_point_multiplication_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Partial Point , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_L512. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_L512. */ -typedef struct icp_qat_fw_maths_point_verify_gfp_l512_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gfp_l512_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gfp_l512_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Point Multiplication , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_MULTIPLICATION_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_MULTIPLICATION_GFP_521. */ -typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_output_s { - uint64_t xk; /**< x coordinate of resultant EC point (9 qwords)*/ - uint64_t yk; /**< y coordinate of resultant EC point (9 qwords)*/ +typedef struct icp_qat_fw_maths_point_multiplication_gfp_521_output_s +{ + uint64_t xk; /**< x coordinate of resultant EC point (9 qwords)*/ + uint64_t yk; /**< y coordinate of resultant EC point (9 qwords)*/ } icp_qat_fw_maths_point_multiplication_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief * Output parameter list for ECC GFP Partial Point Verification , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #MATHS_POINT_VERIFY_GFP_521. + * to be used when icp_qat_fw_pke_response_s::functionalityId is #MATHS_POINT_VERIFY_GFP_521. */ -typedef struct icp_qat_fw_maths_point_verify_gfp_521_output_s { - /* no output parameters */ +typedef struct icp_qat_fw_maths_point_verify_gfp_521_output_s +{ + /* no output parameters */ } icp_qat_fw_maths_point_verify_gfp_521_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC curve25519 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_C25519. + * Output parameter list for ECC curve25519 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_C25519. */ -typedef struct icp_qat_fw_point_multiplication_c25519_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]P (4 - qwords)*/ +typedef struct icp_qat_fw_point_multiplication_c25519_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]P (4 qwords)*/ } icp_qat_fw_point_multiplication_c25519_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC curve25519 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C25519. + * Output parameter list for ECC curve25519 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_C25519. */ -typedef struct icp_qat_fw_generator_multiplication_c25519_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]G (4 - qwords)*/ +typedef struct icp_qat_fw_generator_multiplication_c25519_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]G (4 qwords)*/ } icp_qat_fw_generator_multiplication_c25519_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC edwards25519 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_point_multiplication_ed25519_output_s { - uint64_t - xr; /**< xR = Twisted Edwards affine coordinate X of point [k]P (4 - qwords)*/ - uint64_t - yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]P (4 - qwords)*/ + * Output parameter list for ECC edwards25519 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_point_multiplication_ed25519_output_s +{ + uint64_t xr; /**< xR = Twisted Edwards affine coordinate X of point [k]P (4 qwords)*/ + uint64_t yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]P (4 qwords)*/ } icp_qat_fw_point_multiplication_ed25519_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC edwards25519 Generator Point Multiplication - * [k]G, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED25519. - */ -typedef struct icp_qat_fw_generator_multiplication_ed25519_output_s { - uint64_t - xr; /**< xR = Twisted Edwards affine coordinate X of point [k]G (4 - qwords)*/ - uint64_t - yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]G (4 - qwords)*/ + * Output parameter list for ECC edwards25519 Generator Point Multiplication [k]G, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_ED25519. + */ +typedef struct icp_qat_fw_generator_multiplication_ed25519_output_s +{ + uint64_t xr; /**< xR = Twisted Edwards affine coordinate X of point [k]G (4 qwords)*/ + uint64_t yr; /**< yR = Twisted Edwards affine coordinate Y of point [k]G (4 qwords)*/ } icp_qat_fw_generator_multiplication_ed25519_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC curve448 Variable Point Multiplication - * [k]P(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_C448. + * Output parameter list for ECC curve448 Variable Point Multiplication [k]P(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_C448. */ -typedef struct icp_qat_fw_point_multiplication_c448_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]P (8 - qwords)*/ +typedef struct icp_qat_fw_point_multiplication_c448_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]P (8 qwords)*/ } icp_qat_fw_point_multiplication_c448_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC curve448 Generator Point Multiplication - * [k]G(x), as specified in RFC7748 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_C448. + * Output parameter list for ECC curve448 Generator Point Multiplication [k]G(x), as specified in RFC7748 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_C448. */ -typedef struct icp_qat_fw_generator_multiplication_c448_output_s { - uint64_t - xr; /**< xR = Montgomery affine coordinate X of point [k]G (8 - qwords)*/ +typedef struct icp_qat_fw_generator_multiplication_c448_output_s +{ + uint64_t xr; /**< xR = Montgomery affine coordinate X of point [k]G (8 qwords)*/ } icp_qat_fw_generator_multiplication_c448_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC edwards448 Variable Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #POINT_MULTIPLICATION_ED448. + * Output parameter list for ECC edwards448 Variable Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #POINT_MULTIPLICATION_ED448. */ -typedef struct icp_qat_fw_point_multiplication_ed448_output_s { - uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]P (8 - qwords)*/ - uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]P (8 - qwords)*/ +typedef struct icp_qat_fw_point_multiplication_ed448_output_s +{ + uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]P (8 qwords)*/ + uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]P (8 qwords)*/ } icp_qat_fw_point_multiplication_ed448_output_t; + + /** * @ingroup icp_qat_fw_mmp * @brief - * Output parameter list for ECC edwards448 Generator Point Multiplication - * [k]P, as specified in RFC8032 , - * to be used when icp_qat_fw_pke_response_s::functionalityId is - * #GENERATOR_MULTIPLICATION_ED448. + * Output parameter list for ECC edwards448 Generator Point Multiplication [k]P, as specified in RFC8032 , + * to be used when icp_qat_fw_pke_response_s::functionalityId is #GENERATOR_MULTIPLICATION_ED448. */ -typedef struct icp_qat_fw_generator_multiplication_ed448_output_s { - uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]G (8 - qwords)*/ - uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]G (8 - qwords)*/ +typedef struct icp_qat_fw_generator_multiplication_ed448_output_s +{ + uint64_t xr; /**< xR = Edwards affine coordinate X of point [k]G (8 qwords)*/ + uint64_t yr; /**< yR = Edwards affine coordinate Y of point [k]G (8 qwords)*/ } icp_qat_fw_generator_multiplication_ed448_output_t; +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P521 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P521. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC P384 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P384. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s +{ + uint64_t r; /**< ECDSA signature r (6 qwords)*/ + uint64_t s; /**< ECDSA signature s (6 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for ECC KPT P256 ECDSA Sign RS , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_ECDSA_SIGN_RS_P256. + */ +typedef struct icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s +{ + uint64_t r; /**< ECDSA signature r (4 qwords)*/ + uint64_t s; /**< ECDSA signature s (4 qwords)*/ +} icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 512 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_512_output_s +{ + uint64_t m; /**< message representative, < n (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_512_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 1024 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_s +{ + uint64_t m; /**< message representative, < n (16 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 1536 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_1536. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_s +{ + uint64_t m; /**< message representative, < n (24 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 2048 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_2048. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_s +{ + uint64_t m; /**< message representative, < n (32 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 3072 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_3072. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_s +{ + uint64_t m; /**< message representative, < n (48 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 4096 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_s +{ + uint64_t m; /**< message representative, < n (64 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 8192 Decryption , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP1_8192. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_s +{ + uint64_t m; /**< message representative, < n (128 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 512 decryption second form , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_512. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_512_output_s +{ + uint64_t m; /**< message representative, < (p*q) (8 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_512_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 1024 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_1024. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_s +{ + uint64_t m; /**< message representative, < (p*q) (16 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for KPT RSA 1536 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_1536. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_s +{ + uint64_t m; /**< message representative, < (p*q) (24 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 2048 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_2048. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_s +{ + uint64_t m; /**< message representative, < (p*q) (32 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_3072. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_s +{ + uint64_t m; /**< message representative, < (p*q) (48 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 4096 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_4096. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_s +{ + uint64_t m; /**< message representative, < (p*q) (64 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_t; + +/** + * @ingroup icp_qat_fw_mmp + * @brief + * Output parameter list for RSA 8192 Decryption with CRT , + * to be used when icp_qat_fw_pke_response_s::functionalityId is + * #PKE_KPT_RSA_DP2_8192. + */ +typedef struct icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_s +{ + uint64_t m; /**< message representative, < (p*q) (128 qwords)*/ +} icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_t; + /** * @ingroup icp_qat_fw_mmp * @brief * MMP output parameters */ -typedef union icp_qat_fw_mmp_output_param_u { - /** Generic parameter structure : All members of this wrapper structure - * are pointers to large integers. - */ - uint64_t flat_array[ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX]; +typedef union icp_qat_fw_mmp_output_param_u +{ + /** Generic parameter structure : All members of this wrapper structure + * are pointers to large integers. + */ + uint64_t flat_array[ICP_QAT_FW_PKE_OUTPUT_COUNT_MAX]; + + /** ECC P384 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p384_output_t + mmp_ec_point_multiplication_p384; + + /** ECC P384 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p384_output_t + mmp_ec_generator_multiplication_p384; + + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_t mmp_ecdsa_sign_rs_p384; + + /** ECC P256 Variable Point Multiplication [k]P */ + icp_qat_fw_mmp_ec_point_multiplication_p256_output_t + mmp_ec_point_multiplication_p256; - /** Initialisation sequence */ - icp_qat_fw_mmp_init_output_t mmp_init; + /** ECC P256 Generator Point Multiplication [k]G */ + icp_qat_fw_mmp_ec_generator_multiplication_p256_output_t + mmp_ec_generator_multiplication_p256; - /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ - icp_qat_fw_mmp_dh_g2_768_output_t mmp_dh_g2_768; + /** ECC P256 ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_t mmp_ecdsa_sign_rs_p256; - /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ - icp_qat_fw_mmp_dh_768_output_t mmp_dh_768; + /** ECC SM2 point multiply [k]G */ + icp_qat_fw_mmp_ecsm2_generator_multiplication_output_t + mmp_ecsm2_generator_multiplication; - /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ - icp_qat_fw_mmp_dh_g2_1024_output_t mmp_dh_g2_1024; + /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified in + * RFC7748 */ + icp_qat_fw_point_multiplication_c25519_output_t point_multiplication_c25519; - /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ - icp_qat_fw_mmp_dh_1024_output_t mmp_dh_1024; + /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified in + * RFC7748 */ + icp_qat_fw_generator_multiplication_c25519_output_t + generator_multiplication_c25519; - /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ - icp_qat_fw_mmp_dh_g2_1536_output_t mmp_dh_g2_1536; + /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in + * RFC8032 */ + icp_qat_fw_point_multiplication_ed25519_output_t + point_multiplication_ed25519; - /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ - icp_qat_fw_mmp_dh_1536_output_t mmp_dh_1536; + /** ECC edwards25519 Generator Point Multiplication [k]G, as specified in + * RFC8032 */ + icp_qat_fw_generator_multiplication_ed25519_output_t + generator_multiplication_ed25519; - /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ - icp_qat_fw_mmp_dh_g2_2048_output_t mmp_dh_g2_2048; + /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in + * RFC7748 */ + icp_qat_fw_point_multiplication_c448_output_t point_multiplication_c448; - /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ - icp_qat_fw_mmp_dh_2048_output_t mmp_dh_2048; + /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in + * RFC7748 */ + icp_qat_fw_generator_multiplication_c448_output_t + generator_multiplication_c448; - /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ - icp_qat_fw_mmp_dh_g2_3072_output_t mmp_dh_g2_3072; + /** ECC edwards448 Variable Point Multiplication [k]P, as specified in + * RFC8032 */ + icp_qat_fw_point_multiplication_ed448_output_t point_multiplication_ed448; - /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ - icp_qat_fw_mmp_dh_3072_output_t mmp_dh_3072; + /** ECC edwards448 Generator Point Multiplication [k]G, as specified in + * RFC8032 */ + icp_qat_fw_generator_multiplication_ed448_output_t + generator_multiplication_ed448; - /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ - icp_qat_fw_mmp_dh_g2_4096_output_t mmp_dh_g2_4096; + /** Initialisation sequence */ + icp_qat_fw_mmp_init_output_t mmp_init; - /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ - icp_qat_fw_mmp_dh_4096_output_t mmp_dh_4096; + /** Diffie-Hellman Modular exponentiation base 2 for 768-bit numbers */ + icp_qat_fw_mmp_dh_g2_768_output_t mmp_dh_g2_768; - /** RSA 512 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_512_output_t mmp_rsa_kp1_512; + /** Diffie-Hellman Modular exponentiation for 768-bit numbers */ + icp_qat_fw_mmp_dh_768_output_t mmp_dh_768; - /** RSA 512 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_512_output_t mmp_rsa_kp2_512; + /** Diffie-Hellman Modular exponentiation base 2 for 1024-bit numbers */ + icp_qat_fw_mmp_dh_g2_1024_output_t mmp_dh_g2_1024; - /** RSA 512 Encryption */ - icp_qat_fw_mmp_rsa_ep_512_output_t mmp_rsa_ep_512; + /** Diffie-Hellman Modular exponentiation for 1024-bit numbers */ + icp_qat_fw_mmp_dh_1024_output_t mmp_dh_1024; - /** RSA 512 Decryption */ - icp_qat_fw_mmp_rsa_dp1_512_output_t mmp_rsa_dp1_512; + /** Diffie-Hellman Modular exponentiation base 2 for 1536-bit numbers */ + icp_qat_fw_mmp_dh_g2_1536_output_t mmp_dh_g2_1536; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_512_output_t mmp_rsa_dp2_512; + /** Diffie-Hellman Modular exponentiation for 1536-bit numbers */ + icp_qat_fw_mmp_dh_1536_output_t mmp_dh_1536; - /** RSA 1024 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1024_output_t mmp_rsa_kp1_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 2048-bit numbers */ + icp_qat_fw_mmp_dh_g2_2048_output_t mmp_dh_g2_2048; - /** RSA 1024 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1024_output_t mmp_rsa_kp2_1024; + /** Diffie-Hellman Modular exponentiation for 2048-bit numbers */ + icp_qat_fw_mmp_dh_2048_output_t mmp_dh_2048; - /** RSA 1024 Encryption */ - icp_qat_fw_mmp_rsa_ep_1024_output_t mmp_rsa_ep_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 3072-bit numbers */ + icp_qat_fw_mmp_dh_g2_3072_output_t mmp_dh_g2_3072; - /** RSA 1024 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1024_output_t mmp_rsa_dp1_1024; + /** Diffie-Hellman Modular exponentiation for 3072-bit numbers */ + icp_qat_fw_mmp_dh_3072_output_t mmp_dh_3072; - /** RSA 1024 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1024_output_t mmp_rsa_dp2_1024; + /** Diffie-Hellman Modular exponentiation base 2 for 4096-bit numbers */ + icp_qat_fw_mmp_dh_g2_4096_output_t mmp_dh_g2_4096; - /** RSA 1536 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_1536_output_t mmp_rsa_kp1_1536; + /** Diffie-Hellman Modular exponentiation for 4096-bit numbers */ + icp_qat_fw_mmp_dh_4096_output_t mmp_dh_4096; - /** RSA 1536 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_1536_output_t mmp_rsa_kp2_1536; + /** Diffie-Hellman Modular exponentiation base 2 for 8192-bit numbers */ + icp_qat_fw_mmp_dh_g2_8192_output_t mmp_dh_g2_8192; - /** RSA 1536 Encryption */ - icp_qat_fw_mmp_rsa_ep_1536_output_t mmp_rsa_ep_1536; + /** Diffie-Hellman Modular exponentiation for 8192-bit numbers */ + icp_qat_fw_mmp_dh_8192_output_t mmp_dh_8192; - /** RSA 1536 Decryption */ - icp_qat_fw_mmp_rsa_dp1_1536_output_t mmp_rsa_dp1_1536; + /** RSA 512 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_512_output_t mmp_rsa_kp1_512; - /** RSA 1536 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_1536_output_t mmp_rsa_dp2_1536; + /** RSA 512 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_512_output_t mmp_rsa_kp2_512; - /** RSA 2048 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_2048_output_t mmp_rsa_kp1_2048; + /** RSA 512 Encryption */ + icp_qat_fw_mmp_rsa_ep_512_output_t mmp_rsa_ep_512; - /** RSA 2048 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_2048_output_t mmp_rsa_kp2_2048; + /** RSA 512 Decryption */ + icp_qat_fw_mmp_rsa_dp1_512_output_t mmp_rsa_dp1_512; - /** RSA 2048 Encryption */ - icp_qat_fw_mmp_rsa_ep_2048_output_t mmp_rsa_ep_2048; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_512_output_t mmp_rsa_dp2_512; - /** RSA 2048 Decryption */ - icp_qat_fw_mmp_rsa_dp1_2048_output_t mmp_rsa_dp1_2048; + /** RSA 1024 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1024_output_t mmp_rsa_kp1_1024; - /** RSA 2048 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_2048_output_t mmp_rsa_dp2_2048; + /** RSA 1024 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1024_output_t mmp_rsa_kp2_1024; - /** RSA 3072 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_3072_output_t mmp_rsa_kp1_3072; + /** RSA 1024 Encryption */ + icp_qat_fw_mmp_rsa_ep_1024_output_t mmp_rsa_ep_1024; - /** RSA 3072 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_3072_output_t mmp_rsa_kp2_3072; + /** RSA 1024 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1024_output_t mmp_rsa_dp1_1024; - /** RSA 3072 Encryption */ - icp_qat_fw_mmp_rsa_ep_3072_output_t mmp_rsa_ep_3072; + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1024_output_t mmp_rsa_dp2_1024; - /** RSA 3072 Decryption */ - icp_qat_fw_mmp_rsa_dp1_3072_output_t mmp_rsa_dp1_3072; + /** RSA 1536 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_1536_output_t mmp_rsa_kp1_1536; - /** RSA 3072 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_3072_output_t mmp_rsa_dp2_3072; + /** RSA 1536 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_1536_output_t mmp_rsa_kp2_1536; - /** RSA 4096 key generation first form */ - icp_qat_fw_mmp_rsa_kp1_4096_output_t mmp_rsa_kp1_4096; + /** RSA 1536 Encryption */ + icp_qat_fw_mmp_rsa_ep_1536_output_t mmp_rsa_ep_1536; - /** RSA 4096 key generation second form */ - icp_qat_fw_mmp_rsa_kp2_4096_output_t mmp_rsa_kp2_4096; + /** RSA 1536 Decryption */ + icp_qat_fw_mmp_rsa_dp1_1536_output_t mmp_rsa_dp1_1536; - /** RSA 4096 Encryption */ - icp_qat_fw_mmp_rsa_ep_4096_output_t mmp_rsa_ep_4096; + /** RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_1536_output_t mmp_rsa_dp2_1536; - /** RSA 4096 Decryption */ - icp_qat_fw_mmp_rsa_dp1_4096_output_t mmp_rsa_dp1_4096; + /** RSA 2048 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_2048_output_t mmp_rsa_kp1_2048; - /** RSA 4096 Decryption with CRT */ - icp_qat_fw_mmp_rsa_dp2_4096_output_t mmp_rsa_dp2_4096; + /** RSA 2048 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_2048_output_t mmp_rsa_kp2_2048; - /** GCD primality test for 192-bit numbers */ - icp_qat_fw_mmp_gcd_pt_192_output_t mmp_gcd_pt_192; + /** RSA 2048 Encryption */ + icp_qat_fw_mmp_rsa_ep_2048_output_t mmp_rsa_ep_2048; - /** GCD primality test for 256-bit numbers */ - icp_qat_fw_mmp_gcd_pt_256_output_t mmp_gcd_pt_256; + /** RSA 2048 Decryption */ + icp_qat_fw_mmp_rsa_dp1_2048_output_t mmp_rsa_dp1_2048; - /** GCD primality test for 384-bit numbers */ - icp_qat_fw_mmp_gcd_pt_384_output_t mmp_gcd_pt_384; + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_2048_output_t mmp_rsa_dp2_2048; - /** GCD primality test for 512-bit numbers */ - icp_qat_fw_mmp_gcd_pt_512_output_t mmp_gcd_pt_512; + /** RSA 3072 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_3072_output_t mmp_rsa_kp1_3072; - /** GCD primality test for 768-bit numbers */ - icp_qat_fw_mmp_gcd_pt_768_output_t mmp_gcd_pt_768; + /** RSA 3072 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_3072_output_t mmp_rsa_kp2_3072; - /** GCD primality test for 1024-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1024_output_t mmp_gcd_pt_1024; + /** RSA 3072 Encryption */ + icp_qat_fw_mmp_rsa_ep_3072_output_t mmp_rsa_ep_3072; - /** GCD primality test for 1536-bit numbers */ - icp_qat_fw_mmp_gcd_pt_1536_output_t mmp_gcd_pt_1536; + /** RSA 3072 Decryption */ + icp_qat_fw_mmp_rsa_dp1_3072_output_t mmp_rsa_dp1_3072; - /** GCD primality test for 2048-bit numbers */ - icp_qat_fw_mmp_gcd_pt_2048_output_t mmp_gcd_pt_2048; + /** RSA 3072 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_3072_output_t mmp_rsa_dp2_3072; - /** GCD primality test for 3072-bit numbers */ - icp_qat_fw_mmp_gcd_pt_3072_output_t mmp_gcd_pt_3072; + /** RSA 4096 key generation first form */ + icp_qat_fw_mmp_rsa_kp1_4096_output_t mmp_rsa_kp1_4096; - /** GCD primality test for 4096-bit numbers */ - icp_qat_fw_mmp_gcd_pt_4096_output_t mmp_gcd_pt_4096; + /** RSA 4096 key generation second form */ + icp_qat_fw_mmp_rsa_kp2_4096_output_t mmp_rsa_kp2_4096; - /** Fermat primality test for 160-bit numbers */ - icp_qat_fw_mmp_fermat_pt_160_output_t mmp_fermat_pt_160; + /** RSA 4096 Encryption */ + icp_qat_fw_mmp_rsa_ep_4096_output_t mmp_rsa_ep_4096; - /** Fermat primality test for 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_512_output_t mmp_fermat_pt_512; + /** RSA 4096 Decryption */ + icp_qat_fw_mmp_rsa_dp1_4096_output_t mmp_rsa_dp1_4096; - /** Fermat primality test for <e; 512-bit numbers */ - icp_qat_fw_mmp_fermat_pt_l512_output_t mmp_fermat_pt_l512; + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_4096_output_t mmp_rsa_dp2_4096; - /** Fermat primality test for 768-bit numbers */ - icp_qat_fw_mmp_fermat_pt_768_output_t mmp_fermat_pt_768; + /** RSA 8192 Encryption */ + icp_qat_fw_mmp_rsa_ep_8192_output_t mmp_rsa_ep_8192; - /** Fermat primality test for 1024-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1024_output_t mmp_fermat_pt_1024; + /** RSA 8192 Decryption */ + icp_qat_fw_mmp_rsa_dp1_8192_output_t mmp_rsa_dp1_8192; - /** Fermat primality test for 1536-bit numbers */ - icp_qat_fw_mmp_fermat_pt_1536_output_t mmp_fermat_pt_1536; + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_rsa_dp2_8192_output_t mmp_rsa_dp2_8192; - /** Fermat primality test for 2048-bit numbers */ - icp_qat_fw_mmp_fermat_pt_2048_output_t mmp_fermat_pt_2048; + /** GCD primality test for 192-bit numbers */ + icp_qat_fw_mmp_gcd_pt_192_output_t mmp_gcd_pt_192; - /** Fermat primality test for 3072-bit numbers */ - icp_qat_fw_mmp_fermat_pt_3072_output_t mmp_fermat_pt_3072; + /** GCD primality test for 256-bit numbers */ + icp_qat_fw_mmp_gcd_pt_256_output_t mmp_gcd_pt_256; - /** Fermat primality test for 4096-bit numbers */ - icp_qat_fw_mmp_fermat_pt_4096_output_t mmp_fermat_pt_4096; + /** GCD primality test for 384-bit numbers */ + icp_qat_fw_mmp_gcd_pt_384_output_t mmp_gcd_pt_384; - /** Miller-Rabin primality test for 160-bit numbers */ - icp_qat_fw_mmp_mr_pt_160_output_t mmp_mr_pt_160; + /** GCD primality test for 512-bit numbers */ + icp_qat_fw_mmp_gcd_pt_512_output_t mmp_gcd_pt_512; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_512_output_t mmp_mr_pt_512; + /** GCD primality test for 768-bit numbers */ + icp_qat_fw_mmp_gcd_pt_768_output_t mmp_gcd_pt_768; - /** Miller-Rabin primality test for 768-bit numbers */ - icp_qat_fw_mmp_mr_pt_768_output_t mmp_mr_pt_768; + /** GCD primality test for 1024-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1024_output_t mmp_gcd_pt_1024; - /** Miller-Rabin primality test for 1024-bit numbers */ - icp_qat_fw_mmp_mr_pt_1024_output_t mmp_mr_pt_1024; + /** GCD primality test for 1536-bit numbers */ + icp_qat_fw_mmp_gcd_pt_1536_output_t mmp_gcd_pt_1536; - /** Miller-Rabin primality test for 1536-bit numbers */ - icp_qat_fw_mmp_mr_pt_1536_output_t mmp_mr_pt_1536; + /** GCD primality test for 2048-bit numbers */ + icp_qat_fw_mmp_gcd_pt_2048_output_t mmp_gcd_pt_2048; - /** Miller-Rabin primality test for 2048-bit numbers */ - icp_qat_fw_mmp_mr_pt_2048_output_t mmp_mr_pt_2048; + /** GCD primality test for 3072-bit numbers */ + icp_qat_fw_mmp_gcd_pt_3072_output_t mmp_gcd_pt_3072; - /** Miller-Rabin primality test for 3072-bit numbers */ - icp_qat_fw_mmp_mr_pt_3072_output_t mmp_mr_pt_3072; + /** GCD primality test for 4096-bit numbers */ + icp_qat_fw_mmp_gcd_pt_4096_output_t mmp_gcd_pt_4096; - /** Miller-Rabin primality test for 4096-bit numbers */ - icp_qat_fw_mmp_mr_pt_4096_output_t mmp_mr_pt_4096; + /** Fermat primality test for 160-bit numbers */ + icp_qat_fw_mmp_fermat_pt_160_output_t mmp_fermat_pt_160; - /** Miller-Rabin primality test for 512-bit numbers */ - icp_qat_fw_mmp_mr_pt_l512_output_t mmp_mr_pt_l512; + /** Fermat primality test for 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_512_output_t mmp_fermat_pt_512; - /** Lucas primality test for 160-bit numbers */ - icp_qat_fw_mmp_lucas_pt_160_output_t mmp_lucas_pt_160; + /** Fermat primality test for <e; 512-bit numbers */ + icp_qat_fw_mmp_fermat_pt_l512_output_t mmp_fermat_pt_l512; - /** Lucas primality test for 512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_512_output_t mmp_lucas_pt_512; + /** Fermat primality test for 768-bit numbers */ + icp_qat_fw_mmp_fermat_pt_768_output_t mmp_fermat_pt_768; - /** Lucas primality test for 768-bit numbers */ - icp_qat_fw_mmp_lucas_pt_768_output_t mmp_lucas_pt_768; + /** Fermat primality test for 1024-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1024_output_t mmp_fermat_pt_1024; - /** Lucas primality test for 1024-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1024_output_t mmp_lucas_pt_1024; + /** Fermat primality test for 1536-bit numbers */ + icp_qat_fw_mmp_fermat_pt_1536_output_t mmp_fermat_pt_1536; - /** Lucas primality test for 1536-bit numbers */ - icp_qat_fw_mmp_lucas_pt_1536_output_t mmp_lucas_pt_1536; + /** Fermat primality test for 2048-bit numbers */ + icp_qat_fw_mmp_fermat_pt_2048_output_t mmp_fermat_pt_2048; - /** Lucas primality test for 2048-bit numbers */ - icp_qat_fw_mmp_lucas_pt_2048_output_t mmp_lucas_pt_2048; + /** Fermat primality test for 3072-bit numbers */ + icp_qat_fw_mmp_fermat_pt_3072_output_t mmp_fermat_pt_3072; - /** Lucas primality test for 3072-bit numbers */ - icp_qat_fw_mmp_lucas_pt_3072_output_t mmp_lucas_pt_3072; + /** Fermat primality test for 4096-bit numbers */ + icp_qat_fw_mmp_fermat_pt_4096_output_t mmp_fermat_pt_4096; - /** Lucas primality test for 4096-bit numbers */ - icp_qat_fw_mmp_lucas_pt_4096_output_t mmp_lucas_pt_4096; + /** Miller-Rabin primality test for 160-bit numbers */ + icp_qat_fw_mmp_mr_pt_160_output_t mmp_mr_pt_160; - /** Lucas primality test for L512-bit numbers */ - icp_qat_fw_mmp_lucas_pt_l512_output_t mmp_lucas_pt_l512; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_512_output_t mmp_mr_pt_512; - /** Modular exponentiation for numbers less than 512-bits */ - icp_qat_fw_maths_modexp_l512_output_t maths_modexp_l512; + /** Miller-Rabin primality test for 768-bit numbers */ + icp_qat_fw_mmp_mr_pt_768_output_t mmp_mr_pt_768; - /** Modular exponentiation for numbers less than 1024-bit */ - icp_qat_fw_maths_modexp_l1024_output_t maths_modexp_l1024; + /** Miller-Rabin primality test for 1024-bit numbers */ + icp_qat_fw_mmp_mr_pt_1024_output_t mmp_mr_pt_1024; - /** Modular exponentiation for numbers less than 1536-bits */ - icp_qat_fw_maths_modexp_l1536_output_t maths_modexp_l1536; + /** Miller-Rabin primality test for 1536-bit numbers */ + icp_qat_fw_mmp_mr_pt_1536_output_t mmp_mr_pt_1536; - /** Modular exponentiation for numbers less than 2048-bit */ - icp_qat_fw_maths_modexp_l2048_output_t maths_modexp_l2048; + /** Miller-Rabin primality test for 2048-bit numbers */ + icp_qat_fw_mmp_mr_pt_2048_output_t mmp_mr_pt_2048; - /** Modular exponentiation for numbers less than 2560-bits */ - icp_qat_fw_maths_modexp_l2560_output_t maths_modexp_l2560; + /** Miller-Rabin primality test for 3072-bit numbers */ + icp_qat_fw_mmp_mr_pt_3072_output_t mmp_mr_pt_3072; - /** Modular exponentiation for numbers less than 3072-bits */ - icp_qat_fw_maths_modexp_l3072_output_t maths_modexp_l3072; + /** Miller-Rabin primality test for 4096-bit numbers */ + icp_qat_fw_mmp_mr_pt_4096_output_t mmp_mr_pt_4096; - /** Modular exponentiation for numbers less than 3584-bits */ - icp_qat_fw_maths_modexp_l3584_output_t maths_modexp_l3584; + /** Miller-Rabin primality test for 512-bit numbers */ + icp_qat_fw_mmp_mr_pt_l512_output_t mmp_mr_pt_l512; - /** Modular exponentiation for numbers less than 4096-bit */ - icp_qat_fw_maths_modexp_l4096_output_t maths_modexp_l4096; + /** Lucas primality test for 160-bit numbers */ + icp_qat_fw_mmp_lucas_pt_160_output_t mmp_lucas_pt_160; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_odd_l128_output_t maths_modinv_odd_l128; + /** Lucas primality test for 512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_512_output_t mmp_lucas_pt_512; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_odd_l192_output_t maths_modinv_odd_l192; + /** Lucas primality test for 768-bit numbers */ + icp_qat_fw_mmp_lucas_pt_768_output_t mmp_lucas_pt_768; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_odd_l256_output_t maths_modinv_odd_l256; + /** Lucas primality test for 1024-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1024_output_t mmp_lucas_pt_1024; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_odd_l384_output_t maths_modinv_odd_l384; + /** Lucas primality test for 1536-bit numbers */ + icp_qat_fw_mmp_lucas_pt_1536_output_t mmp_lucas_pt_1536; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_odd_l512_output_t maths_modinv_odd_l512; + /** Lucas primality test for 2048-bit numbers */ + icp_qat_fw_mmp_lucas_pt_2048_output_t mmp_lucas_pt_2048; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_odd_l768_output_t maths_modinv_odd_l768; + /** Lucas primality test for 3072-bit numbers */ + icp_qat_fw_mmp_lucas_pt_3072_output_t mmp_lucas_pt_3072; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_odd_l1024_output_t maths_modinv_odd_l1024; + /** Lucas primality test for 4096-bit numbers */ + icp_qat_fw_mmp_lucas_pt_4096_output_t mmp_lucas_pt_4096; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_odd_l1536_output_t maths_modinv_odd_l1536; + /** Lucas primality test for L512-bit numbers */ + icp_qat_fw_mmp_lucas_pt_l512_output_t mmp_lucas_pt_l512; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_odd_l2048_output_t maths_modinv_odd_l2048; + /** Modular exponentiation for numbers less than 512-bits */ + icp_qat_fw_maths_modexp_l512_output_t maths_modexp_l512; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_odd_l3072_output_t maths_modinv_odd_l3072; + /** Modular exponentiation for numbers less than 1024-bit */ + icp_qat_fw_maths_modexp_l1024_output_t maths_modexp_l1024; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_odd_l4096_output_t maths_modinv_odd_l4096; + /** Modular exponentiation for numbers less than 1536-bits */ + icp_qat_fw_maths_modexp_l1536_output_t maths_modexp_l1536; - /** Modular multiplicative inverse for numbers less than 128 bits */ - icp_qat_fw_maths_modinv_even_l128_output_t maths_modinv_even_l128; + /** Modular exponentiation for numbers less than 2048-bit */ + icp_qat_fw_maths_modexp_l2048_output_t maths_modexp_l2048; - /** Modular multiplicative inverse for numbers less than 192 bits */ - icp_qat_fw_maths_modinv_even_l192_output_t maths_modinv_even_l192; + /** Modular exponentiation for numbers less than 2560-bits */ + icp_qat_fw_maths_modexp_l2560_output_t maths_modexp_l2560; - /** Modular multiplicative inverse for numbers less than 256 bits */ - icp_qat_fw_maths_modinv_even_l256_output_t maths_modinv_even_l256; + /** Modular exponentiation for numbers less than 3072-bits */ + icp_qat_fw_maths_modexp_l3072_output_t maths_modexp_l3072; - /** Modular multiplicative inverse for numbers less than 384 bits */ - icp_qat_fw_maths_modinv_even_l384_output_t maths_modinv_even_l384; + /** Modular exponentiation for numbers less than 3584-bits */ + icp_qat_fw_maths_modexp_l3584_output_t maths_modexp_l3584; - /** Modular multiplicative inverse for numbers less than 512 bits */ - icp_qat_fw_maths_modinv_even_l512_output_t maths_modinv_even_l512; + /** Modular exponentiation for numbers less than 4096-bit */ + icp_qat_fw_maths_modexp_l4096_output_t maths_modexp_l4096; - /** Modular multiplicative inverse for numbers less than 768 bits */ - icp_qat_fw_maths_modinv_even_l768_output_t maths_modinv_even_l768; + /** Modular exponentiation for numbers up to 8192 bits */ + icp_qat_fw_maths_modexp_l8192_output_t maths_modexp_l8192; - /** Modular multiplicative inverse for numbers less than 1024 bits */ - icp_qat_fw_maths_modinv_even_l1024_output_t maths_modinv_even_l1024; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_odd_l128_output_t maths_modinv_odd_l128; - /** Modular multiplicative inverse for numbers less than 1536 bits */ - icp_qat_fw_maths_modinv_even_l1536_output_t maths_modinv_even_l1536; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_odd_l192_output_t maths_modinv_odd_l192; - /** Modular multiplicative inverse for numbers less than 2048 bits */ - icp_qat_fw_maths_modinv_even_l2048_output_t maths_modinv_even_l2048; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_odd_l256_output_t maths_modinv_odd_l256; - /** Modular multiplicative inverse for numbers less than 3072 bits */ - icp_qat_fw_maths_modinv_even_l3072_output_t maths_modinv_even_l3072; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_odd_l384_output_t maths_modinv_odd_l384; - /** Modular multiplicative inverse for numbers less than 4096 bits */ - icp_qat_fw_maths_modinv_even_l4096_output_t maths_modinv_even_l4096; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_odd_l512_output_t maths_modinv_odd_l512; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t mmp_dsa_gen_p_1024_160; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_odd_l768_output_t maths_modinv_odd_l768; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_1024_output_t mmp_dsa_gen_g_1024; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_odd_l1024_output_t maths_modinv_odd_l1024; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_1024_output_t mmp_dsa_gen_y_1024; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_odd_l1536_output_t maths_modinv_odd_l1536; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t mmp_dsa_sign_r_1024_160; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_odd_l2048_output_t maths_modinv_odd_l2048; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_160_output_t mmp_dsa_sign_s_160; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_odd_l3072_output_t maths_modinv_odd_l3072; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t mmp_dsa_sign_r_s_1024_160; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_odd_l4096_output_t maths_modinv_odd_l4096; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_1024_160_output_t mmp_dsa_verify_1024_160; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_odd_l8192_output_t maths_modinv_odd_l8192; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t mmp_dsa_gen_p_2048_224; + /** Modular multiplicative inverse for numbers less than 128 bits */ + icp_qat_fw_maths_modinv_even_l128_output_t maths_modinv_even_l128; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_2048_output_t mmp_dsa_gen_y_2048; + /** Modular multiplicative inverse for numbers less than 192 bits */ + icp_qat_fw_maths_modinv_even_l192_output_t maths_modinv_even_l192; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t mmp_dsa_sign_r_2048_224; + /** Modular multiplicative inverse for numbers less than 256 bits */ + icp_qat_fw_maths_modinv_even_l256_output_t maths_modinv_even_l256; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_224_output_t mmp_dsa_sign_s_224; + /** Modular multiplicative inverse for numbers less than 384 bits */ + icp_qat_fw_maths_modinv_even_l384_output_t maths_modinv_even_l384; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t mmp_dsa_sign_r_s_2048_224; + /** Modular multiplicative inverse for numbers less than 512 bits */ + icp_qat_fw_maths_modinv_even_l512_output_t maths_modinv_even_l512; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_224_output_t mmp_dsa_verify_2048_224; + /** Modular multiplicative inverse for numbers less than 768 bits */ + icp_qat_fw_maths_modinv_even_l768_output_t maths_modinv_even_l768; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t mmp_dsa_gen_p_2048_256; + /** Modular multiplicative inverse for numbers less than 1024 bits */ + icp_qat_fw_maths_modinv_even_l1024_output_t maths_modinv_even_l1024; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_2048_output_t mmp_dsa_gen_g_2048; + /** Modular multiplicative inverse for numbers less than 1536 bits */ + icp_qat_fw_maths_modinv_even_l1536_output_t maths_modinv_even_l1536; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t mmp_dsa_sign_r_2048_256; + /** Modular multiplicative inverse for numbers less than 2048 bits */ + icp_qat_fw_maths_modinv_even_l2048_output_t maths_modinv_even_l2048; - /** DSA Sign S */ - icp_qat_fw_mmp_dsa_sign_s_256_output_t mmp_dsa_sign_s_256; + /** Modular multiplicative inverse for numbers less than 3072 bits */ + icp_qat_fw_maths_modinv_even_l3072_output_t maths_modinv_even_l3072; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t mmp_dsa_sign_r_s_2048_256; + /** Modular multiplicative inverse for numbers less than 4096 bits */ + icp_qat_fw_maths_modinv_even_l4096_output_t maths_modinv_even_l4096; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_2048_256_output_t mmp_dsa_verify_2048_256; + /** Modular multiplicative inverse for numbers up to 8192 bits */ + icp_qat_fw_maths_modinv_even_l8192_output_t maths_modinv_even_l8192; - /** DSA parameter generation P */ - icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t mmp_dsa_gen_p_3072_256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_1024_160_output_t mmp_dsa_gen_p_1024_160; - /** DSA key generation G */ - icp_qat_fw_mmp_dsa_gen_g_3072_output_t mmp_dsa_gen_g_3072; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_1024_output_t mmp_dsa_gen_g_1024; - /** DSA key generation Y */ - icp_qat_fw_mmp_dsa_gen_y_3072_output_t mmp_dsa_gen_y_3072; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_1024_output_t mmp_dsa_gen_y_1024; - /** DSA Sign R */ - icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t mmp_dsa_sign_r_3072_256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_1024_160_output_t mmp_dsa_sign_r_1024_160; - /** DSA Sign R S */ - icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t mmp_dsa_sign_r_s_3072_256; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_160_output_t mmp_dsa_sign_s_160; - /** DSA Verify */ - icp_qat_fw_mmp_dsa_verify_3072_256_output_t mmp_dsa_verify_3072_256; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_1024_160_output_t mmp_dsa_sign_r_s_1024_160; - /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t - mmp_ecdsa_sign_rs_gf2_l256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_1024_160_output_t mmp_dsa_verify_1024_160; - /** ECDSA Sign R for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t mmp_ecdsa_sign_r_gf2_l256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_224_output_t mmp_dsa_gen_p_2048_224; - /** ECDSA Sign S for curves with n < 2^256 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t mmp_ecdsa_sign_s_gf2_l256; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_2048_output_t mmp_dsa_gen_y_2048; - /** ECDSA Verify for curves B/K-163 and B/K-233 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t mmp_ecdsa_verify_gf2_l256; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_224_output_t mmp_dsa_sign_r_2048_224; - /** ECDSA Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t - mmp_ecdsa_sign_rs_gf2_l512; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_224_output_t mmp_dsa_sign_s_224; - /** ECDSA GF2 Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t mmp_ecdsa_sign_r_gf2_l512; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_224_output_t mmp_dsa_sign_r_s_2048_224; - /** ECDSA GF2 Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t mmp_ecdsa_sign_s_gf2_l512; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_224_output_t mmp_dsa_verify_2048_224; - /** ECDSA GF2 Verify */ - icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t mmp_ecdsa_verify_gf2_l512; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_2048_256_output_t mmp_dsa_gen_p_2048_256; - /** ECDSA GF2 Sign RS for curves B-571/K-571 */ - icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t mmp_ecdsa_sign_rs_gf2_571; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_2048_output_t mmp_dsa_gen_g_2048; - /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ - icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t mmp_ecdsa_sign_s_gf2_571; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_2048_256_output_t mmp_dsa_sign_r_2048_256; - /** ECDSA GF2 Sign R for degree 571 */ - icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t mmp_ecdsa_sign_r_gf2_571; + /** DSA Sign S */ + icp_qat_fw_mmp_dsa_sign_s_256_output_t mmp_dsa_sign_s_256; - /** ECDSA GF2 Verify for degree 571 */ - icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t mmp_ecdsa_verify_gf2_571; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_2048_256_output_t mmp_dsa_sign_r_s_2048_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l256_output_t - maths_point_multiplication_gf2_l256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_2048_256_output_t mmp_dsa_verify_2048_256; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l256_output_t - maths_point_verify_gf2_l256; + /** DSA parameter generation P */ + icp_qat_fw_mmp_dsa_gen_p_3072_256_output_t mmp_dsa_gen_p_3072_256; - /** MATHS GF2 Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gf2_l512_output_t - maths_point_multiplication_gf2_l512; + /** DSA key generation G */ + icp_qat_fw_mmp_dsa_gen_g_3072_output_t mmp_dsa_gen_g_3072; - /** MATHS GF2 Point Verification */ - icp_qat_fw_maths_point_verify_gf2_l512_output_t - maths_point_verify_gf2_l512; + /** DSA key generation Y */ + icp_qat_fw_mmp_dsa_gen_y_3072_output_t mmp_dsa_gen_y_3072; - /** ECC GF2 Point Multiplication for curves B-571/K-571 */ - icp_qat_fw_maths_point_multiplication_gf2_571_output_t - maths_point_multiplication_gf2_571; + /** DSA Sign R */ + icp_qat_fw_mmp_dsa_sign_r_3072_256_output_t mmp_dsa_sign_r_3072_256; - /** ECC GF2 Point Verification for degree 571 */ - icp_qat_fw_maths_point_verify_gf2_571_output_t - maths_point_verify_gf2_571; + /** DSA Sign R S */ + icp_qat_fw_mmp_dsa_sign_r_s_3072_256_output_t mmp_dsa_sign_r_s_3072_256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t mmp_ecdsa_sign_r_gfp_l256; + /** DSA Verify */ + icp_qat_fw_mmp_dsa_verify_3072_256_output_t mmp_dsa_verify_3072_256; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t mmp_ecdsa_sign_s_gfp_l256; + /** ECDSA Sign RS for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_t mmp_ecdsa_sign_rs_gf2_l256; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t - mmp_ecdsa_sign_rs_gfp_l256; + /** ECDSA Sign R for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_t mmp_ecdsa_sign_r_gf2_l256; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t mmp_ecdsa_verify_gfp_l256; + /** ECDSA Sign S for curves with n < 2^256 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_t mmp_ecdsa_sign_s_gf2_l256; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t mmp_ecdsa_sign_r_gfp_l512; + /** ECDSA Verify for curves B/K-163 and B/K-233 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l256_output_t mmp_ecdsa_verify_gf2_l256; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t mmp_ecdsa_sign_s_gfp_l512; + /** ECDSA Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l512_output_t mmp_ecdsa_sign_rs_gf2_l512; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t - mmp_ecdsa_sign_rs_gfp_l512; + /** ECDSA GF2 Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_t mmp_ecdsa_sign_r_gf2_l512; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t mmp_ecdsa_verify_gfp_l512; + /** ECDSA GF2 Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_t mmp_ecdsa_sign_s_gf2_l512; - /** ECDSA GFP Sign R */ - icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t mmp_ecdsa_sign_r_gfp_521; + /** ECDSA GF2 Verify */ + icp_qat_fw_mmp_ecdsa_verify_gf2_l512_output_t mmp_ecdsa_verify_gf2_l512; - /** ECDSA GFP Sign S */ - icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t mmp_ecdsa_sign_s_gfp_521; + /** ECDSA GF2 Sign RS for curves B-571/K-571 */ + icp_qat_fw_mmp_ecdsa_sign_rs_gf2_571_output_t mmp_ecdsa_sign_rs_gf2_571; - /** ECDSA GFP Sign RS */ - icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t mmp_ecdsa_sign_rs_gfp_521; + /** ECDSA GF2 Sign S for curves with deg(q) < 576 */ + icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_t mmp_ecdsa_sign_s_gf2_571; - /** ECDSA GFP Verify */ - icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t mmp_ecdsa_verify_gfp_521; + /** ECDSA GF2 Sign R for degree 571 */ + icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_t mmp_ecdsa_sign_r_gf2_571; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l256_output_t - maths_point_multiplication_gfp_l256; + /** ECDSA GF2 Verify for degree 571 */ + icp_qat_fw_mmp_ecdsa_verify_gf2_571_output_t mmp_ecdsa_verify_gf2_571; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_l256_output_t - maths_point_verify_gfp_l256; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l256_output_t maths_point_multiplication_gf2_l256; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_l512_output_t - maths_point_multiplication_gfp_l512; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l256_output_t maths_point_verify_gf2_l256; - /** ECC GFP Partial Point */ - icp_qat_fw_maths_point_verify_gfp_l512_output_t - maths_point_verify_gfp_l512; + /** MATHS GF2 Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gf2_l512_output_t maths_point_multiplication_gf2_l512; - /** ECC GFP Point Multiplication */ - icp_qat_fw_maths_point_multiplication_gfp_521_output_t - maths_point_multiplication_gfp_521; + /** MATHS GF2 Point Verification */ + icp_qat_fw_maths_point_verify_gf2_l512_output_t maths_point_verify_gf2_l512; - /** ECC GFP Partial Point Verification */ - icp_qat_fw_maths_point_verify_gfp_521_output_t - maths_point_verify_gfp_521; + /** ECC GF2 Point Multiplication for curves B-571/K-571 */ + icp_qat_fw_maths_point_multiplication_gf2_571_output_t maths_point_multiplication_gf2_571; - /** ECC curve25519 Variable Point Multiplication [k]P(x), as specified - * in RFC7748 */ - icp_qat_fw_point_multiplication_c25519_output_t - point_multiplication_c25519; + /** ECC GF2 Point Verification for degree 571 */ + icp_qat_fw_maths_point_verify_gf2_571_output_t maths_point_verify_gf2_571; - /** ECC curve25519 Generator Point Multiplication [k]G(x), as specified - * in RFC7748 */ - icp_qat_fw_generator_multiplication_c25519_output_t - generator_multiplication_c25519; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l256_output_t mmp_ecdsa_sign_r_gfp_l256; - /** ECC edwards25519 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed25519_output_t - point_multiplication_ed25519; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l256_output_t mmp_ecdsa_sign_s_gfp_l256; - /** ECC edwards25519 Generator Point Multiplication [k]G, as specified - * in RFC8032 */ - icp_qat_fw_generator_multiplication_ed25519_output_t - generator_multiplication_ed25519; + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l256_output_t mmp_ecdsa_sign_rs_gfp_l256; - /** ECC curve448 Variable Point Multiplication [k]P(x), as specified in - * RFC7748 */ - icp_qat_fw_point_multiplication_c448_output_t point_multiplication_c448; + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l256_output_t mmp_ecdsa_verify_gfp_l256; - /** ECC curve448 Generator Point Multiplication [k]G(x), as specified in - * RFC7748 */ - icp_qat_fw_generator_multiplication_c448_output_t - generator_multiplication_c448; + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_l512_output_t mmp_ecdsa_sign_r_gfp_l512; - /** ECC edwards448 Variable Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_point_multiplication_ed448_output_t - point_multiplication_ed448; + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_l512_output_t mmp_ecdsa_sign_s_gfp_l512; + + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_l512_output_t mmp_ecdsa_sign_rs_gfp_l512; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_l512_output_t mmp_ecdsa_verify_gfp_l512; + + /** ECDSA GFP Sign R */ + icp_qat_fw_mmp_ecdsa_sign_r_gfp_521_output_t mmp_ecdsa_sign_r_gfp_521; + + /** ECDSA GFP Sign S */ + icp_qat_fw_mmp_ecdsa_sign_s_gfp_521_output_t mmp_ecdsa_sign_s_gfp_521; + + /** ECDSA GFP Sign RS */ + icp_qat_fw_mmp_ecdsa_sign_rs_gfp_521_output_t mmp_ecdsa_sign_rs_gfp_521; + + /** ECDSA GFP Verify */ + icp_qat_fw_mmp_ecdsa_verify_gfp_521_output_t mmp_ecdsa_verify_gfp_521; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l256_output_t maths_point_multiplication_gfp_l256; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_l256_output_t maths_point_verify_gfp_l256; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_l512_output_t maths_point_multiplication_gfp_l512; + + /** ECC GFP Partial Point */ + icp_qat_fw_maths_point_verify_gfp_l512_output_t maths_point_verify_gfp_l512; + + /** ECC GFP Point Multiplication */ + icp_qat_fw_maths_point_multiplication_gfp_521_output_t maths_point_multiplication_gfp_521; + + /** ECC GFP Partial Point Verification */ + icp_qat_fw_maths_point_verify_gfp_521_output_t maths_point_verify_gfp_521; + + /** ECC P521 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_t mmp_kpt_ecdsa_sign_rs_p521; + + /** ECC P384 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_t mmp_kpt_ecdsa_sign_rs_p384; + + /** ECC KPT P256 ECDSA Sign RS */ + icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_t mmp_kpt_ecdsa_sign_rs_p256; + + /** KPT RSA 512 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_512_output_t mmp_kpt_rsa_dp1_512; + + /** KPT RSA 1024 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_t mmp_kpt_rsa_dp1_1024; + + /** KPT RSA 1536 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_t mmp_kpt_rsa_dp1_1536; + + /** KPT RSA 2048 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_t mmp_kpt_rsa_dp1_2048; + + /** KPT RSA 3072 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_t mmp_kpt_rsa_dp1_3072; + + /** KPT RSA 4096 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_t mmp_kpt_rsa_dp1_4096; + + /** KPT RSA 8192 Decryption */ + icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_t mmp_kpt_rsa_dp1_8192; + + /** RSA 512 decryption second form */ + icp_qat_fw_mmp_kpt_rsa_dp2_512_output_t mmp_kpt_rsa_dp2_512; + + /** RSA 1024 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_t mmp_kpt_rsa_dp2_1024; + + /** KPT RSA 1536 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_t mmp_kpt_rsa_dp2_1536; + + /** RSA 2048 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_t mmp_kpt_rsa_dp2_2048; + + /** */ + icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_t mmp_kpt_rsa_dp2_3072; + + /** RSA 4096 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_t mmp_kpt_rsa_dp2_4096; + + /** RSA 8192 Decryption with CRT */ + icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_t mmp_kpt_rsa_dp2_8192; - /** ECC edwards448 Generator Point Multiplication [k]P, as specified in - * RFC8032 */ - icp_qat_fw_generator_multiplication_ed448_output_t - generator_multiplication_ed448; } icp_qat_fw_mmp_output_param_t; + + #endif /* __ICP_QAT_FW_MMP__ */ + /* --- (Automatically generated (build v. 2.7), do not modify manually) --- */ /* --- end of file --- */ diff --git a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h --- a/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h +++ b/sys/dev/qat/qat_api/firmware/include/icp_qat_fw_mmp_ids.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ + + +/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- */ + /** * @file icp_qat_fw_mmp_ids.h * @ingroup icp_qat_fw_mmp @@ -14,7 +18,159 @@ #ifndef __ICP_QAT_FW_MMP_IDS__ #define __ICP_QAT_FW_MMP_IDS__ -#define PKE_INIT 0x09061798 +#define PKE_ECSM2_GENERATOR_MULTIPLICATION 0x220f16ae +/**< Functionality ID for ECC SM2 point multiply [k]G + * @li 1 input parameters : @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s::xd xd @endlink @link + * icp_qat_fw_mmp_ecsm2_generator_multiplication_output_s::yd yd @endlink + */ +#define PKE_ECSM2_POINT_MULTIPLICATION 0x211716ce +/**< Functionality ID for ECC SM2 point multiply [k]P + * @li 3 input parameters : @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::k k @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::x x @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_input_s::y y @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_output_s::xd xd @endlink @link + * icp_qat_fw_mmp_ecsm2_point_multiplication_output_s::yd yd @endlink + */ +#define PKE_ECSM2_POINT_VERIFY 0x1b0716a6 +/**< Functionality ID for ECC SM2 point verify + * @li 2 input parameters : @link icp_qat_fw_mmp_ecsm2_point_verify_input_s::x x + * @endlink @link icp_qat_fw_mmp_ecsm2_point_verify_input_s::y y @endlink + * @li no output parameters + */ +#define PKE_ECSM2_SIGN_RS 0x222116fe +/**< Functionality ID for ECC SM2 Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_sign_rs_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecsm2_sign_rs_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecsm2_sign_rs_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_sign_rs_output_s::r r + * @endlink @link icp_qat_fw_mmp_ecsm2_sign_rs_output_s::s s @endlink + */ +#define PKE_ECSM2_VERIFY 0x29241743 +/**< Functionality ID for ECC SM2 Signature Verify + * @li 5 input parameters : @link icp_qat_fw_mmp_ecsm2_verify_input_s::e e + * @endlink @link icp_qat_fw_mmp_ecsm2_verify_input_s::r r @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::s s @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_verify_input_s::yp yp @endlink + * @li no output parameters + */ +#define PKE_ECSM2_ENCRYPTION 0x25221720 +/**< Functionality ID for ECC SM2 encryption + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_encryption_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecsm2_encryption_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_encryption_input_s::yp yp @endlink + * @li 4 output parameters : @link icp_qat_fw_mmp_ecsm2_encryption_output_s::xc + * xc @endlink @link icp_qat_fw_mmp_ecsm2_encryption_output_s::yc yc @endlink + * @link icp_qat_fw_mmp_ecsm2_encryption_output_s::xpb xpb @endlink @link + * icp_qat_fw_mmp_ecsm2_encryption_output_s::ypb ypb @endlink + */ +#define PKE_ECSM2_DECRYPTION 0x201716e6 +/**< Functionality ID for ECC SM2 decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_ecsm2_decryption_input_s::d d + * @endlink @link icp_qat_fw_mmp_ecsm2_decryption_input_s::xpb xpb @endlink + * @link icp_qat_fw_mmp_ecsm2_decryption_input_s::ypb ypb @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_decryption_output_s::xd + * xd @endlink @link icp_qat_fw_mmp_ecsm2_decryption_output_s::yd yd @endlink + */ +#define PKE_ECSM2_KEYEX_P1 0x220f16be +/**< Functionality ID for ECC SM2 key exchange phase1 + * @li 1 input parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p1_input_s::k k + * @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p1_output_s::xd xd + * @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p1_output_s::yd yd @endlink + */ +#define PKE_ECSM2_KEYEX_P2 0x22361768 +/**< Functionality ID for ECC SM2 key exchange phase2 + * @li 7 input parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::r r + * @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::d d @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::x1 x1 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::x2 x2 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::y2 y2 @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ecsm2_keyex_p2_input_s::yp yp @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecsm2_keyex_p2_output_s::xus + * xus @endlink @link icp_qat_fw_mmp_ecsm2_keyex_p2_output_s::yus yus @endlink + */ +#define POINT_MULTIPLICATION_C25519 0x0a0634c6 +/**< Functionality ID for ECC curve25519 Variable Point Multiplication [k]P(x), + * as specified in RFC7748 + * @li 2 input parameters : @link + * icp_qat_fw_point_multiplication_c25519_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_c25519_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_point_multiplication_c25519_output_s::xr xr @endlink + */ +#define GENERATOR_MULTIPLICATION_C25519 0x0a0634d6 +/**< Functionality ID for ECC curve25519 Generator Point Multiplication [k]G(x), + * as specified in RFC7748 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_c25519_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_generator_multiplication_c25519_output_s::xr xr @endlink + */ +#define POINT_MULTIPLICATION_ED25519 0x100b34e6 +/**< Functionality ID for ECC edwards25519 Variable Point Multiplication [k]P, + * as specified in RFC8032 + * @li 3 input parameters : @link + * icp_qat_fw_point_multiplication_ed25519_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_ed25519_input_s::yp yp @endlink @link + * icp_qat_fw_point_multiplication_ed25519_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_point_multiplication_ed25519_output_s::xr xr @endlink @link + * icp_qat_fw_point_multiplication_ed25519_output_s::yr yr @endlink + */ +#define GENERATOR_MULTIPLICATION_ED25519 0x100a34f6 +/**< Functionality ID for ECC edwards25519 Generator Point Multiplication [k]G, + * as specified in RFC8032 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_ed25519_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_generator_multiplication_ed25519_output_s::xr xr @endlink @link + * icp_qat_fw_generator_multiplication_ed25519_output_s::yr yr @endlink + */ +#define POINT_MULTIPLICATION_C448 0x0c063506 +/**< Functionality ID for ECC curve448 Variable Point Multiplication [k]P(x), as + * specified in RFC7748 + * @li 2 input parameters : @link + * icp_qat_fw_point_multiplication_c448_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_c448_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_point_multiplication_c448_output_s::xr xr @endlink + */ +#define GENERATOR_MULTIPLICATION_C448 0x0c063516 +/**< Functionality ID for ECC curve448 Generator Point Multiplication [k]G(x), + * as specified in RFC7748 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_c448_input_s::k k @endlink + * @li 1 output parameters : @link + * icp_qat_fw_generator_multiplication_c448_output_s::xr xr @endlink + */ +#define POINT_MULTIPLICATION_ED448 0x1a0b3526 +/**< Functionality ID for ECC edwards448 Variable Point Multiplication [k]P, as + * specified in RFC8032 + * @li 3 input parameters : @link + * icp_qat_fw_point_multiplication_ed448_input_s::xp xp @endlink @link + * icp_qat_fw_point_multiplication_ed448_input_s::yp yp @endlink @link + * icp_qat_fw_point_multiplication_ed448_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_point_multiplication_ed448_output_s::xr xr @endlink @link + * icp_qat_fw_point_multiplication_ed448_output_s::yr yr @endlink + */ +#define GENERATOR_MULTIPLICATION_ED448 0x1a0a3536 +/**< Functionality ID for ECC edwards448 Generator Point Multiplication [k]P, as + * specified in RFC8032 + * @li 1 input parameters : @link + * icp_qat_fw_generator_multiplication_ed448_input_s::k k @endlink + * @li 2 output parameters : @link + * icp_qat_fw_generator_multiplication_ed448_output_s::xr xr @endlink @link + * icp_qat_fw_generator_multiplication_ed448_output_s::yr yr @endlink + */ +#define PKE_INIT 0x0806169f /**< Functionality ID for Initialisation sequence * @li 1 input parameters : @link icp_qat_fw_mmp_init_input_s::z z @endlink * @li 1 output parameters : @link icp_qat_fw_mmp_init_output_s::zz zz @endlink @@ -115,6 +271,22 @@ * icp_qat_fw_mmp_dh_4096_input_s::m m @endlink * @li 1 output parameters : @link icp_qat_fw_mmp_dh_4096_output_s::r r @endlink */ +#define PKE_DH_G2_8192 0x8d0b3626 +/**< Functionality ID for Diffie-Hellman Modular exponentiation base 2 for + * 8192-bit numbers + * @li 2 input parameters : @link icp_qat_fw_mmp_dh_g2_8192_input_s::e e + * @endlink @link icp_qat_fw_mmp_dh_g2_8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_dh_g2_8192_output_s::r r + * @endlink + */ +#define PKE_DH_8192 0xcd0d3636 +/**< Functionality ID for Diffie-Hellman Modular exponentiation for 8192-bit + * numbers + * @li 3 input parameters : @link icp_qat_fw_mmp_dh_8192_input_s::g g @endlink + * @link icp_qat_fw_mmp_dh_8192_input_s::e e @endlink @link + * icp_qat_fw_mmp_dh_8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_dh_8192_output_s::r r @endlink + */ #define PKE_RSA_KP1_512 0x191d1a9a /**< Functionality ID for RSA 512 key generation first form * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_kp1_512_input_s::p p @@ -391,6 +563,33 @@ * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp2_4096_output_s::m m * @endlink */ +#define PKE_RSA_EP_8192 0xc31335c6 +/**< Functionality ID for RSA 8192 Encryption + * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_ep_8192_input_s::m m + * @endlink @link icp_qat_fw_mmp_rsa_ep_8192_input_s::e e @endlink @link + * icp_qat_fw_mmp_rsa_ep_8192_input_s::n n @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_ep_8192_output_s::c c + * @endlink + */ +#define PKE_RSA_DP1_8192 0xc31335e6 +/**< Functionality ID for RSA 8192 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_rsa_dp1_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_rsa_dp1_8192_input_s::d d @endlink @link + * icp_qat_fw_mmp_rsa_dp1_8192_input_s::n n @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp1_8192_output_s::m m + * @endlink + */ +#define PKE_RSA_DP2_8192 0xc9133606 +/**< Functionality ID for RSA 8192 Decryption with CRT + * @li 6 input parameters : @link icp_qat_fw_mmp_rsa_dp2_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_rsa_dp2_8192_input_s::p p @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::q q @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::dp dp @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::dq dq @endlink @link + * icp_qat_fw_mmp_rsa_dp2_8192_input_s::qinv qinv @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_rsa_dp2_8192_output_s::m m + * @endlink + */ #define PKE_GCD_PT_192 0x19201fcd /**< Functionality ID for GCD primality test for 192-bit numbers * @li 1 input parameters : @link icp_qat_fw_mmp_gcd_pt_192_input_s::m m @@ -677,6 +876,14 @@ * @li 1 output parameters : @link icp_qat_fw_maths_modexp_l4096_output_s::r r * @endlink */ +#define MATHS_MODEXP_L8192 0xc50c3646 +/**< Functionality ID for Modular exponentiation for numbers up to 8192 bits + * @li 3 input parameters : @link icp_qat_fw_maths_modexp_l8192_input_s::g g + * @endlink @link icp_qat_fw_maths_modexp_l8192_input_s::e e @endlink @link + * icp_qat_fw_maths_modexp_l8192_input_s::m m @endlink + * @li 1 output parameters : @link icp_qat_fw_maths_modexp_l8192_output_s::r r + * @endlink + */ #define MATHS_MODINV_ODD_L128 0x090623f8 /**< Functionality ID for Modular multiplicative inverse for numbers less than * 128 bits @@ -765,6 +972,14 @@ * @li 1 output parameters : @link icp_qat_fw_maths_modinv_odd_l4096_output_s::c * c @endlink */ +#define MATHS_MODINV_ODD_L8192 0x88073656 +/**< Functionality ID for Modular multiplicative inverse for numbers up to 8192 + * bits + * @li 2 input parameters : @link icp_qat_fw_maths_modinv_odd_l8192_input_s::a a + * @endlink @link icp_qat_fw_maths_modinv_odd_l8192_input_s::b b @endlink + * @li 1 output parameters : @link icp_qat_fw_maths_modinv_odd_l8192_output_s::c + * c @endlink + */ #define MATHS_MODINV_EVEN_L128 0x0906243a /**< Functionality ID for Modular multiplicative inverse for numbers less than * 128 bits @@ -853,6 +1068,14 @@ * @li 1 output parameters : @link * icp_qat_fw_maths_modinv_even_l4096_output_s::c c @endlink */ +#define MATHS_MODINV_EVEN_L8192 0xc80d3666 +/**< Functionality ID for Modular multiplicative inverse for numbers up to 8192 + * bits + * @li 2 input parameters : @link icp_qat_fw_maths_modinv_even_l8192_input_s::a + * a @endlink @link icp_qat_fw_maths_modinv_even_l8192_input_s::b b @endlink + * @li 1 output parameters : @link + * icp_qat_fw_maths_modinv_even_l8192_output_s::c c @endlink + */ #define PKE_DSA_GEN_P_1024_160 0x381824a4 /**< Functionality ID for DSA parameter generation P * @li 2 input parameters : @link icp_qat_fw_mmp_dsa_gen_p_1024_160_input_s::x x @@ -1461,81 +1684,60 @@ * icp_qat_fw_maths_point_verify_gfp_521_input_s::b b @endlink * @li no output parameters */ -#define POINT_MULTIPLICATION_C25519 0x0a0634c6 -/**< Functionality ID for ECC curve25519 Variable Point Multiplication [k]P(x), - * as specified in RFC7748 - * @li 2 input parameters : @link - * icp_qat_fw_point_multiplication_c25519_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_c25519_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_point_multiplication_c25519_output_s::xr xr @endlink - */ -#define GENERATOR_MULTIPLICATION_C25519 0x0a0634d6 -/**< Functionality ID for ECC curve25519 Generator Point Multiplication [k]G(x), - * as specified in RFC7748 - * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_c25519_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_generator_multiplication_c25519_output_s::xr xr @endlink - */ -#define POINT_MULTIPLICATION_ED25519 0x100b34e6 -/**< Functionality ID for ECC edwards25519 Variable Point Multiplication [k]P, - * as specified in RFC8032 +#define PKE_EC_POINT_MULTIPLICATION_P256 0x0a083546 +/**< Functionality ID for ECC P256 Variable Point Multiplication [k]P(x) * @li 3 input parameters : @link - * icp_qat_fw_point_multiplication_ed25519_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_ed25519_input_s::yp yp @endlink @link - * icp_qat_fw_point_multiplication_ed25519_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::yp yp @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_point_multiplication_ed25519_output_s::xr xr @endlink @link - * icp_qat_fw_point_multiplication_ed25519_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p256_point_multiplication_output_s::xr xr @endlink @link + * icp_qat_fw_mmp_ec_p256_point_multiplication_output_s::yr yr @endlink */ -#define GENERATOR_MULTIPLICATION_ED25519 0x100a34f6 -/**< Functionality ID for ECC edwards25519 Generator Point Multiplication [k]G, - * as specified in RFC8032 +#define PKE_EC_GENERATOR_MULTIPLICATION_P256 0x12073556 +/**< Functionality ID for ECC P256 Generator Point Multiplication [k]G(x) * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_ed25519_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p256_generator_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_generator_multiplication_ed25519_output_s::xr xr @endlink @link - * icp_qat_fw_generator_multiplication_ed25519_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p256_generator_multiplication_output_s::xr xr @endlink + * @link icp_qat_fw_mmp_ec_p256_generator_multiplication_output_s::yr yr + * @endlink */ -#define POINT_MULTIPLICATION_C448 0x0c063506 -/**< Functionality ID for ECC curve448 Variable Point Multiplication [k]P(x), as - * specified in RFC7748 - * @li 2 input parameters : @link - * icp_qat_fw_point_multiplication_c448_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_c448_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_point_multiplication_c448_output_s::xr xr @endlink +#define PKE_ECDSA_SIGN_RS_P256 0x18133566 +/**< Functionality ID for ECC P256 ECDSA Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecdsa_sign_rs_p256_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s::r + * r @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p256_output_s::s s @endlink */ -#define GENERATOR_MULTIPLICATION_C448 0x0c063516 -/**< Functionality ID for ECC curve448 Generator Point Multiplication [k]G(x), - * as specified in RFC7748 - * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_c448_input_s::k k @endlink - * @li 1 output parameters : @link - * icp_qat_fw_generator_multiplication_c448_output_s::xr xr @endlink - */ -#define POINT_MULTIPLICATION_ED448 0x1a0b3526 -/**< Functionality ID for ECC edwards448 Variable Point Multiplication [k]P, as - * specified in RFC8032 +#define PKE_EC_POINT_MULTIPLICATION_P384 0x0b083586 +/**< Functionality ID for ECC P384 Variable Point Multiplication [k]P(x) * @li 3 input parameters : @link - * icp_qat_fw_point_multiplication_ed448_input_s::xp xp @endlink @link - * icp_qat_fw_point_multiplication_ed448_input_s::yp yp @endlink @link - * icp_qat_fw_point_multiplication_ed448_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::xp xp @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::yp yp @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_point_multiplication_ed448_output_s::xr xr @endlink @link - * icp_qat_fw_point_multiplication_ed448_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p384_point_multiplication_output_s::xr xr @endlink @link + * icp_qat_fw_mmp_ec_p384_point_multiplication_output_s::yr yr @endlink */ -#define GENERATOR_MULTIPLICATION_ED448 0x1a0a3536 -/**< Functionality ID for ECC edwards448 Generator Point Multiplication [k]P, as - * specified in RFC8032 +#define PKE_EC_GENERATOR_MULTIPLICATION_P384 0x0b073596 +/**< Functionality ID for ECC P384 Generator Point Multiplication [k]G(x) * @li 1 input parameters : @link - * icp_qat_fw_generator_multiplication_ed448_input_s::k k @endlink + * icp_qat_fw_mmp_ec_p384_generator_multiplication_input_s::k k @endlink * @li 2 output parameters : @link - * icp_qat_fw_generator_multiplication_ed448_output_s::xr xr @endlink @link - * icp_qat_fw_generator_multiplication_ed448_output_s::yr yr @endlink + * icp_qat_fw_mmp_ec_p384_generator_multiplication_output_s::xr xr @endlink + * @link icp_qat_fw_mmp_ec_p384_generator_multiplication_output_s::yr yr + * @endlink + */ +#define PKE_ECDSA_SIGN_RS_P384 0x1a1335a6 +/**< Functionality ID for ECC P384 ECDSA Sign RS + * @li 3 input parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::k k + * @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::e e @endlink @link + * icp_qat_fw_mmp_ecdsa_sign_rs_p384_input_s::d d @endlink + * @li 2 output parameters : @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s::r + * r @endlink @link icp_qat_fw_mmp_ecdsa_sign_rs_p384_output_s::s s @endlink */ - #define PKE_LIVENESS 0x00000001 /**< Functionality ID for PKE_LIVENESS * @li 0 input parameter(s) @@ -1544,12 +1746,186 @@ #define PKE_INTERFACE_SIGNATURE 0x972ded54 /**< Encoded signature of the interface specifications */ - #define PKE_INVALID_FUNC_ID 0xffffffff +#define PKE_KPT_ECDSA_SIGN_RS_P521 0xb6563896 +/**< Functionality ID for ECC P521 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::kpt_wrapping_context + * kpt_wrapping_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p521_output_s::s s @endlink + */ +#define PKE_KPT_ECDSA_SIGN_RS_P384 0x22143876 +/**< Functionality ID for ECC P384 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::kpt_wrapping_context + * kpt_wrapping_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p384_output_s::s s @endlink + */ +#define PKE_KPT_ECDSA_SIGN_RS_P256 0x8d153856 +/**< Functionality ID for ECC KPT P256 ECDSA Sign RS + * @li 3 input parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::kpt_wrapped kpt_wrapped + * @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::key_unwrap_context + * key_unwrap_context @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_input_s::e e @endlink + * @li 2 output parameters : @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s::r r @endlink @link + * icp_qat_fw_mmp_kpt_ecdsa_sign_rs_p256_output_s::s s @endlink + */ +#define PKE_KPT_RSA_DP1_512 0x1b1c3696 +/**< Functionality ID for KPT RSA 512 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_512_input_s::kpt_unwrap_context kpt_unwrap_context + * @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_512_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_1024 0x2d1d36b6 +/**< Functionality ID for KPT RSA 1024 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_1024_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1024_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_1536 0x451d36d6 +/**< Functionality ID for KPT RSA 1536 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_1536_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_1536_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_2048 0x661936f6 +/**< Functionality ID for KPT RSA 2048 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_2048_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_2048_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_3072 0x751d3716 +/**< Functionality ID for KPT RSA 3072 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_3072_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_3072_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_4096 0x9d1d3736 +/**< Functionality ID for KPT RSA 4096 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_4096_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_4096_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP1_8192 0xbe203756 +/**< Functionality ID for KPT RSA 8192 Decryption + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp1_8192_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp1_8192_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_512 0x241d3776 +/**< Functionality ID for RSA 512 decryption second form + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_512_input_s::kpt_unwrap_context kpt_unwrap_context + * @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_512_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_1024 0x4e1d3796 +/**< Functionality ID for RSA 1024 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_1024_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1024_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_1536 0x762b37b6 +/**< Functionality ID for KPT RSA 1536 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_1536_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_1536_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_2048 0xa41a37d6 +/**< Functionality ID for RSA 2048 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_2048_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_2048_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_3072 0xd41a37f6 +/**< Functionality ID for + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_3072_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_3072_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_4096 0xd22a3816 +/**< Functionality ID for RSA 4096 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_4096_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_4096_output_s::m m + * @endlink + */ +#define PKE_KPT_RSA_DP2_8192 0xae383836 +/**< Functionality ID for RSA 8192 Decryption with CRT + * @li 3 input parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::c c + * @endlink @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::kpt_wrapped + * kpt_wrapped @endlink @link + * icp_qat_fw_mmp_kpt_rsa_dp2_8192_input_s::kpt_unwrap_context + * kpt_unwrap_context @endlink + * @li 1 output parameters : @link icp_qat_fw_mmp_kpt_rsa_dp2_8192_output_s::m m + * @endlink + */ #endif /* __ICP_QAT_FW_MMP_IDS__ */ -/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- - */ +/* --- (Automatically generated (relocation v. 1.3), do not modify manually) --- */ /* --- end of file --- */ diff --git a/sys/dev/qat/qat_api/include/cpa.h b/sys/dev/qat/qat_api/include/cpa.h --- a/sys/dev/qat/qat_api/include/cpa.h +++ b/sys/dev/qat/qat_api/include/cpa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -418,8 +418,12 @@ /**< RAID */ CPA_ACC_SVC_TYPE_XML = CPA_INSTANCE_TYPE_XML, /**< XML */ - CPA_ACC_SVC_TYPE_VIDEO_ANALYTICS + CPA_ACC_SVC_TYPE_VIDEO_ANALYTICS, /**< Video Analytics */ + CPA_ACC_SVC_TYPE_CRYPTO_ASYM, + /**< Cryptography - Asymmetric service */ + CPA_ACC_SVC_TYPE_CRYPTO_SYM + /**< Cryptography - Symmetric service */ } CpaAccelerationServiceType; /** @@ -586,7 +590,7 @@ CpaPhysicalInstanceId physInstId; /**< Identifies the "physical instance" of the accelerator. */ -#define CPA_MAX_CORES 256 +#define CPA_MAX_CORES 4096 /**< Maximum number of cores to support in the coreAffinity bitmap. */ CPA_BITMAP(coreAffinity, CPA_MAX_CORES); /**< A bitmap identifying the core or cores to which the instance @@ -670,6 +674,124 @@ */ } CpaInstanceEvent; +/*****************************************************************************/ +/* CPA Instance Management Functions */ +/*****************************************************************************/ +/** + ***************************************************************************** + * @file cpa.h + * @ingroup cpa + * Get the number of Acceleration Service instances that are supported by + * the API implementation. + * + * @description + * This function will get the number of instances that are supported + * for the required Acceleration Service by an implementation of the CPA + * API. This number is then used to determine the size of the array that + * must be passed to @ref cpaGetInstances(). + * + * @context + * This function MUST NOT be called from an interrupt context as it MAY + * sleep. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] accelerationServiceType Acceleration Service required + * @param[out] pNumInstances Pointer to where the number of + * instances will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * None + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated + * + * @see + * cpaGetInstances + * + *****************************************************************************/ +CpaStatus +cpaGetNumInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U *pNumInstances); + +/** + ***************************************************************************** + * @file cpa.h + * @ingroup cpa + * Get the handles to the required Acceleration Service instances that are + * supported by the API implementation. + * + * @description + * This function will return handles to the required Acceleration Service + * instances that are supported by an implementation of the CPA API. These + * instance handles can then be used as input parameters with other + * API functions. + * + * This function will populate an array that has been allocated by the + * caller. The size of this array will have been determined by the + * cpaGetNumInstances() function. + * + * @context + * This function MUST NOT be called from an interrupt context as it MAY + * sleep. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] accelerationServiceType Acceleration Service requested + * @param[in] numInstances Size of the array. If the value is + * greater than the number of instances + * supported, then an error (@ref + * CPA_STATUS_INVALID_PARAM) is returned. + * @param[in,out] cpaInstances Pointer to where the instance + * handles will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * None + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated + * + * @see + * cpaGetNumInstances + * + *****************************************************************************/ +CpaStatus +cpaGetInstances( + const CpaAccelerationServiceType accelerationServiceType, + Cpa16U numInstances, + CpaInstanceHandle *cpaInstances); + #ifdef __cplusplus } /* close the extern "C" { */ #endif diff --git a/sys/dev/qat/qat_api/include/cpa_dev.h b/sys/dev/qat/qat_api/include/cpa_dev.h --- a/sys/dev/qat/qat_api/include/cpa_dev.h +++ b/sys/dev/qat/qat_api/include/cpa_dev.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/cpa_types.h b/sys/dev/qat/qat_api/include/cpa_types.h --- a/sys/dev/qat/qat_api/include/cpa_types.h +++ b/sys/dev/qat/qat_api/include/cpa_types.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -132,21 +132,6 @@ * NULL definition. */ #endif -#ifndef TRUE -#define TRUE (1==1) -/**< - * @file cpa_types.h - * @ingroup cpa_Types - * True value definition. */ -#endif -#ifndef FALSE -#define FALSE (0==1) -/**< - * @file cpa_types.h - * @ingroup cpa_Types - * False value definition. */ -#endif - /** ***************************************************************************** * @ingroup cpa_Types @@ -159,8 +144,8 @@ *****************************************************************************/ typedef enum _CpaBoolean { - CPA_FALSE = FALSE, /**< False value */ - CPA_TRUE = TRUE /**< True value */ + CPA_FALSE = (0==1), /**< False value */ + CPA_TRUE = (1==1) /**< True value */ } CpaBoolean; diff --git a/sys/dev/qat/qat_api/include/dc/cpa_dc.h b/sys/dev/qat/qat_api/include/dc/cpa_dc.h --- a/sys/dev/qat/qat_api/include/dc/cpa_dc.h +++ b/sys/dev/qat/qat_api/include/dc/cpa_dc.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,16 @@ * @description * These functions specify the API for Data Compression operations. * + * The Data Compression API has the following: + * 1) Session based API functions + * These functions require a session to be created before performing any + * DC operations. Subsequent DC API functions make use of the returned + * Session Handle within their structures or function prototypes. + * 2) Session-less or No-Session (Ns) based API functions. + * These functions do not require a session to be initialized before + * performing DC operations. They are "one-shot" API function calls + * that submit DC requests directly using the supplied parameters. + * * @remarks * * @@ -78,7 +88,7 @@ * for this interface. * *****************************************************************************/ -#define CPA_DC_API_VERSION_NUM_MAJOR (2) +#define CPA_DC_API_VERSION_NUM_MAJOR (3) /** ***************************************************************************** @@ -95,47 +105,71 @@ /** ***************************************************************************** + * @file cpa_dc.h * @ingroup cpaDc - * Compression API session handle type + * CPA DC API version at least + * @description + * The minimal supported CPA_DC API version. Allow to check if the API + * version is equal or above some version to avoid compilation issues + * with an older API version. * + *****************************************************************************/ +#define CPA_DC_API_VERSION_AT_LEAST(major, minor) \ + (CPA_DC_API_VERSION_NUM_MAJOR > major || \ + (CPA_DC_API_VERSION_NUM_MAJOR == major && \ + CPA_DC_API_VERSION_NUM_MINOR >= minor)) + +/** + ***************************************************************************** + * @file cpa_dc.h + * @ingroup cpaDc + * CPA DC API version less than * @description - * Handle used to uniquely identify a Compression API session handle. This - * handle is established upon registration with the API using - * cpaDcInitSession(). + * The maximum supported CPA_DC API version. Allow to check if the API + * version is below some version to avoid compilation issues with a newer + * API version. + * + *****************************************************************************/ +#define CPA_DC_API_VERSION_LESS_THAN(major, minor) \ + (CPA_DC_API_VERSION_NUM_MAJOR < major || \ + (CPA_DC_API_VERSION_NUM_MAJOR == major && \ + CPA_DC_API_VERSION_NUM_MINOR < minor)) + +/** + ***************************************************************************** + * @ingroup cpaDc + * Size of bitmap needed for compression chaining capabilities. * + * @description + * Defines the number of bits in the bitmap to represent supported + * chaining capabilities @ref dcChainCapInfo. Should be set to + * at least one greater than the largest value in the enumerated type + * @ref CpaDcChainOperations, so that the value of the enum constant + * can also be used as the bit position in the bitmap. * + * A larger value was chosen to allow for extensibility without the need + * to change the size of the bitmap (to ease backwards compatibility in + * future versions of the API). * *****************************************************************************/ -typedef void * CpaDcSessionHandle; - +#define CPA_DC_CHAIN_CAP_BITMAP_SIZE (32) /** ***************************************************************************** * @ingroup cpaDc - * Supported file types + * Compression API session handle type * * @description - * This enumerated lists identified file types. Used to select Huffman - * trees. - * File types are associated with Precompiled Huffman Trees. + * Handle used to uniquely identify a Compression API session handle. This + * handle is established upon registration with the API using + * cpaDcInitSession(). + * * - * @deprecated - * As of v1.6 of the Compression API, this enum has been deprecated. * *****************************************************************************/ -typedef enum _CpaDcFileType -{ - CPA_DC_FT_ASCII, - /**< ASCII File Type */ - CPA_DC_FT_CSS, - /**< Cascading Style Sheet File Type */ - CPA_DC_FT_HTML, - /**< HTML or XML (or similar) file type */ - CPA_DC_FT_JAVA, - /**< File Java code or similar */ - CPA_DC_FT_OTHER - /**< Other file types */ -} CpaDcFileType; +typedef void * CpaDcSessionHandle; + + /** ***************************************************************************** * @ingroup cpaDc @@ -185,7 +219,7 @@ *****************************************************************************/ typedef enum _CpaDcHuffType { - CPA_DC_HT_STATIC, + CPA_DC_HT_STATIC = 0, /**< Static Huffman Trees */ CPA_DC_HT_PRECOMP, /**< Precompiled Huffman Trees */ @@ -203,23 +237,73 @@ * In combination with CpaDcChecksum it is used to decide on the file * header and footer format. * - * @deprecated - * As of v1.6 of the Compression API, CPA_DC_LZS, CPA_DC_ELZS and - * CPA_DC_LZSS have been deprecated and should not be used. - * *****************************************************************************/ typedef enum _CpaDcCompType { - CPA_DC_LZS, - /**< LZS Compression */ - CPA_DC_ELZS, - /**< Extended LZS Compression */ - CPA_DC_LZSS, - /**< LZSS Compression */ - CPA_DC_DEFLATE + CPA_DC_DEFLATE = 3, /**< Deflate Compression */ + CPA_DC_LZ4, + /**< LZ4 Compression */ + CPA_DC_LZ4S + /**< LZ4S Compression */ } CpaDcCompType; +/** + ***************************************************************************** + * @ingroup cpaDc + * Support for defined algorithm window sizes + * + * @description + * This enumerated list defines the valid window sizes that can be + * used with the supported algorithms + *****************************************************************************/ +typedef enum _CpaDcCompWindowSize +{ + CPA_DC_WINSIZE_4K = 0, + /**< Window size of 4KB */ + CPA_DC_WINSIZE_8K, + /**< Window size of 8KB */ + CPA_DC_WINSIZE_16K, + /**< Window size of 16KB */ + CPA_DC_WINSIZE_32K + /**< Window size of 32KB */ +} CpaDcCompWindowSize; + +/** + ***************************************************************************** + * @ingroup cpaDc + * Min match size in bytes + * @description + * This is the min match size that will be used for the search algorithm. + * It is only configurable for LZ4S. + *****************************************************************************/ +typedef enum _CpaDcCompMinMatch +{ + CPA_DC_MIN_3_BYTE_MATCH = 0, + /**< Min Match of 3 bytes */ + CPA_DC_MIN_4_BYTE_MATCH + /**< Min Match of 4 bytes */ +} CpaDcCompMinMatch; + +/** + ***************************************************************************** + * @ingroup cpaDc + * Maximum LZ4 output block size + * @description + * Maximum LZ4 output block size + *****************************************************************************/ +typedef enum _CpaDcCompLZ4BlockMaxSize +{ + CPA_DC_LZ4_MAX_BLOCK_SIZE_64K = 0, + /**< Maximum block size 64K */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_256K, + /**< Maximum block size 256K */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_1M, + /**< Maximum block size 1M */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_4M, + /**< Maximum block size 4M */ +} CpaDcCompLZ4BlockMaxSize; + /** ***************************************************************************** * @ingroup cpaDc @@ -232,12 +316,16 @@ *****************************************************************************/ typedef enum _CpaDcChecksum { - CPA_DC_NONE, - /**< No checksums required */ + CPA_DC_NONE = 0, + /**< No checksum required */ CPA_DC_CRC32, - /**< application requires a CRC32 checksum */ - CPA_DC_ADLER32 + /**< Application requires a CRC32 checksum */ + CPA_DC_ADLER32, /**< Application requires Adler-32 checksum */ + CPA_DC_CRC32_ADLER32, + /**< Application requires both CRC32 and Adler-32 checksums */ + CPA_DC_XXHASH32, + /**< Application requires xxHash-32 checksum */ } CpaDcChecksum; @@ -253,7 +341,7 @@ *****************************************************************************/ typedef enum _CpaDcSessionDir { - CPA_DC_DIR_COMPRESS, + CPA_DC_DIR_COMPRESS = 0, /**< Session will be used for compression */ CPA_DC_DIR_DECOMPRESS, /**< Session will be used for decompression */ @@ -261,6 +349,8 @@ /**< Session will be used for both compression and decompression */ } CpaDcSessionDir; +typedef CpaDcSessionDir CpaDcDir; + /** ***************************************************************************** * @ingroup cpaDc @@ -280,13 +370,15 @@ *****************************************************************************/ typedef enum _CpaDcSessionState { - CPA_DC_STATEFUL, + CPA_DC_STATEFUL = 0, /**< Session will be stateful, implying that state may need to be saved in some situations */ CPA_DC_STATELESS /**< Session will be stateless, implying no state will be stored*/ } CpaDcSessionState; +typedef CpaDcSessionState CpaDcState; + /** ***************************************************************************** * @ingroup cpaDc @@ -316,8 +408,14 @@ /**< Compression level 7 */ CPA_DC_L8, /**< Compression level 8 */ - CPA_DC_L9 + CPA_DC_L9, /**< Compression level 9 */ + CPA_DC_L10, + /**< Compression level 10 */ + CPA_DC_L11, + /**< Compression level 11 */ + CPA_DC_L12 + /**< Compression level 12 */ } CpaDcCompLvl; /** @@ -384,6 +482,14 @@ * (not supported) */ CPA_DC_CRC_INTEG_ERR = -20, /**< A data integrity CRC error was detected */ + CPA_DC_LZ4_MAX_BLOCK_SIZE_EXCEEDED = -93, + /**< LZ4 max block size exceeded */ + CPA_DC_LZ4_BLOCK_OVERFLOW_ERR = -95, + /**< LZ4 Block Overflow Error */ + CPA_DC_LZ4_TOKEN_IS_ZERO_ERR = -98, + /**< LZ4 Decoded token offset or token length is zero */ + CPA_DC_LZ4_DISTANCE_OUT_OF_RANGE_ERR = -100, + /**< LZ4 Distance out of range for len/distance pair */ } CpaDcReqStatus; /** @@ -393,11 +499,16 @@ * * @description * This enumeration lists the supported modes for automatically selecting - * the best Huffman encoding which would lead to the best compression - * results. + * the best encoding which would lead to the best compression results. + * + * When CPA_DC_ASB_ENABLED is used the output will be a format compliant + * block, whether the data is compressed or not. * - * The CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS value is deprecated - * and should not be used. + * The following values are deprecated and should not be used. They + * will be removed in a future version of this file. + * - CPA_DC_ASB_STATIC_DYNAMIC + * - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS + * - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS * *****************************************************************************/ typedef enum _CpaDcAutoSelectBest @@ -409,9 +520,11 @@ CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS = 2, /**< Auto select between uncompressed, static and dynamic compression, * using stored block deflate headers if uncompressed is selected */ - CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS = 3 + CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS = 3, /**< Auto select between uncompressed, static and dynamic compression, * using no deflate headers if uncompressed is selected */ + CPA_DC_ASB_ENABLED = 4, + /**< Auto select best mode is enabled */ } CpaDcAutoSelectBest; /** @@ -420,8 +533,8 @@ * Supported modes for skipping regions of input or output buffers. * * @description - * This enumeration lists the supported modes for skipping regions of - * input or output buffers. + * This enumeration lists the supported modes for skipping regions of + * input or output buffers. * *****************************************************************************/ typedef enum _CpaDcSkipMode @@ -433,7 +546,7 @@ CPA_DC_SKIP_AT_END = 2, /**< Skip region is at the end of the buffer. */ CPA_DC_SKIP_STRIDE = 3 - /**< Skip region occurs at regular intervals within the buffer. + /**< Skip region occurs at regular intervals within the buffer. CpaDcSkipData.strideLength specifies the number of bytes between each skip region. */ } CpaDcSkipMode; @@ -547,21 +660,38 @@ CpaBoolean statelessDeflateDecompression; /**sessType should be set to + * CPA_DC_CHAIN_COMPRESS_DECOMPRESS and pSessionData[]->pDcSetupData + * should point to a CpaDcSessionSetupData structure. + * + * -# For a symmetric crypto session, the corresponding + * pSessionData[]->sessType should be set to CPA_DC_CHAIN_SYMMETRIC_CRYPTO + * and pSessionData[]->pCySetupData should point to a + * CpaCySymSessionSetupData structure. + * + * -# Combined compression sessions are not supported for chaining. + * + * -# Stateful compression is not supported for chaining. + * + * -# Both CRC32 and Adler32 over the input data are supported for chaining. + * + * @see + * None + * + *****************************************************************************/ +CpaStatus +cpaDcChainInitSession(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcChainOperations operation, + Cpa8U numSessions, + CpaDcChainSessionSetupData *pSessionData, + CpaDcCallbackFn callbackFn); + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Reset a compression chaining session. + * + * @description + * This function will reset a previously initialized session handle. + * Reset will fail if outstanding calls still exist for the initialized + * session handle. + * The client needs to retry the reset function at a later time. + * + * @context + * This is a synchronous function that cannot sleep. It can be + * executed in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * The session has been initialized via cpaDcChainInitSession function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcChainInitSession() + * + *****************************************************************************/ +CpaStatus +cpaDcChainResetSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle); + + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Remove a compression chaining session. + * + * @description + * This function will remove a previously initialized session handle + * and the installed callback handler function. Removal will fail if + * outstanding calls still exist for the initialized session handle. + * The client needs to retry the remove function at a later time. + * The memory for the session handle MUST not be freed until this call + * has completed successfully. + * + * @context + * This is a synchronous function that cannot sleep. It can be executed + * in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcChainInitSession() + * + *****************************************************************************/ +CpaStatus +cpaDcChainRemoveSession(const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle); + +/** + ***************************************************************************** + * @ingroup cpaDcChain + * Submit a request to perform chaining operations. + * + * @description + * This function is used to perform chaining operations over data from + * the source buffer. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] dcInstance Target service instance. + * @param[in,out] pSessionHandle Session handle. + * @param[in] pSrcBuff Pointer to input data buffer. + * @param[out] pDestBuff Pointer to output data buffer. + * @param[in] operation Operation for the chaining request + * @param[in] numOpDatas The entries size CpaDcChainOpData array + * @param[in] pChainOpData Pointer to an array of CpaDcChainOpData + * structures. There should be numOpDatas + * entries in the array. + * @param[in,out] pResults Pointer to CpaDcChainRqResults structure. + * @param[in] callbackTag User supplied value to help correlate + * the callback with its associated request. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_DC_BAD_DATA The input data was not properly formed. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * pSessionHandle has been setup using cpaDcChainInitSession() + * @post + * pSessionHandle has session related state information + * @note + * This function passes control to the compression service for chaining + * processing, the supported chaining operations are described in + * CpaDcChainOperations. + * + * pChainOpData Setup Rules + * -# Each element in CpaDcChainOpData structure array holds either a + * (de)compression or a symmetric crypto operation data. + * + * -# The order of entries in pChainOpData[] must be consistent with the + * order of operations described for the chaining operation in + * CpaDcChainOperations. + * As an example, for CPA_DC_CHAIN_COMPRESS_THEN_ENCRYPT, pChainOpData[0] + * must contain the compression operation data and pChainOpData[1] must + * contain the encryption operation data. + * + * -# The numOpDatas for each chaining operation are specified in the + * comments for the operation in CpaDcChainOperations. + * + * -# For a (de)compression operation, the corresponding + * pChainOpData[]->opType should be set to + * CPA_DC_CHAIN_COMPRESS_DECOMPRESS and pChainOpData[]->pDcOp should + * point to a CpaDcOpData structure. + * + * -# For a symmetric crypto operation, the corresponding + * pChainOpData[]->opType should be set to + * CPA_DC_CHAIN_SYMMETRIC_CRYPTO and pChainOpData[]->pCySymOp should + * point to a CpaCySymOpData structure. + * + * -# Stateful compression is not supported for chaining. + * + * -# Partial packet processing is not supported. + * + * This function has identical buffer processing rules as + * cpaDcCompressData(). + * + * This function has identical checksum processing rules as + * cpaDcCompressData(), except: + * -# pResults->crc32 is available to application if + * CpaDcSessionSetupData->checksum is set to CPA_DC_CRC32 + * + * -# pResults->adler32 is available to application if + * CpaDcSessionSetupData->checksum is set to CPA_DC_ADLER32 + * + * -# Both pResults->crc32 and pResults->adler32 are available if + * CpaDcSessionSetupData->checksum is set to CPA_DC_CRC32_ADLER32 + * + * Synchronous or asynchronous operation of the API is determined by + * the value of the callbackFn parameter passed to cpaDcChainInitSession() + * when the sessionHandle was setup. If a non-NULL value was specified + * then the supplied callback function will be invoked asynchronously + * with the response of this request. + * + * This function has identical response ordering rules as + * cpaDcCompressData(). + * + * @see + * cpaDcCompressData + * + *****************************************************************************/ +CpaStatus +cpaDcChainPerformOp(CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaBufferList *pSrcBuff, + CpaBufferList *pDestBuff, + CpaDcChainOperations operation, + Cpa8U numOpDatas, + CpaDcChainOpData *pChainOpData, + CpaDcChainRqResults *pResults, + void *callbackTag ); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif + +#endif /* CPA_DC_CHAIN_H */ diff --git a/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h b/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h --- a/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h +++ b/sys/dev/qat/qat_api/include/dc/cpa_dc_dp.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -143,7 +143,11 @@ /**< Instance to which the request is to be enqueued */ CpaDcSessionHandle pSessionHandle; - /**< DC Session associated with the stream of requests */ + /**< DC Session associated with the stream of requests. + * This field is only valid when using the session based API functions. + * This field must be set to NULL if the application wishes to use + * the No-Session (Ns) API. + */ CpaPhysicalAddr srcBuffer; /**< Physical address of the source buffer on which to operate. @@ -215,8 +219,18 @@ * It may be used to store information that might be useful when * processing the response later. */ -} CpaDcDpOpData; + CpaDcNsSetupData *pSetupData; + /**< Pointer to the No-session (Ns) Setup data for configuration of this + * request. + * + * This @ref CpaDcNsSetupData structure must be initialised when using the + * Data Plane No-Session (Ns) API. Otherwise it should be set to NULL. + * When initialized, the existing Data Plane API functions can be used + * as is. + */ + +} CpaDcDpOpData; /** ***************************************************************************** @@ -226,7 +240,7 @@ * @description * This is the callback function prototype. The callback function is * registered by the application using the @ref cpaDcDpRegCbFunc - * function call, and called back on completion of asycnhronous + * function call, and called back on completion of asynchronous * requests made via calls to @ref cpaDcDpEnqueueOp or @ref * cpaDcDpEnqueueOpBatch. * @@ -306,8 +320,8 @@ * Only a synchronous version of this function is provided. * * Session data is expected to include interim checksum values, various - * counters and other other session related data that needs to persist - * between invocations. + * counters and other session related data that needs to persist between + * invocations. * For a given implementation of this API, it is safe to assume that * cpaDcDpGetSessionSize() will always return the same session size and * that the size will not be different for different setup data @@ -405,6 +419,65 @@ CpaDcSessionSetupData *pSessionData ); +/** + ***************************************************************************** + * @ingroup cpaDc + * Compression Session Update Function. + * + * @description + * This function is used to modify some select compression parameters + * of a previously initialized session handlei for a data plane session. + * Th update will fail if resources required for the new session settings + * are not available. Specifically, this function may fail if no + * intermediate buffers are associated with the instance, and the + * intended change would require these buffers. + * This function can be called at any time after a successful call of + * cpaDcDpInitSession(). + * This function does not change the parameters to compression request + * already in flight. + * + * @context + * This is a synchronous function that cannot sleep. It can be + * executed in a context that does not permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * No. + * @reentrant + * No + * @threadSafe + * No + * + * @param[in] dcInstance Instance handle. + * @param[in,out] pSessionHandle Session handle. + * @param[in] pSessionUpdateData Session Data. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request + * + * @pre + * The component has been initialized via cpaDcStartInstance function. + * The session has been initialized via cpaDcDpInitSession function. + * @post + * None + * @note + * This is a synchronous function and has no completion callback + * associated with it. + * + * @see + * cpaDcDpInitSession() + * + *****************************************************************************/ +CpaStatus cpaDcDpUpdateSession( const CpaInstanceHandle dcInstance, + CpaDcSessionHandle pSessionHandle, + CpaDcSessionUpdateData *pSessionUpdateData ); + /** ***************************************************************************** * @ingroup cpaDc @@ -468,7 +541,7 @@ * @description * This function allows a completion callback function to be registered. * The registered callback function is invoked on completion of - * asycnhronous requests made via calls to @ref cpaDcDpEnqueueOp + * asynchronous requests made via calls to @ref cpaDcDpEnqueueOp * or @ref cpaDcDpEnqueueOpBatch. * @context * This is a synchronous function and it cannot sleep. It can be @@ -569,7 +642,8 @@ * * @pre * The session identified by pOpData->pSessionHandle was setup using - * @ref cpaDcDpInitSession. + * @ref cpaDcDpInitSession OR pOpData->pSetupData data structure was + * initialized for No-Session (Ns) usage. * The instance identified by pOpData->dcInstance has had a * callback function registered via @ref cpaDcDpRegCbFunc. * @@ -584,8 +658,6 @@ * @see * @ref cpaDcDpPerformOpNow *****************************************************************************/ - - CpaStatus cpaDcDpEnqueueOp(CpaDcDpOpData *pOpData, const CpaBoolean performOpNow); @@ -665,7 +737,8 @@ * * @pre * The session identified by pOpData[i]->pSessionHandle was setup using - * @ref cpaDcDpInitSession. + * @ref cpaDcDpInitSession OR pOpData[i]->pSetupData data structure was + * initialized for No-Session (Ns) usage. * The instance identified by pOpData[i]->dcInstance has had a * callback function registered via @ref cpaDcDpRegCbFunc. * @@ -694,7 +767,7 @@ * compression data plane API. * * @description - * This function triggers processing of previously enqueed requests on the + * This function triggers processing of previously enqueued requests on the * referenced instance. * * diff --git a/sys/dev/qat/qat_api/include/icp_sal_versions.h b/sys/dev/qat/qat_api/include/icp_sal_versions.h --- a/sys/dev/qat/qat_api/include/icp_sal_versions.h +++ b/sys/dev/qat/qat_api/include/icp_sal_versions.h @@ -27,7 +27,7 @@ /* Part name and number of the accelerator device */ #define SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER 3 -#define SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER 12 +#define SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER 13 #define SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER 0 /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_common.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ * for this interface. * *****************************************************************************/ -#define CPA_CY_API_VERSION_NUM_MAJOR (2) +#define CPA_CY_API_VERSION_NUM_MAJOR (3) /** ***************************************************************************** @@ -98,10 +98,43 @@ * this interface. * *****************************************************************************/ -#define CPA_CY_API_VERSION_NUM_MINOR (3) +#define CPA_CY_API_VERSION_NUM_MINOR (0) /** ***************************************************************************** + * @file cpa_cy_common.h + * @ingroup cpa_cyCommon + * CPA CY API version at least + * @description + * The minimal supported CPA_CY API version. Allow to check if the API + * version is equal or above some version to avoid compilation issues + * with an older API version. + * + *****************************************************************************/ +#define CPA_CY_API_VERSION_AT_LEAST(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR > major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR >= minor)) + +/** + ***************************************************************************** + * @file cpa_cy_common.h + * @ingroup cpa_cyCommon + * CPA CY API version less than + * @description + * The maximum supported CPA_CY API version. Allow to check if the API + * version is below some version to avoid compilation issues with a newer + * API version. + * + *****************************************************************************/ +#define CPA_CY_API_VERSION_LESS_THAN(major, minor) \ + (CPA_CY_API_VERSION_NUM_MAJOR < major || \ + (CPA_CY_API_VERSION_NUM_MAJOR == major && \ + CPA_CY_API_VERSION_NUM_MINOR < minor)) + +/** + ***************************************************************************** + * @file cpa_cy_common.h * @ingroup cpaCyCommon * Request priority * @description diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_dh.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,7 @@ CpaFlatBuffer primeP; /**< Flat buffer containing a pointer to the random odd prime number (p). * The bit-length of this number may be one of 768, 1024, 1536, 2048, - * 3072 or 4096. + * 3072, 4096 or 8192. */ CpaFlatBuffer baseG; /**< Flat buffer containing a pointer to base (g). This MUST comply with @@ -131,7 +131,7 @@ CpaFlatBuffer primeP; /**< Flat buffer containing a pointer to the random odd prime number (p). * The bit-length of this number may be one of 768, 1024, 1536, 2048, - * 3072 or 4096. + * 3072, 4096 or 8192. * This SHOULD be same prime number as was used in the phase 1 key * generation operation. */ CpaFlatBuffer remoteOctetStringPV; @@ -230,7 +230,7 @@ * operations as defined in the PKCS #3 standard. It may be used to * generate the (local) octet string public value (PV) key. * The prime number sizes specified in RFC 2409, 4306, and part of - * RFC 3526 are supported (bit sizes 6144 and 8192 from RFC 3536 are not + * RFC 3526 are supported (bit size 6144 from RFC 3536 is not * supported). * * @context diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_dsa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ec.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,7 +66,7 @@ * 1. Montgomery 25519 Curve | scalar point Multiplication * Input: Montgomery affine coordinate X of point P * Scalar k - * Output: Montgomery affine coordinate X of point [k/P + * Output: Montgomery affine coordinate X of point [k]P * Decode: Scalar k always decoded by implementation * * 2. Montgomery 25519 Curve | generator point Multiplication @@ -80,13 +80,17 @@ * Scalar k * Output: Twisted Edwards affine coordinate X of point [k]P * Twisted Edwards affine coordinate Y of point [k]P - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 4. Twisted Edwards 25519 Curve | generator point Multiplication * Input: Scalar k * Output: Twisted Edwards affine coordinate X of point [k]G * Twisted Edwards affine coordinate Y of point [k]G - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 5. Montgomery 448 Curve | scalar point Multiplication * Input: Montgomery affine coordinate X of point P @@ -105,13 +109,17 @@ * Scalar k * Output: Edwards affine coordinate X of point [k]P * Edwards affine coordinate Y of point [k]P - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * 8. Edwards 448 Curve | generator point Multiplication * Input: Scalar k * Output: Edwards affine coordinate X of point [k]G * Edwards affine coordinate Y of point [k]G - * Decode: Caller must specify if decoding is required + * Decode: Caller must supply parameters in MSB order, the + * implementation will not explicitly decode according + * to RFC#7748 Section 5 * * @note * Large numbers are represented on the QuickAssist API as described @@ -158,6 +166,35 @@ /**< A binary field, GF(2^m) */ } CpaCyEcFieldType; +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Enumeration listing curve types to use with generic multiplication + * and verification routines. + * + * @description + * This structure contains a list of different elliptic curve types. + * EC Point multiplication and other operations depend on the type of + * the curve. + * + * @see + * cpaCyEcGenericPointMultiply() + * cpaCyEcGenericPointVerify() + * + *****************************************************************************/ +typedef enum _CpaCyEcCurveType +{ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_PRIME = 1, + /**< A Weierstrass curve with arithmetic in terms of the + * arithmetic of integers modulo p over a prime field. */ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_BINARY, + /**< A Weierstrass curve with arithmetic in terms of operations on bits + * over a binary field. */ + CPA_CY_EC_CURVE_TYPE_WEIERSTRASS_KOBLITZ_BINARY, + /**< A Weierstrass-koblitz curve with arithmetic in terms of operations on + * the bits over a binary field. */ +} CpaCyEcCurveType; + /** ***************************************************************************** * @ingroup cpaCyEc @@ -175,16 +212,112 @@ CPA_CY_EC_MONTEDWDS_CURVE25519_TYPE = 1, /**< Montgomery 25519 curve */ CPA_CY_EC_MONTEDWDS_ED25519_TYPE, - /**< Twisted Edwards 25519 curve */ + /**< Edwards 25519 curve */ CPA_CY_EC_MONTEDWDS_CURVE448_TYPE, /**< Montgomery 448 curve */ CPA_CY_EC_MONTEDWDS_ED448_TYPE, - /**< Twisted Edwards 448 curve */ + /**< Edwards 448 curve */ } CpaCyEcMontEdwdsCurveType; /** ***************************************************************************** - * @file cpa_cy_ec.h + * @ingroup cpaCyEc + * Curve parameters for a Weierstrass type curve. + * + * @description + * This structure contains curve parameters for Weierstrass type + * curve: y^2 = x^3 + ax + b + * The client MUST allocate the memory for this structure + * When the structure is passed into the function, ownership of the memory + * passes to the function. Ownership of the memory returns to the client + * when this structure is returned in the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * The legend used in this structure is borrowed from RFC7748 + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the function, and before it + * has been returned in the callback, undefined behavior will result. + * + * @see + * CpaCyEcCurveParameters + * CpaCyEcFieldType + * + *****************************************************************************/ +typedef struct _CpaCyEcCurveParametersWeierstrass +{ + CpaCyEcFieldType fieldType; + /**< Prime or Binary */ + CpaFlatBuffer p; + /**< Prime modulus or irreducible polynomial over GF(2^m) */ + CpaFlatBuffer a; + /**< a coefficient */ + CpaFlatBuffer b; + /**< b coefficient */ + CpaFlatBuffer h; + /**< Cofactor */ +} CpaCyEcCurveParametersWeierstrass; + +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Union characterised by a specific curve. + * + * @description + * This union allows for the characterisation of different curve types + * encapsulted in one data type. The intention is that new curve types + * will be added in the future. + * + * @note + * + * @see + * CpaCyEcCurveParametersWeierstrass + * + *****************************************************************************/ +typedef union _CpaCyEcCurveParameters +{ + CpaCyEcCurveParametersWeierstrass weierstrassParameters; +} CpaCyEcCurveParameters; + +/** + ***************************************************************************** + * @ingroup cpaCyEc + * Unified curve parameters. + * + * @description + * This structure provides a single data type that can describe a number + * of different curve types. The intention is to add further + * curve types in the future, thus the union field will allow for that + * expansion. + * + * The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the function, and before it + * has been returned in the callback, undefined behavior will result. + * + * @see + * CpaCyEcCurveParameters + * cpaCyEcGenericPointMultiply + * cpaCyEcGenericPointVerify + * + *****************************************************************************/ +typedef struct _CpaCyEcCurve +{ + CpaCyEcCurveType curveType; + CpaCyEcCurveParameters parameters; +} CpaCyEcCurve; + +/** + ***************************************************************************** * @ingroup cpaCyEc * EC Point Multiplication Operation Data. * @@ -230,21 +363,22 @@ * data pointer of the Flat Buffer to NULL. */ CpaCyEcFieldType fieldType; /**< field type for the operation */ -} CpaCyEcPointMultiplyOpData; - +} CpaCyEcPointMultiplyOpData CPA_DEPRECATED; /** ***************************************************************************** * @ingroup cpaCyEc - * EC Point Verification Operation Data. + * Generic EC Point Multiplication Operation Data. * * @description - * This structure contains the operation data for the cpaCyEcPointVerify - * function. The client MUST allocate the memory for this structure and the - * items pointed to by this structure. When the structure is passed into - * the function, ownership of the memory passes to the function. Ownership - * of the memory returns to the client when this structure is returned in - * the callback function. + * This structure contains a generic EC point and a multiplier for use with + * cpaCyEcGenericPointMultiply. This is common for representing all EC + * points, irrespective of curve type: Weierstrass, Montgomery and Twisted + * Edwards (at this time only Weierstrass are supported). The same + * point + multiplier format can be used when performing generator + * multiplication, in which case the xP, yP supplied in this structure will + * be ignored by QAT API library & a generator point will be inserted in + * their place. * * For optimal performance all data buffers SHOULD be 8-byte aligned. * @@ -253,36 +387,71 @@ * * @note * If the client modifies or frees the memory referenced in this - * structure after it has been submitted to the CpaCyEcPointVerify + * structure after it has been submitted to the cpaCyEcGenericPointMultiply * function, and before it has been returned in the callback, undefined * behavior will result. * * @see - * cpaCyEcPointVerify() + * cpaCyEcGenericPointMultiply() * *****************************************************************************/ -typedef struct _CpaCyEcPointVerifyOpData { - CpaFlatBuffer xq; - /**< x coordinate candidate point */ - CpaFlatBuffer yq; - /**< y coordinate candidate point */ - CpaFlatBuffer q; - /**< prime modulus or irreducible polynomial over GF(2^m) */ - CpaFlatBuffer a; - /**< a elliptic curve coefficient */ - CpaFlatBuffer b; - /**< b elliptic curve coefficient */ +typedef struct _CpaCyEcGenericPointMultiplyOpData { + CpaFlatBuffer k; + /** 0 and k < n) */ + CpaFlatBuffer xP; + /** pair specified in the structure + * lies on the curve indicated in the cpaCyEcGenericPointVerify API. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcGenericPointVerify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcGenericPointVerify() + * + *****************************************************************************/ +typedef struct _CpaCyEcGenericPointVerifyOpData { + CpaFlatBuffer xP; + /** 0 and k < n) */ + CpaFlatBuffer xP; + /**< x coordinate of public key */ + CpaFlatBuffer yP; + /**< y coordinate of public key */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2EncryptOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Decryption Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Decrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Decrypt + * function, and before it has been returned in the callback, undefined + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Decrypt + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Decrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2DecryptOpData { + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaFlatBuffer x1; + /**< x coordinate of [k]G */ + CpaFlatBuffer y1; + /**< y coordinate of [k]G */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2DecryptOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Point Multiplication Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2PointMultiply + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2PointMultiply + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2PointMultiply() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2PointMultiplyOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2PointMultiplyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Generator Multiplication Operation Data. + * + * @description + * This structure contains the operation data for the + * cpaCyEcsm2GeneratorMultiply function. The client MUST allocate the + * memory for this structure and the items pointed to by this structure. + * When the structure is passed into the function, ownership of the + * memory passes to the function. Ownership of the memory returns to the + * client when this structure is returned in the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2GeneratorMultiply + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2GeneratorMultiply() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2GeneratorMultiplyOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2GeneratorMultiplyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Point Verify Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2PointVerify + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2PointVerify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2PointVerify() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2PointVerifyOpData { + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2PointVerifyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Signature Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Sign + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Sign + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Sign() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2SignOpData { + CpaFlatBuffer k; + /**< scalar multiplier (k > 0 and k < n) */ + CpaFlatBuffer e; + /**< digest of the message */ + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2SignOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Signature Verify Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2Verify + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2Verify + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2Verify() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2VerifyOpData { + CpaFlatBuffer e; + /**< digest of the message */ + CpaFlatBuffer r; + /**< signature r */ + CpaFlatBuffer s; + /**< signature s */ + CpaFlatBuffer xP; + /**< x coordinate of public key */ + CpaFlatBuffer yP; + /**< y coordinate of public key */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2VerifyOpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange Phase 1 Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2KeyExPhase1 + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2KeyExPhase1 + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2KeyExPhase1() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExPhase1OpData { + CpaFlatBuffer r; + /**< scalar multiplier (r > 0 and r < n) */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2KeyExPhase1OpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange Phase 2 Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyEcsm2KeyExPhase2 + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. a.pData[0] = MSB. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyEcsm2KeyExPhase2 + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcsm2KeyExPhase2() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExPhase2OpData { + CpaFlatBuffer r; + /**< scalar multiplier (r > 0 and r < n) */ + CpaFlatBuffer d; + /**< private key (d > 0 and d < n) */ + CpaFlatBuffer x1; + /**< x coordinate of a point on the curve from other side */ + CpaFlatBuffer x2; + /**< x coordinate of a point on the curve from phase 1 */ + CpaFlatBuffer y2; + /**< y coordinate of a point on the curve from phase 1 */ + CpaFlatBuffer xP; + /**< x coordinate of public key from other side */ + CpaFlatBuffer yP; + /**< y coordinate of public key from other side */ + CpaCyEcFieldType fieldType; + /**< field type for the operation */ +} CpaCyEcsm2KeyExPhase2OpData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Encryption Output Data. + * + * @description + * This structure contains the output data of the cpaCyEcsm2Encrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2Encrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2EncryptOutputData { + CpaFlatBuffer x1; + /**< x coordinate of [k]G */ + CpaFlatBuffer y1; + /**< y coordinate of [k]G */ + CpaFlatBuffer x2; + /**< x coordinate of [k]Pb */ + CpaFlatBuffer y2; + /**< y coordinate of [k]Pb */ +} CpaCyEcsm2EncryptOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Decryption Output Data. + * + * @description + * This structure contains the output data of the cpaCyEcsm2Decrypt + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2Decrypt() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2DecryptOutputData { + CpaFlatBuffer x2; + /**< x coordinate of [k]Pb */ + CpaFlatBuffer y2; + /**< y coordinate of [k]Pb */ +} CpaCyEcsm2DecryptOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * SM2 Key Exchange (Phase 1 & Phase 2) Output Data. + * + * @description + * This structure contains the output data of the key exchange(phase 1 & 2) + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @see + * cpaCyEcsm2KeyExPhase1(),cpaCyEcsm2KeyExPhase2() + * + *****************************************************************************/ +typedef struct _CpaCyEcsm2KeyExOutputData { + CpaFlatBuffer x; + /**< x coordinate of a point on the curve */ + CpaFlatBuffer y; + /**< y coordinate of a point on the curve */ +} CpaCyEcsm2KeyExOutputData; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Cryptographic ECSM2 Statistics. + * @description + * This structure contains statistics on the Cryptographic ECSM2 + * operations. Statistics are set to zero when the component is + * initialized, and are collected per instance. + * + ****************************************************************************/ +typedef struct _CpaCyEcsm2Stats64 { + Cpa64U numEcsm2PointMultiplyRequests; + /**< Total number of ECSM2 Point Multiplication operation requests. */ + Cpa64U numEcsm2PointMultiplyRequestErrors; + /**< Total number of ECSM2 Point Multiplication operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2PointMultiplyCompleted; + /**< Total number of ECSM2 Point Multiplication operation requests that + * completed successfully. */ + Cpa64U numEcsm2PointMultiplyCompletedError; + /**< Total number of ECSM2 Point Multiplication operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2PointMultiplyCompletedOutputInvalid; + /**< Total number of ECSM2 Point Multiplication or Point Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2GeneratorMultiplyRequests; + /**< Total number of ECSM2 Generator Multiplication operation requests. */ + Cpa64U numEcsm2GeneratorMultiplyRequestErrors; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2GeneratorMultiplyCompleted; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * completed successfully. */ + Cpa64U numEcsm2GeneratorMultiplyCompletedError; + /**< Total number of ECSM2 Generator Multiplication operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2GeneratorMultiplyCompletedOutputInvalid; + /**< Total number of ECSM2 Generator Multiplication or Point Verify + * operation requests that could not be completed successfully due to an + * invalid output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2PointVerifyRequests; + /**< Total number of ECSM2 Point Verify operation requests. */ + Cpa64U numEcsm2PointVerifyRequestErrors; + /**< Total number of ECSM2 Point Verify operation requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2PointVerifyCompleted; + /**< Total number of ECSM2 Point Verify operation requests that + * completed successfully. */ + Cpa64U numEcsm2PointVerifyCompletedError; + /**< Total number of ECSM2 Point Verify operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2PointVerifyCompletedOutputInvalid; + /**< Total number of ECSM2 Point Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2SignRequests; + /**< Total number of ECSM2 Sign operation requests. */ + Cpa64U numEcsm2SignRequestErrors; + /**< Total number of ECSM2 Sign operation requests that had an error + * and could not be processed. */ + Cpa64U numEcsm2SignCompleted; + /**< Total number of ECSM2 Sign operation requests that completed + * successfully. */ + Cpa64U numEcsm2SignCompletedError; + /**< Total number of ECSM2 Sign operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2SignCompletedOutputInvalid; + /**< Total number of ECSM2 Sign operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2VerifyRequests; + /**< Total number of ECSM2 Verify operation requests. */ + Cpa64U numEcsm2VerifyRequestErrors; + /**< Total number of ECSM2 Verify operation requests that had an error + * and could not be processed. */ + Cpa64U numEcsm2VerifyCompleted; + /**< Total number of ECSM2 Verify operation requests that completed + * successfully. */ + Cpa64U numEcsm2VerifyCompletedError; + /**< Total number of ECSM2 Verify operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2VerifyCompletedOutputInvalid; + /**< Total number of ECSM2 Verify operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2EncryptRequests; + /**< Total number of ECSM2 Encryption requests. */ + Cpa64U numEcsm2EncryptRequestErrors; + /**< Total number of ECSM2 Point Encryption requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2EncryptCompleted; + /**< Total number of ECSM2 Encryption operation requests that + * completed successfully. */ + Cpa64U numEcsm2EncryptCompletedError; + /**< Total number of ECSM2 Encryption operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2EncryptCompletedOutputInvalid; + /**< Total number of ECSM2 Encryption operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2DecryptRequests; + /**< Total number of ECSM2 Decryption operation requests. */ + Cpa64U numEcsm2DecryptRequestErrors; + /**< Total number of ECSM2 Point Decryption requests that had + * an error and could not be processed. */ + Cpa64U numEcsm2DecryptCompleted; + /**< Total number of ECSM2 Decryption operation requests that + * completed successfully. */ + Cpa64U numEcsm2DecryptCompletedError; + /**< Total number of ECSM2 Decryption operation requests that could + * not be completed successfully due to errors. */ + Cpa64U numEcsm2DecryptCompletedOutputInvalid; + /**< Total number of ECSM2 Decryption operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2KeyExPhase1Requests; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests. */ + Cpa64U numEcsm2KeyExPhase1RequestErrors; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2KeyExPhase1Completed; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * completed successfully. */ + Cpa64U numEcsm2KeyExPhase1CompletedError; + /**< Total number of ECSM2 Key Exchange Phase1 operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2KeyExPhase1CompletedOutputInvalid; + /**< Total number of ECSM2 Key Exchange Phase1 operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ + + Cpa64U numEcsm2KeyExPhase2Requests; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests. */ + Cpa64U numEcsm2KeyExPhase2RequestErrors; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * had an error and could not be processed. */ + Cpa64U numEcsm2KeyExPhase2Completed; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * completed successfully. */ + Cpa64U numEcsm2KeyExPhase2CompletedError; + /**< Total number of ECSM2 Key Exchange Phase2 operation requests that + * could not be completed successfully due to errors. */ + Cpa64U numEcsm2KeyExPhase2CompletedOutputInvalid; + /**< Total number of ECSM2 Key Exchange Phase2 operation + * requests that could not be completed successfully due to an invalid + * output. Note that this does not indicate an error. */ +} CpaCyEcsm2Stats64; + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Definition of callback function invoked for cpaCyEcsm2Sign + * requests. + * + * @description + * This is the callback function for: + * cpaCyEcsm2Sign + * + * @context + * This callback function can be executed in a context that DOES NOT + * permit sleeping to occur. + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] status Status of the operation. Valid values are + * CPA_STATUS_SUCCESS and CPA_STATUS_FAIL. + * @param[in] pOpData A pointer to Operation data supplied in + * request. + * @param[in] pass Indicate whether pOut is valid or not. + * CPA_TRUE == pass, pOut is valid + * CPA_FALSE == pass, pOut is invalid + * @param[in] pR Ecsm2 message signature r. + * @param[in] pS Ecsm2 message signature s. + * + * @retval + * None + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * cpaCyEcsm2GeneratorMultiply() + * + *****************************************************************************/ +typedef void (*CpaCyEcsm2SignCbFunc)(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaBoolean pass, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Definition of callback function invoked for cpaCyEcsm2Verify requests. + * + * @description + * This is the prototype for the CpaCyEcsm2VerifyCbFunc callback function. + * + * @context + * This callback function can be executed in a context that DOES NOT + * permit sleeping to occur. + * @assumptions + * None + * @sideEffects + * None + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] status Status of the operation. Valid values are + * CPA_STATUS_SUCCESS and CPA_STATUS_FAIL. + * @param[in] pOpData Operation data pointer supplied in request. + * @param[in] verifyStatus The verification status. + * + * @retval + * None + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * cpaCyEcsm2Verify() + * + *****************************************************************************/ +typedef void (*CpaCyEcsm2VerifyCbFunc)(void *pCallbackTag, + CpaStatus status, + void *pOpData, + CpaBoolean verifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Point Multiplication. + * + * @description + * This function performs SM2 Point Multiplication, multiply + * a point (P) by k (scalar) ([k]P). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pMultiplyStatus Multiply status + * CPA_TRUE == pOutputData is valid + * CPA_FALSE == pOutputData is invalid + * @param[out] pXk x coordinate of the resulting point + * multiplication + * @param[out] pYk y coordinate of the resulting point + * multiplication + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2PointMultiplyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2PointMultiplyOpData, + * CpaCyEcPointMultiplyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2PointMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2PointMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk); + +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Generator Multiplication. + * + * @description + * This function performs SM2 Generator Multiplication, multiply the + * generator point (G) by k (scalar) ([k]G). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pMultiplyStatus Multiply status + * CPA_TRUE == pOutputData is valid + * CPA_FALSE == pOutputData is invalid + * @param[out] pXk x coordinate of the resulting point + * multiplication + * @param[out] pYk y coordinate of the resulting point + * multiplication + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcPointMultiplyCbFunc is generated in response to this function + * call. For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2GeneratorMultiplyOpData, + * CpaCyEcPointMultiplyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2GeneratorMultiply(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointMultiplyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2GeneratorMultiplyOpData *pOpData, + CpaBoolean *pMultiplyStatus, + CpaFlatBuffer *pXk, + CpaFlatBuffer *pYk); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Point Verify. + * + * @description + * This function performs SM2 Point Verify, to check if the input point + * on the curve or not. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pVerifyStatus Verification status + * CPA_TRUE == verify pass + * CPA_FALSE == verify fail + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2VerifyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2PointVerifyOpData, + * CpaCyEcPointVerifyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2PointVerify(const CpaInstanceHandle instanceHandle, + const CpaCyEcPointVerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2PointVerifyOpData *pOpData, + CpaBoolean *pVerifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Signature (Step A4 to A7). + * + * @description + * This function implements step A4 to A7 (in Section 5.2 in "Generation + * of Signature" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pSignStatus Signature status + * CPA_TRUE = pOutputData is valid + * CPA_FALSE = pOutputData is invalid + * @param[out] pR R output of the resulting signature operation + * @param[out] pS S output of the resulting signature operation + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2SignCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2SignOpData, + * CpaCyEcsm2SignCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Sign(const CpaInstanceHandle instanceHandle, + const CpaCyEcsm2SignCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2SignOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Signature Verify (Step B5 to B7). + * + * @description + * This function implements step B5 to B7 (in Section 5.3 in "Verification + * of Signature" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pVerifyStatus Status of the signature verification + * CPA_TRUE == verify pass + * CPA_FALSE == verify fail + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcsm2VerifyCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2VerifyOpData, + * CpaCyEcsm2VerifyCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Verify(const CpaInstanceHandle instanceHandle, + const CpaCyEcsm2VerifyCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2VerifyOpData *pOpData, + CpaBoolean *pVerifyStatus); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Encryption (Step A2 to A4). + * + * @description + * This function implements step A2 to A4 (in Section 7.2 in + * "Algorithm for Encryption and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Ecrypted message + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2EncryptOpData, + * CpaCyEcsm2EncryptOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Encrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2EncryptOpData *pOpData, + CpaCyEcsm2EncryptOutputData *pOutputData); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Decryption (Step B1 to B3). + * + * @description + * This function implements step B1 to B3 (in Section 7.3 in "Algorithm + * for Decryption and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Decrypted message + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2DecryptOpData, + * CpaCyEcsm2DecryptOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2Decrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2DecryptOpData *pOpData, + CpaCyEcsm2DecryptOutputData *pOutputData); + +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Key Exchange Phase 1 (Step A2/B2). + * + * @description + * This function implements step A2 (User A) or B2 (User B) + * (in Section 6.2 in "Key Exchange Protocol and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Output of key exchange phase 1 ([r]G) + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2KeyExPhase1OpData, + * CpaCyEcsm2KeyExOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2KeyExPhase1(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase1OpData *pOpData, + CpaCyEcsm2KeyExOutputData *pOutputData); +/** + ***************************************************************************** + * @file cpa_cy_ec.h + * @ingroup cpaCyEcsm2 + * Perform SM2 Key Exchange Phase 2 (Step A4 to A7, B3 to B6). + * + * @description + * This function implements steps A4 to A7(User A) or B3 to B6(User B) + * (in Section 6.2 in "Key Exchange Protocol and the Flow Chart" Part 1). + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pOutputData Output of key exchange phase2. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * When pCb is non-NULL an asynchronous callback of type + * CpaCyGenFlatBufCbFunc is generated in response to this function call. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * + * @see + * CpaCyEcsm2KeyExPhase2OpData, + * CpaCyEcsm2KeyExOutputData, + * CpaCyGenFlatBufCbFunc + * + *****************************************************************************/ +CpaStatus +cpaCyEcsm2KeyExPhase2(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pCb, + void *pCallbackTag, + const CpaCyEcsm2KeyExPhase2OpData *pOpData, + CpaCyEcsm2KeyExOutputData *pOutputData); +/** + ***************************************************************************** + * @file cpa_cy_ecsm2.h + * @ingroup cpaCyEcsm2 + * Query statistics for a specific ECSM2 instance. + * + * @description + * This function will query a specific instance of the ECSM2 implementation + * for statistics. The user MUST allocate the CpaCyEcsm2Stats64 structure + * and pass the reference to that structure into this function call. This + * function writes the statistic results into the passed in + * CpaCyEcsm2Stats64 structure. + * + * Note: statistics returned by this function do not interrupt current data + * processing and as such can be slightly out of sync with operations that + * are in progress during the statistics retrieval process. + * + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[out] pEcsm2Stats Pointer to memory into which the statistics + * will be written. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * Component has been initialized. + * @post + * None + * @note + * This function operates in a synchronous manner and no asynchronous + * callback will be generated. + * @see + * CpaCyEcsm2Stats64 + *****************************************************************************/ + +CpaStatus +cpaCyEcsm2QueryStats64(const CpaInstanceHandle instanceHandle_in, + CpaCyEcsm2Stats64 *pEcsm2Stats); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif + +#endif /*CPA_CY_ECSM2_H_*/ diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_im.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -242,6 +242,9 @@ /**< CPA_TRUE if instance supports the Edwards and Montgomery elliptic * curves of the EC API. * See @ref cpaCyEc */ + CpaBoolean ecSm2Supported; + /**< CPA_TRUE if instance supports the EcSM2 API. + * See @ref cpaCyEcsm2. */ } CpaCyCapabilitiesInfo; /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_key.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -151,8 +151,7 @@ * The length field indicates the length of the label in bytes. To use this * field, the sslOp must be CPA_CY_KEY_SSL_OP_USER_DEFINED, * or otherwise it is ignored and can be set to NULL. - * Implementation-specific limits - * may apply to this length. */ + * Implementation-specific limits may apply to this length. */ } CpaCyKeyGenSslOpData; /** @@ -298,7 +297,7 @@ #define CPA_CY_HKDF_SUBLABEL_FINISHED ((Cpa16U)0x0008) /**< Bit for creation of key material for 'finished' sublabel */ -#define CPA_CY_HKDF_KEY_MAX_SECRET_SZ ((Cpa8U)64) +#define CPA_CY_HKDF_KEY_MAX_SECRET_SZ ((Cpa8U)80) /** space in bytes PSK or (EC)DH */ #define CPA_CY_HKDF_KEY_MAX_HMAC_SZ ((Cpa8U)48) /** space in bytes of CPA_CY_SYM_HASH_SHA384 result */ @@ -346,7 +345,6 @@ /** ***************************************************************************** - * @file cpa_cy_key.h * @ingroup cpaCyKeyGen * TLS data for key generation functions * @description @@ -838,7 +836,6 @@ /** ***************************************************************************** - * @file cpa_cy_key.h * @ingroup cpaCyKeyGen * TLS Key Generation Function version 3. * @description diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_kpt.h @@ -0,0 +1,853 @@ +/*************************************************************************** + * + * BSD LICENSE + * + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * + ***************************************************************************/ + +/* + ***************************************************************************** + * Doxygen group definitions + ****************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * + * @defgroup cpaCyKpt Intel(R) Key Protection Technology (KPT) Cryptographic API + * + * @ingroup cpaCy + * + * @description + * These functions specify the APIs for Key Protection Technology (KPT) + * Cryptographic services. + * + * @note + * These functions implement the KPT Cryptographic API. + * This API is experimental and subject to change. + * + *****************************************************************************/ + +#ifndef __CPA_CY_KPT_H__ +#define __CPA_CY_KPT_H__ + +#ifdef __cplusplus +extern "C" { +#endif +#include "cpa_cy_common.h" +#include "cpa_cy_rsa.h" +#include "cpa_cy_ecdsa.h" +#include "cpa_cy_ec.h" + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT wrapping key handle + * + * @description + * Handle to a unique wrapping key in wrapping key table. Application + * creates it in KPT key transfer phase and maintains it for KPT Crypto + * service. For each KPT Crypto service API invocation, this handle will + * be used to get a SWK(Symmetric Wrapping Key) to unwrap + * WPK(Wrapped Private Key) before performing the requested crypto + * service. + * + *****************************************************************************/ +typedef Cpa64U CpaCyKptHandle; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Return Status + * @description + * This enumeration lists all the possible return status after completing + * KPT APIs. + * + *****************************************************************************/ +typedef enum CpaCyKptKeyManagementStatus_t +{ + CPA_CY_KPT_SUCCESS = 0, + /**< Generic success status for all KPT wrapping key handling functions*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_VFID, + /**< SWK count exceeds the configured maxmium value per VFID*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_PASID, + /**< SWK count exceeds the configured maxmium value per PASID*/ + CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED, + /**< SWK count exceeds the configured maxmium value when not scoped to + * VFID or PASID*/ + CPA_CY_KPT_SWK_FAIL_NOT_FOUND, + /**< Unable to find SWK entry by handle */ + CPA_CY_KPT_FAILED, +} CpaCyKptKeyManagementStatus; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * PKCS#1 v2.2 RSA-3K signature output length in bytes. + * @see CpaCyKptValidationKey + * + *****************************************************************************/ +#define CPA_CY_RSA3K_SIG_SIZE_INBYTES 384 + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT device credentials key certificate + * @description + * This structure defines the key format for use with KPT. + * @see + * cpaCyKptQueryDeviceCredentials + * + *****************************************************************************/ +typedef struct CpaCyKptValidationKey_t +{ + CpaCyRsaPublicKey publicKey; + /**< Key */ + Cpa8U signature[CPA_CY_RSA3K_SIG_SIZE_INBYTES]; + /**< Signature of key */ +} CpaCyKptValidationKey; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Cipher algorithms used to generate a wrapped private key (WPK) from + * the clear private key. + * + * @description + * This enumeration lists supported cipher algorithms and modes. + * + *****************************************************************************/ +typedef enum CpaCyKptWrappingKeyType_t +{ + CPA_CY_KPT_WRAPPING_KEY_TYPE_AES256_GCM = 0 +} CpaCyKptWrappingKeyType; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * KPT Loading key format specification. + * @description + * This structure defines the format of the symmetric wrapping key to be + * loaded into KPT. Application sets these parameters through the + * cpaCyKptLoadKey calls. + * + *****************************************************************************/ +typedef struct CpaCyKptLoadKey_t +{ + CpaFlatBuffer eSWK; + /**< Encrypted SWK */ + CpaCyKptWrappingKeyType wrappingAlgorithm; + /**< Symmetric wrapping algorithm */ +} CpaCyKptLoadKey; + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Max length of initialization vector + * @description + * Defines the permitted max iv length in bytes that may be used in + * private key wrapping/unwrapping.For AEC-GCM, iv length is 12 bytes. + * + *@see cpaCyKptUnwrapContext + * + *****************************************************************************/ +#define CPA_CY_KPT_MAX_IV_LENGTH (12) + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Max length of Additional Authenticated Data + * @description + * Defines the permitted max aad length in bytes that may be used in + * private key wrapping/unwrapping. + * + *@see cpaCyKptUnwrapContext + * + *****************************************************************************/ +#define CPA_CY_KPT_MAX_AAD_LENGTH (16) + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Structure of KPT unwrapping context. + * @description + * This structure is a parameter of KPT crypto APIs, it contains data + * relating to KPT WPK unwrapping, the application needs to fill in this + * information. + * + *****************************************************************************/ +typedef struct CpaCyKptUnwrapContext_t +{ + CpaCyKptHandle kptHandle; + /**< This is application's unique handle that identifies its + * (symmetric) wrapping key*/ + Cpa8U iv[CPA_CY_KPT_MAX_IV_LENGTH]; + /**< Initialization Vector */ + Cpa8U additionalAuthData[CPA_CY_KPT_MAX_AAD_LENGTH]; + /**< A buffer holding the Additional Authenticated Data.*/ + Cpa32U aadLenInBytes; + /**< Number of bytes representing the size of AAD within additionalAuthData + * buffer. */ +} CpaCyKptUnwrapContext; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * RSA Private Key Structure For Representation 1. + * @description + * This structure contains the first representation that can be used for + * describing the RSA private key, represented by the tuple of the + * modulus (N) and the private exponent (D). + * The representation is encrypted as follows: + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * Key = SWK + * AAD = DER(OID) + * Input = (D || N) + * Encrypt (SWK, AAD, (D || N)) + * Output (AuthTag, (D || N)') + * EncryptedRSAKey = (D || N)' + * + * privateKey = (EncryptedRSAKey || AuthTag) + * + * OID's that shall be supported by KPT implementation: + * OID DER(OID) + * 1.2.840.113549.1.1 06 08 2A 86 48 86 F7 0D 01 01 + * + * Permitted lengths for N and D are: + * - 512 bits (64 bytes), + * - 1024 bits (128 bytes), + * - 1536 bits (192 bytes), + * - 2048 bits (256 bytes), + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). + * + * AuthTag is 128 bits (16 bytes) + * + * @note It is important that the value D is big enough. It is STRONGLY + * recommended that this value is at least half the length of the modulus + * N to protect against the Wiener attack. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKeyRep1_t +{ + CpaFlatBuffer privateKey; + /**< The EncryptedRSAKey concatenated with AuthTag */ +} CpaCyKptRsaPrivateKeyRep1; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT RSA Private Key Structure For Representation 2. + * @description + * This structure contains the second representation that can be used for + * describing the RSA private key. The quintuple of p, q, dP, dQ, and qInv + * (explained below and in the spec) are required for the second + * representation. For KPT the parameters are Encrypted + * with the assoicated SWK as follows: + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * Key = SWK + * AAD = DER(OID) + * Input = (P || Q || dP || dQ || Qinv || publicExponentE) + * Expanded Description: + * Encrypt (SWK, AAD, + * (P || Q || dP || dQ || Qinv || publicExponentE)) + * EncryptedRSAKey = (P || Q || dP || dQ || Qinv || publicExponentE)' + * Output (AuthTag, EncryptedRSAKey) + * + * privateKey = EncryptedRSAKey || AuthTag + * + * OID's that shall be supported by KPT implementation: + * OID DER(OID) + * 1.2.840.113549.1.1 06 08 2A 86 48 86 F7 0D 01 01 + * + * All of the encrypted parameters will be of equal size. The length of + * each will be equal to keySize in bytes/2. + * For example for a key size of 256 Bytes (2048 bits), the length of + * P, Q, dP, dQ, and Qinv are all 128 Bytes, plus the + * publicExponentE of 256 Bytes, giving a total size for + * EncryptedRSAKey of 896 Bytes. + * + * AuthTag is 128 bits (16 bytes) + * + * Permitted Key Sizes are: + * - 512 bits (64 bytes), + * - 1024 bits (128 bytes), + * - 1536 bits (192 bytes), + * - 2048 bits (256 bytes), + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKeyRep2_t +{ + CpaFlatBuffer privateKey; + /**< RSA private key representation 2 is built up from the + * tuple of p, q, dP, dQ, qInv, publicExponentE and AuthTag. + */ +} CpaCyKptRsaPrivateKeyRep2; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * RSA Private Key Structure. + * @description + * This structure contains the two representations that can be used for + * describing the RSA private key. The privateKeyRepType will be used to + * identify which representation is to be used. Typically, using the + * second representation results in faster decryption operations. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaPrivateKey_t +{ + CpaCyRsaVersion version; + /**< Indicates the version of the PKCS #1 specification that is + * supported. + * Note that this applies to both representations. */ + CpaCyRsaPrivateKeyRepType privateKeyRepType; + /**< This value is used to identify which of the private key + * representation types in this structure is relevant. + * When performing key generation operations for Type 2 representations, + * memory must also be allocated for the type 1 representations, and values + * for both will be returned. */ + CpaCyKptRsaPrivateKeyRep1 privateKeyRep1; + /**< This is the first representation of the RSA private key as + * defined in the PKCS #1 V2.2 specification. */ + CpaCyKptRsaPrivateKeyRep2 privateKeyRep2; + /**< This is the second representation of the RSA private key as + * defined in the PKCS #1 V2.2 specification. */ +} CpaCyKptRsaPrivateKey; + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT RSA Decryption Primitive Operation Data + * @description + * This structure lists the different items that are required in the + * cpaCyKptRsaDecrypt function. As the RSA decryption primitive and + * signature primitive operations are mathematically identical this + * structure may also be used to perform an RSA signature primitive + * operation. + * When performing an RSA decryption primitive operation, the input data + * is the cipher text and the output data is the message text. + * When performing an RSA signature primitive operation, the input data + * is the message and the output data is the signature. + * The client MUST allocate the memory for this structure. When the + * structure is passed into the function, ownership of the memory passes + * to he function. Ownership of the memory returns to the client when + * this structure is returned in the CpaCyGenFlatBufCbFunc + * callback function. + * + * @note + * If the client modifies or frees the memory referenced in this structure + * after it has been submitted to the cpaCyKptRsaDecrypt function, and + * before it has been returned in the callback, undefined behavior will + * result. + * All values in this structure are required to be in Most Significant Byte + * first order, e.g. inputData.pData[0] = MSB. + * + *****************************************************************************/ +typedef struct CpaCyKptRsaDecryptOpData_t +{ + CpaCyKptRsaPrivateKey *pRecipientPrivateKey; + /**< Pointer to the recipient's RSA private key. */ + CpaFlatBuffer inputData; + /**< The input data that the RSA decryption primitive operation is + * performed on. The data pointed to is an integer that MUST be in big- + * endian order. The value MUST be between 0 and the modulus n - 1. */ +} CpaCyKptRsaDecryptOpData; + + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * KPT ECDSA Sign R & S Operation Data. + * + * @description + * This structure contains the operation data for the cpaCyKptEcdsaSignRS + * function. The client MUST allocate the memory for this structure and the + * items pointed to by this structure. When the structure is passed into + * the function, ownership of the memory passes to the function. Ownership + * of the memory returns to the client when this structure is returned in + * the callback function. + * This key structure is encrypted when passed into cpaCyKptEcdsaSignRS + * Encrypt - AES-256-GCM (Key, AAD, Input) + * "||" - denotes concatenation + * + * Key = SWK + * AAD = DER(OID) + * Input = (d) + * Encrypt (SWK, AAD, (d)) + * Output (AuthTag, EncryptedECKey) + * + * privatekey == EncryptedECKey || AuthTag + * + * OID's that shall be supported by KPT implementation: + * Curve OID DER(OID) + * secp256r1 1.2.840.10045.3.1.7 06 08 2A 86 48 CE 3D 03 01 07 + * secp384r1 1.3.132.0.34 06 05 2B 81 04 00 22 + * secp521r1 1.3.132.0.35 06 05 2B 81 04 00 23 + * + * Expected private key (d) sizes: + * secp256r1 256 bits + * secp384r1 384 bits + * secp521r1 576 bits (rounded up to a multiple of 64-bit quadword) + * + * AuthTag is 128 bits (16 bytes) + * + * For optimal performance all data buffers SHOULD be 8-byte aligned. + * + * @note + * If the client modifies or frees the memory referenced in this + * structure after it has been submitted to the cpaCyKptEcdsaSignRS + * function, and before it has been returned in the callback, undefined + * behavior will result. + * + * @see + * cpaCyEcdsaSignRS() + * + *****************************************************************************/ +typedef struct CpaCyKptEcdsaSignRSOpData_t +{ + CpaFlatBuffer privateKey; + /**< Encrypted private key data of the form + * EncryptECKey || AuthTag */ + CpaFlatBuffer m; + /**< digest of the message to be signed */ +} CpaCyKptEcdsaSignRSOpData; + +/** + ***************************************************************************** + * Discovery and Provisioning APIs for KPT + * + *****************************************************************************/ + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Query KPT's issuing public key(R_Pu) and signature from QAT driver. + * @description + * This function is to query the RSA3K issuing key and its + * PKCS#1 v2.2 SHA-384 signature from the QAT driver. + * @context + * This function may sleep, and MUST NOT be called in interrupt context. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @param[in] instanceHandle Instance handle. + * @param[out] pIssueCert KPT-2.0 Issuing certificate in PEM format + as defined in RFC#7468 + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Issuing key retrieved successfully + * CPA_CY_KPT_FAILED Operation failed + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_FAIL Function failed. Suggested course of action + * is to shutdown and restart. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * Note that this is a synchronous function and has no completion callback + * associated with it. + * @see + * + *****************************************************************************/ + CpaStatus + cpaCyKptQueryIssuingKeys(const CpaInstanceHandle instanceHandle, + CpaFlatBuffer *pPublicX509IssueCert, + CpaCyKptKeyManagementStatus *pKptStatus); + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Query KPT's Per-Part public key(I_pu) and signature from QAT + * device + * @description + * This function is to query RSA3K Per-Part public key and its + * PKCS#1 v2.2 SHA-384 signature from the QAT device. + * @context + * This function may sleep, and MUST NOT be called in interrupt context. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @param[in] instanceHandle Instance handle. + * @param[out] pDevCredential Device Per-Part public key + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Device credentials retrieved successfully + * CPA_CY_KPT_FAILED Operation failed + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_FAIL Function failed. Suggested course of action + * is to shutdown and restart. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * Note that this is a synchronous function and has no completion callback + * associated with it. + * @see + * + *****************************************************************************/ + CpaStatus + cpaCyKptQueryDeviceCredentials(const CpaInstanceHandle instanceHandle, + CpaCyKptValidationKey *pDevCredential, + CpaCyKptKeyManagementStatus *pKptStatus); + + /** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT key loading function. + * + * @description + * This function is invoked by a QAT application to load an encrypted + * symmetric wrapping key. + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle QAT service instance handle. + * @param[in] pSWK Encrypted SWK + * @param[out] keyHandle A 64-bit handle value created by KPT + * @param[out] pKptStatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Key Loaded successfully + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_VFID + * SWK count exceeds the configured maxmium value per VFID + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED_PER_PASID + * SWK count exceeds the configured maxmium value per PASID + * CPA_CY_KPT_LOADKEY_FAIL_QUOTA_EXCEEDED + * SWK count exceeds the configured maxmium value when not scoped to + * VFID or PASID + * CPA_CY_KPT_FAILED Operation failed due to unspecified reason + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * @retval CPA_STATUS_UNSUPPORTED KPT-2.0 is not supported. + * + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * None + *****************************************************************************/ + CpaStatus + cpaCyKptLoadKey(CpaInstanceHandle instanceHandle, + CpaCyKptLoadKey *pSWK, + CpaCyKptHandle *keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus); + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT delete keys function according to key handle + * + * @description + * Before closing a QAT session(instance), an application that has + * previously stored its wrapping key in a QAT device using the KPT + * framework executes this call to delete its wrapping key in the QAT + * device. + * @context + * This is a synchronous function and it can sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * This function is synchronous and blocking. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle QAT service instance handle. + * @param[in] keyHandle A 64-bit handle value + * @param[out] pkptstatus One of the status codes denoted in the + * enumerate type CpaCyKptKeyManagementStatus + * CPA_CY_KPT_SUCCESS Key Deleted successfully + * CPA_CY_KPT_SWK_FAIL_NOT_FOUND For any reason the input handle cannot be + * found. + * CPA_CY_KPT_FAILED Operation failed due to unspecified reason + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. + * Resubmit the request. + * @pre + * Component has been initialized. + * @post + * None + * @note + * None + * @see + * None + *****************************************************************************/ +CpaStatus +cpaCyKptDeleteKey(CpaInstanceHandle instanceHandle, + CpaCyKptHandle keyHandle, + CpaCyKptKeyManagementStatus *pKptStatus); + +/** +***************************************************************************** +* Usage APIs for KPT +* +*****************************************************************************/ + +/** + ***************************************************************************** + * @file cpa_cy_kpt.h + * @ingroup cpaCyKpt + * Perform KPT-2.0 mode RSA decrypt primitive operation on the input data. + * + * @description + * This function is a variant of cpaCyRsaDecrypt, which will perform + * an RSA decryption primitive operation on the input data using the + * specified RSA private key which are encrypted. As the RSA decryption + * primitive and signing primitive operations are mathematically + * identical this function may also be used to perform an RSA signing + * primitive operation. + * + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pRsaDecryptCb Pointer to callback function to be invoked + * when the operation is complete. If this is + * set to a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag Opaque User Data for this specific call. + * Will be returned unchanged in the callback. + * @param[in] pDecryptOpData Structure containing all the data needed to + * perform the RSA decrypt operation. The + * client code allocates the memory for this + * structure. This component takes ownership + * of the memory until it is returned in the + * callback. + * @param[out] pOutputData Pointer to structure into which the result of + * the RSA decryption primitive is written. The + * client MUST allocate this memory. The data + * pointed to is an integer in big-endian order. + * The value will be between 0 and the modulus + * n - 1. + * On invocation the callback function will + * contain this parameter in the pOut parameter. + * @param[in] pKptUnwrapContext Pointer of structure into which the content + * of KptUnwrapContext is kept. The client MUST + * allocate this memory and copy structure + * KptUnwrapContext into this flat buffer. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting.Resubmit + * the request. + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * By virtue of invoking cpaSyKptRsaDecrypt, the implementation understands + * that pDecryptOpData contains an encrypted private key that requires + * unwrapping. KptUnwrapContext contains a 'KptHandle' field that points + * to the unwrapping key in the WKT. + * When pRsaDecryptCb is non-NULL an asynchronous callback is generated in + * response to this function call. + * Any errors generated during processing are reported as part of the + * callback status code. For optimal performance, data pointers SHOULD be + * 8-byte aligned. + * In KPT release, private key field in CpaCyKptRsaDecryptOpData is a + * concatenation of cipher text and hash tag. + * For optimal performance, data pointers SHOULD be 8-byte aligned. + * @see + * CpaCyKptRsaDecryptOpData, + * CpaCyGenFlatBufCbFunc, + * + *****************************************************************************/ +CpaStatus +cpaCyKptRsaDecrypt(const CpaInstanceHandle instanceHandle, + const CpaCyGenFlatBufCbFunc pRsaDecryptCb, + void *pCallbackTag, + const CpaCyKptRsaDecryptOpData *pDecryptOpData, + CpaFlatBuffer *pOutputData, + CpaCyKptUnwrapContext *pKptUnwrapContext); + +/** + ***************************************************************************** + * @ingroup cpaCyKpt + * Generate ECDSA Signature R & S. + * @description + * This function is a variant of cpaCyEcdsaSignRS, it generates ECDSA + * signature R & S as per ANSI X9.62 2005 section 7.3. + * @context + * When called as an asynchronous function it cannot sleep. It can be + * executed in a context that does not permit sleeping. + * When called as a synchronous function it may sleep. It MUST NOT be + * executed in a context that DOES NOT permit sleeping. + * @assumptions + * None + * @sideEffects + * None + * @blocking + * Yes when configured to operate in synchronous mode. + * @reentrant + * No + * @threadSafe + * Yes + * + * @param[in] instanceHandle Instance handle. + * @param[in] pCb Callback function pointer. If this is set to + * a NULL value the function will operate + * synchronously. + * @param[in] pCallbackTag User-supplied value to help identify request. + * @param[in] pOpData Structure containing all the data needed to + * perform the operation. The client code + * allocates the memory for this structure. This + * component takes ownership of the memory until + * it is returned in the callback. + * @param[out] pSignStatus In synchronous mode, the multiply output is + * valid (CPA_TRUE) or the output is invalid + * (CPA_FALSE). + * @param[out] pR ECDSA message signature r. + * @param[out] pS ECDSA message signature s. + * @param[in] pKptUnwrapContext Pointer of structure into which the content + * of KptUnwrapContext is kept,The client MUST + * allocate this memory and copy structure + * KptUnwrapContext into this flat buffer. + * + * @retval CPA_STATUS_SUCCESS Function executed successfully. + * @retval CPA_STATUS_FAIL Function failed. + * @retval CPA_STATUS_RETRY Resubmit the request. + * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in. + * @retval CPA_STATUS_RESOURCE Error related to system resources. + * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit + * the request. + * @retval CPA_STATUS_UNSUPPORTED Function is not supported. + * + * @pre + * The component has been initialized via cpaCyStartInstance function. + * @post + * None + * @note + * By virtue of invoking the cpaCyKptEcdsaSignRS, the implementation + * understands CpaCyEcdsaSignRSOpData contains an encrypted private key that + * requires unwrapping. KptUnwrapContext contains a 'KptHandle' field + * that points to the unwrapping key in the WKT. + * When pCb is non-NULL an asynchronous callback of type + * CpaCyEcdsaSignRSCbFunc generated in response to this function + * call. + * In KPT release, private key field in CpaCyEcdsaSignRSOpData is a + * concatenation of cipher text and hash tag. + * @see + * None + *****************************************************************************/ +CpaStatus +cpaCyKptEcdsaSignRS(const CpaInstanceHandle instanceHandle, + const CpaCyEcdsaSignRSCbFunc pCb, + void *pCallbackTag, + const CpaCyKptEcdsaSignRSOpData *pOpData, + CpaBoolean *pSignStatus, + CpaFlatBuffer *pR, + CpaFlatBuffer *pS, + CpaCyKptUnwrapContext *pKptUnwrapContext); + +#ifdef __cplusplus +} /* close the extern "C" { */ +#endif +#endif diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ln.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -76,8 +76,8 @@ * MSB is b[0]. Otherwise, all bytes from b[0] up to the MSB MUST be * set to 0x00. * - * The largest bit-length we support today is 4096 bits. In other - * words, we can deal with numbers up to a value of (2^4096)-1. + * The largest bit-length we support today is 8192 bits. In other + * words, we can deal with numbers up to a value of (2^8192)-1. * *****************************************************************************/ @@ -110,21 +110,21 @@ * result. * The values of the base, the exponent and the modulus MUST all be less - * than 2^4096, and the modulus must not be equal to zero. + * than 2^8192, and the modulus must not be equal to zero. *****************************************************************************/ typedef struct _CpaCyLnModExpOpData { CpaFlatBuffer modulus; /**< Flat buffer containing a pointer to the modulus. - * This number may be up to 4096 bits in length, and MUST be greater + * This number may be up to 8192 bits in length, and MUST be greater * than zero. */ CpaFlatBuffer base; /**< Flat buffer containing a pointer to the base. - * This number may be up to 4096 bits in length. + * This number may be up to 8192 bits in length. */ CpaFlatBuffer exponent; /**< Flat buffer containing a pointer to the exponent. - * This number may be up to 4096 bits in length. + * This number may be up to 8192 bits in length. */ } CpaCyLnModExpOpData; @@ -146,19 +146,19 @@ * result. * * Note that the values of A and B MUST NOT both be even numbers, and - * both MUST be less than 2^4096. + * both MUST be less than 2^8192. *****************************************************************************/ typedef struct _CpaCyLnModInvOpData { CpaFlatBuffer A; /**< Flat buffer containing a pointer to the value that will be * inverted. - * This number may be up to 4096 bits in length, it MUST NOT be zero, + * This number may be up to 8192 bits in length, it MUST NOT be zero, * and it MUST be co-prime with B. */ CpaFlatBuffer B; /**< Flat buffer containing a pointer to the value that will be used as * the modulus. - * This number may be up to 4096 bits in length, it MUST NOT be zero, + * This number may be up to 8192 bits in length, it MUST NOT be zero, * and it MUST be co-prime with A. */ } CpaCyLnModInvOpData; diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_prime.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_rsa.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -138,8 +138,9 @@ * - 1024 bits (128 bytes), * - 1536 bits (192 bytes), * - 2048 bits (256 bytes), - * - 3072 bits (384 bytes), or - * - 4096 bits (512 bytes). + * - 3072 bits (384 bytes), + * - 4096 bits (512 bytes), or + * - 8192 bits (1024 bytes). */ CpaFlatBuffer privateExponentD; /**< The private exponent (d). For key generation operations the @@ -467,6 +468,17 @@ Cpa64U numRsaDecryptCompletedErrors; /**< Total number of RSA decrypt operations that could not be * completed successfully due to errors. */ + Cpa64U numKptRsaDecryptRequests; + /**< Total number of successful KPT RSA decrypt operation requests. */ + Cpa64U numKptRsaDecryptRequestErrors; + /**< Total number of KPT RSA decrypt requests that had an error and could + * not be processed. */ + Cpa64U numKptRsaDecryptCompleted; + /**< Total number of KPT RSA decrypt operations that completed + * successfully. */ + Cpa64U numKptRsaDecryptCompletedErrors; + /**< Total number of KPT RSA decrypt operations that could not be + * completed successfully due to errors. */ } CpaCyRsaStats64; /** diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -372,17 +372,17 @@ * CPA_CY_SYM_HASH_MODE_AUTH. Only 128-bit keys are supported. */ CPA_CY_SYM_HASH_ZUC_EIA3, /**< ZUC algorithm in EIA3 mode */ - CPA_CY_SYM_HASH_SHA3_224, - /**< 224 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and - * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash - * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. - */ CPA_CY_SYM_HASH_SHA3_256, /**< 256 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. * Partial requests are not supported, that is, only requests * of CPA_CY_SYM_PACKET_TYPE_FULL are supported. */ + CPA_CY_SYM_HASH_SHA3_224, + /**< 224 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and + * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash + * mode CPA_CY_SYM_HASH_MODE_NESTED is not supported for this algorithm. + */ CPA_CY_SYM_HASH_SHA3_384, /**< 384 bit SHA-3 algorithm. Only CPA_CY_SYM_HASH_MODE_PLAIN and * CPA_CY_SYM_HASH_MODE_AUTH are supported, that is, the hash @@ -1453,7 +1453,7 @@ *****************************************************************************/ CpaStatus cpaCySymSessionInUse(CpaCySymSessionCtx sessionCtx, - CpaBoolean* pSessionInUse); + CpaBoolean* pSessionInUse); /** ***************************************************************************** @@ -1519,6 +1519,9 @@ * - The cipher algorithm is not CPA_CY_SYM_CIPHER_CHACHA and the hash * algorithm is not CPA_CY_SYM_HASH_POLY. * + * - The cipher algorithm is not CPA_CY_SYM_CIPHER_AES_GCM and the hash + * algorithm is not CPA_CY_SYM_HASH_AES_GCM. + * * - The instance/implementation supports partial packets as one of * its capabilities (see @ref CpaCySymCapabilitiesInfo). * diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h --- a/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h +++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_sym_dp.h @@ -2,7 +2,7 @@ * * BSD LICENSE * - * Copyright(c) 2007-2022 Intel Corporation. All rights reserved. + * Copyright(c) 2007-2023 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h b/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h --- a/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h +++ b/sys/dev/qat/qat_api/qat_direct/include/icp_accel_devices.h @@ -98,7 +98,10 @@ DEVICE_200XXVF, DEVICE_C4XXX, DEVICE_C4XXXVF, - DEVICE_GEN4 + DEVICE_D15XX, + DEVICE_D15XXVF, + DEVICE_4XXX, + DEVICE_4XXXVF } device_type_t; /* diff --git a/sys/dev/qat/qat_common/adf_aer.c b/sys/dev/qat/qat_common/adf_aer.c --- a/sys/dev/qat/qat_common/adf_aer.c +++ b/sys/dev/qat/qat_common/adf_aer.c @@ -284,8 +284,6 @@ adf_error_notifier((uintptr_t)accel_dev); if (!accel_dev->is_vf) { - if (accel_dev->u1.pf.vf_info) - adf_pf2vf_notify_fatal_error(accel_dev); adf_dev_autoreset(accel_dev); } diff --git a/sys/dev/qat/qat_common/adf_cfg.c b/sys/dev/qat/qat_common/adf_cfg.c --- a/sys/dev/qat/qat_common/adf_cfg.c +++ b/sys/dev/qat/qat_common/adf_cfg.c @@ -5,6 +5,8 @@ #include "adf_cfg.h" #include "adf_common_drv.h" #include "adf_cfg_dev_dbg.h" +#include "adf_cfg_device.h" +#include "adf_cfg_sysctl.h" #include "adf_heartbeat_dbg.h" #include "adf_ver_dbg.h" #include "adf_fw_counters.h" @@ -30,8 +32,54 @@ sx_init(&dev_cfg_data->lock, "qat cfg data"); accel_dev->cfg = dev_cfg_data; + /* Default device configuration initialization */ + if (!accel_dev->is_vf) { + + if (IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev)))) { + dev_cfg_data->num_user_processes = + ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM; + + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL_USER, + ADF_CFG_MAX_VAL); + + if (accel_dev->accel_id % 2 == 0) { + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_SYM_ASYM, + ADF_CFG_MAX_VAL); + } else { + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_DC, + ADF_CFG_MAX_VAL); + } + } else { + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL, + ADF_CFG_MAX_VAL); + dev_cfg_data->num_user_processes = 0; + strncpy(dev_cfg_data->cfg_services, + ADF_CFG_SYM_DC, + ADF_CFG_MAX_VAL); + } + } else { + dev_cfg_data->num_user_processes = + ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM; + + strncpy(dev_cfg_data->cfg_mode, + ADF_CFG_KERNEL, + ADF_CFG_MAX_VAL); + + strncpy(dev_cfg_data->cfg_services, + "sym;asym", + ADF_CFG_MAX_VAL); + } + + if (adf_cfg_sysctl_add(accel_dev)) + goto err; + if (adf_cfg_dev_dbg_add(accel_dev)) goto err; + if (!accel_dev->is_vf) { if (adf_heartbeat_dbg_add(accel_dev)) goto err; @@ -94,6 +142,7 @@ adf_cfg_section_del_all(&dev_cfg_data->sec_list); sx_xunlock(&dev_cfg_data->lock); + adf_cfg_sysctl_remove(accel_dev); adf_cfg_dev_dbg_remove(accel_dev); if (!accel_dev->is_vf) { adf_ver_dbg_del(accel_dev); diff --git a/sys/dev/qat/qat_common/adf_cfg_device.c b/sys/dev/qat/qat_common/adf_cfg_device.c --- a/sys/dev/qat/qat_common/adf_cfg_device.c +++ b/sys/dev/qat/qat_common/adf_cfg_device.c @@ -7,7 +7,7 @@ #include "icp_qat_hw.h" #include "adf_common_drv.h" -#define ADF_CFG_SVCS_MAX (25) +#define ADF_CFG_SVCS_MAX (12) #define ADF_CFG_DEPRE_PARAMS_NUM (4) #define ADF_CFG_CAP_DC ADF_ACCEL_CAPABILITIES_COMPRESSION @@ -83,6 +83,14 @@ ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + { "asym;sym", + ADF_CFG_CY_RINGS, + ADF_CFG_CAP_CY, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + { "sym;asym", + ADF_CFG_CY_RINGS, + ADF_CFG_CAP_CY, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, { "sym", ADF_CFG_SYM_RINGS, @@ -116,57 +124,6 @@ ADF_CFG_SYM_DC_RINGS, ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;sym", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "sym;inline", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;asym", - ADF_CFG_SYM_RINGS, - ADF_CFG_CAP_SYM, - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "asym;inline", - ADF_CFG_ASYM_RINGS, - ADF_CFG_CAP_ASYM, - ADF_CFG_FW_CAP_ECEDMONT }, - { "inline", 0, 0, 0 }, - { "inline;cy", - ADF_CFG_CY_RINGS, - ADF_CFG_CAP_CY, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "cy;inline", - ADF_CFG_CY_RINGS, - ADF_CFG_CAP_CY, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;inline", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, - { "inline;dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, - { "cy;dc;inline", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "cy;inline;dc", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;inline;cy", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "dc;cy;inline", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;cy;dc", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, - { "inline;dc;cy", - ADF_CFG_CY_DC_RINGS, - ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, - ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, } }, { ADF_FW_IMAGE_CRYPTO, { @@ -174,8 +131,7 @@ ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "sym", ADF_CFG_SYM_RINGS, ADF_CFG_CAP_SYM, @@ -196,8 +152,7 @@ ADF_CFG_CY_RINGS, ADF_CFG_CAP_CY, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 }, { "sym", ADF_CFG_SYM_RINGS, @@ -212,14 +167,12 @@ ADF_CFG_CY_DC_RINGS, ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "dc;cy", ADF_CFG_CY_DC_RINGS, ADF_CFG_CAP_CY | ADF_CFG_CAP_DC, ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF | - ADF_CFG_FW_CAP_ECEDMONT | - ADF_CFG_FW_CAP_EXT_ALGCHAIN }, + ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN }, { "asym;dc", ADF_CFG_ASYM_DC_RINGS, ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC, @@ -380,9 +333,34 @@ void adf_cfg_set_asym_rings_mask(struct adf_accel_dev *accel_dev) { + int service; + u16 ena_srv_mask; + u16 service_type; + u16 asym_mask = 0; + struct adf_cfg_device *cfg_dev = accel_dev->cfg->dev; struct adf_hw_device_data *hw_data = accel_dev->hw_device; - hw_data->asym_rings_mask = 0; + if (!cfg_dev) { + hw_data->asym_rings_mask = ADF_CFG_DEF_ASYM_MASK; + return; + } + + ena_srv_mask = accel_dev->hw_device->ring_to_svc_map; + + /* parse each service */ + for (service = 0; service < ADF_CFG_MAX_SERVICES; service++) { + service_type = GET_SRV_TYPE(ena_srv_mask, service); + switch (service_type) { + case CRYPTO: + case ASYM: + SET_ASYM_MASK(asym_mask, service); + if (service_type == CRYPTO) + service++; + break; + } + } + + hw_data->asym_rings_mask = asym_mask; } void @@ -579,7 +557,6 @@ { u32 enabled_svc_caps = 0; u32 enabled_fw_caps = 0; - if (adf_cfg_get_caps_enabled(accel_dev, &enabled_svc_caps, &enabled_fw_caps)) @@ -701,47 +678,342 @@ device->instances = NULL; } +/* + * Static configuration for userspace + */ static int -adf_cfg_static_conf(struct adf_accel_dev *accel_dev) +adf_cfg_static_conf_user(struct adf_accel_dev *accel_dev, + int cy_enabled, + int dc_enabled) { int ret = 0; unsigned long val = 0; char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; - int cpus; - int instances = 0; - int cy_poll_instances; - int cy_irq_instances; - int dc_instances; + int cy_user_instances = 0; + int dc_user_instances = 0; int i = 0; + int cpus = num_online_cpus(); + + if (!(IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev))))) { + device_printf( + GET_DEV(accel_dev), + "User space configuration supported only on QAT 4xxx devices\n"); + return ENXIO; + } + + ret |= adf_cfg_section_add(accel_dev, ADF_SAL_SEC); + + if (accel_dev->is_vf) { + if (cy_enabled) + cy_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_CY_VF; + + if (dc_enabled) + dc_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_DC_VF; + } else { + if (cy_enabled) + cy_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_CY; + + if (dc_enabled) + dc_user_instances = + ADF_CFG_STATIC_CONF_USER_INST_NUM_DC; + } + + val = cy_user_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = dc_user_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = accel_dev->cfg->num_user_processes; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_PROCESSES); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + for (i = 0; i < cy_user_instances; i++) { + val = (accel_dev->accel_id * cy_user_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = 0; i < dc_user_instances; i++) { + val = (accel_dev->accel_id * dc_user_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR); + } - cpus = num_online_cpus(); - instances = - GET_MAX_BANKS(accel_dev) > cpus ? GET_MAX_BANKS(accel_dev) : cpus; + return ret; +} + +static int +adf_cfg_static_conf_kernel(struct adf_accel_dev *accel_dev, + int asym_enabled, + int sym_enabled, + int dc_enabled) +{ + int ret = 0; + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + unsigned long val = 0; + int i = 0; + int instances = 0; + int cy_poll_instances = 0; + int cy_irq_instances = 0; + int dc_instances = 0; + int def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL; + int def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ; + int def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC; + int cpus = num_online_cpus(); + + instances = GET_MAX_BANKS(accel_dev); if (!instances) return EFAULT; - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_DC) - dc_instances = ADF_CFG_STATIC_CONF_INST_NUM_DC; - else - return EFAULT; - instances -= dc_instances; + if (accel_dev->is_vf) { + def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL_VF; + def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ_VF; + def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC_VF; + } - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL) - cy_poll_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL; - else - return EFAULT; - instances -= cy_poll_instances; + /* Get the mode enabled by user */ + ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC); - if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ) - cy_irq_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ; - else - return EFAULT; - instances -= cy_irq_instances; + if (dc_enabled) { + if (instances >= def_dc_inst) { + dc_instances = def_dc_inst; + instances -= dc_instances; + } else { + return EFAULT; + } + } + + if (asym_enabled || sym_enabled) { + if (instances >= def_cy_poll_inst) { + cy_poll_instances = def_cy_poll_inst; + instances -= cy_poll_instances; + } else { + return EFAULT; + } + + if (sym_enabled) { + if (instances >= def_cy_irq_inst) { + cy_irq_instances = def_cy_irq_inst; + instances -= cy_irq_instances; + } else { + return EFAULT; + } + } + } + + val = (cy_poll_instances + cy_irq_instances); + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = dc_instances; + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + for (i = 0; i < (cy_irq_instances); i++) { + val = (accel_dev->accel_id * cy_irq_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_IRQ; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances); + i++) { + val = (accel_dev->accel_id * cy_poll_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_CY_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + for (i = 0; i < dc_instances; i++) { + val = (accel_dev->accel_id * dc_instances + i) % cpus; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + val = ADF_CFG_STATIC_CONF_POLL; + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC "%d" ADF_POLL_MODE, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); + + snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); + snprintf(key, + ADF_CFG_MAX_KEY_LEN_IN_BYTES, + ADF_DC_NAME_FORMAT, + i); + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + } + + return ret; +} + +static int +adf_cfg_static_conf(struct adf_accel_dev *accel_dev) +{ + int ret = 0; + unsigned long val = 0; + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + char *token, *cur_str; + int ks_enabled = 0; + int us_enabled = 0; + int asym_enabled = 0; + int sym_enabled = 0; + int cy_enabled = 0; + int dc_enabled = 0; + + strncpy(value, accel_dev->cfg->cfg_mode, ADF_CFG_MAX_VAL); + cur_str = value; + + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + while (token) { + if (!strncmp(token, ADF_CFG_KERNEL, strlen(ADF_CFG_KERNEL))) + ks_enabled = 1; + if (!strncmp(token, ADF_CFG_USER, strlen(ADF_CFG_USER))) + us_enabled = 1; + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + } + + /* Get the services enabled by user */ + strncpy(value, accel_dev->cfg->cfg_services, ADF_CFG_MAX_VAL); + cur_str = value; + + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + while (token) { + if (!strncmp(token, ADF_CFG_SYM, strlen(ADF_CFG_SYM))) { + sym_enabled = 1; + } + if (!strncmp(token, ADF_CFG_ASYM, strlen(ADF_CFG_ASYM))) { + asym_enabled = 1; + } + /* cy means both asym & crypto should be enabled + * Hardware resources allocation check will be done later + */ + if (!strncmp(token, ADF_CFG_CY, strlen(ADF_CFG_CY))) { + asym_enabled = 1; + sym_enabled = 1; + } + if (!strncmp(token, ADF_SERVICE_DC, strlen(ADF_SERVICE_DC))) { + dc_enabled = 1; + } + + token = strsep(&cur_str, ADF_SERVICES_SEPARATOR); + } + + if (asym_enabled || sym_enabled) { + cy_enabled = 1; + } ret |= adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC); + snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED); - ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC); + if (strcmp(ADF_CFG_SYM_ASYM, accel_dev->cfg->cfg_services) == 0) { + strncpy(value, ADF_CFG_CY, ADF_CFG_MAX_VAL_LEN_IN_BYTES); + } else { + strncpy(value, + accel_dev->cfg->cfg_services, + ADF_CFG_MAX_VAL_LEN_IN_BYTES); + } + + ret |= adf_cfg_add_key_value_param( + accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR); val = ADF_CFG_STATIC_CONF_VER; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CONFIG_VERSION); @@ -769,6 +1041,15 @@ return EFAULT; } + /* User defined adjustement basing on serives enabled */ + if (cy_enabled && !dc_enabled) { + cy_au += dc_au; + dc_au = 0; + } else if (!cy_enabled && dc_enabled) { + dc_au += cy_au; + cy_au = 0; + } + val = cy_au; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, @@ -806,22 +1087,6 @@ ret |= adf_cfg_add_key_value_param( accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC); - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED); - if ((cy_poll_instances + cy_irq_instances) == 0 && dc_instances > 0) { - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_DC); - } else if (((cy_poll_instances + cy_irq_instances)) > 0 && - dc_instances == 0) { - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_SYM); - } else { - snprintf(value, - ADF_CFG_MAX_VAL_LEN_IN_BYTES, - "%s;%s", - ADF_CFG_SYM, - ADF_CFG_DC); - } - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR); - val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC; snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DC); ret |= adf_cfg_add_key_value_param( @@ -877,97 +1142,20 @@ ret |= adf_cfg_add_key_value_param( accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC); - val = (cy_poll_instances + cy_irq_instances); - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = dc_instances; - snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - for (i = 0; i < (cy_irq_instances); i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_IRQ; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + if (ks_enabled) { + ret |= adf_cfg_static_conf_kernel(accel_dev, + asym_enabled, + sym_enabled, + dc_enabled); } - for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances); - i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_POLL; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_CY_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); - } - - for (i = 0; i < dc_instances; i++) { - val = i; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - val = ADF_CFG_STATIC_CONF_POLL; - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC "%d" ADF_POLL_MODE, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC); - - snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i); - snprintf(key, - ADF_CFG_MAX_KEY_LEN_IN_BYTES, - ADF_DC_NAME_FORMAT, - i); - ret |= adf_cfg_add_key_value_param( - accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR); + if (us_enabled) { + ret |= + adf_cfg_static_conf_user(accel_dev, cy_enabled, dc_enabled); } if (ret) - ret = EFAULT; + ret = ENXIO; return ret; } diff --git a/sys/dev/qat/qat_common/adf_cfg_sysctl.c b/sys/dev/qat/qat_common/adf_cfg_sysctl.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_cfg_sysctl.c @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_cfg.h" +#include "adf_cfg_sysctl.h" +#include "adf_cfg_device.h" +#include "adf_common_drv.h" +#include +#include + +#define ADF_CFG_SYSCTL_BUF_SZ ADF_CFG_MAX_VAL +#define ADF_CFG_UP_STR "up" +#define ADF_CFG_DOWN_STR "down" + +#define ADF_CFG_MAX_USER_PROCESSES 64 + +static int +adf_cfg_down(struct adf_accel_dev *accel_dev) +{ + int ret = 0; + + if (!adf_dev_started(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Device qat_dev%d already down\n", + accel_dev->accel_id); + return 0; + } + + if (adf_dev_in_use(accel_dev)) { + pr_err("QAT: Device %d in use\n", accel_dev->accel_id); + goto out; + } + + if (adf_dev_stop(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Failed to stop qat_dev%d\n", + accel_dev->accel_id); + ret = EFAULT; + goto out; + } + + adf_dev_shutdown(accel_dev); + +out: + return ret; +} + +static int +adf_cfg_up(struct adf_accel_dev *accel_dev) +{ + int ret; + + if (adf_dev_started(accel_dev)) + return 0; + + if (NULL == accel_dev->hw_device->config_device) + return ENXIO; + + ret = accel_dev->hw_device->config_device(accel_dev); + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to start qat_dev%d\n", + accel_dev->accel_id); + return ret; + } + + ret = adf_dev_init(accel_dev); + if (!ret) + ret = adf_dev_start(accel_dev); + + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to start qat_dev%d\n", + accel_dev->accel_id); + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); + } + + if (!ret) { + struct adf_cfg_device *cfg_dev = NULL; + + cfg_dev = accel_dev->cfg->dev; + adf_cfg_device_clear(cfg_dev, accel_dev); + free(cfg_dev, M_QAT); + accel_dev->cfg->dev = NULL; + } + + return 0; +} + +static const char *const cfg_serv[] = + { "sym;asym", "sym", "asym", "dc", "sym;dc", "asym;dc", "cy", "cy;dc" }; + +static const char *const cfg_mode[] = { "ks;us", "us", "ks" }; + +static int adf_cfg_sysctl_services_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ]; + unsigned int len; + int ret = 0; + int i = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + strlcpy(buf, dev_cfg_data->cfg_services, sizeof(buf)); + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + /* Handle config change */ + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EINVAL; + } + + len = strlen(buf); + + for (i = 0; i < ARRAY_SIZE(cfg_serv); i++) { + if ((len > 0 && strncasecmp(cfg_serv[i], buf, len) == 0)) { + strlcpy(dev_cfg_data->cfg_services, + buf, + ADF_CFG_MAX_VAL); + break; + } + } + + if (i == ARRAY_SIZE(cfg_serv)) { + device_printf(GET_DEV(accel_dev), + "Unknown service configuration\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_mode_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ]; + unsigned int len; + int ret = 0; + int i = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + strlcpy(buf, dev_cfg_data->cfg_mode, sizeof(buf)); + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + /* Handle config change */ + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EBUSY; + } + + len = strlen(buf); + + for (i = 0; i < ARRAY_SIZE(cfg_mode); i++) { + if ((len > 0 && strncasecmp(cfg_mode[i], buf, len) == 0)) { + strlcpy(dev_cfg_data->cfg_mode, buf, ADF_CFG_MAX_VAL); + break; + } + } + + if (i == ARRAY_SIZE(cfg_mode)) { + device_printf(GET_DEV(accel_dev), + "Unknown configuration mode\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + char buf[ADF_CFG_SYSCTL_BUF_SZ] = { 0 }; + unsigned int len; + int ret = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + if (adf_dev_started(accel_dev)) { + strlcpy(buf, ADF_CFG_UP_STR, sizeof(buf)); + } else { + strlcpy(buf, ADF_CFG_DOWN_STR, sizeof(buf)); + } + + ret = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (ret != 0 || req->newptr == NULL) + return ret; + + len = strlen(buf); + + if ((len > 0 && strncasecmp(ADF_CFG_UP_STR, buf, len) == 0)) { + ret = adf_cfg_up(accel_dev); + + } else if (len > 0 && strncasecmp(ADF_CFG_DOWN_STR, buf, len) == 0) { + ret = adf_cfg_down(accel_dev); + + } else { + device_printf(GET_DEV(accel_dev), "QAT: Invalid operation\n"); + ret = EINVAL; + } + + return ret; +} + +static int adf_cfg_sysctl_num_processes_handle(SYSCTL_HANDLER_ARGS) +{ + struct adf_cfg_device_data *dev_cfg_data; + struct adf_accel_dev *accel_dev; + uint32_t num_user_processes = 0; + int ret = 0; + + accel_dev = arg1; + if (!accel_dev) + return ENXIO; + + dev_cfg_data = accel_dev->cfg; + if (!dev_cfg_data) + return ENXIO; + + num_user_processes = dev_cfg_data->num_user_processes; + + ret = sysctl_handle_int(oidp, &num_user_processes, 0, req); + if (ret != 0 || req->newptr == NULL) + return ret; + + if (adf_dev_started(accel_dev)) { + device_printf( + GET_DEV(accel_dev), + "QAT: configuration could be changed in down state only\n"); + return EBUSY; + } + + if (num_user_processes > ADF_CFG_MAX_USER_PROCESSES) { + return EINVAL; + } + + dev_cfg_data->num_user_processes = num_user_processes; + + return ret; +} + +int +adf_cfg_sysctl_add(struct adf_accel_dev *accel_dev) +{ + struct sysctl_ctx_list *qat_sysctl_ctx; + struct sysctl_oid *qat_sysctl_tree; + + if (!accel_dev) + return EINVAL; + + qat_sysctl_ctx = + device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev); + qat_sysctl_tree = + device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "state", + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_handle, + "A", + "QAT State"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "cfg_services", + CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_services_handle, + "A", + "QAT services confguration"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "cfg_mode", + CTLTYPE_STRING | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_mode_handle, + "A", + "QAT mode configuration"); + + SYSCTL_ADD_PROC(qat_sysctl_ctx, + SYSCTL_CHILDREN(qat_sysctl_tree), + OID_AUTO, + "num_user_processes", + CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, + accel_dev, + 0, + adf_cfg_sysctl_num_processes_handle, + "I", + "QAT user processes number "); + + return 0; +} + +void +adf_cfg_sysctl_remove(struct adf_accel_dev *accel_dev) +{ +} diff --git a/sys/dev/qat/qat_common/adf_ctl_drv.c b/sys/dev/qat/qat_common/adf_ctl_drv.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_ctl_drv.c @@ -0,0 +1,491 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_cfg.h" +#include "adf_cfg_common.h" +#include "adf_cfg_user.h" +#include "adf_heartbeat.h" +#include "adf_cfg_device.h" + +#define DEVICE_NAME "qat_adf_ctl" + +static struct sx adf_ctl_lock; + +static d_ioctl_t adf_ctl_ioctl; + +void *misc_counter; + +static struct cdevsw adf_ctl_cdevsw = { + .d_version = D_VERSION, + .d_ioctl = adf_ctl_ioctl, + .d_name = DEVICE_NAME, +}; + +static struct cdev *adf_ctl_dev; + +static void adf_chr_drv_destroy(void) +{ + destroy_dev(adf_ctl_dev); +} + +struct adf_user_addr_info { + struct list_head list; + void *user_addr; +}; + +static int adf_chr_drv_create(void) +{ + adf_ctl_dev = make_dev(&adf_ctl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, + DEVICE_NAME); + + if (!adf_ctl_dev) { + printf("QAT: failed to create device\n"); + goto err_cdev_del; + } + return 0; +err_cdev_del: + return EFAULT; +} + +static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data, + caddr_t arg) +{ + *ctl_data = (struct adf_user_cfg_ctl_data *)arg; + return 0; +} + +static int adf_copy_keyval_to_user(struct adf_accel_dev *accel_dev, + struct adf_user_cfg_ctl_data *ctl_data) +{ + struct adf_user_cfg_key_val key_val; + struct adf_user_cfg_section section; + char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0}; + char *user_ptr; + + if (copyin(ctl_data->config_section, §ion, + sizeof(struct adf_user_cfg_section))) { + device_printf(GET_DEV(accel_dev), + "failed to copy section info\n"); + return EFAULT; + } + + if (copyin(section.params, &key_val, + sizeof(struct adf_user_cfg_key_val))) { + device_printf(GET_DEV(accel_dev), "failed to copy key val\n"); + return EFAULT; + } + + user_ptr = ((char *)section.params) + ADF_CFG_MAX_KEY_LEN_IN_BYTES; + + if (adf_cfg_get_param_value( + accel_dev, section.name, key_val.key, val)) { + return EFAULT; + } + + if (copyout(val, user_ptr, + ADF_CFG_MAX_VAL_LEN_IN_BYTES)) { + device_printf(GET_DEV(accel_dev), + "failed to copy keyvalue to user!\n"); + return EFAULT; + } + + return 0; +} + +static int adf_ctl_ioctl_get_num_devices(unsigned int cmd, + caddr_t arg) +{ + adf_devmgr_get_num_dev((uint32_t *)arg); + + return 0; +} + +static int adf_ctl_ioctl_get_status(unsigned int cmd, + caddr_t arg) +{ + struct adf_hw_device_data *hw_data; + struct adf_dev_status_info *dev_info; + struct adf_accel_dev *accel_dev; + + dev_info = (struct adf_dev_status_info *)arg; + + accel_dev = adf_devmgr_get_dev_by_id(dev_info->accel_id); + if (!accel_dev) + return ENODEV; + + hw_data = accel_dev->hw_device; + dev_info->state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN; + dev_info->num_ae = hw_data->get_num_aes(hw_data); + dev_info->num_accel = hw_data->get_num_accels(hw_data); + dev_info->num_logical_accel = hw_data->num_logical_accel; + dev_info->banks_per_accel = hw_data->num_banks + / hw_data->num_logical_accel; + strlcpy(dev_info->name, hw_data->dev_class->name, + sizeof(dev_info->name)); + dev_info->instance_id = hw_data->instance_id; + dev_info->type = hw_data->dev_class->type; + dev_info->bus = pci_get_bus(accel_to_pci_dev(accel_dev)); + dev_info->dev = pci_get_slot(accel_to_pci_dev(accel_dev)); + dev_info->fun = pci_get_function(accel_to_pci_dev(accel_dev)); + dev_info->domain = pci_get_domain(accel_to_pci_dev(accel_dev)); + + dev_info->pci_device_id = pci_get_device(accel_to_pci_dev(accel_dev)); + + dev_info->node_id = accel_dev->accel_pci_dev.node; + dev_info->sku = accel_dev->accel_pci_dev.sku; + + dev_info->device_mem_available = accel_dev->aram_info ? + accel_dev->aram_info->inter_buff_aram_region_size : 0; + + return 0; +} + +static int adf_ctl_ioctl_heartbeat(unsigned int cmd, + caddr_t arg) +{ + int ret = 0; + struct adf_accel_dev *accel_dev; + struct adf_dev_heartbeat_status_ctl *hb_status; + + hb_status = (struct adf_dev_heartbeat_status_ctl *)arg; + + accel_dev = adf_devmgr_get_dev_by_id(hb_status->device_id); + if (!accel_dev) + return ENODEV; + + if (adf_heartbeat_status(accel_dev, &hb_status->status)) { + device_printf(GET_DEV(accel_dev), + "failed to get heartbeat status\n"); + return EAGAIN; + } + return ret; +} + +static int adf_ctl_ioctl_dev_get_value(unsigned int cmd, + caddr_t arg) +{ + int ret = 0; + struct adf_user_cfg_ctl_data *ctl_data; + struct adf_accel_dev *accel_dev; + + ret = adf_ctl_alloc_resources(&ctl_data, arg); + if (ret) + return ret; + + accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id); + if (!accel_dev) { + printf("QAT: Device %d not found\n", ctl_data->device_id); + ret = ENODEV; + goto out; + } + + ret = adf_copy_keyval_to_user(accel_dev, ctl_data); + if (ret) { + ret = ENODEV; + goto out; + } +out: + return ret; +} + +static struct adf_uio_control_bundle + *adf_ctl_ioctl_bundle(struct adf_user_reserve_ring reserve) +{ + struct adf_accel_dev *accel_dev; + struct adf_uio_control_accel *accel; + struct adf_uio_control_bundle *bundle = NULL; + u8 num_rings_per_bank = 0; + + accel_dev = adf_devmgr_get_dev_by_id(reserve.accel_id); + if (!accel_dev) { + pr_err("QAT: Failed to get accel_dev\n"); + return NULL; + } + num_rings_per_bank = accel_dev->hw_device->num_rings_per_bank; + + accel = accel_dev->accel; + if (!accel) { + pr_err("QAT: Failed to get accel\n"); + return NULL; + } + + if (reserve.bank_nr >= GET_MAX_BANKS(accel_dev)) { + pr_err("QAT: Invalid bank number %d\n", reserve.bank_nr); + return NULL; + } + if (reserve.ring_mask & ~((1 << num_rings_per_bank) - 1)) { + pr_err("QAT: Invalid ring mask %0X\n", reserve.ring_mask); + return NULL; + } + if (accel->num_ker_bundles > reserve.bank_nr) { + pr_err("QAT: Invalid user reserved bank\n"); + return NULL; + } + bundle = &accel->bundle[reserve.bank_nr]; + + return bundle; +} + +static int adf_ctl_ioctl_reserve_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve = {0}; + struct adf_uio_control_bundle *bundle; + struct adf_uio_instance_rings *instance_rings; + int pid_entry_found = 0; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + if (bundle->rings_used & reserve.ring_mask) { + pr_err("QAT: Bundle %d, rings 0x%04X already reserved\n", + reserve.bank_nr, + reserve.ring_mask); + mutex_unlock(&bundle->lock); + return -EINVAL; + } + mutex_unlock(&bundle->lock); + + /* Find the list entry for this process */ + mutex_lock(&bundle->list_lock); + list_for_each_entry(instance_rings, &bundle->list, list) { + if (instance_rings->user_pid == curproc->p_pid) { + pid_entry_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (!pid_entry_found) { + pr_err("QAT: process %d not found\n", curproc->p_pid); + return -EINVAL; + } + + instance_rings->ring_mask |= reserve.ring_mask; + mutex_lock(&bundle->lock); + bundle->rings_used |= reserve.ring_mask; + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_release_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + struct adf_uio_instance_rings *instance_rings; + int pid_entry_found; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + /* Find the list entry for this process */ + pid_entry_found = 0; + mutex_lock(&bundle->list_lock); + list_for_each_entry(instance_rings, &bundle->list, list) { + if (instance_rings->user_pid == curproc->p_pid) { + pid_entry_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (!pid_entry_found) { + pr_err("QAT: No ring reservation found for PID %d\n", + curproc->p_pid); + return -EINVAL; + } + + if ((instance_rings->ring_mask & reserve.ring_mask) != + reserve.ring_mask) { + pr_err("QAT: Attempt to release rings not reserved by this process\n"); + return -EINVAL; + } + + instance_rings->ring_mask &= ~reserve.ring_mask; + mutex_lock(&bundle->lock); + bundle->rings_used &= ~reserve.ring_mask; + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_enable_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + bundle->rings_enabled |= reserve.ring_mask; + adf_update_uio_ring_arb(bundle); + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl_disable_ring(caddr_t arg) +{ + struct adf_user_reserve_ring reserve; + struct adf_uio_control_bundle *bundle; + + reserve = *((struct adf_user_reserve_ring *)arg); + + bundle = adf_ctl_ioctl_bundle(reserve); + if (!bundle) { + pr_err("QAT: Failed to get bundle\n"); + return -EINVAL; + } + + mutex_lock(&bundle->lock); + bundle->rings_enabled &= ~reserve.ring_mask; + adf_update_uio_ring_arb(bundle); + mutex_unlock(&bundle->lock); + + return 0; +} + +static int adf_ctl_ioctl(struct cdev *dev, + u_long cmd, + caddr_t arg, + int fflag, + struct thread *td) +{ + int ret = 0; + bool allowed = false; + int i; + static const unsigned int unrestricted_cmds[] = { + IOCTL_GET_NUM_DEVICES, IOCTL_STATUS_ACCEL_DEV, + IOCTL_HEARTBEAT_ACCEL_DEV, IOCTL_GET_CFG_VAL, + IOCTL_RESERVE_RING, IOCTL_RELEASE_RING, + IOCTL_ENABLE_RING, IOCTL_DISABLE_RING, + }; + + if (priv_check(curthread, PRIV_DRIVER)) { + for (i = 0; i < ARRAY_SIZE(unrestricted_cmds); i++) { + if (cmd == unrestricted_cmds[i]) { + allowed = true; + break; + } + } + if (!allowed) + return EACCES; + } + + /* All commands have an argument */ + if (!arg) + return EFAULT; + + if (sx_xlock_sig(&adf_ctl_lock)) + return EINTR; + + switch (cmd) { + case IOCTL_GET_NUM_DEVICES: + ret = adf_ctl_ioctl_get_num_devices(cmd, arg); + break; + case IOCTL_STATUS_ACCEL_DEV: + ret = adf_ctl_ioctl_get_status(cmd, arg); + break; + case IOCTL_GET_CFG_VAL: + ret = adf_ctl_ioctl_dev_get_value(cmd, arg); + break; + case IOCTL_RESERVE_RING: + ret = adf_ctl_ioctl_reserve_ring(arg); + break; + case IOCTL_RELEASE_RING: + ret = adf_ctl_ioctl_release_ring(arg); + break; + case IOCTL_ENABLE_RING: + ret = adf_ctl_ioctl_enable_ring(arg); + break; + case IOCTL_DISABLE_RING: + ret = adf_ctl_ioctl_disable_ring(arg); + break; + case IOCTL_HEARTBEAT_ACCEL_DEV: + ret = adf_ctl_ioctl_heartbeat(cmd, arg); + break; + default: + printf("QAT: Invalid ioctl\n"); + ret = ENOTTY; + break; + } + sx_xunlock(&adf_ctl_lock); + return ret; +} + +int +adf_register_ctl_device_driver(void) +{ + sx_init(&adf_ctl_lock, "adf ctl"); + + if (adf_chr_drv_create()) + goto err_chr_dev; + + adf_state_init(); + if (adf_processes_dev_register() != 0) + goto err_processes_dev_register; + return 0; + +err_processes_dev_register: + adf_chr_drv_destroy(); +err_chr_dev: + sx_destroy(&adf_ctl_lock); + return EFAULT; +} + +void +adf_unregister_ctl_device_driver(void) +{ + adf_processes_dev_unregister(); + adf_state_destroy(); + adf_chr_drv_destroy(); + adf_clean_vf_map(false); + sx_destroy(&adf_ctl_lock); +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_dev_processes.c @@ -0,0 +1,677 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ + +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" + +#define ADF_DEV_PROCESSES_NAME "qat_dev_processes" +#define ADF_DEV_STATE_NAME "qat_dev_state" + +#define ADF_STATE_CALLOUT_TIME 10 + +static const char *mtx_name = "state_callout_mtx"; + +static d_open_t adf_processes_open; +static void adf_processes_release(void *data); +static d_read_t adf_processes_read; +static d_write_t adf_processes_write; + +static d_open_t adf_state_open; +static void adf_state_release(void *data); +static d_read_t adf_state_read; +static int adf_state_kqfilter(struct cdev *dev, struct knote *kn); +static int adf_state_kqread_event(struct knote *kn, long hint); +static void adf_state_kqread_detach(struct knote *kn); + +static struct callout callout; +static struct mtx mtx; +static struct service_hndl adf_state_hndl; + +struct entry_proc_events { + struct adf_state_priv_data *proc_events; + + SLIST_ENTRY(entry_proc_events) entries_proc_events; +}; + +struct entry_state { + struct adf_state state; + + STAILQ_ENTRY(entry_state) entries_state; +}; + +SLIST_HEAD(proc_events_head, entry_proc_events); +STAILQ_HEAD(state_head, entry_state); + +static struct proc_events_head proc_events_head; + +struct adf_processes_priv_data { + char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES]; + int read_flag; + struct list_head list; +}; + +struct adf_state_priv_data { + struct cdev *cdev; + struct selinfo rsel; + struct state_head state_head; +}; + +static struct cdevsw adf_processes_cdevsw = { + .d_version = D_VERSION, + .d_open = adf_processes_open, + .d_read = adf_processes_read, + .d_write = adf_processes_write, + .d_name = ADF_DEV_PROCESSES_NAME, +}; + +static struct cdevsw adf_state_cdevsw = { + .d_version = D_VERSION, + .d_open = adf_state_open, + .d_read = adf_state_read, + .d_kqfilter = adf_state_kqfilter, + .d_name = ADF_DEV_STATE_NAME, +}; + +static struct filterops adf_state_read_filterops = { + .f_isfd = 1, + .f_attach = NULL, + .f_detach = adf_state_kqread_detach, + .f_event = adf_state_kqread_event, +}; + +static struct cdev *adf_processes_dev; +static struct cdev *adf_state_dev; + +static LINUX_LIST_HEAD(processes_list); + +struct sx processes_list_sema; +SX_SYSINIT(processes_list_sema, &processes_list_sema, "adf proc list"); + +static void +adf_chr_drv_destroy(void) +{ + destroy_dev(adf_processes_dev); +} + +static int +adf_chr_drv_create(void) +{ + + adf_processes_dev = make_dev(&adf_processes_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + ADF_DEV_PROCESSES_NAME); + if (adf_processes_dev == NULL) { + printf("QAT: failed to create device\n"); + goto err_cdev_del; + } + return 0; +err_cdev_del: + return EFAULT; +} + +static int +adf_processes_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + int i = 0, devices = 0; + struct adf_accel_dev *accel_dev = NULL; + struct adf_processes_priv_data *prv_data = NULL; + int error = 0; + + for (i = 0; i < ADF_MAX_DEVICES; i++) { + accel_dev = adf_devmgr_get_dev_by_id(i); + if (!accel_dev) + continue; + if (!adf_dev_started(accel_dev)) + continue; + devices++; + } + if (!devices) { + printf("QAT: No active devices found.\n"); + return ENXIO; + } + prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); + if (!prv_data) + return ENOMEM; + INIT_LIST_HEAD(&prv_data->list); + error = devfs_set_cdevpriv(prv_data, adf_processes_release); + if (error) { + free(prv_data, M_QAT); + return error; + } + + return 0; +} + +static int +adf_get_first_started_dev(void) +{ + int i = 0; + struct adf_accel_dev *accel_dev = NULL; + + for (i = 0; i < ADF_MAX_DEVICES; i++) { + accel_dev = adf_devmgr_get_dev_by_id(i); + if (!accel_dev) + continue; + if (adf_dev_started(accel_dev)) + return i; + } + + return -1; +} + +static int +adf_processes_write(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct adf_processes_priv_data *prv_data = NULL; + struct adf_processes_priv_data *pdata = NULL; + int dev_num = 0, pr_num = 0; + struct list_head *lpos = NULL; + char usr_name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES] = { 0 }; + struct adf_accel_dev *accel_dev = NULL; + struct adf_cfg_section *section_ptr = NULL; + bool pr_name_available = 1; + uint32_t num_accel_devs = 0; + int error = 0; + ssize_t count; + int dev_id; + + error = devfs_get_cdevpriv((void **)&prv_data); + if (error) { + printf("QAT: invalid file descriptor\n"); + return error; + } + + if (prv_data->read_flag == 1) { + printf("QAT: can only write once\n"); + return EBADF; + } + count = uio->uio_resid; + if ((count <= 0) || (count > ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) { + printf("QAT: wrong size %d\n", (int)count); + return EIO; + } + + error = uiomove(usr_name, count, uio); + if (error) { + printf("QAT: can't copy data\n"); + return error; + } + + /* Lock other processes and try to find out the process name */ + if (sx_xlock_sig(&processes_list_sema)) { + printf("QAT: can't aquire process info lock\n"); + return EBADF; + } + + dev_id = adf_get_first_started_dev(); + if (-1 == dev_id) { + pr_err("QAT: could not find started device\n"); + sx_xunlock(&processes_list_sema); + return -EIO; + } + + accel_dev = adf_devmgr_get_dev_by_id(dev_id); + if (!accel_dev) { + pr_err("QAT: could not find started device\n"); + sx_xunlock(&processes_list_sema); + return -EIO; + } + + /* If there is nothing there then take the first name and return */ + if (list_empty(&processes_list)) { + snprintf(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES, + "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d", + usr_name, + 0); + list_add(&prv_data->list, &processes_list); + sx_xunlock(&processes_list_sema); + prv_data->read_flag = 1; + return 0; + } + + /* If there are processes running then search for a first free name */ + adf_devmgr_get_num_dev(&num_accel_devs); + for (dev_num = 0; dev_num < num_accel_devs; dev_num++) { + accel_dev = adf_devmgr_get_dev_by_id(dev_num); + if (!accel_dev) + continue; + + if (!adf_dev_started(accel_dev)) + continue; /* to next device */ + + for (pr_num = 0; pr_num < GET_MAX_PROCESSES(accel_dev); + pr_num++) { + snprintf(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES, + "%s" ADF_INTERNAL_USERSPACE_SEC_SUFF "%d", + usr_name, + pr_num); + pr_name_available = 1; + /* Figure out if section exists in the config table */ + section_ptr = + adf_cfg_sec_find(accel_dev, prv_data->name); + if (NULL == section_ptr) { + /* This section name doesn't exist */ + pr_name_available = 0; + /* As process_num enumerates from 0, once we get + * to one which doesn't exist no further ones + * will exist. On to next device + */ + break; + } + /* Figure out if it's been taken already */ + list_for_each(lpos, &processes_list) + { + pdata = + list_entry(lpos, + struct adf_processes_priv_data, + list); + if (!strncmp( + pdata->name, + prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES)) { + pr_name_available = 0; + break; + } + } + if (pr_name_available) + break; + } + if (pr_name_available) + break; + } + /* + * If we have a valid name that is not on + * the list take it and add to the list + */ + if (pr_name_available) { + list_add(&prv_data->list, &processes_list); + sx_xunlock(&processes_list_sema); + prv_data->read_flag = 1; + return 0; + } + /* If not then the process needs to wait */ + sx_xunlock(&processes_list_sema); + explicit_bzero(prv_data->name, ADF_CFG_MAX_SECTION_LEN_IN_BYTES); + prv_data->read_flag = 0; + return 1; +} + +static int +adf_processes_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct adf_processes_priv_data *prv_data = NULL; + int error = 0; + + error = devfs_get_cdevpriv((void **)&prv_data); + if (error) { + printf("QAT: invalid file descriptor\n"); + return error; + } + + /* + * If there is a name that the process can use then give it + * to the proocess. + */ + if (prv_data->read_flag) { + error = uiomove(prv_data->name, + strnlen(prv_data->name, + ADF_CFG_MAX_SECTION_LEN_IN_BYTES), + uio); + if (error) { + printf("QAT: failed to copy data to user\n"); + return error; + } + return 0; + } + + return EIO; +} + +static void +adf_processes_release(void *data) +{ + struct adf_processes_priv_data *prv_data = NULL; + + prv_data = (struct adf_processes_priv_data *)data; + sx_xlock(&processes_list_sema); + list_del(&prv_data->list); + sx_xunlock(&processes_list_sema); + free(prv_data, M_QAT); +} + +int +adf_processes_dev_register(void) +{ + return adf_chr_drv_create(); +} + +void +adf_processes_dev_unregister(void) +{ + adf_chr_drv_destroy(); +} + +static void +adf_state_callout_notify_ev(void *arg) +{ + int notified = 0; + struct adf_state_priv_data *priv = NULL; + struct entry_proc_events *proc_events = NULL; + + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) { + notified = 1; + priv = proc_events->proc_events; + wakeup(priv); + selwakeup(&priv->rsel); + KNOTE_UNLOCKED(&priv->rsel.si_note, 0); + } + } + if (notified) + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); +} + +static void +adf_state_set(int dev, enum adf_event event) +{ + struct adf_accel_dev *accel_dev = NULL; + struct state_head *head = NULL; + struct entry_proc_events *proc_events = NULL; + struct entry_state *state = NULL; + + accel_dev = adf_devmgr_get_dev_by_id(dev); + if (!accel_dev) + return; + mtx_lock(&mtx); + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + state = NULL; + head = &proc_events->proc_events->state_head; + state = malloc(sizeof(struct entry_state), + M_QAT, + M_NOWAIT | M_ZERO); + if (!state) + continue; + state->state.dev_state = event; + state->state.dev_id = dev; + STAILQ_INSERT_TAIL(head, state, entries_state); + if (event == ADF_EVENT_STOP) { + state = NULL; + state = malloc(sizeof(struct entry_state), + M_QAT, + M_NOWAIT | M_ZERO); + if (!state) + continue; + state->state.dev_state = ADF_EVENT_SHUTDOWN; + state->state.dev_id = dev; + STAILQ_INSERT_TAIL(head, state, entries_state); + } + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); +} + +static int +adf_state_event_handler(struct adf_accel_dev *accel_dev, enum adf_event event) +{ + int ret = 0; + +#if defined(QAT_UIO) && defined(QAT_DBG) + if (event > ADF_EVENT_DBG_SHUTDOWN) + return -EINVAL; +#else + if (event > ADF_EVENT_ERROR) + return -EINVAL; +#endif /* defined(QAT_UIO) && defined(QAT_DBG) */ + + switch (event) { + case ADF_EVENT_INIT: + return ret; + case ADF_EVENT_SHUTDOWN: + return ret; + case ADF_EVENT_RESTARTING: + break; + case ADF_EVENT_RESTARTED: + break; + case ADF_EVENT_START: + return ret; + case ADF_EVENT_STOP: + break; + case ADF_EVENT_ERROR: + break; +#if defined(QAT_UIO) && defined(QAT_DBG) + case ADF_EVENT_PROC_CRASH: + break; + case ADF_EVENT_MANUAL_DUMP: + break; + case ADF_EVENT_SLICE_HANG: + break; + case ADF_EVENT_DBG_SHUTDOWN: + break; +#endif /* defined(QAT_UIO) && defined(QAT_DBG) */ + default: + return -1; + } + + adf_state_set(accel_dev->accel_id, event); + + return 0; +} + +static int +adf_state_kqfilter(struct cdev *dev, struct knote *kn) +{ + struct adf_state_priv_data *priv; + + mtx_lock(&mtx); + priv = dev->si_drv1; + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &adf_state_read_filterops; + kn->kn_hook = priv; + knlist_add(&priv->rsel.si_note, kn, 0); + mtx_unlock(&mtx); + return 0; + default: + mtx_unlock(&mtx); + return -EINVAL; + } +} + +static int +adf_state_kqread_event(struct knote *kn, long hint) +{ + return 1; +} + +static void +adf_state_kqread_detach(struct knote *kn) +{ + struct adf_state_priv_data *priv = NULL; + + mtx_lock(&mtx); + if (!kn) { + mtx_unlock(&mtx); + return; + } + priv = kn->kn_hook; + if (!priv) { + mtx_unlock(&mtx); + return; + } + knlist_remove(&priv->rsel.si_note, kn, 1); + mtx_unlock(&mtx); +} + +void +adf_state_init(void) +{ + adf_state_dev = make_dev(&adf_state_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + "%s", + ADF_DEV_STATE_NAME); + SLIST_INIT(&proc_events_head); + mtx_init(&mtx, mtx_name, NULL, MTX_DEF); + callout_init_mtx(&callout, &mtx, 0); + explicit_bzero(&adf_state_hndl, sizeof(adf_state_hndl)); + adf_state_hndl.event_hld = adf_state_event_handler; + adf_state_hndl.name = "adf_state_event_handler"; + mtx_lock(&mtx); + adf_service_register(&adf_state_hndl); + callout_reset(&callout, + ADF_STATE_CALLOUT_TIME, + adf_state_callout_notify_ev, + NULL); + mtx_unlock(&mtx); +} + +void +adf_state_destroy(void) +{ + struct entry_proc_events *proc_events = NULL; + + mtx_lock(&mtx); + adf_service_unregister(&adf_state_hndl); + callout_stop(&callout); + while (!SLIST_EMPTY(&proc_events_head)) { + proc_events = SLIST_FIRST(&proc_events_head); + SLIST_REMOVE_HEAD(&proc_events_head, entries_proc_events); + free(proc_events, M_QAT); + } + destroy_dev(adf_state_dev); + mtx_unlock(&mtx); + mtx_destroy(&mtx); +} + +static int +adf_state_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct adf_state_priv_data *prv_data = NULL; + struct entry_proc_events *entry_proc_events = NULL; + int ret = 0; + + prv_data = malloc(sizeof(*prv_data), M_QAT, M_WAITOK | M_ZERO); + if (!prv_data) + return -ENOMEM; + entry_proc_events = + malloc(sizeof(struct entry_proc_events), M_QAT, M_WAITOK | M_ZERO); + if (!entry_proc_events) { + free(prv_data, M_QAT); + return -ENOMEM; + } + mtx_lock(&mtx); + prv_data->cdev = dev; + prv_data->cdev->si_drv1 = prv_data; + knlist_init_mtx(&prv_data->rsel.si_note, &mtx); + STAILQ_INIT(&prv_data->state_head); + entry_proc_events->proc_events = prv_data; + SLIST_INSERT_HEAD(&proc_events_head, + entry_proc_events, + entries_proc_events); + ret = devfs_set_cdevpriv(prv_data, adf_state_release); + if (ret) { + SLIST_REMOVE(&proc_events_head, + entry_proc_events, + entry_proc_events, + entries_proc_events); + free(entry_proc_events, M_QAT); + free(prv_data, M_QAT); + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); + return ret; +} + +static int +adf_state_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + int ret = 0; + struct adf_state_priv_data *prv_data = NULL; + struct state_head *state_head = NULL; + struct entry_state *entry_state = NULL; + struct adf_state *state = NULL; + struct entry_proc_events *proc_events = NULL; + + mtx_lock(&mtx); + ret = devfs_get_cdevpriv((void **)&prv_data); + if (ret) { + mtx_unlock(&mtx); + return 0; + } + state_head = &prv_data->state_head; + if (STAILQ_EMPTY(state_head)) { + mtx_unlock(&mtx); + return 0; + } + entry_state = STAILQ_FIRST(state_head); + state = &entry_state->state; + ret = uiomove(state, sizeof(struct adf_state), uio); + if (!ret && !STAILQ_EMPTY(state_head)) { + STAILQ_REMOVE_HEAD(state_head, entries_state); + free(entry_state, M_QAT); + } + SLIST_FOREACH (proc_events, &proc_events_head, entries_proc_events) { + if (!STAILQ_EMPTY(&proc_events->proc_events->state_head)) { + prv_data = proc_events->proc_events; + wakeup(prv_data); + selwakeup(&prv_data->rsel); + KNOTE_UNLOCKED(&prv_data->rsel.si_note, 0); + } + } + callout_schedule(&callout, ADF_STATE_CALLOUT_TIME); + mtx_unlock(&mtx); + return ret; +} + +static void +adf_state_release(void *data) +{ + struct adf_state_priv_data *prv_data = NULL; + struct entry_state *entry_state = NULL; + struct entry_proc_events *entry_proc_events = NULL; + struct entry_proc_events *tmp = NULL; + + mtx_lock(&mtx); + prv_data = (struct adf_state_priv_data *)data; + knlist_delete(&prv_data->rsel.si_note, curthread, 1); + knlist_destroy(&prv_data->rsel.si_note); + seldrain(&prv_data->rsel); + while (!STAILQ_EMPTY(&prv_data->state_head)) { + entry_state = STAILQ_FIRST(&prv_data->state_head); + STAILQ_REMOVE_HEAD(&prv_data->state_head, entries_state); + free(entry_state, M_QAT); + } + SLIST_FOREACH_SAFE (entry_proc_events, + &proc_events_head, + entries_proc_events, + tmp) { + if (entry_proc_events->proc_events == prv_data) { + SLIST_REMOVE(&proc_events_head, + entry_proc_events, + entry_proc_events, + entries_proc_events); + free(entry_proc_events, M_QAT); + } + } + free(prv_data, M_QAT); + mtx_unlock(&mtx); +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio.c b/sys/dev/qat/qat_common/adf_freebsd_uio.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_uio.c @@ -0,0 +1,450 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADF_UIO_GET_NAME(accel_dev) (GET_HW_DATA(accel_dev)->dev_class->name) +#define ADF_UIO_GET_TYPE(accel_dev) (GET_HW_DATA(accel_dev)->dev_class->type) +#define ADF_UIO_GET_BAR(accel_dev) \ + (GET_HW_DATA(accel_dev)->get_etr_bar_id(GET_HW_DATA(accel_dev))) + +static d_ioctl_t adf_uio_ioctl; +static d_mmap_single_t adf_uio_mmap_single; + +static struct cdevsw adf_uio_cdevsw = { .d_ioctl = adf_uio_ioctl, + .d_mmap_single = adf_uio_mmap_single, + .d_version = D_VERSION, + .d_name = "qat" }; + +struct adf_uio_open_bundle { + struct adf_uio_control_accel *accel; + int bundle; + struct file **mem_files; + int num_mem_files; +}; + +static void +adf_release_bundle(void *arg) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + struct adf_uio_control_bundle *bundle = NULL; + struct adf_uio_instance_rings *instance_rings, *tmp; + int i = 0; + + handle = arg; + accel = handle->accel; + bundle = &accel->bundle[handle->bundle]; + + mutex_lock(&bundle->lock); + adf_uio_do_cleanup_orphan(bundle->hardware_bundle_number, accel); + mutex_unlock(&bundle->lock); + + for (i = 0; i < handle->num_mem_files; i++) { + /* + * Similar to the garbage collection of orphaned file + * descriptor references in UNIX domain socket control + * messages, the current thread isn't relevant to the + * the file descriptor reference being released. In + * particular, the current thread does not hold any + * advisory file locks on these file descriptors. + */ + fdrop(handle->mem_files[i], NULL); + } + free(handle->mem_files, M_QAT); + + mtx_lock(&accel->lock); + + mutex_lock(&bundle->list_lock); + list_for_each_entry_safe(instance_rings, tmp, &bundle->list, list) + { + if (instance_rings->user_pid == curproc->p_pid) { + list_del(&instance_rings->list); + free(instance_rings, M_QAT); + break; + } + } + mutex_unlock(&bundle->list_lock); + + adf_dev_put(accel->accel_dev); + accel->num_handles--; + free(handle, M_QAT); + if (!accel->num_handles) { + cv_broadcast(&accel->cleanup_ok); + /* the broadcasting effect happens after releasing accel->lock + */ + } + mtx_unlock(&accel->lock); +} + +static int +adf_add_mem_fd(struct adf_accel_dev *accel_dev, int mem_fd) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + struct file *fp, **new_files; + cap_rights_t rights; + int error = -1, old_count = 0; + + error = devfs_get_cdevpriv((void **)&handle); + if (error) + return (error); + + error = fget(curthread, mem_fd, cap_rights_init(&rights), &fp); + if (error) { + printf( + "Failed to fetch file pointer from current process %d \n", + __LINE__); + return (error); + } + + accel = accel_dev->accel; + mtx_lock(&accel->lock); + for (;;) { + old_count = handle->num_mem_files; + mtx_unlock(&accel->lock); + new_files = malloc((old_count + 1) * sizeof(*new_files), + M_QAT, + M_WAITOK); + mtx_lock(&accel->lock); + if (old_count == handle->num_mem_files) { + if (old_count != 0) { + memcpy(new_files, + handle->mem_files, + old_count * sizeof(*new_files)); + free(handle->mem_files, M_QAT); + } + handle->mem_files = new_files; + new_files[old_count] = fp; + handle->num_mem_files++; + break; + } else + free(new_files, M_QAT); + } + mtx_unlock(&accel->lock); + return (0); +} + +static vm_object_t +adf_uio_map_bar(struct adf_accel_dev *accel_dev, uint8_t bank_offset) +{ + unsigned int ring_bundle_size, offset; + struct sglist *sg = NULL; + struct adf_uio_control_accel *accel = accel_dev->accel; + struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info; + vm_object_t obj; + + ring_bundle_size = csr_info->ring_bundle_size; + offset = bank_offset * ring_bundle_size; + + sg = sglist_alloc(1, M_WAITOK); + + /* Starting from new HW there is an additional offset + * for bundle CSRs + */ + sglist_append_phys(sg, + accel->bar->base_addr + offset + + csr_info->csr_addr_offset, + ring_bundle_size); + + obj = vm_pager_allocate( + OBJT_SG, sg, ring_bundle_size, VM_PROT_RW, 0, NULL); + if (obj != NULL) { + VM_OBJECT_WLOCK(obj); + vm_object_set_memattr(obj, VM_MEMATTR_UNCACHEABLE); + VM_OBJECT_WUNLOCK(obj); + } + sglist_free(sg); + + return obj; +} + +static int +adf_alloc_bundle(struct adf_accel_dev *accel_dev, int bundle_nr) +{ + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_open_bundle *handle = NULL; + int error; + + if (bundle_nr < 0 || bundle_nr >= GET_MAX_BANKS(accel_dev)) { + printf("ERROR in %s (%d) %d\n", __func__, bundle_nr, __LINE__); + return EINVAL; + } + + accel = accel_dev->accel; + handle = malloc(sizeof(*handle), M_QAT, M_WAITOK | M_ZERO); + if (!handle) { + printf("ERROR in adf_alloc_bundle %d\n", __LINE__); + return ENOMEM; + } + handle->accel = accel; + handle->bundle = bundle_nr; + + mtx_lock(&accel->lock); + adf_dev_get(accel_dev); + accel->num_handles++; + mtx_unlock(&accel->lock); + + error = devfs_set_cdevpriv(handle, adf_release_bundle); + if (error) { + adf_release_bundle(handle); + device_printf(GET_DEV(accel_dev), + "ERROR in adf_alloc_bundle %d\n", + __LINE__); + return (error); + } + + return (0); +} + +static int +adf_uio_ioctl(struct cdev *dev, + u_long cmd, + caddr_t data, + int fflag, + struct thread *td) +{ + struct adf_accel_dev *accel_dev = dev->si_drv1; + struct adf_hw_csr_info *csr_info = NULL; + + if (!accel_dev) { + printf("%s - accel_dev is NULL\n", __func__); + return EFAULT; + } + + csr_info = &accel_dev->hw_device->csr_info; + + switch (cmd) { + case IOCTL_GET_BUNDLE_SIZE: + *(uint32_t *)data = csr_info->ring_bundle_size; + break; + case IOCTL_ALLOC_BUNDLE: + return (adf_alloc_bundle(accel_dev, *(int *)data)); + case IOCTL_GET_ACCEL_TYPE: + *(uint32_t *)data = ADF_UIO_GET_TYPE(accel_dev); + break; + case IOCTL_ADD_MEM_FD: + return (adf_add_mem_fd(accel_dev, *(int *)data)); + default: + return (ENOTTY); + } + return (0); +} + +static int +adf_uio_mmap_single(struct cdev *dev, + vm_ooffset_t *offset, + vm_size_t size, + struct vm_object **object, + int nprot) +{ + struct adf_uio_open_bundle *handle = NULL; + struct adf_uio_control_accel *accel = NULL; + struct adf_uio_control_bundle *bundle = NULL; + struct adf_uio_instance_rings *instance_rings; + int error; + + error = devfs_get_cdevpriv((void **)&handle); + if (error) + return (error); + + if (!handle->accel) { + printf("QAT: Error - no accel in handle\n"); + return EINVAL; + } + accel = handle->accel; + + if (!accel->accel_dev) { + printf("QAT: Error - no accel_dev in accel\n"); + return EINVAL; + } + + bundle = &accel->bundle[handle->bundle]; + if (!bundle->obj) { + printf("QAT: Error no vm_object in bundle\n"); + return EINVAL; + } + + /* Adding pid to bundle list */ + instance_rings = + malloc(sizeof(*instance_rings), M_QAT, M_WAITOK | M_ZERO); + if (!instance_rings) { + printf("QAT: Memory allocation error - line: %d\n", __LINE__); + return -ENOMEM; + } + instance_rings->user_pid = curproc->p_pid; + instance_rings->ring_mask = 0; + mutex_lock(&bundle->list_lock); + list_add_tail(&instance_rings->list, &bundle->list); + mutex_unlock(&bundle->list_lock); + + vm_object_reference(bundle->obj); + *object = bundle->obj; + return (0); +} + +static inline void +adf_uio_init_accel_ctrl(struct adf_uio_control_accel *accel, + struct adf_accel_dev *accel_dev, + unsigned int nb_bundles) +{ + struct adf_uio_control_bundle *bundle; + struct qat_uio_bundle_dev *priv; + unsigned int i; + + accel->nb_bundles = nb_bundles; + accel->total_used_bundles = 0; + + for (i = 0; i < nb_bundles; i++) { + /*initialize the bundle */ + bundle = &accel->bundle[i]; + priv = &bundle->uio_priv; + bundle->hardware_bundle_number = + GET_MAX_BANKS(accel_dev) - nb_bundles + i; + + INIT_LIST_HEAD(&bundle->list); + priv->bundle = bundle; + priv->accel = accel; + + mutex_init(&bundle->lock); + mutex_init(&bundle->list_lock); + if (!accel->bar) + printf("ERROR: bar not defined in accel\n"); + else + bundle->csr_addr = (void *)accel->bar->virt_addr; + } +} + +/** + * Initialization bars on dev start. + */ +static inline void +adf_uio_init_bundle_dev(struct adf_uio_control_accel *accel, + struct adf_accel_dev *accel_dev, + unsigned int nb_bundles) +{ + struct adf_uio_control_bundle *bundle; + unsigned int i; + + for (i = 0; i < nb_bundles; i++) { + bundle = &accel->bundle[i]; + bundle->obj = + adf_uio_map_bar(accel_dev, bundle->hardware_bundle_number); + if (!bundle->obj) { + device_printf(GET_DEV(accel_dev), + "ERROR in adf_alloc_bundle %d\n", + __LINE__); + } + } +} + +int +adf_uio_register(struct adf_accel_dev *accel_dev) +{ + struct adf_uio_control_accel *accel = NULL; + char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 }; + int nb_bundles; + + if (!accel_dev) { + printf("%s - accel_dev is NULL\n", __func__); + return EFAULT; + } + + if (adf_cfg_get_param_value( + accel_dev, ADF_GENERAL_SEC, ADF_FIRST_USER_BUNDLE, val)) { + nb_bundles = 0; + } else { + nb_bundles = GET_MAX_BANKS(accel_dev); + } + + if (nb_bundles) { + accel = malloc(sizeof(*accel) + + nb_bundles * + sizeof(struct adf_uio_control_bundle), + M_QAT, + M_WAITOK | M_ZERO); + mtx_init(&accel->lock, "qat uio", NULL, MTX_DEF); + accel->accel_dev = accel_dev; + accel->bar = accel_dev->accel_pci_dev.pci_bars + + ADF_UIO_GET_BAR(accel_dev); + + adf_uio_init_accel_ctrl(accel, accel_dev, nb_bundles); + accel->cdev = make_dev(&adf_uio_cdevsw, + 0, + UID_ROOT, + GID_WHEEL, + 0600, + "%s", + device_get_nameunit(GET_DEV(accel_dev))); + if (accel->cdev == NULL) { + mtx_destroy(&accel->lock); + goto fail_clean; + } + accel->cdev->si_drv1 = accel_dev; + accel_dev->accel = accel; + cv_init(&accel->cleanup_ok, "uio_accel_cv"); + + adf_uio_init_bundle_dev(accel, accel_dev, nb_bundles); + } + return 0; +fail_clean: + free(accel, M_QAT); + device_printf(GET_DEV(accel_dev), "Failed to register UIO devices\n"); + return ENODEV; +} + +void +adf_uio_remove(struct adf_accel_dev *accel_dev) +{ + struct adf_uio_control_accel *accel = accel_dev->accel; + struct adf_uio_control_bundle *bundle; + unsigned int i; + + if (accel) { + /* Un-mapping all bars */ + for (i = 0; i < accel->nb_bundles; i++) { + bundle = &accel->bundle[i]; + vm_object_deallocate(bundle->obj); + } + + destroy_dev(accel->cdev); + mtx_lock(&accel->lock); + while (accel->num_handles) { + cv_timedwait_sig(&accel->cleanup_ok, + &accel->lock, + 3 * hz); + } + mtx_unlock(&accel->lock); + mtx_destroy(&accel->lock); + cv_destroy(&accel->cleanup_ok); + free(accel, M_QAT); + accel_dev->accel = NULL; + } +} diff --git a/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_freebsd_uio_cleanup.c @@ -0,0 +1,404 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "qat_freebsd.h" +#include "adf_cfg.h" +#include "adf_common_drv.h" +#include "adf_accel_devices.h" +#include "icp_qat_uclo.h" +#include "icp_qat_fw.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_cfg_strings.h" +#include "adf_uio_control.h" +#include "adf_uio_cleanup.h" +#include "adf_uio.h" +#include "adf_transport_access_macros.h" +#include "adf_transport_internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TX_RINGS_DISABLE 0 +#define TX_RINGS_ENABLE 1 +#define PKE_REQ_SIZE 64 +#define BASE_ADDR_SHIFT 6 +#define PKE_RX_RING_0 0 +#define PKE_RX_RING_1 1 + +#define ADF_RING_EMPTY_RETRY_DELAY 2 +#define ADF_RING_EMPTY_MAX_RETRY 15 + +struct bundle_orphan_ring { + unsigned long tx_mask; + unsigned long rx_mask; + unsigned long asym_mask; + int bank; + struct resource *csr_base; + struct adf_uio_control_bundle *bundle; +}; + +/* + * if orphan->tx_mask does not match with orphan->rx_mask + */ +static void +check_orphan_ring(struct adf_accel_dev *accel_dev, + struct bundle_orphan_ring *orphan, + struct adf_hw_device_data *hw_data) +{ + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + int i; + int tx_rx_gap = hw_data->tx_rx_gap; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + struct resource *csr_base = orphan->csr_base; + int bank = orphan->bank; + + for (i = 0; i < num_rings_per_bank; i++) { + if (test_bit(i, &orphan->tx_mask)) { + int rx_ring = i + tx_rx_gap; + + if (!test_bit(rx_ring, &orphan->rx_mask)) { + __clear_bit(i, &orphan->tx_mask); + + /* clean up this tx ring */ + csr_ops->write_csr_ring_config(csr_base, + bank, + i, + 0); + csr_ops->write_csr_ring_base(csr_base, + bank, + i, + 0); + } + + } else if (test_bit(i, &orphan->rx_mask)) { + int tx_ring = i - tx_rx_gap; + + if (!test_bit(tx_ring, &orphan->tx_mask)) { + __clear_bit(i, &orphan->rx_mask); + + /* clean up this rx ring */ + csr_ops->write_csr_ring_config(csr_base, + bank, + i, + 0); + csr_ops->write_csr_ring_base(csr_base, + bank, + i, + 0); + } + } + } +} + +static int +get_orphan_bundle(int bank, + struct adf_uio_control_accel *accel, + struct bundle_orphan_ring **orphan_bundle_out) +{ + int i; + int ret = 0; + struct resource *csr_base; + unsigned long tx_mask; + unsigned long asym_mask; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + struct bundle_orphan_ring *orphan_bundle = NULL; + uint64_t base; + struct list_head *entry; + struct adf_uio_instance_rings *instance_rings; + struct adf_uio_control_bundle *bundle; + u16 ring_mask = 0; + + orphan_bundle = + malloc(sizeof(*orphan_bundle), M_QAT, M_WAITOK | M_ZERO); + if (!orphan_bundle) + return ENOMEM; + + csr_base = accel->bar->virt_addr; + orphan_bundle->csr_base = csr_base; + orphan_bundle->bank = bank; + + orphan_bundle->tx_mask = 0; + orphan_bundle->rx_mask = 0; + tx_mask = accel_dev->hw_device->tx_rings_mask; + asym_mask = accel_dev->hw_device->asym_rings_mask; + + /* Get ring mask for this process. */ + bundle = &accel->bundle[bank]; + orphan_bundle->bundle = bundle; + mutex_lock(&bundle->list_lock); + list_for_each(entry, &bundle->list) + { + instance_rings = + list_entry(entry, struct adf_uio_instance_rings, list); + if (instance_rings->user_pid == curproc->p_pid) { + ring_mask = instance_rings->ring_mask; + break; + } + } + mutex_unlock(&bundle->list_lock); + + for (i = 0; i < num_rings_per_bank; i++) { + base = csr_ops->read_csr_ring_base(csr_base, bank, i); + + if (!base) + continue; + if (!(ring_mask & 1 << i)) + continue; /* Not reserved for this process. */ + + if (test_bit(i, &tx_mask)) + __set_bit(i, &orphan_bundle->tx_mask); + else + __set_bit(i, &orphan_bundle->rx_mask); + + if (test_bit(i, &asym_mask)) + __set_bit(i, &orphan_bundle->asym_mask); + } + + if (orphan_bundle->tx_mask || orphan_bundle->rx_mask) + check_orphan_ring(accel_dev, orphan_bundle, hw_data); + + *orphan_bundle_out = orphan_bundle; + return ret; +} + +static void +put_orphan_bundle(struct bundle_orphan_ring *bundle) +{ + if (!bundle) + return; + + free(bundle, M_QAT); +} + +/* cleanup all ring */ +static void +cleanup_all_ring(struct adf_uio_control_accel *accel, + struct bundle_orphan_ring *orphan) +{ + int i; + struct resource *csr_base = orphan->csr_base; + unsigned long mask = orphan->rx_mask | orphan->tx_mask; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + int bank = orphan->bank; + + mutex_lock(&orphan->bundle->lock); + orphan->bundle->rings_enabled &= ~mask; + adf_update_uio_ring_arb(orphan->bundle); + mutex_unlock(&orphan->bundle->lock); + + for (i = 0; i < num_rings_per_bank; i++) { + if (!test_bit(i, &mask)) + continue; + + csr_ops->write_csr_ring_config(csr_base, bank, i, 0); + csr_ops->write_csr_ring_base(csr_base, bank, i, 0); + } +} + +/* + * Return true, if number of messages in tx ring is equal to number + * of messages in corresponding rx ring, else false. + */ +static bool +is_all_resp_recvd(struct adf_hw_csr_ops *csr_ops, + struct bundle_orphan_ring *bundle, + const u8 num_rings_per_bank) +{ + u32 rx_tail = 0, tx_head = 0, rx_ring_msg_offset = 0, + tx_ring_msg_offset = 0, tx_rx_offset = num_rings_per_bank / 2, + idx = 0, retry = 0, delay = ADF_RING_EMPTY_RETRY_DELAY; + + do { + for_each_set_bit(idx, &bundle->tx_mask, tx_rx_offset) + { + rx_tail = + csr_ops->read_csr_ring_tail(bundle->csr_base, + 0, + (idx + tx_rx_offset)); + tx_head = csr_ops->read_csr_ring_head(bundle->csr_base, + 0, + idx); + + /* + * Normalize messages in tx rings to match rx ring + * message size, i.e., size of response message(32). + * Asym messages are 64 bytes each, so right shift + * by 1 to normalize to 32. Sym and compression + * messages are 128 bytes each, so right shift by 2 + * to normalize to 32. + */ + if (bundle->asym_mask & (1 << idx)) + tx_ring_msg_offset = (tx_head >> 1); + else + tx_ring_msg_offset = (tx_head >> 2); + + rx_ring_msg_offset = rx_tail; + + if (tx_ring_msg_offset != rx_ring_msg_offset) + break; + } + if (idx == tx_rx_offset) + /* All Tx and Rx ring message counts match */ + return true; + + DELAY(delay); + delay *= 2; + } while (++retry < ADF_RING_EMPTY_MAX_RETRY); + + return false; +} + +static int +bundle_need_cleanup(int bank, struct adf_uio_control_accel *accel) +{ + struct resource *csr_base = accel->bar->virt_addr; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 num_rings_per_bank = hw_data->num_rings_per_bank; + int i; + + if (!csr_base) + return 0; + + for (i = 0; i < num_rings_per_bank; i++) { + if (csr_ops->read_csr_ring_base(csr_base, bank, i)) + return 1; + } + + return 0; +} + +static void +cleanup_orphan_ring(struct bundle_orphan_ring *orphan, + struct adf_uio_control_accel *accel) +{ + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u8 number_rings_per_bank = hw_data->num_rings_per_bank; + + /* disable the interrupt */ + csr_ops->write_csr_int_col_en(orphan->csr_base, orphan->bank, 0); + + /* + * wait firmware finish the in-process ring + * 1. disable all tx rings + * 2. check if all responses are received + * 3. reset all rings + */ + adf_disable_ring_arb(accel_dev, orphan->csr_base, 0, orphan->tx_mask); + + if (!is_all_resp_recvd(csr_ops, orphan, number_rings_per_bank)) { + device_printf(GET_DEV(accel_dev), + "Failed to clean up orphan rings"); + return; + } + + /* + * When the execution reaches here, it is assumed that + * there is no inflight request in the rings and that + * there is no in-process ring. + */ + + cleanup_all_ring(accel, orphan); +} + +void +adf_uio_do_cleanup_orphan(int bank, struct adf_uio_control_accel *accel) +{ + int ret, pid_found; + struct adf_uio_instance_rings *instance_rings, *tmp; + struct adf_uio_control_bundle *bundle; + /* orphan is local pointer allocated and deallocated in this function */ + struct bundle_orphan_ring *orphan = NULL; + struct adf_accel_dev *accel_dev = accel->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + if (!bundle_need_cleanup(bank, accel)) + goto release; + + ret = get_orphan_bundle(bank, accel, &orphan); + if (ret != 0) + return; + + /* + * If driver supports ring pair reset, no matter process + * exits normally or abnormally, just do ring pair reset. + * ring pair reset will reset all ring pair registers to + * default value. Driver only needs to reset ring mask + */ + if (hw_data->ring_pair_reset) { + hw_data->ring_pair_reset( + accel_dev, orphan->bundle->hardware_bundle_number); + mutex_lock(&orphan->bundle->lock); + /* + * If processes exit normally, rx_mask, tx_mask + * and rings_enabled are all 0, below expression + * have no impact on rings_enabled. + * If processes exit abnormally, rings_enabled + * will be set as 0 by below expression. + */ + orphan->bundle->rings_enabled &= + ~(orphan->rx_mask | orphan->tx_mask); + mutex_unlock(&orphan->bundle->lock); + goto out; + } + + if (!orphan->tx_mask && !orphan->rx_mask) + goto out; + + device_printf(GET_DEV(accel_dev), + "Process %d %s exit with orphan rings %lx:%lx\n", + curproc->p_pid, + curproc->p_comm, + orphan->tx_mask, + orphan->rx_mask); + + if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status)) { + cleanup_orphan_ring(orphan, accel); + } +out: + put_orphan_bundle(orphan); + +release: + + bundle = &accel->bundle[bank]; + /* + * If the user process died without releasing the rings + * then force a release here. + */ + mutex_lock(&bundle->list_lock); + pid_found = 0; + list_for_each_entry_safe(instance_rings, tmp, &bundle->list, list) + { + if (instance_rings->user_pid == curproc->p_pid) { + pid_found = 1; + break; + } + } + mutex_unlock(&bundle->list_lock); + + if (pid_found) { + mutex_lock(&bundle->lock); + bundle->rings_used &= ~instance_rings->ring_mask; + mutex_unlock(&bundle->lock); + } +} diff --git a/sys/dev/qat/qat_common/adf_gen2_hw_data.c b/sys/dev/qat/qat_common/adf_gen2_hw_data.c --- a/sys/dev/qat/qat_common/adf_gen2_hw_data.c +++ b/sys/dev/qat/qat_common/adf_gen2_hw_data.c @@ -55,6 +55,12 @@ WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value); } +static dma_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE(csr_base_addr, bank, ring); +} + static void write_csr_ring_base(struct resource *csr_base_addr, u32 bank, @@ -106,6 +112,12 @@ WRITE_CSR_RING_SRV_ARB_EN(csr_base_addr, bank, value); } +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + void adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) { @@ -113,6 +125,9 @@ csr_info->arb_enable_mask = 0xFF; + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE; + csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; csr_ops->read_csr_ring_head = read_csr_ring_head; csr_ops->write_csr_ring_head = write_csr_ring_head; @@ -120,6 +135,7 @@ csr_ops->write_csr_ring_tail = write_csr_ring_tail; csr_ops->read_csr_e_stat = read_csr_e_stat; csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; csr_ops->write_csr_ring_base = write_csr_ring_base; csr_ops->write_csr_int_flag = write_csr_int_flag; csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; @@ -128,5 +144,5 @@ csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; } -EXPORT_SYMBOL_GPL(adf_gen2_init_hw_csr_info); diff --git a/sys/dev/qat/qat_common/adf_gen4_hw_data.c b/sys/dev/qat/qat_common/adf_gen4_hw_data.c --- a/sys/dev/qat/qat_common/adf_gen4_hw_data.c +++ b/sys/dev/qat/qat_common/adf_gen4_hw_data.c @@ -2,8 +2,12 @@ /* Copyright(c) 2021 Intel Corporation */ /* $FreeBSD$ */ #include "adf_accel_devices.h" +#include "adf_common_drv.h" #include "adf_gen4_hw_data.h" +#define ADF_RPRESET_TIMEOUT_MS 5000 +#define ADF_RPRESET_POLLING_INTERVAL 20 + static u64 build_csr_ring_base_addr(bus_addr_t addr, u32 size) { @@ -55,6 +59,12 @@ WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value); } +static bus_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE(csr_base_addr, bank, ring); +} + static void write_csr_ring_base(struct resource *csr_base_addr, u32 bank, @@ -106,6 +116,12 @@ WRITE_CSR_RING_SRV_ARB_EN(csr_base_addr, bank, value); } +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + void adf_gen4_init_hw_csr_info(struct adf_hw_csr_info *csr_info) { @@ -113,6 +129,9 @@ csr_info->arb_enable_mask = 0x1; + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE; + csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; csr_ops->read_csr_ring_head = read_csr_ring_head; csr_ops->write_csr_ring_head = write_csr_ring_head; @@ -120,6 +139,7 @@ csr_ops->write_csr_ring_tail = write_csr_ring_tail; csr_ops->read_csr_e_stat = read_csr_e_stat; csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; csr_ops->write_csr_ring_base = write_csr_ring_base; csr_ops->write_csr_int_flag = write_csr_int_flag; csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; @@ -128,8 +148,64 @@ csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; +} + +static int +reset_ring_pair(struct resource *csr, u32 bank_number) +{ + int reset_timeout = ADF_RPRESET_TIMEOUT_MS; + const int timeout_step = ADF_RPRESET_POLLING_INTERVAL; + u32 val; + + /* Write rpresetctl register bit#0 as 1 + * As rpresetctl registers have no RW bits, no need to preserve + * values for other bits, just write bit#0 + * NOTE: bit#12-bit#31 are WO, the write operation only takes + * effect when bit#1 is written 1 for pasid level reset + */ + ADF_CSR_WR(csr, + ADF_WQM_CSR_RPRESETCTL(bank_number), + BIT(ADF_WQM_CSR_RPRESETCTL_SHIFT)); + + /* Read rpresetsts register to wait for rp reset complete */ + while (reset_timeout > 0) { + val = ADF_CSR_RD(csr, ADF_WQM_CSR_RPRESETSTS(bank_number)); + if (val & ADF_WQM_CSR_RPRESETSTS_MASK) + break; + pause_ms("adfstop", timeout_step); + reset_timeout -= timeout_step; + } + if (reset_timeout <= 0) + return EFAULT; + + /* When rp reset is done, clear rpresetsts bit0 */ + ADF_CSR_WR(csr, + ADF_WQM_CSR_RPRESETSTS(bank_number), + BIT(ADF_WQM_CSR_RPRESETSTS_SHIFT)); + return 0; +} + +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); + struct resource *csr; + int ret; + + if (bank_number >= hw_data->num_banks) + return -EINVAL; + + csr = (&GET_BARS(accel_dev)[etr_bar_id])->virt_addr; + + ret = reset_ring_pair(csr, bank_number); + if (ret) + device_printf(GET_DEV(accel_dev), + "ring pair reset failure (timeout)\n"); + + return ret; } -EXPORT_SYMBOL_GPL(adf_gen4_init_hw_csr_info); static inline void adf_gen4_unpack_ssm_wdtimer(u64 value, u32 *upper, u32 *lower) @@ -173,4 +249,9 @@ return 0; } -EXPORT_SYMBOL_GPL(adf_gen4_set_ssm_wdtimer); + +int +adf_pfvf_comms_disabled(struct adf_accel_dev *accel_dev) +{ + return 0; +} diff --git a/sys/dev/qat/qat_common/adf_gen4_pfvf.c b/sys/dev/qat/qat_common/adf_gen4_pfvf.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_gen4_pfvf.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_gen4_pfvf.h" +#include "adf_pfvf_utils.h" +#include "adf_pfvf_vf_proto.h" + +#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 0x41A180 +#define ADF_4XXX_VM2PF_MSK 0x41A1C0 +#define ADF_GEN4_VF_MSK 0xFFFF + +#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 + +#define ADF_4XXXIOV_PF2VM_OFFSET 0x100C +#define ADF_4XXXIOV_VM2PF_OFFSET 0x1008 +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_vf_get_pfvf_offset(u32 i) +{ + return ADF_4XXXIOV_PF2VM_OFFSET; +} + +static u32 +adf_gen4_vf_get_vfpf_offset(u32 i) +{ + return ADF_4XXXIOV_VM2PF_OFFSET; +} + +static int +adf_gen4_pfvf_send(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + u32 pfvf_offset, + struct mutex *csr_lock) +{ + struct resource *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) + device_printf(GET_DEV(accel_dev), + "ACK not received from remote\n"); + + mutex_unlock(csr_lock); + return ret; +} + +static int +adf_gen4_vf2pf_send(struct adf_accel_dev *accel_dev, + struct pfvf_message msg, + u32 pfvf_offset, + struct mutex *csr_lock) +{ + return adf_gen4_pfvf_send(accel_dev, msg, pfvf_offset, csr_lock); +} + +static struct pfvf_message +adf_gen4_pfvf_recv(struct adf_accel_dev *accel_dev, + u32 pfvf_offset, + u8 compat_ver) +{ + struct resource *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct pfvf_message msg = { 0 }; + u32 csr_val; + + /* Read message from the CSR */ + csr_val = ADF_CSR_RD(pmisc_addr, pfvf_offset); + if (!(csr_val & ADF_PFVF_INT)) { + device_printf(GET_DEV(accel_dev), + "Spurious PFVF interrupt, msg 0x%.8x. Ignored\n", + csr_val); + return msg; + } + + /* 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); +} + +static struct pfvf_message +adf_gen4_pf2vf_recv(struct adf_accel_dev *accel_dev, + u32 pfvf_offset, + u8 compat_ver) +{ + return adf_gen4_pfvf_recv(accel_dev, pfvf_offset, compat_ver); +} + +void +adf_gen4_init_vf_pfvf_ops(struct adf_pfvf_ops *pfvf_ops) +{ + pfvf_ops->enable_comms = adf_enable_vf2pf_comms; + pfvf_ops->get_pf2vf_offset = adf_gen4_vf_get_pfvf_offset; + pfvf_ops->get_vf2pf_offset = adf_gen4_vf_get_vfpf_offset; + pfvf_ops->send_msg = adf_gen4_vf2pf_send; + pfvf_ops->recv_msg = adf_gen4_pf2vf_recv; +} diff --git a/sys/dev/qat/qat_common/adf_gen4_timer.c b/sys/dev/qat/qat_common/adf_gen4_timer.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_gen4_timer.c @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include "adf_accel_devices.h" +#include "adf_heartbeat.h" +#include "adf_common_drv.h" +#include "icp_qat_fw_init_admin.h" +#include "adf_gen4_timer.h" + +#include "adf_dev_err.h" + +#define ADF_GEN4_INT_TIMER_VALUE_IN_MS 200 +/* Interval within timer interrupt. Value in miliseconds. */ + +#define ADF_GEN4_MAX_INT_TIMER_VALUE_IN_MS 0xFFFFFFFF +/* MAX Interval within timer interrupt. Value in miliseconds. */ + +static u64 +adf_get_next_timeout(u32 timeout_val) +{ + u64 timeout = msecs_to_jiffies(timeout_val); + + return rounddown(jiffies + timeout, timeout); +} + +static void +adf_hb_irq_bh_handler(struct work_struct *work) +{ + struct icp_qat_fw_init_admin_req req = { 0 }; + struct icp_qat_fw_init_admin_resp resp = { 0 }; + struct adf_hb_timer_data *hb_timer_data = + container_of(work, struct adf_hb_timer_data, hb_int_timer_work); + struct adf_accel_dev *accel_dev = hb_timer_data->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + u32 ae_mask = hw_data->ae_mask; + + if (!accel_dev->int_timer || !accel_dev->int_timer->enabled) + goto end; + + /* Update heartbeat count via init/admin cmd */ + if (!accel_dev->admin) { + device_printf(GET_DEV(accel_dev), + "adf_admin is not available\n"); + goto end; + } + + req.cmd_id = ICP_QAT_FW_HEARTBEAT_SYNC; + req.heartbeat_ticks = accel_dev->int_timer->int_cnt; + + if (adf_send_admin(accel_dev, &req, &resp, ae_mask)) + device_printf(GET_DEV(accel_dev), + "Failed to update qat's HB count\n"); + +end: + kfree(hb_timer_data); +} + +static void +timer_handler(struct timer_list *tl) +{ + struct adf_int_timer *int_timer = from_timer(int_timer, tl, timer); + struct adf_accel_dev *accel_dev = int_timer->accel_dev; + struct adf_hb_timer_data *hb_timer_data = NULL; + u64 timeout_val = adf_get_next_timeout(int_timer->timeout_val); + /* Update TL TBD */ + + /* Schedule a heartbeat work queue to update HB */ + hb_timer_data = kzalloc(sizeof(*hb_timer_data), GFP_ATOMIC); + if (hb_timer_data) { + hb_timer_data->accel_dev = accel_dev; + + INIT_WORK(&hb_timer_data->hb_int_timer_work, + adf_hb_irq_bh_handler); + queue_work(int_timer->timer_irq_wq, + &hb_timer_data->hb_int_timer_work); + } else { + device_printf(GET_DEV(accel_dev), + "Failed to alloc heartbeat timer data\n"); + } + int_timer->int_cnt++; + mod_timer(tl, timeout_val); +} + +int +adf_int_timer_init(struct adf_accel_dev *accel_dev) +{ + u64 timeout_val = adf_get_next_timeout(ADF_GEN4_INT_TIMER_VALUE_IN_MS); + struct adf_int_timer *int_timer = NULL; + char wqname[32] = { 0 }; + + if (!accel_dev) + return 0; + + int_timer = kzalloc(sizeof(*int_timer), GFP_KERNEL); + if (!int_timer) + return -ENOMEM; + + sprintf(wqname, "qat_timer_wq_%d", accel_dev->accel_id); + + int_timer->timer_irq_wq = alloc_workqueue(wqname, WQ_MEM_RECLAIM, 1); + + if (!int_timer->timer_irq_wq) { + kfree(int_timer); + return -ENOMEM; + } + + int_timer->accel_dev = accel_dev; + int_timer->timeout_val = ADF_GEN4_INT_TIMER_VALUE_IN_MS; + int_timer->int_cnt = 0; + int_timer->enabled = true; + accel_dev->int_timer = int_timer; + + timer_setup(&int_timer->timer, timer_handler, 0); + mod_timer(&int_timer->timer, timeout_val); + + return 0; +} + +void +adf_int_timer_exit(struct adf_accel_dev *accel_dev) +{ + if (accel_dev && accel_dev->int_timer) { + del_timer_sync(&accel_dev->int_timer->timer); + accel_dev->int_timer->enabled = false; + + if (accel_dev->int_timer->timer_irq_wq) { + flush_workqueue(accel_dev->int_timer->timer_irq_wq); + destroy_workqueue(accel_dev->int_timer->timer_irq_wq); + } + + kfree(accel_dev->int_timer); + accel_dev->int_timer = NULL; + } +} diff --git a/sys/dev/qat/qat_common/adf_gen2_hw_data.c b/sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c copy from sys/dev/qat/qat_common/adf_gen2_hw_data.c copy to sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c --- a/sys/dev/qat/qat_common/adf_gen2_hw_data.c +++ b/sys/dev/qat/qat_common/adf_gen4vf_hw_csr_data.c @@ -1,19 +1,19 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2021 Intel Corporation */ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ -#include "adf_gen2_hw_data.h" -#include "icp_qat_hw.h" +#include "adf_accel_devices.h" +#include "adf_gen4vf_hw_csr_data.h" static u64 -build_csr_ring_base_addr(bus_addr_t addr, u32 size) +build_csr_ring_base_addr(dma_addr_t addr, u32 size) { - return BUILD_RING_BASE_ADDR(addr, size); + return BUILD_RING_BASE_ADDR_GEN4(addr, size); } static u32 read_csr_ring_head(struct resource *csr_base_addr, u32 bank, u32 ring) { - return READ_CSR_RING_HEAD(csr_base_addr, bank, ring); + return READ_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring); } static void @@ -22,13 +22,13 @@ u32 ring, u32 value) { - WRITE_CSR_RING_HEAD(csr_base_addr, bank, ring, value); + WRITE_CSR_RING_HEAD_GEN4VF(csr_base_addr, bank, ring, value); } static u32 read_csr_ring_tail(struct resource *csr_base_addr, u32 bank, u32 ring) { - return READ_CSR_RING_TAIL(csr_base_addr, bank, ring); + return READ_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring); } static void @@ -37,13 +37,13 @@ u32 ring, u32 value) { - WRITE_CSR_RING_TAIL(csr_base_addr, bank, ring, value); + WRITE_CSR_RING_TAIL_GEN4VF(csr_base_addr, bank, ring, value); } static u32 read_csr_e_stat(struct resource *csr_base_addr, u32 bank) { - return READ_CSR_E_STAT(csr_base_addr, bank); + return READ_CSR_E_STAT_GEN4VF(csr_base_addr, bank); } static void @@ -52,67 +52,94 @@ u32 ring, u32 value) { - WRITE_CSR_RING_CONFIG(csr_base_addr, bank, ring, value); + WRITE_CSR_RING_CONFIG_GEN4VF(csr_base_addr, bank, ring, value); +} + +static dma_addr_t +read_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring) +{ + return READ_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring); } static void write_csr_ring_base(struct resource *csr_base_addr, u32 bank, u32 ring, - bus_addr_t addr) + dma_addr_t addr) { - WRITE_CSR_RING_BASE(csr_base_addr, bank, ring, addr); + WRITE_CSR_RING_BASE_GEN4VF(csr_base_addr, bank, ring, addr); } static void write_csr_int_flag(struct resource *csr_base_addr, u32 bank, u32 value) { - WRITE_CSR_INT_FLAG(csr_base_addr, bank, value); + WRITE_CSR_INT_FLAG_GEN4VF(csr_base_addr, bank, value); } static void write_csr_int_srcsel(struct resource *csr_base_addr, u32 bank) { - WRITE_CSR_INT_SRCSEL(csr_base_addr, bank); + WRITE_CSR_INT_SRCSEL_GEN4VF(csr_base_addr, bank); } static void write_csr_int_col_en(struct resource *csr_base_addr, u32 bank, u32 value) { - WRITE_CSR_INT_COL_EN(csr_base_addr, bank, value); + WRITE_CSR_INT_COL_EN_GEN4VF(csr_base_addr, bank, value); } static void write_csr_int_col_ctl(struct resource *csr_base_addr, u32 bank, u32 value) { - WRITE_CSR_INT_COL_CTL(csr_base_addr, bank, value); + WRITE_CSR_INT_COL_CTL_GEN4VF(csr_base_addr, bank, value); } static void write_csr_int_flag_and_col(struct resource *csr_base_addr, u32 bank, u32 value) { - WRITE_CSR_INT_FLAG_AND_COL(csr_base_addr, bank, value); + WRITE_CSR_INT_FLAG_AND_COL_GEN4VF(csr_base_addr, bank, value); } static u32 read_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank) { - return READ_CSR_RING_SRV_ARB_EN(csr_base_addr, bank); + return READ_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank); } static void write_csr_ring_srv_arb_en(struct resource *csr_base_addr, u32 bank, u32 value) { - WRITE_CSR_RING_SRV_ARB_EN(csr_base_addr, bank, value); + WRITE_CSR_RING_SRV_ARB_EN_GEN4VF(csr_base_addr, bank, value); +} + +static u32 +get_src_sel_mask(void) +{ + return ADF_BANK_INT_SRC_SEL_MASK_GEN4; +} + +static u32 +get_int_col_ctl_enable_mask(void) +{ + return ADF_RING_CSR_INT_COL_CTL_ENABLE; +} + +static u32 +get_bank_irq_mask(u32 irq_mask) +{ + return 0x1; } void -adf_gen2_init_hw_csr_info(struct adf_hw_csr_info *csr_info) +gen4vf_init_hw_csr_info(struct adf_hw_csr_info *csr_info) { struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops; - csr_info->arb_enable_mask = 0xFF; - + csr_info->csr_addr_offset = ADF_RING_CSR_ADDR_OFFSET_GEN4VF; + csr_info->ring_bundle_size = ADF_RING_BUNDLE_SIZE_GEN4; + csr_info->bank_int_flag_clear_mask = ADF_BANK_INT_FLAG_CLEAR_MASK_GEN4; + csr_info->num_rings_per_int_srcsel = ADF_RINGS_PER_INT_SRCSEL_GEN4; + csr_info->arb_enable_mask = 0x1; csr_ops->build_csr_ring_base_addr = build_csr_ring_base_addr; csr_ops->read_csr_ring_head = read_csr_ring_head; csr_ops->write_csr_ring_head = write_csr_ring_head; @@ -120,6 +147,7 @@ csr_ops->write_csr_ring_tail = write_csr_ring_tail; csr_ops->read_csr_e_stat = read_csr_e_stat; csr_ops->write_csr_ring_config = write_csr_ring_config; + csr_ops->read_csr_ring_base = read_csr_ring_base; csr_ops->write_csr_ring_base = write_csr_ring_base; csr_ops->write_csr_int_flag = write_csr_int_flag; csr_ops->write_csr_int_srcsel = write_csr_int_srcsel; @@ -128,5 +156,7 @@ csr_ops->write_csr_int_flag_and_col = write_csr_int_flag_and_col; csr_ops->read_csr_ring_srv_arb_en = read_csr_ring_srv_arb_en; csr_ops->write_csr_ring_srv_arb_en = write_csr_ring_srv_arb_en; + csr_ops->get_src_sel_mask = get_src_sel_mask; + csr_ops->get_int_col_ctl_enable_mask = get_int_col_ctl_enable_mask; + csr_ops->get_bank_irq_mask = get_bank_irq_mask; } -EXPORT_SYMBOL_GPL(adf_gen2_init_hw_csr_info); diff --git a/sys/dev/qat/qat_common/adf_hw_arbiter.c b/sys/dev/qat/qat_common/adf_hw_arbiter.c --- a/sys/dev/qat/qat_common/adf_hw_arbiter.c +++ b/sys/dev/qat/qat_common/adf_hw_arbiter.c @@ -114,6 +114,25 @@ arben); } +void +adf_update_uio_ring_arb(struct adf_uio_control_bundle *bundle) +{ + int shift; + u32 arben, arben_tx, arben_rx, arb_mask; + struct adf_accel_dev *accel_dev = bundle->uio_priv.accel->accel_dev; + struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info; + struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops; + + arb_mask = csr_info->arb_enable_mask; + shift = hweight32(arb_mask); + + arben_tx = bundle->rings_enabled & arb_mask; + arben_rx = (bundle->rings_enabled >> shift) & arb_mask; + arben = arben_tx & arben_rx; + csr_ops->write_csr_ring_srv_arb_en(bundle->csr_addr, + bundle->hardware_bundle_number, + arben); +} void adf_enable_ring_arb(struct adf_accel_dev *accel_dev, void *csr_addr, @@ -121,16 +140,15 @@ unsigned int mask) { struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev); - struct resource *csr = csr_addr; u32 arbenable; - if (!csr) + if (!csr_addr) return; mutex_lock(&csr_arb_lock); - arbenable = csr_ops->read_csr_ring_srv_arb_en(csr, bank_nr); + arbenable = csr_ops->read_csr_ring_srv_arb_en(csr_addr, bank_nr); arbenable |= mask & 0xFF; - csr_ops->write_csr_ring_srv_arb_en(csr, bank_nr, arbenable); + csr_ops->write_csr_ring_srv_arb_en(csr_addr, bank_nr, arbenable); mutex_unlock(&csr_arb_lock); } diff --git a/sys/dev/qat/qat_common/adf_init.c b/sys/dev/qat/qat_common/adf_init.c --- a/sys/dev/qat/qat_common/adf_init.c +++ b/sys/dev/qat/qat_common/adf_init.c @@ -10,6 +10,7 @@ #include "icp_qat_fw_init_admin.h" #include "adf_cfg_strings.h" #include "adf_dev_err.h" +#include "adf_uio.h" #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" #include @@ -77,7 +78,6 @@ char mmp_version[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; struct adf_hw_device_data *hw_data = NULL; unsigned long val; - if (!accel_dev) return -EINVAL; @@ -349,18 +349,9 @@ hw_data->enable_error_correction(accel_dev); - if (hw_data->enable_vf2pf_comms && - hw_data->enable_vf2pf_comms(accel_dev)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed to enable vf2pf comms\n"); - return EFAULT; - } - - if (adf_pf_vf_capabilities_init(accel_dev)) - return EFAULT; - - if (adf_pf_vf_ring_to_svc_init(accel_dev)) - return EFAULT; + ret = hw_data->csr_info.pfvf_ops.enable_comms(accel_dev); + if (ret) + return ret; if (adf_cfg_add_device_params(accel_dev)) return EFAULT; @@ -462,6 +453,12 @@ return EFAULT; } + if (hw_data->int_timer_init && hw_data->int_timer_init(accel_dev)) { + device_printf(GET_DEV(accel_dev), + "Failed to init heartbeat interrupt timer\n"); + return -EFAULT; + } + list_for_each(list_itr, &service_table) { service = list_entry(list_itr, struct service_hndl, list); @@ -474,6 +471,18 @@ set_bit(accel_dev->accel_id, service->start_status); } + if (accel_dev->is_vf || !accel_dev->u1.pf.vf_info) { + /*Register UIO devices */ + if (adf_uio_register(accel_dev)) { + adf_uio_remove(accel_dev); + device_printf(GET_DEV(accel_dev), + "Failed to register UIO devices\n"); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ENODEV; + } + } + if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status) && adf_cfg_add_ext_params(accel_dev)) return EFAULT; @@ -521,6 +530,9 @@ clear_bit(ADF_STATUS_STARTING, &accel_dev->status); clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + if (accel_dev->hw_device->int_timer_exit) + accel_dev->hw_device->int_timer_exit(accel_dev); + list_for_each(list_itr, &service_table) { service = list_entry(list_itr, struct service_hndl, list); @@ -529,6 +541,11 @@ clear_bit(accel_dev->accel_id, service->start_status); } + if (accel_dev->is_vf || !accel_dev->u1.pf.vf_info) { + /* Remove UIO Devices */ + adf_uio_remove(accel_dev); + } + if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) { if (adf_ae_stop(accel_dev)) device_printf(GET_DEV(accel_dev), @@ -596,9 +613,6 @@ hw_data->disable_iov(accel_dev); - if (hw_data->disable_vf2pf_comms) - hw_data->disable_vf2pf_comms(accel_dev); - if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) { hw_data->free_irq(accel_dev); clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status); diff --git a/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c b/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c deleted file mode 100644 --- a/sys/dev/qat/qat_common/adf_pf2vf_capabilities.c +++ /dev/null @@ -1,147 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" -#include "adf_cfg.h" - -#define ADF_VF2PF_CAPABILITIES_V1_VERSION 1 -#define ADF_VF2PF_CAPABILITIES_V1_LENGTH 4 -#define ADF_VF2PF_CAPABILITIES_V2_VERSION 2 -#define ADF_VF2PF_CAPABILITIES_CAP_OFFSET 4 -#define ADF_VF2PF_CAPABILITIES_V2_LENGTH 8 -#define ADF_VF2PF_CAPABILITIES_V3_VERSION 3 -#define ADF_VF2PF_CAPABILITIES_FREQ_OFFSET 8 -#define ADF_VF2PF_CAPABILITIES_V3_LENGTH 12 - -static int -adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num) -{ - static u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 }; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - u32 ext_dc_caps = hw_data->extended_dc_capabilities; - u32 capabilities = hw_data->accel_capabilities_mask; - u32 frequency = hw_data->clock_frequency; - u16 byte = 0; - u16 index = 0; - - for (byte = 0; byte < sizeof(ext_dc_caps); byte++) { - data[byte] = (ext_dc_caps >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - for (byte = 0, index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET; - byte < sizeof(capabilities); - byte++, index++) { - data[index] = (capabilities >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - if (frequency) { - for (byte = 0, index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET; - byte < sizeof(frequency); - byte++, index++) { - data[index] = - (frequency >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - *length = ADF_VF2PF_CAPABILITIES_V3_LENGTH; - *block_version = ADF_VF2PF_CAPABILITIES_V3_VERSION; - } else { - *length = ADF_VF2PF_CAPABILITIES_V2_LENGTH; - *block_version = ADF_VF2PF_CAPABILITIES_V2_VERSION; - } - - *buffer = data; - return 0; -} - -int -adf_pf_vf_capabilities_init(struct adf_accel_dev *accel_dev) -{ - u8 data[ADF_VF2PF_CAPABILITIES_V3_LENGTH] = { 0 }; - u8 len = ADF_VF2PF_CAPABILITIES_V3_LENGTH; - u8 version = ADF_VF2PF_CAPABILITIES_V2_VERSION; - u32 ex_dc_cap = 0; - u32 capabilities = 0; - u32 frequency = 0; - u16 byte = 0; - u16 index = 0; - - if (!accel_dev->is_vf) { - /* on the pf */ - if (!adf_iov_is_block_provider_registered( - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY)) - adf_iov_block_provider_register( - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY, - adf_pf_capabilities_msg_provider); - } else if (accel_dev->u1.vf.pf_version >= - ADF_PFVF_COMPATIBILITY_CAPABILITIES) { - /* on the vf */ - if (adf_iov_block_get(accel_dev, - ADF_VF2PF_BLOCK_MSG_CAP_SUMMARY, - &version, - data, - &len)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed adf_iov_block_get\n"); - return EFAULT; - } - - if (len < ADF_VF2PF_CAPABILITIES_V1_LENGTH) { - device_printf( - GET_DEV(accel_dev), - "Capabilities message truncated to %d bytes\n", - len); - return EFAULT; - } - - for (byte = 0; byte < sizeof(ex_dc_cap); byte++) { - ex_dc_cap |= data[byte] << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->extended_dc_capabilities = ex_dc_cap; - - /* Get capabilities if provided by PF */ - if (len >= ADF_VF2PF_CAPABILITIES_V2_LENGTH) { - for (byte = 0, - index = ADF_VF2PF_CAPABILITIES_CAP_OFFSET; - byte < sizeof(capabilities); - byte++, index++) { - capabilities |= data[index] - << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->accel_capabilities_mask = - capabilities; - } else { - device_printf(GET_DEV(accel_dev), - "PF did not communicate capabilities\n"); - } - - /* Get frequency if provided by the PF */ - if (len >= ADF_VF2PF_CAPABILITIES_V3_LENGTH) { - for (byte = 0, - index = ADF_VF2PF_CAPABILITIES_FREQ_OFFSET; - byte < sizeof(frequency); - byte++, index++) { - frequency |= data[index] - << (byte * ADF_PFVF_DATA_SHIFT); - } - accel_dev->hw_device->clock_frequency = frequency; - } else { - device_printf(GET_DEV(accel_dev), - "PF did not communicate frequency\n"); - } - - } else { - /* The PF is too old to support the extended capabilities */ - accel_dev->hw_device->extended_dc_capabilities = 0; - } - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_pf2vf_msg.c b/sys/dev/qat/qat_common/adf_pf2vf_msg.c deleted file mode 100644 --- a/sys/dev/qat/qat_common/adf_pf2vf_msg.c +++ /dev/null @@ -1,896 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" - -adf_iov_block_provider - pf2vf_message_providers[ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE + 1]; -unsigned char pfvf_crc8_table[] = - { 0x00, 0x97, 0xB9, 0x2E, 0xE5, 0x72, 0x5C, 0xCB, 0x5D, 0xCA, 0xE4, 0x73, - 0xB8, 0x2F, 0x01, 0x96, 0xBA, 0x2D, 0x03, 0x94, 0x5F, 0xC8, 0xE6, 0x71, - 0xE7, 0x70, 0x5E, 0xC9, 0x02, 0x95, 0xBB, 0x2C, 0xE3, 0x74, 0x5A, 0xCD, - 0x06, 0x91, 0xBF, 0x28, 0xBE, 0x29, 0x07, 0x90, 0x5B, 0xCC, 0xE2, 0x75, - 0x59, 0xCE, 0xE0, 0x77, 0xBC, 0x2B, 0x05, 0x92, 0x04, 0x93, 0xBD, 0x2A, - 0xE1, 0x76, 0x58, 0xCF, 0x51, 0xC6, 0xE8, 0x7F, 0xB4, 0x23, 0x0D, 0x9A, - 0x0C, 0x9B, 0xB5, 0x22, 0xE9, 0x7E, 0x50, 0xC7, 0xEB, 0x7C, 0x52, 0xC5, - 0x0E, 0x99, 0xB7, 0x20, 0xB6, 0x21, 0x0F, 0x98, 0x53, 0xC4, 0xEA, 0x7D, - 0xB2, 0x25, 0x0B, 0x9C, 0x57, 0xC0, 0xEE, 0x79, 0xEF, 0x78, 0x56, 0xC1, - 0x0A, 0x9D, 0xB3, 0x24, 0x08, 0x9F, 0xB1, 0x26, 0xED, 0x7A, 0x54, 0xC3, - 0x55, 0xC2, 0xEC, 0x7B, 0xB0, 0x27, 0x09, 0x9E, 0xA2, 0x35, 0x1B, 0x8C, - 0x47, 0xD0, 0xFE, 0x69, 0xFF, 0x68, 0x46, 0xD1, 0x1A, 0x8D, 0xA3, 0x34, - 0x18, 0x8F, 0xA1, 0x36, 0xFD, 0x6A, 0x44, 0xD3, 0x45, 0xD2, 0xFC, 0x6B, - 0xA0, 0x37, 0x19, 0x8E, 0x41, 0xD6, 0xF8, 0x6F, 0xA4, 0x33, 0x1D, 0x8A, - 0x1C, 0x8B, 0xA5, 0x32, 0xF9, 0x6E, 0x40, 0xD7, 0xFB, 0x6C, 0x42, 0xD5, - 0x1E, 0x89, 0xA7, 0x30, 0xA6, 0x31, 0x1F, 0x88, 0x43, 0xD4, 0xFA, 0x6D, - 0xF3, 0x64, 0x4A, 0xDD, 0x16, 0x81, 0xAF, 0x38, 0xAE, 0x39, 0x17, 0x80, - 0x4B, 0xDC, 0xF2, 0x65, 0x49, 0xDE, 0xF0, 0x67, 0xAC, 0x3B, 0x15, 0x82, - 0x14, 0x83, 0xAD, 0x3A, 0xF1, 0x66, 0x48, 0xDF, 0x10, 0x87, 0xA9, 0x3E, - 0xF5, 0x62, 0x4C, 0xDB, 0x4D, 0xDA, 0xF4, 0x63, 0xA8, 0x3F, 0x11, 0x86, - 0xAA, 0x3D, 0x13, 0x84, 0x4F, 0xD8, 0xF6, 0x61, 0xF7, 0x60, 0x4E, 0xD9, - 0x12, 0x85, 0xAB, 0x3C }; - -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; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_vintmsk_offset(0), 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; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_vintmsk_offset(0), 0x2); -} - -static int -__adf_iov_putmsg(struct adf_accel_dev *accel_dev, - u32 msg, - u8 vf_nr, - bool is_notification) -{ - struct adf_accel_pci *pci_info = &accel_dev->accel_pci_dev; - struct adf_hw_device_data *hw_data = accel_dev->hw_device; - struct resource *pmisc_bar_addr = - pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)].virt_addr; - u32 val, pf2vf_offset; - u32 total_delay = 0, mdelay = ADF_IOV_MSG_ACK_DELAY_MS, - udelay = ADF_IOV_MSG_ACK_DELAY_US; - u32 local_in_use_mask, local_in_use_pattern; - u32 remote_in_use_mask, remote_in_use_pattern; - struct mutex *lock; /* lock preventing concurrent acces of CSR */ - u32 int_bit; - int ret = 0; - struct pfvf_stats *pfvf_counters = NULL; - - if (accel_dev->is_vf) { - pf2vf_offset = hw_data->get_pf2vf_offset(0); - lock = &accel_dev->u1.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; - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - } else { - pf2vf_offset = hw_data->get_pf2vf_offset(vf_nr); - lock = &accel_dev->u1.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; - pfvf_counters = &accel_dev->u1.pf.vf_info[vf_nr].pfvf_counters; - } - - mutex_lock(lock); - - /* Check if PF2VF CSR is in use by remote function */ - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - if ((val & remote_in_use_mask) == remote_in_use_pattern) { - device_printf(GET_DEV(accel_dev), - "PF2VF CSR in use by remote function\n"); - ret = EAGAIN; - pfvf_counters->busy++; - goto out; - } - - /* Attempt to get ownership of PF2VF CSR */ - msg &= ~local_in_use_mask; - msg |= local_in_use_pattern; - ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg | int_bit); - pfvf_counters->tx++; - - /* Wait for confirmation from remote func it received the message */ - do { - if (udelay < ADF_IOV_MSG_ACK_EXP_MAX_DELAY_US) { - usleep_range(udelay, udelay * 2); - udelay = udelay * 2; - total_delay = total_delay + udelay; - } else { - pause_ms("adfstop", mdelay); - total_delay = total_delay + (mdelay * 1000); - } - val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); - } while ((val & int_bit) && - (total_delay < ADF_IOV_MSG_ACK_LIN_MAX_DELAY_US)); - - if (val & int_bit) { - device_printf(GET_DEV(accel_dev), - "ACK not received from remote\n"); - pfvf_counters->no_ack++; - val &= ~int_bit; - ret = EIO; - } - - /* For fire-and-forget notifications, the receiver does not clear - * the in-use pattern. This is used to detect collisions. - */ - if (is_notification && (val & ~int_bit) != msg) { - /* Collision must have overwritten the message */ - device_printf(GET_DEV(accel_dev), - "Collision on notification\n"); - pfvf_counters->collision++; - ret = EAGAIN; - goto out; - } - - /* - * 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 ((val & local_in_use_mask) == local_in_use_pattern) - ADF_CSR_WR(pmisc_bar_addr, - pf2vf_offset, - val & ~local_in_use_mask); - -out: - mutex_unlock(lock); - return ret; -} - -static int -adf_iov_put(struct adf_accel_dev *accel_dev, - u32 msg, - u8 vf_nr, - bool is_notification) -{ - u32 count = 0, delay = ADF_IOV_MSG_RETRY_DELAY; - int ret; - struct pfvf_stats *pfvf_counters = NULL; - - if (accel_dev->is_vf) - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - else - pfvf_counters = &accel_dev->u1.pf.vf_info[vf_nr].pfvf_counters; - - do { - ret = __adf_iov_putmsg(accel_dev, msg, vf_nr, is_notification); - if (ret == EAGAIN) - pause_ms("adfstop", delay); - delay = delay * 2; - } while (ret == EAGAIN && ++count < ADF_IOV_MSG_MAX_RETRIES); - if (ret == EAGAIN) { - if (is_notification) - pfvf_counters->event_timeout++; - else - pfvf_counters->tx_timeout++; - } - - return ret; -} - -/** - * adf_iov_putmsg() - send PF2VF message - * @accel_dev: Pointer to acceleration device. - * @msg: Message to send - * @vf_nr: VF number to which the message will be sent - * - * Function sends a messge from the PF to a VF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) -{ - return adf_iov_put(accel_dev, msg, vf_nr, false); -} - -/** - * adf_iov_notify() - send PF2VF notification message - * @accel_dev: Pointer to acceleration device. - * @msg: Message to send - * @vf_nr: VF number to which the message will be sent - * - * Function sends a notification messge from the PF to a VF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_iov_notify(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) -{ - return adf_iov_put(accel_dev, msg, vf_nr, true); -} - -u8 -adf_pfvf_crc(u8 start_crc, u8 *buf, u8 len) -{ - u8 crc = start_crc; - - while (len-- > 0) - crc = pfvf_crc8_table[(crc ^ *buf++) & 0xff]; - - return crc; -} - -int -adf_iov_block_provider_register(u8 msg_type, - const adf_iov_block_provider provider) -{ - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - return -EINVAL; - } - if (pf2vf_message_providers[msg_type]) { - pr_err("QAT: Provider %ps already registered for message %d\n", - pf2vf_message_providers[msg_type], - msg_type); - return -EINVAL; - } - - pf2vf_message_providers[msg_type] = provider; - return 0; -} - -u8 -adf_iov_is_block_provider_registered(u8 msg_type) -{ - if (pf2vf_message_providers[msg_type]) - return 1; - else - return 0; -} - -int -adf_iov_block_provider_unregister(u8 msg_type, - const adf_iov_block_provider provider) -{ - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - return -EINVAL; - } - if (pf2vf_message_providers[msg_type] != provider) { - pr_err("QAT: Provider %ps not registered for message %d\n", - provider, - msg_type); - return -EINVAL; - } - - pf2vf_message_providers[msg_type] = NULL; - return 0; -} - -static int -adf_iov_block_get_data(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility, - bool crc) -{ - u8 *buffer; - u8 size; - u8 msg_ver; - u8 crc8; - - if (msg_type >= ARRAY_SIZE(pf2vf_message_providers)) { - pr_err("QAT: invalid message type %d for PF2VF provider\n", - msg_type); - *data = ADF_PF2VF_INVALID_BLOCK_TYPE; - return -EINVAL; - } - - if (!pf2vf_message_providers[msg_type]) { - pr_err("QAT: No registered provider for message %d\n", - msg_type); - *data = ADF_PF2VF_INVALID_BLOCK_TYPE; - return -EINVAL; - } - - if ((*pf2vf_message_providers[msg_type])( - accel_dev, &buffer, &size, &msg_ver, compatibility, byte_num)) { - pr_err("QAT: unknown error from provider for message %d\n", - msg_type); - *data = ADF_PF2VF_UNSPECIFIED_ERROR; - return -EINVAL; - } - - if ((msg_type <= ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE && - size > ADF_VF2PF_SMALL_PAYLOAD_SIZE) || - (msg_type <= ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE && - size > ADF_VF2PF_MEDIUM_PAYLOAD_SIZE) || - size > ADF_VF2PF_LARGE_PAYLOAD_SIZE) { - pr_err("QAT: Invalid size %d provided for message type %d\n", - size, - msg_type); - *data = ADF_PF2VF_PAYLOAD_TRUNCATED; - return -EINVAL; - } - - if ((!byte_num && crc) || byte_num >= size + ADF_VF2PF_BLOCK_DATA) { - pr_err("QAT: Invalid byte number %d for message %d\n", - byte_num, - msg_type); - *data = ADF_PF2VF_INVALID_BYTE_NUM_REQ; - return -EINVAL; - } - - if (crc) { - crc8 = adf_pfvf_crc(ADF_CRC8_INIT_VALUE, &msg_ver, 1); - crc8 = adf_pfvf_crc(crc8, &size, 1); - *data = adf_pfvf_crc(crc8, buffer, byte_num - 1); - } else { - if (byte_num == 0) - *data = msg_ver; - else if (byte_num == 1) - *data = size; - else - *data = buffer[byte_num - 2]; - } - - return 0; -} - -static int -adf_iov_block_get_byte(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility) -{ - return adf_iov_block_get_data( - accel_dev, msg_type, byte_num, data, compatibility, false); -} - -static int -adf_iov_block_get_crc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 byte_num, - u8 *data, - u8 compatibility) -{ - return adf_iov_block_get_data( - accel_dev, msg_type, byte_num, data, compatibility, true); -} - -int adf_iov_compatibility_check(struct adf_accel_dev *accel_dev, u8 compat_ver); - -void -adf_vf2pf_req_hndl(struct adf_accel_vf_info *vf_info) -{ - struct adf_accel_dev *accel_dev = vf_info->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]; - struct resource *pmisc_addr = pmisc->virt_addr; - u32 msg, resp = 0, vf_nr = vf_info->vf_nr; - u8 byte_num = 0; - u8 msg_type = 0; - u8 resp_type; - int res; - u8 data; - u8 compat = 0x0; - int vf_compat_ver = 0; - bool is_notification = false; - - /* Read message from the VF */ - msg = ADF_CSR_RD(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr)); - if (!(msg & ADF_VF2PF_INT)) { - device_printf(GET_DEV(accel_dev), - "Spurious VF2PF interrupt. msg %X. Ignored\n", - msg); - vf_info->pfvf_counters.spurious++; - goto out; - } - vf_info->pfvf_counters.rx++; - - if (!(msg & ADF_VF2PF_MSGORIGIN_SYSTEM)) { - /* Ignore legacy non-system (non-kernel) VF2PF messages */ - device_printf(GET_DEV(accel_dev), - "Ignored non-system message from VF%d (0x%x);\n", - vf_nr + 1, - msg); - /* - * To ack, clear the VF2PFINT bit. - * Because this must be a legacy message, the far side - * must clear the in-use pattern. - */ - msg &= ~(ADF_VF2PF_INT); - ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg); - - goto out; - } - - switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> ADF_VF2PF_MSGTYPE_SHIFT) { - case ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ: - - { - is_notification = false; - vf_compat_ver = msg >> ADF_VF2PF_COMPAT_VER_REQ_SHIFT; - vf_info->compat_ver = vf_compat_ver; - - resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_VERSION_RESP - << ADF_PF2VF_MSGTYPE_SHIFT) | - (ADF_PFVF_COMPATIBILITY_VERSION - << ADF_PF2VF_VERSION_RESP_VERS_SHIFT)); - - device_printf( - GET_DEV(accel_dev), - "Compatibility Version Request from VF%d vers=%u\n", - vf_nr + 1, - vf_info->compat_ver); - - if (vf_compat_ver < ADF_PFVF_COMPATIBILITY_VERSION) - compat = adf_iov_compatibility_check(accel_dev, - vf_compat_ver); - else if (vf_compat_ver == ADF_PFVF_COMPATIBILITY_VERSION) - compat = ADF_PF2VF_VF_COMPATIBLE; - else - compat = ADF_PF2VF_VF_COMPAT_UNKNOWN; - - resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - - if (compat == ADF_PF2VF_VF_INCOMPATIBLE) - device_printf(GET_DEV(accel_dev), - "VF%d and PF are incompatible.\n", - vf_nr + 1); - } break; - case ADF_VF2PF_MSGTYPE_VERSION_REQ: - device_printf(GET_DEV(accel_dev), - "Legacy VersionRequest received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = false; - - /* legacy driver, VF compat_ver is 0 */ - vf_info->compat_ver = 0; - - resp = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_VERSION_RESP - << ADF_PF2VF_MSGTYPE_SHIFT)); - - /* PF always newer than legacy VF */ - compat = - adf_iov_compatibility_check(accel_dev, vf_info->compat_ver); - resp |= compat << ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - - /* Set legacy major and minor version num */ - resp |= 1 << ADF_PF2VF_MAJORVERSION_SHIFT | - 1 << ADF_PF2VF_MINORVERSION_SHIFT; - - if (compat == ADF_PF2VF_VF_INCOMPATIBLE) - device_printf(GET_DEV(accel_dev), - "VF%d and PF are incompatible.\n", - vf_nr + 1); - break; - case ADF_VF2PF_MSGTYPE_INIT: { - device_printf(GET_DEV(accel_dev), - "Init message received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = true; - vf_info->init = true; - } break; - case ADF_VF2PF_MSGTYPE_SHUTDOWN: { - device_printf(GET_DEV(accel_dev), - "Shutdown message received from VF%d 0x%x\n", - vf_nr + 1, - msg); - is_notification = true; - vf_info->init = false; - } break; - case ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ: - case ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ: - case ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ: { - is_notification = false; - switch ((msg & ADF_VF2PF_MSGTYPE_MASK) >> - ADF_VF2PF_MSGTYPE_SHIFT) { - case ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_LARGE_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE; - break; - case ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_MEDIUM_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE; - break; - case ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ: - byte_num = - ((msg & ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_MASK) >> - ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT); - msg_type = - ((msg & ADF_VF2PF_SMALL_BLOCK_REQ_TYPE_MASK) >> - ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT); - msg_type += ADF_VF2PF_MIN_SMALL_MESSAGE_TYPE; - break; - } - - if (msg >> ADF_VF2PF_BLOCK_REQ_CRC_SHIFT) { - res = adf_iov_block_get_crc(accel_dev, - msg_type, - byte_num, - &data, - vf_info->compat_ver); - if (res) - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_ERROR; - else - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_CRC; - } else { - if (!byte_num) - vf_info->pfvf_counters.blk_tx++; - - res = adf_iov_block_get_byte(accel_dev, - msg_type, - byte_num, - &data, - vf_info->compat_ver); - if (res) - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_ERROR; - else - resp_type = ADF_PF2VF_BLOCK_RESP_TYPE_DATA; - } - resp = - (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_BLOCK_RESP << ADF_PF2VF_MSGTYPE_SHIFT) | - (resp_type << ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT) | - (data << ADF_PF2VF_BLOCK_RESP_DATA_SHIFT)); - } break; - default: - device_printf(GET_DEV(accel_dev), - "Unknown message from VF%d (0x%x);\n", - vf_nr + 1, - msg); - } - - /* To ack, clear the VF2PFINT bit and the in-use-by */ - msg &= ~ADF_VF2PF_INT; - /* - * Clear the in-use pattern if the sender won't do it. - * Because the compatibility version must be the first message - * exchanged between the VF and PF, the vf_info->compat_ver must be - * set at this time. - * The in-use pattern is not cleared for notifications so that - * it can be used for collision detection. - */ - if (vf_info->compat_ver >= ADF_PFVF_COMPATIBILITY_FAST_ACK && - !is_notification) - msg &= ~ADF_VF2PF_IN_USE_BY_VF_MASK; - ADF_CSR_WR(pmisc_addr, hw_data->get_pf2vf_offset(vf_nr), msg); - - if (resp && adf_iov_putmsg(accel_dev, resp, vf_nr)) - device_printf(GET_DEV(accel_dev), - "Failed to send response to VF\n"); - -out: - return; -} - -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)); - - int i, num_vfs = accel_dev->u1.pf.num_vfs; - for (i = 0, vf = accel_dev->u1.pf.vf_info; i < num_vfs; i++, vf++) { - if (vf->init && adf_iov_notify(accel_dev, msg, i)) - device_printf(GET_DEV(accel_dev), - "Failed to send restarting msg to VF%d\n", - i); - } -} - -void -adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev) -{ - struct adf_accel_vf_info *vf; - int i, num_vfs = accel_dev->u1.pf.num_vfs; - u32 msg = (ADF_PF2VF_MSGORIGIN_SYSTEM | - (ADF_PF2VF_MSGTYPE_FATAL_ERROR << ADF_PF2VF_MSGTYPE_SHIFT)); - - for (i = 0, vf = accel_dev->u1.pf.vf_info; i < num_vfs; i++, vf++) { - if (vf->init && adf_iov_notify(accel_dev, msg, i)) - device_printf( - GET_DEV(accel_dev), - "Failed to send fatal error msg 0x%x to VF%d\n", - msg, - i); - } -} - -int -adf_iov_register_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc) -{ - struct adf_accel_compat_manager *cm = accel_dev->cm; - int num = 0; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ENOMEM; - } - - for (num = 0; num < ADF_COMPAT_CHECKER_MAX; num++) { - if (cm->iov_compat_checkers[num]) { - if (cc == cm->iov_compat_checkers[num]) { - device_printf(GET_DEV(accel_dev), - "QAT: already registered\n"); - return EFAULT; - } - } else { - /* registering the new checker */ - cm->iov_compat_checkers[num] = cc; - break; - } - } - - if (num >= ADF_COMPAT_CHECKER_MAX) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility checkers are overflow.\n"); - return EFAULT; - } - - cm->num_chker = num; - return 0; -} - -int -adf_iov_unregister_compat_checker(struct adf_accel_dev *accel_dev, - const adf_iov_compat_checker_t cc) -{ - struct adf_accel_compat_manager *cm = accel_dev->cm; - int num = 0; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ENOMEM; - } - num = cm->num_chker - 1; - - if (num < 0) { - device_printf( - GET_DEV(accel_dev), - "QAT: Array 'iov_compat_checkers' may use index value(s) -1\n"); - return EFAULT; - } - if (cc == cm->iov_compat_checkers[num]) { - /* unregistering the given checker */ - cm->iov_compat_checkers[num] = NULL; - } else { - device_printf( - GET_DEV(accel_dev), - "QAT: unregistering not in the registered order\n"); - return EFAULT; - } - - cm->num_chker--; - return 0; -} - -int -adf_iov_init_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm) -{ - if (!(*cm)) { - *cm = malloc(sizeof(**cm), M_QAT, M_WAITOK | M_ZERO); - } else { - /* zero the struct */ - explicit_bzero(*cm, sizeof(**cm)); - } - - return 0; -} - -int -adf_iov_shutdown_compat_manager(struct adf_accel_dev *accel_dev, - struct adf_accel_compat_manager **cm) -{ - if (*cm) { - free(*cm, M_QAT); - *cm = NULL; - } - return 0; -} - -int -adf_iov_compatibility_check(struct adf_accel_dev *accel_dev, u8 compat_ver) -{ - int compatible = ADF_PF2VF_VF_COMPATIBLE; - int i = 0; - struct adf_accel_compat_manager *cm = accel_dev->cm; - - if (!cm) { - device_printf(GET_DEV(accel_dev), - "QAT: compatibility manager not initialized\n"); - return ADF_PF2VF_VF_INCOMPATIBLE; - } - for (i = 0; i < cm->num_chker; i++) { - compatible = cm->iov_compat_checkers[i](accel_dev, compat_ver); - if (compatible == ADF_PF2VF_VF_INCOMPATIBLE) { - device_printf( - GET_DEV(accel_dev), - "QAT: PF and VF are incompatible [checker%d]\n", - i); - break; - } - } - return compatible; -} - -static int -adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) -{ - unsigned long timeout = msecs_to_jiffies(ADF_IOV_MSG_RESP_TIMEOUT); - u32 msg = 0; - int ret = 0; - int comp = 0; - int response_received = 0; - int retry_count = 0; - struct pfvf_stats *pfvf_counters = NULL; - - pfvf_counters = &accel_dev->u1.vf.pfvf_counters; - - msg = ADF_VF2PF_MSGORIGIN_SYSTEM; - msg |= ADF_VF2PF_MSGTYPE_COMPAT_VER_REQ << ADF_VF2PF_MSGTYPE_SHIFT; - msg |= ADF_PFVF_COMPATIBILITY_VERSION << ADF_VF2PF_COMPAT_VER_REQ_SHIFT; - BUILD_BUG_ON(ADF_PFVF_COMPATIBILITY_VERSION > 255); - /* Clear communication flag - without that VF will not be waiting for - * the response from host driver, and start sending init. - */ - accel_dev->u1.vf.iov_msg_completion = 0; - do { - /* Send request from VF to PF */ - if (retry_count) - pfvf_counters->retry++; - if (adf_iov_putmsg(accel_dev, msg, 0)) { - device_printf( - GET_DEV(accel_dev), - "Failed to send Compat Version Request.\n"); - return EIO; - } - mutex_lock(&accel_dev->u1.vf.vf2pf_lock); - if (accel_dev->u1.vf.iov_msg_completion == 0 && - sx_sleep(&accel_dev->u1.vf.iov_msg_completion, - &accel_dev->u1.vf.vf2pf_lock.sx, - 0, - "pfver", - timeout) == EWOULDBLOCK) { - /* It's possible that wakeup could be missed */ - if (accel_dev->u1.vf.iov_msg_completion) { - response_received = 1; - } else { - device_printf( - GET_DEV(accel_dev), - "IOV request/response message timeout expired\n"); - } - } else { - response_received = 1; - } - mutex_unlock(&accel_dev->u1.vf.vf2pf_lock); - } while (!response_received && - ++retry_count < ADF_IOV_MSG_RESP_RETRIES); - - if (!response_received) - pfvf_counters->rx_timeout++; - else - pfvf_counters->rx_rsp++; - if (!response_received) - return EIO; - - if (accel_dev->u1.vf.compatible == ADF_PF2VF_VF_COMPAT_UNKNOWN) - /* Response from PF received, check compatibility */ - comp = adf_iov_compatibility_check(accel_dev, - accel_dev->u1.vf.pf_version); - else - comp = accel_dev->u1.vf.compatible; - - ret = (comp == ADF_PF2VF_VF_COMPATIBLE) ? 0 : EFAULT; - if (ret) - device_printf( - GET_DEV(accel_dev), - "VF is not compatible with PF, due to the reason %d\n", - comp); - - return ret; -} - -/** - * adf_enable_vf2pf_comms() - Function enables communication from vf to pf - * - * @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) -{ - int ret = 0; - - /* init workqueue for VF */ - ret = adf_init_vf_wq(); - if (ret) - return ret; - - adf_enable_pf2vf_interrupts(accel_dev); - adf_iov_init_compat_manager(accel_dev, &accel_dev->cm); - return adf_vf2pf_request_version(accel_dev); -} -/** - * adf_disable_vf2pf_comms() - Function disables communication from vf to pf - * - * @accel_dev: Pointer to acceleration device virtual function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - return adf_iov_shutdown_compat_manager(accel_dev, &accel_dev->cm); -} - -/** - * adf_pf_enable_vf2pf_comms() - Function enables communication from pf - * - * @accel_dev: Pointer to acceleration device physical function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - adf_iov_init_compat_manager(accel_dev, &accel_dev->cm); - return 0; -} - -/** - * adf_pf_disable_vf2pf_comms() - Function disables communication from pf - * - * @accel_dev: Pointer to acceleration device physical function. - * - * Return: 0 on success, error code otherwise. - */ -int -adf_pf_disable_vf2pf_comms(struct adf_accel_dev *accel_dev) -{ - return adf_iov_shutdown_compat_manager(accel_dev, &accel_dev->cm); -} diff --git a/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c b/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c deleted file mode 100644 --- a/sys/dev/qat/qat_common/adf_pf2vf_ring_to_svc_map.c +++ /dev/null @@ -1,74 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" -#include "adf_cfg.h" - -#define ADF_VF2PF_RING_TO_SVC_VERSION 1 -#define ADF_VF2PF_RING_TO_SVC_LENGTH 2 - -int -adf_pf_ring_to_svc_msg_provider(struct adf_accel_dev *accel_dev, - u8 **buffer, - u8 *length, - u8 *block_version, - u8 compatibility, - u8 byte_num) -{ - static u8 data[ADF_VF2PF_RING_TO_SVC_LENGTH] = { 0 }; - struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev); - u16 ring_to_svc_map = hw_data->ring_to_svc_map; - u16 byte = 0; - - for (byte = 0; byte < ADF_VF2PF_RING_TO_SVC_LENGTH; byte++) { - data[byte] = (ring_to_svc_map >> (byte * ADF_PFVF_DATA_SHIFT)) & - ADF_PFVF_DATA_MASK; - } - - *length = ADF_VF2PF_RING_TO_SVC_LENGTH; - *block_version = ADF_VF2PF_RING_TO_SVC_VERSION; - *buffer = data; - - return 0; -} - -int -adf_pf_vf_ring_to_svc_init(struct adf_accel_dev *accel_dev) -{ - u8 data[ADF_VF2PF_RING_TO_SVC_LENGTH] = { 0 }; - u8 len = ADF_VF2PF_RING_TO_SVC_LENGTH; - u8 version = ADF_VF2PF_RING_TO_SVC_VERSION; - u16 ring_to_svc_map = 0; - u16 byte = 0; - - if (!accel_dev->is_vf) { - /* on the pf */ - if (!adf_iov_is_block_provider_registered( - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ)) - adf_iov_block_provider_register( - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ, - adf_pf_ring_to_svc_msg_provider); - } else if (accel_dev->u1.vf.pf_version >= - ADF_PFVF_COMPATIBILITY_RING_TO_SVC_MAP) { - /* on the vf */ - if (adf_iov_block_get(accel_dev, - ADF_VF2PF_BLOCK_MSG_GET_RING_TO_SVC_REQ, - &version, - data, - &len)) { - device_printf(GET_DEV(accel_dev), - "QAT: Failed adf_iov_block_get\n"); - return EFAULT; - } - for (byte = 0; byte < ADF_VF2PF_RING_TO_SVC_LENGTH; byte++) { - ring_to_svc_map |= data[byte] - << (byte * ADF_PFVF_DATA_SHIFT); - } - GET_HW_DATA(accel_dev)->ring_to_svc_map = ring_to_svc_map; - } - - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_pfvf_utils.c b/sys/dev/qat/qat_common/adf_pfvf_utils.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_utils.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include "adf_accel_devices.h" +#include "adf_pfvf_msg.h" +#include "adf_pfvf_utils.h" + +/* CRC Calculation */ +#define ADF_CRC8_INIT_VALUE 0xFF + +static const unsigned char pfvf_crc8_table[] = + { 0x00, 0x97, 0xB9, 0x2E, 0xE5, 0x72, 0x5C, 0xCB, 0x5D, 0xCA, 0xE4, 0x73, + 0xB8, 0x2F, 0x01, 0x96, 0xBA, 0x2D, 0x03, 0x94, 0x5F, 0xC8, 0xE6, 0x71, + 0xE7, 0x70, 0x5E, 0xC9, 0x02, 0x95, 0xBB, 0x2C, 0xE3, 0x74, 0x5A, 0xCD, + 0x06, 0x91, 0xBF, 0x28, 0xBE, 0x29, 0x07, 0x90, 0x5B, 0xCC, 0xE2, 0x75, + 0x59, 0xCE, 0xE0, 0x77, 0xBC, 0x2B, 0x05, 0x92, 0x04, 0x93, 0xBD, 0x2A, + 0xE1, 0x76, 0x58, 0xCF, 0x51, 0xC6, 0xE8, 0x7F, 0xB4, 0x23, 0x0D, 0x9A, + 0x0C, 0x9B, 0xB5, 0x22, 0xE9, 0x7E, 0x50, 0xC7, 0xEB, 0x7C, 0x52, 0xC5, + 0x0E, 0x99, 0xB7, 0x20, 0xB6, 0x21, 0x0F, 0x98, 0x53, 0xC4, 0xEA, 0x7D, + 0xB2, 0x25, 0x0B, 0x9C, 0x57, 0xC0, 0xEE, 0x79, 0xEF, 0x78, 0x56, 0xC1, + 0x0A, 0x9D, 0xB3, 0x24, 0x08, 0x9F, 0xB1, 0x26, 0xED, 0x7A, 0x54, 0xC3, + 0x55, 0xC2, 0xEC, 0x7B, 0xB0, 0x27, 0x09, 0x9E, 0xA2, 0x35, 0x1B, 0x8C, + 0x47, 0xD0, 0xFE, 0x69, 0xFF, 0x68, 0x46, 0xD1, 0x1A, 0x8D, 0xA3, 0x34, + 0x18, 0x8F, 0xA1, 0x36, 0xFD, 0x6A, 0x44, 0xD3, 0x45, 0xD2, 0xFC, 0x6B, + 0xA0, 0x37, 0x19, 0x8E, 0x41, 0xD6, 0xF8, 0x6F, 0xA4, 0x33, 0x1D, 0x8A, + 0x1C, 0x8B, 0xA5, 0x32, 0xF9, 0x6E, 0x40, 0xD7, 0xFB, 0x6C, 0x42, 0xD5, + 0x1E, 0x89, 0xA7, 0x30, 0xA6, 0x31, 0x1F, 0x88, 0x43, 0xD4, 0xFA, 0x6D, + 0xF3, 0x64, 0x4A, 0xDD, 0x16, 0x81, 0xAF, 0x38, 0xAE, 0x39, 0x17, 0x80, + 0x4B, 0xDC, 0xF2, 0x65, 0x49, 0xDE, 0xF0, 0x67, 0xAC, 0x3B, 0x15, 0x82, + 0x14, 0x83, 0xAD, 0x3A, 0xF1, 0x66, 0x48, 0xDF, 0x10, 0x87, 0xA9, 0x3E, + 0xF5, 0x62, 0x4C, 0xDB, 0x4D, 0xDA, 0xF4, 0x63, 0xA8, 0x3F, 0x11, 0x86, + 0xAA, 0x3D, 0x13, 0x84, 0x4F, 0xD8, 0xF6, 0x61, 0xF7, 0x60, 0x4E, 0xD9, + 0x12, 0x85, 0xAB, 0x3C }; + +static u8 +adf_pfvf_crc(u8 start_crc, u8 const *buf, u8 len) +{ + u8 crc = start_crc; + + while (len-- > 0) + crc = pfvf_crc8_table[(crc ^ *buf++) & 0xff]; + + return crc; +} + +u8 +adf_pfvf_calc_blkmsg_crc(u8 const *buf, u8 buf_len) +{ + return adf_pfvf_crc(ADF_CRC8_INIT_VALUE, buf, buf_len); +} + +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)) { + device_printf( + 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)) + device_printf(GET_DEV(accel_dev), + "Invalid PFVF msg with no type received\n"); + + return msg; +} diff --git a/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c b/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_vf_msg.c @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include "adf_accel_devices.h" +#include "adf_common_drv.h" +#include "adf_pfvf_msg.h" +#include "adf_pfvf_vf_msg.h" +#include "adf_pfvf_vf_proto.h" + +/** + * adf_vf2pf_notify_init() - send init msg to PF + * @accel_dev: Pointer to acceleration VF device. + * + * Function sends an init message from the VF to a PF + * + * Return: 0 on success, error code otherwise. + */ +int +adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_INIT }; + + if (adf_send_vf2pf_msg(accel_dev, msg)) { + device_printf(GET_DEV(accel_dev), + "Failed to send Init event to PF\n"); + return -EFAULT; + } + set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + return 0; +} + +/** + * adf_vf2pf_notify_shutdown() - send shutdown msg to PF + * @accel_dev: Pointer to acceleration VF device. + * + * Function sends a shutdown message from the VF to a PF + * + * Return: void + */ +void +adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev) +{ + 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)) + device_printf(GET_DEV(accel_dev), + "Failed to send Shutdown event to PF\n"); +} + +int +adf_vf2pf_request_version(struct adf_accel_dev *accel_dev) +{ + u8 pf_version; + int compat; + int ret; + 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); + + ret = adf_send_vf2pf_req(accel_dev, msg, &resp); + if (ret) { + device_printf( + GET_DEV(accel_dev), + "Failed to send Compatibility Version Request.\n"); + return ret; + } + + 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) { + case ADF_PF2VF_VF_COMPATIBLE: + break; + case ADF_PF2VF_VF_COMPAT_UNKNOWN: + /* VF is newer than PF - compatible for now */ + break; + case ADF_PF2VF_VF_INCOMPATIBLE: + device_printf( + GET_DEV(accel_dev), + "PF (vers %d) and VF (vers %d) are not compatible\n", + pf_version, + ADF_PFVF_COMPAT_THIS_VERSION); + return -EINVAL; + default: + device_printf( + GET_DEV(accel_dev), + "Invalid response from PF; assume not compatible\n"); + return -EINVAL; + } + + accel_dev->u1.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->u1.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)) { + device_printf(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 + device_printf(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 { + device_printf(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 { + device_printf( + GET_DEV(accel_dev), + "Capabilities message truncated to %d bytes\n", + len); + return -EFAULT; + } + } + + 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->u1.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)) { + device_printf(GET_DEV(accel_dev), + "QAT: Failed to get block message response\n"); + return -EFAULT; + } + + if (unlikely(len < sizeof(struct ring_to_svc_map_v1))) { + device_printf(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/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c b/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_common/adf_pfvf_vf_proto.c @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#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" + +#define __bf_shf(x) (__builtin_ffsll(x) - 1) + +#define FIELD_MAX(_mask) ({ (typeof(_mask))((_mask) >> __bf_shf(_mask)); }) + +#define FIELD_PREP(_mask, _val) \ + ({ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); }) + +#define FIELD_GET(_mask, _reg) \ + ({ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); }) + +/** + * adf_send_vf2pf_msg() - send VF to PF message + * @accel_dev: Pointer to acceleration device + * @msg: Message to send + * + * This function allows the VF to send a message to the PF. + * + * Return: 0 on success, error code otherwise. + */ +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_pf2vf_offset(0); + + int ret = pfvf_ops->send_msg(accel_dev, + msg, + pfvf_offset, + &accel_dev->u1.vf.vf2pf_lock); + return ret; +} + +/** + * adf_recv_pf2vf_msg() - receive a PF to VF message + * @accel_dev: Pointer to acceleration device + * + * This function allows the VF to receive a message from the PF. + * + * Return: a valid message on success, zero otherwise. + */ +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_vf2pf_offset(0); // 1008 + return pfvf_ops->recv_msg(accel_dev, + pfvf_offset, + accel_dev->u1.vf.pf_compat_ver); +} + +/** + * adf_send_vf2pf_req() - send VF2PF request message + * @accel_dev: Pointer to acceleration device. + * @msg: Request message to send + * @resp: Returned PF response + * + * This function sends a message that requires a response from the VF to the PF + * and waits for a reply. + * + * Return: 0 on success, error code otherwise. + */ +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->u1.vf.msg_received); + /* Send request from VF to PF */ + do { + ret = adf_send_vf2pf_msg(accel_dev, msg); + if (ret) { + device_printf(GET_DEV(accel_dev), + "Failed to send request msg to PF\n"); + return ret; + } + + /* Wait for response, if it times out retry */ + ret = + wait_for_completion_timeout(&accel_dev->u1.vf.msg_received, + timeout); + if (ret) { + if (likely(resp)) + *resp = accel_dev->u1.vf.response; + + /* Once copied, set to an invalid value */ + accel_dev->u1.vf.response.type = 0; + + return 0; + } + + device_printf(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, + 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 { + device_printf(GET_DEV(accel_dev), + "Invalid message type %u\n", + *type); + return -EINVAL; + } + + /* Sanity check */ + if (*data > max_data) { + device_printf(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)) { + device_printf(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)) { + device_printf( + 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)) { + device_printf(GET_DEV(accel_dev), + "Invalid block message type %d\n", + type); + return -EINVAL; + } + + if (unlikely(*buffer_len < ADF_PFVF_BLKMSG_HEADER_SIZE)) { + device_printf(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])) { + device_printf(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])) { + device_printf(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)) { + device_printf( + 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) +{ + switch (msg.type) { + case ADF_PF2VF_MSGTYPE_RESTARTING: + adf_pf2vf_handle_pf_restarting(accel_dev); + return false; + case ADF_PF2VF_MSGTYPE_RP_RESET_RESP: + adf_pf2vf_handle_pf_rp_reset(accel_dev, msg); + return true; + case ADF_PF2VF_MSGTYPE_VERSION_RESP: + case ADF_PF2VF_MSGTYPE_BLKMSG_RESP: + accel_dev->u1.vf.response = msg; + complete(&accel_dev->u1.vf.msg_received); + return true; + default: + device_printf( + GET_DEV(accel_dev), + "Unknown message from PF (type 0x%.4x, data: 0x%.4x)\n", + msg.type, + msg.data); + } + + return false; +} + +bool +adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev) +{ + struct pfvf_message msg; + + msg = adf_recv_pf2vf_msg(accel_dev); + 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; +} + +/** + * adf_enable_vf2pf_comms() - Function enables communication from vf to pf + * + * @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) +{ + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + int ret; + + hw_data->enable_pf2vf_interrupt(accel_dev); + + ret = adf_vf2pf_request_version(accel_dev); + if (ret) + return ret; + + ret = adf_vf2pf_get_capabilities(accel_dev); + if (ret) + return ret; + + ret = adf_vf2pf_get_ring_to_svc(accel_dev); + return ret; +} diff --git a/sys/dev/qat/qat_common/adf_transport.c b/sys/dev/qat/qat_common/adf_transport.c --- a/sys/dev/qat/qat_common/adf_transport.c +++ b/sys/dev/qat/qat_common/adf_transport.c @@ -74,6 +74,10 @@ adf_enable_ring_irq(struct adf_etr_bank_data *bank, u32 ring) { struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev); + u32 enable_int_col_mask = 0; + + if (csr_ops->get_int_col_ctl_enable_mask) + enable_int_col_mask = csr_ops->get_int_col_ctl_enable_mask(); mtx_lock(&bank->lock); bank->irq_mask |= (1 << ring); @@ -83,7 +87,8 @@ bank->irq_mask); csr_ops->write_csr_int_col_ctl(bank->csr_addr, bank->bank_number, - bank->irq_coalesc_timer); + bank->irq_coalesc_timer | + enable_int_col_mask); } static void @@ -142,9 +147,10 @@ ring->callback((u32 *)msg); atomic_dec(ring->inflights); *msg = ADF_RING_EMPTY_SIG; - ring->head = adf_modulo(ring->head + ADF_MSG_SIZE_TO_BYTES( - ring->msg_size), - ADF_RING_SIZE_MODULO(ring->ring_size)); + ring->head = + adf_modulo(ring->head + + ADF_MSG_SIZE_TO_BYTES(ring->msg_size), + ADF_RING_SIZE_MODULO(ring->ring_size)); msg_counter++; msg = (u32 *)((uintptr_t)ring->base_addr + ring->head); } diff --git a/sys/dev/qat/qat_common/adf_vf2pf_msg.c b/sys/dev/qat/qat_common/adf_vf2pf_msg.c deleted file mode 100644 --- a/sys/dev/qat/qat_common/adf_vf2pf_msg.c +++ /dev/null @@ -1,275 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007-2022 Intel Corporation */ -/* $FreeBSD$ */ -#include "adf_accel_devices.h" -#include "adf_common_drv.h" -#include "adf_pf2vf_msg.h" - -/** - * adf_vf2pf_init() - send init msg to PF - * @accel_dev: Pointer to acceleration VF device. - * - * Function sends an init messge from the VF to a PF - * - * Return: 0 on success, error code otherwise. - */ -int -adf_vf2pf_init(struct adf_accel_dev *accel_dev) -{ - u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | - (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT)); - if (adf_iov_notify(accel_dev, msg, 0)) { - device_printf(GET_DEV(accel_dev), - "Failed to send Init event to PF\n"); - return -EFAULT; - } - set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - return 0; -} - -/** - * adf_vf2pf_shutdown() - send shutdown msg to PF - * @accel_dev: Pointer to acceleration VF device. - * - * Function sends a shutdown messge from the VF to a PF - * - * Return: void - */ -void -adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) -{ - u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | - (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT)); - mutex_init(&accel_dev->u1.vf.vf2pf_lock); - if (test_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status)) - if (adf_iov_notify(accel_dev, msg, 0)) - device_printf(GET_DEV(accel_dev), - "Failed to send Shutdown event to PF\n"); - mutex_destroy(&accel_dev->u1.vf.vf2pf_lock); -} - -static int -adf_iov_block_get_bc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *data, - int get_crc) -{ - u8 blk_type; - u32 msg; - unsigned long timeout = msecs_to_jiffies(ADF_IOV_MSG_RESP_TIMEOUT); - int response_received = 0; - int retry_count = 0; - - msg = ADF_VF2PF_MSGORIGIN_SYSTEM; - if (get_crc) - msg |= 1 << ADF_VF2PF_BLOCK_REQ_CRC_SHIFT; - - if (msg_type <= ADF_VF2PF_MAX_SMALL_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_SMALL_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_SMALL_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_SMALL_BLOCK_BYTE_NUM_SHIFT; - } else if (msg_type <= ADF_VF2PF_MAX_MEDIUM_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_MEDIUM_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_MEDIUM_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type - ADF_VF2PF_MIN_MEDIUM_MESSAGE_TYPE; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_MEDIUM_BLOCK_BYTE_NUM_SHIFT; - } else if (msg_type <= ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE) { - if (msg_index >= - ADF_VF2PF_LARGE_PAYLOAD_SIZE + ADF_VF2PF_BLOCK_DATA) { - device_printf( - GET_DEV(accel_dev), - "Invalid byte index %d for message type %d\n", - msg_index, - msg_type); - return -EINVAL; - } - msg |= ADF_VF2PF_MSGTYPE_GET_LARGE_BLOCK_REQ - << ADF_VF2PF_MSGTYPE_SHIFT; - blk_type = msg_type - ADF_VF2PF_MIN_LARGE_MESSAGE_TYPE; - msg |= blk_type << ADF_VF2PF_BLOCK_REQ_TYPE_SHIFT; - msg |= msg_index << ADF_VF2PF_LARGE_BLOCK_BYTE_NUM_SHIFT; - } else { - device_printf(GET_DEV(accel_dev), - "Invalid message type %d\n", - msg_type); - } - accel_dev->u1.vf.iov_msg_completion = 0; - do { - /* Send request from VF to PF */ - if (retry_count) - accel_dev->u1.vf.pfvf_counters.retry++; - if (adf_iov_putmsg(accel_dev, msg, 0)) { - device_printf(GET_DEV(accel_dev), - "Failed to send block request to PF\n"); - return EIO; - } - - /* Wait for response */ - mutex_lock(&accel_dev->u1.vf.vf2pf_lock); - if (accel_dev->u1.vf.iov_msg_completion == 0 && - sx_sleep(&accel_dev->u1.vf.iov_msg_completion, - &accel_dev->u1.vf.vf2pf_lock.sx, - 0, - "pfver", - timeout) == EWOULDBLOCK) { - /* It's possible that wakeup could be missed */ - if (accel_dev->u1.vf.iov_msg_completion) { - response_received = 1; - } else { - device_printf( - GET_DEV(accel_dev), - "IOV request/response message timeout expired\n"); - } - } else { - response_received = 1; - } - mutex_unlock(&accel_dev->u1.vf.vf2pf_lock); - } while (!response_received && - ++retry_count < ADF_IOV_MSG_RESP_RETRIES); - - if (!response_received) - accel_dev->u1.vf.pfvf_counters.rx_timeout++; - else - accel_dev->u1.vf.pfvf_counters.rx_rsp++; - - if (!response_received) - return EIO; - - if (accel_dev->u1.vf.pf2vf_block_resp_type != - (get_crc ? ADF_PF2VF_BLOCK_RESP_TYPE_CRC : - ADF_PF2VF_BLOCK_RESP_TYPE_DATA)) { - device_printf( - GET_DEV(accel_dev), - "%sBlock response type %d, data %d, msg %d, index %d\n", - get_crc ? "CRC " : "", - accel_dev->u1.vf.pf2vf_block_resp_type, - accel_dev->u1.vf.pf2vf_block_byte, - msg_type, - msg_index); - return -EIO; - } - *data = accel_dev->u1.vf.pf2vf_block_byte; - return 0; -} - -static int -adf_iov_block_get_byte(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *data) -{ - return adf_iov_block_get_bc(accel_dev, msg_type, msg_index, data, 0); -} - -static int -adf_iov_block_get_crc(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 msg_index, - u8 *crc) -{ - return adf_iov_block_get_bc(accel_dev, msg_type, msg_index - 1, crc, 1); -} - -int -adf_iov_block_get(struct adf_accel_dev *accel_dev, - u8 msg_type, - u8 *block_version, - u8 *buffer, - u8 *length) -{ - u8 buf_size = *length; - u8 payload_len; - u8 remote_crc; - u8 local_crc; - u8 buf_index; - int ret; - - if (msg_type > ADF_VF2PF_MAX_LARGE_MESSAGE_TYPE) { - device_printf(GET_DEV(accel_dev), - "Invalid message type %d\n", - msg_type); - return -EINVAL; - } - - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - ADF_VF2PF_BLOCK_VERSION_BYTE, - block_version); - if (ret) - return ret; - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - ADF_VF2PF_BLOCK_LEN_BYTE, - length); - - if (ret) - return ret; - - payload_len = *length; - - if (buf_size < payload_len) { - device_printf( - GET_DEV(accel_dev), - "Truncating block type %d response from %d to %d bytes\n", - msg_type, - payload_len, - buf_size); - payload_len = buf_size; - } - - /* Get the data */ - for (buf_index = 0; buf_index < payload_len; buf_index++) { - ret = adf_iov_block_get_byte(accel_dev, - msg_type, - buf_index + ADF_VF2PF_BLOCK_DATA, - buffer + buf_index); - if (ret) - return ret; - } - - ret = adf_iov_block_get_crc(accel_dev, - msg_type, - payload_len + ADF_VF2PF_BLOCK_DATA, - &remote_crc); - if (ret) - return ret; - local_crc = adf_pfvf_crc(ADF_CRC8_INIT_VALUE, block_version, 1); - local_crc = adf_pfvf_crc(local_crc, length, 1); - local_crc = adf_pfvf_crc(local_crc, buffer, payload_len); - if (local_crc != remote_crc) { - device_printf( - GET_DEV(accel_dev), - "CRC error on msg type %d. Local %02X, remote %02X\n", - msg_type, - local_crc, - remote_crc); - accel_dev->u1.vf.pfvf_counters.crc_err++; - return EIO; - } - - accel_dev->u1.vf.pfvf_counters.blk_rx++; - *length = payload_len; - return 0; -} diff --git a/sys/dev/qat/qat_common/adf_vf_isr.c b/sys/dev/qat/qat_common/adf_vf_isr.c --- a/sys/dev/qat/qat_common/adf_vf_isr.c +++ b/sys/dev/qat/qat_common/adf_vf_isr.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -16,19 +17,17 @@ #include "adf_cfg_common.h" #include "adf_transport_access_macros.h" #include "adf_transport_internal.h" -#include "adf_pf2vf_msg.h" - -#define ADF_VINTSOU_BUN BIT(0) -#define ADF_VINTSOU_PF2VF BIT(1) +#include "adf_pfvf_utils.h" static TASKQUEUE_DEFINE_THREAD(qat_vf); +static TASKQUEUE_DEFINE_THREAD(qat_bank_handler); static struct workqueue_struct *adf_vf_stop_wq; static DEFINE_MUTEX(vf_stop_wq_lock); struct adf_vf_stop_data { struct adf_accel_dev *accel_dev; - struct work_struct vf_stop_work; + struct work_struct work; }; static int @@ -57,135 +56,84 @@ adf_dev_stop_async(struct work_struct *work) { struct adf_vf_stop_data *stop_data = - container_of(work, struct adf_vf_stop_data, vf_stop_work); + container_of(work, struct adf_vf_stop_data, work); struct adf_accel_dev *accel_dev = stop_data->accel_dev; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; adf_dev_restarting_notify(accel_dev); adf_dev_stop(accel_dev); adf_dev_shutdown(accel_dev); /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); + hw_data->enable_pf2vf_interrupt(accel_dev); kfree(stop_data); } -static void -adf_pf2vf_bh_handler(void *data, int pending) +int +adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev) { - struct adf_accel_dev *accel_dev = data; - 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)]; - struct resource *pmisc_bar_addr = pmisc->virt_addr; - u32 msg; - bool is_notification = false; - - /* Read the message from PF */ - msg = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_pf2vf_offset(0)); - if (!(msg & ADF_PF2VF_INT)) { - device_printf(GET_DEV(accel_dev), - "Spurious PF2VF interrupt. msg %X. Ignored\n", - msg); - accel_dev->u1.vf.pfvf_counters.spurious++; - goto out; - } - accel_dev->u1.vf.pfvf_counters.rx++; + struct adf_vf_stop_data *stop_data; - if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) { + clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); + stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); + if (!stop_data) { device_printf(GET_DEV(accel_dev), - "Ignore non-system PF2VF message(0x%x)\n", - msg); - /* - * To ack, clear the VF2PFINT bit. - * Because this must be a legacy message, the far side - * must clear the in-use pattern. - */ - msg &= ~ADF_PF2VF_INT; - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); - goto out; + "Couldn't schedule stop for vf_%d\n", + accel_dev->accel_id); + return -ENOMEM; } + stop_data->accel_dev = accel_dev; + INIT_WORK(&stop_data->work, adf_dev_stop_async); + queue_work(adf_vf_stop_wq, &stop_data->work); - switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) { - case ADF_PF2VF_MSGTYPE_RESTARTING: { - struct adf_vf_stop_data *stop_data; + return 0; +} - is_notification = true; +int +adf_pf2vf_handle_pf_rp_reset(struct adf_accel_dev *accel_dev, + struct pfvf_message msg) +{ + accel_dev->u1.vf.rpreset_sts = msg.data; + if (accel_dev->u1.vf.rpreset_sts == RPRESET_SUCCESS) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(success) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else if (accel_dev->u1.vf.rpreset_sts == RPRESET_NOT_SUPPORTED) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(not supported) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else if (accel_dev->u1.vf.rpreset_sts == RPRESET_INVAL_BANK) + device_printf( + GET_DEV(accel_dev), + "rpreset resp(invalid bank) from PF type:0x%x data:0x%x\n", + msg.type, + msg.data); + else + device_printf( + GET_DEV(accel_dev), + "rpreset resp(timeout) from PF type:0x%x data:0x%x\nn", + msg.type, + msg.data); + + complete(&accel_dev->u1.vf.msg_received); - device_printf(GET_DEV(accel_dev), - "Restarting msg received from PF 0x%x\n", - msg); - - clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); - if (!stop_data) { - device_printf(GET_DEV(accel_dev), - "Couldn't schedule stop for vf_%d\n", - accel_dev->accel_id); - goto out; - } - stop_data->accel_dev = accel_dev; - INIT_WORK(&stop_data->vf_stop_work, adf_dev_stop_async); - queue_work(adf_vf_stop_wq, &stop_data->vf_stop_work); - break; - } - case ADF_PF2VF_MSGTYPE_VERSION_RESP: - device_printf(GET_DEV(accel_dev), - "Version resp received from PF 0x%x\n", - msg); - is_notification = false; - accel_dev->u1.vf.pf_version = - (msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >> - ADF_PF2VF_VERSION_RESP_VERS_SHIFT; - accel_dev->u1.vf.compatible = - (msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >> - ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; - accel_dev->u1.vf.iov_msg_completion = 1; - wakeup(&accel_dev->u1.vf.iov_msg_completion); - break; - case ADF_PF2VF_MSGTYPE_BLOCK_RESP: - is_notification = false; - accel_dev->u1.vf.pf2vf_block_byte = - (msg & ADF_PF2VF_BLOCK_RESP_DATA_MASK) >> - ADF_PF2VF_BLOCK_RESP_DATA_SHIFT; - accel_dev->u1.vf.pf2vf_block_resp_type = - (msg & ADF_PF2VF_BLOCK_RESP_TYPE_MASK) >> - ADF_PF2VF_BLOCK_RESP_TYPE_SHIFT; - accel_dev->u1.vf.iov_msg_completion = 1; - wakeup(&accel_dev->u1.vf.iov_msg_completion); - break; - case ADF_PF2VF_MSGTYPE_FATAL_ERROR: - device_printf(GET_DEV(accel_dev), - "Fatal error received from PF 0x%x\n", - msg); - is_notification = true; - if (adf_notify_fatal_error(accel_dev)) - device_printf(GET_DEV(accel_dev), - "Couldn't notify fatal error\n"); - break; - default: - device_printf(GET_DEV(accel_dev), - "Unknown PF2VF message(0x%x)\n", - msg); - } + return 0; +} + +static void +adf_pf2vf_bh_handler(void *data, int pending) +{ + struct adf_accel_dev *accel_dev = data; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + if (adf_recv_and_handle_pf2vf_msg(accel_dev)) + /* Re-enable PF2VF interrupts */ + hw_data->enable_pf2vf_interrupt(accel_dev); - /* To ack, clear the PF2VFINT bit */ - msg &= ~ADF_PF2VF_INT; - /* - * Clear the in-use pattern if the sender won't do it. - * Because the compatibility version must be the first message - * exchanged between the VF and PF, the pf.version must be - * set at this time. - * The in-use pattern is not cleared for notifications so that - * it can be used for collision detection. - */ - if (accel_dev->u1.vf.pf_version >= ADF_PFVF_COMPATIBILITY_FAST_ACK && - !is_notification) - msg &= ~ADF_PF2VF_IN_USE_BY_PF_MASK; - ADF_CSR_WR(pmisc_bar_addr, hw_data->get_pf2vf_offset(0), msg); - -out: - /* Re-enable PF2VF interrupts */ - adf_enable_pf2vf_interrupts(accel_dev); return; } @@ -211,46 +159,86 @@ mutex_destroy(&accel_dev->u1.vf.vf2pf_lock); } +static void +adf_bh_handler(void *data, int pending) +{ + struct adf_etr_bank_data *bank = (void *)data; + + adf_response_handler((uintptr_t)bank); + + return; +} + +static int +adf_setup_bh(struct adf_accel_dev *accel_dev) +{ + int i = 0; + struct adf_etr_data *priv_data = accel_dev->transport; + + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + TASK_INIT(&priv_data->banks[i].resp_handler, + 0, + adf_bh_handler, + &priv_data->banks[i]); + } + + return 0; +} + +static void +adf_cleanup_bh(struct adf_accel_dev *accel_dev) +{ + int i = 0; + struct adf_etr_data *transport; + + if (!accel_dev || !accel_dev->transport) + return; + + transport = accel_dev->transport; + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + taskqueue_cancel(taskqueue_qat_bank_handler, + &transport->banks[i].resp_handler, + NULL); + taskqueue_drain(taskqueue_qat_bank_handler, + &transport->banks[i].resp_handler); + } +} + static void adf_isr(void *privdata) { struct adf_accel_dev *accel_dev = privdata; 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)]; - struct resource *pmisc_bar_addr = pmisc->virt_addr; - u32 v_int, v_mask; - int handled = 0; - - /* Read VF INT source CSR to determine the source of VF interrupt */ - v_int = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_vintsou_offset()); - v_mask = ADF_CSR_RD(pmisc_bar_addr, hw_data->get_vintmsk_offset(0)); + struct adf_hw_csr_ops *csr_ops = &hw_data->csr_info.csr_ops; + int int_active_bundles = 0; + int i = 0; /* Check for PF2VF interrupt */ - if ((v_int & ~v_mask) & ADF_VINTSOU_PF2VF) { + if (hw_data->interrupt_active_pf2vf(accel_dev)) { /* Disable PF to VF interrupt */ - adf_disable_pf2vf_interrupts(accel_dev); - + hw_data->disable_pf2vf_interrupt(accel_dev); /* Schedule tasklet to handle interrupt BH */ taskqueue_enqueue(taskqueue_qat_vf, &accel_dev->u1.vf.pf2vf_bh_tasklet); - handled = 1; } - if ((v_int & ~v_mask) & ADF_VINTSOU_BUN) { - struct adf_etr_data *etr_data = accel_dev->transport; - struct adf_etr_bank_data *bank = &etr_data->banks[0]; - - /* Disable Flag and Coalesce Ring Interrupts */ - WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, - bank->bank_number, - 0); - adf_response_handler((uintptr_t)&etr_data->banks[0]); - handled = 1; + if (hw_data->get_int_active_bundles) + int_active_bundles = hw_data->get_int_active_bundles(accel_dev); + + for (i = 0; i < GET_MAX_BANKS(accel_dev); i++) { + if (int_active_bundles & BIT(i)) { + struct adf_etr_data *etr_data = accel_dev->transport; + struct adf_etr_bank_data *bank = &etr_data->banks[i]; + + /* Disable Flag and Coalesce Ring Interrupts */ + csr_ops->write_csr_int_flag_and_col(bank->csr_addr, + bank->bank_number, + 0); + /* Schedule tasklet to handle interrupt BH */ + taskqueue_enqueue(taskqueue_qat_bank_handler, + &bank->resp_handler); + } } - - if (handled) - return; } static int @@ -259,6 +247,8 @@ device_t pdev = accel_to_pci_dev(accel_dev); int ret; int rid = 1; + int cpu; + accel_dev->u1.vf.irq = bus_alloc_resource_any(pdev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (accel_dev->u1.vf.irq == NULL) { @@ -272,24 +262,25 @@ adf_isr, accel_dev, &accel_dev->u1.vf.cookie); + if (ret) { + device_printf(GET_DEV(accel_dev), "failed to enable irq\n"); + goto errout; + } + + cpu = accel_dev->accel_id % num_online_cpus(); + ret = bus_bind_intr(pdev, accel_dev->u1.vf.irq, cpu); if (ret) { device_printf(GET_DEV(accel_dev), - "failed to enable irq for %s\n", - accel_dev->u1.vf.irq_name); - return ret; + "failed to bind IRQ handler to cpu core\n"); + goto errout; } - return ret; -} + accel_dev->u1.vf.irq_enabled = true; -static int -adf_setup_bh(struct adf_accel_dev *accel_dev) -{ - return 0; -} + return ret; +errout: + bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); -static void -adf_cleanup_bh(struct adf_accel_dev *accel_dev) -{ + return ret; } /** @@ -302,8 +293,13 @@ adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev) { device_t pdev = accel_to_pci_dev(accel_dev); - bus_teardown_intr(pdev, accel_dev->u1.vf.irq, accel_dev->u1.vf.cookie); - bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); + + if (accel_dev->u1.vf.irq_enabled) { + bus_teardown_intr(pdev, + accel_dev->u1.vf.irq, + accel_dev->u1.vf.cookie); + bus_free_resource(pdev, SYS_RES_IRQ, accel_dev->u1.vf.irq); + } adf_cleanup_bh(accel_dev); adf_cleanup_pf2vf_bh(accel_dev); adf_disable_msi(accel_dev); @@ -324,30 +320,39 @@ goto err_out; if (adf_setup_pf2vf_bh(accel_dev)) - goto err_out; + goto err_disable_msi; if (adf_setup_bh(accel_dev)) goto err_out; if (adf_request_msi_irq(accel_dev)) - goto err_out; + goto err_disable_msi; return 0; + +err_disable_msi: + adf_disable_msi(accel_dev); + err_out: - adf_vf_isr_resource_free(accel_dev); - return EFAULT; + return -EFAULT; } /** * adf_flush_vf_wq() - Flush workqueue for VF + * @accel_dev: Pointer to acceleration device. * - * Function flushes workqueue 'adf_vf_stop_wq' for VF. + * Function disables the PF/VF interrupts on the VF so that no new messages + * are received and flushes the workqueue 'adf_vf_stop_wq'. * * Return: void. */ void -adf_flush_vf_wq(void) +adf_flush_vf_wq(struct adf_accel_dev *accel_dev) { + struct adf_hw_device_data *hw_data = accel_dev->hw_device; + + hw_data->disable_pf2vf_interrupt(accel_dev); + if (adf_vf_stop_wq) flush_workqueue(adf_vf_stop_wq); } @@ -376,18 +381,11 @@ return ret; } -/** - * adf_exit_vf_wq() - Destroy workqueue for VF - * - * Function destroy workqueue 'adf_vf_stop_wq' for VF. - * - * Return: void. - */ void adf_exit_vf_wq(void) { - if (adf_vf_stop_wq) { + if (adf_vf_stop_wq) destroy_workqueue(adf_vf_stop_wq); - adf_vf_stop_wq = NULL; - } + + adf_vf_stop_wq = NULL; } diff --git a/sys/dev/qat/qat_common/qat_common_module.c b/sys/dev/qat/qat_common/qat_common_module.c --- a/sys/dev/qat/qat_common/qat_common_module.c +++ b/sys/dev/qat/qat_common/qat_common_module.c @@ -13,6 +13,9 @@ if (adf_init_fatal_error_wq()) return EFAULT; + if (adf_register_ctl_device_driver()) + return EFAULT; + return 0; } @@ -22,7 +25,7 @@ adf_exit_vf_wq(); adf_exit_aer(); adf_exit_fatal_error_wq(); - adf_clean_vf_map(false); + adf_unregister_ctl_device_driver(); } static int diff --git a/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c b/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c --- a/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_200xx/adf_200xx_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_200xx_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -143,18 +144,6 @@ *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_200XX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_200XX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -489,8 +478,6 @@ hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -509,11 +496,8 @@ hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->measure_clock = measure_clock; hw_data->get_ae_clock = get_ae_clock; hw_data->reset_device = adf_reset_flr; @@ -536,6 +520,7 @@ hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.h @@ -6,6 +6,9 @@ #include +#define DEFAULT_4XXX_ASYM_AE_MASK 0x03 +#define DEFAULT_401XX_ASYM_AE_MASK 0x3F + /* PCIe configuration space */ #define ADF_4XXX_SRAM_BAR 0 #define ADF_4XXX_PMISC_BAR 1 @@ -56,6 +59,7 @@ #define ADF_4XXX_ERRMSK3 (0x41A21C) #define ADF_4XXX_VFLNOTIFY BIT(7) +#define ADF_4XXX_DEF_ASYM_MASK 0x1 /* Arbiter configuration */ #define ADF_4XXX_ARB_CONFIG (BIT(31) | BIT(6) | BIT(0)) @@ -105,7 +109,7 @@ ICP_ACCEL_4XXX_MASK_SMX_SLICE = BIT(6), }; -void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data); +void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 id); void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data); #endif diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_4xxx_hw_data.c @@ -6,8 +6,10 @@ #include #include #include -#include +#include #include +#include +#include #include "adf_4xxx_hw_data.h" #include "adf_heartbeat.h" #include "icp_qat_fw_init_admin.h" @@ -85,17 +87,17 @@ u16 rng_to_svc_msk; }; -static struct adf_enabled_services adf_4xxx_svcs[] = { - { "dc", ADF_4XXX_DC }, - { "sym", ADF_4XXX_SYM }, - { "asym", ADF_4XXX_ASYM }, - { "dc;asym", ADF_4XXX_ASYM_DC }, - { "asym;dc", ADF_4XXX_ASYM_DC }, - { "sym;dc", ADF_4XXX_SYM_DC }, - { "dc;sym", ADF_4XXX_SYM_DC }, - { "asym;sym", ADF_4XXX_ASYM_SYM }, - { "sym;asym", ADF_4XXX_ASYM_SYM }, -}; +static struct adf_enabled_services adf_4xxx_svcs[] = + { { "dc", ADF_4XXX_DC }, + { "sym", ADF_4XXX_SYM }, + { "asym", ADF_4XXX_ASYM }, + { "dc;asym", ADF_4XXX_ASYM_DC }, + { "asym;dc", ADF_4XXX_ASYM_DC }, + { "sym;dc", ADF_4XXX_SYM_DC }, + { "dc;sym", ADF_4XXX_SYM_DC }, + { "asym;sym", ADF_4XXX_ASYM_SYM }, + { "sym;asym", ADF_4XXX_ASYM_SYM }, + { "cy", ADF_4XXX_ASYM_SYM } }; static struct adf_hw_device_class adf_4xxx_class = { .name = ADF_4XXX_DEVICE_NAME, @@ -117,6 +119,12 @@ return ~fusectl4 & ADF_4XXX_ACCELENGINES_MASK; } +static void +adf_set_asym_rings_mask(struct adf_accel_dev *accel_dev) +{ + accel_dev->hw_device->asym_rings_mask = ADF_4XXX_DEF_ASYM_MASK; +} + static int get_ring_to_svc_map(struct adf_accel_dev *accel_dev, u16 *ring_to_svc_map) { @@ -216,28 +224,45 @@ ICP_ACCEL_CAPABILITIES_COMPRESSION | ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION | ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION | - ICP_ACCEL_CAPABILITIES_HKDF | ICP_ACCEL_CAPABILITIES_SHA3_EXT | - ICP_ACCEL_CAPABILITIES_SM3 | ICP_ACCEL_CAPABILITIES_SM4 | - ICP_ACCEL_CAPABILITIES_CHACHA_POLY | - ICP_ACCEL_CAPABILITIES_AESGCM_SPC | - ICP_ACCEL_CAPABILITIES_AES_V2 | ICP_ACCEL_CAPABILITIES_RL; + ICP_ACCEL_CAPABILITIES_SHA3 | ICP_ACCEL_CAPABILITIES_HKDF | + ICP_ACCEL_CAPABILITIES_SHA3_EXT | ICP_ACCEL_CAPABILITIES_SM3 | + ICP_ACCEL_CAPABILITIES_SM4 | ICP_ACCEL_CAPABILITIES_CHACHA_POLY | + ICP_ACCEL_CAPABILITIES_AESGCM_SPC | ICP_ACCEL_CAPABILITIES_AES_V2 | + ICP_ACCEL_CAPABILITIES_RL | ICP_ACCEL_CAPABILITIES_ECEDMONT | + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; if (fusectl1 & ICP_ACCEL_4XXX_MASK_CIPHER_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_HKDF; capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; } - if (fusectl1 & ICP_ACCEL_4XXX_MASK_AUTH_SLICE) + 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_MASK_PKE_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + capabilities &= ~ICP_ACCEL_CAPABILITIES_ECEDMONT; + } if (fusectl1 & ICP_ACCEL_4XXX_MASK_COMPRESS_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_COMPRESSION; + capabilities &= ~ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION; + capabilities &= ~ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION; capabilities &= ~ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64; } if (fusectl1 & ICP_ACCEL_4XXX_MASK_SMX_SLICE) { capabilities &= ~ICP_ACCEL_CAPABILITIES_SM3; capabilities &= ~ICP_ACCEL_CAPABILITIES_SM4; } + 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; + } + return capabilities; } @@ -388,15 +413,18 @@ if (!*num_sym_au || !(service_mask & ADF_ACCEL_CRYPTO)) { disabled_caps = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC | ICP_ACCEL_CAPABILITIES_CIPHER | + ICP_ACCEL_CAPABILITIES_SHA3 | ICP_ACCEL_CAPABILITIES_SHA3_EXT | - ICP_ACCEL_CAPABILITIES_SM3 | ICP_ACCEL_CAPABILITIES_SM4 | + ICP_ACCEL_CAPABILITIES_HKDF | ICP_ACCEL_CAPABILITIES_SM3 | + ICP_ACCEL_CAPABILITIES_SM4 | ICP_ACCEL_CAPABILITIES_CHACHA_POLY | ICP_ACCEL_CAPABILITIES_AESGCM_SPC | - ICP_ACCEL_CAPABILITIES_AES_V2; + ICP_ACCEL_CAPABILITIES_AES_V2 | + ICP_ACCEL_CAPABILITIES_AUTHENTICATION; } if (!*num_asym_au || !(service_mask & ADF_ACCEL_ASYM)) { disabled_caps |= ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC | - ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + ICP_ACCEL_CAPABILITIES_ECEDMONT; } if (!*num_dc_au || !(service_mask & ADF_ACCEL_COMPRESSION)) { disabled_caps |= ICP_ACCEL_CAPABILITIES_COMPRESSION | @@ -771,6 +799,7 @@ u16 service_type; u32 service_mask; unsigned long thd_srv_mask = default_active_thd_mask; + struct adf_hw_device_data *hw_data = accel_dev->hw_device; ena_srv_mask = accel_dev->hw_device->ring_to_svc_map; /* If ring_to_svc_map is not changed, return default arbiter value */ @@ -798,6 +827,8 @@ if (au->services == ADF_ACCEL_COMPRESSION) thd_srv_mask = dc_me_active_thd_mask; + else if (au->services == ADF_ACCEL_ASYM) + thd_srv_mask = hw_data->asym_ae_active_thd_mask; else thd_srv_mask = default_active_thd_mask; @@ -901,7 +932,7 @@ } void -adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data) +adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 id) { hw_data->dev_class = &adf_4xxx_class; hw_data->instance_id = adf_4xxx_class.instances++; @@ -954,16 +985,28 @@ hw_data->set_msix_rttable = set_msix_default_rttable; hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer; hw_data->disable_iov = adf_disable_sriov; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->config_device = adf_config_device; - hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; + hw_data->set_asym_rings_mask = adf_set_asym_rings_mask; hw_data->get_hb_clock = get_hb_clock; + hw_data->int_timer_init = adf_int_timer_init; + hw_data->int_timer_exit = adf_int_timer_exit; hw_data->get_heartbeat_status = adf_get_heartbeat_status; hw_data->get_ae_clock = get_ae_clock; hw_data->measure_clock = measure_clock; hw_data->query_storage_cap = 1; + hw_data->ring_pair_reset = adf_gen4_ring_pair_reset; + + switch (id) { + case ADF_401XX_PCI_DEVICE_ID: + hw_data->asym_ae_active_thd_mask = DEFAULT_401XX_ASYM_AE_MASK; + break; + case ADF_4XXX_PCI_DEVICE_ID: + default: + hw_data->asym_ae_active_thd_mask = DEFAULT_4XXX_ASYM_AE_MASK; + } adf_gen4_init_hw_csr_info(&hw_data->csr_info); + adf_gen4_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c b/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c +++ b/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c @@ -91,12 +91,12 @@ int ret, rid; struct adf_cfg_device *cfg_dev = NULL; - /* Set pci MaxPayLoad to 256. Implemented to avoid the issue of + /* Set pci MaxPayLoad to 512. Implemented to avoid the issue of * Pci-passthrough causing Maxpayload to be reset to 128 bytes * when the device is reset. */ - if (pci_get_max_payload(dev) != 256) - pci_set_max_payload(dev, 256); + if (pci_get_max_payload(dev) != 512) + pci_set_max_payload(dev, 512); accel_dev = device_get_softc(dev); @@ -119,7 +119,7 @@ hw_data = malloc(sizeof(*hw_data), M_QAT_4XXX, M_WAITOK | M_ZERO); accel_dev->hw_device = hw_data; - adf_init_hw_data_4xxx(accel_dev->hw_device); + adf_init_hw_data_4xxx(accel_dev->hw_device, pci_get_device(dev)); accel_pci_dev->revid = pci_get_revid(dev); hw_data->fuses = pci_read_config(dev, ADF_4XXX_FUSECTL4_OFFSET, 4); if (accel_pci_dev->revid == 0x00) { @@ -154,7 +154,7 @@ if (ret) goto out_err; - pci_set_max_read_req(dev, 1024); + pci_set_max_read_req(dev, 4096); ret = bus_dma_tag_create(bus_get_dma_tag(dev), 1, diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#ifndef ADF_4XXXVF_HW_DATA_H_ +#define ADF_4XXXVF_HW_DATA_H_ + +#define ADF_4XXXIOV_PMISC_BAR 1 +#define ADF_4XXXIOV_ACCELERATORS_MASK 0x1 +#define ADF_4XXXIOV_ACCELENGINES_MASK 0x1 +#define ADF_4XXXIOV_MAX_ACCELERATORS 1 +#define ADF_4XXXIOV_MAX_ACCELENGINES 1 +#define ADF_4XXXIOV_NUM_RINGS_PER_BANK 2 +#define ADF_4XXXIOV_RX_RINGS_OFFSET 1 +#define ADF_4XXXIOV_TX_RINGS_MASK 0x1 +#define ADF_4XXXIOV_ETR_BAR 0 +#define ADF_4XXXIOV_ETR_MAX_BANKS 4 + +#define ADF_4XXXIOV_VINTSOU_OFFSET 0x0 +#define ADF_4XXXIOV_VINTMSK_OFFSET 0x4 +#define ADF_4XXXIOV_VINTSOUPF2VM_OFFSET 0x1000 +#define ADF_4XXXIOV_VINTMSKPF2VM_OFFSET 0x1004 +#define ADF_4XXX_DEF_ASYM_MASK 0x1 + +/* Virtual function fuses */ +#define ADF_4XXXIOV_VFFUSECTL0_OFFSET (0x40) +#define ADF_4XXXIOV_VFFUSECTL1_OFFSET (0x44) +#define ADF_4XXXIOV_VFFUSECTL2_OFFSET (0x4C) +#define ADF_4XXXIOV_VFFUSECTL4_OFFSET (0x1C4) +#define ADF_4XXXIOV_VFFUSECTL5_OFFSET (0x1C8) + +void adf_init_hw_data_4xxxiov(struct adf_hw_device_data *hw_data); +void adf_clean_hw_data_4xxxiov(struct adf_hw_device_data *hw_data); +u32 adf_4xxxvf_get_hw_cap(struct adf_accel_dev *accel_dev); +#endif diff --git a/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c new file mode 100644 --- /dev/null +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_4xxxvf_hw_data.c @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright(c) 2007-2022 Intel Corporation */ +/* $FreeBSD$ */ +#include +#include +#include +#include +#include +#include +#include "adf_4xxxvf_hw_data.h" +#include "icp_qat_hw.h" +#include "adf_transport_internal.h" +#include "adf_pfvf_vf_proto.h" + +static struct adf_hw_device_class adf_4xxxiov_class = + { .name = ADF_4XXXVF_DEVICE_NAME, .type = DEV_4XXXVF, .instances = 0 }; + +#define ADF_4XXXIOV_DEFAULT_RING_TO_SRV_MAP \ + (ASYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM_SYM ADF_4XXXIOV_DEFAULT_RING_TO_SRV_MAP + +#define ADF_4XXXIOV_DC \ + (COMP | COMP << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_SYM \ + (SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM \ + (ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + ASYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_ASYM_DC \ + (ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_SYM_DC \ + (SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +#define ADF_4XXXIOV_NA \ + (NA | NA << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \ + NA << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \ + NA << ADF_CFG_SERV_RING_PAIR_3_SHIFT) + +struct adf_enabled_services { + const char svcs_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; + u16 rng_to_svc_msk; +}; + +static struct adf_enabled_services adf_4xxxiov_svcs[] = + { { "dc", ADF_4XXXIOV_DC }, + { "sym", ADF_4XXXIOV_SYM }, + { "asym", ADF_4XXXIOV_ASYM }, + { "dc;asym", ADF_4XXXIOV_ASYM_DC }, + { "asym;dc", ADF_4XXXIOV_ASYM_DC }, + { "sym;dc", ADF_4XXXIOV_SYM_DC }, + { "dc;sym", ADF_4XXXIOV_SYM_DC }, + { "asym;sym", ADF_4XXXIOV_ASYM_SYM }, + { "sym;asym", ADF_4XXXIOV_ASYM_SYM }, + { "cy", ADF_4XXXIOV_ASYM_SYM } }; + +static u32 +get_accel_mask(struct adf_accel_dev *accel_dev) +{ + return ADF_4XXXIOV_ACCELERATORS_MASK; +} + +static u32 +get_ae_mask(struct adf_accel_dev *accel_dev) +{ + return ADF_4XXXIOV_ACCELENGINES_MASK; +} + +static u32 +get_num_accels(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_MAX_ACCELERATORS; +} + +static u32 +get_num_aes(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_MAX_ACCELENGINES; +} + +static u32 +get_misc_bar_id(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_PMISC_BAR; +} + +static u32 +get_etr_bar_id(struct adf_hw_device_data *self) +{ + return ADF_4XXXIOV_ETR_BAR; +} + +static u32 +get_clock_speed(struct adf_hw_device_data *self) +{ + /* CPP clock is half high-speed clock */ + return self->clock_frequency / 2; +} + +static enum dev_sku_info +get_sku(struct adf_hw_device_data *self) +{ + return DEV_SKU_VF; +} + +static int +adf_vf_int_noop(struct adf_accel_dev *accel_dev) +{ + return 0; +} + +static void +adf_vf_void_noop(struct adf_accel_dev *accel_dev) +{ +} + +u32 +adf_4xxxvf_get_hw_cap(struct adf_accel_dev *accel_dev) +{ + device_t pdev = accel_dev->accel_pci_dev.pci_dev; + u32 vffusectl1; + u32 capabilities; + + capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC + + ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC + + ICP_ACCEL_CAPABILITIES_CIPHER + + ICP_ACCEL_CAPABILITIES_AUTHENTICATION + + ICP_ACCEL_CAPABILITIES_COMPRESSION + + ICP_ACCEL_CAPABILITIES_SHA3_EXT + ICP_ACCEL_CAPABILITIES_SM2 + + ICP_ACCEL_CAPABILITIES_SM3 + ICP_ACCEL_CAPABILITIES_SM4 + + ICP_ACCEL_CAPABILITIES_CHACHA_POLY + + ICP_ACCEL_CAPABILITIES_AESGCM_SPC + + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64 + + ICP_ACCEL_CAPABILITIES_LZ4_COMPRESSION + + ICP_ACCEL_CAPABILITIES_LZ4S_COMPRESSION; + + /* Get fused capabilities */ + vffusectl1 = pci_read_config(pdev, ADF_4XXXIOV_VFFUSECTL1_OFFSET, 4); + + if (vffusectl1 & BIT(7)) { + capabilities &= + ~(ICP_ACCEL_CAPABILITIES_SM3 + ICP_ACCEL_CAPABILITIES_SM4); + } + if (vffusectl1 & BIT(6)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_SM3; + } + if (vffusectl1 & BIT(3)) { + capabilities &= ~(ICP_ACCEL_CAPABILITIES_COMPRESSION + + ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY64); + } + if (vffusectl1 & BIT(2)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC; + } + if (vffusectl1 & BIT(1)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_AUTHENTICATION; + } + if (vffusectl1 & BIT(0)) { + capabilities &= ~ICP_ACCEL_CAPABILITIES_CIPHER; + } + return capabilities; +} + +static void +adf_set_asym_rings_mask(struct adf_accel_dev *accel_dev) +{ + accel_dev->hw_device->asym_rings_mask = ADF_4XXX_DEF_ASYM_MASK; +} + +static void +enable_pf2vm_interrupt(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + ADF_CSR_WR(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET, 0x0); +} + +static void +disable_pf2vm_interrupt(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + ADF_CSR_WR(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET, BIT(0)); +} + +static int +interrupt_active_pf2vm(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + u32 v_sou, v_msk; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + v_sou = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTSOUPF2VM_OFFSET); + v_msk = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTMSKPF2VM_OFFSET); + + return ((v_sou & ~v_msk) & BIT(0)) ? 1 : 0; +} + +static int +get_int_active_bundles(struct adf_accel_dev *accel_dev) +{ + struct adf_hw_device_data *hw_data; + struct adf_bar *pmisc; + struct resource *pmisc_bar_addr; + u32 v_sou, v_msk; + + hw_data = accel_dev->hw_device; + pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)]; + pmisc_bar_addr = pmisc->virt_addr; + + v_sou = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTSOU_OFFSET); + v_msk = ADF_CSR_RD(pmisc_bar_addr, ADF_4XXXIOV_VINTMSK_OFFSET); + + return v_sou & ~v_msk & 0xF; +} + +static void +get_ring_svc_map_data(int ring_pair_index, + u16 ring_to_svc_map, + u8 *serv_type, + int *ring_index, + int *num_rings_per_srv, + int bank_num) +{ + *serv_type = + GET_SRV_TYPE(ring_to_svc_map, bank_num % ADF_CFG_NUM_SERVICES); + *ring_index = 0; + *num_rings_per_srv = ADF_4XXXIOV_NUM_RINGS_PER_BANK / 2; +} + +static int +get_ring_to_svc_map(struct adf_accel_dev *accel_dev, u16 *ring_to_svc_map) +{ + char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + char val[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; + u32 i = 0; + + /* Get the services enabled by user if provided. + * The function itself will also be called during the driver probe + * procedure where no ServicesEnable is provided. Then the device + * should still start with default configuration without + * ServicesEnable. Hence it still returns 0 when the + * adf_cfg_get_param_value() function returns failure. + */ + snprintf(key, sizeof(key), ADF_SERVICES_ENABLED); + if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val)) + return 0; + + for (i = 0; i < ARRAY_SIZE(adf_4xxxiov_svcs); i++) { + if (!strncmp(val, + adf_4xxxiov_svcs[i].svcs_enabled, + ADF_CFG_MAX_KEY_LEN_IN_BYTES)) { + *ring_to_svc_map = adf_4xxxiov_svcs[i].rng_to_svc_msk; + return 0; + } + } + + device_printf(GET_DEV(accel_dev), + "Invalid services enabled: %s\n", + val); + return EFAULT; +} + +static int +adf_4xxxvf_ring_pair_reset(struct adf_accel_dev *accel_dev, u32 bank_number) +{ + struct pfvf_message req = { 0 }; + unsigned long timeout = msecs_to_jiffies(ADF_PFVF_MSG_RESP_TIMEOUT); + int ret = 0; + + if (bank_number >= accel_dev->hw_device->num_banks) + return EINVAL; + + req.type = ADF_VF2PF_MSGTYPE_RP_RESET; + req.data = bank_number; + mutex_lock(&accel_dev->u1.vf.rpreset_lock); + init_completion(&accel_dev->u1.vf.msg_received); + accel_dev->u1.vf.rpreset_sts = RPRESET_SUCCESS; + if (adf_send_vf2pf_msg(accel_dev, req)) { + device_printf(GET_DEV(accel_dev), + "vf ring pair reset failure (vf2pf msg error)\n"); + ret = EFAULT; + goto out; + } + if (!wait_for_completion_timeout(&accel_dev->u1.vf.msg_received, + timeout)) { + device_printf( + GET_DEV(accel_dev), + "vf ring pair reset failure (pf2vf msg timeout)\n"); + ret = EFAULT; + goto out; + } + if (accel_dev->u1.vf.rpreset_sts != RPRESET_SUCCESS) { + device_printf( + GET_DEV(accel_dev), + "vf ring pair reset failure (pf reports error)\n"); + ret = EFAULT; + goto out; + } + +out: + mutex_unlock(&accel_dev->u1.vf.rpreset_lock); + return ret; +} + +void +adf_init_hw_data_4xxxiov(struct adf_hw_device_data *hw_data) +{ + hw_data->dev_class = &adf_4xxxiov_class; + hw_data->num_banks = ADF_4XXXIOV_ETR_MAX_BANKS; + hw_data->num_rings_per_bank = ADF_4XXXIOV_NUM_RINGS_PER_BANK; + hw_data->num_accel = ADF_4XXXIOV_MAX_ACCELERATORS; + hw_data->num_logical_accel = 1; + hw_data->num_engines = ADF_4XXXIOV_MAX_ACCELENGINES; + hw_data->tx_rx_gap = ADF_4XXXIOV_RX_RINGS_OFFSET; + hw_data->tx_rings_mask = ADF_4XXXIOV_TX_RINGS_MASK; + hw_data->ring_to_svc_map = ADF_4XXXIOV_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; + hw_data->init_admin_comms = adf_vf_int_noop; + hw_data->exit_admin_comms = adf_vf_void_noop; + hw_data->send_admin_init = adf_vf2pf_notify_init; + hw_data->init_arb = adf_vf_int_noop; + hw_data->exit_arb = adf_vf_void_noop; + hw_data->disable_iov = adf_vf2pf_notify_shutdown; + hw_data->get_accel_mask = get_accel_mask; + hw_data->get_ae_mask = get_ae_mask; + hw_data->get_num_accels = get_num_accels; + hw_data->get_num_aes = get_num_aes; + hw_data->get_etr_bar_id = get_etr_bar_id; + hw_data->get_misc_bar_id = get_misc_bar_id; + hw_data->get_clock_speed = get_clock_speed; + hw_data->get_sku = get_sku; + hw_data->enable_ints = adf_vf_void_noop; + hw_data->reset_device = adf_reset_flr; + hw_data->restore_device = adf_dev_restore; + hw_data->get_ring_svc_map_data = get_ring_svc_map_data; + hw_data->get_ring_to_svc_map = get_ring_to_svc_map; + hw_data->get_accel_cap = adf_4xxxvf_get_hw_cap; + hw_data->config_device = adf_config_device; + hw_data->set_asym_rings_mask = adf_set_asym_rings_mask; + hw_data->ring_pair_reset = adf_4xxxvf_ring_pair_reset; + hw_data->enable_pf2vf_interrupt = enable_pf2vm_interrupt; + hw_data->disable_pf2vf_interrupt = disable_pf2vm_interrupt; + hw_data->interrupt_active_pf2vf = interrupt_active_pf2vm; + hw_data->get_int_active_bundles = get_int_active_bundles; + hw_data->dev_class->instances++; + adf_devmgr_update_class_index(hw_data); + gen4vf_init_hw_csr_info(&hw_data->csr_info); + adf_gen4_init_vf_pfvf_ops(&hw_data->csr_info.pfvf_ops); +} + +void +adf_clean_hw_data_4xxxiov(struct adf_hw_device_data *hw_data) +{ + hw_data->dev_class->instances--; + adf_devmgr_update_class_index(hw_data); +} diff --git a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c copy from sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c copy to sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c --- a/sys/dev/qat/qat_hw/qat_4xxx/adf_drv.c +++ b/sys/dev/qat/qat_hw/qat_4xxxvf/adf_drv.c @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright(c) 2007 - 2022 Intel Corporation */ +/* Copyright(c) 2007-2022 Intel Corporation */ /* $FreeBSD$ */ #include "qat_freebsd.h" -#include "adf_cfg.h" -#include "adf_common_drv.h" -#include "adf_accel_devices.h" -#include "adf_4xxx_hw_data.h" +#include +#include +#include +#include "adf_4xxxvf_hw_data.h" #include "adf_gen4_hw_data.h" #include "adf_fw_counters.h" #include "adf_cfg_device.h" @@ -14,10 +14,8 @@ #include #include #include -#include "adf_heartbeat_dbg.h" -#include "adf_cnvnr_freq_counters.h" -static MALLOC_DEFINE(M_QAT_4XXX, "qat_4xxx", "qat_4xxx"); +static MALLOC_DEFINE(M_QAT_4XXXVF, "qat_4xxxvf", "qat_4xxxvf"); #define ADF_SYSTEM_DEVICE(device_id) \ { \ @@ -25,8 +23,8 @@ } static const struct pci_device_id adf_pci_tbl[] = - { ADF_SYSTEM_DEVICE(ADF_4XXX_PCI_DEVICE_ID), - ADF_SYSTEM_DEVICE(ADF_401XX_PCI_DEVICE_ID), + { ADF_SYSTEM_DEVICE(ADF_4XXXIOV_PCI_DEVICE_ID), + ADF_SYSTEM_DEVICE(ADF_401XXIOV_PCI_DEVICE_ID), { 0, } }; @@ -40,7 +38,7 @@ if (pci_get_vendor(dev) == id->vendor && pci_get_device(dev) == id->device) { device_set_desc(dev, - "Intel " ADF_4XXX_DEVICE_NAME + "Intel " ADF_4XXXVF_DEVICE_NAME " QuickAssist"); return BUS_PROBE_GENERIC; } @@ -52,10 +50,12 @@ adf_cleanup_accel(struct adf_accel_dev *accel_dev) { struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev; + struct adf_accel_dev *pf; int i; if (accel_dev->dma_tag) bus_dma_tag_destroy(accel_dev->dma_tag); + for (i = 0; i < ADF_PCI_MAX_BARS; i++) { struct adf_bar *bar = &accel_pci_dev->pci_bars[i]; @@ -65,40 +65,43 @@ bar->virt_addr); } + /* + * As adf_clean_hw_data_4xxxiov() will update class index, before + * index is updated, vf must be remove from accel_table. + */ + pf = adf_devmgr_pci_to_accel_dev(pci_find_pf(accel_pci_dev->pci_dev)); + adf_devmgr_rm_dev(accel_dev, pf); + if (accel_dev->hw_device) { switch (pci_get_device(accel_pci_dev->pci_dev)) { - case ADF_4XXX_PCI_DEVICE_ID: - case ADF_401XX_PCI_DEVICE_ID: - adf_clean_hw_data_4xxx(accel_dev->hw_device); + case ADF_4XXXIOV_PCI_DEVICE_ID: + case ADF_401XXIOV_PCI_DEVICE_ID: + adf_clean_hw_data_4xxxiov(accel_dev->hw_device); break; default: break; } - free(accel_dev->hw_device, M_QAT_4XXX); + free(accel_dev->hw_device, M_QAT_4XXXVF); accel_dev->hw_device = NULL; } adf_cfg_dev_remove(accel_dev); - adf_devmgr_rm_dev(accel_dev, NULL); } static int adf_attach(device_t dev) { struct adf_accel_dev *accel_dev; + struct adf_accel_dev *pf; struct adf_accel_pci *accel_pci_dev; struct adf_hw_device_data *hw_data; unsigned int i, bar_nr; - int ret, rid; + int ret = 0; + int rid; struct adf_cfg_device *cfg_dev = NULL; - /* Set pci MaxPayLoad to 256. Implemented to avoid the issue of - * Pci-passthrough causing Maxpayload to be reset to 128 bytes - * when the device is reset. - */ - if (pci_get_max_payload(dev) != 256) - pci_set_max_payload(dev, 256); - accel_dev = device_get_softc(dev); + accel_dev->is_vf = true; + pf = adf_devmgr_pci_to_accel_dev(pci_find_pf(dev)); INIT_LIST_HEAD(&accel_dev->crypto_list); accel_pci_dev = &accel_dev->accel_pci_dev; @@ -107,50 +110,33 @@ if (bus_get_domain(dev, &accel_pci_dev->node) != 0) accel_pci_dev->node = 0; - /* Add accel device to accel table. - * This should be called before adf_cleanup_accel is called - */ - if (adf_devmgr_add_dev(accel_dev, NULL)) { - device_printf(dev, "Failed to add new accelerator device.\n"); - return ENXIO; + /* Add accel device to accel table */ + if (adf_devmgr_add_dev(accel_dev, pf)) { + device_printf(GET_DEV(accel_dev), + "Failed to add new accelerator device.\n"); + return -EFAULT; } - /* Allocate and configure device configuration structure */ - hw_data = malloc(sizeof(*hw_data), M_QAT_4XXX, M_WAITOK | M_ZERO); + hw_data = malloc(sizeof(*hw_data), M_QAT_4XXXVF, M_WAITOK | M_ZERO); + if (!hw_data) { + ret = -ENOMEM; + goto out_err; + } accel_dev->hw_device = hw_data; - adf_init_hw_data_4xxx(accel_dev->hw_device); + adf_init_hw_data_4xxxiov(accel_dev->hw_device); accel_pci_dev->revid = pci_get_revid(dev); - hw_data->fuses = pci_read_config(dev, ADF_4XXX_FUSECTL4_OFFSET, 4); - if (accel_pci_dev->revid == 0x00) { - device_printf(dev, "A0 stepping is not supported.\n"); - ret = ENODEV; - goto out_err; - } - /* Get PPAERUCM values and store */ - ret = adf_aer_store_ppaerucm_reg(dev, hw_data); - if (ret) - goto out_err; + hw_data->fuses = pci_read_config(dev, ADF_4XXXIOV_VFFUSECTL4_OFFSET, 4); /* Get Accelerators and Accelerators Engines masks */ hw_data->accel_mask = hw_data->get_accel_mask(accel_dev); hw_data->ae_mask = hw_data->get_ae_mask(accel_dev); - + hw_data->admin_ae_mask = hw_data->ae_mask; accel_pci_dev->sku = hw_data->get_sku(hw_data); - /* If the device has no acceleration engines then ignore it. */ - if (!hw_data->accel_mask || !hw_data->ae_mask || - (~hw_data->ae_mask & 0x01)) { - device_printf(dev, "No acceleration units found\n"); - ret = ENXIO; - goto out_err; - } /* Create device configuration table */ ret = adf_cfg_dev_add(accel_dev); - if (ret) - goto out_err; - ret = adf_clock_debugfs_add(accel_dev); if (ret) goto out_err; @@ -170,13 +156,8 @@ NULL, NULL, &accel_dev->dma_tag); - if (ret) - goto out_err; - if (hw_data->get_accel_cap) { - hw_data->accel_capabilities_mask = - hw_data->get_accel_cap(accel_dev); - } + hw_data->accel_capabilities_mask = adf_4xxxvf_get_hw_cap(accel_dev); /* Find and map all the device's BARS */ i = 0; @@ -185,49 +166,64 @@ struct adf_bar *bar; rid = PCIR_BAR(bar_nr); - if (bus_get_resource(dev, SYS_RES_MEMORY, rid, NULL, NULL) != 0) + if (bus_get_resource(dev, SYS_RES_MEMORY, rid, NULL, NULL) != + 0) { continue; + } bar = &accel_pci_dev->pci_bars[i++]; bar->virt_addr = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!bar->virt_addr) { - device_printf(dev, "Failed to map BAR %d\n", bar_nr); + device_printf(GET_DEV(accel_dev), + "Failed to map BAR %d\n", + bar_nr); ret = ENXIO; goto out_err; } bar->base_addr = rman_get_start(bar->virt_addr); bar->size = rman_get_size(bar->virt_addr); } - pci_enable_busmaster(dev); - if (!accel_dev->hw_device->config_device) { - ret = EFAULT; + if (i == 0) { + device_printf( + GET_DEV(accel_dev), + "No BARs mapped. Please check if PCI BARs are mapped correctly for device\n"); + ret = ENXIO; goto out_err; } - ret = accel_dev->hw_device->config_device(accel_dev); + pci_enable_busmaster(dev); + + /* Completion for VF2PF request/response message exchange */ + init_completion(&accel_dev->u1.vf.msg_received); + mutex_init(&accel_dev->u1.vf.rpreset_lock); + + ret = hw_data->config_device(accel_dev); if (ret) goto out_err; ret = adf_dev_init(accel_dev); - if (ret) - goto out_dev_shutdown; - - ret = adf_dev_start(accel_dev); - if (ret) - goto out_dev_stop; + if (!ret) + ret = adf_dev_start(accel_dev); + + if (ret) { + device_printf( + GET_DEV(accel_dev), + "Failed to start - make sure PF enabled services match VF configuration.\n"); + adf_dev_stop(accel_dev); + adf_dev_shutdown(accel_dev); + return 0; + } cfg_dev = accel_dev->cfg->dev; adf_cfg_device_clear(cfg_dev, accel_dev); free(cfg_dev, M_QAT); accel_dev->cfg->dev = NULL; + return ret; -out_dev_stop: - adf_dev_stop(accel_dev); -out_dev_shutdown: - adf_dev_shutdown(accel_dev); + out_err: adf_cleanup_accel(accel_dev); return ret; @@ -238,18 +234,32 @@ { struct adf_accel_dev *accel_dev = device_get_softc(dev); - if (adf_dev_stop(accel_dev)) { - device_printf(dev, "Failed to stop QAT accel dev\n"); - return EBUSY; + if (!accel_dev) { + printf("QAT: Driver removal failed\n"); + return EFAULT; } + adf_flush_vf_wq(accel_dev); + clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); + adf_dev_stop(accel_dev); adf_dev_shutdown(accel_dev); - adf_cleanup_accel(accel_dev); - return 0; } +static int +adf_modevent(module_t mod, int type, void *data) +{ + + switch (type) { + case MOD_UNLOAD: + adf_clean_vf_map(true); + return 0; + default: + return EOPNOTSUPP; + } +} + static device_method_t adf_methods[] = { DEVMETHOD(device_probe, adf_probe), DEVMETHOD(device_attach, adf_attach), DEVMETHOD(device_detach, adf_detach), @@ -260,8 +270,13 @@ adf_methods, sizeof(struct adf_accel_dev) }; -DRIVER_MODULE_ORDERED(qat_4xxx, pci, adf_driver, NULL, NULL, SI_ORDER_THIRD); -MODULE_VERSION(qat_4xxx, 1); -MODULE_DEPEND(qat_4xxx, qat_common, 1, 1, 1); -MODULE_DEPEND(qat_4xxx, qat_api, 1, 1, 1); -MODULE_DEPEND(qat_4xxx, linuxkpi, 1, 1, 1); +DRIVER_MODULE_ORDERED(qat_4xxxvf, + pci, + adf_driver, + adf_modevent, + NULL, + SI_ORDER_THIRD); +MODULE_VERSION(qat_4xxxvf, 1); +MODULE_DEPEND(qat_4xxxvf, qat_common, 1, 1, 1); +MODULE_DEPEND(qat_4xxxvf, qat_api, 1, 1, 1); +MODULE_DEPEND(qat_4xxxvf, linuxkpi, 1, 1, 1); diff --git a/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c --- a/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c3xxx/adf_c3xxx_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_c3xxx_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -142,18 +143,6 @@ *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C3XXX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C3XXX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -362,8 +351,6 @@ hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -382,11 +369,8 @@ hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->measure_clock = measure_clock; hw_data->get_ae_clock = get_ae_clock; hw_data->reset_device = adf_reset_flr; @@ -410,6 +394,7 @@ hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c b/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c --- a/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c4xxx/adf_c4xxx_hw_data.c @@ -5,11 +5,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #include "adf_c4xxx_hw_data.h" #include "adf_c4xxx_reset.h" #include "adf_c4xxx_inline.h" @@ -608,18 +609,6 @@ } } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C4XXX_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C4XXX_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -2154,8 +2143,6 @@ hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -2180,11 +2167,8 @@ hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = c4xxx_set_ssm_wdtimer; hw_data->check_slice_hang = c4xxx_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->reset_device = adf_reset_flr; hw_data->restore_device = adf_c4xxx_dev_restore; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->init_accel_units = adf_init_accel_units; hw_data->reset_hw_units = adf_c4xxx_reset_hw_units; hw_data->exit_accel_units = adf_exit_accel_units; @@ -2210,6 +2194,7 @@ hw_data->set_asym_rings_mask = adf_cfg_set_asym_rings_mask; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); hw_data->csr_info.arb_enable_mask = 0xF; } diff --git a/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c b/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c --- a/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_c62x/adf_c62x_hw_data.c @@ -4,9 +4,10 @@ #include #include #include -#include +#include #include #include +#include #include "adf_c62x_hw_data.h" #include "icp_qat_hw.h" #include "adf_cfg.h" @@ -146,18 +147,6 @@ *arb_map_config = thrd_to_arb_map_gen; } -static u32 -get_pf2vf_offset(u32 i) -{ - return ADF_C62X_PF2VF_OFFSET(i); -} - -static u32 -get_vintmsk_offset(u32 i) -{ - return ADF_C62X_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -367,8 +356,6 @@ hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -387,11 +374,8 @@ hw_data->enable_ints = adf_enable_ints; hw_data->set_ssm_wdtimer = adf_set_ssm_wdtimer; hw_data->check_slice_hang = adf_check_slice_hang; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->restore_device = adf_dev_restore; hw_data->reset_device = adf_reset_flr; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->get_objs_num = get_objs_num; hw_data->get_obj_name = get_obj_name; hw_data->get_obj_cfg_ae_mask = get_obj_cfg_ae_mask; @@ -415,6 +399,7 @@ hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c b/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c --- a/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/sys/dev/qat/qat_hw/qat_dh895xcc/adf_dh895xcc_hw_data.c @@ -4,10 +4,11 @@ #include "qat_freebsd.h" #include "adf_cfg.h" #include -#include +#include #include #include #include +#include #include "adf_dh895xcc_hw_data.h" #include "icp_qat_hw.h" #include "adf_heartbeat.h" @@ -159,18 +160,6 @@ } } -static uint32_t -get_pf2vf_offset(uint32_t i) -{ - return ADF_DH895XCC_PF2VF_OFFSET(i); -} - -static uint32_t -get_vintmsk_offset(uint32_t i) -{ - return ADF_DH895XCC_VINTMSK_OFFSET(i); -} - static void get_arb_info(struct arb_info *arb_csrs_info) { @@ -354,8 +343,6 @@ hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id; - hw_data->get_pf2vf_offset = get_pf2vf_offset; - hw_data->get_vintmsk_offset = get_vintmsk_offset; hw_data->get_arb_info = get_arb_info; hw_data->get_admin_info = get_admin_info; hw_data->get_errsou_offset = get_errsou_offset; @@ -373,11 +360,8 @@ hw_data->exit_arb = adf_exit_arb; hw_data->get_arb_mapping = adf_get_arbiter_mapping; hw_data->enable_ints = adf_enable_ints; - hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms; - hw_data->disable_vf2pf_comms = adf_pf_disable_vf2pf_comms; hw_data->reset_device = adf_reset_sbr; hw_data->restore_device = adf_dev_restore; - hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; hw_data->get_accel_cap = dh895xcc_get_hw_cap; hw_data->get_heartbeat_status = adf_get_heartbeat_status; hw_data->get_ae_clock = get_ae_clock; @@ -400,6 +384,7 @@ hw_data->post_reset = adf_dev_post_reset; adf_gen2_init_hw_csr_info(&hw_data->csr_info); + adf_gen2_init_pf_pfvf_ops(&hw_data->csr_info.pfvf_ops); } void diff --git a/sys/modules/qat/qat_api/Makefile b/sys/modules/qat/qat_api/Makefile --- a/sys/modules/qat/qat_api/Makefile +++ b/sys/modules/qat/qat_api/Makefile @@ -13,6 +13,9 @@ SRCS+= common/compression/dc_buffers.c SRCS+= common/compression/dc_dp.c SRCS+= common/compression/icp_sal_dc_err.c +SRCS+= common/compression/dc_chain.c +SRCS+= common/compression/dc_ns_datapath.c +SRCS+= common/compression/dc_ns_header_footer.c SRCS+= common/utils/lac_buffer_desc.c SRCS+= common/utils/lac_mem.c SRCS+= common/utils/lac_mem_pools.c @@ -27,6 +30,7 @@ SRCS+= common/ctrl/sal_ctrl_services.c SRCS+= common/ctrl/sal_create_services.c SRCS+= common/ctrl/sal_crypto.c +SRCS+= common/ctrl/sal_get_instances.c SRCS+= common/qat_comms/sal_qat_cmn_msg.c SRCS+= common/crypto/sym/lac_sym_api.c SRCS+= common/crypto/sym/lac_sym_cb.c diff --git a/sys/modules/qat/qat_common/Makefile b/sys/modules/qat/qat_common/Makefile --- a/sys/modules/qat/qat_common/Makefile +++ b/sys/modules/qat/qat_common/Makefile @@ -7,18 +7,20 @@ SRCS+= adf_accel_engine.c adf_freebsd_admin.c adf_aer.c adf_cfg.c qat_common_module.c SRCS+= adf_heartbeat.c adf_freebsd_heartbeat_dbg.c -SRCS+= adf_dev_mgr.c adf_hw_arbiter.c +SRCS+= adf_freebsd_dev_processes.c adf_freebsd_uio.c adf_freebsd_uio_cleanup.c +SRCS+= adf_ctl_drv.c adf_dev_mgr.c adf_hw_arbiter.c SRCS+= adf_init.c adf_transport.c adf_isr.c adf_fw_counters.c adf_dev_err.c SRCS+= adf_gen2_hw_data.c SRCS+= adf_gen4_hw_data.c SRCS+= qat_freebsd.c SRCS+= adf_freebsd_cfg_dev_dbg.c adf_freebsd_ver_dbg.c -SRCS+= adf_cfg_device.c adf_cfg_section.c adf_cfg_instance.c adf_cfg_bundle.c +SRCS+= adf_cfg_device.c adf_cfg_section.c adf_cfg_instance.c adf_cfg_bundle.c adf_cfg_sysctl.c SRCS+= qat_hal.c qat_uclo.c -SRCS+= adf_vf_isr.c adf_pf2vf_msg.c -SRCS+= adf_vf2pf_msg.c -SRCS+= adf_pf2vf_capabilities.c -SRCS+= adf_pf2vf_ring_to_svc_map.c +SRCS+= adf_vf_isr.c +SRCS+= adf_gen4_pfvf.c +SRCS+= adf_gen4_timer.c +SRCS+= adf_pfvf_utils.c adf_pfvf_vf_msg.c adf_pfvf_vf_proto.c +SRCS+= adf_gen4vf_hw_csr_data.c SRCS+= adf_freebsd_transport_debug.c adf_clock.c SRCS+= adf_freebsd_cnvnr_ctrs_dbg.c SRCS+= adf_freebsd_pfvf_ctrs_dbg.c diff --git a/sys/modules/qat/qat_hw/Makefile b/sys/modules/qat/qat_hw/Makefile --- a/sys/modules/qat/qat_hw/Makefile +++ b/sys/modules/qat/qat_hw/Makefile @@ -7,6 +7,7 @@ SRCS+= qat_c62x/adf_c62x_hw_data.c qat_c62x/adf_drv.c SRCS+= qat_200xx/adf_200xx_hw_data.c qat_200xx/adf_drv.c SRCS+= qat_4xxx/adf_4xxx_hw_data.c qat_4xxx/adf_drv.c +SRCS+= qat_4xxxvf/adf_4xxxvf_hw_data.c qat_4xxxvf/adf_drv.c SRCS+= qat_c3xxx/adf_c3xxx_hw_data.c qat_c3xxx/adf_drv.c SRCS+= qat_dh895xcc/adf_dh895xcc_hw_data.c qat_dh895xcc/adf_drv.c SRCS+= qat_c4xxx/adf_c4xxx_hw_data.c qat_c4xxx/adf_drv.c qat_c4xxx/adf_c4xxx_ae_config.c qat_c4xxx/adf_c4xxx_misc_error_stats.c