Page MenuHomeFreeBSD

D39850.diff
No OneTemporary

D39850.diff

This file is larger than 256 KB, so syntax highlighting was skipped.
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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%0D<%AU*T}VshkuUWo$&AaBZCw0?_DD&L%_dx
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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 <linux/types.h>
+#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 <linux/types.h>
+#include "adf_pfvf_msg.h"
+
+/* How long to wait for far side to acknowledge receipt */
+#define ADF_PFVF_MSG_ACK_DELAY_US 4
+#define ADF_PFVF_MSG_ACK_MAX_DELAY_US (1 * USEC_PER_SEC)
+
+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 <linux/types.h>
+#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 <sys/condvar.h>
+
+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 <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/sysctl.h>
/* Cryptodev headers */
#include <opencrypto/cryptodev.h>
@@ -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, &gt; 0 and &lt; 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, &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^768 (12 qwords)*/
- uint64_t m; /**< modulus &ge; 2^767 and &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_768_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^768 (12 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^767 and &lt; 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 &ge; 0 and &lt; 2^768 (12 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^768 (12 qwords)*/
- uint64_t m; /**< modulus &ge; 2^767 and &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_768_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^768 (12 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^768 (12 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^767 and &lt; 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 &gt; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t m; /**< modulus &ge; 2^1023 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_1024_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^1023 and &lt; 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 &ge; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t m; /**< modulus &ge; 2^1023 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_1024_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^1023 and &lt; 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 &gt; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t m; /**< modulus &ge; 2^1535 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_1536_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^1535 and &lt; 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 &ge; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t m; /**< modulus &ge; 2^1535 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_1536_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^1535 and &lt; 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 &gt; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t m; /**< modulus &ge; 2^2047 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_2048_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^2047 and &lt; 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 &ge; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t m; /**< modulus &ge; 2^2047 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_2048_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^2047 and &lt; 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 &gt; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t m; /**< modulus &ge; 2^3071 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_3072_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^3071 and &lt; 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 &ge; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t m; /**< modulus &ge; 2^3071 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_3072_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^3071 and &lt; 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 &gt; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t m; /**< modulus &ge; 2^4095 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_4096_input_s
+{
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^4095 and &lt; 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 &ge; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t e; /**< exponent &gt; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t m; /**< modulus &ge; 2^4095 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_dh_4096_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^4095 and &lt; 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 &gt; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^8191 and &lt; 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 &ge; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t e; /**< exponent &gt; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t m; /**< modulus &ge; 2^8191 and &lt; 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, &nbsp;2 &lt; p &lt; 2^256 (4 qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^256 (4 qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^256 (4 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^256 (4 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^255 &lt; p &lt; 2^256 (4
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^255 &lt; q &lt; 2^256 (4
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^255 &lt; p &lt; 2^256 (4 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^255 &lt; q &lt; 2^256 (4 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (8 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (8 qwords)*/
- uint64_t n; /**< RSA key, &gt; 0 and &lt; 2^256 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_512_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (8 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (8 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; n (8 qwords)*/
- uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^256 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_512_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (8 qwords)*/
+ uint64_t d; /**< RSA private key (RSADP first form) (8 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; (p*q) (8 qwords)*/
- uint64_t
- p; /**< RSA parameter, prime, &nbsp;2^255 &lt; p &lt; 2^256 (4
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^255 &lt; q &lt; 2^256 (4
- qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (4 qwords)*/
- uint64_t dq; /**< RSA private key 0 &lt; dq &lt; q-1 (4 qwords)*/
- uint64_t qinv; /**< RSA private key 0 &lt; qInv &lt; 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, &lt; (p*q) (8 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^255 &lt; p &lt; 2^256 (4 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^255 &lt; q &lt; 2^256 (4 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (4 qwords)*/
+ uint64_t dq; /**< RSA private key 0 &lt; dq &lt; q-1 (4 qwords)*/
+ uint64_t qinv; /**< RSA private key 0 &lt; qInv &lt; 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, &nbsp;2 &lt; p &lt; 2^512 (8 qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^512 (8 qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^512 (8 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^512 (8 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^511 &lt; p &lt; 2^512 (8
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^511 &lt; q &lt; 2^512 (8
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^511 &lt; p &lt; 2^512 (8 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^511 &lt; q &lt; 2^512 (8 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (16 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (16 qwords)*/
- uint64_t n; /**< RSA key, &gt; 0 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_1024_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (16 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (16 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; n (16 qwords)*/
- uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_1024_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (16 qwords)*/
+ uint64_t d; /**< RSA private key (RSADP first form) (16 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; (p*q) (16 qwords)*/
- uint64_t
- p; /**< RSA parameter, prime, &nbsp;2^511 &lt; p &lt; 2^512 (8
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^511 &lt; q &lt; 2^512 (8
- qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (8 qwords)*/
- uint64_t dq; /**< RSA private key 0 &lt; dq &lt; q-1 (8 qwords)*/
- uint64_t qinv; /**< RSA private key 0 &lt; qInv &lt; 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, &lt; (p*q) (16 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^511 &lt; p &lt; 2^512 (8 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^511 &lt; q &lt; 2^512 (8 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (8 qwords)*/
+ uint64_t dq; /**< RSA private key 0 &lt; dq &lt; q-1 (8 qwords)*/
+ uint64_t qinv; /**< RSA private key 0 &lt; qInv &lt; 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, &nbsp;2 &lt; p &lt; 2^768 (12
- qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^768 (12
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^768 (12 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^768 (12 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^767 &lt; p &lt; 2^768 (12
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^767 &lt; q &lt; 2^768 (12
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^767 &lt; p &lt; 2^768 (12 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^767 &lt; q &lt; 2^768 (12 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (24 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; (p*q)-1 (24 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_1536_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (24 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; (p*q)-1 (24 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; n (24 qwords)*/
- uint64_t d; /**< RSA private key (24 qwords)*/
- uint64_t n; /**< RSA key, &gt; 0 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_1536_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (24 qwords)*/
+ uint64_t d; /**< RSA private key (24 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; (p*q) (24 qwords)*/
- uint64_t
- p; /**< RSA parameter, prime, &nbsp;2^767 &lt; p &lt; 2^768 (12
- qwords)*/
- uint64_t
- q; /**< RSA parameter, prime, &nbsp;2^767 &lt; p &lt; 2^768 (12
- qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (12 qwords)*/
- uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (12 qwords)*/
- uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &lt; (p*q) (24 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^767 &lt; p &lt; 2^768 (12 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^767 &lt; p &lt; 2^768 (12 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (12 qwords)*/
+ uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (12 qwords)*/
+ uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &nbsp;2 &lt; p &lt; 2^1024 (16
- qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^1024 (16
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^1024 (16 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^1024 (16 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^1023 &lt; p &lt; 2^1024
- (16 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^1023 &lt; q &lt; 2^1024
- (16 qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^1023 &lt; p &lt; 2^1024 (16 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^1023 &lt; q &lt; 2^1024 (16 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (32 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (32 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_2048_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (32 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (32 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; n (32 qwords)*/
- uint64_t d; /**< RSA private key (32 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_2048_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (32 qwords)*/
+ uint64_t d; /**< RSA private key (32 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; (p*q) (32 qwords)*/
- uint64_t p; /**< RSA parameter, prime, &nbsp;2^1023 &lt; p &lt; 2^1024
- (16 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^1023 &lt; q &lt; 2^1024
- (16 qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (16 qwords)*/
- uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (16 qwords)*/
- uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &lt; (p*q) (32 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^1023 &lt; p &lt; 2^1024 (16 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^1023 &lt; q &lt; 2^1024 (16 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (16 qwords)*/
+ uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (16 qwords)*/
+ uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &nbsp;2 &lt; p &lt; 2^1536 (24
- qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^1536 (24
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^1536 (24 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^1536 (24 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^1535 &lt; p &lt; 2^1536
- (24 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^1535 &lt; q &lt; 2^1536
- (24 qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^1535 &lt; p &lt; 2^1536 (24 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^1535 &lt; q &lt; 2^1536 (24 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (48 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (48 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_3072_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (48 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (48 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; n (48 qwords)*/
- uint64_t d; /**< RSA private key (48 qwords)*/
- uint64_t n; /**< RSA key &gt; 0 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_3072_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (48 qwords)*/
+ uint64_t d; /**< RSA private key (48 qwords)*/
+ uint64_t n; /**< RSA key &gt; 0 and &lt; 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, &lt; (p*q) (48 qwords)*/
- uint64_t p; /**< RSA parameter, prime, &nbsp;2^1535 &lt; p &lt; 2^1536
- (24 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^1535 &lt; q &lt; 2^1536
- (24 qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (24 qwords)*/
- uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (24 qwords)*/
- uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &lt; (p*q) (48 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^1535 &lt; p &lt; 2^1536 (24 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^1535 &lt; q &lt; 2^1536 (24 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (24 qwords)*/
+ uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (24 qwords)*/
+ uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &nbsp;2 &lt; p &lt; 2^2048 (32
- qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^2048 (32
- qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2 &lt; p &lt; 2^2048 (32 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2 &lt; q &lt; 2^2048 (32 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &nbsp;2^2047 &lt; p &lt; 2^2048
- (32 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^2047 &lt; q &lt; 2^2048
- (32 qwords)*/
- uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1,
- &nbsp;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, &nbsp;2^2047 &lt; p &lt; 2^2048 (32 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^2047 &lt; q &lt; 2^2048 (32 qwords)*/
+ uint64_t e; /**< RSA public key, must be odd, &ge; 3 and &le; (p*q)-1, &nbsp;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, &lt; n (64 qwords)*/
- uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (64 qwords)*/
- uint64_t n; /**< RSA key, &gt; 0 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_4096_input_s
+{
+ uint64_t m; /**< message representative, &lt; n (64 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (64 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; n (64 qwords)*/
- uint64_t d; /**< RSA private key (64 qwords)*/
- uint64_t n; /**< RSA key, &gt; 0 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_4096_input_s
+{
+ uint64_t c; /**< cipher text representative, &lt; n (64 qwords)*/
+ uint64_t d; /**< RSA private key (64 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; (p*q) (64 qwords)*/
- uint64_t p; /**< RSA parameter, prime, &nbsp;2^2047 &lt; p &lt; 2^2048
- (32 qwords)*/
- uint64_t q; /**< RSA parameter, prime, &nbsp;2^2047 &lt; q &lt; 2^2048
- (32 qwords)*/
- uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (32 qwords)*/
- uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (32 qwords)*/
- uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &lt; (p*q) (64 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^2047 &lt; p &lt; 2^2048 (32 qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^2047 &lt; q &lt; 2^2048 (32 qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (32 qwords)*/
+ uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (32 qwords)*/
+ uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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, &lt; n (128 qwords)*/
+ uint64_t e; /**< RSA public key, &ge; 3 and &le; n-1 (128 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; n (128 qwords)*/
+ uint64_t d; /**< RSA private key (128 qwords)*/
+ uint64_t n; /**< RSA key, &gt; 0 and &lt; 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, &lt; (p*q) (128 qwords)*/
+ uint64_t p; /**< RSA parameter, prime, &nbsp;2^4095 &lt; p &lt; 2^4096 (64
+ qwords)*/
+ uint64_t q; /**< RSA parameter, prime, &nbsp;2^4095 &lt; q &lt; 2^4096 (64
+ qwords)*/
+ uint64_t dp; /**< RSA private key, 0 &lt; dp &lt; p-1 (64 qwords)*/
+ uint64_t dq; /**< RSA private key, 0 &lt; dq &lt; q-1 (64 qwords)*/
+ uint64_t qinv; /**< RSA private key, 0 &lt; qInv &lt; 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 &gt; 1 and &lt; 2^192 (3 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_192_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^256 (4 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_256_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^384 (6 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_384_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_512_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_768_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_1024_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_2048_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_3072_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 1 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_gcd_pt_4096_input_s
+{
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &lt; m &lt; 2^160 (3 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_160_input_s
+{
+ uint64_t m; /**< prime candidate, 2^159 &lt; m &lt; 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 &lt; m &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_512_input_s
+{
+ uint64_t m; /**< prime candidate, 2^511 &lt; m &lt; 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 &lte; 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 &lt; m &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_l512_input_s
+{
+ uint64_t m; /**< prime candidate, 5 &lt; m &lt; 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 &lt; m &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_768_input_s
+{
+ uint64_t m; /**< prime candidate, 2^767 &lt; m &lt; 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 &lt; m &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_1024_input_s
+{
+ uint64_t m; /**< prime candidate, 2^1023 &lt; m &lt; 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 &lt; m &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_1536_input_s
+{
+ uint64_t m; /**< prime candidate, 2^1535 &lt; m &lt; 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 &lt; m &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_2048_input_s
+{
+ uint64_t m; /**< prime candidate, 2^2047 &lt; m &lt; 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 &lt; m &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_3072_input_s
+{
+ uint64_t m; /**< prime candidate, 2^3071 &lt; m &lt; 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 &lt; m &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_fermat_pt_4096_input_s
+{
+ uint64_t m; /**< prime candidate, 2^4095 &lt; m &lt; 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 &gt; 1 and &lt; m-1 (3 qwords)*/
- uint64_t m; /**< prime candidate &gt; 2^159 and &lt; 2^160 (3 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_160_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (3 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^159 and &lt; 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 &gt; 1 and &lt; m-1 (8 qwords)*/
- uint64_t m; /**< prime candidate &gt; 2^511 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_512_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (8 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^511 and &lt; 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 &gt; 1 and &lt; m-1 (12 qwords)*/
- uint64_t m; /**< prime candidate &gt; 2^767 and &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_768_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (12 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^767 and &lt; 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 &gt; 1 and &lt; m-1 (16 qwords)*/
- uint64_t
- m; /**< prime candidate &gt; 2^1023 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_1024_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (16 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^1023 and &lt; 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 &gt; 1 and &lt; m-1 (24 qwords)*/
- uint64_t
- m; /**< prime candidate &gt; 2^1535 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_1536_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (24 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^1535 and &lt; 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 &gt; 1 and &lt;m-1 (32 qwords)*/
- uint64_t
- m; /**< prime candidate &gt; 2^2047 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_2048_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt;m-1 (32 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^2047 and &lt; 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 &gt; 1 and &lt; m-1 (48 qwords)*/
- uint64_t
- m; /**< prime candidate &gt; 2^3071 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_3072_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (48 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^3071 and &lt; 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 &gt; 1 and &lt; m-1 (64 qwords)*/
- uint64_t
- m; /**< prime candidate &gt; 2^4095 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_4096_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (64 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 2^4095 and &lt; 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 &gt; 1 and &lt; m-1 (8 qwords)*/
- uint64_t m; /**< prime candidate &gt; 1 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_mr_pt_l512_input_s
+{
+ uint64_t x; /**< randomness &gt; 1 and &lt; m-1 (8 qwords)*/
+ uint64_t m; /**< prime candidate &gt; 1 and &lt; 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 &gt; 2^159 and &lt; 2^160 (3 qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_160_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^159 and &lt; 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 &gt; 2^511 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_512_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^511 and &lt; 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 &gt; 2^767 and &lt; 2^768 (12 qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_768_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^767 and &lt; 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 &gt; 2^1023 and &lt; 2^1024 (16
- qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_1024_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^1023 and &lt; 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 &gt; 2^1535 and &lt; 2^1536 (24
- qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_1536_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^1535 and &lt; 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 &gt; 2^2047 and &lt; 2^2048 (32
- qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_2048_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^2047 and &lt; 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 &gt; 2^3071 and &lt; 2^3072 (48
- qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_3072_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^3071 and &lt; 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 &gt; 2^4096 and &lt; 2^4096 (64
- qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_4096_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 2^4096 and &lt; 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 &gt; 5 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_mmp_lucas_pt_l512_input_s
+{
+ uint64_t m; /**< odd prime candidate &gt; 5 and &lt; 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 &ge; 0 and &lt; 2^512 (8 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^512 (8 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^512 (8 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l512_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^512 (8 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^512 (8 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^1024 (16 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l1024_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^1536 (24 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l1536_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^2048 (32 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l2048_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^2560 (40 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^2560 (40 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^2560 (40 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l2560_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^2560 (40 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^2560 (40 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^3072 (48 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l3072_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^3584 (56 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^3584 (56 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^3584 (56 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l3584_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^3584 (56 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^3584 (56 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t e; /**< exponent &ge; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t m; /**< modulus &gt; 0 and &lt; 2^4096 (64 qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l4096_input_s
+{
+ uint64_t g; /**< base &ge; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &ge; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t e; /**< exponent &ge; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t m; /**< modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^128 (2 qwords)*/
- uint64_t
- b; /**< odd modulus &gt; 0 and &lt; 2^128, coprime to a (2 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l128_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^128 (2 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^192 (3 qwords)*/
- uint64_t
- b; /**< odd modulus &gt; 0 and &lt; 2^192, coprime to a (3 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l192_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^192 (3 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^256 (4 qwords)*/
- uint64_t
- b; /**< odd modulus &gt; 0 and &lt; 2^256, coprime to a (4 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l256_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^256 (4 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^384 (6 qwords)*/
- uint64_t
- b; /**< odd modulus &gt; 0 and &lt; 2^384, coprime to a (6 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l384_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^384 (6 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^512 (8 qwords)*/
- uint64_t
- b; /**< odd modulus &gt; 0 and &lt; 2^512, coprime to a (8 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l512_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^512 (8 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^768 (12 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^768 ,coprime to a (12
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l768_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^768 (12 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^1024, coprime to a (16
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l1024_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^1536, coprime to a (24
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l1536_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^2048, coprime to a (32
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l2048_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^3072, coprime to a (48
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l3072_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t b; /**< odd modulus &gt; 0 and &lt; 2^4096, coprime to a (64
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l4096_input_s
+{
+ uint64_t a; /**< number &gt; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t
+ b; /**< odd modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^128 (2 qwords)*/
- uint64_t
- b; /**< even modulus &gt; 0 and &lt; 2^128, coprime with a (2
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l128_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^128 (2 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^192 (3 qwords)*/
- uint64_t
- b; /**< even modulus &gt; 0 and &lt; 2^192, coprime with a (3
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l192_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^192 (3 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^256 (4 qwords)*/
- uint64_t
- b; /**< even modulus &gt; 0 and &lt; 2^256, coprime with a (4
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l256_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^256 (4 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^384 (6 qwords)*/
- uint64_t
- b; /**< even modulus &gt; 0 and &lt; 2^384, coprime with a (6
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l384_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^384 (6 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^512 (8 qwords)*/
- uint64_t
- b; /**< even modulus &gt; 0 and &lt; 2^512, coprime with a (8
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l512_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^512 (8 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^768 (12 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^768, coprime with a
- (12 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l768_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^768 (12 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^1024 (16 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^1024, coprime with a
- (16 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l1024_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^1024 (16 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^1536 (24 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^1536, coprime with a
- (24 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l1536_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^1536 (24 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^2048 (32 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^2048, coprime with a
- (32 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l2048_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^2048 (32 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^3072 (48 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^3072, coprime with a
- (48 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l3072_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^3072 (48 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^4096 (64 qwords)*/
- uint64_t b; /**< even modulus &gt; 0 and &lt; 2^4096, coprime with a
- (64 qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l4096_input_s
+{
+ uint64_t a; /**< odd number &gt; 0 and &lt; 2^4096 (64 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^8192 (128 qwords)*/
+ uint64_t b; /**< even modulus &gt; 0 and &lt; 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 &gt; 0 and &lt; 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 &gt; 0 and &lt; 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 &lt; 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 &lt; e &lt; 2^256) (4 qwords)*/
- uint64_t d; /**< private key (&gt;0 and &lt; n) (4 qwords)*/
- uint64_t
- r; /**< ECDSA r signature value (&gt;0 and &lt; n) (4 qwords)*/
- uint64_t k; /**< random value &gt; 0 and &lt; n (4 qwords)*/
- uint64_t n; /**< order of the base point G (2 &lt; n &lt; 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 &lt; e &lt; 2^256) (4 qwords)*/
+ uint64_t d; /**< private key (&gt;0 and &lt; n) (4 qwords)*/
+ uint64_t r; /**< ECDSA r signature value (&gt;0 and &lt; n) (4 qwords)*/
+ uint64_t k; /**< random value &gt; 0 and &lt; n (4 qwords)*/
+ uint64_t n; /**< order of the base point G (2 &lt; n &lt; 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 (&gt; 0 and degree(x(G)) &lt; degree(q)) (8 qwords)*/
+ uint64_t yg; /**< y coordinate of verified base point (&gt; 0 and degree(y(G)) &lt; degree(q)) (8 qwords)*/
+ uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and &lt; 2^512) (8 qwords)*/
+ uint64_t q; /**< field polynomial of degree &gt; 2 and &lt; 512 (8 qwords)*/
+ uint64_t a; /**< a equation coefficient (degree(a) &lt; degree(q)) (8 qwords)*/
+ uint64_t b; /**< b equation coefficient (degree(b) &lt; degree(q)) (8 qwords)*/
+ uint64_t k; /**< random value &gt; 0 and &lt; 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 &lt; e &lt; 2^512) (8 qwords)*/
+ uint64_t d; /**< private key (&gt;0 and &lt; n) (8 qwords)*/
+ uint64_t r; /**< ECDSA r signature value (&gt;0 and &lt; n) (8 qwords)*/
+ uint64_t k; /**< random value &gt; 0 and &lt; n (8 qwords)*/
+ uint64_t n; /**< order of the base point G, which must be prime and a divisor of #E and &lt; 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) &lt; 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 &lt; 2^576 (9 qwords)*/
+ uint64_t d; /**< private key (&gt; 0 and &lt; n) (9 qwords)*/
+ uint64_t r; /**< ECDSA r signature value (&gt; 0 and &lt; n) (9 qwords)*/
+ uint64_t k; /**< random value (&gt; 0 and &lt; n) (9 qwords)*/
+ uint64_t n; /**< order of the base point of the curve (n &lt; 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) &lt; degree(q)) (9 qwords)*/
+ uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) &lt; degree(q)) (9 qwords)*/
+ uint64_t k; /**< random value &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^256 (4 qwords)*/
+ uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt; 256) (4 qwords)*/
+ uint64_t yg; /**< y coordinate of curve point (degree(yG) &lt; 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) &lt; 256 (4 qwords)*/
+ uint64_t a; /**< a equation coefficient of curve, degree(a) &lt; 256 (4 qwords)*/
+ uint64_t b; /**< b equation coefficient of curve, degree(b) &lt; 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 &gt; 0 and &lt; 2^512 (8 qwords)*/
+ uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt; 512) (8 qwords)*/
+ uint64_t yg; /**< y coordinate of curve point (degree(yG) &lt; 512) (8 qwords)*/
+ uint64_t a; /**< a equation coefficient (degree(a) &lt; 512) (8 qwords)*/
+ uint64_t b; /**< b equation coefficient (degree(b) &lt; 512) (8 qwords)*/
+ uint64_t q; /**< field polynomial of degree &gt; 2 and &lt; 512 (8 qwords)*/
+ uint64_t h; /**< cofactor (&lt; 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 &gt; 2 and &lt; 512 (8 qwords)*/
+ uint64_t a; /**< a equation coefficient (degree(a) &lt; 512) (8 qwords)*/
+ uint64_t b; /**< b equation coefficient (degree(a) &lt; 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 &gt; 0 and &lt; 2^576 (9 qwords)*/
+ uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt; degree(q)) (9 qwords)*/
+ uint64_t yg; /**< y coordinate of curve point (degree(xG) &lt; 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 (&gt; 0 and
- degree(x(G)) &lt; degree(q)) (8 qwords)*/
- uint64_t yg; /**< y coordinate of verified base point (&gt; 0 and
- degree(y(G)) &lt; degree(q)) (8 qwords)*/
- uint64_t n; /**< order of the base point G, which must be prime and a
- divisor of #E and &lt; 2^512) (8 qwords)*/
- uint64_t
- q; /**< field polynomial of degree &gt; 2 and &lt; 512 (8 qwords)*/
- uint64_t a; /**< a equation coefficient (degree(a) &lt; degree(q)) (8
- qwords)*/
- uint64_t b; /**< b equation coefficient (degree(b) &lt; degree(q)) (8
- qwords)*/
- uint64_t k; /**< random value &gt; 0 and &lt; 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 &lt; e &lt; 2^512) (8 qwords)*/
- uint64_t d; /**< private key (&gt;0 and &lt; n) (8 qwords)*/
- uint64_t
- r; /**< ECDSA r signature value (&gt;0 and &lt; n) (8 qwords)*/
- uint64_t k; /**< random value &gt; 0 and &lt; n (8 qwords)*/
- uint64_t n; /**< order of the base point G, which must be prime and a
- divisor of #E and &lt; 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) &lt; 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 &lt; 2^576 (9 qwords)*/
- uint64_t d; /**< private key (&gt; 0 and &lt; n) (9 qwords)*/
- uint64_t
- r; /**< ECDSA r signature value (&gt; 0 and &lt; n) (9 qwords)*/
- uint64_t k; /**< random value (&gt; 0 and &lt; n) (9 qwords)*/
- uint64_t
- n; /**< order of the base point of the curve (n &lt; 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) &lt;
- degree(q)) (9 qwords)*/
- uint64_t b; /**< b coefficient of curve B/K-571 (degree(b) &lt;
- degree(q)) (9 qwords)*/
- uint64_t k; /**< random value &gt; 0 and &lt; 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 &gt; 0 and &lt; 2^256 (4 qwords)*/
- uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt; 256) (4
- qwords)*/
- uint64_t yg; /**< y coordinate of curve point (degree(yG) &lt; 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) &lt; 256 (4 qwords)*/
- uint64_t
- a; /**< a equation coefficient of curve, degree(a) &lt; 256 (4
- qwords)*/
- uint64_t
- b; /**< b equation coefficient of curve, degree(b) &lt; 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 &gt; 0 and &lt; 2^512 (8 qwords)*/
- uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt; 512) (8
- qwords)*/
- uint64_t yg; /**< y coordinate of curve point (degree(yG) &lt; 512) (8
- qwords)*/
- uint64_t
- a; /**< a equation coefficient (degree(a) &lt; 512) (8 qwords)*/
- uint64_t
- b; /**< b equation coefficient (degree(b) &lt; 512) (8 qwords)*/
- uint64_t
- q; /**< field polynomial of degree &gt; 2 and &lt; 512 (8 qwords)*/
- uint64_t h; /**< cofactor (&lt; 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 &gt; 2 and &lt; 512 (8 qwords)*/
- uint64_t
- a; /**< a equation coefficient (degree(a) &lt; 512) (8 qwords)*/
- uint64_t
- b; /**< b equation coefficient (degree(a) &lt; 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 &gt; 0 and &lt; 2^576 (9 qwords)*/
- uint64_t xg; /**< x coordinate of curve point (degree(xG) &lt;
- degree(q)) (9 qwords)*/
- uint64_t yg; /**< y coordinate of curve point (degree(xG) &lt;
- 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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 &lte; 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 &lte; 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 &lt; 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 &lt; 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) &lt; 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) &lt; 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 &ge; 0 and &lt; m (12
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_768_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (12
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_768_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (16
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_1024_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (16
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_1024_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (24
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_1536_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (24
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_1536_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (32
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_2048_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (32
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_2048_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (48
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_3072_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (48
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_3072_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (64
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_g2_4096_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (64
- qwords)*/
+typedef struct icp_qat_fw_mmp_dh_4096_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; 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 &ge; 0 and &lt; 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, &lt; n (8 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_512_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (8 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_512_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (8 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_512_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; n (16 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_1024_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (16 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_1024_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (16 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_1024_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; n (24 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_1536_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (24 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_1536_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (24 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_1536_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; n (32 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_2048_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (32 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_2048_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (32 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_2048_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; n (48 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_3072_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (48 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_3072_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (48 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_3072_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; n (64 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_ep_4096_output_s
+{
+ uint64_t c; /**< cipher text representative, &lt; 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, &lt; n (64 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp1_4096_output_s
+{
+ uint64_t m; /**< message representative, &lt; 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, &lt; (p*q) (64 qwords)*/
+typedef struct icp_qat_fw_mmp_rsa_dp2_4096_output_s
+{
+ uint64_t m; /**< message representative, &lt; (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, &lt; 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, &lt; 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, &lt; (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 &lte; 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 &lte; 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 &ge; 0 and &lt; m (8
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l512_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (16
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l1024_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (24
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l1536_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (32
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l2048_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (40
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l2560_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (48
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l3072_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (56
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l3584_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; m (64
- qwords)*/
+typedef struct icp_qat_fw_maths_modexp_l4096_output_s
+{
+ uint64_t r; /**< modular exponentiation result &ge; 0 and &lt; 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 &ge; 0 and &lt; 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, &gt; 0 and &lt; b (2
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l128_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (3
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l192_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (4
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l256_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (6
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l384_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (8
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l512_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (12
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l768_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (16
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l1024_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (24
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l1536_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (32
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l2048_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (48
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l3072_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (64
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_odd_l4096_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (2
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l128_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (3
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l192_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (4
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l256_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (6
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l384_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (8
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l512_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (12
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l768_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (16
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l1024_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (24
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l1536_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (32
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l2048_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (48
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l3072_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; b (64
- qwords)*/
+typedef struct icp_qat_fw_maths_modinv_even_l4096_output_s
+{
+ uint64_t c; /**< modular multiplicative inverse of a, &gt; 0 and &lt; 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, &gt; 0 and &lt; 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 &gt; 0 and &lt; n (4 qwords)*/
- uint64_t s; /**< ECDSA signature s &gt; 0 and &lt; n (4 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_rs_gf2_l256_output_s
+{
+ uint64_t r; /**< ECDSA signature r &gt; 0 and &lt; n (4 qwords)*/
+ uint64_t s; /**< ECDSA signature s &gt; 0 and &lt; 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 &gt; 0 and &lt; n (4 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l256_output_s
+{
+ uint64_t r; /**< ECDSA signature r &gt; 0 and &lt; 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 &lt; 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 &gt; 0 and &lt; n (4 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l256_output_s
+{
+ uint64_t s; /**< ECDSA signature s &gt; 0 and &lt; 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 &gt; 0 and &lt; n ECDSA signature s
- &gt; 0 and &lt; 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 &gt; 0 and &lt; n ECDSA signature s &gt; 0 and &lt; 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 &gt; 0 and &lt; n (8 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_l512_output_s
+{
+ uint64_t r; /**< ECDSA signature r &gt; 0 and &lt; 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 &gt; 0 and &lt; n (8 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_l512_output_s
+{
+ uint64_t s; /**< ECDSA signature s &gt; 0 and &lt; 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 &gt; 0 and &lt; n ECDSA signature s
- &gt; 0 and &lt; 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 &gt; 0 and &lt; n ECDSA signature s &gt; 0 and &lt; 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) &lt; 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) &lt; 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 &gt; 0 and &lt; n (9 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_s_gf2_571_output_s
+{
+ uint64_t s; /**< ECDSA signature s &gt; 0 and &lt; 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 &gt; 0 and &lt; n (9 qwords)*/
+typedef struct icp_qat_fw_mmp_ecdsa_sign_r_gf2_571_output_s
+{
+ uint64_t r; /**< ECDSA signature r &gt; 0 and &lt; 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 (&lt; degree(q)) (4
- qwords)*/
- uint64_t yk; /**< y coordinate of resultant point (&lt; degree(q)) (4
- qwords)*/
+typedef struct icp_qat_fw_maths_point_multiplication_gf2_l256_output_s
+{
+ uint64_t xk; /**< x coordinate of resultant point (&lt; degree(q)) (4 qwords)*/
+ uint64_t yk; /**< y coordinate of resultant point (&lt; 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 (&lt; q) (8 qwords)*/
- uint64_t yk; /**< y coordinate of resultant point (&lt; q) (8 qwords)*/
+typedef struct icp_qat_fw_maths_point_multiplication_gf2_l512_output_s
+{
+ uint64_t xk; /**< x coordinate of resultant point (&lt; q) (8 qwords)*/
+ uint64_t yk; /**< y coordinate of resultant point (&lt; 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 &lt;
- degree(q)) (9 qwords)*/
- uint64_t yk; /**< y coordinate of resultant point (degree &lt;
- 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 &lt; degree(q)) (9 qwords)*/
+ uint64_t yk; /**< y coordinate of resultant point (degree &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; 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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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, &lt; (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 &lte; 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 &lte; 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 &lt; 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) &lt; 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 &lt; 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) &lt; 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;
/**<True if the Instance supports Stateless Deflate
decompression */
+ CpaBoolean statelessLZ4Compression;
+ /**<True if the Instance supports Stateless LZ4 compression */
+ CpaBoolean statelessLZ4Decompression;
+ /**<True if the Instance supports Stateless LZ4 decompression */
+ CpaBoolean statefulLZ4Decompression;
+ /**<True if the Instance supports Stateful LZ4 decompression */
+ CpaBoolean statelessLZ4SCompression;
+ /**<True if the Instance supports Stateless LZ4S compression */
CpaBoolean checksumCRC32;
/**<True if the Instance can calculate a CRC32 checksum over
- the uncompressed data*/
+ the uncompressed data. This value is only calculated when
+ CPA_DC_DEFLATE is configured as the algorithm for
+ CpaDcCompType */
CpaBoolean checksumAdler32;
/**<True if the Instance can calculate an Adler-32 checksum over
- the uncompressed data */
+ the uncompressed data. This value is only calculated when
+ CPA_DC_DEFLATE is configured as the algorithm for
+ CpaDcCompType */
+ CpaBoolean checksumXXHash32;
+ /**<True if the Instance can calculate an xxHash-32 hash over
+ the uncompressed data. This value is only calculated when
+ CPA_DC_LZ4 or CPA_DC_LZ4S is configured as the algorithm for
+ CpaDcCompType */
CpaBoolean dynamicHuffman;
/**<True if the Instance supports dynamic Huffman trees in deflate
- blocks*/
+ blocks */
CpaBoolean dynamicHuffmanBufferReq;
/**<True if an Instance specific buffer is required to perform
a dynamic Huffman tree deflate request */
CpaBoolean precompiledHuffman;
/**<True if the Instance supports precompiled Huffman trees in
- deflate blocks*/
+ deflate blocks */
CpaBoolean autoSelectBestHuffmanTree;
/**<True if the Instance has the ability to automatically select
between different Huffman encoding schemes for better
@@ -604,8 +734,19 @@
* compressed content that resulted in a compressAndVerify error.
*/
CpaBoolean integrityCrcs;
- /**<True if the instance supports integrity CRC checking in the
- * compression/decompression datapath. */
+ /**<True if the instance supports 32 bit integrity CRC checking in
+ * the compression/decompression datapath. Refer to
+ * @ref CpaDcOpData for more details on integrity checking. */
+ CPA_BITMAP(dcChainCapInfo, CPA_DC_CHAIN_CAP_BITMAP_SIZE);
+ /**< Bitmap representing which chaining capabilities are supported
+ * by the instance.
+ * Bits can be tested using the macro @ref CPA_BITMAP_BIT_TEST.
+ * The bit positions are those specified in the enumerated type
+ * @ref CpaDcChainOperations in cpa_dc_chain.h. */
+ CpaBoolean integrityCrcs64b;
+ /**<True if the instance supports 64 bit integrity CRC checking in
+ * the compression / decompression datapath. Refer to
+ * @ref CpaDcOpData for more details on integrity checking. */
} CpaDcInstanceCapabilities;
/**
@@ -617,10 +758,6 @@
* client needs to complete the information in this structure in order to
* setup a session.
*
- * @deprecated
- * As of v1.6 of the Compression API, the fileType and deflateWindowSize
- * fields in this structure have been deprecated and should not be used.
- *
****************************************************************************/
typedef struct _CpaDcSessionSetupData {
CpaDcCompLvl compLevel;
@@ -632,28 +769,78 @@
CpaDcAutoSelectBest autoSelectBestHuffmanTree;
/**<Indicates if and how the implementation should select the best
* Huffman encoding. */
- CpaDcFileType fileType;
- /**<File type for the purpose of determining Huffman Codes from
- * CpaDcFileType.
- * As of v1.6 of the Compression API, this field has been deprecated
- * and should not be used. */
CpaDcSessionDir sessDirection;
/**<Session direction indicating whether session is used for
compression, decompression or both */
CpaDcSessionState sessState;
/**<Session state indicating whether the session should be configured
as stateless or stateful */
- Cpa32U deflateWindowSize;
- /**<Base 2 logarithm of maximum window size minus 8 (a value of 7 for
- * a 32K window size). Permitted values are 0 to 7. cpaDcDecompressData
- * may return an error if an attempt is made to decompress a stream that
- * has a larger window size.
- * As of v1.6 of the Compression API, this field has been deprecated and
- * should not be used. */
+ CpaDcCompWindowSize windowSize;
+ /**<Window size from CpaDcCompWindowSize */
+ CpaDcCompMinMatch minMatch;
+ /**<Min Match size from CpaDcCompMinMatch */
+ CpaDcCompLZ4BlockMaxSize lz4BlockMaxSize;
+ /**<Window size from CpaDcCompLZ4BlockMaxSize */
+ CpaBoolean lz4BlockChecksum;
+ /**<LZ4 Block Checksum setting for the LZ4 request.
+ For LZ4 decompression operations, this setting must be set based
+ on the B.Checksum flag originating from the LZ4 frame header.
+ For LZ4 compression operations, this setting will be ignored as
+ the implementation does not support generation of Data Block
+ checksums. */
+ CpaBoolean lz4BlockIndependence;
+ /**<LZ4 Block Independence Flag setting.
+ For LZ4 compression operations, this setting must be set based on
+ the Block Independence Flag originating from the LZ4 frame header.
+ For LZ4 decompression operations, this setting is ignored.
+ For data compressed with lz4BlockIndependence set to CPA_FALSE,
+ it is not possible to perform parallel decompression on the
+ compressed blocks. It is also not possible to access the produced
+ LZ4 blocks randomly.
+ */
CpaDcChecksum checksum;
/**<Desired checksum required for the session */
+ CpaBoolean accumulateXXHash;
+ /**<If TRUE the xxHash calculation for LZ4 requests using the session
+ based API, cpaDcCompressData2 and cpaDcCompressData, will be
+ accumulated across requests, with a valid xxHash being written to
+ CpaDcRqResults.checksum for the request which specifies
+ CPA_DC_FLUSH_FINAL in CpaDcOpData.flushFlag. When the
+ CPA_DC_FLUSH_FINAL is received, the internal XXHash state will be
+ reset for this session.
+ One exception is if a CPA_DC_OVERFLOW error is returned, the xxHash
+ value in the checksum field will be valid for requests up to that
+ point and the internal XXHash state will not be reset. This will
+ allow a user to either create an LZ4 frame based off the data at the
+ time of overflow, or correct the overflow condition and continue
+ submitting requests until specifying CPA_DC_FLUSH_FINAL.
+ Additionally the user can force the internal XXHash state to reset
+ (even on overflow) by calling cpaDcResetXXHashState on this session.
+ For the sessionless API, cpaDcNsCompressData, this flag will have
+ no effect */
} CpaDcSessionSetupData;
+typedef CpaDcSessionSetupData CpaDcNsSetupData;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Session Update Data.
+ * @description
+ * This structure contains data relating to updating up a session. The
+ * client needs to complete the information in this structure in order to
+ * update a session.
+ *
+ ****************************************************************************/
+typedef struct _CpaDcSessionUpdateData {
+ CpaDcCompLvl compLevel;
+ /**<Compression Level from CpaDcCompLvl */
+ CpaDcHuffType huffType;
+ /**<Huffman type from CpaDcHuffType */
+ CpaBoolean enableDmm;
+ /**<Desired DMM required for the session */
+} CpaDcSessionUpdateData ;
+
/**
*****************************************************************************
* @ingroup cpaDc
@@ -715,13 +902,42 @@
Cpa32U consumed;
/**< Octets consumed by the operation */
Cpa32U checksum;
- /**< Initial checksum passed into stateless operations.
- Will also be updated to the checksum produced by the operation */
- CpaBoolean endOfLastBlock;
+ /**< The checksum produced by the operation. For some checksum
+ * algorithms, setting this field on the input to a stateless
+ * compression/decompression request can be used to pass in an initial
+ * checksum value that will be used to seed the checksums produced by
+ * the stateless operation.
+ *
+ * The checksum algorithm CPA_DC_XXHASH32 does not support passing an
+ * input value in this parameter. Any initial value passed will be
+ * ignored by the compression/decompression operation when this
+ * checksum algorithm is used. */
+ CpaBoolean endOfLastBlock;
/**< Decompression operation has stopped at the end of the last
* block in a deflate stream. */
+ CpaBoolean dataUncompressed;
+ /**< If TRUE the output data for this request is uncompressed and
+ * in the format setup for the request. This value is only valid
+ * for CPA_DC_ASB_ENABLED or if compressAndVerifyAndRecover is set to
+ * TRUE in the CpaDcOpData structure for a request. */
} CpaDcRqResults;
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Integrity CRC Size
+ * @description
+ * Enum of possible integrity CRC sizes.
+ *
+ ****************************************************************************/
+typedef enum _CpaDcIntegrityCrcSize
+{
+ CPA_DC_INTEGRITY_CRC32 = 0,
+ /**< 32-bit Integrity CRCs */
+ CPA_DC_INTEGRITY_CRC64,
+ /**< 64-bit integrity CRCs */
+} CpaDcIntegrityCrcSize;
+
/**
*****************************************************************************
* @ingroup cpaDc
@@ -736,6 +952,20 @@
Cpa32U oCrc; /**< CRC calculated on request's output buffer */
} CpaIntegrityCrc;
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Integrity CRC64 calculation details
+ * @description
+ * This structure contains information about resulting integrity CRC64
+ * calculations performed for a single request.
+ *
+ ****************************************************************************/
+typedef struct _CpaIntegrityCrc64b {
+ Cpa64U iCrc; /**< CRC calculated on request's input buffer */
+ Cpa64U oCrc; /**< CRC calculated on request's output buffer */
+} CpaIntegrityCrc64b;
+
/**
*****************************************************************************
* @ingroup cpaDc
@@ -745,7 +975,10 @@
* After successful request, this structure will contain
* all resulting CRCs.
* Integrity specific CRCs (when enabled/supported) are located in
- * 'CpaIntegrityCrc integrityCrc' field.
+ * 'CpaIntegrityCrc integrityCrc' field for 32bit values and in
+ * 'CpaIntegrityCrc64b integrityCrC64b' field for 64 bit values.
+ * Integrity CRCs cannot be accumulated across multiple requests and
+ * do not provide seeding capabilities.
* @note
* this structure must be allocated in physical contiguous memory
*
@@ -758,7 +991,9 @@
/**< ADLER32 calculated on the input buffer during compression
* requests and on the output buffer during decompression requests. */
CpaIntegrityCrc integrityCrc;
- /**< Integrity CRCs */
+ /**< 32bit Integrity CRCs */
+ CpaIntegrityCrc64b integrityCrc64b;
+ /**< 64bit Integrity CRCs */
} CpaCrcData;
/**
@@ -815,8 +1050,6 @@
CpaBoolean integrityCrcCheck;
/**< If set to true, the implementation will verify that data
* integrity is preserved through the processing pipeline.
- * This behaviour supports stateless and stateful behavior for
- * both static and dynamic Huffman encoding.
*
* Integrity CRC checking is not supported for decompression operations
* over data that contains multiple gzip headers. */
@@ -825,6 +1058,10 @@
* against hardware generated integrity CRCs to ensure that data
* integrity is maintained when transferring data to and from the
* hardware accelerator. */
+ CpaDcIntegrityCrcSize integrityCrcSize;
+ /**< This option specifies the size of the CRC to be used for data
+ * integrity checking. As such it is only valid if this request is
+ * configured for data integrity checks. */
CpaDcSkipData inputSkipData;
/**< Optional skip regions in the input buffers */
CpaDcSkipData outputSkipData;
@@ -1032,6 +1269,115 @@
cpaDcResetSession(const CpaInstanceHandle dcInstance,
CpaDcSessionHandle pSessionHandle );
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Reset of the xxHash internal state on a session.
+ *
+ * @description
+ * This function will reset the internal xxHash state maintained within a
+ * session. This would be used in conjunction with the
+ * CpaDcSessionSetupData.accumulateXXHash flag being set to TRUE for this
+ * session. It will enable reseting (reinitialising) just the xxHash
+ * calculation back to the state when the session was first initialised.
+ *
+ * @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_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 cpaDcInitSession function.
+ * @post
+ * None
+ * @note
+ * This is a synchronous function and has no completion callback
+ * associated with it.
+ *
+ * @see
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcResetXXHashState(const CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle );
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Compression Session Update Function.
+ *
+ * @description
+ * This function is used to modify some select compression parameters
+ * of a previously initialized session handle.
+ * 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
+ * Yes
+ *
+ * @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 cpaDcInitSession function.
+ * @post
+ * None
+ * @note
+ * This is a synchronous function and has no completion callback
+ * associated with it.
+ *
+ * @see
+ * cpaDcInitSession()
+ *
+ *****************************************************************************/
+CpaStatus cpaDcUpdateSession(const CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaDcSessionUpdateData *pSessionUpdateData );
/**
*****************************************************************************
@@ -1129,6 +1475,9 @@
* @note
* This is a synchronous function and has no completion callback
* associated with it.
+ * The cpaDcDeflateCompressBound() API is intended to reduce the likelihood
+ * of overflow occurring during compression operations. An overflow may
+ * occur in some exception cases.
*
* @see
* None
@@ -1140,6 +1489,106 @@
Cpa32U inputSize,
Cpa32U *outputSize );
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * LZ4 Compression Bound API
+ *
+ * @description
+ * This function provides the maximum output buffer size for a LZ4
+ * compression operation in the "worst case" (non-compressible) scenario.
+ * It's primary purpose is for output buffer memory allocation.
+ *
+ * @context
+ * This is a synchronous function that will not 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] inputSize Input Buffer size.
+ * @param[out] outputSize Maximum output buffer size.
+ *
+ * @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
+ * 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
+ * None
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcLZ4CompressBound(const CpaInstanceHandle dcInstance,
+ Cpa32U inputSize,
+ Cpa32U *outputSize );
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * LZ4S Compression Bound API
+ *
+ * @description
+ * This function provides the maximum output buffer size for a LZ4S
+ * compression operation in the "worst case" (non-compressible) scenario.
+ * It's primary purpose is for output buffer memory allocation.
+ *
+ * @context
+ * This is a synchronous function that will not 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] inputSize Input Buffer size.
+ * @param[out] outputSize Maximum output buffer size.
+ *
+ * @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
+ * 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
+ * None
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcLZ4SCompressBound(const CpaInstanceHandle dcInstance,
+ Cpa32U inputSize,
+ Cpa32U *outputSize );
+
/**
*****************************************************************************
* @ingroup cpaDc
@@ -1381,7 +1830,7 @@
* @param[in] pSrcBuff Pointer to data buffer for compression.
* @param[in] pDestBuff Pointer to buffer space for data after
* compression.
- * @param[in] pOpData Additional input parameters.
+ * @param[in,out] pOpData Additional parameters.
* @param[in,out] pResults Pointer to results structure
* @param[in] callbackTag User supplied value to help correlate
* the callback with its associated
@@ -1417,6 +1866,88 @@
CpaDcRqResults *pResults,
void *callbackTag );
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Submit a request to compress a buffer of data without requiring a
+ * session to be created. This is a No-Session (Ns) variant of the
+ * cpaDcCompressData function.
+ *
+ * @description
+ * This API consumes data from the input buffer and generates compressed
+ * data in the output buffer. Unlike the other compression APIs this
+ * does not use a previously created session. This is a "one-shot" API
+ * that requests can be directly submitted to.
+ *
+ * @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] pSetupData Configuration structure for compression.
+ * @param[in] pSrcBuff Pointer to data buffer for compression.
+ * @param[in] pDestBuff Pointer to buffer space for data after
+ * compression.
+ * @param[in] pOpData Additional input parameters.
+ * @param[in,out] pResults Pointer to results structure
+ * @param[in] callbackFn For synchronous operation this callback
+ * shall be a null pointer.
+ * @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_STATUS_UNSUPPORTED Function is not supported.
+ * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit
+ * the request.
+ *
+ * @pre
+ * None
+ * @post
+ * None
+ * @note
+ * This function passes control to the compression service for processing
+ *
+ * Checksum rules.
+ * The checksum rules are the same as those for the session based APIs
+ * (cpaDcCompressData or cpaDcCompressData2) with the following exception.
+ * -# If the algorithm specified is CPA_DC_LZ4 or CPA_DC_LZ4S the xxHash32
+ * checksum will not be maintained across calls to the API. The
+ * implication is that the xxHash32 value will only be valid for the
+ * output of a single request, no state will be saved. If an LZ4 frame is
+ * required, even in recoverable error scenarios such as CPA_DC_OVERFLOW,
+ * the checksum will not be continued. If that is required the session
+ * based API must be used.
+ *
+ * @see
+ * None
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcNsCompressData( CpaInstanceHandle dcInstance,
+ CpaDcNsSetupData *pSetupData,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcOpData *pOpData,
+ CpaDcRqResults *pResults,
+ CpaDcCallbackFn callbackFn,
+ void *callbackTag );
/**
*****************************************************************************
* @ingroup cpaDc
@@ -1586,14 +2117,92 @@
CpaDcRqResults *pResults,
void *callbackTag );
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Submit a request to decompress a buffer of data without requiring a
+ * session to be created. This is a No-Session (Ns) variant of the
+ * cpaDcDecompressData function.
+ *
+ * @description
+ * This API consumes data from the input buffer and generates decompressed
+ * data in the output buffer. Unlike the other decompression APIs this
+ * does not use a previously created session. This is a "one-shot" API
+ * that requests can be directly submitted to.
+ *
+ * @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] pSetupData Configuration structure for decompression..
+ * @param[in] pSrcBuff Pointer to data buffer for decompression.
+ * @param[in] pDestBuff Pointer to buffer space for data
+ * after decompression.
+ * @param[in] pOpData Additional input parameters.
+ * @param[in,out] pResults Pointer to results structure
+ * @param[in] callbackFn For synchronous operation this callback
+ * shall be a null pointer.
+ * @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_STATUS_UNSUPPORTED Function is not supported.
+ * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit
+ * the request.
+ *
+ * @pre
+ * None
+ * @post
+ * None
+ * @note
+ * This function passes control to the decompression service. The function
+ * returns the status from the service.
+ *
+ * @see
+ * cpaDcDecompressData()
+ * cpaDcCompressData2()
+ * cpaDcCompressData()
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcNsDecompressData( CpaInstanceHandle dcInstance,
+ CpaDcNsSetupData *pSetupData,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcOpData *pOpData,
+ CpaDcRqResults *pResults,
+ CpaDcCallbackFn callbackFn,
+ void *callbackTag );
+
/**
*****************************************************************************
* @ingroup cpaDc
* Generate compression header.
*
* @description
- * This API generates the gzip or the zlib header and stores it in the
- * output buffer.
+ * This function generates the gzip header, zlib header or LZ4 frame
+ * header and stores it in the destination buffer. The type of header
+ * created is determined using the compression algorithm selected using
+ * CpaDcSessionSetupData.compType, for the session associated with the
+ * session handle.
*
* @context
* This function may be call from any context.
@@ -1608,7 +2217,7 @@
* @threadSafe
* Yes
*
- * @param[in,out] pSessionHandle Session handle.
+ * @param[in] pSessionHandle Session handle.
* @param[in] pDestBuff Pointer to data buffer where the
* compression header will go.
* @param[out] count Pointer to counter filled in with
@@ -1625,13 +2234,14 @@
* pSessionHandle has been setup using cpaDcInitSession()
*
* @note
- * This function can output a 10 byte gzip header or 2 byte zlib header to
- * the destination buffer. The session properties are used to determine
- * the header type. To output a header the session must have been
- * initialized with CpaDcCompType CPA_DC_DEFLATE for any other value no
- * header is produced. To output a gzip header the session must have been
- * initialized with CpaDcChecksum CPA_DC_CRC32. To output a zlib header
- * the session must have been initialized with CpaDcChecksum CPA_DC_ADLER32.
+ * When the deflate compression algorithm is used, this function can output
+ * a 10 byte gzip header or 2 byte zlib header to the destination buffer.
+ * The session properties are used to determine the header type. To
+ * output a Gzip or a Zlib header the session must have been initialized
+ * with CpaDcCompType CPA_DC_DEFLATE.
+ * To output a gzip header the session must have been initialized with
+ * CpaDcChecksum CPA_DC_CRC32. To output a zlib header the session must
+ * have been initialized with CpaDcChecksum CPA_DC_ADLER32.
* For CpaDcChecksum CPA_DC_NONE no header is output.
*
* If the compression requires a gzip header, then this header requires
@@ -1651,10 +2261,29 @@
* - Bit 5: FDICT 0 = default, 1 is preset dictionary
* - Bits 6 - 7: FLEVEL, compression level (see RFC 1950)
*
- * The counter parameter will be set
- * to the number of bytes added to the buffer. The pData will be
- * not be changed.
- *
+ * When LZ4 algorithm is used, this function can output a 7 byte frame
+ * header. This function will set the LZ4 frame header with:
+ * - Magic number 0x184D2204
+ * - The LZ4 max block size defined in the CpaDcSessionSetupData
+ * - Flag byte as:
+ * * Version = 1
+ * * Block independence = 0
+ * * Block checksum = 0
+ * * Content size present = 0
+ * * Content checksum present = 1
+ * * Dictionary ID present = 0
+ * - Content size = 0
+ * - Dictionary ID = 0
+ * - Header checksum = 1 byte representing the second byte of the
+ * XXH32 of the frame decriptor field.
+ *
+ * The counter parameter will be set to the number of bytes added to the
+ * buffer. The pData will be not be changed.
+ *
+ * For any of the compression algorithms used, the application is
+ * responsible to offset the pData pointer in CpaBufferList by the length
+ * of the header before calling the CpaDcCompressData() or
+ * CpaDcCompressData2() functions.
* @see
* None
*
@@ -1669,8 +2298,11 @@
* Generate compression footer.
*
* @description
- * This API generates the footer for gzip or zlib and stores it in the
- * output buffer.
+ * This function generates the footer for gzip, zlib or LZ4.
+ * The generated footer is stored it in the destination buffer.
+ * The type of footer created is determined using the compression
+ * algorithm selected for the session associated with the session handle.
+ *
* @context
* This function may be call from any context.
* @assumptions
@@ -1705,12 +2337,18 @@
*
* @note
* Depending on the session variables, this function can add the
- * alder32 footer to the zlib compressed data as defined in RFC1950. If
- * required, it can also add the gzip footer, which is the crc32 of the
- * uncompressed data and the length of the uncompressed data. This
- * section is defined in RFC1952. The session variables used to determine
- * the header type are CpaDcCompType and CpaDcChecksum, see cpaDcGenerateHeader
- * for more details.
+ * alder32 footer to the zlib compressed data as defined in RFC1950.
+ * If required, it can also add the gzip footer, which is the crc32 of the
+ * uncompressed data and the length of the uncompressed data.
+ * This section is defined in RFC1952. The session variables used to
+ * determine the header type are CpaDcCompType and CpaDcChecksum, see
+ * cpaDcGenerateHeader for more details.
+ *
+ * For LZ4 compression, this function adds the LZ4 frame footer
+ * using XXH32 algorithm of the uncompressed data. The XXH32 checksum is
+ * added after the end mark. This section is defined in the documentation
+ * of the LZ4 frame format at:
+ * https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md
*
* An artifact of invoking this function for writing the footer data is
* that all opaque session specific data is re-initialized. If the
@@ -1718,11 +2356,12 @@
* application can continue processing compression requests using the
* same session handle.
*
- * The produced element of the pResults structure will be incremented by the
- * numbers bytes added to the buffer. The pointer to the buffer
- * will not be modified.
- *
- * This function is not supported for stateless sessions.
+ * The produced element of the pResults structure will be incremented by
+ * the numbers bytes added to the buffer. The pointer to the buffer will
+ * not be modified. It is necessary for the application to ensure that
+ * there is always sufficient memory in the destination buffer to append
+ * the footer. In the event that the destination buffer would be too small
+ * to accept the footer, overflow will not be reported.
*
* @see
* None
@@ -1730,7 +2369,150 @@
*****************************************************************************/
CpaStatus
cpaDcGenerateFooter( CpaDcSessionHandle pSessionHandle,
- CpaFlatBuffer *pDestBuff, CpaDcRqResults *pResults );
+ CpaFlatBuffer *pDestBuff,
+ CpaDcRqResults *pResults );
+
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Generate compression header without requiring a session to be created.
+ * This is a No-Session (Ns) variant of the cpaDcGenerateHeader function.
+ *
+ * @description
+ * This API generates the required compression format header and stores it
+ * in the output buffer.
+ *
+ * @context
+ * This function may be called from any context.
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] pSetupData Pointer to Ns Configuration structure.
+ * @param[in] pDestBuff Pointer to data buffer where the
+ * compression header will go.
+ * @param[out] count Pointer to counter filled in with
+ * header size.
+ *
+ * @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_RESTARTING API implementation is restarting. Resubmit
+ * the request.
+ * @retval CPA_STATUS_UNSUPPORTED Function is not supported.
+ *
+ * @pre
+ * None
+ *
+ * @note
+ * This function outputs the required compression format header to
+ * the destination buffer. The CpaDcNsSetupData structure fields are used to
+ * determine the header type.
+ *
+ * To output an LZ4 header the structure must have been initialized with
+ * with CpaDcCompType CPA_DC_LZ4.
+ * To output a gzip or zlib header the structure must have been initialized
+ * with CpaDcCompType CPA_DC_DEFLATE.
+ * To output a gzip header the structure must have been initialized with
+ * CpaDcChecksum CPA_DC_CRC32.
+ * To output a zlib header the structure must have been initialized with
+ * CpaDcChecksum CPA_DC_ADLER32.
+ * For CpaDcChecksum CPA_DC_NONE no header is output.
+ *
+ * The counter parameter will be set to the number of bytes added to the
+ * buffer.
+ *
+ * @see
+ * cpaDcGenerateHeader
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcNsGenerateHeader( CpaDcNsSetupData *pSetupData,
+ CpaFlatBuffer *pDestBuff,
+ Cpa32U *count );
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDc
+ * Generate compression footer without requiring a session to be created.
+ * This is a No-Session (Ns) variant of the cpaDcGenerateFooter function.
+ *
+ * @description
+ * This API generates the footer for the required format and stores it in
+ * the destination buffer.
+ * @context
+ * This function may be call from any context.
+ * @assumptions
+ * None
+ * @sideEffects
+ * All session variables are reset
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] pSetupData Pointer to Ns Configuration structure.
+ * @param[in] totalLength Total accumulated length of input data
+ * processed. See description for formats
+ * that make use of this parameter.
+ * @param[in] pDestBuff Pointer to data buffer where the
+ * compression footer will go.
+ * @param[in,out] pResults Pointer to results structure filled by
+ * CpaDcNsCompressData. Updated with the
+ * results of this API call
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_FAIL Function failed.
+ * @retval CPA_STATUS_UNSUPPORTED Function is not supported.
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in.
+ * @retval CPA_STATUS_RESTARTING API implementation is restarting. Resubmit
+ * the request.
+ * @retval CPA_STATUS_UNSUPPORTED Function is not supported.
+ *
+ * @pre
+ * pResults structure has been filled by CpaDcNsCompressData().
+ *
+ * @note
+ * This function outputs the required compression format footer to
+ * the destination buffer. The CpaDcNsSetupData structure fields are used to
+ * determine the footer type created.
+ *
+ * To output an LZ4 footer the structure must have been initialized with
+ * with CpaDcCompType CPA_DC_LZ4.
+ * To output a gzip or zlib footer the structure must have been initialized
+ * with CpaDcCompType CPA_DC_DEFLATE.
+ * To output a gzip footer the structure must have been initialized with
+ * CpaDcChecksum CPA_DC_CRC32 and the totalLength parameter initialized to
+ * the total accumulated length of data processed.
+ * To output a zlib footer the structure must have been initialized with
+ * CpaDcChecksum CPA_DC_ADLER32.
+ * For CpaDcChecksum CPA_DC_NONE no footer is output.
+ *
+ * The produced element of the pResults structure will be incremented by the
+ * number of bytes added to the buffer. The pointer to the buffer
+ * will not be modified.
+ *
+ * @see
+ * CpaDcNsSetupData
+ * cpaDcNsGenerateHeader
+ * cpaDcGenerateFooter
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcNsGenerateFooter( CpaDcNsSetupData *pSetupData,
+ Cpa64U totalLength,
+ CpaFlatBuffer *pDestBuff,
+ CpaDcRqResults *pResults );
/**
@@ -2275,7 +3057,7 @@
* lists or hash tables.
* For stateless sessions the context size returned from this function
* will be zero. For stateful sessions the context size returned will
- * depend on the session setup data.
+ * depend on the session setup data and may be zero.
*
* Session data is expected to include interim checksum values, various
* counters and other session related data that needs to persist
diff --git a/sys/dev/qat/qat_api/include/dc/cpa_dc_bp.h b/sys/dev/qat/qat_api/include/dc/cpa_dc_bp.h
--- a/sys/dev/qat/qat_api/include/dc/cpa_dc_bp.h
+++ b/sys/dev/qat/qat_api/include/dc/cpa_dc_bp.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/dc/cpa_dc_chain.h b/sys/dev/qat/qat_api/include/dc/cpa_dc_chain.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/qat/qat_api/include/dc/cpa_dc_chain.h
@@ -0,0 +1,659 @@
+/****************************************************************************
+ *
+ * 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_dc_chain.h
+ *
+ * @defgroup cpaDcChain Data Compression Chaining API
+ *
+ * @ingroup cpaDc
+ *
+ * @description
+ * These functions specify the API for Data Compression Chaining operations.
+ *
+ * @remarks
+ *
+ *
+ *****************************************************************************/
+
+#ifndef CPA_DC_CHAIN_H
+#define CPA_DC_CHAIN_H
+
+#ifdef __cplusplus
+extern"C" {
+#endif
+
+#include "cpa_dc.h"
+#include "cpa_cy_sym.h"
+
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Supported operations for compression chaining
+ *
+ * @description
+ * This enumeration lists the supported operations for compression chaining
+ *
+ *****************************************************************************/
+typedef enum _CpaDcChainOperations
+{
+ CPA_DC_CHAIN_COMPRESS_THEN_HASH,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform hash on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for hash setup data*/
+ CPA_DC_CHAIN_COMPRESS_THEN_ENCRYPT,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform encryption on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for encryption setup data*/
+ CPA_DC_CHAIN_COMPRESS_THEN_HASH_ENCRYPT,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform hash on compressed text and
+ * encryption on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for hash and encryption setup data*/
+ CPA_DC_CHAIN_COMPRESS_THEN_ENCRYPT_HASH,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform encryption on compressed text and
+ * hash on compressed & encrypted text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for encryption and hash setup data*/
+ CPA_DC_CHAIN_COMPRESS_THEN_AEAD,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform AEAD encryption on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for AEAD encryption setup data*/
+ CPA_DC_CHAIN_HASH_THEN_COMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform hash on plain text
+ * 2nd operation is to perform compression on plain text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for hash setup data
+ * 2nd entry is for compression setup data*/
+ CPA_DC_CHAIN_HASH_VERIFY_THEN_DECOMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform hash verify on compressed text
+ * 2nd operation is to perform decompression on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for hash setup data
+ * 2nd entry is for decompression setup data*/
+ CPA_DC_CHAIN_DECRYPT_THEN_DECOMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform decryption on compressed & encrypted text
+ * 2nd operation is to perform decompression on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for decryption setup data
+ * 2nd entry is for decompression setup data*/
+ CPA_DC_CHAIN_HASH_VERIFY_DECRYPT_THEN_DECOMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform hash verify on compressed & encrypted text
+ * and decryption on compressed & encrypted text
+ * 2nd operation is to perform decompression on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for hash and decryption setup data
+ * 2nd entry is for decompression setup data*/
+ CPA_DC_CHAIN_DECRYPT_HASH_VERIFY_THEN_DECOMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform decryption on compressed & encrypted text
+ * and hash verify on compressed text
+ * 2nd operation is to perform decompression on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for decryption and hash setup data
+ * 2nd entry is for decompression setup data*/
+ CPA_DC_CHAIN_AEAD_THEN_DECOMPRESS,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform AEAD decryption on compressed & encrypted text
+ * 2nd operation is to perform decompression on compressed text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for AEAD decryption setup data
+ * 2nd entry is for decompression setup data*/
+ CPA_DC_CHAIN_DECOMPRESS_THEN_HASH_VERIFY,
+ /**< 2 operations for chaining:
+ * 1st operation is to perform decompression on compressed text
+ * 2nd operation is to perform hash verify on plain text
+ **< 2 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for decompression setup data
+ * 2nd entry is for hash setup data*/
+ CPA_DC_CHAIN_COMPRESS_THEN_AEAD_THEN_HASH,
+ /**< 3 operations for chaining:
+ * 1st operation is to perform compression on plain text
+ * 2nd operation is to perform AEAD encryption compressed text
+ * 3rd operation is to perfom hash on compressed & encrypted text
+ **< 3 entries in CpaDcChainSessionSetupData array:
+ * 1st entry is for compression setup data
+ * 2nd entry is for AEAD encryption setup data
+ * 3rd entry is for hash setup data*/
+} CpaDcChainOperations;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Supported session types for data compression chaining.
+ *
+ * @description
+ * This enumeration lists the supported session types
+ * for data compression chaining.
+ *****************************************************************************/
+typedef enum _CpaDcChainSessionType
+{
+ CPA_DC_CHAIN_COMPRESS_DECOMPRESS,
+ /**< Indicate the session is for compression or decompression */
+ CPA_DC_CHAIN_SYMMETRIC_CRYPTO,
+ /**< Indicate the session is for symmetric crypto */
+} CpaDcChainSessionType;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Chaining Session Setup Data.
+ * @description
+ * This structure contains data relating to set up chaining sessions. The
+ * client needs to complete the information in this structure in order to
+ * setup chaining sessions.
+ *
+ ****************************************************************************/
+typedef struct _CpaDcChainSessionSetupData {
+ CpaDcChainSessionType sessType;
+ /**Indicate the type for this session */
+ union {
+ CpaDcSessionSetupData *pDcSetupData;
+ /**< Pointer to compression session setup data */
+ CpaCySymSessionSetupData *pCySetupData;
+ /**< Pointer to symmectric crypto session setup data */
+ };
+} CpaDcChainSessionSetupData;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Compression chaining request input parameters.
+ * @description
+ * This structure contains the request information to use with
+ * compression chaining operations.
+ *
+ ****************************************************************************/
+typedef struct _CpaDcChainOpData {
+ CpaDcChainSessionType opType;
+ /**< Indicate the type for this operation */
+ union {
+ CpaDcOpData *pDcOp;
+ /**< Pointer to compression operation data */
+ CpaCySymOpData *pCySymOp;
+ /**< Pointer to symmectric crypto operation data */
+ };
+} CpaDcChainOpData;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Chaining request results data
+ * @description
+ * This structure contains the request results.
+ *
+ ****************************************************************************/
+typedef struct _CpaDcChainRqResults {
+ CpaDcReqStatus dcStatus;
+ /**< Additional status details from compression accelerator */
+ CpaStatus cyStatus;
+ /**< Additional status details from symmetric crypto accelerator */
+ CpaBoolean verifyResult;
+ /**< This parameter is valid when the verifyDigest option is set in the
+ * CpaCySymSessionSetupData structure. A value of CPA_TRUE indicates
+ * that the compare succeeded. A value of CPA_FALSE indicates that the
+ * compare failed */
+ Cpa32U produced;
+ /**< Octets produced to the output buffer */
+ Cpa32U consumed;
+ /**< Octets consumed from the input buffer */
+ Cpa32U crc32;
+ /**< crc32 checksum produced by chaining operations */
+ Cpa32U adler32;
+ /**< adler32 checksum produced by chaining operations */
+}CpaDcChainRqResults;
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Get the size of the memory required to hold the chaining sessions
+ * information.
+ *
+ * @description
+ * The client of the Data Compression API is responsible for
+ * allocating sufficient memory to hold chaining sessions information.
+ * This function provides a way for determining the size of chaining
+ * sessions.
+ *
+ * @context
+ * No restrictions
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] dcInstance Instance handle.
+ * @param[in] operation The operation for chaining
+ * @param[in] numSessions Number of sessions for the chaining
+ * @param[in] pSessionData Pointer to an array of
+ * CpaDcChainSessionSetupData structures.
+ * There should be numSessions entries in
+ * the array.
+ * @param[out] pSessionSize On return, this parameter will be the size
+ * of the memory that will be required by
+ * cpaDcChainInitSession() for 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_UNSUPPORTED Function is not supported.
+ *
+ * @pre
+ * None
+ * @post
+ * None
+ * @note
+ * Only a synchronous version of this function is provided.
+ *
+ * @see
+ * cpaDcChainInitSession()
+ *
+ *****************************************************************************/
+CpaStatus
+cpaDcChainGetSessionSize(CpaInstanceHandle dcInstance,
+ CpaDcChainOperations operation,
+ Cpa8U numSessions,
+ CpaDcChainSessionSetupData *pSessionData,
+ Cpa32U* pSessionSize);
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcChain
+ * Initialize data compression chaining session
+ *
+ * @description
+ * This function is used to initialize compression/decompression chaining
+ * sessions.
+ * This function returns a unique session handle each time this function
+ * is invoked.
+ * If the session has been configured with a callback function, then
+ * the order of the callbacks are guaranteed to be in the same order the
+ * compression or decompression requests were submitted for each session,
+ * so long as a single thread of execution is used for job submission.
+ *
+ * @context
+ * This is a synchronous function and it 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 derived from discovery
+ * functions.
+ * @param[in,out] pSessionHandle Pointer to a session handle.
+ * @param[in] operation The operations for chaining
+ * @param[in] numSessions Number of sessions for chaining
+ * @param[in,out] pSessionData Pointer to an array of
+ * CpaDcChainSessionSetupData structures.
+ * There should be numSessions entries in
+ * the array.
+ * @param[in] callbackFn For synchronous operation this callback
+ * shall be a null pointer.
+ *
+ * @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
+ * dcInstance has been started using cpaDcStartInstance.
+ * @post
+ * None
+ * @note
+ * Only a synchronous version of this function is provided.
+ *
+ * pSessionData Setup Rules
+ * -# Each element in CpaDcChainSessionSetupData structure array provides
+ * (de)compression or a symmetric crypto session setup data.
+ *
+ * -# The supported chaining operations are listed in CpaDcChainOperations.
+ * This enum indicates the number of operations in a chain and the order
+ * in which they are performed.
+ *
+ * -# The order of entries in pSessionData[] should be consistent with the
+ * CpaDcChainOperations perform order.
+ * As an example, for CPA_DC_CHAIN_COMPRESS_THEN_ENCRYPT, pSessionData[0]
+ * holds the compression setup data and pSessionData[1] holds the
+ * encryption setup data..
+ *
+ * -# The numSessions for each chaining operation are provided in
+ * the comments of enum CpaDcChainOperations.
+ *
+ * -# For a (de)compression session, the corresponding
+ * pSessionData[]->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;
+ /** <scalar multiplier (k > 0 and k < n) */
+ CpaFlatBuffer xP;
+ /** <x coordinate of public key */
+ CpaFlatBuffer yP;
+ /** <y coordinate of public key */
+ CpaCyEcCurve *pCurve;
+ /** <curve type specific parameters */
+ CpaBoolean generator;
+ /** <if TRUE xP and yP are the generator points */
+} CpaCyEcGenericPointMultiplyOpData;
- CpaCyEcFieldType fieldType;
- /**< field type for the operation */
-} CpaCyEcPointVerifyOpData;
+/**
+ *****************************************************************************
+ * @ingroup cpaCyEc
+ * Generic EC Point Verify Operation Data.
+ *
+ * @description
+ * This structure contains the operation data for the
+ * cpaCyEcGenericPointVerify function. This is common for representing
+ * all EC points, irrespective of curve type: Weierstrass, Montgomery and
+ * Twisted Edwards (at this time only Weierstrass are supported).
+ *
+ * This structure contains a generic EC point, irrespective of curve type.
+ * It is used to verify when the <x,y> 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;
+ /** <x coordinate of public key */
+ CpaFlatBuffer yP;
+ /** <y coordinate of public key */
+ CpaCyEcCurve *pCurve;
+ /** <curve type specific parameters */
+} CpaCyEcGenericPointVerifyOpData;
/**
*****************************************************************************
- * @file cpa_cy_ec.h
* @ingroup cpaCyEc
* EC Point Multiplication Operation Data for Edwards or
- 8 Montgomery curves as specificied in RFC#7748.
+ * Montgomery curves as specificied in RFC#7748.
*
* @description
* This structure contains the operation data for the
@@ -300,9 +469,9 @@
*
* @note
* If the client modifies or frees the memory referenced in this
- * structure after it has been submitted to the cpaCyEcPointMultiply
- * function, and before it has been returned in the callback, undefined
- * behavior will result.
+ * structure after it has been submitted to the
+ * cpaCyEcMontEdwdsPointMultiply function, and before it has been returned
+ * in the callback, undefined behavior will result.
*
* All buffers in this structure need to be:
* - 32 bytes in size for 25519 curves
@@ -319,21 +488,63 @@
/**< True if the operation is a generator multiplication (kG)
* False if it is a variable point multiplcation (kP). */
CpaFlatBuffer k;
- /**< k or generator for the operation */
+ /**< k scalar multiplier for the operation */
CpaFlatBuffer x;
/**< x value. Used in scalar varable point multiplication operations.
* Not required if the generator is True. Must be NULL if not required.
* The size of the buffer MUST be 32B for 25519 curves and 64B for 448
* curves */
CpaFlatBuffer y;
- /**< y value. Used in variable point multiplication of operations.
- * Not required for curves defined only on scalar operations.
+ /**< y value. Used in variable point multiplication of operations.
* Not required if the generator is True.
* Must be NULL if not required.
* The size of the buffer MUST be 32B for 25519 curves and 64B for 448
* curves */
} CpaCyEcMontEdwdsPointMultiplyOpData;
+/**
+ *****************************************************************************
+ * @ingroup cpaCyEc
+ * EC Point Verification 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.
+ *
+ * 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 CpaCyEcPointVerify
+ * function, and before it has been returned in the callback, undefined
+ * behavior will result.
+ *
+ * @see
+ * cpaCyEcPointVerify()
+ *
+ *****************************************************************************/
+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 */
+ CpaCyEcFieldType fieldType;
+ /**< field type for the operation */
+} CpaCyEcPointVerifyOpData CPA_DEPRECATED;
+
/**
*****************************************************************************
* @ingroup cpaCyEc
@@ -414,7 +625,7 @@
* @note
* None
* @see
- * cpaCyEcPointMultiply()
+ * cpaCyEcGenericPointMultiply()
*
*****************************************************************************/
typedef void (*CpaCyEcPointMultiplyCbFunc)(void *pCallbackTag,
@@ -428,7 +639,7 @@
/**
*****************************************************************************
* @ingroup cpaCyEc
- * Definition of callback function invoked for cpaCyEcPointVerify
+ * Definition of callback function invoked for cpaCyEcGenericPointVerify
* requests.
* @context
* This callback function can be executed in a context that DOES NOT
@@ -460,7 +671,7 @@
* @note
* None
* @see
- * cpaCyEcPointVerify()
+ * cpaCyEcGenericPointVerify()
*
*****************************************************************************/
typedef void (*CpaCyEcPointVerifyCbFunc)(void *pCallbackTag,
@@ -474,6 +685,9 @@
* @ingroup cpaCyEc
* Perform EC Point Multiplication.
*
+ * @deprecated
+ * This function is replaced with @ref cpaCyEcGenericPointMultiply
+ *
* @description
* This function performs Elliptic Curve Point Multiplication as per
* ANSI X9.63 Annex D.3.2.
@@ -534,7 +748,7 @@
* CpaCyEcPointMultiplyCbFunc
*
*****************************************************************************/
-CpaStatus
+CpaStatus CPA_DEPRECATED
cpaCyEcPointMultiply(const CpaInstanceHandle instanceHandle,
const CpaCyEcPointMultiplyCbFunc pCb,
void *pCallbackTag,
@@ -549,6 +763,9 @@
* @ingroup cpaCyEc
* Verify that a point is on an elliptic curve.
*
+ * @deprecated
+ * This function is replaced with @ref cpaCyEcGenericPointVerify
+ *
* @description
* This function performs Elliptic Curve Point Verification, as per
* steps a, b and c of ANSI X9.62 Annex A.4.2. (To perform the final
@@ -620,7 +837,7 @@
* CpaCyEcPointVerifyCbFunc
*
*****************************************************************************/
-CpaStatus
+CpaStatus CPA_DEPRECATED
cpaCyEcPointVerify(const CpaInstanceHandle instanceHandle,
const CpaCyEcPointVerifyCbFunc pCb,
void *pCallbackTag,
@@ -629,7 +846,148 @@
/**
*****************************************************************************
- * @file cpa_cy_ec.h
+ * @ingroup cpaCyEc
+ * Generic ECC point multiplication operation.
+ *
+ * @description
+ * This is the generic ECC point multiplication operation, which is
+ * agnostic to the type of the curve used.
+ *
+ * @context
+ *
+ * @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 In synchronous mode, the multiply output is
+ * valid (CPA_TRUE) or the output is invalid
+ * (CPA_FALSE).
+ *
+ * @param[out] pXk Pointer to xk flat buffer.
+ * @param[out] pYk Pointer to yk flat buffer.
+ *
+ * @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
+ * 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
+ * CpaCyEcPointMultiplyOpData,
+ * CpaCyEcPointMultiplyCbFunc
+ * CpaCyEcCurveType
+ * CpaCyEcCurveParameters
+ *****************************************************************************/
+CpaStatus
+cpaCyEcGenericPointMultiply(
+ const CpaInstanceHandle instanceHandle,
+ const CpaCyEcPointMultiplyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcGenericPointMultiplyOpData *pOpData,
+ CpaBoolean *pMultiplyStatus,
+ CpaFlatBuffer *pXk,
+ CpaFlatBuffer *pYk);
+
+/**
+ *****************************************************************************
+ * @ingroup cpaCyEc
+ * Generic ECC point verification operation.
+ *
+ * @description
+ * This is the generic ECC point verification operation, which is
+ * agnostic to the type of the curve used.
+ *
+ * @context
+ *
+ * @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 In synchronous mode, the verification
+ * output is valid (CPA_TRUE) or the output is
+ * invalid (CPA_FALSE).
+
+ * @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
+ * When pCb is non-NULL an asynchronous callback of type
+ * CpaCyEcPointVerifyCbFunc is generated in response to this function call.
+ * For optimal performance, data pointers SHOULD be 8-byte aligned.
+ * @see
+ * CpaCyEcGenericPointVerifyOpData,
+ * CpaCyEcPointVerifyCbFunc
+ * CpaCyEcCurveType
+ * CpaCyEcCurveParameters
+ *****************************************************************************/
+CpaStatus
+cpaCyEcGenericPointVerify (
+ const CpaInstanceHandle instanceHandle,
+ const CpaCyEcPointVerifyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcGenericPointVerifyOpData *pOpData,
+ CpaBoolean *pVerifyStatus);
+
+/**
+ *****************************************************************************
* @ingroup cpaCyEc
* Perform EC Point Multiplication on an Edwards or Montgomery curve as
* defined in RFC#7748.
diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdh.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdh.h
--- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdh.h
+++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdh.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
@@ -294,7 +294,6 @@
CpaFlatBuffer *pXk,
CpaFlatBuffer *pYk);
-
/**
*****************************************************************************
* @ingroup cpaCyEcdh
diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdsa.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdsa.h
--- a/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdsa.h
+++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecdsa.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
@@ -267,7 +267,6 @@
/**< field type for the operation */
} CpaCyEcdsaVerifyOpData;
-
/**
*****************************************************************************
* @ingroup cpaCyEcdsa
@@ -339,6 +338,21 @@
/**< Total number of ECDSA Verification operation requests that resulted
* in an invalid output.
* Note that this does not indicate an error. */
+ Cpa64U numKptEcdsaSignRSCompletedOutputInvalid;
+ /**< Total number of KPT ECDSA Sign R & S operation requests could not be
+ * completed successfully due to an invalid output.
+ * Note that this does not indicate an error. */
+ Cpa64U numKptEcdsaSignRSCompleted;
+ /**< Total number of KPT ECDSA Sign R & S operation requests that completed
+ * successfully. */
+ Cpa64U numKptEcdsaSignRSRequests;
+ /**< Total number of KPT ECDSA Sign R & S operation requests. */
+ Cpa64U numKptEcdsaSignRSRequestErrors;
+ /**< Total number of KPT ECDSA Sign R & S operation requests that had an
+ * error and could not be processed. */
+ Cpa64U numKptEcdsaSignRSCompletedErrors;
+ /**< Total number of KPT ECDSA Sign R & S operation requests that could
+ * not be completed successfully due to errors. */
} CpaCyEcdsaStats64;
@@ -775,7 +789,6 @@
const CpaCyEcdsaVerifyOpData *pOpData,
CpaBoolean *pVerifyStatus);
-
/**
*****************************************************************************
* @ingroup cpaCyEcdsa
diff --git a/sys/dev/qat/qat_api/include/lac/cpa_cy_ecsm2.h b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecsm2.h
new file mode 100644
--- /dev/null
+++ b/sys/dev/qat/qat_api/include/lac/cpa_cy_ecsm2.h
@@ -0,0 +1,1464 @@
+/***************************************************************************
+ *
+ * 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_ecsm2.h
+ *
+ * @defgroup cpaCyEcsm2 Elliptic Curve SM2 (ECSM2) API
+ *
+ * @ingroup cpaCy
+ *
+ * @description
+ * These functions specify the API for Public Key Encryption
+ * (Cryptography) SM2 operations.
+ *
+ * Chinese Public Key Algorithm based on Elliptic Curve Theory
+ *
+ * @note
+ * The naming, terms, and reference on SM2 elliptic curve, and their
+ * flow of algorithms inside this API header file are from the link
+ * below, please kindly refer to it for details.
+ * https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ *****************************************************************************/
+
+#ifndef CPA_CY_ECSM2_H_
+#define CPA_CY_ECSM2_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cpa_cy_common.h"
+#include "cpa_cy_ec.h"
+
+/**
+ *****************************************************************************
+ * @file cpa_cy_ecsm2.h
+ * @ingroup cpaCyEcsm2
+ * SM2 Encryption Operation Data.
+ *
+ * @description
+ * This structure contains the operation data for the cpaCyEcsm2Encrypt
+ * 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 cpaCyEcsm2Encrypt
+ * function, and before it has been returned in the callback, undefined
+ * behavior will result.
+ *
+ * @see
+ * cpaCyEcsm2Encrypt()
+ *
+ *****************************************************************************/
+typedef struct _CpaCyEcsm2EncryptOpData {
+ CpaFlatBuffer k;
+ /**< scalar multiplier (k > 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 <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#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 <sys/mutex.h>
+#include <sys/sbuf.h>
+
+#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 <sys/bus.h>
+#include <sys/lock.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/sx.h>
+#include <sys/malloc.h>
+#include <machine/atomic.h>
+#include <dev/pci/pcivar.h>
+#include <sys/conf.h>
+#include <sys/systm.h>
+#include <sys/queue.h>
+#include <sys/proc.h>
+#include <sys/types.h>
+#include <sys/priv.h>
+#include <linux/list.h>
+#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, &section,
+ 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 <sys/conf.h>
+#include <sys/capsicum.h>
+#include <sys/kdb.h>
+#include <sys/condvar.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/sglist.h>
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#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 <sys/param.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
+#include <sys/sglist.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_param.h>
+
+#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 <linux/iopoll.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_gen4_pfvf.h"
+#include "adf_pfvf_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 <sys/mutex.h>
@@ -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 <linux/device.h>
-#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 <linux/delay.h>
-#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 <linux/device.h>
-#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 <linux/types.h>
+#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 <linux/bitfield.h>
+#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 <linux/kernel.h>
+#include "adf_accel_devices.h"
+#include "adf_common_drv.h"
+#include "adf_pfvf_msg.h"
+#include "adf_pfvf_utils.h"
+#include "adf_pfvf_vf_msg.h"
+#include "adf_pfvf_vf_proto.h"
+
+#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 <sys/systm.h>
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <sys/interrupt.h>
#include <dev/pci/pcivar.h>
#include <sys/param.h>
#include <linux/workqueue.h>
@@ -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 <adf_accel_devices.h>
#include <adf_common_drv.h>
#include <adf_cfg.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_dev_err.h>
#include <adf_gen2_hw_data.h>
+#include <adf_gen2_pfvf.h>
#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 <adf_accel_devices.h>
+#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 <adf_cfg.h>
#include <adf_common_drv.h>
#include <adf_dev_err.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_gen4_hw_data.h>
+#include <adf_gen4_pfvf.h>
+#include <adf_gen4_timer.h>
#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 <adf_accel_devices.h>
+#include <adf_cfg.h>
+#include <adf_common_drv.h>
+#include <adf_gen4vf_hw_csr_data.h>
+#include <adf_gen4_pfvf.h>
+#include <adf_pfvf_vf_msg.h>
+#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 <adf_accel_devices.h>
+#include <adf_common_drv.h>
+#include <adf_cfg.h>
+#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 <sys/malloc.h>
#include <machine/bus_dma.h>
#include <dev/pci/pcireg.h>
-#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 <adf_accel_devices.h>
#include <adf_common_drv.h>
#include <adf_cfg.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_dev_err.h>
#include <adf_gen2_hw_data.h>
+#include <adf_gen2_pfvf.h>
#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 <linux/compiler.h>
#include <adf_accel_devices.h>
#include <adf_common_drv.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_dev_err.h>
#include <adf_cfg.h>
#include <adf_fw_counters.h>
#include <adf_gen2_hw_data.h>
+#include <adf_gen2_pfvf.h>
#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 <adf_accel_devices.h>
#include <adf_common_drv.h>
#include <adf_cfg.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_dev_err.h>
#include <adf_gen2_hw_data.h>
+#include <adf_gen2_pfvf.h>
#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 <adf_accel_devices.h>
-#include <adf_pf2vf_msg.h>
+#include <adf_pfvf_msg.h>
#include <adf_common_drv.h>
#include <adf_dev_err.h>
#include <adf_gen2_hw_data.h>
+#include <adf_gen2_pfvf.h>
#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

File Metadata

Mime Type
text/plain
Expires
Tue, Feb 11, 1:25 PM (13 h, 2 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
18/2c/5b4f31231fe49e785862d083ffa7
Default Alt Text
D39850.diff (1 MB)

Event Timeline