aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/qat/qat_api/common
diff options
context:
space:
mode:
authorJulian Grajkowski <julianx.grajkowski@intel.com>2022-07-19 08:15:34 +0000
committerMark Johnston <markj@FreeBSD.org>2022-07-27 15:12:35 +0000
commit78ee8d1c4cdad7a56dbf50f1c8ade75531ce620c (patch)
tree4e96ef389636fdec894275b41201927d26d7677c /sys/dev/qat/qat_api/common
parentf4f56ff43dbd30930f4b018e39ba2b9abf84551f (diff)
Diffstat (limited to 'sys/dev/qat/qat_api/common')
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_buffers.c116
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_datapath.c1790
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_dp.c545
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_header_footer.c237
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_session.c957
-rw-r--r--sys/dev/qat/qat_api/common/compression/dc_stats.c90
-rw-r--r--sys/dev/qat/qat_api/common/compression/icp_sal_dc_err.c33
-rw-r--r--sys/dev/qat/qat_api/common/compression/include/dc_datapath.h186
-rw-r--r--sys/dev/qat/qat_api/common/compression/include/dc_error_counter.h25
-rw-r--r--sys/dev/qat/qat_api/common/compression/include/dc_header_footer.h44
-rw-r--r--sys/dev/qat/qat_api/common/compression/include/dc_session.h278
-rw-r--r--sys/dev/qat/qat_api/common/compression/include/dc_stats.h81
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_session.h622
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym.h356
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_alg_chain.h294
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_auth_enc.h87
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cb.h55
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher.h312
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher_defs.h182
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash.h559
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_defs.h344
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_precomputes.h176
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_key.h184
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_partial.h121
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat.h209
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_cipher.h291
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash.h309
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash_defs_lookup.h139
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_key.h189
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_queue.h51
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_stats.h191
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c3021
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c1860
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_api.c1130
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_auth_enc.c197
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cb.c545
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c416
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_compile_check.c45
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_dp.c1080
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash.c783
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash_sw_precomputes.c353
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_partial.c75
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_queue.c165
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/lac_sym_stats.c139
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat.c227
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_cipher.c889
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash.c942
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash_defs_lookup.c491
-rw-r--r--sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_key.c196
-rw-r--r--sys/dev/qat/qat_api/common/ctrl/sal_compression.c1554
-rw-r--r--sys/dev/qat/qat_api/common/ctrl/sal_create_services.c105
-rw-r--r--sys/dev/qat/qat_api/common/ctrl/sal_crypto.c1837
-rw-r--r--sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c1344
-rw-r--r--sys/dev/qat/qat_api/common/ctrl/sal_list.c99
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_buffer_desc.h252
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_common.h847
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_hooks.h234
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_list.h137
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_log.h46
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_mem.h577
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_mem_pools.h278
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_module.h13
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_sal.h498
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_sal_ctrl.h100
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_sal_types.h198
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_sal_types_crypto.h179
-rw-r--r--sys/dev/qat/qat_api/common/include/lac_sync.h376
-rw-r--r--sys/dev/qat/qat_api/common/include/sal_qat_cmn_msg.h209
-rw-r--r--sys/dev/qat/qat_api/common/include/sal_service_state.h94
-rw-r--r--sys/dev/qat/qat_api/common/include/sal_statistics.h102
-rw-r--r--sys/dev/qat/qat_api/common/include/sal_string_parse.h66
-rw-r--r--sys/dev/qat/qat_api/common/include/sal_types_compression.h150
-rw-r--r--sys/dev/qat/qat_api/common/qat_comms/sal_qat_cmn_msg.c219
-rw-r--r--sys/dev/qat/qat_api/common/stubs/lac_stubs.c413
-rw-r--r--sys/dev/qat/qat_api/common/utils/lac_buffer_desc.c492
-rw-r--r--sys/dev/qat/qat_api/common/utils/lac_lock_free_stack.h87
-rw-r--r--sys/dev/qat/qat_api/common/utils/lac_mem.c118
-rw-r--r--sys/dev/qat/qat_api/common/utils/lac_mem_pools.c430
-rw-r--r--sys/dev/qat/qat_api/common/utils/lac_sync.c123
-rw-r--r--sys/dev/qat/qat_api/common/utils/sal_service_state.c46
-rw-r--r--sys/dev/qat/qat_api/common/utils/sal_statistics.c203
-rw-r--r--sys/dev/qat/qat_api/common/utils/sal_string_parse.c59
-rw-r--r--sys/dev/qat/qat_api/common/utils/sal_user_process.c84
-rw-r--r--sys/dev/qat/qat_api/common/utils/sal_versions.c177
84 files changed, 33353 insertions, 0 deletions
diff --git a/sys/dev/qat/qat_api/common/compression/dc_buffers.c b/sys/dev/qat/qat_api/common/compression/dc_buffers.c
new file mode 100644
index 000000000000..1a5d9bc8973e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_buffers.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_buffers.c
+ *
+ * @defgroup Dc_DataCompression DC Data Compression
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Implementation of the buffer management operations for
+ * Data Compression service.
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_dc.h"
+#include "cpa_dc_bp.h"
+
+#include "sal_types_compression.h"
+#include "icp_qat_fw_comp.h"
+
+#define CPA_DC_CEIL_DIV(x, y) (((x) + (y)-1) / (y))
+#define DC_DEST_BUFF_EXTRA_DEFLATE_GEN2 (55)
+
+CpaStatus
+cpaDcBufferListGetMetaSize(const CpaInstanceHandle instanceHandle,
+ Cpa32U numBuffers,
+ Cpa32U *pSizeInBytes)
+{
+ CpaInstanceHandle insHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = instanceHandle;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(insHandle);
+ LAC_CHECK_NULL_PARAM(pSizeInBytes);
+
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ if (0 == numBuffers) {
+ QAT_UTILS_LOG("Number of buffers is 0.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ *pSizeInBytes = (sizeof(icp_buffer_list_desc_t) +
+ (sizeof(icp_flat_buffer_desc_t) * (numBuffers + 1)) +
+ ICP_DESCRIPTOR_ALIGNMENT_BYTES);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcBnpBufferListGetMetaSize(const CpaInstanceHandle instanceHandle,
+ Cpa32U numJobs,
+ Cpa32U *pSizeInBytes)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+static inline CpaStatus
+dcDeflateBoundGen2(CpaDcHuffType huffType, Cpa32U inputSize, Cpa32U *outputSize)
+{
+ /* Formula for GEN2 deflate:
+ * ceil(9 * Total input bytes / 8) + 55 bytes.
+ * 55 bytes is the skid pad value for GEN2 devices.
+ */
+ *outputSize =
+ CPA_DC_CEIL_DIV(9 * inputSize, 8) + DC_DEST_BUFF_EXTRA_DEFLATE_GEN2;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcDeflateCompressBound(const CpaInstanceHandle dcInstance,
+ CpaDcHuffType huffType,
+ Cpa32U inputSize,
+ Cpa32U *outputSize)
+{
+ CpaInstanceHandle insHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(insHandle);
+ LAC_CHECK_NULL_PARAM(outputSize);
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+ if (!inputSize) {
+ QAT_UTILS_LOG(
+ "The input size needs to be greater than zero.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((CPA_DC_HT_STATIC != huffType) &&
+ (CPA_DC_HT_FULL_DYNAMIC != huffType)) {
+ QAT_UTILS_LOG("Invalid huffType value.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ return dcDeflateBoundGen2(huffType, inputSize, outputSize);
+}
diff --git a/sys/dev/qat/qat_api/common/compression/dc_datapath.c b/sys/dev/qat/qat_api/common/compression/dc_datapath.c
new file mode 100644
index 000000000000..0e2aa9f389e2
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_datapath.c
@@ -0,0 +1,1790 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_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 "sal_types_compression.h"
+#include "dc_stats.h"
+#include "lac_buffer_desc.h"
+#include "lac_sal.h"
+#include "lac_log.h"
+#include "lac_sync.h"
+#include "sal_service_state.h"
+#include "sal_qat_cmn_msg.h"
+#include "dc_error_counter.h"
+#define DC_COMP_MAX_BUFF_SIZE (1024 * 64)
+
+static QatUtilsAtomic dcErrorCount[MAX_DC_ERROR_TYPE];
+
+void
+dcErrorLog(CpaDcReqStatus dcError)
+{
+ Cpa32U absError = 0;
+
+ absError = abs(dcError);
+ if ((dcError < CPA_DC_OK) && (absError < MAX_DC_ERROR_TYPE)) {
+ qatUtilsAtomicInc(&(dcErrorCount[absError]));
+ }
+}
+
+Cpa64U
+getDcErrorCounter(CpaDcReqStatus dcError)
+{
+ Cpa32U absError = 0;
+
+ absError = abs(dcError);
+ if (!(dcError >= CPA_DC_OK || dcError < CPA_DC_EMPTY_DYM_BLK)) {
+ return (Cpa64U)qatUtilsAtomicGet(&dcErrorCount[absError]);
+ }
+
+ return 0;
+}
+
+void
+dcCompression_ProcessCallback(void *pRespMsg)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ icp_qat_fw_comp_resp_t *pCompRespMsg = NULL;
+ void *callbackTag = NULL;
+ Cpa64U *pReqData = NULL;
+ CpaDcDpOpData *pResponse = NULL;
+ CpaDcRqResults *pResults = NULL;
+ CpaDcCallbackFn pCbFunc = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ sal_compression_service_t *pService = NULL;
+ dc_compression_cookie_t *pCookie = NULL;
+ CpaDcOpData *pOpData = NULL;
+ CpaBoolean cmpPass = CPA_TRUE, xlatPass = CPA_TRUE;
+ CpaBoolean verifyHwIntegrityCrcs = CPA_FALSE;
+ Cpa8U cmpErr = ERR_CODE_NO_ERROR, xlatErr = ERR_CODE_NO_ERROR;
+ dc_request_dir_t compDecomp = DC_COMPRESSION_REQUEST;
+ Cpa8U opStatus = ICP_QAT_FW_COMN_STATUS_FLAG_OK;
+ Cpa8U hdrFlags = 0;
+
+ /* Cast response message to compression response message type */
+ pCompRespMsg = (icp_qat_fw_comp_resp_t *)pRespMsg;
+
+ /* Extract request data pointer from the opaque data */
+ LAC_MEM_SHARED_READ_TO_PTR(pCompRespMsg->opaque_data, pReqData);
+
+ /* Extract fields from the request data structure */
+ pCookie = (dc_compression_cookie_t *)pReqData;
+ if (!pCookie)
+ return;
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pCookie->pSessionHandle);
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ pResponse = (CpaDcDpOpData *)pReqData;
+ pResults = &(pResponse->results);
+
+ if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
+ compDecomp = DC_DECOMPRESSION_REQUEST;
+ }
+ } else {
+ pSessionDesc = pCookie->pSessionDesc;
+ pResults = pCookie->pResults;
+ callbackTag = pCookie->callbackTag;
+ pCbFunc = pCookie->pSessionDesc->pCompressionCb;
+ compDecomp = pCookie->compDecomp;
+ pOpData = pCookie->pDcOpData;
+ }
+
+ pService = (sal_compression_service_t *)(pCookie->dcInstance);
+
+ opStatus = pCompRespMsg->comn_resp.comn_status;
+
+ if (NULL != pOpData) {
+ verifyHwIntegrityCrcs = pOpData->verifyHwIntegrityCrcs;
+ }
+
+ hdrFlags = pCompRespMsg->comn_resp.hdr_flags;
+
+ /* Get the cmp error code */
+ cmpErr = pCompRespMsg->comn_resp.comn_error.s1.cmp_err_code;
+ if (ICP_QAT_FW_COMN_RESP_UNSUPPORTED_REQUEST_STAT_GET(opStatus)) {
+ /* Compression not supported by firmware, set produced/consumed
+ to zero
+ and call the cb function with status CPA_STATUS_UNSUPPORTED
+ */
+ QAT_UTILS_LOG("Compression feature not supported\n");
+ status = CPA_STATUS_UNSUPPORTED;
+ pResults->status = (Cpa8S)cmpErr;
+ pResults->consumed = 0;
+ pResults->produced = 0;
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ if (pResponse)
+ pResponse->responseStatus =
+ CPA_STATUS_UNSUPPORTED;
+ (pService->pDcDpCb)(pResponse);
+ } else {
+ /* Free the memory pool */
+ Lac_MemPoolEntryFree(pCookie);
+ pCookie = NULL;
+ if (NULL != pCbFunc) {
+ pCbFunc(callbackTag, status);
+ }
+ }
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompCompletedErrors, pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompCompletedErrors,
+ pService);
+ }
+ return;
+ } else {
+ /* Check compression response status */
+ cmpPass =
+ (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
+ ICP_QAT_FW_COMN_RESP_CMP_STAT_GET(opStatus));
+ }
+
+ if (CPA_DC_INCOMPLETE_FILE_ERR == (Cpa8S)cmpErr) {
+ cmpPass = CPA_TRUE;
+ cmpErr = ERR_CODE_NO_ERROR;
+ }
+ /* log the slice hang and endpoint push/pull error inside the response
+ */
+ if (ERR_CODE_SSM_ERROR == (Cpa8S)cmpErr) {
+ QAT_UTILS_LOG(
+ "Slice hang detected on the compression slice.\n");
+ } else if (ERR_CODE_ENDPOINT_ERROR == (Cpa8S)cmpErr) {
+ QAT_UTILS_LOG(
+ "PCIe End Point Push/Pull or TI/RI Parity error detected.\n");
+ }
+
+ /* We return the compression error code for now. We would need to update
+ * the API if we decide to return both error codes */
+ pResults->status = (Cpa8S)cmpErr;
+
+ /* Check the translator status */
+ if ((DC_COMPRESSION_REQUEST == compDecomp) &&
+ (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) {
+ /* Check translator response status */
+ xlatPass =
+ (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
+ ICP_QAT_FW_COMN_RESP_XLAT_STAT_GET(opStatus));
+
+ /* Get the translator error code */
+ xlatErr = pCompRespMsg->comn_resp.comn_error.s1.xlat_err_code;
+
+ /* Return a fatal error or a potential error in the translator
+ * slice
+ * if the compression slice did not return any error */
+ if ((CPA_DC_OK == pResults->status) ||
+ (CPA_DC_FATALERR == (Cpa8S)xlatErr)) {
+ pResults->status = (Cpa8S)xlatErr;
+ }
+ }
+ /* Update dc error counter */
+ dcErrorLog(pResults->status);
+
+ if (CPA_FALSE == pSessionDesc->isDcDp) {
+ /* In case of any error for an end of packet request, we need to
+ * update
+ * the request type for the following request */
+ if (CPA_DC_FLUSH_FINAL == pCookie->flushFlag && cmpPass &&
+ xlatPass) {
+ pSessionDesc->requestType = DC_REQUEST_FIRST;
+ } else {
+ pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT;
+ }
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) ||
+ ((CPA_DC_STATELESS == pSessionDesc->sessState) &&
+ (DC_COMPRESSION_REQUEST == compDecomp))) {
+ /* Overflow is a valid use case for Traditional API
+ * only.
+ * Stateful Overflow is supported in both compression
+ * and
+ * decompression direction.
+ * Stateless Overflow is supported only in compression
+ * direction.
+ */
+ if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr)
+ cmpPass = CPA_TRUE;
+
+ if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) {
+ xlatPass = CPA_TRUE;
+ }
+ }
+ } else {
+ if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr) {
+ cmpPass = CPA_FALSE;
+ }
+ if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) {
+ xlatPass = CPA_FALSE;
+ }
+ }
+
+ if ((CPA_TRUE == cmpPass) && (CPA_TRUE == xlatPass)) {
+ /* Extract the response from the firmware */
+ pResults->consumed =
+ pCompRespMsg->comp_resp_pars.input_byte_counter;
+ pResults->produced =
+ pCompRespMsg->comp_resp_pars.output_byte_counter;
+ pSessionDesc->cumulativeConsumedBytes += pResults->consumed;
+
+ if (CPA_DC_OVERFLOW != (Cpa8S)xlatErr) {
+ if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
+ pResults->checksum =
+ pCompRespMsg->comp_resp_pars.crc.legacy
+ .curr_crc32;
+ } else if (CPA_DC_ADLER32 ==
+ pSessionDesc->checksumType) {
+ pResults->checksum =
+ pCompRespMsg->comp_resp_pars.crc.legacy
+ .curr_adler_32;
+ }
+ pSessionDesc->previousChecksum = pResults->checksum;
+ }
+
+ if (DC_DECOMPRESSION_REQUEST == compDecomp) {
+ pResults->endOfLastBlock =
+ (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));
+ }
+
+ /* Save the checksum for the next request */
+ if ((CPA_DC_OVERFLOW != (Cpa8S)xlatErr) &&
+ (CPA_TRUE == verifyHwIntegrityCrcs)) {
+ pSessionDesc->previousChecksum =
+ pSessionDesc->seedSwCrc.swCrcI;
+ }
+
+ /* Check if a CNV recovery happened and
+ * increase stats counter
+ */
+ if ((DC_COMPRESSION_REQUEST == compDecomp) &&
+ ICP_QAT_FW_COMN_HDR_CNV_FLAG_GET(hdrFlags) &&
+ ICP_QAT_FW_COMN_HDR_CNVNR_FLAG_GET(hdrFlags)) {
+ COMPRESSION_STAT_INC(numCompCnvErrorsRecovered,
+ pService);
+ }
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ if (pResponse)
+ pResponse->responseStatus = CPA_STATUS_SUCCESS;
+ } else {
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompCompleted,
+ pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompCompleted,
+ pService);
+ }
+ }
+ } else {
+ pResults->consumed = 0;
+ pResults->produced = 0;
+ if (CPA_DC_OVERFLOW == pResults->status &&
+ CPA_DC_STATELESS == pSessionDesc->sessState) {
+ /* This error message will be returned by Data Plane API
+ * in both
+ * compression and decompression direction. With
+ * Traditional API
+ * this error message will be returned only in stateless
+ * decompression direction */
+ QAT_UTILS_LOG(
+ "Unrecoverable error: stateless overflow. You may need to increase the size of your destination buffer.\n");
+ }
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ if (pResponse)
+ pResponse->responseStatus = CPA_STATUS_FAIL;
+ } else {
+ if (CPA_DC_OK != pResults->status &&
+ CPA_DC_INCOMPLETE_FILE_ERR != pResults->status) {
+ status = CPA_STATUS_FAIL;
+ }
+
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompCompletedErrors,
+ pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompCompletedErrors,
+ pService);
+ }
+ }
+ }
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ /* Decrement number of stateless pending callbacks for session
+ */
+ pSessionDesc->pendingDpStatelessCbCount--;
+ (pService->pDcDpCb)(pResponse);
+ } else {
+ /* Decrement number of pending callbacks for session */
+ if (CPA_DC_STATELESS == pSessionDesc->sessState) {
+ qatUtilsAtomicDec(
+ &(pCookie->pSessionDesc->pendingStatelessCbCount));
+ } else if (0 !=
+ qatUtilsAtomicGet(&pCookie->pSessionDesc
+ ->pendingStatefulCbCount)) {
+ qatUtilsAtomicDec(
+ &(pCookie->pSessionDesc->pendingStatefulCbCount));
+ }
+
+ /* Free the memory pool */
+ if (NULL != pCookie) {
+ Lac_MemPoolEntryFree(pCookie);
+ pCookie = NULL;
+ }
+
+ if (NULL != pCbFunc) {
+ pCbFunc(callbackTag, status);
+ }
+ }
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Check that all the parameters in the pOpData structure are valid
+ *
+ * @description
+ * Check that all the parameters in the pOpData structure are valid
+ *
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pOpData Pointer to request information structure
+ * holding parameters for cpaDcCompress2 and
+ * CpaDcDecompressData2
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCheckOpData(sal_compression_service_t *pService, CpaDcOpData *pOpData)
+{
+ CpaDcSkipMode skipMode = 0;
+
+ if ((pOpData->flushFlag < CPA_DC_FLUSH_NONE) ||
+ (pOpData->flushFlag > CPA_DC_FLUSH_FULL)) {
+ LAC_INVALID_PARAM_LOG("Invalid flushFlag value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ skipMode = pOpData->inputSkipData.skipMode;
+ if ((skipMode < CPA_DC_SKIP_DISABLED) ||
+ (skipMode > CPA_DC_SKIP_STRIDE)) {
+ LAC_INVALID_PARAM_LOG("Invalid input skip mode value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ skipMode = pOpData->outputSkipData.skipMode;
+ if ((skipMode < CPA_DC_SKIP_DISABLED) ||
+ (skipMode > CPA_DC_SKIP_STRIDE)) {
+ LAC_INVALID_PARAM_LOG("Invalid output skip mode value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->integrityCrcCheck == CPA_FALSE &&
+ pOpData->verifyHwIntegrityCrcs == CPA_TRUE) {
+ LAC_INVALID_PARAM_LOG(
+ "integrityCrcCheck must be set to true"
+ "in order to enable verifyHwIntegrityCrcs");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->integrityCrcCheck != CPA_TRUE &&
+ pOpData->integrityCrcCheck != CPA_FALSE) {
+ LAC_INVALID_PARAM_LOG("Invalid integrityCrcCheck value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->verifyHwIntegrityCrcs != CPA_TRUE &&
+ pOpData->verifyHwIntegrityCrcs != CPA_FALSE) {
+ LAC_INVALID_PARAM_LOG("Invalid verifyHwIntegrityCrcs value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->compressAndVerify != CPA_TRUE &&
+ pOpData->compressAndVerify != CPA_FALSE) {
+ LAC_INVALID_PARAM_LOG("Invalid cnv decompress check value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_TRUE == pOpData->integrityCrcCheck &&
+ CPA_FALSE == pService->generic_service_info.integrityCrcCheck) {
+ LAC_INVALID_PARAM_LOG("Integrity CRC check is not "
+ "supported on this device");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Check the compression source buffer for Batch and Pack API.
+ *
+ * @description
+ * Check that all the parameters used for Pack compression
+ * request are valid. This function essentially checks the source buffer
+ * parameters and results structure parameters.
+ *
+ * @param[in] pSessionHandle Session handle
+ * @param[in] pSrcBuff Pointer to data buffer for compression
+ * @param[in] pDestBuff Pointer to buffer space allocated for
+ * output data
+ * @param[in] pResults Pointer to results structure
+ * @param[in] flushFlag Indicates the type of flush to be
+ * performed
+ * @param[in] srcBuffSize Size of the source buffer
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCheckSourceData(CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ Cpa64U srcBuffSize,
+ CpaDcSkipData *skipData)
+{
+ dc_session_desc_t *pSessionDesc = NULL;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pSrcBuff);
+ LAC_CHECK_NULL_PARAM(pDestBuff);
+ LAC_CHECK_NULL_PARAM(pResults);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ if (NULL == pSessionDesc) {
+ LAC_INVALID_PARAM_LOG("Session handle not as expected");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((flushFlag < CPA_DC_FLUSH_NONE) ||
+ (flushFlag > CPA_DC_FLUSH_FULL)) {
+ LAC_INVALID_PARAM_LOG("Invalid flushFlag value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pSrcBuff == pDestBuff) {
+ LAC_INVALID_PARAM_LOG("In place operation not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Compressing zero bytes is not supported for stateless sessions
+ * for non Batch and Pack requests */
+ if ((CPA_DC_STATELESS == pSessionDesc->sessState) &&
+ (0 == srcBuffSize) && (NULL == skipData)) {
+ LAC_INVALID_PARAM_LOG(
+ "The source buffer size needs to be greater than "
+ "zero bytes for stateless sessions");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (srcBuffSize > DC_BUFFER_MAX_SIZE) {
+ LAC_INVALID_PARAM_LOG(
+ "The source buffer size needs to be less than or "
+ "equal to 2^32-1 bytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Check the compression or decompression function parameters.
+ *
+ * @description
+ * Check that all the parameters used for a Batch and Pack compression
+ * request are valid. This function essentially checks the destination
+ * buffer parameters and intermediate buffer parameters.
+ *
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pSessionHandle Session handle
+ * @param[in] pDestBuff Pointer to buffer space allocated for
+ * output data
+ * @param[in] compDecomp Direction of the operation
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCheckDestinationData(sal_compression_service_t *pService,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pDestBuff,
+ dc_request_dir_t compDecomp)
+{
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa64U destBuffSize = 0;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pDestBuff);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ if (NULL == pSessionDesc) {
+ LAC_INVALID_PARAM_LOG("Session handle not as expected");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (LacBuffDesc_BufferListVerify(pDestBuff,
+ &destBuffSize,
+ LAC_NO_ALIGNMENT_SHIFT) !=
+ CPA_STATUS_SUCCESS) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid destination buffer list parameter");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (destBuffSize > DC_BUFFER_MAX_SIZE) {
+ LAC_INVALID_PARAM_LOG(
+ "The destination buffer size needs to be less "
+ "than or equal to 2^32-1 bytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ LAC_INVALID_PARAM_LOG(
+ "The session type should not be data plane");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
+
+ /* Check if intermediate buffers are supported */
+ if ((0 == pService->pInterBuffPtrsArrayPhyAddr) ||
+ (NULL == pService->pInterBuffPtrsArray)) {
+ LAC_LOG_ERROR(
+ "No intermediate buffer defined for this instance "
+ "- see cpaDcStartInstance");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure that the destination buffer size is greater or
+ * equal to 128B */
+ if (destBuffSize < DC_DEST_BUFFER_DYN_MIN_SIZE) {
+ LAC_INVALID_PARAM_LOG(
+ "Destination buffer size should be "
+ "greater or equal to 128B");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else
+ {
+ /* Ensure that the destination buffer size is greater or
+ * equal to devices min output buff size */
+ if (destBuffSize <
+ pService->comp_device_data.minOutputBuffSize) {
+ LAC_INVALID_PARAM_LOG1(
+ "Destination buffer size should be "
+ "greater or equal to %d bytes",
+ pService->comp_device_data
+ .minOutputBuffSize);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ } else {
+ /* Ensure that the destination buffer size is greater than
+ * 0 bytes */
+ if (destBuffSize < DC_DEST_BUFFER_DEC_MIN_SIZE) {
+ LAC_INVALID_PARAM_LOG(
+ "Destination buffer size should be "
+ "greater than 0 bytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Populate the compression request parameters
+ *
+ * @description
+ * This function will populate the compression request parameters
+ *
+ * @param[out] pCompReqParams Pointer to the compression request parameters
+ * @param[in] pCookie Pointer to the compression cookie
+ *
+ *****************************************************************************/
+static void
+dcCompRequestParamsPopulate(icp_qat_fw_comp_req_params_t *pCompReqParams,
+ dc_compression_cookie_t *pCookie)
+{
+ pCompReqParams->comp_len = pCookie->srcTotalDataLenInBytes;
+ pCompReqParams->out_buffer_sz = pCookie->dstTotalDataLenInBytes;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Create the requests for compression or decompression
+ *
+ * @description
+ * Create the requests for compression or decompression. This function
+ * will update the cookie will all required information.
+ *
+ * @param{out] pCookie Pointer to the compression cookie
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in pSessionHandle Session handle
+ * @param[in] pSrcBuff Pointer to data buffer for compression
+ * @param[in] pDestBuff Pointer to buffer space for data after
+ * compression
+ * @param[in] pResults Pointer to results structure
+ * @param[in] flushFlag Indicates the type of flush to be
+ * performed
+ * @param[in] pOpData Pointer to request information structure
+ * holding parameters for cpaDcCompress2
+ * and CpaDcDecompressData2
+ * @param[in] callbackTag Pointer to the callback tag
+ * @param[in] compDecomp Direction of the operation
+ * @param[in] compressAndVerify Compress and Verify
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCreateRequest(dc_compression_cookie_t *pCookie,
+ sal_compression_service_t *pService,
+ dc_session_desc_t *pSessionDesc,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ CpaDcOpData *pOpData,
+ void *callbackTag,
+ dc_request_dir_t compDecomp,
+ dc_cnv_mode_t cnvMode)
+{
+ icp_qat_fw_comp_req_t *pMsg = NULL;
+ icp_qat_fw_comp_req_params_t *pCompReqParams = NULL;
+ Cpa64U srcAddrPhys = 0, dstAddrPhys = 0;
+ Cpa64U srcTotalDataLenInBytes = 0, dstTotalDataLenInBytes = 0;
+
+ Cpa32U rpCmdFlags = 0;
+ Cpa8U sop = ICP_QAT_FW_COMP_SOP;
+ Cpa8U eop = ICP_QAT_FW_COMP_EOP;
+ Cpa8U bFinal = ICP_QAT_FW_COMP_NOT_BFINAL;
+ Cpa8U crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY;
+ Cpa8U cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
+ Cpa8U cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
+ CpaBoolean integrityCrcCheck = CPA_FALSE;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaDcFlush flush = CPA_DC_FLUSH_NONE;
+ Cpa32U initial_adler = 1;
+ Cpa32U initial_crc32 = 0;
+ icp_qat_fw_comp_req_t *pReqCache = NULL;
+
+ /* Write the buffer descriptors */
+ status = LacBuffDesc_BufferListDescWriteAndGetSize(
+ pSrcBuff,
+ &srcAddrPhys,
+ CPA_FALSE,
+ &srcTotalDataLenInBytes,
+ &(pService->generic_service_info));
+ if (status != CPA_STATUS_SUCCESS) {
+ return status;
+ }
+
+ status = LacBuffDesc_BufferListDescWriteAndGetSize(
+ pDestBuff,
+ &dstAddrPhys,
+ CPA_FALSE,
+ &dstTotalDataLenInBytes,
+ &(pService->generic_service_info));
+ if (status != CPA_STATUS_SUCCESS) {
+ return status;
+ }
+
+ /* Populate the compression cookie */
+ pCookie->dcInstance = pService;
+ pCookie->pSessionHandle = pSessionHandle;
+ pCookie->callbackTag = callbackTag;
+ pCookie->pSessionDesc = pSessionDesc;
+ pCookie->pDcOpData = pOpData;
+ pCookie->pResults = pResults;
+ pCookie->compDecomp = compDecomp;
+ pCookie->pUserSrcBuff = NULL;
+ pCookie->pUserDestBuff = NULL;
+
+ /* Extract flush flag from either the opData or from the
+ * parameter. Opdata have been introduce with APIs
+ * cpaDcCompressData2 and cpaDcDecompressData2 */
+ if (NULL != pOpData) {
+ flush = pOpData->flushFlag;
+ integrityCrcCheck = pOpData->integrityCrcCheck;
+ } else {
+ flush = flushFlag;
+ }
+ pCookie->flushFlag = flush;
+
+ /* The firmware expects the length in bytes for source and destination
+ * to be Cpa32U parameters. However the total data length could be
+ * bigger as allocated by the user. We ensure that this is not the case
+ * in dcCheckSourceData and cast the values to Cpa32U here */
+ pCookie->srcTotalDataLenInBytes = (Cpa32U)srcTotalDataLenInBytes;
+ if ((DC_COMPRESSION_REQUEST == compDecomp) &&
+ (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) {
+ if (pService->minInterBuffSizeInBytes <
+ (Cpa32U)dstTotalDataLenInBytes) {
+ pCookie->dstTotalDataLenInBytes =
+ (Cpa32U)(pService->minInterBuffSizeInBytes);
+ } else {
+ pCookie->dstTotalDataLenInBytes =
+ (Cpa32U)dstTotalDataLenInBytes;
+ }
+ } else
+ {
+ pCookie->dstTotalDataLenInBytes =
+ (Cpa32U)dstTotalDataLenInBytes;
+ }
+
+ /* Device can not decompress an odd byte decompression request
+ * if bFinal is not set
+ */
+ if (CPA_TRUE != pService->comp_device_data.oddByteDecompNobFinal) {
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
+ (CPA_DC_FLUSH_FINAL != flushFlag) &&
+ (DC_DECOMPRESSION_REQUEST == compDecomp) &&
+ (pCookie->srcTotalDataLenInBytes & 0x1)) {
+ pCookie->srcTotalDataLenInBytes--;
+ }
+ }
+ /* Device can not decompress odd byte interim requests */
+ if (CPA_TRUE != pService->comp_device_data.oddByteDecompInterim) {
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
+ (CPA_DC_FLUSH_FINAL != flushFlag) &&
+ (CPA_DC_FLUSH_FULL != flushFlag) &&
+ (DC_DECOMPRESSION_REQUEST == compDecomp) &&
+ (pCookie->srcTotalDataLenInBytes & 0x1)) {
+ pCookie->srcTotalDataLenInBytes--;
+ }
+ }
+
+ pMsg = (icp_qat_fw_comp_req_t *)&pCookie->request;
+
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ pReqCache = &(pSessionDesc->reqCacheComp);
+ } else {
+ pReqCache = &(pSessionDesc->reqCacheDecomp);
+ }
+
+ /* Fills the msg from the template cached in the session descriptor */
+ memcpy((void *)pMsg,
+ (void *)(pReqCache),
+ LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES);
+
+ if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
+ initial_adler = 1;
+ initial_crc32 = 0;
+
+ if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ pSessionDesc->previousChecksum = 1;
+ } else {
+ pSessionDesc->previousChecksum = 0;
+ }
+ } else if (CPA_DC_STATELESS == pSessionDesc->sessState) {
+ pSessionDesc->previousChecksum = pResults->checksum;
+
+ if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ initial_adler = pSessionDesc->previousChecksum;
+ } else {
+ initial_crc32 = pSessionDesc->previousChecksum;
+ }
+ }
+
+ /* Backup source and destination buffer addresses,
+ * CRC calculations both for CNV and translator overflow
+ * will be performed on them in the callback function.
+ */
+ pCookie->pUserSrcBuff = pSrcBuff;
+ pCookie->pUserDestBuff = pDestBuff;
+
+ /*
+ * Due to implementation of CNV support and need for backwards
+ * compatibility certain fields in the request and response structs had
+ * been changed, moved or placed in unions cnvMode flag signifies fields
+ * to be selected from req/res
+ *
+ * Doing extended crc checks makes sense only when we want to do the
+ * actual CNV
+ */
+ if (CPA_TRUE == pService->generic_service_info.integrityCrcCheck &&
+ CPA_TRUE == integrityCrcCheck) {
+ pMsg->comp_pars.crc.crc_data_addr =
+ pSessionDesc->physDataIntegrityCrcs;
+ crcMode = ICP_QAT_FW_COMP_CRC_MODE_E2E;
+ } else {
+ /* Legacy request structure */
+ pMsg->comp_pars.crc.legacy.initial_adler = initial_adler;
+ pMsg->comp_pars.crc.legacy.initial_crc32 = initial_crc32;
+ crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY;
+ }
+
+ /* Populate the cmdFlags */
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ pSessionDesc->previousRequestType = pSessionDesc->requestType;
+
+ if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
+ /* Update the request type for following requests */
+ pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT;
+
+ /* Reinitialise the cumulative amount of consumed bytes
+ */
+ pSessionDesc->cumulativeConsumedBytes = 0;
+
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ pSessionDesc->isSopForCompressionProcessed =
+ CPA_TRUE;
+ } else if (DC_DECOMPRESSION_REQUEST == compDecomp) {
+ pSessionDesc->isSopForDecompressionProcessed =
+ CPA_TRUE;
+ }
+ } else {
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ if (CPA_TRUE ==
+ pSessionDesc
+ ->isSopForCompressionProcessed) {
+ sop = ICP_QAT_FW_COMP_NOT_SOP;
+ } else {
+ pSessionDesc
+ ->isSopForCompressionProcessed =
+ CPA_TRUE;
+ }
+ } else if (DC_DECOMPRESSION_REQUEST == compDecomp) {
+ if (CPA_TRUE ==
+ pSessionDesc
+ ->isSopForDecompressionProcessed) {
+ sop = ICP_QAT_FW_COMP_NOT_SOP;
+ } else {
+ pSessionDesc
+ ->isSopForDecompressionProcessed =
+ CPA_TRUE;
+ }
+ }
+ }
+
+ if ((CPA_DC_FLUSH_FINAL == flush) ||
+ (CPA_DC_FLUSH_FULL == flush)) {
+ /* Update the request type for following requests */
+ pSessionDesc->requestType = DC_REQUEST_FIRST;
+ } else {
+ eop = ICP_QAT_FW_COMP_NOT_EOP;
+ }
+ } else {
+
+ if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
+ /* Reinitialise the cumulative amount of consumed bytes
+ */
+ pSessionDesc->cumulativeConsumedBytes = 0;
+ }
+ }
+
+ /* (LW 14 - 15) */
+ pCompReqParams = &(pMsg->comp_pars);
+ dcCompRequestParamsPopulate(pCompReqParams, pCookie);
+ if (CPA_DC_FLUSH_FINAL == flush) {
+ bFinal = ICP_QAT_FW_COMP_BFINAL;
+ }
+
+ switch (cnvMode) {
+ case DC_CNVNR:
+ cnvRecovery = ICP_QAT_FW_COMP_CNV_RECOVERY;
+ /* Fall through is intended here, because for CNVNR
+ * cnvDecompReq also needs to be set */
+ case DC_CNV:
+ cnvDecompReq = ICP_QAT_FW_COMP_CNV;
+ break;
+ case DC_NO_CNV:
+ cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
+ cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
+ break;
+ }
+
+ /* LW 18 */
+ rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
+ sop, eop, bFinal, cnvDecompReq, cnvRecovery, crcMode);
+ pMsg->comp_pars.req_par_flags = rpCmdFlags;
+
+ /* Populates the QAT common request middle part of the message
+ * (LW 6 to 11) */
+ SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)pMsg,
+ pCookie,
+ DC_DEFAULT_QAT_PTR_TYPE,
+ srcAddrPhys,
+ dstAddrPhys,
+ 0,
+ 0);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Send a compression request to QAT
+ *
+ * @description
+ * Send the requests for compression or decompression to QAT
+ *
+ * @param{in] pCookie Pointer to the compression cookie
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in] compDecomp Direction of the operation
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcSendRequest(dc_compression_cookie_t *pCookie,
+ sal_compression_service_t *pService,
+ dc_session_desc_t *pSessionDesc,
+ dc_request_dir_t compDecomp)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* Send to QAT */
+ status = icp_adf_transPutMsg(pService->trans_handle_compression_tx,
+ (void *)&(pCookie->request),
+ LAC_QAT_DC_REQ_SZ_LW);
+
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
+ (CPA_STATUS_RETRY == status)) {
+ /* reset requestType after receiving an retry on
+ * the stateful request */
+ pSessionDesc->requestType = pSessionDesc->previousRequestType;
+ }
+
+ return status;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Process the synchronous and asynchronous case for compression or
+ * decompression
+ *
+ * @description
+ * Process the synchronous and asynchronous case for compression or
+ * decompression. This function will then create and send the request to
+ * the firmware.
+ *
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in] dcInstance Instance handle derived from discovery
+ * functions
+ * @param[in] pSessionHandle Session handle
+ * @param[in] numRequests Number of operations in the batch request
+ * @param[in] pBatchOpData Address of the list of jobs to be processed
+ * @param[in] pSrcBuff Pointer to data buffer for compression
+ * @param[in] pDestBuff Pointer to buffer space for data after
+ * compression
+ * @param[in] pResults Pointer to results structure
+ * @param[in] flushFlag Indicates the type of flush to be
+ * performed
+ * @param[in] pOpData Pointer to request information structure
+ * holding parameters for cpaDcCompress2 and
+ * CpaDcDecompressData2
+ * @param[in] callbackTag Pointer to the callback tag
+ * @param[in] compDecomp Direction of the operation
+ * @param[in] isAsyncMode Used to know if synchronous or asynchronous
+ * mode
+ * @param[in] cnvMode CNV Mode
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_RETRY Retry operation
+ * @retval CPA_STATUS_FAIL Function failed
+ * @retval CPA_STATUS_RESOURCE Resource error
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCompDecompData(sal_compression_service_t *pService,
+ dc_session_desc_t *pSessionDesc,
+ CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ CpaDcOpData *pOpData,
+ void *callbackTag,
+ dc_request_dir_t compDecomp,
+ CpaBoolean isAsyncMode,
+ dc_cnv_mode_t cnvMode)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ dc_compression_cookie_t *pCookie = NULL;
+
+ if ((LacSync_GenWakeupSyncCaller == pSessionDesc->pCompressionCb) &&
+ isAsyncMode == CPA_TRUE) {
+ lac_sync_op_data_t *pSyncCallbackData = NULL;
+
+ status = LacSync_CreateSyncCookie(&pSyncCallbackData);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = dcCompDecompData(pService,
+ pSessionDesc,
+ dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ pOpData,
+ pSyncCallbackData,
+ compDecomp,
+ CPA_FALSE,
+ cnvMode);
+ } else {
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ CpaStatus syncStatus = CPA_STATUS_SUCCESS;
+
+ syncStatus =
+ LacSync_WaitForCallback(pSyncCallbackData,
+ DC_SYNC_CALLBACK_TIMEOUT,
+ &status,
+ NULL);
+
+ /* If callback doesn't come back */
+ if (CPA_STATUS_SUCCESS != syncStatus) {
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(
+ numCompCompletedErrors, pService);
+ } else {
+ COMPRESSION_STAT_INC(
+ numDecompCompletedErrors, pService);
+ }
+ LAC_LOG_ERROR("Callback timed out");
+ status = syncStatus;
+ }
+ } else {
+ /* As the Request was not sent the Callback will never
+ * be called, so need to indicate that we're finished
+ * with cookie so it can be destroyed. */
+ LacSync_SetSyncCookieComplete(pSyncCallbackData);
+ }
+
+ LacSync_DestroySyncCookie(&pSyncCallbackData);
+ return status;
+ }
+
+ /* Allocate the compression cookie
+ * The memory is freed in callback or in sendRequest if an error occurs
+ */
+ pCookie = (dc_compression_cookie_t *)Lac_MemPoolEntryAlloc(
+ pService->compression_mem_pool);
+ if (NULL == pCookie) {
+ LAC_LOG_ERROR("Cannot get mem pool entry for compression");
+ status = CPA_STATUS_RESOURCE;
+ } else if ((void *)CPA_STATUS_RETRY == pCookie) {
+ pCookie = NULL;
+ status = CPA_STATUS_RETRY;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = dcCreateRequest(pCookie,
+ pService,
+ pSessionDesc,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ pOpData,
+ callbackTag,
+ compDecomp,
+ cnvMode);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Increment number of pending callbacks for session */
+ if (CPA_DC_STATELESS == pSessionDesc->sessState) {
+ qatUtilsAtomicInc(
+ &(pSessionDesc->pendingStatelessCbCount));
+ }
+ status =
+ dcSendRequest(pCookie, pService, pSessionDesc, compDecomp);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompRequests, pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompRequests, pService);
+ }
+ } else {
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompRequestsErrors, pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompRequestsErrors, pService);
+ }
+
+ /* Decrement number of pending callbacks for session */
+ if (CPA_DC_STATELESS == pSessionDesc->sessState) {
+ qatUtilsAtomicDec(
+ &(pSessionDesc->pendingStatelessCbCount));
+ } else {
+ qatUtilsAtomicDec(
+ &(pSessionDesc->pendingStatefulCbCount));
+ }
+
+ /* Free the memory pool */
+ if (NULL != pCookie) {
+ if (status != CPA_STATUS_UNSUPPORTED) {
+ /* Free the memory pool */
+ Lac_MemPoolEntryFree(pCookie);
+ pCookie = NULL;
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Handle zero length compression or decompression requests
+ *
+ * @description
+ * Handle zero length compression or decompression requests
+ *
+ * @param[in] pService Pointer to the compression service
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in] pResults Pointer to results structure
+ * @param[in] flushFlag Indicates the type of flush to be
+ * performed
+ * @param[in] callbackTag User supplied value to help correlate
+ * the callback with its associated request
+ * @param[in] compDecomp Direction of the operation
+ *
+ * @retval CPA_TRUE Zero length SOP or MOP processed
+ * @retval CPA_FALSE Zero length EOP
+ *
+ *****************************************************************************/
+static CpaStatus
+dcZeroLengthRequests(sal_compression_service_t *pService,
+ dc_session_desc_t *pSessionDesc,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ void *callbackTag,
+ dc_request_dir_t compDecomp)
+{
+ CpaBoolean status = CPA_FALSE;
+ CpaDcCallbackFn pCbFunc = pSessionDesc->pCompressionCb;
+
+ if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
+ /* Reinitialise the cumulative amount of consumed bytes */
+ pSessionDesc->cumulativeConsumedBytes = 0;
+
+ /* Zero length SOP */
+ if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ pResults->checksum = 1;
+ } else {
+ pResults->checksum = 0;
+ }
+
+ status = CPA_TRUE;
+ } else if ((CPA_DC_FLUSH_NONE == flushFlag) ||
+ (CPA_DC_FLUSH_SYNC == flushFlag)) {
+ /* Zero length MOP */
+ pResults->checksum = pSessionDesc->previousChecksum;
+ status = CPA_TRUE;
+ }
+
+ if (CPA_TRUE == status) {
+ pResults->status = CPA_DC_OK;
+ pResults->produced = 0;
+ pResults->consumed = 0;
+
+ /* Increment statistics */
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ COMPRESSION_STAT_INC(numCompRequests, pService);
+ COMPRESSION_STAT_INC(numCompCompleted, pService);
+ } else {
+ COMPRESSION_STAT_INC(numDecompRequests, pService);
+ COMPRESSION_STAT_INC(numDecompCompleted, pService);
+ }
+
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+
+ if ((NULL != pCbFunc) &&
+ (LacSync_GenWakeupSyncCaller != pCbFunc)) {
+ pCbFunc(callbackTag, CPA_STATUS_SUCCESS);
+ }
+
+ return CPA_TRUE;
+ }
+
+ return CPA_FALSE;
+}
+
+static CpaStatus
+dcParamCheck(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ sal_compression_service_t *pService,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ dc_session_desc_t *pSessionDesc,
+ CpaDcFlush flushFlag,
+ Cpa64U srcBuffSize)
+{
+
+ if (dcCheckSourceData(pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ srcBuffSize,
+ NULL) != CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (dcCheckDestinationData(
+ pService, pSessionHandle, pDestBuff, DC_COMPRESSION_REQUEST) !=
+ CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
+ LAC_INVALID_PARAM_LOG("Invalid sessDirection value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcCompressData(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ void *callbackTag)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ Cpa64U srcBuffSize = 0;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(insHandle);
+
+ /* This check is outside the parameter checking as it is needed to
+ * manage zero length requests */
+ if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
+ &srcBuffSize,
+ LAC_NO_ALIGNMENT_SHIFT) !=
+ CPA_STATUS_SUCCESS) {
+ LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ if (CPA_STATUS_SUCCESS !=
+ dcParamCheck(insHandle,
+ pSessionHandle,
+ pService,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pSessionDesc,
+ flushFlag,
+ srcBuffSize)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid session state, stateful sessions "
+ "are not supported");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if (!(pService->generic_service_info.dcExtendedFeatures &
+ DC_CNV_EXTENDED_CAPABILITY)) {
+ LAC_INVALID_PARAM_LOG(
+ "CompressAndVerify feature not supported");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if (!(pService->generic_service_info.dcExtendedFeatures &
+ DC_CNVNR_EXTENDED_CAPABILITY)) {
+ LAC_INVALID_PARAM_LOG(
+ "CompressAndVerifyAndRecovery feature not supported");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ return dcCompDecompData(pService,
+ pSessionDesc,
+ dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ NULL,
+ callbackTag,
+ DC_COMPRESSION_REQUEST,
+ CPA_TRUE,
+ DC_CNVNR);
+}
+
+CpaStatus
+cpaDcCompressData2(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcOpData *pOpData,
+ CpaDcRqResults *pResults,
+ void *callbackTag)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ Cpa64U srcBuffSize = 0;
+ dc_cnv_mode_t cnvMode = DC_NO_CNV;
+
+ LAC_CHECK_NULL_PARAM(pOpData);
+
+ if (((CPA_TRUE != pOpData->compressAndVerify) &&
+ (CPA_FALSE != pOpData->compressAndVerify)) ||
+ ((CPA_FALSE != pOpData->compressAndVerifyAndRecover) &&
+ (CPA_TRUE != pOpData->compressAndVerifyAndRecover))) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((CPA_FALSE == pOpData->compressAndVerify) &&
+ (CPA_TRUE == pOpData->compressAndVerifyAndRecover)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+
+ if ((CPA_TRUE == pOpData->compressAndVerify) &&
+ (CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
+ (CPA_FALSE == pOpData->integrityCrcCheck)) {
+ return cpaDcCompressData(dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pOpData->flushFlag,
+ callbackTag);
+ }
+
+ if (CPA_FALSE == pOpData->compressAndVerify) {
+ LAC_INVALID_PARAM_LOG(
+ "Data compression without verification not allowed");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pOpData);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(insHandle);
+
+ /* This check is outside the parameter checking as it is needed to
+ * manage zero length requests */
+ if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
+ &srcBuffSize,
+ LAC_NO_ALIGNMENT_SHIFT) !=
+ CPA_STATUS_SUCCESS) {
+ LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (CPA_TRUE == pOpData->compressAndVerify &&
+ CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid session state, stateful sessions "
+ "not supported with CNV");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if (!(pService->generic_service_info.dcExtendedFeatures &
+ DC_CNV_EXTENDED_CAPABILITY) &&
+ (CPA_TRUE == pOpData->compressAndVerify)) {
+ LAC_INVALID_PARAM_LOG(
+ "CompressAndVerify feature not supported");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if (CPA_STATUS_SUCCESS !=
+ dcParamCheck(insHandle,
+ pSessionHandle,
+ pService,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pSessionDesc,
+ pOpData->flushFlag,
+ srcBuffSize)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (CPA_STATUS_SUCCESS != dcCheckOpData(pService, pOpData)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (CPA_TRUE != pOpData->compressAndVerify) {
+ if (srcBuffSize > DC_COMP_MAX_BUFF_SIZE) {
+ LAC_LOG_ERROR(
+ "Compression payload greater than 64KB is "
+ "unsupported, when CnV is disabled\n");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+ }
+
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ /* Lock the session to check if there are in-flight stateful
+ * requests */
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+
+ /* Check if there is already one in-flight stateful request */
+ if (0 !=
+ qatUtilsAtomicGet(
+ &(pSessionDesc->pendingStatefulCbCount))) {
+ LAC_LOG_ERROR(
+ "Only one in-flight stateful request supported");
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+ return CPA_STATUS_RETRY;
+ }
+
+ if (0 == srcBuffSize) {
+ if (CPA_TRUE ==
+ dcZeroLengthRequests(pService,
+ pSessionDesc,
+ pResults,
+ pOpData->flushFlag,
+ callbackTag,
+ DC_COMPRESSION_REQUEST)) {
+ return CPA_STATUS_SUCCESS;
+ }
+ }
+
+ qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount));
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+ }
+
+ if (CPA_TRUE == pOpData->compressAndVerify) {
+ cnvMode = DC_CNV;
+ }
+
+ return dcCompDecompData(pService,
+ pSessionDesc,
+ dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pOpData->flushFlag,
+ pOpData,
+ callbackTag,
+ DC_COMPRESSION_REQUEST,
+ CPA_TRUE,
+ cnvMode);
+}
+
+static CpaStatus
+dcDecompressDataCheck(CpaInstanceHandle insHandle,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ Cpa64U *srcBufferSize)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa64U srcBuffSize = 0;
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(insHandle);
+
+ /* This check is outside the parameter checking as it is needed to
+ * manage zero length requests */
+ if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
+ &srcBuffSize,
+ LAC_NO_ALIGNMENT_SHIFT) !=
+ CPA_STATUS_SUCCESS) {
+ LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ if (dcCheckSourceData(pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ srcBuffSize,
+ NULL) != CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (dcCheckDestinationData(pService,
+ pSessionHandle,
+ pDestBuff,
+ DC_DECOMPRESSION_REQUEST) !=
+ CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) {
+ LAC_INVALID_PARAM_LOG("Invalid sessDirection value");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+
+ *srcBufferSize = srcBuffSize;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcDecompressData(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcRqResults *pResults,
+ CpaDcFlush flushFlag,
+ void *callbackTag)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ Cpa64U srcBuffSize = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ status = dcDecompressDataCheck(insHandle,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ &srcBuffSize);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ /* Lock the session to check if there are in-flight stateful
+ * requests */
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot lock session lock");
+ return CPA_STATUS_RESOURCE;
+ }
+
+ /* Check if there is already one in-flight stateful request */
+ if (0 !=
+ qatUtilsAtomicGet(
+ &(pSessionDesc->pendingStatefulCbCount))) {
+ LAC_LOG_ERROR(
+ "Only one in-flight stateful request supported");
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+ return CPA_STATUS_RETRY;
+ }
+
+ if ((0 == srcBuffSize) ||
+ ((1 == srcBuffSize) && (CPA_DC_FLUSH_FINAL != flushFlag) &&
+ (CPA_DC_FLUSH_FULL != flushFlag))) {
+ if (CPA_TRUE ==
+ dcZeroLengthRequests(pService,
+ pSessionDesc,
+ pResults,
+ flushFlag,
+ callbackTag,
+ DC_DECOMPRESSION_REQUEST)) {
+ return CPA_STATUS_SUCCESS;
+ }
+ }
+
+ qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount));
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&(pSessionDesc->sessionLock))) {
+ LAC_LOG_ERROR("Cannot unlock session lock");
+ }
+ }
+
+ return dcCompDecompData(pService,
+ pSessionDesc,
+ dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ flushFlag,
+ NULL,
+ callbackTag,
+ DC_DECOMPRESSION_REQUEST,
+ CPA_TRUE,
+ DC_NO_CNV);
+}
+
+CpaStatus
+cpaDcDecompressData2(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaBufferList *pSrcBuff,
+ CpaBufferList *pDestBuff,
+ CpaDcOpData *pOpData,
+ CpaDcRqResults *pResults,
+ void *callbackTag)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa64U srcBuffSize = 0;
+ LAC_CHECK_NULL_PARAM(pOpData);
+
+ if (CPA_FALSE == pOpData->integrityCrcCheck) {
+
+ return cpaDcDecompressData(dcInstance,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pOpData->flushFlag,
+ callbackTag);
+ }
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ status = dcDecompressDataCheck(insHandle,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pOpData->flushFlag,
+ &srcBuffSize);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ LAC_INVALID_PARAM_LOG("Invalid session: Stateful session is "
+ "not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ return dcCompDecompData(pService,
+ pSessionDesc,
+ insHandle,
+ pSessionHandle,
+ pSrcBuff,
+ pDestBuff,
+ pResults,
+ pOpData->flushFlag,
+ pOpData,
+ callbackTag,
+ DC_DECOMPRESSION_REQUEST,
+ CPA_TRUE,
+ DC_NO_CNV);
+}
diff --git a/sys/dev/qat/qat_api/common/compression/dc_dp.c b/sys/dev/qat/qat_api/common/compression/dc_dp.c
new file mode 100644
index 000000000000..4a24bf17dc32
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_dp.c
@@ -0,0 +1,545 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_dp.c
+ *
+ * @defgroup cpaDcDp Data Compression Data Plane API
+ *
+ * @ingroup cpaDcDp
+ *
+ * @description
+ * Implementation of the Data Compression DP operations.
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_dc.h"
+#include "cpa_dc_dp.h"
+
+#include "icp_qat_fw_comp.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "dc_session.h"
+#include "dc_datapath.h"
+#include "lac_common.h"
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "sal_types_compression.h"
+#include "lac_sal.h"
+#include "lac_sync.h"
+#include "sal_service_state.h"
+#include "sal_qat_cmn_msg.h"
+#include "icp_sal_poll.h"
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcDp
+ * Check that pOpData is valid
+ *
+ * @description
+ * Check that all the parameters defined in the pOpData are valid
+ *
+ * @param[in] pOpData Pointer to a structure containing the
+ * request parameters
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+dcDataPlaneParamCheck(const CpaDcDpOpData *pOpData)
+{
+ sal_compression_service_t *pService = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+
+ LAC_CHECK_NULL_PARAM(pOpData);
+ LAC_CHECK_NULL_PARAM(pOpData->dcInstance);
+ LAC_CHECK_NULL_PARAM(pOpData->pSessionHandle);
+
+ /* Ensure this is a compression instance */
+ SAL_CHECK_INSTANCE_TYPE(pOpData->dcInstance,
+ SAL_SERVICE_TYPE_COMPRESSION);
+
+ pService = (sal_compression_service_t *)(pOpData->dcInstance);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
+ if (NULL == pSessionDesc) {
+ QAT_UTILS_LOG("Session handle not as expected.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_FALSE == pSessionDesc->isDcDp) {
+ QAT_UTILS_LOG("The session type should be data plane.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Compressing zero byte is not supported */
+ if ((CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) &&
+ (0 == pOpData->bufferLenToCompress)) {
+ QAT_UTILS_LOG(
+ "The source buffer length to compress needs to be greater than zero byte.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->sessDirection > CPA_DC_DIR_DECOMPRESS) {
+ QAT_UTILS_LOG("Invalid direction of operation.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (0 == pOpData->srcBuffer) {
+ QAT_UTILS_LOG("Invalid srcBuffer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pOpData->destBuffer) {
+ QAT_UTILS_LOG("Invalid destBuffer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (pOpData->srcBuffer == pOpData->destBuffer) {
+ QAT_UTILS_LOG("In place operation is not supported.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pOpData->thisPhys) {
+ QAT_UTILS_LOG("Invalid thisPhys\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((CPA_TRUE != pOpData->compressAndVerify) &&
+ (CPA_FALSE != pOpData->compressAndVerify)) {
+ QAT_UTILS_LOG("Invalid compressAndVerify\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if ((CPA_TRUE == pOpData->compressAndVerify) &&
+ !(pService->generic_service_info.dcExtendedFeatures &
+ DC_CNV_EXTENDED_CAPABILITY)) {
+ QAT_UTILS_LOG("Invalid compressAndVerify, no CNV capability\n");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+ if ((CPA_TRUE != pOpData->compressAndVerifyAndRecover) &&
+ (CPA_FALSE != pOpData->compressAndVerifyAndRecover)) {
+ QAT_UTILS_LOG("Invalid compressAndVerifyAndRecover\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if ((CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
+ (CPA_FALSE == pOpData->compressAndVerify)) {
+ QAT_UTILS_LOG("CnVnR option set without setting CnV\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if ((CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
+ !(pService->generic_service_info.dcExtendedFeatures &
+ DC_CNVNR_EXTENDED_CAPABILITY)) {
+ QAT_UTILS_LOG(
+ "Invalid CnVnR option set and no CnVnR capability.\n");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if ((CPA_DP_BUFLIST == pOpData->srcBufferLen) &&
+ (CPA_DP_BUFLIST != pOpData->destBufferLen)) {
+ QAT_UTILS_LOG(
+ "The source and destination buffers need to be of the same type (both flat buffers or buffer lists).\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if ((CPA_DP_BUFLIST != pOpData->srcBufferLen) &&
+ (CPA_DP_BUFLIST == pOpData->destBufferLen)) {
+ QAT_UTILS_LOG(
+ "The source and destination buffers need to be of the same type (both flat buffers or buffer lists).\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_DP_BUFLIST != pOpData->srcBufferLen) {
+ if (pOpData->srcBufferLen < pOpData->bufferLenToCompress) {
+ QAT_UTILS_LOG(
+ "srcBufferLen is smaller than bufferLenToCompress.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData->destBufferLen < pOpData->bufferLenForData) {
+ QAT_UTILS_LOG(
+ "destBufferLen is smaller than bufferLenForData.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ /* We are assuming that there is enough memory in the source and
+ * destination buffer lists. We only receive physical addresses
+ * of the
+ * buffers so we are unable to test it here */
+ LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->srcBuffer);
+ LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->destBuffer);
+ }
+
+ LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->thisPhys);
+
+ if ((CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) ||
+ (CPA_DC_DIR_COMBINED == pSessionDesc->sessDirection)) {
+ if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
+ /* Check if Intermediate Buffer Array pointer is NULL */
+ if ((0 == pService->pInterBuffPtrsArrayPhyAddr) ||
+ (NULL == pService->pInterBuffPtrsArray)) {
+ QAT_UTILS_LOG(
+ "No intermediate buffer defined for this instance - see cpaDcStartInstance.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure that the destination buffer length for data is
+ * greater
+ * or equal to 128B */
+ if (pOpData->bufferLenForData <
+ DC_DEST_BUFFER_DYN_MIN_SIZE) {
+ QAT_UTILS_LOG(
+ "Destination buffer length for data should be greater or equal to 128B.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ /* Ensure that the destination buffer length for data is
+ * greater
+ * or equal to min output buffsize */
+ if (pOpData->bufferLenForData <
+ pService->comp_device_data.minOutputBuffSize) {
+ QAT_UTILS_LOG(
+ "Destination buffer size should be greater or equal to %d bytes.\n",
+ pService->comp_device_data
+ .minOutputBuffSize);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcDpGetSessionSize(CpaInstanceHandle dcInstance,
+ CpaDcSessionSetupData *pSessionData,
+ Cpa32U *pSessionSize)
+{
+ return dcGetSessionSize(dcInstance, pSessionData, pSessionSize, NULL);
+}
+
+CpaStatus
+cpaDcDpInitSession(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaDcSessionSetupData *pSessionData)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ dc_session_desc_t *pSessionDesc = NULL;
+ sal_compression_service_t *pService = NULL;
+
+ LAC_CHECK_INSTANCE_HANDLE(dcInstance);
+ SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
+
+ pService = (sal_compression_service_t *)dcInstance;
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(pService);
+
+ /* Stateful is not supported */
+ if (CPA_DC_STATELESS != pSessionData->sessState) {
+ QAT_UTILS_LOG("Invalid sessState value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ status =
+ dcInitSession(dcInstance, pSessionHandle, pSessionData, NULL, NULL);
+ if (CPA_STATUS_SUCCESS == status) {
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ pSessionDesc->isDcDp = CPA_TRUE;
+
+ ICP_QAT_FW_COMN_PTR_TYPE_SET(
+ pSessionDesc->reqCacheDecomp.comn_hdr.comn_req_flags,
+ DC_DP_QAT_PTR_TYPE);
+ ICP_QAT_FW_COMN_PTR_TYPE_SET(
+ pSessionDesc->reqCacheComp.comn_hdr.comn_req_flags,
+ DC_DP_QAT_PTR_TYPE);
+ }
+
+ return status;
+}
+
+CpaStatus
+cpaDcDpRemoveSession(const CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle)
+{
+ return cpaDcRemoveSession(dcInstance, pSessionHandle);
+}
+
+CpaStatus
+cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance,
+ const CpaDcDpCallbackFn pNewCb)
+{
+ sal_compression_service_t *pService = NULL;
+
+ LAC_CHECK_NULL_PARAM(dcInstance);
+ SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
+ LAC_CHECK_NULL_PARAM(pNewCb);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(dcInstance);
+
+ pService = (sal_compression_service_t *)dcInstance;
+ pService->pDcDpCb = pNewCb;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup cpaDcDp
+ *
+ * @description
+ * Writes the message to the ring
+ *
+ * @param[in] pOpData Pointer to a structure containing the
+ * request parameters
+ * @param[in] pCurrentQatMsg Pointer to current QAT message on the ring
+ *
+ *****************************************************************************/
+static void
+dcDpWriteRingMsg(CpaDcDpOpData *pOpData, icp_qat_fw_comp_req_t *pCurrentQatMsg)
+{
+ icp_qat_fw_comp_req_t *pReqCache = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa8U bufferFormat;
+
+ Cpa8U cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
+ Cpa8U cnvnrCompReq = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
+
+ if (CPA_DC_DIR_COMPRESS == pOpData->sessDirection) {
+ pReqCache = &(pSessionDesc->reqCacheComp);
+ /* CNV check */
+ if (CPA_TRUE == pOpData->compressAndVerify) {
+ cnvDecompReq = ICP_QAT_FW_COMP_CNV;
+ /* CNVNR check */
+ if (CPA_TRUE == pOpData->compressAndVerifyAndRecover) {
+ cnvnrCompReq = ICP_QAT_FW_COMP_CNV_RECOVERY;
+ }
+ }
+ } else {
+ pReqCache = &(pSessionDesc->reqCacheDecomp);
+ }
+
+ /* Fills in the template DC ET ring message - cached from the
+ * session descriptor */
+ memcpy((void *)pCurrentQatMsg,
+ (void *)(pReqCache),
+ (LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES));
+
+ if (CPA_DP_BUFLIST == pOpData->srcBufferLen) {
+ bufferFormat = QAT_COMN_PTR_TYPE_SGL;
+ } else {
+ bufferFormat = QAT_COMN_PTR_TYPE_FLAT;
+ }
+
+ pCurrentQatMsg->comp_pars.req_par_flags |=
+ ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
+ 0, 0, 0, cnvDecompReq, cnvnrCompReq, 0);
+
+ SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)pCurrentQatMsg,
+ pOpData,
+ bufferFormat,
+ pOpData->srcBuffer,
+ pOpData->destBuffer,
+ pOpData->srcBufferLen,
+ pOpData->destBufferLen);
+
+ pCurrentQatMsg->comp_pars.comp_len = pOpData->bufferLenToCompress;
+ pCurrentQatMsg->comp_pars.out_buffer_sz = pOpData->bufferLenForData;
+}
+
+CpaStatus
+cpaDcDpEnqueueOp(CpaDcDpOpData *pOpData, const CpaBoolean performOpNow)
+{
+ icp_qat_fw_comp_req_t *pCurrentQatMsg = NULL;
+ icp_comms_trans_handle trans_handle = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ status = dcDataPlaneParamCheck(pOpData);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ if ((CPA_FALSE == pOpData->compressAndVerify) &&
+ (CPA_DC_DIR_COMPRESS == pOpData->sessDirection)) {
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(pOpData->dcInstance);
+
+ trans_handle = ((sal_compression_service_t *)pOpData->dcInstance)
+ ->trans_handle_compression_tx;
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
+
+ if ((CPA_DC_DIR_COMPRESS == pOpData->sessDirection) &&
+ (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection)) {
+ QAT_UTILS_LOG(
+ "The session does not support this direction of operation.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ } else if ((CPA_DC_DIR_DECOMPRESS == pOpData->sessDirection) &&
+ (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection)) {
+ QAT_UTILS_LOG(
+ "The session does not support this direction of operation.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ icp_adf_getSingleQueueAddr(trans_handle, (void **)&pCurrentQatMsg);
+ if (NULL == pCurrentQatMsg) {
+ return CPA_STATUS_RETRY;
+ }
+
+ dcDpWriteRingMsg(pOpData, pCurrentQatMsg);
+ pSessionDesc->pendingDpStatelessCbCount++;
+
+ if (CPA_TRUE == performOpNow) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcDpEnqueueOpBatch(const Cpa32U numberRequests,
+ CpaDcDpOpData *pOpData[],
+ const CpaBoolean performOpNow)
+{
+ icp_qat_fw_comp_req_t *pCurrentQatMsg = NULL;
+ icp_comms_trans_handle trans_handle = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa32U i = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_compression_service_t *pService = NULL;
+
+ LAC_CHECK_NULL_PARAM(pOpData);
+ LAC_CHECK_NULL_PARAM(pOpData[0]);
+ LAC_CHECK_NULL_PARAM(pOpData[0]->dcInstance);
+
+ pService = (sal_compression_service_t *)(pOpData[0]->dcInstance);
+ if ((numberRequests == 0) ||
+ (numberRequests > pService->maxNumCompConcurrentReq)) {
+ QAT_UTILS_LOG(
+ "The number of requests needs to be between 1 and %d.\n",
+ pService->maxNumCompConcurrentReq);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ for (i = 0; i < numberRequests; i++) {
+ status = dcDataPlaneParamCheck(pOpData[i]);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ /* Check that all instance handles and session handles are the
+ * same */
+ if (pOpData[i]->dcInstance != pOpData[0]->dcInstance) {
+ QAT_UTILS_LOG(
+ "All instance handles should be the same in the pOpData.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pOpData[i]->pSessionHandle != pOpData[0]->pSessionHandle) {
+ QAT_UTILS_LOG(
+ "All session handles should be the same in the pOpData.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ for (i = 0; i < numberRequests; i++) {
+ if ((CPA_FALSE == pOpData[i]->compressAndVerify) &&
+ (CPA_DC_DIR_COMPRESS == pOpData[i]->sessDirection)) {
+ return CPA_STATUS_UNSUPPORTED;
+ }
+ }
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(pOpData[0]->dcInstance);
+
+ trans_handle = ((sal_compression_service_t *)pOpData[0]->dcInstance)
+ ->trans_handle_compression_tx;
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData[0]->pSessionHandle);
+
+ for (i = 0; i < numberRequests; i++) {
+ if ((CPA_DC_DIR_COMPRESS == pOpData[i]->sessDirection) &&
+ (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection)) {
+ QAT_UTILS_LOG(
+ "The session does not support this direction of operation.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ } else if ((CPA_DC_DIR_DECOMPRESS ==
+ pOpData[i]->sessDirection) &&
+ (CPA_DC_DIR_COMPRESS ==
+ pSessionDesc->sessDirection)) {
+ QAT_UTILS_LOG(
+ "The session does not support this direction of operation.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ icp_adf_getQueueMemory(trans_handle,
+ numberRequests,
+ (void **)&pCurrentQatMsg);
+ if (NULL == pCurrentQatMsg) {
+ return CPA_STATUS_RETRY;
+ }
+
+ for (i = 0; i < numberRequests; i++) {
+ dcDpWriteRingMsg(pOpData[i], pCurrentQatMsg);
+ icp_adf_getQueueNext(trans_handle, (void **)&pCurrentQatMsg);
+ }
+
+ pSessionDesc->pendingDpStatelessCbCount += numberRequests;
+
+ if (CPA_TRUE == performOpNow) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+icp_sal_DcPollDpInstance(CpaInstanceHandle dcInstance, Cpa32U responseQuota)
+{
+ icp_comms_trans_handle trans_handle = NULL;
+
+ LAC_CHECK_INSTANCE_HANDLE(dcInstance);
+ SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(dcInstance);
+
+ trans_handle = ((sal_compression_service_t *)dcInstance)
+ ->trans_handle_compression_rx;
+
+ return icp_adf_pollQueue(trans_handle, responseQuota);
+}
+
+CpaStatus
+cpaDcDpPerformOpNow(CpaInstanceHandle dcInstance)
+{
+ icp_comms_trans_handle trans_handle = NULL;
+
+ LAC_CHECK_NULL_PARAM(dcInstance);
+ SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(dcInstance);
+
+ trans_handle = ((sal_compression_service_t *)dcInstance)
+ ->trans_handle_compression_tx;
+
+ if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/compression/dc_header_footer.c b/sys/dev/qat/qat_api/common/compression/dc_header_footer.c
new file mode 100644
index 000000000000..4a92e20ba0f4
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_header_footer.c
@@ -0,0 +1,237 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_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 "icp_adf_init.h"
+
+/*
+ *******************************************************************************
+ * Include private header files
+ *******************************************************************************
+ */
+#include "dc_header_footer.h"
+#include "dc_session.h"
+#include "dc_datapath.h"
+
+CpaStatus
+cpaDcGenerateHeader(CpaDcSessionHandle pSessionHandle,
+ CpaFlatBuffer *pDestBuff,
+ Cpa32U *count)
+{
+ dc_session_desc_t *pSessionDesc = NULL;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pDestBuff);
+ LAC_CHECK_NULL_PARAM(pDestBuff->pData);
+ LAC_CHECK_NULL_PARAM(count);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (NULL == pSessionDesc) {
+ QAT_UTILS_LOG("Session handle not as expected\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
+ QAT_UTILS_LOG("Invalid session direction\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_DC_DEFLATE == pSessionDesc->compType) {
+ /* Adding a Gzip header */
+ if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
+ Cpa8U *pDest = pDestBuff->pData;
+
+ if (pDestBuff->dataLenInBytes < DC_GZIP_HEADER_SIZE) {
+ QAT_UTILS_LOG(
+ "The dataLenInBytes of the dest buffer is too small.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ pDest[0] = DC_GZIP_ID1; /* ID1 */
+ pDest[1] = DC_GZIP_ID2; /* ID2 */
+ pDest[2] =
+ 0x08; /* CM = 8 denotes "deflate" compression */
+ pDest[3] = 0x00; /* FLG = 0 denotes "No extra fields" */
+ pDest[4] = 0x00;
+ pDest[5] = 0x00;
+ pDest[6] = 0x00;
+ pDest[7] = 0x00; /* MTIME = 0x00 means time stamp not
+ available */
+
+ /* XFL = 4 - compressor used fastest compression, */
+ /* XFL = 2 - compressor used maximum compression. */
+ pDest[8] = 0;
+ if (CPA_DC_L1 == pSessionDesc->compLevel)
+ pDest[8] = DC_GZIP_FAST_COMP;
+ else if (CPA_DC_L4 >= pSessionDesc->compLevel)
+ pDest[8] = DC_GZIP_MAX_COMP;
+
+ pDest[9] =
+ DC_GZIP_FILESYSTYPE; /* OS = 0 means FAT filesystem
+ (MS-DOS, OS/2, NT/Win32), 3 - Unix */
+
+ /* Set to the number of bytes added to the buffer */
+ *count = DC_GZIP_HEADER_SIZE;
+ }
+
+ /* Adding a Zlib header */
+ else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ Cpa8U *pDest = pDestBuff->pData;
+ Cpa16U header = 0, level = 0;
+
+ if (pDestBuff->dataLenInBytes < DC_ZLIB_HEADER_SIZE) {
+ QAT_UTILS_LOG(
+ "The dataLenInBytes of the dest buffer is too small.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* CMF = CM | CMINFO.
+ CM = 8 denotes "deflate" compression,
+ CMINFO = 7 indicates a 32K window size */
+ /* Depending on the device, at compression levels above
+ L1, the
+ window size can be 8 or 16K bytes.
+ The file will decompress ok if a greater window size
+ is specified
+ in the header. */
+ header =
+ (DC_ZLIB_CM_DEFLATE +
+ (DC_32K_WINDOW_SIZE << DC_ZLIB_WINDOWSIZE_OFFSET))
+ << LAC_NUM_BITS_IN_BYTE;
+
+ switch (pSessionDesc->compLevel) {
+ case CPA_DC_L1:
+ level = DC_ZLIB_LEVEL_0;
+ break;
+ case CPA_DC_L2:
+ level = DC_ZLIB_LEVEL_1;
+ break;
+ case CPA_DC_L3:
+ level = DC_ZLIB_LEVEL_2;
+ break;
+ default:
+ level = DC_ZLIB_LEVEL_3;
+ }
+
+ /* Bits 6 - 7: FLEVEL, compression level */
+ header |= level << DC_ZLIB_FLEVEL_OFFSET;
+
+ /* The header has to be a multiple of 31 */
+ header += DC_ZLIB_HEADER_OFFSET -
+ (header % DC_ZLIB_HEADER_OFFSET);
+
+ pDest[0] = (Cpa8U)(header >> LAC_NUM_BITS_IN_BYTE);
+ pDest[1] = (Cpa8U)header;
+
+ /* Set to the number of bytes added to the buffer */
+ *count = DC_ZLIB_HEADER_SIZE;
+ }
+
+ /* If deflate but no checksum required */
+ else {
+ *count = 0;
+ }
+ } else {
+ /* There is no header for other compressed data */
+ *count = 0;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcGenerateFooter(CpaDcSessionHandle pSessionHandle,
+ CpaFlatBuffer *pDestBuff,
+ CpaDcRqResults *pRes)
+{
+ dc_session_desc_t *pSessionDesc = NULL;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pDestBuff);
+ LAC_CHECK_NULL_PARAM(pDestBuff->pData);
+ LAC_CHECK_NULL_PARAM(pRes);
+
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+
+ if (NULL == pSessionDesc) {
+ QAT_UTILS_LOG("Session handle not as expected\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
+ QAT_UTILS_LOG("Invalid session direction\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_DC_DEFLATE == pSessionDesc->compType) {
+ if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
+ Cpa8U *pDest = pDestBuff->pData;
+ Cpa32U crc32 = pRes->checksum;
+ Cpa64U totalLenBeforeCompress =
+ pSessionDesc->cumulativeConsumedBytes;
+
+ if (pDestBuff->dataLenInBytes < DC_GZIP_FOOTER_SIZE) {
+ QAT_UTILS_LOG(
+ "The dataLenInBytes of the dest buffer is too small.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Crc32 of the uncompressed data */
+ pDest[0] = (Cpa8U)crc32;
+ pDest[1] = (Cpa8U)(crc32 >> LAC_NUM_BITS_IN_BYTE);
+ pDest[2] = (Cpa8U)(crc32 >> 2 * LAC_NUM_BITS_IN_BYTE);
+ pDest[3] = (Cpa8U)(crc32 >> 3 * LAC_NUM_BITS_IN_BYTE);
+
+ /* Length of the uncompressed data */
+ pDest[4] = (Cpa8U)totalLenBeforeCompress;
+ pDest[5] = (Cpa8U)(totalLenBeforeCompress >>
+ LAC_NUM_BITS_IN_BYTE);
+ pDest[6] = (Cpa8U)(totalLenBeforeCompress >>
+ 2 * LAC_NUM_BITS_IN_BYTE);
+ pDest[7] = (Cpa8U)(totalLenBeforeCompress >>
+ 3 * LAC_NUM_BITS_IN_BYTE);
+
+ /* Increment produced by the number of bytes added to
+ * the buffer */
+ pRes->produced += DC_GZIP_FOOTER_SIZE;
+ } else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ Cpa8U *pDest = pDestBuff->pData;
+ Cpa32U adler32 = pRes->checksum;
+
+ if (pDestBuff->dataLenInBytes < DC_ZLIB_FOOTER_SIZE) {
+ QAT_UTILS_LOG(
+ "The dataLenInBytes of the dest buffer is too small.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Adler32 of the uncompressed data */
+ pDest[0] = (Cpa8U)(adler32 >> 3 * LAC_NUM_BITS_IN_BYTE);
+ pDest[1] = (Cpa8U)(adler32 >> 2 * LAC_NUM_BITS_IN_BYTE);
+ pDest[2] = (Cpa8U)(adler32 >> LAC_NUM_BITS_IN_BYTE);
+ pDest[3] = (Cpa8U)adler32;
+
+ /* Increment produced by the number of bytes added to
+ * the buffer */
+ pRes->produced += DC_ZLIB_FOOTER_SIZE;
+ }
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/compression/dc_session.c b/sys/dev/qat/qat_api/common/compression/dc_session.c
new file mode 100644
index 000000000000..1d742e227a10
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_session.c
@@ -0,0 +1,957 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_session.c
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Implementation of the Data Compression session operations.
+ *
+ *****************************************************************************/
+
+/*
+ *******************************************************************************
+ * Include public/global header files
+ *******************************************************************************
+ */
+#include "cpa.h"
+#include "cpa_dc.h"
+
+#include "icp_qat_fw.h"
+#include "icp_qat_fw_comp.h"
+#include "icp_qat_hw.h"
+
+/*
+ *******************************************************************************
+ * Include private header files
+ *******************************************************************************
+ */
+#include "dc_session.h"
+#include "dc_datapath.h"
+#include "lac_mem_pools.h"
+#include "sal_types_compression.h"
+#include "lac_buffer_desc.h"
+#include "sal_service_state.h"
+#include "sal_qat_cmn_msg.h"
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Check that pSessionData is valid
+ *
+ * @description
+ * Check that all the parameters defined in the pSessionData are valid
+ *
+ * @param[in] pSessionData Pointer to a user instantiated structure
+ * containing session data
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_FAIL Function failed to find device
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ * @retval CPA_STATUS_UNSUPPORTED Unsupported algorithm/feature
+ *
+ *****************************************************************************/
+static CpaStatus
+dcCheckSessionData(const CpaDcSessionSetupData *pSessionData,
+ CpaInstanceHandle dcInstance)
+{
+ CpaDcInstanceCapabilities instanceCapabilities = { 0 };
+
+ cpaDcQueryCapabilities(dcInstance, &instanceCapabilities);
+
+ if ((pSessionData->compLevel < CPA_DC_L1) ||
+ (pSessionData->compLevel > CPA_DC_L9)) {
+ 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)) {
+ QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (pSessionData->compType != CPA_DC_DEFLATE) {
+ QAT_UTILS_LOG("Invalid compType value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((pSessionData->huffType < CPA_DC_HT_STATIC) ||
+ (pSessionData->huffType > CPA_DC_HT_FULL_DYNAMIC) ||
+ (CPA_DC_HT_PRECOMP == pSessionData->huffType)) {
+ QAT_UTILS_LOG("Invalid huffType value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((pSessionData->sessDirection < CPA_DC_DIR_COMPRESS) ||
+ (pSessionData->sessDirection > CPA_DC_DIR_COMBINED)) {
+ QAT_UTILS_LOG("Invalid sessDirection value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((pSessionData->sessState < CPA_DC_STATEFUL) ||
+ (pSessionData->sessState > CPA_DC_STATELESS)) {
+ QAT_UTILS_LOG("Invalid sessState value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((pSessionData->checksum < CPA_DC_NONE) ||
+ (pSessionData->checksum > CPA_DC_ADLER32)) {
+ QAT_UTILS_LOG("Invalid checksum value\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Populate the compression hardware block
+ *
+ * @description
+ * This function will populate the compression hardware block and update
+ * the size in bytes of the block
+ *
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in] pCompConfig Pointer to slice config word
+ * @param[in] compDecomp Direction of the operation
+ * @param[in] enableDmm Delayed Match Mode
+ *
+ *****************************************************************************/
+static void
+dcCompHwBlockPopulate(dc_session_desc_t *pSessionDesc,
+ icp_qat_hw_compression_config_t *pCompConfig,
+ dc_request_dir_t compDecomp,
+ icp_qat_hw_compression_delayed_match_t enableDmm)
+{
+ icp_qat_hw_compression_direction_t dir =
+ ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
+ icp_qat_hw_compression_algo_t algo =
+ ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
+ icp_qat_hw_compression_depth_t depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
+ icp_qat_hw_compression_file_type_t filetype =
+ ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
+
+ /* Set the direction */
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ dir = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
+ } else {
+ dir = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS;
+ }
+
+ if (CPA_DC_DEFLATE == pSessionDesc->compType) {
+ algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
+ } else {
+ QAT_UTILS_LOG("Algorithm not supported for Compression\n");
+ }
+
+ /* Set the depth */
+ if (DC_DECOMPRESSION_REQUEST == compDecomp) {
+ depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
+ } else {
+ switch (pSessionDesc->compLevel) {
+ case CPA_DC_L1:
+ depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
+ break;
+ case CPA_DC_L2:
+ depth = ICP_QAT_HW_COMPRESSION_DEPTH_4;
+ break;
+ case CPA_DC_L3:
+ depth = ICP_QAT_HW_COMPRESSION_DEPTH_8;
+ break;
+ default:
+ depth = ICP_QAT_HW_COMPRESSION_DEPTH_16;
+ }
+ }
+
+ /* The file type is set to ICP_QAT_HW_COMPRESSION_FILE_TYPE_0. The other
+ * modes will be used in the future for precompiled huffman trees */
+ filetype = ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
+
+ pCompConfig->val = ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(
+ dir, enableDmm, algo, depth, filetype);
+
+ pCompConfig->reserved = 0;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Populate the compression content descriptor
+ *
+ * @description
+ * This function will populate the compression content descriptor
+ *
+ * @param[in] pService Pointer to the service
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in] contextBufferAddrPhys Physical address of the context buffer
+ * @param[out] pMsg Pointer to the compression message
+ * @param[in] nextSlice Next slice
+ * @param[in] compDecomp Direction of the operation
+ *
+ *****************************************************************************/
+static void
+dcCompContentDescPopulate(sal_compression_service_t *pService,
+ dc_session_desc_t *pSessionDesc,
+ CpaPhysicalAddr contextBufferAddrPhys,
+ icp_qat_fw_comp_req_t *pMsg,
+ icp_qat_fw_slice_t nextSlice,
+ dc_request_dir_t compDecomp)
+{
+
+ icp_qat_fw_comp_cd_hdr_t *pCompControlBlock = NULL;
+ icp_qat_hw_compression_config_t *pCompConfig = NULL;
+ CpaBoolean bankEnabled = CPA_FALSE;
+
+ pCompControlBlock = (icp_qat_fw_comp_cd_hdr_t *)&(pMsg->comp_cd_ctrl);
+ pCompConfig =
+ (icp_qat_hw_compression_config_t *)(pMsg->cd_pars.sl
+ .comp_slice_cfg_word);
+
+ ICP_QAT_FW_COMN_NEXT_ID_SET(pCompControlBlock, nextSlice);
+ ICP_QAT_FW_COMN_CURR_ID_SET(pCompControlBlock, ICP_QAT_FW_SLICE_COMP);
+
+ pCompControlBlock->comp_cfg_offset = 0;
+
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
+ (CPA_DC_DEFLATE == pSessionDesc->compType) &&
+ (DC_DECOMPRESSION_REQUEST == compDecomp)) {
+ /* Enable A, B, C, D, and E (CAMs). */
+ pCompControlBlock->ram_bank_flags =
+ ICP_QAT_FW_COMP_RAM_FLAGS_BUILD(
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank I */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank H */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank G */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank F */
+ ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank E */
+ ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank D */
+ ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank C */
+ ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank B */
+ ICP_QAT_FW_COMP_BANK_ENABLED); /* Bank A */
+ bankEnabled = CPA_TRUE;
+ } else {
+ /* Disable all banks */
+ pCompControlBlock->ram_bank_flags =
+ ICP_QAT_FW_COMP_RAM_FLAGS_BUILD(
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank I */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank H */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank G */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank F */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank E */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank D */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank C */
+ ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank B */
+ ICP_QAT_FW_COMP_BANK_DISABLED); /* Bank A */
+ }
+
+ if (DC_COMPRESSION_REQUEST == compDecomp) {
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ pService->generic_service_info,
+ pCompControlBlock->comp_state_addr,
+ pSessionDesc->stateRegistersComp);
+ } else {
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ pService->generic_service_info,
+ pCompControlBlock->comp_state_addr,
+ pSessionDesc->stateRegistersDecomp);
+ }
+
+ if (CPA_TRUE == bankEnabled) {
+ pCompControlBlock->ram_banks_addr = contextBufferAddrPhys;
+ } else {
+ pCompControlBlock->ram_banks_addr = 0;
+ }
+
+ pCompControlBlock->resrvd = 0;
+
+ /* Populate Compression Hardware Setup Block */
+ dcCompHwBlockPopulate(pSessionDesc,
+ pCompConfig,
+ compDecomp,
+ pService->comp_device_data.enableDmm);
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Populate the translator content descriptor
+ *
+ * @description
+ * This function will populate the translator content descriptor
+ *
+ * @param[out] pMsg Pointer to the compression message
+ * @param[in] nextSlice Next slice
+ *
+ *****************************************************************************/
+static void
+dcTransContentDescPopulate(icp_qat_fw_comp_req_t *pMsg,
+ icp_qat_fw_slice_t nextSlice)
+{
+
+ icp_qat_fw_xlt_cd_hdr_t *pTransControlBlock = NULL;
+ pTransControlBlock = (icp_qat_fw_xlt_cd_hdr_t *)&(pMsg->u2.xlt_cd_ctrl);
+
+ ICP_QAT_FW_COMN_NEXT_ID_SET(pTransControlBlock, nextSlice);
+ ICP_QAT_FW_COMN_CURR_ID_SET(pTransControlBlock, ICP_QAT_FW_SLICE_XLAT);
+
+ pTransControlBlock->resrvd1 = 0;
+ pTransControlBlock->resrvd2 = 0;
+ pTransControlBlock->resrvd3 = 0;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Get the context size and the history size
+ *
+ * @description
+ * This function will get the size of the context buffer and the history
+ * buffer. The history buffer is a subset of the context buffer and its
+ * size is needed for stateful compression.
+
+ * @param[in] dcInstance DC Instance Handle
+ *
+ * @param[in] pSessionData Pointer to a user instantiated
+ * structure containing session data
+ * @param[out] pContextSize Pointer to the context size
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ *
+ *
+ *****************************************************************************/
+static CpaStatus
+dcGetContextSize(CpaInstanceHandle dcInstance,
+ CpaDcSessionSetupData *pSessionData,
+ Cpa32U *pContextSize)
+{
+ sal_compression_service_t *pCompService = NULL;
+
+ pCompService = (sal_compression_service_t *)dcInstance;
+
+ *pContextSize = 0;
+ if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
+ (CPA_DC_DEFLATE == pSessionData->compType) &&
+ (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection)) {
+ *pContextSize =
+ pCompService->comp_device_data.inflateContextSize;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+dcInitSession(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaDcSessionSetupData *pSessionData,
+ CpaBufferList *pContextBuffer,
+ CpaDcCallbackFn callbackFn)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_compression_service_t *pService = NULL;
+ icp_qat_fw_comp_req_t *pReqCache = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ CpaPhysicalAddr contextAddrPhys = 0;
+ CpaPhysicalAddr physAddress = 0;
+ CpaPhysicalAddr physAddressAligned = 0;
+ Cpa32U minContextSize = 0, historySize = 0;
+ Cpa32U rpCmdFlags = 0;
+ icp_qat_fw_serv_specif_flags cmdFlags = 0;
+ Cpa8U secureRam = ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ Cpa8U sessType = ICP_QAT_FW_COMP_STATELESS_SESSION;
+ Cpa8U autoSelectBest = ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST;
+ Cpa8U enhancedAutoSelectBest = ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST;
+ Cpa8U disableType0EnhancedAutoSelectBest =
+ ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST;
+ icp_qat_fw_la_cmd_id_t dcCmdId =
+ (icp_qat_fw_la_cmd_id_t)ICP_QAT_FW_COMP_CMD_STATIC;
+ icp_qat_fw_comn_flags cmnRequestFlags = 0;
+ dc_integrity_crc_fw_t *pDataIntegrityCrcs = NULL;
+
+ cmnRequestFlags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(DC_DEFAULT_QAT_PTR_TYPE,
+ QAT_COMN_CD_FLD_TYPE_16BYTE_DATA);
+
+ pService = (sal_compression_service_t *)dcInstance;
+
+ secureRam = pService->comp_device_data.useDevRam;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pSessionData);
+
+ /* Check that the parameters defined in the pSessionData are valid for
+ * the
+ * device */
+ if (CPA_STATUS_SUCCESS !=
+ dcCheckSessionData(pSessionData, dcInstance)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
+ (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection)) {
+ QAT_UTILS_LOG("Stateful sessions are not supported.\n");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ if (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) {
+ /* Test if DRAM is available for the intermediate buffers */
+ if ((NULL == pService->pInterBuffPtrsArray) &&
+ (0 == pService->pInterBuffPtrsArrayPhyAddr)) {
+ if (CPA_DC_ASB_STATIC_DYNAMIC ==
+ pSessionData->autoSelectBestHuffmanTree) {
+ /* Define the Huffman tree as static */
+ pSessionData->huffType = CPA_DC_HT_STATIC;
+ } else {
+ QAT_UTILS_LOG(
+ "No buffer defined for this instance - see cpaDcStartInstance.\n");
+ return CPA_STATUS_RESOURCE;
+ }
+ }
+ }
+
+ if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
+ (CPA_DC_DEFLATE == pSessionData->compType)) {
+ /* Get the size of the context buffer */
+ status =
+ dcGetContextSize(dcInstance, pSessionData, &minContextSize);
+
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG(
+ "Unable to get the context size of the session.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* If the minContextSize is zero it means we will not save or
+ * restore
+ * any history */
+ if (0 != minContextSize) {
+ Cpa64U contextBuffSize = 0;
+
+ LAC_CHECK_NULL_PARAM(pContextBuffer);
+
+ if (LacBuffDesc_BufferListVerify(
+ pContextBuffer,
+ &contextBuffSize,
+ LAC_NO_ALIGNMENT_SHIFT) != CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Ensure that the context buffer size is greater or
+ * equal
+ * to minContextSize */
+ if (contextBuffSize < minContextSize) {
+ QAT_UTILS_LOG(
+ "Context buffer size should be greater or equal to %d.\n",
+ minContextSize);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+ /* Re-align the session structure to 64 byte alignment */
+ physAddress =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
+ (Cpa8U *)pSessionHandle +
+ sizeof(void *));
+
+ if (physAddress == 0) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the session.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ physAddressAligned =
+ (CpaPhysicalAddr)LAC_ALIGN_POW2_ROUNDUP(physAddress,
+ LAC_64BYTE_ALIGNMENT);
+
+ pSessionDesc = (dc_session_desc_t *)
+ /* Move the session pointer by the physical offset
+ between aligned and unaligned memory */
+ ((Cpa8U *)pSessionHandle + sizeof(void *) +
+ (physAddressAligned - physAddress));
+
+ /* Save the aligned pointer in the first bytes (size of LAC_ARCH_UINT)
+ * of the session memory */
+ *((LAC_ARCH_UINT *)pSessionHandle) = (LAC_ARCH_UINT)pSessionDesc;
+
+ /* Zero the compression session */
+ LAC_OS_BZERO(pSessionDesc, sizeof(dc_session_desc_t));
+
+ /* Write the buffer descriptor for context/history */
+ if (0 != minContextSize) {
+ status = LacBuffDesc_BufferListDescWrite(
+ pContextBuffer,
+ &contextAddrPhys,
+ CPA_FALSE,
+ &(pService->generic_service_info));
+
+ if (status != CPA_STATUS_SUCCESS) {
+ return status;
+ }
+
+ pSessionDesc->pContextBuffer = pContextBuffer;
+ pSessionDesc->historyBuffSize = historySize;
+ }
+
+ pSessionDesc->cumulativeConsumedBytes = 0;
+
+ /* Initialise pSessionDesc */
+ pSessionDesc->requestType = DC_REQUEST_FIRST;
+ pSessionDesc->huffType = pSessionData->huffType;
+ pSessionDesc->compType = pSessionData->compType;
+ pSessionDesc->checksumType = pSessionData->checksum;
+ pSessionDesc->autoSelectBestHuffmanTree =
+ pSessionData->autoSelectBestHuffmanTree;
+ pSessionDesc->sessDirection = pSessionData->sessDirection;
+ pSessionDesc->sessState = pSessionData->sessState;
+ pSessionDesc->compLevel = pSessionData->compLevel;
+ pSessionDesc->isDcDp = CPA_FALSE;
+ pSessionDesc->minContextSize = minContextSize;
+ pSessionDesc->isSopForCompressionProcessed = CPA_FALSE;
+ pSessionDesc->isSopForDecompressionProcessed = CPA_FALSE;
+
+ if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ pSessionDesc->previousChecksum = 1;
+ } else {
+ pSessionDesc->previousChecksum = 0;
+ }
+
+ if (CPA_DC_STATEFUL == pSessionData->sessState) {
+ /* Init the spinlock used to lock the access to the number of
+ * stateful
+ * in-flight requests */
+ status = LAC_SPINLOCK_INIT(&(pSessionDesc->sessionLock));
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG(
+ "Spinlock init failed for sessionLock.\n");
+ return CPA_STATUS_RESOURCE;
+ }
+ }
+
+ /* For asynchronous - use the user supplied callback
+ * for synchronous - use the internal synchronous callback */
+ pSessionDesc->pCompressionCb = ((void *)NULL != (void *)callbackFn) ?
+ callbackFn :
+ LacSync_GenWakeupSyncCaller;
+
+ /* Reset the pending callback counters */
+ qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount);
+ qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount);
+ pSessionDesc->pendingDpStatelessCbCount = 0;
+
+ if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) {
+ if (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) {
+ /* Populate the compression section of the content
+ * descriptor */
+ dcCompContentDescPopulate(pService,
+ pSessionDesc,
+ contextAddrPhys,
+ &(pSessionDesc->reqCacheComp),
+ ICP_QAT_FW_SLICE_XLAT,
+ DC_COMPRESSION_REQUEST);
+
+ /* Populate the translator section of the content
+ * descriptor */
+ dcTransContentDescPopulate(
+ &(pSessionDesc->reqCacheComp),
+ ICP_QAT_FW_SLICE_DRAM_WR);
+
+ if (0 != pService->pInterBuffPtrsArrayPhyAddr) {
+ pReqCache = &(pSessionDesc->reqCacheComp);
+
+ pReqCache->u1.xlt_pars.inter_buff_ptr =
+ pService->pInterBuffPtrsArrayPhyAddr;
+ }
+ } else {
+ dcCompContentDescPopulate(pService,
+ pSessionDesc,
+ contextAddrPhys,
+ &(pSessionDesc->reqCacheComp),
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ DC_COMPRESSION_REQUEST);
+ }
+ }
+
+ /* Populate the compression section of the content descriptor for
+ * the decompression case or combined */
+ if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) {
+ dcCompContentDescPopulate(pService,
+ pSessionDesc,
+ contextAddrPhys,
+ &(pSessionDesc->reqCacheDecomp),
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ DC_DECOMPRESSION_REQUEST);
+ }
+
+ if (CPA_DC_STATEFUL == pSessionData->sessState) {
+ sessType = ICP_QAT_FW_COMP_STATEFUL_SESSION;
+
+ LAC_OS_BZERO(&pSessionDesc->stateRegistersComp,
+ sizeof(pSessionDesc->stateRegistersComp));
+
+ LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp,
+ sizeof(pSessionDesc->stateRegistersDecomp));
+ }
+
+ /* Get physical address of E2E CRC buffer */
+ pSessionDesc->physDataIntegrityCrcs = (icp_qat_addr_width_t)
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
+ &pSessionDesc->dataIntegrityCrcs);
+ if (0 == pSessionDesc->physDataIntegrityCrcs) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of Data Integrity buffer.\n");
+ return CPA_STATUS_FAIL;
+ }
+ /* Initialize default CRC parameters */
+ pDataIntegrityCrcs = &pSessionDesc->dataIntegrityCrcs;
+ pDataIntegrityCrcs->crc32 = 0;
+ pDataIntegrityCrcs->adler32 = 1;
+ pDataIntegrityCrcs->oCrc32Cpr = DC_INVALID_CRC;
+ pDataIntegrityCrcs->iCrc32Cpr = DC_INVALID_CRC;
+ pDataIntegrityCrcs->oCrc32Xlt = DC_INVALID_CRC;
+ pDataIntegrityCrcs->iCrc32Xlt = DC_INVALID_CRC;
+ pDataIntegrityCrcs->xorFlags = DC_XOR_FLAGS_DEFAULT;
+ pDataIntegrityCrcs->crcPoly = DC_CRC_POLY_DEFAULT;
+ pDataIntegrityCrcs->xorOut = DC_XOR_OUT_DEFAULT;
+
+ /* Initialise seed checksums */
+ pSessionDesc->seedSwCrc.swCrcI = 0;
+ pSessionDesc->seedSwCrc.swCrcO = 0;
+
+ /* Populate the cmdFlags */
+ switch (pSessionDesc->autoSelectBestHuffmanTree) {
+ case CPA_DC_ASB_DISABLED:
+ break;
+ case CPA_DC_ASB_STATIC_DYNAMIC:
+ autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
+ break;
+ case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS:
+ autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
+ enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST;
+ break;
+ case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS:
+ autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
+ enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST;
+ disableType0EnhancedAutoSelectBest =
+ ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST;
+ break;
+ default:
+ break;
+ }
+
+ rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
+ ICP_QAT_FW_COMP_SOP,
+ ICP_QAT_FW_COMP_EOP,
+ ICP_QAT_FW_COMP_BFINAL,
+ ICP_QAT_FW_COMP_NO_CNV,
+ ICP_QAT_FW_COMP_NO_CNV_RECOVERY,
+ ICP_QAT_FW_COMP_CRC_MODE_LEGACY);
+
+ cmdFlags =
+ ICP_QAT_FW_COMP_FLAGS_BUILD(sessType,
+ autoSelectBest,
+ enhancedAutoSelectBest,
+ disableType0EnhancedAutoSelectBest,
+ secureRam);
+
+ if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) {
+ if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
+ dcCmdId = (icp_qat_fw_la_cmd_id_t)(
+ ICP_QAT_FW_COMP_CMD_DYNAMIC);
+ }
+
+ pReqCache = &(pSessionDesc->reqCacheComp);
+ pReqCache->comp_pars.req_par_flags = rpCmdFlags;
+ pReqCache->comp_pars.crc.legacy.initial_adler = 1;
+ pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
+
+ /* Populate header of the common request message */
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
+ (uint8_t)dcCmdId,
+ cmnRequestFlags,
+ cmdFlags);
+ }
+
+ if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) {
+ dcCmdId =
+ (icp_qat_fw_la_cmd_id_t)(ICP_QAT_FW_COMP_CMD_DECOMPRESS);
+ pReqCache = &(pSessionDesc->reqCacheDecomp);
+ pReqCache->comp_pars.req_par_flags = rpCmdFlags;
+ pReqCache->comp_pars.crc.legacy.initial_adler = 1;
+ pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
+
+ /* Populate header of the common request message */
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
+ (uint8_t)dcCmdId,
+ cmnRequestFlags,
+ cmdFlags);
+ }
+
+ return status;
+}
+
+CpaStatus
+cpaDcInitSession(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaDcSessionSetupData *pSessionData,
+ CpaBufferList *pContextBuffer,
+ CpaDcCallbackFn callbackFn)
+{
+ CpaInstanceHandle insHandle = NULL;
+ sal_compression_service_t *pService = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(pService);
+
+ return dcInitSession(insHandle,
+ pSessionHandle,
+ pSessionData,
+ pContextBuffer,
+ callbackFn);
+}
+
+CpaStatus
+cpaDcResetSession(const CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle insHandle = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa64U numPendingStateless = 0;
+ Cpa64U numPendingStateful = 0;
+ icp_comms_trans_handle trans_handle = NULL;
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pSessionDesc);
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ insHandle = dcInstance;
+ } else {
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+ }
+ LAC_CHECK_NULL_PARAM(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+ /* Check if SAL is running otherwise return an error */
+ SAL_RUNNING_CHECK(insHandle);
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ trans_handle = ((sal_compression_service_t *)dcInstance)
+ ->trans_handle_compression_tx;
+ if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
+ /* Process the remaining messages on the ring */
+ SalQatMsg_updateQueueTail(trans_handle);
+ QAT_UTILS_LOG(
+ "There are remaining messages on the ring\n");
+ return CPA_STATUS_RETRY;
+ }
+
+ /* Check if there are stateless pending requests */
+ if (0 != pSessionDesc->pendingDpStatelessCbCount) {
+ QAT_UTILS_LOG(
+ "There are %llu stateless DP requests pending.\n",
+ (unsigned long long)
+ pSessionDesc->pendingDpStatelessCbCount);
+ return CPA_STATUS_RETRY;
+ }
+ } else {
+ numPendingStateless =
+ qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
+ numPendingStateful =
+ qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
+ /* Check if there are stateless pending requests */
+ if (0 != numPendingStateless) {
+ QAT_UTILS_LOG(
+ "There are %llu stateless requests pending.\n",
+ (unsigned long long)numPendingStateless);
+ return CPA_STATUS_RETRY;
+ }
+ /* Check if there are stateful pending requests */
+ if (0 != numPendingStateful) {
+ QAT_UTILS_LOG(
+ "There are %llu stateful requests pending.\n",
+ (unsigned long long)numPendingStateful);
+ return CPA_STATUS_RETRY;
+ }
+
+ /* Reset pSessionDesc */
+ pSessionDesc->requestType = DC_REQUEST_FIRST;
+ pSessionDesc->cumulativeConsumedBytes = 0;
+ if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
+ pSessionDesc->previousChecksum = 1;
+ } else {
+ pSessionDesc->previousChecksum = 0;
+ }
+ }
+ /* Reset the pending callback counters */
+ qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount);
+ qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount);
+ pSessionDesc->pendingDpStatelessCbCount = 0;
+ if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
+ LAC_OS_BZERO(&pSessionDesc->stateRegistersComp,
+ sizeof(pSessionDesc->stateRegistersComp));
+ LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp,
+ sizeof(pSessionDesc->stateRegistersDecomp));
+ }
+ return status;
+}
+
+CpaStatus
+cpaDcRemoveSession(const CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle insHandle = NULL;
+ dc_session_desc_t *pSessionDesc = NULL;
+ Cpa64U numPendingStateless = 0;
+ Cpa64U numPendingStateful = 0;
+ icp_comms_trans_handle trans_handle = NULL;
+
+ LAC_CHECK_NULL_PARAM(pSessionHandle);
+ pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
+ LAC_CHECK_NULL_PARAM(pSessionDesc);
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ insHandle = dcInstance;
+ } else {
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+ }
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ /* Check if SAL is running otherwise return an error */
+ SAL_RUNNING_CHECK(insHandle);
+
+ if (CPA_TRUE == pSessionDesc->isDcDp) {
+ trans_handle = ((sal_compression_service_t *)insHandle)
+ ->trans_handle_compression_tx;
+
+ if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
+ /* Process the remaining messages on the ring */
+ SalQatMsg_updateQueueTail(trans_handle);
+ QAT_UTILS_LOG(
+ "There are remaining messages on the ring.\n");
+ return CPA_STATUS_RETRY;
+ }
+
+ /* Check if there are stateless pending requests */
+ if (0 != pSessionDesc->pendingDpStatelessCbCount) {
+ QAT_UTILS_LOG(
+ "There are %llu stateless DP requests pending.\n",
+ (unsigned long long)
+ pSessionDesc->pendingDpStatelessCbCount);
+ return CPA_STATUS_RETRY;
+ }
+ } else {
+ numPendingStateless =
+ qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
+ numPendingStateful =
+ qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
+
+ /* Check if there are stateless pending requests */
+ if (0 != numPendingStateless) {
+ QAT_UTILS_LOG(
+ "There are %llu stateless requests pending.\n",
+ (unsigned long long)numPendingStateless);
+ status = CPA_STATUS_RETRY;
+ }
+
+ /* Check if there are stateful pending requests */
+ if (0 != numPendingStateful) {
+ QAT_UTILS_LOG(
+ "There are %llu stateful requests pending.\n",
+ (unsigned long long)numPendingStateful);
+ status = CPA_STATUS_RETRY;
+ }
+ if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
+ (CPA_STATUS_SUCCESS == status)) {
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK_DESTROY(
+ &(pSessionDesc->sessionLock))) {
+ QAT_UTILS_LOG(
+ "Failed to destory session lock.\n");
+ }
+ }
+ }
+
+ return status;
+}
+
+CpaStatus
+dcGetSessionSize(CpaInstanceHandle dcInstance,
+ CpaDcSessionSetupData *pSessionData,
+ Cpa32U *pSessionSize,
+ Cpa32U *pContextSize)
+{
+
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle insHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ /* Check parameters */
+ LAC_CHECK_NULL_PARAM(insHandle);
+ LAC_CHECK_NULL_PARAM(pSessionData);
+ LAC_CHECK_NULL_PARAM(pSessionSize);
+
+ if (dcCheckSessionData(pSessionData, insHandle) != CPA_STATUS_SUCCESS) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Get session size for session data */
+ *pSessionSize = sizeof(dc_session_desc_t) + LAC_64BYTE_ALIGNMENT +
+ sizeof(LAC_ARCH_UINT);
+
+ if (NULL != pContextSize) {
+ status =
+ dcGetContextSize(insHandle, pSessionData, pContextSize);
+
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG(
+ "Unable to get the context size of the session.\n");
+ return CPA_STATUS_FAIL;
+ }
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcGetSessionSize(CpaInstanceHandle dcInstance,
+ CpaDcSessionSetupData *pSessionData,
+ Cpa32U *pSessionSize,
+ Cpa32U *pContextSize)
+{
+
+ LAC_CHECK_NULL_PARAM(pContextSize);
+
+ return dcGetSessionSize(dcInstance,
+ pSessionData,
+ pSessionSize,
+ pContextSize);
+}
diff --git a/sys/dev/qat/qat_api/common/compression/dc_stats.c b/sys/dev/qat/qat_api/common/compression/dc_stats.c
new file mode 100644
index 000000000000..bcd3d61cb3c6
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/dc_stats.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_stats.c
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Implementation of the Data Compression stats operations.
+ *
+ *****************************************************************************/
+
+/*
+ *******************************************************************************
+ * Include public/global header files
+ *******************************************************************************
+ */
+#include "cpa.h"
+#include "cpa_dc.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+/*
+ *******************************************************************************
+ * Include private header files
+ *******************************************************************************
+ */
+#include "lac_common.h"
+#include "icp_accel_devices.h"
+#include "sal_statistics.h"
+#include "dc_session.h"
+#include "dc_datapath.h"
+#include "lac_mem_pools.h"
+#include "sal_service_state.h"
+#include "sal_types_compression.h"
+#include "dc_stats.h"
+
+CpaStatus
+dcStatsInit(sal_compression_service_t *pService)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ pService->pCompStatsArr =
+ LAC_OS_MALLOC(COMPRESSION_NUM_STATS * sizeof(QatUtilsAtomic));
+
+ if (pService->pCompStatsArr == NULL) {
+ status = CPA_STATUS_RESOURCE;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ COMPRESSION_STATS_RESET(pService);
+ }
+
+ return status;
+}
+
+void
+dcStatsFree(sal_compression_service_t *pService)
+{
+ if (NULL != pService->pCompStatsArr) {
+ LAC_OS_FREE(pService->pCompStatsArr);
+ }
+}
+
+CpaStatus
+cpaDcGetStats(CpaInstanceHandle dcInstance, CpaDcStats *pStatistics)
+{
+ sal_compression_service_t *pService = NULL;
+ CpaInstanceHandle insHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ LAC_CHECK_NULL_PARAM(pStatistics);
+ SAL_RUNNING_CHECK(insHandle);
+
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+
+ /* Retrieves the statistics for compression */
+ COMPRESSION_STATS_GET(pStatistics, pService);
+
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/compression/icp_sal_dc_err.c b/sys/dev/qat/qat_api/common/compression/icp_sal_dc_err.c
new file mode 100644
index 000000000000..6b3735b4051b
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/icp_sal_dc_err.c
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file icp_sal_dc_err.c
+ *
+ * @defgroup SalCommon
+ *
+ * @ingroup SalCommon
+ *
+ *****************************************************************************/
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+#include "cpa.h"
+#include "icp_sal.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "dc_error_counter.h"
+
+Cpa64U
+icp_sal_get_dc_error(Cpa8S dcError)
+{
+ return getDcErrorCounter(dcError);
+}
diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_datapath.h b/sys/dev/qat/qat_api/common/compression/include/dc_datapath.h
new file mode 100644
index 000000000000..0a6ef7191704
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/include/dc_datapath.h
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_datapath.h
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Definition of the Data Compression datapath parameters.
+ *
+ *******************
+ * **********************************************************/
+#ifndef DC_DATAPATH_H_
+#define DC_DATAPATH_H_
+
+#define LAC_QAT_DC_REQ_SZ_LW 32
+#define LAC_QAT_DC_RESP_SZ_LW 8
+
+/* Restriction on the source buffer size for compression due to the firmware
+ * processing */
+#define DC_SRC_BUFFER_MIN_SIZE (15)
+
+/* Restriction on the destination buffer size for compression due to
+ * the management of skid buffers in the firmware */
+#define DC_DEST_BUFFER_DYN_MIN_SIZE (128)
+#define DC_DEST_BUFFER_STA_MIN_SIZE (64)
+/* C62x and C3xxx pcie rev0 devices require an additional 32bytes */
+#define DC_DEST_BUFFER_STA_ADDITIONAL_SIZE (32)
+
+/* C4xxx device only requires 47 bytes */
+#define DC_DEST_BUFFER_MIN_SIZE (47)
+
+/* Minimum destination buffer size for decompression */
+#define DC_DEST_BUFFER_DEC_MIN_SIZE (1)
+
+/* Restriction on the source and destination buffer sizes for compression due
+ * to the firmware taking 32 bits parameters. The max size is 2^32-1 */
+#define DC_BUFFER_MAX_SIZE (0xFFFFFFFF)
+
+/* DC Source & Destination buffer type (FLAT/SGL) */
+#define DC_DEFAULT_QAT_PTR_TYPE QAT_COMN_PTR_TYPE_SGL
+#define DC_DP_QAT_PTR_TYPE QAT_COMN_PTR_TYPE_FLAT
+
+/* Offset to first byte of Input Byte Counter (IBC) in state register */
+#define DC_STATE_IBC_OFFSET (8)
+/* Size in bytes of input byte counter (IBC) in state register */
+#define DC_IBC_SIZE_IN_BYTES (4)
+
+/* Offset to first byte to CRC32 in state register */
+#define DC_STATE_CRC32_OFFSET (40)
+/* Offset to first byte to output CRC32 in state register */
+#define DC_STATE_OUTPUT_CRC32_OFFSET (48)
+/* Offset to first byte to input CRC32 in state register */
+#define DC_STATE_INPUT_CRC32_OFFSET (52)
+
+/* Offset to first byte of ADLER32 in state register */
+#define DC_STATE_ADLER32_OFFSET (48)
+
+/* 8 bit mask value */
+#define DC_8_BIT_MASK (0xff)
+
+/* 8 bit shift position */
+#define DC_8_BIT_SHIFT_POS (8)
+
+/* Size in bytes of checksum */
+#define DC_CHECKSUM_SIZE_IN_BYTES (4)
+
+/* Mask used to set the most significant bit to zero */
+#define DC_STATE_REGISTER_ZERO_MSB_MASK (0x7F)
+
+/* Mask used to keep only the most significant bit and set the others to zero */
+#define DC_STATE_REGISTER_KEEP_MSB_MASK (0x80)
+
+/* Compression state register word containing the parity bit */
+#define DC_STATE_REGISTER_PARITY_BIT_WORD (5)
+
+/* Location of the parity bit within the compression state register word */
+#define DC_STATE_REGISTER_PARITY_BIT (7)
+
+/* size which needs to be reserved before the results field to
+ * align the results field with the API struct */
+#define DC_API_ALIGNMENT_OFFSET (offsetof(CpaDcDpOpData, results))
+
+/* Mask used to check the CompressAndVerify capability bit */
+#define DC_CNV_EXTENDED_CAPABILITY (0x01)
+
+/* Mask used to check the CompressAndVerifyAndRecover capability bit */
+#define DC_CNVNR_EXTENDED_CAPABILITY (0x100)
+
+/* Default values for CNV integrity checks,
+ * those are used to inform hardware of specifying CRC parameters to be used
+ * when calculating CRCs */
+#define DC_CRC_POLY_DEFAULT 0x04c11db7
+#define DC_XOR_FLAGS_DEFAULT 0xe0000
+#define DC_XOR_OUT_DEFAULT 0xffffffff
+#define DC_INVALID_CRC 0x0
+
+/**
+*******************************************************************************
+* @ingroup cpaDc Data Compression
+* Compression cookie
+* @description
+* This cookie stores information for a particular compression perform op.
+* This includes various user-supplied parameters for the operation which
+* will be needed in our callback function.
+* A pointer to this cookie is stored in the opaque data field of the QAT
+* message so that it can be accessed in the asynchronous callback.
+* @note
+* The order of the parameters within this structure is important. It needs
+* to match the order of the parameters in CpaDcDpOpData up to the
+* pSessionHandle. This allows the correct processing of the callback.
+*****************************************************************************/
+typedef struct dc_compression_cookie_s {
+ Cpa8U dcReqParamsBuffer[DC_API_ALIGNMENT_OFFSET];
+ /**< Memory block - was previously reserved for request parameters.
+ * Now size maintained so following members align with API struct,
+ * but no longer used for request parameters */
+ CpaDcRqResults reserved;
+ /**< This is reserved for results to correctly align the structure
+ * to match the one from the data plane API */
+ CpaInstanceHandle dcInstance;
+ /**< Compression instance handle */
+ CpaDcSessionHandle pSessionHandle;
+ /**< Pointer to the session handle */
+ icp_qat_fw_comp_req_t request;
+ /**< Compression request */
+ void *callbackTag;
+ /**< Opaque data supplied by the client */
+ dc_session_desc_t *pSessionDesc;
+ /**< Pointer to the session descriptor */
+ CpaDcFlush flushFlag;
+ /**< Flush flag */
+ CpaDcOpData *pDcOpData;
+ /**< struct containing flags and CRC related data for this session */
+ CpaDcRqResults *pResults;
+ /**< Pointer to result buffer holding consumed and produced data */
+ Cpa32U srcTotalDataLenInBytes;
+ /**< Total length of the source data */
+ Cpa32U dstTotalDataLenInBytes;
+ /**< Total length of the destination data */
+ dc_request_dir_t compDecomp;
+ /**< Used to know whether the request is compression or decompression.
+ * Useful when defining the session as combined */
+ CpaBufferList *pUserSrcBuff;
+ /**< virtual userspace ptr to source SGL */
+ CpaBufferList *pUserDestBuff;
+ /**< virtual userspace ptr to destination SGL */
+} dc_compression_cookie_t;
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Callback function called for compression and decompression requests in
+ * asynchronous mode
+ *
+ * @description
+ * Called to process compression and decompression response messages. This
+ * callback will check for errors, update the statistics and will call the
+ * user callback
+ *
+ * @param[in] pRespMsg Response message
+ *
+ *****************************************************************************/
+void dcCompression_ProcessCallback(void *pRespMsg);
+
+/**
+*****************************************************************************
+* @ingroup Dc_DataCompression
+* Describes CNV and CNVNR modes
+*
+* @description
+* This enum is used to indicate the CNV modes.
+*
+*****************************************************************************/
+typedef enum dc_cnv_mode_s {
+ DC_NO_CNV = 0,
+ /* CNV = FALSE, CNVNR = FALSE */
+ DC_CNV,
+ /* CNV = TRUE, CNVNR = FALSE */
+ DC_CNVNR,
+ /* CNV = TRUE, CNVNR = TRUE */
+} dc_cnv_mode_t;
+
+#endif /* DC_DATAPATH_H_ */
diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_error_counter.h b/sys/dev/qat/qat_api/common/compression/include/dc_error_counter.h
new file mode 100644
index 000000000000..dd1189fd970a
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/include/dc_error_counter.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_error_counter.h
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Definition of the Data Compression Error Counter parameters.
+ *
+ *****************************************************************************/
+#ifndef DC_ERROR_COUNTER_H
+#define DC_ERROR_COUNTER_H
+
+#include "cpa_types.h"
+#include "cpa_dc.h"
+
+#define MAX_DC_ERROR_TYPE 20
+
+void dcErrorLog(CpaDcReqStatus dcError);
+Cpa64U getDcErrorCounter(CpaDcReqStatus dcError);
+
+#endif /* DC_ERROR_COUNTER_H */
diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_header_footer.h b/sys/dev/qat/qat_api/common/compression/include/dc_header_footer.h
new file mode 100644
index 000000000000..0ec2cc6f3f16
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/include/dc_header_footer.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_header_footer.h
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Definition of the Data Compression header and footer parameters.
+ *
+ *****************************************************************************/
+#ifndef DC_HEADER_FOOTER_H_
+#define DC_HEADER_FOOTER_H_
+
+/* Header and footer sizes for Zlib and Gzip */
+#define DC_ZLIB_HEADER_SIZE (2)
+#define DC_GZIP_HEADER_SIZE (10)
+#define DC_ZLIB_FOOTER_SIZE (4)
+#define DC_GZIP_FOOTER_SIZE (8)
+
+/* Values used to build the headers for Zlib and Gzip */
+#define DC_GZIP_ID1 (0x1f)
+#define DC_GZIP_ID2 (0x8b)
+#define DC_GZIP_FILESYSTYPE (0x03)
+#define DC_ZLIB_WINDOWSIZE_OFFSET (4)
+#define DC_ZLIB_FLEVEL_OFFSET (6)
+#define DC_ZLIB_HEADER_OFFSET (31)
+
+/* Compression level for Zlib */
+#define DC_ZLIB_LEVEL_0 (0)
+#define DC_ZLIB_LEVEL_1 (1)
+#define DC_ZLIB_LEVEL_2 (2)
+#define DC_ZLIB_LEVEL_3 (3)
+
+/* CM parameter for Zlib */
+#define DC_ZLIB_CM_DEFLATE (8)
+
+/* Type of Gzip compression */
+#define DC_GZIP_FAST_COMP (4)
+#define DC_GZIP_MAX_COMP (2)
+
+#endif /* DC_HEADER_FOOTER_H_ */
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
new file mode 100644
index 000000000000..5a4961fadd60
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/include/dc_session.h
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_session.h
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Definition of the Data Compression session parameters.
+ *
+ *****************************************************************************/
+#ifndef DC_SESSION_H
+#define DC_SESSION_H
+
+#include "cpa_dc_dp.h"
+#include "icp_qat_fw_comp.h"
+#include "sal_qat_cmn_msg.h"
+
+/* Maximum number of intermediate buffers SGLs for devices
+ * with a maximum of 6 compression slices */
+#define DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES (12)
+
+/* Maximum number of intermediate buffers SGLs for devices
+ * with a maximum of 10 max compression slices */
+#define DC_QAT_MAX_NUM_INTER_BUFFERS_10COMP_SLICES (20)
+
+/* Maximum number of intermediate buffers SGLs for devices
+ * with a maximum of 24 max compression slices and 32 MEs */
+#define DC_QAT_MAX_NUM_INTER_BUFFERS_24COMP_SLICES (64)
+
+/* Maximum size of the state registers 64 bytes */
+#define DC_QAT_STATE_REGISTERS_MAX_SIZE (64)
+
+/* Size of the history window.
+ * Base 2 logarithm of maximum window size minus 8 */
+#define DC_8K_WINDOW_SIZE (5)
+#define DC_16K_WINDOW_SIZE (6)
+#define DC_32K_WINDOW_SIZE (7)
+
+/* Context size */
+#define DC_DEFLATE_MAX_CONTEXT_SIZE (49152)
+#define DC_INFLATE_CONTEXT_SIZE (36864)
+
+#define DC_DEFLATE_EH_MAX_CONTEXT_SIZE (65536)
+#define DC_DEFLATE_EH_MIN_CONTEXT_SIZE (49152)
+#define DC_INFLATE_EH_CONTEXT_SIZE (34032)
+
+/* Retrieve the session descriptor pointer from the session context structure
+ * that the user allocates. The pointer to the internally realigned address
+ * is stored at the start of the session context that the user allocates */
+#define DC_SESSION_DESC_FROM_CTX_GET(pSession) \
+ (dc_session_desc_t *)(*(LAC_ARCH_UINT *)pSession)
+
+/* Maximum size for the compression part of the content descriptor */
+#define DC_QAT_COMP_CONTENT_DESC_SIZE sizeof(icp_qat_fw_comp_cd_hdr_t)
+
+/* Maximum size for the translator part of the content descriptor */
+#define DC_QAT_TRANS_CONTENT_DESC_SIZE \
+ (sizeof(icp_qat_fw_xlt_cd_hdr_t) + DC_QAT_MAX_TRANS_SETUP_BLK_SZ)
+
+/* Maximum size of the decompression content descriptor */
+#define DC_QAT_CONTENT_DESC_DECOMP_MAX_SIZE \
+ LAC_ALIGN_POW2_ROUNDUP(DC_QAT_COMP_CONTENT_DESC_SIZE, \
+ (1 << LAC_64BYTE_ALIGNMENT_SHIFT))
+
+/* Maximum size of the compression content descriptor */
+#define DC_QAT_CONTENT_DESC_COMP_MAX_SIZE \
+ LAC_ALIGN_POW2_ROUNDUP(DC_QAT_COMP_CONTENT_DESC_SIZE + \
+ DC_QAT_TRANS_CONTENT_DESC_SIZE, \
+ (1 << LAC_64BYTE_ALIGNMENT_SHIFT))
+
+/* Direction of the request */
+typedef enum dc_request_dir_e {
+ DC_COMPRESSION_REQUEST = 1,
+ DC_DECOMPRESSION_REQUEST
+} dc_request_dir_t;
+
+/* Type of the compression request */
+typedef enum dc_request_type_e {
+ DC_REQUEST_FIRST = 1,
+ DC_REQUEST_SUBSEQUENT
+} dc_request_type_t;
+
+typedef enum dc_block_type_e {
+ DC_CLEARTEXT_TYPE = 0,
+ DC_STATIC_TYPE,
+ DC_DYNAMIC_TYPE
+} dc_block_type_t;
+
+/* Internal data structure supporting end to end data integrity checks. */
+typedef struct dc_integrity_crc_fw_s {
+ Cpa32U crc32;
+ /* CRC32 checksum returned for compressed data */
+ Cpa32U adler32;
+ /* ADLER32 checksum returned for compressed data */
+ Cpa32U oCrc32Cpr;
+ /* CRC32 checksum returned for data output by compression accelerator */
+ Cpa32U iCrc32Cpr;
+ /* CRC32 checksum returned for input data to compression accelerator */
+ Cpa32U oCrc32Xlt;
+ /* CRC32 checksum returned for data output by translator accelerator */
+ Cpa32U iCrc32Xlt;
+ /* CRC32 checksum returned for input data to translator accelerator */
+ Cpa32U xorFlags;
+ /* Initialise transactor pCRC controls in state register */
+ Cpa32U crcPoly;
+ /* CRC32 polynomial used by hardware */
+ Cpa32U xorOut;
+ /* CRC32 from XOR stage (Input CRC is xor'ed with value in the state) */
+ Cpa32U deflateBlockType;
+ /* Bit 1 - Bit 0
+ * 0 0 -> RAW DATA + Deflate header.
+ * This will not produced any CRC check because
+ * the output will not come from the slices.
+ * It will be a simple copy from input to output
+ * buffers list.
+ * 0 1 -> Static deflate block type
+ * 1 0 -> Dynamic deflate block type
+ * 1 1 -> Invalid type */
+} dc_integrity_crc_fw_t;
+
+typedef struct dc_sw_checksums_s {
+ Cpa32U swCrcI;
+ Cpa32U swCrcO;
+} dc_sw_checksums_t;
+
+/* Session descriptor structure for compression */
+typedef struct dc_session_desc_s {
+ Cpa8U stateRegistersComp[DC_QAT_STATE_REGISTERS_MAX_SIZE];
+ /**< State registers for compression */
+ Cpa8U stateRegistersDecomp[DC_QAT_STATE_REGISTERS_MAX_SIZE];
+ /**< State registers for decompression */
+ icp_qat_fw_comp_req_t reqCacheComp;
+ /**< Cache as much as possible of the compression request in a pre-built
+ * request */
+ icp_qat_fw_comp_req_t reqCacheDecomp;
+ /**< Cache as much as possible of the decompression request in a
+ * pre-built
+ * request */
+ dc_request_type_t requestType;
+ /**< Type of the compression request. As stateful mode do not support
+ * more
+ * than one in-flight request there is no need to use spinlocks */
+ dc_request_type_t previousRequestType;
+ /**< Type of the previous compression request. Used in cases where there
+ * the
+ * stateful operation needs to be resubmitted */
+ CpaDcHuffType huffType;
+ /**< Huffman tree type */
+ CpaDcCompType compType;
+ /**< Compression type */
+ CpaDcChecksum checksumType;
+ /**< Type of checksum */
+ CpaDcAutoSelectBest autoSelectBestHuffmanTree;
+ /**< Indicates if the implementation selects the best Huffman encoding
+ */
+ CpaDcSessionDir sessDirection;
+ /**< Session direction */
+ CpaDcSessionState sessState;
+ /**< Session state */
+ Cpa32U deflateWindowSize;
+ /**< Window size */
+ CpaDcCompLvl compLevel;
+ /**< Compression level */
+ CpaDcCallbackFn pCompressionCb;
+ /**< Callback function defined for the traditional compression session
+ */
+ QatUtilsAtomic pendingStatelessCbCount;
+ /**< Keeps track of number of pending requests on stateless session */
+ QatUtilsAtomic pendingStatefulCbCount;
+ /**< Keeps track of number of pending requests on stateful session */
+ Cpa64U pendingDpStatelessCbCount;
+ /**< Keeps track of number of data plane pending requests on stateless
+ * session */
+ struct mtx sessionLock;
+ /**< Lock used to provide exclusive access for number of stateful
+ * in-flight
+ * requests update */
+ CpaBoolean isDcDp;
+ /**< Indicates if the data plane API is used */
+ Cpa32U minContextSize;
+ /**< Indicates the minimum size required to allocate the context buffer
+ */
+ CpaBufferList *pContextBuffer;
+ /**< Context buffer */
+ Cpa32U historyBuffSize;
+ /**< Size of the history buffer */
+ Cpa64U cumulativeConsumedBytes;
+ /**< Cumulative amount of consumed bytes. Used to build the footer in
+ * the
+ * stateful case */
+ Cpa32U previousChecksum;
+ /**< Save the previous value of the checksum. Used to process zero byte
+ * stateful compression or decompression requests */
+ CpaBoolean isSopForCompressionProcessed;
+ /**< Indicates whether a Compression Request is received in this session
+ */
+ CpaBoolean isSopForDecompressionProcessed;
+ /**< Indicates whether a Decompression Request is received in this
+ * session
+ */
+ /**< Data integrity table */
+ dc_integrity_crc_fw_t dataIntegrityCrcs;
+ /**< Physical address of Data integrity buffer */
+ CpaPhysicalAddr physDataIntegrityCrcs;
+ /* Seed checksums structure used to calculate software calculated
+ * checksums.
+ */
+ dc_sw_checksums_t seedSwCrc;
+ /* Driver calculated integrity software CRC */
+ dc_sw_checksums_t integritySwCrc;
+} dc_session_desc_t;
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Initialise a compression session
+ *
+ * @description
+ * This function will initialise a compression session
+ *
+ * @param[in] dcInstance Instance handle derived from discovery
+ * functions
+ * @param[in,out] pSessionHandle Pointer to a session handle
+ * @param[in,out] pSessionData Pointer to a user instantiated structure
+ * containing session data
+ * @param[in] pContextBuffer Pointer to context buffer
+ *
+ * @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
+ *****************************************************************************/
+CpaStatus dcInitSession(CpaInstanceHandle dcInstance,
+ CpaDcSessionHandle pSessionHandle,
+ CpaDcSessionSetupData *pSessionData,
+ CpaBufferList *pContextBuffer,
+ CpaDcCallbackFn callbackFn);
+
+/**
+ *****************************************************************************
+ * @ingroup Dc_DataCompression
+ * Get the size of the memory required to hold the session information
+ *
+ * @description
+ * This function will get the size of the memory required to hold the
+ * session information
+ *
+ * @param[in] dcInstance Instance handle derived from discovery
+ * functions
+ * @param[in] pSessionData Pointer to a user instantiated structure
+ * containing session data
+ * @param[out] pSessionSize On return, this parameter will be the size
+ * of the memory that will be
+ * required by cpaDcInitSession() for session
+ * data.
+ * @param[out] pContextSize On return, this parameter will be the size
+ * of the memory that will be required
+ * for context data. Context data is
+ * save/restore data including history and
+ * any implementation specific data that is
+ * required for a save/restore operation.
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_FAIL Function failed
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *****************************************************************************/
+CpaStatus dcGetSessionSize(CpaInstanceHandle dcInstance,
+ CpaDcSessionSetupData *pSessionData,
+ Cpa32U *pSessionSize,
+ Cpa32U *pContextSize);
+
+#endif /* DC_SESSION_H */
diff --git a/sys/dev/qat/qat_api/common/compression/include/dc_stats.h b/sys/dev/qat/qat_api/common/compression/include/dc_stats.h
new file mode 100644
index 000000000000..357be30107b1
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/compression/include/dc_stats.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file dc_stats.h
+ *
+ * @ingroup Dc_DataCompression
+ *
+ * @description
+ * Definition of the Data Compression stats parameters.
+ *
+ *****************************************************************************/
+#ifndef DC_STATS_H_
+#define DC_STATS_H_
+
+/* Number of Compression statistics */
+#define COMPRESSION_NUM_STATS (sizeof(CpaDcStats) / sizeof(Cpa64U))
+
+#define COMPRESSION_STAT_INC(statistic, pService) \
+ do { \
+ if (CPA_TRUE == \
+ pService->generic_service_info.stats->bDcStatsEnabled) { \
+ qatUtilsAtomicInc( \
+ &pService->pCompStatsArr[offsetof(CpaDcStats, \
+ statistic) / \
+ sizeof(Cpa64U)]); \
+ } \
+ } while (0)
+
+/* Macro to get all Compression stats (from internal array of atomics) */
+#define COMPRESSION_STATS_GET(compStats, pService) \
+ do { \
+ int i; \
+ for (i = 0; i < COMPRESSION_NUM_STATS; i++) { \
+ ((Cpa64U *)compStats)[i] = \
+ qatUtilsAtomicGet(&pService->pCompStatsArr[i]); \
+ } \
+ } while (0)
+
+/* Macro to reset all Compression stats */
+#define COMPRESSION_STATS_RESET(pService) \
+ do { \
+ int i; \
+ for (i = 0; i < COMPRESSION_NUM_STATS; i++) { \
+ qatUtilsAtomicSet(0, &pService->pCompStatsArr[i]); \
+ } \
+ } while (0)
+
+/**
+*******************************************************************************
+* @ingroup Dc_DataCompression
+* Initialises the compression stats
+*
+* @description
+* This function allocates and initialises the stats array to 0
+*
+* @param[in] pService Pointer to a compression service structure
+*
+* @retval CPA_STATUS_SUCCESS initialisation successful
+* @retval CPA_STATUS_RESOURCE array allocation failed
+*
+*****************************************************************************/
+CpaStatus dcStatsInit(sal_compression_service_t *pService);
+
+/**
+*******************************************************************************
+* @ingroup Dc_DataCompression
+* Frees the compression stats
+*
+* @description
+* This function frees the stats array
+*
+* @param[in] pService Pointer to a compression service structure
+*
+* @retval None
+*
+*****************************************************************************/
+void dcStatsFree(sal_compression_service_t *pService);
+
+#endif /* DC_STATS_H_ */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_session.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_session.h
new file mode 100644
index 000000000000..6ae3c51e7766
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_session.h
@@ -0,0 +1,622 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_session.h
+ *
+ * @defgroup LacSym_Session Session
+ *
+ * @ingroup LacSym
+ *
+ * Definition of symmetric session descriptor structure
+ *
+ * @lld_start
+ *
+ * @lld_overview
+ * A session is required for each symmetric operation. The session descriptor
+ * holds information about the session from when the session is initialised to
+ * when the session is removed. The session descriptor is used in the
+ * subsequent perform operations in the paths for both sending the request and
+ * receiving the response. The session descriptor and any other state
+ * information required for processing responses from the QAT are stored in an
+ * internal cookie. A pointer to this cookie is stored in the opaque data
+ * field of the QAT request.
+ *
+ * The user allocates the memory for the session using the size returned from
+ * \ref cpaCySymSessionCtxGetSize(). Internally this memory is re-aligned on a
+ * 64 byte boundary for use by the QAT engine. The aligned pointer is saved in
+ * the first bytes (size of void *) of the session memory. This address
+ * is then dereferenced in subsequent performs to get access to the session
+ * descriptor.
+ *
+ * <b>LAC Session Init</b>\n The session descriptor is re-aligned and
+ * populated. This includes populating the content descriptor which contains
+ * the hardware setup for the QAT engine. The content descriptor is a read
+ * only structure after session init and a pointer to it is sent to the QAT
+ * for each perform operation.
+ *
+ * <b>LAC Perform </b>\n
+ * The address for the session descriptor is got by dereferencing the first
+ * bytes of the session memory (size of void *). For each successful
+ * request put on the ring, the pendingCbCount for the session is incremented.
+ *
+ * <b>LAC Callback </b>\n
+ * For each successful response the pendingCbCount for the session is
+ * decremented. See \ref LacSymCb_ProcessCallbackInternal()
+ *
+ * <b>LAC Session Remove </b>\n
+ * The address for the session descriptor is got by dereferencing the first
+ * bytes of the session memory (size of void *).
+ * The pendingCbCount for the session is checked to see if it is 0. If it is
+ * non 0 then there are requests in flight. An error is returned to the user.
+ *
+ * <b>Concurrency</b>\n
+ * A reference count is used to prevent the descriptor being removed
+ * while there are requests in flight.
+ *
+ * <b>Reference Count</b>\n
+ * - The perform funcion increments the reference count for the session.
+ * - The callback function decrements the reference count for the session.
+ * - The Remove function checks the reference count to ensure that it is 0.
+ *
+ * @lld_dependencies
+ * - \ref LacMem "Memory" - Inline memory functions
+ * - QatUtils: logging, locking & virt to phys translations.
+ *
+ * @lld_initialisation
+ *
+ * @lld_module_algorithms
+ *
+ * @lld_process_context
+ *
+ * @lld_end
+ *
+ *****************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_SESSION_H
+#define LAC_SYM_SESSION_H
+
+/*
+ * Common alignment attributes to ensure
+ * hashStatePrefixBuffer is 64-byte aligned
+ */
+#define ALIGN_START(x)
+#define ALIGN_END(x) __attribute__((__aligned__(x)))
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "icp_accel_devices.h"
+#include "lac_list.h"
+#include "lac_sal_types.h"
+#include "sal_qat_cmn_msg.h"
+#include "lac_sym_cipher_defs.h"
+#include "lac_sym.h"
+#include "lac_sym_hash_defs.h"
+#include "lac_sym_qat_hash.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+/**
+*******************************************************************************
+* @ingroup LacSym_Session
+* Symmetric session descriptor
+* @description
+* This structure stores information about a session
+* Note: struct types lac_session_d1_s and lac_session_d2_s are subsets of
+* this structure. Elements in all three should retain the same order
+* Only this structure is used in the session init call. The other two are
+* for determining the size of memory to allocate.
+* The comments section of each of the other two structures below show
+* the conditions that determine which session context memory size to use.
+*****************************************************************************/
+typedef struct lac_session_desc_s {
+ Cpa8U contentDescriptor[LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE];
+ /**< QAT Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U contentDescriptorOptimised[LAC_SYM_OPTIMISED_CD_SIZE];
+ /**< QAT Optimised Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaCySymOp symOperation;
+ /**< type of command to be performed */
+ sal_qat_content_desc_info_t contentDescInfo;
+ /**< info on the content descriptor */
+ sal_qat_content_desc_info_t contentDescOptimisedInfo;
+ /**< info on the optimised content descriptor */
+ icp_qat_fw_la_cmd_id_t laCmdId;
+ /**<Command Id for the QAT FW */
+ lac_sym_qat_hash_state_buffer_info_t hashStateBufferInfo;
+ /**< info on the hash state prefix buffer */
+ CpaCySymHashAlgorithm hashAlgorithm;
+ /**< hash algorithm */
+ Cpa32U authKeyLenInBytes;
+ /**< Authentication key length in bytes */
+ CpaCySymHashMode hashMode;
+ /**< Mode of the hash operation. plain, auth or nested */
+ Cpa32U hashResultSize;
+ /**< size of the digest produced/compared in bytes */
+ CpaCySymCipherAlgorithm cipherAlgorithm;
+ /**< Cipher algorithm and mode */
+ Cpa32U cipherKeyLenInBytes;
+ /**< Cipher key length in bytes */
+ CpaCySymCipherDirection cipherDirection;
+ /**< This parameter determines if the cipher operation is an encrypt or
+ * a decrypt operation. */
+ CpaCySymPacketType partialState;
+ /**< state of the partial packet. This can be written to by the perform
+ * because the SpinLock pPartialInFlightSpinlock guarantees that the
+ * state is accessible in only one place at a time. */
+ icp_qat_la_bulk_req_hdr_t reqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t reqCacheMid;
+ icp_qat_la_bulk_req_ftr_t reqCacheFtr;
+ /**< Cache as much as possible of the bulk request in a pre built
+ * request (header, mid & footer). */
+ CpaCySymCbFunc pSymCb;
+ /**< symmetric function callback pointer */
+ union {
+ QatUtilsAtomic pendingCbCount;
+ /**< Keeps track of number of pending requests. */
+ QatUtilsAtomic pendingDpCbCount;
+ /**< Keeps track of number of pending DP requests (not thread
+ * safe)*/
+ } u;
+ struct lac_sym_bulk_cookie_s *pRequestQueueHead;
+ /**< A fifo list of queued QAT requests. Head points to first queue
+ * entry */
+ struct lac_sym_bulk_cookie_s *pRequestQueueTail;
+ /**< A fifo list of queued QAT requests. Tail points to last queue entry
+ */
+ struct mtx requestQueueLock;
+ /**< A lock to protect accesses to the above request queue */
+ CpaInstanceHandle pInstance;
+ /**< Pointer to Crypto instance running this session. */
+ CpaBoolean isAuthEncryptOp : 1;
+ /**< if the algorithm chaining operation is auth encrypt */
+ CpaBoolean nonBlockingOpsInProgress : 1;
+ /**< Flag is set if a non blocking operation is in progress for a
+ * session.
+ * If set to false, new requests will be queued until the condition is
+ * cleared.
+ * ASSUMPTION: Only one blocking condition per session can exist at any
+ * time
+ */
+ CpaBoolean internalSession : 1;
+ /**< Flag which is set if the session was set up internally for DRBG */
+ CpaBoolean isDPSession : 1;
+ /**< Flag which is set if the session was set up for Data Plane */
+ CpaBoolean digestVerify : 1;
+ /**< Session digest verify for data plane and for CCM/GCM for trad
+ * api. For other cases on trad api this flag is set in each performOp
+ */
+ CpaBoolean digestIsAppended : 1;
+ /**< Flag indicating whether the digest is appended immediately
+ * following
+ * the region over which the digest is computed */
+ CpaBoolean isCipher : 1;
+ /**< Flag indicating whether symOperation includes a cipher operation */
+ CpaBoolean isAuth : 1;
+ /**< Flag indicating whether symOperation includes an auth operation */
+ CpaBoolean useSymConstantsTable : 1;
+ /**< Flag indicating whether the SymConstantsTable can be used or not */
+ CpaBoolean useOptimisedContentDesc : 1;
+ /**< Flag indicating whether to use the optimised CD or not */
+ icp_qat_la_bulk_req_hdr_t shramReqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t shramReqCacheMid;
+ icp_qat_la_bulk_req_ftr_t shramReqCacheFtr;
+ /**< Alternative pre-built request (header, mid & footer)
+ * for use with symConstantsTable. */
+ CpaBoolean isPartialSupported : 1;
+ /**< Flag indicating whether symOperation support partial packet */
+ CpaBoolean isSinglePass : 1;
+ /**< Flag indicating whether symOperation is single pass operation */
+ icp_qat_fw_serv_specif_flags laCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_fw_comn_flags cmnRequestFlags;
+ /**< Common request flags type */
+ icp_qat_fw_ext_serv_specif_flags laExtCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_la_bulk_req_hdr_t reqSpcCacheHdr;
+ icp_qat_la_bulk_req_ftr_t reqSpcCacheFtr;
+ /**< request (header & footer)for use with Single Pass. */
+ icp_qat_hw_auth_mode_t qatHashMode;
+ /**< Hash Mode for the qat slices. Not to be confused with QA-API
+ * hashMode
+ */
+ void *writeRingMsgFunc;
+ /**< function which will be called to write ring message */
+ Cpa32U aadLenInBytes;
+ /**< For CCM,GCM and Snow3G cases, this parameter holds the AAD size,
+ * otherwise it is set to zero */
+ ALIGN_START(64)
+ Cpa8U hashStatePrefixBuffer[LAC_MAX_AAD_SIZE_BYTES] ALIGN_END(64);
+ /**< hash state prefix buffer used for hash operations - AAD only
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U hashStatePrefixBufferExt[LAC_MAX_HASH_STATE_BUFFER_SIZE_BYTES -
+ LAC_MAX_AAD_SIZE_BYTES];
+ /**< hash state prefix buffer used for hash operations - Remainder of
+ * array.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U cipherPartialOpState[LAC_CIPHER_STATE_SIZE_MAX];
+ /**< Buffer to hold the cipher state for the session (for partial ops).
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U cipherARC4InitialState[LAC_CIPHER_ARC4_STATE_LEN_BYTES];
+ /**< Buffer to hold the initial ARC4 cipher state for the session, which
+ * is derived from the user-supplied base key during session
+ * registration.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaPhysicalAddr cipherARC4InitialStatePhysAddr;
+ /**< The physical address of the ARC4 initial state, set at init
+ ** session time .
+ */
+} lac_session_desc_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSym_Session
+* Symmetric session descriptor - d1
+* @description
+* This structure stores information about a specific session which
+* assumes the following:
+* - cipher algorithm is not ARC4 or Snow3G
+* - partials not used
+* - not AuthEncrypt operation
+* - hash mode not Auth or Nested
+* - no hashStatePrefixBuffer required
+* It is therefore a subset of the standard symmetric session descriptor,
+* with a smaller memory footprint
+*****************************************************************************/
+typedef struct lac_session_desc_d1_s {
+ Cpa8U contentDescriptor[LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE];
+ /**< QAT Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U contentDescriptorOptimised[LAC_SYM_OPTIMISED_CD_SIZE];
+ /**< QAT Optimised Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaCySymOp symOperation;
+ /**< type of command to be performed */
+ sal_qat_content_desc_info_t contentDescInfo;
+ /**< info on the content descriptor */
+ sal_qat_content_desc_info_t contentDescOptimisedInfo;
+ /**< info on the optimised content descriptor */
+ icp_qat_fw_la_cmd_id_t laCmdId;
+ /**<Command Id for the QAT FW */
+ lac_sym_qat_hash_state_buffer_info_t hashStateBufferInfo;
+ /**< info on the hash state prefix buffer */
+ CpaCySymHashAlgorithm hashAlgorithm;
+ /**< hash algorithm */
+ Cpa32U authKeyLenInBytes;
+ /**< Authentication key length in bytes */
+ CpaCySymHashMode hashMode;
+ /**< Mode of the hash operation. plain, auth or nested */
+ Cpa32U hashResultSize;
+ /**< size of the digest produced/compared in bytes */
+ CpaCySymCipherAlgorithm cipherAlgorithm;
+ /**< Cipher algorithm and mode */
+ Cpa32U cipherKeyLenInBytes;
+ /**< Cipher key length in bytes */
+ CpaCySymCipherDirection cipherDirection;
+ /**< This parameter determines if the cipher operation is an encrypt or
+ * a decrypt operation. */
+ CpaCySymPacketType partialState;
+ /**< state of the partial packet. This can be written to by the perform
+ * because the SpinLock pPartialInFlightSpinlock guarantees that that
+ * the
+ * state is accessible in only one place at a time. */
+ icp_qat_la_bulk_req_hdr_t reqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t reqCacheMid;
+ icp_qat_la_bulk_req_ftr_t reqCacheFtr;
+ /**< Cache as much as possible of the bulk request in a pre built
+ * request (header, mid & footer). */
+ CpaCySymCbFunc pSymCb;
+ /**< symmetric function callback pointer */
+ union {
+ QatUtilsAtomic pendingCbCount;
+ /**< Keeps track of number of pending requests. */
+ Cpa64U pendingDpCbCount;
+ /**< Keeps track of number of pending DP requests (not thread
+ * safe)*/
+ } u;
+ struct lac_sym_bulk_cookie_s *pRequestQueueHead;
+ /**< A fifo list of queued QAT requests. Head points to first queue
+ * entry */
+ struct lac_sym_bulk_cookie_s *pRequestQueueTail;
+ /**< A fifo list of queued QAT requests. Tail points to last queue entry
+ */
+ struct mtx requestQueueLock;
+ /**< A lock to protect accesses to the above request queue */
+ CpaInstanceHandle pInstance;
+ /**< Pointer to Crypto instance running this session. */
+ CpaBoolean isAuthEncryptOp : 1;
+ /**< if the algorithm chaining operation is auth encrypt */
+ CpaBoolean nonBlockingOpsInProgress : 1;
+ /**< Flag is set if a non blocking operation is in progress for a
+ * session.
+ * If set to false, new requests will be queued until the condition is
+ * cleared.
+ * ASSUMPTION: Only one blocking condition per session can exist at any
+ * time
+ */
+ CpaBoolean internalSession : 1;
+ /**< Flag which is set if the session was set up internally for DRBG */
+ CpaBoolean isDPSession : 1;
+ /**< Flag which is set if the session was set up for Data Plane */
+ CpaBoolean digestVerify : 1;
+ /**< Session digest verify for data plane and for CCM/GCM for trad
+ * api. For other cases on trad api this flag is set in each performOp
+ */
+ CpaBoolean digestIsAppended : 1;
+ /**< Flag indicating whether the digest is appended immediately
+ * following
+ * the region over which the digest is computed */
+ CpaBoolean isCipher : 1;
+ /**< Flag indicating whether symOperation includes a cipher operation */
+ CpaBoolean isAuth : 1;
+ /**< Flag indicating whether symOperation includes an auth operation */
+ CpaBoolean useSymConstantsTable : 1;
+ /**< Flag indicating whether the SymConstantsTable can be used or not */
+ CpaBoolean useOptimisedContentDesc : 1;
+ /**< Flag indicating whether to use the optimised CD or not */
+ icp_qat_la_bulk_req_hdr_t shramReqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t shramReqCacheMid;
+ icp_qat_la_bulk_req_ftr_t shramReqCacheFtr;
+ /**< Alternative pre-built request (header, mid & footer)
+ * for use with symConstantsTable. */
+ CpaBoolean isPartialSupported : 1;
+ /**< Flag indicating whether symOperation support partial packet */
+ CpaBoolean isSinglePass : 1;
+ /**< Flag indicating whether symOperation is single pass operation */
+ icp_qat_fw_serv_specif_flags laCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_fw_comn_flags cmnRequestFlags;
+ /**< Common request flags type */
+ icp_qat_fw_ext_serv_specif_flags laExtCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_la_bulk_req_hdr_t reqSpcCacheHdr;
+ icp_qat_la_bulk_req_ftr_t reqSpcCacheFtr;
+ /**< request (header & footer)for use with Single Pass. */
+ icp_qat_hw_auth_mode_t qatHashMode;
+ /**< Hash Mode for the qat slices. Not to be confused with QA-API
+ * hashMode
+ */
+ void *writeRingMsgFunc;
+ /**< function which will be called to write ring message */
+} lac_session_desc_d1_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSym_Session
+* Symmetric session descriptor - d2
+* @description
+* This structure stores information about a specific session which
+* assumes the following:
+* - authEncrypt only
+* - partials not used
+* - hasStatePrefixBuffer just contains AAD
+* It is therefore a subset of the standard symmetric session descriptor,
+* with a smaller memory footprint
+*****************************************************************************/
+typedef struct lac_session_desc_d2_s {
+ Cpa8U contentDescriptor[LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE];
+ /**< QAT Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ Cpa8U contentDescriptorOptimised[LAC_SYM_OPTIMISED_CD_SIZE];
+ /**< QAT Optimised Content Descriptor for this session.
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaCySymOp symOperation;
+ /**< type of command to be performed */
+ sal_qat_content_desc_info_t contentDescInfo;
+ /**< info on the content descriptor */
+ sal_qat_content_desc_info_t contentDescOptimisedInfo;
+ /**< info on the optimised content descriptor */
+ icp_qat_fw_la_cmd_id_t laCmdId;
+ /**<Command Id for the QAT FW */
+ lac_sym_qat_hash_state_buffer_info_t hashStateBufferInfo;
+ /**< info on the hash state prefix buffer */
+ CpaCySymHashAlgorithm hashAlgorithm;
+ /**< hash algorithm */
+ Cpa32U authKeyLenInBytes;
+ /**< Authentication key length in bytes */
+ CpaCySymHashMode hashMode;
+ /**< Mode of the hash operation. plain, auth or nested */
+ Cpa32U hashResultSize;
+ /**< size of the digest produced/compared in bytes */
+ CpaCySymCipherAlgorithm cipherAlgorithm;
+ /**< Cipher algorithm and mode */
+ Cpa32U cipherKeyLenInBytes;
+ /**< Cipher key length in bytes */
+ CpaCySymCipherDirection cipherDirection;
+ /**< This parameter determines if the cipher operation is an encrypt or
+ * a decrypt operation. */
+ CpaCySymPacketType partialState;
+ /**< state of the partial packet. This can be written to by the perform
+ * because the SpinLock pPartialInFlightSpinlock guarantees that that
+ * the
+ * state is accessible in only one place at a time. */
+ icp_qat_la_bulk_req_hdr_t reqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t reqCacheMid;
+ icp_qat_la_bulk_req_ftr_t reqCacheFtr;
+ /**< Cache as much as possible of the bulk request in a pre built
+ * request (header. mid & footer). */
+ CpaCySymCbFunc pSymCb;
+ /**< symmetric function callback pointer */
+ union {
+ QatUtilsAtomic pendingCbCount;
+ /**< Keeps track of number of pending requests. */
+ Cpa64U pendingDpCbCount;
+ /**< Keeps track of number of pending DP requests (not thread
+ * safe)*/
+ } u;
+ struct lac_sym_bulk_cookie_s *pRequestQueueHead;
+ /**< A fifo list of queued QAT requests. Head points to first queue
+ * entry */
+ struct lac_sym_bulk_cookie_s *pRequestQueueTail;
+ /**< A fifo list of queued QAT requests. Tail points to last queue entry
+ */
+ struct mtx requestQueueLock;
+ /**< A lock to protect accesses to the above request queue */
+ CpaInstanceHandle pInstance;
+ /**< Pointer to Crypto instance running this session. */
+ CpaBoolean isAuthEncryptOp : 1;
+ /**< if the algorithm chaining operation is auth encrypt */
+ CpaBoolean nonBlockingOpsInProgress : 1;
+ /**< Flag is set if a non blocking operation is in progress for a
+ * session.
+ * If set to false, new requests will be queued until the condition is
+ * cleared.
+ * ASSUMPTION: Only one blocking condition per session can exist at any
+ * time
+ */
+ CpaBoolean internalSession : 1;
+ /**< Flag which is set if the session was set up internally for DRBG */
+ CpaBoolean isDPSession : 1;
+ /**< Flag which is set if the session was set up for Data Plane */
+ CpaBoolean digestVerify : 1;
+ /**< Session digest verify for data plane and for CCM/GCM for trad
+ * api. For other cases on trad api this flag is set in each performOp
+ */
+ CpaBoolean digestIsAppended : 1;
+ /**< Flag indicating whether the digest is appended immediately
+ * following
+ * the region over which the digest is computed */
+ CpaBoolean isCipher : 1;
+ /**< Flag indicating whether symOperation includes a cipher operation */
+ CpaBoolean isAuth : 1;
+ /**< Flag indicating whether symOperation includes an auth operation */
+ CpaBoolean useSymConstantsTable : 1;
+ /**< Flag indicating whether the SymConstantsTable can be used or not */
+ CpaBoolean useOptimisedContentDesc : 1;
+ /**< Flag indicating whether to use the optimised CD or not */
+ icp_qat_la_bulk_req_hdr_t shramReqCacheHdr;
+ icp_qat_fw_la_key_gen_common_t shramReqCacheMid;
+ icp_qat_la_bulk_req_ftr_t shramReqCacheFtr;
+ /**< Alternative pre-built request (header. mid & footer)
+ * for use with symConstantsTable. */
+ CpaBoolean isPartialSupported : 1;
+ /**< Flag indicating whether symOperation support partial packet */
+ CpaBoolean isSinglePass : 1;
+ /**< Flag indicating whether symOperation is single pass operation */
+ icp_qat_fw_serv_specif_flags laCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_fw_comn_flags cmnRequestFlags;
+ /**< Common request flags type */
+ icp_qat_fw_ext_serv_specif_flags laExtCmdFlags;
+ /**< Common request - Service specific flags type */
+ icp_qat_la_bulk_req_hdr_t reqSpcCacheHdr;
+ icp_qat_la_bulk_req_ftr_t reqSpcCacheFtr;
+ /**< request (header & footer)for use with Single Pass. */
+ icp_qat_hw_auth_mode_t qatHashMode;
+ /**< Hash Mode for the qat slices. Not to be confused with QA-API
+ * hashMode
+ */
+ void *writeRingMsgFunc;
+ /**< function which will be called to write ring message */
+ Cpa32U aadLenInBytes;
+ /**< For CCM,GCM and Snow3G cases, this parameter holds the AAD size,
+ * otherwise it is set to zero */
+ ALIGN_START(64)
+ Cpa8U hashStatePrefixBuffer[LAC_MAX_AAD_SIZE_BYTES] ALIGN_END(64);
+ /**< hash state prefix buffer used for hash operations - AAD only
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+} lac_session_desc_d2_t;
+
+#define LAC_SYM_SESSION_SIZE \
+ (sizeof(lac_session_desc_t) + LAC_64BYTE_ALIGNMENT + \
+ sizeof(LAC_ARCH_UINT))
+/**< @ingroup LacSym_Session
+ * Size of the memory that the client has to allocate for a session. Extra
+ * memory is needed to internally re-align the data. The pointer to the algined
+ * data is stored at the start of the user allocated memory hence the extra
+ * space for an LAC_ARCH_UINT */
+
+#define LAC_SYM_SESSION_D1_SIZE \
+ (sizeof(lac_session_desc_d1_t) + LAC_64BYTE_ALIGNMENT + \
+ sizeof(LAC_ARCH_UINT))
+/**< @ingroup LacSym_Session
+** Size of the memory that the client has to allocate for a session where :
+* - cipher algorithm not ARC4 or Snow3G, no Partials, nonAuthEncrypt.
+* Extra memory is needed to internally re-align the data. The pointer to the
+* aligned data is stored at the start of the user allocated memory hence the
+* extra space for an LAC_ARCH_UINT */
+
+#define LAC_SYM_SESSION_D2_SIZE \
+ (sizeof(lac_session_desc_d2_t) + LAC_64BYTE_ALIGNMENT + \
+ sizeof(LAC_ARCH_UINT))
+/**< @ingroup LacSym_Session
+** Size of the memory that the client has to allocate for a session where :
+* - authEncrypt, no Partials - so hashStatePrefixBuffer is only AAD
+* Extra memory is needed to internally re-align the data. The pointer to the
+* aligned data is stored at the start of the user allocated memory hence the
+* extra space for an LAC_ARCH_UINT */
+
+#define LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSession) \
+ (lac_session_desc_t *)(*(LAC_ARCH_UINT *)pSession)
+/**< @ingroup LacSym_Session
+ * Retrieve the session descriptor pointer from the session context structure
+ * that the user allocates. The pointer to the internally realigned address
+ * is stored at the start of the session context that the user allocates */
+
+/**
+*******************************************************************************
+* @ingroup LacSym_Session
+* This function initializes a session
+*
+* @description
+* This function is called from the LAC session register API functions.
+* It validates all input parameters. If an invalid parameter is passed,
+* an error is returned to the calling function. If all parameters are valid
+* a symmetric session is initialized
+*
+* @param[in] instanceHandle_in Instance Handle
+* @param[in] pSymCb callback function
+* @param[in] pSessionSetupData pointer to the strucutre containing the setup
+*data
+* @param[in] isDpSession CPA_TRUE for a data plane session
+* @param[out] pSessionCtx Pointer to session context
+*
+*
+* @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.
+*
+*/
+
+CpaStatus LacSym_InitSession(const CpaInstanceHandle instanceHandle_in,
+ const CpaCySymCbFunc pSymCb,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ const CpaBoolean isDpSession,
+ CpaCySymSessionCtx pSessionCtx);
+
+#endif /* LAC_SYM_SESSION_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym.h
new file mode 100644
index 000000000000..402fe85378a1
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym.h
@@ -0,0 +1,356 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym.h
+ *
+ * @defgroup LacSym Symmetric
+ *
+ * @ingroup Lac
+ *
+ * Symmetric component includes cipher, Hash, chained cipher & hash,
+ * authenticated encryption and key generation.
+ *
+ * @lld_start
+ * @lld_overview
+ *
+ * The symmetric component demuliplexes the following crypto operations to
+ * the appropriate sub-components: cipher, hash, algorithm chaining and
+ * authentication encryption. It is a common layer between the above
+ * mentioned components where common resources are allocated and paramater
+ * checks are done. The operation specific resource allocation and parameter
+ * checks are done in the sub-component itself.
+ *
+ * The symmetric component demultiplexes the session register/deregister
+ * and perform functions to the appropriate subcomponents.
+ *
+ * @lld_dependencies
+ * - \ref LacSymPartial "Partial Packet Code": This code manages the partial
+ * packet state for a session.
+ * - \ref LacBufferDesc "Common Buffer Code" : This code traverses a buffer
+ * chain to ensure it is valid.
+ * - \ref LacSymStats "Statistics": Manages statistics for symmetric
+ * - \ref LacSymQat "Symmetric QAT": The symmetric qat component is
+ * initialiased by the symmetric component.
+ * - \ref LacCipher "Cipher" : demultiplex cipher opertions to this component.
+ * - \ref LacHash "Hash" : demultiplex hash opertions to this component.
+ * to this component.
+ * - \ref LacAlgChain "Algorithm Chaining": The algorithm chaining component
+ * - OSAL : Memory allocation, Mutex's, atomics
+ *
+ * @lld_initialisation
+ * This component is initialied during the LAC initialisation sequence. It
+ * initialises the session table, statistics, symmetric QAT, initialises the
+ * hash definitions lookup table, the hash alg supported lookup table and
+ * registers a callback function with the symmetric response handler to process
+ * response messages for Cipher, Hash and Algorithm-Chaining requests.
+ *
+ * @lld_module_algorithms
+ *
+ * @lld_process_context
+ * Refer to \ref LacHash "Hash" and \ref LacCipher "Cipher" for sequence
+ * diagrams from the symmetric component through the sub components.
+ *
+ * @lld_end
+ *
+ ***************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_H
+#define LAC_SYM_H
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "cpa_cy_sym_dp.h"
+#include "lac_common.h"
+#include "lac_mem_pools.h"
+#include "lac_sym_cipher_defs.h"
+#include "icp_qat_fw_la.h"
+
+#define LAC_SYM_KEY_TLS_PREFIX_SIZE 128
+/**< Hash Prefix size in bytes for TLS (128 = MAX = SHA2 (384, 512)*/
+
+#define LAC_SYM_OPTIMISED_CD_SIZE 64
+/**< The size of the optimised content desc in DRAM*/
+
+#define LAC_SYM_KEY_MAX_HASH_STATE_BUFFER (LAC_SYM_KEY_TLS_PREFIX_SIZE * 2)
+/**< hash state prefix buffer structure that holds the maximum sized secret */
+
+#define LAC_SYM_HASH_BUFFER_LEN 64
+/**< Buffer length to hold 16 byte MD5 key and 20 byte SHA1 key */
+
+/* The ARC4 key will not be stored in the content descriptor so we only need to
+ * reserve enough space for the next biggest cipher setup block.
+ * Kasumi needs to store 2 keys and to have the size of 2 blocks for fw*/
+#define LAC_SYM_QAT_MAX_CIPHER_SETUP_BLK_SZ \
+ (sizeof(icp_qat_hw_cipher_config_t) + 2 * ICP_QAT_HW_KASUMI_KEY_SZ + \
+ 2 * ICP_QAT_HW_KASUMI_BLK_SZ)
+/**< @ingroup LacSymQat
+ * Maximum size for the cipher setup block of the content descriptor */
+
+#define LAC_SYM_QAT_MAX_HASH_SETUP_BLK_SZ sizeof(icp_qat_hw_auth_algo_blk_t)
+/**< @ingroup LacSymQat
+ * Maximum size for the hash setup block of the content descriptor */
+
+#define LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE \
+ LAC_ALIGN_POW2_ROUNDUP(LAC_SYM_QAT_MAX_CIPHER_SETUP_BLK_SZ + \
+ LAC_SYM_QAT_MAX_HASH_SETUP_BLK_SZ, \
+ (1 << LAC_64BYTE_ALIGNMENT_SHIFT))
+/**< @ingroup LacSymQat
+ * Maximum size of content descriptor. This is incremented to the next multiple
+ * of 64 so that it can be 64 byte aligned */
+
+#define LAC_SYM_QAT_API_ALIGN_COOKIE_OFFSET \
+ (offsetof(CpaCySymDpOpData, instanceHandle))
+/**< @ingroup LacSymQat
+ * Size which needs to be reserved before the instanceHandle field of
+ * lac_sym_bulk_cookie_s to align it to the correspondent instanceHandle
+ * in CpaCySymDpOpData */
+
+#define LAC_SIZE_OF_CACHE_HDR_IN_LW 6
+/**< Size of Header part of reqCache/shramReqCache */
+
+#define LAC_SIZE_OF_CACHE_MID_IN_LW 2
+/**< Size of Mid part (LW14/15) of reqCache/shramReqCache */
+
+#define LAC_SIZE_OF_CACHE_FTR_IN_LW 6
+/**< Size of Footer part of reqCache/shramReqCache */
+
+#define LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW 20
+/**< Size of dummy reqCache/shramReqCache to clear */
+
+#define LAC_START_OF_CACHE_MID_IN_LW 14
+/**< Starting LW of reqCache/shramReqCache Mid */
+
+#define LAC_START_OF_CACHE_FTR_IN_LW 26
+/**< Starting LW of reqCache/shramReqCache Footer */
+
+/**
+ *******************************************************************************
+ * @ingroup LacSym
+ * Symmetric cookie
+ *
+ * @description
+ * This cookie stores information for a particular symmetric perform op.
+ * This includes the request params, re-aligned Cipher IV, the request
+ * message sent to the QAT engine, and various user-supplied parameters
+ * for the operation which will be needed in our callback function.
+ * A pointer to this cookie is stored in the opaque data field of the QAT
+ * message so that it can be accessed in the asynchronous callback.
+ * Cookies for multiple operations on a given session can be linked
+ * together to allow queuing of requests using the pNext field.
+ *
+ * The parameters are placed in order to match the CpaCySymDpOpData
+ *structure
+ *****************************************************************************/
+typedef struct lac_sym_bulk_cookie_s {
+
+ /* CpaCySymDpOpData struct so need to keep this here for correct
+ * alignment*/
+ Cpa8U reserved[LAC_SYM_QAT_API_ALIGN_COOKIE_OFFSET];
+ /** NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaInstanceHandle instanceHandle;
+ /**< Instance handle for the operation */
+ CpaCySymSessionCtx sessionCtx;
+ /**< Session context */
+ void *pCallbackTag;
+ /**< correlator supplied by the client */
+ icp_qat_fw_la_bulk_req_t qatMsg;
+ /**< QAT request message */
+ const CpaCySymOpData *pOpData;
+ /**< pointer to the op data structure that the user supplied in the
+ * perform
+ * operation. The op data is modified in the process callback function
+ * and the pointer is returned to the user in their callback function */
+ CpaBoolean updateSessionIvOnSend;
+ /**< Boolean flag to indicate if the session cipher IV buffer should be
+ * updated prior to sending the request */
+ CpaBoolean updateUserIvOnRecieve;
+ /**< Boolean flag to indicate if the user's cipher IV buffer should be
+ * updated after receiving the response from the QAT */
+ CpaBoolean updateKeySizeOnRecieve;
+/**< Boolean flag to indicate if the cipher key size should be
+ * updated after receiving the response from the QAT */
+ CpaBufferList *pDstBuffer;
+ /**< Pointer to destination buffer to hold the data output */
+ struct lac_sym_bulk_cookie_s *pNext;
+ /**< Pointer to next node in linked list (if request is queued) */
+} lac_sym_bulk_cookie_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* symmetric Key cookie
+* @description
+* This cookie stores information for a particular keygen perform op.
+* This includes a hash content descriptor, request params, hash state
+* buffer, and various user-supplied parameters for the operation which
+* will be needed in our callback function.
+* A pointer to this cookie is stored in the opaque data field of the QAT
+* message so that it can be accessed in the asynchronous callback.
+*****************************************************************************/
+typedef struct lac_sym_key_cookie_s {
+ CpaInstanceHandle instanceHandle;
+ /**< QAT device id supplied by the client */
+ void *pCallbackTag;
+ /**< Mechanism used. TLS, SSL or MGF */
+ Cpa8U contentDesc[LAC_SYM_QAT_MAX_HASH_SETUP_BLK_SZ];
+ /**< Content descriptor.
+ **< NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine */
+ union {
+ icp_qat_fw_la_ssl_key_material_input_t sslKeyInput;
+ /**< SSL key material input structure */
+ icp_qat_fw_la_tls_key_material_input_t tlsKeyInput;
+ /**< TLS key material input structure */
+ icp_qat_fw_la_hkdf_key_material_input_t tlsHKDFKeyInput;
+ /**< TLS HHKDF key material input structure */
+ } u;
+ /**< NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine */
+ Cpa8U hashStateBuffer[LAC_SYM_KEY_MAX_HASH_STATE_BUFFER];
+ /**< hash state prefix buffer
+ * NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine
+ */
+ CpaCyGenFlatBufCbFunc pKeyGenCb;
+ /**< callback function supplied by the client */
+ void *pKeyGenOpData;
+ /**< pointer to the (SSL/TLS) or MGF op data structure that the user
+ * supplied in the perform operation */
+ CpaFlatBuffer *pKeyGenOutputData;
+ /**< Output data pointer supplied by the client */
+ Cpa8U hashKeyBuffer[LAC_SYM_HASH_BUFFER_LEN];
+ /**< 36 byte buffer to store MD5 key and SHA1 key */
+} lac_sym_key_cookie_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSymNrbg
+* symmetric NRBG cookie
+* @description
+* This cookie stores information for a particular NRBG operation.
+* This includes various user-supplied parameters for the operation which
+* will be needed in our callback function.
+* A pointer to this cookie is stored in the opaque data field of the QAT
+* message so that it can be accessed in the asynchronous callback.
+*****************************************************************************/
+typedef struct lac_sym_nrbg_cookie_s {
+ CpaInstanceHandle instanceHandle;
+ /**< QAT device id supplied by the client */
+ void *pCallbackTag;
+ /**< Opaque data supplied by the client */
+ icp_qat_fw_la_trng_test_result_t trngHTResult;
+ /**< TRNG health test result
+ **< NOTE: Field must be correctly aligned in memory for access by QAT
+ * engine */
+ icp_qat_fw_la_trng_req_t trngReq;
+ /**< TRNG request message */
+ CpaCyGenFlatBufCbFunc pCb;
+ /**< Callback function supplied by the client */
+ void *pOpData;
+ /**< Op data pointer supplied by the client */
+ CpaFlatBuffer *pOutputData;
+ /**< Output data pointer supplied by the client */
+} lac_sym_nrbg_cookie_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSym
+* symmetric cookie
+* @description
+* used to determine the amount of memory to allocate for the symmetric
+* cookie pool. As symmetric, random and key generation shared the same
+* pool
+*****************************************************************************/
+typedef struct lac_sym_cookie_s {
+ union {
+ lac_sym_bulk_cookie_t bulkCookie;
+ /**< symmetric bulk cookie */
+ lac_sym_key_cookie_t keyCookie;
+ /**< symmetric key cookie */
+ lac_sym_nrbg_cookie_t nrbgCookie;
+ /**< symmetric NRBG cookie */
+ } u;
+ Cpa64U keyContentDescPhyAddr;
+ Cpa64U keyHashStateBufferPhyAddr;
+ Cpa64U keySslKeyInputPhyAddr;
+ Cpa64U keyTlsKeyInputPhyAddr;
+} lac_sym_cookie_t;
+
+typedef struct icp_qat_la_auth_req_params_s {
+ /** equivalent of LW26 of icp_qat_fw_la_auth_req_params_s */
+ union {
+ uint8_t inner_prefix_sz;
+ /**< Size in bytes of the inner prefix data */
+
+ uint8_t aad_sz;
+ /**< Size in bytes of padded AAD data to prefix to the packet
+ * for CCM
+ * or GCM processing */
+ } u2;
+
+ uint8_t resrvd1;
+ /**< reserved */
+
+ uint8_t hash_state_sz;
+ /**< Number of quad words of inner and outer hash prefix data to process
+ * Maximum size is 240 */
+
+ uint8_t auth_res_sz;
+ /**< Size in bytes of the authentication result */
+} icp_qat_la_auth_req_params_t;
+
+/* Header (LW's 0 - 5) of struct icp_qat_fw_la_bulk_req_s */
+typedef struct icp_qat_la_bulk_req_hdr_s {
+ /**< LWs 0-1 */
+ icp_qat_fw_comn_req_hdr_t comn_hdr;
+ /**< Common request header - for Service Command Id,
+ * use service-specific Crypto Command Id.
+ * Service Specific Flags - use Symmetric Crypto Command Flags
+ * (all of cipher, auth, SSL3, TLS and MGF,
+ * excluding TRNG - field unused) */
+
+ /**< LWs 2-5 */
+ icp_qat_fw_comn_req_hdr_cd_pars_t cd_pars;
+ /**< Common Request content descriptor field which points either to a
+ * content descriptor
+ * parameter block or contains the service-specific data itself. */
+} icp_qat_la_bulk_req_hdr_t;
+
+/** Footer (LW's 26 - 31) of struct icp_qat_fw_la_bulk_req_s */
+typedef struct icp_qat_la_bulk_req_ftr_s {
+ /**< LW 0 - equivalent to LW26 of icp_qat_fw_la_bulk_req_t */
+ icp_qat_la_auth_req_params_t serv_specif_rqpars;
+ /**< Common request service-specific parameter field */
+
+ /**< LW's 1-5, equivalent to LWs 27-31 of icp_qat_fw_la_bulk_req_s */
+ icp_qat_fw_comn_req_cd_ctrl_t cd_ctrl;
+ /**< Common request content descriptor control block -
+ * this field is service-specific */
+} icp_qat_la_bulk_req_ftr_t;
+
+/**
+ ***
+ *******************************************************************************
+ * @ingroup LacSym
+ * Compile time check of lac_sym_bulk_cookie_t
+ *
+ * @description
+ * Performs a compile time check of lac_sym_bulk_cookie_t to ensure IA
+ * assumptions are valid.
+ *
+ *****************************************************************************/
+void LacSym_CompileTimeAssertions(void);
+
+void LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
+void LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
+
+#endif /* LAC_SYM_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_alg_chain.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_alg_chain.h
new file mode 100644
index 000000000000..1750fd0bebf4
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_alg_chain.h
@@ -0,0 +1,294 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ *****************************************************************************
+ * @file lac_sym_alg_chain.h
+ *
+ * @defgroup LacAlgChain Algorithm Chaining
+ *
+ * @ingroup LacSym
+ *
+ * Interfaces exposed by the Algorithm Chaining Component
+ *
+ * @lld_start
+ *
+ * @lld_overview
+ * This is the LAC Algorithm-Chaining feature component. This component
+ * implements session registration and cleanup functions, and a perform
+ * function. Statistics are maintained to track requests issued and completed,
+ * errors incurred, and authentication verification failures. For each
+ * function the parameters supplied by the client are checked, and then the
+ * function proceeds if all the parameters are valid. This component also
+ * incorporates support for Authenticated-Encryption (CCM and GCM) which
+ * essentially comprises of a cipher operation and a hash operation combined.
+ *
+ * This component can combine a cipher operation with a hash operation or just
+ * simply create a hash only or cipher only operation and is called from the
+ * LAC Symmetric API component. In turn it calls the LAC Cipher, LAC Hash, and
+ * LAC Symmetric QAT components. The goal here is to duplicate as little code
+ * as possible from the Cipher and Hash components.
+ *
+ * The cipher and hash operations can be combined in either order, i.e. cipher
+ * first then hash or hash first then cipher. The client specifies this via
+ * the algChainOrder field in the session context. This ordering choice is
+ * stored as part of the session descriptor, so that it is known when a
+ * perform request is issued. In the case of Authenticated-Encryption, the
+ * ordering is an implicit part of the CCM or GCM protocol.
+ *
+ * When building a content descriptor, as part of session registration, this
+ * component asks the Cipher and Hash components to build their respective
+ * parts of the session descriptor. The key aspect here is to provide the
+ * correct offsets to the Cipher and Hash components for where in the content
+ * descriptor to write their Config and Hardware Setup blocks. Also the
+ * Config block in each case must specify the appropriate next slice.
+ *
+ * When building request parameters, as part of a perform operation, this
+ * component asks the Cipher and Hash components to build their respective
+ * parts of the request parameters block. Again the key aspect here is to
+ * provide the correct offsets to the Cipher and Hash components for where in
+ * the request parameters block to write their parameters. Also the request
+ * parameters block in each case must specify the appropriate next slice.
+ *
+ * Parameter checking for session registration and for operation perform is
+ * mostly delegated to the Cipher and Hash components. There are a few
+ * extra checks that this component must perform: check the algChainOrder
+ * parameter, ensure that CCM/GCM are specified for hash/cipher algorithms
+ * as appropriate, and ensure that requests are for full packets (partial
+ * packets are not supported for Algorithm-Chaining).
+ *
+ * The perform operation allocates a cookie to capture information required
+ * in the request callback. This cookie is then freed in the callback.
+ *
+ * @lld_dependencies
+ * - \ref LacCipher "Cipher" : For taking care of the cipher aspects of
+ * session registration and operation perform
+ * - \ref LacHash "Hash" : For taking care of the hash aspects of session
+ * registration and operation perform
+ * - \ref LacSymCommon "Symmetric Common" : statistics.
+ * - \ref LacSymQat "Symmetric QAT": To build the QAT request message,
+ * request param structure, and populate the content descriptor. Also
+ * for registering a callback function to process the QAT response.
+ * - \ref QatComms "QAT Comms" : For sending messages to the QAT, and for
+ * setting the response callback
+ * - \ref LacMem "Mem" : For memory allocation and freeing, virtual/physical
+ * address translation, and translating between scalar and pointer types
+ * - OSAL : For atomics and locking
+ *
+ * @lld_module_algorithms
+ * This component builds up a chain of slices at session init time
+ * and stores it in the session descriptor. This is used for building up the
+ * content descriptor at session init time and the request parameters structure
+ * in the perform operation.
+ *
+ * The offsets for the first slice are updated so that the second slice adds
+ * its configuration information after that of the first slice. The first
+ * slice also configures the next slice appropriately.
+ *
+ * This component is very much hard-coded to just support cipher+hash or
+ * hash+cipher. It should be quite possible to extend this idea to support
+ * an arbitrary chain of commands, by building up a command chain that can
+ * be traversed in order to build up the appropriate configuration for the
+ * QAT. This notion should be looked at in the future if other forms of
+ * Algorithm-Chaining are desired.
+ *
+ * @lld_process_context
+ *
+ * @lld_end
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+#ifndef LAC_SYM_ALG_CHAIN_H
+#define LAC_SYM_ALG_CHAIN_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "lac_session.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+/* Macro for checking if zero length buffer are supported
+ * only for cipher is AES-GCM and hash are AES-GCM/AES-GMAC */
+#define IS_ZERO_LENGTH_BUFFER_SUPPORTED(cipherAlgo, hashAlgo) \
+ (CPA_CY_SYM_CIPHER_AES_GCM == cipherAlgo && \
+ (CPA_CY_SYM_HASH_AES_GMAC == hashAlgo || \
+ CPA_CY_SYM_HASH_AES_GCM == hashAlgo))
+
+/**
+*******************************************************************************
+* @ingroup LacAlgChain
+* This function registers a session for an Algorithm-Chaining operation.
+*
+* @description
+* This function is called from the LAC session register API function for
+* Algorithm-Chaining operations. It validates all input parameters. If
+* an invalid parameter is passed, an error is returned to the calling
+* function. If all parameters are valid an Algorithm-Chaining session is
+* registered.
+*
+* @param[in] instanceHandle Instance Handle
+*
+* @param[in] pSessionCtx Pointer to session context which contains
+* parameters which are static for a given
+* cryptographic session such as operation type,
+* mechanisms, and keys for cipher and/or digest
+* operations.
+* @param[out] pSessionDesc Pointer to session descriptor
+*
+* @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.
+*
+* @see cpaCySymInitSession()
+*
+*****************************************************************************/
+CpaStatus LacAlgChain_SessionInit(const CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionCtx,
+ lac_session_desc_t *pSessionDesc);
+
+/**
+*******************************************************************************
+* @ingroup LacAlgChain
+* Data path function for the Algorithm-Chaining component
+*
+* @description
+* This function gets called from cpaCySymPerformOp() which is the
+* symmetric LAC API function. It is the data path function for the
+* Algorithm-Chaining component. It does the parameter checking on the
+* client supplied parameters and if the parameters are valid, the
+* operation is performed and a request sent to the QAT, otherwise an
+* error is returned to the client.
+*
+* @param[in] instanceHandle Instance Handle
+*
+* @param[in] pSessionDesc Pointer to session descriptor
+* @param[in] pCallbackTag The application's context for this call
+* @param[in] pOpData Pointer to a structure containing request
+* parameters. The client code allocates the memory for
+* this structure. This component takes ownership of
+* the memory until it is returned in the callback.
+*
+* @param[in] pSrcBuffer Source Buffer List
+* @param[out] pDstBuffer Destination Buffer List
+* @param[out] pVerifyResult Verify Result
+*
+* @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 resource.
+*
+* @see cpaCySymPerformOp()
+*
+*****************************************************************************/
+CpaStatus LacAlgChain_Perform(const CpaInstanceHandle instanceHandle,
+ lac_session_desc_t *pSessionDesc,
+ void *pCallbackTag,
+ const CpaCySymOpData *pOpData,
+ const CpaBufferList *pSrcBuffer,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean *pVerifyResult);
+
+/**
+*******************************************************************************
+* @ingroup LacAlgChain
+* This function is used to update cipher key, as specified in provided
+* input.
+*
+* @description
+* This function is called from the LAC session register API function for
+* Algorithm-Chaining operations. It validates all input parameters. If
+* an invalid parameter is passed, an error is returned to the calling
+* function. If all parameters are valid an Algorithm-Chaining session is
+* updated.
+*
+* @threadSafe
+* No
+*
+* @param[in] pSessionDesc Pointer to session descriptor
+* @param[in] pCipherKey Pointer to new cipher key.
+*
+* @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.
+*
+*****************************************************************************/
+CpaStatus LacAlgChain_SessionCipherKeyUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pCipherKey);
+
+/**
+*******************************************************************************
+* @ingroup LacAlgChain
+* This function is used to update authentication key, as specified in
+* provided input.
+*
+* @description
+* This function is called from the LAC session register API function for
+* Algorithm-Chaining operations. It validates all input parameters. If
+* an invalid parameter is passed, an error is returned to the calling
+* function. If all parameters are valid an Algorithm-Chaining session is
+* updated.
+*
+* @threadSafe
+* No
+*
+* @param[in] pSessionDesc Pointer to session descriptor
+* @param[in] pCipherKey Pointer to new authentication key.
+*
+* @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.
+*
+*****************************************************************************/
+CpaStatus LacAlgChain_SessionAuthKeyUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAuthKey);
+
+/**
+*******************************************************************************
+* @ingroup LacAlgChain
+* This function is used to update AAD length as specified in provided
+* input.
+*
+* @description
+* This function is called from the LAC session register API function for
+* Algorithm-Chaining operations. It validates all input parameters. If
+* an invalid parameter is passed, an error is returned to the calling
+* function. If all parameters are valid an Algorithm-Chaining session is
+* updated.
+*
+* @threadSafe
+* No
+*
+* @param[in] pSessionDesc Pointer to session descriptor
+* @param[in] newAADLength New AAD length.
+*
+* @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.
+*
+*****************************************************************************/
+CpaStatus LacAlgChain_SessionAADUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa32U newAADLength);
+
+#endif /* LAC_SYM_ALG_CHAIN_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_auth_enc.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_auth_enc.h
new file mode 100644
index 000000000000..76e5e53c38a8
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_auth_enc.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_auth_enc.h
+ *
+ * @defgroup LacAuthEnc Authenticated Encryption
+ *
+ * @ingroup LacSym
+ *
+ * @description
+ * Authenticated encryption specific functionality.
+ * For CCM related code NIST SP 800-38C is followed.
+ * For GCM related code NIST SP 800-38D is followed.
+ *
+ ***************************************************************************/
+#ifndef LAC_SYM_AUTH_ENC_H_
+#define LAC_SYM_AUTH_ENC_H_
+
+/* This define for CCM describes constant sum of n and q */
+#define LAC_ALG_CHAIN_CCM_NQ_CONST 15
+
+/* These defines for CCM describe maximum and minimum
+ * length of nonce in bytes*/
+#define LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MAX 13
+#define LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MIN 7
+
+/**
+ * @ingroup LacAuthEnc
+ * This function applies any necessary padding to additional authentication data
+ * pointed by pAdditionalAuthData field of pOpData as described in
+ * NIST SP 800-38D
+ *
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in,out] pAdditionalAuthData Pointer to AAD
+ *
+ * @retval CPA_STATUS_SUCCESS Operation finished successfully
+ *
+ * @pre pAdditionalAuthData has been param checked
+ *
+ */
+void LacSymAlgChain_PrepareGCMData(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAdditionalAuthData);
+
+/**
+ * @ingroup LacAuthEnc
+ * This function prepares param checks iv and aad for CCM
+ *
+ * @param[in,out] pAdditionalAuthData Pointer to AAD
+ * @param[in,out] pIv Pointer to IV
+ * @param[in] messageLenToCipherInBytes Size of the message to cipher
+ * @param[in] ivLenInBytes Size of the IV
+ *
+ * @retval CPA_STATUS_SUCCESS Operation finished successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed
+ *
+ */
+CpaStatus LacSymAlgChain_CheckCCMData(Cpa8U *pAdditionalAuthData,
+ Cpa8U *pIv,
+ Cpa32U messageLenToCipherInBytes,
+ Cpa32U ivLenInBytes);
+
+/**
+ * @ingroup LacAuthEnc
+ * This function prepares Ctr0 and B0-Bn blocks for CCM algorithm as described
+ * in NIST SP 800-38C. Ctr0 block is placed in pIv field of pOpData and B0-BN
+ * blocks are placed in pAdditionalAuthData.
+ *
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ * @param[in,out] pAdditionalAuthData Pointer to AAD
+ * @param[in,out] pIv Pointer to IV
+ * @param[in] messageLenToCipherInBytes Size of the message to cipher
+ * @param[in] ivLenInBytes Size of the IV
+ *
+ * @retval none
+ *
+ * @pre parameters have been checked using LacSymAlgChain_CheckCCMData()
+ */
+void LacSymAlgChain_PrepareCCMData(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAdditionalAuthData,
+ Cpa8U *pIv,
+ Cpa32U messageLenToCipherInBytes,
+ Cpa32U ivLenInBytes);
+
+#endif /* LAC_SYM_AUTH_ENC_H_ */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cb.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cb.h
new file mode 100644
index 000000000000..5332f8aab510
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cb.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_cb.h
+ *
+ * @defgroup LacSymCb Symmetric callback functions
+ *
+ * @ingroup LacSym
+ *
+ * Functions to assist with callback processing for the symmetric component
+ ***************************************************************************/
+
+#ifndef LAC_SYM_CB_H
+#define LAC_SYM_CB_H
+
+/**
+ *****************************************************************************
+ * @ingroup LacSym
+ * Dequeue pending requests
+ * @description
+ * This function is called by a callback function of a blocking
+ * operation (either a partial packet or a hash precompute operaion)
+ * in softIRQ context. It dequeues requests for the following reasons:
+ * 1. All pre-computes that happened when initialising a session
+ * have completed. Dequeue any requests that were queued on the
+ * session while waiting for the precompute operations to complete.
+ * 2. A partial packet request has completed. Dequeue any partials
+ * that were queued for this session while waiting for a previous
+ * partial to complete.
+ *
+ * @param[in] pSessionDesc Pointer to the session descriptor
+ *
+ * @return CpaStatus
+ *
+ ****************************************************************************/
+CpaStatus LacSymCb_PendingReqsDequeue(lac_session_desc_t *pSessionDesc);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSym
+ * Register symmetric callback funcion handlers
+ *
+ * @description
+ * This function registers the symmetric callback handler functions with
+ * the main symmetric callback handler function
+ *
+ * @return None
+ *
+ ****************************************************************************/
+void LacSymCb_CallbacksRegister(void);
+
+#endif /* LAC_SYM_CB_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher.h
new file mode 100644
index 000000000000..822e9ce03f94
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_cipher.h
+ *
+ * @defgroup LacCipher Cipher
+ *
+ * @ingroup LacSym
+ *
+ * API functions of the cipher component
+ *
+ * @lld_start
+ * @lld_overview
+ * There is a single \ref icp_LacSym "Symmetric LAC API" for hash, cipher,
+ * auth encryption and algorithm chaining. This API is implemented by the
+ * \ref LacSym "Symmetric" module. It demultiplexes calls to this API into
+ * their basic operation and does some common parameter checking and deals
+ * with accesses to the session table.
+ *
+ * The cipher component supports data encryption/decryption using the AES, DES,
+ * and Triple-DES cipher algorithms, in ECB, CBC and CTR modes. The ARC4 stream
+ * cipher algorithm is also supported. Data may be provided as a full packet,
+ * or as a sequence of partial packets. The result of the operation can be
+ * written back to the source buffer (in-place) or to a seperate output buffer
+ * (out-of-place). Data must be encapsulated in ICP buffers.
+ *
+ * The cipher component is responsible for implementing the cipher-specific
+ * functionality for registering and de-registering a session, for the perform
+ * operation and for processing the QAT responses to cipher requests. Statistics
+ * are maintained for cipher in the symmetric \ref CpaCySymStats64 "stats"
+ * structure. This module has been seperated out into two. The cipher QAT module
+ * deals entirely with QAT data structures. The cipher module itself has minimal
+ * exposure to the QAT data structures.
+ *
+ * @lld_dependencies
+ * - \ref LacCommon
+ * - \ref LacSymQat "Symmetric QAT": Hash uses the lookup table provided by
+ * this module to validate user input. Hash also uses this module to build
+ * the hash QAT request message, request param structure, populate the
+ * content descriptor, allocate and populate the hash state prefix buffer.
+ * Hash also registers its function to process the QAT response with this
+ * module.
+ * - OSAL : For memory functions, atomics and locking
+ *
+ * @lld_module_algorithms
+ * In general, all the cipher algorithms supported by this component are
+ * implemented entirely by the QAT. However, in the case of the ARC4 algorithm,
+ * it was deemed more efficient to carry out some processing on IA. During
+ * session registration, an initial state is derived from the base key provided
+ * by the user, using a simple ARC4 Key Scheduling Algorithm (KSA). Then the
+ * base key is discarded, but the state is maintained for the duration of the
+ * session.
+ *
+ * The ARC4 key scheduling algorithm (KSA) is specified as follows
+ * (taken from http://en.wikipedia.org/wiki/RC4_(cipher)):
+ * \code
+ * for i from 0 to 255
+ * S[i] := i
+ * endfor
+ * j := 0
+ * for i from 0 to 255
+ * j := (j + S[i] + key[i mod keylength]) mod 256
+ * swap(S[i],S[j])
+ * endfor
+ * \endcode
+ *
+ * On registration of a new ARC4 session, the user provides a base key of any
+ * length from 1 to 256 bytes. This algorithm produces the initial ARC4 state
+ * (key matrix + i & j index values) from that base key. This ARC4 state is
+ * used as input for each ARC4 cipher operation in that session, and is updated
+ * by the QAT after each operation. The ARC4 state is stored in a session
+ * descriptor, and it's memory is freed when the session is deregistered.
+ *
+ * <b>Block Vs. Stream Ciphers</b>\n
+ * Block ciphers are treated slightly differently than Stream ciphers by this
+ * cipher component. Supported stream ciphers consist of AES and
+ * TripleDES algorithms in CTR mode, and ARC4. The 2 primary differences are:
+ * - Data buffers for block ciphers are required to be a multiple of the
+ * block size defined for the algorithm (e.g. 8 bytes for DES). For stream
+ * ciphers, there is no such restriction.
+ * - For stream ciphers, decryption is performed by setting the QAT hardware
+ * to encryption mode.
+ *
+ * <b>Memory address alignment of data buffers </b>\n
+ * The QAT requires that most data buffers are aligned on an 8-byte memory
+ * address boundary (64-byte boundary for optimum performance). For Cipher,
+ * this applies to the cipher key buffer passed in the Content Descriptor,
+ * and the IV/State buffer passed in the Request Parameters block in each
+ * request. Both of these buffers are provided by the user. It does not
+ * apply to the cipher source/destination data buffers.
+ * Alignment of the key buffer is ensured because the key is always copied
+ * from the user provided buffer into a new (aligned) buffer for the QAT
+ * (the hardware setup block, which configures the QAT slice). This is done
+ * once only during session registration, and the user's key buffer can be
+ * effectively discarded after that.
+ * The IV/State buffer is provided per-request by the user, so it is recommended
+ * to the user to provide aligned buffers for optimal performance. In the case
+ * where an unaligned buffer is provided, a new temporary buffer is allocated
+ * and the user's IV/State data is copied into this buffer. The aligned buffer
+ * is then passed to the QAT in the request. In the response callback, if the
+ * IV was updated by the QAT, the contents are copied back to the user's buffer
+ * and the temporary buffer is freed.
+ *
+ * @lld_process_context
+ *
+ * Session Register Sequence Diagram: For ARC4 cipher algorithm
+ * \msc
+ * APP [label="Application"], SYM [label="Symmetric LAC"],
+ * Achain [label="Alg chain"], Cipher, SQAT [label="Symmetric QAT"];
+ *
+ * APP=>SYM [ label = "cpaCySymInitSession(cbFunc)",
+ * URL="\ref cpaCySymInitSession()"] ;
+ * SYM=>SYM [ label = "LacSymSession_ParamCheck()",
+ * URL="\ref LacSymSession_ParamCheck()"];
+ * SYM=>Achain [ label = "LacAlgChain_SessionInit()",
+ * URL="\ref LacAlgChain_SessionInit()"];
+ * Achain=>Cipher [ label = "LacCipher_SessionSetupDataCheck()",
+ * URL="\ref LacCipher_SessionSetupDataCheck()"];
+ * Achain<<Cipher [ label="return"];
+ * Achain=>SQAT [ label = "LacSymQat_CipherContentDescPopulate()",
+ * URL="\ref LacSymQat_CipherContentDescPopulate()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>SQAT [ label = "LacSymQat_CipherArc4StateInit()",
+ * URL="\ref LacSymQat_CipherArc4StateInit()"];
+ * Achain<<SQAT [ label="return"];
+ * SYM<<Achain [ label = "status" ];
+ * SYM=>SYM [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * APP<<SYM [label = "status"];
+ * \endmsc
+ *
+ * Perform Sequence Diagram: TripleDES CBC-mode encryption, in-place full
+ *packet, asynchronous mode \msc APP [label="Application"], SYM
+ *[label="Symmetric LAC"], SC [label="Symmetric Common"], Achain [label="Alg
+ *chain"], Cipher, SQAT [label="Symmetric QAT"], BUF [label="LAC Buffer Desc"],
+ *SYMQ [label="Symmetric Queue"], SYMCB [label="Symmetric Callback"], LMP
+ *[label="LAC Mem Pool"], QATCOMMS [label="QAT Comms"];
+ *
+ * APP=>SYM [ label = "cpaCySymPerformOp()",
+ * URL="\ref cpaCySymPerformOp()"] ;
+ * SYM=>SYM [ label = "LacSym_Perform()",
+ * URL="\ref LacSym_Perform()"];
+ * SYM=>SYM [ label = "LacSymPerform_BufferParamCheck()",
+ * URL="\ref LacSymPerform_BufferParamCheck()"];
+ * SYM<<SYM [ label = "status"];
+ * SYM=>Achain [ label = "LacAlgChain_Perform()",
+ * URL="\ref LacCipher()"];
+ * Achain=>Cipher [ label = "LacCipher_PerformParamCheck()",
+ * URL="\ref LacCipher_PerformParamCheck()"];
+ * Achain<<Cipher [ label="status"];
+ * Achain=>LMP [label="Lac_MemPoolEntryAlloc()",
+ * URL="\ref Lac_MemPoolEntryAlloc()"];
+ * Achain<<LMP [label="return"];
+ * Achain=>Cipher [ label = "LacCipher_PerformIvCheckAndAlign()",
+ * URL="\ref LacCipher_PerformIvCheckAndAlign()"];
+ * Achain<<Cipher [ label="status"];
+ * Achain=>SQAT [ label = "LacSymQat_CipherRequestParamsPopulate()",
+ * URL="\ref LacSymQat_CipherRequestParamsPopulate()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>BUF [ label = "LacBuffDesc_BufferListDescWrite()",
+ * URL = "\ref LacBuffDesc_BufferListDescWrite()"];
+ * Achain<<BUF [ label="return"];
+ * Achain=>SQAT [ label = "SalQatMsg_CmnMsgAndReqParamsPopulate()",
+ * URL="\ref SalQatMsg_CmnMsgAndReqParamsPopulate()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>SYMQ [ label = "LacSymQueue_RequestSend()",
+ * URL="\ref LacSymQueue_RequestSend()"];
+ * SYMQ=>QATCOMMS [ label = "QatComms_MsgSend()",
+ * URL="\ref QatComms_MsgSend()"];
+ * SYMQ<<QATCOMMS [ label="status"];
+ * Achain<<SYMQ [ label="status"];
+ * SYM<<Achain[ label="status"];
+ * SYM=>SYM [ label = "LacSym_PartialPacketStateUpdate()",
+ * URL="\ref LacSym_PartialPacketStateUpdate()"];
+ * SYM<<SYM [ label = "return"];
+ * SYM=>SC [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * SYM<<SC [ label="return"];
+ * SYM<<SYM [ label = "status"];
+ * APP<<SYM [label = "status"];
+ * ... [label = "QAT processing the request and generates response"];
+ * ...;
+ * QATCOMMS=>QATCOMMS [label ="QatComms_ResponseMsgHandler()",
+ * URL="\ref QatComms_ResponseMsgHandler()"];
+ * QATCOMMS=>SQAT [label ="LacSymQat_SymRespHandler()",
+ * URL="\ref LacSymQat_SymRespHandler()"];
+ * SQAT=>SYMCB [label="LacSymCb_ProcessCallback()",
+ * URL="\ref LacSymCb_ProcessCallback()"];
+ * SYMCB=>SYMCB [label="LacSymCb_ProcessCallbackInternal()",
+ * URL="\ref LacSymCb_ProcessCallbackInternal()"];
+ * SYMCB=>LMP [label="Lac_MemPoolEntryFree()",
+ * URL="\ref Lac_MemPoolEntryFree()"];
+ * SYMCB<<LMP [label="return"];
+ * SYMCB=>SC [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * SYMCB<<SC [label = "return"];
+ * SYMCB=>APP [label="cbFunc"];
+ * SYMCB<<APP [label="return"];
+ * SQAT<<SYMCB [label="return"];
+ * QATCOMMS<<SQAT [label="return"];
+ * \endmsc
+ *
+ * #See the sequence diagram for cpaCySymInitSession()
+ *
+ * @lld_end
+ *
+ *****************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_CIPHER_H
+#define LAC_SYM_CIPHER_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "lac_session.h"
+#include "lac_sym.h"
+
+/*
+ * WARNING: There are no checks done on the parameters of the functions in
+ * this file. The expected values of the parameters are documented and it is
+ * up to the caller to provide valid values.
+ */
+
+/***************************************************************************/
+
+/**
+ *****************************************************************************
+ * @ingroup LacCipher
+ * Cipher session setup data check
+ *
+ * @description
+ * This function will check any algorithm-specific fields
+ * in the session cipher setup data structure
+ *
+ * @param[in] pCipherSetupData Pointer to session cipher context
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_FAIL Function failed.
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter.
+ *
+ *****************************************************************************/
+CpaStatus LacCipher_SessionSetupDataCheck(
+ const CpaCySymCipherSetupData *pCipherSetupData);
+
+/**
+*******************************************************************************
+* @ingroup LacCipher
+* Function that checks the perform common parameters for cipher
+*
+* @description
+* This function checks the perform parameters for cipher operations
+*
+* @param[in] cipherAlgorithm read only pointer to cipher context structure
+*
+* @param[in] pOpData read only pointer to user-supplied data for this
+* cipher operation
+* @param[in] packetLen read only length of data in buffer
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_INVALID_PARAM Invalid parameter
+*
+*****************************************************************************/
+CpaStatus LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm cipherAlgorithm,
+ const CpaCySymOpData *pOpData,
+ const Cpa64U packetLen);
+
+/**
+ *****************************************************************************
+ * @ingroup LacCipher
+ * Cipher perform IV check
+ *
+ * @description
+ * This function will perform algorithm-specific checks on the
+ * cipher Initialisation Vector data provided by the user.
+ *
+ * @param[in] pCbCookie Pointer to struct containing internal cookie
+ * data for the operation
+ * @param[in] qatPacketType QAT partial packet type (start/mid/end/none)
+ * @param[out] ppIvBuffer Returns a pointer to an IV buffer.
+ *
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_FAIL Function failed.
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter.
+ *
+ * @see LacCipher_Perform(), LacCipher_IvBufferRestore()
+ *
+ * @note LacCipher_IvBufferRestore() must be called when the request is
+ * completed to update the users IV buffer, only in the case of partial
+ * packet requests
+ *
+ *****************************************************************************/
+CpaStatus LacCipher_PerformIvCheck(sal_service_t *pService,
+ lac_sym_bulk_cookie_t *pCbCookie,
+ Cpa32U qatPacketType,
+ Cpa8U **ppIvBuffer);
+
+#endif /* LAC_SYM_CIPHER_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher_defs.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher_defs.h
new file mode 100644
index 000000000000..4eddb70420da
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_cipher_defs.h
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_cipher_defs.h
+ *
+ * @ingroup LacCipher
+ *
+ * @description
+ * This file defines constants for the cipher operations.
+ *
+ *****************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_CIPHER_DEFS_H
+#define LAC_SYM_CIPHER_DEFS_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+/***************************************************************************/
+
+/*
+ * Constants value for ARC4 algorithm
+ */
+/* ARC4 algorithm block size */
+#define LAC_CIPHER_ARC4_BLOCK_LEN_BYTES 8
+/* ARC4 key matrix size (bytes) */
+#define LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES 256
+/* ARC4 256 bytes for key matrix, 2 for i and j and 6 bytes for padding */
+#define LAC_CIPHER_ARC4_STATE_LEN_BYTES 264
+
+#define LAC_SYM_SNOW3G_CIPHER_CONFIG_FOR_HASH_SZ 40
+/* Snow3g cipher config required for performing a Snow3g hash operation.
+ * It contains 8 Bytes of config for hardware, 16 Bytes of Key and requires
+ * 16 Bytes for the IV.
+ */
+
+/* Key Modifier (KM) 4 bytes used in Kasumi algorithm in F8 mode to XOR
+ * Cipher Key (CK) */
+#define LAC_CIPHER_KASUMI_F8_KEY_MODIFIER_4_BYTES 0x55555555
+
+/* The IV length for Kasumi Kgcore is 8 bytes */
+#define LAC_CIPHER_KASUMI_F8_IV_LENGTH 8
+
+/* The Counter length for Kasumi Kgcore is 8 bytes */
+#define LAC_CIPHER_KASUMI_F8_COUNTER_LENGTH 8
+
+/* The IV length for AES F8 is 16 bytes */
+#define LAC_CIPHER_AES_F8_IV_LENGTH 16
+
+/* For Snow3G UEA2, need to make sure last 8 Bytes of IV buffer are
+ * zero. */
+#define LAC_CIPHER_SNOW3G_UEA2_IV_BUFFER_ZERO_LENGTH 8
+
+/* Reserve enough space for max length cipher state
+ * (can be IV , counter or ARC4 state) */
+#define LAC_CIPHER_STATE_SIZE_MAX LAC_CIPHER_ARC4_STATE_LEN_BYTES
+
+/* Reserve enough space for max length cipher IV
+ * (can be A value for Kasumi(passed in as IV), IV or counter,
+ * but not ARC4 state) */
+#define LAC_CIPHER_IV_SIZE_MAX ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ
+
+/* 96-bit case of IV for GCM algorithm */
+#define LAC_CIPHER_IV_SIZE_GCM_12 12
+
+/* 96-bit case of IV for CCP/GCM single pass algorithm */
+#define LAC_CIPHER_SPC_IV_SIZE 12
+/*
+ * Constants value for NULL algorithm
+ */
+/* NULL algorithm block size */
+#define LAC_CIPHER_NULL_BLOCK_LEN_BYTES 8
+
+/* Macro to check if the Algorithm is SM4 */
+#define LAC_CIPHER_IS_SM4(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_SM4_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_SM4_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_SM4_CTR))
+
+/* Macro to check if the Algorithm is CHACHA */
+#define LAC_CIPHER_IS_CHACHA(algo) (algo == CPA_CY_SYM_CIPHER_CHACHA)
+/* Macro to check if the Algorithm is AES */
+#define LAC_CIPHER_IS_AES(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_AES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_CTR) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_CCM) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_GCM) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_XTS))
+
+/* Macro to check if the Algorithm is DES */
+#define LAC_CIPHER_IS_DES(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_DES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_DES_CBC))
+
+/* Macro to check if the Algorithm is Triple DES */
+#define LAC_CIPHER_IS_TRIPLE_DES(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_3DES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_3DES_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_3DES_CTR))
+
+/* Macro to check if the Algorithm is Kasumi */
+#define LAC_CIPHER_IS_KASUMI(algo) (algo == CPA_CY_SYM_CIPHER_KASUMI_F8)
+
+/* Macro to check if the Algorithm is Snow3G UEA2 */
+#define LAC_CIPHER_IS_SNOW3G_UEA2(algo) (algo == CPA_CY_SYM_CIPHER_SNOW3G_UEA2)
+
+/* Macro to check if the Algorithm is ARC4 */
+#define LAC_CIPHER_IS_ARC4(algo) (algo == CPA_CY_SYM_CIPHER_ARC4)
+
+/* Macro to check if the Algorithm is ZUC EEA3 */
+#define LAC_CIPHER_IS_ZUC_EEA3(algo) (algo == CPA_CY_SYM_CIPHER_ZUC_EEA3)
+
+/* Macro to check if the Algorithm is NULL */
+#define LAC_CIPHER_IS_NULL(algo) (algo == CPA_CY_SYM_CIPHER_NULL)
+
+/* Macro to check if the Mode is CTR */
+#define LAC_CIPHER_IS_CTR_MODE(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_AES_CTR) || \
+ (algo == CPA_CY_SYM_CIPHER_3DES_CTR) || (LAC_CIPHER_IS_CCM(algo)) || \
+ (LAC_CIPHER_IS_GCM(algo)) || (LAC_CIPHER_IS_CHACHA(algo)) || \
+ (algo == CPA_CY_SYM_CIPHER_SM4_CTR))
+
+/* Macro to check if the Algorithm is ECB */
+#define LAC_CIPHER_IS_ECB_MODE(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_AES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_DES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_3DES_ECB) || \
+ (algo == CPA_CY_SYM_CIPHER_NULL) || \
+ (algo == CPA_CY_SYM_CIPHER_SNOW3G_UEA2) || \
+ (algo == CPA_CY_SYM_CIPHER_SM4_ECB))
+
+/* Macro to check if the Algorithm Mode is F8 */
+#define LAC_CIPHER_IS_F8_MODE(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_KASUMI_F8) || \
+ (algo == CPA_CY_SYM_CIPHER_AES_F8))
+
+/* Macro to check if the Algorithm is CBC */
+#define LAC_CIPHER_IS_CBC_MODE(algo) \
+ ((algo == CPA_CY_SYM_CIPHER_AES_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_DES_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_3DES_CBC) || \
+ (algo == CPA_CY_SYM_CIPHER_SM4_CBC))
+
+/* Macro to check if the Algorithm is CCM */
+#define LAC_CIPHER_IS_CCM(algo) (algo == CPA_CY_SYM_CIPHER_AES_CCM)
+
+/* Macro to check if the Algorithm is GCM */
+#define LAC_CIPHER_IS_GCM(algo) (algo == CPA_CY_SYM_CIPHER_AES_GCM)
+
+/* Macro to check if the Algorithm is AES-F8 */
+#define LAC_CIPHER_IS_AES_F8(algo) (algo == CPA_CY_SYM_CIPHER_AES_F8)
+
+/* Macro to check if the Algorithm Mode is XTS */
+#define LAC_CIPHER_IS_XTS_MODE(algo) (algo == CPA_CY_SYM_CIPHER_AES_XTS)
+
+/* Macro to check if the Algorithm is single pass */
+#define LAC_CIPHER_IS_SPC(cipher, hash, mask) \
+ ((LAC_CIPHER_IS_CHACHA(cipher) && (CPA_CY_SYM_HASH_POLY == hash) && \
+ ((mask)&ICP_ACCEL_CAPABILITIES_CHACHA_POLY)) || \
+ (LAC_CIPHER_IS_GCM(cipher) && ((CPA_CY_SYM_HASH_AES_GCM == hash) || \
+ (CPA_CY_SYM_HASH_AES_GMAC == hash)) && \
+ ((mask)&ICP_ACCEL_CAPABILITIES_AESGCM_SPC)))
+
+#endif /* LAC_CIPHER_DEFS_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash.h
new file mode 100644
index 000000000000..b2cd7bcd0b8c
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash.h
@@ -0,0 +1,559 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ *****************************************************************************
+ * @file lac_sym_hash.h
+ *
+ * @defgroup LacHash Hash
+ *
+ * @ingroup LacSym
+ *
+ * API functions of the Hash component
+ *
+ * @lld_start
+ * @lld_overview
+ * There is a single \ref cpaCySym "Symmetric LAC API" for hash, cipher,
+ * auth encryption and algorithm chaining. This API is implemented by the
+ * \ref LacSym "Symmetric" module. It demultiplexes calls to this API into
+ * their basic operation and does some common parameter checking and deals
+ * with accesses to the session table.
+ *
+ * The hash component supports hashing in 3 modes. PLAIN, AUTH and NESTED.
+ * Plain mode is used to provide data integrity while auth mode is used to
+ * provide integrity as well as its authenticity. Nested mode is inteded
+ * for use by non standard HMAC like algorithms such as for the SSL master
+ * key secret. Partial packets is supported for both plain and auth modes.
+ * In-place and out-of-place processing is supported for all modes. The
+ * verify operation is supported for PLAIN and AUTH modes only.
+ *
+ * The hash component is responsible for implementing the hash specific
+ * functionality for initialising a session and for a perform operation.
+ * Statistics are maintained in the symmetric \ref CpaCySymStats64 "stats"
+ * structure. This module has been seperated out into two. The hash QAT module
+ * deals entirely with QAT data structures. The hash module itself has minimal
+ * exposure to the QAT data structures.
+ *
+ * @lld_dependencies
+ * - \ref LacCommon
+ * - \ref LacSymQat "Symmetric QAT": Hash uses the lookup table provided by
+ * this module to validate user input. Hash also uses this module to build
+ * the hash QAT request message, request param structure, populate the
+ * content descriptor, allocate and populate the hash state prefix buffer.
+ * Hash also registers its function to process the QAT response with this
+ * module.
+ * - OSAL : For memory functions, atomics and locking
+ *
+ * @lld_module_algorithms
+ * <b>a. HMAC Precomputes</b>\n
+ * HMAC algorithm is specified as follows:
+ * \f$ HMAC(msg) = hash((key \oplus opad) \parallel
+ * hash((key \oplus ipad) \parallel msg ))\f$.
+ * The key is fixed per session, and is padded up to the block size of the
+ * algorithm if necessary and xored with the ipad/opad. The following portion
+ * of the operation can be precomputed: \f$ hash(key \oplus ipad) \f$ as the
+ * output of this intermediate hash will be the same for every perform
+ * operation. This intermediate state is the intermediate state of a partial
+ * partial packet. It is used as the initialiser state to \f$ hash(msg) \f$.
+ * The same applies to \f$ hash(key \oplus ipad) \f$. There is a saving in
+ * the data path by the length of time it takes to do two hashes on a block
+ * size of data. Note: a partial packet operation generates an intermediate
+ * state. The final operation on a partial packet or when a full packet is
+ * used applies padding and gives the final hash result. Esentially for the
+ * inner hash, a partial packet final is issued on the data, using the
+ * precomputed intermediate state and returns the digest.
+ *
+ * For the HMAC precomputes, \ref LacSymHash_HmacPreCompute(), there are two
+ * hash operations done using a internal content descriptor to configure the
+ * QAT. A first partial packet is specified as the packet type for the
+ * pre-computes as we need the state that uses the initialiser constants
+ * specific to the algorithm. The resulting output is copied from the hash
+ * state prefix buffer into the QAT content descriptor for the session being
+ * initialised. The state is used each perform operation as the initialiser
+ * to the algorithm
+ *
+ * <b>b. AES XCBC Precomputes</b>\n
+ * A similar technique to HMAC will be used to generate the precomputes for
+ * AES XCBC. In this case a cipher operation will be used to generate the
+ * precomputed result. The Pre-compute operation involves deriving 3 128-bit
+ * keys (K1, K2 and K3) from the 128-bit secret key K.
+ *
+ * - K1 = 0x01010101010101010101010101010101 encrypted with Key K
+ * - K2 = 0x02020202020202020202020202020202 encrypted with Key K
+ * - K3 = 0x03030303030303030303030303030303 encrypted with Key K
+ *
+ * A content descriptor is created with the cipher algorithm set to AES
+ * in ECB mode and with the keysize set to 128 bits. The 3 constants, 16 bytes
+ * each, are copied into the src buffer and an in-place cipher operation is
+ * performed on the 48 bytes. ECB mode does not maintain the state, therefore
+ * the 3 keys can be encrypted in one perform. The encrypted result is used by
+ * the state2 field in the hash setup block of the content descriptor.
+ *
+ * The precompute operations use a different lac command ID and thus have a
+ * different route in the response path to the symmetric code. In this
+ * precompute callback function the output of the precompute operation is
+ * copied into the content descriptor for the session being registered.
+ *
+ * <b>c. AES CCM Precomputes</b>\n
+ * The precomputes for AES CCM are trivial, i.e. there is no need to perform
+ * a cipher or a digest operation. Instead, the key is stored directly in
+ * the state2 field.
+ *
+ * <b>d. AES GCM Precomputes</b>\n
+ * As with AES XCBC precomputes, a cipher operation will be used to generate
+ * the precomputed result for AES GCM. In this case the Galois Hash
+ * Multiplier (H) must be derived and stored in the state2 field. H is
+ * derived by encrypting a 16-byte block of zeroes with the
+ * cipher/authentication key, using AES in ECB mode.
+ *
+ * <b>Key size for Auth algorithms</b>\n
+ * <i>Min Size</i>\n
+ * RFC 2104 states "The key for HMAC can be of any length. However, less than
+ * L bytes is strongly discouraged as it would decrease the security strength
+ * of the function."
+ *
+ * FIPS 198a states "The size of the key, K, shall be equal to or greater than
+ * L/2, where L is the size of the hash function output."
+ *
+ * RFC 4434 states "If the key has fewer than 128 bits, lengthen it to exactly
+ * 128 bits by padding it on the right with zero bits.
+ *
+ * A key length of 0 upwards is accepted. It is up to the client to pass in a
+ * key that complies with the standard they wish to support.
+ *
+ * <i>Max Size</i>\n
+ * RFC 2104 section 2 states : "Applications that use keys longer than B bytes
+ * will first hash the key using H and then use the resultant L byte string
+ * as the actual key to HMAC
+ *
+ * RFC 4434 section 2 states:
+ * "If the key is 129 bits or longer, shorten it to exactly 128 bits
+ * by performing the steps in AES-XCBC-PRF-128 (that is, the
+ * algorithm described in this document). In that re-application of
+ * this algorithm, the key is 128 zero bits; the message is the
+ * too-long current key."
+ *
+ * We push this up to the client. They need to do the hash operation through
+ * the LAC API if the key is greater than the block size of the algorithm. This
+ * will reduce the key size to the digest size of the algorithm.
+ *
+ * RFC 3566 section 4 states:
+ * AES-XCBC-MAC-96 is a secret key algorithm. For use with either ESP or
+ * AH a fixed key length of 128-bits MUST be supported. Key lengths
+ * other than 128-bits MUST NOT be supported (i.e., only 128-bit keys are
+ * to be used by AES-XCBC-MAC-96).
+ *
+ * In this case it is up to the client to provide a key that complies with
+ * the standards. i.e. exactly 128 bits in size.
+ *
+ *
+ * <b>HMAC-MD5-96 and HMAC-SHA1-96</b>\n
+ * HMAC-MD5-96 and HMAC-SHA1-96 are defined as requirements by Look Aside
+ * IPsec. The differences between HMAC-SHA1 and HMAC-SHA1-96 are that the
+ * digest produced is truncated and there are strict requirements on the
+ * size of the key that is used.
+ *
+ * They are supported in LAC by HMAC-MD5 and HMAC-SHA1. The field
+ * \ref CpaCySymHashSetupData::digestResultLenInBytes in the LAC API in
+ * bytes needs to be set to 12 bytes. There are also requirements regarding
+ * the keysize. It is up to the client to ensure the key size meets the
+ * requirements of the standards they are using.
+ *
+ * RFC 2403: HMAC-MD5-96 Key lengths other than 128-bits MUST NOT be supported.
+ * HMAC-MD5-96 produces a 128-bit authenticator value. For use with either
+ * ESP or AH, a truncated value using the first 96 bits MUST be supported.
+ *
+ * RFC2404: HMAC-SHA1-96 Key lengths other than 160- bits MUST NOT be supported
+ * HMAC-SHA-1-96 produces a 160-bit authenticator value. For use with either
+ * ESP or AH, a truncated value using the first 96 bits MUST be supported.
+ *
+ * <b>Out of place operations</b>
+ * When verify is disabled, the digest will be written to the destination
+ * buffer. When verify is enabled, the digest calculated is compared to the
+ * digest stored in the source buffer.
+ *
+ * <b>Partial Packets</b>
+ * Partial packets are handled in the \ref LacSym "Symmetric" component for
+ * the request. The hash callback function handles the update of the state
+ * in the callback.
+ *
+ *
+ * @lld_process_context
+ *
+ * Session Register Sequence Diagram: For hash modes plain and nested.
+ * \msc
+ * APP [label="Application"], SYM [label="Symmetric LAC"],
+ * Achain [label="Alg chain"], Hash, SQAT [label="Symmetric QAT"];
+ *
+ * APP=>SYM [ label = "cpaCySymInitSession(cbFunc)",
+ * URL="\ref cpaCySymInitSession()"] ;
+ * SYM=>SYM [ label = "LacSymSession_ParamCheck()",
+ * URL="\ref LacSymSession_ParamCheck()"];
+ * SYM=>Achain [ label = "LacAlgChain_SessionInit()",
+ * URL="\ref LacAlgChain_SessionInit()"];
+ * Achain=>Hash [ label = "LacHash_HashContextCheck()",
+ * URL="\ref LacHash_HashContextCheck()"];
+ * Achain<<Hash [ label="return"];
+ * Achain=>SQAT [ label = "LacSymQat_HashContentDescInit()",
+ * URL="\ref LacSymQat_HashContentDescInit()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>Hash [ label = "LacHash_StatePrefixAadBufferInit()",
+ * URL="\ref LacHash_StatePrefixAadBufferInit()"];
+ * Hash=>SQAT [ label = "LacSymQat_HashStatePrefixAadBufferSizeGet()",
+ * URL="\ref LacSymQat_HashStatePrefixAadBufferSizeGet()"];
+ * Hash<<SQAT [ label="return"];
+ * Hash=>SQAT [ label = "LacSymQat_HashStatePrefixAadBufferPopulate()",
+ * URL="\ref LacSymQat_HashStatePrefixAadBufferPopulate()"];
+ * Hash<<SQAT [ label="return"];
+ * Achain<<Hash [ label="return"];
+ * SYM<<Achain [ label = "status" ];
+ * SYM=>SYM [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * APP<<SYM [label = "status"];
+ * \endmsc
+ *
+ * Perform Sequence Diagram: For all 3 modes, full packets and in-place.
+ * \msc
+ * APP [label="Application"], SYM [label="Symmetric LAC"],
+ * Achain [label="Alg chain"], Hash, SQAT [label="Symmetric QAT"],
+ * QATCOMMS [label="QAT Comms"];
+ *
+ * APP=>SYM [ label = "cpaCySymPerformOp()",
+ * URL="\ref cpaCySymPerformOp()"] ;
+ * SYM=>SYM [ label = "LacSymPerform_BufferParamCheck()",
+ * URL="\ref LacSymPerform_BufferParamCheck()"];
+ * SYM=>Achain [ label = "LacAlgChain_Perform()",
+ * URL="\ref LacAlgChain_Perform()"];
+ * Achain=>Achain [ label = "Lac_MemPoolEntryAlloc()",
+ * URL="\ref Lac_MemPoolEntryAlloc()"];
+ * Achain=>SQAT [ label = "LacSymQat_packetTypeGet()",
+ * URL="\ref LacSymQat_packetTypeGet()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>Achain [ label = "LacBuffDesc_BufferListTotalSizeGet()",
+ * URL="\ref LacBuffDesc_BufferListTotalSizeGet()"];
+ * Achain=>Hash [ label = "LacHash_PerformParamCheck()",
+ * URL = "\ref LacHash_PerformParamCheck()"];
+ * Achain<<Hash [ label="status"];
+ * Achain=>SQAT [ label = "LacSymQat_HashRequestParamsPopulate()",
+ * URL="\ref LacSymQat_HashRequestParamsPopulate()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain<<SQAT [ label="cmdFlags"];
+ *
+ * Achain=>Achain [ label = "LacBuffDesc_BufferListDescWrite()",
+ * URL="\ref LacBuffDesc_BufferListDescWrite()"];
+ * Achain=>SQAT [ label = "SalQatMsg_CmnMsgAndReqParamsPopulate()",
+ * URL="\ref SalQatMsg_CmnMsgAndReqParamsPopulate()"];
+ * Achain<<SQAT [ label="return"];
+ * Achain=>SYM [ label = "LacSymQueue_RequestSend()",
+ * URL="\ref LacSymQueue_RequestSend()"];
+ * SYM=>QATCOMMS [ label = "QatComms_MsgSend()",
+ * URL="\ref QatComms_MsgSend()"];
+ * SYM<<QATCOMMS [ label="status"];
+ * Achain<<SYM [ label="status"];
+ * SYM<<Achain [ label="status"];
+ * SYM=>SYM [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * APP<<SYM [label = "status"];
+ * ... [label = "QAT processing the request and generates response.
+ * Callback in Bottom Half Context"];
+ * ...;
+ * QATCOMMS=>QATCOMMS [label ="QatComms_ResponseMsgHandler()",
+ * URL="\ref QatComms_ResponseMsgHandler()"];
+ * QATCOMMS=>SQAT [label ="LacSymQat_SymRespHandler()",
+ * URL="\ref LacSymQat_SymRespHandler()"];
+ * SQAT=>SYM [label="LacSymCb_ProcessCallback()",
+ * URL="\ref LacSymCb_ProcessCallback()"];
+ * SYM=>SYM [label = "LacSymCb_ProcessCallbackInternal()",
+ * URL="\ref LacSymCb_ProcessCallbackInternal()"];
+ * SYM=>SYM [label = "Lac_MemPoolEntryFree()",
+ * URL="\ref Lac_MemPoolEntryFree()"];
+ * SYM=>SYM [label = "LAC_SYM_STAT_INC", URL="\ref LAC_SYM_STAT_INC"];
+ * SYM=>APP [label="cbFunc"];
+ * APP>>SYM [label="return"];
+ * SYM>>SQAT [label="return"];
+ * SQAT>>QATCOMMS [label="return"];
+ * \endmsc
+ *
+ * @lld_end
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+#ifndef LAC_SYM_HASH_H
+#define LAC_SYM_HASH_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "lac_session.h"
+#include "lac_buffer_desc.h"
+
+/**
+ *****************************************************************************
+ * @ingroup LacHash
+ * Definition of callback function.
+ *
+ * @description
+ * This is the callback function prototype. The callback function is
+ * invoked when a hash precompute operation completes.
+ *
+ * @param[in] pCallbackTag Opaque value provided by user while making
+ * individual function call.
+ *
+ * @retval
+ * None
+ *****************************************************************************/
+typedef void (*lac_hash_precompute_done_cb_t)(void *pCallbackTag);
+
+/*
+ * WARNING: There are no checks done on the parameters of the functions in
+ * this file. The expected values of the parameters are documented and it is
+ * up to the caller to provide valid values.
+ */
+
+/**
+*******************************************************************************
+* @ingroup LacHash
+* validate the hash context
+*
+* @description
+* The client populates the hash context in the session context structure
+* This is passed as parameter to the session register API function and
+* needs to be validated.
+*
+* @param[in] pHashSetupData pointer to hash context structure
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_INVALID_PARAM Invalid parameter
+*
+*****************************************************************************/
+CpaStatus LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData);
+
+/**
+ ******************************************************************************
+ * @ingroup LacHash
+ * Populate the hash pre-compute data.
+ *
+ * @description
+ * This function populates the state1 and state2 fields with the hash
+ * pre-computes. This is only done for authentication. The state1
+ * and state2 pointers must be set to point to the correct locations
+ * in the content descriptor where the precompute result(s) will be
+ * written, before this function is called.
+ *
+ * @param[in] instanceHandle Instance Handle
+ * @param[in] pSessionSetup pointer to session setup data
+ * @param[in] callbackFn Callback function which is invoked when
+ * the precompute operation is completed
+ * @param[in] pCallbackTag Opaque data which is passed back to the user
+ * as a parameter in the callback function
+ * @param[out] pWorkingBuffer Pointer to working buffer, sufficient memory
+ * must be allocated by the caller for this.
+ * Assumption that this is 8 byte aligned.
+ * @param[out] pState1 pointer to State 1 in content descriptor
+ * @param[out] pState2 pointer to State 2 in content descriptor
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_RETRY Retry the operation.
+ * @retval CPA_STATUS_RESOURCE Error Allocating memory
+ * @retval CPA_STATUS_FAIL Operation Failed
+ *
+ *****************************************************************************/
+CpaStatus LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,
+ CpaCySymSessionSetupData *pSessionSetup,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag,
+ Cpa8U *pWorkingBuffer,
+ Cpa8U *pState1,
+ Cpa8U *pState2);
+
+/**
+ ******************************************************************************
+ * @ingroup LacHash
+ * populate the hash state prefix aad buffer.
+ *
+ * @description
+ * This function populates the hash state prefix aad buffer. This function
+ * is not called for CCM/GCM operations as the AAD data varies per request
+ * and is stored in the cookie as opposed to the session descriptor.
+ *
+ * @param[in] pHashSetupData pointer to hash setup structure
+ * @param[in] pHashControlBlock pointer to hash control block
+ * @param[in] qatHashMode QAT Mode for hash
+ * @param[in] pHashStateBuffer pointer to hash state prefix aad buffer
+ * @param[in] pHashStateBufferInfo Pointer to hash state prefix buffer info
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_FAIL Operation Failed
+ *
+ *****************************************************************************/
+CpaStatus LacHash_StatePrefixAadBufferInit(
+ sal_service_t *pService,
+ const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_la_bulk_req_ftr_t *pHashControlBlock,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ Cpa8U *pHashStateBuffer,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo);
+
+/**
+*******************************************************************************
+* @ingroup LacHash
+* Check parameters for a hash perform operation
+*
+* @description
+* This function checks the parameters for a hash perform operation.
+*
+* @param[in] pSessionDesc Pointer to session descriptor.
+* @param[in] pOpData Pointer to request parameters.
+* @param[in] srcPktSize Total size of the Buffer List
+* @param[in] pVerifyResult Pointer to user flag
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_INVALID_PARAM Invalid Parameter
+*
+*****************************************************************************/
+CpaStatus LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
+ lac_session_desc_t *pSessionDesc,
+ const CpaCySymOpData *pOpData,
+ Cpa64U srcPktSize,
+ const CpaBoolean *pVerifyResult);
+
+/**
+*******************************************************************************
+* @ingroup LacHash
+* Perform hash precompute operation for HMAC
+*
+* @description
+* This function sends 2 requests to the CPM for the hmac precompute
+* operations. The results of the ipad and opad state calculation
+* is copied into pState1 and pState2 (e.g. these may be the state1 and
+* state2 buffers in a hash content desciptor) and when
+* the final operation has completed the condition passed as a param to
+* this function is set to true.
+*
+* This function performs the XORing of the IPAD and OPAD constants to
+* the key (which was padded to the block size of the algorithm)
+*
+* @param[in] instanceHandle Instance Handle
+* @param[in] hashAlgorithm Hash Algorithm
+* @param[in] authKeyLenInBytes Length of Auth Key
+* @param[in] pAuthKey Pointer to Auth Key
+* @param[out] pWorkingMemory Pointer to working memory that is carved
+* up and used in the pre-compute operations.
+* Assumption that this is 8 byte aligned.
+* @param[out] pState1 Pointer to State 1 in content descriptor
+* @param[out] pState2 Pointer to State 2 in content descriptor
+* @param[in] callbackFn Callback function which is invoked when
+* the precompute operation is completed
+* @param[in] pCallbackTag Opaque data which is passed back to the user
+* as a parameter in the callback function
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_RETRY Retry the operation.
+* @retval CPA_STATUS_FAIL Operation Failed
+*
+*****************************************************************************/
+CpaStatus LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ Cpa32U authKeyLenInBytes,
+ Cpa8U *pAuthKey,
+ Cpa8U *pWorkingMemory,
+ Cpa8U *pState1,
+ Cpa8U *pState2,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag);
+
+/**
+*******************************************************************************
+ * @ingroup LacHash
+ * Perform hash precompute operation for XCBC MAC and GCM
+ *
+ * @description
+ * This function sends 1 request to the CPM for the precompute operation
+ * based on an AES ECB cipher. The results of the calculation is copied
+ * into pState (this may be a pointer to the State 2 buffer in a Hash
+ * content descriptor) and when the operation has completed the condition
+ * passed as a param to this function is set to true.
+ *
+ * @param[in] instanceHandle Instance Handle
+ * @param[in] hashAlgorithm Hash Algorithm
+ * @param[in] authKeyLenInBytes Length of Auth Key
+ * @param[in] pAuthKey Auth Key
+ * @param[out] pWorkingMemory Pointer to working memory that is carved
+ * up and used in the pre-compute operations.
+ * Assumption that this is 8 byte aligned.
+ * @param[out] pState Pointer to output state
+ * @param[in] callbackFn Callback function which is invoked when
+ * the precompute operation is completed
+ * @param[in] pCallbackTag Opaque data which is passed back to the user
+ * as a parameter in the callback function
+
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_RETRY Retry the operation.
+ * @retval CPA_STATUS_FAIL Operation Failed
+ *
+ *****************************************************************************/
+CpaStatus LacSymHash_AesECBPreCompute(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ Cpa32U authKeyLenInBytes,
+ Cpa8U *pAuthKey,
+ Cpa8U *pWorkingMemory,
+ Cpa8U *pState,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag);
+
+/**
+*******************************************************************************
+* @ingroup LacHash
+* initialise data structures for the hash precompute operations
+*
+* @description
+* This function registers the precompute callback handler function, which
+* is different to the default one used by symmetric. Content desciptors
+* are preallocted for the hmac precomputes as they are constant for these
+* operations.
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_RESOURCE Error allocating memory
+*
+*****************************************************************************/
+CpaStatus LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+* @ingroup LacHash
+* free resources allocated for the precompute operations
+*
+* @description
+* free up the memory allocated on init time for the content descriptors
+* that were allocated for the HMAC precompute operations.
+*
+* @return none
+*
+*****************************************************************************/
+void LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle);
+
+void LacSync_GenBufListVerifyCb(void *pCallbackTag,
+ CpaStatus status,
+ CpaCySymOp operationType,
+ void *pOpData,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean opResult);
+
+#endif /* LAC_SYM_HASH_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_defs.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_defs.h
new file mode 100644
index 000000000000..e95b0efb5b0e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_defs.h
@@ -0,0 +1,344 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_hash_defs.h
+ *
+ * @defgroup LacHashDefs Hash Definitions
+ *
+ * @ingroup LacHash
+ *
+ * Constants for hash algorithms
+ *
+ ***************************************************************************/
+
+#ifndef LAC_SYM_HASH_DEFS_H
+#define LAC_SYM_HASH_DEFS_H
+
+/* Constant for MD5 algorithm */
+#define LAC_HASH_MD5_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * MD5 block size in bytes */
+#define LAC_HASH_MD5_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * MD5 digest length in bytes */
+#define LAC_HASH_MD5_STATE_SIZE 16
+/**< @ingroup LacHashDefs
+ * MD5 state size */
+
+/* Constants for SHA1 algorithm */
+#define LAC_HASH_SHA1_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA1 Block size in bytes */
+#define LAC_HASH_SHA1_DIGEST_SIZE 20
+/**< @ingroup LacHashDefs
+ * SHA1 digest length in bytes */
+#define LAC_HASH_SHA1_STATE_SIZE 20
+/**< @ingroup LacHashDefs
+ * SHA1 state size */
+
+/* Constants for SHA224 algorithm */
+#define LAC_HASH_SHA224_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA224 block size in bytes */
+#define LAC_HASH_SHA224_DIGEST_SIZE 28
+/**< @ingroup LacHashDefs
+ * SHA224 digest length in bytes */
+#define LAC_HASH_SHA224_STATE_SIZE 32
+/**< @ingroup LacHashDefs
+ * SHA224 state size */
+
+/* Constants for SHA256 algorithm */
+#define LAC_HASH_SHA256_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA256 block size in bytes */
+#define LAC_HASH_SHA256_DIGEST_SIZE 32
+/**< @ingroup LacHashDefs
+ * SHA256 digest length */
+#define LAC_HASH_SHA256_STATE_SIZE 32
+/**< @ingroup LacHashDefs
+ * SHA256 state size */
+
+/* Constants for SHA384 algorithm */
+#define LAC_HASH_SHA384_BLOCK_SIZE 128
+/**< @ingroup LacHashDefs
+ * SHA384 block size in bytes */
+#define LAC_HASH_SHA384_DIGEST_SIZE 48
+/**< @ingroup LacHashDefs
+ * SHA384 digest length in bytes */
+#define LAC_HASH_SHA384_STATE_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA384 state size */
+
+/* Constants for SHA512 algorithm */
+#define LAC_HASH_SHA512_BLOCK_SIZE 128
+/**< @ingroup LacHashDefs
+ * SHA512 block size in bytes */
+#define LAC_HASH_SHA512_DIGEST_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA512 digest length in bytes */
+#define LAC_HASH_SHA512_STATE_SIZE 64
+/**< @ingroup LacHashDefs
+ * SHA512 state size */
+
+/* Constants for SHA3_224 algorithm */
+#define LAC_HASH_SHA3_224_BLOCK_SIZE 144
+/**< @ingroup LacHashDefs
+ * SHA3_224 block size in bytes */
+#define LAC_HASH_SHA3_224_DIGEST_SIZE 28
+/**< @ingroup LacHashDefs
+ * SHA3_224 digest length in bytes */
+#define LAC_HASH_SHA3_224_STATE_SIZE 28
+/**< @ingroup LacHashDefs
+ * SHA3_224 state size */
+
+/* Constants for SHA3_256 algorithm */
+#define LAC_HASH_SHA3_256_BLOCK_SIZE 136
+/**< @ingroup LacHashDefs
+ * SHA3_256 block size in bytes */
+#define LAC_HASH_SHA3_256_DIGEST_SIZE 32
+/**< @ingroup LacHashDefs
+ * SHA3_256 digest length in bytes */
+#define LAC_HASH_SHA3_256_STATE_SIZE 32
+/**< @ingroup LacHashDefs
+ * SHA3_256 state size */
+
+/* Constants for SHA3_384 algorithm */
+#define LAC_HASH_SHA3_384_BLOCK_SIZE 104
+/**< @ingroup LacHashDefs
+ * * SHA3_384 block size in bytes */
+#define LAC_HASH_SHA3_384_DIGEST_SIZE 48
+/**< @ingroup LacHashDefs
+ * * SHA3_384 digest length in bytes */
+#define LAC_HASH_SHA3_384_STATE_SIZE 48
+/**< @ingroup LacHashDefs
+ * * SHA3_384 state size */
+
+/* Constants for SHA3_512 algorithm */
+#define LAC_HASH_SHA3_512_BLOCK_SIZE 72
+/**< @ingroup LacHashDefs
+ * * * SHA3_512 block size in bytes */
+#define LAC_HASH_SHA3_512_DIGEST_SIZE 64
+/**< @ingroup LacHashDefs
+ * * * SHA3_512 digest length in bytes */
+#define LAC_HASH_SHA3_512_STATE_SIZE 64
+/**< @ingroup LacHashDefs
+ * * * SHA3_512 state size */
+
+/* Constants for SHAKE_128 algorithm */
+#define LAC_HASH_SHAKE_128_BLOCK_SIZE 168
+/**< @ingroup LacHashDefs
+ * * * SHAKE_128 block size in bytes */
+#define LAC_HASH_SHAKE_128_DIGEST_SIZE 0xFFFFFFFF
+/**< @ingroup LacHashDefs
+ * * * SHAKE_128 digest length in bytes ((2^32)-1)*/
+
+/* Constants for SHAKE_256 algorithm */
+#define LAC_HASH_SHAKE_256_BLOCK_SIZE 136
+/**< @ingroup LacHashDefs
+ * * * SHAKE_256 block size in bytes */
+#define LAC_HASH_SHAKE_256_DIGEST_SIZE 0xFFFFFFFF
+/**< @ingroup LacHashDefs
+ * * * SHAKE_256 digest length in bytes ((2^ 32)-1)*/
+
+/* Constants for POLY algorithm */
+#define LAC_HASH_POLY_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * POLY block size in bytes */
+#define LAC_HASH_POLY_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * POLY digest length */
+#define LAC_HASH_POLY_STATE_SIZE 0
+/**< @ingroup LacHashDefs
+ * POLY state size */
+
+/* Constants for SM3 algorithm */
+#define LAC_HASH_SM3_BLOCK_SIZE 64
+/**< @ingroup LacHashDefs
+ * SM3 block size in bytes */
+#define LAC_HASH_SM3_DIGEST_SIZE 32
+/**< @ingroup LacHashDefs
+ * SM3 digest length */
+#define LAC_HASH_SM3_STATE_SIZE 32
+/**< @ingroup LacHashDefs
+ * SM3 state size */
+
+/* Constants for XCBC precompute algorithm */
+#define LAC_HASH_XCBC_PRECOMP_KEY_NUM 3
+/**< @ingroup LacHashDefs
+ * The Pre-compute operation involves deriving 3 128-bit
+ * keys (K1, K2 and K3) */
+
+/* Constants for XCBC MAC algorithm */
+#define LAC_HASH_XCBC_MAC_BLOCK_SIZE 16
+/**< @ingroup LacHashDefs
+ * XCBC_MAC block size in bytes */
+#define LAC_HASH_XCBC_MAC_128_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * XCBC_MAC_PRF_128 digest length in bytes */
+
+/* Constants for AES CMAC algorithm */
+#define LAC_HASH_CMAC_BLOCK_SIZE 16
+/**< @ingroup LacHashDefs
+ * AES CMAC block size in bytes */
+#define LAC_HASH_CMAC_128_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * AES CMAC digest length in bytes */
+
+/* constants for AES CCM */
+#define LAC_HASH_AES_CCM_BLOCK_SIZE 16
+/**< @ingroup LacHashDefs
+ * block size for CBC-MAC part of CCM */
+#define LAC_HASH_AES_CCM_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * untruncated size of authentication field */
+
+/* constants for AES GCM */
+#define LAC_HASH_AES_GCM_BLOCK_SIZE 16
+/**< @ingroup LacHashDefs
+ * block size for Galois Hash 128 part of CCM */
+#define LAC_HASH_AES_GCM_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * untruncated size of authentication field */
+
+/* constants for KASUMI F9 */
+#define LAC_HASH_KASUMI_F9_BLOCK_SIZE 8
+/**< @ingroup LacHashDefs
+ * KASUMI_F9 block size in bytes */
+#define LAC_HASH_KASUMI_F9_DIGEST_SIZE 4
+/**< @ingroup LacHashDefs
+ * KASUMI_F9 digest size in bytes */
+
+/* constants for SNOW3G UIA2 */
+#define LAC_HASH_SNOW3G_UIA2_BLOCK_SIZE 8
+/**< @ingroup LacHashDefs
+ * SNOW3G UIA2 block size in bytes */
+#define LAC_HASH_SNOW3G_UIA2_DIGEST_SIZE 4
+/**< @ingroup LacHashDefs
+ * SNOW3G UIA2 digest size in bytes */
+
+/* constants for AES CBC MAC */
+#define LAC_HASH_AES_CBC_MAC_BLOCK_SIZE 16
+/**< @ingroup LacHashDefs
+ * AES CBC MAC block size in bytes */
+#define LAC_HASH_AES_CBC_MAC_DIGEST_SIZE 16
+/**< @ingroup LacHashDefs
+ * AES CBC MAC digest size in bytes */
+
+#define LAC_HASH_ZUC_EIA3_BLOCK_SIZE 4
+/**< @ingroup LacHashDefs
+ * ZUC EIA3 block size in bytes */
+#define LAC_HASH_ZUC_EIA3_DIGEST_SIZE 4
+/**< @ingroup LacHashDefs
+ * ZUC EIA3 digest size in bytes */
+
+/* constants for AES GCM ICV allowed sizes */
+#define LAC_HASH_AES_GCM_ICV_SIZE_8 8
+#define LAC_HASH_AES_GCM_ICV_SIZE_12 12
+#define LAC_HASH_AES_GCM_ICV_SIZE_16 16
+
+/* constants for AES CCM ICV allowed sizes */
+#define LAC_HASH_AES_CCM_ICV_SIZE_MIN 4
+#define LAC_HASH_AES_CCM_ICV_SIZE_MAX 16
+
+/* constants for authentication algorithms */
+#define LAC_HASH_IPAD_BYTE 0x36
+/**< @ingroup LacHashDefs
+ * Ipad Byte */
+#define LAC_HASH_OPAD_BYTE 0x5c
+/**< @ingroup LacHashDefs
+ * Opad Byte */
+
+#define LAC_HASH_IPAD_4_BYTES 0x36363636
+/**< @ingroup LacHashDefs
+ * Ipad for 4 Bytes */
+#define LAC_HASH_OPAD_4_BYTES 0x5c5c5c5c
+/**< @ingroup LacHashDefs
+ * Opad for 4 Bytes */
+
+/* Key Modifier (KM) value used in Kasumi algorithm in F9 mode to XOR
+ * Integrity Key (IK) */
+#define LAC_HASH_KASUMI_F9_KEY_MODIFIER_4_BYTES 0xAAAAAAAA
+/**< @ingroup LacHashDefs
+ * Kasumi F9 Key Modifier for 4 bytes */
+
+#define LAC_SYM_QAT_HASH_IV_REQ_MAX_SIZE_QW 2
+/**< @ingroup LacSymQatHash
+ * Maximum size of IV embedded in the request.
+ * This is set to 2, namely 4 LONGWORDS. */
+
+#define LAC_SYM_QAT_HASH_STATE1_MAX_SIZE_BYTES LAC_HASH_SHA512_BLOCK_SIZE
+/**< @ingroup LacSymQatHash
+ * Maximum size of state1 in the hash setup block of the content descriptor.
+ * This is set to the block size of SHA512. */
+
+#define LAC_SYM_QAT_HASH_STATE2_MAX_SIZE_BYTES LAC_HASH_SHA512_BLOCK_SIZE
+/**< @ingroup LacSymQatHash
+ * Maximum size of state2 in the hash setup block of the content descriptor.
+ * This is set to the block size of SHA512. */
+
+#define LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES 255
+/**< Maximum size of the inner and outer prefix for nested hashing operations.
+ * This is got from the maximum size supported by the accelerator which stores
+ * the size in an 8bit field */
+
+#define LAC_MAX_HASH_STATE_STORAGE_SIZE \
+ (sizeof(icp_qat_hw_auth_counter_t) + LAC_HASH_SHA512_STATE_SIZE)
+/**< Maximum size of the hash state storage section of the hash state prefix
+ * buffer */
+
+#define LAC_MAX_HASH_STATE_BUFFER_SIZE_BYTES \
+ LAC_MAX_HASH_STATE_STORAGE_SIZE + \
+ (LAC_ALIGN_POW2_ROUNDUP(LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES, \
+ LAC_QUAD_WORD_IN_BYTES) * \
+ 2)
+/**< Maximum size of the hash state prefix buffer will be for nested hash when
+ * there is the maximum sized inner prefix and outer prefix */
+
+#define LAC_MAX_AAD_SIZE_BYTES 256
+/**< Maximum size of AAD in bytes */
+
+#define IS_HMAC_ALG(algorithm) \
+ ((algorithm == CPA_CY_SYM_HASH_MD5) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA1) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA224) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA256) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA384) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA512) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA3_224) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA3_256) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA3_384) || \
+ (algorithm == CPA_CY_SYM_HASH_SHA3_512) || \
+ (algorithm == CPA_CY_SYM_HASH_SM3))
+/**< @ingroup LacSymQatHash
+ * Macro to detect if the hash algorithm is a HMAC algorithm */
+
+#define IS_HASH_MODE_1(qatHashMode) (ICP_QAT_HW_AUTH_MODE1 == qatHashMode)
+/**< @ingroup LacSymQatHash
+ * Macro to detect is qat hash mode is set to 1 (precompute mode)
+ * only used with algorithms in hash mode CPA_CY_SYM_HASH_MODE_AUTH */
+
+#define IS_HASH_MODE_2(qatHashMode) (ICP_QAT_HW_AUTH_MODE2 == qatHashMode)
+/**< @ingroup LacSymQatHash
+ * Macro to detect is qat hash mode is set to 2. This is used for TLS and
+ * mode 2 HMAC (no preompute mode) */
+
+#define IS_HASH_MODE_2_AUTH(qatHashMode, hashMode) \
+ ((IS_HASH_MODE_2(qatHashMode)) && \
+ (CPA_CY_SYM_HASH_MODE_AUTH == hashMode))
+/**< @ingroup LacSymQatHash
+ * Macro to check for qat hash mode is set to 2 and the hash mode is
+ * Auth. This applies to HMAC algorithms (no pre compute). This is used
+ * to differntiate between TLS and HMAC */
+
+#define IS_HASH_MODE_2_NESTED(qatHashMode, hashMode) \
+ ((IS_HASH_MODE_2(qatHashMode)) && \
+ (CPA_CY_SYM_HASH_MODE_NESTED == hashMode))
+/**< @ingroup LacSymQatHash
+ * Macro to check for qat hash mode is set to 2 and the LAC hash mode is
+ * Nested. This applies to TLS. This is used to differentiate between
+ * TLS and HMAC */
+
+#endif /* LAC_SYM_HASH_DEFS_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_precomputes.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_precomputes.h
new file mode 100644
index 000000000000..6fd93cc28175
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_hash_precomputes.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_hash_precomputes.h
+ *
+ * @defgroup LacHashDefs Hash Definitions
+ *
+ * @ingroup LacHash
+ *
+ * Constants for hash algorithms
+ *
+ ***************************************************************************/
+#ifndef LAC_SYM_HASH_PRECOMPUTES_H
+#define LAC_SYM_HASH_PRECOMPUTES_H
+
+#include "lac_sym_hash.h"
+
+#define LAC_SYM_AES_CMAC_RB_128 0x87 /* constant used for */
+ /* CMAC calculation */
+
+#define LAC_SYM_HASH_MSBIT_MASK 0x80 /* Mask to check MSB top bit */
+ /* zero or one */
+
+#define LAC_SINGLE_BUFFER_HW_META_SIZE \
+ (sizeof(icp_buffer_list_desc_t) + sizeof(icp_flat_buffer_desc_t))
+/**< size of memory to allocate for the HW buffer list that is sent to the
+ * QAT */
+
+#define LAC_SYM_HASH_PRECOMP_MAX_WORKING_BUFFER \
+ ((sizeof(lac_sym_hash_precomp_op_data_t) * 2) + \
+ sizeof(lac_sym_hash_precomp_op_t))
+/**< maximum size of the working data for the HMAC precompute operations
+ *
+ * Maximum size of lac_sym_hash_precomp_op_data_t is 264 bytes. For hash
+ * precomputes there are 2 of these structrues and a further
+ * lac_sym_hash_precomp_op_t structure required. This comes to a total of 536
+ * bytes.
+ * For the asynchronous version of the precomputes, the memory for the hash
+ * state prefix buffer is used as the working memory. There are 584 bytes
+ * which are alloacted for the hash state prefix buffer which is enough to
+ * carve up for the precomputes.
+ */
+
+#define LAC_SYM_HASH_PRECOMP_MAX_AES_ECB_DATA \
+ ((ICP_QAT_HW_AES_128_KEY_SZ) * (3))
+/**< Maximum size for the data that an AES ECB precompute is generated on */
+
+/**
+ *****************************************************************************
+ * @ingroup LacHashDefs
+ * Precompute type enum
+ * @description
+ * Enum used to distinguish between precompute types
+ *
+ *****************************************************************************/
+typedef enum {
+ LAC_SYM_HASH_PRECOMP_HMAC = 1,
+ /**< Hmac precompute operation. Copy state from hash state buffer */
+ LAC_SYM_HASH_PRECOMP_AES_ECB,
+ /**< XCBC/CGM precompute, Copy state from data buffer */
+} lac_sym_hash_precomp_type_t;
+
+/**
+ *****************************************************************************
+ * @ingroup LacHashDefs
+ * overall precompute management structure
+ * @description
+ * structure used to manage the precompute operations for a session
+ *
+ *****************************************************************************/
+typedef struct lac_sym_hash_precomp_op_s {
+ lac_hash_precompute_done_cb_t callbackFn;
+ /**< Callback function to be invoked when the final precompute completes
+ */
+
+ void *pCallbackTag;
+ /**< Opaque data to be passed back as a parameter in the callback */
+
+ QatUtilsAtomic opsPending;
+ /**< counter used to determine if the current precompute is the
+ * final one. */
+
+} lac_sym_hash_precomp_op_t;
+
+/**
+ *****************************************************************************
+ * @ingroup LacHashDefs
+ * hmac precompute structure as used by the QAT
+ * @description
+ * data used by the QAT for HMAC precomputes
+ *
+ * Must be allocated on an 8-byte aligned memory address.
+ *
+ *****************************************************************************/
+typedef struct lac_sym_hash_hmac_precomp_qat_s {
+ Cpa8U data[LAC_HASH_SHA512_BLOCK_SIZE];
+ /**< data to be hashed - block size of data for the algorithm */
+ /* NOTE: to save space we could have got the QAT to overwrite
+ * this with the hash state storage */
+ icp_qat_fw_la_auth_req_params_t hashReqParams;
+ /**< Request parameters as read in by the QAT */
+ Cpa8U bufferDesc[LAC_SINGLE_BUFFER_HW_META_SIZE];
+ /**< Buffer descriptor structure */
+ Cpa8U hashStateStorage[LAC_MAX_HASH_STATE_STORAGE_SIZE];
+ /**< Internal buffer where QAT writes the intermediate partial
+ * state that is used in the precompute */
+} lac_sym_hash_hmac_precomp_qat_t;
+
+/**
+ *****************************************************************************
+ * @ingroup LacHashDefs
+ * AES ECB precompute structure as used by the QAT
+ * @description
+ * data used by the QAT for AES ECB precomptes
+ *
+ * Must be allocated on an 8-byte aligned memory address.
+ *
+ *****************************************************************************/
+typedef struct lac_sym_hash_aes_precomp_qat_s {
+ Cpa8U contentDesc[LAC_SYM_QAT_MAX_CIPHER_SETUP_BLK_SZ];
+ /**< Content descriptor for a cipher operation */
+ Cpa8U data[LAC_SYM_HASH_PRECOMP_MAX_AES_ECB_DATA];
+ /**< The data to be ciphered is conatined here and the result is
+ * written in place back into this buffer */
+ icp_qat_fw_la_cipher_req_params_t cipherReqParams;
+ /**< Request parameters as read in by the QAT */
+ Cpa8U bufferDesc[LAC_SINGLE_BUFFER_HW_META_SIZE];
+ /**< Buffer descriptor structure */
+} lac_sym_hash_aes_precomp_qat_t;
+
+/**
+ *****************************************************************************
+ * @ingroup LacHashDefs
+ * overall structure for managing a single precompute operation
+ * @description
+ * overall structure for managing a single precompute operation
+ *
+ * Must be allocated on an 8-byte aligned memory address.
+ *
+ *****************************************************************************/
+typedef struct lac_sym_hash_precomp_op_data_s {
+ sal_crypto_service_t *pInstance;
+ /**< Instance handle for the operation */
+ Cpa8U reserved[4];
+ /**< padding to align later structures on minimum 8-Byte address */
+ lac_sym_hash_precomp_type_t opType;
+ /**< operation type to determine the precompute type in the callback */
+ lac_sym_hash_precomp_op_t *pOpStatus;
+ /**< structure containing the counter and the condition for the overall
+ * precompute operation. This is a pointer because the memory structure
+ * may be shared between precomputes when there are more than 1 as in
+ * the
+ * case of HMAC */
+ union {
+ lac_sym_hash_hmac_precomp_qat_t hmacQatData;
+ /**< Data sent to the QAT for hmac precomputes */
+ lac_sym_hash_aes_precomp_qat_t aesQatData;
+ /**< Data sent to the QAT for AES ECB precomputes */
+ } u;
+
+ /**< ASSUMPTION: The above structures are 8 byte aligned if the overall
+ * struct is 8 byte aligned, as there are two 4 byte fields before this
+ * union */
+ Cpa32U stateSize;
+ /**< Size of the state to be copied into the state pointer in the
+ * content
+ * descriptor */
+ Cpa8U *pState;
+ /**< pointer to the state in the content descriptor where the result of
+ * the precompute should be copied to */
+} lac_sym_hash_precomp_op_data_t;
+
+#endif /* LAC_SYM_HASH_PRECOMPUTES_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_key.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_key.h
new file mode 100644
index 000000000000..bae0d8faabc7
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_key.h
@@ -0,0 +1,184 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ *****************************************************************************
+ * @file lac_sym_key.h
+ *
+ * @defgroup LacSymKey Key Generation
+ *
+ * @ingroup LacSym
+ *
+ * @lld_start
+ *
+ * @lld_overview
+ *
+ * Key generation component is reponsible for SSL, TLS & MGF operations. All
+ * memory required for the keygen operations is got from the keygen cookie
+ * structure which is carved up as required.
+ *
+ * For SSL the QAT accelerates the nested hash function with MD5 as the
+ * outer hash and SHA1 as the inner hash.
+ *
+ * Refer to sections in draft-freier-ssl-version3-02.txt:
+ * 6.1 Asymmetric cryptographic computations - This refers to coverting
+ * the pre master secret to the master secret.
+ * 6.2.2 Converting the master secret into keys and MAC secrets - Using
+ * the master secret to generate the key material.
+ *
+ * For TLS the QAT accelerates the PRF function as described in
+ * rfc4346 - TLS version 1.1 (this obsoletes rfc2246 - TLS version 1.0)
+ * 5. HMAC and the pseudorandom function - For the TLS PRF and getting
+ * S1 and S2 from the secret.
+ * 6.3. Key calculation - For how the key material is generated
+ * 7.4.9. Finished - How the finished message uses the TLS PRF
+ * 8.1. Computing the master secret
+ *
+ *
+ * @lld_dependencies
+ * \ref LacSymQatHash: for building up hash content descriptor
+ * \ref LacMem: for virt to phys coversions
+ *
+ * @lld_initialisation
+ * The reponse handler is registered with Symmetric. The Maximum SSL is
+ * allocated. A structure is allocated containing all the TLS lables that
+ * are supported. On shutdown the memory for these structures are freed.
+ *
+ * @lld_module_algorithms
+ * @lld_process_context
+ *
+ * @lld_end
+ *
+ *
+ *****************************************************************************/
+#ifndef LAC_SYM_KEY_H_
+#define LAC_SYM_KEY_H_
+
+#include "icp_qat_fw_la.h"
+#include "cpa_cy_key.h"
+
+/**< @ingroup LacSymKey
+ * Label for SSL. Size is 136 bytes for 16 iterations, which can theroretically
+ * generate up to 256 bytes of output data. QAT will generate a maximum of
+ * 255 bytes */
+
+#define LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL ("master secret")
+/**< @ingroup LacSymKey
+ * Label for TLS Master Secret Key Derivation, as defined in RFC4346 */
+
+#define LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL ("key expansion")
+/**< @ingroup LacSymKey
+ * Label for TLS Key Material Generation, as defined in RFC4346. */
+
+#define LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL ("client finished")
+/**< @ingroup LacSymKey
+ * Label for TLS Client finished Message, as defined in RFC4346. */
+
+#define LAC_SYM_KEY_TLS_SERVER_FIN_LABEL ("server finished")
+/**< @ingroup LacSymKey
+ * Label for TLS Server finished Message, as defined in RFC4346. */
+
+/*
+*******************************************************************************
+* Define Constants and Macros for SSL, TLS and MGF
+*******************************************************************************
+*/
+
+#define LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW 0
+/**< Used to indicate there is no hash block offset in the content descriptor
+ */
+
+/*
+*******************************************************************************
+* Define Constant lengths for HKDF TLS v1.3 sublabels.
+*******************************************************************************
+*/
+#define HKDF_SUB_LABEL_KEY_LENGTH ((Cpa8U)13)
+#define HKDF_SUB_LABEL_IV_LENGTH ((Cpa8U)12)
+#define HKDF_SUB_LABEL_RESUMPTION_LENGTH ((Cpa8U)20)
+#define HKDF_SUB_LABEL_FINISHED_LENGTH ((Cpa8U)18)
+#define HKDF_SUB_LABELS_ALL \
+ (CPA_CY_HKDF_SUBLABEL_KEY | CPA_CY_HKDF_SUBLABEL_IV | \
+ CPA_CY_HKDF_SUBLABEL_RESUMPTION | CPA_CY_HKDF_SUBLABEL_FINISHED)
+#define LAC_KEY_HKDF_SUBLABELS_NUM 4
+#define LAC_KEY_HKDF_DIGESTS 0
+#define LAC_KEY_HKDF_CIPHERS_MAX (CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256 + 1)
+#define LAC_KEY_HKDF_SUBLABELS_MAX (LAC_KEY_HKDF_SUBLABELS_NUM + 1)
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * TLS label struct
+ *
+ * @description
+ * This structure is used to hold the various TLS labels. Each field is
+ * on an 8 byte boundary provided the structure itslef is 8 bytes aligned.
+ *****************************************************************************/
+typedef struct lac_sym_key_tls_labels_s {
+ Cpa8U masterSecret[ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX];
+ /**< Master secret label */
+ Cpa8U keyMaterial[ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX];
+ /**< Key material label */
+ Cpa8U clientFinished[ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX];
+ /**< client finished label */
+ Cpa8U serverFinished[ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX];
+ /**< server finished label */
+} lac_sym_key_tls_labels_t;
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * TLS HKDF sub label struct
+ *
+ * @description
+ * This structure is used to hold the various TLS HKDF sub labels.
+ * Each field is on an 8 byte boundary.
+ *****************************************************************************/
+typedef struct lac_sym_key_tls_hkdf_sub_labels_s {
+ CpaCyKeyGenHKDFExpandLabel keySublabel256;
+ /**< CPA_CY_HKDF_SUBLABEL_KEY */
+ CpaCyKeyGenHKDFExpandLabel ivSublabel256;
+ /**< CPA_CY_HKDF_SUBLABEL_IV */
+ CpaCyKeyGenHKDFExpandLabel resumptionSublabel256;
+ /**< CPA_CY_HKDF_SUBLABEL_RESUMPTION */
+ CpaCyKeyGenHKDFExpandLabel finishedSublabel256;
+ /**< CPA_CY_HKDF_SUBLABEL_FINISHED */
+ CpaCyKeyGenHKDFExpandLabel keySublabel384;
+ /**< CPA_CY_HKDF_SUBLABEL_KEY */
+ CpaCyKeyGenHKDFExpandLabel ivSublabel384;
+ /**< CPA_CY_HKDF_SUBLABEL_IV */
+ CpaCyKeyGenHKDFExpandLabel resumptionSublabel384;
+ /**< CPA_CY_HKDF_SUBLABEL_RESUMPTION */
+ CpaCyKeyGenHKDFExpandLabel finishedSublabel384;
+ /**< CPA_CY_HKDF_SUBLABEL_FINISHED */
+ CpaCyKeyGenHKDFExpandLabel keySublabelChaChaPoly;
+ /**< CPA_CY_HKDF_SUBLABEL_KEY */
+ CpaCyKeyGenHKDFExpandLabel ivSublabelChaChaPoly;
+ /**< CPA_CY_HKDF_SUBLABEL_IV */
+ CpaCyKeyGenHKDFExpandLabel resumptionSublabelChaChaPoly;
+ /**< CPA_CY_HKDF_SUBLABEL_RESUMPTION */
+ CpaCyKeyGenHKDFExpandLabel finishedSublabelChaChaPoly;
+ /**< CPA_CY_HKDF_SUBLABEL_FINISHED */
+ Cpa64U sublabelPhysAddr256;
+ /**< Physical address of the SHA-256 subLabels */
+ Cpa64U sublabelPhysAddr384;
+ /**< Physical address of the SHA-384 subLabels */
+ Cpa64U sublabelPhysAddrChaChaPoly;
+ /**< Physical address of the ChaChaPoly subLabels */
+} lac_sym_key_tls_hkdf_sub_labels_t;
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * This function prints the stats to standard out.
+ *
+ * @retval CPA_STATUS_SUCCESS Status Success
+ * @retval CPA_STATUS_FAIL General failure
+ *
+ *****************************************************************************/
+void LacKeygen_StatsShow(CpaInstanceHandle instanceHandle);
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_partial.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_partial.h
new file mode 100644
index 000000000000..b3088784a273
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_partial.h
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_partial.h
+ *
+ * @defgroup LacSymPartial Partial Packets
+ *
+ * @ingroup LacSymCommon
+ *
+ * Partial packet handling code
+ *
+ * @lld_start
+ *
+ * <b>Partials In Flight</b>\n
+ * The API states that for partial packets the client should not submit
+ * the next partial request until the callback for the current partial has
+ * been called. We have chosen to enforce this rather than letting the user
+ * proceed where they would get an incorrect digest, cipher result.
+ *
+ * Maintain a SpinLock for partials in flight per session. Try and acquire this
+ * SpinLock. If it cant be acquired return an error straight away to the client
+ * as there is already a partial in flight. There is no blocking in the data
+ * path for this.
+ *
+ * By preventing any other partials from coming in while a partial is in flight
+ * we can check and change the state of the session without having to lock
+ * round it (dont want to have to lock and block in the data path). The state
+ * of the session indicates the previous packet type that a request was
+ * successfully completed for. The last packet type is only updated for partial
+ * packets. This state determines the packet types that can be accepted.
+ * e.g a last partial will not be accepted unless the previous packet was a
+ * partial. By only allowing one partial packet to be in flight, there is no
+ * need to lock around the update of the previous packet type for the session.
+ *
+ * The ECB Cipher mode, ciphers each block separately. No state is maintained
+ * between blocks. There is no need to wait for the callback for previous
+ * partial in ECB mode as the result of the previous partial has no impact on
+ * it. The API and our implementation only allows 1 partial packet to be in
+ * flight per session, therefore a partial packet request for ECB mode must
+ * be fully completed (ie. callback called) before the next partial request
+ * can be issued.
+ *
+ * <b>Partial Ordering</b>\n
+ * The ordering that the user submits partial packets will be checked.
+ * (we could have let the user proceed where they will get an incorrect
+ * digest/cipher result but chose against this).
+ *
+ * -# Maintain the last packet type of a partial operation for the session. If
+ * there have been no previous partials, we will accept only first partials
+ * -# The state must be set to partial before we will accept a final partial.
+ * i.e. a partial request must have already completed.
+ *
+ * The last packet type is updated in the callback for partial packets as this
+ * is the only place we can guarantee that a partial packet operation has been
+ * completed. When a partial completes the state can be updated from FULL to
+ * PARTIAL. The SpinLock for partial packets in flight for the session can be
+ * unlocked at this point. On a final Partial request the last packet type is
+ * reset back to FULL. NOTE: This is not done at the same time as the check in
+ * the perform as if an error occurs we would have to roll back the state
+ *
+ * For Hash mode it is possible to interleave full and a single partial
+ * packet stream in a session as the hash state buffer is updated for partial
+ * packets. It is not touched by full packets. For cipher mode, as the client
+ * manages the state, they can interleave full and a single partial packets.
+ * For ARC4, the state is managed internally and the packet type will always
+ * be set to partial internally.
+ *
+ * @lld_end
+ *
+ ***************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_PARTIAL_H
+#define LAC_SYM_PARTIAL_H
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/***************************************************************************/
+
+/**
+*******************************************************************************
+* @ingroup LacSymPartial
+* check if partial packet request is valid for a session
+*
+* @description
+* This function checks to see if there is a partial packet request in
+* flight and then if the partial state is correct
+*
+* @param[in] packetType Partial packet request
+* @param[in] partialState Partial state of session
+*
+* @retval CPA_STATUS_SUCCESS Normal Operation
+* @retval CPA_STATUS_INVALID_PARAM Invalid Parameter
+*
+*****************************************************************************/
+CpaStatus LacSym_PartialPacketStateCheck(CpaCySymPacketType packetType,
+ CpaCySymPacketType partialState);
+
+/**
+*******************************************************************************
+* @ingroup LacSymPartial
+* update the state of the partial packet in a session
+*
+* @description
+* This function is called in callback operation. It updates the state
+* of a partial packet in a session and indicates that there is no
+* longer a partial packet in flight for the session
+*
+* @param[in] packetType Partial packet request
+* @param[out] pPartialState Pointer to partial state of session
+*
+*****************************************************************************/
+void LacSym_PartialPacketStateUpdate(CpaCySymPacketType packetType,
+ CpaCySymPacketType *pPartialState);
+
+#endif /* LAC_SYM_PARTIAL_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat.h
new file mode 100644
index 000000000000..af49764b6498
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat.h
+ *
+ * @defgroup LacSymQat Symmetric QAT
+ *
+ * @ingroup LacSym
+ *
+ * Interfaces for populating the qat structures for a symmetric operation
+ *
+ * @lld_start
+ *
+ * @lld_overview
+ * This file documents the interfaces for populating the qat structures
+ * that are common for all symmetric operations.
+ *
+ * @lld_dependencies
+ * - \ref LacSymQatHash "Hash QAT Comms" Sym Qat commons for Hash
+ * - \ref LacSymQat_Cipher "Cipher QAT Comms" Sym Qat commons for Cipher
+ * - OSAL: logging
+ * - \ref LacMem "Memory" - Inline memory functions
+ *
+ * @lld_initialisation
+ * This component is initialied during the LAC initialisation sequence. It
+ * is called by the Symmetric Initialisation function.
+ *
+ * @lld_module_algorithms
+ *
+ * @lld_process_context
+ * Refer to \ref LacHash "Hash" and \ref LacCipher "Cipher" for sequence
+ * diagrams to see their interactions with this code.
+ *
+ *
+ * @lld_end
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+#ifndef LAC_SYM_QAT_H
+#define LAC_SYM_QAT_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "icp_accel_devices.h"
+#include "icp_qat_fw_la.h"
+#include "icp_qat_hw.h"
+#include "lac_session.h"
+#include "sal_qat_cmn_msg.h"
+#include "lac_common.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#define LAC_SYM_DEFAULT_QAT_PTR_TYPE QAT_COMN_PTR_TYPE_SGL
+#define LAC_SYM_DP_QAT_PTR_TYPE QAT_COMN_PTR_TYPE_FLAT
+#define LAC_SYM_KEY_QAT_PTR_TYPE QAT_COMN_PTR_TYPE_FLAT
+/**< @ingroup LacSymQat
+ * LAC SYM Source & Destination buffer type (FLAT/SGL) */
+
+#define LAC_QAT_SYM_REQ_SZ_LW 32
+#define SYM_TX_MSG_SIZE (LAC_QAT_SYM_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES)
+#define NRBG_TX_MSG_SIZE (LAC_QAT_SYM_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES)
+
+#define LAC_QAT_SYM_RESP_SZ_LW 8
+#define SYM_RX_MSG_SIZE (LAC_QAT_SYM_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES)
+#define NRBG_RX_MSG_SIZE (LAC_QAT_SYM_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES)
+
+/**
+ *******************************************************************************
+ * @ingroup LacSymQat
+ * Symmetric crypto response handler
+ *
+ * @description
+ * This function handles the symmetric crypto response
+ *
+ * @param[in] trans_handle transport handle (if ICP_QAT_DBG set)
+ * @param[in] instanceHandle void* pRespMsg
+ *
+ *
+ *****************************************************************************/
+void LacSymQat_SymRespHandler(void *pRespMsg);
+
+/**
+ *******************************************************************************
+ * @ingroup LacSymQat
+ * Initialise the Symmetric QAT code
+ *
+ * @description
+ * This function initialises the symmetric QAT code
+ *
+ * @param[in] device Pointer to the acceleration device
+ * structure
+ * @param[in] instanceHandle Instance handle
+ * @param[in] numSymRequests Number of concurrent requests a pair
+ * (tx and rx) need to support
+ *
+ * @return CPA_STATUS_SUCCESS Operation successful
+ * @return CPA_STATUS_FAIL Initialisation Failed
+ *
+ *****************************************************************************/
+CpaStatus LacSymQat_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacSymQat
+ * Register a response handler function for a symmetric command ID
+ *
+ * @description
+ * This function registers a response handler function for a symmetric
+ * operation.
+ *
+ * Note: This operation should only be performed once by the init function
+ * of a component. There is no corresponding deregister function, but
+ * registering a NULL function pointer will have the same effect. There
+ * MUST not be any requests in flight when calling this function.
+ *
+ * @param[in] lacCmdId Command Id of operation
+ * @param[in] pCbHandler callback handler function
+ *
+ * @return None
+ *
+ *****************************************************************************/
+void LacSymQat_RespHandlerRegister(icp_qat_fw_la_cmd_id_t lacCmdId,
+ sal_qat_resp_handler_func_t pCbHandler);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat
+ * get the QAT packet type
+ *
+ * @description
+ * This function returns the QAT packet type for a LAC packet type. The
+ * LAC packet type does not indicate a first partial. therefore for a
+ * partial request, the previous packet type needs to be looked at to
+ * figure out if the current partial request is a first partial.
+ *
+ *
+ * @param[in] packetType LAC Packet type
+ * @param[in] packetState LAC Previous Packet state
+ * @param[out] pQatPacketType Packet type using the QAT macros
+ *
+ * @return none
+ *
+ *****************************************************************************/
+void LacSymQat_packetTypeGet(CpaCySymPacketType packetType,
+ CpaCySymPacketType packetState,
+ Cpa32U *pQatPacketType);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat
+ * Populate the command flags based on the packet type
+ *
+ * @description
+ * This function populates the following flags in the Symmetric Crypto
+ * service_specif_flags field of the common header of the request:
+ * - LA_PARTIAL
+ * - UPDATE_STATE
+ * - RET_AUTH_RES
+ * - CMP_AUTH_RES
+ * based on looking at the input params listed below.
+ *
+ * @param[in] qatPacketType Packet type
+ * @param[in] cmdId Command Id
+ * @param[in] cipherAlgorithm Cipher Algorithm
+ * @param[out] pLaCommandFlags Command Flags
+ *
+ * @return none
+ *
+ *****************************************************************************/
+void LacSymQat_LaPacketCommandFlagSet(Cpa32U qatPacketType,
+ icp_qat_fw_la_cmd_id_t laCmdId,
+ CpaCySymCipherAlgorithm cipherAlgorithm,
+ Cpa16U *pLaCommandFlags,
+ Cpa32U ivLenInBytes);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat
+ *
+ *
+ * @description
+ * defaults the common request service specific flags
+ *
+ * @param[in] laCmdFlags Common request service specific flags
+ * @param[in] symOp Type of operation performed e.g hash or cipher
+ *
+ * @return none
+ *
+ *****************************************************************************/
+
+void LacSymQat_LaSetDefaultFlags(icp_qat_fw_serv_specif_flags *laCmdFlags,
+ CpaCySymOp symOp);
+
+#endif /* LAC_SYM_QAT_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_cipher.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_cipher.h
new file mode 100644
index 000000000000..2360aa53633f
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_cipher.h
@@ -0,0 +1,291 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat_cipher.h
+ *
+ * @defgroup LacSymQat_Cipher Cipher QAT
+ *
+ * @ingroup LacSymQat
+ *
+ * external interfaces for populating QAT structures for cipher operations.
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+#ifndef LAC_SYM_QAT_CIPHER_H
+#define LAC_SYM_QAT_CIPHER_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa_cy_sym.h"
+#include "icp_qat_fw_la.h"
+#include "lac_session.h"
+#include "lac_sal_types_crypto.h"
+
+/*
+ **************************************************************************
+ * @ingroup LacSymQat_Cipher
+ *
+ * @description
+ * Defines for building the cipher request params cache
+ *
+ ************************************************************************** */
+
+#define LAC_SYM_QAT_CIPHER_NEXT_ID_BIT_OFFSET 24
+#define LAC_SYM_QAT_CIPHER_CURR_ID_BIT_OFFSET 16
+#define LAC_SYM_QAT_CIPHER_STATE_SIZE_BIT_OFFSET 8
+#define LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC 9
+#define LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC 2
+#define LAC_SYM_QAT_CIPHER_STATE_SIZE_SPC 48
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * Retrieve the cipher block size in bytes for a given algorithm
+ *
+ * @description
+ * This function returns a hard-coded block size for the specific cipher
+ * algorithm
+ *
+ * @param[in] cipherAlgorithm Cipher algorithm for the current session
+ *
+ * @retval The block size, in bytes, for the given cipher algorithm
+ *
+ *****************************************************************************/
+Cpa8U
+LacSymQat_CipherBlockSizeBytesGet(CpaCySymCipherAlgorithm cipherAlgorithm);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * Retrieve the cipher IV/state size in bytes for a given algorithm
+ *
+ * @description
+ * This function returns a hard-coded IV/state size for the specific cipher
+ * algorithm
+ *
+ * @param[in] cipherAlgorithm Cipher algorithm for the current session
+ *
+ * @retval The IV/state size, in bytes, for the given cipher algorithm
+ *
+ *****************************************************************************/
+Cpa32U LacSymQat_CipherIvSizeBytesGet(CpaCySymCipherAlgorithm cipherAlgorithm);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * Populate the cipher request params structure
+ *
+ * @description
+ * This function is passed a pointer to the 128B request block.
+ * (This memory must be allocated prior to calling this function). It
+ * populates:
+ * - the cipher fields of the req_params block in the request. No
+ * need to zero this first, all fields will be populated.
+ * - the corresponding CIPH_IV_FLD flag in the serv_specif_flags field
+ * of the common header.
+ * To do this it uses the parameters described below and the following
+ *fields from the request block which must be populated prior to calling this
+ *function:
+ * - cd_ctrl.cipher_state_sz
+ * - UPDATE_STATE flag in comn_hdr.serv_specif_flags
+ *
+ *
+ * @param[in] pReq Pointer to request block.
+ * *
+ * @param[in] cipherOffsetInBytes Offset to cipher data in user data buffer
+ *
+ * @param[in] cipherLenInBytes Length of cipher data in buffer
+ *
+ * @param[in] ivBufferPhysAddr Physical address of aligned IV/state
+ * buffer
+ * @param[in] pIvBufferVirt Virtual address of aligned IV/state
+ * buffer
+ * @retval void
+ *
+ *****************************************************************************/
+CpaStatus LacSymQat_CipherRequestParamsPopulate(icp_qat_fw_la_bulk_req_t *pReq,
+ Cpa32U cipherOffsetInBytes,
+ Cpa32U cipherLenInBytes,
+ Cpa64U ivBufferPhysAddr,
+ Cpa8U *pIvBufferVirt);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * Derive initial ARC4 cipher state from a base key
+ *
+ * @description
+ * An initial state for an ARC4 cipher session is derived from the base
+ * key provided by the user, using the ARC4 Key Scheduling Algorithm (KSA)
+ *
+ * @param[in] pKey The base key provided by the user
+ *
+ * @param[in] keyLenInBytes The length of the base key provided.
+ * The range of valid values is 1-256 bytes
+ *
+ * @param[out] pArc4CipherState The initial state is written to this buffer,
+ * including i and j values, and 6 bytes of padding
+ * so 264 bytes must be allocated for this buffer
+ * by the caller
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherArc4StateInit(const Cpa8U *pKey,
+ Cpa32U keyLenInBytes,
+ Cpa8U *pArc4CipherState);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_CipherXTSModeUpdateKeyLen
+ * Update the initial XTS key after the first partial has been received.
+ *
+ * @description
+ * For XTS mode using partial packets, after the first partial response
+ * has been received, the the key length needs to be halved for subsequent
+ * partials.
+ *
+ * @param[in] pSessionDesc The session descriptor.
+ *
+ * @param[in] newKeySizeInBytes The new key size..
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherXTSModeUpdateKeyLen(lac_session_desc_t *pSessionDesc,
+ Cpa32U newKeySizeInBytes);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * LacSymQat_CipherCtrlBlockInitialize()
+ *
+ * @description
+ * intialize the cipher control block with all zeros
+ *
+ * @param[in] pMsg Pointer to the common request message
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherCtrlBlockInitialize(icp_qat_fw_la_bulk_req_t *pMsg);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * LacSymQat_CipherCtrlBlockWrite()
+ *
+ * @description
+ * This function populates the cipher control block of the common request
+ * message
+ *
+ * @param[in] pMsg Pointer to the common request message
+ *
+ * @param[in] cipherAlgorithm Cipher Algorithm to be used
+ *
+ * @param[in] targetKeyLenInBytes cipher key length in bytes of selected
+ * algorithm
+ *
+ * @param[out] nextSlice SliceID for next control block
+ * entry. This value is known only by
+ * the calling component
+ *
+ * @param[out] cipherCfgOffsetInQuadWord Offset into the config table in QW
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherCtrlBlockWrite(icp_qat_la_bulk_req_ftr_t *pMsg,
+ Cpa32U cipherAlgorithm,
+ Cpa32U targetKeyLenInBytes,
+ icp_qat_fw_slice_t nextSlice,
+ Cpa8U cipherCfgOffsetInQuadWord);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * LacSymQat_CipherHwBlockPopulateCfgData()
+ *
+ * @description
+ * Populate the physical HW block with config data
+ *
+ * @param[in] pSession Pointer to the session data
+ *
+ * @param[in] pCipherHwBlock pointer to the hardware control block
+ * in the common message
+ *
+ * @param[in] pSizeInBytes
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherHwBlockPopulateCfgData(lac_session_desc_t *pSession,
+ const void *pCipherHwBlock,
+ Cpa32U *pSizeInBytes);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * LacSymQat_CipherGetCfgData()
+ *
+ * @description
+ * setup the config data for cipher
+ *
+ * @param[in] pSession Pointer to the session data
+ *
+ * @param[in] pAlgorithm *
+ * @param[in] pMode
+ * @param[in] pDir
+ * @param[in] pKey_convert
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherGetCfgData(lac_session_desc_t *pSession,
+ icp_qat_hw_cipher_algo_t *pAlgorithm,
+ icp_qat_hw_cipher_mode_t *pMode,
+ icp_qat_hw_cipher_dir_t *pDir,
+ icp_qat_hw_cipher_convert_t *pKey_convert);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQat_Cipher
+ * LacSymQat_CipherHwBlockPopulateKeySetup()
+ *
+ * @description
+ * populate the key setup data in the cipher hardware control block
+ * in the common request message
+ *
+ * param[in] pCipherSetupData Pointer to cipher setup data
+ *
+ * @param[in] targetKeyLenInBytes Target key length. If key length given
+ * in cipher setup data is less that this,
+ * the key will be "rounded up" to this
+ * target length by padding it with 0's.
+ * In normal no-padding case, the target
+ * key length MUST match the key length
+ * in the cipher setup data.
+ *
+ * @param[in] pCipherHwBlock Pointer to the cipher hardware block
+ *
+ * @param[out] pCipherHwBlockSizeBytes Size in bytes of cipher setup block
+ *
+ *
+ * @retval void
+ *
+ *****************************************************************************/
+void LacSymQat_CipherHwBlockPopulateKeySetup(
+ const CpaCySymCipherSetupData *pCipherSetupData,
+ Cpa32U targetKeyLenInBytes,
+ const void *pCipherHwBlock,
+ Cpa32U *pCipherHwBlockSizeBytes);
+
+#endif /* LAC_SYM_QAT_CIPHER_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash.h
new file mode 100644
index 000000000000..147e10f573f0
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash.h
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat_hash.h
+ *
+ * @defgroup LacSymQatHash Hash QAT
+ *
+ * @ingroup LacSymQat
+ *
+ * interfaces for populating qat structures for a hash operation
+ *
+ *****************************************************************************/
+
+/*****************************************************************************/
+
+#ifndef LAC_SYM_QAT_HASH_H
+#define LAC_SYM_QAT_HASH_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "icp_qat_fw_la.h"
+#include "icp_qat_hw.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "lac_common.h"
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * hash precomputes
+ *
+ * @description
+ * This structure contains infomation on the hash precomputes
+ *
+ *****************************************************************************/
+typedef struct lac_sym_qat_hash_precompute_info_s {
+ Cpa8U *pState1;
+ /**< state1 pointer */
+ Cpa32U state1Size;
+ /**< state1 size */
+ Cpa8U *pState2;
+ /**< state2 pointer */
+ Cpa32U state2Size;
+ /**< state2 size */
+} lac_sym_qat_hash_precompute_info_t;
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * hash state prefix buffer info
+ *
+ * @description
+ * This structure contains infomation on the hash state prefix aad buffer
+ *
+ *****************************************************************************/
+typedef struct lac_sym_qat_hash_state_buffer_info_s {
+ Cpa64U pDataPhys;
+ /**< Physical pointer to the hash state prefix buffer */
+ Cpa8U *pData;
+ /**< Virtual pointer to the hash state prefix buffer */
+ Cpa8U stateStorageSzQuadWords;
+ /**< hash state storage size in quad words */
+ Cpa8U prefixAadSzQuadWords;
+ /**< inner prefix/aad and outer prefix size in quad words */
+} lac_sym_qat_hash_state_buffer_info_t;
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * Init the hash specific part of the content descriptor.
+ *
+ * @description
+ * This function populates the hash specific fields of the control block
+ * and the hardware setup block for a digest session. This function sets
+ * the size param to hold the size of the hash setup block.
+ *
+ * In the case of hash only, the content descriptor will contain just a
+ * hash control block and hash setup block. In the case of chaining it
+ * will contain the hash control block and setup block along with the
+ * control block and setup blocks of additional services.
+ *
+ * Note: The memory for the content descriptor MUST be allocated prior to
+ * calling this function. The memory for the hash control block and hash
+ * setup block MUST be set to 0 prior to calling this function.
+ *
+ * @image html contentDescriptor.png "Content Descriptor"
+ *
+ * @param[in] pMsg Pointer to req Parameter Footer
+ *
+ * @param[in] pHashSetupData Pointer to the hash setup data as
+ * defined in the LAC API.
+ *
+ * @param[in] pHwBlockBase Pointer to the base of the hardware
+ * setup block
+ *
+ * @param[in] hashBlkOffsetInHwBlock Offset in quad-words from the base of
+ * the hardware setup block where the
+ * hash block will start. This offset
+ * is stored in the control block. It
+ * is used to figure out where to write
+ * that hash setup block.
+ *
+ * @param[in] nextSlice SliceID for next control block
+ * entry This value is known only by
+ * the calling component
+ *
+ * @param[in] qatHashMode QAT hash mode
+ *
+ * @param[in] useSymConstantsTable Indicate if Shared-SRAM constants table
+ * is used for this session. If TRUE, the
+ * h/w setup block is NOT populated
+ *
+ * @param[in] useOptimisedContentDesc Indicate if optimised content desc
+ * is used for this session.
+ *
+ * @param[in] pPrecompute For auth mode, this is the pointer
+ * to the precompute data. Otherwise this
+ * should be set to NULL
+ *
+ * @param[out] pHashBlkSizeInBytes size in bytes of hash setup block
+ *
+ * @return void
+ *
+ *****************************************************************************/
+void
+LacSymQat_HashContentDescInit(icp_qat_la_bulk_req_ftr_t *pMsg,
+ CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData,
+ void *pHwBlockBase,
+ Cpa32U hashBlkOffsetInHwBlock,
+ icp_qat_fw_slice_t nextSlice,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaBoolean useSymConstantsTable,
+ CpaBoolean useOptimisedContentDesc,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ Cpa32U *pHashBlkSizeInBytes);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * Calculate the size of the hash state prefix aad buffer
+ *
+ * @description
+ * This function inspects the hash control block and based on the values
+ * in the fields, it calculates the size of the hash state prefix aad
+ * buffer.
+ *
+ * A partial packet processing request is possible at any stage during a
+ * hash session. In this case, there will always be space for the hash
+ * state storage field of the hash state prefix buffer. When there is
+ * AAD data just the inner prefix AAD data field is used.
+ *
+ * @param[in] pMsg Pointer to the Request Message
+ *
+ * @param[out] pHashStateBuf Pointer to hash state prefix buffer info
+ * structure.
+ *
+ * @return None
+ *
+ *****************************************************************************/
+void LacSymQat_HashStatePrefixAadBufferSizeGet(
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * Populate the fields of the hash state prefix buffer
+ *
+ * @description
+ * This function populates the inner prefix/aad fields and/or the outer
+ * prefix field of the hash state prefix buffer.
+ *
+ * @param[in] pHashStateBuf Pointer to hash state prefix buffer info
+ * structure.
+ *
+ * @param[in] pMsg Pointer to the Request Message
+ *
+ * @param[in] pInnerPrefixAad Pointer to the Inner Prefix or Aad data
+ * This is NULL where if the data size is 0
+ *
+ * @param[in] innerPrefixSize Size of inner prefix/aad data in bytes
+ *
+ * @param[in] pOuterPrefix Pointer to the Outer Prefix data. This is
+ * NULL where the data size is 0.
+ *
+ * @param[in] outerPrefixSize Size of the outer prefix data in bytes
+ *
+ * @return void
+ *
+ *****************************************************************************/
+void LacSymQat_HashStatePrefixAadBufferPopulate(
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf,
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ Cpa8U *pInnerPrefixAad,
+ Cpa8U innerPrefixSize,
+ Cpa8U *pOuterPrefix,
+ Cpa8U outerPrefixSize);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ * Populate the hash request params structure
+ *
+ * @description
+ * This function is passed a pointer to the 128B Request block.
+ * (This memory must be allocated prior to calling this function). It
+ * populates the fields of this block using the parameters as described
+ * below. It is also expected that this structure has been set to 0
+ * prior to calling this function.
+ *
+ *
+ * @param[in] pReq Pointer to 128B request block.
+ *
+ * @param[in] authOffsetInBytes start offset of data that the digest is to
+ * be computed on.
+ *
+ * @param[in] authLenInBytes Length of data digest calculated on
+ *
+ * @param[in] pService Pointer to service data
+ *
+ * @param[in] pHashStateBuf Pointer to hash state buffer info. This
+ * structure contains the pointers and sizes.
+ * If there is no hash state prefix buffer
+ * required, this parameter can be set to NULL
+ *
+ * @param[in] qatPacketType Packet type using QAT macros. The hash
+ * state buffer pointer and state size will be
+ * different depending on the packet type
+ *
+ * @param[in] hashResultSize Size of the final hash result in bytes.
+ *
+ * @param[in] digestVerify Indicates if verify is enabled or not
+ *
+ * @param[in] pAuthResult Virtual pointer to digest
+ *
+ * @return CPA_STATUS_SUCCESS or CPA_STATUS_FAIL
+ *
+ *****************************************************************************/
+CpaStatus LacSymQat_HashRequestParamsPopulate(
+ icp_qat_fw_la_bulk_req_t *pReq,
+ Cpa32U authOffsetInBytes,
+ Cpa32U authLenInBytes,
+ sal_service_t *pService,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf,
+ Cpa32U qatPacketType,
+ Cpa32U hashResultSize,
+ CpaBoolean digestVerify,
+ Cpa8U *pAuthResult,
+ CpaCySymHashAlgorithm alg,
+ void *data);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymQatHash
+ *
+ *
+ * @description
+ * This fn returns the QAT values for hash algorithm and nested fields
+ *
+ *
+ * @param[in] pInstance Pointer to service instance.
+ *
+ * @param[in] qatHashMode value for hash mode on the fw qat
+ *interface.
+ *
+ * @param[in] apiHashMode value for hash mode on the QA API.
+ *
+ * @param[in] apiHashAlgorithm value for hash algorithm on the QA API.
+ *
+ * @param[out] pQatAlgorithm Pointer to return fw qat value for
+ *algorithm.
+ *
+ * @param[out] pQatNested Pointer to return fw qat value for nested.
+ *
+ *
+ * @return
+ * none
+ *
+ *****************************************************************************/
+void LacSymQat_HashGetCfgData(CpaInstanceHandle pInstance,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaCySymHashMode apiHashMode,
+ CpaCySymHashAlgorithm apiHashAlgorithm,
+ icp_qat_hw_auth_algo_t *pQatAlgorithm,
+ CpaBoolean *pQatNested);
+
+void LacSymQat_HashSetupReqParamsMetaData(
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData,
+ CpaBoolean hashStateBuffer,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaBoolean digestVerify);
+
+#endif /* LAC_SYM_QAT_HASH_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash_defs_lookup.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash_defs_lookup.h
new file mode 100644
index 000000000000..23db82a3b180
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_hash_defs_lookup.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat_hash_defs_lookup.h
+ *
+ * @defgroup LacSymQatHashDefsLookup Hash Defs Lookup
+ *
+ * @ingroup LacSymQatHash
+ *
+ * API to be used for the hash defs lookup table.
+ *
+ *****************************************************************************/
+
+#ifndef LAC_SYM_QAT_HASH_DEFS_LOOKUP_P_H
+#define LAC_SYM_QAT_HASH_DEFS_LOOKUP_P_H
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/**
+******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* Finishing Hash algorithm
+* @description
+* This define points to the last available hash algorithm
+* @NOTE: If a new algorithm is added to the api, this #define
+* MUST be updated to being the last hash algorithm in the struct
+* CpaCySymHashAlgorithm in the file cpa_cy_sym.h
+*****************************************************************************/
+#define CPA_CY_HASH_ALG_END CPA_CY_SYM_HASH_SM3
+
+/***************************************************************************/
+
+/**
+******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* hash algorithm specific structure
+* @description
+* This structure contain constants specific to an algorithm.
+*****************************************************************************/
+typedef struct lac_sym_qat_hash_alg_info_s {
+ Cpa32U digestLength; /**< Digest length in bytes */
+ Cpa32U blockLength; /**< Block length in bytes */
+ Cpa8U *initState; /**< Initialiser state for hash algorithm */
+ Cpa32U stateSize; /**< size of above state in bytes */
+} lac_sym_qat_hash_alg_info_t;
+
+/**
+******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* hash qat specific structure
+* @description
+* This structure contain constants as defined by the QAT for an
+* algorithm.
+*****************************************************************************/
+typedef struct lac_sym_qat_hash_qat_info_s {
+ Cpa32U algoEnc; /**< QAT Algorithm encoding */
+ Cpa32U authCounter; /**< Counter value for Auth */
+ Cpa32U state1Length; /**< QAT state1 length in bytes */
+ Cpa32U state2Length; /**< QAT state2 length in bytes */
+} lac_sym_qat_hash_qat_info_t;
+
+/**
+******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* hash defs structure
+* @description
+* This type contains pointers to the hash algorithm structure and
+* to the hash qat specific structure
+*****************************************************************************/
+typedef struct lac_sym_qat_hash_defs_s {
+ lac_sym_qat_hash_alg_info_t *algInfo;
+ /**< pointer to hash info structure */
+ lac_sym_qat_hash_qat_info_t *qatInfo;
+ /**< pointer to hash QAT info structure */
+} lac_sym_qat_hash_defs_t;
+
+/**
+*******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* initialise the hash lookup table
+*
+* @description
+* This function initialises the digest lookup table.
+*
+* @note
+* This function does not have a corresponding shutdown function.
+*
+* @return CPA_STATUS_SUCCESS Operation successful
+* @return CPA_STATUS_RESOURCE Allocating of hash lookup table failed
+*
+*****************************************************************************/
+CpaStatus LacSymQat_HashLookupInit(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* get hash algorithm specific structure from lookup table
+*
+* @description
+* This function looks up the hash lookup array for a structure
+* containing data specific to a hash algorithm. The hashAlgorithm enum
+* value MUST be in the correct range prior to calling this function.
+*
+* @param[in] hashAlgorithm Hash Algorithm
+* @param[out] ppHashAlgInfo Hash Alg Info structure
+*
+* @return None
+*
+*****************************************************************************/
+void LacSymQat_HashAlgLookupGet(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ lac_sym_qat_hash_alg_info_t **ppHashAlgInfo);
+
+/**
+*******************************************************************************
+* @ingroup LacSymQatHashDefsLookup
+* get hash defintions from lookup table.
+*
+* @description
+* This function looks up the hash lookup array for a structure
+* containing data specific to a hash algorithm. This includes both
+* algorithm specific info and qat specific infro. The hashAlgorithm enum
+* value MUST be in the correct range prior to calling this function.
+*
+* @param[in] hashAlgorithm Hash Algorithm
+* @param[out] ppHashDefsInfo Hash Defs structure
+*
+* @return void
+*
+*****************************************************************************/
+void LacSymQat_HashDefsLookupGet(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ lac_sym_qat_hash_defs_t **ppHashDefsInfo);
+
+#endif /* LAC_SYM_QAT_HASH_DEFS_LOOKUP_P_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_key.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_key.h
new file mode 100644
index 000000000000..a6a5d5169e11
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_qat_key.h
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat_key.h
+ *
+ * @defgroup LacSymQatKey Key QAT
+ *
+ * @ingroup LacSymQat
+ *
+ * interfaces for populating qat structures for a key operation
+ *
+ *****************************************************************************/
+
+#ifndef LAC_SYM_QAT_KEY_H
+#define LAC_SYM_QAT_KEY_H
+
+#include "cpa.h"
+#include "lac_sym.h"
+#include "icp_qat_fw_la.h"
+
+/**
+******************************************************************************
+* @ingroup LacSymQatKey
+* Number of bytes generated per iteration
+* @description
+* This define is the number of bytes generated per iteration
+*****************************************************************************/
+#define LAC_SYM_QAT_KEY_SSL_BYTES_PER_ITERATION (16)
+
+/**
+******************************************************************************
+* @ingroup LacSymQatKey
+* Shift to calculate the number of iterations
+* @description
+* This define is the shift to calculate the number of iterations
+*****************************************************************************/
+#define LAC_SYM_QAT_KEY_SSL_ITERATIONS_SHIFT LAC_16BYTE_ALIGNMENT_SHIFT
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate the SSL request
+*
+* @description
+* Populate the SSL request
+*
+* @param[out] pKeyGenReqHdr Pointer to Key Generation request Header
+* @param[out] pKeyGenReqMid Pointer to LW's 14/15 of Key Gen request
+* @param[in] generatedKeyLenInBytes Length of Key generated
+* @param[in] labelLenInBytes Length of Label
+* @param[in] secretLenInBytes Length of Secret
+* @param[in] iterations Number of iterations. This is related
+* to the label length.
+*
+* @return None
+*
+*****************************************************************************/
+void
+LacSymQat_KeySslRequestPopulate(icp_qat_la_bulk_req_hdr_t *pKeyGenReqHdr,
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqMid,
+ Cpa32U generatedKeyLenInBytes,
+ Cpa32U labelLenInBytes,
+ Cpa32U secretLenInBytes,
+ Cpa32U iterations);
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate the TLS request
+*
+* @description
+* Populate the TLS request
+*
+* @param[out] pKeyGenReq Pointer to Key Generation request
+* @param[in] generatedKeyLenInBytes Length of Key generated
+* @param[in] labelLenInBytes Length of Label
+* @param[in] secretLenInBytes Length of Secret
+* @param[in] seedLenInBytes Length of Seed
+* @param[in] cmdId Command Id to differentiate TLS versions
+*
+* @return None
+*
+*****************************************************************************/
+void LacSymQat_KeyTlsRequestPopulate(
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqParams,
+ Cpa32U generatedKeyLenInBytes,
+ Cpa32U labelLenInBytes,
+ Cpa32U secretLenInBytes,
+ Cpa8U seedLenInBytes,
+ icp_qat_fw_la_cmd_id_t cmdId);
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate MGF request
+*
+* @description
+* Populate MGF request
+*
+* @param[out] pKeyGenReqHdr Pointer to Key Generation request Header
+* @param[out] pKeyGenReqMid Pointer to LW's 14/15 of Key Gen request
+* @param[in] seedLenInBytes Length of Seed
+* @param[in] maskLenInBytes Length of Mask
+* @param[in] hashLenInBytes Length of hash
+*
+* @return None
+*
+*****************************************************************************/
+void
+LacSymQat_KeyMgfRequestPopulate(icp_qat_la_bulk_req_hdr_t *pKeyGenReqHdr,
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqMid,
+ Cpa8U seedLenInBytes,
+ Cpa16U maskLenInBytes,
+ Cpa8U hashLenInBytes);
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate the SSL key material input
+*
+* @description
+* Populate the SSL key material input
+*
+* @param[in] pService Pointer to service
+* @param[out] pSslKeyMaterialInput Pointer to SSL key material input
+* @param[in] pSeed Pointer to Seed
+* @param[in] labelPhysAddr Physical address of the label
+* @param[in] pSecret Pointer to Secret
+*
+* @return None
+*
+*****************************************************************************/
+void LacSymQat_KeySslKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_ssl_key_material_input_t *pSslKeyMaterialInput,
+ void *pSeed,
+ Cpa64U labelPhysAddr,
+ void *pSecret);
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate the TLS key material input
+*
+* @description
+* Populate the TLS key material input
+*
+* @param[in] pService Pointer to service
+* @param[out] pTlsKeyMaterialInput Pointer to TLS key material input
+* @param[in] pSeed Pointer to Seed
+* @param[in] labelPhysAddr Physical address of the label
+*
+* @return None
+*
+*****************************************************************************/
+void LacSymQat_KeyTlsKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_tls_key_material_input_t *pTlsKeyMaterialInput,
+ void *pSeed,
+ Cpa64U labelPhysAddr);
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Populate the TLS HKDF key material input
+*
+* @description
+* Populate the TLS HKDF key material input
+*
+* @param[in] pService Pointer to service
+* @param[out] pTlsKeyMaterialInput Pointer to TLS key material input
+* @param[in] pSeed Pointer to Seed
+* @param[in] labelPhysAddr Physical address of the label
+* @param[in] cmdId Command ID
+*
+* @return None
+*
+*****************************************************************************/
+void LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_hkdf_key_material_input_t *pTlsKeyMaterialInput,
+ CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData,
+ Cpa64U subLabelsPhysAddr,
+ icp_qat_fw_la_cmd_id_t cmdId);
+
+#endif /* LAC_SYM_QAT_KEY_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_queue.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_queue.h
new file mode 100644
index 000000000000..d7a5cd3c9e92
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_queue.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ******************************************************************************
+ * @file lac_sym_queue.h
+ *
+ * @defgroup LacSymQueue Symmetric request queueing functions
+ *
+ * @ingroup LacSym
+ *
+ * Function prototypes for sending/queuing symmetric requests
+ *****************************************************************************/
+
+#ifndef LAC_SYM_QUEUE_H
+#define LAC_SYM_QUEUE_H
+
+#include "cpa.h"
+#include "lac_session.h"
+#include "lac_sym.h"
+
+/**
+*******************************************************************************
+* @ingroup LacSymQueue
+* Send a request message to the QAT, or queue it if necessary
+*
+* @description
+* This function will send a request message to the QAT. However, if a
+* blocking condition exists on the session (e.g. partial packet in flight,
+* precompute in progress), then the message will instead be pushed on to
+* the request queue for the session and will be sent later to the QAT
+* once the blocking condition is cleared.
+*
+* @param[in] instanceHandle Handle for instance of QAT
+* @param[in] pRequest Pointer to request cookie
+* @param[out] pSessionDesc Pointer to session descriptor
+*
+*
+* @retval CPA_STATUS_SUCCESS Success
+* @retval CPA_STATUS_FAIL Function failed.
+* @retval CPA_STATUS_RESOURCE Problem Acquiring system resource
+* @retval CPA_STATUS_RETRY Failed to send message to QAT due to queue
+* full condition
+*
+*****************************************************************************/
+CpaStatus LacSymQueue_RequestSend(const CpaInstanceHandle instanceHandle,
+ lac_sym_bulk_cookie_t *pRequest,
+ lac_session_desc_t *pSessionDesc);
+
+#endif /* LAC_SYM_QUEUE_H */
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_stats.h b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_stats.h
new file mode 100644
index 000000000000..b5d823420163
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/include/lac_sym_stats.h
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_stats.h
+ *
+ * @defgroup LacSymCommon Symmetric Common
+ *
+ * @ingroup LacSym
+ *
+ * Symetric Common consists of common statistics, buffer and partial packet
+ * functionality.
+ *
+ ***************************************************************************/
+
+/**
+ ***************************************************************************
+ * @defgroup LacSymStats Statistics
+ *
+ * @ingroup LacSymCommon
+ *
+ * definitions and prototypes for LAC symmetric statistics.
+ *
+ * @lld_start
+ * In the LAC API the stats fields are defined as Cpa32U but
+ * QatUtilsAtomic is the type that the atomic API supports. Therefore we
+ * need to define a structure internally with the same fields as the API
+ * stats structure, but each field must be of type QatUtilsAtomic.
+ *
+ * - <b>Incrementing Statistics:</b>\n
+ * Atomically increment the statistic on the internal stats structure.
+ *
+ * - <b>Providing a copy of the stats back to the user:</b>\n
+ * Use atomicGet to read the atomic variable for each stat field in the
+ * local internal stat structure. These values are saved in structure
+ * (as defined by the LAC API) that the client will provide a pointer
+ * to as a parameter.
+ *
+ * - <b>Stats Show:</b>\n
+ * Use atomicGet to read the atomic variables for each field in the local
+ * internal stat structure and print to the screen
+ *
+ * - <b>Stats Array:</b>\n
+ * A macro is used to get the offset off the stat in the structure. This
+ * offset is passed to a function which uses it to increment the stat
+ * at that offset.
+ *
+ * @lld_end
+ *
+ ***************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_SYM_STATS_H
+#define LAC_SYM_STATS_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "cpa_cy_common.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* increment a symmetric statistic
+*
+* @description
+* Increment the statistics
+*
+* @param statistic IN The field in the symmetric statistics structure to be
+* incremented
+* @param instanceHandle IN engine Id Number
+*
+* @retval None
+*
+*****************************************************************************/
+#define LAC_SYM_STAT_INC(statistic, instanceHandle) \
+ LacSym_StatsInc(offsetof(CpaCySymStats64, statistic), instanceHandle)
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* initialises the symmetric stats
+*
+* @description
+* This function allocates and initialises the stats array to 0
+*
+* @param instanceHandle Instance Handle
+*
+* @retval CPA_STATUS_SUCCESS initialisation successful
+* @retval CPA_STATUS_RESOURCE array allocation failed
+*
+*****************************************************************************/
+CpaStatus LacSym_StatsInit(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* Frees the symmetric stats
+*
+* @description
+* This function frees the stats array
+*
+* @param instanceHandle Instance Handle
+*
+* @retval None
+*
+*****************************************************************************/
+void LacSym_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* Inrement a stat
+*
+* @description
+* This function incrementes a stat for a specific engine.
+*
+* @param offset IN offset of stat field in structure
+* @param instanceHandle IN qat Handle
+*
+* @retval None
+*
+*****************************************************************************/
+void LacSym_StatsInc(Cpa32U offset, CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* Copy the contents of the statistics structure for an engine
+*
+* @description
+* This function copies the 32bit symmetric statistics structure for
+* a specific engine into an address supplied as a parameter.
+*
+* @param instanceHandle IN engine Id Number
+* @param pSymStats OUT stats structure to copy the stats for the into
+*
+* @retval None
+*
+*****************************************************************************/
+void LacSym_Stats32CopyGet(CpaInstanceHandle instanceHandle,
+ struct _CpaCySymStats *const pSymStats);
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* Copy the contents of the statistics structure for an engine
+*
+* @description
+* This function copies the 64bit symmetric statistics structure for
+* a specific engine into an address supplied as a parameter.
+*
+* @param instanceHandle IN engine Id Number
+* @param pSymStats OUT stats structure to copy the stats for the into
+*
+* @retval None
+*
+*****************************************************************************/
+void LacSym_Stats64CopyGet(CpaInstanceHandle instanceHandle,
+ CpaCySymStats64 *const pSymStats);
+
+/**
+*******************************************************************************
+* @ingroup LacSymStats
+* print the symmetric stats to standard output
+*
+* @description
+* The statistics for symmetric are printed to standard output.
+*
+* @retval None
+*
+* @see LacSym_StatsCopyGet()
+*
+*****************************************************************************/
+void LacSym_StatsShow(CpaInstanceHandle instanceHandle);
+
+#endif /*LAC_SYM_STATS_H_*/
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
new file mode 100644
index 000000000000..2f27a1781876
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/key/lac_sym_key.c
@@ -0,0 +1,3021 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ *****************************************************************************
+ * @file lac_sym_key.c
+ *
+ * @ingroup LacSymKey
+ *
+ * This file contains the implementation of all keygen functionality
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_cy_key.h"
+#include "cpa_cy_im.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+
+#include "qat_utils.h"
+
+#include "lac_log.h"
+#include "lac_hooks.h"
+#include "lac_sym.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym_qat.h"
+#include "lac_sal.h"
+#include "lac_sym_key.h"
+#include "lac_sal_types_crypto.h"
+#include "sal_service_state.h"
+#include "lac_sym_qat_key.h"
+#include "lac_sym_hash_defs.h"
+#include "sal_statistics.h"
+
+/* Number of statistics */
+#define LAC_KEY_NUM_STATS (sizeof(CpaCyKeyGenStats64) / sizeof(Cpa64U))
+
+#define LAC_KEY_STAT_INC(statistic, instanceHandle) \
+ do { \
+ sal_crypto_service_t *pService = NULL; \
+ pService = (sal_crypto_service_t *)instanceHandle; \
+ if (CPA_TRUE == \
+ pService->generic_service_info.stats \
+ ->bKeyGenStatsEnabled) { \
+ qatUtilsAtomicInc( \
+ &pService \
+ ->pLacKeyStats[offsetof(CpaCyKeyGenStats64, \
+ statistic) / \
+ sizeof(Cpa64U)]); \
+ } \
+ } while (0)
+/**< Macro to increment a Key stat (derives offset into array of atomics) */
+
+#define LAC_KEY_STATS32_GET(keyStats, instanceHandle) \
+ do { \
+ int i; \
+ sal_crypto_service_t *pService = \
+ (sal_crypto_service_t *)instanceHandle; \
+ for (i = 0; i < LAC_KEY_NUM_STATS; i++) { \
+ ((Cpa32U *)&(keyStats))[i] = \
+ (Cpa32U)qatUtilsAtomicGet( \
+ &pService->pLacKeyStats[i]); \
+ } \
+ } while (0)
+/**< Macro to get all 32bit Key stats (from internal array of atomics) */
+
+#define LAC_KEY_STATS64_GET(keyStats, instanceHandle) \
+ do { \
+ int i; \
+ sal_crypto_service_t *pService = \
+ (sal_crypto_service_t *)instanceHandle; \
+ for (i = 0; i < LAC_KEY_NUM_STATS; i++) { \
+ ((Cpa64U *)&(keyStats))[i] = \
+ qatUtilsAtomicGet(&pService->pLacKeyStats[i]); \
+ } \
+ } while (0)
+/**< Macro to get all 64bit Key stats (from internal array of atomics) */
+
+#define IS_HKDF_UNSUPPORTED(cmdId, hkdfSupported) \
+ ((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= cmdId && \
+ ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >= cmdId) && \
+ !hkdfSupported) /**< macro to check whether the HKDF algorithm can be \
+ supported on the device */
+
+/* Sublabel for HKDF TLS Key Generation, as defined in RFC8446. */
+const static Cpa8U key256[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 16, 9, 't',
+ 'l', 's', '1', '3',
+ ' ', 'k', 'e', 'y',
+ 0 };
+const static Cpa8U key384[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 32, 9, 't',
+ 'l', 's', '1', '3',
+ ' ', 'k', 'e', 'y',
+ 0 };
+const static Cpa8U keyChaChaPoly[HKDF_SUB_LABEL_KEY_LENGTH] = { 0, 32, 9,
+ 't', 'l', 's',
+ '1', '3', ' ',
+ 'k', 'e', 'y',
+ 0 };
+/* Sublabel for HKDF TLS IV key Generation, as defined in RFC8446. */
+const static Cpa8U iv256[HKDF_SUB_LABEL_IV_LENGTH] = { 0, 12, 8, 't',
+ 'l', 's', '1', '3',
+ ' ', 'i', 'v', 0 };
+const static Cpa8U iv384[HKDF_SUB_LABEL_IV_LENGTH] = { 0, 12, 8, 't',
+ 'l', 's', '1', '3',
+ ' ', 'i', 'v', 0 };
+/* Sublabel for HKDF TLS RESUMPTION key Generation, as defined in RFC8446. */
+const static Cpa8U resumption256[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
+ { 0, 32, 16, 't', 'l', 's', '1', '3', ' ', 'r',
+ 'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
+const static Cpa8U resumption384[HKDF_SUB_LABEL_RESUMPTION_LENGTH] =
+ { 0, 48, 16, 't', 'l', 's', '1', '3', ' ', 'r',
+ 'e', 's', 'u', 'm', 'p', 't', 'i', 'o', 'n', 0 };
+/* Sublabel for HKDF TLS FINISHED key Generation, as defined in RFC8446. */
+const static Cpa8U finished256[HKDF_SUB_LABEL_FINISHED_LENGTH] =
+ { 0, 32, 14, 't', 'l', 's', '1', '3', ' ',
+ 'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
+const static Cpa8U finished384[HKDF_SUB_LABEL_FINISHED_LENGTH] =
+ { 0, 48, 14, 't', 'l', 's', '1', '3', ' ',
+ 'f', 'i', 'n', 'i', 's', 'h', 'e', 'd', 0 };
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * SSL/TLS stat type
+ *
+ * @description
+ * This enum determines which stat should be incremented
+ *****************************************************************************/
+typedef enum {
+ LAC_KEY_REQUESTS = 0,
+ /**< Key requests sent */
+ LAC_KEY_REQUEST_ERRORS,
+ /**< Key requests errors */
+ LAC_KEY_COMPLETED,
+ /**< Key requests which received responses */
+ LAC_KEY_COMPLETED_ERRORS
+ /**< Key requests which received responses with errors */
+} lac_key_stat_type_t;
+
+/*** Local functions prototypes ***/
+static void
+LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags);
+
+static CpaStatus
+LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const void *pKeyGenMgfOpData,
+ CpaFlatBuffer *pGeneratedMaskBuffer,
+ CpaBoolean bIsExtRequest);
+
+static void
+LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags);
+
+static CpaStatus
+LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pKeyGenSslTlsOpData,
+ Cpa8U hashAlgorithm,
+ CpaFlatBuffer *pKeyGenOutpuData);
+
+/*** Implementation ***/
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Get the instance handle. Support single handle.
+ * @param[in] instanceHandle_in user supplied handle.
+ * @retval CpaInstanceHandle the instance handle
+ */
+static CpaInstanceHandle
+LacKey_GetHandle(CpaInstanceHandle instanceHandle_in)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+ return instanceHandle;
+}
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Perform SSL/TLS key gen operation
+*
+* @description
+* Perform SSL/TLS key gen operation
+*
+* @param[in] instanceHandle QAT device handle.
+* @param[in] pKeyGenCb Pointer to callback function to be invoked
+* when the operation is complete.
+* @param[in] pCallbackTag Opaque User Data for this specific call.
+* @param[in] lacCmdId Lac command ID (identify SSL & TLS ops)
+* @param[in] pKeyGenSslTlsOpData Structure containing all the data needed to
+* perform the SSL/TLS key generation
+* operation.
+* @param[in] hashAlgorithm Specifies the hash algorithm to use.
+* According to RFC5246, this should be
+* "SHA-256 or a stronger standard hash
+* function."
+* @param[out] pKeyGenOutputData pointer to where output result should be
+* written
+*
+* @retval CPA_STATUS_SUCCESS Function executed successfully.
+* @retval CPA_STATUS_FAIL Function failed.
+* @retval CPA_STATUS_RETRY Function should be retried.
+* @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in.
+* @retval CPA_STATUS_RESOURCE Error related to system resources.
+*
+*****************************************************************************/
+static CpaStatus
+LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pKeyGenSslTlsOpData,
+ Cpa8U hashAlgorithm,
+ CpaFlatBuffer *pKeyGenOutputData);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Increment stat for TLS or SSL operation
+ *
+ * @description
+ * This is a generic function to update the stats for either a TLS or SSL
+ * operation.
+ *
+ * @param[in] lacCmdId Indicate SSL or TLS operations
+ * @param[in] statType Statistics Type
+ * @param[in] instanceHandle Instance Handle
+ *
+ * @return None
+ *
+ *****************************************************************************/
+static void
+LacKey_StatsInc(icp_qat_fw_la_cmd_id_t lacCmdId,
+ lac_key_stat_type_t statType,
+ CpaInstanceHandle instanceHandle)
+{
+ if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
+ switch (statType) {
+ case LAC_KEY_REQUESTS:
+ LAC_KEY_STAT_INC(numSslKeyGenRequests, instanceHandle);
+ break;
+ case LAC_KEY_REQUEST_ERRORS:
+ LAC_KEY_STAT_INC(numSslKeyGenRequestErrors,
+ instanceHandle);
+ break;
+ case LAC_KEY_COMPLETED:
+ LAC_KEY_STAT_INC(numSslKeyGenCompleted, instanceHandle);
+ break;
+ case LAC_KEY_COMPLETED_ERRORS:
+ LAC_KEY_STAT_INC(numSslKeyGenCompletedErrors,
+ instanceHandle);
+ break;
+ default:
+ QAT_UTILS_LOG("Invalid statistics type\n");
+ break;
+ }
+ } else /* TLS v1.0/1.1 and 1.2 */
+ {
+ switch (statType) {
+ case LAC_KEY_REQUESTS:
+ LAC_KEY_STAT_INC(numTlsKeyGenRequests, instanceHandle);
+ break;
+ case LAC_KEY_REQUEST_ERRORS:
+ LAC_KEY_STAT_INC(numTlsKeyGenRequestErrors,
+ instanceHandle);
+ break;
+ case LAC_KEY_COMPLETED:
+ LAC_KEY_STAT_INC(numTlsKeyGenCompleted, instanceHandle);
+ break;
+ case LAC_KEY_COMPLETED_ERRORS:
+ LAC_KEY_STAT_INC(numTlsKeyGenCompletedErrors,
+ instanceHandle);
+ break;
+ default:
+ QAT_UTILS_LOG("Invalid statistics type\n");
+ break;
+ }
+ }
+}
+
+void
+LacKeygen_StatsShow(CpaInstanceHandle instanceHandle)
+{
+ CpaCyKeyGenStats64 keyStats = { 0 };
+
+ LAC_KEY_STATS64_GET(keyStats, instanceHandle);
+
+ QAT_UTILS_LOG(SEPARATOR BORDER
+ " Key Stats: " BORDER
+ "\n" SEPARATOR);
+
+ QAT_UTILS_LOG(BORDER " SSL Key Requests: %16llu " BORDER
+ "\n" BORDER
+ " SSL Key Request Errors: %16llu " BORDER
+ "\n" BORDER
+ " SSL Key Completed %16llu " BORDER
+ "\n" BORDER
+ " SSL Key Complete Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (unsigned long long)keyStats.numSslKeyGenRequests,
+ (unsigned long long)keyStats.numSslKeyGenRequestErrors,
+ (unsigned long long)keyStats.numSslKeyGenCompleted,
+ (unsigned long long)keyStats.numSslKeyGenCompletedErrors);
+
+ QAT_UTILS_LOG(BORDER " TLS Key Requests: %16llu " BORDER
+ "\n" BORDER
+ " TLS Key Request Errors: %16llu " BORDER
+ "\n" BORDER
+ " TLS Key Completed %16llu " BORDER
+ "\n" BORDER
+ " TLS Key Complete Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (unsigned long long)keyStats.numTlsKeyGenRequests,
+ (unsigned long long)keyStats.numTlsKeyGenRequestErrors,
+ (unsigned long long)keyStats.numTlsKeyGenCompleted,
+ (unsigned long long)keyStats.numTlsKeyGenCompletedErrors);
+
+ QAT_UTILS_LOG(BORDER " MGF Key Requests: %16llu " BORDER
+ "\n" BORDER
+ " MGF Key Request Errors: %16llu " BORDER
+ "\n" BORDER
+ " MGF Key Completed %16llu " BORDER
+ "\n" BORDER
+ " MGF Key Complete Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (unsigned long long)keyStats.numMgfKeyGenRequests,
+ (unsigned long long)keyStats.numMgfKeyGenRequestErrors,
+ (unsigned long long)keyStats.numMgfKeyGenCompleted,
+ (unsigned long long)keyStats.numMgfKeyGenCompletedErrors);
+}
+
+/** @ingroup LacSymKey */
+CpaStatus
+cpaCyKeyGenQueryStats(CpaInstanceHandle instanceHandle_in,
+ struct _CpaCyKeyGenStats *pSymKeyStats)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSymKeyStats);
+
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ LAC_KEY_STATS32_GET(*pSymKeyStats, instanceHandle);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacSymKey */
+CpaStatus
+cpaCyKeyGenQueryStats64(CpaInstanceHandle instanceHandle_in,
+ CpaCyKeyGenStats64 *pSymKeyStats)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSymKeyStats);
+
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ LAC_KEY_STATS64_GET(*pSymKeyStats, instanceHandle);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Return the size of the digest for a specific hash algorithm.
+ * @description
+ * Return the expected digest size based on the sha algorithm submitted.
+ * The only supported value are sha256, sha384 and sha512.
+ *
+ * @param[in] hashAlgorithm either sha256, sha384 or sha512.
+ * @return the expected size or 0 for an invalid hash.
+ *
+ *****************************************************************************/
+static Cpa32U
+getDigestSizeFromHashAlgo(CpaCySymHashAlgorithm hashAlgorithm)
+{
+ switch (hashAlgorithm) {
+ case CPA_CY_SYM_HASH_SHA256:
+ return LAC_HASH_SHA256_DIGEST_SIZE;
+ case CPA_CY_SYM_HASH_SHA384:
+ return LAC_HASH_SHA384_DIGEST_SIZE;
+ case CPA_CY_SYM_HASH_SHA512:
+ return LAC_HASH_SHA512_DIGEST_SIZE;
+ case CPA_CY_SYM_HASH_SM3:
+ return LAC_HASH_SM3_DIGEST_SIZE;
+ default:
+ return 0;
+ }
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Return the hash algorithm for a specific cipher.
+ * @description
+ * Return the hash algorithm related to the cipher suite.
+ * Supported hash's are SHA256, and SHA384.
+ *
+ * @param[in] cipherSuite AES_128_GCM, AES_256_GCM, AES_128_CCM,
+ * and CHACHA20_POLY1305.
+ * @return the expected hash algorithm or 0 for an invalid cipher.
+ *
+ *****************************************************************************/
+static CpaCySymHashAlgorithm
+getHashAlgorithmFromCipherSuiteHKDF(CpaCyKeyHKDFCipherSuite cipherSuite)
+{
+ switch (cipherSuite) {
+ case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256: /* Fall through */
+ case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
+ case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
+ case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
+ return CPA_CY_SYM_HASH_SHA256;
+ case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
+ return CPA_CY_SYM_HASH_SHA384;
+ default:
+ return 0;
+ }
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Return the digest size of cipher.
+ * @description
+ * Return the output key size of specific cipher, for specified sub label
+ *
+ * @param[in] cipherSuite = AES_128_GCM, AES_256_GCM, AES_128_CCM,
+ * and CHACHA20_POLY1305.
+ * subLabels = KEY, IV, RESUMPTION, and FINISHED.
+ * @return the expected digest size of the cipher.
+ *
+ *****************************************************************************/
+static const Cpa32U cipherSuiteHKDFHashSizes
+ [LAC_KEY_HKDF_CIPHERS_MAX][LAC_KEY_HKDF_SUBLABELS_MAX] = {
+ {}, /* Not used */
+ { 32, 16, 12, 32, 32 }, /* AES_128_GCM_SHA256 */
+ { 48, 32, 12, 48, 48 }, /* AES_256_GCM_SHA384 */
+ { 32, 32, 12, 32, 32 }, /* CHACHA20_POLY1305_SHA256 */
+ { 32, 16, 12, 32, 32 }, /* AES_128_CCM_SHA256 */
+ { 32, 16, 12, 32, 32 } /* AES_128_CCM_8_SHA256 */
+ };
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Key Generation MGF response handler
+ *
+ * @description
+ * Handles Key Generation MGF response messages from the QAT.
+ *
+ * @param[in] lacCmdId Command id of the original request
+ * @param[in] pOpaqueData Pointer to opaque data that was in request
+ * @param[in] cmnRespFlags Indicates whether request succeeded
+ *
+ * @return void
+ *
+ *****************************************************************************/
+static void
+LacSymKey_MgfHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags)
+{
+ CpaCyKeyGenMgfOpData *pMgfOpData = NULL;
+ lac_sym_key_cookie_t *pCookie = NULL;
+ CpaCyGenFlatBufCbFunc pKeyGenMgfCb = NULL;
+ void *pCallbackTag = NULL;
+ CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaBoolean respStatusOk =
+ (ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
+ ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
+ CPA_TRUE :
+ CPA_FALSE;
+
+ pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
+
+ if (CPA_TRUE == respStatusOk) {
+ status = CPA_STATUS_SUCCESS;
+ LAC_KEY_STAT_INC(numMgfKeyGenCompleted,
+ pCookie->instanceHandle);
+ } else {
+ status = CPA_STATUS_FAIL;
+ LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
+ pCookie->instanceHandle);
+ }
+
+ pKeyGenMgfCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
+
+ pMgfOpData = pCookie->pKeyGenOpData;
+ pCallbackTag = pCookie->pCallbackTag;
+ pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
+
+ Lac_MemPoolEntryFree(pCookie);
+
+ (*pKeyGenMgfCb)(pCallbackTag, status, pMgfOpData, pGeneratedKeyBuffer);
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Synchronous mode of operation wrapper function
+ *
+ * @description
+ * Wrapper function to implement synchronous mode of operation for
+ * cpaCyKeyGenMgf and cpaCyKeyGenMgfExt function.
+ *
+ * @param[in] instanceHandle Instance handle
+ * @param[in] pKeyGenCb Internal callback function pointer
+ * @param[in] pCallbackTag Callback tag
+ * @param[in] pKeyGenMgfOpData Pointer to user provided Op Data structure
+ * @param[in] pGeneratedMaskBuffer Pointer to a buffer where generated mask
+ * will be stored
+ * @param[in] bIsExtRequest Indicates origin of function call;
+ * if CPA_TRUE then the call comes from
+ * cpaCyKeyGenMgfExt function, otherwise
+ * from cpaCyKeyGenMgf
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_FAIL Function failed.
+ * @retval CPA_STATUS_RETRY Function should be retried.
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in.
+ * @retval CPA_STATUS_RESOURCE Error related to system resources.
+ *
+ *****************************************************************************/
+static CpaStatus
+LacSymKey_MgfSync(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const void *pKeyGenMgfOpData,
+ CpaFlatBuffer *pGeneratedMaskBuffer,
+ CpaBoolean bIsExtRequest)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ lac_sync_op_data_t *pSyncCallbackData = NULL;
+
+ status = LacSync_CreateSyncCookie(&pSyncCallbackData);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ if (CPA_TRUE == bIsExtRequest) {
+ status = cpaCyKeyGenMgfExt(
+ instanceHandle,
+ LacSync_GenFlatBufCb,
+ pSyncCallbackData,
+ (const CpaCyKeyGenMgfOpDataExt *)pKeyGenMgfOpData,
+ pGeneratedMaskBuffer);
+ } else {
+ status = cpaCyKeyGenMgf(instanceHandle,
+ LacSync_GenFlatBufCb,
+ pSyncCallbackData,
+ (const CpaCyKeyGenMgfOpData *)
+ pKeyGenMgfOpData,
+ pGeneratedMaskBuffer);
+ }
+ } else {
+ /* Failure allocating sync cookie */
+ LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ CpaStatus syncStatus = CPA_STATUS_SUCCESS;
+
+ syncStatus =
+ LacSync_WaitForCallback(pSyncCallbackData,
+ LAC_SYM_SYNC_CALLBACK_TIMEOUT,
+ &status,
+ NULL);
+
+ /* If callback doesn't come back */
+ if (CPA_STATUS_SUCCESS != syncStatus) {
+ LAC_KEY_STAT_INC(numMgfKeyGenCompletedErrors,
+ instanceHandle);
+ LAC_LOG_ERROR("Callback timed out");
+ status = syncStatus;
+ }
+ } else {
+ /* As the Request was not sent the Callback will never
+ * be called, so need to indicate that we're finished
+ * with cookie so it can be destroyed.
+ */
+ LacSync_SetSyncCookieComplete(pSyncCallbackData);
+ }
+
+ LacSync_DestroySyncCookie(&pSyncCallbackData);
+
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Perform MGF key gen operation
+ *
+ * @description
+ * This function performs MGF key gen operation. It is common for requests
+ * coming from both cpaCyKeyGenMgf and cpaCyKeyGenMgfExt QAT API
+ * functions.
+ *
+ * @param[in] instanceHandle Instance handle
+ * @param[in] pKeyGenCb Pointer to callback function to be invoked
+ * when the operation is complete.
+ * @param[in] pCallbackTag Opaque User Data for this specific call.
+ * @param[in] pOpData Pointer to the Op Data structure provided by
+ * the user in API function call. For calls
+ * originating from cpaCyKeyGenMgfExt it will
+ * point to CpaCyKeyGenMgfOpDataExt type of
+ * structure while for calls originating from
+ * cpaCyKeyGenMgf it will point to
+ * CpaCyKeyGenMgfOpData type of structure.
+ * @param[in] pKeyGenMgfOpData Pointer to the user provided
+ * CpaCyKeyGenMgfOpData structure. For calls
+ * originating from cpaCyKeyGenMgf it will
+ * point to the same structure as pOpData
+ * parameter; for calls originating from
+ * cpaCyKeyGenMgfExt it will point to the
+ * baseOpData member of the
+ * CpaCyKeyGenMgfOpDataExt structure passed in
+ * as a parameter to the API function call.
+ * @param[in] pGeneratedMaskBuffer Pointer to a buffer where generated mask
+ * will be stored
+ * @param[in] hashAlgorithm Indicates which hash algorithm is to be used
+ * to perform MGF key gen operation. For calls
+ * originating from cpaCyKeyGenMgf it will
+ * always be CPA_CY_SYM_HASH_SHA1.
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_FAIL Function failed.
+ * @retval CPA_STATUS_RETRY Function should be retried.
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in.
+ * @retval CPA_STATUS_RESOURCE Error related to system resources.
+ *
+ *****************************************************************************/
+static CpaStatus
+LacSymKey_MgfCommon(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const void *pOpData,
+ const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
+ CpaFlatBuffer *pGeneratedMaskBuffer,
+ CpaCySymHashAlgorithm hashAlgorithm)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
+ icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
+ icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
+ icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
+ Cpa8U *pMsgDummy = NULL;
+ Cpa8U *pCacheDummyHdr = NULL;
+ Cpa8U *pCacheDummyMid = NULL;
+ Cpa8U *pCacheDummyFtr = NULL;
+ sal_qat_content_desc_info_t contentDescInfo = { 0 };
+ lac_sym_key_cookie_t *pCookie = NULL;
+ lac_sym_cookie_t *pSymCookie = NULL;
+ sal_crypto_service_t *pService = NULL;
+ Cpa64U inputPhysAddr = 0;
+ Cpa64U outputPhysAddr = 0;
+/* Structure initializer is supported by C99, but it is
+ * not supported by some former Intel compiler.
+ */
+ CpaCySymHashSetupData hashSetupData = { 0 };
+ Cpa32U hashBlkSizeInBytes = 0;
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
+ icp_qat_fw_serv_specif_flags laCmdFlags = 0;
+ icp_qat_fw_comn_flags cmnRequestFlags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
+ QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
+
+ pService = (sal_crypto_service_t *)instanceHandle;
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ SAL_RUNNING_CHECK(instanceHandle);
+ LAC_CHECK_NULL_PARAM(pOpData);
+ LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData);
+ LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer);
+ LAC_CHECK_NULL_PARAM(pGeneratedMaskBuffer->pData);
+ LAC_CHECK_NULL_PARAM(pKeyGenMgfOpData->seedBuffer.pData);
+
+ /* Maximum seed length for MGF1 request */
+ if (pKeyGenMgfOpData->seedBuffer.dataLenInBytes >
+ ICP_QAT_FW_LA_MGF_SEED_LEN_MAX) {
+ LAC_INVALID_PARAM_LOG("seedBuffer.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Maximum mask length for MGF1 request */
+ if (pKeyGenMgfOpData->maskLenInBytes > ICP_QAT_FW_LA_MGF_MASK_LEN_MAX) {
+ LAC_INVALID_PARAM_LOG("maskLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* check for enough space in the flat buffer */
+ if (pKeyGenMgfOpData->maskLenInBytes >
+ pGeneratedMaskBuffer->dataLenInBytes) {
+ LAC_INVALID_PARAM_LOG("pGeneratedMaskBuffer.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Get hash alg info */
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ hashAlgorithm,
+ &pHashAlgInfo);
+
+ /* Allocate the cookie */
+ pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
+ pService->lac_sym_cookie_pool);
+ if (NULL == pCookie) {
+ LAC_LOG_ERROR("Cannot get mem pool entry");
+ status = CPA_STATUS_RESOURCE;
+ } else if ((void *)CPA_STATUS_RETRY == pCookie) {
+ pCookie = NULL;
+ status = CPA_STATUS_RETRY;
+ } else {
+ pSymCookie = (lac_sym_cookie_t *)pCookie;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* populate the cookie */
+ pCookie->instanceHandle = instanceHandle;
+ pCookie->pCallbackTag = pCallbackTag;
+ pCookie->pKeyGenOpData = (void *)LAC_CONST_PTR_CAST(pOpData);
+ pCookie->pKeyGenCb = pKeyGenCb;
+ pCookie->pKeyGenOutputData = pGeneratedMaskBuffer;
+ hashSetupData.hashAlgorithm = hashAlgorithm;
+ hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
+ hashSetupData.digestResultLenInBytes =
+ pHashAlgInfo->digestLength;
+
+ /* Populate the CD ctrl Block (LW 27 - LW 31)
+ * and the CD Hash HW setup block
+ */
+ LacSymQat_HashContentDescInit(
+ &(keyGenReqFtr),
+ instanceHandle,
+ &hashSetupData,
+ /* point to base of hw setup block */
+ (Cpa8U *)pCookie->contentDesc,
+ LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ ICP_QAT_HW_AUTH_MODE0, /* just a plain hash */
+ CPA_FALSE, /* Not using sym Constants Table in Shared SRAM
+ */
+ CPA_FALSE, /* not using the optimised Content Desc */
+ NULL,
+ &hashBlkSizeInBytes);
+
+ /* Populate the Req param LW 14-26 */
+ LacSymQat_KeyMgfRequestPopulate(
+ &keyGenReqHdr,
+ &keyGenReqMid,
+ pKeyGenMgfOpData->seedBuffer.dataLenInBytes,
+ pKeyGenMgfOpData->maskLenInBytes,
+ (Cpa8U)pHashAlgInfo->digestLength);
+
+ contentDescInfo.pData = pCookie->contentDesc;
+ contentDescInfo.hardwareSetupBlockPhys =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyContentDescPhyAddr);
+ contentDescInfo.hwBlkSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
+
+ /* Populate common request fields */
+ inputPhysAddr =
+ LAC_MEM_CAST_PTR_TO_UINT64(LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info,
+ pKeyGenMgfOpData->seedBuffer.pData));
+
+ if (inputPhysAddr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the seed buffer physical address");
+ status = CPA_STATUS_FAIL;
+ }
+ outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
+ pGeneratedMaskBuffer->pData));
+ if (outputPhysAddr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the mask");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Make up the full keyGenReq struct from its constituents */
+ pMsgDummy = (Cpa8U *)&(keyGenReq);
+ pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
+ pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
+ pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
+
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memset((pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
+ 0,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_MID_IN_LW),
+ pCacheDummyMid,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
+ keyGenReq),
+ &(contentDescInfo));
+
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
+ ICP_QAT_FW_LA_CMD_MGF1,
+ cmnRequestFlags,
+ laCmdFlags);
+
+ /*
+ * MGF uses a flat buffer but we can use zero for source and
+ * dest length because the firmware will use the seed length,
+ * hash length and mask length to find source length.
+ */
+ SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
+ pCookie,
+ LAC_SYM_KEY_QAT_PTR_TYPE,
+ inputPhysAddr,
+ outputPhysAddr,
+ 0,
+ 0);
+
+ /* Send to QAT */
+ status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
+ (void *)&(keyGenReq),
+ LAC_QAT_SYM_REQ_SZ_LW);
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Update stats */
+ LAC_KEY_STAT_INC(numMgfKeyGenRequests, instanceHandle);
+ } else {
+ LAC_KEY_STAT_INC(numMgfKeyGenRequestErrors, instanceHandle);
+ /* clean up memory */
+ if (NULL != pCookie) {
+ Lac_MemPoolEntryFree(pCookie);
+ }
+ }
+ return status;
+}
+
+/**
+ * cpaCyKeyGenMgf
+ */
+CpaStatus
+cpaCyKeyGenMgf(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenMgfOpData *pKeyGenMgfOpData,
+ CpaFlatBuffer *pGeneratedMaskBuffer)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ /* If synchronous Operation */
+ if (NULL == pKeyGenCb) {
+ return LacSymKey_MgfSync(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ (const void *)pKeyGenMgfOpData,
+ pGeneratedMaskBuffer,
+ CPA_FALSE);
+ }
+ /* Asynchronous Operation */
+ return LacSymKey_MgfCommon(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ (const void *)pKeyGenMgfOpData,
+ pKeyGenMgfOpData,
+ pGeneratedMaskBuffer,
+ CPA_CY_SYM_HASH_SHA1);
+}
+
+/**
+ * cpaCyKeyGenMgfExt
+ */
+CpaStatus
+cpaCyKeyGenMgfExt(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenMgfOpDataExt *pKeyGenMgfOpDataExt,
+ CpaFlatBuffer *pGeneratedMaskBuffer)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ /* If synchronous Operation */
+ if (NULL == pKeyGenCb) {
+ return LacSymKey_MgfSync(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ (const void *)pKeyGenMgfOpDataExt,
+ pGeneratedMaskBuffer,
+ CPA_TRUE);
+ }
+
+ /* Param check specific for Ext function, rest of parameters validated
+ * in LacSymKey_MgfCommon
+ */
+ LAC_CHECK_NULL_PARAM(pKeyGenMgfOpDataExt);
+ if (CPA_CY_SYM_HASH_MD5 > pKeyGenMgfOpDataExt->hashAlgorithm ||
+ CPA_CY_SYM_HASH_SHA512 < pKeyGenMgfOpDataExt->hashAlgorithm) {
+ LAC_INVALID_PARAM_LOG("hashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Asynchronous Operation */
+ return LacSymKey_MgfCommon(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ (const void *)pKeyGenMgfOpDataExt,
+ &pKeyGenMgfOpDataExt->baseOpData,
+ pGeneratedMaskBuffer,
+ pKeyGenMgfOpDataExt->hashAlgorithm);
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * Key Generation SSL & TLS response handler
+ *
+ * @description
+ * Handles Key Generation SSL & TLS response messages from the QAT.
+ *
+ * @param[in] lacCmdId Command id of the original request
+ * @param[in] pOpaqueData Pointer to opaque data that was in request
+ * @param[in] cmnRespFlags LA response flags
+ *
+ * @return void
+ *
+ *****************************************************************************/
+static void
+LacSymKey_SslTlsHandleResponse(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags)
+{
+ void *pSslTlsOpData = NULL;
+ CpaCyGenFlatBufCbFunc pKeyGenSslTlsCb = NULL;
+ lac_sym_key_cookie_t *pCookie = NULL;
+ void *pCallbackTag = NULL;
+ CpaFlatBuffer *pGeneratedKeyBuffer = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ CpaBoolean respStatusOk =
+ (ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
+ ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags)) ?
+ CPA_TRUE :
+ CPA_FALSE;
+
+ pCookie = (lac_sym_key_cookie_t *)pOpaqueData;
+
+ pSslTlsOpData = pCookie->pKeyGenOpData;
+
+ if (CPA_TRUE == respStatusOk) {
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_COMPLETED,
+ pCookie->instanceHandle);
+ } else {
+ status = CPA_STATUS_FAIL;
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_COMPLETED_ERRORS,
+ pCookie->instanceHandle);
+ }
+
+ pKeyGenSslTlsCb = (CpaCyGenFlatBufCbFunc)(pCookie->pKeyGenCb);
+
+ pCallbackTag = pCookie->pCallbackTag;
+ pGeneratedKeyBuffer = pCookie->pKeyGenOutputData;
+
+ Lac_MemPoolEntryFree(pCookie);
+
+ (*pKeyGenSslTlsCb)(pCallbackTag,
+ status,
+ pSslTlsOpData,
+ pGeneratedKeyBuffer);
+}
+
+/**
+*******************************************************************************
+* @ingroup LacSymKey
+* Synchronous mode of operation function wrapper for performing SSL/TLS
+* key gen operation
+*
+* @description
+* Synchronous mode of operation function wrapper for performing SSL/TLS
+* key gen operation
+*
+* @param[in] instanceHandle QAT device handle.
+* @param[in] pKeyGenCb Pointer to callback function to be invoked
+* when the operation is complete.
+* @param[in] pCallbackTag Opaque User Data for this specific call.
+* @param[in] lacCmdId Lac command ID (identify SSL & TLS ops)
+* @param[in] pKeyGenSslTlsOpData Structure containing all the data needed to
+* perform the SSL/TLS key generation
+* operation.
+* @param[in] hashAlgorithm Specifies the hash algorithm to use.
+* According to RFC5246, this should be
+* "SHA-256 or a stronger standard hash
+* function."
+* @param[out] pKeyGenOutputData pointer to where output result should be
+* written
+*
+* @retval CPA_STATUS_SUCCESS Function executed successfully.
+* @retval CPA_STATUS_FAIL Function failed.
+* @retval CPA_STATUS_RETRY Function should be retried.
+* @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in.
+* @retval CPA_STATUS_RESOURCE Error related to system resources.
+*
+*****************************************************************************/
+static CpaStatus
+LacSymKey_SslTlsSync(CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pKeyGenSslTlsOpData,
+ Cpa8U hashAlgorithm,
+ CpaFlatBuffer *pKeyGenOutpuData)
+{
+ lac_sync_op_data_t *pSyncCallbackData = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ status = LacSync_CreateSyncCookie(&pSyncCallbackData);
+ if (CPA_STATUS_SUCCESS == status) {
+ status = LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
+ pKeyGenCb,
+ pSyncCallbackData,
+ lacCmdId,
+ pKeyGenSslTlsOpData,
+ hashAlgorithm,
+ pKeyGenOutpuData);
+ } else {
+ /* Failure allocating sync cookie */
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_REQUEST_ERRORS,
+ instanceHandle);
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ CpaStatus syncStatus = CPA_STATUS_SUCCESS;
+
+ syncStatus =
+ LacSync_WaitForCallback(pSyncCallbackData,
+ LAC_SYM_SYNC_CALLBACK_TIMEOUT,
+ &status,
+ NULL);
+
+ /* If callback doesn't come back */
+ if (CPA_STATUS_SUCCESS != syncStatus) {
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_COMPLETED_ERRORS,
+ instanceHandle);
+ LAC_LOG_ERROR("Callback timed out");
+ status = syncStatus;
+ }
+ } else {
+ /* As the Request was not sent the Callback will never
+ * be called, so need to indicate that we're finished
+ * with cookie so it can be destroyed.
+ */
+ LacSync_SetSyncCookieComplete(pSyncCallbackData);
+ }
+
+ LacSync_DestroySyncCookie(&pSyncCallbackData);
+
+ return status;
+}
+
+static CpaStatus
+computeHashKey(CpaFlatBuffer *secret,
+ CpaFlatBuffer *hash,
+ CpaCySymHashAlgorithm *hashAlgorithm)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ switch (*hashAlgorithm) {
+ case CPA_CY_SYM_HASH_MD5:
+ status = qatUtilsHashMD5Full(secret->pData,
+ hash->pData,
+ secret->dataLenInBytes);
+ break;
+ case CPA_CY_SYM_HASH_SHA1:
+ status = qatUtilsHashSHA1Full(secret->pData,
+ hash->pData,
+ secret->dataLenInBytes);
+ break;
+ case CPA_CY_SYM_HASH_SHA256:
+ status = qatUtilsHashSHA256Full(secret->pData,
+ hash->pData,
+ secret->dataLenInBytes);
+ break;
+ case CPA_CY_SYM_HASH_SHA384:
+ status = qatUtilsHashSHA384Full(secret->pData,
+ hash->pData,
+ secret->dataLenInBytes);
+ break;
+ case CPA_CY_SYM_HASH_SHA512:
+ status = qatUtilsHashSHA512Full(secret->pData,
+ hash->pData,
+ secret->dataLenInBytes);
+ break;
+ default:
+ status = CPA_STATUS_FAIL;
+ }
+ return status;
+}
+
+static CpaStatus
+LacSymKey_KeyGenSslTls_GenCommon(CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pKeyGenSslTlsOpData,
+ Cpa8U hashAlgCipher,
+ CpaFlatBuffer *pKeyGenOutputData)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaBoolean precompute = CPA_FALSE;
+ icp_qat_fw_la_bulk_req_t keyGenReq = { { 0 } };
+ icp_qat_la_bulk_req_hdr_t keyGenReqHdr = { { 0 } };
+ icp_qat_fw_la_key_gen_common_t keyGenReqMid = { { 0 } };
+ icp_qat_la_bulk_req_ftr_t keyGenReqFtr = { { { 0 } } };
+ Cpa8U *pMsgDummy = NULL;
+ Cpa8U *pCacheDummyHdr = NULL;
+ Cpa8U *pCacheDummyMid = NULL;
+ Cpa8U *pCacheDummyFtr = NULL;
+ lac_sym_key_cookie_t *pCookie = NULL;
+ lac_sym_cookie_t *pSymCookie = NULL;
+ Cpa64U inputPhysAddr = 0;
+ Cpa64U outputPhysAddr = 0;
+/* Structure initializer is supported by C99, but it is
+ * not supported by some former Intel compiler.
+ */
+ CpaCySymHashSetupData hashSetupData = { 0 };
+ sal_qat_content_desc_info_t contentDescInfo = { 0 };
+ Cpa32U hashBlkSizeInBytes = 0;
+ Cpa32U tlsPrefixLen = 0;
+
+ CpaFlatBuffer inputSecret = { 0 };
+ CpaFlatBuffer hashKeyOutput = { 0 };
+ Cpa32U uSecretLen = 0;
+ CpaCySymHashNestedModeSetupData *pNestedModeSetupData =
+ &(hashSetupData.nestedModeSetupData);
+ icp_qat_fw_serv_specif_flags laCmdFlags = 0;
+ icp_qat_fw_comn_flags cmnRequestFlags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(QAT_COMN_PTR_TYPE_FLAT,
+ QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
+
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ /* If synchronous Operation */
+ if (NULL == pKeyGenCb) {
+ return LacSymKey_SslTlsSync(instanceHandle,
+ LacSync_GenFlatBufCb,
+ pCallbackTag,
+ lacCmdId,
+ pKeyGenSslTlsOpData,
+ hashAlgCipher,
+ pKeyGenOutputData);
+ }
+ /* Allocate the cookie */
+ pCookie = (lac_sym_key_cookie_t *)Lac_MemPoolEntryAlloc(
+ pService->lac_sym_cookie_pool);
+ if (NULL == pCookie) {
+ LAC_LOG_ERROR("Cannot get mem pool entry");
+ status = CPA_STATUS_RESOURCE;
+ } else if ((void *)CPA_STATUS_RETRY == pCookie) {
+ pCookie = NULL;
+ status = CPA_STATUS_RETRY;
+ } else {
+ pSymCookie = (lac_sym_cookie_t *)pCookie;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ icp_qat_hw_auth_mode_t qatHashMode = 0;
+
+ if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
+ qatHashMode = ICP_QAT_HW_AUTH_MODE0;
+ } else /* TLS v1.1, v1.2, v1.3 */
+ {
+ qatHashMode = ICP_QAT_HW_AUTH_MODE2;
+ }
+
+ pCookie->instanceHandle = pService;
+ pCookie->pCallbackTag = pCallbackTag;
+ pCookie->pKeyGenCb = pKeyGenCb;
+ pCookie->pKeyGenOpData = pKeyGenSslTlsOpData;
+ pCookie->pKeyGenOutputData = pKeyGenOutputData;
+ hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_NESTED;
+
+ /* SSL3 */
+ if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
+ hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
+ hashSetupData.digestResultLenInBytes =
+ LAC_HASH_MD5_DIGEST_SIZE;
+ pNestedModeSetupData->outerHashAlgorithm =
+ CPA_CY_SYM_HASH_MD5;
+
+ pNestedModeSetupData->pInnerPrefixData = NULL;
+ pNestedModeSetupData->innerPrefixLenInBytes = 0;
+ pNestedModeSetupData->pOuterPrefixData = NULL;
+ pNestedModeSetupData->outerPrefixLenInBytes = 0;
+ }
+ /* TLS v1.1 */
+ else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId) {
+ CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
+
+ hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
+ hashSetupData.digestResultLenInBytes =
+ LAC_HASH_MD5_DIGEST_SIZE;
+ pNestedModeSetupData->outerHashAlgorithm =
+ CPA_CY_SYM_HASH_MD5;
+
+ uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
+
+ /* We want to handle pre_master_secret > 128 bytes
+ * therefore we
+ * only verify if the current operation is Master Secret
+ * Derive.
+ * The other operations remain unchanged.
+ */
+ if ((uSecretLen >
+ ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX) &&
+ (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
+ pKeyGenTlsOpData->tlsOp ||
+ CPA_CY_KEY_TLS_OP_USER_DEFINED ==
+ pKeyGenTlsOpData->tlsOp)) {
+ CpaCySymHashAlgorithm hashAlgorithm =
+ (CpaCySymHashAlgorithm)hashAlgCipher;
+ /* secret = [s1 | s2 ]
+ * s1 = outer prefix, s2 = inner prefix
+ * length of s1 and s2 = ceil(secret_length / 2)
+ * (secret length + 1)/2 will always give the
+ * ceil as
+ * division by 2
+ * (>>1) will give the smallest integral value
+ * not less than
+ * arg
+ */
+ tlsPrefixLen =
+ (pKeyGenTlsOpData->secret.dataLenInBytes +
+ 1) >>
+ 1;
+ inputSecret.dataLenInBytes = tlsPrefixLen;
+ inputSecret.pData =
+ pKeyGenTlsOpData->secret.pData;
+
+ /* Since the pre_master_secret is > 128, we
+ * split the input
+ * pre_master_secret in 2 halves and compute the
+ * MD5 of the
+ * first half and the SHA1 on the second half.
+ */
+ hashAlgorithm = CPA_CY_SYM_HASH_MD5;
+
+ /* Initialize pointer where MD5 key will go. */
+ hashKeyOutput.pData =
+ &pCookie->hashKeyBuffer[0];
+ hashKeyOutput.dataLenInBytes =
+ LAC_HASH_MD5_DIGEST_SIZE;
+ computeHashKey(&inputSecret,
+ &hashKeyOutput,
+ &hashAlgorithm);
+
+ pNestedModeSetupData->pOuterPrefixData =
+ &pCookie->hashKeyBuffer[0];
+ pNestedModeSetupData->outerPrefixLenInBytes =
+ LAC_HASH_MD5_DIGEST_SIZE;
+
+ /* Point to the second half of the
+ * pre_master_secret */
+ inputSecret.pData =
+ pKeyGenTlsOpData->secret.pData +
+ (pKeyGenTlsOpData->secret.dataLenInBytes -
+ tlsPrefixLen);
+
+ /* Compute SHA1 on the second half of the
+ * pre_master_secret
+ */
+ hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
+ /* Initialize pointer where SHA1 key will go. */
+ hashKeyOutput.pData =
+ &pCookie->hashKeyBuffer
+ [LAC_HASH_MD5_DIGEST_SIZE];
+ hashKeyOutput.dataLenInBytes =
+ LAC_HASH_SHA1_DIGEST_SIZE;
+ computeHashKey(&inputSecret,
+ &hashKeyOutput,
+ &hashAlgorithm);
+
+ pNestedModeSetupData->pInnerPrefixData =
+ &pCookie->hashKeyBuffer
+ [LAC_HASH_MD5_DIGEST_SIZE];
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ LAC_HASH_SHA1_DIGEST_SIZE;
+ } else {
+ /* secret = [s1 | s2 ]
+ * s1 = outer prefix, s2 = inner prefix
+ * length of s1 and s2 = ceil(secret_length / 2)
+ * (secret length + 1)/2 will always give the
+ * ceil as
+ * division by 2
+ * (>>1) will give the smallest integral value
+ * not less than
+ * arg
+ */
+ tlsPrefixLen =
+ (pKeyGenTlsOpData->secret.dataLenInBytes +
+ 1) >>
+ 1;
+ /* last byte of s1 will be first byte of s2 if
+ * Length is odd
+ */
+ pNestedModeSetupData->pInnerPrefixData =
+ pKeyGenTlsOpData->secret.pData +
+ (pKeyGenTlsOpData->secret.dataLenInBytes -
+ tlsPrefixLen);
+
+ pNestedModeSetupData->pOuterPrefixData =
+ pKeyGenTlsOpData->secret.pData;
+
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ pNestedModeSetupData
+ ->outerPrefixLenInBytes = tlsPrefixLen;
+ }
+ }
+ /* TLS v1.2 */
+ else if (ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
+ CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
+ CpaCySymHashAlgorithm hashAlgorithm =
+ (CpaCySymHashAlgorithm)hashAlgCipher;
+
+ uSecretLen = pKeyGenTlsOpData->secret.dataLenInBytes;
+
+ hashSetupData.hashAlgorithm =
+ (CpaCySymHashAlgorithm)hashAlgorithm;
+ hashSetupData.digestResultLenInBytes =
+ (Cpa32U)getDigestSizeFromHashAlgo(hashAlgorithm);
+ pNestedModeSetupData->outerHashAlgorithm =
+ (CpaCySymHashAlgorithm)hashAlgorithm;
+ if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
+ pKeyGenTlsOpData->tlsOp ||
+ CPA_CY_KEY_TLS_OP_USER_DEFINED ==
+ pKeyGenTlsOpData->tlsOp) {
+ switch (hashAlgorithm) {
+ case CPA_CY_SYM_HASH_SM3:
+ precompute = CPA_FALSE;
+ break;
+ case CPA_CY_SYM_HASH_SHA256:
+ if (uSecretLen >
+ ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX) {
+ precompute = CPA_TRUE;
+ }
+ break;
+ case CPA_CY_SYM_HASH_SHA384:
+ case CPA_CY_SYM_HASH_SHA512:
+ if (uSecretLen >
+ ICP_QAT_FW_LA_TLS_SECRET_LEN_MAX) {
+ precompute = CPA_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (CPA_TRUE == precompute) {
+ /* Case when secret > algorithm block size
+ * RFC 4868: For SHA-256 Block size is 512 bits,
+ * for SHA-384
+ * and SHA-512 Block size is 1024 bits
+ * Initialize pointer
+ * where SHAxxx key will go.
+ */
+ hashKeyOutput.pData =
+ &pCookie->hashKeyBuffer[0];
+ hashKeyOutput.dataLenInBytes =
+ hashSetupData.digestResultLenInBytes;
+ computeHashKey(&pKeyGenTlsOpData->secret,
+ &hashKeyOutput,
+ &hashSetupData.hashAlgorithm);
+
+ /* Outer prefix = secret , inner prefix = secret
+ * secret < 64 bytes
+ */
+ pNestedModeSetupData->pInnerPrefixData =
+ hashKeyOutput.pData;
+ pNestedModeSetupData->pOuterPrefixData =
+ hashKeyOutput.pData;
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ hashKeyOutput.dataLenInBytes;
+ pNestedModeSetupData->outerPrefixLenInBytes =
+ hashKeyOutput.dataLenInBytes;
+ } else {
+ /* Outer prefix = secret , inner prefix = secret
+ * secret <= 64 bytes
+ */
+ pNestedModeSetupData->pInnerPrefixData =
+ pKeyGenTlsOpData->secret.pData;
+
+ pNestedModeSetupData->pOuterPrefixData =
+ pKeyGenTlsOpData->secret.pData;
+
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ pKeyGenTlsOpData->secret.dataLenInBytes;
+ pNestedModeSetupData->outerPrefixLenInBytes =
+ pKeyGenTlsOpData->secret.dataLenInBytes;
+ }
+ }
+ /* TLS v1.3 */
+ else if ((ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId) &&
+ (ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL >=
+ lacCmdId)) {
+ CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
+ CpaCySymHashAlgorithm hashAlgorithm =
+ getHashAlgorithmFromCipherSuiteHKDF(hashAlgCipher);
+
+ /* Set HASH data */
+ hashSetupData.hashAlgorithm = hashAlgorithm;
+ /* Calculate digest length from the HASH type */
+ hashSetupData.digestResultLenInBytes =
+ cipherSuiteHKDFHashSizes[hashAlgCipher]
+ [LAC_KEY_HKDF_DIGESTS];
+ /* Outer Hash type is the same as inner hash type */
+ pNestedModeSetupData->outerHashAlgorithm =
+ hashAlgorithm;
+
+ /* EXPAND (PRK):
+ * Outer prefix = secret, inner prefix = secret
+ * EXTRACT (SEED/SALT):
+ * Outer prefix = seed, inner prefix = seed
+ * Secret <= 64 Bytes
+ * We do not pre compute as secret can't be larger than
+ * 64 bytes
+ */
+
+ if ((ICP_QAT_FW_LA_CMD_HKDF_EXPAND == lacCmdId) ||
+ (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId)) {
+ pNestedModeSetupData->pInnerPrefixData =
+ pKeyGenTlsOpData->secret;
+ pNestedModeSetupData->pOuterPrefixData =
+ pKeyGenTlsOpData->secret;
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ pKeyGenTlsOpData->secretLen;
+ pNestedModeSetupData->outerPrefixLenInBytes =
+ pKeyGenTlsOpData->secretLen;
+ } else {
+ pNestedModeSetupData->pInnerPrefixData =
+ pKeyGenTlsOpData->seed;
+ pNestedModeSetupData->pOuterPrefixData =
+ pKeyGenTlsOpData->seed;
+ pNestedModeSetupData->innerPrefixLenInBytes =
+ pKeyGenTlsOpData->seedLen;
+ pNestedModeSetupData->outerPrefixLenInBytes =
+ pKeyGenTlsOpData->seedLen;
+ }
+ }
+
+ /* Set the footer Data.
+ * Note that following function doesn't look at inner/outer
+ * prefix pointers in nested digest ctx
+ */
+ LacSymQat_HashContentDescInit(
+ &keyGenReqFtr,
+ instanceHandle,
+ &hashSetupData,
+ pCookie
+ ->contentDesc, /* Pointer to base of hw setup block */
+ LAC_SYM_KEY_NO_HASH_BLK_OFFSET_QW,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ qatHashMode,
+ CPA_FALSE, /* Not using sym Constants Table in SRAM */
+ CPA_FALSE, /* Not using the optimised content Desc */
+ NULL, /* Precompute data */
+ &hashBlkSizeInBytes);
+
+ /* SSL3 */
+ if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == lacCmdId) {
+ CpaCyKeyGenSslOpData *pKeyGenSslOpData =
+ (CpaCyKeyGenSslOpData *)pKeyGenSslTlsOpData;
+ Cpa8U *pLabel = NULL;
+ Cpa32U labelLen = 0;
+ Cpa8U iterations = 0;
+ Cpa64U labelPhysAddr = 0;
+
+ /* Iterations = ceiling of output required / output per
+ * iteration Ceiling of a / b = (a + (b-1)) / b
+ */
+ iterations =
+ (pKeyGenSslOpData->generatedKeyLenInBytes +
+ (LAC_SYM_QAT_KEY_SSL_BYTES_PER_ITERATION - 1)) >>
+ LAC_SYM_QAT_KEY_SSL_ITERATIONS_SHIFT;
+
+ if (CPA_CY_KEY_SSL_OP_USER_DEFINED ==
+ pKeyGenSslOpData->sslOp) {
+ pLabel = pKeyGenSslOpData->userLabel.pData;
+ labelLen =
+ pKeyGenSslOpData->userLabel.dataLenInBytes;
+ labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info, pLabel);
+
+ if (labelPhysAddr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the"
+ " label");
+ status = CPA_STATUS_FAIL;
+ }
+ } else {
+ pLabel = pService->pSslLabel;
+
+ /* Calculate label length.
+ * eg. 3 iterations is ABBCCC so length is 6
+ */
+ labelLen =
+ ((iterations * iterations) + iterations) >>
+ 1;
+ labelPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
+ }
+
+ LacSymQat_KeySslRequestPopulate(
+ &keyGenReqHdr,
+ &keyGenReqMid,
+ pKeyGenSslOpData->generatedKeyLenInBytes,
+ labelLen,
+ pKeyGenSslOpData->secret.dataLenInBytes,
+ iterations);
+
+ LacSymQat_KeySslKeyMaterialInputPopulate(
+ &(pService->generic_service_info),
+ &(pCookie->u.sslKeyInput),
+ pKeyGenSslOpData->seed.pData,
+ labelPhysAddr,
+ pKeyGenSslOpData->secret.pData);
+
+ inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keySslKeyInputPhyAddr);
+ }
+ /* TLS v1.1, v1.2 */
+ else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == lacCmdId ||
+ ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == lacCmdId) {
+ CpaCyKeyGenTlsOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenTlsOpData *)pKeyGenSslTlsOpData;
+ lac_sym_qat_hash_state_buffer_info_t
+ hashStateBufferInfo = { 0 };
+ CpaBoolean hashStateBuffer = CPA_FALSE;
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
+ (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
+ keyGenReqFtr.cd_ctrl);
+ icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
+ Cpa8U *pLabel = NULL;
+ Cpa32U labelLen = 0;
+ Cpa64U labelPhysAddr = 0;
+ hashStateBufferInfo.pData = pCookie->hashStateBuffer;
+ hashStateBufferInfo.pDataPhys =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyHashStateBufferPhyAddr);
+ hashStateBufferInfo.stateStorageSzQuadWords = 0;
+
+ LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
+ instanceHandle,
+ &(hashSetupData),
+ hashStateBuffer,
+ qatHashMode,
+ CPA_FALSE);
+
+ pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
+ keyGenReqFtr.serv_specif_rqpars);
+
+ hashStateBufferInfo.prefixAadSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ pHashReqParams->u2.inner_prefix_sz +
+ pHashControlBlock->outer_prefix_sz);
+
+ /* Copy prefix data into hash state buffer */
+ pMsgDummy = (Cpa8U *)&(keyGenReq);
+ pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
+ pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
+ pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_MID_IN_LW),
+ pCacheDummyMid,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_MID_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ LacSymQat_HashStatePrefixAadBufferPopulate(
+ &hashStateBufferInfo,
+ &keyGenReqFtr,
+ pNestedModeSetupData->pInnerPrefixData,
+ pNestedModeSetupData->innerPrefixLenInBytes,
+ pNestedModeSetupData->pOuterPrefixData,
+ pNestedModeSetupData->outerPrefixLenInBytes);
+
+ /* Firmware only looks at hash state buffer pointer and
+ * the
+ * hash state buffer size so all other fields are set to
+ * 0
+ */
+ LacSymQat_HashRequestParamsPopulate(
+ &(keyGenReq),
+ 0, /* Auth offset */
+ 0, /* Auth length */
+ &(pService->generic_service_info),
+ &hashStateBufferInfo, /* Hash state prefix buffer */
+ ICP_QAT_FW_LA_PARTIAL_NONE,
+ 0, /* Hash result size */
+ CPA_FALSE,
+ NULL,
+ CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
+ NULL); /* HKDF only */
+
+ /* Set up the labels and their length */
+ if (CPA_CY_KEY_TLS_OP_USER_DEFINED ==
+ pKeyGenTlsOpData->tlsOp) {
+ pLabel = pKeyGenTlsOpData->userLabel.pData;
+ labelLen =
+ pKeyGenTlsOpData->userLabel.dataLenInBytes;
+ labelPhysAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info, pLabel);
+
+ if (labelPhysAddr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the"
+ " label");
+ status = CPA_STATUS_FAIL;
+ }
+ } else if (CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE ==
+ pKeyGenTlsOpData->tlsOp) {
+ pLabel = pService->pTlsLabel->masterSecret;
+ labelLen =
+ sizeof(
+ LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) -
+ 1;
+ labelPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
+ } else if (CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE ==
+ pKeyGenTlsOpData->tlsOp) {
+ pLabel = pService->pTlsLabel->keyMaterial;
+ labelLen =
+ sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) -
+ 1;
+ labelPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
+ } else if (CPA_CY_KEY_TLS_OP_CLIENT_FINISHED_DERIVE ==
+ pKeyGenTlsOpData->tlsOp) {
+ pLabel = pService->pTlsLabel->clientFinished;
+ labelLen =
+ sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) -
+ 1;
+ labelPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
+ } else {
+ pLabel = pService->pTlsLabel->serverFinished;
+ labelLen =
+ sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) -
+ 1;
+ labelPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pLabel);
+ }
+ LacSymQat_KeyTlsRequestPopulate(
+ &keyGenReqMid,
+ pKeyGenTlsOpData->generatedKeyLenInBytes,
+ labelLen,
+ pKeyGenTlsOpData->secret.dataLenInBytes,
+ pKeyGenTlsOpData->seed.dataLenInBytes,
+ lacCmdId);
+
+ LacSymQat_KeyTlsKeyMaterialInputPopulate(
+ &(pService->generic_service_info),
+ &(pCookie->u.tlsKeyInput),
+ pKeyGenTlsOpData->seed.pData,
+ labelPhysAddr);
+
+ inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyTlsKeyInputPhyAddr);
+ }
+ /* TLS v1.3 */
+ else if (ICP_QAT_FW_LA_CMD_HKDF_EXTRACT <= lacCmdId &&
+ ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND >=
+ lacCmdId) {
+ CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
+ lac_sym_qat_hash_state_buffer_info_t
+ hashStateBufferInfo = { 0 };
+ CpaBoolean hashStateBuffer = CPA_FALSE;
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
+ (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
+ keyGenReqFtr.cd_ctrl);
+ icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
+ hashStateBufferInfo.pData = pCookie->hashStateBuffer;
+ hashStateBufferInfo.pDataPhys =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyHashStateBufferPhyAddr);
+ hashStateBufferInfo.stateStorageSzQuadWords = 0;
+
+ LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
+ instanceHandle,
+ &(hashSetupData),
+ hashStateBuffer,
+ qatHashMode,
+ CPA_FALSE);
+
+ pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
+ keyGenReqFtr.serv_specif_rqpars);
+
+ hashStateBufferInfo.prefixAadSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ pHashReqParams->u2.inner_prefix_sz +
+ pHashControlBlock->outer_prefix_sz);
+
+ /* Copy prefix data into hash state buffer */
+ pMsgDummy = (Cpa8U *)&(keyGenReq);
+ pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
+ pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
+ pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_MID_IN_LW),
+ pCacheDummyMid,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_MID_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ LacSymQat_HashStatePrefixAadBufferPopulate(
+ &hashStateBufferInfo,
+ &keyGenReqFtr,
+ pNestedModeSetupData->pInnerPrefixData,
+ pNestedModeSetupData->innerPrefixLenInBytes,
+ pNestedModeSetupData->pOuterPrefixData,
+ pNestedModeSetupData->outerPrefixLenInBytes);
+
+ /* Firmware only looks at hash state buffer pointer and
+ * the
+ * hash state buffer size so all other fields are set to
+ * 0
+ */
+ LacSymQat_HashRequestParamsPopulate(
+ &(keyGenReq),
+ 0, /* Auth offset */
+ 0, /* Auth length */
+ &(pService->generic_service_info),
+ &hashStateBufferInfo, /* Hash state prefix buffer */
+ ICP_QAT_FW_LA_PARTIAL_NONE,
+ 0, /* Hash result size */
+ CPA_FALSE,
+ NULL,
+ CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
+ pKeyGenTlsOpData->secret); /* IKM or PRK */
+
+ LacSymQat_KeyTlsRequestPopulate(
+ &keyGenReqMid,
+ cipherSuiteHKDFHashSizes[hashAlgCipher]
+ [LAC_KEY_HKDF_DIGESTS],
+ /* For EXTRACT, EXPAND, FW expects info to be passed
+ as label */
+ pKeyGenTlsOpData->infoLen,
+ pKeyGenTlsOpData->secretLen,
+ pKeyGenTlsOpData->seedLen,
+ lacCmdId);
+
+ LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
+ &(pService->generic_service_info),
+ &(pCookie->u.tlsHKDFKeyInput),
+ pKeyGenTlsOpData,
+ 0, /* No subLabels used */
+ lacCmdId); /* Pass op being performed */
+
+ inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyTlsKeyInputPhyAddr);
+ }
+ /* TLS v1.3 LABEL */
+ else if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == lacCmdId ||
+ ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL ==
+ lacCmdId) {
+ CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData =
+ (CpaCyKeyGenHKDFOpData *)pKeyGenSslTlsOpData;
+ Cpa64U subLabelsPhysAddr = 0;
+ lac_sym_qat_hash_state_buffer_info_t
+ hashStateBufferInfo = { 0 };
+ CpaBoolean hashStateBuffer = CPA_FALSE;
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock =
+ (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(
+ keyGenReqFtr.cd_ctrl);
+ icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
+ hashStateBufferInfo.pData = pCookie->hashStateBuffer;
+ hashStateBufferInfo.pDataPhys =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyHashStateBufferPhyAddr);
+ hashStateBufferInfo.stateStorageSzQuadWords = 0;
+
+ LacSymQat_HashSetupReqParamsMetaData(&(keyGenReqFtr),
+ instanceHandle,
+ &(hashSetupData),
+ hashStateBuffer,
+ qatHashMode,
+ CPA_FALSE);
+
+ pHashReqParams = (icp_qat_la_auth_req_params_t *)&(
+ keyGenReqFtr.serv_specif_rqpars);
+
+ hashStateBufferInfo.prefixAadSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ pHashReqParams->u2.inner_prefix_sz +
+ pHashControlBlock->outer_prefix_sz);
+
+ /* Copy prefix data into hash state buffer */
+ pMsgDummy = (Cpa8U *)&(keyGenReq);
+ pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
+ pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
+ pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_MID_IN_LW),
+ pCacheDummyMid,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_MID_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ LacSymQat_HashStatePrefixAadBufferPopulate(
+ &hashStateBufferInfo,
+ &keyGenReqFtr,
+ pNestedModeSetupData->pInnerPrefixData,
+ pNestedModeSetupData->innerPrefixLenInBytes,
+ pNestedModeSetupData->pOuterPrefixData,
+ pNestedModeSetupData->outerPrefixLenInBytes);
+
+ /* Firmware only looks at hash state buffer pointer and
+ * the
+ * hash state buffer size so all other fields are set to
+ * 0
+ */
+ LacSymQat_HashRequestParamsPopulate(
+ &(keyGenReq),
+ 0, /* Auth offset */
+ 0, /* Auth length */
+ &(pService->generic_service_info),
+ &hashStateBufferInfo, /* Hash state prefix buffer */
+ ICP_QAT_FW_LA_PARTIAL_NONE,
+ 0, /* Hash result size */
+ CPA_FALSE,
+ NULL,
+ CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
+ pKeyGenTlsOpData->secret); /* IKM or PRK */
+
+ LacSymQat_KeyTlsRequestPopulate(
+ &keyGenReqMid,
+ cipherSuiteHKDFHashSizes[hashAlgCipher]
+ [LAC_KEY_HKDF_DIGESTS],
+ pKeyGenTlsOpData->numLabels, /* Number of Labels */
+ pKeyGenTlsOpData->secretLen,
+ pKeyGenTlsOpData->seedLen,
+ lacCmdId);
+
+ /* Get physical address of subLabels */
+ switch (hashAlgCipher) {
+ case CPA_CY_HKDF_TLS_AES_128_GCM_SHA256: /* Fall Through
+ */
+ case CPA_CY_HKDF_TLS_AES_128_CCM_SHA256:
+ case CPA_CY_HKDF_TLS_AES_128_CCM_8_SHA256:
+ subLabelsPhysAddr = pService->pTlsHKDFSubLabel
+ ->sublabelPhysAddr256;
+ break;
+ case CPA_CY_HKDF_TLS_CHACHA20_POLY1305_SHA256:
+ subLabelsPhysAddr =
+ pService->pTlsHKDFSubLabel
+ ->sublabelPhysAddrChaChaPoly;
+ break;
+ case CPA_CY_HKDF_TLS_AES_256_GCM_SHA384:
+ subLabelsPhysAddr = pService->pTlsHKDFSubLabel
+ ->sublabelPhysAddr384;
+ break;
+ default:
+ break;
+ }
+
+ LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
+ &(pService->generic_service_info),
+ &(pCookie->u.tlsHKDFKeyInput),
+ pKeyGenTlsOpData,
+ subLabelsPhysAddr,
+ lacCmdId); /* Pass op being performed */
+
+ inputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyTlsKeyInputPhyAddr);
+ }
+
+ outputPhysAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
+ pKeyGenOutputData->pData));
+
+ if (outputPhysAddr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the"
+ " output buffer");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ Cpa8U lw26[4];
+ char *tmp = NULL;
+ unsigned char a;
+ int n = 0;
+ /* Make up the full keyGenReq struct from its constituents
+ * before calling the SalQatMsg functions below.
+ * Note: The full cache struct has been reduced to a
+ * header, mid and footer for memory size reduction
+ */
+ pMsgDummy = (Cpa8U *)&(keyGenReq);
+ pCacheDummyHdr = (Cpa8U *)&(keyGenReqHdr);
+ pCacheDummyMid = (Cpa8U *)&(keyGenReqMid);
+ pCacheDummyFtr = (Cpa8U *)&(keyGenReqFtr);
+
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_MID_IN_LW),
+ pCacheDummyMid,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_MID_IN_LW));
+ memcpy(&lw26,
+ pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ LAC_LONG_WORD_IN_BYTES);
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
+ tmp = (char *)(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW));
+
+ /* Copy LW26, or'd with what's already there, into the Msg, for
+ * TLS */
+ for (n = 0; n < LAC_LONG_WORD_IN_BYTES; n++) {
+ a = (unsigned char)*(tmp + n);
+ lw26[n] = lw26[n] | a;
+ }
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ &lw26,
+ LAC_LONG_WORD_IN_BYTES);
+
+ contentDescInfo.pData = pCookie->contentDesc;
+ contentDescInfo.hardwareSetupBlockPhys =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ pSymCookie->keyContentDescPhyAddr);
+ contentDescInfo.hwBlkSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(hashBlkSizeInBytes);
+
+ /* Populate common request fields */
+ SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)&(
+ keyGenReq),
+ &(contentDescInfo));
+
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&keyGenReq,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
+ lacCmdId,
+ cmnRequestFlags,
+ laCmdFlags);
+
+ SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)&(keyGenReq),
+ pCookie,
+ LAC_SYM_KEY_QAT_PTR_TYPE,
+ inputPhysAddr,
+ outputPhysAddr,
+ 0,
+ 0);
+
+ /* Send to QAT */
+ status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
+ (void *)&(keyGenReq),
+ LAC_QAT_SYM_REQ_SZ_LW);
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Update stats */
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_REQUESTS,
+ pCookie->instanceHandle);
+ } else {
+ /* Clean up cookie memory */
+ if (NULL != pCookie) {
+ LacKey_StatsInc(lacCmdId,
+ LAC_KEY_REQUEST_ERRORS,
+ pCookie->instanceHandle);
+ Lac_MemPoolEntryFree(pCookie);
+ }
+ }
+ return status;
+}
+
+/**
+ * @ingroup LacSymKey
+ * Parameters check for TLS v1.0/1.1, v1.2, v1.3 and SSL3
+ * @description
+ * Check user parameters against the firmware/spec requirements.
+ *
+ * @param[in] pKeyGenOpData Pointer to a structure containing all
+ * the data needed to perform the key
+ * generation operation.
+ * @param[in] hashAlgCipher Specifies the hash algorithm,
+ * or cipher we are using.
+ * According to RFC5246, this should be
+ * "SHA-256 or a stronger standard hash
+ * function."
+ * @param[in] pGeneratedKeyBuffer User output buffers.
+ * @param[in] cmdId Keygen operation to perform.
+ */
+static CpaStatus
+LacSymKey_CheckParamSslTls(const void *pKeyGenOpData,
+ Cpa8U hashAlgCipher,
+ const CpaFlatBuffer *pGeneratedKeyBuffer,
+ icp_qat_fw_la_cmd_id_t cmdId)
+{
+ /* Api max value */
+ Cpa32U maxSecretLen = 0;
+ Cpa32U maxSeedLen = 0;
+ Cpa32U maxOutputLen = 0;
+ Cpa32U maxInfoLen = 0;
+ Cpa32U maxLabelLen = 0;
+
+ /* User info */
+ Cpa32U uSecretLen = 0;
+ Cpa32U uSeedLen = 0;
+ Cpa32U uOutputLen = 0;
+
+ LAC_CHECK_NULL_PARAM(pKeyGenOpData);
+ LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer);
+ LAC_CHECK_NULL_PARAM(pGeneratedKeyBuffer->pData);
+
+ if (ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE == cmdId) {
+ CpaCyKeyGenSslOpData *opData =
+ (CpaCyKeyGenSslOpData *)pKeyGenOpData;
+
+ /* User info */
+ uSecretLen = opData->secret.dataLenInBytes;
+ uSeedLen = opData->seed.dataLenInBytes;
+ uOutputLen = opData->generatedKeyLenInBytes;
+
+ /* Api max value */
+ maxSecretLen = ICP_QAT_FW_LA_SSL_SECRET_LEN_MAX;
+ maxSeedLen = ICP_QAT_FW_LA_SSL_SEED_LEN_MAX;
+ maxOutputLen = ICP_QAT_FW_LA_SSL_OUTPUT_LEN_MAX;
+
+ /* Check user buffers */
+ LAC_CHECK_NULL_PARAM(opData->secret.pData);
+ LAC_CHECK_NULL_PARAM(opData->seed.pData);
+
+ /* Check operation */
+ if ((Cpa32U)opData->sslOp > CPA_CY_KEY_SSL_OP_USER_DEFINED) {
+ LAC_INVALID_PARAM_LOG("opData->sslOp");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if ((Cpa32U)opData->sslOp == CPA_CY_KEY_SSL_OP_USER_DEFINED) {
+ LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
+ /* Maximum label length for SSL Key Gen request */
+ if (opData->userLabel.dataLenInBytes >
+ ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX) {
+ LAC_INVALID_PARAM_LOG(
+ "userLabel.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Only seed length for SSL3 Key Gen request */
+ if (maxSeedLen != uSeedLen) {
+ LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Maximum output length for SSL3 Key Gen request */
+ if (uOutputLen > maxOutputLen) {
+ LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ /* TLS v1.1 or TLS v.12 */
+ else if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId ||
+ ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE == cmdId) {
+ CpaCyKeyGenTlsOpData *opData =
+ (CpaCyKeyGenTlsOpData *)pKeyGenOpData;
+
+ /* User info */
+ uSecretLen = opData->secret.dataLenInBytes;
+ uSeedLen = opData->seed.dataLenInBytes;
+ uOutputLen = opData->generatedKeyLenInBytes;
+
+ if (ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE == cmdId) {
+ /* Api max value */
+ /* ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX needs to be
+ * multiplied
+ * by 4 in order to verifiy the 512 conditions. We did
+ * not change
+ * ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX as it
+ * represents
+ * the max value tha firmware can handle.
+ */
+ maxSecretLen =
+ ICP_QAT_FW_LA_TLS_V1_1_SECRET_LEN_MAX * 4;
+ } else {
+ /* Api max value */
+ /* ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX needs to be
+ * multiplied
+ * by 8 in order to verifiy the 512 conditions. We did
+ * not change
+ * ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX as it
+ * represents
+ * the max value tha firmware can handle.
+ */
+ maxSecretLen =
+ ICP_QAT_FW_LA_TLS_V1_2_SECRET_LEN_MAX * 8;
+
+ /* Check Hash algorithm */
+ if (0 == getDigestSizeFromHashAlgo(hashAlgCipher)) {
+ LAC_INVALID_PARAM_LOG("hashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ maxSeedLen = ICP_QAT_FW_LA_TLS_SEED_LEN_MAX;
+ maxOutputLen = ICP_QAT_FW_LA_TLS_OUTPUT_LEN_MAX;
+ /* Check user buffers */
+ LAC_CHECK_NULL_PARAM(opData->secret.pData);
+ LAC_CHECK_NULL_PARAM(opData->seed.pData);
+
+ /* Check operation */
+ if ((Cpa32U)opData->tlsOp > CPA_CY_KEY_TLS_OP_USER_DEFINED) {
+ LAC_INVALID_PARAM_LOG("opData->tlsOp");
+ return CPA_STATUS_INVALID_PARAM;
+ } else if ((Cpa32U)opData->tlsOp ==
+ CPA_CY_KEY_TLS_OP_USER_DEFINED) {
+ LAC_CHECK_NULL_PARAM(opData->userLabel.pData);
+ /* Maximum label length for TLS Key Gen request */
+ if (opData->userLabel.dataLenInBytes >
+ ICP_QAT_FW_LA_TLS_LABEL_LEN_MAX) {
+ LAC_INVALID_PARAM_LOG(
+ "userLabel.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Maximum/only seed length for TLS Key Gen request */
+ if (((Cpa32U)opData->tlsOp !=
+ CPA_CY_KEY_TLS_OP_MASTER_SECRET_DERIVE) &&
+ ((Cpa32U)opData->tlsOp !=
+ CPA_CY_KEY_TLS_OP_KEY_MATERIAL_DERIVE)) {
+ if (uSeedLen > maxSeedLen) {
+ LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ if (maxSeedLen != uSeedLen) {
+ LAC_INVALID_PARAM_LOG("seed.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Maximum output length for TLS Key Gen request */
+ if (uOutputLen > maxOutputLen) {
+ LAC_INVALID_PARAM_LOG("generatedKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ /* TLS v1.3 */
+ else if (cmdId >= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT &&
+ cmdId <= ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL) {
+ CpaCyKeyGenHKDFOpData *HKDF_Data =
+ (CpaCyKeyGenHKDFOpData *)pKeyGenOpData;
+ CpaCyKeyHKDFCipherSuite cipherSuite = hashAlgCipher;
+ CpaCySymHashAlgorithm hashAlgorithm =
+ getHashAlgorithmFromCipherSuiteHKDF(cipherSuite);
+ maxSeedLen =
+ cipherSuiteHKDFHashSizes[cipherSuite][LAC_KEY_HKDF_DIGESTS];
+ maxSecretLen = CPA_CY_HKDF_KEY_MAX_SECRET_SZ;
+ maxInfoLen = CPA_CY_HKDF_KEY_MAX_INFO_SZ;
+ maxLabelLen = CPA_CY_HKDF_KEY_MAX_LABEL_SZ;
+
+ uSecretLen = HKDF_Data->secretLen;
+
+ /* Check using supported hash function */
+ if (0 ==
+ (uOutputLen = getDigestSizeFromHashAlgo(hashAlgorithm))) {
+ LAC_INVALID_PARAM_LOG("Hash function not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Number of labels does not exceed the MAX */
+ if (HKDF_Data->numLabels > CPA_CY_HKDF_KEY_MAX_LABEL_COUNT) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.numLabels");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ switch (cmdId) {
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT:
+ if (maxSeedLen < HKDF_Data->seedLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.seedLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND:
+ maxSecretLen =
+ cipherSuiteHKDFHashSizes[cipherSuite]
+ [LAC_KEY_HKDF_DIGESTS];
+
+ if (maxInfoLen < HKDF_Data->infoLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.infoLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND:
+ uOutputLen *= 2;
+ if (maxSeedLen < HKDF_Data->seedLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.seedLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (maxInfoLen < HKDF_Data->infoLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.infoLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL: /* Fall through */
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL: {
+ Cpa8U subl_mask = 0, subl_number = 1;
+ Cpa8U i = 0;
+
+ if (maxSeedLen < HKDF_Data->seedLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CpaCyKeyGenHKDFOpData.seedLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* If EXPAND set uOutputLen to zero */
+ if (ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL == cmdId) {
+ uOutputLen = 0;
+ maxSecretLen = cipherSuiteHKDFHashSizes
+ [cipherSuite][LAC_KEY_HKDF_DIGESTS];
+ }
+
+ for (i = 0; i < HKDF_Data->numLabels; i++) {
+ /* Check that the labelLen does not overflow */
+ if (maxLabelLen <
+ HKDF_Data->label[i].labelLen) {
+ LAC_INVALID_PARAM_LOG1(
+ "CpaCyKeyGenHKDFOpData.label[%d].labelLen",
+ i);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (HKDF_Data->label[i].sublabelFlag &
+ ~HKDF_SUB_LABELS_ALL) {
+ LAC_INVALID_PARAM_LOG1(
+ "CpaCyKeyGenHKDFOpData.label[%d]."
+ "subLabelFlag",
+ i);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Calculate the appended subLabel output
+ * lengths and
+ * check that the output buffer that the user
+ * has
+ * supplied is the correct length.
+ */
+ uOutputLen += cipherSuiteHKDFHashSizes
+ [cipherSuite][LAC_KEY_HKDF_DIGESTS];
+ /* Get mask of subLabel */
+ subl_mask = HKDF_Data->label[i].sublabelFlag;
+
+ for (subl_number = 1;
+ subl_number <= LAC_KEY_HKDF_SUBLABELS_NUM;
+ subl_number++) {
+ /* Add the used subLabel key lengths */
+ if (subl_mask & 1) {
+ uOutputLen +=
+ cipherSuiteHKDFHashSizes
+ [cipherSuite]
+ [subl_number];
+ }
+ subl_mask >>= 1;
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+ } else {
+ LAC_INVALID_PARAM_LOG("TLS/SSL operation");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Maximum secret length for TLS/SSL Key Gen request */
+ if (uSecretLen > maxSecretLen) {
+ LAC_INVALID_PARAM_LOG("HKFD.secretLen/secret.dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Check for enough space in the flat buffer */
+ if (uOutputLen > pGeneratedKeyBuffer->dataLenInBytes) {
+ LAC_INVALID_PARAM_LOG("pGeneratedKeyBuffer->dataLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *
+ */
+/**
+ * @ingroup LacSymKey
+ * Common Keygen Code for TLS v1.0/1.1, v1.2 and SSL3.
+ * @description
+ * Check user parameters and perform the required operation.
+ *
+ * @param[in] instanceHandle_in Instance handle.
+ * @param[in] pKeyGenCb 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] pKeyGenOpData Pointer to a structure containing all
+ * the data needed to perform the key
+ * generation operation.
+ * @param[in] hashAlgorithm Specifies the hash algorithm to use.
+ * According to RFC5246, this should be
+ * "SHA-256 or a stronger standard hash
+ * function."
+ * @param[out] pGeneratedKeyBuffer User output buffer.
+ * @param[in] cmdId Keygen operation to perform.
+ */
+static CpaStatus
+LacSymKey_KeyGenSslTls(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const void *pKeyGenOpData,
+ Cpa8U hashAlgorithm,
+ CpaFlatBuffer *pGeneratedKeyBuffer,
+ icp_qat_fw_la_cmd_id_t cmdId)
+{
+ 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,
+ pGeneratedKeyBuffer,
+ cmdId);
+ if (CPA_STATUS_SUCCESS != status)
+ return status;
+ return LacSymKey_KeyGenSslTls_GenCommon(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ cmdId,
+ LAC_CONST_PTR_CAST(
+ pKeyGenOpData),
+ hashAlgorithm,
+ pGeneratedKeyBuffer);
+}
+
+/**
+ * @ingroup LacSymKey
+ * SSL Key Generation Function.
+ * @description
+ * This function is used for SSL key generation. It implements the key
+ * generation function defined in section 6.2.2 of the SSL 3.0
+ * specification as described in
+ * http://www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt.
+ *
+ * The input seed is taken as a flat buffer and the generated key is
+ * returned to caller in a flat destination data buffer.
+ *
+ * @param[in] instanceHandle_in Instance handle.
+ * @param[in] pKeyGenCb 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] pKeyGenSslOpData Pointer to a structure containing all
+ * the data needed to perform the SSL key
+ * generation 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] pGeneratedKeyBuffer Caller MUST allocate a sufficient
+ * buffer to hold the key generation
+ * output. The data pointer SHOULD be
+ * aligned on an 8-byte boundary. The
+ * length field passed in represents the
+ * size of the buffer in bytes. The value
+ * that is returned is the size of the
+ * result key in bytes.
+ * On invocation the callback function
+ * will contain this parameter in the
+ * pOut parameter.
+ *
+ * @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.
+ */
+CpaStatus
+cpaCyKeyGenSsl(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenSslOpData *pKeyGenSslOpData,
+ CpaFlatBuffer *pGeneratedKeyBuffer)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ return LacSymKey_KeyGenSslTls(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ LAC_CONST_PTR_CAST(pKeyGenSslOpData),
+ CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
+ pGeneratedKeyBuffer,
+ ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE);
+}
+
+/**
+ * @ingroup LacSymKey
+ * TLS Key Generation Function.
+ * @description
+ * This function is used for TLS key generation. It implements the
+ * TLS PRF (Pseudo Random Function) as defined by RFC2246 (TLS v1.0)
+ * and RFC4346 (TLS v1.1).
+ *
+ * The input seed is taken as a flat buffer and the generated key is
+ * returned to caller in a flat destination data buffer.
+ *
+ * @param[in] instanceHandle_in Instance handle.
+ * @param[in] pKeyGenCb 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] pKeyGenTlsOpData Pointer to a structure containing all
+ * the data needed to perform the TLS key
+ * generation 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] pGeneratedKeyBuffer Caller MUST allocate a sufficient
+ * buffer to hold the key generation
+ * output. The data pointer SHOULD be
+ * aligned on an 8-byte boundary. The
+ * length field passed in represents the
+ * size of the buffer in bytes. The value
+ * that is returned is the size of the
+ * result key in bytes.
+ * On invocation the callback function
+ * will contain this parameter in the
+ * pOut parameter.
+ *
+ * @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.
+ *
+ */
+CpaStatus
+cpaCyKeyGenTls(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
+ CpaFlatBuffer *pGeneratedKeyBuffer)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ return LacSymKey_KeyGenSslTls(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
+ CPA_CY_SYM_HASH_NONE, /* Hash algorithm */
+ pGeneratedKeyBuffer,
+ ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE);
+}
+
+/**
+ * @ingroup LacSymKey
+ * @description
+ * This function is used for TLS key generation. It implements the
+ * TLS PRF (Pseudo Random Function) as defined by RFC5246 (TLS v1.2).
+ *
+ * The input seed is taken as a flat buffer and the generated key is
+ * returned to caller in a flat destination data buffer.
+ *
+ * @param[in] instanceHandle_in Instance handle.
+ * @param[in] pKeyGenCb 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] pKeyGenTlsOpData Pointer to a structure containing all
+ * the data needed to perform the TLS key
+ * generation 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[in] hashAlgorithm Specifies the hash algorithm to use.
+ * According to RFC5246, this should be
+ * "SHA-256 or a stronger standard hash
+ * function."
+ * @param[out] pGeneratedKeyBuffer Caller MUST allocate a sufficient
+ * buffer to hold the key generation
+ * output. The data pointer SHOULD be
+ * aligned on an 8-byte boundary. The
+ * length field passed in represents the
+ * size of the buffer in bytes. The value
+ * that is returned is the size of the
+ * result key in bytes.
+ * On invocation the callback function
+ * will contain this parameter in the
+ * pOut parameter.
+ *
+ * @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.
+ */
+CpaStatus
+cpaCyKeyGenTls2(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenTlsOpData *pKeyGenTlsOpData,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ CpaFlatBuffer *pGeneratedKeyBuffer)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ return LacSymKey_KeyGenSslTls(instanceHandle,
+ pKeyGenCb,
+ pCallbackTag,
+ LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
+ hashAlgorithm,
+ pGeneratedKeyBuffer,
+ ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE);
+}
+
+/**
+ * @ingroup LacSymKey
+ * @description
+ * This function is used for TLS1.3 HKDF key generation. It implements
+ * the "extract-then-expand" paradigm as defined by RFC 5869.
+ *
+ * The input seed/secret/info is taken as a flat buffer and the generated
+ * key(s)/labels are returned to caller in a flat data buffer.
+ *
+ * @param[in] instanceHandle_in Instance handle.
+ * @param[in] pKeyGenCb 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] pKeyGenTlsOpData Pointer to a structure containing
+ * the data needed to perform the HKDF key
+ * generation operation.
+ * The client code allocates the memory
+ * for this structure as contiguous
+ * pinned memory.
+ * This component takes ownership of the
+ * memory until it is returned in the
+ * callback.
+ * @param[in] hashAlgorithm Specifies the hash algorithm to use.
+ * According to RFC5246, this should be
+ * "SHA-256 or a stronger standard hash
+ * function."
+ * @param[out] pGeneratedKeyBuffer Caller MUST allocate a sufficient
+ * buffer to hold the key generation
+ * output. The data pointer SHOULD be
+ * aligned on an 8-byte boundary. The
+ * length field passed in represents the
+ * size of the buffer in bytes. The value
+ * that is returned is the size of the
+ * result key in bytes.
+ * On invocation the callback function
+ * will contain this parameter in the
+ * pOut parameter.
+ *
+ * @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.
+ */
+CpaStatus
+cpaCyKeyGenTls3(const CpaInstanceHandle instanceHandle_in,
+ const CpaCyGenFlatBufCbFunc pKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData,
+ CpaCyKeyHKDFCipherSuite cipherSuite,
+ CpaFlatBuffer *pGeneratedKeyBuffer)
+{
+
+ LAC_CHECK_NULL_PARAM(pKeyGenTlsOpData);
+ switch (pKeyGenTlsOpData->hkdfKeyOp) {
+ case CPA_CY_HKDF_KEY_EXTRACT: /* Fall through */
+ case CPA_CY_HKDF_KEY_EXPAND:
+ case CPA_CY_HKDF_KEY_EXTRACT_EXPAND:
+ case CPA_CY_HKDF_KEY_EXPAND_LABEL:
+ case CPA_CY_HKDF_KEY_EXTRACT_EXPAND_LABEL:
+ break;
+ default:
+ LAC_INVALID_PARAM_LOG("HKDF operation not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+
+ return LacSymKey_KeyGenSslTls(instanceHandle_in,
+ pKeyGenCb,
+ pCallbackTag,
+ LAC_CONST_PTR_CAST(pKeyGenTlsOpData),
+ cipherSuite,
+ pGeneratedKeyBuffer,
+ (icp_qat_fw_la_cmd_id_t)
+ pKeyGenTlsOpData->hkdfKeyOp);
+}
+
+/*
+ * LacSymKey_Init
+ */
+CpaStatus
+LacSymKey_Init(CpaInstanceHandle instanceHandle_in)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
+ sal_crypto_service_t *pService = NULL;
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+
+ pService = (sal_crypto_service_t *)instanceHandle;
+
+ pService->pLacKeyStats =
+ LAC_OS_MALLOC(LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
+
+ if (NULL != pService->pLacKeyStats) {
+ LAC_OS_BZERO((void *)pService->pLacKeyStats,
+ LAC_KEY_NUM_STATS * sizeof(QatUtilsAtomic));
+
+ status = LAC_OS_CAMALLOC(&pService->pSslLabel,
+ ICP_QAT_FW_LA_SSL_LABEL_LEN_MAX,
+ LAC_8BYTE_ALIGNMENT,
+ pService->nodeAffinity);
+ } else {
+ status = CPA_STATUS_RESOURCE;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ Cpa32U i = 0;
+ Cpa32U offset = 0;
+
+ /* Initialise SSL label ABBCCC..... */
+ for (i = 0; i < ICP_QAT_FW_LA_SSL_ITERATES_LEN_MAX; i++) {
+ memset(pService->pSslLabel + offset, 'A' + i, i + 1);
+ offset += (i + 1);
+ }
+
+ /* Allocate memory for TLS labels */
+ status = LAC_OS_CAMALLOC(&pService->pTlsLabel,
+ sizeof(lac_sym_key_tls_labels_t),
+ LAC_8BYTE_ALIGNMENT,
+ pService->nodeAffinity);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Allocate memory for HKDF sub_labels */
+ status =
+ LAC_OS_CAMALLOC(&pService->pTlsHKDFSubLabel,
+ sizeof(lac_sym_key_tls_hkdf_sub_labels_t),
+ LAC_8BYTE_ALIGNMENT,
+ pService->nodeAffinity);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ LAC_OS_BZERO(pService->pTlsLabel,
+ sizeof(lac_sym_key_tls_labels_t));
+
+ /* Copy the TLS v1.2 labels into the dynamically allocated
+ * structure */
+ memcpy(pService->pTlsLabel->masterSecret,
+ LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL,
+ sizeof(LAC_SYM_KEY_TLS_MASTER_SECRET_LABEL) - 1);
+
+ memcpy(pService->pTlsLabel->keyMaterial,
+ LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL,
+ sizeof(LAC_SYM_KEY_TLS_KEY_MATERIAL_LABEL) - 1);
+
+ memcpy(pService->pTlsLabel->clientFinished,
+ LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL,
+ sizeof(LAC_SYM_KEY_TLS_CLIENT_FIN_LABEL) - 1);
+
+ memcpy(pService->pTlsLabel->serverFinished,
+ LAC_SYM_KEY_TLS_SERVER_FIN_LABEL,
+ sizeof(LAC_SYM_KEY_TLS_SERVER_FIN_LABEL) - 1);
+
+ LAC_OS_BZERO(pService->pTlsHKDFSubLabel,
+ sizeof(lac_sym_key_tls_hkdf_sub_labels_t));
+
+ /* Copy the TLS v1.3 subLabels into the dynamically allocated
+ * struct */
+ /* KEY SHA-256 */
+ memcpy(&pService->pTlsHKDFSubLabel->keySublabel256,
+ &key256,
+ HKDF_SUB_LABEL_KEY_LENGTH);
+ pService->pTlsHKDFSubLabel->keySublabel256.labelLen =
+ HKDF_SUB_LABEL_KEY_LENGTH;
+ pService->pTlsHKDFSubLabel->keySublabel256.sublabelFlag = 1
+ << QAT_FW_HKDF_INNER_SUBLABEL_16_BYTE_OKM_BITPOS;
+ /* KEY SHA-384 */
+ memcpy(&pService->pTlsHKDFSubLabel->keySublabel384,
+ &key384,
+ HKDF_SUB_LABEL_KEY_LENGTH);
+ pService->pTlsHKDFSubLabel->keySublabel384.labelLen =
+ HKDF_SUB_LABEL_KEY_LENGTH;
+ pService->pTlsHKDFSubLabel->keySublabel384.sublabelFlag = 1
+ << QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
+ /* KEY CHACHAPOLY */
+ memcpy(&pService->pTlsHKDFSubLabel->keySublabelChaChaPoly,
+ &keyChaChaPoly,
+ HKDF_SUB_LABEL_KEY_LENGTH);
+ pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.labelLen =
+ HKDF_SUB_LABEL_KEY_LENGTH;
+ pService->pTlsHKDFSubLabel->keySublabelChaChaPoly.sublabelFlag =
+ 1 << QAT_FW_HKDF_INNER_SUBLABEL_32_BYTE_OKM_BITPOS;
+ /* IV SHA-256 */
+ memcpy(&pService->pTlsHKDFSubLabel->ivSublabel256,
+ &iv256,
+ HKDF_SUB_LABEL_IV_LENGTH);
+ pService->pTlsHKDFSubLabel->ivSublabel256.labelLen =
+ HKDF_SUB_LABEL_IV_LENGTH;
+ pService->pTlsHKDFSubLabel->ivSublabel256.sublabelFlag = 1
+ << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
+ /* IV SHA-384 */
+ memcpy(&pService->pTlsHKDFSubLabel->ivSublabel384,
+ &iv384,
+ HKDF_SUB_LABEL_IV_LENGTH);
+ pService->pTlsHKDFSubLabel->ivSublabel384.labelLen =
+ HKDF_SUB_LABEL_IV_LENGTH;
+ pService->pTlsHKDFSubLabel->ivSublabel384.sublabelFlag = 1
+ << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
+ /* IV CHACHAPOLY */
+ memcpy(&pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly,
+ &iv256,
+ HKDF_SUB_LABEL_IV_LENGTH);
+ pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.labelLen =
+ HKDF_SUB_LABEL_IV_LENGTH;
+ pService->pTlsHKDFSubLabel->ivSublabelChaChaPoly.sublabelFlag =
+ 1 << QAT_FW_HKDF_INNER_SUBLABEL_12_BYTE_OKM_BITPOS;
+ /* RESUMPTION SHA-256 */
+ memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel256,
+ &resumption256,
+ HKDF_SUB_LABEL_RESUMPTION_LENGTH);
+ pService->pTlsHKDFSubLabel->resumptionSublabel256.labelLen =
+ HKDF_SUB_LABEL_RESUMPTION_LENGTH;
+ /* RESUMPTION SHA-384 */
+ memcpy(&pService->pTlsHKDFSubLabel->resumptionSublabel384,
+ &resumption384,
+ HKDF_SUB_LABEL_RESUMPTION_LENGTH);
+ pService->pTlsHKDFSubLabel->resumptionSublabel384.labelLen =
+ HKDF_SUB_LABEL_RESUMPTION_LENGTH;
+ /* RESUMPTION CHACHAPOLY */
+ memcpy(
+ &pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly,
+ &resumption256,
+ HKDF_SUB_LABEL_RESUMPTION_LENGTH);
+ pService->pTlsHKDFSubLabel->resumptionSublabelChaChaPoly
+ .labelLen = HKDF_SUB_LABEL_RESUMPTION_LENGTH;
+ /* FINISHED SHA-256 */
+ memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel256,
+ &finished256,
+ HKDF_SUB_LABEL_FINISHED_LENGTH);
+ pService->pTlsHKDFSubLabel->finishedSublabel256.labelLen =
+ HKDF_SUB_LABEL_FINISHED_LENGTH;
+ /* FINISHED SHA-384 */
+ memcpy(&pService->pTlsHKDFSubLabel->finishedSublabel384,
+ &finished384,
+ HKDF_SUB_LABEL_FINISHED_LENGTH);
+ pService->pTlsHKDFSubLabel->finishedSublabel384.labelLen =
+ HKDF_SUB_LABEL_FINISHED_LENGTH;
+ /* FINISHED CHACHAPOLY */
+ memcpy(&pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly,
+ &finished256,
+ HKDF_SUB_LABEL_FINISHED_LENGTH);
+ pService->pTlsHKDFSubLabel->finishedSublabelChaChaPoly
+ .labelLen = HKDF_SUB_LABEL_FINISHED_LENGTH;
+
+ /* Set physical address of sublabels */
+ pService->pTlsHKDFSubLabel->sublabelPhysAddr256 =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ &pService->pTlsHKDFSubLabel->keySublabel256);
+ pService->pTlsHKDFSubLabel->sublabelPhysAddr384 =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ &pService->pTlsHKDFSubLabel->keySublabel384);
+ pService->pTlsHKDFSubLabel->sublabelPhysAddrChaChaPoly =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ &pService->pTlsHKDFSubLabel->keySublabelChaChaPoly);
+
+ /* Register request handlers */
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(
+ ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(
+ ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXTRACT,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HKDF_EXPAND,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(
+ ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(
+ ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(
+ ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL,
+ LacSymKey_SslTlsHandleResponse);
+
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_MGF1,
+ LacSymKey_MgfHandleResponse);
+ }
+
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_OS_FREE(pService->pLacKeyStats);
+ LAC_OS_CAFREE(pService->pSslLabel);
+ LAC_OS_CAFREE(pService->pTlsLabel);
+ LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
+ }
+
+ return status;
+}
+
+/*
+ * LacSymKey_Shutdown
+ */
+CpaStatus
+LacSymKey_Shutdown(CpaInstanceHandle instanceHandle_in)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle instanceHandle = LacKey_GetHandle(instanceHandle_in);
+ sal_crypto_service_t *pService = NULL;
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+
+ pService = (sal_crypto_service_t *)instanceHandle;
+
+ if (NULL != pService->pLacKeyStats) {
+ LAC_OS_FREE(pService->pLacKeyStats);
+ }
+
+ LAC_OS_CAFREE(pService->pSslLabel);
+ LAC_OS_CAFREE(pService->pTlsLabel);
+ LAC_OS_CAFREE(pService->pTlsHKDFSubLabel);
+
+ return status;
+}
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
new file mode 100644
index 000000000000..c2d30c77eeab
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_alg_chain.c
@@ -0,0 +1,1860 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ ***************************************************************************
+ * @file lac_sym_alg_chain.c Algorithm Chaining Perform
+ *
+ * @ingroup LacAlgChain
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "lac_mem.h"
+#include "lac_log.h"
+#include "lac_sym.h"
+#include "lac_list.h"
+#include "icp_qat_fw_la.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "lac_sym_alg_chain.h"
+#include "lac_sym_cipher.h"
+#include "lac_sym_cipher_defs.h"
+#include "lac_sym_hash.h"
+#include "lac_sym_hash_defs.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_sym_qat_hash.h"
+#include "lac_sym_stats.h"
+#include "lac_sym_queue.h"
+#include "lac_sym_cb.h"
+#include "sal_string_parse.h"
+#include "lac_sym_auth_enc.h"
+#include "lac_sym_qat.h"
+
+/**
+ * @ingroup LacAlgChain
+ * Function which checks for support of partial packets for symmetric
+ * crypto operations
+ *
+ * @param[in] pService Pointer to service descriptor
+ * @param[in/out] pSessionDesc Pointer to session descriptor
+ *
+ */
+static void
+LacSymCheck_IsPartialSupported(Cpa32U capabilitiesMask,
+ lac_session_desc_t *pSessionDesc)
+{
+ CpaBoolean isHashPartialSupported = CPA_FALSE;
+ CpaBoolean isCipherPartialSupported = CPA_FALSE;
+ CpaBoolean isPartialSupported = CPA_FALSE;
+
+ switch (pSessionDesc->cipherAlgorithm) {
+ /* Following ciphers don't support partial */
+ case CPA_CY_SYM_CIPHER_KASUMI_F8:
+ case CPA_CY_SYM_CIPHER_AES_F8:
+ case CPA_CY_SYM_CIPHER_SNOW3G_UEA2:
+ case CPA_CY_SYM_CIPHER_CHACHA:
+ case CPA_CY_SYM_CIPHER_ZUC_EEA3:
+ break;
+ /* All others support partial */
+ default:
+ isCipherPartialSupported = CPA_TRUE;
+ }
+ switch (pSessionDesc->hashAlgorithm) {
+ /* Following hash don't support partial */
+ case CPA_CY_SYM_HASH_KASUMI_F9:
+ case CPA_CY_SYM_HASH_SNOW3G_UIA2:
+ case CPA_CY_SYM_HASH_POLY:
+ case CPA_CY_SYM_HASH_ZUC_EIA3:
+ case CPA_CY_SYM_HASH_SHAKE_128:
+ case CPA_CY_SYM_HASH_SHAKE_256:
+ break;
+ /* Following hash may support partial based on device capabilities */
+ case CPA_CY_SYM_HASH_SHA3_256:
+ if (ICP_ACCEL_CAPABILITIES_SHA3_EXT & capabilitiesMask) {
+ isHashPartialSupported = CPA_TRUE;
+ }
+ break;
+ /* All others support partial */
+ default:
+ isHashPartialSupported = CPA_TRUE;
+ }
+ switch (pSessionDesc->symOperation) {
+ case CPA_CY_SYM_OP_CIPHER:
+ isPartialSupported = isCipherPartialSupported;
+ break;
+ case CPA_CY_SYM_OP_HASH:
+ isPartialSupported = isHashPartialSupported;
+ break;
+ case CPA_CY_SYM_OP_ALGORITHM_CHAINING:
+ if (isCipherPartialSupported && isHashPartialSupported) {
+ isPartialSupported = CPA_TRUE;
+ }
+ break;
+ case CPA_CY_SYM_OP_NONE:
+ break;
+ }
+ pSessionDesc->isPartialSupported = isPartialSupported;
+}
+
+/**
+ * @ingroup LacAlgChain
+ * This callback function will be invoked whenever a hash precompute
+ * operation completes. It will dequeue and send any QAT requests
+ * which were queued up while the precompute was in progress.
+ *
+ * @param[in] callbackTag Opaque value provided by user. This will
+ * be a pointer to the session descriptor.
+ *
+ * @retval
+ * None
+ *
+ */
+static void
+LacSymAlgChain_HashPrecomputeDoneCb(void *callbackTag)
+{
+ LacSymCb_PendingReqsDequeue((lac_session_desc_t *)callbackTag);
+}
+
+/**
+ * @ingroup LacAlgChain
+ * Walk the buffer list and find the address for the given offset within
+ * a buffer.
+ *
+ * @param[in] pBufferList Buffer List
+ * @param[in] packetOffset Offset in the buffer list for which address
+ * is to be found.
+ * @param[out] ppDataPtr This is where the sought pointer will be put
+ * @param[out] pSpaceLeft Pointer to a variable in which information about
+ * available space from the given offset to the end
+ * of the flat buffer it is located in will be returned
+ *
+ * @retval CPA_STATUS_SUCCESS Address with a given offset is found in the list
+ * @retval CPA_STATUS_FAIL Address with a given offset not found in the list.
+ *
+ */
+static CpaStatus
+LacSymAlgChain_PtrFromOffsetGet(const CpaBufferList *pBufferList,
+ const Cpa32U packetOffset,
+ Cpa8U **ppDataPtr)
+{
+ Cpa32U currentOffset = 0;
+ Cpa32U i = 0;
+
+ for (i = 0; i < pBufferList->numBuffers; i++) {
+ Cpa8U *pCurrData = pBufferList->pBuffers[i].pData;
+ Cpa32U currDataSize = pBufferList->pBuffers[i].dataLenInBytes;
+
+ /* If the offset is within the address space of the current
+ * buffer */
+ if ((packetOffset >= currentOffset) &&
+ (packetOffset < (currentOffset + currDataSize))) {
+ /* increment by offset of the address in the current
+ * buffer */
+ *ppDataPtr = pCurrData + (packetOffset - currentOffset);
+ return CPA_STATUS_SUCCESS;
+ }
+
+ /* Increment by the size of the buffer */
+ currentOffset += currDataSize;
+ }
+
+ return CPA_STATUS_FAIL;
+}
+
+static void
+LacAlgChain_CipherCDBuild(const CpaCySymCipherSetupData *pCipherData,
+ lac_session_desc_t *pSessionDesc,
+ icp_qat_fw_slice_t nextSlice,
+ Cpa8U cipherOffsetInConstantsTable,
+ icp_qat_fw_comn_flags *pCmnRequestFlags,
+ icp_qat_fw_serv_specif_flags *pLaCmdFlags,
+ Cpa8U *pHwBlockBaseInDRAM,
+ Cpa32U *pHwBlockOffsetInDRAM)
+{
+ Cpa8U *pCipherKeyField = NULL;
+ Cpa8U cipherOffsetInReqQW = 0;
+ Cpa32U sizeInBytes = 0;
+
+ /* Construct the ContentDescriptor in DRAM */
+ cipherOffsetInReqQW = (*pHwBlockOffsetInDRAM / LAC_QUAD_WORD_IN_BYTES);
+ ICP_QAT_FW_LA_CIPH_AUTH_CFG_OFFSET_FLAG_SET(
+ *pLaCmdFlags, ICP_QAT_FW_CIPH_AUTH_CFG_OFFSET_IN_CD_SETUP);
+
+ /* construct cipherConfig in CD in DRAM */
+ LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
+ pHwBlockBaseInDRAM +
+ *pHwBlockOffsetInDRAM,
+ &sizeInBytes);
+
+ *pHwBlockOffsetInDRAM += sizeInBytes;
+
+ /* Cipher key will be in CD in DRAM.
+ * The Request contains a ptr to the CD.
+ * This ptr will be copied into the request later once the CD is
+ * fully constructed, but the flag is set here. */
+ pCipherKeyField = pHwBlockBaseInDRAM + *pHwBlockOffsetInDRAM;
+ ICP_QAT_FW_COMN_CD_FLD_TYPE_SET(*pCmnRequestFlags,
+ QAT_COMN_CD_FLD_TYPE_64BIT_ADR);
+
+ LacSymQat_CipherHwBlockPopulateKeySetup(
+ pCipherData,
+ pCipherData->cipherKeyLenInBytes,
+ pCipherKeyField,
+ &sizeInBytes);
+ /* update offset */
+ *pHwBlockOffsetInDRAM += sizeInBytes;
+
+ LacSymQat_CipherCtrlBlockWrite(&(pSessionDesc->reqCacheFtr),
+ pSessionDesc->cipherAlgorithm,
+ pSessionDesc->cipherKeyLenInBytes,
+ nextSlice,
+ cipherOffsetInReqQW);
+ if (LAC_CIPHER_IS_GCM(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_CHACHA(pSessionDesc->cipherAlgorithm)) {
+ LacSymQat_CipherCtrlBlockWrite(
+ &(pSessionDesc->reqSpcCacheFtr),
+ pSessionDesc->cipherAlgorithm,
+ pSessionDesc->cipherKeyLenInBytes,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ cipherOffsetInReqQW);
+ }
+}
+
+static void
+LacAlgChain_HashCDBuild(
+ const CpaCySymHashSetupData *pHashData,
+ CpaInstanceHandle instanceHandle,
+ lac_session_desc_t *pSessionDesc,
+ icp_qat_fw_slice_t nextSlice,
+ Cpa8U hashOffsetInConstantsTable,
+ icp_qat_fw_comn_flags *pCmnRequestFlags,
+ icp_qat_fw_serv_specif_flags *pLaCmdFlags,
+ lac_sym_qat_hash_precompute_info_t *pPrecomputeData,
+ lac_sym_qat_hash_precompute_info_t *pPrecomputeDataOptimisedCd,
+ Cpa8U *pHwBlockBaseInDRAM,
+ Cpa32U *pHwBlockOffsetInDRAM,
+ Cpa8U *pOptimisedHwBlockBaseInDRAM,
+ Cpa32U *pOptimisedHwBlockOffsetInDRAM)
+{
+ Cpa32U sizeInBytes = 0;
+ Cpa32U hwBlockOffsetInQuadWords =
+ *pHwBlockOffsetInDRAM / LAC_QUAD_WORD_IN_BYTES;
+
+ /* build:
+ * - the hash part of the ContentDescriptor in DRAM */
+ /* - the hash part of the CD control block in the Request template */
+ LacSymQat_HashContentDescInit(&(pSessionDesc->reqCacheFtr),
+ instanceHandle,
+ pHashData,
+ pHwBlockBaseInDRAM,
+ hwBlockOffsetInQuadWords,
+ nextSlice,
+ pSessionDesc->qatHashMode,
+ CPA_FALSE,
+ CPA_FALSE,
+ pPrecomputeData,
+ &sizeInBytes);
+
+ /* Using DRAM CD so update offset */
+ *pHwBlockOffsetInDRAM += sizeInBytes;
+
+ sizeInBytes = 0;
+}
+
+CpaStatus
+LacAlgChain_SessionAADUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa32U newAADLength)
+{
+ icp_qat_la_bulk_req_ftr_t *req_ftr = &pSessionDesc->reqCacheFtr;
+ icp_qat_la_auth_req_params_t *req_params = &req_ftr->serv_specif_rqpars;
+
+ if (!pSessionDesc)
+ return CPA_STATUS_FAIL;
+
+ pSessionDesc->aadLenInBytes = newAADLength;
+ req_params->u2.aad_sz =
+ LAC_ALIGN_POW2_ROUNDUP(newAADLength, LAC_HASH_AES_GCM_BLOCK_SIZE);
+
+ if (CPA_TRUE == pSessionDesc->isSinglePass) {
+ Cpa8U *pHwBlockBaseInDRAM = NULL;
+ Cpa32U hwBlockOffsetInDRAM = 0;
+ Cpa32U pSizeInBytes = 0;
+ CpaCySymCipherAlgorithm cipher = pSessionDesc->cipherAlgorithm;
+
+ pHwBlockBaseInDRAM =
+ (Cpa8U *)pSessionDesc->contentDescInfo.pData;
+ if (pSessionDesc->cipherDirection ==
+ CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT) {
+ if (LAC_CIPHER_IS_GCM(cipher)) {
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC);
+ } else {
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC);
+ }
+ }
+ LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
+ pHwBlockBaseInDRAM +
+ hwBlockOffsetInDRAM,
+ &pSizeInBytes);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+LacAlgChain_SessionCipherKeyUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pCipherKey)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ if (pSessionDesc == NULL || pCipherKey == NULL)
+ return CPA_STATUS_FAIL;
+
+ if (LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm)) {
+ LacSymQat_CipherArc4StateInit(
+ pCipherKey,
+ pSessionDesc->cipherKeyLenInBytes,
+ pSessionDesc->cipherARC4InitialState);
+ } else {
+ CpaCySymCipherSetupData cipherSetupData = { 0 };
+ Cpa32U sizeInBytes;
+ Cpa8U *pCipherKeyField;
+ sal_qat_content_desc_info_t *pCdInfo =
+ &(pSessionDesc->contentDescInfo);
+
+ cipherSetupData.cipherAlgorithm = pSessionDesc->cipherAlgorithm;
+ cipherSetupData.cipherKeyLenInBytes =
+ pSessionDesc->cipherKeyLenInBytes;
+ cipherSetupData.pCipherKey = pCipherKey;
+
+ switch (pSessionDesc->symOperation) {
+ case CPA_CY_SYM_OP_CIPHER: {
+ pCipherKeyField = (Cpa8U *)pCdInfo->pData +
+ sizeof(icp_qat_hw_cipher_config_t);
+
+ LacSymQat_CipherHwBlockPopulateKeySetup(
+ &(cipherSetupData),
+ cipherSetupData.cipherKeyLenInBytes,
+ pCipherKeyField,
+ &sizeInBytes);
+
+ if (pSessionDesc->useSymConstantsTable) {
+ pCipherKeyField = (Cpa8U *)&(
+ pSessionDesc->shramReqCacheHdr.cd_pars.s1
+ .serv_specif_fields);
+
+ LacSymQat_CipherHwBlockPopulateKeySetup(
+ &(cipherSetupData),
+ cipherSetupData.cipherKeyLenInBytes,
+ pCipherKeyField,
+ &sizeInBytes);
+ }
+ } break;
+
+ case CPA_CY_SYM_OP_ALGORITHM_CHAINING: {
+ icp_qat_fw_cipher_auth_cd_ctrl_hdr_t *cd_ctrl =
+ (icp_qat_fw_cipher_auth_cd_ctrl_hdr_t
+ *)&pSessionDesc->reqCacheFtr.cd_ctrl;
+
+ pCipherKeyField = (Cpa8U *)pCdInfo->pData +
+ cd_ctrl->cipher_cfg_offset *
+ LAC_QUAD_WORD_IN_BYTES +
+ sizeof(icp_qat_hw_cipher_config_t);
+
+ LacSymQat_CipherHwBlockPopulateKeySetup(
+ &(cipherSetupData),
+ cipherSetupData.cipherKeyLenInBytes,
+ pCipherKeyField,
+ &sizeInBytes);
+ } break;
+
+ default:
+ LAC_LOG_ERROR("Invalid sym operation\n");
+ status = CPA_STATUS_INVALID_PARAM;
+ break;
+ }
+ }
+ return status;
+}
+
+CpaStatus
+LacAlgChain_SessionAuthKeyUpdate(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAuthKey)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa8U *pHwBlockBaseInDRAM = NULL;
+ Cpa8U *pOutHashSetup = NULL;
+ Cpa8U *pInnerState1 = NULL;
+ Cpa8U *pInnerState2 = NULL;
+ CpaCySymSessionSetupData sessionSetup = { 0 };
+
+ if (pSessionDesc == NULL || pAuthKey == NULL)
+ return CPA_STATUS_FAIL;
+
+ icp_qat_fw_cipher_auth_cd_ctrl_hdr_t *cd_ctrl =
+ (icp_qat_fw_cipher_auth_cd_ctrl_hdr_t *)&pSessionDesc->reqCacheFtr
+ .cd_ctrl;
+
+ pHwBlockBaseInDRAM = (Cpa8U *)pSessionDesc->contentDescInfo.pData;
+
+ sessionSetup.hashSetupData.hashAlgorithm = pSessionDesc->hashAlgorithm;
+ sessionSetup.hashSetupData.hashMode = pSessionDesc->hashMode;
+ sessionSetup.hashSetupData.authModeSetupData.authKey = pAuthKey;
+ sessionSetup.hashSetupData.authModeSetupData.authKeyLenInBytes =
+ pSessionDesc->authKeyLenInBytes;
+ sessionSetup.hashSetupData.authModeSetupData.aadLenInBytes =
+ pSessionDesc->aadLenInBytes;
+ sessionSetup.hashSetupData.digestResultLenInBytes =
+ pSessionDesc->hashResultSize;
+
+ sessionSetup.cipherSetupData.cipherAlgorithm =
+ pSessionDesc->cipherAlgorithm;
+ sessionSetup.cipherSetupData.cipherKeyLenInBytes =
+ pSessionDesc->cipherKeyLenInBytes;
+
+ /* Calculate hash states offsets */
+ pInnerState1 = pHwBlockBaseInDRAM +
+ cd_ctrl->hash_cfg_offset * LAC_QUAD_WORD_IN_BYTES +
+ sizeof(icp_qat_hw_auth_setup_t);
+
+ pInnerState2 = pInnerState1 + cd_ctrl->inner_state1_sz;
+
+ pOutHashSetup = pInnerState2 + cd_ctrl->inner_state2_sz;
+
+ /* Calculate offset of cipher key */
+ if (pSessionDesc->laCmdId == ICP_QAT_FW_LA_CMD_CIPHER_HASH) {
+ sessionSetup.cipherSetupData.pCipherKey =
+ (Cpa8U *)pHwBlockBaseInDRAM +
+ sizeof(icp_qat_hw_cipher_config_t);
+ } else if (pSessionDesc->laCmdId == ICP_QAT_FW_LA_CMD_HASH_CIPHER) {
+ sessionSetup.cipherSetupData.pCipherKey =
+ pOutHashSetup + sizeof(icp_qat_hw_cipher_config_t);
+ } else if (CPA_TRUE == pSessionDesc->isSinglePass) {
+ CpaCySymCipherAlgorithm cipher = pSessionDesc->cipherAlgorithm;
+ Cpa32U hwBlockOffsetInDRAM = 0;
+
+ if (pSessionDesc->cipherDirection ==
+ CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) {
+ sessionSetup.cipherSetupData.pCipherKey =
+ (Cpa8U *)pHwBlockBaseInDRAM +
+ sizeof(icp_qat_hw_cipher_config_t);
+ } else {
+ if (LAC_CIPHER_IS_GCM(cipher))
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC);
+ else
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC);
+ sessionSetup.cipherSetupData.pCipherKey =
+ (Cpa8U *)pHwBlockBaseInDRAM + hwBlockOffsetInDRAM +
+ sizeof(icp_qat_hw_cipher_config_t);
+ }
+ }
+
+ if (!sessionSetup.cipherSetupData.pCipherKey)
+ return CPA_STATUS_FAIL;
+
+ if (CPA_CY_SYM_HASH_SHA3_256 == pSessionDesc->hashAlgorithm) {
+ if (CPA_FALSE == pSessionDesc->isAuthEncryptOp) {
+ lac_sym_qat_hash_state_buffer_info_t
+ *pHashStateBufferInfo =
+ &(pSessionDesc->hashStateBufferInfo);
+
+ sal_crypto_service_t *pService =
+ (sal_crypto_service_t *)pSessionDesc->pInstance;
+
+ status = LacHash_StatePrefixAadBufferInit(
+ &(pService->generic_service_info),
+ &(sessionSetup.hashSetupData),
+ &(pSessionDesc->reqCacheFtr),
+ pSessionDesc->qatHashMode,
+ pSessionDesc->hashStatePrefixBuffer,
+ pHashStateBufferInfo);
+ /* SHRAM Constants Table not used for Auth-Enc */
+ }
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == pSessionDesc->hashAlgorithm) {
+ Cpa8U *authKey =
+ (Cpa8U *)pOutHashSetup + sizeof(icp_qat_hw_cipher_config_t);
+ memcpy(authKey, pAuthKey, pSessionDesc->authKeyLenInBytes);
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 == pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_CBC_MAC == pSessionDesc->hashAlgorithm) {
+ memcpy(pInnerState2, pAuthKey, pSessionDesc->authKeyLenInBytes);
+ } else if (CPA_CY_SYM_HASH_AES_CMAC == pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_KASUMI_F9 == pSessionDesc->hashAlgorithm ||
+ IS_HASH_MODE_1(pSessionDesc->qatHashMode)) {
+ if (CPA_CY_SYM_HASH_AES_CMAC == pSessionDesc->hashAlgorithm) {
+ memset(pInnerState2, 0, cd_ctrl->inner_state2_sz);
+ }
+
+ /* Block messages until precompute is completed */
+ pSessionDesc->nonBlockingOpsInProgress = CPA_FALSE;
+
+ status = LacHash_PrecomputeDataCreate(
+ pSessionDesc->pInstance,
+ (CpaCySymSessionSetupData *)&(sessionSetup),
+ LacSymAlgChain_HashPrecomputeDoneCb,
+ pSessionDesc,
+ pSessionDesc->hashStatePrefixBuffer,
+ pInnerState1,
+ pInnerState2);
+ }
+
+ return status;
+}
+
+/** @ingroup LacAlgChain */
+CpaStatus
+LacAlgChain_SessionInit(const CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ lac_session_desc_t *pSessionDesc)
+{
+ CpaStatus stat, status = CPA_STATUS_SUCCESS;
+ sal_qat_content_desc_info_t *pCdInfo = NULL;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+ Cpa32U capabilitiesMask =
+ pService->generic_service_info.capabilitiesMask;
+ Cpa8U *pHwBlockBaseInDRAM = NULL;
+ Cpa8U *pOptimisedHwBlockBaseInDRAM = NULL;
+ Cpa32U hwBlockOffsetInDRAM = 0;
+ Cpa32U optimisedHwBlockOffsetInDRAM = 0;
+ Cpa8U cipherOffsetInConstantsTable = 0;
+ Cpa8U hashOffsetInConstantsTable = 0;
+ icp_qat_fw_comn_req_t *pMsg = NULL;
+ const CpaCySymCipherSetupData *pCipherData;
+ const CpaCySymHashSetupData *pHashData;
+ Cpa16U proto = ICP_QAT_FW_LA_NO_PROTO; /* no CCM/GCM/Snow3G */
+ CpaCySymAlgChainOrder chainOrder = 0;
+ lac_sym_qat_hash_precompute_info_t precomputeData = { 0 };
+ lac_sym_qat_hash_precompute_info_t precomputeDataOptimisedCd = { 0 };
+
+ pCipherData = &(pSessionSetupData->cipherSetupData);
+ pHashData = &(pSessionSetupData->hashSetupData);
+
+ /*-------------------------------------------------------------------------
+ * Populate session data
+ *-----------------------------------------------------------------------*/
+
+ /* Initialise Request Queue */
+ stat = LAC_SPINLOCK_INIT(&pSessionDesc->requestQueueLock);
+ if (CPA_STATUS_SUCCESS != stat) {
+ LAC_LOG_ERROR("Spinlock init failed for sessionLock");
+ return CPA_STATUS_RESOURCE;
+ }
+
+ pSessionDesc->pRequestQueueHead = NULL;
+ pSessionDesc->pRequestQueueTail = NULL;
+ pSessionDesc->nonBlockingOpsInProgress = CPA_TRUE;
+ pSessionDesc->pInstance = instanceHandle;
+ pSessionDesc->digestIsAppended = pSessionSetupData->digestIsAppended;
+ pSessionDesc->digestVerify = pSessionSetupData->verifyDigest;
+
+ /* Reset the pending callback counter */
+ qatUtilsAtomicSet(0, &pSessionDesc->u.pendingCbCount);
+ qatUtilsAtomicSet(0, &pSessionDesc->u.pendingDpCbCount);
+
+ /* Partial state must be set to full, to indicate that next packet
+ * expected on the session is a full packet or the start of a
+ * partial packet. */
+ pSessionDesc->partialState = CPA_CY_SYM_PACKET_TYPE_FULL;
+
+ pSessionDesc->symOperation = pSessionSetupData->symOperation;
+ switch (pSessionDesc->symOperation) {
+ case CPA_CY_SYM_OP_CIPHER:
+ pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER;
+ pSessionDesc->isCipher = TRUE;
+ pSessionDesc->isAuth = FALSE;
+ pSessionDesc->isAuthEncryptOp = CPA_FALSE;
+
+ if (CPA_CY_SYM_CIPHER_SNOW3G_UEA2 ==
+ pSessionSetupData->cipherSetupData.cipherAlgorithm) {
+ proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
+ } else if (CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
+ pSessionSetupData->cipherSetupData.cipherAlgorithm) {
+ proto = ICP_QAT_FW_LA_ZUC_3G_PROTO;
+ }
+ break;
+ case CPA_CY_SYM_OP_HASH:
+ pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_AUTH;
+ pSessionDesc->isCipher = FALSE;
+ pSessionDesc->isAuth = TRUE;
+ pSessionDesc->isAuthEncryptOp = CPA_FALSE;
+
+ if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionSetupData->hashSetupData.hashAlgorithm) {
+ proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionSetupData->hashSetupData.hashAlgorithm) {
+ proto = ICP_QAT_FW_LA_ZUC_3G_PROTO;
+ }
+
+ break;
+ case CPA_CY_SYM_OP_ALGORITHM_CHAINING:
+ pSessionDesc->isCipher = TRUE;
+ pSessionDesc->isAuth = TRUE;
+
+ {
+ /* set up some useful shortcuts */
+ CpaCySymCipherAlgorithm cipherAlgorithm =
+ pSessionSetupData->cipherSetupData.cipherAlgorithm;
+ CpaCySymCipherDirection cipherDir =
+ pSessionSetupData->cipherSetupData.cipherDirection;
+
+ if (LAC_CIPHER_IS_CCM(cipherAlgorithm)) {
+ pSessionDesc->isAuthEncryptOp = CPA_TRUE;
+ pSessionDesc->digestIsAppended = CPA_TRUE;
+ proto = ICP_QAT_FW_LA_CCM_PROTO;
+
+ /* Derive chainOrder from direction for
+ * isAuthEncryptOp
+ * cases */
+ /* For CCM & GCM modes: force digest verify flag
+ _TRUE
+ for decrypt and _FALSE for encrypt. For all
+ other cases
+ use user defined value */
+
+ if (CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT ==
+ cipherDir) {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
+ pSessionDesc->digestVerify = CPA_FALSE;
+ } else {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
+ pSessionDesc->digestVerify = CPA_TRUE;
+ }
+ } else if (LAC_CIPHER_IS_GCM(cipherAlgorithm)) {
+ pSessionDesc->isAuthEncryptOp = CPA_TRUE;
+ proto = ICP_QAT_FW_LA_GCM_PROTO;
+
+ /* Derive chainOrder from direction for
+ * isAuthEncryptOp
+ * cases */
+ /* For CCM & GCM modes: force digest verify flag
+ _TRUE
+ for decrypt and _FALSE for encrypt. For all
+ other cases
+ use user defined value */
+
+ if (CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT ==
+ cipherDir) {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
+ pSessionDesc->digestVerify = CPA_FALSE;
+ } else {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
+ pSessionDesc->digestVerify = CPA_TRUE;
+ }
+ } else if (LAC_CIPHER_IS_CHACHA(cipherAlgorithm)) {
+ pSessionDesc->isAuthEncryptOp = CPA_TRUE;
+ proto = ICP_QAT_FW_LA_SINGLE_PASS_PROTO;
+
+ if (CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT ==
+ cipherDir) {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
+ } else {
+ chainOrder =
+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
+ }
+ } else {
+ pSessionDesc->isAuthEncryptOp = CPA_FALSE;
+ /* Use the chainOrder passed in */
+ chainOrder = pSessionSetupData->algChainOrder;
+ if ((chainOrder !=
+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER) &&
+ (chainOrder !=
+ CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH)) {
+ LAC_INVALID_PARAM_LOG("algChainOrder");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionSetupData->hashSetupData
+ .hashAlgorithm) {
+ proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionSetupData->hashSetupData
+ .hashAlgorithm) {
+ proto = ICP_QAT_FW_LA_ZUC_3G_PROTO;
+ }
+ }
+
+ if (CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH ==
+ chainOrder) {
+ pSessionDesc->laCmdId =
+ ICP_QAT_FW_LA_CMD_CIPHER_HASH;
+ } else if (
+ CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER ==
+ chainOrder) {
+ pSessionDesc->laCmdId =
+ ICP_QAT_FW_LA_CMD_HASH_CIPHER;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (pSessionDesc->isCipher) {
+/* Populate cipher specific session data */
+
+ status = LacCipher_SessionSetupDataCheck(pCipherData);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ pSessionDesc->cipherAlgorithm =
+ pCipherData->cipherAlgorithm;
+ pSessionDesc->cipherKeyLenInBytes =
+ pCipherData->cipherKeyLenInBytes;
+ pSessionDesc->cipherDirection =
+ pCipherData->cipherDirection;
+
+ /* ARC4 base key isn't added to the content descriptor,
+ * because
+ * we don't need to pass it directly to the QAT engine.
+ * Instead
+ * an initial cipher state & key matrix is derived from
+ * the
+ * base key and provided to the QAT through the state
+ * pointer
+ * in the request params. We'll store this initial state
+ * in
+ * the session descriptor. */
+
+ if (LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm)) {
+ LacSymQat_CipherArc4StateInit(
+ pCipherData->pCipherKey,
+ pSessionDesc->cipherKeyLenInBytes,
+ pSessionDesc->cipherARC4InitialState);
+
+ pSessionDesc->cipherARC4InitialStatePhysAddr =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info,
+ pSessionDesc->cipherARC4InitialState);
+
+ if (0 ==
+ pSessionDesc
+ ->cipherARC4InitialStatePhysAddr) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of "
+ "the initial state for ARC4\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ }
+ }
+
+ if ((CPA_STATUS_SUCCESS == status) && pSessionDesc->isAuth) {
+ /* Populate auth-specific session data */
+ const CpaCySymHashSetupData *pHashData =
+ &pSessionSetupData->hashSetupData;
+
+ status = LacHash_HashContextCheck(instanceHandle, pHashData);
+ if (CPA_STATUS_SUCCESS == status) {
+ pSessionDesc->hashResultSize =
+ pHashData->digestResultLenInBytes;
+ pSessionDesc->hashMode = pHashData->hashMode;
+ pSessionDesc->hashAlgorithm = pHashData->hashAlgorithm;
+
+ /* Save the authentication key length for further update
+ */
+ if (CPA_CY_SYM_HASH_MODE_AUTH == pHashData->hashMode) {
+ pSessionDesc->authKeyLenInBytes =
+ pHashData->authModeSetupData
+ .authKeyLenInBytes;
+ }
+ if (CPA_TRUE == pSessionDesc->isAuthEncryptOp ||
+ (pHashData->hashAlgorithm ==
+ CPA_CY_SYM_HASH_SNOW3G_UIA2 ||
+ pHashData->hashAlgorithm ==
+ CPA_CY_SYM_HASH_ZUC_EIA3)) {
+ pSessionDesc->aadLenInBytes =
+ pHashData->authModeSetupData.aadLenInBytes;
+ }
+
+ /* Set the QAT hash mode */
+ if ((pHashData->hashMode ==
+ CPA_CY_SYM_HASH_MODE_NESTED) ||
+ (pHashData->hashMode ==
+ CPA_CY_SYM_HASH_MODE_PLAIN) ||
+ (pHashData->hashMode == CPA_CY_SYM_HASH_MODE_AUTH &&
+ pHashData->hashAlgorithm ==
+ CPA_CY_SYM_HASH_AES_CBC_MAC)) {
+ pSessionDesc->qatHashMode =
+ ICP_QAT_HW_AUTH_MODE0;
+ } else /* CPA_CY_SYM_HASH_MODE_AUTH
+ && anything except CPA_CY_SYM_HASH_AES_CBC_MAC
+ */
+ {
+ if (IS_HMAC_ALG(pHashData->hashAlgorithm)) {
+ /* SHA3 and SM3 HMAC do not support
+ * precompute, force MODE2
+ * for AUTH */
+ if ((CPA_CY_SYM_HASH_SHA3_224 ==
+ pHashData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHA3_256 ==
+ pHashData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHA3_384 ==
+ pHashData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHA3_512 ==
+ pHashData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SM3 ==
+ pHashData->hashAlgorithm)) {
+ pSessionDesc->qatHashMode =
+ ICP_QAT_HW_AUTH_MODE2;
+ } else {
+ pSessionDesc->qatHashMode =
+ ICP_QAT_HW_AUTH_MODE1;
+ }
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pHashData->hashAlgorithm) {
+ pSessionDesc->qatHashMode =
+ ICP_QAT_HW_AUTH_MODE0;
+ } else {
+ pSessionDesc->qatHashMode =
+ ICP_QAT_HW_AUTH_MODE1;
+ }
+ }
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * 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 desciptor is used in the SHRAM case for
+ *AES-128-HMAC-SHA1
+ *-----------------------------------------------------------------------*/
+ if (CPA_STATUS_SUCCESS == status) {
+
+ LacSymCheck_IsPartialSupported(capabilitiesMask, pSessionDesc);
+
+ /* setup some convenience pointers */
+ pCdInfo = &(pSessionDesc->contentDescInfo);
+ pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
+ hwBlockOffsetInDRAM = 0;
+
+ /*
+ * Build the header flags with the default settings for this
+ * session.
+ */
+ if (pSessionDesc->isDPSession == CPA_TRUE) {
+ pSessionDesc->cmnRequestFlags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(
+ QAT_COMN_CD_FLD_TYPE_64BIT_ADR,
+ LAC_SYM_DP_QAT_PTR_TYPE);
+ } else {
+ pSessionDesc->cmnRequestFlags =
+ ICP_QAT_FW_COMN_FLAGS_BUILD(
+ QAT_COMN_CD_FLD_TYPE_64BIT_ADR,
+ LAC_SYM_DEFAULT_QAT_PTR_TYPE);
+ }
+
+ LacSymQat_LaSetDefaultFlags(&pSessionDesc->laCmdFlags,
+ pSessionDesc->symOperation);
+
+ switch (pSessionDesc->symOperation) {
+ case CPA_CY_SYM_OP_CIPHER: {
+ LacAlgChain_CipherCDBuild(
+ pCipherData,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ cipherOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM);
+ } break;
+ case CPA_CY_SYM_OP_HASH:
+ LacAlgChain_HashCDBuild(pHashData,
+ instanceHandle,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ hashOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ &precomputeData,
+ &precomputeDataOptimisedCd,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM,
+ NULL,
+ NULL);
+ break;
+ case CPA_CY_SYM_OP_ALGORITHM_CHAINING:
+ /* For CCM/GCM, CPM firmware currently expects the
+ * cipher and
+ * hash h/w setup blocks to be arranged according to the
+ * chain
+ * order (Except for GCM/CCM, order doesn't actually
+ * matter as
+ * long as the config offsets are set correctly in CD
+ * control
+ * blocks
+ */
+ if (CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER ==
+ chainOrder) {
+ LacAlgChain_HashCDBuild(
+ pHashData,
+ instanceHandle,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_CIPHER,
+ hashOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ &precomputeData,
+ &precomputeDataOptimisedCd,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM,
+ pOptimisedHwBlockBaseInDRAM,
+ &optimisedHwBlockOffsetInDRAM);
+
+ LacAlgChain_CipherCDBuild(
+ pCipherData,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ cipherOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM);
+ if (LAC_CIPHER_IS_SPC(
+ pCipherData->cipherAlgorithm,
+ pHashData->hashAlgorithm,
+ capabilitiesMask)) {
+ pCdInfo->hwBlkSzQuadWords =
+ (LAC_BYTES_TO_QUADWORDS(
+ hwBlockOffsetInDRAM));
+ pMsg = (icp_qat_fw_comn_req_t *)&(
+ pSessionDesc->reqSpcCacheHdr);
+ SalQatMsg_ContentDescHdrWrite(
+ (icp_qat_fw_comn_req_t *)pMsg,
+ pCdInfo);
+ }
+ } else {
+ LacAlgChain_CipherCDBuild(
+ pCipherData,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_AUTH,
+ cipherOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM);
+
+ if (LAC_CIPHER_IS_SPC(
+ pCipherData->cipherAlgorithm,
+ pHashData->hashAlgorithm,
+ capabilitiesMask)) {
+ pCdInfo->hwBlkSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ hwBlockOffsetInDRAM);
+ pMsg = (icp_qat_fw_comn_req_t *)&(
+ pSessionDesc->reqSpcCacheHdr);
+ SalQatMsg_ContentDescHdrWrite(
+ (icp_qat_fw_comn_req_t *)pMsg,
+ pCdInfo);
+ }
+ LacAlgChain_HashCDBuild(
+ pHashData,
+ instanceHandle,
+ pSessionDesc,
+ ICP_QAT_FW_SLICE_DRAM_WR,
+ hashOffsetInConstantsTable,
+ &pSessionDesc->cmnRequestFlags,
+ &pSessionDesc->laCmdFlags,
+ &precomputeData,
+ &precomputeDataOptimisedCd,
+ pHwBlockBaseInDRAM,
+ &hwBlockOffsetInDRAM,
+ pOptimisedHwBlockBaseInDRAM,
+ &optimisedHwBlockOffsetInDRAM);
+ }
+ break;
+ default:
+ LAC_LOG_ERROR("Invalid sym operation\n");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if ((CPA_STATUS_SUCCESS == status) && pSessionDesc->isAuth) {
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
+ &(pSessionDesc->hashStateBufferInfo);
+ CpaBoolean hashStateBuffer = CPA_TRUE;
+
+ /* set up fields in both the cd_ctrl and reqParams which
+ * describe
+ * the ReqParams block */
+ LacSymQat_HashSetupReqParamsMetaData(
+ &(pSessionDesc->reqCacheFtr),
+ instanceHandle,
+ pHashData,
+ hashStateBuffer,
+ pSessionDesc->qatHashMode,
+ pSessionDesc->digestVerify);
+
+ /* populate the hash state prefix buffer info structure
+ * (part of user allocated session memory & the
+ * buffer itself. For CCM/GCM the buffer is stored in the
+ * cookie and is not initialised here) */
+ if (CPA_FALSE == pSessionDesc->isAuthEncryptOp) {
+ LAC_CHECK_64_BYTE_ALIGNMENT(
+ &(pSessionDesc->hashStatePrefixBuffer[0]));
+ status = LacHash_StatePrefixAadBufferInit(
+ &(pService->generic_service_info),
+ pHashData,
+ &(pSessionDesc->reqCacheFtr),
+ pSessionDesc->qatHashMode,
+ pSessionDesc->hashStatePrefixBuffer,
+ pHashStateBufferInfo);
+ /* SHRAM Constants Table not used for Auth-Enc */
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ if (IS_HASH_MODE_1(pSessionDesc->qatHashMode) ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pHashData->hashAlgorithm) {
+ LAC_CHECK_64_BYTE_ALIGNMENT(
+ &(pSessionDesc->hashStatePrefixBuffer[0]));
+
+ /* Block messages until precompute is completed
+ */
+ pSessionDesc->nonBlockingOpsInProgress =
+ CPA_FALSE;
+ status = LacHash_PrecomputeDataCreate(
+ instanceHandle,
+ (CpaCySymSessionSetupData *)
+ pSessionSetupData,
+ LacSymAlgChain_HashPrecomputeDoneCb,
+ pSessionDesc,
+ pSessionDesc->hashStatePrefixBuffer,
+ precomputeData.pState1,
+ precomputeData.pState2);
+ } else if (pHashData->hashAlgorithm ==
+ CPA_CY_SYM_HASH_AES_CBC_MAC) {
+ LAC_OS_BZERO(precomputeData.pState2,
+ precomputeData.state2Size);
+ memcpy(precomputeData.pState2,
+ pHashData->authModeSetupData.authKey,
+ pHashData->authModeSetupData
+ .authKeyLenInBytes);
+ }
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+
+ if (pSessionDesc->digestVerify) {
+
+ ICP_QAT_FW_LA_CMP_AUTH_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_CMP_AUTH_RES);
+ ICP_QAT_FW_LA_RET_AUTH_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_NO_RET_AUTH_RES);
+ } else {
+
+ ICP_QAT_FW_LA_RET_AUTH_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_RET_AUTH_RES);
+ ICP_QAT_FW_LA_CMP_AUTH_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
+ }
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+
+ pCdInfo->hwBlkSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(hwBlockOffsetInDRAM);
+ pMsg = (icp_qat_fw_comn_req_t *)&(pSessionDesc->reqCacheHdr);
+
+ /* Configure the ContentDescriptor field
+ * in the request if not done already */
+ SalQatMsg_ContentDescHdrWrite((icp_qat_fw_comn_req_t *)pMsg,
+ pCdInfo);
+
+ if (CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
+ pSessionSetupData->cipherSetupData.cipherAlgorithm ||
+ pHashData->hashAlgorithm == CPA_CY_SYM_HASH_ZUC_EIA3) {
+ /* New bit position (12) for ZUC. The FW provides a
+ * specific macro
+ * to use to set the ZUC proto flag. With the new FW I/F
+ * this needs
+ * to be set for both Cipher and Auth */
+ ICP_QAT_FW_LA_ZUC_3G_PROTO_FLAG_SET(
+ pSessionDesc->laCmdFlags, proto);
+ } else {
+ /* Configure the common header */
+ ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags,
+ proto);
+ }
+
+ /* set Append flag, if digest is appended */
+ if (pSessionDesc->digestIsAppended) {
+ ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_DIGEST_IN_BUFFER);
+ } else {
+ ICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(
+ pSessionDesc->laCmdFlags,
+ ICP_QAT_FW_LA_NO_DIGEST_IN_BUFFER);
+ }
+
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pMsg,
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
+ pSessionDesc->laCmdId,
+ pSessionDesc->cmnRequestFlags,
+ pSessionDesc->laCmdFlags);
+ }
+
+ return status;
+}
+
+/** @ingroup LacAlgChain */
+CpaStatus
+LacAlgChain_Perform(const CpaInstanceHandle instanceHandle,
+ lac_session_desc_t *pSessionDesc,
+ void *pCallbackTag,
+ const CpaCySymOpData *pOpData,
+ const CpaBufferList *pSrcBuffer,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean *pVerifyResult)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+ Cpa32U capabilitiesMask =
+ pService->generic_service_info.capabilitiesMask;
+ lac_sym_bulk_cookie_t *pCookie = NULL;
+ lac_sym_cookie_t *pSymCookie = NULL;
+ icp_qat_fw_la_bulk_req_t *pMsg = NULL;
+ Cpa8U *pMsgDummy = NULL;
+ Cpa8U *pCacheDummyHdr = NULL;
+ Cpa8U *pCacheDummyFtr = NULL;
+ Cpa32U qatPacketType = 0;
+ CpaBufferList *pBufferList = NULL;
+ Cpa8U *pDigestResult = NULL;
+ Cpa64U srcAddrPhys = 0;
+ Cpa64U dstAddrPhys = 0;
+ icp_qat_fw_la_cmd_id_t laCmdId;
+ sal_qat_content_desc_info_t *pCdInfo = NULL;
+ Cpa8U *pHwBlockBaseInDRAM = NULL;
+ Cpa32U hwBlockOffsetInDRAM = 0;
+ Cpa32U sizeInBytes = 0;
+ icp_qat_fw_cipher_cd_ctrl_hdr_t *pSpcCdCtrlHdr = NULL;
+ CpaCySymCipherAlgorithm cipher;
+ CpaCySymHashAlgorithm hash;
+ Cpa8U paddingLen = 0;
+ Cpa8U blockLen = 0;
+ Cpa64U srcPktSize = 0;
+
+ /* Set the command id */
+ laCmdId = pSessionDesc->laCmdId;
+
+ cipher = pSessionDesc->cipherAlgorithm;
+ hash = pSessionDesc->hashAlgorithm;
+
+ /* Convert Alg Chain Request to Cipher Request for CCP and
+ * AES_GCM single pass */
+ if (!pSessionDesc->isSinglePass &&
+ LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
+ (LAC_CIPHER_SPC_IV_SIZE == pOpData->ivLenInBytes)) {
+ pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER;
+ laCmdId = pSessionDesc->laCmdId;
+ pSessionDesc->symOperation = CPA_CY_SYM_OP_CIPHER;
+ pSessionDesc->isSinglePass = CPA_TRUE;
+ pSessionDesc->isCipher = CPA_TRUE;
+ pSessionDesc->isAuthEncryptOp = CPA_FALSE;
+ pSessionDesc->isAuth = CPA_FALSE;
+ if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ pSessionDesc->aadLenInBytes =
+ pOpData->messageLenToHashInBytes;
+ if (ICP_QAT_FW_SPC_AAD_SZ_MAX <
+ pSessionDesc->aadLenInBytes) {
+ LAC_INVALID_PARAM_LOG(
+ "aadLenInBytes for AES_GMAC");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* New bit position (13) for SINGLE PASS.
+ * The FW provides a specific macro to use to set the proto flag
+ */
+ ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET(
+ pSessionDesc->laCmdFlags, ICP_QAT_FW_LA_SINGLE_PASS_PROTO);
+ ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags, 0);
+
+ pCdInfo = &(pSessionDesc->contentDescInfo);
+ pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
+ if (CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT ==
+ pSessionDesc->cipherDirection) {
+ if (LAC_CIPHER_IS_GCM(cipher))
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC);
+ else
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC);
+ }
+ /* construct cipherConfig in CD in DRAM */
+ LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
+ pHwBlockBaseInDRAM +
+ hwBlockOffsetInDRAM,
+ &sizeInBytes);
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&(
+ pSessionDesc->reqSpcCacheHdr),
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
+ pSessionDesc->laCmdId,
+ pSessionDesc->cmnRequestFlags,
+ pSessionDesc->laCmdFlags);
+ } else if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ pSessionDesc->aadLenInBytes = pOpData->messageLenToHashInBytes;
+ }
+
+ if (LAC_CIPHER_IS_CHACHA(cipher) &&
+ (LAC_CIPHER_SPC_IV_SIZE != pOpData->ivLenInBytes)) {
+ LAC_INVALID_PARAM_LOG("IV for CHACHA");
+ return CPA_STATUS_INVALID_PARAM;
+ } else if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ if (pOpData->messageLenToHashInBytes == 0 ||
+ pOpData->pAdditionalAuthData != NULL) {
+ LAC_INVALID_PARAM_LOG(
+ "For AES_GMAC, AAD Length "
+ "(messageLenToHashInBytes) must "
+ "be non zero and pAdditionalAuthData "
+ "must be NULL");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
+ if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) {
+ status = LacSymAlgChain_CheckCCMData(
+ pOpData->pAdditionalAuthData,
+ pOpData->pIv,
+ pOpData->messageLenToCipherInBytes,
+ pOpData->ivLenInBytes);
+ if (CPA_STATUS_SUCCESS == status) {
+ LacSymAlgChain_PrepareCCMData(
+ pSessionDesc,
+ pOpData->pAdditionalAuthData,
+ pOpData->pIv,
+ pOpData->messageLenToCipherInBytes,
+ pOpData->ivLenInBytes);
+ }
+ } else if (CPA_CY_SYM_HASH_AES_GCM ==
+ pSessionDesc->hashAlgorithm) {
+ if (pSessionDesc->aadLenInBytes != 0 &&
+ pOpData->pAdditionalAuthData == NULL) {
+ LAC_INVALID_PARAM_LOG("pAdditionalAuthData");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ LacSymAlgChain_PrepareGCMData(
+ pSessionDesc, pOpData->pAdditionalAuthData);
+ }
+ }
+ }
+
+ /* allocate cookie (used by callback function) */
+ if (CPA_STATUS_SUCCESS == status) {
+ pSymCookie = (lac_sym_cookie_t *)Lac_MemPoolEntryAlloc(
+ pService->lac_sym_cookie_pool);
+ if (pSymCookie == NULL) {
+ LAC_LOG_ERROR("Cannot allocate cookie - NULL");
+ status = CPA_STATUS_RESOURCE;
+ } else if ((void *)CPA_STATUS_RETRY == pSymCookie) {
+ pSymCookie = NULL;
+ status = CPA_STATUS_RETRY;
+ } else {
+ pCookie = &(pSymCookie->u.bulkCookie);
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* write the buffer descriptors */
+ if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(cipher, hash)) {
+ status =
+ LacBuffDesc_BufferListDescWriteAndAllowZeroBuffer(
+ (CpaBufferList *)pSrcBuffer,
+ &srcAddrPhys,
+ CPA_FALSE,
+ &(pService->generic_service_info));
+ } else {
+ status = LacBuffDesc_BufferListDescWrite(
+ (CpaBufferList *)pSrcBuffer,
+ &srcAddrPhys,
+ CPA_FALSE,
+ &(pService->generic_service_info));
+ }
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR("Unable to write src buffer descriptors");
+ }
+
+ /* For out of place operations */
+ if ((pSrcBuffer != pDstBuffer) &&
+ (CPA_STATUS_SUCCESS == status)) {
+ if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(cipher, hash)) {
+ status =
+ LacBuffDesc_BufferListDescWriteAndAllowZeroBuffer(
+ pDstBuffer,
+ &dstAddrPhys,
+ CPA_FALSE,
+ &(pService->generic_service_info));
+ } else {
+ status = LacBuffDesc_BufferListDescWrite(
+ pDstBuffer,
+ &dstAddrPhys,
+ CPA_FALSE,
+ &(pService->generic_service_info));
+ }
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR(
+ "Unable to write dest buffer descriptors");
+ }
+ }
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ /* populate the cookie */
+ pCookie->pCallbackTag = pCallbackTag;
+ pCookie->sessionCtx = pOpData->sessionCtx;
+ pCookie->pOpData = (const CpaCySymOpData *)pOpData;
+ pCookie->pDstBuffer = pDstBuffer;
+ pCookie->updateSessionIvOnSend = CPA_FALSE;
+ pCookie->updateUserIvOnRecieve = CPA_FALSE;
+ pCookie->updateKeySizeOnRecieve = CPA_FALSE;
+ pCookie->pNext = NULL;
+ pCookie->instanceHandle = pService;
+
+ /* get the qat packet type for LAC packet type */
+ LacSymQat_packetTypeGet(pOpData->packetType,
+ pSessionDesc->partialState,
+ &qatPacketType);
+ /*
+ * For XTS mode, the key size must be updated after
+ * the first partial has been sent. Set a flag here so the
+ * response knows to do this.
+ */
+ if ((laCmdId != ICP_QAT_FW_LA_CMD_AUTH) &&
+ (CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
+ (LAC_CIPHER_IS_XTS_MODE(pSessionDesc->cipherAlgorithm)) &&
+ (qatPacketType == ICP_QAT_FW_LA_PARTIAL_START)) {
+ pCookie->updateKeySizeOnRecieve = CPA_TRUE;
+ }
+
+ /*
+ * Now create the Request.
+ * Start by populating it from the cache in the session
+ * descriptor.
+ */
+ pMsg = &(pCookie->qatMsg);
+ pMsgDummy = (Cpa8U *)pMsg;
+
+ if (pSessionDesc->isSinglePass) {
+ pCacheDummyHdr =
+ (Cpa8U *)&(pSessionDesc->reqSpcCacheHdr);
+ pCacheDummyFtr =
+ (Cpa8U *)&(pSessionDesc->reqSpcCacheFtr);
+ } else {
+ /* Normally, we want to use the SHRAM Constants Table if
+ * possible
+ * for best performance (less DRAM accesses incurred by
+ * CPM). But
+ * we can't use it for partial-packet hash operations.
+ * This is why
+ * we build 2 versions of the message template at
+ * sessionInit,
+ * one for SHRAM Constants Table usage and the other
+ * (default) for
+ * Content Descriptor h/w setup data in DRAM. And we
+ * chose between
+ * them here on a per-request basis, when we know the
+ * packetType
+ */
+ if ((!pSessionDesc->useSymConstantsTable) ||
+ (pSessionDesc->isAuth &&
+ (CPA_CY_SYM_PACKET_TYPE_FULL !=
+ pOpData->packetType))) {
+ pCacheDummyHdr =
+ (Cpa8U *)&(pSessionDesc->reqCacheHdr);
+ pCacheDummyFtr =
+ (Cpa8U *)&(pSessionDesc->reqCacheFtr);
+ } else {
+ pCacheDummyHdr =
+ (Cpa8U *)&(pSessionDesc->shramReqCacheHdr);
+ pCacheDummyFtr =
+ (Cpa8U *)&(pSessionDesc->shramReqCacheFtr);
+ }
+ }
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memset((pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
+ 0,
+ (LAC_LONG_WORD_IN_BYTES *
+ LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
+ memcpy(pMsgDummy + (LAC_LONG_WORD_IN_BYTES *
+ LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
+ /*
+ * Populate the comn_mid section
+ */
+ SalQatMsg_CmnMidWrite(pMsg,
+ pCookie,
+ LAC_SYM_DEFAULT_QAT_PTR_TYPE,
+ srcAddrPhys,
+ dstAddrPhys,
+ 0,
+ 0);
+
+ /*
+ * Populate the serv_specif_flags field of the Request header
+ * Some of the flags are set up here.
+ * Others are set up later when the RequestParams are set up.
+ */
+
+ LacSymQat_LaPacketCommandFlagSet(
+ qatPacketType,
+ laCmdId,
+ pSessionDesc->cipherAlgorithm,
+ &pMsg->comn_hdr.serv_specif_flags,
+ pOpData->ivLenInBytes);
+
+ if (pSessionDesc->isSinglePass) {
+ ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
+ pMsg->comn_hdr.serv_specif_flags,
+ ICP_QAT_FW_LA_GCM_IV_LEN_NOT_12_OCTETS);
+
+ if (CPA_CY_SYM_PACKET_TYPE_PARTIAL ==
+ pOpData->packetType) {
+ ICP_QAT_FW_LA_RET_AUTH_SET(
+ pMsg->comn_hdr.serv_specif_flags,
+ ICP_QAT_FW_LA_NO_RET_AUTH_RES);
+
+ ICP_QAT_FW_LA_CMP_AUTH_SET(
+ pMsg->comn_hdr.serv_specif_flags,
+ ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
+ }
+ }
+
+ LacBuffDesc_BufferListTotalSizeGet(pSrcBuffer, &srcPktSize);
+
+ /*
+ * Populate the CipherRequestParams section of the Request
+ */
+ if (laCmdId != ICP_QAT_FW_LA_CMD_AUTH) {
+
+ Cpa8U *pIvBuffer = NULL;
+
+ status = LacCipher_PerformParamCheck(
+ pSessionDesc->cipherAlgorithm, pOpData, srcPktSize);
+ if (CPA_STATUS_SUCCESS != status) {
+ /* free the cookie */
+ Lac_MemPoolEntryFree(pCookie);
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* align cipher IV */
+ status = LacCipher_PerformIvCheck(
+ &(pService->generic_service_info),
+ pCookie,
+ qatPacketType,
+ &pIvBuffer);
+ }
+ if (pSessionDesc->isSinglePass &&
+ ((ICP_QAT_FW_LA_PARTIAL_MID == qatPacketType) ||
+ (ICP_QAT_FW_LA_PARTIAL_END == qatPacketType))) {
+ /* For SPC stateful cipher state size for mid
+ * and
+ * end partial packet is 48 bytes
+ */
+ pSpcCdCtrlHdr =
+ (icp_qat_fw_cipher_cd_ctrl_hdr_t *)&(
+ pMsg->cd_ctrl);
+ pSpcCdCtrlHdr->cipher_state_sz =
+ LAC_BYTES_TO_QUADWORDS(
+ LAC_SYM_QAT_CIPHER_STATE_SIZE_SPC);
+ }
+ /*populate the cipher request parameters */
+ if (CPA_STATUS_SUCCESS == status) {
+ Cpa64U ivBufferPhysAddr = 0;
+
+ if (pIvBuffer != NULL) {
+ /* User OpData memory being used for IV
+ * buffer */
+ /* get the physical address */
+ ivBufferPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info,
+ pIvBuffer);
+ if (0 == ivBufferPhysAddr) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address "
+ "of the IV\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+
+ if (status == CPA_STATUS_SUCCESS) {
+ status =
+ LacSymQat_CipherRequestParamsPopulate(
+ pMsg,
+ pOpData
+ ->cryptoStartSrcOffsetInBytes,
+ pOpData
+ ->messageLenToCipherInBytes,
+ ivBufferPhysAddr,
+ pIvBuffer);
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status &&
+ pSessionDesc->isSinglePass) {
+ Cpa64U aadBufferPhysAddr = 0;
+
+ /* For CHACHA and AES-GCM there is an AAD buffer
+ * if
+ * aadLenInBytes is nonzero In case of AES-GMAC,
+ * AAD buffer
+ * passed in the src buffer.
+ */
+ if (0 != pSessionDesc->aadLenInBytes &&
+ CPA_CY_SYM_HASH_AES_GMAC !=
+ pSessionDesc->hashAlgorithm) {
+ LAC_CHECK_NULL_PARAM(
+ pOpData->pAdditionalAuthData);
+ blockLen =
+ LacSymQat_CipherBlockSizeBytesGet(
+ pSessionDesc->cipherAlgorithm);
+ if ((pSessionDesc->aadLenInBytes %
+ blockLen) != 0) {
+ paddingLen = blockLen -
+ (pSessionDesc
+ ->aadLenInBytes %
+ blockLen);
+ memset(
+ &pOpData->pAdditionalAuthData
+ [pSessionDesc
+ ->aadLenInBytes],
+ 0,
+ paddingLen);
+ }
+
+ /* User OpData memory being used for aad
+ * buffer */
+ /* get the physical address */
+ aadBufferPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info,
+ pOpData->pAdditionalAuthData);
+ if (0 == aadBufferPhysAddr) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address "
+ "of the aad\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ icp_qat_fw_la_cipher_req_params_t *pCipherReqParams =
+ (icp_qat_fw_la_cipher_req_params_t
+ *)((Cpa8U *)&(
+ pMsg->serv_specif_rqpars) +
+ ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
+ pCipherReqParams->spc_aad_addr =
+ aadBufferPhysAddr;
+ pCipherReqParams->spc_aad_sz =
+ pSessionDesc->aadLenInBytes;
+
+ if (CPA_TRUE !=
+ pSessionDesc->digestIsAppended) {
+ Cpa64U digestBufferPhysAddr = 0;
+ /* User OpData memory being used
+ * for digest buffer */
+ /* get the physical address */
+ digestBufferPhysAddr =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService
+ ->generic_service_info,
+ pOpData->pDigestResult);
+ if (0 != digestBufferPhysAddr) {
+ pCipherReqParams
+ ->spc_auth_res_addr =
+ digestBufferPhysAddr;
+ pCipherReqParams
+ ->spc_auth_res_sz =
+ pSessionDesc
+ ->hashResultSize;
+ } else {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address "
+ "of the digest\n");
+ status =
+ CPA_STATUS_FAIL;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Set up HashRequestParams part of Request
+ */
+ if ((status == CPA_STATUS_SUCCESS) &&
+ (laCmdId != ICP_QAT_FW_LA_CMD_CIPHER)) {
+ Cpa32U authOffsetInBytes =
+ pOpData->hashStartSrcOffsetInBytes;
+ Cpa32U authLenInBytes =
+ pOpData->messageLenToHashInBytes;
+
+ status = LacHash_PerformParamCheck(instanceHandle,
+ pSessionDesc,
+ pOpData,
+ srcPktSize,
+ pVerifyResult);
+ if (CPA_STATUS_SUCCESS != status) {
+ /* free the cookie */
+ Lac_MemPoolEntryFree(pCookie);
+ return status;
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Info structure for CCM/GCM */
+ lac_sym_qat_hash_state_buffer_info_t
+ hashStateBufferInfo = { 0 };
+ lac_sym_qat_hash_state_buffer_info_t
+ *pHashStateBufferInfo =
+ &(pSessionDesc->hashStateBufferInfo);
+
+ if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
+ icp_qat_fw_la_auth_req_params_t *pHashReqParams =
+ (icp_qat_fw_la_auth_req_params_t
+ *)((Cpa8U *)&(
+ pMsg->serv_specif_rqpars) +
+ ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
+
+ hashStateBufferInfo.pData =
+ pOpData->pAdditionalAuthData;
+ if (pOpData->pAdditionalAuthData ==
+ NULL) {
+ hashStateBufferInfo.pDataPhys =
+ 0;
+ } else {
+ hashStateBufferInfo
+ .pDataPhys = LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService
+ ->generic_service_info,
+ pOpData
+ ->pAdditionalAuthData));
+ }
+
+ hashStateBufferInfo
+ .stateStorageSzQuadWords = 0;
+ hashStateBufferInfo
+ .prefixAadSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ pHashReqParams->u2.aad_sz);
+
+ /* Overwrite hash state buffer info
+ * structure pointer
+ * with the one created for CCM/GCM */
+ pHashStateBufferInfo =
+ &hashStateBufferInfo;
+
+ /* Aad buffer could be null in the GCM
+ * case */
+ if (0 ==
+ hashStateBufferInfo.pDataPhys &&
+ CPA_CY_SYM_HASH_AES_GCM !=
+ pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GMAC !=
+ pSessionDesc->hashAlgorithm) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address"
+ "of the AAD\n");
+ status = CPA_STATUS_FAIL;
+ }
+
+ /* for CCM/GCM the hash and cipher data
+ * regions
+ * are equal */
+ authOffsetInBytes =
+ pOpData
+ ->cryptoStartSrcOffsetInBytes;
+
+ /* For authenticated encryption,
+ * authentication length is
+ * determined by
+ * messageLenToCipherInBytes for AES-GCM
+ * and
+ * AES-CCM, and by
+ * messageLenToHashInBytes for AES-GMAC.
+ * You don't see the latter here, as
+ * that is the initial
+ * value of authLenInBytes. */
+ if (pSessionDesc->hashAlgorithm !=
+ CPA_CY_SYM_HASH_AES_GMAC)
+ authLenInBytes =
+ pOpData
+ ->messageLenToCipherInBytes;
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionDesc->hashAlgorithm) {
+ hashStateBufferInfo.pData =
+ pOpData->pAdditionalAuthData;
+ hashStateBufferInfo.pDataPhys =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ pService->generic_service_info,
+ hashStateBufferInfo.pData);
+ hashStateBufferInfo
+ .stateStorageSzQuadWords = 0;
+ hashStateBufferInfo
+ .prefixAadSzQuadWords =
+ LAC_BYTES_TO_QUADWORDS(
+ pSessionDesc->aadLenInBytes);
+
+ pHashStateBufferInfo =
+ &hashStateBufferInfo;
+
+ if (0 ==
+ hashStateBufferInfo.pDataPhys) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address"
+ "of the AAD\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ if (CPA_CY_SYM_HASH_AES_CCM ==
+ pSessionDesc->hashAlgorithm) {
+ if (CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT ==
+ pSessionDesc->cipherDirection) {
+ /* On a decrypt path pSrcBuffer
+ * is used as this is
+ * where encrypted digest is
+ * located. Firmware
+ * uses encrypted digest for
+ * compare/verification*/
+ pBufferList =
+ (CpaBufferList *)pSrcBuffer;
+ } else {
+ /* On an encrypt path pDstBuffer
+ * is used as this is
+ * where encrypted digest will
+ * be written */
+ pBufferList =
+ (CpaBufferList *)pDstBuffer;
+ }
+ status = LacSymAlgChain_PtrFromOffsetGet(
+ pBufferList,
+ pOpData->cryptoStartSrcOffsetInBytes +
+ pOpData
+ ->messageLenToCipherInBytes,
+ &pDigestResult);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR(
+ "Cannot set digest pointer within the"
+ " buffer list - offset out of bounds");
+ }
+ } else {
+ pDigestResult = pOpData->pDigestResult;
+ }
+
+ if (CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
+ pSessionDesc->symOperation) {
+ /* In alg chaining mode, packets are not
+ * seen as partials
+ * for hash operations. Override to
+ * NONE.
+ */
+ qatPacketType =
+ ICP_QAT_FW_LA_PARTIAL_NONE;
+ }
+ if (CPA_TRUE ==
+ pSessionDesc->digestIsAppended) {
+ /*Check if the destination buffer can
+ * handle the digest
+ * if digestIsAppend is true*/
+ if (srcPktSize <
+ (authOffsetInBytes +
+ authLenInBytes +
+ pSessionDesc->hashResultSize)) {
+ status =
+ CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ /* populate the hash request parameters
+ */
+ status =
+ LacSymQat_HashRequestParamsPopulate(
+ pMsg,
+ authOffsetInBytes,
+ authLenInBytes,
+ &(pService
+ ->generic_service_info),
+ pHashStateBufferInfo,
+ qatPacketType,
+ pSessionDesc->hashResultSize,
+ pSessionDesc->digestVerify,
+ pSessionDesc->digestIsAppended ?
+ NULL :
+ pDigestResult,
+ pSessionDesc->hashAlgorithm,
+ NULL);
+ }
+ }
+ }
+ }
+
+ /*
+ * send the message to the QAT
+ */
+ if (CPA_STATUS_SUCCESS == status) {
+ qatUtilsAtomicInc(&(pSessionDesc->u.pendingCbCount));
+
+ status = LacSymQueue_RequestSend(instanceHandle,
+ pCookie,
+ pSessionDesc);
+
+ if (CPA_STATUS_SUCCESS != status) {
+ /* Decrease pending callback counter on send fail. */
+ qatUtilsAtomicDec(&(pSessionDesc->u.pendingCbCount));
+ }
+ }
+ /* Case that will catch all error status's for this function */
+ if (CPA_STATUS_SUCCESS != status) {
+ /* free the cookie */
+ if (NULL != pSymCookie) {
+ Lac_MemPoolEntryFree(pSymCookie);
+ }
+ }
+ return status;
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_api.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_api.c
new file mode 100644
index 000000000000..70446ef988b0
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_api.c
@@ -0,0 +1,1130 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_api.c Implementation of the symmetric API
+ *
+ * @ingroup LacSym
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "cpa_cy_im.h"
+
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_transport_dp.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "icp_qat_fw_la.h"
+
+/*
+ ******************************************************************************
+ * Include private header files
+ ******************************************************************************
+ */
+#include "lac_common.h"
+#include "lac_log.h"
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "lac_list.h"
+#include "lac_sym.h"
+#include "lac_sym_qat.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "lac_session.h"
+#include "lac_sym_cipher.h"
+#include "lac_sym_hash.h"
+#include "lac_sym_alg_chain.h"
+#include "lac_sym_stats.h"
+#include "lac_sym_partial.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym_cb.h"
+#include "lac_buffer_desc.h"
+#include "lac_sync.h"
+#include "lac_hooks.h"
+#include "lac_sal_types_crypto.h"
+#include "sal_service_state.h"
+
+#define IS_EXT_ALG_CHAIN_UNSUPPORTED( \
+ cipherAlgorithm, hashAlgorithm, extAlgchainSupported) \
+ ((((CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm || \
+ CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \
+ CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) || \
+ ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \
+ CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \
+ CPA_CY_SYM_CIPHER_ZUC_EEA3 == cipherAlgorithm) && \
+ CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) || \
+ ((CPA_CY_SYM_CIPHER_NULL == cipherAlgorithm || \
+ CPA_CY_SYM_CIPHER_AES_CTR == cipherAlgorithm || \
+ CPA_CY_SYM_CIPHER_SNOW3G_UEA2 == cipherAlgorithm) && \
+ CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm)) && \
+ !extAlgchainSupported)
+
+/*** Local functions definitions ***/
+static CpaStatus
+LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
+ const CpaBufferList *const pDstBuffer,
+ const lac_session_desc_t *const pSessionDesc,
+ const CpaCySymOpData *const pOpData);
+
+void getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSym
+ * Generic bufferList callback function.
+ * @description
+ * This function is used when the API is called in synchronous mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set the
+ * status and opResult element of that cookie structure and
+ * kick the sid.
+ * This function may be used directly as a callback function.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[in] operationType Operation Type
+ * @param[in] pOpData Pointer to the Op Data
+ * @param[out] pDstBuffer Pointer to destination buffer list
+ * @param[out] opResult Boolean to indicate the result of the operation
+ *
+ * @return void
+ *
+ *****************************************************************************/
+void
+LacSync_GenBufListVerifyCb(void *pCallbackTag,
+ CpaStatus status,
+ CpaCySymOp operationType,
+ void *pOpData,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean opResult)
+{
+ LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
+}
+
+/*
+*******************************************************************************
+* Define static function definitions
+*******************************************************************************
+*/
+/**
+ * @ingroup LacSym
+ * Function which perform parameter checks on session setup data
+ *
+ * @param[in] CpaInstanceHandle Instance Handle
+ * @param[in] pSessionSetupData Pointer to session setup data
+ *
+ * @retval CPA_STATUS_SUCCESS The operation succeeded
+ * @retval CPA_STATUS_INVALID_PARAM An invalid parameter value was found
+ */
+static CpaStatus
+LacSymSession_ParamCheck(const CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionSetupData)
+{
+ /* initialize convenient pointers to cipher and hash contexts */
+ const CpaCySymCipherSetupData *const pCipherSetupData =
+ (const CpaCySymCipherSetupData *)&pSessionSetupData
+ ->cipherSetupData;
+ const CpaCySymHashSetupData *const pHashSetupData =
+ &pSessionSetupData->hashSetupData;
+
+ CpaCySymCapabilitiesInfo capInfo;
+ CpaCyCapabilitiesInfo cyCapInfo;
+ cpaCySymQueryCapabilities(instanceHandle, &capInfo);
+ SalCtrl_CyQueryCapabilities(instanceHandle, &cyCapInfo);
+
+ /* Ensure cipher algorithm is correct and supported */
+ if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
+ pSessionSetupData->symOperation) ||
+ (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation)) {
+ /* Protect against value of cipher outside the bitmap
+ * and check if cipher algorithm is correct
+ */
+ if ((pCipherSetupData->cipherAlgorithm >=
+ CPA_CY_SYM_CIPHER_CAP_BITMAP_SIZE) ||
+ (!CPA_BITMAP_BIT_TEST(capInfo.ciphers,
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG("cipherAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Ensure hash algorithm is correct and supported */
+ if ((CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
+ pSessionSetupData->symOperation) ||
+ (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation)) {
+ /* Ensure SHAKE algorithms are not supported */
+ if ((CPA_CY_SYM_HASH_SHAKE_128 ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHAKE_256 ==
+ pHashSetupData->hashAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Hash algorithms SHAKE-128 and SHAKE-256 "
+ "are not supported.");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ /* Protect against value of hash outside the bitmap
+ * and check if hash algorithm is correct
+ */
+ if ((pHashSetupData->hashAlgorithm >=
+ CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) ||
+ (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
+ pHashSetupData->hashAlgorithm))) {
+ LAC_INVALID_PARAM_LOG("hashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* ensure CCM, GCM, Kasumi, Snow3G and ZUC cipher and hash algorithms
+ * are
+ * selected together for Algorithm Chaining */
+ if (CPA_CY_SYM_OP_ALGORITHM_CHAINING ==
+ pSessionSetupData->symOperation) {
+ /* ensure both hash and cipher algorithms are POLY and CHACHA */
+ if (((CPA_CY_SYM_CIPHER_CHACHA ==
+ pCipherSetupData->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_POLY != pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm) &&
+ (CPA_CY_SYM_CIPHER_CHACHA !=
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash "
+ "Algorithms for CHACHA/POLY");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure both hash and cipher algorithms are CCM */
+ if (((CPA_CY_SYM_CIPHER_AES_CCM ==
+ pCipherSetupData->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_AES_CCM !=
+ pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_AES_CCM ==
+ pHashSetupData->hashAlgorithm) &&
+ (CPA_CY_SYM_CIPHER_AES_CCM !=
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash Algorithms for CCM");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure both hash and cipher algorithms are GCM/GMAC */
+ if ((CPA_CY_SYM_CIPHER_AES_GCM ==
+ pCipherSetupData->cipherAlgorithm &&
+ (CPA_CY_SYM_HASH_AES_GCM !=
+ pHashSetupData->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GMAC !=
+ pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_AES_GCM ==
+ pHashSetupData->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_GMAC ==
+ pHashSetupData->hashAlgorithm) &&
+ CPA_CY_SYM_CIPHER_AES_GCM !=
+ pCipherSetupData->cipherAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash Algorithms for GCM");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure both hash and cipher algorithms are Kasumi */
+ if (((CPA_CY_SYM_CIPHER_KASUMI_F8 ==
+ pCipherSetupData->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_KASUMI_F9 !=
+ pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_KASUMI_F9 ==
+ pHashSetupData->hashAlgorithm) &&
+ (CPA_CY_SYM_CIPHER_KASUMI_F8 !=
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash Algorithms for Kasumi");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (IS_EXT_ALG_CHAIN_UNSUPPORTED(
+ pCipherSetupData->cipherAlgorithm,
+ pHashSetupData->hashAlgorithm,
+ cyCapInfo.extAlgchainSupported)) {
+ LAC_UNSUPPORTED_PARAM_LOG(
+ "ExtAlgChain feature not supported");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ /* ensure both hash and cipher algorithms are Snow3G */
+ if (((CPA_CY_SYM_CIPHER_SNOW3G_UEA2 ==
+ pCipherSetupData->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
+ pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pHashSetupData->hashAlgorithm) &&
+ (CPA_CY_SYM_CIPHER_SNOW3G_UEA2 !=
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash Algorithms for Snow3G");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure both hash and cipher algorithms are ZUC */
+ if (((CPA_CY_SYM_CIPHER_ZUC_EEA3 ==
+ pCipherSetupData->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_ZUC_EIA3 !=
+ pHashSetupData->hashAlgorithm)) ||
+ ((CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pHashSetupData->hashAlgorithm) &&
+ (CPA_CY_SYM_CIPHER_ZUC_EEA3 !=
+ pCipherSetupData->cipherAlgorithm))) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid combination of Cipher/Hash Algorithms for ZUC");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ /* not Algorithm Chaining so prevent CCM/GCM being selected */
+ else if (CPA_CY_SYM_OP_CIPHER == pSessionSetupData->symOperation) {
+ /* ensure cipher algorithm is not CCM or GCM */
+ if ((CPA_CY_SYM_CIPHER_AES_CCM ==
+ pCipherSetupData->cipherAlgorithm) ||
+ (CPA_CY_SYM_CIPHER_AES_GCM ==
+ pCipherSetupData->cipherAlgorithm) ||
+ (CPA_CY_SYM_CIPHER_CHACHA ==
+ pCipherSetupData->cipherAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid Cipher Algorithm for non-Algorithm "
+ "Chaining operation");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_OP_HASH == pSessionSetupData->symOperation) {
+ /* ensure hash algorithm is not CCM or GCM/GMAC */
+ if ((CPA_CY_SYM_HASH_AES_CCM ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GCM ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GMAC ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_POLY == pHashSetupData->hashAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid Hash Algorithm for non-Algorithm Chaining operation");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ /* Unsupported operation. Return error */
+ else {
+ LAC_INVALID_PARAM_LOG("symOperation");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure that cipher direction param is
+ * valid for cipher and algchain ops */
+ if (CPA_CY_SYM_OP_HASH != pSessionSetupData->symOperation) {
+ if ((pCipherSetupData->cipherDirection !=
+ CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT) &&
+ (pCipherSetupData->cipherDirection !=
+ CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT)) {
+ LAC_INVALID_PARAM_LOG("Invalid Cipher Direction");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+
+/**
+ * @ingroup LacSym
+ * Function which perform parameter checks on data buffers for symmetric
+ * crypto operations
+ *
+ * @param[in] pSrcBuffer Pointer to source buffer list
+ * @param[in] pDstBuffer Pointer to destination buffer list
+ * @param[in] pSessionDesc Pointer to session descriptor
+ * @param[in] pOpData Pointer to CryptoSymOpData.
+ *
+ * @retval CPA_STATUS_SUCCESS The operation succeeded
+ * @retval CPA_STATUS_INVALID_PARAM An invalid parameter value was found
+ */
+
+static CpaStatus
+LacSymPerform_BufferParamCheck(const CpaBufferList *const pSrcBuffer,
+ const CpaBufferList *const pDstBuffer,
+ const lac_session_desc_t *const pSessionDesc,
+ const CpaCySymOpData *const pOpData)
+{
+ Cpa64U srcBufferLen = 0, dstBufferLen = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* verify packet type is in correct range */
+ switch (pOpData->packetType) {
+ case CPA_CY_SYM_PACKET_TYPE_FULL:
+ case CPA_CY_SYM_PACKET_TYPE_PARTIAL:
+ case CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL:
+ break;
+ default: {
+ LAC_INVALID_PARAM_LOG("packetType");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
+ CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
+ (0 == pOpData->messageLenToHashInBytes))) {
+ if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
+ pSessionDesc->cipherAlgorithm,
+ pSessionDesc->hashAlgorithm)) {
+ status = LacBuffDesc_BufferListVerifyNull(
+ pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
+ } else {
+ status = LacBuffDesc_BufferListVerify(
+ pSrcBuffer, &srcBufferLen, LAC_NO_ALIGNMENT_SHIFT);
+ }
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_INVALID_PARAM_LOG("Source buffer invalid");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ /* check MetaData !NULL */
+ if (NULL == pSrcBuffer->pPrivateMetaData) {
+ LAC_INVALID_PARAM_LOG(
+ "Source buffer MetaData cannot be NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* out of place checks */
+ if (pSrcBuffer != pDstBuffer) {
+ /* exception for this check is zero length hash requests to
+ * allow */
+ /* for srcBufflen=DstBufferLen=0 */
+ if (!((CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation &&
+ CPA_CY_SYM_HASH_MODE_PLAIN == pSessionDesc->hashMode) &&
+ (0 == pOpData->messageLenToHashInBytes))) {
+ /* Verify buffer(s) for dest packet & return packet
+ * length */
+ if (IS_ZERO_LENGTH_BUFFER_SUPPORTED(
+ pSessionDesc->cipherAlgorithm,
+ pSessionDesc->hashAlgorithm)) {
+ status = LacBuffDesc_BufferListVerifyNull(
+ pDstBuffer,
+ &dstBufferLen,
+ LAC_NO_ALIGNMENT_SHIFT);
+ } else {
+ status = LacBuffDesc_BufferListVerify(
+ pDstBuffer,
+ &dstBufferLen,
+ LAC_NO_ALIGNMENT_SHIFT);
+ }
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_INVALID_PARAM_LOG(
+ "Destination buffer invalid");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ /* check MetaData !NULL */
+ if (NULL == pDstBuffer->pPrivateMetaData) {
+ LAC_INVALID_PARAM_LOG(
+ "Dest buffer MetaData cannot be NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ /* Check that src Buffer and dst Buffer Lengths are equal */
+ if (srcBufferLen != dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "Source and Dest buffer lengths need to be equal ");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* check for partial packet suport for the session operation */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
+ if (CPA_FALSE == pSessionDesc->isPartialSupported) {
+ /* return out here to simplify cleanup */
+ LAC_INVALID_PARAM_LOG(
+ "Partial packets not supported for operation");
+ return CPA_STATUS_INVALID_PARAM;
+ } else {
+ /* This function checks to see if the partial packet
+ * sequence
+ * is correct */
+ if (CPA_STATUS_SUCCESS !=
+ LacSym_PartialPacketStateCheck(
+ pOpData->packetType,
+ pSessionDesc->partialState)) {
+ LAC_INVALID_PARAM_LOG("Partial packet Type");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymInitSession(const CpaInstanceHandle instanceHandle_in,
+ const CpaCySymCbFunc pSymCb,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ CpaCySymSessionCtx pSessionCtx)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle instanceHandle = NULL;
+ sal_service_t *pService = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ pService = (sal_service_t *)instanceHandle;
+
+ /* check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(pService);
+
+ status = LacSym_InitSession(instanceHandle,
+ pSymCb,
+ pSessionSetupData,
+ CPA_FALSE, /* isDPSession */
+ pSessionCtx);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Increment the stats for a session registered successfully */
+ LAC_SYM_STAT_INC(numSessionsInitialized, instanceHandle);
+ } else /* if there was an error */
+ {
+ LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
+ }
+
+ return status;
+}
+
+CpaStatus
+cpaCySymSessionInUse(CpaCySymSessionCtx pSessionCtx, CpaBoolean *pSessionInUse)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ lac_session_desc_t *pSessionDesc = NULL;
+
+ LAC_CHECK_NULL_PARAM(pSessionInUse);
+ LAC_CHECK_INSTANCE_HANDLE(pSessionCtx);
+
+ *pSessionInUse = CPA_FALSE;
+
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
+
+ /* If there are pending requests */
+ if (pSessionDesc->isDPSession) {
+ if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount)))
+ *pSessionInUse = CPA_TRUE;
+ } else {
+ if (qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount)))
+ *pSessionInUse = CPA_TRUE;
+ }
+
+ return status;
+}
+
+CpaStatus
+LacSym_InitSession(const CpaInstanceHandle instanceHandle,
+ const CpaCySymCbFunc pSymCb,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ const CpaBoolean isDPSession,
+ CpaCySymSessionCtx pSessionCtx)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ lac_session_desc_t *pSessionDesc = NULL;
+ Cpa32U sessionCtxSizeInBytes = 0;
+ CpaPhysicalAddr physAddress = 0;
+ CpaPhysicalAddr physAddressAligned = 0;
+ sal_service_t *pService = NULL;
+ const CpaCySymCipherSetupData *pCipherSetupData = NULL;
+ const CpaCySymHashSetupData *pHashSetupData = NULL;
+
+/* Instance param checking done by calling function */
+
+ LAC_CHECK_NULL_PARAM(pSessionSetupData);
+ LAC_CHECK_NULL_PARAM(pSessionCtx);
+ status = LacSymSession_ParamCheck(instanceHandle, pSessionSetupData);
+ LAC_CHECK_STATUS(status);
+
+ /* set the session priority for QAT AL*/
+ if ((CPA_CY_PRIORITY_HIGH == pSessionSetupData->sessionPriority) ||
+ (CPA_CY_PRIORITY_NORMAL == pSessionSetupData->sessionPriority)) {
+ // do nothing - clean up this code. use RANGE macro
+ } else {
+ LAC_INVALID_PARAM_LOG("sessionPriority");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+
+ pCipherSetupData = &pSessionSetupData->cipherSetupData;
+ pHashSetupData = &pSessionSetupData->hashSetupData;
+
+ pService = (sal_service_t *)instanceHandle;
+
+ /* Re-align the session structure to 64 byte alignment */
+ physAddress =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
+ (Cpa8U *)pSessionCtx + sizeof(void *));
+
+ if (0 == physAddress) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the session");
+ return CPA_STATUS_FAIL;
+ }
+
+ physAddressAligned =
+ LAC_ALIGN_POW2_ROUNDUP(physAddress, LAC_64BYTE_ALIGNMENT);
+
+ pSessionDesc = (lac_session_desc_t *)
+ /* Move the session pointer by the physical offset
+ between aligned and unaligned memory */
+ ((Cpa8U *)pSessionCtx + sizeof(void *) +
+ (physAddressAligned - physAddress));
+
+ /* save the aligned pointer in the first bytes (size of unsigned long)
+ * of the session memory */
+ *((LAC_ARCH_UINT *)pSessionCtx) = (LAC_ARCH_UINT)pSessionDesc;
+
+ /* start off with a clean session */
+ /* Choose Session Context size */
+ getCtxSize(pSessionSetupData, &sessionCtxSizeInBytes);
+ switch (sessionCtxSizeInBytes) {
+ case LAC_SYM_SESSION_D1_SIZE:
+ memset(pSessionDesc, 0, sizeof(lac_session_desc_d1_t));
+ break;
+ case LAC_SYM_SESSION_D2_SIZE:
+ memset(pSessionDesc, 0, sizeof(lac_session_desc_d2_t));
+ break;
+ default:
+ memset(pSessionDesc, 0, sizeof(lac_session_desc_t));
+ break;
+ }
+
+ /* Setup content descriptor info structure
+ * assumption that content descriptor is the first field in
+ * in the session descriptor */
+ pSessionDesc->contentDescInfo.pData = (Cpa8U *)pSessionDesc;
+ pSessionDesc->contentDescInfo.hardwareSetupBlockPhys =
+ physAddressAligned;
+
+ pSessionDesc->contentDescOptimisedInfo.pData =
+ ((Cpa8U *)pSessionDesc + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
+ pSessionDesc->contentDescOptimisedInfo.hardwareSetupBlockPhys =
+ (physAddressAligned + LAC_SYM_QAT_CONTENT_DESC_MAX_SIZE);
+
+ /* Set the Common Session Information */
+ pSessionDesc->symOperation = pSessionSetupData->symOperation;
+
+ if (CPA_FALSE == isDPSession) {
+ /* For asynchronous - use the user supplied callback
+ * for synchronous - use the internal synchronous callback */
+ pSessionDesc->pSymCb = ((void *)NULL != (void *)pSymCb) ?
+ pSymCb :
+ LacSync_GenBufListVerifyCb;
+ }
+
+ pSessionDesc->isDPSession = isDPSession;
+ if ((CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_CIPHER_CHACHA == pCipherSetupData->cipherAlgorithm) ||
+ (CPA_CY_SYM_CIPHER_ARC4 == pCipherSetupData->cipherAlgorithm)) {
+ pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgFull;
+ } else {
+ pSessionDesc->writeRingMsgFunc = LacDp_WriteRingMsgOpt;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* Session set up via API call (not internal one) */
+ /* Services such as DRBG call the crypto api as part of their
+ * service
+ * hence the need to for the flag, it is needed to distinguish
+ * between
+ * an internal and external session.
+ */
+ pSessionDesc->internalSession = CPA_FALSE;
+
+ status = LacAlgChain_SessionInit(instanceHandle,
+ pSessionSetupData,
+ pSessionDesc);
+ }
+ return status;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymRemoveSession(const CpaInstanceHandle instanceHandle_in,
+ CpaCySymSessionCtx pSessionCtx)
+{
+ lac_session_desc_t *pSessionDesc = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle instanceHandle = NULL;
+ Cpa64U numPendingRequests = 0;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSessionCtx);
+
+ /* check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pSessionCtx);
+
+ LAC_CHECK_NULL_PARAM(pSessionDesc);
+
+ if (CPA_TRUE == pSessionDesc->isDPSession) {
+ /*
+ * Based on one instance, we can initialize multiple sessions.
+ * For example, we can initialize the session "X" and session
+ * "Y" with
+ * the same instance "A". If there is no operation pending for
+ * session
+ * "X", we can remove the session "X".
+ *
+ * Now we only check the @pSessionDesc->pendingDpCbCount, if it
+ * becomes
+ * zero, we can remove the session.
+ *
+ * Why?
+ * (1) We increase it in the cpaCySymDpEnqueueOp/
+ * cpaCySymDpEnqueueOpBatch.
+ * (2) We decrease it in the LacSymCb_ProcessCallback.
+ *
+ * If the @pSessionDesc->pendingDpCbCount becomes zero, it means
+ * there is no operation pending for the session "X" anymore, so
+ * we can
+ * remove this session. Maybe there is still some requests left
+ * in the
+ * instance's ring (icp_adf_queueDataToSend() returns true), but
+ * the
+ * request does not belong to "X", it belongs to session "Y".
+ */
+ numPendingRequests =
+ qatUtilsAtomicGet(&(pSessionDesc->u.pendingDpCbCount));
+ } else {
+ numPendingRequests =
+ qatUtilsAtomicGet(&(pSessionDesc->u.pendingCbCount));
+ }
+
+ /* If there are pending requests */
+ if (0 != numPendingRequests) {
+ QAT_UTILS_LOG("There are %llu requests pending\n",
+ (unsigned long long)numPendingRequests);
+ status = CPA_STATUS_RETRY;
+ if (CPA_TRUE == pSessionDesc->isDPSession) {
+ /* Need to update tail if messages queue on tx hi ring
+ for
+ data plane api */
+ icp_comms_trans_handle trans_handle =
+ ((sal_crypto_service_t *)instanceHandle)
+ ->trans_handle_sym_tx;
+
+ if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
+ /* process the remaining messages in the ring */
+ QAT_UTILS_LOG("Submitting enqueued requests\n");
+ /*
+ * SalQatMsg_updateQueueTail
+ */
+ SalQatMsg_updateQueueTail(trans_handle);
+ return status;
+ }
+ }
+ }
+ if (CPA_STATUS_SUCCESS == status) {
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK_DESTROY(&pSessionDesc->requestQueueLock)) {
+ LAC_LOG_ERROR("Failed to destroy request queue lock");
+ }
+ if (CPA_FALSE == pSessionDesc->isDPSession) {
+ LAC_SYM_STAT_INC(numSessionsRemoved, instanceHandle);
+ }
+ } else if (CPA_FALSE == pSessionDesc->isDPSession) {
+ LAC_SYM_STAT_INC(numSessionErrors, instanceHandle);
+ }
+ return status;
+}
+
+/** @ingroup LacSym */
+static CpaStatus
+LacSym_Perform(const CpaInstanceHandle instanceHandle,
+ void *callbackTag,
+ const CpaCySymOpData *pOpData,
+ const CpaBufferList *pSrcBuffer,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean *pVerifyResult,
+ CpaBoolean isAsyncMode)
+{
+ lac_session_desc_t *pSessionDesc = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ /* check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+ LAC_CHECK_NULL_PARAM(pOpData);
+ LAC_CHECK_NULL_PARAM(pOpData->sessionCtx);
+ LAC_CHECK_NULL_PARAM(pSrcBuffer);
+ LAC_CHECK_NULL_PARAM(pDstBuffer);
+
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
+ LAC_CHECK_NULL_PARAM(pSessionDesc);
+
+ /*check whether Payload size is zero for CHACHA-POLY*/
+ if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
+ (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
+ if (!pOpData->messageLenToCipherInBytes) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid messageLenToCipherInBytes for CHACHA-POLY");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+
+ /* If synchronous Operation - Callback function stored in the session
+ * descriptor so a flag is set in the perform to indicate that
+ * the perform is being re-called for the synchronous operation */
+ if ((LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb) &&
+ isAsyncMode == CPA_TRUE) {
+ CpaBoolean opResult = CPA_FALSE;
+ lac_sync_op_data_t *pSyncCallbackData = NULL;
+
+ status = LacSync_CreateSyncCookie(&pSyncCallbackData);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = LacSym_Perform(instanceHandle,
+ pSyncCallbackData,
+ pOpData,
+ pSrcBuffer,
+ pDstBuffer,
+ pVerifyResult,
+ CPA_FALSE);
+ } else {
+ /* Failure allocating sync cookie */
+ LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ CpaStatus syncStatus = CPA_STATUS_SUCCESS;
+ syncStatus = LacSync_WaitForCallback(
+ pSyncCallbackData,
+ LAC_SYM_SYNC_CALLBACK_TIMEOUT,
+ &status,
+ &opResult);
+ /* If callback doesn't come back */
+ if (CPA_STATUS_SUCCESS != syncStatus) {
+ LAC_SYM_STAT_INC(numSymOpCompletedErrors,
+ instanceHandle);
+ LAC_LOG_ERROR("Callback timed out");
+ status = syncStatus;
+ }
+ } else {
+ /* As the Request was not sent the Callback will never
+ * be called, so need to indicate that we're finished
+ * with cookie so it can be destroyed. */
+ LacSync_SetSyncCookieComplete(pSyncCallbackData);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ if (NULL != pVerifyResult) {
+ *pVerifyResult = opResult;
+ }
+ }
+
+ LacSync_DestroySyncCookie(&pSyncCallbackData);
+ return status;
+ }
+
+ status =
+ LacSymPerform_BufferParamCheck((const CpaBufferList *)pSrcBuffer,
+ pDstBuffer,
+ pSessionDesc,
+ pOpData);
+ LAC_CHECK_STATUS(status);
+
+ if ((!pSessionDesc->digestIsAppended) &&
+ (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
+ /* Check that pDigestResult is not NULL */
+ LAC_CHECK_NULL_PARAM(pOpData->pDigestResult);
+ }
+
+ status = LacAlgChain_Perform(instanceHandle,
+ pSessionDesc,
+ callbackTag,
+ pOpData,
+ pSrcBuffer,
+ pDstBuffer,
+ pVerifyResult);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* check for partial packet suport for the session operation */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) {
+ LacSym_PartialPacketStateUpdate(
+ pOpData->packetType, &pSessionDesc->partialState);
+ }
+ /* increment #requests stat */
+ LAC_SYM_STAT_INC(numSymOpRequests, instanceHandle);
+ }
+ /* Retry also results in the errors stat been incremented */
+ else {
+ /* increment #errors stat */
+ LAC_SYM_STAT_INC(numSymOpRequestErrors, instanceHandle);
+ }
+ return status;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymPerformOp(const CpaInstanceHandle instanceHandle_in,
+ void *callbackTag,
+ const CpaCySymOpData *pOpData,
+ const CpaBufferList *pSrcBuffer,
+ CpaBufferList *pDstBuffer,
+ CpaBoolean *pVerifyResult)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ return LacSym_Perform(instanceHandle,
+ callbackTag,
+ pOpData,
+ pSrcBuffer,
+ pDstBuffer,
+ pVerifyResult,
+ CPA_TRUE);
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymQueryStats(const CpaInstanceHandle instanceHandle_in,
+ struct _CpaCySymStats *pSymStats)
+{
+
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSymStats);
+
+ /* check if crypto service is running
+ * otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ /* copy the fields from the internal structure into the api defined
+ * structure */
+ LacSym_Stats32CopyGet(instanceHandle, pSymStats);
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymQueryStats64(const CpaInstanceHandle instanceHandle_in,
+ CpaCySymStats64 *pSymStats)
+{
+
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSymStats);
+
+ /* check if crypto service is running
+ * otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ /* copy the fields from the internal structure into the api defined
+ * structure */
+ LacSym_Stats64CopyGet(instanceHandle, pSymStats);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymSessionCtxGetSize(const CpaInstanceHandle instanceHandle_in,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSessionSetupData);
+ LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
+
+ /* check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+ *pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacSym */
+CpaStatus
+cpaCySymSessionCtxGetDynamicSize(
+ const CpaInstanceHandle instanceHandle_in,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSessionSetupData);
+ LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
+
+ /* check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+ /* Choose Session Context size */
+ getCtxSize(pSessionSetupData, pSessionCtxSizeInBytes);
+
+
+ return CPA_STATUS_SUCCESS;
+}
+
+void
+getCtxSize(const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes)
+{
+ /* using lac_session_desc_d1_t */
+ if ((pSessionSetupData->cipherSetupData.cipherAlgorithm !=
+ CPA_CY_SYM_CIPHER_ARC4) &&
+ (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
+ CPA_CY_SYM_CIPHER_SNOW3G_UEA2) &&
+ (pSessionSetupData->hashSetupData.hashAlgorithm !=
+ CPA_CY_SYM_HASH_SNOW3G_UIA2) &&
+ (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
+ CPA_CY_SYM_CIPHER_AES_CCM) &&
+ (pSessionSetupData->cipherSetupData.cipherAlgorithm !=
+ CPA_CY_SYM_CIPHER_AES_GCM) &&
+ (pSessionSetupData->hashSetupData.hashMode !=
+ CPA_CY_SYM_HASH_MODE_AUTH) &&
+ (pSessionSetupData->hashSetupData.hashMode !=
+ CPA_CY_SYM_HASH_MODE_NESTED) &&
+ (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
+ *pSessionCtxSizeInBytes = LAC_SYM_SESSION_D1_SIZE;
+ }
+ /* using lac_session_desc_d2_t */
+ else if (((pSessionSetupData->cipherSetupData.cipherAlgorithm ==
+ CPA_CY_SYM_CIPHER_AES_CCM) ||
+ (pSessionSetupData->cipherSetupData.cipherAlgorithm ==
+ CPA_CY_SYM_CIPHER_AES_GCM)) &&
+ (pSessionSetupData->partialsNotRequired == CPA_TRUE)) {
+ *pSessionCtxSizeInBytes = LAC_SYM_SESSION_D2_SIZE;
+ }
+ /* using lac_session_desc_t */
+ else {
+ *pSessionCtxSizeInBytes = LAC_SYM_SESSION_SIZE;
+ }
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSym
+ *****************************************************************************/
+CpaStatus
+cpaCyBufferListGetMetaSize(const CpaInstanceHandle instanceHandle_in,
+ Cpa32U numBuffers,
+ Cpa32U *pSizeInBytes)
+{
+
+ CpaInstanceHandle instanceHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSizeInBytes);
+
+ /* In the case of zero buffers we still need to allocate one
+ * descriptor to pass to the firmware */
+ if (0 == numBuffers) {
+ numBuffers = 1;
+ }
+
+ /* Note: icp_buffer_list_desc_t is 8 bytes in size and
+ * icp_flat_buffer_desc_t is 16 bytes in size. Therefore if
+ * icp_buffer_list_desc_t is aligned
+ * so will each icp_flat_buffer_desc_t structure */
+
+ *pSizeInBytes = sizeof(icp_buffer_list_desc_t) +
+ (sizeof(icp_flat_buffer_desc_t) * numBuffers) +
+ ICP_DESCRIPTOR_ALIGNMENT_BYTES;
+
+
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_auth_enc.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_auth_enc.c
new file mode 100644
index 000000000000..fe46b7eee3df
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_auth_enc.c
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_auth_enc.c
+ *
+ * @ingroup LacAuthEnc
+ *
+ * @description
+ * Authenticated encryption specific functionality.
+ * For CCM related code NIST SP 800-38C is followed.
+ * For GCM related code NIST SP 800-38D is followed.
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "lac_log.h"
+#include "lac_common.h"
+#include "lac_session.h"
+#include "lac_sym_auth_enc.h"
+
+/* These defines describe position of the flag fields
+ * in B0 block for CCM algorithm*/
+#define LAC_ALG_CHAIN_CCM_B0_FLAGS_ADATA_SHIFT 6
+#define LAC_ALG_CHAIN_CCM_B0_FLAGS_T_SHIFT 3
+
+/* This macro builds flags field to be put in B0 block for CCM algorithm */
+#define LAC_ALG_CHAIN_CCM_BUILD_B0_FLAGS(Adata, t, q) \
+ ((((Adata) > 0 ? 1 : 0) << LAC_ALG_CHAIN_CCM_B0_FLAGS_ADATA_SHIFT) | \
+ ((((t)-2) >> 1) << LAC_ALG_CHAIN_CCM_B0_FLAGS_T_SHIFT) | ((q)-1))
+
+/**
+ * @ingroup LacAuthEnc
+ */
+CpaStatus
+LacSymAlgChain_CheckCCMData(Cpa8U *pAdditionalAuthData,
+ Cpa8U *pIv,
+ Cpa32U messageLenToCipherInBytes,
+ Cpa32U ivLenInBytes)
+{
+ Cpa8U q = 0;
+
+ LAC_CHECK_NULL_PARAM(pIv);
+ LAC_CHECK_NULL_PARAM(pAdditionalAuthData);
+
+ /* check if n is within permitted range */
+ if (ivLenInBytes < LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MIN ||
+ ivLenInBytes > LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MAX) {
+ LAC_INVALID_PARAM_LOG2("ivLenInBytes for CCM algorithm "
+ "must be between %d and %d inclusive",
+ LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MIN,
+ LAC_ALG_CHAIN_CCM_N_LEN_IN_BYTES_MAX);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ q = LAC_ALG_CHAIN_CCM_NQ_CONST - ivLenInBytes;
+
+ /* Check if q is big enough to hold actual length of message to cipher
+ * if q = 8 -> maxlen = 2^64 always good as
+ * messageLenToCipherInBytes is 32 bits
+ * if q = 7 -> maxlen = 2^56 always good
+ * if q = 6 -> maxlen = 2^48 always good
+ * if q = 5 -> maxlen = 2^40 always good
+ * if q = 4 -> maxlen = 2^32 always good.
+ */
+ if ((messageLenToCipherInBytes >= (1 << (q * LAC_NUM_BITS_IN_BYTE))) &&
+ (q < sizeof(Cpa32U))) {
+ LAC_INVALID_PARAM_LOG(
+ "messageLenToCipherInBytes too long for the given"
+ " ivLenInBytes for CCM algorithm\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+
+/**
+ * @ingroup LacAuthEnc
+ */
+void
+LacSymAlgChain_PrepareCCMData(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAdditionalAuthData,
+ Cpa8U *pIv,
+ Cpa32U messageLenToCipherInBytes,
+ Cpa32U ivLenInBytes)
+{
+ Cpa8U n =
+ ivLenInBytes; /* assumes ivLenInBytes has been param checked */
+ Cpa8U q = LAC_ALG_CHAIN_CCM_NQ_CONST - n;
+ Cpa8U lenOfEncodedLen = 0;
+ Cpa16U lenAEncoded = 0;
+ Cpa32U bitStrQ = 0;
+
+ /* populate Ctr0 block - stored in pIv */
+ pIv[0] = (q - 1);
+ /* bytes 1 to n are already set with nonce by the user */
+ /* set last q bytes with 0 */
+ memset(pIv + n + 1, 0, q);
+
+ /* Encode the length of associated data 'a'. As the API limits the
+ * length
+ * of an array pointed by pAdditionalAuthData to be 240 bytes max, the
+ * maximum length of 'a' might be 240 - 16 - 2 = 222. Hence the encoding
+ * below is simplified. */
+ if (pSessionDesc->aadLenInBytes > 0) {
+ lenOfEncodedLen = sizeof(Cpa16U);
+ lenAEncoded = QAT_UTILS_HOST_TO_NW_16(
+ (Cpa16U)pSessionDesc->aadLenInBytes);
+ }
+
+ /* populate B0 block */
+ /* first, set the flags field */
+ pAdditionalAuthData[0] =
+ LAC_ALG_CHAIN_CCM_BUILD_B0_FLAGS(lenOfEncodedLen,
+ pSessionDesc->hashResultSize,
+ q);
+ /* bytes 1 to n are already set with nonce by the user*/
+ /* put Q in bytes 16-q...15 */
+ bitStrQ = QAT_UTILS_HOST_TO_NW_32(messageLenToCipherInBytes);
+
+ if (q > sizeof(bitStrQ)) {
+ memset(pAdditionalAuthData + n + 1, 0, q);
+ memcpy(pAdditionalAuthData + n + 1 + (q - sizeof(bitStrQ)),
+ (Cpa8U *)&bitStrQ,
+ sizeof(bitStrQ));
+ } else {
+ memcpy(pAdditionalAuthData + n + 1,
+ ((Cpa8U *)&bitStrQ) + (sizeof(bitStrQ) - q),
+ q);
+ }
+
+ /* populate B1-Bn blocks */
+ if (lenAEncoded > 0) {
+ *(Cpa16U
+ *)(&pAdditionalAuthData[1 + LAC_ALG_CHAIN_CCM_NQ_CONST]) =
+ lenAEncoded;
+ /* Next bytes are already set by the user with
+ * the associated data 'a' */
+
+ /* Check if padding is required */
+ if (((pSessionDesc->aadLenInBytes + lenOfEncodedLen) %
+ LAC_HASH_AES_CCM_BLOCK_SIZE) != 0) {
+ Cpa8U paddingLen = 0;
+ Cpa8U paddingIndex = 0;
+
+ paddingLen = LAC_HASH_AES_CCM_BLOCK_SIZE -
+ ((pSessionDesc->aadLenInBytes + lenOfEncodedLen) %
+ LAC_HASH_AES_CCM_BLOCK_SIZE);
+
+ paddingIndex = 1 + LAC_ALG_CHAIN_CCM_NQ_CONST;
+ paddingIndex +=
+ lenOfEncodedLen + pSessionDesc->aadLenInBytes;
+
+ memset(&pAdditionalAuthData[paddingIndex],
+ 0,
+ paddingLen);
+ }
+ }
+}
+
+/**
+ * @ingroup LacAuthEnc
+ */
+void
+LacSymAlgChain_PrepareGCMData(lac_session_desc_t *pSessionDesc,
+ Cpa8U *pAdditionalAuthData)
+{
+ Cpa8U paddingLen = 0;
+
+ if ((pSessionDesc->aadLenInBytes % LAC_HASH_AES_GCM_BLOCK_SIZE) != 0) {
+ paddingLen = LAC_HASH_AES_GCM_BLOCK_SIZE -
+ (pSessionDesc->aadLenInBytes % LAC_HASH_AES_GCM_BLOCK_SIZE);
+
+ memset(&pAdditionalAuthData[pSessionDesc->aadLenInBytes],
+ 0,
+ paddingLen);
+ }
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cb.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cb.c
new file mode 100644
index 000000000000..8fa0a798304e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cb.c
@@ -0,0 +1,545 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_cb.c Callback handler functions for symmetric components
+ *
+ * @ingroup LacSym
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_qat_fw_la.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+
+#include "lac_sym.h"
+#include "lac_sym_cipher.h"
+#include "lac_common.h"
+#include "lac_list.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "lac_session.h"
+#include "lac_sym_stats.h"
+#include "lac_log.h"
+#include "lac_sym_cb.h"
+#include "lac_sym_hash.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_sym_qat.h"
+
+#define DEQUEUE_MSGPUT_MAX_RETRIES 10000
+
+/*
+*******************************************************************************
+* Define static function definitions
+*******************************************************************************
+*/
+
+/**
+ *****************************************************************************
+ * @ingroup LacSymCb
+ * Function to clean computed data.
+ *
+ * @description
+ * This function cleans GCM or CCM data in the case of a failure.
+ *
+ * @param[in] pSessionDesc pointer to the session descriptor
+ * @param[out] pBufferList pointer to the bufferlist to clean
+ * @param[in] pOpData pointer to operation data
+ * @param[in] isCCM is it a CCM operation boolean
+ *
+ * @return None
+ *****************************************************************************/
+static void
+LacSymCb_CleanUserData(const lac_session_desc_t *pSessionDesc,
+ CpaBufferList *pBufferList,
+ const CpaCySymOpData *pOpData,
+ CpaBoolean isCCM)
+{
+ Cpa8U authTagLen = 0;
+
+ /* Retrieve authTagLen */
+ authTagLen = pSessionDesc->hashResultSize;
+
+ /* Cleaning */
+ if (isCCM) {
+ /* for CCM the digest is inside the buffer list */
+ LacBuffDesc_BufferListZeroFromOffset(
+ pBufferList,
+ pOpData->cryptoStartSrcOffsetInBytes,
+ pOpData->messageLenToCipherInBytes + authTagLen);
+ } else {
+ /* clean buffer list */
+ LacBuffDesc_BufferListZeroFromOffset(
+ pBufferList,
+ pOpData->cryptoStartSrcOffsetInBytes,
+ pOpData->messageLenToCipherInBytes);
+ }
+ if ((CPA_TRUE != pSessionDesc->digestIsAppended) &&
+ (NULL != pOpData->pDigestResult)) {
+ /* clean digest */
+ memset(pOpData->pDigestResult, 0, authTagLen);
+ }
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSymCb
+ * Definition of callback function for processing symmetric responses
+ *
+ * @description
+ * This callback is invoked to process symmetric response messages from
+ * the QAT. It will extract some details from the message and invoke
+ * the user's callback to complete a symmetric operation.
+ *
+ * @param[in] pCookie Pointer to cookie associated with this request
+ * @param[in] qatRespStatusOkFlag Boolean indicating ok/fail status from QAT
+ * @param[in] status Status variable indicating an error occurred
+ * in sending the message (e.g. when dequeueing)
+ * @param[in] pSessionDesc Session descriptor
+ *
+ * @return None
+ *****************************************************************************/
+static void
+LacSymCb_ProcessCallbackInternal(lac_sym_bulk_cookie_t *pCookie,
+ CpaBoolean qatRespStatusOkFlag,
+ CpaStatus status,
+ lac_session_desc_t *pSessionDesc)
+{
+ CpaCySymCbFunc pSymCb = NULL;
+ void *pCallbackTag = NULL;
+ CpaCySymOpData *pOpData = NULL;
+ CpaBufferList *pDstBuffer = NULL;
+ CpaCySymOp operationType = CPA_CY_SYM_OP_NONE;
+ CpaStatus dequeueStatus = CPA_STATUS_SUCCESS;
+
+ CpaInstanceHandle instanceHandle = CPA_INSTANCE_HANDLE_SINGLE;
+ /* NOTE: cookie pointer validated in previous function */
+ instanceHandle = pCookie->instanceHandle;
+
+ pOpData = (CpaCySymOpData *)LAC_CONST_PTR_CAST(pCookie->pOpData);
+ operationType = pSessionDesc->symOperation;
+
+ /* Set the destination pointer to the one supplied in the cookie. */
+ pDstBuffer = pCookie->pDstBuffer;
+
+ /* For a digest verify operation - for full packet and final partial
+ * only, perform a comparison with the digest generated and with the one
+ * supplied in the packet. */
+
+ if (((pSessionDesc->isSinglePass &&
+ (CPA_CY_SYM_CIPHER_AES_GCM == pSessionDesc->cipherAlgorithm)) ||
+ (CPA_CY_SYM_OP_CIPHER != operationType)) &&
+ (CPA_TRUE == pSessionDesc->digestVerify) &&
+ ((CPA_CY_SYM_PACKET_TYPE_FULL == pOpData->packetType) ||
+ (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == pOpData->packetType))) {
+ if (CPA_FALSE == qatRespStatusOkFlag) {
+ LAC_SYM_STAT_INC(numSymOpVerifyFailures,
+ instanceHandle);
+
+ /* The comparison has failed at this point (status is
+ * fail),
+ * need to clean any sensitive calculated data up to
+ * this point.
+ * The data calculated is no longer useful to the end
+ * result and
+ * does not need to be returned to the user so setting
+ * buffers to
+ * zero.
+ */
+ if (pSessionDesc->cipherAlgorithm ==
+ CPA_CY_SYM_CIPHER_AES_CCM) {
+ LacSymCb_CleanUserData(pSessionDesc,
+ pDstBuffer,
+ pOpData,
+ CPA_TRUE);
+ } else if (pSessionDesc->cipherAlgorithm ==
+ CPA_CY_SYM_CIPHER_AES_GCM) {
+ LacSymCb_CleanUserData(pSessionDesc,
+ pDstBuffer,
+ pOpData,
+ CPA_FALSE);
+ }
+ }
+ } else {
+ /* Most commands have no point of failure and always return
+ * success. This is the default response from the QAT.
+ * If status is already set to an error value, don't overwrite
+ * it
+ */
+ if ((CPA_STATUS_SUCCESS == status) &&
+ (CPA_TRUE != qatRespStatusOkFlag)) {
+ LAC_LOG_ERROR("Response status value not as expected");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+
+ pSymCb = pSessionDesc->pSymCb;
+ pCallbackTag = pCookie->pCallbackTag;
+
+ /* State returned to the client for intermediate partials packets
+ * for hash only and cipher only partial packets. Cipher update
+ * allow next partial through */
+ if (CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) {
+ if ((CPA_CY_SYM_OP_CIPHER == operationType) ||
+ (CPA_CY_SYM_OP_ALGORITHM_CHAINING == operationType)) {
+ if (CPA_TRUE == pCookie->updateUserIvOnRecieve) {
+ /* Update the user's IV buffer
+ * Very important to do this BEFORE dequeuing
+ * subsequent partial requests, as the state
+ * buffer
+ * may get overwritten
+ */
+ memcpy(pCookie->pOpData->pIv,
+ pSessionDesc->cipherPartialOpState,
+ pCookie->pOpData->ivLenInBytes);
+ }
+ if (CPA_TRUE == pCookie->updateKeySizeOnRecieve &&
+ LAC_CIPHER_IS_XTS_MODE(
+ pSessionDesc->cipherAlgorithm)) {
+ LacSymQat_CipherXTSModeUpdateKeyLen(
+ pSessionDesc,
+ pSessionDesc->cipherKeyLenInBytes / 2);
+ }
+ }
+ } else if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == pOpData->packetType) {
+ if ((CPA_CY_SYM_OP_CIPHER == operationType) ||
+ (CPA_CY_SYM_OP_ALGORITHM_CHAINING == operationType)) {
+ if (CPA_TRUE == LAC_CIPHER_IS_XTS_MODE(
+ pSessionDesc->cipherAlgorithm)) {
+ /*
+ * For XTS mode, we replace the updated key with
+ * the original key - for subsequent partial
+ * requests
+ *
+ */
+ LacSymQat_CipherXTSModeUpdateKeyLen(
+ pSessionDesc,
+ pSessionDesc->cipherKeyLenInBytes);
+ }
+ }
+ }
+
+ if ((CPA_CY_SYM_PACKET_TYPE_FULL != pOpData->packetType) &&
+ (qatRespStatusOkFlag != CPA_FALSE)) {
+ /* There may be requests blocked pending the completion of this
+ * operation
+ */
+
+ dequeueStatus = LacSymCb_PendingReqsDequeue(pSessionDesc);
+ if (CPA_STATUS_SUCCESS != dequeueStatus) {
+ LAC_SYM_STAT_INC(numSymOpCompletedErrors,
+ instanceHandle);
+ qatRespStatusOkFlag = CPA_FALSE;
+ if (CPA_STATUS_SUCCESS == status) {
+ status = dequeueStatus;
+ }
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* update stats */
+ if (pSessionDesc->internalSession == CPA_FALSE) {
+ LAC_SYM_STAT_INC(numSymOpCompleted, instanceHandle);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_SYM_STAT_INC(numSymOpCompletedErrors,
+ instanceHandle);
+ }
+ }
+ }
+
+ qatUtilsAtomicDec(&(pSessionDesc->u.pendingCbCount));
+
+ /* deallocate the memory for the internal callback cookie */
+ Lac_MemPoolEntryFree(pCookie);
+
+ /* user callback function is the last thing to be called */
+ pSymCb(pCallbackTag,
+ status,
+ operationType,
+ pOpData,
+ pDstBuffer,
+ qatRespStatusOkFlag);
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymCb
+ * Definition of callback function for processing symmetric Data Plane
+ * responses
+ *
+ * @description
+ * This callback checks the status, decrements the number of operations
+ * pending and calls the user callback
+ *
+ * @param[in/out] pResponse pointer to the response structure
+ * @param[in] qatRespStatusOkFlag status
+ * @param[in] pSessionDesc pointer to the session descriptor
+ *
+ * @return None
+ ******************************************************************************/
+static void
+LacSymCb_ProcessDpCallback(CpaCySymDpOpData *pResponse,
+ CpaBoolean qatRespStatusOkFlag,
+ lac_session_desc_t *pSessionDesc)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* For CCM and GCM, if qatRespStatusOkFlag is false, the data has to be
+ * cleaned as stated in RFC 3610; in DP mode, it is the user
+ * responsability
+ * to do so */
+
+ if (CPA_FALSE == pSessionDesc->isSinglePass) {
+ if ((CPA_CY_SYM_OP_CIPHER == pSessionDesc->symOperation) ||
+ (CPA_FALSE == pSessionDesc->digestVerify)) {
+ /* If not doing digest compare and qatRespStatusOkFlag
+ !=
+ CPA_TRUE
+ then there is something very wrong */
+ if (CPA_FALSE == qatRespStatusOkFlag) {
+ LAC_LOG_ERROR(
+ "Response status value not as expected");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ }
+
+ ((sal_crypto_service_t *)pResponse->instanceHandle)
+ ->pSymDpCb(pResponse, status, qatRespStatusOkFlag);
+ /*
+ * Decrement the number of pending CB.
+ *
+ * If the @pendingDpCbCount becomes zero, we may remove the session,
+ * please
+ * read more information in the cpaCySymRemoveSession().
+ *
+ * But there is a field in the @pResponse to store the session,
+ * the "sessionCtx". In another word, in the above @->pSymDpCb()
+ * callback,
+ * it may use the session again. If we decrease the @pendingDpCbCount
+ * before
+ * the @->pSymDpCb(), there is a _risk_ the @->pSymDpCb() may reference
+ * to
+ * a deleted session.
+ *
+ * So in order to avoid the risk, we decrease the @pendingDpCbCount
+ * after
+ * the @->pSymDpCb() callback.
+ */
+ qatUtilsAtomicDec(&pSessionDesc->u.pendingDpCbCount);
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymCb
+ * Definition of callback function for processing symmetric responses
+ *
+ * @description
+ * This callback, which is registered with the common symmetric response
+ * message handler, is invoked to process symmetric response messages from
+ * the QAT. It will extract the response status from the cmnRespFlags set
+ * by the QAT, and then will pass it to @ref
+ * LacSymCb_ProcessCallbackInternal to complete the response processing.
+ *
+ * @param[in] lacCmdId ID of the symmetric QAT command of the request
+ * message
+ * @param[in] pOpaqueData pointer to opaque data in the request message
+ * @param[in] cmnRespFlags Flags set by QAT to indicate response status
+ *
+ * @return None
+ ******************************************************************************/
+static void
+LacSymCb_ProcessCallback(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags)
+{
+ CpaCySymDpOpData *pDpOpData = (CpaCySymDpOpData *)pOpaqueData;
+ lac_session_desc_t *pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pDpOpData->sessionCtx);
+ CpaBoolean qatRespStatusOkFlag =
+ (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
+ ICP_QAT_FW_COMN_RESP_CRYPTO_STAT_GET(cmnRespFlags));
+
+ if (CPA_TRUE == pSessionDesc->isDPSession) {
+ /* DP session */
+ LacSymCb_ProcessDpCallback(pDpOpData,
+ qatRespStatusOkFlag,
+ pSessionDesc);
+ } else {
+ /* Trad session */
+ LacSymCb_ProcessCallbackInternal((lac_sym_bulk_cookie_t *)
+ pOpaqueData,
+ qatRespStatusOkFlag,
+ CPA_STATUS_SUCCESS,
+ pSessionDesc);
+ }
+}
+
+/*
+*******************************************************************************
+* Define public/global function definitions
+*******************************************************************************
+*/
+
+/**
+ * @ingroup LacSymCb
+ *
+ * @return CpaStatus
+ * value returned will be the result of icp_adf_transPutMsg
+ */
+CpaStatus
+LacSymCb_PendingReqsDequeue(lac_session_desc_t *pSessionDesc)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = NULL;
+ Cpa32U retries = 0;
+
+ pService = (sal_crypto_service_t *)pSessionDesc->pInstance;
+
+ /* Need to protect access to queue head and tail pointers, which may
+ * be accessed by multiple contexts simultaneously for enqueue and
+ * dequeue operations
+ */
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK(&pSessionDesc->requestQueueLock)) {
+ LAC_LOG_ERROR("Failed to lock request queue");
+ return CPA_STATUS_RESOURCE;
+ }
+
+ /* Clear the blocking flag in the session descriptor */
+ pSessionDesc->nonBlockingOpsInProgress = CPA_TRUE;
+
+ while ((NULL != pSessionDesc->pRequestQueueHead) &&
+ (CPA_TRUE == pSessionDesc->nonBlockingOpsInProgress)) {
+
+ /* If we send a partial packet request, set the
+ * blockingOpsInProgress
+ * flag for the session to indicate that subsequent requests
+ * must be
+ * queued up until this request completes
+ */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL !=
+ pSessionDesc->pRequestQueueHead->pOpData->packetType) {
+ pSessionDesc->nonBlockingOpsInProgress = CPA_FALSE;
+ }
+
+ /* At this point, we're clear to send the request. For cipher
+ * requests,
+ * we need to check if the session IV needs to be updated. This
+ * can
+ * only be done when no other partials are in flight for this
+ * session,
+ * to ensure the cipherPartialOpState buffer in the session
+ * descriptor
+ * is not currently in use
+ */
+ if (CPA_TRUE ==
+ pSessionDesc->pRequestQueueHead->updateSessionIvOnSend) {
+ if (LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm)) {
+ memcpy(pSessionDesc->cipherPartialOpState,
+ pSessionDesc->cipherARC4InitialState,
+ LAC_CIPHER_ARC4_STATE_LEN_BYTES);
+ } else {
+ memcpy(pSessionDesc->cipherPartialOpState,
+ pSessionDesc->pRequestQueueHead->pOpData
+ ->pIv,
+ pSessionDesc->pRequestQueueHead->pOpData
+ ->ivLenInBytes);
+ }
+ }
+
+ /*
+ * Now we'll attempt to send the message directly to QAT. We'll
+ * keep
+ * looing until it succeeds (or at least a very high number of
+ * retries),
+ * as the failure only happens when the ring is full, and this
+ * is only
+ * a temporary situation. After a few retries, space will become
+ * availble, allowing the putMsg to succeed.
+ */
+ retries = 0;
+ do {
+ /* Send to QAT */
+ status = icp_adf_transPutMsg(
+ pService->trans_handle_sym_tx,
+ (void *)&(pSessionDesc->pRequestQueueHead->qatMsg),
+ LAC_QAT_SYM_REQ_SZ_LW);
+
+ retries++;
+ /*
+ * Yield to allow other threads that may be on this
+ * session to poll
+ * and make some space on the ring
+ */
+ if (CPA_STATUS_SUCCESS != status) {
+ qatUtilsYield();
+ }
+ } while ((CPA_STATUS_SUCCESS != status) &&
+ (retries < DEQUEUE_MSGPUT_MAX_RETRIES));
+
+ if ((CPA_STATUS_SUCCESS != status) ||
+ (retries >= DEQUEUE_MSGPUT_MAX_RETRIES)) {
+ LAC_LOG_ERROR(
+ "Failed to SalQatMsg_transPutMsg, maximum retries exceeded.");
+ goto cleanup;
+ }
+
+ pSessionDesc->pRequestQueueHead =
+ pSessionDesc->pRequestQueueHead->pNext;
+ }
+
+ /* If we've drained the queue, ensure the tail pointer is set to NULL */
+ if (NULL == pSessionDesc->pRequestQueueHead) {
+ pSessionDesc->pRequestQueueTail = NULL;
+ }
+
+cleanup:
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&pSessionDesc->requestQueueLock)) {
+ LAC_LOG_ERROR("Failed to unlock request queue");
+ }
+ return status;
+}
+
+/**
+ * @ingroup LacSymCb
+ */
+void
+LacSymCb_CallbacksRegister()
+{
+ /*** HASH ***/
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_AUTH,
+ LacSymCb_ProcessCallback);
+
+ /*** ALGORITHM-CHAINING CIPHER_HASH***/
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_CIPHER_HASH,
+ LacSymCb_ProcessCallback);
+
+ /*** ALGORITHM-CHAINING HASH_CIPHER***/
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_HASH_CIPHER,
+ LacSymCb_ProcessCallback);
+
+ /*** CIPHER ***/
+ LacSymQat_RespHandlerRegister(ICP_QAT_FW_LA_CMD_CIPHER,
+ LacSymCb_ProcessCallback);
+
+ /* Call compile time param check function to ensure it is included
+ in the build by the compiler - this compile time check
+ ensures callbacks run as expected */
+ LacSym_CompileTimeAssertions();
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c
new file mode 100644
index 000000000000..0039c1f66884
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_cipher.c
@@ -0,0 +1,416 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_cipher.c Cipher
+ *
+ * @ingroup LacCipher
+ *
+ * @description Functions specific to cipher
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+
+#include "icp_qat_fw_la.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "lac_sym_cipher.h"
+#include "lac_session.h"
+#include "lac_mem.h"
+#include "lac_common.h"
+#include "lac_list.h"
+#include "lac_sym.h"
+#include "lac_sym_key.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "lac_sym_cipher_defs.h"
+#include "lac_sym_cipher.h"
+#include "lac_sym_stats.h"
+#include "lac_sym.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_log.h"
+#include "lac_buffer_desc.h"
+
+/*
+*******************************************************************************
+* Static Variables
+*******************************************************************************
+*/
+
+CpaStatus
+LacCipher_PerformIvCheck(sal_service_t *pService,
+ lac_sym_bulk_cookie_t *pCbCookie,
+ Cpa32U qatPacketType,
+ Cpa8U **ppIvBuffer)
+{
+ const CpaCySymOpData *pOpData = pCbCookie->pOpData;
+ lac_session_desc_t *pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pOpData->sessionCtx);
+ CpaCySymCipherAlgorithm algorithm = pSessionDesc->cipherAlgorithm;
+
+ /* Perform IV check. */
+ if (LAC_CIPHER_IS_CTR_MODE(algorithm) ||
+ LAC_CIPHER_IS_CBC_MODE(algorithm) ||
+ LAC_CIPHER_IS_AES_F8(algorithm) ||
+ LAC_CIPHER_IS_XTS_MODE(algorithm)) {
+ unsigned ivLenInBytes =
+ LacSymQat_CipherIvSizeBytesGet(algorithm);
+ LAC_CHECK_NULL_PARAM(pOpData->pIv);
+ if (pOpData->ivLenInBytes != ivLenInBytes) {
+ if (!(/* GCM with 12 byte IV is OK */
+ (LAC_CIPHER_IS_GCM(algorithm) &&
+ pOpData->ivLenInBytes ==
+ LAC_CIPHER_IV_SIZE_GCM_12) ||
+ /* IV len for CCM has been checked before */
+ LAC_CIPHER_IS_CCM(algorithm))) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Always copy the user's IV into another cipher state buffer if
+ * the request is part of a partial packet sequence
+ * (ensures that pipelined partial requests use same
+ * buffer)
+ */
+ if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) {
+ /* Set the value of the ppIvBuffer to that supplied
+ * by the user.
+ * NOTE: There is no guarantee that this address is
+ * aligned on
+ * an 8 or 64 Byte address. */
+ *ppIvBuffer = pOpData->pIv;
+ } else {
+ /* For partial packets, we use a per-session buffer to
+ * maintain
+ * the IV. This allows us to easily pass the updated IV
+ * forward
+ * to the next partial in the sequence. This makes
+ * internal
+ * buffering of partials easier to implement.
+ */
+ *ppIvBuffer = pSessionDesc->cipherPartialOpState;
+
+ /* Ensure that the user's IV buffer gets updated between
+ * partial
+ * requests so that they may also see the residue from
+ * the
+ * previous partial. Not needed for final partials
+ * though.
+ */
+ if ((ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) ||
+ (ICP_QAT_FW_LA_PARTIAL_MID == qatPacketType)) {
+ pCbCookie->updateUserIvOnRecieve = CPA_TRUE;
+
+ if (ICP_QAT_FW_LA_PARTIAL_START ==
+ qatPacketType) {
+ /* if the previous partial state was
+ * full, then this is
+ * the first partial in the sequence so
+ * we need to copy
+ * in the user's IV. But, we have to be
+ * very careful
+ * here not to overwrite the
+ * cipherPartialOpState just
+ * yet in case there's a previous
+ * partial sequence in
+ * flight, so we defer the copy for now.
+ * This will be
+ * completed in the
+ * LacSymQueue_RequestSend() function.
+ */
+ pCbCookie->updateSessionIvOnSend =
+ CPA_TRUE;
+ }
+ /* For subsequent partials in a sequence, we'll
+ * re-use the
+ * IV that was written back by the QAT, using
+ * internal
+ * request queueing if necessary to ensure that
+ * the next
+ * partial request isn't issued to the QAT until
+ * the
+ * previous one completes
+ */
+ }
+ }
+ } else if (LAC_CIPHER_IS_KASUMI(algorithm)) {
+ LAC_CHECK_NULL_PARAM(pOpData->pIv);
+
+ if (LAC_CIPHER_IS_KASUMI(algorithm) &&
+ (pOpData->ivLenInBytes != LAC_CIPHER_KASUMI_F8_IV_LENGTH)) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+
+ *ppIvBuffer = pOpData->pIv;
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(algorithm)) {
+ LAC_CHECK_NULL_PARAM(pOpData->pIv);
+ if (LAC_CIPHER_IS_SNOW3G_UEA2(algorithm) &&
+ (pOpData->ivLenInBytes != ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ)) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ *ppIvBuffer = pOpData->pIv;
+ } else if (LAC_CIPHER_IS_ARC4(algorithm)) {
+ if (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) {
+ /* For full packets, the initial ARC4 state is stored in
+ * the
+ * session descriptor. Use it directly.
+ */
+ *ppIvBuffer = pSessionDesc->cipherARC4InitialState;
+ } else {
+ /* For partial packets, we maintain the running ARC4
+ * state in
+ * dedicated buffer in the session descriptor
+ */
+ *ppIvBuffer = pSessionDesc->cipherPartialOpState;
+
+ if (ICP_QAT_FW_LA_PARTIAL_START == qatPacketType) {
+ /* if the previous partial state was full, then
+ * this is the
+ * first partial in the sequence so we need to
+ * (re-)initialise
+ * the contents of the state buffer using the
+ * initial state
+ * that is stored in the session descriptor.
+ * But, we have to be
+ * very careful here not to overwrite the
+ * cipherPartialOpState
+ * just yet in case there's a previous partial
+ * sequence in
+ * flight, so we defer the copy for now. This
+ * will be completed
+ * in the LacSymQueue_RequestSend() function
+ * when clear to send.
+ */
+ pCbCookie->updateSessionIvOnSend = CPA_TRUE;
+ }
+ }
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(algorithm)) {
+ LAC_CHECK_NULL_PARAM(pOpData->pIv);
+ if (pOpData->ivLenInBytes != ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ *ppIvBuffer = pOpData->pIv;
+ } else {
+ *ppIvBuffer = NULL;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+
+CpaStatus
+LacCipher_SessionSetupDataCheck(const CpaCySymCipherSetupData *pCipherSetupData)
+{
+ /* No key required for NULL algorithm */
+ if (!LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm)) {
+ LAC_CHECK_NULL_PARAM(pCipherSetupData->pCipherKey);
+
+ /* Check that algorithm and keys passed in are correct size */
+ if (LAC_CIPHER_IS_ARC4(pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes >
+ ICP_QAT_HW_ARC4_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid ARC4 cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_CCM(
+ pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_128_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid AES CCM cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_XTS_MODE(
+ pCipherSetupData->cipherAlgorithm)) {
+ if ((pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_128_XTS_KEY_SZ) &&
+ (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_256_XTS_KEY_SZ)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid AES XTS cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_AES(
+ pCipherSetupData->cipherAlgorithm)) {
+ if ((pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_128_KEY_SZ) &&
+ (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_192_KEY_SZ) &&
+ (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_256_KEY_SZ)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid AES cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_AES_F8(
+ pCipherSetupData->cipherAlgorithm)) {
+ if ((pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_128_F8_KEY_SZ) &&
+ (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_192_F8_KEY_SZ) &&
+ (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_AES_256_F8_KEY_SZ)) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid AES cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_DES(
+ pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_DES_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid DES cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_TRIPLE_DES(
+ pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_3DES_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid Triple-DES cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_KASUMI(
+ pCipherSetupData->cipherAlgorithm)) {
+ /* QAT-FW only supports 128 bits Cipher Key size for
+ * Kasumi F8
+ * Ref: 3GPP TS 55.216 V6.2.0 */
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_KASUMI_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid Kasumi cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(
+ pCipherSetupData->cipherAlgorithm)) {
+ /* QAT-FW only supports 256 bits Cipher Key size for
+ * Snow_3G */
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid Snow_3G cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(
+ pCipherSetupData->cipherAlgorithm)) {
+ /* ZUC EEA3 */
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid ZUC cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_CHACHA(
+ pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_CHACHAPOLY_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid CHACHAPOLY cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_SM4(
+ pCipherSetupData->cipherAlgorithm)) {
+ if (pCipherSetupData->cipherKeyLenInBytes !=
+ ICP_QAT_HW_SM4_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid SM4 cipher key length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ LAC_INVALID_PARAM_LOG("Invalid cipher algorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+LacCipher_PerformParamCheck(CpaCySymCipherAlgorithm algorithm,
+ const CpaCySymOpData *pOpData,
+ const Cpa64U packetLen)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* The following check will cover the dstBuffer as well, since
+ * the dstBuffer cannot be smaller than the srcBuffer (checked in
+ * LacSymPerform_BufferParamCheck() called from LacSym_Perform())
+ */
+ if ((pOpData->messageLenToCipherInBytes +
+ pOpData->cryptoStartSrcOffsetInBytes) > packetLen) {
+ LAC_INVALID_PARAM_LOG("cipher len + offset greater than "
+ "srcBuffer packet len");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /*
+ * XTS Mode allow for ciphers which are not multiples of
+ * the block size.
+ */
+ /* Perform algorithm-specific checks */
+ if (LAC_CIPHER_IS_XTS_MODE(algorithm) &&
+ ((pOpData->packetType == CPA_CY_SYM_PACKET_TYPE_FULL) ||
+ (pOpData->packetType ==
+ CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL))) {
+ /*
+ * If this is the last of a partial request
+ */
+ if (pOpData->messageLenToCipherInBytes <
+ ICP_QAT_HW_AES_BLK_SZ) {
+ LAC_INVALID_PARAM_LOG(
+ "data size must be greater than block "
+ "size for last XTS partial or XTS "
+ "full packet");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (!(LAC_CIPHER_IS_ARC4(algorithm) ||
+ LAC_CIPHER_IS_CTR_MODE(algorithm) ||
+ LAC_CIPHER_IS_F8_MODE(algorithm) ||
+ LAC_CIPHER_IS_SNOW3G_UEA2(algorithm) ||
+ LAC_CIPHER_IS_XTS_MODE(algorithm) ||
+ LAC_CIPHER_IS_CHACHA(algorithm) ||
+ LAC_CIPHER_IS_ZUC_EEA3(algorithm))) {
+ /* Mask & check below is based on assumption that block
+ * size is
+ * a power of 2. If data size is not a multiple of the
+ * block size,
+ * the "remainder" bits selected by the mask be non-zero
+ */
+ if (pOpData->messageLenToCipherInBytes &
+ (LacSymQat_CipherBlockSizeBytesGet(algorithm) -
+ 1)) {
+ LAC_INVALID_PARAM_LOG(
+ "data size must be block size multiple");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+ return status;
+}
+
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_compile_check.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_compile_check.c
new file mode 100644
index 000000000000..d732add29c76
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_compile_check.c
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *
+ * <COPYRIGHT_TAG>
+ *
+ ***************************************************************************/
+
+/**
+ ***************************************************************************
+ * @file lac_sym_compile_check.c
+ *
+ * @ingroup LacSym
+ *
+ * This file checks at compile time that some assumptions about the layout
+ * of key structures are as expected.
+ *
+ *
+ ***************************************************************************/
+
+#include "cpa.h"
+
+#include "lac_common.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "lac_sym.h"
+#include "cpa_cy_sym_dp.h"
+
+#define COMPILE_TIME_ASSERT(pred) \
+ switch (0) { \
+ case 0: \
+ case pred:; \
+ }
+
+void
+LacSym_CompileTimeAssertions(void)
+{
+ /* *************************************************************
+ * Check sessionCtx is at the same location in bulk cookie and
+ * CpaCySymDpOpData.
+ * This is required for the callbacks to work as expected -
+ * see LacSymCb_ProcessCallback
+ * ************************************************************* */
+
+ COMPILE_TIME_ASSERT(offsetof(lac_sym_bulk_cookie_t, sessionCtx) ==
+ offsetof(CpaCySymDpOpData, sessionCtx));
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_dp.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_dp.c
new file mode 100644
index 000000000000..4ccf1f7f82d5
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_dp.c
@@ -0,0 +1,1080 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_dp.c
+ * Implementation of the symmetric data plane API
+ *
+ * @ingroup cpaCySymDp
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "cpa_cy_sym_dp.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_transport_dp.h"
+#include "icp_adf_debug.h"
+#include "icp_sal_poll.h"
+
+#include "qat_utils.h"
+
+#include "lac_mem.h"
+#include "lac_log.h"
+#include "lac_sym.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_list.h"
+#include "lac_sal_types_crypto.h"
+#include "sal_service_state.h"
+#include "lac_sym_auth_enc.h"
+
+typedef void (*write_ringMsgFunc_t)(CpaCySymDpOpData *pRequest,
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
+
+/**
+ *****************************************************************************
+ * @ingroup cpaCySymDp
+ * Check that the operation data is valid
+ *
+ * @description
+ * Check that all the parameters defined in the operation data are valid
+ *
+ * @param[in] pRequest Pointer to an operation data for crypto
+ * data plane API
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
+ *
+ *****************************************************************************/
+static CpaStatus
+LacDp_EnqueueParamCheck(const CpaCySymDpOpData *pRequest)
+{
+ lac_session_desc_t *pSessionDesc = NULL;
+ CpaCySymCipherAlgorithm cipher = 0;
+ CpaCySymHashAlgorithm hash = 0;
+ Cpa32U capabilitiesMask = 0;
+
+ LAC_CHECK_NULL_PARAM(pRequest);
+ LAC_CHECK_NULL_PARAM(pRequest->instanceHandle);
+ LAC_CHECK_NULL_PARAM(pRequest->sessionCtx);
+
+ /* Ensure this is a crypto instance */
+ SAL_CHECK_INSTANCE_TYPE(pRequest->instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
+ if (NULL == pSessionDesc) {
+ do {
+ qatUtilsSleep(500);
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(
+ pRequest->sessionCtx);
+ } while (NULL == pSessionDesc);
+ }
+ if (NULL == pSessionDesc) {
+ LAC_INVALID_PARAM_LOG("Session context not as expected");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_FALSE == pSessionDesc->isDPSession) {
+ LAC_INVALID_PARAM_LOG(
+ "Session not initialised for data plane API");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /*check whether Payload size is zero for CHACHA-POLY */
+ if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
+ (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
+ (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
+ if (!pRequest->messageLenToCipherInBytes) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid messageLenToCipherInBytes for CHACHA-POLY");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (0 == pRequest->srcBuffer) {
+ LAC_INVALID_PARAM_LOG("Invalid srcBuffer");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pRequest->dstBuffer) {
+ LAC_INVALID_PARAM_LOG("Invalid destBuffer");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pRequest->thisPhys) {
+ LAC_INVALID_PARAM_LOG("Invalid thisPhys");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Check that src buffer Len = dst buffer Len
+ Note this also checks that they are of the same type */
+ if (pRequest->srcBufferLen != pRequest->dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "Source and Destination buffer lengths need to be equal");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* digestVerify and digestIsAppended on Hash-Only operation not
+ * supported */
+ if (pSessionDesc->digestIsAppended && pSessionDesc->digestVerify &&
+ (CPA_CY_SYM_OP_HASH == pSessionDesc->symOperation)) {
+ LAC_INVALID_PARAM_LOG(
+ "digestVerify and digestIsAppended set "
+ "on Hash-Only operation is not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Cipher specific tests */
+ if (CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) {
+ /* Perform IV check */
+ if ((LAC_CIPHER_IS_CTR_MODE(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_CBC_MODE(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_AES_F8(pSessionDesc->cipherAlgorithm)) &&
+ (!(LAC_CIPHER_IS_CCM(pSessionDesc->cipherAlgorithm)))) {
+ Cpa32U ivLenInBytes = LacSymQat_CipherIvSizeBytesGet(
+ pSessionDesc->cipherAlgorithm);
+ if (pRequest->ivLenInBytes != ivLenInBytes) {
+ if (!(/* GCM with 12 byte IV is OK */
+ (LAC_CIPHER_IS_GCM(
+ pSessionDesc->cipherAlgorithm) &&
+ pRequest->ivLenInBytes ==
+ LAC_CIPHER_IV_SIZE_GCM_12))) {
+ LAC_INVALID_PARAM_LOG(
+ "invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ if (0 == pRequest->iv) {
+ LAC_INVALID_PARAM_LOG("invalid iv of 0");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* pRequest->pIv is only used for CCM so is not checked
+ * here */
+ } else if (LAC_CIPHER_IS_KASUMI(
+ pSessionDesc->cipherAlgorithm)) {
+ if (LAC_CIPHER_KASUMI_F8_IV_LENGTH !=
+ pRequest->ivLenInBytes) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pRequest->iv) {
+ LAC_INVALID_PARAM_LOG("invalid iv of 0");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(
+ pSessionDesc->cipherAlgorithm)) {
+ if (ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ !=
+ pRequest->ivLenInBytes) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pRequest->iv) {
+ LAC_INVALID_PARAM_LOG("invalid iv of 0");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(
+ pSessionDesc->cipherAlgorithm)) {
+ if (ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ !=
+ pRequest->ivLenInBytes) {
+ LAC_INVALID_PARAM_LOG("invalid cipher IV size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (0 == pRequest->iv) {
+ LAC_INVALID_PARAM_LOG("invalid iv of 0");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (LAC_CIPHER_IS_CCM(pSessionDesc->cipherAlgorithm)) {
+ if (CPA_STATUS_SUCCESS !=
+ LacSymAlgChain_CheckCCMData(
+ pRequest->pAdditionalAuthData,
+ pRequest->pIv,
+ pRequest->messageLenToCipherInBytes,
+ pRequest->ivLenInBytes)) {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Perform algorithm-specific checks */
+ if (!(LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_CTR_MODE(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_F8_MODE(pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_SNOW3G_UEA2(
+ pSessionDesc->cipherAlgorithm) ||
+ LAC_CIPHER_IS_ZUC_EEA3(pSessionDesc->cipherAlgorithm))) {
+ /* Mask & check below is based on assumption that block
+ * size is
+ * a power of 2. If data size is not a multiple of the
+ * block size,
+ * the "remainder" bits selected by the mask be non-zero
+ */
+ if (pRequest->messageLenToCipherInBytes &
+ (LacSymQat_CipherBlockSizeBytesGet(
+ pSessionDesc->cipherAlgorithm) -
+ 1)) {
+ LAC_INVALID_PARAM_LOG(
+ "Data size must be block size multiple");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ cipher = pSessionDesc->cipherAlgorithm;
+ hash = pSessionDesc->hashAlgorithm;
+ capabilitiesMask =
+ ((sal_crypto_service_t *)pRequest->instanceHandle)
+ ->generic_service_info.capabilitiesMask;
+ if (LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
+ (LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes)) {
+ /* For CHACHA and AES_GCM single pass there is an AAD
+ * buffer
+ * if aadLenInBytes is nonzero. AES_GMAC AAD is stored
+ * in
+ * source buffer, therefore there is no separate AAD
+ * buffer. */
+ if ((0 != pSessionDesc->aadLenInBytes) &&
+ (CPA_CY_SYM_HASH_AES_GMAC !=
+ pSessionDesc->hashAlgorithm)) {
+ LAC_CHECK_NULL_PARAM(
+ pRequest->pAdditionalAuthData);
+ }
+
+ /* Ensure AAD length for AES_GMAC spc */
+ if ((CPA_CY_SYM_HASH_AES_GMAC == hash) &&
+ (ICP_QAT_FW_SPC_AAD_SZ_MAX <
+ pRequest->messageLenToHashInBytes)) {
+ LAC_INVALID_PARAM_LOG(
+ "aadLenInBytes for AES_GMAC");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+ /* Hash specific tests */
+ if (CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation) {
+ /* For CCM, snow3G and ZUC there is always an AAD buffer
+ For GCM there is an AAD buffer if aadLenInBytes is
+ nonzero */
+ if ((CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm &&
+ (0 != pSessionDesc->aadLenInBytes))) {
+ LAC_CHECK_NULL_PARAM(pRequest->pAdditionalAuthData);
+ if (0 == pRequest->additionalAuthData) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid additionalAuthData");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionDesc->hashAlgorithm) {
+ if (0 == pRequest->additionalAuthData) {
+ LAC_INVALID_PARAM_LOG(
+ "Invalid additionalAuthData");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if ((CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm) &&
+ (!pSessionDesc->digestIsAppended) &&
+ (0 == pRequest->digestResult)) {
+ LAC_INVALID_PARAM_LOG("Invalid digestResult");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) {
+ if ((pRequest->cryptoStartSrcOffsetInBytes +
+ pRequest->messageLenToCipherInBytes +
+ pSessionDesc->hashResultSize) >
+ pRequest->dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "CCM - Not enough room for"
+ " digest in destination buffer");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_TRUE == pSessionDesc->digestIsAppended) {
+ if (CPA_CY_SYM_HASH_AES_GMAC ==
+ pSessionDesc->hashAlgorithm) {
+ if ((pRequest->hashStartSrcOffsetInBytes +
+ pRequest->messageLenToHashInBytes +
+ pSessionDesc->hashResultSize) >
+ pRequest->dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "Append Digest - Not enough room for"
+ " digest in destination buffer for "
+ "AES GMAC algorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ if (CPA_CY_SYM_HASH_AES_GCM ==
+ pSessionDesc->hashAlgorithm) {
+ if ((pRequest->cryptoStartSrcOffsetInBytes +
+ pRequest->messageLenToCipherInBytes +
+ pSessionDesc->hashResultSize) >
+ pRequest->dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "Append Digest - Not enough room "
+ "for digest in destination buffer"
+ " for GCM algorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if ((pRequest->hashStartSrcOffsetInBytes +
+ pRequest->messageLenToHashInBytes +
+ pSessionDesc->hashResultSize) >
+ pRequest->dstBufferLen) {
+ LAC_INVALID_PARAM_LOG(
+ "Append Digest - Not enough room for"
+ " digest in destination buffer");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ if (pRequest->messageLenToHashInBytes == 0 ||
+ pRequest->pAdditionalAuthData != NULL) {
+ LAC_INVALID_PARAM_LOG(
+ "For AES_GMAC, AAD Length "
+ "(messageLenToHashInBytes) must be "
+ "non zero and pAdditionalAuthData "
+ "must be NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+ }
+
+ if (CPA_DP_BUFLIST != pRequest->srcBufferLen) {
+ if ((CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) &&
+ ((pRequest->messageLenToCipherInBytes +
+ pRequest->cryptoStartSrcOffsetInBytes) >
+ pRequest->srcBufferLen)) {
+ LAC_INVALID_PARAM_LOG(
+ "cipher len + offset greater than "
+ "srcBufferLen");
+ return CPA_STATUS_INVALID_PARAM;
+ } else if ((CPA_CY_SYM_OP_CIPHER !=
+ pSessionDesc->symOperation) &&
+ (CPA_CY_SYM_HASH_AES_CCM !=
+ pSessionDesc->hashAlgorithm) &&
+ (CPA_CY_SYM_HASH_AES_GCM !=
+ pSessionDesc->hashAlgorithm) &&
+ (CPA_CY_SYM_HASH_AES_GMAC !=
+ pSessionDesc->hashAlgorithm) &&
+ ((pRequest->messageLenToHashInBytes +
+ pRequest->hashStartSrcOffsetInBytes) >
+ pRequest->srcBufferLen)) {
+ LAC_INVALID_PARAM_LOG(
+ "hash len + offset greater than srcBufferLen");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->srcBuffer);
+ LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->dstBuffer);
+ }
+
+ LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->thisPhys);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup cpaCySymDp
+ * Write Message on the ring and write request params
+ * This is the optimized version, which should not be used for
+ * algorithm of CCM, GCM and RC4
+ *
+ * @description
+ * Write Message on the ring and write request params
+ *
+ * @param[in/out] pRequest Pointer to operation data for crypto
+ * data plane API
+ * @param[in/out] pCurrentQatMsg Pointer to ring memory where msg will
+ * be written
+ *
+ * @retval none
+ *
+ *****************************************************************************/
+
+void
+LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
+{
+ lac_session_desc_t *pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
+ Cpa8U *pMsgDummy = NULL;
+ Cpa8U *pCacheDummyHdr = NULL;
+ Cpa8U *pCacheDummyFtr = NULL;
+
+ pMsgDummy = (Cpa8U *)pCurrentQatMsg;
+ /* Write Request */
+ /*
+ * Fill in the header and footer bytes of the ET ring message - cached
+ * from
+ * the session descriptor.
+ */
+ pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
+ pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
+
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memset((pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
+ 0,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
+ memcpy(pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ SalQatMsg_CmnMidWrite(pCurrentQatMsg,
+ pRequest,
+ (CPA_DP_BUFLIST == pRequest->srcBufferLen ?
+ QAT_COMN_PTR_TYPE_SGL :
+ QAT_COMN_PTR_TYPE_FLAT),
+ pRequest->srcBuffer,
+ pRequest->dstBuffer,
+ pRequest->srcBufferLen,
+ pRequest->dstBufferLen);
+
+ /* Write Request Params */
+ if (pSessionDesc->isCipher) {
+
+ LacSymQat_CipherRequestParamsPopulate(
+ pCurrentQatMsg,
+ pRequest->cryptoStartSrcOffsetInBytes,
+ pRequest->messageLenToCipherInBytes,
+ pRequest->iv,
+ pRequest->pIv);
+ }
+
+ if (pSessionDesc->isAuth) {
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
+ &(pSessionDesc->hashStateBufferInfo);
+ icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
+ (icp_qat_fw_la_auth_req_params_t
+ *)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
+ ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
+
+ if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
+ pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
+ (pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
+ /* prefixAadSzQuadWords > 0 when there is prefix data
+ - i.e. nested hash or HMAC no precompute cases
+ Note partials not supported on DP api so we do not need
+ dynamic hash state in this case */
+ pRequest->additionalAuthData =
+ pHashStateBufferInfo->pDataPhys +
+ LAC_QUADWORDS_TO_BYTES(
+ pHashStateBufferInfo->stateStorageSzQuadWords);
+ }
+
+ /* The first 24 bytes in icp_qat_fw_la_auth_req_params_t can be
+ * copied directly from the op request data because they share a
+ * corresponding layout. The remaining 4 bytes are taken
+ * from the session message template and use values
+ * preconfigured at
+ * sessionInit (updated per request for some specific cases
+ * below)
+ */
+ memcpy(pAuthReqPars,
+ (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
+ ((unsigned long)&(pAuthReqPars->u2.inner_prefix_sz) -
+ (unsigned long)pAuthReqPars));
+
+ if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
+ pAuthReqPars->hash_state_sz =
+ LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionDesc->hashAlgorithm) {
+ pAuthReqPars->hash_state_sz =
+ LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
+ }
+ }
+
+}
+
+/**
+ *****************************************************************************
+ * @ingroup cpaCySymDp
+ * Write Message on the ring and write request params
+ *
+ * @description
+ * Write Message on the ring and write request params
+ *
+ * @param[in/out] pRequest Pointer to operation data for crypto
+ * data plane API
+ * @param[in/out] pCurrentQatMsg Pointer to ring memory where msg will
+ * be written
+ *
+ * @retval none
+ *
+ *****************************************************************************/
+
+void
+LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
+{
+ lac_session_desc_t *pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
+ Cpa8U *pMsgDummy = NULL;
+ Cpa8U *pCacheDummyHdr = NULL;
+ Cpa8U *pCacheDummyFtr = NULL;
+ sal_qat_content_desc_info_t *pCdInfo = NULL;
+ Cpa8U *pHwBlockBaseInDRAM = NULL;
+ Cpa32U hwBlockOffsetInDRAM = 0;
+ Cpa32U sizeInBytes = 0;
+ CpaCySymCipherAlgorithm cipher = pSessionDesc->cipherAlgorithm;
+ CpaCySymHashAlgorithm hash = pSessionDesc->hashAlgorithm;
+ Cpa32U capabilitiesMask =
+ ((sal_crypto_service_t *)pRequest->instanceHandle)
+ ->generic_service_info.capabilitiesMask;
+
+ Cpa8U paddingLen = 0;
+ Cpa8U blockLen = 0;
+
+ pMsgDummy = (Cpa8U *)pCurrentQatMsg;
+ /* Write Request */
+ /*
+ * Fill in the header and footer bytes of the ET ring message - cached
+ * from
+ * the session descriptor.
+ */
+
+ if (!pSessionDesc->isSinglePass &&
+ LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
+ (LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes)) {
+ pSessionDesc->isSinglePass = CPA_TRUE;
+ pSessionDesc->isCipher = CPA_TRUE;
+ pSessionDesc->isAuthEncryptOp = CPA_FALSE;
+ pSessionDesc->isAuth = CPA_FALSE;
+ pSessionDesc->symOperation = CPA_CY_SYM_OP_CIPHER;
+ pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER;
+ if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ pSessionDesc->aadLenInBytes =
+ pRequest->messageLenToHashInBytes;
+ }
+ /* New bit position (13) for SINGLE PASS.
+ * The FW provides a specific macro to use to set the proto flag
+ */
+ ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET(
+ pSessionDesc->laCmdFlags, ICP_QAT_FW_LA_SINGLE_PASS_PROTO);
+ ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags, 0);
+
+ pCdInfo = &(pSessionDesc->contentDescInfo);
+ pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
+ if (CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT ==
+ pSessionDesc->cipherDirection) {
+ if (LAC_CIPHER_IS_GCM(cipher))
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC);
+ else
+ hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
+ LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC);
+ }
+ /* construct cipherConfig in CD in DRAM */
+ LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
+ pHwBlockBaseInDRAM +
+ hwBlockOffsetInDRAM,
+ &sizeInBytes);
+ SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&(
+ pSessionDesc->reqSpcCacheHdr),
+ ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
+ pSessionDesc->laCmdId,
+ pSessionDesc->cmnRequestFlags,
+ pSessionDesc->laCmdFlags);
+ } else if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
+ pSessionDesc->aadLenInBytes = pRequest->messageLenToHashInBytes;
+ }
+ if (pSessionDesc->isSinglePass) {
+ pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqSpcCacheHdr);
+ pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqSpcCacheFtr);
+ } else {
+ if (!pSessionDesc->useSymConstantsTable) {
+ pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
+ pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
+ } else {
+ pCacheDummyHdr =
+ (Cpa8U *)&(pSessionDesc->shramReqCacheHdr);
+ pCacheDummyFtr =
+ (Cpa8U *)&(pSessionDesc->shramReqCacheFtr);
+ }
+ }
+ memcpy(pMsgDummy,
+ pCacheDummyHdr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
+ memset((pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
+ 0,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
+ memcpy(pMsgDummy +
+ (LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
+ pCacheDummyFtr,
+ (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
+
+ SalQatMsg_CmnMidWrite(pCurrentQatMsg,
+ pRequest,
+ (CPA_DP_BUFLIST == pRequest->srcBufferLen ?
+ QAT_COMN_PTR_TYPE_SGL :
+ QAT_COMN_PTR_TYPE_FLAT),
+ pRequest->srcBuffer,
+ pRequest->dstBuffer,
+ pRequest->srcBufferLen,
+ pRequest->dstBufferLen);
+
+ if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm &&
+ pSessionDesc->isAuth == CPA_TRUE) {
+ /* prepare IV and AAD for CCM */
+ LacSymAlgChain_PrepareCCMData(
+ pSessionDesc,
+ pRequest->pAdditionalAuthData,
+ pRequest->pIv,
+ pRequest->messageLenToCipherInBytes,
+ pRequest->ivLenInBytes);
+
+ /* According to the API, for CCM and GCM,
+ * messageLenToHashInBytes
+ * and hashStartSrcOffsetInBytes are not initialized by the
+ * user and must be set by the driver
+ */
+ pRequest->hashStartSrcOffsetInBytes =
+ pRequest->cryptoStartSrcOffsetInBytes;
+ pRequest->messageLenToHashInBytes =
+ pRequest->messageLenToCipherInBytes;
+ } else if (!pSessionDesc->isSinglePass &&
+ (CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm)) {
+ /* GCM case */
+ if (CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm) {
+ /* According to the API, for CCM and GCM,
+ * messageLenToHashInBytes and hashStartSrcOffsetInBytes
+ * are not initialized by the user and must be set
+ * by the driver
+ */
+ pRequest->hashStartSrcOffsetInBytes =
+ pRequest->cryptoStartSrcOffsetInBytes;
+ pRequest->messageLenToHashInBytes =
+ pRequest->messageLenToCipherInBytes;
+
+ LacSymAlgChain_PrepareGCMData(
+ pSessionDesc, pRequest->pAdditionalAuthData);
+ }
+
+ if (LAC_CIPHER_IV_SIZE_GCM_12 == pRequest->ivLenInBytes) {
+ ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
+ pCurrentQatMsg->comn_hdr.serv_specif_flags,
+ ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS);
+ }
+ }
+
+ /* Write Request Params */
+ if (pSessionDesc->isCipher) {
+ if (CPA_CY_SYM_CIPHER_ARC4 == pSessionDesc->cipherAlgorithm) {
+ /* ARC4 does not have an IV but the field is used to
+ * store the
+ * initial state */
+ pRequest->iv =
+ pSessionDesc->cipherARC4InitialStatePhysAddr;
+ }
+
+ LacSymQat_CipherRequestParamsPopulate(
+ pCurrentQatMsg,
+ pRequest->cryptoStartSrcOffsetInBytes,
+ pRequest->messageLenToCipherInBytes,
+ pRequest->iv,
+ pRequest->pIv);
+ if (pSessionDesc->isSinglePass) {
+ icp_qat_fw_la_cipher_req_params_t *pCipherReqParams =
+ (icp_qat_fw_la_cipher_req_params_t
+ *)((Cpa8U *)&(
+ pCurrentQatMsg->serv_specif_rqpars) +
+ ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
+
+ pCipherReqParams->spc_aad_addr =
+ (uint64_t)pRequest->additionalAuthData;
+ pCipherReqParams->spc_aad_sz =
+ pSessionDesc->aadLenInBytes;
+
+ pCipherReqParams->spc_auth_res_addr =
+ (uint64_t)pRequest->digestResult;
+ pCipherReqParams->spc_auth_res_sz =
+ pSessionDesc->hashResultSize;
+
+ /* For CHACHA and AES_GCM single pass AAD buffer needs
+ * alignment
+ * if aadLenInBytes is nonzero.
+ * In case of AES-GMAC, AAD buffer passed in the src
+ * buffer.
+ */
+ if (0 != pSessionDesc->aadLenInBytes &&
+ CPA_CY_SYM_HASH_AES_GMAC !=
+ pSessionDesc->hashAlgorithm) {
+ blockLen = LacSymQat_CipherBlockSizeBytesGet(
+ pSessionDesc->cipherAlgorithm);
+ if ((pSessionDesc->aadLenInBytes % blockLen) !=
+ 0) {
+ paddingLen = blockLen -
+ (pSessionDesc->aadLenInBytes %
+ blockLen);
+ memset(
+ &pRequest->pAdditionalAuthData
+ [pSessionDesc->aadLenInBytes],
+ 0,
+ paddingLen);
+ }
+ }
+ }
+ }
+
+ if (pSessionDesc->isAuth) {
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
+ &(pSessionDesc->hashStateBufferInfo);
+ icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
+ (icp_qat_fw_la_auth_req_params_t
+ *)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
+ ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
+
+ if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
+ pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
+ CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
+ (pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
+ /* prefixAadSzQuadWords > 0 when there is prefix data
+ - i.e. nested hash or HMAC no precompute cases
+ Note partials not supported on DP api so we do not need
+ dynamic hash state in this case */
+ pRequest->additionalAuthData =
+ pHashStateBufferInfo->pDataPhys +
+ LAC_QUADWORDS_TO_BYTES(
+ pHashStateBufferInfo->stateStorageSzQuadWords);
+ }
+
+ /* The first 24 bytes in icp_qat_fw_la_auth_req_params_t can be
+ * copied directly from the op request data because they share a
+ * corresponding layout. The remaining 4 bytes are taken
+ * from the session message template and use values
+ * preconfigured at
+ * sessionInit (updated per request for some specific cases
+ * below)
+ */
+
+ /* We force a specific compiler optimisation here. The length
+ * to
+ * be copied turns out to be always 16, and by coding a memcpy
+ * with
+ * a literal value the compiler will compile inline code (in
+ * fact,
+ * only two vector instructions) to effect the copy. This gives
+ * us
+ * a huge performance increase.
+ */
+ unsigned long cplen =
+ (unsigned long)&(pAuthReqPars->u2.inner_prefix_sz) -
+ (unsigned long)pAuthReqPars;
+ if (cplen == 16)
+ memcpy(pAuthReqPars,
+ (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
+ 16);
+ else
+ memcpy(pAuthReqPars,
+ (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
+ cplen);
+
+ if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
+ pAuthReqPars->hash_state_sz =
+ LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pSessionDesc->hashAlgorithm ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pSessionDesc->hashAlgorithm) {
+ pAuthReqPars->hash_state_sz =
+ LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
+ }
+ }
+
+}
+
+CpaStatus
+cpaCySymDpSessionCtxGetSize(const CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ /* All other param checks are common with trad api */
+ /* Check for valid pointers */
+ LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
+ status = cpaCySymSessionCtxGetSize(instanceHandle,
+ pSessionSetupData,
+ pSessionCtxSizeInBytes);
+
+ return status;
+}
+
+CpaStatus
+cpaCySymDpSessionCtxGetDynamicSize(
+ const CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ Cpa32U *pSessionCtxSizeInBytes)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ /* All other param checks are common with trad api */
+ /* Check for valid pointers */
+ LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
+ status = cpaCySymSessionCtxGetDynamicSize(instanceHandle,
+ pSessionSetupData,
+ pSessionCtxSizeInBytes);
+
+ return status;
+}
+
+/** @ingroup cpaCySymDp */
+CpaStatus
+cpaCySymDpInitSession(CpaInstanceHandle instanceHandle,
+ const CpaCySymSessionSetupData *pSessionSetupData,
+ CpaCySymDpSessionCtx sessionCtx)
+{
+ CpaStatus status = CPA_STATUS_FAIL;
+ sal_service_t *pService = NULL;
+
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSessionSetupData);
+ pService = (sal_service_t *)instanceHandle;
+
+ /* Check crypto service is running otherwise return an error */
+ SAL_RUNNING_CHECK(pService);
+
+ status = LacSym_InitSession(instanceHandle,
+ NULL, /* Callback */
+ pSessionSetupData,
+ CPA_TRUE, /* isDPSession */
+ sessionCtx);
+ return status;
+}
+
+CpaStatus
+cpaCySymDpRemoveSession(const CpaInstanceHandle instanceHandle,
+ CpaCySymDpSessionCtx sessionCtx)
+{
+
+ /* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+/* All other param checks are common with trad api */
+
+ return cpaCySymRemoveSession(instanceHandle, sessionCtx);
+}
+
+CpaStatus
+cpaCySymDpRegCbFunc(const CpaInstanceHandle instanceHandle,
+ const CpaCySymDpCbFunc pSymDpCb)
+{
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pSymDpCb);
+ SAL_RUNNING_CHECK(instanceHandle);
+ pService->pSymDpCb = pSymDpCb;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaCySymDpEnqueueOp(CpaCySymDpOpData *pRequest, const CpaBoolean performOpNow)
+{
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
+ icp_comms_trans_handle trans_handle = NULL;
+ lac_session_desc_t *pSessionDesc = NULL;
+ write_ringMsgFunc_t callFunc;
+
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+
+ LAC_CHECK_NULL_PARAM(pRequest);
+ status = LacDp_EnqueueParamCheck(pRequest);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ trans_handle = ((sal_crypto_service_t *)pRequest->instanceHandle)
+ ->trans_handle_sym_tx;
+
+ pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
+ icp_adf_getSingleQueueAddr(trans_handle, (void **)&pCurrentQatMsg);
+ if (NULL == pCurrentQatMsg) {
+ /*
+ * No space is available on the queue.
+ */
+ return CPA_STATUS_RETRY;
+ }
+
+ callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
+
+ LAC_CHECK_NULL_PARAM(callFunc);
+
+ callFunc(pRequest, pCurrentQatMsg);
+
+ qatUtilsAtomicInc(&(pSessionDesc->u.pendingDpCbCount));
+
+ if (CPA_TRUE == performOpNow) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaCySymDpPerformOpNow(const CpaInstanceHandle instanceHandle)
+{
+ icp_comms_trans_handle trans_handle = NULL;
+
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ trans_handle =
+ ((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_tx;
+
+ if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaCySymDpEnqueueOpBatch(const Cpa32U numberRequests,
+ CpaCySymDpOpData *pRequests[],
+ const CpaBoolean performOpNow)
+{
+ icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
+ icp_comms_trans_handle trans_handle = NULL;
+ lac_session_desc_t *pSessionDesc = NULL;
+ write_ringMsgFunc_t callFunc;
+ Cpa32U i = 0;
+
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = NULL;
+
+
+ LAC_CHECK_NULL_PARAM(pRequests);
+ LAC_CHECK_NULL_PARAM(pRequests[0]);
+ LAC_CHECK_NULL_PARAM(pRequests[0]->instanceHandle);
+
+ pService = (sal_crypto_service_t *)(pRequests[0]->instanceHandle);
+
+ if ((0 == numberRequests) ||
+ (numberRequests > pService->maxNumSymReqBatch)) {
+ LAC_INVALID_PARAM_LOG1(
+ "The number of requests needs to be between 1 "
+ "and %d",
+ pService->maxNumSymReqBatch);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ for (i = 0; i < numberRequests; i++) {
+ status = LacDp_EnqueueParamCheck(pRequests[i]);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ /* Check that all instance handles are the same */
+ if (pRequests[i]->instanceHandle !=
+ pRequests[0]->instanceHandle) {
+ LAC_INVALID_PARAM_LOG(
+ "All instance handles should be the same "
+ "in the requests");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ trans_handle = ((sal_crypto_service_t *)pRequests[0]->instanceHandle)
+ ->trans_handle_sym_tx;
+ pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[0]->sessionCtx);
+ icp_adf_getQueueMemory(trans_handle,
+ numberRequests,
+ (void **)&pCurrentQatMsg);
+ if (NULL == pCurrentQatMsg) {
+ /*
+ * No space is available on the queue.
+ */
+ return CPA_STATUS_RETRY;
+ }
+
+ for (i = 0; i < numberRequests; i++) {
+ pSessionDesc =
+ LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[i]->sessionCtx);
+ callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
+ callFunc(pRequests[i], pCurrentQatMsg);
+ icp_adf_getQueueNext(trans_handle, (void **)&pCurrentQatMsg);
+ qatUtilsAtomicAdd(1, &(pSessionDesc->u.pendingDpCbCount));
+ }
+
+ if (CPA_TRUE == performOpNow) {
+ SalQatMsg_updateQueueTail(trans_handle);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+icp_sal_CyPollDpInstance(const CpaInstanceHandle instanceHandle,
+ const Cpa32U responseQuota)
+{
+ icp_comms_trans_handle trans_handle = NULL;
+
+ LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ /* Check if SAL is initialised otherwise return an error */
+ SAL_RUNNING_CHECK(instanceHandle);
+
+ trans_handle =
+ ((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_rx;
+
+ return icp_adf_pollQueue(trans_handle, responseQuota);
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash.c
new file mode 100644
index 000000000000..e662d0d6d220
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash.c
@@ -0,0 +1,783 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_hash.c
+ *
+ * @ingroup LacHash
+ *
+ * Hash specific functionality
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "lac_common.h"
+#include "lac_mem.h"
+#include "lac_sym.h"
+#include "lac_session.h"
+#include "lac_sym_hash.h"
+#include "lac_log.h"
+#include "lac_sym_qat_hash.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym_cb.h"
+#include "lac_sync.h"
+
+#define LAC_HASH_ALG_MODE_NOT_SUPPORTED(alg, mode) \
+ ((((CPA_CY_SYM_HASH_KASUMI_F9 == (alg)) || \
+ (CPA_CY_SYM_HASH_SNOW3G_UIA2 == (alg)) || \
+ (CPA_CY_SYM_HASH_AES_XCBC == (alg)) || \
+ (CPA_CY_SYM_HASH_AES_CCM == (alg)) || \
+ (CPA_CY_SYM_HASH_AES_GCM == (alg)) || \
+ (CPA_CY_SYM_HASH_AES_GMAC == (alg)) || \
+ (CPA_CY_SYM_HASH_AES_CMAC == (alg)) || \
+ (CPA_CY_SYM_HASH_ZUC_EIA3 == (alg))) && \
+ (CPA_CY_SYM_HASH_MODE_AUTH != (mode))) || \
+ (((CPA_CY_SYM_HASH_SHA3_224 == (alg)) || \
+ (CPA_CY_SYM_HASH_SHA3_256 == (alg)) || \
+ (CPA_CY_SYM_HASH_SHA3_384 == (alg)) || \
+ (CPA_CY_SYM_HASH_SHA3_512 == (alg))) && \
+ (CPA_CY_SYM_HASH_MODE_NESTED == (mode))) || \
+ (((CPA_CY_SYM_HASH_SHAKE_128 == (alg)) || \
+ (CPA_CY_SYM_HASH_SHAKE_256 == (alg))) && \
+ (CPA_CY_SYM_HASH_MODE_AUTH == (mode))))
+
+/**< Macro to check for valid algorithm-mode combination */
+
+/**
+ * @ingroup LacHash
+ * This callback function will be invoked whenever a synchronous
+ * hash precompute operation completes. It will set the wait
+ * queue flag for the synchronous operation.
+ *
+ * @param[in] pCallbackTag Opaque value provided by user. This will
+ * be a pointer to a wait queue flag.
+ *
+ * @retval
+ * None
+ *
+ */
+static void
+LacHash_SyncPrecomputeDoneCb(void *pCallbackTag)
+{
+ LacSync_GenWakeupSyncCaller(pCallbackTag, CPA_STATUS_SUCCESS);
+}
+
+/** @ingroup LacHash */
+CpaStatus
+LacHash_StatePrefixAadBufferInit(
+ sal_service_t *pService,
+ const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_la_bulk_req_ftr_t *pReq,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ Cpa8U *pHashStateBuffer,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo)
+{
+ /* set up the hash state prefix buffer info structure */
+ pHashStateBufferInfo->pData = pHashStateBuffer;
+
+ pHashStateBufferInfo->pDataPhys = LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService), pHashStateBuffer));
+
+ if (pHashStateBufferInfo->pDataPhys == 0) {
+ LAC_LOG_ERROR("Unable to get the physical address of "
+ "the hash state buffer");
+ return CPA_STATUS_FAIL;
+ }
+
+ LacSymQat_HashStatePrefixAadBufferSizeGet(pReq, pHashStateBufferInfo);
+
+ /* Prefix data gets copied to the hash state buffer for nested mode */
+ if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
+ LacSymQat_HashStatePrefixAadBufferPopulate(
+ pHashStateBufferInfo,
+ pReq,
+ pHashSetupData->nestedModeSetupData.pInnerPrefixData,
+ pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes,
+ pHashSetupData->nestedModeSetupData.pOuterPrefixData,
+ pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes);
+ }
+ /* For mode2 HMAC the key gets copied into both the inner and
+ * outer prefix fields */
+ else if (IS_HASH_MODE_2_AUTH(qatHashMode, pHashSetupData->hashMode)) {
+ LacSymQat_HashStatePrefixAadBufferPopulate(
+ pHashStateBufferInfo,
+ pReq,
+ pHashSetupData->authModeSetupData.authKey,
+ pHashSetupData->authModeSetupData.authKeyLenInBytes,
+ pHashSetupData->authModeSetupData.authKey,
+ pHashSetupData->authModeSetupData.authKeyLenInBytes);
+ }
+ /* else do nothing for the other cases */
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacHash */
+CpaStatus
+LacHash_PrecomputeDataCreate(const CpaInstanceHandle instanceHandle,
+ CpaCySymSessionSetupData *pSessionSetup,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag,
+ Cpa8U *pWorkingBuffer,
+ Cpa8U *pState1,
+ Cpa8U *pState2)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa8U *pAuthKey = NULL;
+ Cpa32U authKeyLenInBytes = 0;
+ CpaCySymHashAlgorithm hashAlgorithm =
+ pSessionSetup->hashSetupData.hashAlgorithm;
+ CpaCySymHashAuthModeSetupData *pAuthModeSetupData =
+ &pSessionSetup->hashSetupData.authModeSetupData;
+
+ /* synchronous operation */
+ if (NULL == callbackFn) {
+ lac_sync_op_data_t *pSyncCallbackData = NULL;
+
+ status = LacSync_CreateSyncCookie(&pSyncCallbackData);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = LacHash_PrecomputeDataCreate(
+ instanceHandle,
+ pSessionSetup,
+ LacHash_SyncPrecomputeDoneCb,
+ /* wait queue condition from sync cookie */
+ pSyncCallbackData,
+ pWorkingBuffer,
+ pState1,
+ pState2);
+ } else {
+ return status;
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ CpaStatus syncStatus = CPA_STATUS_SUCCESS;
+
+ syncStatus = LacSync_WaitForCallback(
+ pSyncCallbackData,
+ LAC_SYM_SYNC_CALLBACK_TIMEOUT,
+ &status,
+ NULL);
+
+ /* If callback doesn't come back */
+ if (CPA_STATUS_SUCCESS != syncStatus) {
+ QAT_UTILS_LOG(
+ "callback functions for precomputes did not return\n");
+ status = syncStatus;
+ }
+ } else {
+ /* As the Request was not sent the Callback will never
+ * be called, so need to indicate that we're finished
+ * with cookie so it can be destroyed. */
+ LacSync_SetSyncCookieComplete(pSyncCallbackData);
+ }
+ LacSync_DestroySyncCookie(&pSyncCallbackData);
+
+ return status;
+ }
+
+ /* set up convenience pointers */
+ pAuthKey = pAuthModeSetupData->authKey;
+ authKeyLenInBytes = pAuthModeSetupData->authKeyLenInBytes;
+
+ /* Pre-compute data state pointers must already be set up
+ * by LacSymQat_HashSetupBlockInit()
+ */
+
+ /* state1 is not allocated for AES XCBC/CCM/GCM/Kasumi/UIA2
+ * so for these algorithms set state2 only */
+ if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
+ status = LacSymHash_AesECBPreCompute(instanceHandle,
+ hashAlgorithm,
+ authKeyLenInBytes,
+ pAuthKey,
+ pWorkingBuffer,
+ pState2,
+ callbackFn,
+ pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
+ /* First, copy the original key to pState2 */
+ memcpy(pState2, pAuthKey, authKeyLenInBytes);
+ /* Then precompute */
+ status = LacSymHash_AesECBPreCompute(instanceHandle,
+ hashAlgorithm,
+ authKeyLenInBytes,
+ pAuthKey,
+ pWorkingBuffer,
+ pState2,
+ callbackFn,
+ pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_AES_CCM == hashAlgorithm) {
+ /*
+ * The Inner Hash Initial State2 block must contain K
+ * (the cipher key) and 16 zeroes which will be replaced with
+ * EK(Ctr0) by the QAT-ME.
+ */
+
+ /* write the auth key which for CCM is equivalent to cipher key
+ */
+ memcpy(pState2,
+ pSessionSetup->cipherSetupData.pCipherKey,
+ pSessionSetup->cipherSetupData.cipherKeyLenInBytes);
+
+ /* initialize remaining buffer space to all zeroes */
+ LAC_OS_BZERO(
+ pState2 +
+ pSessionSetup->cipherSetupData.cipherKeyLenInBytes,
+ ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ);
+
+ /* There is no request sent to the QAT for this operation,
+ * so just invoke the user's callback directly to signal
+ * completion of the precompute
+ */
+ callbackFn(pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
+ /*
+ * The Inner Hash Initial State2 block contains the following
+ * H (the Galois Hash Multiplier)
+ * len(A) (the length of A), (length before padding)
+ * 16 zeroes which will be replaced with EK(Ctr0) by the
+ * QAT.
+ */
+
+ /* Memset state2 to 0 */
+ LAC_OS_BZERO(pState2,
+ ICP_QAT_HW_GALOIS_H_SZ +
+ ICP_QAT_HW_GALOIS_LEN_A_SZ +
+ ICP_QAT_HW_GALOIS_E_CTR0_SZ);
+
+ /* write H (the Galois Hash Multiplier) where H = E(K, 0...0)
+ * This will only write bytes 0-15 of pState2
+ */
+ status = LacSymHash_AesECBPreCompute(
+ instanceHandle,
+ hashAlgorithm,
+ pSessionSetup->cipherSetupData.cipherKeyLenInBytes,
+ pSessionSetup->cipherSetupData.pCipherKey,
+ pWorkingBuffer,
+ pState2,
+ callbackFn,
+ pCallbackTag);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* write len(A) (the length of A) into bytes 16-19 of
+ * pState2
+ * in big-endian format. This field is 8 bytes */
+ *(Cpa32U *)&pState2[ICP_QAT_HW_GALOIS_H_SZ] =
+ LAC_MEM_WR_32(pAuthModeSetupData->aadLenInBytes);
+ }
+ } else if (CPA_CY_SYM_HASH_KASUMI_F9 == hashAlgorithm) {
+ Cpa32U wordIndex = 0;
+ Cpa32U *pTempKey = (Cpa32U *)(pState2 + authKeyLenInBytes);
+ /*
+ * The Inner Hash Initial State2 block must contain IK
+ * (Initialisation Key), followed by IK XOR-ed with KM
+ * (Key Modifier): IK||(IK^KM).
+ */
+
+ /* write the auth key */
+ memcpy(pState2, pAuthKey, authKeyLenInBytes);
+ /* initialise temp key with auth key */
+ memcpy(pTempKey, pAuthKey, authKeyLenInBytes);
+
+ /* XOR Key with KASUMI F9 key modifier at 4 bytes level */
+ for (wordIndex = 0;
+ wordIndex < LAC_BYTES_TO_LONGWORDS(authKeyLenInBytes);
+ wordIndex++) {
+ pTempKey[wordIndex] ^=
+ LAC_HASH_KASUMI_F9_KEY_MODIFIER_4_BYTES;
+ }
+ /* There is no request sent to the QAT for this operation,
+ * so just invoke the user's callback directly to signal
+ * completion of the precompute
+ */
+ callbackFn(pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == hashAlgorithm) {
+ /*
+ * The Inner Hash Initial State2 should be all zeros
+ */
+ LAC_OS_BZERO(pState2, ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ);
+
+ /* There is no request sent to the QAT for this operation,
+ * so just invoke the user's callback directly to signal
+ * completion of the precompute
+ */
+ callbackFn(pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 == hashAlgorithm) {
+ /*
+ * The Inner Hash Initial State2 should contain the key
+ * and zero the rest of the state.
+ */
+ LAC_OS_BZERO(pState2, ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ);
+ memcpy(pState2, pAuthKey, authKeyLenInBytes);
+
+ /* There is no request sent to the QAT for this operation,
+ * so just invoke the user's callback directly to signal
+ * completion of the precompute
+ */
+ callbackFn(pCallbackTag);
+ } else if (CPA_CY_SYM_HASH_POLY == hashAlgorithm) {
+ /* There is no request sent to the QAT for this operation,
+ * so just invoke the user's callback directly to signal
+ * completion of the precompute
+ */
+ callbackFn(pCallbackTag);
+ } else /* For Hmac Precomputes */
+ {
+ status = LacSymHash_HmacPreComputes(instanceHandle,
+ hashAlgorithm,
+ authKeyLenInBytes,
+ pAuthKey,
+ pWorkingBuffer,
+ pState1,
+ pState2,
+ callbackFn,
+ pCallbackTag);
+ }
+
+ return status;
+}
+
+
+/** @ingroup LacHash */
+CpaStatus
+LacHash_HashContextCheck(CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData)
+{
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
+ lac_sym_qat_hash_alg_info_t *pOuterHashAlgInfo = NULL;
+ CpaCySymCapabilitiesInfo capInfo;
+
+ /*Protect against value of hash outside the bitmap*/
+ if ((pHashSetupData->hashAlgorithm) >=
+ CPA_CY_SYM_HASH_CAP_BITMAP_SIZE) {
+ LAC_INVALID_PARAM_LOG("hashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ cpaCySymQueryCapabilities(instanceHandle, &capInfo);
+ if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
+ pHashSetupData->hashAlgorithm) &&
+ pHashSetupData->hashAlgorithm != CPA_CY_SYM_HASH_AES_CBC_MAC) {
+ /* Ensure SHAKE algorithms are not supported */
+ if ((CPA_CY_SYM_HASH_SHAKE_128 ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHAKE_256 ==
+ pHashSetupData->hashAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Hash algorithms SHAKE-128 and SHAKE-256 "
+ "are not supported.");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ LAC_INVALID_PARAM_LOG("hashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ switch (pHashSetupData->hashMode) {
+ case CPA_CY_SYM_HASH_MODE_PLAIN:
+ case CPA_CY_SYM_HASH_MODE_AUTH:
+ case CPA_CY_SYM_HASH_MODE_NESTED:
+ break;
+
+ default: {
+ LAC_INVALID_PARAM_LOG("hashMode");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(pHashSetupData->hashAlgorithm,
+ pHashSetupData->hashMode)) {
+ LAC_INVALID_PARAM_LOG("hashAlgorithm and hashMode combination");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ pHashSetupData->hashAlgorithm,
+ &pHashAlgInfo);
+
+ /* note: nested hash mode checks digest length against outer algorithm
+ */
+ if ((CPA_CY_SYM_HASH_MODE_PLAIN == pHashSetupData->hashMode) ||
+ (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode)) {
+ /* Check Digest Length is permitted by the algorithm */
+ if ((0 == pHashSetupData->digestResultLenInBytes) ||
+ (pHashSetupData->digestResultLenInBytes >
+ pHashAlgInfo->digestLength)) {
+ LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ if (CPA_CY_SYM_HASH_MODE_AUTH == pHashSetupData->hashMode) {
+ if (CPA_CY_SYM_HASH_AES_GCM == pHashSetupData->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_GMAC == pHashSetupData->hashAlgorithm) {
+ Cpa32U aadDataSize = 0;
+
+ /* RFC 4106: Implementations MUST support a full-length
+ * 16-octet
+ * ICV, and MAY support 8 or 12 octet ICVs, and MUST NOT
+ * support
+ * other ICV lengths. */
+ if ((pHashSetupData->digestResultLenInBytes !=
+ LAC_HASH_AES_GCM_ICV_SIZE_8) &&
+ (pHashSetupData->digestResultLenInBytes !=
+ LAC_HASH_AES_GCM_ICV_SIZE_12) &&
+ (pHashSetupData->digestResultLenInBytes !=
+ LAC_HASH_AES_GCM_ICV_SIZE_16)) {
+ LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure aadLen is within maximum limit imposed by QAT
+ */
+ aadDataSize =
+ pHashSetupData->authModeSetupData.aadLenInBytes;
+
+ /* round the aad size to the multiple of GCM hash block
+ * size. */
+ aadDataSize =
+ LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
+ LAC_HASH_AES_GCM_BLOCK_SIZE);
+
+ if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX &&
+ CPA_CY_SYM_HASH_AES_GMAC !=
+ pHashSetupData->hashAlgorithm) {
+ LAC_INVALID_PARAM_LOG("aadLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_AES_CCM ==
+ pHashSetupData->hashAlgorithm) {
+ Cpa32U aadDataSize = 0;
+
+ /* RFC 3610: Valid values are 4, 6, 8, 10, 12, 14, and
+ * 16 octets */
+ if ((pHashSetupData->digestResultLenInBytes >=
+ LAC_HASH_AES_CCM_ICV_SIZE_MIN) &&
+ (pHashSetupData->digestResultLenInBytes <=
+ LAC_HASH_AES_CCM_ICV_SIZE_MAX)) {
+ if ((pHashSetupData->digestResultLenInBytes &
+ 0x01) != 0) {
+ LAC_INVALID_PARAM_LOG(
+ "digestResultLenInBytes must be a multiple of 2");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* ensure aadLen is within maximum limit imposed by QAT
+ */
+ /* at the beginning of the buffer there is B0 block */
+ aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
+
+ /* then, if there is some 'a' data, the buffer will
+ * store encoded
+ * length of 'a' and 'a' itself */
+ if (pHashSetupData->authModeSetupData.aadLenInBytes >
+ 0) {
+ /* as the QAT API puts the requirement on the
+ * pAdditionalAuthData not to be bigger than 240
+ * bytes then we
+ * just need 2 bytes to store encoded length of
+ * 'a' */
+ aadDataSize += sizeof(Cpa16U);
+ aadDataSize += pHashSetupData->authModeSetupData
+ .aadLenInBytes;
+ }
+
+ /* round the aad size to the multiple of CCM block
+ * size.*/
+ aadDataSize =
+ LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
+ LAC_HASH_AES_CCM_BLOCK_SIZE);
+ if (aadDataSize > ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
+ LAC_INVALID_PARAM_LOG("aadLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_KASUMI_F9 ==
+ pHashSetupData->hashAlgorithm) {
+ /* QAT-FW only supports 128 bit Integrity Key size for
+ * Kasumi f9
+ * Ref: 3GPP TS 35.201 version 7.0.0 Release 7 */
+ if (pHashSetupData->authModeSetupData
+ .authKeyLenInBytes !=
+ ICP_QAT_HW_KASUMI_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pHashSetupData->hashAlgorithm) {
+
+ /* QAT-FW only supports 128 bits Integrity Key size for
+ * Snow3g */
+ if (pHashSetupData->authModeSetupData
+ .authKeyLenInBytes !=
+ ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ /* For Snow3g hash aad field contains IV - it needs to
+ * be 16
+ * bytes long
+ */
+ if (pHashSetupData->authModeSetupData.aadLenInBytes !=
+ ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ) {
+ LAC_INVALID_PARAM_LOG("aadLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_AES_XCBC ==
+ pHashSetupData->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_CMAC ==
+ pHashSetupData->hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_CBC_MAC ==
+ pHashSetupData->hashAlgorithm) {
+ /* ensure auth key len is valid (128-bit keys supported)
+ */
+ if ((pHashSetupData->authModeSetupData
+ .authKeyLenInBytes !=
+ ICP_QAT_HW_AES_128_KEY_SZ)) {
+ LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pHashSetupData->hashAlgorithm) {
+
+ /* QAT-FW only supports 128 bits Integrity Key size for
+ * ZUC */
+ if (pHashSetupData->authModeSetupData
+ .authKeyLenInBytes !=
+ ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ) {
+ LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ /* For ZUC EIA3 hash aad field contains IV - it needs to
+ * be 16
+ * bytes long
+ */
+ if (pHashSetupData->authModeSetupData.aadLenInBytes !=
+ ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ) {
+ LAC_INVALID_PARAM_LOG("aadLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else if (CPA_CY_SYM_HASH_POLY ==
+ pHashSetupData->hashAlgorithm) {
+ if (pHashSetupData->digestResultLenInBytes !=
+ ICP_QAT_HW_SPC_CTR_SZ) {
+ LAC_INVALID_PARAM_LOG("Digest Length for CCP");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ if (pHashSetupData->authModeSetupData.aadLenInBytes >
+ ICP_QAT_FW_CCM_GCM_AAD_SZ_MAX) {
+ LAC_INVALID_PARAM_LOG("AAD Length for CCP");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ /* The key size must be less than or equal the block
+ * length */
+ if (pHashSetupData->authModeSetupData
+ .authKeyLenInBytes >
+ pHashAlgInfo->blockLength) {
+ LAC_INVALID_PARAM_LOG("authKeyLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* when the key size is greater than 0 check pointer is not null
+ */
+ if (CPA_CY_SYM_HASH_AES_CCM != pHashSetupData->hashAlgorithm &&
+ CPA_CY_SYM_HASH_AES_GCM != pHashSetupData->hashAlgorithm &&
+ pHashSetupData->authModeSetupData.authKeyLenInBytes > 0) {
+ LAC_CHECK_NULL_PARAM(
+ pHashSetupData->authModeSetupData.authKey);
+ }
+ } else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
+ if (!CPA_BITMAP_BIT_TEST(capInfo.hashes,
+ pHashSetupData->nestedModeSetupData
+ .outerHashAlgorithm)) {
+ /* Ensure SHAKE algorithms are not supported */
+ if ((CPA_CY_SYM_HASH_SHAKE_128 ==
+ pHashSetupData->nestedModeSetupData
+ .outerHashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SHAKE_256 ==
+ pHashSetupData->nestedModeSetupData
+ .outerHashAlgorithm)) {
+ LAC_INVALID_PARAM_LOG(
+ "Hash algorithms SHAKE-128 and SHAKE-256 "
+ "are not supported.");
+ return CPA_STATUS_UNSUPPORTED;
+ }
+
+ LAC_INVALID_PARAM_LOG("outerHashAlgorithm");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (LAC_HASH_ALG_MODE_NOT_SUPPORTED(
+ pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
+ pHashSetupData->hashMode)) {
+ LAC_INVALID_PARAM_LOG(
+ "outerHashAlgorithm and hashMode combination");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ LacSymQat_HashAlgLookupGet(
+ instanceHandle,
+ pHashSetupData->nestedModeSetupData.outerHashAlgorithm,
+ &pOuterHashAlgInfo);
+
+ /* Check Digest Length is permitted by the algorithm */
+ if ((0 == pHashSetupData->digestResultLenInBytes) ||
+ (pHashSetupData->digestResultLenInBytes >
+ pOuterHashAlgInfo->digestLength)) {
+ LAC_INVALID_PARAM_LOG("digestResultLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
+ LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
+ LAC_INVALID_PARAM_LOG("innerPrefixLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes >
+ 0) {
+ LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
+ .pInnerPrefixData);
+ }
+
+ if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
+ LAC_MAX_INNER_OUTER_PREFIX_SIZE_BYTES) {
+ LAC_INVALID_PARAM_LOG("outerPrefixLenInBytes");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes >
+ 0) {
+ LAC_CHECK_NULL_PARAM(pHashSetupData->nestedModeSetupData
+ .pOuterPrefixData);
+ }
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/** @ingroup LacHash */
+CpaStatus
+LacHash_PerformParamCheck(CpaInstanceHandle instanceHandle,
+ lac_session_desc_t *pSessionDesc,
+ const CpaCySymOpData *pOpData,
+ Cpa64U srcPktSize,
+ const CpaBoolean *pVerifyResult)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
+
+ /* digestVerify and digestIsAppended on Hash-Only operation not
+ * supported */
+ if (pSessionDesc->digestIsAppended && pSessionDesc->digestVerify &&
+ (CPA_CY_SYM_OP_HASH == pSessionDesc->symOperation)) {
+ LAC_INVALID_PARAM_LOG(
+ "digestVerify and digestIsAppended set "
+ "on Hash-Only operation is not supported");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* check the digest result pointer */
+ if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
+ !pSessionDesc->digestIsAppended &&
+ (NULL == pOpData->pDigestResult)) {
+ LAC_INVALID_PARAM_LOG("pDigestResult is NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /*
+ * Check if the pVerifyResult pointer is not null for hash operation
+ * when
+ * the packet is the last one and user has set verifyDigest flag
+ * Also, this is only needed for symchronous operation, so check if the
+ * callback pointer is the internal synchronous one rather than a user-
+ * supplied one.
+ */
+ if ((CPA_TRUE == pSessionDesc->digestVerify) &&
+ (CPA_CY_SYM_PACKET_TYPE_PARTIAL != pOpData->packetType) &&
+ (LacSync_GenBufListVerifyCb == pSessionDesc->pSymCb)) {
+ if (NULL == pVerifyResult) {
+ LAC_INVALID_PARAM_LOG(
+ "Null pointer pVerifyResult for hash op");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* verify start offset + messageLenToDigest is inside the source packet.
+ * this also verifies that the start offset is inside the packet
+ * Note: digest is specified as a pointer therefore it can be
+ * written anywhere so we cannot check for this been inside a buffer
+ * CCM/GCM specify the auth region using just the cipher params as this
+ * region is the same for auth and cipher. It is not checked here */
+ if ((CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm)) {
+ /* ensure AAD data pointer is non-NULL if AAD len > 0 */
+ if ((pSessionDesc->aadLenInBytes > 0) &&
+ (NULL == pOpData->pAdditionalAuthData)) {
+ LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ if ((pOpData->hashStartSrcOffsetInBytes +
+ pOpData->messageLenToHashInBytes) > srcPktSize) {
+ LAC_INVALID_PARAM_LOG(
+ "hashStartSrcOffsetInBytes + "
+ "messageLenToHashInBytes > Src Buffer Packet Length");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* For Snow3g & ZUC hash pAdditionalAuthData field
+ * of OpData should contain IV */
+ if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 == pSessionDesc->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_ZUC_EIA3 == pSessionDesc->hashAlgorithm)) {
+ if (NULL == pOpData->pAdditionalAuthData) {
+ LAC_INVALID_PARAM_LOG("pAdditionalAuthData is NULL");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* partial packets need to be multiples of the algorithm block size in
+ * hash
+ * only mode (except for final partial packet) */
+ if ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == pOpData->packetType) &&
+ (CPA_CY_SYM_OP_HASH == pSessionDesc->symOperation)) {
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ pSessionDesc->hashAlgorithm,
+ &pHashAlgInfo);
+
+ /* check if the message is a multiple of the block size. */
+ if ((pOpData->messageLenToHashInBytes %
+ pHashAlgInfo->blockLength) != 0) {
+ LAC_INVALID_PARAM_LOG(
+ "messageLenToHashInBytes not block size");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ return status;
+}
+
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash_sw_precomputes.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash_sw_precomputes.c
new file mode 100644
index 000000000000..be3a39755b4a
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_hash_sw_precomputes.c
@@ -0,0 +1,353 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_hash_sw_precomputes.c
+ *
+ * @ingroup LacHashDefs
+ *
+ * Hash Software
+ ***************************************************************************/
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+
+#include "qat_utils.h"
+#include "lac_mem.h"
+#include "lac_sym.h"
+#include "lac_log.h"
+#include "lac_mem_pools.h"
+#include "lac_list.h"
+#include "lac_sym_hash_defs.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sal.h"
+#include "lac_session.h"
+#include "lac_sym_hash_precomputes.h"
+
+static CpaStatus
+LacSymHash_Compute(CpaCySymHashAlgorithm hashAlgorithm,
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo,
+ Cpa8U *in,
+ Cpa8U *out)
+{
+ /*
+ * Note: from SHA hashes appropriate endian swapping is required.
+ * For sha1, sha224 and sha256 double words based swapping.
+ * For sha384 and sha512 quad words swapping.
+ * No endianes swapping for md5 is required.
+ */
+ CpaStatus status = CPA_STATUS_FAIL;
+ Cpa32U i = 0;
+ switch (hashAlgorithm) {
+ case CPA_CY_SYM_HASH_MD5:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashMD5(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashMD5 Failed\n");
+ return status;
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ case CPA_CY_SYM_HASH_SHA1:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashSHA1(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashSHA1 Failed\n");
+ return status;
+ }
+ for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
+ i++) {
+ ((Cpa32U *)(out))[i] =
+ LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ case CPA_CY_SYM_HASH_SHA224:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashSHA224(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashSHA224 Failed\n");
+ return status;
+ }
+ for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
+ i++) {
+ ((Cpa32U *)(out))[i] =
+ LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ case CPA_CY_SYM_HASH_SHA256:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashSHA256(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashSHA256 Failed\n");
+ return status;
+ }
+ for (i = 0; i < LAC_BYTES_TO_LONGWORDS(pHashAlgInfo->stateSize);
+ i++) {
+ ((Cpa32U *)(out))[i] =
+ LAC_MEM_WR_32(((Cpa32U *)(out))[i]);
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ case CPA_CY_SYM_HASH_SHA384:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashSHA384(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashSHA384 Failed\n");
+ return status;
+ }
+ for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize);
+ i++) {
+ ((Cpa64U *)(out))[i] =
+ LAC_MEM_WR_64(((Cpa64U *)(out))[i]);
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ case CPA_CY_SYM_HASH_SHA512:
+ if (CPA_STATUS_SUCCESS != qatUtilsHashSHA512(in, out)) {
+ LAC_LOG_ERROR("qatUtilsHashSHA512 Failed\n");
+ return status;
+ }
+ for (i = 0; i < LAC_BYTES_TO_QUADWORDS(pHashAlgInfo->stateSize);
+ i++) {
+ ((Cpa64U *)(out))[i] =
+ LAC_MEM_WR_64(((Cpa64U *)(out))[i]);
+ }
+ status = CPA_STATUS_SUCCESS;
+ break;
+ default:
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ return status;
+}
+
+CpaStatus
+LacSymHash_HmacPreComputes(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ Cpa32U authKeyLenInBytes,
+ Cpa8U *pAuthKey,
+ Cpa8U *pWorkingMemory,
+ Cpa8U *pState1,
+ Cpa8U *pState2,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag)
+{
+ Cpa8U *pIpadData = NULL;
+ Cpa8U *pOpadData = NULL;
+ CpaStatus status = CPA_STATUS_FAIL;
+ lac_sym_hash_precomp_op_data_t *pHmacIpadOpData =
+ (lac_sym_hash_precomp_op_data_t *)pWorkingMemory;
+ lac_sym_hash_precomp_op_data_t *pHmacOpadOpData = pHmacIpadOpData + 1;
+
+ /* Convenience pointers */
+ lac_sym_hash_hmac_precomp_qat_t *pHmacIpadQatData =
+ &pHmacIpadOpData->u.hmacQatData;
+ lac_sym_hash_hmac_precomp_qat_t *pHmacOpadQatData =
+ &pHmacOpadOpData->u.hmacQatData;
+
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
+ Cpa32U i = 0;
+ Cpa32U padLenBytes = 0;
+
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ hashAlgorithm,
+ &pHashAlgInfo);
+ pHmacIpadOpData->stateSize = pHashAlgInfo->stateSize;
+ pHmacOpadOpData->stateSize = pHashAlgInfo->stateSize;
+
+ /* Copy HMAC key into buffers */
+ if (authKeyLenInBytes > 0) {
+ memcpy(pHmacIpadQatData->data, pAuthKey, authKeyLenInBytes);
+ memcpy(pHmacOpadQatData->data, pAuthKey, authKeyLenInBytes);
+ }
+
+ padLenBytes = pHashAlgInfo->blockLength - authKeyLenInBytes;
+
+ /* Clear the remaining buffer space */
+ if (padLenBytes > 0) {
+ LAC_OS_BZERO(pHmacIpadQatData->data + authKeyLenInBytes,
+ padLenBytes);
+ LAC_OS_BZERO(pHmacOpadQatData->data + authKeyLenInBytes,
+ padLenBytes);
+ }
+
+ /* XOR Key with IPAD at 4-byte level */
+ for (i = 0; i < pHashAlgInfo->blockLength; i++) {
+ Cpa8U *ipad = pHmacIpadQatData->data + i;
+ Cpa8U *opad = pHmacOpadQatData->data + i;
+
+ *ipad ^= LAC_HASH_IPAD_BYTE;
+ *opad ^= LAC_HASH_OPAD_BYTE;
+ }
+ pIpadData = (Cpa8U *)pHmacIpadQatData->data;
+ pOpadData = (Cpa8U *)pHmacOpadQatData->data;
+
+ status = LacSymHash_Compute(hashAlgorithm,
+ pHashAlgInfo,
+ (Cpa8U *)pIpadData,
+ pState1);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = LacSymHash_Compute(hashAlgorithm,
+ pHashAlgInfo,
+ (Cpa8U *)pOpadData,
+ pState2);
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ callbackFn(pCallbackTag);
+ }
+ return status;
+}
+
+CpaStatus
+LacSymHash_AesECBPreCompute(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ Cpa32U authKeyLenInBytes,
+ Cpa8U *pAuthKey,
+ Cpa8U *pWorkingMemory,
+ Cpa8U *pState,
+ lac_hash_precompute_done_cb_t callbackFn,
+ void *pCallbackTag)
+{
+ CpaStatus status = CPA_STATUS_FAIL;
+ Cpa32U stateSize = 0, x = 0;
+ lac_sym_qat_hash_alg_info_t *pHashAlgInfo = NULL;
+
+ if (CPA_CY_SYM_HASH_AES_XCBC == hashAlgorithm) {
+ Cpa8U *in = pWorkingMemory;
+ Cpa8U *out = pState;
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ hashAlgorithm,
+ &pHashAlgInfo);
+ stateSize = pHashAlgInfo->stateSize;
+ memcpy(pWorkingMemory, pHashAlgInfo->initState, stateSize);
+
+ for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM; x++) {
+ if (CPA_STATUS_SUCCESS !=
+ qatUtilsAESEncrypt(
+ pAuthKey, authKeyLenInBytes, in, out)) {
+ return status;
+ }
+ in += LAC_HASH_XCBC_MAC_BLOCK_SIZE;
+ out += LAC_HASH_XCBC_MAC_BLOCK_SIZE;
+ }
+ status = CPA_STATUS_SUCCESS;
+ } else if (CPA_CY_SYM_HASH_AES_CMAC == hashAlgorithm) {
+ Cpa8U *out = pState;
+ Cpa8U k1[LAC_HASH_CMAC_BLOCK_SIZE],
+ k2[LAC_HASH_CMAC_BLOCK_SIZE];
+ Cpa8U *ptr = NULL, i = 0;
+ stateSize = LAC_HASH_CMAC_BLOCK_SIZE;
+ LacSymQat_HashAlgLookupGet(instanceHandle,
+ hashAlgorithm,
+ &pHashAlgInfo);
+ /* Original state size includes K, K1 and K2 which are of equal
+ * length.
+ * For precompute state size is only of the length of K which is
+ * equal
+ * to the block size for CPA_CY_SYM_HASH_AES_CMAC.
+ * The algorithm is described in rfc4493
+ * K is just copeid, K1 and K2 need to be single inplace encrypt
+ * with AES.
+ * */
+ memcpy(out, pHashAlgInfo->initState, stateSize);
+ memcpy(out, pAuthKey, authKeyLenInBytes);
+ out += LAC_HASH_CMAC_BLOCK_SIZE;
+
+ for (x = 0; x < LAC_HASH_XCBC_PRECOMP_KEY_NUM - 1; x++) {
+ if (CPA_STATUS_SUCCESS !=
+ qatUtilsAESEncrypt(
+ pAuthKey, authKeyLenInBytes, out, out)) {
+ return status;
+ }
+ out += LAC_HASH_CMAC_BLOCK_SIZE;
+ }
+
+ ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE;
+
+ /* Derived keys (k1 and k2), copy them to
+ * pPrecompOpData->pState,
+ * but remember that at the beginning is original key (K0)
+ */
+ /* Calculating K1 */
+ for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++, ptr++) {
+ k1[i] = (*ptr) << 1;
+ if (i != 0) {
+ k1[i - 1] |=
+ (*ptr) >> (LAC_NUM_BITS_IN_BYTE - 1);
+ }
+ if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) {
+ /* If msb of pState + LAC_HASH_CMAC_BLOCK_SIZE
+ is set xor
+ with RB. Because only the final byte of RB is
+ non-zero
+ this is all we need to xor */
+ if ((*(pState + LAC_HASH_CMAC_BLOCK_SIZE)) &
+ LAC_SYM_HASH_MSBIT_MASK) {
+ k1[i] ^= LAC_SYM_AES_CMAC_RB_128;
+ }
+ }
+ }
+
+ /* Calculating K2 */
+ for (i = 0; i < LAC_HASH_CMAC_BLOCK_SIZE; i++) {
+ k2[i] = (k1[i]) << 1;
+ if (i != 0) {
+ k2[i - 1] |=
+ (k1[i]) >> (LAC_NUM_BITS_IN_BYTE - 1);
+ }
+ if (i + 1 == LAC_HASH_CMAC_BLOCK_SIZE) {
+ /* If msb of k1 is set xor last byte with RB */
+ if (k1[0] & LAC_SYM_HASH_MSBIT_MASK) {
+ k2[i] ^= LAC_SYM_AES_CMAC_RB_128;
+ }
+ }
+ }
+ /* Now, when we have K1 & K2 lets copy them to the state2 */
+ ptr = pState + LAC_HASH_CMAC_BLOCK_SIZE;
+ memcpy(ptr, k1, LAC_HASH_CMAC_BLOCK_SIZE);
+ ptr += LAC_HASH_CMAC_BLOCK_SIZE;
+ memcpy(ptr, k2, LAC_HASH_CMAC_BLOCK_SIZE);
+ status = CPA_STATUS_SUCCESS;
+ } else if (CPA_CY_SYM_HASH_AES_GCM == hashAlgorithm ||
+ CPA_CY_SYM_HASH_AES_GMAC == hashAlgorithm) {
+ Cpa8U *in = pWorkingMemory;
+ Cpa8U *out = pState;
+ LAC_OS_BZERO(pWorkingMemory, ICP_QAT_HW_GALOIS_H_SZ);
+
+ if (CPA_STATUS_SUCCESS !=
+ qatUtilsAESEncrypt(pAuthKey, authKeyLenInBytes, in, out)) {
+ return status;
+ }
+ status = CPA_STATUS_SUCCESS;
+ } else {
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ callbackFn(pCallbackTag);
+ return status;
+}
+
+CpaStatus
+LacSymHash_HmacPrecompInit(CpaInstanceHandle instanceHandle)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ return status;
+}
+
+void
+LacSymHash_HmacPrecompShutdown(CpaInstanceHandle instanceHandle)
+{
+ return;
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_partial.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_partial.c
new file mode 100644
index 000000000000..4a937c7d093a
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_partial.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_partial.c common partial packet functions
+ *
+ * @ingroup LacSym
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+
+#include "lac_log.h"
+#include "lac_sym.h"
+#include "cpa_cy_sym.h"
+#include "lac_common.h"
+
+#include "lac_sym_partial.h"
+
+CpaStatus
+LacSym_PartialPacketStateCheck(CpaCySymPacketType packetType,
+ CpaCySymPacketType partialState)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* ASSUMPTION - partial requests on a given session must be issued
+ * sequentially to guarantee ordering
+ * (i.e. issuing partials on concurrent threads for a particular session
+ * just wouldn't work)
+ */
+
+ /* state is no partial - only a partial is allowed */
+ if (((CPA_CY_SYM_PACKET_TYPE_FULL == partialState) &&
+ (CPA_CY_SYM_PACKET_TYPE_PARTIAL == packetType)) ||
+
+ /* state is partial - only a partial or final partial is allowed */
+ ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == partialState) &&
+ ((CPA_CY_SYM_PACKET_TYPE_PARTIAL == packetType) ||
+ (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packetType)))) {
+ status = CPA_STATUS_SUCCESS;
+ } else /* invalid sequence */
+ {
+ LAC_INVALID_PARAM_LOG("invalid partial packet sequence");
+ status = CPA_STATUS_INVALID_PARAM;
+ }
+
+ return status;
+}
+
+void
+LacSym_PartialPacketStateUpdate(CpaCySymPacketType packetType,
+ CpaCySymPacketType *pPartialState)
+{
+ /* if previous packet was either a full or ended a partial stream,
+ * update
+ * state to partial to indicate a new partial stream was created */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL == *pPartialState) {
+ *pPartialState = CPA_CY_SYM_PACKET_TYPE_PARTIAL;
+ } else {
+ /* if packet type is final - reset the partial state */
+ if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packetType) {
+ *pPartialState = CPA_CY_SYM_PACKET_TYPE_FULL;
+ }
+ }
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_queue.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_queue.c
new file mode 100644
index 000000000000..977fb0b84d0b
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_queue.c
@@ -0,0 +1,165 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_queue.c Functions for sending/queuing symmetric requests
+ *
+ * @ingroup LacSym
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_debug.h"
+#include "icp_adf_transport.h"
+#include "lac_sym_queue.h"
+#include "lac_sym_qat.h"
+#include "lac_session.h"
+#include "lac_sym.h"
+#include "lac_log.h"
+#include "icp_qat_fw_la.h"
+#include "lac_sal_types_crypto.h"
+
+#define GetSingleBitFromByte(byte, bit) ((byte) & (1 << (bit)))
+
+/*
+*******************************************************************************
+* Define public/global function definitions
+*******************************************************************************
+*/
+
+CpaStatus
+LacSymQueue_RequestSend(const CpaInstanceHandle instanceHandle,
+ lac_sym_bulk_cookie_t *pRequest,
+ lac_session_desc_t *pSessionDesc)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaBoolean enqueued = CPA_FALSE;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+ /* Enqueue the message instead of sending directly if:
+ * (i) a blocking operation is in progress
+ * (ii) there are previous requests already in the queue
+ */
+ if ((CPA_FALSE == pSessionDesc->nonBlockingOpsInProgress) ||
+ (NULL != pSessionDesc->pRequestQueueTail)) {
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINLOCK(&pSessionDesc->requestQueueLock)) {
+ LAC_LOG_ERROR("Failed to lock request queue");
+ return CPA_STATUS_RESOURCE;
+ }
+
+ /* Re-check blockingOpsInProgress and pRequestQueueTail in case
+ * either
+ * changed before the lock was acquired. The lock is shared
+ * with
+ * the callback context which drains this queue
+ */
+ if ((CPA_FALSE == pSessionDesc->nonBlockingOpsInProgress) ||
+ (NULL != pSessionDesc->pRequestQueueTail)) {
+ /* Enqueue the message and exit */
+ /* The FIFO queue is made up of a head and tail pointer.
+ * The head pointer points to the first/oldest, entry
+ * in the queue, and the tail pointer points to the
+ * last/newest
+ * entry in the queue
+ */
+
+ if (NULL != pSessionDesc->pRequestQueueTail) {
+ /* Queue is non-empty. Add this request to the
+ * list */
+ pSessionDesc->pRequestQueueTail->pNext =
+ pRequest;
+ } else {
+ /* Queue is empty. Initialise the head pointer
+ * as well */
+ pSessionDesc->pRequestQueueHead = pRequest;
+ }
+
+ pSessionDesc->pRequestQueueTail = pRequest;
+
+ /* request is queued, don't send to QAT here */
+ enqueued = CPA_TRUE;
+ }
+ if (CPA_STATUS_SUCCESS !=
+ LAC_SPINUNLOCK(&pSessionDesc->requestQueueLock)) {
+ LAC_LOG_ERROR("Failed to unlock request queue");
+ }
+ }
+
+ if (CPA_FALSE == enqueued) {
+ /* If we send a partial packet request, set the
+ * blockingOpsInProgress
+ * flag for the session to indicate that subsequent requests
+ * must be
+ * queued up until this request completes
+ *
+ * @assumption
+ * If we have got here it means that there were no previous
+ * blocking
+ * operations in progress and, since multiple partial packet
+ * requests
+ * on a given session cannot be issued concurrently, there
+ * should be
+ * no need for a critical section around the following code
+ */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL !=
+ pRequest->pOpData->packetType) {
+ /* Select blocking operations which this reqest will
+ * complete */
+ pSessionDesc->nonBlockingOpsInProgress = CPA_FALSE;
+ }
+
+ /* At this point, we're clear to send the request. For cipher
+ * requests,
+ * we need to check if the session IV needs to be updated. This
+ * can
+ * only be done when no other partials are in flight for this
+ * session,
+ * to ensure the cipherPartialOpState buffer in the session
+ * descriptor
+ * is not currently in use
+ */
+ if (CPA_TRUE == pRequest->updateSessionIvOnSend) {
+ if (LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm)) {
+ memcpy(pSessionDesc->cipherPartialOpState,
+ pSessionDesc->cipherARC4InitialState,
+ LAC_CIPHER_ARC4_STATE_LEN_BYTES);
+ } else {
+ memcpy(pSessionDesc->cipherPartialOpState,
+ pRequest->pOpData->pIv,
+ pRequest->pOpData->ivLenInBytes);
+ }
+ }
+
+ /* Send to QAT */
+ status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
+ (void *)&(pRequest->qatMsg),
+ LAC_QAT_SYM_REQ_SZ_LW);
+
+ /* if fail to send request, we need to change
+ * nonBlockingOpsInProgress
+ * to CPA_TRUE
+ */
+ if ((CPA_STATUS_SUCCESS != status) &&
+ (CPA_CY_SYM_PACKET_TYPE_FULL !=
+ pRequest->pOpData->packetType)) {
+ pSessionDesc->nonBlockingOpsInProgress = CPA_TRUE;
+ }
+ }
+ return status;
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_stats.c b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_stats.c
new file mode 100644
index 000000000000..ca1bbb99d3a4
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/lac_sym_stats.c
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_stats.c Implementation of symmetric stats
+ *
+ * @ingroup LacSym
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "lac_mem_pools.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "icp_qat_fw_la.h"
+#include "lac_sym_qat.h"
+#include "lac_sym_stats.h"
+#include "lac_sal_types_crypto.h"
+#include "sal_statistics.h"
+
+/* Number of Symmetric Crypto statistics */
+#define LAC_SYM_NUM_STATS (sizeof(CpaCySymStats64) / sizeof(Cpa64U))
+
+CpaStatus
+LacSym_StatsInit(CpaInstanceHandle instanceHandle)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ pService->pLacSymStatsArr =
+ LAC_OS_MALLOC(LAC_SYM_NUM_STATS * sizeof(QatUtilsAtomic));
+
+ if (NULL != pService->pLacSymStatsArr) {
+ LAC_OS_BZERO((void *)LAC_CONST_VOLATILE_PTR_CAST(
+ pService->pLacSymStatsArr),
+ LAC_SYM_NUM_STATS * sizeof(QatUtilsAtomic));
+ } else {
+ status = CPA_STATUS_RESOURCE;
+ }
+ return status;
+}
+
+void
+LacSym_StatsFree(CpaInstanceHandle instanceHandle)
+{
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+ if (NULL != pService->pLacSymStatsArr) {
+ LAC_OS_FREE(pService->pLacSymStatsArr);
+ }
+}
+
+void
+LacSym_StatsInc(Cpa32U offset, CpaInstanceHandle instanceHandle)
+{
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+ if (CPA_TRUE ==
+ pService->generic_service_info.stats->bSymStatsEnabled) {
+ qatUtilsAtomicInc(
+ &pService->pLacSymStatsArr[offset / sizeof(Cpa64U)]);
+ }
+}
+
+void
+LacSym_Stats32CopyGet(CpaInstanceHandle instanceHandle,
+ struct _CpaCySymStats *const pSymStats)
+{
+ int i = 0;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ for (i = 0; i < LAC_SYM_NUM_STATS; i++) {
+ ((Cpa32U *)pSymStats)[i] =
+ (Cpa32U)qatUtilsAtomicGet(&pService->pLacSymStatsArr[i]);
+ }
+}
+
+void
+LacSym_Stats64CopyGet(CpaInstanceHandle instanceHandle,
+ CpaCySymStats64 *const pSymStats)
+{
+ int i = 0;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ for (i = 0; i < LAC_SYM_NUM_STATS; i++) {
+ ((Cpa64U *)pSymStats)[i] =
+ qatUtilsAtomicGet(&pService->pLacSymStatsArr[i]);
+ }
+}
+
+void
+LacSym_StatsShow(CpaInstanceHandle instanceHandle)
+{
+ CpaCySymStats64 symStats = { 0 };
+
+ LacSym_Stats64CopyGet(instanceHandle, &symStats);
+
+ QAT_UTILS_LOG(SEPARATOR BORDER
+ " Symmetric Stats " BORDER
+ "\n" SEPARATOR);
+
+ /* Session Info */
+ QAT_UTILS_LOG(BORDER " Sessions Initialized: %16llu " BORDER
+ "\n" BORDER
+ " Sessions Removed: %16llu " BORDER
+ "\n" BORDER
+ " Session Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (unsigned long long)symStats.numSessionsInitialized,
+ (unsigned long long)symStats.numSessionsRemoved,
+ (unsigned long long)symStats.numSessionErrors);
+
+ /* Session info */
+ QAT_UTILS_LOG(
+ BORDER " Symmetric Requests: %16llu " BORDER "\n" BORDER
+ " Symmetric Request Errors: %16llu " BORDER "\n" BORDER
+ " Symmetric Completed: %16llu " BORDER "\n" BORDER
+ " Symmetric Completed Errors: %16llu " BORDER "\n" BORDER
+ " Symmetric Verify Failures: %16llu " BORDER
+ "\n" SEPARATOR,
+ (unsigned long long)symStats.numSymOpRequests,
+ (unsigned long long)symStats.numSymOpRequestErrors,
+ (unsigned long long)symStats.numSymOpCompleted,
+ (unsigned long long)symStats.numSymOpCompletedErrors,
+ (unsigned long long)symStats.numSymOpVerifyFailures);
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat.c b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat.c
new file mode 100644
index 000000000000..c55da0a0d531
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat.c
@@ -0,0 +1,227 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat.c Interfaces for populating the symmetric qat structures
+ *
+ * @ingroup LacSymQat
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "cpa.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "icp_accel_devices.h"
+#include "icp_adf_cfg.h"
+#include "lac_log.h"
+#include "lac_sym.h"
+#include "lac_sym_qat.h"
+#include "lac_sal_types_crypto.h"
+#include "sal_string_parse.h"
+#include "lac_sym_key.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_sym_qat_hash.h"
+
+#define EMBEDDED_CIPHER_KEY_MAX_SIZE 16
+static void
+LacSymQat_SymLogSliceHangError(icp_qat_fw_la_cmd_id_t symCmdId)
+{
+ Cpa8U cmdId = symCmdId;
+
+ switch (cmdId) {
+ case ICP_QAT_FW_LA_CMD_CIPHER:
+ case ICP_QAT_FW_LA_CMD_CIPHER_PRE_COMP:
+ LAC_LOG_ERROR("slice hang detected on CPM cipher slice.");
+ break;
+
+ case ICP_QAT_FW_LA_CMD_AUTH:
+ case ICP_QAT_FW_LA_CMD_AUTH_PRE_COMP:
+ LAC_LOG_ERROR("slice hang detected on CPM auth slice.");
+ break;
+
+ case ICP_QAT_FW_LA_CMD_CIPHER_HASH:
+ case ICP_QAT_FW_LA_CMD_HASH_CIPHER:
+ case ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE:
+ case ICP_QAT_FW_LA_CMD_TLS_V1_1_KEY_DERIVE:
+ case ICP_QAT_FW_LA_CMD_TLS_V1_2_KEY_DERIVE:
+ case ICP_QAT_FW_LA_CMD_MGF1:
+ default:
+ LAC_LOG_ERROR(
+ "slice hang detected on CPM cipher or auth slice.");
+ }
+ return;
+}
+
+/* sym crypto response handlers */
+static sal_qat_resp_handler_func_t
+ respHandlerSymTbl[ICP_QAT_FW_LA_CMD_DELIMITER];
+
+void
+LacSymQat_SymRespHandler(void *pRespMsg)
+{
+ Cpa8U lacCmdId = 0;
+ void *pOpaqueData = NULL;
+ icp_qat_fw_la_resp_t *pRespMsgFn = NULL;
+ Cpa8U opStatus = ICP_QAT_FW_COMN_STATUS_FLAG_OK;
+ Cpa8U comnErr = ERR_CODE_NO_ERROR;
+
+ pRespMsgFn = (icp_qat_fw_la_resp_t *)pRespMsg;
+ LAC_MEM_SHARED_READ_TO_PTR(pRespMsgFn->opaque_data, pOpaqueData);
+
+ lacCmdId = pRespMsgFn->comn_resp.cmd_id;
+ opStatus = pRespMsgFn->comn_resp.comn_status;
+ comnErr = pRespMsgFn->comn_resp.comn_error.s.comn_err_code;
+
+ /* log the slice hang and endpoint push/pull error inside the response
+ */
+ if (ERR_CODE_SSM_ERROR == (Cpa8S)comnErr) {
+ LacSymQat_SymLogSliceHangError(lacCmdId);
+ } else if (ERR_CODE_ENDPOINT_ERROR == (Cpa8S)comnErr) {
+ LAC_LOG_ERROR("The PCIe End Point Push/Pull or"
+ " TI/RI Parity error detected.");
+ }
+
+ /* call the response message handler registered for the command ID */
+ respHandlerSymTbl[lacCmdId]((icp_qat_fw_la_cmd_id_t)lacCmdId,
+ pOpaqueData,
+ (icp_qat_fw_comn_flags)opStatus);
+}
+
+CpaStatus
+LacSymQat_Init(CpaInstanceHandle instanceHandle)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* Initialise the Hash lookup table */
+ status = LacSymQat_HashLookupInit(instanceHandle);
+
+ return status;
+}
+
+void
+LacSymQat_RespHandlerRegister(icp_qat_fw_la_cmd_id_t lacCmdId,
+ sal_qat_resp_handler_func_t pCbHandler)
+{
+ if (lacCmdId >= ICP_QAT_FW_LA_CMD_DELIMITER) {
+ QAT_UTILS_LOG("Invalid Command ID\n");
+ return;
+ }
+
+ /* set the response handler for the command ID */
+ respHandlerSymTbl[lacCmdId] = pCbHandler;
+}
+
+void
+LacSymQat_LaPacketCommandFlagSet(Cpa32U qatPacketType,
+ icp_qat_fw_la_cmd_id_t laCmdId,
+ CpaCySymCipherAlgorithm cipherAlgorithm,
+ Cpa16U *pLaCommandFlags,
+ Cpa32U ivLenInBytes)
+{
+ /* For Chacha ciphers set command flag as partial none to proceed
+ * with stateless processing */
+ if (LAC_CIPHER_IS_CHACHA(cipherAlgorithm) ||
+ LAC_CIPHER_IS_SM4(cipherAlgorithm)) {
+ ICP_QAT_FW_LA_PARTIAL_SET(*pLaCommandFlags,
+ ICP_QAT_FW_LA_PARTIAL_NONE);
+ return;
+ }
+ ICP_QAT_FW_LA_PARTIAL_SET(*pLaCommandFlags, qatPacketType);
+
+ /* For ECB-mode ciphers, IV is NULL so update-state flag
+ * must be disabled always.
+ * For all other ciphers and auth
+ * update state is disabled for full packets and final partials */
+ if (((laCmdId != ICP_QAT_FW_LA_CMD_AUTH) &&
+ LAC_CIPHER_IS_ECB_MODE(cipherAlgorithm)) ||
+ (ICP_QAT_FW_LA_PARTIAL_NONE == qatPacketType) ||
+ (ICP_QAT_FW_LA_PARTIAL_END == qatPacketType)) {
+ ICP_QAT_FW_LA_UPDATE_STATE_SET(*pLaCommandFlags,
+ ICP_QAT_FW_LA_NO_UPDATE_STATE);
+ }
+ /* For first or middle partials set the update state command flag */
+ else {
+ ICP_QAT_FW_LA_UPDATE_STATE_SET(*pLaCommandFlags,
+ ICP_QAT_FW_LA_UPDATE_STATE);
+
+ if (laCmdId == ICP_QAT_FW_LA_CMD_AUTH) {
+ /* For hash only partial - verify and return auth result
+ * are
+ * disabled */
+ ICP_QAT_FW_LA_RET_AUTH_SET(
+ *pLaCommandFlags, ICP_QAT_FW_LA_NO_RET_AUTH_RES);
+
+ ICP_QAT_FW_LA_CMP_AUTH_SET(
+ *pLaCommandFlags, ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
+ }
+ }
+
+ if ((LAC_CIPHER_IS_GCM(cipherAlgorithm)) &&
+ (LAC_CIPHER_IV_SIZE_GCM_12 == ivLenInBytes))
+
+ {
+ ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
+ *pLaCommandFlags, ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS);
+ }
+}
+
+void
+LacSymQat_packetTypeGet(CpaCySymPacketType packetType,
+ CpaCySymPacketType packetState,
+ Cpa32U *pQatPacketType)
+{
+ /* partial */
+ if (CPA_CY_SYM_PACKET_TYPE_PARTIAL == packetType) {
+ /* if the previous state was full, then this is the first packet
+ */
+ if (CPA_CY_SYM_PACKET_TYPE_FULL == packetState) {
+ *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_START;
+ } else {
+ *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_MID;
+ }
+ }
+ /* final partial */
+ else if (CPA_CY_SYM_PACKET_TYPE_LAST_PARTIAL == packetType) {
+ *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_END;
+ }
+ /* full packet - CPA_CY_SYM_PACKET_TYPE_FULL */
+ else {
+ *pQatPacketType = ICP_QAT_FW_LA_PARTIAL_NONE;
+ }
+}
+
+void
+LacSymQat_LaSetDefaultFlags(icp_qat_fw_serv_specif_flags *laCmdFlags,
+ CpaCySymOp symOp)
+{
+
+ ICP_QAT_FW_LA_PARTIAL_SET(*laCmdFlags, ICP_QAT_FW_LA_PARTIAL_NONE);
+
+ ICP_QAT_FW_LA_UPDATE_STATE_SET(*laCmdFlags,
+ ICP_QAT_FW_LA_NO_UPDATE_STATE);
+
+ if (symOp != CPA_CY_SYM_OP_CIPHER) {
+ ICP_QAT_FW_LA_RET_AUTH_SET(*laCmdFlags,
+ ICP_QAT_FW_LA_RET_AUTH_RES);
+ } else {
+ ICP_QAT_FW_LA_RET_AUTH_SET(*laCmdFlags,
+ ICP_QAT_FW_LA_NO_RET_AUTH_RES);
+ }
+
+ ICP_QAT_FW_LA_CMP_AUTH_SET(*laCmdFlags, ICP_QAT_FW_LA_NO_CMP_AUTH_RES);
+
+ ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
+ *laCmdFlags, ICP_QAT_FW_LA_GCM_IV_LEN_NOT_12_OCTETS);
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_cipher.c b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_cipher.c
new file mode 100644
index 000000000000..b958d3723703
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_cipher.c
@@ -0,0 +1,889 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_qat_cipher.c QAT-related support functions for Cipher
+ *
+ * @ingroup LacSymQat_Cipher
+ *
+ * @description Functions to support the QAT related operations for Cipher
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "lac_sym_qat.h"
+#include "lac_sym_qat_cipher.h"
+#include "lac_mem.h"
+#include "lac_common.h"
+#include "cpa_cy_sym.h"
+#include "lac_sym_qat.h"
+#include "lac_sym_cipher_defs.h"
+#include "icp_qat_hw.h"
+#include "icp_qat_fw_la.h"
+
+/*****************************************************************************
+ * Internal data
+ *****************************************************************************/
+
+typedef enum _icp_qat_hw_key_depend {
+ IS_KEY_DEP_NO = 0,
+ IS_KEY_DEP_YES,
+} icp_qat_hw_key_depend;
+
+/* LAC_CIPHER_IS_XTS_MODE */
+static const uint8_t key_size_xts[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES128, // ICP_QAT_HW_AES_128_XTS_KEY_SZ
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES256 // ICP_QAT_HW_AES_256_XTS_KEY_SZ
+};
+/* LAC_CIPHER_IS_AES */
+static const uint8_t key_size_aes[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES128, // ICP_QAT_HW_AES_128_KEY_SZ
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES192, // ICP_QAT_HW_AES_192_KEY_SZ
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES256 // ICP_QAT_HW_AES_256_KEY_SZ
+};
+/* LAC_CIPHER_IS_AES_F8 */
+static const uint8_t key_size_f8[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES128, // ICP_QAT_HW_AES_128_F8_KEY_SZ
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES192, // ICP_QAT_HW_AES_192_F8_KEY_SZ
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_AES256 // ICP_QAT_HW_AES_256_F8_KEY_SZ
+};
+/* LAC_CIPHER_IS_SM4 */
+static const uint8_t key_size_sm4[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ ICP_QAT_HW_CIPHER_ALGO_SM4 // ICP_QAT_HW_SM4_KEY_SZ
+};
+
+typedef struct _icp_qat_hw_cipher_info {
+ icp_qat_hw_cipher_algo_t algorithm;
+ icp_qat_hw_cipher_mode_t mode;
+ icp_qat_hw_cipher_convert_t key_convert[2];
+ icp_qat_hw_cipher_dir_t dir[2];
+ icp_qat_hw_key_depend isKeyLenDepend;
+ const uint8_t *pAlgByKeySize;
+} icp_qat_hw_cipher_info;
+
+static const icp_qat_hw_cipher_info icp_qat_alg_info[] =
+ {
+ /* CPA_CY_SYM_CIPHER_NULL */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_NULL,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_ARC4 */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_ARC4,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_ECB */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_YES,
+ key_size_aes,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_CBC */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_CBC_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_YES,
+ key_size_aes,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_CTR */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt
+ * Overriding default values previously set for AES
+ */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_YES,
+ key_size_aes,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_CCM */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt
+ * Overriding default values previously set for AES
+ */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_YES,
+ key_size_aes,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_GCM */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt
+ * Overriding default values previously set for AES
+ */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_YES,
+ key_size_aes,
+ },
+ /* CPA_CY_SYM_CIPHER_DES_ECB */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_DES,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_DES_CBC */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_DES,
+ ICP_QAT_HW_CIPHER_CBC_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_3DES_ECB */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_3DES,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_3DES_CBC */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_3DES,
+ ICP_QAT_HW_CIPHER_CBC_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_3DES_CTR */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_3DES,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt
+ * Overriding default values previously set for AES
+ */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_KASUMI_F8 */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_KASUMI,
+ ICP_QAT_HW_CIPHER_F8_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_SNOW3G_UEA2 */
+ {
+ /* The KEY_CONVERT bit has to be set for Snow_3G operation */
+ ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_KEY_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_F8 */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_F8_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_YES,
+ key_size_f8,
+ },
+ /* CPA_CY_SYM_CIPHER_AES_XTS */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_AES128,
+ ICP_QAT_HW_CIPHER_XTS_MODE,
+ /* AES decrypt key needs to be reversed. Instead of reversing the key
+ * at session registration, it is instead reversed on-the-fly by
+ * setting the KEY_CONVERT bit here
+ */
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_YES,
+ key_size_xts,
+ },
+ /* CPA_CY_SYM_CIPHER_ZUC_EEA3 */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_KEY_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_CHACHA */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_CHACHA20_POLY1305,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ { ICP_QAT_HW_CIPHER_KEY_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_NO,
+ NULL,
+ },
+ /* CPA_CY_SYM_CIPHER_SM4_ECB */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_SM4,
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_YES,
+ key_size_sm4,
+ },
+ /* CPA_CY_SYM_CIPHER_SM4_CBC */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_SM4,
+ ICP_QAT_HW_CIPHER_CBC_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_KEY_CONVERT },
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_DECRYPT },
+ IS_KEY_DEP_YES,
+ key_size_sm4,
+ },
+ /* CPA_CY_SYM_CIPHER_SM4_CTR */
+ {
+ ICP_QAT_HW_CIPHER_ALGO_SM4,
+ ICP_QAT_HW_CIPHER_CTR_MODE,
+ { ICP_QAT_HW_CIPHER_NO_CONVERT, ICP_QAT_HW_CIPHER_NO_CONVERT },
+ /* Streaming ciphers are a special case. Decrypt = encrypt */
+ { ICP_QAT_HW_CIPHER_ENCRYPT, ICP_QAT_HW_CIPHER_ENCRYPT },
+ IS_KEY_DEP_YES,
+ key_size_sm4,
+ },
+ };
+
+/*****************************************************************************
+ * Internal functions
+ *****************************************************************************/
+
+void
+LacSymQat_CipherCtrlBlockWrite(icp_qat_la_bulk_req_ftr_t *pMsg,
+ Cpa32U cipherAlgorithm,
+ Cpa32U targetKeyLenInBytes,
+ icp_qat_fw_slice_t nextSlice,
+ Cpa8U cipherCfgOffsetInQuadWord)
+{
+ icp_qat_fw_cipher_cd_ctrl_hdr_t *cd_ctrl =
+ (icp_qat_fw_cipher_cd_ctrl_hdr_t *)&(pMsg->cd_ctrl);
+
+ /* state_padding_sz is nonzero for f8 mode only */
+ cd_ctrl->cipher_padding_sz = 0;
+
+ /* Base Key is not passed down to QAT in the case of ARC4 or NULL */
+ if (LAC_CIPHER_IS_ARC4(cipherAlgorithm) ||
+ LAC_CIPHER_IS_NULL(cipherAlgorithm)) {
+ cd_ctrl->cipher_key_sz = 0;
+ } else if (LAC_CIPHER_IS_KASUMI(cipherAlgorithm)) {
+ cd_ctrl->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(ICP_QAT_HW_KASUMI_F8_KEY_SZ);
+ cd_ctrl->cipher_padding_sz =
+ ICP_QAT_HW_MODE_F8_NUM_REG_TO_CLEAR;
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(cipherAlgorithm)) {
+ /* For Snow3G UEA2 content descriptor key size is
+ key size plus iv size */
+ cd_ctrl->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(ICP_QAT_HW_SNOW_3G_UEA2_KEY_SZ +
+ ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ);
+ } else if (LAC_CIPHER_IS_AES_F8(cipherAlgorithm)) {
+ cd_ctrl->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(targetKeyLenInBytes);
+ cd_ctrl->cipher_padding_sz =
+ 2 * ICP_QAT_HW_MODE_F8_NUM_REG_TO_CLEAR;
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(cipherAlgorithm)) {
+ /* For ZUC EEA3 content descriptor key size is
+ key size plus iv size */
+ cd_ctrl->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(ICP_QAT_HW_ZUC_3G_EEA3_KEY_SZ +
+ ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ);
+ } else {
+ cd_ctrl->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(targetKeyLenInBytes);
+ }
+
+ cd_ctrl->cipher_state_sz = LAC_BYTES_TO_QUADWORDS(
+ LacSymQat_CipherIvSizeBytesGet(cipherAlgorithm));
+
+ cd_ctrl->cipher_cfg_offset = cipherCfgOffsetInQuadWord;
+
+ ICP_QAT_FW_COMN_NEXT_ID_SET(cd_ctrl, nextSlice);
+ ICP_QAT_FW_COMN_CURR_ID_SET(cd_ctrl, ICP_QAT_FW_SLICE_CIPHER);
+}
+
+void
+LacSymQat_CipherGetCfgData(lac_session_desc_t *pSession,
+ icp_qat_hw_cipher_algo_t *pAlgorithm,
+ icp_qat_hw_cipher_mode_t *pMode,
+ icp_qat_hw_cipher_dir_t *pDir,
+ icp_qat_hw_cipher_convert_t *pKey_convert)
+{
+
+ CpaCySymCipherAlgorithm cipherAlgorithm = 0;
+ icp_qat_hw_cipher_dir_t cipherDirection = 0;
+
+ /* Set defaults */
+ *pKey_convert = ICP_QAT_HW_CIPHER_NO_CONVERT;
+ *pAlgorithm = ICP_QAT_HW_CIPHER_ALGO_NULL;
+ *pMode = ICP_QAT_HW_CIPHER_ECB_MODE;
+ *pDir = ICP_QAT_HW_CIPHER_ENCRYPT;
+
+ /* decrease since it's numbered from 1 instead of 0 */
+ cipherAlgorithm = pSession->cipherAlgorithm - 1;
+ cipherDirection =
+ pSession->cipherDirection == CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT ?
+ ICP_QAT_HW_CIPHER_ENCRYPT :
+ ICP_QAT_HW_CIPHER_DECRYPT;
+
+ *pAlgorithm = icp_qat_alg_info[cipherAlgorithm].algorithm;
+ *pMode = icp_qat_alg_info[cipherAlgorithm].mode;
+ *pDir = icp_qat_alg_info[cipherAlgorithm].dir[cipherDirection];
+ *pKey_convert =
+ icp_qat_alg_info[cipherAlgorithm].key_convert[cipherDirection];
+
+ if (IS_KEY_DEP_NO != icp_qat_alg_info[cipherAlgorithm].isKeyLenDepend) {
+ *pAlgorithm = icp_qat_alg_info[cipherAlgorithm]
+ .pAlgByKeySize[pSession->cipherKeyLenInBytes];
+ }
+ /* Set the mode */
+ if (LAC_CIPHER_IS_CTR_MODE(pSession->cipherAlgorithm)) {
+ *pMode = ICP_QAT_HW_CIPHER_CTR_MODE;
+ *pKey_convert = ICP_QAT_HW_CIPHER_NO_CONVERT;
+ /* CCP and AES_GCM single pass, despite being limited to
+ * CTR/AEAD mode,
+ * support both Encrypt/Decrypt modes - this is because of the
+ * differences in the hash computation/verification paths in
+ * encrypt/decrypt modes respectively.
+ * By default CCP is set as CTR Mode.Set AEAD Mode for AES_GCM.
+ */
+ if (pSession->isSinglePass) {
+ if (LAC_CIPHER_IS_GCM(pSession->cipherAlgorithm))
+ *pMode = ICP_QAT_HW_CIPHER_AEAD_MODE;
+ if (cipherDirection == ICP_QAT_HW_CIPHER_DECRYPT)
+ *pDir = ICP_QAT_HW_CIPHER_DECRYPT;
+ }
+ }
+}
+
+void
+LacSymQat_CipherHwBlockPopulateCfgData(lac_session_desc_t *pSession,
+ const void *pCipherHwBlock,
+ Cpa32U *pSizeInBytes)
+{
+ icp_qat_hw_cipher_algo_t algorithm = ICP_QAT_HW_CIPHER_ALGO_NULL;
+ icp_qat_hw_cipher_mode_t mode = ICP_QAT_HW_CIPHER_ECB_MODE;
+ icp_qat_hw_cipher_dir_t dir = ICP_QAT_HW_CIPHER_ENCRYPT;
+ icp_qat_hw_cipher_convert_t key_convert;
+ icp_qat_hw_cipher_config_t *pCipherConfig =
+ (icp_qat_hw_cipher_config_t *)pCipherHwBlock;
+ Cpa32U aed_hash_cmp_length = 0;
+
+ *pSizeInBytes = 0;
+
+ LacSymQat_CipherGetCfgData(
+ pSession, &algorithm, &mode, &dir, &key_convert);
+
+ /* Build the cipher config into the hardware setup block */
+ if (pSession->isSinglePass) {
+ aed_hash_cmp_length = pSession->hashResultSize;
+ pCipherConfig->reserved = ICP_QAT_HW_CIPHER_CONFIG_BUILD_UPPER(
+ pSession->aadLenInBytes);
+ } else {
+ pCipherConfig->reserved = 0;
+ }
+
+ pCipherConfig->val = ICP_QAT_HW_CIPHER_CONFIG_BUILD(
+ mode, algorithm, key_convert, dir, aed_hash_cmp_length);
+
+ *pSizeInBytes = sizeof(icp_qat_hw_cipher_config_t);
+}
+
+void
+LacSymQat_CipherHwBlockPopulateKeySetup(
+ const CpaCySymCipherSetupData *pCipherSetupData,
+ Cpa32U targetKeyLenInBytes,
+ const void *pCipherHwBlock,
+ Cpa32U *pSizeInBytes)
+{
+ Cpa8U *pCipherKey = (Cpa8U *)pCipherHwBlock;
+ Cpa32U actualKeyLenInBytes = pCipherSetupData->cipherKeyLenInBytes;
+
+ *pSizeInBytes = 0;
+
+ /* Key is copied into content descriptor for all cases except for
+ * Arc4 and Null cipher */
+ if (!(LAC_CIPHER_IS_ARC4(pCipherSetupData->cipherAlgorithm) ||
+ LAC_CIPHER_IS_NULL(pCipherSetupData->cipherAlgorithm))) {
+ /* Set the Cipher key field in the cipher block */
+ memcpy(pCipherKey,
+ pCipherSetupData->pCipherKey,
+ actualKeyLenInBytes);
+ /* Pad the key with 0's if required */
+ if (0 < (targetKeyLenInBytes - actualKeyLenInBytes)) {
+ LAC_OS_BZERO(pCipherKey + actualKeyLenInBytes,
+ targetKeyLenInBytes - actualKeyLenInBytes);
+ }
+ *pSizeInBytes += targetKeyLenInBytes;
+
+ /* For Kasumi in F8 mode Cipher Key is concatenated with
+ * Cipher Key XOR-ed with Key Modifier (CK||CK^KM) */
+ if (LAC_CIPHER_IS_KASUMI(pCipherSetupData->cipherAlgorithm)) {
+ Cpa32U wordIndex = 0;
+ Cpa32U *pu32CipherKey =
+ (Cpa32U *)pCipherSetupData->pCipherKey;
+ Cpa32U *pTempKey =
+ (Cpa32U *)(pCipherKey + targetKeyLenInBytes);
+
+ /* XOR Key with KASUMI F8 key modifier at 4 bytes level
+ */
+ for (wordIndex = 0; wordIndex <
+ LAC_BYTES_TO_LONGWORDS(targetKeyLenInBytes);
+ wordIndex++) {
+ pTempKey[wordIndex] = pu32CipherKey[wordIndex] ^
+ LAC_CIPHER_KASUMI_F8_KEY_MODIFIER_4_BYTES;
+ }
+
+ *pSizeInBytes += targetKeyLenInBytes;
+
+ /* also add padding for F8 */
+ *pSizeInBytes += LAC_QUADWORDS_TO_BYTES(
+ ICP_QAT_HW_MODE_F8_NUM_REG_TO_CLEAR);
+ LAC_OS_BZERO((Cpa8U *)pTempKey + targetKeyLenInBytes,
+ LAC_QUADWORDS_TO_BYTES(
+ ICP_QAT_HW_MODE_F8_NUM_REG_TO_CLEAR));
+ }
+ /* For AES in F8 mode Cipher Key is concatenated with
+ * Cipher Key XOR-ed with Key Mask (CK||CK^KM) */
+ else if (LAC_CIPHER_IS_AES_F8(
+ pCipherSetupData->cipherAlgorithm)) {
+ Cpa32U index = 0;
+ Cpa8U *pTempKey =
+ pCipherKey + (targetKeyLenInBytes / 2);
+ *pSizeInBytes += targetKeyLenInBytes;
+ /* XOR Key with key Mask */
+ for (index = 0; index < targetKeyLenInBytes; index++) {
+ pTempKey[index] =
+ pCipherKey[index] ^ pTempKey[index];
+ }
+ pTempKey = (pCipherKey + targetKeyLenInBytes);
+ /* also add padding for AES F8 */
+ *pSizeInBytes += 2 * targetKeyLenInBytes;
+ LAC_OS_BZERO(pTempKey, 2 * targetKeyLenInBytes);
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(
+ pCipherSetupData->cipherAlgorithm)) {
+ /* For Snow3G zero area after the key for FW */
+ LAC_OS_BZERO(pCipherKey + targetKeyLenInBytes,
+ ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ);
+
+ *pSizeInBytes += ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ;
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(
+ pCipherSetupData->cipherAlgorithm)) {
+ /* For ZUC zero area after the key for FW */
+ LAC_OS_BZERO(pCipherKey + targetKeyLenInBytes,
+ ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ);
+
+ *pSizeInBytes += ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ;
+ }
+ }
+}
+
+/*****************************************************************************
+ * External functions
+ *****************************************************************************/
+
+Cpa8U
+LacSymQat_CipherBlockSizeBytesGet(CpaCySymCipherAlgorithm cipherAlgorithm)
+{
+ if (LAC_CIPHER_IS_ARC4(cipherAlgorithm)) {
+ return LAC_CIPHER_ARC4_BLOCK_LEN_BYTES;
+ } else if (LAC_CIPHER_IS_AES(cipherAlgorithm) ||
+ LAC_CIPHER_IS_AES_F8(cipherAlgorithm)) {
+ return ICP_QAT_HW_AES_BLK_SZ;
+ } else if (LAC_CIPHER_IS_DES(cipherAlgorithm)) {
+ return ICP_QAT_HW_DES_BLK_SZ;
+ } else if (LAC_CIPHER_IS_TRIPLE_DES(cipherAlgorithm)) {
+ return ICP_QAT_HW_3DES_BLK_SZ;
+ } else if (LAC_CIPHER_IS_KASUMI(cipherAlgorithm)) {
+ return ICP_QAT_HW_KASUMI_BLK_SZ;
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(cipherAlgorithm)) {
+ return ICP_QAT_HW_SNOW_3G_BLK_SZ;
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(cipherAlgorithm)) {
+ return ICP_QAT_HW_ZUC_3G_BLK_SZ;
+ } else if (LAC_CIPHER_IS_NULL(cipherAlgorithm)) {
+ return LAC_CIPHER_NULL_BLOCK_LEN_BYTES;
+ } else if (LAC_CIPHER_IS_CHACHA(cipherAlgorithm)) {
+ return ICP_QAT_HW_CHACHAPOLY_BLK_SZ;
+ } else if (LAC_CIPHER_IS_SM4(cipherAlgorithm)) {
+ return ICP_QAT_HW_SM4_BLK_SZ;
+ } else {
+ QAT_UTILS_LOG("Algorithm not supported in Cipher\n");
+ return 0;
+ }
+}
+
+Cpa32U
+LacSymQat_CipherIvSizeBytesGet(CpaCySymCipherAlgorithm cipherAlgorithm)
+{
+ if (CPA_CY_SYM_CIPHER_ARC4 == cipherAlgorithm) {
+ return LAC_CIPHER_ARC4_STATE_LEN_BYTES;
+ } else if (LAC_CIPHER_IS_KASUMI(cipherAlgorithm)) {
+ return ICP_QAT_HW_KASUMI_BLK_SZ;
+ } else if (LAC_CIPHER_IS_SNOW3G_UEA2(cipherAlgorithm)) {
+ return ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ;
+ } else if (LAC_CIPHER_IS_ZUC_EEA3(cipherAlgorithm)) {
+ return ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ;
+ } else if (LAC_CIPHER_IS_CHACHA(cipherAlgorithm)) {
+ return ICP_QAT_HW_CHACHAPOLY_IV_SZ;
+ } else if (LAC_CIPHER_IS_ECB_MODE(cipherAlgorithm)) {
+ return 0;
+ } else {
+ return (Cpa32U)LacSymQat_CipherBlockSizeBytesGet(
+ cipherAlgorithm);
+ }
+}
+
+inline CpaStatus
+LacSymQat_CipherRequestParamsPopulate(icp_qat_fw_la_bulk_req_t *pReq,
+ Cpa32U cipherOffsetInBytes,
+ Cpa32U cipherLenInBytes,
+ Cpa64U ivBufferPhysAddr,
+ Cpa8U *pIvBufferVirt)
+{
+ icp_qat_fw_la_cipher_req_params_t *pCipherReqParams;
+ icp_qat_fw_cipher_cd_ctrl_hdr_t *pCipherCdCtrlHdr;
+ icp_qat_fw_serv_specif_flags *pCipherSpecificFlags;
+
+ pCipherReqParams = (icp_qat_fw_la_cipher_req_params_t
+ *)((Cpa8U *)&(pReq->serv_specif_rqpars) +
+ ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
+ pCipherCdCtrlHdr = (icp_qat_fw_cipher_cd_ctrl_hdr_t *)&(pReq->cd_ctrl);
+ pCipherSpecificFlags = &(pReq->comn_hdr.serv_specif_flags);
+
+ pCipherReqParams->cipher_offset = cipherOffsetInBytes;
+ pCipherReqParams->cipher_length = cipherLenInBytes;
+
+ /* Don't copy the buffer into the Msg if
+ * it's too big for the cipher_IV_array
+ * OR if the FW needs to update it
+ * OR if there's no buffer supplied
+ * OR if last partial
+ */
+ if ((pCipherCdCtrlHdr->cipher_state_sz >
+ LAC_SYM_QAT_HASH_IV_REQ_MAX_SIZE_QW) ||
+ (ICP_QAT_FW_LA_UPDATE_STATE_GET(*pCipherSpecificFlags) ==
+ ICP_QAT_FW_LA_UPDATE_STATE) ||
+ (pIvBufferVirt == NULL) ||
+ (ICP_QAT_FW_LA_PARTIAL_GET(*pCipherSpecificFlags) ==
+ ICP_QAT_FW_LA_PARTIAL_END)) {
+ /* Populate the field with a ptr to the flat buffer */
+ pCipherReqParams->u.s.cipher_IV_ptr = ivBufferPhysAddr;
+ pCipherReqParams->u.s.resrvd1 = 0;
+ /* Set the flag indicating the field format */
+ ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(
+ *pCipherSpecificFlags, ICP_QAT_FW_CIPH_IV_64BIT_PTR);
+ } else {
+ /* Populate the field with the contents of the buffer,
+ * zero field first as data may be smaller than the field */
+ memset(pCipherReqParams->u.cipher_IV_array,
+ 0,
+ LAC_LONGWORDS_TO_BYTES(ICP_QAT_FW_NUM_LONGWORDS_4));
+
+ /* We force a specific compiler optimisation here. The length
+ * to
+ * be copied turns out to be always 16, and by coding a memcpy
+ * with
+ * a literal value the compiler will compile inline code (in
+ * fact,
+ * only two vector instructions) to effect the copy. This gives
+ * us
+ * a huge performance increase.
+ */
+ unsigned long cplen =
+ LAC_QUADWORDS_TO_BYTES(pCipherCdCtrlHdr->cipher_state_sz);
+
+ if (cplen == 16)
+ memcpy(pCipherReqParams->u.cipher_IV_array,
+ pIvBufferVirt,
+ 16);
+ else
+ memcpy(pCipherReqParams->u.cipher_IV_array,
+ pIvBufferVirt,
+ cplen);
+ /* Set the flag indicating the field format */
+ ICP_QAT_FW_LA_CIPH_IV_FLD_FLAG_SET(
+ *pCipherSpecificFlags, ICP_QAT_FW_CIPH_IV_16BYTE_DATA);
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+void
+LacSymQat_CipherArc4StateInit(const Cpa8U *pKey,
+ Cpa32U keyLenInBytes,
+ Cpa8U *pArc4CipherState)
+{
+ Cpa32U i = 0;
+ Cpa32U j = 0;
+ Cpa32U k = 0;
+
+ for (i = 0; i < LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES; ++i) {
+ pArc4CipherState[i] = (Cpa8U)i;
+ }
+
+ for (i = 0; i < LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES; ++i) {
+ Cpa8U swap = 0;
+
+ if (k >= keyLenInBytes)
+ k -= keyLenInBytes;
+
+ j = (j + pArc4CipherState[i] + pKey[k]);
+ if (j >= LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES)
+ j %= LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES;
+ ++k;
+
+ /* Swap state[i] & state[j] */
+ swap = pArc4CipherState[i];
+ pArc4CipherState[i] = pArc4CipherState[j];
+ pArc4CipherState[j] = swap;
+ }
+
+ /* Initialise i & j values for QAT */
+ pArc4CipherState[LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES] = 0;
+ pArc4CipherState[LAC_CIPHER_ARC4_KEY_MATRIX_LEN_BYTES + 1] = 0;
+}
+
+/* Update the cipher_key_sz in the Request cache prepared and stored
+ * in the session */
+void
+LacSymQat_CipherXTSModeUpdateKeyLen(lac_session_desc_t *pSessionDesc,
+ Cpa32U newKeySizeInBytes)
+{
+ icp_qat_fw_cipher_cd_ctrl_hdr_t *pCipherControlBlock = NULL;
+
+ pCipherControlBlock = (icp_qat_fw_cipher_cd_ctrl_hdr_t *)&(
+ pSessionDesc->reqCacheFtr.cd_ctrl);
+
+ pCipherControlBlock->cipher_key_sz =
+ LAC_BYTES_TO_QUADWORDS(newKeySizeInBytes);
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash.c b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash.c
new file mode 100644
index 000000000000..a39734ad16d0
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash.c
@@ -0,0 +1,942 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_qat_hash.c
+ *
+ * @ingroup LacSymQatHash
+ *
+ * Implementation for populating QAT data structures for hash operation
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "cpa_cy_sym.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "lac_log.h"
+#include "lac_mem.h"
+#include "lac_sym.h"
+#include "lac_common.h"
+#include "lac_sym_qat.h"
+#include "lac_list.h"
+#include "lac_sal_types.h"
+#include "lac_sym_qat_hash.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+
+/**
+ * This structure contains pointers into the hash setup block of the
+ * security descriptor. As the hash setup block contains fields that
+ * are of variable length, pointers must be calculated to these fields
+ * and the hash setup block is populated using these pointers. */
+typedef struct lac_hash_blk_ptrs_s {
+ icp_qat_hw_auth_setup_t *pInHashSetup;
+ /**< inner hash setup */
+ Cpa8U *pInHashInitState1;
+ /**< inner initial state 1 */
+ Cpa8U *pInHashInitState2;
+ /**< inner initial state 2 */
+ icp_qat_hw_auth_setup_t *pOutHashSetup;
+ /**< outer hash setup */
+ Cpa8U *pOutHashInitState1;
+ /**< outer hash initial state */
+} lac_hash_blk_ptrs_t;
+
+typedef struct lac_hash_blk_ptrs_optimised_s {
+ Cpa8U *pInHashInitState1;
+ /**< inner initial state 1 */
+ Cpa8U *pInHashInitState2;
+ /**< inner initial state 2 */
+
+} lac_hash_blk_ptrs_optimised_t;
+
+/**
+ * This function calculates the pointers into the hash setup block
+ * based on the control block
+ *
+ * @param[in] pHashControlBlock Pointer to hash control block
+ * @param[in] pHwBlockBase pointer to base of hardware block
+ * @param[out] pHashBlkPtrs structure containing pointers to
+ * various fields in the hash setup block
+ *
+ * @return void
+ */
+static void
+LacSymQat_HashHwBlockPtrsInit(icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock,
+ void *pHwBlockBase,
+ lac_hash_blk_ptrs_t *pHashBlkPtrs);
+
+static void
+LacSymQat_HashSetupBlockOptimisedFormatInit(
+ const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock,
+ void *pHwBlockBase,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ lac_sym_qat_hash_defs_t *pHashDefs,
+ lac_sym_qat_hash_defs_t *pOuterHashDefs);
+
+/**
+ * This function populates the hash setup block
+ *
+ * @param[in] pHashSetupData Pointer to the hash context
+ * @param[in] pHashControlBlock Pointer to hash control block
+ * @param[in] pHwBlockBase pointer to base of hardware block
+ * @param[in] qatHashMode QAT hash mode
+ * @param[in] pPrecompute For auth mode, this is the pointer
+ * to the precompute data. Otherwise this
+ * should be set to NULL
+ * @param[in] pHashDefs Pointer to Hash definitions
+ * @param[in] pOuterHashDefs Pointer to Outer Hash definitions.
+ * Required for nested hash mode only
+ *
+ * @return void
+ */
+static void
+LacSymQat_HashSetupBlockInit(const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock,
+ void *pHwBlockBase,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ lac_sym_qat_hash_defs_t *pHashDefs,
+ lac_sym_qat_hash_defs_t *pOuterHashDefs);
+
+/** @ingroup LacSymQatHash */
+void
+LacSymQat_HashGetCfgData(CpaInstanceHandle pInstance,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaCySymHashMode apiHashMode,
+ CpaCySymHashAlgorithm apiHashAlgorithm,
+ icp_qat_hw_auth_algo_t *pQatAlgorithm,
+ CpaBoolean *pQatNested)
+{
+ lac_sym_qat_hash_defs_t *pHashDefs = NULL;
+
+ LacSymQat_HashDefsLookupGet(pInstance, apiHashAlgorithm, &pHashDefs);
+ *pQatAlgorithm = pHashDefs->qatInfo->algoEnc;
+
+ if (IS_HASH_MODE_2(qatHashMode)) {
+ /* set bit for nested hashing */
+ *pQatNested = ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED;
+ }
+ /* Nested hash in mode 0. */
+ else if (CPA_CY_SYM_HASH_MODE_NESTED == apiHashMode) {
+ /* set bit for nested hashing */
+ *pQatNested = ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED;
+ }
+ /* mode0 - plain or mode1 - auth */
+ else {
+ *pQatNested = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;
+ }
+}
+
+/** @ingroup LacSymQatHash */
+void
+LacSymQat_HashContentDescInit(icp_qat_la_bulk_req_ftr_t *pMsg,
+ CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData,
+ void *pHwBlockBase,
+ Cpa32U hwBlockOffsetInQuadWords,
+ icp_qat_fw_slice_t nextSlice,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaBoolean useSymConstantsTable,
+ CpaBoolean useOptimisedContentDesc,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ Cpa32U *pHashBlkSizeInBytes)
+{
+
+ icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl =
+ (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(pMsg->cd_ctrl);
+ lac_sym_qat_hash_defs_t *pHashDefs = NULL;
+ lac_sym_qat_hash_defs_t *pOuterHashDefs = NULL;
+ Cpa32U hashSetupBlkSize = 0;
+
+ /* setup the offset in QuadWords into the hw blk */
+ cd_ctrl->hash_cfg_offset = hwBlockOffsetInQuadWords;
+
+ ICP_QAT_FW_COMN_NEXT_ID_SET(cd_ctrl, nextSlice);
+ ICP_QAT_FW_COMN_CURR_ID_SET(cd_ctrl, ICP_QAT_FW_SLICE_AUTH);
+
+ LacSymQat_HashDefsLookupGet(instanceHandle,
+ pHashSetupData->hashAlgorithm,
+ &pHashDefs);
+
+ /* Hmac in mode 2 TLS */
+ if (IS_HASH_MODE_2(qatHashMode)) {
+ /* Set bit for nested hashing.
+ * Make sure not to overwrite other flags in hash_flags byte.
+ */
+ ICP_QAT_FW_HASH_FLAG_AUTH_HDR_NESTED_SET(
+ cd_ctrl->hash_flags, ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED);
+ }
+ /* Nested hash in mode 0 */
+ else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
+ /* Set bit for nested hashing.
+ * Make sure not to overwrite other flags in hash_flags byte.
+ */
+ ICP_QAT_FW_HASH_FLAG_AUTH_HDR_NESTED_SET(
+ cd_ctrl->hash_flags, ICP_QAT_FW_AUTH_HDR_FLAG_DO_NESTED);
+ }
+ /* mode0 - plain or mode1 - auth */
+ else {
+ ICP_QAT_FW_HASH_FLAG_AUTH_HDR_NESTED_SET(
+ cd_ctrl->hash_flags, ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED);
+ }
+
+ /* set the final digest size */
+ cd_ctrl->final_sz = pHashSetupData->digestResultLenInBytes;
+
+ /* set the state1 size */
+ cd_ctrl->inner_state1_sz =
+ LAC_ALIGN_POW2_ROUNDUP(pHashDefs->qatInfo->state1Length,
+ LAC_QUAD_WORD_IN_BYTES);
+
+ /* set the inner result size to the digest length */
+ cd_ctrl->inner_res_sz = pHashDefs->algInfo->digestLength;
+
+ /* set the state2 size - only for mode 1 Auth algos and AES CBC MAC */
+ if (IS_HASH_MODE_1(qatHashMode) ||
+ pHashSetupData->hashAlgorithm == CPA_CY_SYM_HASH_AES_CBC_MAC ||
+ pHashSetupData->hashAlgorithm == CPA_CY_SYM_HASH_ZUC_EIA3) {
+ cd_ctrl->inner_state2_sz =
+ LAC_ALIGN_POW2_ROUNDUP(pHashDefs->qatInfo->state2Length,
+ LAC_QUAD_WORD_IN_BYTES);
+ } else {
+ cd_ctrl->inner_state2_sz = 0;
+ }
+
+ cd_ctrl->inner_state2_offset = cd_ctrl->hash_cfg_offset +
+ LAC_BYTES_TO_QUADWORDS(sizeof(icp_qat_hw_auth_setup_t) +
+ cd_ctrl->inner_state1_sz);
+
+ /* size of inner part of hash setup block */
+ hashSetupBlkSize = sizeof(icp_qat_hw_auth_setup_t) +
+ cd_ctrl->inner_state1_sz + cd_ctrl->inner_state2_sz;
+
+ /* For nested hashing - Fill in the outer fields */
+ if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode ||
+ IS_HASH_MODE_2(qatHashMode)) {
+ /* For nested - use the outer algorithm. This covers TLS and
+ * nested hash. For HMAC mode2 use inner algorithm again */
+ CpaCySymHashAlgorithm outerAlg =
+ (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) ?
+ pHashSetupData->nestedModeSetupData.outerHashAlgorithm :
+ pHashSetupData->hashAlgorithm;
+
+ LacSymQat_HashDefsLookupGet(instanceHandle,
+ outerAlg,
+ &pOuterHashDefs);
+
+ /* outer config offset */
+ cd_ctrl->outer_config_offset = cd_ctrl->inner_state2_offset +
+ LAC_BYTES_TO_QUADWORDS(cd_ctrl->inner_state2_sz);
+
+ cd_ctrl->outer_state1_sz =
+ LAC_ALIGN_POW2_ROUNDUP(pOuterHashDefs->algInfo->stateSize,
+ LAC_QUAD_WORD_IN_BYTES);
+
+ /* outer result size */
+ cd_ctrl->outer_res_sz = pOuterHashDefs->algInfo->digestLength;
+
+ /* outer_prefix_offset will be the size of the inner prefix data
+ * plus the hash state storage size. */
+ /* The prefix buffer is part of the ReqParams, so this param
+ * will be
+ * setup where ReqParams are set up */
+
+ /* add on size of outer part of hash block */
+ hashSetupBlkSize +=
+ sizeof(icp_qat_hw_auth_setup_t) + cd_ctrl->outer_state1_sz;
+ } else {
+ cd_ctrl->outer_config_offset = 0;
+ cd_ctrl->outer_state1_sz = 0;
+ cd_ctrl->outer_res_sz = 0;
+ }
+
+ if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == pHashSetupData->hashAlgorithm) {
+ /* add the size for the cipher config word, the key and the IV*/
+ hashSetupBlkSize += sizeof(icp_qat_hw_cipher_config_t) +
+ pHashSetupData->authModeSetupData.authKeyLenInBytes +
+ ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ;
+ }
+
+ *pHashBlkSizeInBytes = hashSetupBlkSize;
+
+ if (useOptimisedContentDesc) {
+ LacSymQat_HashSetupBlockOptimisedFormatInit(pHashSetupData,
+ cd_ctrl,
+ pHwBlockBase,
+ qatHashMode,
+ pPrecompute,
+ pHashDefs,
+ pOuterHashDefs);
+ } else if (!useSymConstantsTable) {
+ /*****************************************************************************
+ * Populate Hash Setup block *
+ *****************************************************************************/
+ LacSymQat_HashSetupBlockInit(pHashSetupData,
+ cd_ctrl,
+ pHwBlockBase,
+ qatHashMode,
+ pPrecompute,
+ pHashDefs,
+ pOuterHashDefs);
+ }
+}
+
+/* This fn populates fields in both the CD ctrl block and the ReqParams block
+ * which describe the Hash ReqParams:
+ * cd_ctrl.outer_prefix_offset
+ * cd_ctrl.outer_prefix_sz
+ * req_params.inner_prefix_sz/aad_sz
+ * req_params.hash_state_sz
+ * req_params.auth_res_sz
+ *
+ */
+void
+LacSymQat_HashSetupReqParamsMetaData(
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ CpaInstanceHandle instanceHandle,
+ const CpaCySymHashSetupData *pHashSetupData,
+ CpaBoolean hashStateBuffer,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ CpaBoolean digestVerify)
+{
+ icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl = NULL;
+ icp_qat_la_auth_req_params_t *pHashReqParams = NULL;
+ lac_sym_qat_hash_defs_t *pHashDefs = NULL;
+
+ cd_ctrl = (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(pMsg->cd_ctrl);
+ pHashReqParams =
+ (icp_qat_la_auth_req_params_t *)(&(pMsg->serv_specif_rqpars));
+
+ LacSymQat_HashDefsLookupGet(instanceHandle,
+ pHashSetupData->hashAlgorithm,
+ &pHashDefs);
+
+ /* Hmac in mode 2 TLS */
+ if (IS_HASH_MODE_2(qatHashMode)) {
+ /* Inner and outer prefixes are the block length */
+ pHashReqParams->u2.inner_prefix_sz =
+ pHashDefs->algInfo->blockLength;
+ cd_ctrl->outer_prefix_sz = pHashDefs->algInfo->blockLength;
+ cd_ctrl->outer_prefix_offset = LAC_BYTES_TO_QUADWORDS(
+ LAC_ALIGN_POW2_ROUNDUP((pHashReqParams->u2.inner_prefix_sz),
+ LAC_QUAD_WORD_IN_BYTES));
+ }
+ /* Nested hash in mode 0 */
+ else if (CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode) {
+
+ /* set inner and outer prefixes */
+ pHashReqParams->u2.inner_prefix_sz =
+ pHashSetupData->nestedModeSetupData.innerPrefixLenInBytes;
+ cd_ctrl->outer_prefix_sz =
+ pHashSetupData->nestedModeSetupData.outerPrefixLenInBytes;
+ cd_ctrl->outer_prefix_offset = LAC_BYTES_TO_QUADWORDS(
+ LAC_ALIGN_POW2_ROUNDUP((pHashReqParams->u2.inner_prefix_sz),
+ LAC_QUAD_WORD_IN_BYTES));
+ }
+ /* mode0 - plain or mode1 - auth */
+ else {
+ Cpa16U aadDataSize = 0;
+
+ /* For Auth Encrypt set the aad size */
+ if (CPA_CY_SYM_HASH_AES_CCM == pHashSetupData->hashAlgorithm) {
+ /* at the beginning of the buffer there is B0 block */
+ aadDataSize = LAC_HASH_AES_CCM_BLOCK_SIZE;
+
+ /* then, if there is some 'a' data, the buffer will
+ * store encoded
+ * length of 'a' and 'a' itself */
+ if (pHashSetupData->authModeSetupData.aadLenInBytes >
+ 0) {
+ /* as the QAT API puts the requirement on the
+ * pAdditionalAuthData not to be bigger than 240
+ * bytes then we
+ * just need 2 bytes to store encoded length of
+ * 'a' */
+ aadDataSize += sizeof(Cpa16U);
+ aadDataSize += pHashSetupData->authModeSetupData
+ .aadLenInBytes;
+ }
+
+ /* round the aad size to the multiple of CCM block
+ * size.*/
+ pHashReqParams->u2.aad_sz =
+ LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
+ LAC_HASH_AES_CCM_BLOCK_SIZE);
+ } else if (CPA_CY_SYM_HASH_AES_GCM ==
+ pHashSetupData->hashAlgorithm) {
+ aadDataSize =
+ pHashSetupData->authModeSetupData.aadLenInBytes;
+
+ /* round the aad size to the multiple of GCM hash block
+ * size. */
+ pHashReqParams->u2.aad_sz =
+ LAC_ALIGN_POW2_ROUNDUP(aadDataSize,
+ LAC_HASH_AES_GCM_BLOCK_SIZE);
+ } else {
+ pHashReqParams->u2.aad_sz = 0;
+ }
+
+ cd_ctrl->outer_prefix_sz = 0;
+ cd_ctrl->outer_prefix_offset = 0;
+ }
+
+ /* If there is a hash state prefix buffer */
+ if (CPA_TRUE == hashStateBuffer) {
+ /* Note, this sets up size for both aad and non-aad cases */
+ pHashReqParams->hash_state_sz = LAC_BYTES_TO_QUADWORDS(
+ LAC_ALIGN_POW2_ROUNDUP(pHashReqParams->u2.inner_prefix_sz,
+ LAC_QUAD_WORD_IN_BYTES) +
+ LAC_ALIGN_POW2_ROUNDUP(cd_ctrl->outer_prefix_sz,
+ LAC_QUAD_WORD_IN_BYTES));
+ } else {
+ pHashReqParams->hash_state_sz = 0;
+ }
+
+ if (CPA_TRUE == digestVerify) {
+ /* auth result size in bytes to be read in for a verify
+ * operation */
+ pHashReqParams->auth_res_sz =
+ pHashSetupData->digestResultLenInBytes;
+ } else {
+ pHashReqParams->auth_res_sz = 0;
+ }
+
+ pHashReqParams->resrvd1 = 0;
+}
+
+void
+LacSymQat_HashHwBlockPtrsInit(icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl,
+ void *pHwBlockBase,
+ lac_hash_blk_ptrs_t *pHashBlkPtrs)
+{
+ /* encoded offset for inner config is converted to a byte offset. */
+ pHashBlkPtrs->pInHashSetup =
+ (icp_qat_hw_auth_setup_t *)((Cpa8U *)pHwBlockBase +
+ (cd_ctrl->hash_cfg_offset *
+ LAC_QUAD_WORD_IN_BYTES));
+
+ pHashBlkPtrs->pInHashInitState1 = (Cpa8U *)pHashBlkPtrs->pInHashSetup +
+ sizeof(icp_qat_hw_auth_setup_t);
+
+ pHashBlkPtrs->pInHashInitState2 =
+ (Cpa8U *)(pHashBlkPtrs->pInHashInitState1) +
+ cd_ctrl->inner_state1_sz;
+
+ pHashBlkPtrs->pOutHashSetup =
+ (icp_qat_hw_auth_setup_t *)((Cpa8U *)(pHashBlkPtrs
+ ->pInHashInitState2) +
+ cd_ctrl->inner_state2_sz);
+
+ pHashBlkPtrs->pOutHashInitState1 =
+ (Cpa8U *)(pHashBlkPtrs->pOutHashSetup) +
+ sizeof(icp_qat_hw_auth_setup_t);
+}
+
+static void
+LacSymQat_HashSetupBlockInit(const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock,
+ void *pHwBlockBase,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ lac_sym_qat_hash_defs_t *pHashDefs,
+ lac_sym_qat_hash_defs_t *pOuterHashDefs)
+{
+ Cpa32U innerConfig = 0;
+ lac_hash_blk_ptrs_t hashBlkPtrs = { 0 };
+ Cpa32U aed_hash_cmp_length = 0;
+
+ LacSymQat_HashHwBlockPtrsInit(pHashControlBlock,
+ pHwBlockBase,
+ &hashBlkPtrs);
+
+ innerConfig = ICP_QAT_HW_AUTH_CONFIG_BUILD(
+ qatHashMode,
+ pHashDefs->qatInfo->algoEnc,
+ pHashSetupData->digestResultLenInBytes);
+
+ /* Set the Inner hash configuration */
+ hashBlkPtrs.pInHashSetup->auth_config.config = innerConfig;
+ hashBlkPtrs.pInHashSetup->auth_config.reserved = 0;
+
+ /* For mode 1 pre-computes for auth algorithms */
+ if (IS_HASH_MODE_1(qatHashMode) ||
+ CPA_CY_SYM_HASH_AES_CBC_MAC == pHashSetupData->hashAlgorithm ||
+ CPA_CY_SYM_HASH_ZUC_EIA3 == pHashSetupData->hashAlgorithm) {
+ /* for HMAC in mode 1 authCounter is the block size
+ * else the authCounter is 0. The firmware expects the counter
+ * to be
+ * big endian */
+ LAC_MEM_SHARED_WRITE_SWAP(
+ hashBlkPtrs.pInHashSetup->auth_counter.counter,
+ pHashDefs->qatInfo->authCounter);
+
+ /* state 1 is set to 0 for the following algorithms */
+ if ((CPA_CY_SYM_HASH_AES_XCBC ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_CMAC ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_CBC_MAC ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_KASUMI_F9 ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_CCM ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GMAC ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_AES_GCM ==
+ pHashSetupData->hashAlgorithm) ||
+ (CPA_CY_SYM_HASH_ZUC_EIA3 ==
+ pHashSetupData->hashAlgorithm)) {
+ LAC_OS_BZERO(hashBlkPtrs.pInHashInitState1,
+ pHashDefs->qatInfo->state1Length);
+ }
+
+ /* Pad remaining bytes of sha1 precomputes */
+ if (CPA_CY_SYM_HASH_SHA1 == pHashSetupData->hashAlgorithm) {
+ Cpa32U state1PadLen = 0;
+ Cpa32U state2PadLen = 0;
+
+ if (pHashControlBlock->inner_state1_sz >
+ pHashDefs->algInfo->stateSize) {
+ state1PadLen =
+ pHashControlBlock->inner_state1_sz -
+ pHashDefs->algInfo->stateSize;
+ }
+
+ if (pHashControlBlock->inner_state2_sz >
+ pHashDefs->algInfo->stateSize) {
+ state2PadLen =
+ pHashControlBlock->inner_state2_sz -
+ pHashDefs->algInfo->stateSize;
+ }
+
+ if (state1PadLen > 0) {
+
+ LAC_OS_BZERO(hashBlkPtrs.pInHashInitState1 +
+ pHashDefs->algInfo->stateSize,
+ state1PadLen);
+ }
+
+ if (state2PadLen > 0) {
+ LAC_OS_BZERO(hashBlkPtrs.pInHashInitState2 +
+ pHashDefs->algInfo->stateSize,
+ state2PadLen);
+ }
+ }
+
+ pPrecompute->state1Size = pHashDefs->qatInfo->state1Length;
+ pPrecompute->state2Size = pHashDefs->qatInfo->state2Length;
+
+ /* Set the destination for pre-compute state1 data to be written
+ */
+ pPrecompute->pState1 = hashBlkPtrs.pInHashInitState1;
+
+ /* Set the destination for pre-compute state1 data to be written
+ */
+ pPrecompute->pState2 = hashBlkPtrs.pInHashInitState2;
+ }
+ /* For digest and nested digest */
+ else {
+ Cpa32U padLen = pHashControlBlock->inner_state1_sz -
+ pHashDefs->algInfo->stateSize;
+
+ /* counter set to 0 */
+ hashBlkPtrs.pInHashSetup->auth_counter.counter = 0;
+
+ /* set the inner hash state 1 */
+ memcpy(hashBlkPtrs.pInHashInitState1,
+ pHashDefs->algInfo->initState,
+ pHashDefs->algInfo->stateSize);
+
+ if (padLen > 0) {
+ LAC_OS_BZERO(hashBlkPtrs.pInHashInitState1 +
+ pHashDefs->algInfo->stateSize,
+ padLen);
+ }
+ }
+
+ hashBlkPtrs.pInHashSetup->auth_counter.reserved = 0;
+
+ /* Fill in the outer part of the hash setup block */
+ if ((CPA_CY_SYM_HASH_MODE_NESTED == pHashSetupData->hashMode ||
+ IS_HASH_MODE_2(qatHashMode)) &&
+ (NULL != pOuterHashDefs)) {
+ Cpa32U outerConfig = ICP_QAT_HW_AUTH_CONFIG_BUILD(
+ qatHashMode,
+ pOuterHashDefs->qatInfo->algoEnc,
+ pHashSetupData->digestResultLenInBytes);
+
+ Cpa32U padLen = pHashControlBlock->outer_state1_sz -
+ pOuterHashDefs->algInfo->stateSize;
+
+ /* populate the auth config */
+ hashBlkPtrs.pOutHashSetup->auth_config.config = outerConfig;
+ hashBlkPtrs.pOutHashSetup->auth_config.reserved = 0;
+
+ /* outer Counter set to 0 */
+ hashBlkPtrs.pOutHashSetup->auth_counter.counter = 0;
+ hashBlkPtrs.pOutHashSetup->auth_counter.reserved = 0;
+
+ /* set outer hash state 1 */
+ memcpy(hashBlkPtrs.pOutHashInitState1,
+ pOuterHashDefs->algInfo->initState,
+ pOuterHashDefs->algInfo->stateSize);
+
+ if (padLen > 0) {
+ LAC_OS_BZERO(hashBlkPtrs.pOutHashInitState1 +
+ pOuterHashDefs->algInfo->stateSize,
+ padLen);
+ }
+ }
+
+ if (CPA_CY_SYM_HASH_SNOW3G_UIA2 == pHashSetupData->hashAlgorithm) {
+ icp_qat_hw_cipher_config_t *pCipherConfig =
+ (icp_qat_hw_cipher_config_t *)hashBlkPtrs.pOutHashSetup;
+
+ pCipherConfig->val = ICP_QAT_HW_CIPHER_CONFIG_BUILD(
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2,
+ ICP_QAT_HW_CIPHER_KEY_CONVERT,
+ ICP_QAT_HW_CIPHER_ENCRYPT,
+ aed_hash_cmp_length);
+
+ pCipherConfig->reserved = 0;
+
+ memcpy((Cpa8U *)pCipherConfig +
+ sizeof(icp_qat_hw_cipher_config_t),
+ pHashSetupData->authModeSetupData.authKey,
+ pHashSetupData->authModeSetupData.authKeyLenInBytes);
+
+ LAC_OS_BZERO(
+ (Cpa8U *)pCipherConfig +
+ sizeof(icp_qat_hw_cipher_config_t) +
+ pHashSetupData->authModeSetupData.authKeyLenInBytes,
+ ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ);
+ } else if (CPA_CY_SYM_HASH_ZUC_EIA3 == pHashSetupData->hashAlgorithm) {
+ icp_qat_hw_cipher_config_t *pCipherConfig =
+ (icp_qat_hw_cipher_config_t *)hashBlkPtrs.pOutHashSetup;
+
+ pCipherConfig->val = ICP_QAT_HW_CIPHER_CONFIG_BUILD(
+ ICP_QAT_HW_CIPHER_ECB_MODE,
+ ICP_QAT_HW_CIPHER_ALGO_ZUC_3G_128_EEA3,
+ ICP_QAT_HW_CIPHER_KEY_CONVERT,
+ ICP_QAT_HW_CIPHER_ENCRYPT,
+ aed_hash_cmp_length);
+
+ pCipherConfig->reserved = 0;
+
+ memcpy((Cpa8U *)pCipherConfig +
+ sizeof(icp_qat_hw_cipher_config_t),
+ pHashSetupData->authModeSetupData.authKey,
+ pHashSetupData->authModeSetupData.authKeyLenInBytes);
+
+ LAC_OS_BZERO(
+ (Cpa8U *)pCipherConfig +
+ sizeof(icp_qat_hw_cipher_config_t) +
+ pHashSetupData->authModeSetupData.authKeyLenInBytes,
+ ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ);
+ }
+}
+
+static void
+LacSymQat_HashOpHwBlockPtrsInit(icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl,
+ void *pHwBlockBase,
+ lac_hash_blk_ptrs_optimised_t *pHashBlkPtrs)
+{
+ pHashBlkPtrs->pInHashInitState1 = (((Cpa8U *)pHwBlockBase) + 16);
+ pHashBlkPtrs->pInHashInitState2 =
+ (Cpa8U *)(pHashBlkPtrs->pInHashInitState1) +
+ cd_ctrl->inner_state1_sz;
+}
+
+static void
+LacSymQat_HashSetupBlockOptimisedFormatInit(
+ const CpaCySymHashSetupData *pHashSetupData,
+ icp_qat_fw_auth_cd_ctrl_hdr_t *pHashControlBlock,
+ void *pHwBlockBase,
+ icp_qat_hw_auth_mode_t qatHashMode,
+ lac_sym_qat_hash_precompute_info_t *pPrecompute,
+ lac_sym_qat_hash_defs_t *pHashDefs,
+ lac_sym_qat_hash_defs_t *pOuterHashDefs)
+{
+
+ Cpa32U state1PadLen = 0;
+ Cpa32U state2PadLen = 0;
+
+ lac_hash_blk_ptrs_optimised_t pHashBlkPtrs = { 0 };
+
+ LacSymQat_HashOpHwBlockPtrsInit(pHashControlBlock,
+ pHwBlockBase,
+ &pHashBlkPtrs);
+
+ if (pHashControlBlock->inner_state1_sz >
+ pHashDefs->algInfo->stateSize) {
+ state1PadLen = pHashControlBlock->inner_state1_sz -
+ pHashDefs->algInfo->stateSize;
+ }
+
+ if (pHashControlBlock->inner_state2_sz >
+ pHashDefs->algInfo->stateSize) {
+ state2PadLen = pHashControlBlock->inner_state2_sz -
+ pHashDefs->algInfo->stateSize;
+ }
+
+ if (state1PadLen > 0) {
+
+ LAC_OS_BZERO(pHashBlkPtrs.pInHashInitState1 +
+ pHashDefs->algInfo->stateSize,
+ state1PadLen);
+ }
+
+ if (state2PadLen > 0) {
+
+ LAC_OS_BZERO(pHashBlkPtrs.pInHashInitState2 +
+ pHashDefs->algInfo->stateSize,
+ state2PadLen);
+ }
+ pPrecompute->state1Size = pHashDefs->qatInfo->state1Length;
+ pPrecompute->state2Size = pHashDefs->qatInfo->state2Length;
+
+ /* Set the destination for pre-compute state1 data to be written */
+ pPrecompute->pState1 = pHashBlkPtrs.pInHashInitState1;
+
+ /* Set the destination for pre-compute state1 data to be written */
+ pPrecompute->pState2 = pHashBlkPtrs.pInHashInitState2;
+}
+
+void
+LacSymQat_HashStatePrefixAadBufferSizeGet(
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf)
+{
+ const icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl;
+ icp_qat_la_auth_req_params_t *pHashReqParams;
+
+ cd_ctrl = (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(pMsg->cd_ctrl);
+ pHashReqParams =
+ (icp_qat_la_auth_req_params_t *)(&(pMsg->serv_specif_rqpars));
+
+ /* hash state storage needed to support partial packets. Space reserved
+ * for this in all cases */
+ pHashStateBuf->stateStorageSzQuadWords = LAC_BYTES_TO_QUADWORDS(
+ sizeof(icp_qat_hw_auth_counter_t) + cd_ctrl->inner_state1_sz);
+
+ pHashStateBuf->prefixAadSzQuadWords = pHashReqParams->hash_state_sz;
+}
+
+void
+LacSymQat_HashStatePrefixAadBufferPopulate(
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf,
+ icp_qat_la_bulk_req_ftr_t *pMsg,
+ Cpa8U *pInnerPrefixAad,
+ Cpa8U innerPrefixSize,
+ Cpa8U *pOuterPrefix,
+ Cpa8U outerPrefixSize)
+{
+ const icp_qat_fw_auth_cd_ctrl_hdr_t *cd_ctrl =
+ (icp_qat_fw_auth_cd_ctrl_hdr_t *)&(pMsg->cd_ctrl);
+
+ icp_qat_la_auth_req_params_t *pHashReqParams =
+ (icp_qat_la_auth_req_params_t *)(&(pMsg->serv_specif_rqpars));
+
+ /*
+ * Let S be the supplied secret
+ * S1 = S/2 if S is even and (S/2 + 1) if S is odd.
+ * Set length S2 (inner prefix) = S1 and the start address
+ * of S2 is S[S1/2] i.e. if S is odd then S2 starts at the last byte of
+ * S1
+ * _____________________________________________________________
+ * | outer prefix | padding |
+ * |________________| |
+ * | |
+ * |____________________________________________________________|
+ * | inner prefix | padding |
+ * |________________| |
+ * | |
+ * |____________________________________________________________|
+ *
+ */
+ if (NULL != pInnerPrefixAad) {
+ Cpa8U *pLocalInnerPrefix =
+ (Cpa8U *)(pHashStateBuf->pData) +
+ LAC_QUADWORDS_TO_BYTES(
+ pHashStateBuf->stateStorageSzQuadWords);
+ Cpa8U padding =
+ pHashReqParams->u2.inner_prefix_sz - innerPrefixSize;
+ /* copy the inner prefix or aad data */
+ memcpy(pLocalInnerPrefix, pInnerPrefixAad, innerPrefixSize);
+
+ /* Reset with zeroes any area reserved for padding in this block
+ */
+ if (0 < padding) {
+ LAC_OS_BZERO(pLocalInnerPrefix + innerPrefixSize,
+ padding);
+ }
+ }
+
+ if (NULL != pOuterPrefix) {
+ Cpa8U *pLocalOuterPrefix =
+ (Cpa8U *)pHashStateBuf->pData +
+ LAC_QUADWORDS_TO_BYTES(
+ pHashStateBuf->stateStorageSzQuadWords +
+ cd_ctrl->outer_prefix_offset);
+ Cpa8U padding = LAC_QUADWORDS_TO_BYTES(
+ pHashStateBuf->prefixAadSzQuadWords) -
+ pHashReqParams->u2.inner_prefix_sz - outerPrefixSize;
+
+ /* copy the outer prefix */
+ memcpy(pLocalOuterPrefix, pOuterPrefix, outerPrefixSize);
+
+ /* Reset with zeroes any area reserved for padding in this block
+ */
+ if (0 < padding) {
+ LAC_OS_BZERO(pLocalOuterPrefix + outerPrefixSize,
+ padding);
+ }
+ }
+}
+
+inline CpaStatus
+LacSymQat_HashRequestParamsPopulate(
+ icp_qat_fw_la_bulk_req_t *pReq,
+ Cpa32U authOffsetInBytes,
+ Cpa32U authLenInBytes,
+ sal_service_t *pService,
+ lac_sym_qat_hash_state_buffer_info_t *pHashStateBuf,
+ Cpa32U packetType,
+ Cpa32U hashResultSize,
+ CpaBoolean digestVerify,
+ Cpa8U *pAuthResult,
+ CpaCySymHashAlgorithm alg,
+ void *hkdf_secret)
+{
+ Cpa64U authResultPhys = 0;
+ icp_qat_fw_la_auth_req_params_t *pHashReqParams;
+
+ pHashReqParams = (icp_qat_fw_la_auth_req_params_t
+ *)((Cpa8U *)&(pReq->serv_specif_rqpars) +
+ ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
+
+ pHashReqParams->auth_off = authOffsetInBytes;
+ pHashReqParams->auth_len = authLenInBytes;
+
+ /* Set the physical location of secret for HKDF */
+ if (NULL != hkdf_secret) {
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService), pHashReqParams->u1.aad_adr, hkdf_secret);
+
+ if (pHashReqParams->u1.aad_adr == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the"
+ " HKDF secret\n");
+ return CPA_STATUS_FAIL;
+ }
+ }
+
+ /* For a Full packet or last partial need to set the digest result
+ * pointer
+ * and the auth result field */
+ if (NULL != pAuthResult) {
+ authResultPhys =
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL((*pService),
+ (void *)pAuthResult);
+
+ if (authResultPhys == 0) {
+ LAC_LOG_ERROR(
+ "Unable to get the physical address of the"
+ " auth result\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pHashReqParams->auth_res_addr = authResultPhys;
+ } else {
+ pHashReqParams->auth_res_addr = 0;
+ }
+
+ if (CPA_TRUE == digestVerify) {
+ /* auth result size in bytes to be read in for a verify
+ * operation */
+ pHashReqParams->auth_res_sz = hashResultSize;
+ } else {
+ pHashReqParams->auth_res_sz = 0;
+ }
+
+ /* If there is a hash state prefix buffer */
+ if (NULL != pHashStateBuf) {
+ /* Only write the pointer to the buffer if the size is greater
+ * than 0
+ * this will be the case for plain and auth mode due to the
+ * state storage required for partial packets and for nested
+ * mode (when
+ * the prefix data is > 0) */
+ if ((pHashStateBuf->stateStorageSzQuadWords +
+ pHashStateBuf->prefixAadSzQuadWords) > 0) {
+ /* For the first partial packet, the QAT expects the
+ * pointer to the
+ * inner prefix even if there is no memory allocated for
+ * this. The
+ * QAT will internally calculate where to write the
+ * state back. */
+ if ((ICP_QAT_FW_LA_PARTIAL_START == packetType) ||
+ (ICP_QAT_FW_LA_PARTIAL_NONE == packetType)) {
+ // prefix_addr changed to auth_partial_st_prefix
+ pHashReqParams->u1.auth_partial_st_prefix =
+ ((pHashStateBuf->pDataPhys) +
+ LAC_QUADWORDS_TO_BYTES(
+ pHashStateBuf
+ ->stateStorageSzQuadWords));
+ } else {
+ pHashReqParams->u1.auth_partial_st_prefix =
+ pHashStateBuf->pDataPhys;
+ }
+ }
+ /* nested mode when the prefix data is 0 */
+ else {
+ pHashReqParams->u1.auth_partial_st_prefix = 0;
+ }
+
+ /* For middle & last partial, state size is the hash state
+ * storage
+ * if hash mode 2 this will include the prefix data */
+ if ((ICP_QAT_FW_LA_PARTIAL_MID == packetType) ||
+ (ICP_QAT_FW_LA_PARTIAL_END == packetType)) {
+ pHashReqParams->hash_state_sz =
+ (pHashStateBuf->stateStorageSzQuadWords +
+ pHashStateBuf->prefixAadSzQuadWords);
+ }
+ /* For full packets and first partials set the state size to
+ * that of
+ * the prefix/aad. prefix includes both the inner and outer
+ * prefix */
+ else {
+ pHashReqParams->hash_state_sz =
+ pHashStateBuf->prefixAadSzQuadWords;
+ }
+ } else {
+ pHashReqParams->u1.auth_partial_st_prefix = 0;
+ pHashReqParams->hash_state_sz = 0;
+ }
+
+ /* GMAC only */
+ if (CPA_CY_SYM_HASH_AES_GMAC == alg) {
+ pHashReqParams->hash_state_sz = 0;
+ pHashReqParams->u1.aad_adr = 0;
+ }
+
+ /* This field is only used by TLS requests */
+ /* In TLS case this is set after this function is called */
+ pHashReqParams->resrvd1 = 0;
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash_defs_lookup.c b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash_defs_lookup.c
new file mode 100644
index 000000000000..23a77f19cca6
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_hash_defs_lookup.c
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sym_qat_hash_defs_lookup.c Hash Definitions Lookup
+ *
+ * @ingroup LacHashDefsLookup
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "lac_common.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "icp_adf_transport.h"
+#include "lac_sym.h"
+#include "icp_qat_fw_la.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sym_hash_defs.h"
+
+/* state size for xcbc mac consists of 3 * 16 byte keys */
+#define LAC_SYM_QAT_XCBC_STATE_SIZE ((LAC_HASH_XCBC_MAC_BLOCK_SIZE)*3)
+
+#define LAC_SYM_QAT_CMAC_STATE_SIZE ((LAC_HASH_CMAC_BLOCK_SIZE)*3)
+
+/* This type is used for the mapping between the hash algorithm and
+ * the corresponding hash definitions structure */
+typedef struct lac_sym_qat_hash_def_map_s {
+ CpaCySymHashAlgorithm hashAlgorithm;
+ /* hash algorithm */
+ lac_sym_qat_hash_defs_t hashDefs;
+ /* hash defintions pointers */
+} lac_sym_qat_hash_def_map_t;
+
+/*
+*******************************************************************************
+* Static Variables
+*******************************************************************************
+*/
+
+/* initialisers as defined in FIPS and RFCS for digest operations */
+
+/* md5 16 bytes - Initialiser state can be found in RFC 1321*/
+static Cpa8U md5InitialState[LAC_HASH_MD5_STATE_SIZE] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+};
+
+/* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */
+static Cpa8U sha1InitialState[LAC_HASH_SHA1_STATE_SIZE] = {
+ 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba,
+ 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0
+};
+
+/* SHA 224 - 32 bytes - Initialiser state can be found in FIPS stds 180-2 */
+static Cpa8U sha224InitialState[LAC_HASH_SHA224_STATE_SIZE] = {
+ 0xc1, 0x05, 0x9e, 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd,
+ 0x17, 0xf7, 0x0e, 0x59, 0x39, 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58,
+ 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe, 0xfa, 0x4f, 0xa4
+};
+
+/* SHA 256 - 32 bytes - Initialiser state can be found in FIPS stds 180-2 */
+static Cpa8U sha256InitialState[LAC_HASH_SHA256_STATE_SIZE] =
+ { 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae, 0x85, 0x3c, 0x6e, 0xf3,
+ 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f, 0x9b, 0x05,
+ 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19 };
+
+/* SHA 384 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */
+static Cpa8U sha384InitialState[LAC_HASH_SHA384_STATE_SIZE] =
+ { 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
+ 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70,
+ 0xdd, 0x17, 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67,
+ 0x33, 0x26, 0x67, 0xff, 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87,
+ 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c, 0x2e, 0x0d, 0x64, 0xf9, 0x8f,
+ 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4 };
+
+/* SHA 512 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */
+static Cpa8U sha512InitialState[LAC_HASH_SHA512_STATE_SIZE] =
+ { 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae,
+ 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
+ 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51,
+ 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c,
+ 0x2b, 0x3e, 0x6c, 0x1f, 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd,
+ 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79 };
+
+/* SHA3 224 - 28 bytes */
+static Cpa8U sha3_224InitialState[LAC_HASH_SHA3_224_STATE_SIZE] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* SHA3 256 - 32 bytes */
+static Cpa8U sha3_256InitialState[LAC_HASH_SHA3_256_STATE_SIZE] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* SHA3 384 - 48 bytes */
+static Cpa8U sha3_384InitialState[LAC_HASH_SHA3_384_STATE_SIZE] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* SHA3 512 - 64 bytes */
+static Cpa8U sha3_512InitialState[LAC_HASH_SHA3_512_STATE_SIZE] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+/* SM3 - 32 bytes */
+static Cpa8U sm3InitialState[LAC_HASH_SM3_STATE_SIZE] =
+ { 0x73, 0x80, 0x16, 0x6f, 0x49, 0x14, 0xb2, 0xb9, 0x17, 0x24, 0x42,
+ 0xd7, 0xda, 0x8a, 0x06, 0x00, 0xa9, 0x6f, 0x30, 0xbc, 0x16, 0x31,
+ 0x38, 0xaa, 0xe3, 0x8d, 0xee, 0x4d, 0xb0, 0xfb, 0x0e, 0x4e };
+
+/* Constants used in generating K1, K2, K3 from a Key for AES_XCBC_MAC
+ * State defined in RFC 3566 */
+static Cpa8U aesXcbcKeySeed[LAC_SYM_QAT_XCBC_STATE_SIZE] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+};
+
+static Cpa8U aesCmacKeySeed[LAC_HASH_CMAC_BLOCK_SIZE] = { 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00,
+ 0x00 };
+
+/* Hash Algorithm specific structure */
+
+static lac_sym_qat_hash_alg_info_t md5Info = { LAC_HASH_MD5_DIGEST_SIZE,
+ LAC_HASH_MD5_BLOCK_SIZE,
+ md5InitialState,
+ LAC_HASH_MD5_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha1Info = { LAC_HASH_SHA1_DIGEST_SIZE,
+ LAC_HASH_SHA1_BLOCK_SIZE,
+ sha1InitialState,
+ LAC_HASH_SHA1_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha224Info = { LAC_HASH_SHA224_DIGEST_SIZE,
+ LAC_HASH_SHA224_BLOCK_SIZE,
+ sha224InitialState,
+ LAC_HASH_SHA224_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha256Info = { LAC_HASH_SHA256_DIGEST_SIZE,
+ LAC_HASH_SHA256_BLOCK_SIZE,
+ sha256InitialState,
+ LAC_HASH_SHA256_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha384Info = { LAC_HASH_SHA384_DIGEST_SIZE,
+ LAC_HASH_SHA384_BLOCK_SIZE,
+ sha384InitialState,
+ LAC_HASH_SHA384_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha512Info = { LAC_HASH_SHA512_DIGEST_SIZE,
+ LAC_HASH_SHA512_BLOCK_SIZE,
+ sha512InitialState,
+ LAC_HASH_SHA512_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha3_224Info =
+ { LAC_HASH_SHA3_224_DIGEST_SIZE,
+ LAC_HASH_SHA3_224_BLOCK_SIZE,
+ sha3_224InitialState,
+ LAC_HASH_SHA3_224_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha3_256Info =
+ { LAC_HASH_SHA3_256_DIGEST_SIZE,
+ LAC_HASH_SHA3_256_BLOCK_SIZE,
+ sha3_256InitialState,
+ LAC_HASH_SHA3_256_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha3_384Info =
+ { LAC_HASH_SHA3_384_DIGEST_SIZE,
+ LAC_HASH_SHA3_384_BLOCK_SIZE,
+ sha3_384InitialState,
+ LAC_HASH_SHA3_384_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t sha3_512Info =
+ { LAC_HASH_SHA3_512_DIGEST_SIZE,
+ LAC_HASH_SHA3_512_BLOCK_SIZE,
+ sha3_512InitialState,
+ LAC_HASH_SHA3_512_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t polyInfo = { LAC_HASH_POLY_DIGEST_SIZE,
+ LAC_HASH_POLY_BLOCK_SIZE,
+ NULL, /* intial state */
+ LAC_HASH_POLY_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t shake_128Info =
+ { LAC_HASH_SHAKE_128_DIGEST_SIZE, LAC_HASH_SHAKE_128_BLOCK_SIZE, NULL, 0 };
+
+static lac_sym_qat_hash_alg_info_t shake_256Info =
+ { LAC_HASH_SHAKE_256_DIGEST_SIZE, LAC_HASH_SHAKE_256_BLOCK_SIZE, NULL, 0 };
+
+static lac_sym_qat_hash_alg_info_t sm3Info = { LAC_HASH_SM3_DIGEST_SIZE,
+ LAC_HASH_SM3_BLOCK_SIZE,
+ sm3InitialState,
+ LAC_HASH_SM3_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t xcbcMacInfo =
+ { LAC_HASH_XCBC_MAC_128_DIGEST_SIZE,
+ LAC_HASH_XCBC_MAC_BLOCK_SIZE,
+ aesXcbcKeySeed,
+ LAC_SYM_QAT_XCBC_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t aesCmacInfo =
+ { LAC_HASH_CMAC_128_DIGEST_SIZE,
+ LAC_HASH_CMAC_BLOCK_SIZE,
+ aesCmacKeySeed,
+ LAC_SYM_QAT_CMAC_STATE_SIZE };
+
+static lac_sym_qat_hash_alg_info_t aesCcmInfo = {
+ LAC_HASH_AES_CCM_DIGEST_SIZE,
+ LAC_HASH_AES_CCM_BLOCK_SIZE,
+ NULL, /* intial state */
+ 0 /* state size */
+};
+
+static lac_sym_qat_hash_alg_info_t aesGcmInfo = {
+ LAC_HASH_AES_GCM_DIGEST_SIZE,
+ LAC_HASH_AES_GCM_BLOCK_SIZE,
+ NULL, /* initial state */
+ 0 /* state size */
+};
+
+static lac_sym_qat_hash_alg_info_t kasumiF9Info = {
+ LAC_HASH_KASUMI_F9_DIGEST_SIZE,
+ LAC_HASH_KASUMI_F9_BLOCK_SIZE,
+ NULL, /* initial state */
+ 0 /* state size */
+};
+
+static lac_sym_qat_hash_alg_info_t snow3gUia2Info = {
+ LAC_HASH_SNOW3G_UIA2_DIGEST_SIZE,
+ LAC_HASH_SNOW3G_UIA2_BLOCK_SIZE,
+ NULL, /* initial state */
+ 0 /* state size */
+};
+
+static lac_sym_qat_hash_alg_info_t aesCbcMacInfo =
+ { LAC_HASH_AES_CBC_MAC_DIGEST_SIZE,
+ LAC_HASH_AES_CBC_MAC_BLOCK_SIZE,
+ NULL,
+ 0 };
+
+static lac_sym_qat_hash_alg_info_t zucEia3Info = {
+ LAC_HASH_ZUC_EIA3_DIGEST_SIZE,
+ LAC_HASH_ZUC_EIA3_BLOCK_SIZE,
+ NULL, /* initial state */
+ 0 /* state size */
+};
+/* Hash QAT specific structures */
+
+static lac_sym_qat_hash_qat_info_t md5Config = { ICP_QAT_HW_AUTH_ALGO_MD5,
+ LAC_HASH_MD5_BLOCK_SIZE,
+ ICP_QAT_HW_MD5_STATE1_SZ,
+ ICP_QAT_HW_MD5_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha1Config = { ICP_QAT_HW_AUTH_ALGO_SHA1,
+ LAC_HASH_SHA1_BLOCK_SIZE,
+ ICP_QAT_HW_SHA1_STATE1_SZ,
+ ICP_QAT_HW_SHA1_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha224Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA224,
+ LAC_HASH_SHA224_BLOCK_SIZE,
+ ICP_QAT_HW_SHA224_STATE1_SZ,
+ ICP_QAT_HW_SHA224_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha256Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA256,
+ LAC_HASH_SHA256_BLOCK_SIZE,
+ ICP_QAT_HW_SHA256_STATE1_SZ,
+ ICP_QAT_HW_SHA256_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha384Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA384,
+ LAC_HASH_SHA384_BLOCK_SIZE,
+ ICP_QAT_HW_SHA384_STATE1_SZ,
+ ICP_QAT_HW_SHA384_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha512Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA512,
+ LAC_HASH_SHA512_BLOCK_SIZE,
+ ICP_QAT_HW_SHA512_STATE1_SZ,
+ ICP_QAT_HW_SHA512_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha3_224Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA3_224,
+ LAC_HASH_SHA3_224_BLOCK_SIZE,
+ ICP_QAT_HW_SHA3_224_STATE1_SZ,
+ ICP_QAT_HW_SHA3_224_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha3_256Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA3_256,
+ LAC_HASH_SHA3_256_BLOCK_SIZE,
+ ICP_QAT_HW_SHA3_256_STATE1_SZ,
+ ICP_QAT_HW_SHA3_256_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha3_384Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA3_384,
+ LAC_HASH_SHA3_384_BLOCK_SIZE,
+ ICP_QAT_HW_SHA3_384_STATE1_SZ,
+ ICP_QAT_HW_SHA3_384_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t sha3_512Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHA3_512,
+ LAC_HASH_SHA3_512_BLOCK_SIZE,
+ ICP_QAT_HW_SHA3_512_STATE1_SZ,
+ ICP_QAT_HW_SHA3_512_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t shake_128Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHAKE_128, LAC_HASH_SHAKE_128_BLOCK_SIZE, 0, 0 };
+
+static lac_sym_qat_hash_qat_info_t shake_256Config =
+ { ICP_QAT_HW_AUTH_ALGO_SHAKE_256, LAC_HASH_SHAKE_256_BLOCK_SIZE, 0, 0 };
+
+static lac_sym_qat_hash_qat_info_t polyConfig = { ICP_QAT_HW_AUTH_ALGO_POLY,
+ LAC_HASH_POLY_BLOCK_SIZE,
+ 0,
+ 0 };
+
+static lac_sym_qat_hash_qat_info_t sm3Config = { ICP_QAT_HW_AUTH_ALGO_SM3,
+ LAC_HASH_SM3_BLOCK_SIZE,
+ ICP_QAT_HW_SM3_STATE1_SZ,
+ ICP_QAT_HW_SM3_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t xcbcMacConfig =
+ { ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC,
+ 0,
+ ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ,
+ LAC_SYM_QAT_XCBC_STATE_SIZE };
+
+static lac_sym_qat_hash_qat_info_t aesCmacConfig =
+ { ICP_QAT_HW_AUTH_ALGO_AES_XCBC_MAC,
+ 0,
+ ICP_QAT_HW_AES_XCBC_MAC_STATE1_SZ,
+ LAC_SYM_QAT_CMAC_STATE_SIZE };
+
+static lac_sym_qat_hash_qat_info_t aesCcmConfig =
+ { ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC,
+ 0,
+ ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ,
+ ICP_QAT_HW_AES_CBC_MAC_KEY_SZ + ICP_QAT_HW_AES_CCM_CBC_E_CTR0_SZ };
+
+static lac_sym_qat_hash_qat_info_t aesGcmConfig =
+ { ICP_QAT_HW_AUTH_ALGO_GALOIS_128,
+ 0,
+ ICP_QAT_HW_GALOIS_128_STATE1_SZ,
+ ICP_QAT_HW_GALOIS_H_SZ + ICP_QAT_HW_GALOIS_LEN_A_SZ +
+ ICP_QAT_HW_GALOIS_E_CTR0_SZ };
+
+static lac_sym_qat_hash_qat_info_t kasumiF9Config =
+ { ICP_QAT_HW_AUTH_ALGO_KASUMI_F9,
+ 0,
+ ICP_QAT_HW_KASUMI_F9_STATE1_SZ,
+ ICP_QAT_HW_KASUMI_F9_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t snow3gUia2Config =
+ { ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2,
+ 0,
+ ICP_QAT_HW_SNOW_3G_UIA2_STATE1_SZ,
+ ICP_QAT_HW_SNOW_3G_UIA2_STATE2_SZ };
+
+static lac_sym_qat_hash_qat_info_t aesCbcMacConfig =
+ { ICP_QAT_HW_AUTH_ALGO_AES_CBC_MAC,
+ 0,
+ ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ,
+ ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ + ICP_QAT_HW_AES_CBC_MAC_STATE1_SZ };
+
+static lac_sym_qat_hash_qat_info_t zucEia3Config =
+ { ICP_QAT_HW_AUTH_ALGO_ZUC_3G_128_EIA3,
+ 0,
+ ICP_QAT_HW_ZUC_3G_EIA3_STATE1_SZ,
+ ICP_QAT_HW_ZUC_3G_EIA3_STATE2_SZ };
+
+/* Array of mappings between algorithm and info structure
+ * This array is used to populate the lookup table */
+static lac_sym_qat_hash_def_map_t lacHashDefsMapping[] =
+ { { CPA_CY_SYM_HASH_MD5, { &md5Info, &md5Config } },
+ { CPA_CY_SYM_HASH_SHA1, { &sha1Info, &sha1Config } },
+ { CPA_CY_SYM_HASH_SHA224, { &sha224Info, &sha224Config } },
+ { CPA_CY_SYM_HASH_SHA256, { &sha256Info, &sha256Config } },
+ { CPA_CY_SYM_HASH_SHA384, { &sha384Info, &sha384Config } },
+ { CPA_CY_SYM_HASH_SHA512, { &sha512Info, &sha512Config } },
+ { CPA_CY_SYM_HASH_SHA3_224, { &sha3_224Info, &sha3_224Config } },
+ { CPA_CY_SYM_HASH_SHA3_256, { &sha3_256Info, &sha3_256Config } },
+ { CPA_CY_SYM_HASH_SHA3_384, { &sha3_384Info, &sha3_384Config } },
+ { CPA_CY_SYM_HASH_SHA3_512, { &sha3_512Info, &sha3_512Config } },
+ { CPA_CY_SYM_HASH_SHAKE_128, { &shake_128Info, &shake_128Config } },
+ { CPA_CY_SYM_HASH_SHAKE_256, { &shake_256Info, &shake_256Config } },
+ { CPA_CY_SYM_HASH_POLY, { &polyInfo, &polyConfig } },
+ { CPA_CY_SYM_HASH_SM3, { &sm3Info, &sm3Config } },
+ { CPA_CY_SYM_HASH_AES_XCBC, { &xcbcMacInfo, &xcbcMacConfig } },
+ { CPA_CY_SYM_HASH_AES_CMAC, { &aesCmacInfo, &aesCmacConfig } },
+ { CPA_CY_SYM_HASH_AES_CCM, { &aesCcmInfo, &aesCcmConfig } },
+ { CPA_CY_SYM_HASH_AES_GCM, { &aesGcmInfo, &aesGcmConfig } },
+ { CPA_CY_SYM_HASH_KASUMI_F9, { &kasumiF9Info, &kasumiF9Config } },
+ { CPA_CY_SYM_HASH_SNOW3G_UIA2, { &snow3gUia2Info, &snow3gUia2Config } },
+ { CPA_CY_SYM_HASH_AES_GMAC, { &aesGcmInfo, &aesGcmConfig } },
+ { CPA_CY_SYM_HASH_ZUC_EIA3, { &zucEia3Info, &zucEia3Config } },
+ { CPA_CY_SYM_HASH_AES_CBC_MAC, { &aesCbcMacInfo, &aesCbcMacConfig } } };
+
+/*
+ * LacSymQat_HashLookupInit
+ */
+CpaStatus
+LacSymQat_HashLookupInit(CpaInstanceHandle instanceHandle)
+{
+ Cpa32U entry = 0;
+ Cpa32U numEntries = 0;
+ Cpa32U arraySize = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaCySymHashAlgorithm hashAlg = CPA_CY_SYM_HASH_NONE;
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ arraySize =
+ (CPA_CY_HASH_ALG_END + 1) * sizeof(lac_sym_qat_hash_defs_t *);
+ /* Size round up for performance */
+ arraySize = LAC_ALIGN_POW2_ROUNDUP(arraySize, LAC_64BYTE_ALIGNMENT);
+
+ pService->pLacHashLookupDefs = LAC_OS_MALLOC(arraySize);
+
+ if (NULL != pService->pLacHashLookupDefs) {
+ LAC_OS_BZERO(pService->pLacHashLookupDefs, arraySize);
+
+ numEntries = sizeof(lacHashDefsMapping) /
+ sizeof(lac_sym_qat_hash_def_map_t);
+
+ /* initialise the hash lookup definitions table so that the
+ * algorithm
+ * can be used to index into the table */
+ for (entry = 0; entry < numEntries; entry++) {
+ hashAlg = lacHashDefsMapping[entry].hashAlgorithm;
+
+ pService->pLacHashLookupDefs[hashAlg] =
+ &(lacHashDefsMapping[entry].hashDefs);
+ }
+ } else {
+ status = CPA_STATUS_RESOURCE;
+ }
+ return status;
+}
+
+/*
+ * LacSymQat_HashAlgLookupGet
+ */
+void
+LacSymQat_HashAlgLookupGet(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ lac_sym_qat_hash_alg_info_t **ppHashAlgInfo)
+{
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ *ppHashAlgInfo = pService->pLacHashLookupDefs[hashAlgorithm]->algInfo;
+}
+
+/*
+ * LacSymQat_HashDefsLookupGet
+ */
+void
+LacSymQat_HashDefsLookupGet(CpaInstanceHandle instanceHandle,
+ CpaCySymHashAlgorithm hashAlgorithm,
+ lac_sym_qat_hash_defs_t **ppHashDefsInfo)
+{
+ sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
+
+ *ppHashDefsInfo = pService->pLacHashLookupDefs[hashAlgorithm];
+}
diff --git a/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_key.c b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_key.c
new file mode 100644
index 000000000000..abc7710aa96d
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/crypto/sym/qat/lac_sym_qat_key.c
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ *****************************************************************************
+ * @file lac_sym_qat_key.c Interfaces for populating the symmetric qat key
+ * structures
+ *
+ * @ingroup LacSymQatKey
+ *
+ *****************************************************************************/
+
+#include "cpa.h"
+#include "cpa_cy_key.h"
+#include "lac_mem.h"
+#include "icp_qat_fw_la.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "lac_list.h"
+#include "lac_sal_types.h"
+#include "lac_sym_qat_key.h"
+#include "lac_sym_hash_defs.h"
+
+void
+LacSymQat_KeySslRequestPopulate(icp_qat_la_bulk_req_hdr_t *pKeyGenReqHdr,
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqMid,
+ Cpa32U generatedKeyLenInBytes,
+ Cpa32U labelLenInBytes,
+ Cpa32U secretLenInBytes,
+ Cpa32U iterations)
+{
+ /* Rounded to nearest 8 byte boundary */
+ Cpa8U outLenRounded = 0;
+ outLenRounded = LAC_ALIGN_POW2_ROUNDUP(generatedKeyLenInBytes,
+ LAC_QUAD_WORD_IN_BYTES);
+
+ pKeyGenReqMid->u.secret_lgth_ssl = secretLenInBytes;
+ pKeyGenReqMid->u1.s1.output_lgth_ssl = outLenRounded;
+ pKeyGenReqMid->u1.s1.label_lgth_ssl = labelLenInBytes;
+ pKeyGenReqMid->u2.iter_count = iterations;
+ pKeyGenReqMid->u3.resrvd2 = 0;
+ pKeyGenReqMid->resrvd3 = 0;
+
+ /* Set up the common LA flags */
+ pKeyGenReqHdr->comn_hdr.service_cmd_id =
+ ICP_QAT_FW_LA_CMD_SSL3_KEY_DERIVE;
+ pKeyGenReqHdr->comn_hdr.resrvd1 = 0;
+}
+
+void
+LacSymQat_KeyTlsRequestPopulate(
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqParams,
+ Cpa32U generatedKeyLenInBytes,
+ Cpa32U labelInfo, /* Generic name, can be num of labels or label length */
+ Cpa32U secretLenInBytes,
+ Cpa8U seedLenInBytes,
+ icp_qat_fw_la_cmd_id_t cmdId)
+{
+ pKeyGenReqParams->u1.s3.output_lgth_tls =
+ LAC_ALIGN_POW2_ROUNDUP(generatedKeyLenInBytes,
+ LAC_QUAD_WORD_IN_BYTES);
+
+ /* For TLS u param of auth_req_params is set to secretLen */
+ pKeyGenReqParams->u.secret_lgth_tls = secretLenInBytes;
+
+ switch (cmdId) {
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT:
+ pKeyGenReqParams->u2.hkdf_ikm_length = secretLenInBytes;
+ pKeyGenReqParams->u3.resrvd2 = 0;
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND:
+ pKeyGenReqParams->u1.hkdf.info_length = labelInfo;
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND:
+ pKeyGenReqParams->u2.hkdf_ikm_length = secretLenInBytes;
+ pKeyGenReqParams->u1.hkdf.info_length = labelInfo;
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL:
+ /* Num of Labels */
+ pKeyGenReqParams->u1.hkdf_label.num_labels = labelInfo;
+ pKeyGenReqParams->u3.hkdf_num_sublabels = 4; /* 4 subLabels */
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL:
+ pKeyGenReqParams->u2.hkdf_ikm_length = secretLenInBytes;
+ /* Num of Labels */
+ pKeyGenReqParams->u1.hkdf_label.num_labels = labelInfo;
+ pKeyGenReqParams->u3.hkdf_num_sublabels = 4; /* 4 subLabels */
+ break;
+ default:
+ pKeyGenReqParams->u1.s3.label_lgth_tls = labelInfo;
+ pKeyGenReqParams->u2.tls_seed_length = seedLenInBytes;
+ pKeyGenReqParams->u3.resrvd2 = 0;
+ break;
+ }
+ pKeyGenReqParams->resrvd3 = 0;
+}
+
+void
+LacSymQat_KeyMgfRequestPopulate(icp_qat_la_bulk_req_hdr_t *pKeyGenReqHdr,
+ icp_qat_fw_la_key_gen_common_t *pKeyGenReqMid,
+ Cpa8U seedLenInBytes,
+ Cpa16U maskLenInBytes,
+ Cpa8U hashLenInBytes)
+{
+ pKeyGenReqHdr->comn_hdr.service_cmd_id = ICP_QAT_FW_LA_CMD_MGF1;
+ pKeyGenReqMid->u.mask_length =
+ LAC_ALIGN_POW2_ROUNDUP(maskLenInBytes, LAC_QUAD_WORD_IN_BYTES);
+
+ pKeyGenReqMid->u1.s2.hash_length = hashLenInBytes;
+ pKeyGenReqMid->u1.s2.seed_length = seedLenInBytes;
+}
+
+void
+LacSymQat_KeySslKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_ssl_key_material_input_t *pSslKeyMaterialInput,
+ void *pSeed,
+ Cpa64U labelPhysAddr,
+ void *pSecret)
+{
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService), pSslKeyMaterialInput->seed_addr, pSeed);
+
+ pSslKeyMaterialInput->label_addr = labelPhysAddr;
+
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService), pSslKeyMaterialInput->secret_addr, pSecret);
+}
+
+void
+LacSymQat_KeyTlsKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_tls_key_material_input_t *pTlsKeyMaterialInput,
+ void *pSeed,
+ Cpa64U labelPhysAddr)
+{
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService), pTlsKeyMaterialInput->seed_addr, pSeed);
+
+ pTlsKeyMaterialInput->label_addr = labelPhysAddr;
+}
+
+void
+LacSymQat_KeyTlsHKDFKeyMaterialInputPopulate(
+ sal_service_t *pService,
+ icp_qat_fw_la_hkdf_key_material_input_t *pTlsKeyMaterialInput,
+ CpaCyKeyGenHKDFOpData *pKeyGenTlsOpData,
+ Cpa64U subLabelsPhysAddr,
+ icp_qat_fw_la_cmd_id_t cmdId)
+{
+ switch (cmdId) {
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT:
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService),
+ pTlsKeyMaterialInput->ikm_addr,
+ pKeyGenTlsOpData->secret);
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND:
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService),
+ pTlsKeyMaterialInput->labels_addr,
+ pKeyGenTlsOpData->info);
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND:
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService),
+ pTlsKeyMaterialInput->ikm_addr,
+ pKeyGenTlsOpData->secret);
+ pTlsKeyMaterialInput->labels_addr =
+ pTlsKeyMaterialInput->ikm_addr +
+ ((uint64_t)&pKeyGenTlsOpData->info -
+ (uint64_t)&pKeyGenTlsOpData->secret);
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXPAND_LABEL:
+ pTlsKeyMaterialInput->sublabels_addr = subLabelsPhysAddr;
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService),
+ pTlsKeyMaterialInput->labels_addr,
+ pKeyGenTlsOpData->label);
+ break;
+ case ICP_QAT_FW_LA_CMD_HKDF_EXTRACT_AND_EXPAND_LABEL:
+ pTlsKeyMaterialInput->sublabels_addr = subLabelsPhysAddr;
+ LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
+ (*pService),
+ pTlsKeyMaterialInput->ikm_addr,
+ pKeyGenTlsOpData->secret);
+ pTlsKeyMaterialInput->labels_addr =
+ pTlsKeyMaterialInput->ikm_addr +
+ ((uint64_t)&pKeyGenTlsOpData->label -
+ (uint64_t)&pKeyGenTlsOpData->secret);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_compression.c b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c
new file mode 100644
index 000000000000..d8523d23b0e0
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/ctrl/sal_compression.c
@@ -0,0 +1,1554 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_compression.c
+ *
+ * @ingroup SalCtrl
+ *
+ * @description
+ * This file contains the sal implementation for compression.
+ *
+ *****************************************************************************/
+
+/* QAT-API includes */
+#include "cpa.h"
+#include "cpa_dc.h"
+
+/* QAT utils includes */
+#include "qat_utils.h"
+
+/* ADF includes */
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_cfg.h"
+#include "icp_adf_accel_mgr.h"
+#include "icp_adf_poll.h"
+#include "icp_adf_debug.h"
+#include "icp_adf_esram.h"
+#include "icp_qat_hw.h"
+
+/* SAL includes */
+#include "lac_mem.h"
+#include "lac_common.h"
+#include "lac_mem_pools.h"
+#include "sal_statistics.h"
+#include "lac_list.h"
+#include "icp_sal_poll.h"
+#include "sal_types_compression.h"
+#include "dc_session.h"
+#include "dc_datapath.h"
+#include "dc_stats.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "sal_string_parse.h"
+#include "sal_service_state.h"
+#include "lac_buffer_desc.h"
+#include "icp_qat_fw_comp.h"
+#include "icp_sal_versions.h"
+
+/* C string null terminator size */
+#define SAL_NULL_TERM_SIZE 1
+
+/* Type to access extended features bit fields */
+typedef struct dc_extended_features_s {
+ unsigned is_cnv : 1; /* Bit<0> */
+ unsigned padding : 7;
+ unsigned is_cnvnr : 1; /* Bit<8> */
+ unsigned not_used : 23;
+} dc_extd_ftrs_t;
+
+/*
+ * Prints statistics for a compression instance
+ */
+static int
+SalCtrl_CompresionDebug(void *private_data, char *data, int size, int offset)
+{
+ sal_compression_service_t *pCompressionService =
+ (sal_compression_service_t *)private_data;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaDcStats dcStats = { 0 };
+ Cpa32S len = 0;
+
+ status = cpaDcGetStats(pCompressionService, &dcStats);
+ if (status != CPA_STATUS_SUCCESS) {
+ QAT_UTILS_LOG("cpaDcGetStats returned error.\n");
+ return (-1);
+ }
+
+ /* Engine Info */
+ if (NULL != pCompressionService->debug_file) {
+ len += snprintf(data + len,
+ size - len,
+ SEPARATOR BORDER
+ " Statistics for Instance %24s | \n" SEPARATOR,
+ pCompressionService->debug_file->name);
+ }
+
+ /* Perform Info */
+ len += snprintf(data + len,
+ size - len,
+ BORDER " DC comp Requests: %16llu " BORDER
+ "\n" BORDER
+ " DC comp Request Errors: %16llu " BORDER
+ "\n" BORDER
+ " DC comp Completed: %16llu " BORDER
+ "\n" BORDER
+ " DC comp Completed Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (long long unsigned int)dcStats.numCompRequests,
+ (long long unsigned int)dcStats.numCompRequestsErrors,
+ (long long unsigned int)dcStats.numCompCompleted,
+ (long long unsigned int)dcStats.numCompCompletedErrors);
+
+ /* Perform Info */
+ len += snprintf(
+ data + len,
+ size - len,
+ BORDER " DC decomp Requests: %16llu " BORDER "\n" BORDER
+ " DC decomp Request Errors: %16llu " BORDER "\n" BORDER
+ " DC decomp Completed: %16llu " BORDER "\n" BORDER
+ " DC decomp Completed Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (long long unsigned int)dcStats.numDecompRequests,
+ (long long unsigned int)dcStats.numDecompRequestsErrors,
+ (long long unsigned int)dcStats.numDecompCompleted,
+ (long long unsigned int)dcStats.numDecompCompletedErrors);
+ return 0;
+}
+
+/* Initialise device specific information needed by compression service */
+static CpaStatus
+SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device,
+ sal_compression_service_t *pCompService)
+{
+ switch (device->deviceType) {
+ case DEVICE_DH895XCC:
+ case DEVICE_DH895XCCVF:
+ pCompService->generic_service_info.integrityCrcCheck =
+ CPA_FALSE;
+ pCompService->numInterBuffs =
+ DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
+ pCompService->comp_device_data.minOutputBuffSize =
+ DC_DEST_BUFFER_STA_MIN_SIZE;
+ pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
+ pCompService->comp_device_data.oddByteDecompInterim = CPA_FALSE;
+ pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
+ pCompService->comp_device_data.useDevRam =
+ ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ pCompService->comp_device_data.enableDmm =
+ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED;
+
+ pCompService->comp_device_data.inflateContextSize =
+ DC_INFLATE_CONTEXT_SIZE;
+ pCompService->comp_device_data.highestHwCompressionDepth =
+ ICP_QAT_HW_COMPRESSION_DEPTH_16;
+
+ pCompService->comp_device_data.windowSizeMask =
+ (1 << DC_8K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
+ pCompService->comp_device_data.cnvnrSupported = CPA_FALSE;
+ break;
+ case DEVICE_C3XXX:
+ case DEVICE_C3XXXVF:
+ case DEVICE_200XX:
+ case DEVICE_200XXVF:
+ pCompService->generic_service_info.integrityCrcCheck =
+ CPA_FALSE;
+ pCompService->numInterBuffs =
+ DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
+ pCompService->comp_device_data.oddByteDecompNobFinal =
+ CPA_FALSE;
+ pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
+ pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
+ pCompService->comp_device_data.useDevRam =
+ ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ pCompService->comp_device_data.inflateContextSize =
+ DC_INFLATE_EH_CONTEXT_SIZE;
+ pCompService->comp_device_data.highestHwCompressionDepth =
+ ICP_QAT_HW_COMPRESSION_DEPTH_16;
+ pCompService->comp_device_data.windowSizeMask =
+ (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
+ pCompService->comp_device_data.minOutputBuffSize =
+ DC_DEST_BUFFER_STA_MIN_SIZE;
+ pCompService->comp_device_data.enableDmm =
+ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
+
+ pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
+ break;
+ case DEVICE_C62X:
+ case DEVICE_C62XVF:
+ pCompService->generic_service_info.integrityCrcCheck =
+ CPA_FALSE;
+ pCompService->numInterBuffs =
+ DC_QAT_MAX_NUM_INTER_BUFFERS_10COMP_SLICES;
+ pCompService->comp_device_data.oddByteDecompNobFinal =
+ CPA_FALSE;
+ pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
+ pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
+ pCompService->comp_device_data.useDevRam =
+ ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ pCompService->comp_device_data.inflateContextSize =
+ DC_INFLATE_EH_CONTEXT_SIZE;
+ pCompService->comp_device_data.windowSizeMask =
+ (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
+ pCompService->comp_device_data.minOutputBuffSize =
+ DC_DEST_BUFFER_STA_MIN_SIZE;
+ pCompService->comp_device_data.enableDmm =
+ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
+ pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
+ break;
+ case DEVICE_C4XXX:
+ case DEVICE_C4XXXVF:
+ pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE;
+ pCompService->numInterBuffs =
+ DC_QAT_MAX_NUM_INTER_BUFFERS_24COMP_SLICES;
+ pCompService->comp_device_data.minOutputBuffSize =
+ DC_DEST_BUFFER_MIN_SIZE;
+ pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
+ pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
+ pCompService->comp_device_data.translatorOverflow = CPA_TRUE;
+ if (pCompService->generic_service_info.capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_INLINE) {
+ pCompService->comp_device_data.useDevRam =
+ ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ } else {
+ pCompService->comp_device_data.useDevRam =
+ ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
+ }
+ pCompService->comp_device_data.enableDmm =
+ ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
+ pCompService->comp_device_data.inflateContextSize =
+ DC_INFLATE_EH_CONTEXT_SIZE;
+ pCompService->comp_device_data.highestHwCompressionDepth =
+ ICP_QAT_HW_COMPRESSION_DEPTH_128;
+ pCompService->comp_device_data.windowSizeMask =
+ (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
+ pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
+ break;
+ default:
+ QAT_UTILS_LOG("Unknown device type! - %d.\n",
+ device->deviceType);
+ return CPA_STATUS_FAIL;
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+SalCtrl_CompressionInit(icp_accel_dev_t *device, sal_service_t *service)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U numCompConcurrentReq = 0;
+ Cpa32U request_ring_id = 0;
+ Cpa32U response_ring_id = 0;
+
+ char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char compMemPool[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char *instance_name = NULL;
+ sal_statistics_collection_t *pStatsCollection =
+ (sal_statistics_collection_t *)device->pQatStats;
+ icp_resp_deliv_method rx_resp_type = ICP_RESP_TYPE_IRQ;
+ sal_compression_service_t *pCompressionService =
+ (sal_compression_service_t *)service;
+ Cpa32U msgSize = 0;
+ char *section = DYN_SEC;
+
+ SAL_SERVICE_GOOD_FOR_INIT(pCompressionService);
+
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_INITIALIZING;
+
+ if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+ if (pStatsCollection == NULL) {
+ return CPA_STATUS_FAIL;
+ }
+
+ /* Get Config Info: Accel Num, bank Num, packageID,
+ coreAffinity, nodeAffinity and response mode
+ */
+
+ pCompressionService->acceleratorNum = 0;
+
+ /* Initialise device specific compression data */
+ SalCtrl_CompressionInit_CompData(device, pCompressionService);
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "BankNumber",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ temp_string);
+ return status;
+ }
+
+ pCompressionService->bankNum =
+ Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "IsPolled",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ temp_string);
+ return status;
+ }
+ pCompressionService->isPolled =
+ (Cpa8U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ /* User instances only support poll and epoll mode */
+ if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
+ QAT_UTILS_LOG(
+ "IsPolled %u is not supported for user instance %s.\n",
+ pCompressionService->isPolled,
+ temp_string);
+ return CPA_STATUS_FAIL;
+ }
+
+ if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
+ rx_resp_type = ICP_RESP_TYPE_POLL;
+ }
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ADF_DEV_PKG_ID,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ ADF_DEV_PKG_ID);
+ return status;
+ }
+ pCompressionService->pkgID =
+ (Cpa16U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ADF_DEV_NODE_ID,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ ADF_DEV_NODE_ID);
+ return status;
+ }
+ pCompressionService->nodeAffinity =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ /* In case of interrupt instance, use the bank affinity set by adf_ctl
+ * Otherwise, use the instance affinity for backwards compatibility */
+ if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
+ /* Next need to read the [AcceleratorX] section of the config
+ * file */
+ status = Sal_StringParsing("Accelerator",
+ pCompressionService->acceleratorNum,
+ "",
+ temp_string2);
+ LAC_CHECK_STATUS(status);
+
+ status = Sal_StringParsing("Bank",
+ pCompressionService->bankNum,
+ "CoreAffinity",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ } else {
+ strncpy(temp_string2,
+ section,
+ sizeof(temp_string2) - SAL_NULL_TERM_SIZE);
+ temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES -
+ SAL_NULL_TERM_SIZE] = '\0';
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "CoreAffinity",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ }
+
+ status = icp_adf_cfgGetParamValue(device,
+ temp_string2,
+ temp_string,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ temp_string);
+ return status;
+ }
+ pCompressionService->coreAffinity =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "NumConcurrentRequests",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ temp_string);
+ return status;
+ }
+
+ numCompConcurrentReq =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+ if (validateConcurrRequest(numCompConcurrentReq)) {
+ QAT_UTILS_LOG(
+ "Invalid NumConcurrentRequests, valid values are: {64, 128, 256, ... 32768, 65536}.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* ADF does not allow us to completely fill the ring for batch requests
+ */
+ pCompressionService->maxNumCompConcurrentReq =
+ (numCompConcurrentReq - SAL_BATCH_SUBMIT_FREE_SPACE);
+
+ /* 1. Create transport handles */
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "RingTx",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+
+ msgSize = LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES;
+ status = icp_adf_transCreateHandle(
+ device,
+ ICP_TRANS_TYPE_ETR,
+ section,
+ pCompressionService->acceleratorNum,
+ pCompressionService->bankNum,
+ temp_string,
+ lac_getRingType(SAL_RING_TYPE_DC),
+ NULL,
+ ICP_RESP_TYPE_NONE,
+ numCompConcurrentReq,
+ msgSize,
+ (icp_comms_trans_handle *)&(
+ pCompressionService->trans_handle_compression_tx));
+ LAC_CHECK_STATUS(status);
+
+ if (icp_adf_transGetRingNum(
+ pCompressionService->trans_handle_compression_tx,
+ &request_ring_id) != CPA_STATUS_SUCCESS) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ QAT_UTILS_LOG("Failed to get DC TX ring number.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "RingRx",
+ temp_string);
+ if (CPA_STATUS_SUCCESS != status) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+ return status;
+ }
+
+ msgSize = LAC_QAT_DC_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES;
+ status = icp_adf_transCreateHandle(
+ device,
+ ICP_TRANS_TYPE_ETR,
+ section,
+ pCompressionService->acceleratorNum,
+ pCompressionService->bankNum,
+ temp_string,
+ lac_getRingType(SAL_RING_TYPE_NONE),
+ (icp_trans_callback)dcCompression_ProcessCallback,
+ rx_resp_type,
+ numCompConcurrentReq,
+ msgSize,
+ (icp_comms_trans_handle *)&(
+ pCompressionService->trans_handle_compression_rx));
+ if (CPA_STATUS_SUCCESS != status) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+ return status;
+ }
+
+ if (icp_adf_transGetRingNum(
+ pCompressionService->trans_handle_compression_rx,
+ &response_ring_id) != CPA_STATUS_SUCCESS) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+
+ QAT_UTILS_LOG("Failed to get DC RX ring number.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* 2. Allocates memory pools */
+
+ /* Valid initialisation value for a pool ID */
+ pCompressionService->compression_mem_pool = LAC_MEM_POOL_INIT_POOL_ID;
+
+ status = Sal_StringParsing(
+ "Comp",
+ pCompressionService->generic_service_info.instance,
+ "_MemPool",
+ compMemPool);
+ if (CPA_STATUS_SUCCESS != status) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+
+ return status;
+ }
+
+ status = Lac_MemPoolCreate(&pCompressionService->compression_mem_pool,
+ compMemPool,
+ (numCompConcurrentReq + 1),
+ sizeof(dc_compression_cookie_t),
+ LAC_64BYTE_ALIGNMENT,
+ CPA_FALSE,
+ pCompressionService->nodeAffinity);
+ if (CPA_STATUS_SUCCESS != status) {
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+
+ return status;
+ }
+
+ /* Init compression statistics */
+ status = dcStatsInit(pCompressionService);
+ if (CPA_STATUS_SUCCESS != status) {
+ Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+
+ return status;
+ }
+ if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
+ /* Get instance name for stats */
+ instance_name = LAC_OS_MALLOC(ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ if (NULL == instance_name) {
+ Lac_MemPoolDestroy(
+ pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+
+ return CPA_STATUS_RESOURCE;
+ }
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "Name",
+ temp_string);
+ if (CPA_STATUS_SUCCESS != status) {
+ Lac_MemPoolDestroy(
+ pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+ LAC_OS_FREE(instance_name);
+ return status;
+ }
+ status = icp_adf_cfgGetParamValue(device,
+ section,
+ temp_string,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ temp_string);
+
+ Lac_MemPoolDestroy(
+ pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+ LAC_OS_FREE(instance_name);
+ return status;
+ }
+
+ snprintf(instance_name,
+ ADF_CFG_MAX_VAL_LEN_IN_BYTES,
+ "%s",
+ adfGetParam);
+
+ pCompressionService->debug_file =
+ LAC_OS_MALLOC(sizeof(debug_file_info_t));
+ if (NULL == pCompressionService->debug_file) {
+ Lac_MemPoolDestroy(
+ pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+ LAC_OS_FREE(instance_name);
+ return CPA_STATUS_RESOURCE;
+ }
+
+ memset(pCompressionService->debug_file,
+ 0,
+ sizeof(debug_file_info_t));
+ pCompressionService->debug_file->name = instance_name;
+ pCompressionService->debug_file->seq_read =
+ SalCtrl_CompresionDebug;
+ pCompressionService->debug_file->private_data =
+ pCompressionService;
+ pCompressionService->debug_file->parent =
+ pCompressionService->generic_service_info.debug_parent_dir;
+
+ status = icp_adf_debugAddFile(device,
+ pCompressionService->debug_file);
+ if (CPA_STATUS_SUCCESS != status) {
+ Lac_MemPoolDestroy(
+ pCompressionService->compression_mem_pool);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+
+ icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+ LAC_OS_FREE(instance_name);
+ LAC_OS_FREE(pCompressionService->debug_file);
+ return status;
+ }
+ }
+ pCompressionService->generic_service_info.stats = pStatsCollection;
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_INITIALIZED;
+
+ return status;
+}
+
+CpaStatus
+SalCtrl_CompressionStart(icp_accel_dev_t *device, sal_service_t *service)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ sal_compression_service_t *pCompressionService =
+ (sal_compression_service_t *)service;
+
+ if (SAL_SERVICE_STATE_INITIALIZED !=
+ pCompressionService->generic_service_info.state) {
+ QAT_UTILS_LOG("Not in the correct state to call start.\n");
+ return CPA_STATUS_FAIL;
+ }
+ /**************************************************************/
+ /* Obtain Extended Features. I.e. Compress And Verify */
+ /**************************************************************/
+ pCompressionService->generic_service_info.dcExtendedFeatures =
+ device->dcExtendedFeatures;
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_RUNNING;
+
+ return status;
+}
+
+CpaStatus
+SalCtrl_CompressionStop(icp_accel_dev_t *device, sal_service_t *service)
+{
+ sal_compression_service_t *pCompressionService =
+ (sal_compression_service_t *)service;
+
+ if (SAL_SERVICE_STATE_RUNNING !=
+ pCompressionService->generic_service_info.state) {
+ QAT_UTILS_LOG("Not in the correct state to call stop.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ if (icp_adf_is_dev_in_reset(device)) {
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_RESTARTING;
+ return CPA_STATUS_SUCCESS;
+ }
+
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_SHUTTING_DOWN;
+ return CPA_STATUS_RETRY;
+}
+
+CpaStatus
+SalCtrl_CompressionShutdown(icp_accel_dev_t *device, sal_service_t *service)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ sal_compression_service_t *pCompressionService =
+ (sal_compression_service_t *)service;
+ sal_statistics_collection_t *pStatsCollection =
+ (sal_statistics_collection_t *)device->pQatStats;
+
+ if ((SAL_SERVICE_STATE_INITIALIZED !=
+ pCompressionService->generic_service_info.state) &&
+ (SAL_SERVICE_STATE_SHUTTING_DOWN !=
+ pCompressionService->generic_service_info.state) &&
+ (SAL_SERVICE_STATE_RESTARTING !=
+ pCompressionService->generic_service_info.state)) {
+ QAT_UTILS_LOG("Not in the correct state to call shutdown.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
+
+ status = icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_tx);
+ LAC_CHECK_STATUS(status);
+
+ status = icp_adf_transReleaseHandle(
+ pCompressionService->trans_handle_compression_rx);
+ LAC_CHECK_STATUS(status);
+
+ if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
+ /* Clean stats */
+ if (NULL != pCompressionService->debug_file) {
+ icp_adf_debugRemoveFile(
+ pCompressionService->debug_file);
+ LAC_OS_FREE(pCompressionService->debug_file->name);
+ LAC_OS_FREE(pCompressionService->debug_file);
+ pCompressionService->debug_file = NULL;
+ }
+ }
+ pCompressionService->generic_service_info.stats = NULL;
+ dcStatsFree(pCompressionService);
+
+ if (icp_adf_is_dev_in_reset(device)) {
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_RESTARTING;
+ return CPA_STATUS_SUCCESS;
+ }
+ pCompressionService->generic_service_info.state =
+ SAL_SERVICE_STATE_SHUTDOWN;
+ return status;
+}
+
+CpaStatus
+cpaDcGetStatusText(const CpaInstanceHandle dcInstance,
+ const CpaStatus errStatus,
+ Cpa8S *pStatusText)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ LAC_CHECK_NULL_PARAM(pStatusText);
+
+ switch (errStatus) {
+ case CPA_STATUS_SUCCESS:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_SUCCESS);
+ break;
+ case CPA_STATUS_FAIL:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FAIL);
+ break;
+ case CPA_STATUS_RETRY:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RETRY);
+ break;
+ case CPA_STATUS_RESOURCE:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RESOURCE);
+ break;
+ case CPA_STATUS_INVALID_PARAM:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_INVALID_PARAM);
+ break;
+ case CPA_STATUS_FATAL:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FATAL);
+ break;
+ case CPA_STATUS_UNSUPPORTED:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_UNSUPPORTED);
+ break;
+ default:
+ status = CPA_STATUS_INVALID_PARAM;
+ break;
+ }
+
+ return status;
+}
+
+CpaStatus
+cpaDcGetNumIntermediateBuffers(CpaInstanceHandle dcInstance,
+ Cpa16U *pNumBuffers)
+{
+ CpaInstanceHandle insHandle = NULL;
+ sal_compression_service_t *pService = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = dcInstance;
+ }
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ LAC_CHECK_NULL_PARAM(pNumBuffers);
+
+ pService = (sal_compression_service_t *)insHandle;
+ *pNumBuffers = pService->numInterBuffs;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcStartInstance(CpaInstanceHandle instanceHandle,
+ Cpa16U numBuffers,
+ CpaBufferList **pIntermediateBufferPtrsArray)
+{
+ icp_qat_addr_width_t *pInterBuffPtrsArray = NULL;
+ icp_qat_addr_width_t pArrayBufferListDescPhyAddr = 0;
+ icp_qat_addr_width_t bufListDescPhyAddr;
+ icp_qat_addr_width_t bufListAlignedPhyAddr;
+ CpaFlatBuffer *pClientCurrFlatBuffer = NULL;
+ icp_buffer_list_desc_t *pBufferListDesc = NULL;
+ icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
+ CpaInstanceInfo2 info = { 0 };
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_compression_service_t *pService = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ Cpa16U bufferIndex = 0;
+ Cpa32U numFlatBuffers = 0;
+ Cpa64U clientListSize = 0;
+ CpaBufferList *pClientCurrentIntermediateBuffer = NULL;
+ Cpa32U bufferIndex2 = 0;
+ CpaBufferList **pTempIntermediateBufferPtrsArray;
+ Cpa64U lastClientListSize = 0;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = instanceHandle;
+ }
+ LAC_CHECK_NULL_PARAM(insHandle);
+
+ status = cpaDcInstanceGetInfo2(insHandle, &info);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Can not get instance info.\n");
+ return status;
+ }
+
+ dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
+ if (NULL == dev) {
+ QAT_UTILS_LOG("Can not find device for the instance\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ if (NULL == pIntermediateBufferPtrsArray) {
+ /* Increment dev ref counter and return - DRAM is not used */
+ icp_qa_dev_get(dev);
+ return CPA_STATUS_SUCCESS;
+ }
+
+ if (0 == numBuffers) {
+ /* Increment dev ref counter and return - DRAM is not used */
+ icp_qa_dev_get(dev);
+ return CPA_STATUS_SUCCESS;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+
+ if ((numBuffers > 0) && (NULL == pIntermediateBufferPtrsArray)) {
+ QAT_UTILS_LOG("Invalid Intermediate Buffers Array pointer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Check number of intermediate buffers allocated by user */
+ if ((pService->numInterBuffs != numBuffers)) {
+ QAT_UTILS_LOG("Invalid number of buffers\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ pTempIntermediateBufferPtrsArray = pIntermediateBufferPtrsArray;
+ for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
+ if (NULL == *pTempIntermediateBufferPtrsArray) {
+ QAT_UTILS_LOG(
+ "Intermediate Buffer - Invalid Buffer List pointer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (NULL == (*pTempIntermediateBufferPtrsArray)->pBuffers) {
+ QAT_UTILS_LOG(
+ "Intermediate Buffer - Invalid Flat Buffer descriptor pointer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (NULL ==
+ (*pTempIntermediateBufferPtrsArray)->pPrivateMetaData) {
+ QAT_UTILS_LOG(
+ "Intermediate Buffer - Invalid Private MetaData descriptor pointer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ clientListSize = 0;
+ for (bufferIndex2 = 0; bufferIndex2 <
+ (*pTempIntermediateBufferPtrsArray)->numBuffers;
+ bufferIndex2++) {
+
+ if ((0 !=
+ (*pTempIntermediateBufferPtrsArray)
+ ->pBuffers[bufferIndex2]
+ .dataLenInBytes) &&
+ NULL ==
+ (*pTempIntermediateBufferPtrsArray)
+ ->pBuffers[bufferIndex2]
+ .pData) {
+ QAT_UTILS_LOG(
+ "Intermediate Buffer - Invalid Flat Buffer pointer\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ clientListSize += (*pTempIntermediateBufferPtrsArray)
+ ->pBuffers[bufferIndex2]
+ .dataLenInBytes;
+ }
+
+ if (bufferIndex != 0) {
+ if (lastClientListSize != clientListSize) {
+ QAT_UTILS_LOG(
+ "SGLs have to be of the same size.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ } else {
+ lastClientListSize = clientListSize;
+ }
+ pTempIntermediateBufferPtrsArray++;
+ }
+
+ /* Allocate array of physical pointers to icp_buffer_list_desc_t */
+ status = LAC_OS_CAMALLOC(&pInterBuffPtrsArray,
+ (numBuffers * sizeof(icp_qat_addr_width_t)),
+ LAC_64BYTE_ALIGNMENT,
+ pService->nodeAffinity);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Can not allocate Intermediate Buffers array.\n");
+ return status;
+ }
+
+ /* Get physical address of the intermediate buffer pointers array */
+ pArrayBufferListDescPhyAddr = LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pInterBuffPtrsArray));
+
+ pService->pInterBuffPtrsArray = pInterBuffPtrsArray;
+ pService->pInterBuffPtrsArrayPhyAddr = pArrayBufferListDescPhyAddr;
+
+ /* Get the full size of the buffer list */
+ /* Assumption: all the SGLs allocated by the user have the same size */
+ clientListSize = 0;
+ for (bufferIndex = 0;
+ bufferIndex < (*pIntermediateBufferPtrsArray)->numBuffers;
+ bufferIndex++) {
+ clientListSize += ((*pIntermediateBufferPtrsArray)
+ ->pBuffers[bufferIndex]
+ .dataLenInBytes);
+ }
+ pService->minInterBuffSizeInBytes = clientListSize;
+
+ for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
+
+ /* Get pointer to the client Intermediate Buffer List
+ * (CpaBufferList) */
+ pClientCurrentIntermediateBuffer =
+ *pIntermediateBufferPtrsArray;
+
+ /* Get number of flat buffers in the buffer list */
+ numFlatBuffers = pClientCurrentIntermediateBuffer->numBuffers;
+
+ /* Get pointer to the client array of CpaFlatBuffers */
+ pClientCurrFlatBuffer =
+ pClientCurrentIntermediateBuffer->pBuffers;
+
+ /* Calculate Physical address of current private SGL */
+ bufListDescPhyAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService),
+ pClientCurrentIntermediateBuffer->pPrivateMetaData);
+ if (bufListDescPhyAddr == 0) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the metadata.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* Align SGL physical address */
+ bufListAlignedPhyAddr =
+ LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
+ ICP_DESCRIPTOR_ALIGNMENT_BYTES);
+
+ /* Set physical address of the Intermediate Buffer SGL in the
+ * SGLs array
+ */
+ *pInterBuffPtrsArray =
+ LAC_MEM_CAST_PTR_TO_UINT64(bufListAlignedPhyAddr);
+
+ /* Calculate (virtual) offset to the buffer list descriptor */
+ pBufferListDesc =
+ (icp_buffer_list_desc_t
+ *)((LAC_ARCH_UINT)pClientCurrentIntermediateBuffer
+ ->pPrivateMetaData +
+ (LAC_ARCH_UINT)(bufListAlignedPhyAddr -
+ bufListDescPhyAddr));
+
+ /* Set number of flat buffers in the physical Buffer List
+ * descriptor */
+ pBufferListDesc->numBuffers = numFlatBuffers;
+
+ /* Go past the Buffer List descriptor to the list of buffer
+ * descriptors
+ */
+ pCurrFlatBufDesc =
+ (icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
+
+ /* Loop for each flat buffer in the SGL */
+ while (0 != numFlatBuffers) {
+ /* Set length of the current flat buffer */
+ pCurrFlatBufDesc->dataLenInBytes =
+ pClientCurrFlatBuffer->dataLenInBytes;
+
+ /* Set physical address of the flat buffer */
+ pCurrFlatBufDesc->phyBuffer =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService), pClientCurrFlatBuffer->pData));
+
+ if (pCurrFlatBufDesc->phyBuffer == 0) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the flat buffer.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pCurrFlatBufDesc++;
+ pClientCurrFlatBuffer++;
+ numFlatBuffers--;
+ }
+ pIntermediateBufferPtrsArray++;
+ pInterBuffPtrsArray++;
+ }
+
+ pService->generic_service_info.isInstanceStarted = CPA_TRUE;
+
+ /* Increment dev ref counter */
+ icp_qa_dev_get(dev);
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcStopInstance(CpaInstanceHandle instanceHandle)
+{
+ CpaInstanceHandle insHandle = NULL;
+ CpaInstanceInfo2 info = { 0 };
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_compression_service_t *pService = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = instanceHandle;
+ }
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ pService = (sal_compression_service_t *)insHandle;
+
+ /* Free Intermediate Buffer Pointers Array */
+ if (pService->pInterBuffPtrsArray != NULL) {
+ LAC_OS_CAFREE(pService->pInterBuffPtrsArray);
+ pService->pInterBuffPtrsArray = 0;
+ }
+
+ pService->pInterBuffPtrsArrayPhyAddr = 0;
+
+ status = cpaDcInstanceGetInfo2(insHandle, &info);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Can not get instance info.\n");
+ return status;
+ }
+ dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
+ if (NULL == dev) {
+ QAT_UTILS_LOG("Can not find device for the instance.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pService->generic_service_info.isInstanceStarted = CPA_FALSE;
+
+ /* Decrement dev ref counter */
+ icp_qa_dev_put(dev);
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcGetNumInstances(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 = 0;
+ Cpa16U i = 0;
+
+ LAC_CHECK_NULL_PARAM(pNumInstances);
+
+ /* 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);
+ num_accel_dev = 0;
+
+ /* Get ADF to return accel_devs with dc enabled */
+ status = icp_amgr_getAllAccelDevByCapabilities(
+ ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
+ if (CPA_STATUS_SUCCESS == status) {
+ for (i = 0; i < num_accel_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
+ if (NULL != dev_addr) {
+ base_addr = dev_addr->pSalHandle;
+ if (NULL != base_addr) {
+ list_temp =
+ base_addr->compression_services;
+ while (NULL != list_temp) {
+ num++;
+ list_temp =
+ SalList_next(list_temp);
+ }
+ }
+ }
+ }
+
+ *pNumInstances = num;
+ }
+
+ free(pAdfInsts, M_QAT);
+
+ return status;
+}
+
+CpaStatus
+cpaDcGetInstances(Cpa16U numInstances, CpaInstanceHandle *dcInstances)
+{
+ 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 index = 0;
+ Cpa16U i = 0;
+
+ LAC_CHECK_NULL_PARAM(dcInstances);
+ if (0 == numInstances) {
+ QAT_UTILS_LOG("numInstances is 0.\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);
+
+ num_accel_dev = 0;
+ /* Get ADF to return accel_devs with dc enabled */
+ status = icp_amgr_getAllAccelDevByCapabilities(
+ ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ /* First check the number of instances in the system */
+ for (i = 0; i < num_accel_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
+ if (NULL != dev_addr) {
+ base_addr = dev_addr->pSalHandle;
+ if (NULL != base_addr) {
+ list_temp =
+ base_addr->compression_services;
+ while (NULL != list_temp) {
+ if (index >
+ (numInstances - 1)) {
+ break;
+ }
+
+ dcInstances[index] =
+ SalList_getObject(
+ list_temp);
+ list_temp =
+ SalList_next(list_temp);
+ index++;
+ }
+ }
+ }
+ }
+
+ if (numInstances > index) {
+ QAT_UTILS_LOG("Only %d dc instances available.\n",
+ index);
+ status = CPA_STATUS_RESOURCE;
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS == status) {
+ index = 0;
+ for (i = 0; i < num_accel_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)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) {
+ list_temp = base_addr->compression_services;
+ while (NULL != list_temp) {
+ if (index > (numInstances - 1)) {
+ break;
+ }
+
+ dcInstances[index] =
+ SalList_getObject(list_temp);
+ list_temp = SalList_next(list_temp);
+ index++;
+ }
+ }
+ }
+ }
+
+ free(pAdfInsts, M_QAT);
+
+ return status;
+}
+
+CpaStatus
+cpaDcInstanceGetInfo2(const CpaInstanceHandle instanceHandle,
+ CpaInstanceInfo2 *pInstanceInfo2)
+{
+ sal_compression_service_t *pCompressionService = NULL;
+ CpaInstanceHandle insHandle = NULL;
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char keyStr[ADF_CFG_MAX_KEY_LEN_IN_BYTES] = { 0 };
+ char valStr[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char *section = DYN_SEC;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = instanceHandle;
+ }
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+ LAC_CHECK_NULL_PARAM(pInstanceInfo2);
+
+ LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
+ pInstanceInfo2->accelerationServiceType =
+ CPA_ACC_SVC_TYPE_DATA_COMPRESSION;
+
+ snprintf((char *)pInstanceInfo2->vendorName,
+ CPA_INST_VENDOR_NAME_SIZE,
+ "%s",
+ SAL_INFO2_VENDOR_NAME);
+ pInstanceInfo2->vendorName[CPA_INST_VENDOR_NAME_SIZE - 1] = '\0';
+
+ snprintf((char *)pInstanceInfo2->swVersion,
+ CPA_INST_SW_VERSION_SIZE,
+ "Version %d.%d",
+ SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER);
+ pInstanceInfo2->swVersion[CPA_INST_SW_VERSION_SIZE - 1] = '\0';
+
+ /* Note we can safely read the contents of the compression service
+ instance
+ here because icp_amgr_getAccelDevByCapabilities() only returns devs
+ that have started */
+ pCompressionService = (sal_compression_service_t *)insHandle;
+ pInstanceInfo2->physInstId.packageId = pCompressionService->pkgID;
+ pInstanceInfo2->physInstId.acceleratorId =
+ pCompressionService->acceleratorNum;
+ pInstanceInfo2->physInstId.executionEngineId = 0;
+ pInstanceInfo2->physInstId.busAddress =
+ icp_adf_get_busAddress(pInstanceInfo2->physInstId.packageId);
+
+ /* set coreAffinity to zero before use */
+ LAC_OS_BZERO(pInstanceInfo2->coreAffinity,
+ sizeof(pInstanceInfo2->coreAffinity));
+ CPA_BITMAP_BIT_SET(pInstanceInfo2->coreAffinity,
+ pCompressionService->coreAffinity);
+
+ pInstanceInfo2->nodeAffinity = pCompressionService->nodeAffinity;
+
+ if (CPA_TRUE ==
+ pCompressionService->generic_service_info.isInstanceStarted) {
+ pInstanceInfo2->operState = CPA_OPER_STATE_UP;
+ } else {
+ pInstanceInfo2->operState = CPA_OPER_STATE_DOWN;
+ }
+
+ pInstanceInfo2->requiresPhysicallyContiguousMemory = CPA_TRUE;
+
+ if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
+ pInstanceInfo2->isPolled = CPA_TRUE;
+ } else {
+ pInstanceInfo2->isPolled = CPA_FALSE;
+ }
+
+ pInstanceInfo2->isOffloaded = CPA_TRUE;
+ /* Get the instance name and part name from the config file */
+ dev = icp_adf_getAccelDevByAccelId(pCompressionService->pkgID);
+ if (NULL == dev) {
+ QAT_UTILS_LOG("Can not find device for the instance.\n");
+ LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
+ return CPA_STATUS_FAIL;
+ }
+ snprintf((char *)pInstanceInfo2->partName,
+ CPA_INST_PART_NAME_SIZE,
+ SAL_INFO2_PART_NAME,
+ dev->deviceName);
+ pInstanceInfo2->partName[CPA_INST_PART_NAME_SIZE - 1] = '\0';
+
+ if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+ status = Sal_StringParsing(
+ "Dc",
+ pCompressionService->generic_service_info.instance,
+ "Name",
+ keyStr);
+ LAC_CHECK_STATUS(status);
+ status = icp_adf_cfgGetParamValue(dev, section, keyStr, valStr);
+ LAC_CHECK_STATUS(status);
+ strncpy((char *)pInstanceInfo2->instName,
+ valStr,
+ sizeof(pInstanceInfo2->instName) - 1);
+ pInstanceInfo2->instName[CPA_INST_NAME_SIZE - 1] = '\0';
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-truncation"
+#endif
+ snprintf((char *)pInstanceInfo2->instID,
+ CPA_INST_ID_SIZE,
+ "%s_%s",
+ section,
+ valStr);
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcQueryCapabilities(CpaInstanceHandle dcInstance,
+ CpaDcInstanceCapabilities *pInstanceCapabilities)
+{
+ CpaInstanceHandle insHandle = NULL;
+ sal_compression_service_t *pService = NULL;
+ Cpa32U capabilitiesMask = 0;
+ dc_extd_ftrs_t *pExtendedFtrs = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
+ insHandle = dcGetFirstHandle();
+ if (NULL == insHandle) {
+ QAT_UTILS_LOG("Can not get the instance.\n");
+ return CPA_STATUS_FAIL;
+ }
+ } else {
+ insHandle = dcInstance;
+ }
+
+ pService = (sal_compression_service_t *)insHandle;
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+ LAC_CHECK_NULL_PARAM(pInstanceCapabilities);
+
+ memset(pInstanceCapabilities, 0, sizeof(CpaDcInstanceCapabilities));
+
+ capabilitiesMask = pService->generic_service_info.capabilitiesMask;
+
+ /* Set compression capabilities */
+ if (capabilitiesMask & ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY) {
+ pInstanceCapabilities->integrityCrcs = CPA_TRUE;
+ }
+
+ pInstanceCapabilities->endOfLastBlock = CPA_TRUE;
+ pInstanceCapabilities->statefulDeflateCompression = CPA_FALSE;
+ pInstanceCapabilities->statefulDeflateDecompression = CPA_TRUE;
+ pInstanceCapabilities->statelessDeflateCompression = CPA_TRUE;
+ pInstanceCapabilities->statelessDeflateDecompression = CPA_TRUE;
+ pInstanceCapabilities->checksumCRC32 = CPA_TRUE;
+ pInstanceCapabilities->checksumAdler32 = CPA_TRUE;
+ pInstanceCapabilities->dynamicHuffman = CPA_TRUE;
+ pInstanceCapabilities->precompiledHuffman = CPA_FALSE;
+ pInstanceCapabilities->dynamicHuffmanBufferReq = CPA_TRUE;
+ pInstanceCapabilities->autoSelectBestHuffmanTree = CPA_TRUE;
+
+ pInstanceCapabilities->validWindowSizeMaskCompression =
+ pService->comp_device_data.windowSizeMask;
+ pInstanceCapabilities->validWindowSizeMaskDecompression =
+ pService->comp_device_data.windowSizeMask;
+ pExtendedFtrs = (dc_extd_ftrs_t *)&(
+ ((sal_service_t *)insHandle)->dcExtendedFeatures);
+ pInstanceCapabilities->batchAndPack = CPA_FALSE;
+ pInstanceCapabilities->compressAndVerify =
+ (CpaBoolean)pExtendedFtrs->is_cnv;
+ pInstanceCapabilities->compressAndVerifyStrict = CPA_TRUE;
+ pInstanceCapabilities->compressAndVerifyAndRecover =
+ (CpaBoolean)pExtendedFtrs->is_cnvnr;
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+cpaDcSetAddressTranslation(const CpaInstanceHandle instanceHandle,
+ CpaVirtualToPhysical virtual2Physical)
+{
+ sal_service_t *pService = NULL;
+ CpaInstanceHandle insHandle = NULL;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
+ insHandle = dcGetFirstHandle();
+ } else {
+ insHandle = instanceHandle;
+ }
+
+ LAC_CHECK_NULL_PARAM(insHandle);
+ SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
+ LAC_CHECK_NULL_PARAM(virtual2Physical);
+
+ pService = (sal_service_t *)insHandle;
+
+ pService->virt2PhysClient = virtual2Physical;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaDcCommon
+ * Data compression specific polling function which polls a DC instance.
+ *****************************************************************************/
+
+CpaStatus
+icp_sal_DcPollInstance(CpaInstanceHandle instanceHandle_in,
+ Cpa32U response_quota)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_compression_service_t *dc_handle = NULL;
+ sal_service_t *gen_handle = NULL;
+ icp_comms_trans_handle trans_hndTable[DC_NUM_RX_RINGS];
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ dc_handle = (sal_compression_service_t *)dcGetFirstHandle();
+ } else {
+ dc_handle = (sal_compression_service_t *)instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(dc_handle);
+ SAL_RUNNING_CHECK(dc_handle);
+
+ gen_handle = &(dc_handle->generic_service_info);
+ if (SAL_SERVICE_TYPE_COMPRESSION != gen_handle->type) {
+ QAT_UTILS_LOG("Instance handle type is incorrect.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /*
+ * From the instanceHandle we must get the trans_handle and send
+ * down to adf for polling.
+ * Populate our trans handle table with the appropriate handles.
+ */
+ trans_hndTable[0] = dc_handle->trans_handle_compression_rx;
+
+ /* Call adf to do the polling. */
+ status = icp_adf_pollInstance(trans_hndTable,
+ DC_NUM_RX_RINGS,
+ response_quota);
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaDcCommon
+ *****************************************************************************/
+CpaStatus
+cpaDcInstanceSetNotificationCb(
+ const CpaInstanceHandle instanceHandle,
+ const CpaDcInstanceNotificationCbFunc pInstanceNotificationCb,
+ void *pCallbackTag)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_service_t *gen_handle = instanceHandle;
+
+ LAC_CHECK_NULL_PARAM(gen_handle);
+ gen_handle->notification_cb = pInstanceNotificationCb;
+ gen_handle->cb_tag = pCallbackTag;
+ return status;
+}
+
+CpaInstanceHandle
+dcGetFirstHandle(void)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ static icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES] = { 0 };
+ CpaInstanceHandle dcInst = NULL;
+ icp_accel_dev_t *dev_addr = NULL;
+ sal_t *base_addr = NULL;
+ sal_list_t *list_temp = NULL;
+ Cpa16U i, num_dc = 0;
+
+ /* Only need 1 dev with compression enabled - so check all devices */
+ status = icp_amgr_getAllAccelDevByCapabilities(
+ ICP_ACCEL_CAPABILITIES_COMPRESSION, adfInsts, &num_dc);
+ if ((0 == num_dc) || (CPA_STATUS_SUCCESS != status)) {
+ QAT_UTILS_LOG(
+ "No compression devices enabled in the system.\n");
+ return dcInst;
+ }
+
+ for (i = 0; i < num_dc; i++) {
+ dev_addr = (icp_accel_dev_t *)adfInsts[i];
+ if (NULL != dev_addr) {
+ base_addr = dev_addr->pSalHandle;
+ if (NULL != base_addr) {
+ list_temp = base_addr->compression_services;
+ if (NULL != list_temp) {
+ dcInst = SalList_getObject(list_temp);
+ break;
+ }
+ }
+ }
+ }
+ return dcInst;
+}
diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_create_services.c b/sys/dev/qat/qat_api/common/ctrl/sal_create_services.c
new file mode 100644
index 000000000000..d51cc1bcace0
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/ctrl/sal_create_services.c
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_create_services.c
+ *
+ * @defgroup SalCtrl Service Access Layer Controller
+ *
+ * @ingroup SalCtrl
+ *
+ * @description
+ * This file contains the main function to create a specific service.
+ *
+ *****************************************************************************/
+
+#include "cpa.h"
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "qat_utils.h"
+#include "lac_list.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+
+#include "icp_qat_fw_la.h"
+#include "lac_sym_qat.h"
+#include "sal_types_compression.h"
+#include "lac_sal_types_crypto.h"
+
+#include "icp_adf_init.h"
+
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+
+CpaStatus
+SalCtrl_ServiceCreate(sal_service_type_t serviceType,
+ Cpa32U instance,
+ sal_service_t **ppInst)
+{
+ sal_crypto_service_t *pCrypto_service = NULL;
+ sal_compression_service_t *pCompression_service = NULL;
+
+ switch ((sal_service_type_t)serviceType) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ case SAL_SERVICE_TYPE_CRYPTO: {
+ pCrypto_service =
+ malloc(sizeof(sal_crypto_service_t), M_QAT, M_WAITOK);
+
+ /* Zero memory */
+ memset(pCrypto_service, 0, sizeof(sal_crypto_service_t));
+
+ pCrypto_service->generic_service_info.type =
+ (sal_service_type_t)serviceType;
+ pCrypto_service->generic_service_info.state =
+ SAL_SERVICE_STATE_UNINITIALIZED;
+ pCrypto_service->generic_service_info.instance = instance;
+
+ pCrypto_service->generic_service_info.init = SalCtrl_CryptoInit;
+ pCrypto_service->generic_service_info.start =
+ SalCtrl_CryptoStart;
+ pCrypto_service->generic_service_info.stop = SalCtrl_CryptoStop;
+ pCrypto_service->generic_service_info.shutdown =
+ SalCtrl_CryptoShutdown;
+
+ *(ppInst) = &(pCrypto_service->generic_service_info);
+
+ return CPA_STATUS_SUCCESS;
+ }
+ case SAL_SERVICE_TYPE_COMPRESSION: {
+ pCompression_service =
+ malloc(sizeof(sal_compression_service_t), M_QAT, M_WAITOK);
+
+ /* Zero memory */
+ memset(pCompression_service,
+ 0,
+ sizeof(sal_compression_service_t));
+
+ pCompression_service->generic_service_info.type =
+ (sal_service_type_t)serviceType;
+ pCompression_service->generic_service_info.state =
+ SAL_SERVICE_STATE_UNINITIALIZED;
+ pCompression_service->generic_service_info.instance = instance;
+
+ pCompression_service->generic_service_info.init =
+ SalCtrl_CompressionInit;
+ pCompression_service->generic_service_info.start =
+ SalCtrl_CompressionStart;
+ pCompression_service->generic_service_info.stop =
+ SalCtrl_CompressionStop;
+ pCompression_service->generic_service_info.shutdown =
+ SalCtrl_CompressionShutdown;
+
+ *(ppInst) = &(pCompression_service->generic_service_info);
+ return CPA_STATUS_SUCCESS;
+ }
+
+ default: {
+ QAT_UTILS_LOG("Not a valid service type\n");
+ (*ppInst) = NULL;
+ return CPA_STATUS_FAIL;
+ }
+ }
+}
diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_crypto.c b/sys/dev/qat/qat_api/common/ctrl/sal_crypto.c
new file mode 100644
index 000000000000..c97d36103c2b
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/ctrl/sal_crypto.c
@@ -0,0 +1,1837 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file sal_crypto.c Instance handling functions for crypto
+ *
+ * @ingroup SalCtrl
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+/* QAT-API includes */
+#include "cpa.h"
+#include "cpa_types.h"
+#include "cpa_cy_common.h"
+#include "cpa_cy_im.h"
+#include "cpa_cy_key.h"
+#include "cpa_cy_sym.h"
+
+#include "qat_utils.h"
+
+/* ADF includes */
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_cfg.h"
+#include "icp_adf_accel_mgr.h"
+#include "icp_adf_poll.h"
+#include "icp_adf_debug.h"
+
+/* SAL includes */
+#include "lac_log.h"
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "sal_statistics.h"
+#include "lac_common.h"
+#include "lac_list.h"
+#include "lac_hooks.h"
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym.h"
+#include "lac_sym_key.h"
+#include "lac_sym_hash.h"
+#include "lac_sym_cb.h"
+#include "lac_sym_stats.h"
+#include "lac_sal_types_crypto.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "sal_string_parse.h"
+#include "sal_service_state.h"
+#include "icp_sal_poll.h"
+#include "lac_sync.h"
+#include "lac_sym_qat.h"
+#include "icp_sal_versions.h"
+#include "icp_sal_user.h"
+
+#define TH_CY_RX_0 0
+#define TH_CY_RX_1 1
+#define MAX_CY_RX_RINGS 2
+
+#define DOUBLE_INCR 2
+
+#define TH_SINGLE_RX 0
+#define NUM_CRYPTO_SYM_RX_RINGS 1
+#define NUM_CRYPTO_ASYM_RX_RINGS 1
+#define NUM_CRYPTO_NRBG_RX_RINGS 1
+
+static CpaInstanceHandle
+Lac_CryptoGetFirstHandle(void)
+{
+ CpaInstanceHandle instHandle;
+ instHandle = Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO);
+ if (!instHandle) {
+ instHandle = Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ if (!instHandle) {
+ instHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_ASYM);
+ }
+ }
+ return instHandle;
+}
+
+
+/* Function to release the sym handles. */
+static CpaStatus
+SalCtrl_SymReleaseTransHandle(sal_service_t *service)
+{
+
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaStatus ret_status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+
+ if (NULL != pCryptoService->trans_handle_sym_tx) {
+ status = icp_adf_transReleaseHandle(
+ pCryptoService->trans_handle_sym_tx);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+ if (NULL != pCryptoService->trans_handle_sym_rx) {
+ status = icp_adf_transReleaseHandle(
+ pCryptoService->trans_handle_sym_rx);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ return ret_status;
+}
+
+
+/*
+ * @ingroup sal_crypto
+ * Frees resources (memory and transhandles) if allocated
+ *
+ * @param[in] pCryptoService Pointer to sym service instance
+ * @retval SUCCESS if transhandles released
+ * successfully.
+*/
+static CpaStatus
+SalCtrl_SymFreeResources(sal_crypto_service_t *pCryptoService)
+{
+
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* Free memory pools if not NULL */
+ Lac_MemPoolDestroy(pCryptoService->lac_sym_cookie_pool);
+
+ /* Free misc memory if allocated */
+ /* Frees memory allocated for Hmac precomputes */
+ LacSymHash_HmacPrecompShutdown(pCryptoService);
+ /* Free memory allocated for key labels
+ Also clears key stats */
+ LacSymKey_Shutdown(pCryptoService);
+ /* Free hash lookup table if allocated */
+ if (NULL != pCryptoService->pLacHashLookupDefs) {
+ LAC_OS_FREE(pCryptoService->pLacHashLookupDefs);
+ }
+
+ /* Free statistics */
+ LacSym_StatsFree(pCryptoService);
+
+ /* Free transport handles */
+ status = SalCtrl_SymReleaseTransHandle((sal_service_t *)pCryptoService);
+ return status;
+}
+
+
+/**
+ ***********************************************************************
+ * @ingroup SalCtrl
+ * This macro verifies that the status is _SUCCESS
+ * If status is not _SUCCESS then Sym Instance resources are
+ * freed before the function returns the error
+ *
+ * @param[in] status status we are checking
+ *
+ * @return void status is ok (CPA_STATUS_SUCCESS)
+ * @return status The value in the status parameter is an error one
+ *
+ ****************************************************************************/
+#define LAC_CHECK_STATUS_SYM_INIT(status) \
+ do { \
+ if (CPA_STATUS_SUCCESS != status) { \
+ SalCtrl_SymFreeResources(pCryptoService); \
+ return status; \
+ } \
+ } while (0)
+
+
+/* Function that creates the Sym Handles. */
+static CpaStatus
+SalCtrl_SymCreateTransHandle(icp_accel_dev_t *device,
+ sal_service_t *service,
+ Cpa32U numSymRequests,
+ char *section)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ icp_resp_deliv_method rx_resp_type = ICP_RESP_TYPE_IRQ;
+ Cpa32U msgSize = 0;
+
+ if (SAL_RESP_POLL_CFG_FILE == pCryptoService->isPolled) {
+ rx_resp_type = ICP_RESP_TYPE_POLL;
+ }
+
+ if (CPA_FALSE == pCryptoService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+ /* Parse Sym ring details */
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "RingSymTx",
+ temp_string);
+
+ /* Need to free resources in case not _SUCCESS from here */
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ msgSize = LAC_QAT_SYM_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES;
+ status =
+ icp_adf_transCreateHandle(device,
+ ICP_TRANS_TYPE_ETR,
+ section,
+ pCryptoService->acceleratorNum,
+ pCryptoService->bankNum,
+ temp_string,
+ lac_getRingType(SAL_RING_TYPE_A_SYM_HI),
+ NULL,
+ ICP_RESP_TYPE_NONE,
+ numSymRequests,
+ msgSize,
+ (icp_comms_trans_handle *)&(
+ pCryptoService->trans_handle_sym_tx));
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "RingSymRx",
+ temp_string);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ msgSize = LAC_QAT_SYM_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES;
+ status = icp_adf_transCreateHandle(
+ device,
+ ICP_TRANS_TYPE_ETR,
+ section,
+ pCryptoService->acceleratorNum,
+ pCryptoService->bankNum,
+ temp_string,
+ lac_getRingType(SAL_RING_TYPE_NONE),
+ (icp_trans_callback)LacSymQat_SymRespHandler,
+ rx_resp_type,
+ numSymRequests,
+ msgSize,
+ (icp_comms_trans_handle *)&(pCryptoService->trans_handle_sym_rx));
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ return status;
+}
+
+static int
+SalCtrl_CryptoDebug(void *private_data, char *data, int size, int offset)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U len = 0;
+ sal_crypto_service_t *pCryptoService =
+ (sal_crypto_service_t *)private_data;
+
+ switch (offset) {
+ case SAL_STATS_SYM: {
+ CpaCySymStats64 symStats = { 0 };
+ if (CPA_TRUE !=
+ pCryptoService->generic_service_info.stats
+ ->bSymStatsEnabled) {
+ break;
+ }
+ status = cpaCySymQueryStats64(pCryptoService, &symStats);
+ if (status != CPA_STATUS_SUCCESS) {
+ LAC_LOG_ERROR("cpaCySymQueryStats64 returned error\n");
+ return 0;
+ }
+
+ /* Engine Info */
+ len += snprintf(
+ data + len,
+ size - len,
+ SEPARATOR BORDER
+ " Statistics for Instance %24s |\n" BORDER
+ " Symmetric Stats " BORDER
+ "\n" SEPARATOR,
+ pCryptoService->debug_file->name);
+
+ /* Session Info */
+ len += snprintf(
+ data + len,
+ size - len,
+ BORDER " Sessions Initialized: %16llu " BORDER
+ "\n" BORDER
+ " Sessions Removed: %16llu " BORDER
+ "\n" BORDER
+ " Session Errors: %16llu " BORDER
+ "\n" SEPARATOR,
+ (long long unsigned int)symStats.numSessionsInitialized,
+ (long long unsigned int)symStats.numSessionsRemoved,
+ (long long unsigned int)symStats.numSessionErrors);
+
+ /* Session info */
+ len += snprintf(
+ data + len,
+ size - len,
+ BORDER " Symmetric Requests: %16llu " BORDER
+ "\n" BORDER
+ " Symmetric Request Errors: %16llu " BORDER
+ "\n" BORDER
+ " Symmetric Completed: %16llu " BORDER
+ "\n" BORDER
+ " Symmetric Completed Errors: %16llu " BORDER
+ "\n" BORDER
+ " Symmetric Verify Failures: %16llu " BORDER
+ "\n",
+ (long long unsigned int)symStats.numSymOpRequests,
+ (long long unsigned int)symStats.numSymOpRequestErrors,
+ (long long unsigned int)symStats.numSymOpCompleted,
+ (long long unsigned int)symStats.numSymOpCompletedErrors,
+ (long long unsigned int)symStats.numSymOpVerifyFailures);
+ break;
+ }
+ default: {
+ len += snprintf(data + len, size - len, SEPARATOR);
+ return 0;
+ }
+ }
+ return ++offset;
+}
+
+
+static CpaStatus
+SalCtrl_SymInit(icp_accel_dev_t *device, sal_service_t *service)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U numSymConcurrentReq = 0;
+ char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ char *section = DYN_SEC;
+
+ /*Instance may not in the DYN section*/
+ if (CPA_FALSE == pCryptoService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+
+ /* Register callbacks for the symmetric services
+ * (Hash, Cipher, Algorithm-Chaining) (returns void)*/
+ LacSymCb_CallbacksRegister();
+
+ /* Get num concurrent requests from config file */
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "NumConcurrentSymRequests",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ temp_string);
+ return status;
+ }
+
+ numSymConcurrentReq =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+ if (CPA_STATUS_FAIL == validateConcurrRequest(numSymConcurrentReq)) {
+ LAC_LOG_ERROR("Invalid NumConcurrentSymRequests, valid "
+ "values {64, 128, 256, ... 32768, 65536}");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* ADF does not allow us to completely fill the ring for batch requests
+ */
+ pCryptoService->maxNumSymReqBatch =
+ (numSymConcurrentReq - SAL_BATCH_SUBMIT_FREE_SPACE);
+
+ /* Create transport handles */
+ status = SalCtrl_SymCreateTransHandle(device,
+ service,
+ numSymConcurrentReq,
+ section);
+ LAC_CHECK_STATUS(status);
+
+ /* Allocates memory pools */
+
+ /* Create and initialise symmetric cookie memory pool */
+ pCryptoService->lac_sym_cookie_pool = LAC_MEM_POOL_INIT_POOL_ID;
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "SymPool",
+ temp_string);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+ /* Note we need twice (i.e. <<1) the number of sym cookies to
+ support sym ring pairs (and some, for partials) */
+ status =
+ Lac_MemPoolCreate(&pCryptoService->lac_sym_cookie_pool,
+ temp_string,
+ ((numSymConcurrentReq + numSymConcurrentReq + 1)
+ << 1),
+ sizeof(lac_sym_cookie_t),
+ LAC_64BYTE_ALIGNMENT,
+ CPA_FALSE,
+ pCryptoService->nodeAffinity);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+ /* For all sym cookies fill out the physical address of data that
+ will be set to QAT */
+ Lac_MemPoolInitSymCookiesPhyAddr(pCryptoService->lac_sym_cookie_pool);
+
+ /* Clear stats */
+ /* Clears Key stats and allocate memory of SSL and TLS labels
+ These labels are initialised to standard values */
+ status = LacSymKey_Init(pCryptoService);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ /* Initialises the hash lookup table*/
+ status = LacSymQat_Init(pCryptoService);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ /* Fills out content descriptor for precomputes and registers the
+ hash precompute callback */
+ status = LacSymHash_HmacPrecompInit(pCryptoService);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ /* Init the Sym stats */
+ status = LacSym_StatsInit(pCryptoService);
+ LAC_CHECK_STATUS_SYM_INIT(status);
+
+ return status;
+}
+
+static void
+SalCtrl_DebugShutdown(icp_accel_dev_t *device, sal_service_t *service)
+{
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ sal_statistics_collection_t *pStatsCollection =
+ (sal_statistics_collection_t *)device->pQatStats;
+
+ if (CPA_TRUE == pStatsCollection->bStatsEnabled) {
+ /* Clean stats */
+ if (NULL != pCryptoService->debug_file) {
+ icp_adf_debugRemoveFile(pCryptoService->debug_file);
+ LAC_OS_FREE(pCryptoService->debug_file->name);
+ LAC_OS_FREE(pCryptoService->debug_file);
+ pCryptoService->debug_file = NULL;
+ }
+ }
+ pCryptoService->generic_service_info.stats = NULL;
+}
+
+static CpaStatus
+SalCtrl_DebugInit(icp_accel_dev_t *device, sal_service_t *service)
+{
+ char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char *instance_name = NULL;
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ sal_statistics_collection_t *pStatsCollection =
+ (sal_statistics_collection_t *)device->pQatStats;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char *section = DYN_SEC;
+
+ /*Instance may not in the DYN section*/
+ if (CPA_FALSE == pCryptoService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+ if (CPA_TRUE == pStatsCollection->bStatsEnabled) {
+ /* Get instance name for stats */
+ instance_name = LAC_OS_MALLOC(ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ if (NULL == instance_name) {
+ return CPA_STATUS_RESOURCE;
+ }
+
+ status = Sal_StringParsing(
+ "Cy",
+ pCryptoService->generic_service_info.instance,
+ "Name",
+ temp_string);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_OS_FREE(instance_name);
+ return status;
+ }
+ status = icp_adf_cfgGetParamValue(device,
+ section,
+ temp_string,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG(
+ "Failed to get %s from configuration file\n",
+ temp_string);
+ LAC_OS_FREE(instance_name);
+ return status;
+ }
+ snprintf(instance_name,
+ ADF_CFG_MAX_VAL_LEN_IN_BYTES,
+ "%s",
+ adfGetParam);
+
+ pCryptoService->debug_file =
+ LAC_OS_MALLOC(sizeof(debug_file_info_t));
+ if (NULL == pCryptoService->debug_file) {
+ LAC_OS_FREE(instance_name);
+ return CPA_STATUS_RESOURCE;
+ }
+
+ memset(pCryptoService->debug_file,
+ 0,
+ sizeof(debug_file_info_t));
+ pCryptoService->debug_file->name = instance_name;
+ pCryptoService->debug_file->seq_read = SalCtrl_CryptoDebug;
+ pCryptoService->debug_file->private_data = pCryptoService;
+ pCryptoService->debug_file->parent =
+ pCryptoService->generic_service_info.debug_parent_dir;
+
+ status =
+ icp_adf_debugAddFile(device, pCryptoService->debug_file);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_OS_FREE(instance_name);
+ LAC_OS_FREE(pCryptoService->debug_file);
+ return status;
+ }
+ }
+ pCryptoService->generic_service_info.stats = pStatsCollection;
+
+ return status;
+}
+
+static CpaStatus
+SalCtr_InstInit(icp_accel_dev_t *device, sal_service_t *service)
+{
+ char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char *section = DYN_SEC;
+
+ /*Instance may not in the DYN section*/
+ if (CPA_FALSE == pCryptoService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+
+ /* Get Config Info: Accel Num, bank Num, packageID,
+ coreAffinity, nodeAffinity and response mode */
+
+ pCryptoService->acceleratorNum = 0;
+
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "BankNumber",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ temp_string);
+ return status;
+ }
+ pCryptoService->bankNum =
+ (Cpa16U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "IsPolled",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ status =
+ icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ temp_string);
+ return status;
+ }
+ pCryptoService->isPolled =
+ (Cpa8U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ /* Kernel instances do not support epoll mode */
+ if (SAL_RESP_EPOLL_CFG_FILE == pCryptoService->isPolled) {
+ QAT_UTILS_LOG(
+ "IsPolled %u is not supported for kernel instance %s",
+ pCryptoService->isPolled,
+ temp_string);
+ return CPA_STATUS_FAIL;
+ }
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ADF_DEV_PKG_ID,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ ADF_DEV_PKG_ID);
+ return status;
+ }
+ pCryptoService->pkgID =
+ (Cpa16U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ADF_DEV_NODE_ID,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ ADF_DEV_NODE_ID);
+ return status;
+ }
+ pCryptoService->nodeAffinity =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+ /* In case of interrupt instance, use the bank affinity set by adf_ctl
+ * Otherwise, use the instance affinity for backwards compatibility */
+ if (SAL_RESP_POLL_CFG_FILE != pCryptoService->isPolled) {
+ /* Next need to read the [AcceleratorX] section of the config
+ * file */
+ status = Sal_StringParsing("Accelerator",
+ pCryptoService->acceleratorNum,
+ "",
+ temp_string2);
+ LAC_CHECK_STATUS(status);
+ status = Sal_StringParsing("Bank",
+ pCryptoService->bankNum,
+ "CoreAffinity",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ } else {
+ strncpy(temp_string2, section, (strlen(section) + 1));
+ status = Sal_StringParsing(
+ "Cy",
+ pCryptoService->generic_service_info.instance,
+ "CoreAffinity",
+ temp_string);
+ LAC_CHECK_STATUS(status);
+ }
+
+ status = icp_adf_cfgGetParamValue(device,
+ temp_string2,
+ temp_string,
+ adfGetParam);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration file\n",
+ temp_string);
+ return status;
+ }
+ pCryptoService->coreAffinity =
+ (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
+
+ /*No Execution Engine in DH895xcc, so make sure it is zero*/
+ pCryptoService->executionEngine = 0;
+
+ return status;
+}
+
+/* This function:
+ * 1. Creates sym and asym transport handles
+ * 2. Allocates memory pools required by sym and asym services
+.* 3. Clears the sym and asym stats counters
+ * 4. In case service asym or sym is enabled then this function
+ * only allocates resources for these services. i.e if the
+ * service asym is enabled then only asym transport handles
+ * are created and vice versa.
+ */
+CpaStatus
+SalCtrl_CryptoInit(icp_accel_dev_t *device, sal_service_t *service)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ sal_service_type_t svc_type = service->type;
+
+ SAL_SERVICE_GOOD_FOR_INIT(pCryptoService);
+ pCryptoService->generic_service_info.state =
+ SAL_SERVICE_STATE_INITIALIZING;
+
+ /* Set up the instance parameters such as bank number,
+ * coreAffinity, pkgId and node affinity etc
+ */
+ status = SalCtr_InstInit(device, service);
+ LAC_CHECK_STATUS(status);
+ /* Create debug directory for service */
+ status = SalCtrl_DebugInit(device, service);
+ LAC_CHECK_STATUS(status);
+
+ switch (svc_type) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ status = SalCtrl_SymInit(device, service);
+ if (CPA_STATUS_SUCCESS != status) {
+ SalCtrl_DebugShutdown(device, service);
+ return status;
+ }
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO:
+ status = SalCtrl_SymInit(device, service);
+ if (CPA_STATUS_SUCCESS != status) {
+ SalCtrl_DebugShutdown(device, service);
+ return status;
+ }
+ break;
+ default:
+ LAC_LOG_ERROR("Invalid service type\n");
+ status = CPA_STATUS_FAIL;
+ break;
+ }
+
+ pCryptoService->generic_service_info.state =
+ SAL_SERVICE_STATE_INITIALIZED;
+
+ return status;
+}
+
+CpaStatus
+SalCtrl_CryptoStart(icp_accel_dev_t *device, sal_service_t *service)
+{
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ if (pCryptoService->generic_service_info.state !=
+ SAL_SERVICE_STATE_INITIALIZED) {
+ LAC_LOG_ERROR("Not in the correct state to call start\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pCryptoService->generic_service_info.state = SAL_SERVICE_STATE_RUNNING;
+ return status;
+}
+
+CpaStatus
+SalCtrl_CryptoStop(icp_accel_dev_t *device, sal_service_t *service)
+{
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+
+ if (SAL_SERVICE_STATE_RUNNING !=
+ pCryptoService->generic_service_info.state) {
+ LAC_LOG_ERROR("Not in the correct state to call stop");
+ }
+
+ pCryptoService->generic_service_info.state =
+ SAL_SERVICE_STATE_SHUTTING_DOWN;
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+SalCtrl_CryptoShutdown(icp_accel_dev_t *device, sal_service_t *service)
+{
+ sal_crypto_service_t *pCryptoService = (sal_crypto_service_t *)service;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_service_type_t svc_type = service->type;
+
+ if ((SAL_SERVICE_STATE_INITIALIZED !=
+ pCryptoService->generic_service_info.state) &&
+ (SAL_SERVICE_STATE_SHUTTING_DOWN !=
+ pCryptoService->generic_service_info.state)) {
+ LAC_LOG_ERROR("Not in the correct state to call shutdown \n");
+ return CPA_STATUS_FAIL;
+ }
+
+
+ /* Free memory and transhandles */
+ switch (svc_type) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ if (SalCtrl_SymFreeResources(pCryptoService)) {
+ status = CPA_STATUS_FAIL;
+ }
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO:
+ if (SalCtrl_SymFreeResources(pCryptoService)) {
+ status = CPA_STATUS_FAIL;
+ }
+ break;
+ default:
+ LAC_LOG_ERROR("Invalid service type\n");
+ status = CPA_STATUS_FAIL;
+ break;
+ }
+
+ SalCtrl_DebugShutdown(device, service);
+
+ pCryptoService->generic_service_info.state = SAL_SERVICE_STATE_SHUTDOWN;
+
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyGetStatusText(const CpaInstanceHandle instanceHandle,
+ CpaStatus errStatus,
+ Cpa8S *pStatusText)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+
+ LAC_CHECK_NULL_PARAM(pStatusText);
+
+ switch (errStatus) {
+ case CPA_STATUS_SUCCESS:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_SUCCESS);
+ break;
+ case CPA_STATUS_FAIL:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FAIL);
+ break;
+ case CPA_STATUS_RETRY:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RETRY);
+ break;
+ case CPA_STATUS_RESOURCE:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RESOURCE);
+ break;
+ case CPA_STATUS_INVALID_PARAM:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_INVALID_PARAM);
+ break;
+ case CPA_STATUS_FATAL:
+ LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FATAL);
+ break;
+ default:
+ status = CPA_STATUS_INVALID_PARAM;
+ break;
+ }
+ return status;
+}
+
+void
+SalCtrl_CyQueryCapabilities(sal_service_t *pGenericService,
+ CpaCyCapabilitiesInfo *pCapInfo)
+{
+ memset(pCapInfo, 0, sizeof(CpaCyCapabilitiesInfo));
+
+ if (SAL_SERVICE_TYPE_CRYPTO == pGenericService->type ||
+ SAL_SERVICE_TYPE_CRYPTO_SYM == pGenericService->type) {
+ pCapInfo->symSupported = CPA_TRUE;
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN) {
+ pCapInfo->extAlgchainSupported = CPA_TRUE;
+ }
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_HKDF) {
+ pCapInfo->hkdfSupported = CPA_TRUE;
+ }
+ }
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_ECEDMONT) {
+ pCapInfo->ecEdMontSupported = CPA_TRUE;
+ }
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_RANDOM_NUMBER) {
+ pCapInfo->nrbgSupported = CPA_TRUE;
+ }
+
+ pCapInfo->drbgSupported = CPA_FALSE;
+ pCapInfo->randSupported = CPA_FALSE;
+ pCapInfo->nrbgSupported = CPA_FALSE;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyStartInstance(CpaInstanceHandle instanceHandle_in)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+/* Structure initializer is supported by C99, but it is
+ * not supported by some former Intel compilers.
+ */
+ CpaInstanceInfo2 info = { 0 };
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO);
+ if (!instanceHandle) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ }
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+
+ pService = (sal_crypto_service_t *)instanceHandle;
+
+ status = cpaCyInstanceGetInfo2(instanceHandle, &info);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR("Can not get instance info\n");
+ return status;
+ }
+ dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
+ if (NULL == dev) {
+ LAC_LOG_ERROR("Can not find device for the instance\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pService->generic_service_info.isInstanceStarted = CPA_TRUE;
+
+ /* Increment dev ref counter */
+ icp_qa_dev_get(dev);
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyStopInstance(CpaInstanceHandle instanceHandle_in)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+/* Structure initializer is supported by C99, but it is
+ * not supported by some former Intel compilers.
+ */
+ CpaInstanceInfo2 info = { 0 };
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *pService = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_CryptoGetFirstHandle();
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+
+ status = cpaCyInstanceGetInfo2(instanceHandle, &info);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR("Can not get instance info\n");
+ return status;
+ }
+ dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
+ if (NULL == dev) {
+ LAC_LOG_ERROR("Can not find device for the instance\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ pService = (sal_crypto_service_t *)instanceHandle;
+
+ pService->generic_service_info.isInstanceStarted = CPA_FALSE;
+
+ /* Decrement dev ref counter */
+ icp_qa_dev_put(dev);
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyInstanceSetNotificationCb(
+ const CpaInstanceHandle instanceHandle,
+ const CpaCyInstanceNotificationCbFunc pInstanceNotificationCb,
+ void *pCallbackTag)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_service_t *gen_handle = instanceHandle;
+
+
+ LAC_CHECK_NULL_PARAM(gen_handle);
+ gen_handle->notification_cb = pInstanceNotificationCb;
+ gen_handle->cb_tag = pCallbackTag;
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyGetNumInstances(Cpa16U *pNumInstances)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle cyInstanceHandle;
+ CpaInstanceInfo2 info;
+ 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;
+
+ LAC_CHECK_NULL_PARAM(pNumInstances);
+
+ /* 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);
+ num_accel_dev = 0;
+ /* Get ADF to return all accel_devs that support either
+ * symmetric or asymmetric crypto */
+ status = icp_amgr_getAllAccelDevByCapabilities(
+ (ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC),
+ pAdfInsts,
+ &num_accel_dev);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR("No support for crypto\n");
+ *pNumInstances = 0;
+ free(pAdfInsts, M_QAT);
+ return status;
+ }
+
+ for (i = 0; i < num_accel_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
+ if (NULL == dev_addr || NULL == dev_addr->pSalHandle) {
+ continue;
+ }
+
+ base_addr = dev_addr->pSalHandle;
+ list_temp = base_addr->crypto_services;
+ while (NULL != list_temp) {
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ if (CPA_STATUS_SUCCESS == status &&
+ CPA_TRUE == info.isPolled) {
+ num_inst++;
+ }
+ list_temp = SalList_next(list_temp);
+ }
+ list_temp = base_addr->asym_services;
+ while (NULL != list_temp) {
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ if (CPA_STATUS_SUCCESS == status &&
+ CPA_TRUE == info.isPolled) {
+ num_inst++;
+ }
+ list_temp = SalList_next(list_temp);
+ }
+ list_temp = base_addr->sym_services;
+ while (NULL != list_temp) {
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ if (CPA_STATUS_SUCCESS == status &&
+ CPA_TRUE == info.isPolled) {
+ num_inst++;
+ }
+ list_temp = SalList_next(list_temp);
+ }
+ }
+ *pNumInstances = num_inst;
+ free(pAdfInsts, M_QAT);
+
+
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyGetInstances(Cpa16U numInstances, CpaInstanceHandle *pCyInstances)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaInstanceHandle cyInstanceHandle;
+ CpaInstanceInfo2 info;
+ 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;
+
+
+ LAC_CHECK_NULL_PARAM(pCyInstances);
+ if (0 == numInstances) {
+ LAC_INVALID_PARAM_LOG("NumInstances is 0");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Get the number of crypto instances */
+ status = cpaCyGetNumInstances(&num_allocated_instances);
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ if (numInstances > num_allocated_instances) {
+ QAT_UTILS_LOG("Only %d crypto 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);
+
+ num_accel_dev = 0;
+ /* Get ADF to return all accel_devs that support either
+ * symmetric or asymmetric crypto */
+ status = icp_amgr_getAllAccelDevByCapabilities(
+ (ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC |
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC),
+ pAdfInsts,
+ &num_accel_dev);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_LOG_ERROR("No support for crypto\n");
+ free(pAdfInsts, M_QAT);
+ return status;
+ }
+
+ for (i = 0; i < num_accel_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)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;
+ }
+ list_temp = base_addr->crypto_services;
+ while (NULL != list_temp) {
+ if (index > (numInstances - 1)) {
+ break;
+ }
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ list_temp = SalList_next(list_temp);
+ if (CPA_STATUS_SUCCESS != status ||
+ CPA_TRUE != info.isPolled) {
+ continue;
+ }
+ pCyInstances[index] = cyInstanceHandle;
+ index++;
+ }
+ list_temp = base_addr->asym_services;
+ while (NULL != list_temp) {
+ if (index > (numInstances - 1)) {
+ break;
+ }
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ list_temp = SalList_next(list_temp);
+ if (CPA_STATUS_SUCCESS != status ||
+ CPA_TRUE != info.isPolled) {
+ continue;
+ }
+ pCyInstances[index] = cyInstanceHandle;
+ index++;
+ }
+ list_temp = base_addr->sym_services;
+ while (NULL != list_temp) {
+ if (index > (numInstances - 1)) {
+ break;
+ }
+ cyInstanceHandle = SalList_getObject(list_temp);
+ status = cpaCyInstanceGetInfo2(cyInstanceHandle, &info);
+ list_temp = SalList_next(list_temp);
+ if (CPA_STATUS_SUCCESS != status ||
+ CPA_TRUE != info.isPolled) {
+ continue;
+ }
+ pCyInstances[index] = cyInstanceHandle;
+ index++;
+ }
+ }
+ free(pAdfInsts, M_QAT);
+
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyInstanceGetInfo(const CpaInstanceHandle instanceHandle_in,
+ struct _CpaInstanceInfo *pInstanceInfo)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+ sal_crypto_service_t *pCryptoService = NULL;
+ sal_service_t *pGenericService = NULL;
+
+ Cpa8U name[CPA_INST_NAME_SIZE] =
+ "Intel(R) DH89XXCC instance number: %02x, type: Crypto";
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_CryptoGetFirstHandle();
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+ LAC_CHECK_NULL_PARAM(pInstanceInfo);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ pCryptoService = (sal_crypto_service_t *)instanceHandle;
+
+ pInstanceInfo->type = CPA_INSTANCE_TYPE_CRYPTO;
+
+ /* According to cpa.h instance state is initialized and ready for use
+ * or shutdown. Therefore need to map our running state to initialised
+ * or shutdown */
+ if (SAL_SERVICE_STATE_RUNNING ==
+ pCryptoService->generic_service_info.state) {
+ pInstanceInfo->state = CPA_INSTANCE_STATE_INITIALISED;
+ } else {
+ pInstanceInfo->state = CPA_INSTANCE_STATE_SHUTDOWN;
+ }
+
+ pGenericService = (sal_service_t *)instanceHandle;
+ snprintf((char *)pInstanceInfo->name,
+ CPA_INST_NAME_SIZE,
+ (char *)name,
+ pGenericService->instance);
+
+ pInstanceInfo->name[CPA_INST_NAME_SIZE - 1] = '\0';
+
+ snprintf((char *)pInstanceInfo->version,
+ CPA_INSTANCE_MAX_NAME_SIZE_IN_BYTES,
+ "%d.%d",
+ CPA_CY_API_VERSION_NUM_MAJOR,
+ CPA_CY_API_VERSION_NUM_MINOR);
+
+ pInstanceInfo->version[CPA_INSTANCE_MAX_VERSION_SIZE_IN_BYTES - 1] =
+ '\0';
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCyInstanceGetInfo2(const CpaInstanceHandle instanceHandle_in,
+ CpaInstanceInfo2 *pInstanceInfo2)
+{
+ CpaInstanceHandle instanceHandle = NULL;
+ sal_crypto_service_t *pCryptoService = NULL;
+ icp_accel_dev_t *dev = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char keyStr[ADF_CFG_MAX_KEY_LEN_IN_BYTES] = { 0 };
+ char valStr[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char *section = DYN_SEC;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_CryptoGetFirstHandle();
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+ LAC_CHECK_NULL_PARAM(pInstanceInfo2);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
+ pInstanceInfo2->accelerationServiceType = CPA_ACC_SVC_TYPE_CRYPTO;
+ snprintf((char *)pInstanceInfo2->vendorName,
+ CPA_INST_VENDOR_NAME_SIZE,
+ "%s",
+ SAL_INFO2_VENDOR_NAME);
+ pInstanceInfo2->vendorName[CPA_INST_VENDOR_NAME_SIZE - 1] = '\0';
+
+ snprintf((char *)pInstanceInfo2->swVersion,
+ CPA_INST_SW_VERSION_SIZE,
+ "Version %d.%d",
+ SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER);
+ pInstanceInfo2->swVersion[CPA_INST_SW_VERSION_SIZE - 1] = '\0';
+
+ /* Note we can safely read the contents of the crypto service instance
+ here because icp_amgr_getAllAccelDevByCapabilities() only returns
+ devs
+ that have started */
+ pCryptoService = (sal_crypto_service_t *)instanceHandle;
+ pInstanceInfo2->physInstId.packageId = pCryptoService->pkgID;
+ pInstanceInfo2->physInstId.acceleratorId =
+ pCryptoService->acceleratorNum;
+ pInstanceInfo2->physInstId.executionEngineId =
+ pCryptoService->executionEngine;
+ pInstanceInfo2->physInstId.busAddress =
+ icp_adf_get_busAddress(pInstanceInfo2->physInstId.packageId);
+
+ /*set coreAffinity to zero before use */
+ LAC_OS_BZERO(pInstanceInfo2->coreAffinity,
+ sizeof(pInstanceInfo2->coreAffinity));
+ CPA_BITMAP_BIT_SET(pInstanceInfo2->coreAffinity,
+ pCryptoService->coreAffinity);
+ pInstanceInfo2->nodeAffinity = pCryptoService->nodeAffinity;
+
+ if (SAL_SERVICE_STATE_RUNNING ==
+ pCryptoService->generic_service_info.state) {
+ pInstanceInfo2->operState = CPA_OPER_STATE_UP;
+ } else {
+ pInstanceInfo2->operState = CPA_OPER_STATE_DOWN;
+ }
+
+ pInstanceInfo2->requiresPhysicallyContiguousMemory = CPA_TRUE;
+ if (SAL_RESP_POLL_CFG_FILE == pCryptoService->isPolled) {
+ pInstanceInfo2->isPolled = CPA_TRUE;
+ } else {
+ pInstanceInfo2->isPolled = CPA_FALSE;
+ }
+ pInstanceInfo2->isOffloaded = CPA_TRUE;
+
+ /* Get the instance name and part name*/
+ dev = icp_adf_getAccelDevByAccelId(pCryptoService->pkgID);
+ if (NULL == dev) {
+ LAC_LOG_ERROR("Can not find device for the instance\n");
+ LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
+ return CPA_STATUS_FAIL;
+ }
+ snprintf((char *)pInstanceInfo2->partName,
+ CPA_INST_PART_NAME_SIZE,
+ SAL_INFO2_PART_NAME,
+ dev->deviceName);
+ pInstanceInfo2->partName[CPA_INST_PART_NAME_SIZE - 1] = '\0';
+
+ status =
+ Sal_StringParsing("Cy",
+ pCryptoService->generic_service_info.instance,
+ "Name",
+ keyStr);
+ LAC_CHECK_STATUS(status);
+
+ if (CPA_FALSE == pCryptoService->generic_service_info.is_dyn) {
+ section = icpGetProcessName();
+ }
+
+ status = icp_adf_cfgGetParamValue(dev, section, keyStr, valStr);
+ LAC_CHECK_STATUS(status);
+
+ snprintf((char *)pInstanceInfo2->instName,
+ CPA_INST_NAME_SIZE,
+ "%s",
+ valStr);
+ snprintf((char *)pInstanceInfo2->instID,
+ CPA_INST_ID_SIZE,
+ "%s_%s",
+ section,
+ valStr);
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+
+CpaStatus
+cpaCyQueryCapabilities(const CpaInstanceHandle instanceHandle_in,
+ CpaCyCapabilitiesInfo *pCapInfo)
+{
+ /* Verify Instance exists */
+ CpaInstanceHandle instanceHandle = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_CryptoGetFirstHandle();
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pCapInfo);
+
+ SalCtrl_CyQueryCapabilities((sal_service_t *)instanceHandle, pCapInfo);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCySym
+ *****************************************************************************/
+CpaStatus
+cpaCySymQueryCapabilities(const CpaInstanceHandle instanceHandle_in,
+ CpaCySymCapabilitiesInfo *pCapInfo)
+{
+ sal_crypto_service_t *pCryptoService = NULL;
+ sal_service_t *pGenericService = NULL;
+ CpaInstanceHandle instanceHandle = NULL;
+
+ /* Verify Instance exists */
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO);
+ if (!instanceHandle) {
+ instanceHandle =
+ Lac_GetFirstHandle(SAL_SERVICE_TYPE_CRYPTO_SYM);
+ }
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(pCapInfo);
+
+ pCryptoService = (sal_crypto_service_t *)instanceHandle;
+ pGenericService = &(pCryptoService->generic_service_info);
+
+ memset(pCapInfo, '\0', sizeof(CpaCySymCapabilitiesInfo));
+ /* An asym crypto instance does not support sym service */
+ if (SAL_SERVICE_TYPE_CRYPTO_ASYM == pGenericService->type) {
+ return CPA_STATUS_SUCCESS;
+ }
+
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_NULL);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_ARC4);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_ECB);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_CBC);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_CTR);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_CCM);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_GCM);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_DES_ECB);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_DES_CBC);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_3DES_ECB);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_3DES_CBC);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_3DES_CTR);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_KASUMI_F8);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_SNOW3G_UEA2);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_F8);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_AES_XTS);
+
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_MD5);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA1);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA224);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA256);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA384);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA512);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_XCBC);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_CCM);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_GCM);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_KASUMI_F9);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SNOW3G_UIA2);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_CMAC);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_GMAC);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_AES_CBC_MAC);
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ZUC) {
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers,
+ CPA_CY_SYM_CIPHER_ZUC_EEA3);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_ZUC_EIA3);
+ }
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CHACHA_POLY) {
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_POLY);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers, CPA_CY_SYM_CIPHER_CHACHA);
+ }
+
+ if (pGenericService->capabilitiesMask & ICP_ACCEL_CAPABILITIES_SM3) {
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SM3);
+ }
+
+ pCapInfo->partialPacketSupported = CPA_TRUE;
+
+ if (pGenericService->capabilitiesMask & ICP_ACCEL_CAPABILITIES_SHA3) {
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA3_256);
+ pCapInfo->partialPacketSupported = CPA_FALSE;
+ }
+
+ if (pGenericService->capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_SHA3_EXT) {
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA3_224);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA3_256);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA3_384);
+ CPA_BITMAP_BIT_SET(pCapInfo->hashes, CPA_CY_SYM_HASH_SHA3_512);
+ pCapInfo->partialPacketSupported = CPA_FALSE;
+ }
+
+ if (pGenericService->capabilitiesMask & ICP_ACCEL_CAPABILITIES_SM4) {
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers,
+ CPA_CY_SYM_CIPHER_SM4_ECB);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers,
+ CPA_CY_SYM_CIPHER_SM4_CBC);
+ CPA_BITMAP_BIT_SET(pCapInfo->ciphers,
+ CPA_CY_SYM_CIPHER_SM4_CTR);
+ pCapInfo->partialPacketSupported = CPA_FALSE;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ *****************************************************************************/
+CpaStatus
+cpaCySetAddressTranslation(const CpaInstanceHandle instanceHandle_in,
+ CpaVirtualToPhysical virtual2physical)
+{
+
+ CpaInstanceHandle instanceHandle = NULL;
+ sal_service_t *pService = NULL;
+
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ instanceHandle = Lac_CryptoGetFirstHandle();
+ } else {
+ instanceHandle = instanceHandle_in;
+ }
+
+ LAC_CHECK_NULL_PARAM(instanceHandle);
+ SAL_CHECK_INSTANCE_TYPE(instanceHandle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ LAC_CHECK_NULL_PARAM(virtual2physical);
+
+ pService = (sal_service_t *)instanceHandle;
+
+ pService->virt2PhysClient = virtual2physical;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ * Crypto specific polling function which polls a crypto instance.
+ *****************************************************************************/
+CpaStatus
+icp_sal_CyPollInstance(CpaInstanceHandle instanceHandle_in,
+ Cpa32U response_quota)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *crypto_handle = NULL;
+ sal_service_t *gen_handle = NULL;
+ icp_comms_trans_handle trans_hndTable[MAX_CY_RX_RINGS] = { 0 };
+ Cpa32U num_rx_rings = 0;
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ crypto_handle =
+ (sal_crypto_service_t *)Lac_CryptoGetFirstHandle();
+ } else {
+ crypto_handle = (sal_crypto_service_t *)instanceHandle_in;
+ }
+ LAC_CHECK_NULL_PARAM(crypto_handle);
+ SAL_RUNNING_CHECK(crypto_handle);
+ SAL_CHECK_INSTANCE_TYPE(crypto_handle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_ASYM |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+
+ gen_handle = &(crypto_handle->generic_service_info);
+
+ /*
+ * From the instanceHandle we must get the trans_handle and send
+ * down to adf for polling.
+ * Populate our trans handle table with the appropriate handles.
+ */
+
+ switch (gen_handle->type) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ trans_hndTable[TH_CY_RX_0] =
+ crypto_handle->trans_handle_asym_rx;
+ num_rx_rings = 1;
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ trans_hndTable[TH_CY_RX_0] = crypto_handle->trans_handle_sym_rx;
+ num_rx_rings = 1;
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO:
+ trans_hndTable[TH_CY_RX_0] = crypto_handle->trans_handle_sym_rx;
+ trans_hndTable[TH_CY_RX_1] =
+ crypto_handle->trans_handle_asym_rx;
+ num_rx_rings = MAX_CY_RX_RINGS;
+ break;
+ default:
+ break;
+ }
+
+ /* Call adf to do the polling. */
+ status =
+ icp_adf_pollInstance(trans_hndTable, num_rx_rings, response_quota);
+
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ * Crypto specific polling function which polls sym crypto ring.
+ *****************************************************************************/
+CpaStatus
+icp_sal_CyPollSymRing(CpaInstanceHandle instanceHandle_in,
+ Cpa32U response_quota)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_crypto_service_t *crypto_handle = NULL;
+ icp_comms_trans_handle trans_hndTable[NUM_CRYPTO_SYM_RX_RINGS] = { 0 };
+
+ if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
+ crypto_handle = (sal_crypto_service_t *)Lac_GetFirstHandle(
+ SAL_SERVICE_TYPE_CRYPTO_SYM);
+ } else {
+ crypto_handle = (sal_crypto_service_t *)instanceHandle_in;
+ }
+ LAC_CHECK_NULL_PARAM(crypto_handle);
+ SAL_CHECK_INSTANCE_TYPE(crypto_handle,
+ (SAL_SERVICE_TYPE_CRYPTO |
+ SAL_SERVICE_TYPE_CRYPTO_SYM));
+ SAL_RUNNING_CHECK(crypto_handle);
+
+ /*
+ * From the instanceHandle we must get the trans_handle and send
+ * down to adf for polling.
+ * Populate our trans handle table with the appropriate handles.
+ */
+ trans_hndTable[TH_SINGLE_RX] = crypto_handle->trans_handle_sym_rx;
+ /* Call adf to do the polling. */
+ status = icp_adf_pollInstance(trans_hndTable,
+ NUM_CRYPTO_SYM_RX_RINGS,
+ response_quota);
+ return status;
+}
+
+
+/**
+ ******************************************************************************
+ * @ingroup cpaCyCommon
+ * Crypto specific polling function which polls an nrbg crypto ring.
+ *****************************************************************************/
+CpaStatus
+icp_sal_CyPollNRBGRing(CpaInstanceHandle instanceHandle_in,
+ Cpa32U response_quota)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* Returns the handle to the first asym crypto instance */
+static CpaInstanceHandle
+Lac_GetFirstAsymHandle(icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES],
+ Cpa16U num_dev)
+{
+ icp_accel_dev_t *dev_addr = NULL;
+ sal_t *base_addr = NULL;
+ sal_list_t *list_temp = NULL;
+ CpaInstanceHandle cyInst = NULL;
+ Cpa16U i = 0;
+
+ for (i = 0; i < num_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)adfInsts[i];
+ base_addr = dev_addr->pSalHandle;
+ if ((NULL != base_addr) && (NULL != base_addr->asym_services)) {
+ list_temp = base_addr->asym_services;
+ cyInst = SalList_getObject(list_temp);
+ break;
+ }
+ }
+
+ return cyInst;
+}
+
+/* Returns the handle to the first sym crypto instance */
+static CpaInstanceHandle
+Lac_GetFirstSymHandle(icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES],
+ Cpa16U num_dev)
+{
+ icp_accel_dev_t *dev_addr = NULL;
+ sal_t *base_addr = NULL;
+ sal_list_t *list_temp = NULL;
+ CpaInstanceHandle cyInst = NULL;
+ Cpa16U i = 0;
+
+ for (i = 0; i < num_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)adfInsts[i];
+ base_addr = dev_addr->pSalHandle;
+ if ((NULL != base_addr) && (NULL != base_addr->sym_services)) {
+ list_temp = base_addr->sym_services;
+ cyInst = SalList_getObject(list_temp);
+ break;
+ }
+ }
+
+ return cyInst;
+}
+
+/* Returns the handle to the first crypto instance
+ * Note that the crypto instance in this case supports
+ * both asym and sym services */
+static CpaInstanceHandle
+Lac_GetFirstCyHandle(icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES], Cpa16U num_dev)
+{
+ icp_accel_dev_t *dev_addr = NULL;
+ sal_t *base_addr = NULL;
+ sal_list_t *list_temp = NULL;
+ CpaInstanceHandle cyInst = NULL;
+ Cpa16U i = 0;
+
+ for (i = 0; i < num_dev; i++) {
+ dev_addr = (icp_accel_dev_t *)adfInsts[i];
+ base_addr = dev_addr->pSalHandle;
+ if ((NULL != base_addr) &&
+ (NULL != base_addr->crypto_services)) {
+ list_temp = base_addr->crypto_services;
+ cyInst = SalList_getObject(list_temp);
+ break;
+ }
+ }
+ return cyInst;
+}
+
+CpaInstanceHandle
+Lac_GetFirstHandle(sal_service_type_t svc_type)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ static icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES] = { 0 };
+ CpaInstanceHandle cyInst = NULL;
+ Cpa16U num_cy_dev = 0;
+ Cpa32U capabilities = 0;
+
+ switch (svc_type) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO:
+ capabilities = ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC;
+ capabilities |= ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC;
+ break;
+ default:
+ LAC_LOG_ERROR("Invalid service type\n");
+ return NULL;
+ break;
+ }
+ /* Only need 1 dev with crypto enabled - so check all devices*/
+ status = icp_amgr_getAllAccelDevByEachCapability(capabilities,
+ adfInsts,
+ &num_cy_dev);
+ if ((0 == num_cy_dev) || (CPA_STATUS_SUCCESS != status)) {
+ LAC_LOG_ERROR("No crypto devices enabled in the system\n");
+ return NULL;
+ }
+
+ switch (svc_type) {
+ case SAL_SERVICE_TYPE_CRYPTO_ASYM:
+ /* Try to find an asym only instance first */
+ cyInst = Lac_GetFirstAsymHandle(adfInsts, num_cy_dev);
+ /* Try to find a cy instance since it also supports asym */
+ if (NULL == cyInst) {
+ cyInst = Lac_GetFirstCyHandle(adfInsts, num_cy_dev);
+ }
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO_SYM:
+ /* Try to find a sym only instance first */
+ cyInst = Lac_GetFirstSymHandle(adfInsts, num_cy_dev);
+ /* Try to find a cy instance since it also supports sym */
+ if (NULL == cyInst) {
+ cyInst = Lac_GetFirstCyHandle(adfInsts, num_cy_dev);
+ }
+ break;
+ case SAL_SERVICE_TYPE_CRYPTO:
+ /* Try to find a cy instance */
+ cyInst = Lac_GetFirstCyHandle(adfInsts, num_cy_dev);
+ break;
+ default:
+ break;
+ }
+ if (NULL == cyInst) {
+ LAC_LOG_ERROR("No remaining crypto instances available\n");
+ }
+ return cyInst;
+}
+
+CpaStatus
+icp_sal_NrbgGetInflightRequests(CpaInstanceHandle instanceHandle_in,
+ Cpa32U *maxInflightRequests,
+ Cpa32U *numInflightRequests)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+icp_sal_SymGetInflightRequests(CpaInstanceHandle instanceHandle,
+ Cpa32U *maxInflightRequests,
+ Cpa32U *numInflightRequests)
+{
+ sal_crypto_service_t *crypto_handle = NULL;
+
+ crypto_handle = (sal_crypto_service_t *)instanceHandle;
+
+ LAC_CHECK_NULL_PARAM(crypto_handle);
+ LAC_CHECK_NULL_PARAM(maxInflightRequests);
+ LAC_CHECK_NULL_PARAM(numInflightRequests);
+ SAL_RUNNING_CHECK(crypto_handle);
+
+ return icp_adf_getInflightRequests(crypto_handle->trans_handle_sym_tx,
+ maxInflightRequests,
+ numInflightRequests);
+}
+
+
+CpaStatus
+icp_sal_dp_SymGetInflightRequests(CpaInstanceHandle instanceHandle,
+ Cpa32U *maxInflightRequests,
+ Cpa32U *numInflightRequests)
+{
+ sal_crypto_service_t *crypto_handle = NULL;
+
+ crypto_handle = (sal_crypto_service_t *)instanceHandle;
+
+ return icp_adf_dp_getInflightRequests(
+ crypto_handle->trans_handle_sym_tx,
+ maxInflightRequests,
+ numInflightRequests);
+}
+
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
new file mode 100644
index 000000000000..4a41340dfabb
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/ctrl/sal_ctrl_services.c
@@ -0,0 +1,1344 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_ctrl_services.c
+ *
+ * @ingroup SalCtrl
+ *
+ * @description
+ * This file contains the core of the service controller implementation.
+ *
+ *****************************************************************************/
+
+/* QAT-API includes */
+#include "cpa.h"
+#include "cpa_cy_key.h"
+#include "cpa_cy_ln.h"
+#include "cpa_cy_dh.h"
+#include "cpa_cy_dsa.h"
+#include "cpa_cy_rsa.h"
+#include "cpa_cy_ec.h"
+#include "cpa_cy_prime.h"
+#include "cpa_cy_sym.h"
+#include "cpa_dc.h"
+
+/* QAT utils includes */
+#include "qat_utils.h"
+
+/* ADF includes */
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_cfg.h"
+#include "icp_adf_init.h"
+#include "icp_adf_accel_mgr.h"
+#include "icp_adf_debug.h"
+
+/* FW includes */
+#include "icp_qat_fw_la.h"
+
+/* SAL includes */
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "lac_list.h"
+#include "lac_hooks.h"
+#include "sal_string_parse.h"
+#include "lac_common.h"
+#include "lac_sal_types.h"
+#include "lac_sal.h"
+#include "lac_sal_ctrl.h"
+#include "icp_sal_versions.h"
+
+#define MAX_SUBSYSTEM_RETRY 64
+
+static char *subsystem_name = "SAL";
+/**< Name used by ADF to identify this component. */
+static char *cy_dir_name = "cy";
+static char *asym_dir_name = "asym";
+static char *sym_dir_name = "sym";
+static char *dc_dir_name = "dc";
+/**< Stats dir names. */
+static char *ver_file_name = "version";
+
+static subservice_registation_handle_t sal_service_reg_handle;
+/**< Data structure used by ADF to keep a reference to this component. */
+
+/*
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to parse the results from ADF
+ * in response to ServiceEnabled query.The results are
+ * semi-colon separated. Internally, the bitmask represented
+ * by the enabled_service is used to track which features are enabled.
+ *
+ * @context
+ * This functions is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device pointer to icp_accel_dev_t structure
+ * @param[in] pEnabledServices pointer to memory where enabled services will
+ * be written.
+ * @retval Status
+ */
+CpaStatus
+SalCtrl_GetEnabledServices(icp_accel_dev_t *device, Cpa32U *pEnabledServices)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ char *token = NULL;
+ char *running = NULL;
+
+ *pEnabledServices = 0;
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ "ServicesEnabled",
+ param_value);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ running = param_value;
+
+ token = strsep(&running, ";");
+
+ while (NULL != token) {
+ do {
+ if (strncmp(token, "asym", strlen("asym")) ==
+ 0) {
+ *pEnabledServices |=
+ SAL_SERVICE_TYPE_CRYPTO_ASYM;
+ break;
+ }
+ if (strncmp(token, "sym", strlen("sym")) == 0) {
+ *pEnabledServices |=
+ SAL_SERVICE_TYPE_CRYPTO_SYM;
+ break;
+ }
+ if (strncmp(token, "cy", strlen("cy")) == 0) {
+ *pEnabledServices |=
+ SAL_SERVICE_TYPE_CRYPTO;
+ break;
+ }
+ if (strncmp(token, "dc", strlen("dc")) == 0) {
+ *pEnabledServices |=
+ SAL_SERVICE_TYPE_COMPRESSION;
+ break;
+ }
+
+ QAT_UTILS_LOG(
+ "Error parsing enabled services from ADF.\n");
+ return CPA_STATUS_FAIL;
+
+ } while (0);
+ token = strsep(&running, ";");
+ }
+ } else {
+ QAT_UTILS_LOG("Failed to get enabled services from ADF.\n");
+ }
+ return status;
+}
+
+/*
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check whether a service is enabled
+ *
+ * @context
+ * This functions is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] enabled_services It is the bitmask for the enabled services
+ * param[in] service It is the service we want to check for
+ */
+CpaBoolean
+SalCtrl_IsServiceEnabled(Cpa32U enabled_services, sal_service_type_t service)
+{
+ return (CpaBoolean)((enabled_services & (Cpa32U)(service)) != 0);
+}
+
+/*
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check whether enabled services has associated
+ * hardware capability support
+ *
+ * @context
+ * This functions is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] device A pointer to an icp_accel_dev_t
+ * param[in] enabled_services It is the bitmask for the enabled services
+ */
+
+CpaStatus
+SalCtrl_GetSupportedServices(icp_accel_dev_t *device, Cpa32U enabled_services)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U capabilitiesMask = 0;
+
+ status = icp_amgr_getAccelDevCapabilities(device, &capabilitiesMask);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC) ||
+ !(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) {
+ QAT_UTILS_LOG(
+ "Device does not support Crypto service\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) {
+ QAT_UTILS_LOG(
+ "Device does not support Asym service\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC)) {
+ QAT_UTILS_LOG(
+ "Device does not support Sym service\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_COMPRESSION)) {
+ QAT_UTILS_LOG(
+ "Device does not support Compression service.\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ }
+
+ return status;
+}
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check if a service is supported
+ * on the device. The key difference between this and
+ * SalCtrl_GetSupportedServices() is that the latter treats it as
+ * an error if the service is unsupported.
+ *
+ * @context
+ * This can be called anywhere.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] device
+ * param[in] service service or services to check
+ *
+ *************************************************************************/
+CpaBoolean
+SalCtrl_IsServiceSupported(icp_accel_dev_t *device,
+ sal_service_type_t service_to_check)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U capabilitiesMask = 0;
+ CpaBoolean service_supported = CPA_TRUE;
+
+ if (!(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO)) &&
+ !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM)) &&
+ !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) &&
+ !(SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_COMPRESSION))) {
+ QAT_UTILS_LOG("Invalid service type\n");
+ service_supported = CPA_FALSE;
+ }
+
+ status = icp_amgr_getAccelDevCapabilities(device, &capabilitiesMask);
+
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Can not get device capabilities.\n");
+ return CPA_FALSE;
+ }
+
+ if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC) ||
+ !(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) {
+ QAT_UTILS_LOG(
+ "Device does not support Crypto service\n");
+ service_supported = CPA_FALSE;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)) {
+ QAT_UTILS_LOG("Device does not support Asym service\n");
+ service_supported = CPA_FALSE;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) {
+ if (!(capabilitiesMask &
+ ICP_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC)) {
+ QAT_UTILS_LOG("Device does not support Sym service\n");
+ service_supported = CPA_FALSE;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled((Cpa32U)service_to_check,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ if (!(capabilitiesMask & ICP_ACCEL_CAPABILITIES_COMPRESSION)) {
+ QAT_UTILS_LOG(
+ "Device does not support Compression service.\n");
+ service_supported = CPA_FALSE;
+ }
+ }
+
+ return service_supported;
+}
+
+/*
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to retrieve how many instances are
+ * to be configured for process specific service.
+ *
+ * @context
+ * This functions is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device A pointer to an icp_accel_dev_t
+ * @param[in] key Represents the parameter's name we want to query
+ * @param[out] pCount Pointer to memory where num instances will be stored
+ * @retval status returned status from ADF or _FAIL if number of instances
+ * is out of range for the device.
+ */
+static CpaStatus
+SalCtrl_GetInstanceCount(icp_accel_dev_t *device, char *key, Cpa32U *pCount)
+{
+ CpaStatus status = CPA_STATUS_FAIL;
+ char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ icpGetProcessName(),
+ key,
+ param_value);
+ if (CPA_STATUS_SUCCESS == status) {
+ *pCount =
+ (Cpa32U)(Sal_Strtoul(param_value, NULL, SAL_CFG_BASE_DEC));
+ if (*pCount > SAL_MAX_NUM_INSTANCES_PER_DEV) {
+ QAT_UTILS_LOG("Number of instances is out of range.\n");
+ status = CPA_STATUS_FAIL;
+ }
+ }
+ return status;
+}
+
+/**************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the shutdown function on all the
+ * service instances.
+ * It also frees all service instance memory allocated at Init.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventShutdown
+ * function.
+ *
+ * @assumptions
+ * params[in] should not be NULL
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] services A pointer to the container of services
+ * @param[in] dbg_dir A pointer to the debug directory
+ * @param[in] svc_type The type of the service instance
+ *
+ ****************************************************************************/
+static CpaStatus
+SalCtrl_ServiceShutdown(icp_accel_dev_t *device,
+ sal_list_t **services,
+ debug_dir_info_t **debug_dir,
+ sal_service_type_t svc_type)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_list_t *dyn_service = NULL;
+ sal_service_t *inst = NULL;
+
+ /* Call Shutdown function for each service instance */
+ SAL_FOR_EACH(*services, sal_service_t, device, shutdown, status);
+
+ if (*debug_dir) {
+ icp_adf_debugRemoveDir(*debug_dir);
+ LAC_OS_FREE(*debug_dir);
+ *debug_dir = NULL;
+ }
+
+ if (!icp_adf_is_dev_in_reset(device)) {
+ dyn_service = *services;
+ while (dyn_service) {
+ inst = (sal_service_t *)SalList_getObject(dyn_service);
+ if (CPA_TRUE == inst->is_dyn) {
+ icp_adf_putDynInstance(device,
+ (adf_service_type_t)
+ svc_type,
+ inst->instance);
+ }
+ dyn_service = SalList_next(dyn_service);
+ }
+ /* Free Sal services controller memory */
+ SalList_free(services);
+ } else {
+ sal_list_t *curr_element = NULL;
+ sal_service_t *service = NULL;
+ curr_element = *services;
+ while (NULL != curr_element) {
+ service =
+ (sal_service_t *)SalList_getObject(curr_element);
+ service->state = SAL_SERVICE_STATE_RESTARTING;
+ curr_element = SalList_next(curr_element);
+ }
+ }
+
+ return status;
+}
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to initialise the service instances.
+ * It allocates memory for service instances and invokes the
+ * Init function on them.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] services A pointer to the container of services
+ * @param[in] dbg_dir A pointer to the debug directory
+ * @param[in] dbg_dir_name Name of the debug directory
+ * @param[in] tail_list SAL's list of services
+ * @param[in] instance_count Number of instances
+ * @param[in] svc_type The type of the service instance
+ *
+ *************************************************************************/
+static CpaStatus
+SalCtrl_ServiceInit(icp_accel_dev_t *device,
+ sal_list_t **services,
+ debug_dir_info_t **dbg_dir,
+ char *dbg_dir_name,
+ sal_list_t *tail_list,
+ Cpa32U instance_count,
+ sal_service_type_t svc_type)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_service_t *pInst = NULL;
+ Cpa32U i = 0;
+ debug_dir_info_t *debug_dir = NULL;
+
+ debug_dir = LAC_OS_MALLOC(sizeof(debug_dir_info_t));
+ if (NULL == debug_dir) {
+ QAT_UTILS_LOG("Failed to allocate memory for debug dir.\n");
+ return CPA_STATUS_RESOURCE;
+ }
+ debug_dir->name = dbg_dir_name;
+ debug_dir->parent = NULL;
+ status = icp_adf_debugAddDir(device, debug_dir);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to add debug dir.\n");
+ LAC_OS_FREE(debug_dir);
+ debug_dir = NULL;
+ return status;
+ }
+
+ if (!icp_adf_is_dev_in_reset(device)) {
+ for (i = 0; i < instance_count; i++) {
+ status = SalCtrl_ServiceCreate(svc_type, i, &pInst);
+ if (CPA_STATUS_SUCCESS != status) {
+ break;
+ }
+ pInst->debug_parent_dir = debug_dir;
+ pInst->capabilitiesMask = device->accelCapabilitiesMask;
+ status = SalList_add(services, &tail_list, pInst);
+ if (CPA_STATUS_SUCCESS != status) {
+ free(pInst, M_QAT);
+ }
+ }
+ } else {
+ sal_list_t *curr_element = *services;
+ sal_service_t *service = NULL;
+ while (NULL != curr_element) {
+ service =
+ (sal_service_t *)SalList_getObject(curr_element);
+ service->debug_parent_dir = debug_dir;
+
+ if (CPA_TRUE == service->isInstanceStarted) {
+ icp_qa_dev_get(device);
+ }
+
+ curr_element = SalList_next(curr_element);
+ }
+ }
+
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to allocate all instances.\n");
+ icp_adf_debugRemoveDir(debug_dir);
+ LAC_OS_FREE(debug_dir);
+ debug_dir = NULL;
+ SalList_free(services);
+ return status;
+ }
+
+ /* Call init function for each service instance */
+ SAL_FOR_EACH(*services, sal_service_t, device, init, status);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to initialise all service instances.\n");
+ /* shutdown all instances initialised before error */
+ SAL_FOR_EACH_STATE(*services,
+ sal_service_t,
+ device,
+ shutdown,
+ SAL_SERVICE_STATE_INITIALIZED);
+ icp_adf_debugRemoveDir(debug_dir);
+ LAC_OS_FREE(debug_dir);
+ debug_dir = NULL;
+ SalList_free(services);
+ return status;
+ }
+ /* initialize the debug directory for relevant service */
+ *dbg_dir = debug_dir;
+
+ return status;
+}
+
+/**************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the start function on all the service instances.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStart function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] services A pointer to the container of services
+ *
+ **************************************************************************/
+static CpaStatus
+SalCtrl_ServiceStart(icp_accel_dev_t *device, sal_list_t *services)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* Call Start function for each service instance */
+ SAL_FOR_EACH(services, sal_service_t, device, start, status);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to start all instances.\n");
+ /* stop all instances started before error */
+ SAL_FOR_EACH_STATE(services,
+ sal_service_t,
+ device,
+ stop,
+ SAL_SERVICE_STATE_RUNNING);
+ return status;
+ }
+
+ if (icp_adf_is_dev_in_reset(device)) {
+ 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_RESTARTED);
+ }
+ curr_element = SalList_next(curr_element);
+ }
+ }
+
+ return status;
+}
+
+/****************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the stop function on all the
+ * service instances.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStop function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] services A pointer to the container of services
+ *
+ *************************************************************************/
+static CpaStatus
+SalCtrl_ServiceStop(icp_accel_dev_t *device, sal_list_t *services)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /* Calling restarting functions */
+ if (icp_adf_is_dev_in_reset(device)) {
+ 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_RESTARTING);
+ }
+ curr_element = SalList_next(curr_element);
+ }
+ }
+
+ /* Call Stop function for each service instance */
+ SAL_FOR_EACH(services, sal_service_t, device, stop, status);
+
+ return status;
+}
+
+/*
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to print hardware and software versions in proc
+ * filesystem entry via ADF Debug interface
+ *
+ * @context
+ * This functions is called from proc filesystem interface
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] private_data A pointer to a private data passed to the
+ * function while adding a debug file.
+ * @param[out] data Pointer to a buffer where version information
+ * needs to be printed to.
+ * @param[in] size Size of a buffer pointed by data.
+ * @param[in] offset Offset in a debug file
+ *
+ * @retval 0 This function always returns 0
+ */
+static int
+SalCtrl_VersionDebug(void *private_data, char *data, int size, int offset)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U len = 0;
+ icp_accel_dev_t *device = (icp_accel_dev_t *)private_data;
+ char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+
+ len += snprintf(
+ data + len,
+ size - len,
+ SEPARATOR BORDER
+ " Hardware and Software versions for device %d " BORDER
+ "\n" SEPARATOR,
+ device->accelId);
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_HW_REV_ID_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ len += snprintf(data + len,
+ size - len,
+ " Hardware Version: %s %s \n",
+ param_value,
+ get_sku_info(device->sku));
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_UOF_VER_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ len += snprintf(data + len,
+ size - len,
+ " Firmware Version: %s \n",
+ param_value);
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_MMP_VER_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ len += snprintf(data + len,
+ size - len,
+ " MMP Version: %s \n",
+ param_value);
+ len += snprintf(data + len,
+ size - len,
+ " Driver Version: %d.%d.%d \n",
+ SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER);
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_LO_COMPATIBLE_DRV_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ len += snprintf(data + len,
+ size - len,
+ " Lowest Compatible Driver: %s \n",
+ param_value);
+
+ len += snprintf(data + len,
+ size - len,
+ " QuickAssist API CY Version: %d.%d \n",
+ CPA_CY_API_VERSION_NUM_MAJOR,
+ CPA_CY_API_VERSION_NUM_MINOR);
+ len += snprintf(data + len,
+ size - len,
+ " QuickAssist API DC Version: %d.%d \n",
+ CPA_DC_API_VERSION_NUM_MAJOR,
+ CPA_DC_API_VERSION_NUM_MINOR);
+
+ len += snprintf(data + len, size - len, SEPARATOR);
+ return 0;
+}
+
+/**************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the shutdown function on all the service
+ * instances. It also frees all service instance memory
+ * allocated at Init.
+ *
+ * @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 Services enabled by user
+ *
+ ****************************************************************************/
+static CpaStatus
+SalCtrl_ServiceEventShutdown(icp_accel_dev_t *device, Cpa32U enabled_services)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaStatus ret_status = CPA_STATUS_SUCCESS;
+ sal_t *service_container = (sal_t *)device->pSalHandle;
+
+ if (NULL == service_container) {
+ QAT_UTILS_LOG("Private data is NULL\n");
+ return CPA_STATUS_FATAL;
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status =
+ SalCtrl_ServiceShutdown(device,
+ &service_container->crypto_services,
+ &service_container->cy_dir,
+ SAL_SERVICE_TYPE_CRYPTO);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM)) {
+ status =
+ SalCtrl_ServiceShutdown(device,
+ &service_container->asym_services,
+ &service_container->asym_dir,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) {
+ status =
+ SalCtrl_ServiceShutdown(device,
+ &service_container->sym_services,
+ &service_container->sym_dir,
+ SAL_SERVICE_TYPE_CRYPTO_SYM);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ status = SalCtrl_ServiceShutdown(
+ device,
+ &service_container->compression_services,
+ &service_container->dc_dir,
+ SAL_SERVICE_TYPE_COMPRESSION);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (service_container->ver_file) {
+ icp_adf_debugRemoveFile(service_container->ver_file);
+ LAC_OS_FREE(service_container->ver_file);
+ service_container->ver_file = NULL;
+ }
+
+ if (!icp_adf_is_dev_in_reset(device)) {
+ /* Free container also */
+ free(service_container, M_QAT);
+ device->pSalHandle = NULL;
+ }
+
+ return ret_status;
+}
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to initialize the service instances.
+ * It first checks (via ADF query) which services are enabled in the
+ * system and the number of each services.
+ * It then invokes the init function on them which creates the
+ * instances and allocates memory for them.
+ *
+ * @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 Services enabled by user
+ *
+ *************************************************************************/
+static CpaStatus
+SalCtrl_ServiceEventInit(icp_accel_dev_t *device, Cpa32U enabled_services)
+{
+ sal_t *service_container = NULL;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_list_t *tail_list = NULL;
+ Cpa32U instance_count = 0;
+
+ status = SalCtrl_GetSupportedServices(device, enabled_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get supported services.\n");
+ return status;
+ }
+
+ if (!icp_adf_is_dev_in_reset(device)) {
+ service_container = malloc(sizeof(sal_t), M_QAT, M_WAITOK);
+ device->pSalHandle = service_container;
+ service_container->asym_services = NULL;
+ service_container->sym_services = NULL;
+ service_container->crypto_services = NULL;
+ service_container->compression_services = NULL;
+ } else {
+ service_container = device->pSalHandle;
+ }
+ service_container->asym_dir = NULL;
+ service_container->sym_dir = NULL;
+ service_container->cy_dir = NULL;
+ service_container->dc_dir = NULL;
+ service_container->ver_file = NULL;
+
+ service_container->ver_file = LAC_OS_MALLOC(sizeof(debug_file_info_t));
+ if (NULL == service_container->ver_file) {
+ free(service_container, M_QAT);
+ return CPA_STATUS_RESOURCE;
+ }
+
+ memset(service_container->ver_file, 0, sizeof(debug_file_info_t));
+ service_container->ver_file->name = ver_file_name;
+ service_container->ver_file->seq_read = SalCtrl_VersionDebug;
+ service_container->ver_file->private_data = device;
+ service_container->ver_file->parent = NULL;
+
+ status = icp_adf_debugAddFile(device, service_container->ver_file);
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_OS_FREE(service_container->ver_file);
+ free(service_container, M_QAT);
+ return status;
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM)) {
+ status = SalCtrl_GetInstanceCount(device,
+ "NumberCyInstances",
+ &instance_count);
+ if (CPA_STATUS_SUCCESS != status) {
+ instance_count = 0;
+ }
+ status = SalCtrl_ServiceInit(device,
+ &service_container->asym_services,
+ &service_container->asym_dir,
+ asym_dir_name,
+ tail_list,
+ instance_count,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_init;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) {
+ status = SalCtrl_GetInstanceCount(device,
+ "NumberCyInstances",
+ &instance_count);
+ if (CPA_STATUS_SUCCESS != status) {
+ instance_count = 0;
+ }
+ status = SalCtrl_ServiceInit(device,
+ &service_container->sym_services,
+ &service_container->sym_dir,
+ sym_dir_name,
+ tail_list,
+ instance_count,
+ SAL_SERVICE_TYPE_CRYPTO_SYM);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_init;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status = SalCtrl_GetInstanceCount(device,
+ "NumberCyInstances",
+ &instance_count);
+ if (CPA_STATUS_SUCCESS != status) {
+ instance_count = 0;
+ }
+ status =
+ SalCtrl_ServiceInit(device,
+ &service_container->crypto_services,
+ &service_container->cy_dir,
+ cy_dir_name,
+ tail_list,
+ instance_count,
+ SAL_SERVICE_TYPE_CRYPTO);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_init;
+ }
+ }
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ status = SalCtrl_GetInstanceCount(device,
+ "NumberDcInstances",
+ &instance_count);
+ if (CPA_STATUS_SUCCESS != status) {
+ instance_count = 0;
+ }
+ status = SalCtrl_ServiceInit(
+ device,
+ &service_container->compression_services,
+ &service_container->dc_dir,
+ dc_dir_name,
+ tail_list,
+ instance_count,
+ SAL_SERVICE_TYPE_COMPRESSION);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_init;
+ }
+ }
+
+ return status;
+
+err_init:
+ SalCtrl_ServiceEventShutdown(device, enabled_services);
+ return status;
+}
+
+/****************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the stop 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_ServiceEventStop(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_ServiceStop(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_ServiceStop(device,
+ service_container->sym_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status =
+ SalCtrl_ServiceStop(device,
+ service_container->crypto_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ status = SalCtrl_ServiceStop(
+ device, service_container->compression_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ ret_status = status;
+ }
+ }
+
+ return ret_status;
+}
+
+/**************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function calls the start 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_ServiceEventStart(icp_accel_dev_t *device, Cpa32U enabled_services)
+{
+ CpaStatus 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_ServiceStart(device,
+ service_container->asym_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_start;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_SYM)) {
+ status = SalCtrl_ServiceStart(device,
+ service_container->sym_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_start;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status =
+ SalCtrl_ServiceStart(device,
+ service_container->crypto_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_start;
+ }
+ }
+
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ status = SalCtrl_ServiceStart(
+ device, service_container->compression_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ goto err_start;
+ }
+ }
+
+ return status;
+err_start:
+ SalCtrl_ServiceEventStop(device, enabled_services);
+ return status;
+}
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is the events handler registered with ADF
+ * for the QA API services (cy, dc) - kernel and user
+ *
+ * @context
+ * This function is called from an ADF context.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] event Event from ADF
+ * @param[in] param Parameter used for back compatibility
+ *
+ ***********************************************************************/
+static CpaStatus
+SalCtrl_ServiceEventHandler(icp_accel_dev_t *device,
+ icp_adf_subsystemEvent_t event,
+ void *param)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ CpaStatus stats_status = CPA_STATUS_SUCCESS;
+ Cpa32U enabled_services = 0;
+
+ status = SalCtrl_GetEnabledServices(device, &enabled_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get enabled services.\n");
+ return status;
+ }
+
+ switch (event) {
+ case ICP_ADF_EVENT_INIT: {
+ /* In case there is no QAT SAL needs to call InitStats */
+ if (NULL == device->pQatStats) {
+ status = SalStatistics_InitStatisticsCollection(device);
+ }
+ if (CPA_STATUS_SUCCESS != status) {
+ return status;
+ }
+
+ status = SalCtrl_ServiceEventInit(device, enabled_services);
+ break;
+ }
+ case ICP_ADF_EVENT_START: {
+ status = SalCtrl_ServiceEventStart(device, enabled_services);
+ break;
+ }
+ case ICP_ADF_EVENT_STOP: {
+ status = SalCtrl_ServiceEventStop(device, enabled_services);
+ break;
+ }
+ case ICP_ADF_EVENT_SHUTDOWN: {
+ status = SalCtrl_ServiceEventShutdown(device, enabled_services);
+ stats_status = SalStatistics_CleanStatisticsCollection(device);
+ if (CPA_STATUS_SUCCESS != status ||
+ CPA_STATUS_SUCCESS != stats_status) {
+ return CPA_STATUS_FAIL;
+ }
+ break;
+ }
+ default:
+ status = CPA_STATUS_SUCCESS;
+ break;
+ }
+ return status;
+}
+
+CpaStatus
+SalCtrl_AdfServicesRegister(void)
+{
+ /* Fill out the global sal_service_reg_handle structure */
+ sal_service_reg_handle.subserviceEventHandler =
+ SalCtrl_ServiceEventHandler;
+ /* Set subsystem name to globally defined name */
+ sal_service_reg_handle.subsystem_name = subsystem_name;
+
+ return icp_adf_subsystemRegister(&sal_service_reg_handle);
+}
+
+CpaStatus
+SalCtrl_AdfServicesUnregister(void)
+{
+ return icp_adf_subsystemUnregister(&sal_service_reg_handle);
+}
+
+CpaStatus
+SalCtrl_AdfServicesStartedCheck(void)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa32U retry_num = 0;
+ CpaBoolean state = CPA_FALSE;
+
+ do {
+ state = icp_adf_isSubsystemStarted(&sal_service_reg_handle);
+ retry_num++;
+ } while ((CPA_FALSE == state) && (retry_num < MAX_SUBSYSTEM_RETRY));
+
+ if (CPA_FALSE == state) {
+ QAT_UTILS_LOG("Sal Ctrl failed to start in given time.\n");
+ status = CPA_STATUS_FAIL;
+ }
+
+ return status;
+}
+
+CpaStatus
+validateConcurrRequest(Cpa32U numConcurrRequests)
+{
+ Cpa32U baseReq = SAL_64_CONCURR_REQUESTS;
+
+ if (SAL_64_CONCURR_REQUESTS > numConcurrRequests) {
+ QAT_UTILS_LOG(
+ "Invalid numConcurrRequests, it is less than min value.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ while (SAL_MAX_CONCURR_REQUESTS >= baseReq) {
+ if (baseReq != numConcurrRequests) {
+ baseReq = baseReq << 1;
+ } else {
+ break;
+ }
+ }
+ if (SAL_MAX_CONCURR_REQUESTS < baseReq) {
+ QAT_UTILS_LOG(
+ "Invalid baseReg, it is greater than max value.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/ctrl/sal_list.c b/sys/dev/qat/qat_api/common/ctrl/sal_list.c
new file mode 100644
index 000000000000..022e271c1639
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/ctrl/sal_list.c
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_list.c
+ *
+ * @ingroup SalCtrl
+ *
+ * List implementations for SAL
+ *
+ *****************************************************************************/
+
+#include "lac_mem.h"
+#include "lac_list.h"
+
+CpaStatus
+SalList_add(sal_list_t **list, sal_list_t **tail, void *pObj)
+{
+ sal_list_t *new_element = NULL;
+
+ if (NULL == *list) {
+ /* First element in list */
+ *list = malloc(sizeof(sal_list_t), M_QAT, M_WAITOK);
+ (*list)->next = NULL;
+ (*list)->pObj = pObj;
+ *tail = *list;
+ } else {
+ /* add to tail of the list */
+ new_element = malloc(sizeof(sal_list_t), M_QAT, M_WAITOK);
+ new_element->pObj = pObj;
+ new_element->next = NULL;
+
+ (*tail)->next = new_element;
+
+ *tail = new_element;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+void *
+SalList_getObject(sal_list_t *list)
+{
+ if (list == NULL) {
+ return NULL;
+ }
+
+ return list->pObj;
+}
+
+void
+SalList_delObject(sal_list_t **list)
+{
+ if (*list == NULL) {
+ return;
+ }
+
+ (*list)->pObj = NULL;
+ return;
+}
+
+void *
+SalList_next(sal_list_t *list)
+{
+ return list->next;
+}
+
+void
+SalList_free(sal_list_t **list)
+{
+ sal_list_t *next_element = NULL;
+ void *pObj = NULL;
+ while (NULL != (*list)) {
+ next_element = SalList_next(*list);
+ pObj = SalList_getObject((*list));
+ LAC_OS_FREE(pObj);
+ LAC_OS_FREE(*list);
+ *list = next_element;
+ }
+}
+
+void
+SalList_del(sal_list_t **head_list, sal_list_t **pre_list, sal_list_t *list)
+{
+ void *pObj = NULL;
+ if ((NULL == *head_list) || (NULL == *pre_list) || (NULL == list)) {
+ return;
+ }
+ if (*head_list == list) { /* delete the first node in list */
+ *head_list = list->next;
+ } else {
+ (*pre_list)->next = list->next;
+ }
+ pObj = SalList_getObject(list);
+ LAC_OS_FREE(pObj);
+ LAC_OS_FREE(list);
+ return;
+}
diff --git a/sys/dev/qat/qat_api/common/include/lac_buffer_desc.h b/sys/dev/qat/qat_api/common/include/lac_buffer_desc.h
new file mode 100644
index 000000000000..079d537d7824
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_buffer_desc.h
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_buffer_desc.h
+ *
+ * @defgroup LacBufferDesc Buffer Descriptors
+ *
+ * @ingroup LacCommon
+ *
+ * Functions which handle updating a user supplied buffer with the QAT
+ * descriptor representation.
+ *
+ ***************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_BUFFER_DESC_H
+#define LAC_BUFFER_DESC_H
+
+/***************************************************************************
+ * Include header files
+ ***************************************************************************/
+#include "cpa.h"
+#include "icp_buffer_desc.h"
+#include "cpa_cy_sym.h"
+#include "lac_common.h"
+
+/**
+*******************************************************************************
+* @ingroup LacBufferDesc
+* Write the buffer descriptor in QAT friendly format.
+*
+* @description
+* Updates the Meta Data associated with the pUserBufferList CpaBufferList
+* This function will also return the (aligned) physical address
+* associated with this CpaBufferList.
+*
+* @param[in] pUserBufferList A pointer to the buffer list to
+* create the meta data for the QAT.
+* @param[out] pBufferListAlignedPhyAddr The pointer to the aligned physical
+* address.
+* @param[in] isPhysicalAddress Type of address
+* @param[in] pService Pointer to generic service
+*
+*****************************************************************************/
+CpaStatus LacBuffDesc_BufferListDescWrite(const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufferListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ sal_service_t *pService);
+
+/**
+*******************************************************************************
+* @ingroup LacBufferDesc
+* Write the buffer descriptor in QAT friendly format.
+*
+* @description
+* Updates the Meta Data associated with the pUserBufferList CpaBufferList
+* This function will also return the (aligned) physical address
+* associated with this CpaBufferList. Zero length buffers are allowed.
+* Should be used for CHA-CHA-POLY and GCM algorithms.
+*
+* @param[in] pUserBufferList A pointer to the buffer list to
+* create the meta data for the QAT.
+* @param[out] pBufferListAlignedPhyAddr The pointer to the aligned physical
+* address.
+* @param[in] isPhysicalAddress Type of address
+* @param[in] pService Pointer to generic service
+*
+*****************************************************************************/
+CpaStatus LacBuffDesc_BufferListDescWriteAndAllowZeroBuffer(
+ const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufferListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ sal_service_t *pService);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Write the buffer descriptor in QAT friendly format.
+ *
+ * @description
+ * Updates the Meta Data associated with the PClientList CpaBufferList
+ * This function will also return the (aligned) physical address
+ * associated with this CpaBufferList and the total data length of the
+ * buffer list.
+ *
+ * @param[in] pUserBufferList A pointer to the buffer list to
+ * create the meta data for the QAT.
+ * @param[out] pBufListAlignedPhyAddr The pointer to the aligned physical
+ * address.
+ * @param[in] isPhysicalAddress Type of address
+ * @param[out] totalDataLenInBytes The pointer to the total data length
+ * of the buffer list
+ * @param[in] pService Pointer to generic service
+ *
+ *****************************************************************************/
+CpaStatus
+LacBuffDesc_BufferListDescWriteAndGetSize(const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ Cpa64U *totalDataLenInBytes,
+ sal_service_t *pService);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Ensure the CpaFlatBuffer is correctly formatted.
+ *
+ * @description
+ * Ensures the CpaFlatBuffer is correctly formatted
+ * This function will also return the total size of the buffers
+ * in the scatter gather list.
+ *
+ * @param[in] pUserFlatBuffer A pointer to the flat buffer to
+ * validate.
+ * @param[out] pPktSize The total size of the packet.
+ * @param[in] alignmentShiftExpected The expected alignment shift of each
+ * of the elements of the scatter gather
+ *
+ * @retval CPA_STATUS_INVALID_PARAM BufferList failed checks
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ *
+ *****************************************************************************/
+CpaStatus
+LacBuffDesc_FlatBufferVerify(const CpaFlatBuffer *pUserFlatBuffer,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Ensure the CpaFlatBuffer is correctly formatted.
+ * This function will allow a size of zero bytes to any of the Flat
+ * buffers.
+ *
+ * @description
+ * Ensures the CpaFlatBuffer is correctly formatted
+ * This function will also return the total size of the buffers
+ * in the scatter gather list.
+ *
+ * @param[in] pUserFlatBuffer A pointer to the flat buffer to
+ * validate.
+ * @param[out] pPktSize The total size of the packet.
+ * @param[in] alignmentShiftExpected The expected alignment shift of each
+ * of the elements of the scatter gather
+ *
+ * @retval CPA_STATUS_INVALID_PARAM BufferList failed checks
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ *
+ *****************************************************************************/
+CpaStatus
+LacBuffDesc_FlatBufferVerifyNull(const CpaFlatBuffer *pUserFlatBuffer,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Ensure the CpaBufferList is correctly formatted.
+ *
+ * @description
+ * Ensures the CpaBufferList pUserBufferList is correctly formatted
+ * including the user supplied metaData.
+ * This function will also return the total size of the buffers
+ * in the scatter gather list.
+ *
+ * @param[in] pUserBufferList A pointer to the buffer list to
+ * validate.
+ * @param[out] pPktSize The total size of the buffers in the
+ * scatter gather list.
+ * @param[in] alignmentShiftExpected The expected alignment shift of each
+ * of the elements of the scatter gather
+ * list.
+ * @retval CPA_STATUS_INVALID_PARAM BufferList failed checks
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ *
+ *****************************************************************************/
+CpaStatus
+LacBuffDesc_BufferListVerify(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Ensure the CpaBufferList is correctly formatted.
+ *
+ * @description
+ * Ensures the CpaBufferList pUserBufferList is correctly formatted
+ * including the user supplied metaData.
+ * This function will also return the total size of the buffers
+ * in the scatter gather list.
+ *
+ * @param[in] pUserBufferList A pointer to the buffer list to
+ * validate.
+ * @param[out] pPktSize The total size of the buffers in the
+ * scatter gather list.
+ * @param[in] alignmentShiftExpected The expected alignment shift of each
+ * of the elements of the scatter gather
+ * list.
+ * @retval CPA_STATUS_INVALID_PARAM BufferList failed checks
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ *
+ *****************************************************************************/
+CpaStatus
+LacBuffDesc_BufferListVerifyNull(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Get the total size of a CpaBufferList.
+ *
+ * @description
+ * This function returns the total size of the buffers
+ * in the scatter gather list.
+ *
+ * @param[in] pUserBufferList A pointer to the buffer list to
+ * calculate the total size for.
+ * @param[out] pPktSize The total size of the buffers in the
+ * scatter gather list.
+ *
+ *****************************************************************************/
+void LacBuffDesc_BufferListTotalSizeGet(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize);
+
+/**
+*******************************************************************************
+ * @ingroup LacBufferDesc
+ * Zero some of the CpaBufferList.
+ *
+ * @description
+ * Zero a section of data within the CpaBufferList from an offset for
+ * a specific length.
+ *
+ * @param[in] pBuffList A pointer to the buffer list to
+ * zero an area of.
+ * @param[in] offset Number of bytes from start of buffer to where
+ * to start zeroing.
+ *
+ * @param[in] lenToZero Number of bytes that will be set to zero
+ * after the call to this function.
+ *****************************************************************************/
+
+void LacBuffDesc_BufferListZeroFromOffset(CpaBufferList *pBuffList,
+ Cpa32U offset,
+ Cpa32U lenToZero);
+
+#endif /* LAC_BUFFER_DESC_H */
diff --git a/sys/dev/qat/qat_api/common/include/lac_common.h b/sys/dev/qat/qat_api/common/include/lac_common.h
new file mode 100644
index 000000000000..fb2fdd95300e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_common.h
@@ -0,0 +1,847 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file lac_common.h Common macros
+ *
+ * @defgroup Lac Look Aside Crypto LLD Doc
+ *
+ *****************************************************************************/
+
+/**
+ *****************************************************************************
+ * @defgroup LacCommon LAC Common
+ * Common code for Lac which includes init/shutdown, memory, logging and
+ * hooks.
+ *
+ * @ingroup Lac
+ *
+ *****************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_COMMON_H
+#define LAC_COMMON_H
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+
+#include "cpa.h"
+#include "qat_utils.h"
+#include "cpa_cy_common.h"
+#include "icp_adf_init.h"
+
+#define LAC_ARCH_UINT uintptr_t
+#define LAC_ARCH_INT intptr_t
+
+/*
+*****************************************************************************
+* Max range values for some primitive param checking
+*****************************************************************************
+*/
+
+/**< Maximum number of instances */
+#define SAL_MAX_NUM_INSTANCES_PER_DEV 512
+
+#define SAL_DEFAULT_RING_SIZE 256
+/**< Default ring size */
+
+#define SAL_64_CONCURR_REQUESTS 64
+#define SAL_128_CONCURR_REQUESTS 128
+#define SAL_256_CONCURR_REQUESTS 256
+#define SAL_512_CONCURR_REQUESTS 512
+#define SAL_1024_CONCURR_REQUESTS 1024
+#define SAL_2048_CONCURR_REQUESTS 2048
+#define SAL_4096_CONCURR_REQUESTS 4096
+#define SAL_MAX_CONCURR_REQUESTS 65536
+/**< Valid options for the num of concurrent requests per ring pair read
+ from the config file. These values are used to size the rings */
+
+#define SAL_BATCH_SUBMIT_FREE_SPACE 2
+/**< For data plane batch submissions ADF leaves 2 spaces free on the ring */
+
+/*
+******************************************************************************
+* Some common settings for QA API queries
+******************************************************************************
+*/
+
+#define SAL_INFO2_VENDOR_NAME "Intel(R)"
+/**< @ingroup LacCommon
+ * Name of vendor of this driver */
+#define SAL_INFO2_PART_NAME "%s with Intel(R) QuickAssist Technology"
+/**< @ingroup LacCommon
+ */
+
+/*
+********************************************************************************
+* User process name defines and functions
+********************************************************************************
+*/
+
+#define LAC_USER_PROCESS_NAME_MAX_LEN 32
+/**< @ingroup LacCommon
+ * Max length of user process name */
+
+#define LAC_KERNEL_PROCESS_NAME "KERNEL_QAT"
+/**< @ingroup LacCommon
+ * Default name for kernel process */
+
+/*
+********************************************************************************
+* response mode indicator from Config file
+********************************************************************************
+*/
+
+#define SAL_RESP_POLL_CFG_FILE 1
+#define SAL_RESP_EPOLL_CFG_FILE 2
+
+/*
+ * @ingroup LacCommon
+ * @description
+ * This function sets the process name
+ *
+ * @context
+ * This functions is called from module_init or from user space process
+ * initialization function
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ *
+ * param[in] processName Process name to be set
+*/
+CpaStatus icpSetProcessName(const char *processName);
+
+/*
+ * @ingroup LacCommon
+ * @description
+ * This function gets the process name
+ *
+ * @context
+ * This functions is called from LAC context
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ *
+*/
+char *icpGetProcessName(void);
+
+/* Sections of the config file */
+#define LAC_CFG_SECTION_GENERAL "GENERAL"
+#define LAC_CFG_SECTION_INTERNAL "INTERNAL"
+
+/*
+********************************************************************************
+* Debug Macros and settings
+********************************************************************************
+*/
+
+#define SEPARATOR "+--------------------------------------------------+\n"
+/**< @ingroup LacCommon
+ * separator used for printing stats to standard output*/
+
+#define BORDER "|"
+/**< @ingroup LacCommon
+ * separator used for printing stats to standard output*/
+
+/**
+*****************************************************************************
+ * @ingroup LacCommon
+ * Component state
+ *
+ * @description
+ * This enum is used to indicate the state that the component is in. Its
+ * purpose is to prevent components from being initialised or shutdown
+ * incorrectly.
+ *
+ *****************************************************************************/
+typedef enum {
+ LAC_COMP_SHUT_DOWN = 0,
+ /**< Component in the Shut Down state */
+ LAC_COMP_SHUTTING_DOWN,
+ /**< Component in the Process of Shutting down */
+ LAC_COMP_INITIALISING,
+ /**< Component in the Process of being initialised */
+ LAC_COMP_INITIALISED,
+ /**< Component in the initialised state */
+} lac_comp_state_t;
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro checks if a parameter is NULL
+ *
+ * @param[in] param Parameter
+ *
+ * @return CPA_STATUS_INVALID_PARAM Parameter is NULL
+ * @return void Parameter is not NULL
+ ******************************************************************************/
+#define LAC_CHECK_NULL_PARAM(param) \
+ do { \
+ if (NULL == (param)) { \
+ return CPA_STATUS_INVALID_PARAM; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro checks if a parameter is within a specified range
+ *
+ * @param[in] param Parameter
+ * @param[in] min Parameter must be greater than OR equal to
+ *min
+ * @param[in] max Parameter must be less than max
+ *
+ * @return CPA_STATUS_INVALID_PARAM Parameter is outside range
+ * @return void Parameter is within range
+ ******************************************************************************/
+#define LAC_CHECK_PARAM_RANGE(param, min, max) \
+ do { \
+ if (((param) < (min)) || ((param) >= (max))) { \
+ return CPA_STATUS_INVALID_PARAM; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This checks if a param is 8 byte aligned.
+ *
+ ******************************************************************************/
+#define LAC_CHECK_8_BYTE_ALIGNMENT(param) \
+ do { \
+ if ((Cpa64U)param % 8 != 0) { \
+ return CPA_STATUS_INVALID_PARAM; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This checks if a param is 64 byte aligned.
+ *
+ ******************************************************************************/
+#define LAC_CHECK_64_BYTE_ALIGNMENT(param) \
+ do { \
+ if ((LAC_ARCH_UINT)param % 64 != 0) { \
+ return CPA_STATUS_INVALID_PARAM; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro returns the size of the buffer list structure given the
+ * number of elements in the buffer list - note: only the sizeof the
+ * buffer list structure is returned.
+ *
+ * @param[in] numBuffers The number of flatbuffers in a buffer list
+ *
+ * @return size of the buffer list structure
+ ******************************************************************************/
+#define LAC_BUFFER_LIST_SIZE_GET(numBuffers) \
+ (sizeof(CpaBufferList) + (numBuffers * sizeof(CpaFlatBuffer)))
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro checks that a flatbuffer is valid i.e. that it is not
+ * null and the data it points to is not null
+ *
+ * @param[in] pFlatBuffer Pointer to flatbuffer
+ *
+ * @return CPA_STATUS_INVALID_PARAM Invalid flatbuffer pointer
+ * @return void flatbuffer is ok
+ ******************************************************************************/
+#define LAC_CHECK_FLAT_BUFFER(pFlatBuffer) \
+ do { \
+ LAC_CHECK_NULL_PARAM((pFlatBuffer)); \
+ LAC_CHECK_NULL_PARAM((pFlatBuffer)->pData); \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro verifies that the status is ok i.e. equal to CPA_STATUS_SUCCESS
+ *
+ * @param[in] status status we are checking
+ *
+ * @return void status is ok (CPA_STATUS_SUCCESS)
+ * @return status The value in the status parameter is an error one
+ *
+ ******************************************************************************/
+#define LAC_CHECK_STATUS(status) \
+ do { \
+ if (CPA_STATUS_SUCCESS != (status)) { \
+ return status; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro verifies that the Instance Handle is valid.
+ *
+ * @param[in] instanceHandle Instance Handle
+ *
+ * @return CPA_STATUS_INVALID_PARAM Parameter is NULL
+ * @return void Parameter is not NULL
+ *
+ ******************************************************************************/
+#define LAC_CHECK_INSTANCE_HANDLE(instanceHandle) \
+ do { \
+ if (NULL == (instanceHandle)) { \
+ return CPA_STATUS_INVALID_PARAM; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro copies a string from one location to another
+ *
+ * @param[out] pDestinationBuffer Pointer to destination buffer
+ * @param[in] pSource Pointer to source buffer
+ *
+ ******************************************************************************/
+#define LAC_COPY_STRING(pDestinationBuffer, pSource) \
+ do { \
+ memcpy(pDestinationBuffer, pSource, (sizeof(pSource) - 1)); \
+ pDestinationBuffer[(sizeof(pSource) - 1)] = '\0'; \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro fills a memory zone with ZEROES
+ *
+ * @param[in] pBuffer Pointer to buffer
+ * @param[in] count Buffer length
+ *
+ * @return void
+ *
+ ******************************************************************************/
+#define LAC_OS_BZERO(pBuffer, count) memset(pBuffer, 0, count);
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro calculates the position of the given member in a struct
+ * Only for use on a struct where all members are of equal size to map
+ * the struct member position to an array index
+ *
+ * @param[in] structType the struct
+ * @param[in] member the member of the given struct
+ *
+ ******************************************************************************/
+#define LAC_IDX_OF(structType, member) \
+ (offsetof(structType, member) / sizeof(((structType *)0)->member))
+
+/*
+********************************************************************************
+* Alignment, Bid define and Bit Operation Macros
+********************************************************************************
+*/
+
+#define LAC_BIT31_SET 0x80000000 /**< bit 31 == 1 */
+#define LAC_BIT7_SET 0x80 /**< bit 7 == 1 */
+#define LAC_BIT6_SET 0x40 /**< bit 6 == 1 */
+#define LAC_BIT5_SET 0x20 /**< bit 5 == 1 */
+#define LAC_BIT4_SET 0x10 /**< bit 4 == 1 */
+#define LAC_BIT3_SET 0x08 /**< bit 3 == 1 */
+#define LAC_BIT2_SET 0x04 /**< bit 2 == 1 */
+#define LAC_BIT1_SET 0x02 /**< bit 1 == 1 */
+#define LAC_BIT0_SET 0x01 /**< bit 0 == 1 */
+
+#define LAC_NUM_BITS_IN_BYTE (8)
+/**< @ingroup LacCommon
+ * Number of bits in a byte */
+
+#define LAC_LONG_WORD_IN_BYTES (4)
+/**< @ingroup LacCommon
+ * Number of bytes in an IA word */
+
+#define LAC_QUAD_WORD_IN_BYTES (8)
+/**< @ingroup LacCommon
+ * Number of bytes in a QUAD word */
+
+#define LAC_QAT_MAX_MSG_SZ_LW (32)
+/**< @ingroup LacCommon
+ * Maximum size in Long Words for a QAT message */
+
+/**
+*****************************************************************************
+ * @ingroup LacCommon
+ * Alignment shift requirements of a buffer.
+ *
+ * @description
+ * This enum is used to indicate the alignment shift of a buffer.
+ * All alignments are to power of 2
+ *
+ *****************************************************************************/
+typedef enum lac_aligment_shift_s {
+ LAC_NO_ALIGNMENT_SHIFT = 0,
+ /**< No alignment shift (to a power of 2)*/
+ LAC_8BYTE_ALIGNMENT_SHIFT = 3,
+ /**< 8 byte alignment shift (to a power of 2)*/
+ LAC_16BYTE_ALIGNMENT_SHIFT = 4,
+ /**< 16 byte alignment shift (to a power of 2)*/
+ LAC_64BYTE_ALIGNMENT_SHIFT = 6,
+ /**< 64 byte alignment shift (to a power of 2)*/
+ LAC_4KBYTE_ALIGNMENT_SHIFT = 12,
+ /**< 4k byte alignment shift (to a power of 2)*/
+} lac_aligment_shift_t;
+
+/**
+*****************************************************************************
+ * @ingroup LacCommon
+ * Alignment of a buffer.
+ *
+ * @description
+ * This enum is used to indicate the alignment requirements of a buffer.
+ *
+ *****************************************************************************/
+typedef enum lac_aligment_s {
+ LAC_NO_ALIGNMENT = 0,
+ /**< No alignment */
+ LAC_1BYTE_ALIGNMENT = 1,
+ /**< 1 byte alignment */
+ LAC_8BYTE_ALIGNMENT = 8,
+ /**< 8 byte alignment*/
+ LAC_64BYTE_ALIGNMENT = 64,
+ /**< 64 byte alignment*/
+ LAC_4KBYTE_ALIGNMENT = 4096,
+ /**< 4k byte alignment */
+} lac_aligment_t;
+
+/**
+*****************************************************************************
+ * @ingroup LacCommon
+ * Size of a buffer.
+ *
+ * @description
+ * This enum is used to indicate the required size.
+ * The buffer must be a multiple of the required size.
+ *
+ *****************************************************************************/
+typedef enum lac_expected_size_s {
+ LAC_NO_LENGTH_REQUIREMENTS = 0,
+ /**< No requirement for size */
+ LAC_4KBYTE_MULTIPLE_REQUIRED = 4096,
+ /**< 4k multiple requirement for size */
+} lac_expected_size_t;
+
+#define LAC_OPTIMAL_ALIGNMENT_SHIFT LAC_64BYTE_ALIGNMENT_SHIFT
+/**< @ingroup LacCommon
+ * optimal alignment to a power of 2 */
+
+#define LAC_SHIFT_8 (1 << LAC_8BYTE_ALIGNMENT_SHIFT)
+/**< shift by 8 bits */
+#define LAC_SHIFT_24 \
+ ((1 << LAC_8BYTE_ALIGNMENT_SHIFT) + (1 << LAC_16BYTE_ALIGNMENT_SHIFT))
+/**< shift by 24 bits */
+
+#define LAC_MAX_16_BIT_VALUE ((1 << 16) - 1)
+/**< @ingroup LacCommon
+ * maximum value a 16 bit type can hold */
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro can be used to avoid an unused variable warning from the
+ * compiler
+ *
+ * @param[in] variable unused variable
+ *
+ ******************************************************************************/
+#define LAC_UNUSED_VARIABLE(x) (void)(x)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro checks if an address is aligned to the specified power of 2
+ * Returns 0 if alignment is ok, or non-zero otherwise
+ *
+ * @param[in] address the address we are checking
+ *
+ * @param[in] alignment the byte alignment to check (specified as power of 2)
+ *
+ ******************************************************************************/
+#define LAC_ADDRESS_ALIGNED(address, alignment) \
+ (!((LAC_ARCH_UINT)(address) & ((1 << (alignment)) - 1)))
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro rounds up a number to a be a multiple of the alignment when
+ * the alignment is a power of 2.
+ *
+ * @param[in] num Number
+ * @param[in] align Alignment (must be a power of 2)
+ *
+ ******************************************************************************/
+#define LAC_ALIGN_POW2_ROUNDUP(num, align) (((num) + (align)-1) & ~((align)-1))
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro generates a bit mask to select a particular bit
+ *
+ * @param[in] bitPos Bit position to select
+ *
+ ******************************************************************************/
+#define LAC_BIT(bitPos) (0x1 << (bitPos))
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in bits to the equivalent size in bytes,
+ * using a bit shift to divide by 8
+ *
+ * @param[in] x size in bits
+ *
+ ******************************************************************************/
+#define LAC_BITS_TO_BYTES(x) ((x) >> 3)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in bytes to the equivalent size in bits,
+ * using a bit shift to multiply by 8
+ *
+ * @param[in] x size in bytes
+ *
+ ******************************************************************************/
+#define LAC_BYTES_TO_BITS(x) ((x) << 3)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in bytes to the equivalent size in longwords,
+ * using a bit shift to divide by 4
+ *
+ * @param[in] x size in bytes
+ *
+ ******************************************************************************/
+#define LAC_BYTES_TO_LONGWORDS(x) ((x) >> 2)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in longwords to the equivalent size in bytes,
+ * using a bit shift to multiply by 4
+ *
+ * @param[in] x size in long words
+ *
+ ******************************************************************************/
+#define LAC_LONGWORDS_TO_BYTES(x) ((x) << 2)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in bytes to the equivalent size in quadwords,
+ * using a bit shift to divide by 8
+ *
+ * @param[in] x size in bytes
+ *
+ ******************************************************************************/
+#define LAC_BYTES_TO_QUADWORDS(x) (((x) >> 3) + (((x) % 8) ? 1 : 0))
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro converts a size in quadwords to the equivalent size in bytes,
+ * using a bit shift to multiply by 8
+ *
+ * @param[in] x size in quad words
+ *
+ ******************************************************************************/
+#define LAC_QUADWORDS_TO_BYTES(x) ((x) << 3)
+
+
+/******************************************************************************/
+
+/*
+*******************************************************************************
+* Mutex Macros
+*******************************************************************************
+*/
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro tries to acquire a mutex and returns the status
+ *
+ * @param[in] pLock Pointer to Lock
+ * @param[in] timeout Timeout
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with Mutex
+ ******************************************************************************/
+#define LAC_LOCK_MUTEX(pLock, timeout) \
+ ((CPA_STATUS_SUCCESS != qatUtilsMutexLock((pLock), (timeout))) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro unlocks a mutex and returns the status
+ *
+ * @param[in] pLock Pointer to Lock
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with Mutex
+ ******************************************************************************/
+#define LAC_UNLOCK_MUTEX(pLock) \
+ ((CPA_STATUS_SUCCESS != qatUtilsMutexUnlock((pLock))) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro initialises a mutex and returns the status
+ *
+ * @param[in] pLock Pointer to Lock
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with Mutex
+ ******************************************************************************/
+#define LAC_INIT_MUTEX(pLock) \
+ ((CPA_STATUS_SUCCESS != qatUtilsMutexInit((pLock))) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro destroys a mutex and returns the status
+ *
+ * @param[in] pLock Pointer to Lock
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with Mutex
+ ******************************************************************************/
+#define LAC_DESTROY_MUTEX(pLock) \
+ ((CPA_STATUS_SUCCESS != qatUtilsMutexDestroy((pLock))) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro calls a trylock on a mutex
+ *
+ * @param[in] pLock Pointer to Lock
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with Mutex
+ ******************************************************************************/
+#define LAC_TRYLOCK_MUTEX(pLock) \
+ ((CPA_STATUS_SUCCESS != \
+ qatUtilsMutexTryLock((pLock), QAT_UTILS_WAIT_NONE)) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/*
+*******************************************************************************
+* Semaphore Macros
+*******************************************************************************
+*/
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro waits on a semaphore and returns the status
+ *
+ * @param[in] sid The semaphore
+ * @param[in] timeout Timeout
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with semaphore
+ ******************************************************************************/
+#define LAC_WAIT_SEMAPHORE(sid, timeout) \
+ ((CPA_STATUS_SUCCESS != qatUtilsSemaphoreWait(&sid, (timeout))) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro checks a semaphore and returns the status
+ *
+ * @param[in] sid The semaphore
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with semaphore
+ ******************************************************************************/
+#define LAC_CHECK_SEMAPHORE(sid) \
+ ((CPA_STATUS_SUCCESS != qatUtilsSemaphoreTryWait(&sid)) ? \
+ CPA_STATUS_RETRY : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro post a semaphore and returns the status
+ *
+ * @param[in] sid The semaphore
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with semaphore
+ ******************************************************************************/
+#define LAC_POST_SEMAPHORE(sid) \
+ ((CPA_STATUS_SUCCESS != qatUtilsSemaphorePost(&sid)) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro initialises a semaphore and returns the status
+ *
+ * @param[in] sid The semaphore
+ * @param[in] semValue Initial semaphore value
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with semaphore
+ ******************************************************************************/
+#define LAC_INIT_SEMAPHORE(sid, semValue) \
+ ((CPA_STATUS_SUCCESS != qatUtilsSemaphoreInit(&sid, semValue)) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/**
+ *******************************************************************************
+ * @ingroup LacCommon
+ * This macro destroys a semaphore and returns the status
+ *
+ * @param[in] sid The semaphore
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully.
+ * @retval CPA_STATUS_RESOURCE Error with semaphore
+ ******************************************************************************/
+#define LAC_DESTROY_SEMAPHORE(sid) \
+ ((CPA_STATUS_SUCCESS != qatUtilsSemaphoreDestroy(&sid)) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+
+/*
+*******************************************************************************
+* Spinlock Macros
+*******************************************************************************
+*/
+typedef struct mtx *lac_lock_t;
+#define LAC_SPINLOCK_INIT(lock) \
+ ((CPA_STATUS_SUCCESS != qatUtilsLockInit(lock)) ? \
+ CPA_STATUS_RESOURCE : \
+ CPA_STATUS_SUCCESS)
+#define LAC_SPINLOCK(lock) \
+ ({ \
+ (void)qatUtilsLock(lock); \
+ CPA_STATUS_SUCCESS; \
+ })
+#define LAC_SPINUNLOCK(lock) \
+ ({ \
+ (void)qatUtilsUnlock(lock); \
+ CPA_STATUS_SUCCESS; \
+ })
+#define LAC_SPINLOCK_DESTROY(lock) \
+ ({ \
+ (void)qatUtilsLockDestroy(lock); \
+ CPA_STATUS_SUCCESS; \
+ })
+
+#define LAC_CONST_PTR_CAST(castee) ((void *)(LAC_ARCH_UINT)(castee))
+#define LAC_CONST_VOLATILE_PTR_CAST(castee) ((void *)(LAC_ARCH_UINT)(castee))
+
+/* Type of ring */
+#define SAL_RING_TYPE_NONE 0
+#define SAL_RING_TYPE_A_SYM_HI 1
+#define SAL_RING_TYPE_A_SYM_LO 2
+#define SAL_RING_TYPE_A_ASYM 3
+#define SAL_RING_TYPE_B_SYM_HI 4
+#define SAL_RING_TYPE_B_SYM_LO 5
+#define SAL_RING_TYPE_B_ASYM 6
+#define SAL_RING_TYPE_DC 7
+#define SAL_RING_TYPE_ADMIN 8
+#define SAL_RING_TYPE_TRNG 9
+
+/* Maps Ring Service to generic service type */
+static inline icp_adf_ringInfoService_t
+lac_getRingType(int type)
+{
+ switch (type) {
+ case SAL_RING_TYPE_NONE:
+ return ICP_ADF_RING_SERVICE_0;
+ case SAL_RING_TYPE_A_SYM_HI:
+ return ICP_ADF_RING_SERVICE_1;
+ case SAL_RING_TYPE_A_SYM_LO:
+ return ICP_ADF_RING_SERVICE_2;
+ case SAL_RING_TYPE_A_ASYM:
+ return ICP_ADF_RING_SERVICE_3;
+ case SAL_RING_TYPE_B_SYM_HI:
+ return ICP_ADF_RING_SERVICE_4;
+ case SAL_RING_TYPE_B_SYM_LO:
+ return ICP_ADF_RING_SERVICE_5;
+ case SAL_RING_TYPE_B_ASYM:
+ return ICP_ADF_RING_SERVICE_6;
+ case SAL_RING_TYPE_DC:
+ return ICP_ADF_RING_SERVICE_7;
+ case SAL_RING_TYPE_ADMIN:
+ return ICP_ADF_RING_SERVICE_8;
+ case SAL_RING_TYPE_TRNG:
+ return ICP_ADF_RING_SERVICE_9;
+ default:
+ return ICP_ADF_RING_SERVICE_0;
+ }
+ return ICP_ADF_RING_SERVICE_0;
+}
+
+/* Maps generic service type to Ring Service type */
+static inline int
+lac_getServiceType(icp_adf_ringInfoService_t type)
+{
+ switch (type) {
+ case ICP_ADF_RING_SERVICE_0:
+ return SAL_RING_TYPE_NONE;
+ case ICP_ADF_RING_SERVICE_1:
+ return SAL_RING_TYPE_A_SYM_HI;
+ case ICP_ADF_RING_SERVICE_2:
+ return SAL_RING_TYPE_A_SYM_LO;
+ case ICP_ADF_RING_SERVICE_3:
+ return SAL_RING_TYPE_A_ASYM;
+ case ICP_ADF_RING_SERVICE_4:
+ return SAL_RING_TYPE_B_SYM_HI;
+ case ICP_ADF_RING_SERVICE_5:
+ return SAL_RING_TYPE_B_SYM_LO;
+ case ICP_ADF_RING_SERVICE_6:
+ return SAL_RING_TYPE_B_ASYM;
+ case ICP_ADF_RING_SERVICE_7:
+ return SAL_RING_TYPE_DC;
+ case ICP_ADF_RING_SERVICE_8:
+ return SAL_RING_TYPE_ADMIN;
+ default:
+ return SAL_RING_TYPE_NONE;
+ }
+ return SAL_RING_TYPE_NONE;
+}
+
+#endif /* LAC_COMMON_H */
diff --git a/sys/dev/qat/qat_api/common/include/lac_hooks.h b/sys/dev/qat/qat_api/common/include/lac_hooks.h
new file mode 100644
index 000000000000..7018b77a480e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_hooks.h
@@ -0,0 +1,234 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *******************************************************************************
+ * @file lac_hooks.h
+ *
+ * @defgroup LacHooks Hooks
+ *
+ * @ingroup LacCommon
+ *
+ * Component Init/Shutdown functions. These are:
+ * - an init function which is called during the intialisation sequence,
+ * - a shutdown function which is called by the overall shutdown function,
+ *
+ ******************************************************************************/
+
+#ifndef LAC_HOOKS_H
+#define LAC_HOOKS_H
+
+/*
+********************************************************************************
+* Include public/global header files
+********************************************************************************
+*/
+
+#include "cpa.h"
+
+/*
+********************************************************************************
+* Include private header files
+********************************************************************************
+*/
+
+/******************************************************************************/
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the Large Number (ModExp and ModInv) module
+ *
+ * @description
+ * This function clears the Large Number statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+CpaStatus LacLn_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees statistics array for Large Number module
+ *
+ * @description
+ * This function frees statistics array for Large Number module
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+void LacLn_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the Prime module
+ *
+ * @description
+ * This function clears the Prime statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+CpaStatus LacPrime_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees the Prime module statistics array
+ *
+ * @description
+ * This function frees the Prime module statistics array
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+void LacPrime_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the DSA module
+ *
+ * @param[in] instanceHandle
+ *
+ * @description
+ * This function clears the DSA statistics
+ *
+ ******************************************************************************/
+CpaStatus LacDsa_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees the DSA module statistics array
+ *
+ * @param[in] instanceHandle
+ *
+ * @description
+ * This function frees the DSA statistics array
+ *
+ ******************************************************************************/
+void LacDsa_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the Diffie Hellmann module
+ *
+ * @description
+ * This function initialises the Diffie Hellman statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+CpaStatus LacDh_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees the Diffie Hellmann module statistics
+ *
+ * @description
+ * This function frees the Diffie Hellmann module statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+void LacDh_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * This function registers the callback handlers to SSL/TLS and MGF,
+ * allocates resources that are needed for the component and clears
+ * the stats.
+ *
+ * @param[in] instanceHandle
+ *
+ * @retval CPA_STATUS_SUCCESS Status Success
+ * @retval CPA_STATUS_FAIL General failure
+ * @retval CPA_STATUS_RESOURCE Resource allocation failure
+ *
+ *****************************************************************************/
+CpaStatus LacSymKey_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ ******************************************************************************
+ * @ingroup LacSymKey
+ * This function frees up resources obtained by the key gen component
+ * and clears the stats
+ *
+ * @param[in] instanceHandle
+ *
+ * @retval CPA_STATUS_SUCCESS Status Success
+ *
+ *****************************************************************************/
+CpaStatus LacSymKey_Shutdown(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the RSA module
+ *
+ * @description
+ * This function clears the RSA statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+CpaStatus LacRsa_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees the RSA module statistics
+ *
+ * @description
+ * This function frees the RSA module statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+void LacRsa_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function initialises the EC module
+ *
+ * @description
+ * This function clears the EC statistics
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+CpaStatus LacEc_Init(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacHooks
+ * This function frees the EC module stats array
+ *
+ * @description
+ * This function frees the EC module stats array
+ *
+ * @param[in] instanceHandle
+ *
+ ******************************************************************************/
+void LacEc_StatsFree(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+ * @ingroup LacSymNrbg
+ * Initialise the NRBG module
+ *
+ * @description
+ * This function registers NRBG callback handlers.
+ *
+ *
+ *****************************************************************************/
+void LacSymNrbg_Init(void);
+
+#endif /* LAC_HOOKS_H */
diff --git a/sys/dev/qat/qat_api/common/include/lac_list.h b/sys/dev/qat/qat_api/common/include/lac_list.h
new file mode 100644
index 000000000000..2af91df155c6
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_list.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_list.h
+ *
+ * @defgroup SalList
+ *
+ * @ingroup SalCtrl
+ *
+ * List structure and list functions.
+ *
+ ***************************************************************************/
+
+#ifndef LAC_LIST_H
+#define LAC_LIST_H
+
+/**
+ *****************************************************************************
+ * @ingroup SalList
+ *
+ * @description
+ * List structure
+ *
+ *****************************************************************************/
+typedef struct sal_list_s {
+
+ struct sal_list_s *next;
+ void *pObj;
+
+} sal_list_t;
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Add a structure to tail of a list.
+ *
+ * @description
+ * Adds pObj to the tail of list (if it exists). Allocates and sets a
+ * new sal_list_t structure.
+ *
+ * @param[in] list Pointer to the head pointer of the list.
+ * Can be NULL if no elements yet in list.
+ * @param[in/out] tail Pointer to tail pointer of the list.
+ * Can be NULL if no elements yet in list.
+ * Is updated by the function to point to
+*tail
+ * of list if pObj has been successfully
+*added.
+ * @param[in] pObj Pointer to structure to add to tail of
+ * the list.
+ * @retval status
+ *
+ *****************************************************************************/
+CpaStatus SalList_add(sal_list_t **list, sal_list_t **tail, void *pObj);
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Delete an element from the list.
+ *
+ * @description
+ * Delete an element from the list.
+ *
+ * @param[in/out] head_list Pointer to the head pointer of the list.
+ * Can be NULL if no elements yet in list.
+ * Is updated by the function
+ * to point to list->next if head_list is
+*list.
+ * @param[in/out] pre_list Pointer to the previous pointer of the
+*list.
+ * Can be NULL if no elements yet in list.
+ * (*pre_list)->next is updated
+ * by the function to point to list->next
+ * @param[in] list Pointer to list.
+ *
+ *****************************************************************************/
+void
+SalList_del(sal_list_t **head_list, sal_list_t **pre_list, sal_list_t *list);
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Returns pObj element in list structure.
+ *
+ * @description
+ * Returns pObj associated with sal_list_t structure.
+ *
+ * @param[in] list Pointer to list element.
+ * @retval void* pObj member of list structure.
+ *
+ *****************************************************************************/
+void *SalList_getObject(sal_list_t *list);
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Set pObj to be NULL in the list.
+ *
+ * @description
+ * Set pObj of a element in the list to be NULL.
+ *
+ * @param[in] list Pointer to list element.
+ *
+ *****************************************************************************/
+void SalList_delObject(sal_list_t **list);
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Returns next element in list structure.
+ *
+ * @description
+ * Returns next associated with sal_list_t structure.
+ *
+ * @param[in] list Pointer to list element.
+ * @retval void* next member of list structure.
+ *
+ *****************************************************************************/
+void *SalList_next(sal_list_t *);
+
+/**
+*******************************************************************************
+ * @ingroup SalList
+ * Frees memory associated with list structure.
+ *
+ * @description
+ * Frees memory associated with list structure and the Obj pointed to by
+ * the list.
+ *
+ * @param[in] list Pointer to list.
+ *
+ *****************************************************************************/
+void SalList_free(sal_list_t **);
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/lac_log.h b/sys/dev/qat/qat_api/common/include/lac_log.h
new file mode 100644
index 000000000000..2593c7b54963
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_log.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_log.h
+ *
+ * @defgroup LacLog Log
+ *
+ * @ingroup LacCommon
+ *
+ * Logging Macros. These macros also log the function name they are called in.
+ *
+ ***************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_LOG_H
+#define LAC_LOG_H
+
+/***************************************************************************
+ * Include public/global header files
+ ***************************************************************************/
+#include "cpa.h"
+#include "lac_common.h"
+#include "icp_accel_devices.h"
+
+#define LAC_INVALID_PARAM_LOG_(log, args...) \
+ QAT_UTILS_LOG("[error] %s() - : Invalid API Param - " log "\n", \
+ __func__, \
+ ##args)
+
+#define LAC_INVALID_PARAM_LOG(log) LAC_INVALID_PARAM_LOG_(log)
+
+#define LAC_INVALID_PARAM_LOG1(log, param1) LAC_INVALID_PARAM_LOG_(log, param1)
+
+#define LAC_INVALID_PARAM_LOG2(log, param1, param2) \
+ LAC_INVALID_PARAM_LOG_(log, param1, param2)
+
+#define LAC_UNSUPPORTED_PARAM_LOG(log) \
+ QAT_UTILS_LOG("%s() - : UnSupported API Param - " log "\n", __func__)
+
+#define LAC_LOG_ERROR(log) QAT_UTILS_LOG("%s() - : " log "\n", __func__)
+
+#endif /* LAC_LOG_H */
diff --git a/sys/dev/qat/qat_api/common/include/lac_mem.h b/sys/dev/qat/qat_api/common/include/lac_mem.h
new file mode 100644
index 000000000000..39be4d9ba651
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_mem.h
@@ -0,0 +1,577 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_mem.h
+ *
+ * @defgroup LacMem Memory
+ *
+ * @ingroup LacCommon
+ *
+ * Memory re-sizing functions and memory accessor macros.
+ *
+ ***************************************************************************/
+
+#ifndef LAC_MEM_H
+#define LAC_MEM_H
+
+/***************************************************************************
+ * Include header files
+ ***************************************************************************/
+#include "cpa.h"
+#include "qat_utils.h"
+#include "lac_common.h"
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * These macros are used to Endian swap variables from IA to QAT.
+ *
+ * @param[out] x The variable to be swapped.
+ *
+ * @retval none
+ ******************************************************************************/
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define LAC_MEM_WR_64(x) QAT_UTILS_HOST_TO_NW_64(x)
+#define LAC_MEM_WR_32(x) QAT_UTILS_HOST_TO_NW_32(x)
+#define LAC_MEM_WR_16(x) QAT_UTILS_HOST_TO_NW_16(x)
+#define LAC_MEM_RD_64(x) QAT_UTILS_NW_TO_HOST_64(x)
+#define LAC_MEM_RD_32(x) QAT_UTILS_NW_TO_HOST_32(x)
+#define LAC_MEM_RD_16(x) QAT_UTILS_NW_TO_HOST_16(x)
+#else
+#define LAC_MEM_WR_64(x) (x)
+#define LAC_MEM_WR_32(x) (x)
+#define LAC_MEM_WR_16(x) (x)
+#define LAC_MEM_RD_64(x) (x)
+#define LAC_MEM_RD_32(x) (x)
+#define LAC_MEM_RD_16(x) (x)
+#endif
+
+/*
+*******************************************************************************
+* Shared Memory Macros (memory accessible by Acceleration Engines, e.g. QAT)
+*******************************************************************************
+*/
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to write to a variable that will be read by the
+ * QAT. The macro will automatically detect the size of the target variable and
+ * will select the correct method for performing the write. The data is cast to
+ * the type of the field that it will be written to.
+ * This macro swaps data if required.
+ *
+ * @param[out] var The variable to be written. Can be a field of a struct.
+ *
+ * @param[in] data The value to be written. Will be cast to the size of the
+ * target.
+ *
+ * @retval none
+ ******************************************************************************/
+#define LAC_MEM_SHARED_WRITE_SWAP(var, data) \
+ do { \
+ switch (sizeof(var)) { \
+ case 1: \
+ (var) = (Cpa8U)(data); \
+ break; \
+ case 2: \
+ (var) = (Cpa16U)(data); \
+ (var) = LAC_MEM_WR_16(((Cpa16U)var)); \
+ break; \
+ case 4: \
+ (var) = (Cpa32U)(data); \
+ (var) = LAC_MEM_WR_32(((Cpa32U)var)); \
+ break; \
+ case 8: \
+ (var) = (Cpa64U)(data); \
+ (var) = LAC_MEM_WR_64(((Cpa64U)var)); \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to read a variable that was written by the QAT.
+ * The macro will automatically detect the size of the data to be read and will
+ * select the correct method for performing the read. The value read from the
+ * variable is cast to the size of the data type it will be stored in.
+ * This macro swaps data if required.
+ *
+ * @param[in] var The variable to be read. Can be a field of a struct.
+ *
+ * @param[out] data The variable to hold the result of the read. Data read
+ * will be cast to the size of this variable
+ *
+ * @retval none
+ ******************************************************************************/
+#define LAC_MEM_SHARED_READ_SWAP(var, data) \
+ do { \
+ switch (sizeof(var)) { \
+ case 1: \
+ (data) = (var); \
+ break; \
+ case 2: \
+ (data) = LAC_MEM_RD_16(((Cpa16U)var)); \
+ break; \
+ case 4: \
+ (data) = LAC_MEM_RD_32(((Cpa32U)var)); \
+ break; \
+ case 8: \
+ (data) = LAC_MEM_RD_64(((Cpa64U)var)); \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to write a pointer to a QAT request. The fields
+ * for pointers in the QAT request and response messages are always 64 bits
+ *
+ * @param[out] var The variable to be written to. Can be a field of a struct.
+ *
+ * @param[in] data The value to be written. Will be cast to size of target
+ * variable
+ *
+ * @retval none
+ ******************************************************************************/
+/* cast pointer to scalar of same size of the native pointer */
+#define LAC_MEM_SHARED_WRITE_FROM_PTR(var, data) \
+ ((var) = (Cpa64U)(LAC_ARCH_UINT)(data))
+
+/* Note: any changes to this macro implementation should also be made to the
+ * similar LAC_MEM_CAST_PTR_TO_UINT64 macro
+ */
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to read a pointer from a QAT response. The fields
+ * for pointers in the QAT request and response messages are always 64 bits
+ *
+ * @param[in] var The variable to be read. Can be a field of a struct.
+ *
+ * @param[out] data The variable to hold the result of the read. Data read
+ * will be cast to the size of this variable
+ *
+ * @retval none
+ ******************************************************************************/
+/* Cast back to native pointer */
+#define LAC_MEM_SHARED_READ_TO_PTR(var, data) \
+ ((data) = (void *)(LAC_ARCH_UINT)(var))
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro safely casts a pointer to a Cpa64U type.
+ *
+ * @param[in] pPtr The pointer to be cast.
+ *
+ * @retval pointer cast to Cpa64U
+ ******************************************************************************/
+#define LAC_MEM_CAST_PTR_TO_UINT64(pPtr) ((Cpa64U)(pPtr))
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro uses an QAT Utils macro to convert from a virtual address to
+ *a
+ * physical address for internally allocated memory.
+ *
+ * @param[in] pVirtAddr The address to be converted.
+ *
+ * @retval The converted physical address
+ ******************************************************************************/
+#define LAC_OS_VIRT_TO_PHYS_INTERNAL(pVirtAddr) \
+ (QAT_UTILS_MMU_VIRT_TO_PHYS(pVirtAddr))
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro should be called on all externally allocated memory it calls
+ * SalMem_virt2PhysExternal function which allows a user
+ * to set the virt2phys function used by an instance.
+ * Defaults to virt to phys for kernel.
+ *
+ * @param[in] genService Generic sal_service_t structure.
+ * @param[in] pVirtAddr The address to be converted.
+ *
+ * @retval The converted physical address
+ ******************************************************************************/
+#define LAC_OS_VIRT_TO_PHYS_EXTERNAL(genService, pVirtAddr) \
+ ((SalMem_virt2PhysExternal(pVirtAddr, &(genService))))
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to write an address variable that will be read by
+ * the QAT. The macro will perform the necessary virt2phys address translation
+ * This macro is only to be called on memory allocated internally by the driver.
+ *
+ * @param[out] var The address variable to write. Can be a field of a struct.
+ *
+ * @param[in] pPtr The pointer variable to containing the address to be
+ * written
+ *
+ * @retval none
+ ******************************************************************************/
+#define LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_INTERNAL(var, pPtr) \
+ do { \
+ Cpa64U physAddr = 0; \
+ physAddr = LAC_MEM_CAST_PTR_TO_UINT64( \
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pPtr)); \
+ var = physAddr; \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This macro can be used to write an address variable that will be read by
+ * the QAT. The macro will perform the necessary virt2phys address translation
+ * This macro is to be used on memory allocated externally by the user. It calls
+ * the user supplied virt2phys address translation.
+ *
+ * @param[in] pService The pointer to the service
+ * @param[out] var The address variable to write. Can be a field of a struct
+ * @param[in] pPtr The pointer variable to containing the address to be
+ * written
+ *
+ * @retval none
+ ******************************************************************************/
+#define LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(pService, var, pPtr) \
+ do { \
+ Cpa64U physAddr = 0; \
+ physAddr = LAC_MEM_CAST_PTR_TO_UINT64( \
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService, pPtr)); \
+ var = physAddr; \
+ } while (0)
+
+/*
+*******************************************************************************
+* OS Memory Macros
+*******************************************************************************
+*/
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This function and associated macro allocates the memory for the given
+ * size and stores the address of the memory allocated in the pointer.
+ *
+ * @param[out] ppMemAddr address of pointer where address will be stored
+ * @param[in] sizeBytes the size of the memory to be allocated.
+ *
+ * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory
+ * @retval CPA_STATUS_SUCCESS Macro executed successfully
+ *
+ ******************************************************************************/
+static __inline CpaStatus
+LacMem_OsMemAlloc(void **ppMemAddr, Cpa32U sizeBytes)
+{
+ *ppMemAddr = malloc(sizeBytes, M_QAT, M_WAITOK);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This function and associated macro allocates the contiguous
+ * memory for the given
+ * size and stores the address of the memory allocated in the pointer.
+ *
+ * @param[out] ppMemAddr address of pointer where address will be stored
+ * @param[in] sizeBytes the size of the memory to be allocated.
+ * @param[in] alignmentBytes the alignment
+ * @param[in] node node to allocate from
+ *
+ * @retval CPA_STATUS_RESOURCE Macro failed to allocate Memory
+ * @retval CPA_STATUS_SUCCESS Macro executed successfully
+ *
+ ******************************************************************************/
+static __inline CpaStatus
+LacMem_OsContigAlignMemAlloc(void **ppMemAddr,
+ Cpa32U sizeBytes,
+ Cpa32U alignmentBytes,
+ Cpa32U node)
+{
+ if ((alignmentBytes & (alignmentBytes - 1)) !=
+ 0) /* if is not power of 2 */
+ {
+ *ppMemAddr = NULL;
+ QAT_UTILS_LOG("alignmentBytes MUST be the power of 2\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ *ppMemAddr =
+ qatUtilsMemAllocContiguousNUMA(sizeBytes, node, alignmentBytes);
+
+ if (NULL == *ppMemAddr) {
+ return CPA_STATUS_RESOURCE;
+ }
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * Macro from the malloc() function
+ *
+ ******************************************************************************/
+#define LAC_OS_MALLOC(sizeBytes) malloc(sizeBytes, M_QAT, M_WAITOK)
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * Macro from the LacMem_OsContigAlignMemAlloc function
+ *
+ ******************************************************************************/
+#define LAC_OS_CAMALLOC(ppMemAddr, sizeBytes, alignmentBytes, node) \
+ LacMem_OsContigAlignMemAlloc((void *)ppMemAddr, \
+ sizeBytes, \
+ alignmentBytes, \
+ node)
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * Macro for declaration static const unsigned int constant. One provides
+ * the compilation time computation with the highest bit set in the
+ * sizeof(TYPE) value. The constant is being put by the linker by default in
+ * .rodata section
+ *
+ * E.g. Statement LAC_DECLARE_HIGHEST_BIT_OF(lac_mem_blk_t)
+ * results in following entry:
+ * static const unsigned int highest_bit_of_lac_mem_blk_t = 3
+ *
+ * CAUTION!!
+ * Macro is prepared only for type names NOT-containing ANY
+ * special characters. Types as amongst others:
+ * - void *
+ * - unsigned long
+ * - unsigned int
+ * are strictly forbidden and will result in compilation error.
+ * Use typedef to provide one-word type name for MACRO's usage.
+ ******************************************************************************/
+#define LAC_DECLARE_HIGHEST_BIT_OF(TYPE) \
+ static const unsigned int highest_bit_of_##TYPE = \
+ (sizeof(TYPE) & 0x80000000 ? 31 : (sizeof(TYPE) & 0x40000000 ? 30 : (sizeof(TYPE) & 0x20000000 ? 29 : ( \
+ sizeof(TYPE) & 0x10000000 ? 28 : ( \
+ sizeof(TYPE) & 0x08000000 ? 27 : ( \
+ sizeof(TYPE) & 0x04000000 ? 26 : ( \
+ sizeof(TYPE) & 0x02000000 ? 25 : ( \
+ sizeof(TYPE) & 0x01000000 ? 24 : ( \
+ sizeof(TYPE) & 0x00800000 ? \
+ 23 : \
+ (sizeof(TYPE) & 0x00400000 ? 22 : ( \
+ sizeof( \
+ TYPE) & \
+ 0x00200000 ? \
+ 21 : \
+ ( \
+ sizeof(TYPE) & 0x00100000 ? 20 : (sizeof(TYPE) & 0x00080000 ? 19 : ( \
+ sizeof( \
+ TYPE) & \
+ 0x00040000 ? \
+ 18 : \
+ ( \
+ sizeof(TYPE) & 0x00020000 ? 17 : ( \
+ sizeof(TYPE) & 0x00010000 ? 16 : (sizeof(TYPE) & \
+ 0x00008000 ? \
+ 15 : \
+ (sizeof(TYPE) & 0x00004000 ? 14 : ( \
+ sizeof(TYPE) & 0x00002000 ? 13 : \
+ ( \
+ sizeof(TYPE) & 0x00001000 ? 12 : ( \
+ sizeof(TYPE) & 0x00000800 ? 11 : ( \
+ sizeof(TYPE) & 0x00000400 ? 10 : \
+ ( \
+ sizeof(TYPE) & \
+ 0x00000200 ? \
+ 9 : \
+ (sizeof( \
+ TYPE) & \
+ 0x00000100 ? \
+ 8 : \
+ (sizeof(TYPE) & 0x00000080 ? 7 : \
+ ( \
+ sizeof(TYPE) & 0x00000040 ? \
+ 6 : \
+ ( \
+ sizeof(TYPE) & 0x00000020 ? 5 : \
+ ( \
+ sizeof(TYPE) & 0x00000010 ? 4 : \
+ ( \
+ sizeof(TYPE) & 0x00000008 ? 3 : \
+ ( \
+ sizeof(TYPE) & 0x00000004 ? 2 : \
+ ( \
+ sizeof(TYPE) & 0x00000002 ? 1 : ( \
+ sizeof(TYPE) & 0x00000001 ? 0 : 32))))))))))))))))) /*16*/))))))))))))))) /* 31 */
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This function and associated macro frees the memory at the given address
+ * and resets the pointer to NULL
+ *
+ * @param[out] ppMemAddr address of pointer where mem address is stored.
+ * If pointer is NULL, the function will exit silently
+ *
+ * @retval void
+ *
+ ******************************************************************************/
+static __inline void
+LacMem_OsMemFree(void **ppMemAddr)
+{
+ free(*ppMemAddr, M_QAT);
+ *ppMemAddr = NULL;
+}
+
+/**
+ *******************************************************************************
+ * @ingroup LacMem
+ * This function and associated macro frees the contiguous memory at the
+ * given address and resets the pointer to NULL
+ *
+ * @param[out] ppMemAddr address of pointer where mem address is stored.
+ * If pointer is NULL, the function will exit silently
+ *
+ * @retval void
+ *
+ ******************************************************************************/
+static __inline void
+LacMem_OsContigAlignMemFree(void **ppMemAddr)
+{
+ if (NULL != *ppMemAddr) {
+ qatUtilsMemFreeNUMA(*ppMemAddr);
+ *ppMemAddr = NULL;
+ }
+}
+
+#define LAC_OS_FREE(pMemAddr) LacMem_OsMemFree((void *)&pMemAddr)
+
+#define LAC_OS_CAFREE(pMemAddr) LacMem_OsContigAlignMemFree((void *)&pMemAddr)
+
+/**
+*******************************************************************************
+ * @ingroup LacMem
+ * Copies user data to a working buffer of the correct size (required by
+ * PKE services)
+ *
+ * @description
+ * This function produces a correctly sized working buffer from the input
+ * user buffer. If the original buffer is too small a new buffer shall
+ * be allocated and memory is copied (left padded with zeros to the
+*required
+ * length).
+ *
+ * The returned working buffer is guaranteed to be of the desired size for
+ * QAT.
+ *
+ * When this function is called pInternalMem describes the user_buffer and
+ * when the function returns pInternalMem describes the working buffer.
+ * This is because pInternalMem describes the memory that will be sent to
+ * QAT.
+ *
+ * The caller must keep the original buffer pointer. The alllocated buffer
+*is
+ * freed (as necessary) using icp_LacBufferRestore().
+ *
+ * @param[in] instanceHandle Handle to crypto instance so pke_resize mem pool
+*can
+ * be located
+ * @param[in] pUserBuffer Pointer on the user buffer
+ * @param[in] userLen length of the user buffer
+ * @param[in] workingLen length of the working (correctly sized) buffer
+ * @param[in/out] pInternalMem pointer to boolean if TRUE on input then
+ * user_buffer is internally allocated memory
+ * if false then it is externally allocated.
+ * This value gets updated by the function
+ * if the returned pointer references internally
+ * allocated memory.
+ *
+ * @return a pointer to the working (correctly sized) buffer or NULL if the
+ * allocation failed
+ *
+ * @note the working length cannot be smaller than the user buffer length
+ *
+ * @warning the working buffer may be the same or different from the original
+ * user buffer; the caller should make no assumptions in this regard
+ *
+ * @see icp_LacBufferRestore()
+ *
+ ******************************************************************************/
+Cpa8U *icp_LacBufferResize(CpaInstanceHandle instanceHandle,
+ Cpa8U *pUserBuffer,
+ Cpa32U userLen,
+ Cpa32U workingLen,
+ CpaBoolean *pInternalMemory);
+
+/**
+*******************************************************************************
+ * @ingroup LacMem
+ * Restores a user buffer
+ *
+ * @description
+ * This function restores a user buffer and releases its
+ * corresponding working buffer. The working buffer, assumed to be
+ * previously obtained using icp_LacBufferResize(), is freed as necessary.
+ *
+ * The contents are copied in the process.
+ *
+ * @note the working length cannot be smaller than the user buffer length
+ *
+ * @param[out] pUserBuffer Pointer on the user buffer
+ * @param[in] userLen length of the user buffer
+ * @param[in] pWorkingBuffer Pointer on the working buffer
+ * @param[in] workingLen working buffer length
+ * @param[in] copyBuf if set _TRUE the data in the workingBuffer
+ * will be copied to the userBuffer before the
+ * workingBuffer is freed.
+ *
+ * @return the status of the operation
+ *
+ * @see icp_LacBufferResize()
+ *
+ ******************************************************************************/
+CpaStatus icp_LacBufferRestore(Cpa8U *pUserBuffer,
+ Cpa32U userLen,
+ Cpa8U *pWorkingBuffer,
+ Cpa32U workingLen,
+ CpaBoolean copyBuf);
+
+/**
+*******************************************************************************
+ * @ingroup LacMem
+ * Uses an instance specific user supplied virt2phys function to convert a
+ * virtual address to a physical address.
+ *
+ * @description
+ * Uses an instance specific user supplied virt2phys function to convert a
+ * virtual address to a physical address. A client of QA API can set the
+ * virt2phys function for an instance by using the
+ * cpaXxSetAddressTranslation() function. If the client does not set the
+ * virt2phys function and the instance is in kernel space then OS specific
+ * virt2phys function will be used. In user space the virt2phys function
+ * MUST be set by the user.
+ *
+ * @param[in] pVirtAddr the virtual addr to be converted
+ * @param[in] pServiceGen Pointer on the sal_service_t structure
+ * so client supplied virt2phys function can be
+ * called.
+ *
+ * @return the physical address
+ *
+ ******************************************************************************/
+CpaPhysicalAddr SalMem_virt2PhysExternal(void *pVirtAddr, void *pServiceGen);
+
+#endif /* LAC_MEM_H */
diff --git a/sys/dev/qat/qat_api/common/include/lac_mem_pools.h b/sys/dev/qat/qat_api/common/include/lac_mem_pools.h
new file mode 100644
index 000000000000..e66769e3a265
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_mem_pools.h
@@ -0,0 +1,278 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_mem_pools.h
+ *
+ * @defgroup LacMemPool Memory Pool Mgmt
+ *
+ * @ingroup LacCommon
+ *
+ * Memory Pool creation and mgmt functions
+ *
+ * @lld_start
+ * @lld_overview
+ * This component is designed as a set of utility functions for the
+ * creation of pre-allocated memory pools. Each pool will be created using OS
+ * memory with a user specified number of elements, element size and element
+ * alignment(alignmnet is at byte granularity).
+ * @lld_dependencies
+ * These utilities rely on QAT Utils for locking mechanisms and memory
+ *allocation
+ * @lld_initialisation
+ * Pool creation needs to be done by each component. There is no specific
+ * initialisation required for this feature.
+ * @lld_module_algorithms
+ * The following is a diagram of how the memory is layed out for each block
+ * in a pool. Each element must be aligned on the boundary requested for in the
+ * create call. In order to hide the management of the pools from the user,
+ * the memory block data is hidden prior to the
+ * data pointer. This way it can be accessed easily on a free call with pointer
+ * arithmatic. The Padding at the start is simply there for alignment and is
+ * unused in the pools.
+ *
+ * -------------------------------------------------------
+ *
+ * |Padding |lac_mem_blk_t | client memory |
+ *
+ * @lld_process_context
+ * @lld_end
+ ***************************************************************************/
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ *
+ *
+ ******************************************************************************/
+
+/***************************************************************************/
+
+#ifndef LAC_MEM_POOLS_H
+#define LAC_MEM_POOLS_H
+
+#include "cpa.h"
+#include "lac_common.h"
+struct lac_mem_pool_hdr_s;
+/**< @ingroup LacMemPool
+ * This is a forward declaration of the structure type lac_mem_pool_hdr_s */
+
+typedef LAC_ARCH_UINT lac_memory_pool_id_t;
+/**< @ingroup LacMemPool
+ * Pool ID type to be used by all clients */
+
+/**< @ingroup LacMemPool
+ * This structure is used to link each memory block in the created pool
+ * together and contain the necessary information for deletion of the block
+ */
+typedef struct lac_mem_blk_s {
+ CpaPhysicalAddr physDataPtr;
+ /**< physical address of data pointer for client */
+ void *pMemAllocPtr;
+ /**< virtual address of the memory block actually allocated */
+ CpaBoolean isInUse;
+ /**< indicates if the pool item is in use */
+ struct lac_mem_blk_s *pNext;
+ /**< link to next blcok in the pool */
+ struct lac_mem_pool_hdr_s *pPoolID;
+ /**< identifier of the pool that this block was allocated from */
+} lac_mem_blk_t;
+
+#define LAC_MEM_POOL_VIRT_TO_PHYS(pVirtAddr) \
+ (((lac_mem_blk_t *)((LAC_ARCH_UINT)pVirtAddr - sizeof(lac_mem_blk_t))) \
+ ->physDataPtr)
+/**< @ingroup LacMemPool
+ * macro for retreiving the physical address of the memory block. */
+
+#define LAC_MEM_POOL_INIT_POOL_ID 0
+/**< @ingroup LacMemPool
+ * macro which defines the valid initialisation value for a pool ID. This is
+ * used as a level of abstraction for the user of this interface */
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function creates a memory pool containing a specified number of
+ * elements of specific size and byte alignment. This function is not reentrant
+ * or thread safe and is only intended to be called during initialisation.
+ *
+ * @blocking
+ * Yes
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ * @param[out] poolID on successful creation of a pool this will
+ * be the ID used for all subsequent accesses
+ * @param[in] poolName The name of the memory pool
+ * @param[in] numElementsInPool number of elements to provision in the pool
+ * @param[in] blkSizeInBytes size in bytes of each element in the pool
+ * @param[in] blkAlignmentInBytes byte alignment required for each element
+ * @param[in] trackMemory track the memory in use by this pool
+ * @param[in] node node to allocate from
+ *
+ * @retval CPA_STATUS_INVALID_PARAM invalid input parameter
+ * @retval CPA_STATUS_RESOURCE error in provisioning resources
+ * @retval CPA_STATUS_SUCCESS function executed successfully
+ *
+ ******************************************************************************/
+CpaStatus Lac_MemPoolCreate(lac_memory_pool_id_t *poolID,
+ char *poolName,
+ unsigned int numElementsInPool,
+ unsigned int blkSizeInBytes,
+ unsigned int blkAlignmentInBytes,
+ CpaBoolean trackMemory,
+ Cpa32U node);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function will destroy the memory pool in it's current state. All memory
+ * blocks which have been returned to the memory pool will be de-allocated and
+ * the pool indetifier will be freed and assigned to NULL. It is the
+ * responsibility of the pool creators to return all memory before a destroy or
+ * memory will be leaked.
+ *
+ * @blocking
+ * Yes
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+
+ * @param[in] poolID Pointer to the memory pool to destroy
+ *
+ ******************************************************************************/
+void Lac_MemPoolDestroy(lac_memory_pool_id_t poolID);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function allocates a block from the pool which has been previously
+ * created. It does not check the validity of the pool Id prior to accessing the
+ * pool. It is up to the calling code to ensure the value is correct.
+ *
+ * @blocking
+ * Yes
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ * @param[in] poolID ID of the pool to allocate memory from
+ *
+ * @retval pointer to the memory which has been allocated from the pool
+ *
+ ******************************************************************************/
+void *Lac_MemPoolEntryAlloc(lac_memory_pool_id_t poolID);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function de-allocates the memory passed in back to the pool from which
+ * it was allocated.
+ *
+ * @blocking
+ * Yes
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ * @param[in] entry memory address of the block to be freed
+ *
+ ******************************************************************************/
+void Lac_MemPoolEntryFree(void *entry);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function returns the number of available entries in a particular pool
+ *
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ * @param[in] poolID ID of the pool
+ *
+ * @retval number of elements left for allocation from the pool
+ *
+ ******************************************************************************/
+unsigned int Lac_MemPoolAvailableEntries(lac_memory_pool_id_t poolID);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function displays the stats associated with the memory pools
+ *
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ *
+ ******************************************************************************/
+void Lac_MemPoolStatsShow(void);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function initialises the physical addresses of the symmetric cookie
+ *
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ * @param[in] poolID ID of the pool
+ *
+ * @retval CPA_STATUS_FAIL function failed
+ * @retval CPA_STATUS_SUCCESS function executed successfully
+ *
+ ******************************************************************************/
+CpaStatus Lac_MemPoolInitSymCookiesPhyAddr(lac_memory_pool_id_t poolID);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function populates all PKE requests with instance constant parameters
+ *
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ * @param[in] poolID ID of the pool
+ * @param[in] instanceHandle instanceHandle
+ *
+ * @retval CPA_STATUS_FAIL function failed
+ * @retval CPA_STATUS_SUCCESS function executed successfully
+ *
+ ******************************************************************************/
+CpaStatus Lac_MemPoolInitAsymCookies(lac_memory_pool_id_t poolID,
+ CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function initialises the physical addresses of the compression cookie
+ *
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ * @param[in] poolID ID of the pool
+ *
+ * @retval CPA_STATUS_FAIL function failed
+ * @retval CPA_STATUS_SUCCESS function executed successfully
+ *
+ ******************************************************************************/
+CpaStatus Lac_MemPoolInitDcCookiePhyAddr(lac_memory_pool_id_t poolID);
+
+#endif /*LAC_MEM_POOLS_H*/
diff --git a/sys/dev/qat/qat_api/common/include/lac_module.h b/sys/dev/qat/qat_api/common/include/lac_module.h
new file mode 100644
index 000000000000..8fe95c2e4cf5
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_module.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+#ifndef __LAC_MODULE_H__
+#define __LAC_MODULE_H__
+
+#include "icp_qat_hw.h"
+
+/* Lac module getter/setter for TUNABLE_INT in lac_module.c */
+icp_qat_hw_auth_mode_t Lac_GetQatHmacMode(void);
+void Lac_SetQatHmacMode(const icp_qat_hw_auth_mode_t);
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/lac_sal.h b/sys/dev/qat/qat_api/common/include/lac_sal.h
new file mode 100644
index 000000000000..0c431dd688e4
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_sal.h
@@ -0,0 +1,498 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file lac_sal.h
+ *
+ * @defgroup SalCtrl Service Access Layer Controller
+ *
+ * @ingroup SalCtrl
+ *
+ * @description
+ * These functions are the functions to be executed for each state
+ * of the state machine for each service.
+ *
+ *****************************************************************************/
+
+#ifndef LAC_SAL_H
+#define LAC_SAL_H
+
+#include "cpa_cy_im.h"
+
+/**
+*******************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function allocates memory for a specific instance type.
+ * Zeros this memory and sets the generic service section of
+ * the instance memory.
+ *
+ * @context
+ * This function is called from the generic services init.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] service The type of the service to be created
+ * (e.g. CRYPTO)
+ * @param[in] instance_num The logical instance number which will
+ * run the service
+ * @param[out] pObj Pointer to specific service instance memory
+ * @retVal CPA_STATUS_SUCCESS Instance memory successfully allocated
+ * @retVal CPA_STATUS_RESOURCE Instance memory not successfully allocated
+ * @retVal CPA_STATUS_FAIL Unsupported service type
+ *
+ *****************************************************************************/
+CpaStatus SalCtrl_ServiceCreate(sal_service_type_t service,
+ Cpa32U instance_num,
+ sal_service_t **pObj);
+
+/**
+*******************************************************************************
+ * @ingroup SalCtl
+ * @description
+ * This macro goes through the 'list' passed in as a parameter. For each
+ * element found in the list, it peforms a cast to the type of the element
+ * given by the 'type' parameter. Finally, it calls the function given by
+ * the 'function' parameter, passing itself and the device as parameters.
+ *
+ * In case of error (i.e. 'function' does not return _SUCCESS or _RETRY)
+ * processing of the 'list' elements will stop and the status_ret will be
+ * updated.
+ *
+ * In case of _RETRY status_ret will be updated but the 'list'
+ * will continue to be processed. _RETRY is only expected when
+ * 'function' is stop.
+ *
+ * @context
+ * This macro is used by both the service and qat event handlers.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ *
+ * @param[in] list The list of services or qats as a type of list_t
+ * @param[in] type It identifies the type of the object inside the
+ * list: service or qat
+ * @param[in] device The ADF accelerator handle for the device
+ * @param[in] function The function pointer to call
+ * @param[in/out] status_ret If an error occured (i.e. status returned from
+ * function is not _SUCCESS) then status_ret is
+ * overwritten with status returned from function.
+ *
+ *****************************************************************************/
+#define SAL_FOR_EACH(list, type, device, function, status_ret) \
+ do { \
+ sal_list_t *curr_element = list; \
+ CpaStatus status_temp = CPA_STATUS_SUCCESS; \
+ typeof(type) *process = NULL; \
+ while (NULL != curr_element) { \
+ process = \
+ (typeof(type) *)SalList_getObject(curr_element); \
+ status_temp = process->function(device, process); \
+ if ((CPA_STATUS_SUCCESS != status_temp) && \
+ (CPA_STATUS_RETRY != status_temp)) { \
+ status_ret = status_temp; \
+ break; \
+ } else { \
+ if (CPA_STATUS_RETRY == status_temp) { \
+ status_ret = status_temp; \
+ } \
+ } \
+ curr_element = SalList_next(curr_element); \
+ } \
+ } while (0)
+
+/**
+*******************************************************************************
+ * @ingroup SalCtl
+ * @description
+ * This macro goes through the 'list' passed in as a parameter. For each
+ * element found in the list, it peforms a cast to the type of the element
+ * given by the 'type' parameter. Finally, it checks the state of the
+ * element and if it is in state 'state_check' then it calls the
+ * function given by the 'function' parameter, passing itself
+ * and the device as parameters.
+ * If the element is not in 'state_check' it returns from the macro.
+ *
+ * In case of error (i.e. 'function' does not return _SUCCESS)
+ * processing of the 'list' elements will continue.
+ *
+ * @context
+ * This macro is used by both the service and qat event handlers.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ *
+ * @param[in] list The list of services or qats as a type of list_t
+ * @param[in] type It identifies the type of the object
+ * inside the list: service or qat
+ * @param[in] device The ADF accelerator handle for the device
+ * @param[in] function The function pointer to call
+ * @param[in] state_check The state to check for
+ *
+ *****************************************************************************/
+#define SAL_FOR_EACH_STATE(list, type, device, function, state_check) \
+ do { \
+ sal_list_t *curr_element = list; \
+ typeof(type) *process = NULL; \
+ while (NULL != curr_element) { \
+ process = \
+ (typeof(type) *)SalList_getObject(curr_element); \
+ if (process->state == state_check) { \
+ process->function(device, process); \
+ } else { \
+ break; \
+ } \
+ curr_element = SalList_next(curr_element); \
+ } \
+ } while (0)
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to initialize an instance of crypto service.
+ * It creates a crypto instance's memory pools. It calls ADF to create
+ * its required transport handles. It calls the sub crypto service init
+ * functions. Resets the stats.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A crypto instance
+ *
+ *************************************************************************/
+CpaStatus SalCtrl_CryptoInit(icp_accel_dev_t *device, sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to start an instance of crypto service.
+ * It sends the first messages to FW on its crypto instance transport
+ * handles. For asymmetric crypto it verifies the header on the downloaded
+ * MMP library.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStart function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A crypto instance
+ *
+ *************************************************************************/
+CpaStatus SalCtrl_CryptoStart(icp_accel_dev_t *device, sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to stop an instance of crypto service.
+ * It checks for inflight messages to the FW. If no messages are pending
+ * it returns success. If messages are pending it returns retry.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStop function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A crypto instance
+ *
+ *************************************************************************/
+CpaStatus SalCtrl_CryptoStop(icp_accel_dev_t *device, sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to shutdown an instance of crypto service.
+ * It frees resources allocated at initialisation - e.g. frees the
+ * memory pools and ADF transport handles.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventShutdown function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A crypto instance
+ *
+ *************************************************************************/
+CpaStatus SalCtrl_CryptoShutdown(icp_accel_dev_t *device,
+ sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function sets the capability info of crypto instances.
+ *
+ * @context
+ * This function is called from the cpaCyQueryCapabilities and
+ * LacSymSession_ParamCheck function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] service A sal_service_t* type
+ * @param[in] cyCapabilityInfo A CpaCyCapabilitiesInfo* type
+ *
+ *************************************************************************/
+void SalCtrl_CyQueryCapabilities(sal_service_t *pGenericService,
+ CpaCyCapabilitiesInfo *pCapInfo);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to initialize an instance of compression service.
+ * It creates a compression instance's memory pools. It calls ADF to create
+ * its required transport handles. It zeros an instances stats.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A compression instance
+ *
+ *************************************************************************/
+
+CpaStatus SalCtrl_CompressionInit(icp_accel_dev_t *device,
+ sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to start an instance of compression service.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStart function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A compression instance
+ *
+ *************************************************************************/
+
+CpaStatus SalCtrl_CompressionStart(icp_accel_dev_t *device,
+ sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to stop an instance of compression service.
+ * It checks for inflight messages to the FW. If no messages are pending
+ * it returns success. If messages are pending it returns retry.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventStop function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A compression instance
+ *
+ *************************************************************************/
+
+CpaStatus SalCtrl_CompressionStop(icp_accel_dev_t *device,
+ sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to shutdown an instance of compression service.
+ * It frees resources allocated at initialisation - e.g. frees the
+ * memory pools and ADF transport handles.
+ *
+ * @context
+ * This function is called from the SalCtrl_ServiceEventShutdown function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No (ADF ensures that this function doesn't need to be thread safe)
+ *
+ * @param[in] device An icp_accel_dev_t* type
+ * @param[in] service A compression instance
+ *
+ *************************************************************************/
+
+CpaStatus SalCtrl_CompressionShutdown(icp_accel_dev_t *device,
+ sal_service_t *service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to get the number of services enabled
+ * from the config table.
+ *
+ * @context
+ * This function is called from the SalCtrl_QatInit
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ *
+ * param[in] device An icp_accel_dev_t* type
+ * param[in] pEnabledServices pointer to a variable used to store
+ * the enabled services
+ *
+ *************************************************************************/
+
+CpaStatus SalCtrl_GetEnabledServices(icp_accel_dev_t *device,
+ Cpa32U *pEnabledServices);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check if a service is enabled
+ *
+ * @context
+ * This function is called from the SalCtrl_QatInit
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] enabled_services
+ * param[in] service
+ *
+ *************************************************************************/
+
+CpaBoolean SalCtrl_IsServiceEnabled(Cpa32U enabled_services,
+ sal_service_type_t service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check if a service is supported on the device
+ * The key difference between this and SalCtrl_GetSupportedServices() is
+ * that the latter treats it as an error if the service is unsupported.
+ *
+ * @context
+ * This can be called anywhere.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] device
+ * param[in] service service or services to check
+ *
+ *************************************************************************/
+CpaBoolean SalCtrl_IsServiceSupported(icp_accel_dev_t *device,
+ sal_service_type_t service);
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check whether enabled services has associated
+ * hardware capability support
+ *
+ * @context
+ * This functions is called from the SalCtrl_ServiceEventInit function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * param[in] device A pointer to an icp_accel_dev_t
+ * param[in] enabled_services It is the bitmask for the enabled services
+ *************************************************************************/
+
+CpaStatus SalCtrl_GetSupportedServices(icp_accel_dev_t *device,
+ Cpa32U enabled_services);
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/lac_sal_ctrl.h b/sys/dev/qat/qat_api/common/include/lac_sal_ctrl.h
new file mode 100644
index 000000000000..f6c53928edf1
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_sal_ctrl.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_sal_ctrl.h
+ *
+ * @ingroup SalCtrl
+ *
+ * Functions to register and deregister qat and service controllers with ADF.
+ *
+ ***************************************************************************/
+
+#ifndef LAC_SAL_CTRL_H
+#define LAC_SAL_CTRL_H
+
+/*******************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check whether the service component
+ * has been successfully started.
+ *
+ * @context
+ * This function is called from the icp_sal_userStart() function.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ ******************************************************************/
+
+CpaStatus SalCtrl_AdfServicesStartedCheck(void);
+
+/*******************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to check whether the user's parameter
+ * for concurrent request is valid.
+ *
+ * @context
+ * This function is called when crypto or compression is init
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ *
+ ******************************************************************/
+CpaStatus validateConcurrRequest(Cpa32U numConcurrRequests);
+
+/*******************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to register adf services
+ *
+ * @context
+ * This function is called from do_userStart() function
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ *
+ ******************************************************************/
+CpaStatus SalCtrl_AdfServicesRegister(void);
+
+/*******************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function is used to unregister adf services.
+ *
+ * @context
+ * This function is called from do_userStart() function
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * Yes
+ * @threadSafe
+ * Yes
+ *
+ ******************************************************************/
+CpaStatus SalCtrl_AdfServicesUnregister(void);
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/lac_sal_types.h b/sys/dev/qat/qat_api/common/include/lac_sal_types.h
new file mode 100644
index 000000000000..36e146665787
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_sal_types.h
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_sal_types.h
+ *
+ * @ingroup SalCtrl
+ *
+ * Generic instance type definitions of SAL controller
+ *
+ ***************************************************************************/
+
+#ifndef LAC_SAL_TYPES_H
+#define LAC_SAL_TYPES_H
+
+#include "lac_sync.h"
+#include "lac_list.h"
+#include "icp_accel_devices.h"
+#include "sal_statistics.h"
+#include "icp_adf_debug.h"
+
+#define SAL_CFG_BASE_DEC 10
+#define SAL_CFG_BASE_HEX 16
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Instance States
+ *
+ * @description
+ * An enumeration containing the possible states for an instance.
+ *
+ *****************************************************************************/
+typedef enum sal_service_state_s {
+ SAL_SERVICE_STATE_UNINITIALIZED = 0,
+ SAL_SERVICE_STATE_INITIALIZING,
+ SAL_SERVICE_STATE_INITIALIZED,
+ SAL_SERVICE_STATE_RUNNING,
+ SAL_SERVICE_STATE_SHUTTING_DOWN,
+ SAL_SERVICE_STATE_SHUTDOWN,
+ SAL_SERVICE_STATE_RESTARTING,
+ SAL_SERVICE_STATE_END
+} sal_service_state_t;
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Service Instance Types
+ *
+ * @description
+ * An enumeration containing the possible types for a service.
+ *
+ *****************************************************************************/
+typedef enum {
+ SAL_SERVICE_TYPE_UNKNOWN = 0,
+ /* symmetric and asymmetric crypto service */
+ SAL_SERVICE_TYPE_CRYPTO = 1,
+ /* compression service */
+ SAL_SERVICE_TYPE_COMPRESSION = 2,
+ /* inline service */
+ SAL_SERVICE_TYPE_INLINE = 4,
+ /* asymmetric crypto only service*/
+ SAL_SERVICE_TYPE_CRYPTO_ASYM = 8,
+ /* symmetric crypto only service*/
+ SAL_SERVICE_TYPE_CRYPTO_SYM = 16,
+ SAL_SERVICE_TYPE_QAT = 32
+} sal_service_type_t;
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Generic Instance Container
+ *
+ * @description
+ * Contains all the common information across the different instances.
+ *
+ *****************************************************************************/
+typedef struct sal_service_s {
+ sal_service_type_t type;
+ /**< Service type (e.g. SAL_SERVICE_TYPE_CRYPTO)*/
+
+ Cpa8U state;
+ /**< Status of the service instance
+ (e.g. SAL_SERVICE_STATE_INITIALIZED) */
+
+ Cpa32U instance;
+ /**< Instance number */
+
+ CpaVirtualToPhysical virt2PhysClient;
+ /**< Function pointer to client supplied virt_to_phys */
+
+ CpaStatus (*init)(icp_accel_dev_t *device,
+ struct sal_service_s *service);
+ /**< Function pointer for instance INIT function */
+ CpaStatus (*start)(icp_accel_dev_t *device,
+ struct sal_service_s *service);
+ /**< Function pointer for instance START function */
+ CpaStatus (*stop)(icp_accel_dev_t *device,
+ struct sal_service_s *service);
+ /**< Function pointer for instance STOP function */
+ CpaStatus (*shutdown)(icp_accel_dev_t *device,
+ struct sal_service_s *service);
+ /**< Function pointer for instance SHUTDOWN function */
+
+ CpaCyInstanceNotificationCbFunc notification_cb;
+ /**< Function pointer for instance restarting handler */
+
+ void *cb_tag;
+ /**< Restarting handler priv data */
+
+ sal_statistics_collection_t *stats;
+ /**< Pointer to device statistics configuration */
+
+ void *debug_parent_dir;
+ /**< Pointer to parent proc dir entry */
+
+ CpaBoolean is_dyn;
+
+ Cpa32U capabilitiesMask;
+ /**< Capabilities mask of the device */
+
+ Cpa32U dcExtendedFeatures;
+ /**< Bit field of features. I.e. Compress And Verify */
+
+ CpaBoolean isInstanceStarted;
+ /**< True if user called StartInstance on this instance */
+
+ CpaBoolean integrityCrcCheck;
+ /** < True if the device supports end to end data integrity checks */
+} sal_service_t;
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * SAL structure
+ *
+ * @description
+ * Contains lists to crypto and compression instances.
+ *
+ *****************************************************************************/
+typedef struct sal_s {
+ sal_list_t *crypto_services;
+ /**< Container of sal_crypto_service_t */
+ sal_list_t *asym_services;
+ /**< Container of sal_asym_service_t */
+ sal_list_t *sym_services;
+ /**< Container of sal_sym_service_t */
+ sal_list_t *compression_services;
+ /**< Container of sal_compression_service_t */
+ debug_dir_info_t *cy_dir;
+ /**< Container for crypto proc debug */
+ debug_dir_info_t *asym_dir;
+ /**< Container for asym proc debug */
+ debug_dir_info_t *sym_dir;
+ /**< Container for sym proc debug */
+ debug_dir_info_t *dc_dir;
+ /**< Container for compression proc debug */
+ debug_file_info_t *ver_file;
+ /**< Container for version debug file */
+} sal_t;
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * SAL debug structure
+ *
+ * @description
+ * Service debug handler
+ *
+ *****************************************************************************/
+typedef struct sal_service_debug_s {
+ icp_accel_dev_t *accel_dev;
+ debug_file_info_t debug_file;
+} sal_service_debug_t;
+
+/**
+ *******************************************************************************
+ * @ingroup SalCtrl
+ * This macro verifies that the right service type has been passed in.
+ *
+ * @param[in] pService pointer to service instance
+ * @param[in] service_type service type to check againstx.
+ *
+ * @return CPA_STATUS_FAIL Parameter is incorrect type
+ *
+ ******************************************************************************/
+#define SAL_CHECK_INSTANCE_TYPE(pService, service_type) \
+ do { \
+ sal_service_t *pGenericService = NULL; \
+ pGenericService = (sal_service_t *)pService; \
+ if (!(service_type & pGenericService->type)) { \
+ QAT_UTILS_LOG("Instance handle type is incorrect.\n"); \
+ return CPA_STATUS_FAIL; \
+ } \
+ } while (0)
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/lac_sal_types_crypto.h b/sys/dev/qat/qat_api/common/include/lac_sal_types_crypto.h
new file mode 100644
index 000000000000..c7db231260ed
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_sal_types_crypto.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+
+/**
+ ***************************************************************************
+ * @file lac_sal_types_crypto.h
+ *
+ * @ingroup SalCtrl
+ *
+ * Generic crypto instance type definition
+ *
+ ***************************************************************************/
+
+#ifndef LAC_SAL_TYPES_CRYPTO_H_
+#define LAC_SAL_TYPES_CRYPTO_H_
+
+#include "lac_sym_qat_hash_defs_lookup.h"
+#include "lac_sym_key.h"
+#include "cpa_cy_sym_dp.h"
+
+#include "icp_adf_debug.h"
+#include "lac_sal_types.h"
+#include "icp_adf_transport.h"
+#include "lac_mem_pools.h"
+
+#define LAC_PKE_FLOW_ID_TAG 0xFFFFFFFC
+#define LAC_PKE_ACCEL_ID_BIT_POS 1
+#define LAC_PKE_SLICE_ID_BIT_POS 0
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Crypto specific Service Container
+ *
+ * @description
+ * Contains information required per crypto service instance.
+ *
+ *****************************************************************************/
+typedef struct sal_crypto_service_s {
+ sal_service_t generic_service_info;
+ /**< An instance of the Generic Service Container */
+
+ lac_memory_pool_id_t lac_sym_cookie_pool;
+ /**< Memory pool ID used for symmetric operations */
+ lac_memory_pool_id_t lac_ec_pool;
+ /**< Memory pool ID used for asymmetric operations */
+ lac_memory_pool_id_t lac_prime_pool;
+ /**< Memory pool ID used for asymmetric operations */
+ lac_memory_pool_id_t lac_pke_req_pool;
+ /**< Memory pool ID used for asymmetric operations */
+ lac_memory_pool_id_t lac_pke_align_pool;
+ /**< Memory pool ID used for asymmetric operations */
+
+ QatUtilsAtomic *pLacSymStatsArr;
+ /**< pointer to an array of atomic stats for symmetric */
+
+ QatUtilsAtomic *pLacKeyStats;
+ /**< pointer to an array of atomic stats for key */
+
+ QatUtilsAtomic *pLacDhStatsArr;
+ /**< pointer to an array of atomic stats for DH */
+
+ QatUtilsAtomic *pLacDsaStatsArr;
+ /**< pointer to an array of atomic stats for Dsa */
+
+ QatUtilsAtomic *pLacRsaStatsArr;
+ /**< pointer to an array of atomic stats for Rsa */
+
+ QatUtilsAtomic *pLacEcStatsArr;
+ /**< pointer to an array of atomic stats for Ecc */
+
+ QatUtilsAtomic *pLacEcdhStatsArr;
+ /**< pointer to an array of atomic stats for Ecc DH */
+
+ QatUtilsAtomic *pLacEcdsaStatsArr;
+ /**< pointer to an array of atomic stats for Ecc DSA */
+
+ QatUtilsAtomic *pLacPrimeStatsArr;
+ /**< pointer to an array of atomic stats for prime */
+
+ QatUtilsAtomic *pLacLnStatsArr;
+ /**< pointer to an array of atomic stats for large number */
+
+ QatUtilsAtomic *pLacDrbgStatsArr;
+ /**< pointer to an array of atomic stats for DRBG */
+
+ Cpa32U pkeFlowId;
+ /**< Flow ID for all pke requests from this instance - identifies
+ accelerator
+ and execution engine to use */
+
+ icp_comms_trans_handle trans_handle_sym_tx;
+ icp_comms_trans_handle trans_handle_sym_rx;
+
+ icp_comms_trans_handle trans_handle_asym_tx;
+ icp_comms_trans_handle trans_handle_asym_rx;
+
+ icp_comms_trans_handle trans_handle_nrbg_tx;
+ icp_comms_trans_handle trans_handle_nrbg_rx;
+
+ Cpa32U maxNumSymReqBatch;
+ /**< Maximum number of requests that can be placed on the sym tx ring
+ for any one batch request (DP api) */
+
+ Cpa16U acceleratorNum;
+ Cpa16U bankNum;
+ Cpa16U pkgID;
+ Cpa8U isPolled;
+ Cpa8U executionEngine;
+ Cpa32U coreAffinity;
+ Cpa32U nodeAffinity;
+ /**< Config Info */
+
+ CpaCySymDpCbFunc pSymDpCb;
+ /**< Sym DP Callback */
+
+ lac_sym_qat_hash_defs_t **pLacHashLookupDefs;
+ /**< table of pointers to standard defined information for all hash
+ algorithms. We support an extra hash algo that is not exported by
+ cy api which is why we need the extra +1 */
+ Cpa8U **ppHmacContentDesc;
+ /**< table of pointers to CD for Hmac precomputes - used at session init
+ */
+
+ Cpa8U *pSslLabel;
+ /**< pointer to memory holding the standard SSL label ABBCCC.. */
+
+ lac_sym_key_tls_labels_t *pTlsLabel;
+ /**< pointer to memory holding the 4 standard TLS labels */
+
+ QatUtilsAtomic drbgErrorState;
+ /**< DRBG related variables */
+
+ lac_sym_key_tls_hkdf_sub_labels_t *pTlsHKDFSubLabel;
+ /**< pointer to memory holding the 4 HKDFLabels sublabels */
+
+ debug_file_info_t *debug_file;
+/**< Statistics handler */
+} sal_crypto_service_t;
+
+/*************************************************************************
+ * @ingroup cpaCyCommon
+ * @description
+ * This function returns a valid asym/sym/crypto instance handle for the
+ * system if it exists. When requesting an instance handle of type sym or
+ * asym, if either is not found then a crypto instance handle is returned
+ * if found, since a crypto handle supports both sym and asym services.
+ * Similarly when requesting a crypto instance handle, if it is not found
+ * then an asym or sym crypto instance handle is returned.
+ *
+ * @performance
+ * To avoid calling this function the user of the QA api should not use
+ * instanceHandle = CPA_INSTANCE_HANDLE_SINGLE.
+ *
+ * @context
+ * This function is called whenever instanceHandle =
+ *CPA_INSTANCE_HANDLE_SINGLE
+ * at the QA Cy api.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @param[in] svc_type Type of crypto service requested.
+ *
+ * @retval Pointer to first crypto instance handle or NULL if no crypto
+ * instances in the system.
+ *
+ *************************************************************************/
+
+CpaInstanceHandle Lac_GetFirstHandle(sal_service_type_t svc_type);
+
+#endif /*LAC_SAL_TYPES_CRYPTO_H_*/
diff --git a/sys/dev/qat/qat_api/common/include/lac_sync.h b/sys/dev/qat/qat_api/common/include/lac_sync.h
new file mode 100644
index 000000000000..b842cce30d87
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/lac_sync.h
@@ -0,0 +1,376 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_sync.h
+ *
+ * @defgroup LacSync LAC synchronous
+ *
+ * @ingroup LacCommon
+ *
+ * Function prototypes and defines for synchronous support
+ *
+ ***************************************************************************/
+
+#ifndef LAC_SYNC_H
+#define LAC_SYNC_H
+
+#include "cpa.h"
+#include "qat_utils.h"
+#include "lac_mem.h"
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *
+ * @description
+ * LAC cookie for synchronous support
+ *
+ *****************************************************************************/
+typedef struct lac_sync_op_data_s {
+ struct sema *sid;
+ /**< Semaphore to signal */
+ CpaStatus status;
+ /**< Output - Status of the QAT response */
+ CpaBoolean opResult;
+ /**< Output - Verification of the operation/protocol status */
+ CpaBoolean complete;
+ /**< Output - Operation is complete */
+ CpaBoolean canceled;
+ /**< Output - Operation canceled */
+} lac_sync_op_data_t;
+
+#define LAC_PKE_SYNC_CALLBACK_TIMEOUT (5000)
+/**< @ingroup LacSync
+ * Timeout waiting for an async callbacks in msecs.
+ * This is derived from the max latency of a PKE request + 1 sec
+ */
+
+#define LAC_SYM_DRBG_POLL_AND_WAIT_TIME_MS (10)
+/**< @ingroup LacSyn
+ * Default interval DRBG polling in msecs */
+
+#define LAC_SYM_SYNC_CALLBACK_TIMEOUT (300)
+/**< @ingroup LacSyn
+ * Timeout for wait for symmetric response in msecs
+*/
+
+#define LAC_INIT_MSG_CALLBACK_TIMEOUT (1922)
+/**< @ingroup LacSyn
+ * Timeout for wait for init messages response in msecs
+*/
+
+#define DC_SYNC_CALLBACK_TIMEOUT (1000)
+/**< @ingroup LacSyn
+ * Timeout for wait for compression response in msecs */
+
+#define LAC_SYN_INITIAL_SEM_VALUE (0)
+/**< @ingroup LacSyn
+ * Initial value of the sync waiting semaphore */
+
+/**
+ *******************************************************************************
+ * @ingroup LacSync
+ * This function allocates a sync op data cookie
+ * and creates and initialises the QAT Utils semaphore
+ *
+ * @param[in] ppSyncCallbackCookie Pointer to synch op data
+ *
+ * @retval CPA_STATUS_RESOURCE Failed to allocate the memory for the cookie.
+ * @retval CPA_STATUS_SUCCESS Success
+ *
+ ******************************************************************************/
+static __inline CpaStatus
+LacSync_CreateSyncCookie(lac_sync_op_data_t **ppSyncCallbackCookie)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ *ppSyncCallbackCookie =
+ malloc(sizeof(lac_sync_op_data_t), M_QAT, M_WAITOK);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ status = LAC_INIT_SEMAPHORE((*ppSyncCallbackCookie)->sid,
+ LAC_SYN_INITIAL_SEM_VALUE);
+ (*ppSyncCallbackCookie)->complete = CPA_FALSE;
+ (*ppSyncCallbackCookie)->canceled = CPA_FALSE;
+ }
+
+ if (CPA_STATUS_SUCCESS != status) {
+ LAC_OS_FREE(*ppSyncCallbackCookie);
+ }
+
+ return status;
+}
+
+/**
+ *******************************************************************************
+ * @ingroup LacSync
+ * This macro frees a sync op data cookie and destroys the QAT Utils
+ *semaphore
+ *
+ * @param[in] ppSyncCallbackCookie Pointer to sync op data
+ *
+ * @return void
+ ******************************************************************************/
+static __inline CpaStatus
+LacSync_DestroySyncCookie(lac_sync_op_data_t **ppSyncCallbackCookie)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ /*
+ * If the operation has not completed, cancel it instead of destroying
+ * the
+ * cookie. Otherwise, the callback might panic. In this case, the cookie
+ * will leak, but it's better than a panic.
+ */
+ if (!(*ppSyncCallbackCookie)->complete) {
+ QAT_UTILS_LOG(
+ "Attempting to destroy an incomplete sync cookie\n");
+ (*ppSyncCallbackCookie)->canceled = CPA_TRUE;
+ return CPA_STATUS_FAIL;
+ }
+
+ status = LAC_DESTROY_SEMAPHORE((*ppSyncCallbackCookie)->sid);
+ LAC_OS_FREE(*ppSyncCallbackCookie);
+ return status;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Function which will wait for a sync callback on a given cookie.
+ *
+ * @param[in] pSyncCallbackCookie Pointer to sync op data
+ * @param[in] timeOut Time to wait for callback (msec)
+ * @param[out] pStatus Status returned by the callback
+ * @param[out] pOpStatus Operation status returned by callback.
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_SUCCESS Fail waiting for a callback
+ *
+ *****************************************************************************/
+static __inline CpaStatus
+LacSync_WaitForCallback(lac_sync_op_data_t *pSyncCallbackCookie,
+ Cpa32S timeOut,
+ CpaStatus *pStatus,
+ CpaBoolean *pOpStatus)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ status = LAC_WAIT_SEMAPHORE(pSyncCallbackCookie->sid, timeOut);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ *pStatus = pSyncCallbackCookie->status;
+ if (NULL != pOpStatus) {
+ *pOpStatus = pSyncCallbackCookie->opResult;
+ }
+ pSyncCallbackCookie->complete = CPA_TRUE;
+ }
+
+ return status;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Function which will check for a sync callback on a given cookie.
+ * Returns whether the callback has happened or not, no timeout.
+ *
+ * @param[in] pSyncCallbackCookie Pointer to sync op data
+ * @param[in] timeOut Time to wait for callback (msec)
+ * @param[out] pStatus Status returned by the callback
+ * @param[out] pOpStatus Operation status returned by callback.
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_FAIL Fail waiting for a callback
+ *
+ *****************************************************************************/
+static __inline CpaStatus
+LacSync_CheckForCallback(lac_sync_op_data_t *pSyncCallbackCookie,
+ CpaStatus *pStatus,
+ CpaBoolean *pOpStatus)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ status = LAC_CHECK_SEMAPHORE(pSyncCallbackCookie->sid);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ *pStatus = pSyncCallbackCookie->status;
+ if (NULL != pOpStatus) {
+ *pOpStatus = pSyncCallbackCookie->opResult;
+ }
+ pSyncCallbackCookie->complete = CPA_TRUE;
+ }
+
+ return status;
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Function which will mark a sync cookie as complete.
+ * If it's known that the callback will not happen it's necessary
+ * to call this, else the cookie can't be destroyed.
+ *
+ * @param[in] pSyncCallbackCookie Pointer to sync op data
+ *
+ * @retval CPA_STATUS_SUCCESS Success
+ * @retval CPA_STATUS_FAIL Failed to mark as complete
+ *
+ *****************************************************************************/
+static __inline CpaStatus
+LacSync_SetSyncCookieComplete(lac_sync_op_data_t *pSyncCallbackCookie)
+{
+ CpaStatus status = CPA_STATUS_FAIL;
+
+ if (NULL != pSyncCallbackCookie) {
+ pSyncCallbackCookie->complete = CPA_TRUE;
+ status = CPA_STATUS_SUCCESS;
+ }
+ return status;
+}
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic verify callback function.
+ * @description
+ * This function is used when the API is called in synchronous mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set the
+ * status element of that cookie structure and kick the sid.
+ * This function may be used directly as a callback function.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[out] pOpdata Pointer to the Op Data
+ * @param[out] opResult Boolean to indicate the result of the operation
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenVerifyCb(void *callbackTag,
+ CpaStatus status,
+ void *pOpdata,
+ CpaBoolean opResult);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic flatbuffer callback function.
+ * @description
+ * This function is used when the API is called in synchronous mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set the
+ * status element of that cookie structure and kick the sid.
+ * This function may be used directly as a callback function.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[in] pOpdata Pointer to the Op Data
+ * @param[out] pOut Pointer to the flat buffer
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenFlatBufCb(void *callbackTag,
+ CpaStatus status,
+ void *pOpdata,
+ CpaFlatBuffer *pOut);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic flatbuffer verify callback function.
+ * @description
+ * This function is used when the API is called in synchronous mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set the
+ * status and opResult element of that cookie structure and
+ * kick the sid.
+ * This function may be used directly as a callback function.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[in] pOpdata Pointer to the Op Data
+ * @param[out] opResult Boolean to indicate the result of the operation
+ * @param[out] pOut Pointer to the flat buffer
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenFlatBufVerifyCb(void *callbackTag,
+ CpaStatus status,
+ void *pOpdata,
+ CpaBoolean opResult,
+ CpaFlatBuffer *pOut);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic dual flatbuffer verify callback function.
+ * @description
+ * This function is used when the API is called in synchronous mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set the
+ * status and opResult element of that cookie structure and
+ * kick the sid.
+ * This function may be used directly as a callback function.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[in] pOpdata Pointer to the Op Data
+ * @param[out] opResult Boolean to indicate the result of the operation
+ * @param[out] pOut0 Pointer to the flat buffer
+ * @param[out] pOut1 Pointer to the flat buffer
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenDualFlatBufVerifyCb(void *callbackTag,
+ CpaStatus status,
+ void *pOpdata,
+ CpaBoolean opResult,
+ CpaFlatBuffer *pOut0,
+ CpaFlatBuffer *pOut1);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic wake up function.
+ * @description
+ * This function is used when the API is called in synchronous
+ * mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set
+ * the status element of that cookie structure and kick the
+ * sid.
+ * This function maybe called from an async callback.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenWakeupSyncCaller(void *callbackTag, CpaStatus status);
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ * Generic wake up verify function.
+ * @description
+ * This function is used when the API is called in synchronous
+ * mode.
+ * It's assumed the callbackTag holds a lac_sync_op_data_t type
+ * and when the callback is received, this callback shall set
+ * the status element and the opResult of that cookie structure
+ * and kick the sid.
+ * This function maybe called from an async callback.
+ *
+ * @param[in] callbackTag Callback Tag
+ * @param[in] status Status of callback
+ * @param[out] opResult Boolean to indicate the result of the operation
+ *
+ * @return void
+ *****************************************************************************/
+void LacSync_GenVerifyWakeupSyncCaller(void *callbackTag,
+ CpaStatus status,
+ CpaBoolean opResult);
+
+#endif /*LAC_SYNC_H*/
diff --git a/sys/dev/qat/qat_api/common/include/sal_qat_cmn_msg.h b/sys/dev/qat/qat_api/common/include/sal_qat_cmn_msg.h
new file mode 100644
index 000000000000..8cd7b08e84ea
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/sal_qat_cmn_msg.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_qat_cmn_msg.c
+ *
+ * @ingroup SalQatCmnMessage
+ *
+ * @description
+ * Implementation for populating the common (across services) QAT structures.
+ *
+ *****************************************************************************/
+#ifndef SAL_QAT_CMN_MSG_H
+#define SAL_QAT_CMN_MSG_H
+/*
+ *******************************************************************************
+ * Include public/global header files
+ *******************************************************************************
+ */
+#include "cpa.h"
+
+/*
+ *******************************************************************************
+ * Include private header files
+ *******************************************************************************
+ */
+#include "lac_common.h"
+#include "icp_accel_devices.h"
+#include "qat_utils.h"
+
+#include "cpa_cy_sym.h"
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "lac_list.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_transport_dp.h"
+
+#include "icp_qat_hw.h"
+#include "icp_qat_fw.h"
+#include "icp_qat_fw_la.h"
+
+/**
+ ******************************************************************************
+ * @ingroup SalQatCmnMessage
+ * content descriptor info structure
+ *
+ * @description
+ * This structure contains generic information on the content descriptor
+ *
+ *****************************************************************************/
+typedef struct sal_qat_content_desc_info_s {
+ CpaPhysicalAddr hardwareSetupBlockPhys;
+ /**< Physical address of hardware setup block of the content descriptor
+ */
+ void *pData;
+ /**< Virtual Pointer to the hardware setup block of the content
+ * descriptor */
+ Cpa8U hwBlkSzQuadWords;
+ /**< Hardware Setup Block size in quad words */
+} sal_qat_content_desc_info_t;
+
+/**
+ *******************************************************************************
+ * @ingroup SalQatCmnMessage
+ * Lookaside response handler function type
+ *
+ * @description
+ * This type definition specifies the function prototype for handling the
+ * response messages for a specific symmetric operation
+ *
+ * @param[in] lacCmdId Look Aside Command ID
+ *
+ * @param[in] pOpaqueData Pointer to Opaque Data
+ *
+ * @param[in] cmnRespFlags Common Response flags
+ *
+ * @return void
+ *
+ *****************************************************************************/
+typedef void (*sal_qat_resp_handler_func_t)(icp_qat_fw_la_cmd_id_t lacCmdId,
+ void *pOpaqueData,
+ icp_qat_fw_comn_flags cmnRespFlags);
+
+/********************************************************************
+ * @ingroup SalQatMsg_CmnHdrWrite
+ *
+ * @description
+ * This function fills in all fields in the icp_qat_fw_comn_req_hdr_t
+ * section of the Request Msg. Build LW0 + LW1 -
+ * service part of the request
+ *
+ * @param[in] pMsg Pointer to 128B Request Msg buffer
+ * @param[in] serviceType type of service request
+ * @param[in] serviceCmdId id for the type of service request
+ * @param[in] cmnFlags common request flags
+ * @param[in] serviceCmdFlags service command flahgs
+ *
+ * @return
+ * None
+ *
+ *****************************************/
+void SalQatMsg_CmnHdrWrite(icp_qat_fw_comn_req_t *pMsg,
+ icp_qat_fw_comn_request_id_t serviceType,
+ uint8_t serviceCmdId,
+ icp_qat_fw_comn_flags cmnFlags,
+ icp_qat_fw_serv_specif_flags serviceCmdFlags);
+
+/********************************************************************
+ * @ingroup SalQatMsg_CmnMidWrite
+ *
+ * @description
+ * This function fills in all fields in the icp_qat_fw_comn_req_mid_t
+ * section of the Request Msg and the corresponding SGL/Flat flag
+ * in the Hdr.
+ *
+ * @param[in] pReq Pointer to 128B Request Msg buffer
+ * @param[in] pOpaqueData Pointer to opaque data used by callback
+ * @param[in] bufferFormat src and dst Buffers are either SGL or Flat
+ format
+ * @param[in] pSrcBuffer Address of source buffer
+ * @param[in] pDstBuffer Address of destination buffer
+ * @param[in] pSrcLength Length of source buffer
+ * @param[in] pDstLength Length of destination buffer
+ *
+
+ * @assumptions
+ * All fields in mid section are zero before fn is called
+
+ * @return
+ * None
+ *
+ *****************************************/
+void SalQatMsg_CmnMidWrite(icp_qat_fw_la_bulk_req_t *pReq,
+ const void *pOpaqueData,
+ Cpa8U bufferFormat,
+ Cpa64U srcBuffer,
+ Cpa64U dstBuffer,
+ Cpa32U srcLength,
+ Cpa32U dstLength);
+
+/********************************************************************
+ * @ingroup SalQatMsg_ContentDescHdrWrite
+ *
+ * @description
+ * This function fills in all fields in the
+ *icp_qat_fw_comn_req_hdr_cd_pars_t
+ * section of the Request Msg.
+ *
+ * @param[in] pMsg Pointer to 128B Request Msg buffer.
+ * @param[in] pContentDescInfo content descripter info.
+ *
+ * @return
+ * none
+ *
+ *****************************************/
+void SalQatMsg_ContentDescHdrWrite(
+ icp_qat_fw_comn_req_t *pMsg,
+ const sal_qat_content_desc_info_t *pContentDescInfo);
+
+/********************************************************************
+ * @ingroup SalQatMsg_CtrlBlkSetToReserved
+ *
+ * @description
+ * This function set the whole contrle block to a reserved state.
+ *
+ * @param[in] _pMsg Pointer to 128B Request Msg buffer.
+ *
+ * @return
+ * none
+ *
+ *****************************************/
+void SalQatMsg_CtrlBlkSetToReserved(icp_qat_fw_comn_req_t *_pMsg);
+
+/********************************************************************
+ * @ingroup SalQatMsg_transPutMsg
+ *
+ * @description
+ *
+ *
+ * @param[in] trans_handle
+ * @param[in] pqat_msg
+ * @param[in] size_in_lws
+ * @param[in] service
+ *
+ * @return
+ * CpaStatus
+ *
+ *****************************************/
+CpaStatus SalQatMsg_transPutMsg(icp_comms_trans_handle trans_handle,
+ void *pqat_msg,
+ Cpa32U size_in_lws,
+ Cpa8U service);
+
+/********************************************************************
+ * @ingroup SalQatMsg_updateQueueTail
+ *
+ * @description
+ *
+ *
+ * @param[in] trans_handle
+ *
+ *
+ * @return
+ * CpaStatus
+ *
+ *****************************************/
+void SalQatMsg_updateQueueTail(icp_comms_trans_handle trans_hnd);
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/sal_service_state.h b/sys/dev/qat/qat_api/common/include/sal_service_state.h
new file mode 100644
index 000000000000..3712d38cc3ac
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/sal_service_state.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file sal_service_state.h
+ *
+ * @defgroup SalServiceState
+ *
+ * @ingroup SalCtrl
+ *
+ * Checks state for generic service instance
+ *
+ ***************************************************************************/
+
+#ifndef SAL_SERVICE_STATE_H_
+#define SAL_SERVICE_STATE_H_
+
+/**
+*******************************************************************************
+ * @ingroup SalServiceState
+ * Check to see if the instance is in the running state
+ *
+ * @description
+ * This function checks the state of an instance to see if it is in the
+ * running state
+ *
+ * @param[in] instance Instance handle (assumes this is valid, i.e. checked
+ * before this function is called)
+ * @retval CPA_TRUE Instance in the RUNNING state
+ * @retval CPA_FALSE Instance not in RUNNING state
+ *
+ *****************************************************************************/
+CpaBoolean Sal_ServiceIsRunning(CpaInstanceHandle instanceHandle);
+
+/**
+*******************************************************************************
+ * @ingroup SalServiceState
+ * Check to see if the instance is beign restarted
+ *
+ * @description
+ * This function checks the state of an instance to see if the device it
+ * uses is being restarted because of hardware error.
+ *
+ * @param[in] instance Instance handle (assumes this is valid, i.e. checked
+ * before this function is called)
+ * @retval CPA_TRUE Device the instance is using is restarting.
+ * @retval CPA_FALSE Device the instance is running.
+ *
+ *****************************************************************************/
+CpaBoolean Sal_ServiceIsRestarting(CpaInstanceHandle instanceHandle);
+
+/**
+ *******************************************************************************
+ * @ingroup SalServiceState
+ * This macro checks if an instance is running. An error message is logged
+ * if it is not in a running state.
+ *
+ * @return CPA_STATUS_FAIL Instance not in RUNNING state.
+ * @return void Instance is in RUNNING state.
+ ******************************************************************************/
+#define SAL_RUNNING_CHECK(instanceHandle) \
+ do { \
+ if (unlikely(CPA_TRUE != \
+ Sal_ServiceIsRunning(instanceHandle))) { \
+ if (CPA_TRUE == \
+ Sal_ServiceIsRestarting(instanceHandle)) { \
+ return CPA_STATUS_RESTARTING; \
+ } \
+ QAT_UTILS_LOG("Instance not in a Running state\n"); \
+ return CPA_STATUS_FAIL; \
+ } \
+ } while (0)
+
+/**
+ *******************************************************************************
+ * @ingroup SalServiceState
+ * This macro checks if an instance is in a state to get init event.
+ *
+ * @return CPA_STATUS_FAIL Instance not in good state.
+ * @return void Instance is in good state.
+ ******************************************************************************/
+#define SAL_SERVICE_GOOD_FOR_INIT(instanceHandle) \
+ do { \
+ sal_service_t *pService = (sal_service_t *)instanceHandle; \
+ if ((SAL_SERVICE_STATE_UNINITIALIZED != pService->state) && \
+ (SAL_SERVICE_STATE_RESTARTING != pService->state)) { \
+ QAT_UTILS_LOG( \
+ "Not in the correct state to call init\n"); \
+ return CPA_STATUS_FAIL; \
+ } \
+ } while (0)
+
+#endif /*SAL_SERVICE_STATE_H_*/
diff --git a/sys/dev/qat/qat_api/common/include/sal_statistics.h b/sys/dev/qat/qat_api/common/include/sal_statistics.h
new file mode 100644
index 000000000000..47c08bc6eae5
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/sal_statistics.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_statistics.h
+ *
+ * @ingroup SalStats
+ *
+ * @description
+ * Statistics related defines, structures and functions
+ *
+ *****************************************************************************/
+
+#ifndef SAL_STATISTICS_H
+#define SAL_STATISTICS_H
+
+#include "sal_statistics_strings.h"
+
+#define SAL_STATS_SYM 0
+#define SAL_STATS_DSA 1
+#define SAL_STATS_DSA2 2
+#define SAL_STATS_RSA 3
+#define SAL_STATS_DH 4
+#define SAL_STATS_KEYGEN 5
+#define SAL_STATS_LN 6
+#define SAL_STATS_PRIME 7
+#define SAL_STATS_ECC 8
+#define SAL_STATS_ECDH 9
+#define SAL_STATS_ECDSA 10
+/**< Numeric values for crypto statistics */
+
+#define SAL_STATISTICS_STRING_OFF "0"
+/**< String representing the value for disabled statistics */
+
+/**
+*****************************************************************************
+ * @ingroup SalStats
+ * Structure describing stats enabled/disabled in the system
+ *
+ * @description
+ * Structure describing stats enabled/disabled in the system
+ *
+ *****************************************************************************/
+typedef struct sal_statistics_collection_s {
+ CpaBoolean bStatsEnabled;
+ /**< If CPA_TRUE then statistics functionality is enabled */
+ CpaBoolean bDcStatsEnabled;
+ /**< If CPA_TRUE then Compression statistics are enabled */
+ CpaBoolean bDhStatsEnabled;
+ /**< If CPA_TRUE then Diffie-Helman statistics are enabled */
+ CpaBoolean bDsaStatsEnabled;
+ /**< If CPA_TRUE then DSA statistics are enabled */
+ CpaBoolean bEccStatsEnabled;
+ /**< If CPA_TRUE then ECC statistics are enabled */
+ CpaBoolean bKeyGenStatsEnabled;
+ /**< If CPA_TRUE then Key Gen statistics are enabled */
+ CpaBoolean bLnStatsEnabled;
+ /**< If CPA_TRUE then Large Number statistics are enabled */
+ CpaBoolean bPrimeStatsEnabled;
+ /**< If CPA_TRUE then Prime statistics are enabled */
+ CpaBoolean bRsaStatsEnabled;
+ /**< If CPA_TRUE then RSA statistics are enabled */
+ CpaBoolean bSymStatsEnabled;
+ /**< If CPA_TRUE then Symmetric Crypto statistics are enabled */
+} sal_statistics_collection_t;
+
+/**
+ ******************************************************************************
+ * @ingroup SalStats
+ *
+ * @description
+ * Initializes structure describing which statistics
+ * are enabled for the acceleration device.
+ *
+ * @param[in] device Pointer to an acceleration device structure
+ *
+ * @retval CPA_STATUS_SUCCESS Operation successful
+ * @retval CPA_STATUS_INVALID_PARAM Invalid param provided
+ * @retval CPA_STATUS_RESOURCE Memory alloc failed
+ * @retval CPA_STATUS_FAIL Operation failed
+ *
+ ******************************************************************************/
+CpaStatus SalStatistics_InitStatisticsCollection(icp_accel_dev_t *device);
+
+/**
+ ******************************************************************************
+ * @ingroup SalStats
+ *
+ * @description
+ * Cleans structure describing which statistics
+ * are enabled for the acceleration device.
+ *
+ * @param[in] device Pointer to an acceleration device structure
+ *
+ * @retval CPA_STATUS_SUCCESS Operation successful
+ * @retval CPA_STATUS_INVALID_PARAM Invalid param provided
+ * @retval CPA_STATUS_FAIL Operation failed
+ *
+ ******************************************************************************/
+CpaStatus SalStatistics_CleanStatisticsCollection(icp_accel_dev_t *device);
+#endif
diff --git a/sys/dev/qat/qat_api/common/include/sal_string_parse.h b/sys/dev/qat/qat_api/common/include/sal_string_parse.h
new file mode 100644
index 000000000000..8654f2c09445
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/sal_string_parse.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_string_parse.h
+ *
+ * @defgroup SalStringParse
+ *
+ * @ingroup SalStringParse
+ *
+ * @description
+ * This file contains string parsing functions
+ *
+ *****************************************************************************/
+
+#ifndef SAL_STRING_PARSE_H
+#define SAL_STRING_PARSE_H
+
+/* Maximum size of the strings used by SAL */
+#define SAL_CFG_MAX_VAL_LEN_IN_BYTES 64
+
+/**
+*******************************************************************************
+ * @ingroup SalStringParse
+ * Builds a string and store it in result
+ *
+ * @description
+ * The result string will be the concatenation of string1, instanceNumber
+ * and string2. The size of result has to be SAL_CFG_MAX_VAL_LEN_IN_BYTES.
+ * We can't check this in this function, this is the user responsibility
+ *
+ * @param[in] string1 First string to concatenate
+ * @param[in] instanceNumber Instance number
+ * @param[in] string2 Second string to concatenate
+ * @param[out] result Resulting string of concatenation
+ *
+ * @retval CPA_STATUS_SUCCESS Function executed successfully
+ * @retval CPA_STATUS_FAIL Function failed
+ *
+ *****************************************************************************/
+CpaStatus Sal_StringParsing(char *string1,
+ Cpa32U instanceNumber,
+ char *string2,
+ char *result);
+
+/**
+*******************************************************************************
+ * @ingroup SalStringParse
+ * Convert a string to an unsigned long
+ *
+ * @description
+ * Parses the string cp in the specified base, and returned it as an
+ * unsigned long value.
+ *
+ * @param[in] cp String to be converted
+ * @param[in] endp Pointer to the end of the string. This parameter
+ * can also be NULL and will not be used in this case
+ * @param[in] cfgBase Base to convert the string
+ *
+ * @retval The string converted to an unsigned long
+ *
+ *****************************************************************************/
+Cpa64U Sal_Strtoul(const char *cp, char **endp, unsigned int cfgBase);
+
+#endif /* SAL_STRING_PARSE_H */
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
new file mode 100644
index 000000000000..12f9f673ac43
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/include/sal_types_compression.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file sal_types_compression.h
+ *
+ * @ingroup SalCtrl
+ *
+ * Generic compression instance type definition
+ *
+ ***************************************************************************/
+#ifndef SAL_TYPES_COMPRESSION_H_
+#define SAL_TYPES_COMPRESSION_H_
+
+#include "cpa_dc.h"
+#include "cpa_dc_dp.h"
+#include "lac_sal_types.h"
+#include "icp_qat_hw.h"
+#include "icp_buffer_desc.h"
+
+#include "lac_mem_pools.h"
+#include "icp_adf_transport.h"
+
+#define DC_NUM_RX_RINGS (1)
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Compression device specific data
+ *
+ * @description
+ * Contains device specific information for a compression service.
+ *
+ *****************************************************************************/
+typedef struct sal_compression_device_data {
+ /* Device specific minimum output buffer size for static compression */
+ Cpa32U minOutputBuffSize;
+
+ /* Enable/disable secureRam/acceleratorRam for intermediate buffers*/
+ Cpa8U useDevRam;
+
+ /* When set, implies device can decompress interim odd byte length
+ * stateful decompression requests.
+ */
+ CpaBoolean oddByteDecompInterim;
+
+ /* When set, implies device can decompress odd byte length
+ * stateful decompression requests when bFinal is absent
+ */
+ CpaBoolean oddByteDecompNobFinal;
+
+ /* Flag to indicate if translator slice overflow is supported */
+ CpaBoolean translatorOverflow;
+
+ /* Flag to enable/disable delayed match mode */
+ icp_qat_hw_compression_delayed_match_t enableDmm;
+
+ Cpa32U inflateContextSize;
+ Cpa8U highestHwCompressionDepth;
+
+ /* Mask that reports supported window sizes for comp/decomp */
+ Cpa8U windowSizeMask;
+
+ /* Flag to indicate CompressAndVerifyAndRecover feature support */
+ CpaBoolean cnvnrSupported;
+} sal_compression_device_data_t;
+
+/**
+ *****************************************************************************
+ * @ingroup SalCtrl
+ * Compression specific Service Container
+ *
+ * @description
+ * Contains information required per compression service instance.
+ *
+ *****************************************************************************/
+typedef struct sal_compression_service_s {
+ /* An instance of the Generic Service Container */
+ sal_service_t generic_service_info;
+
+ /* Memory pool ID used for compression */
+ lac_memory_pool_id_t compression_mem_pool;
+
+ /* Pointer to an array of atomic stats for compression */
+ QatUtilsAtomic *pCompStatsArr;
+
+ /* Size of the DRAM intermediate buffer in bytes */
+ Cpa64U minInterBuffSizeInBytes;
+
+ /* Number of DRAM intermediate buffers */
+ Cpa16U numInterBuffs;
+
+ /* Address of the array of DRAM intermediate buffers*/
+ icp_qat_addr_width_t *pInterBuffPtrsArray;
+ CpaPhysicalAddr pInterBuffPtrsArrayPhyAddr;
+
+ icp_comms_trans_handle trans_handle_compression_tx;
+ icp_comms_trans_handle trans_handle_compression_rx;
+
+ /* Maximum number of in flight requests */
+ Cpa32U maxNumCompConcurrentReq;
+
+ /* Callback function defined for the DcDp API compression session */
+ CpaDcDpCallbackFn pDcDpCb;
+
+ /* Config info */
+ Cpa16U acceleratorNum;
+ Cpa16U bankNum;
+ Cpa16U pkgID;
+ Cpa16U isPolled;
+ Cpa32U coreAffinity;
+ Cpa32U nodeAffinity;
+
+ sal_compression_device_data_t comp_device_data;
+
+ /* Statistics handler */
+ debug_file_info_t *debug_file;
+} sal_compression_service_t;
+
+/*************************************************************************
+ * @ingroup SalCtrl
+ * @description
+ * This function returns a valid compression instance handle for the system
+ * if it exists.
+ *
+ * @performance
+ * To avoid calling this function the user of the QA api should not use
+ * instanceHandle = CPA_INSTANCE_HANDLE_SINGLE.
+ *
+ * @context
+ * This function is called whenever instanceHandle =
+ * CPA_INSTANCE_HANDLE_SINGLE at the QA Dc api.
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @retval Pointer to first compression instance handle or NULL if no
+ * compression instances in the system.
+ *
+ *************************************************************************/
+CpaInstanceHandle dcGetFirstHandle(void);
+
+#endif /*SAL_TYPES_COMPRESSION_H_*/
diff --git a/sys/dev/qat/qat_api/common/qat_comms/sal_qat_cmn_msg.c b/sys/dev/qat/qat_api/common/qat_comms/sal_qat_cmn_msg.c
new file mode 100644
index 000000000000..4331f875aa67
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/qat_comms/sal_qat_cmn_msg.c
@@ -0,0 +1,219 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_qat_cmn_msg.h
+ *
+ * @defgroup SalQatCmnMessage
+ *
+ * @ingroup SalQatCmnMessage
+ *
+ * Interfaces for populating the common QAT structures for a lookaside
+ * operation.
+ *
+ *****************************************************************************/
+
+/*
+******************************************************************************
+* Include public/global header files
+******************************************************************************
+*/
+#include "cpa.h"
+
+/*
+*******************************************************************************
+* Include private header files
+*******************************************************************************
+*/
+#include "qat_utils.h"
+#include "icp_accel_devices.h"
+#include "icp_qat_fw_la.h"
+#include "icp_qat_hw.h"
+#include "lac_common.h"
+#include "lac_mem.h"
+#include "sal_qat_cmn_msg.h"
+
+/********************************************************************
+ * @ingroup SalQatMsg_CmnHdrWrite
+ *
+ * @description
+ * This function fills in all fields in the icp_qat_fw_comn_req_hdr_t
+ * section of the Request Msg. Build LW0 + LW1 -
+ * service part of the request
+ *
+ * @param[in] pMsg Pointer to 128B Request Msg buffer
+ * @param[in] serviceType type of service request
+ * @param[in] serviceCmdId id for the type of service request
+ * @param[in] cmnFlags common request flags
+ * @param[in] serviceCmdFlags service command flahgs
+ *
+ * @return
+ * None
+ *
+ *****************************************/
+void
+SalQatMsg_CmnHdrWrite(icp_qat_fw_comn_req_t *pMsg,
+ icp_qat_fw_comn_request_id_t serviceType,
+ uint8_t serviceCmdId,
+ icp_qat_fw_comn_flags cmnFlags,
+ icp_qat_fw_serv_specif_flags serviceCmdFlags)
+{
+ icp_qat_fw_comn_req_hdr_t *pHeader = &(pMsg->comn_hdr);
+
+ /* LW0 */
+ pHeader->hdr_flags =
+ ICP_QAT_FW_COMN_HDR_FLAGS_BUILD(ICP_QAT_FW_COMN_REQ_FLAG_SET);
+ pHeader->service_type = (uint8_t)serviceType;
+ pHeader->service_cmd_id = serviceCmdId;
+ pHeader->resrvd1 = 0;
+ /* LW1 */
+ pHeader->comn_req_flags = cmnFlags;
+ pHeader->serv_specif_flags = serviceCmdFlags;
+}
+
+/********************************************************************
+ * @ingroup SalQatCmnMessage
+ *
+ * @description
+ * This function fills in all fields in the icp_qat_fw_comn_req_mid_t
+ * section of the Request Msg and the corresponding SGL/Flat flag
+ * in the Hdr.
+ *
+ * @param[in] pReq Pointer to 128B Request Msg buffer
+ * @param[in] pOpaqueData Pointer to opaque data used by callback
+ * @param[in] bufferFormat src and dst Buffers are either SGL or Flat
+ * format
+ * @param[in] pSrcBuffer Address of source buffer
+ * @param[in] pDstBuffer Address of destination buffer
+ * @param[in] pSrcLength Length of source buffer
+ * @param[in] pDstLength Length of destination buffer
+ *
+
+ * @assumptions
+ * All fields in mid section are zero before fn is called
+
+ * @return
+ * None
+ *
+ *****************************************/
+void inline SalQatMsg_CmnMidWrite(icp_qat_fw_la_bulk_req_t *pReq,
+ const void *pOpaqueData,
+ Cpa8U bufferFormat,
+ Cpa64U srcBuffer,
+ Cpa64U dstBuffer,
+ Cpa32U srcLength,
+ Cpa32U dstLength)
+{
+ icp_qat_fw_comn_req_mid_t *pMid = &(pReq->comn_mid);
+
+ LAC_MEM_SHARED_WRITE_FROM_PTR(pMid->opaque_data, pOpaqueData);
+ pMid->src_data_addr = srcBuffer;
+
+ /* In place */
+ if (0 == dstBuffer) {
+ pMid->dest_data_addr = srcBuffer;
+ }
+ /* Out of place */
+ else {
+ pMid->dest_data_addr = dstBuffer;
+ }
+
+ if (bufferFormat == QAT_COMN_PTR_TYPE_SGL) {
+ /* Using ScatterGatherLists so set flag in header */
+ ICP_QAT_FW_COMN_PTR_TYPE_SET(pReq->comn_hdr.comn_req_flags,
+ QAT_COMN_PTR_TYPE_SGL);
+
+ /* Assumption: No need to set src and dest length in this case
+ * as not
+ * used */
+
+ } else {
+ /* Using Flat buffers so set flag in header */
+ ICP_QAT_FW_COMN_PTR_TYPE_SET(pReq->comn_hdr.comn_req_flags,
+ QAT_COMN_PTR_TYPE_FLAT);
+
+ pMid->src_length = srcLength;
+ pMid->dst_length = dstLength;
+ }
+}
+
+/********************************************************************
+ * @ingroup SalQatMsg_ContentDescHdrWrite
+ *
+ * @description
+ * This function fills in all fields in the
+ * icp_qat_fw_comn_req_hdr_cd_pars_t section of the Request Msg.
+ *
+ * @param[in] pMsg Pointer to 128B Request Msg buffer.
+ * @param[in] pContentDescInfo content descripter info.
+ *
+ * @return
+ * none
+ *
+ *****************************************/
+void
+SalQatMsg_ContentDescHdrWrite(
+ icp_qat_fw_comn_req_t *pMsg,
+ const sal_qat_content_desc_info_t *pContentDescInfo)
+{
+ icp_qat_fw_comn_req_hdr_cd_pars_t *pCd_pars = &(pMsg->cd_pars);
+
+ pCd_pars->s.content_desc_addr =
+ pContentDescInfo->hardwareSetupBlockPhys;
+ pCd_pars->s.content_desc_params_sz = pContentDescInfo->hwBlkSzQuadWords;
+ pCd_pars->s.content_desc_resrvd1 = 0;
+ pCd_pars->s.content_desc_hdr_resrvd2 = 0;
+ pCd_pars->s.content_desc_resrvd3 = 0;
+}
+
+/********************************************************************
+ * @ingroup SalQatMsg_CtrlBlkSetToReserved
+ *
+ * @description
+ * This function sets the whole control block to a reserved state.
+ *
+ * @param[in] _pMsg Pointer to 128B Request Msg buffer.
+ *
+ * @return
+ * none
+ *
+ *****************************************/
+void
+SalQatMsg_CtrlBlkSetToReserved(icp_qat_fw_comn_req_t *pMsg)
+{
+
+ icp_qat_fw_comn_req_cd_ctrl_t *pCd_ctrl = &(pMsg->cd_ctrl);
+
+ memset(pCd_ctrl, 0, sizeof(icp_qat_fw_comn_req_cd_ctrl_t));
+}
+
+/********************************************************************
+ * @ingroup SalQatMsg_transPutMsg
+ *
+ * @description
+ *
+ *
+ * @param[in] trans_handle
+ * @param[in] pqat_msg
+ * @param[in] size_in_lws
+ * @param[in] service
+ *
+ * @return
+ * CpaStatus
+ *
+ *****************************************/
+CpaStatus
+SalQatMsg_transPutMsg(icp_comms_trans_handle trans_handle,
+ void *pqat_msg,
+ Cpa32U size_in_lws,
+ Cpa8U service)
+{
+ return icp_adf_transPutMsg(trans_handle, pqat_msg, size_in_lws);
+}
+
+void
+SalQatMsg_updateQueueTail(icp_comms_trans_handle trans_handle)
+{
+ icp_adf_updateQueueTail(trans_handle);
+}
diff --git a/sys/dev/qat/qat_api/common/stubs/lac_stubs.c b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c
new file mode 100644
index 000000000000..b9c0c3237a6c
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/stubs/lac_stubs.c
@@ -0,0 +1,413 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ *
+ * @file lac_stubs.c
+ *
+ * @defgroup kernel stubs
+ *
+ * All PKE and KPT API won't be supported in kernel API
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+/* API Includes */
+#include "cpa.h"
+#include "cpa_cy_dh.h"
+#include "cpa_cy_dsa.h"
+#include "cpa_cy_ecdh.h"
+#include "cpa_cy_ecdsa.h"
+#include "cpa_cy_ec.h"
+#include "cpa_cy_prime.h"
+#include "cpa_cy_rsa.h"
+#include "cpa_cy_ln.h"
+#include "cpa_dc.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_sal_poll.h"
+#include "cpa_cy_sym.h"
+#include "cpa_cy_sym_dp.h"
+#include "cpa_cy_key.h"
+#include "cpa_cy_common.h"
+#include "cpa_cy_im.h"
+#include "icp_sal_user.h"
+
+/* Diffie Hellman */
+CpaStatus
+cpaCyDhKeyGenPhase1(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pDhPhase1Cb,
+ void *pCallbackTag,
+ const CpaCyDhPhase1KeyGenOpData *pPhase1KeyGenData,
+ CpaFlatBuffer *pLocalOctetStringPV)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDhKeyGenPhase2Secret(
+ const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pDhPhase2Cb,
+ void *pCallbackTag,
+ const CpaCyDhPhase2SecretKeyGenOpData *pPhase2SecretKeyGenData,
+ CpaFlatBuffer *pOctetStringSecretKey)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDhQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyDhStats64 *pDhStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDhQueryStats(const CpaInstanceHandle instanceHandle,
+ CpaCyDhStats *pDhStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* DSA */
+CpaStatus
+cpaCyDsaGenPParam(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaGenCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaPParamGenOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pP)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaGenGParam(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaGenCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaGParamGenOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pG)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaGenYParam(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaGenCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaYParamGenOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pY)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaSignR(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaGenCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaRSignOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pR)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaSignS(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaGenCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaSSignOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pS)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaSignRS(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaRSSignCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaRSSignOpData *pOpData,
+ CpaBoolean *pProtocolStatus,
+ CpaFlatBuffer *pR,
+ CpaFlatBuffer *pS)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaVerify(const CpaInstanceHandle instanceHandle,
+ const CpaCyDsaVerifyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyDsaVerifyOpData *pOpData,
+ CpaBoolean *pVerifyStatus)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaQueryStats(const CpaInstanceHandle instanceHandle,
+ CpaCyDsaStats *pDsaStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyDsaQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyDsaStats64 *pDsaStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* ECDH */
+CpaStatus
+cpaCyEcdhPointMultiply(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcdhPointMultiplyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcdhPointMultiplyOpData *pOpData,
+ CpaBoolean *pMultiplyStatus,
+ CpaFlatBuffer *pXk,
+ CpaFlatBuffer *pYk)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcdhQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyEcdhStats64 *pEcdhStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* ECDSA */
+CpaStatus
+cpaCyEcdsaSignR(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcdsaGenSignCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcdsaSignROpData *pOpData,
+ CpaBoolean *pSignStatus,
+ CpaFlatBuffer *pR)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcdsaSignS(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcdsaGenSignCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcdsaSignSOpData *pOpData,
+ CpaBoolean *pSignStatus,
+ CpaFlatBuffer *pS)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcdsaSignRS(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcdsaSignRSCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcdsaSignRSOpData *pOpData,
+ CpaBoolean *pSignStatus,
+ CpaFlatBuffer *pR,
+ CpaFlatBuffer *pS)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcdsaVerify(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcdsaVerifyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcdsaVerifyOpData *pOpData,
+ CpaBoolean *pVerifyStatus)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcdsaQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyEcdsaStats64 *pEcdsaStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* EC */
+CpaStatus
+cpaCyEcPointMultiply(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcPointMultiplyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcPointMultiplyOpData *pOpData,
+ CpaBoolean *pMultiplyStatus,
+ CpaFlatBuffer *pXk,
+ CpaFlatBuffer *pYk)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcPointVerify(const CpaInstanceHandle instanceHandle,
+ const CpaCyEcPointVerifyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcPointVerifyOpData *pOpData,
+ CpaBoolean *pVerifyStatus)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyEcStats64 *pEcStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyEcMontEdwdsPointMultiply(
+ const CpaInstanceHandle instanceHandle,
+ const CpaCyEcPointMultiplyCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyEcMontEdwdsPointMultiplyOpData *pOpData,
+ CpaBoolean *pMultiplyStatus,
+ CpaFlatBuffer *pXk,
+ CpaFlatBuffer *pYk)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* Prime */
+CpaStatus
+cpaCyPrimeTest(const CpaInstanceHandle instanceHandle,
+ const CpaCyPrimeTestCbFunc pCb,
+ void *pCallbackTag,
+ const CpaCyPrimeTestOpData *pOpData,
+ CpaBoolean *pTestPassed)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyPrimeQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyPrimeStats64 *pPrimeStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyPrimeQueryStats(const CpaInstanceHandle instanceHandle,
+ CpaCyPrimeStats *pPrimeStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* RSA */
+CpaStatus
+cpaCyRsaGenKey(const CpaInstanceHandle instanceHandle,
+ const CpaCyRsaKeyGenCbFunc pRsaKeyGenCb,
+ void *pCallbackTag,
+ const CpaCyRsaKeyGenOpData *pKeyGenOpData,
+ CpaCyRsaPrivateKey *pPrivateKey,
+ CpaCyRsaPublicKey *pPublicKey)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyRsaEncrypt(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pRsaEncryptCb,
+ void *pCallbackTag,
+ const CpaCyRsaEncryptOpData *pEncryptOpData,
+ CpaFlatBuffer *pOutputData)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyRsaDecrypt(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pRsaDecryptCb,
+ void *pCallbackTag,
+ const CpaCyRsaDecryptOpData *pDecryptOpData,
+ CpaFlatBuffer *pOutputData)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyRsaQueryStats64(const CpaInstanceHandle instanceHandle,
+ CpaCyRsaStats64 *pRsaStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyRsaQueryStats(const CpaInstanceHandle instanceHandle,
+ CpaCyRsaStats *pRsaStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* Large Number */
+CpaStatus
+cpaCyLnModExp(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pLnModExpCb,
+ void *pCallbackTag,
+ const CpaCyLnModExpOpData *pLnModExpOpData,
+ CpaFlatBuffer *pResult)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyLnModInv(const CpaInstanceHandle instanceHandle,
+ const CpaCyGenFlatBufCbFunc pLnModInvCb,
+ void *pCallbackTag,
+ const CpaCyLnModInvOpData *pLnModInvOpData,
+ CpaFlatBuffer *pResult)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+cpaCyLnStatsQuery64(const CpaInstanceHandle instanceHandle,
+ CpaCyLnStats64 *pLnStats)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+/* Dynamic Instance */
+CpaStatus
+icp_adf_putDynInstance(icp_accel_dev_t *accel_dev,
+ adf_service_type_t stype,
+ Cpa32U instance_id)
+{
+ return CPA_STATUS_FAIL;
+}
+
+CpaStatus
+icp_sal_CyPollAsymRing(CpaInstanceHandle instanceHandle_in,
+ Cpa32U response_quota)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+icp_sal_AsymGetInflightRequests(CpaInstanceHandle instanceHandle,
+ Cpa32U *maxInflightRequests,
+ Cpa32U *numInflightRequests)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
+
+CpaStatus
+icp_sal_AsymPerformOpNow(CpaInstanceHandle instanceHandle)
+{
+ return CPA_STATUS_UNSUPPORTED;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/lac_buffer_desc.c b/sys/dev/qat/qat_api/common/utils/lac_buffer_desc.c
new file mode 100644
index 000000000000..06a6d9bd768e
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/lac_buffer_desc.c
@@ -0,0 +1,492 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file lac_buffer_desc.c Utility functions for setting buffer descriptors
+ *
+ * @ingroup LacBufferDesc
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include header files
+*******************************************************************************
+*/
+#include "qat_utils.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "icp_adf_init.h"
+#include "lac_list.h"
+#include "lac_sal_types.h"
+#include "lac_buffer_desc.h"
+#include "lac_mem.h"
+#include "cpa_cy_common.h"
+
+/*
+*******************************************************************************
+* Define public/global function definitions
+*******************************************************************************
+*/
+/* Invalid physical address value */
+#define INVALID_PHYSICAL_ADDRESS 0
+
+/* Indicates what type of buffer writes need to be perfomed */
+typedef enum lac_buff_write_op_e {
+ WRITE_NORMAL = 0,
+ WRITE_AND_GET_SIZE,
+ WRITE_AND_ALLOW_ZERO_BUFFER,
+} lac_buff_write_op_t;
+
+/* This function implements the buffer description writes for the traditional
+ * APIs */
+static CpaStatus
+LacBuffDesc_CommonBufferListDescWrite(const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ Cpa64U *totalDataLenInBytes,
+ sal_service_t *pService,
+ lac_buff_write_op_t operationType)
+{
+ Cpa32U numBuffers = 0;
+ icp_qat_addr_width_t bufListDescPhyAddr = 0;
+ icp_qat_addr_width_t bufListAlignedPhyAddr = 0;
+ CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
+ icp_buffer_list_desc_t *pBufferListDesc = NULL;
+ icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
+
+ if (WRITE_AND_GET_SIZE == operationType) {
+ *totalDataLenInBytes = 0;
+ }
+
+ numBuffers = pUserBufferList->numBuffers;
+ pCurrClientFlatBuffer = pUserBufferList->pBuffers;
+
+ /*
+ * Get the physical address of this descriptor - need to offset by the
+ * alignment restrictions on the buffer descriptors
+ */
+ bufListDescPhyAddr = (icp_qat_addr_width_t)LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService), pUserBufferList->pPrivateMetaData);
+
+ if (bufListDescPhyAddr == 0) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the metadata.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ bufListAlignedPhyAddr =
+ LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
+ ICP_DESCRIPTOR_ALIGNMENT_BYTES);
+
+ pBufferListDesc = (icp_buffer_list_desc_t *)(LAC_ARCH_UINT)(
+ (LAC_ARCH_UINT)pUserBufferList->pPrivateMetaData +
+ ((LAC_ARCH_UINT)bufListAlignedPhyAddr -
+ (LAC_ARCH_UINT)bufListDescPhyAddr));
+
+ /* Go past the Buffer List descriptor to the list of buffer descriptors
+ */
+ pCurrFlatBufDesc =
+ (icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
+
+ pBufferListDesc->numBuffers = numBuffers;
+
+ if (WRITE_AND_GET_SIZE != operationType) {
+ /* Defining zero buffers is useful for example if running zero
+ * length
+ * hash */
+ if (0 == numBuffers) {
+ /* In the case where there are zero buffers within the
+ * BufList
+ * it is required by firmware that the number is set to
+ * 1
+ * but the phyBuffer and dataLenInBytes are set to
+ * NULL.*/
+ pBufferListDesc->numBuffers = 1;
+ pCurrFlatBufDesc->dataLenInBytes = 0;
+ pCurrFlatBufDesc->phyBuffer = 0;
+ }
+ }
+
+ while (0 != numBuffers) {
+ pCurrFlatBufDesc->dataLenInBytes =
+ pCurrClientFlatBuffer->dataLenInBytes;
+
+ if (WRITE_AND_GET_SIZE == operationType) {
+ /* Calculate the total data length in bytes */
+ *totalDataLenInBytes +=
+ pCurrClientFlatBuffer->dataLenInBytes;
+ }
+
+ /* Check if providing a physical address in the function. If not
+ * we
+ * need to convert it to a physical one */
+ if (CPA_TRUE == isPhysicalAddress) {
+ pCurrFlatBufDesc->phyBuffer =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ (LAC_ARCH_UINT)(pCurrClientFlatBuffer->pData));
+ } else {
+ pCurrFlatBufDesc->phyBuffer =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService), pCurrClientFlatBuffer->pData));
+
+ if (WRITE_AND_ALLOW_ZERO_BUFFER != operationType) {
+ if (INVALID_PHYSICAL_ADDRESS ==
+ pCurrFlatBufDesc->phyBuffer) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the client buffer.\n");
+ return CPA_STATUS_FAIL;
+ }
+ }
+ }
+
+ pCurrFlatBufDesc++;
+ pCurrClientFlatBuffer++;
+
+ numBuffers--;
+ }
+
+ *pBufListAlignedPhyAddr = bufListAlignedPhyAddr;
+ return CPA_STATUS_SUCCESS;
+}
+
+/* This function implements the buffer description writes for the traditional
+ * APIs Zero length buffers are allowed, should be used for CHA-CHA-POLY and
+ * GCM aglorithms */
+CpaStatus
+LacBuffDesc_BufferListDescWriteAndAllowZeroBuffer(
+ const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ sal_service_t *pService)
+{
+ return LacBuffDesc_CommonBufferListDescWrite(
+ pUserBufferList,
+ pBufListAlignedPhyAddr,
+ isPhysicalAddress,
+ NULL,
+ pService,
+ WRITE_AND_ALLOW_ZERO_BUFFER);
+}
+
+/* This function implements the buffer description writes for the traditional
+ * APIs */
+CpaStatus
+LacBuffDesc_BufferListDescWrite(const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ sal_service_t *pService)
+{
+ return LacBuffDesc_CommonBufferListDescWrite(pUserBufferList,
+ pBufListAlignedPhyAddr,
+ isPhysicalAddress,
+ NULL,
+ pService,
+ WRITE_NORMAL);
+}
+
+/* This function does the same processing as LacBuffDesc_BufferListDescWrite
+ * but calculate as well the total length in bytes of the buffer list. */
+CpaStatus
+LacBuffDesc_BufferListDescWriteAndGetSize(const CpaBufferList *pUserBufferList,
+ Cpa64U *pBufListAlignedPhyAddr,
+ CpaBoolean isPhysicalAddress,
+ Cpa64U *totalDataLenInBytes,
+ sal_service_t *pService)
+{
+ Cpa32U numBuffers = 0;
+ icp_qat_addr_width_t bufListDescPhyAddr = 0;
+ icp_qat_addr_width_t bufListAlignedPhyAddr = 0;
+ CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
+ icp_buffer_list_desc_t *pBufferListDesc = NULL;
+ icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
+ *totalDataLenInBytes = 0;
+
+ numBuffers = pUserBufferList->numBuffers;
+ pCurrClientFlatBuffer = pUserBufferList->pBuffers;
+
+ /*
+ * Get the physical address of this descriptor - need to offset by the
+ * alignment restrictions on the buffer descriptors
+ */
+ bufListDescPhyAddr = (icp_qat_addr_width_t)LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService), pUserBufferList->pPrivateMetaData);
+
+ if (INVALID_PHYSICAL_ADDRESS == bufListDescPhyAddr) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the metadata.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ bufListAlignedPhyAddr =
+ LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
+ ICP_DESCRIPTOR_ALIGNMENT_BYTES);
+
+ pBufferListDesc = (icp_buffer_list_desc_t *)(LAC_ARCH_UINT)(
+ (LAC_ARCH_UINT)pUserBufferList->pPrivateMetaData +
+ ((LAC_ARCH_UINT)bufListAlignedPhyAddr -
+ (LAC_ARCH_UINT)bufListDescPhyAddr));
+
+ /* Go past the Buffer List descriptor to the list of buffer descriptors
+ */
+ pCurrFlatBufDesc =
+ (icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
+
+ pBufferListDesc->numBuffers = numBuffers;
+
+ while (0 != numBuffers) {
+ pCurrFlatBufDesc->dataLenInBytes =
+ pCurrClientFlatBuffer->dataLenInBytes;
+
+ /* Calculate the total data length in bytes */
+ *totalDataLenInBytes += pCurrClientFlatBuffer->dataLenInBytes;
+
+ if (isPhysicalAddress == CPA_TRUE) {
+ pCurrFlatBufDesc->phyBuffer =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ (LAC_ARCH_UINT)(pCurrClientFlatBuffer->pData));
+ } else {
+ pCurrFlatBufDesc->phyBuffer =
+ LAC_MEM_CAST_PTR_TO_UINT64(
+ LAC_OS_VIRT_TO_PHYS_EXTERNAL(
+ (*pService), pCurrClientFlatBuffer->pData));
+
+ if (pCurrFlatBufDesc->phyBuffer == 0) {
+ QAT_UTILS_LOG(
+ "Unable to get the physical address of the client buffer.\n");
+ return CPA_STATUS_FAIL;
+ }
+ }
+
+ pCurrFlatBufDesc++;
+ pCurrClientFlatBuffer++;
+
+ numBuffers--;
+ }
+
+ *pBufListAlignedPhyAddr = bufListAlignedPhyAddr;
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+LacBuffDesc_FlatBufferVerify(const CpaFlatBuffer *pUserFlatBuffer,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected)
+{
+ LAC_CHECK_NULL_PARAM(pUserFlatBuffer);
+ LAC_CHECK_NULL_PARAM(pUserFlatBuffer->pData);
+
+ if (0 == pUserFlatBuffer->dataLenInBytes) {
+ QAT_UTILS_LOG("FlatBuffer empty\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ /* Expected alignment */
+ if (LAC_NO_ALIGNMENT_SHIFT != alignmentShiftExpected) {
+ if (!LAC_ADDRESS_ALIGNED(pUserFlatBuffer->pData,
+ alignmentShiftExpected)) {
+ QAT_UTILS_LOG(
+ "FlatBuffer not aligned correctly - expected alignment of %u bytes.\n",
+ 1 << alignmentShiftExpected);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Update the total size of the packet. This function being called in a
+ * loop
+ * for an entire buffer list we need to increment the value */
+ *pPktSize += pUserFlatBuffer->dataLenInBytes;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+LacBuffDesc_FlatBufferVerifyNull(const CpaFlatBuffer *pUserFlatBuffer,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected)
+{
+ LAC_CHECK_NULL_PARAM(pUserFlatBuffer);
+
+ if (0 != pUserFlatBuffer->dataLenInBytes) {
+ LAC_CHECK_NULL_PARAM(pUserFlatBuffer->pData);
+ }
+
+ /* Expected alignment */
+ if (LAC_NO_ALIGNMENT_SHIFT != alignmentShiftExpected) {
+ if (!LAC_ADDRESS_ALIGNED(pUserFlatBuffer->pData,
+ alignmentShiftExpected)) {
+ QAT_UTILS_LOG(
+ "FlatBuffer not aligned correctly - expected alignment of %u bytes.\n",
+ 1 << alignmentShiftExpected);
+ return CPA_STATUS_INVALID_PARAM;
+ }
+ }
+
+ /* Update the total size of the packet. This function being called in a
+ * loop
+ * for an entire buffer list we need to increment the value */
+ *pPktSize += pUserFlatBuffer->dataLenInBytes;
+
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+LacBuffDesc_BufferListVerify(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected)
+{
+ CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
+ Cpa32U numBuffers = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ LAC_CHECK_NULL_PARAM(pUserBufferList);
+ LAC_CHECK_NULL_PARAM(pUserBufferList->pBuffers);
+ LAC_CHECK_NULL_PARAM(pUserBufferList->pPrivateMetaData);
+
+ numBuffers = pUserBufferList->numBuffers;
+
+ if (0 == pUserBufferList->numBuffers) {
+ QAT_UTILS_LOG("Number of buffers is 0.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ pCurrClientFlatBuffer = pUserBufferList->pBuffers;
+
+ *pPktSize = 0;
+ while (0 != numBuffers && status == CPA_STATUS_SUCCESS) {
+ status = LacBuffDesc_FlatBufferVerify(pCurrClientFlatBuffer,
+ pPktSize,
+ alignmentShiftExpected);
+
+ pCurrClientFlatBuffer++;
+ numBuffers--;
+ }
+ return status;
+}
+
+CpaStatus
+LacBuffDesc_BufferListVerifyNull(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize,
+ lac_aligment_shift_t alignmentShiftExpected)
+{
+ CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
+ Cpa32U numBuffers = 0;
+ CpaStatus status = CPA_STATUS_SUCCESS;
+
+ LAC_CHECK_NULL_PARAM(pUserBufferList);
+ LAC_CHECK_NULL_PARAM(pUserBufferList->pBuffers);
+ LAC_CHECK_NULL_PARAM(pUserBufferList->pPrivateMetaData);
+
+ numBuffers = pUserBufferList->numBuffers;
+
+ if (0 == pUserBufferList->numBuffers) {
+ QAT_UTILS_LOG("Number of buffers is 0.\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ pCurrClientFlatBuffer = pUserBufferList->pBuffers;
+
+ *pPktSize = 0;
+ while (0 != numBuffers && status == CPA_STATUS_SUCCESS) {
+ status =
+ LacBuffDesc_FlatBufferVerifyNull(pCurrClientFlatBuffer,
+ pPktSize,
+ alignmentShiftExpected);
+
+ pCurrClientFlatBuffer++;
+ numBuffers--;
+ }
+ return status;
+}
+
+/**
+ ******************************************************************************
+ * @ingroup LacBufferDesc
+ *****************************************************************************/
+void
+LacBuffDesc_BufferListTotalSizeGet(const CpaBufferList *pUserBufferList,
+ Cpa64U *pPktSize)
+{
+ CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
+ Cpa32U numBuffers = 0;
+
+ pCurrClientFlatBuffer = pUserBufferList->pBuffers;
+ numBuffers = pUserBufferList->numBuffers;
+
+ *pPktSize = 0;
+ while (0 != numBuffers) {
+ *pPktSize += pCurrClientFlatBuffer->dataLenInBytes;
+ pCurrClientFlatBuffer++;
+ numBuffers--;
+ }
+}
+
+void
+LacBuffDesc_BufferListZeroFromOffset(CpaBufferList *pBuffList,
+ Cpa32U offset,
+ Cpa32U lenToZero)
+{
+ Cpa32U zeroLen = 0, sizeLeftToZero = 0;
+ Cpa64U currentBufferSize = 0;
+ CpaFlatBuffer *pBuffer = NULL;
+ Cpa8U *pZero = NULL;
+ pBuffer = pBuffList->pBuffers;
+
+ /* Take a copy of total length to zero. */
+ sizeLeftToZero = lenToZero;
+
+ while (sizeLeftToZero > 0) {
+ currentBufferSize = pBuffer->dataLenInBytes;
+ /* check where to start zeroing */
+ if (offset >= currentBufferSize) {
+ /* Need to get to next buffer and reduce
+ * offset size by data len of buffer */
+ offset = offset - pBuffer->dataLenInBytes;
+ pBuffer++;
+ } else {
+ /* Start to Zero from this position */
+ pZero = (Cpa8U *)pBuffer->pData + offset;
+
+ /* Need to calculate the correct number of bytes to zero
+ * for this iteration and for this location.
+ */
+ if (sizeLeftToZero >= pBuffer->dataLenInBytes) {
+ /* The size to zero is spanning buffers, zeroLen
+ * in
+ * this case is from pZero (position) to end of
+ * buffer.
+ */
+ zeroLen = pBuffer->dataLenInBytes - offset;
+ } else {
+ /* zeroLen is set to sizeLeftToZero, then check
+ * if zeroLen and
+ * the offset is greater or equal to the size of
+ * the buffer, if
+ * yes, adjust the zeroLen to zero out the
+ * remainder of this
+ * buffer.
+ */
+ zeroLen = sizeLeftToZero;
+ if ((zeroLen + offset) >=
+ pBuffer->dataLenInBytes) {
+ zeroLen =
+ pBuffer->dataLenInBytes - offset;
+ }
+ } /* end inner else */
+ memset((void *)pZero, 0, zeroLen);
+ sizeLeftToZero = sizeLeftToZero - zeroLen;
+ /* offset is no longer required as any data left to zero
+ * is now
+ * at the start of the next buffer. set offset to zero
+ * and move on
+ * the buffer pointer to the next buffer.
+ */
+ offset = 0;
+ pBuffer++;
+
+ } /* end outer else */
+
+ } /* end while */
+}
diff --git a/sys/dev/qat/qat_api/common/utils/lac_lock_free_stack.h b/sys/dev/qat/qat_api/common/utils/lac_lock_free_stack.h
new file mode 100644
index 000000000000..fda9b0691e03
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/lac_lock_free_stack.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+#ifndef LAC_LOCK_FREE_STACK_H_1
+#define LAC_LOCK_FREE_STACK_H_1
+#include "lac_mem_pools.h"
+
+typedef union {
+ struct {
+ uint64_t ctr : 16;
+ uint64_t ptr : 48;
+ };
+ uint64_t atomic;
+} pointer_t;
+
+typedef struct {
+ volatile pointer_t top;
+} lock_free_stack_t;
+
+static inline void *
+PTR(const uintptr_t addr48)
+{
+#ifdef __x86_64__
+ const int64_t addr64 = addr48 << 16;
+
+ /* Do arithmetic shift to restore kernel canonical address (if not NULL)
+ */
+ return (void *)(addr64 >> 16);
+#else
+ return (void *)(addr48);
+#endif
+}
+
+static inline lac_mem_blk_t *
+pop(lock_free_stack_t *stack)
+{
+ pointer_t old_top;
+ pointer_t new_top;
+ lac_mem_blk_t *next;
+
+ do {
+ old_top.atomic = stack->top.atomic;
+ next = PTR(old_top.ptr);
+ if (NULL == next)
+ return next;
+
+ new_top.ptr = (uintptr_t)next->pNext;
+ new_top.ctr = old_top.ctr + 1;
+ } while (!__sync_bool_compare_and_swap(&stack->top.atomic,
+ old_top.atomic,
+ new_top.atomic));
+
+ return next;
+}
+
+static inline void
+push(lock_free_stack_t *stack, lac_mem_blk_t *val)
+{
+ pointer_t new_top;
+ pointer_t old_top;
+
+ do {
+ old_top.atomic = stack->top.atomic;
+ val->pNext = PTR(old_top.ptr);
+ new_top.ptr = (uintptr_t)val;
+ new_top.ctr = old_top.ctr + 1;
+ } while (!__sync_bool_compare_and_swap(&stack->top.atomic,
+ old_top.atomic,
+ new_top.atomic));
+}
+
+static inline lock_free_stack_t
+_init_stack(void)
+{
+ lock_free_stack_t stack = { { { 0 } } };
+ return stack;
+}
+
+static inline lac_mem_blk_t *
+top(lock_free_stack_t *stack)
+{
+ pointer_t old_top = stack->top;
+ lac_mem_blk_t *next = PTR(old_top.ptr);
+ return next;
+}
+
+#endif
diff --git a/sys/dev/qat/qat_api/common/utils/lac_mem.c b/sys/dev/qat/qat_api/common/utils/lac_mem.c
new file mode 100644
index 000000000000..66bd59815e6d
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/lac_mem.c
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file lac_mem.c Implementation of Memory Functions
+ *
+ * @ingroup LacMem
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include header files
+*******************************************************************************
+*/
+#include "qat_utils.h"
+#include "cpa.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+#include "icp_sal_iommu.h"
+
+#include "lac_mem.h"
+#include "lac_mem_pools.h"
+#include "lac_common.h"
+#include "lac_list.h"
+#include "icp_qat_fw_la.h"
+#include "lac_sal_types.h"
+
+/*
+********************************************************************************
+* Static Variables
+********************************************************************************
+*/
+
+#define MAX_BUFFER_SIZE (LAC_BITS_TO_BYTES(4096))
+/**< @ingroup LacMem
+ * Maximum size of the buffers used in the resize function */
+
+/*
+*******************************************************************************
+* Define public/global function definitions
+*******************************************************************************
+*/
+/**
+ * @ingroup LacMem
+ */
+CpaStatus
+icp_LacBufferRestore(Cpa8U *pUserBuffer,
+ Cpa32U userLen,
+ Cpa8U *pWorkingBuffer,
+ Cpa32U workingLen,
+ CpaBoolean copyBuf)
+{
+ Cpa32U padSize = 0;
+
+ /* NULL is a valid value for working buffer as this function may be
+ * called to clean up in an error case where all the resize operations
+ * were not completed */
+ if (NULL == pWorkingBuffer) {
+ return CPA_STATUS_SUCCESS;
+ }
+
+ if (workingLen < userLen) {
+ QAT_UTILS_LOG("Invalid buffer sizes\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ if (pUserBuffer != pWorkingBuffer) {
+
+ if (CPA_TRUE == copyBuf) {
+ /* Copy from internal buffer to user buffer */
+ padSize = workingLen - userLen;
+ memcpy(pUserBuffer, pWorkingBuffer + padSize, userLen);
+ }
+
+ Lac_MemPoolEntryFree(pWorkingBuffer);
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+/**
+ * @ingroup LacMem
+ */
+CpaPhysicalAddr
+SalMem_virt2PhysExternal(void *pVirtAddr, void *pServiceGen)
+{
+ sal_service_t *pService = (sal_service_t *)pServiceGen;
+
+ if (NULL != pService->virt2PhysClient) {
+ return pService->virt2PhysClient(pVirtAddr);
+ } else {
+ /* Use internal QAT Utils virt to phys */
+ /* Ok for kernel space probably should not use for user */
+ return LAC_OS_VIRT_TO_PHYS_INTERNAL(pVirtAddr);
+ }
+}
+
+size_t
+icp_sal_iommu_get_remap_size(size_t size)
+{
+ return size;
+}
+
+CpaStatus
+icp_sal_iommu_map(Cpa64U phaddr, Cpa64U iova, size_t size)
+{
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+icp_sal_iommu_unmap(Cpa64U iova, size_t size)
+{
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/lac_mem_pools.c b/sys/dev/qat/qat_api/common/utils/lac_mem_pools.c
new file mode 100644
index 000000000000..7bd584bc775f
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/lac_mem_pools.c
@@ -0,0 +1,430 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file lac_mem_pools.c
+ *
+ * @ingroup LacMemPool
+ *
+ * Memory Pool creation and mgmt function implementations
+ *
+ ***************************************************************************/
+
+#include "cpa.h"
+#include "qat_utils.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_init.h"
+#include "icp_adf_transport.h"
+#include "icp_adf_debug.h"
+#include "lac_lock_free_stack.h"
+#include "lac_mem_pools.h"
+#include "lac_mem.h"
+#include "lac_common.h"
+#include "cpa_dc.h"
+#include "dc_session.h"
+#include "dc_datapath.h"
+#include "icp_qat_fw_comp.h"
+#include "icp_buffer_desc.h"
+#include "lac_sym.h"
+
+#define LAC_MEM_POOLS_NUM_SUPPORTED 32000
+/**< @ingroup LacMemPool
+ * Number of mem pools supported */
+
+#define LAC_MEM_POOLS_NAME_SIZE 17
+/**< @ingroup LacMemPool
+ * 16 bytes plus '\\0' terminator */
+
+/**< @ingroup LacMemPool
+ * This structure is used to manage each pool created using this utility
+ * feature. The client will maintain a pointer (identifier) to the created
+ * structure per pool.
+ */
+typedef struct lac_mem_pool_hdr_s {
+ lock_free_stack_t stack;
+ char poolName[LAC_MEM_POOLS_NAME_SIZE]; /*16 bytes of a pool name */
+ /**< up to 16 bytes of a pool name */
+ unsigned int numElementsInPool;
+ /**< number of elements in the Pool */
+ unsigned int blkSizeInBytes;
+ /**< Block size in bytes */
+ unsigned int blkAlignmentInBytes;
+ /**< block alignment in bytes */
+ lac_mem_blk_t **trackBlks;
+ /* An array of mem block pointers to track the allocated entries in pool
+ */
+ volatile size_t availBlks;
+ /* Number of blocks available for allocation in this pool */
+} lac_mem_pool_hdr_t;
+
+static lac_mem_pool_hdr_t *lac_mem_pools[LAC_MEM_POOLS_NUM_SUPPORTED] = {
+ NULL
+};
+/**< @ingroup LacMemPool
+ * Array of pointers to the mem pool header structure
+ */
+
+LAC_DECLARE_HIGHEST_BIT_OF(lac_mem_blk_t);
+/**< @ingroup LacMemPool
+ * local constant for quickening computation of additional space allocated
+ * for holding lac_mem_blk_t container-structure
+ */
+
+/**
+ *******************************************************************************
+ * @ingroup LacMemPool
+ * This function cleans up a mem pool.
+ ******************************************************************************/
+void Lac_MemPoolCleanUpInternal(lac_mem_pool_hdr_t *pPoolID);
+
+static inline Cpa32U
+Lac_MemPoolGetElementRealSize(Cpa32U blkSizeInBytes, Cpa32U blkAlignmentInBytes)
+{
+ Cpa32U addSize = (blkAlignmentInBytes >= sizeof(lac_mem_blk_t) ?
+ blkAlignmentInBytes :
+ 1 << (highest_bit_of_lac_mem_blk_t + 1));
+ return blkSizeInBytes + addSize;
+}
+
+CpaStatus
+Lac_MemPoolCreate(lac_memory_pool_id_t *pPoolID,
+ char *poolName,
+ unsigned int numElementsInPool, /*Number of elements*/
+ unsigned int blkSizeInBytes, /*Block Size in bytes*/
+ unsigned int blkAlignmentInBytes, /*Block alignment (bytes)*/
+ CpaBoolean trackMemory,
+ Cpa32U node)
+{
+ unsigned int poolSearch = 0;
+ unsigned int counter = 0;
+ lac_mem_blk_t *pMemBlkCurrent = NULL;
+
+ void *pMemBlk = NULL;
+
+ if (pPoolID == NULL) {
+ QAT_UTILS_LOG("Invalid Pool ID param\n");
+ return CPA_STATUS_INVALID_PARAM; /*Error*/
+ }
+
+ /* Find First available Pool return error otherwise */
+ while (lac_mem_pools[poolSearch] != NULL) {
+ poolSearch++;
+ if (LAC_MEM_POOLS_NUM_SUPPORTED == poolSearch) {
+ QAT_UTILS_LOG(
+ "No more memory pools available for allocation.\n");
+ return CPA_STATUS_FAIL;
+ }
+ }
+
+ /* Allocate a Pool header */
+ lac_mem_pools[poolSearch] = LAC_OS_MALLOC(sizeof(lac_mem_pool_hdr_t));
+ if (NULL == lac_mem_pools[poolSearch]) {
+ QAT_UTILS_LOG(
+ "Unable to allocate memory for creation of the pool.\n");
+ return CPA_STATUS_RESOURCE; /*Error*/
+ }
+ memset(lac_mem_pools[poolSearch], 0, sizeof(lac_mem_pool_hdr_t));
+
+ /* Copy in Pool Name */
+ if (poolName != NULL) {
+ snprintf(lac_mem_pools[poolSearch]->poolName,
+ LAC_MEM_POOLS_NAME_SIZE,
+ "%s",
+ poolName);
+ } else {
+ LAC_OS_FREE(lac_mem_pools[poolSearch]);
+ lac_mem_pools[poolSearch] = NULL;
+ QAT_UTILS_LOG("Invalid Pool Name pointer\n");
+ return CPA_STATUS_INVALID_PARAM; /*Error*/
+ }
+
+ /* Allocate table for tracking memory blocks */
+ if (CPA_TRUE == trackMemory) {
+ lac_mem_pools[poolSearch]->trackBlks = LAC_OS_MALLOC(
+ (sizeof(lac_mem_blk_t *) * numElementsInPool));
+ if (NULL == lac_mem_pools[poolSearch]->trackBlks) {
+ LAC_OS_FREE(lac_mem_pools[poolSearch]);
+ lac_mem_pools[poolSearch] = NULL;
+ QAT_UTILS_LOG(
+ "Unable to allocate memory for tracking memory blocks.\n");
+ return CPA_STATUS_RESOURCE; /*Error*/
+ }
+ } else {
+ lac_mem_pools[poolSearch]->trackBlks = NULL;
+ }
+
+ lac_mem_pools[poolSearch]->availBlks = 0;
+ lac_mem_pools[poolSearch]->stack = _init_stack();
+
+ /* Calculate alignment needed for allocation */
+ for (counter = 0; counter < numElementsInPool; counter++) {
+ CpaPhysicalAddr physAddr = 0;
+ /* realSize is computed for allocation of blkSize bytes +
+ additional
+ capacity for lac_mem_blk_t structure storage due to the some
+ OSes
+ (BSD) limitations for memory alignment to be power of 2;
+ sizeof(lac_mem_blk_t) is being round up to the closest power
+ of 2 -
+ optimised towards the least CPU overhead but at additional
+ memory
+ cost
+ */
+ Cpa32U realSize =
+ Lac_MemPoolGetElementRealSize(blkSizeInBytes,
+ blkAlignmentInBytes);
+ Cpa32U addSize = realSize - blkSizeInBytes;
+
+ if (CPA_STATUS_SUCCESS != LAC_OS_CAMALLOC(&pMemBlk,
+ realSize,
+ blkAlignmentInBytes,
+ node)) {
+ Lac_MemPoolCleanUpInternal(lac_mem_pools[poolSearch]);
+ lac_mem_pools[poolSearch] = NULL;
+ QAT_UTILS_LOG(
+ "Unable to allocate contiguous chunk of memory.\n");
+ return CPA_STATUS_RESOURCE;
+ }
+
+ /* Calcaulate various offsets */
+ physAddr = LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ (void *)((LAC_ARCH_UINT)pMemBlk + addSize));
+
+ /* physAddr is now already aligned to the greater power of 2:
+ blkAlignmentInBytes or sizeof(lac_mem_blk_t) round up
+ We safely put the structure right before the blkSize
+ real data block
+ */
+ pMemBlkCurrent =
+ (lac_mem_blk_t *)(((LAC_ARCH_UINT)(pMemBlk)) + addSize -
+ sizeof(lac_mem_blk_t));
+
+ pMemBlkCurrent->physDataPtr = physAddr;
+ pMemBlkCurrent->pMemAllocPtr = pMemBlk;
+ pMemBlkCurrent->pPoolID = lac_mem_pools[poolSearch];
+ pMemBlkCurrent->isInUse = CPA_FALSE;
+ pMemBlkCurrent->pNext = NULL;
+
+ push(&lac_mem_pools[poolSearch]->stack, pMemBlkCurrent);
+
+ /* Store allocated memory pointer */
+ if (lac_mem_pools[poolSearch]->trackBlks != NULL) {
+ (lac_mem_pools[poolSearch]->trackBlks[counter]) =
+ (lac_mem_blk_t *)pMemBlkCurrent;
+ }
+ __sync_add_and_fetch(&lac_mem_pools[poolSearch]->availBlks, 1);
+ (lac_mem_pools[poolSearch])->numElementsInPool = counter + 1;
+ }
+
+ /* Set Pool details in the header */
+ (lac_mem_pools[poolSearch])->blkSizeInBytes = blkSizeInBytes;
+ (lac_mem_pools[poolSearch])->blkAlignmentInBytes = blkAlignmentInBytes;
+ /* Set the Pool ID output parameter */
+ *pPoolID = (LAC_ARCH_UINT)(lac_mem_pools[poolSearch]);
+ /* Success */
+ return CPA_STATUS_SUCCESS;
+}
+
+void *
+Lac_MemPoolEntryAlloc(lac_memory_pool_id_t poolID)
+{
+ lac_mem_pool_hdr_t *pPoolID = (lac_mem_pool_hdr_t *)poolID;
+ lac_mem_blk_t *pMemBlkCurrent = NULL;
+
+ /* Explicitly removing NULL PoolID check for speed */
+ if (pPoolID == NULL) {
+ QAT_UTILS_LOG("Invalid Pool ID");
+ return NULL;
+ }
+
+ /* Remove block from pool */
+ pMemBlkCurrent = pop(&pPoolID->stack);
+ if (NULL == pMemBlkCurrent) {
+ return (void *)CPA_STATUS_RETRY;
+ }
+ __sync_sub_and_fetch(&pPoolID->availBlks, 1);
+ pMemBlkCurrent->isInUse = CPA_TRUE;
+ return (void *)((LAC_ARCH_UINT)(pMemBlkCurrent) +
+ sizeof(lac_mem_blk_t));
+}
+
+void
+Lac_MemPoolEntryFree(void *pEntry)
+{
+ lac_mem_blk_t *pMemBlk = NULL;
+
+ /* Explicitly NULL pointer check */
+ if (pEntry == NULL) {
+ QAT_UTILS_LOG("Memory Handle NULL");
+ return;
+ }
+
+ pMemBlk =
+ (lac_mem_blk_t *)((LAC_ARCH_UINT)pEntry - sizeof(lac_mem_blk_t));
+ pMemBlk->isInUse = CPA_FALSE;
+
+ push(&pMemBlk->pPoolID->stack, pMemBlk);
+ __sync_add_and_fetch(&pMemBlk->pPoolID->availBlks, 1);
+}
+
+void
+Lac_MemPoolDestroy(lac_memory_pool_id_t poolID)
+{
+ unsigned int poolSearch = 0;
+ lac_mem_pool_hdr_t *pPoolID = (lac_mem_pool_hdr_t *)poolID;
+
+ if (pPoolID != NULL) {
+ /*Remove entry from table*/
+ while (lac_mem_pools[poolSearch] != pPoolID) {
+ poolSearch++;
+
+ if (LAC_MEM_POOLS_NUM_SUPPORTED == poolSearch) {
+ QAT_UTILS_LOG("Invalid Pool ID submitted.\n");
+ return;
+ }
+ }
+
+ lac_mem_pools[poolSearch] = NULL; /*Remove handle from pool*/
+
+ Lac_MemPoolCleanUpInternal(pPoolID);
+ }
+}
+
+void
+Lac_MemPoolCleanUpInternal(lac_mem_pool_hdr_t *pPoolID)
+{
+ lac_mem_blk_t *pCurrentBlk = NULL;
+ void *pFreePtr = NULL;
+ Cpa32U count = 0;
+
+ if (pPoolID->trackBlks == NULL) {
+ pCurrentBlk = pop(&pPoolID->stack);
+
+ while (pCurrentBlk != NULL) {
+ /* Free Data Blocks */
+ pFreePtr = pCurrentBlk->pMemAllocPtr;
+ pCurrentBlk = pop(&pPoolID->stack);
+ LAC_OS_CAFREE(pFreePtr);
+ }
+ } else {
+ for (count = 0; count < pPoolID->numElementsInPool; count++) {
+ pFreePtr = (pPoolID->trackBlks[count])->pMemAllocPtr;
+ LAC_OS_CAFREE(pFreePtr);
+ }
+ LAC_OS_FREE(pPoolID->trackBlks);
+ }
+ LAC_OS_FREE(pPoolID);
+}
+
+unsigned int
+Lac_MemPoolAvailableEntries(lac_memory_pool_id_t poolID)
+{
+ lac_mem_pool_hdr_t *pPoolID = (lac_mem_pool_hdr_t *)poolID;
+ if (pPoolID == NULL) {
+ QAT_UTILS_LOG("Invalid Pool ID\n");
+ return 0;
+ }
+ return pPoolID->availBlks;
+}
+
+void
+Lac_MemPoolStatsShow(void)
+{
+ unsigned int index = 0;
+ QAT_UTILS_LOG(SEPARATOR BORDER
+ " Memory Pools Stats\n" SEPARATOR);
+
+ while (index < LAC_MEM_POOLS_NUM_SUPPORTED) {
+ if (lac_mem_pools[index] != NULL) {
+ QAT_UTILS_LOG(
+ BORDER " Pool Name: %s \n" BORDER
+ " No. Elements in Pool: %10u \n" BORDER
+ " Element Size in Bytes: %10u \n" BORDER
+ " Alignment in Bytes: %10u \n" BORDER
+ " No. Available Blocks: %10zu \n" SEPARATOR,
+ lac_mem_pools[index]->poolName,
+ lac_mem_pools[index]->numElementsInPool,
+ lac_mem_pools[index]->blkSizeInBytes,
+ lac_mem_pools[index]->blkAlignmentInBytes,
+ lac_mem_pools[index]->availBlks);
+ }
+ index++;
+ }
+}
+
+static void
+Lac_MemPoolInitSymCookies(lac_sym_cookie_t *pSymCookie)
+{
+ pSymCookie->keyContentDescPhyAddr =
+ LAC_OS_VIRT_TO_PHYS_INTERNAL(pSymCookie->u.keyCookie.contentDesc);
+ pSymCookie->keyHashStateBufferPhyAddr = LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ pSymCookie->u.keyCookie.hashStateBuffer);
+ pSymCookie->keySslKeyInputPhyAddr = LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ &(pSymCookie->u.keyCookie.u.sslKeyInput));
+ pSymCookie->keyTlsKeyInputPhyAddr = LAC_OS_VIRT_TO_PHYS_INTERNAL(
+ &(pSymCookie->u.keyCookie.u.tlsKeyInput));
+}
+
+CpaStatus
+Lac_MemPoolInitSymCookiesPhyAddr(lac_memory_pool_id_t poolID)
+{
+ lac_mem_pool_hdr_t *pPoolID = (lac_mem_pool_hdr_t *)poolID;
+ lac_sym_cookie_t *pSymCookie = NULL;
+ lac_mem_blk_t *pCurrentBlk = NULL;
+
+ if (NULL == pPoolID) {
+ QAT_UTILS_LOG("Invalid Pool ID\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ if (pPoolID->trackBlks == NULL) {
+ pCurrentBlk = top(&pPoolID->stack);
+
+ while (pCurrentBlk != NULL) {
+ pSymCookie =
+ (lac_sym_cookie_t *)((LAC_ARCH_UINT)(pCurrentBlk) +
+ sizeof(lac_mem_blk_t));
+ pCurrentBlk = pCurrentBlk->pNext;
+ Lac_MemPoolInitSymCookies(pSymCookie);
+ }
+ } else {
+ Cpa32U count = 0;
+
+ for (count = 0; count < pPoolID->numElementsInPool; count++) {
+ pCurrentBlk = pPoolID->trackBlks[count];
+ pSymCookie =
+ (lac_sym_cookie_t *)((LAC_ARCH_UINT)(pCurrentBlk) +
+ sizeof(lac_mem_blk_t));
+ Lac_MemPoolInitSymCookies(pSymCookie);
+ }
+ }
+ return CPA_STATUS_SUCCESS;
+}
+
+CpaStatus
+Lac_MemPoolInitDcCookiePhyAddr(lac_memory_pool_id_t poolID)
+{
+ lac_mem_pool_hdr_t *pPoolID = (lac_mem_pool_hdr_t *)poolID;
+ lac_mem_blk_t *pCurrentBlk = NULL;
+
+ if (NULL == pPoolID) {
+ QAT_UTILS_LOG("Invalid Pool ID\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ if (NULL == pPoolID->trackBlks) {
+ pCurrentBlk = top(&pPoolID->stack);
+
+ while (pCurrentBlk != NULL) {
+ pCurrentBlk = pCurrentBlk->pNext;
+ }
+ } else {
+ Cpa32U count = 0;
+
+ for (count = 0; count < pPoolID->numElementsInPool; count++) {
+ pCurrentBlk = pPoolID->trackBlks[count];
+ }
+ }
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/lac_sync.c b/sys/dev/qat/qat_api/common/utils/lac_sync.c
new file mode 100644
index 000000000000..25a2f9764bee
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/lac_sync.c
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file lac_sync.c Utility functions containing synchronous callback support
+ * functions
+ *
+ * @ingroup LacSync
+ *
+ *****************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+#include "lac_sync.h"
+#include "lac_common.h"
+
+/*
+*******************************************************************************
+* Define public/global function definitions
+*******************************************************************************
+*/
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenWakeupSyncCaller(void *pCallbackTag, CpaStatus status)
+{
+ lac_sync_op_data_t *pSc = (lac_sync_op_data_t *)pCallbackTag;
+ if (pSc != NULL) {
+ if (pSc->canceled) {
+ QAT_UTILS_LOG("Synchronous operation cancelled.\n");
+ return;
+ }
+ pSc->status = status;
+ if (CPA_STATUS_SUCCESS != LAC_POST_SEMAPHORE(pSc->sid)) {
+ QAT_UTILS_LOG("Failed to post semaphore.\n");
+ }
+ }
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenVerifyWakeupSyncCaller(void *pCallbackTag,
+ CpaStatus status,
+ CpaBoolean opResult)
+{
+ lac_sync_op_data_t *pSc = (lac_sync_op_data_t *)pCallbackTag;
+ if (pSc != NULL) {
+ if (pSc->canceled) {
+ QAT_UTILS_LOG("Synchronous operation cancelled.\n");
+ return;
+ }
+ pSc->status = status;
+ pSc->opResult = opResult;
+ if (CPA_STATUS_SUCCESS != LAC_POST_SEMAPHORE(pSc->sid)) {
+ QAT_UTILS_LOG("Failed to post semaphore.\n");
+ }
+ }
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenVerifyCb(void *pCallbackTag,
+ CpaStatus status,
+ void *pOpData,
+ CpaBoolean opResult)
+{
+ LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenFlatBufCb(void *pCallbackTag,
+ CpaStatus status,
+ void *pOpData,
+ CpaFlatBuffer *pOut)
+{
+ LacSync_GenWakeupSyncCaller(pCallbackTag, status);
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenFlatBufVerifyCb(void *pCallbackTag,
+ CpaStatus status,
+ void *pOpData,
+ CpaBoolean opResult,
+ CpaFlatBuffer *pOut)
+{
+ LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
+}
+
+/**
+ *****************************************************************************
+ * @ingroup LacSync
+ *****************************************************************************/
+void
+LacSync_GenDualFlatBufVerifyCb(void *pCallbackTag,
+ CpaStatus status,
+ void *pOpdata,
+ CpaBoolean opResult,
+ CpaFlatBuffer *pOut0,
+ CpaFlatBuffer *pOut1)
+{
+ LacSync_GenVerifyWakeupSyncCaller(pCallbackTag, status, opResult);
+}
diff --git a/sys/dev/qat/qat_api/common/utils/sal_service_state.c b/sys/dev/qat/qat_api/common/utils/sal_service_state.c
new file mode 100644
index 000000000000..c2fa491e7b73
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/sal_service_state.c
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ ***************************************************************************
+ * @file sal_service_state.c Service state checks
+ *
+ * @ingroup SalServiceState
+ *
+ ***************************************************************************/
+
+/*
+*******************************************************************************
+* Include public/global header files
+*******************************************************************************
+*/
+
+#include "cpa.h"
+#include "qat_utils.h"
+#include "lac_list.h"
+#include "icp_accel_devices.h"
+#include "icp_adf_debug.h"
+#include "lac_sal_types.h"
+#include "sal_service_state.h"
+
+CpaBoolean
+Sal_ServiceIsRunning(CpaInstanceHandle instanceHandle)
+{
+ sal_service_t *pService = (sal_service_t *)instanceHandle;
+
+ if (SAL_SERVICE_STATE_RUNNING == pService->state) {
+ return CPA_TRUE;
+ }
+ return CPA_FALSE;
+}
+
+CpaBoolean
+Sal_ServiceIsRestarting(CpaInstanceHandle instanceHandle)
+{
+ sal_service_t *pService = (sal_service_t *)instanceHandle;
+
+ if (SAL_SERVICE_STATE_RESTARTING == pService->state) {
+ return CPA_TRUE;
+ }
+ return CPA_FALSE;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/sal_statistics.c b/sys/dev/qat/qat_api/common/utils/sal_statistics.c
new file mode 100644
index 000000000000..e311f22283be
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/sal_statistics.c
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_statistics.c
+ *
+ * @defgroup SalStats Sal Statistics
+ *
+ * @ingroup SalStats
+ *
+ * @description
+ * This file contains implementation of statistic related functions
+ *
+ *****************************************************************************/
+
+#include "cpa.h"
+#include "lac_common.h"
+#include "lac_mem.h"
+#include "icp_adf_cfg.h"
+#include "icp_accel_devices.h"
+#include "sal_statistics.h"
+
+#include "icp_adf_debug.h"
+#include "lac_sal_types.h"
+#include "lac_sal.h"
+
+/**
+ ******************************************************************************
+ * @ingroup SalStats
+ * Reads from the config file if the given statistic is enabled
+ *
+ * @description
+ * Reads from the config file if the given statistic is enabled
+ *
+ * @param[in] device Pointer to an acceleration device structure
+ * @param[in] statsName Name of the config value to read the value from
+ * @param[out] pIsEnabled Pointer to a variable where information if the
+ * given stat is enabled or disabled will be stored
+ *
+ * @retval CPA_STATUS_SUCCESS Operation successful
+ * @retval CPA_STATUS_INVALID_PARAM Invalid param provided
+ * @retval CPA_STATUS_FAIL Operation failed
+ *
+ ******************************************************************************/
+static CpaStatus
+SalStatistics_GetStatEnabled(icp_accel_dev_t *device,
+ const char *statsName,
+ CpaBoolean *pIsEnabled)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+
+ LAC_CHECK_NULL_PARAM(pIsEnabled);
+ LAC_CHECK_NULL_PARAM(statsName);
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ statsName,
+ param_value);
+
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get %s from configuration.\n",
+ statsName);
+ return status;
+ }
+
+ if (0 == strncmp(param_value,
+ SAL_STATISTICS_STRING_OFF,
+ strlen(SAL_STATISTICS_STRING_OFF))) {
+ *pIsEnabled = CPA_FALSE;
+ } else {
+ *pIsEnabled = CPA_TRUE;
+ }
+
+ return status;
+}
+
+/* @ingroup SalStats */
+CpaStatus
+SalStatistics_InitStatisticsCollection(icp_accel_dev_t *device)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ sal_statistics_collection_t *pStatsCollection = NULL;
+ Cpa32U enabled_services = 0;
+
+ LAC_CHECK_NULL_PARAM(device);
+
+ pStatsCollection = LAC_OS_MALLOC(sizeof(sal_statistics_collection_t));
+ if (NULL == pStatsCollection) {
+ QAT_UTILS_LOG("Failed to allocate memory for statistic.\n");
+ return CPA_STATUS_RESOURCE;
+ }
+ device->pQatStats = pStatsCollection;
+
+ status = SalStatistics_GetStatEnabled(device,
+ SAL_STATS_CFG_ENABLED,
+ &pStatsCollection->bStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ if (CPA_FALSE == pStatsCollection->bStatsEnabled) {
+ pStatsCollection->bDcStatsEnabled = CPA_FALSE;
+ pStatsCollection->bDhStatsEnabled = CPA_FALSE;
+ pStatsCollection->bDsaStatsEnabled = CPA_FALSE;
+ pStatsCollection->bEccStatsEnabled = CPA_FALSE;
+ pStatsCollection->bKeyGenStatsEnabled = CPA_FALSE;
+ pStatsCollection->bLnStatsEnabled = CPA_FALSE;
+ pStatsCollection->bPrimeStatsEnabled = CPA_FALSE;
+ pStatsCollection->bRsaStatsEnabled = CPA_FALSE;
+ pStatsCollection->bSymStatsEnabled = CPA_FALSE;
+
+ return status;
+ }
+
+ /* What services are enabled */
+ status = SalCtrl_GetEnabledServices(device, &enabled_services);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Failed to get enabled services.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ /* Check if the compression service is enabled */
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_COMPRESSION)) {
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_DC,
+ &pStatsCollection->bDcStatsEnabled);
+ LAC_CHECK_STATUS(status);
+ }
+ /* Check if the asym service is enabled */
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_ASYM) ||
+ SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_DH,
+ &pStatsCollection->bDhStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_DSA,
+ &pStatsCollection->bDsaStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_ECC,
+ &pStatsCollection->bEccStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_KEYGEN,
+ &pStatsCollection->bKeyGenStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_LN,
+ &pStatsCollection->bLnStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_PRIME,
+ &pStatsCollection->bPrimeStatsEnabled);
+ LAC_CHECK_STATUS(status);
+
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_RSA,
+ &pStatsCollection->bRsaStatsEnabled);
+ LAC_CHECK_STATUS(status);
+ }
+
+ /* Check if the sym service is enabled */
+ if (SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO_SYM) ||
+ SalCtrl_IsServiceEnabled(enabled_services,
+ SAL_SERVICE_TYPE_CRYPTO)) {
+ status = SalStatistics_GetStatEnabled(
+ device,
+ SAL_STATS_CFG_SYM,
+ &pStatsCollection->bSymStatsEnabled);
+ LAC_CHECK_STATUS(status);
+ }
+ return status;
+};
+
+/* @ingroup SalStats */
+CpaStatus
+SalStatistics_CleanStatisticsCollection(icp_accel_dev_t *device)
+{
+ sal_statistics_collection_t *pStatsCollection = NULL;
+ LAC_CHECK_NULL_PARAM(device);
+ pStatsCollection = (sal_statistics_collection_t *)device->pQatStats;
+ LAC_OS_FREE(pStatsCollection);
+ device->pQatStats = NULL;
+ return CPA_STATUS_SUCCESS;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/sal_string_parse.c b/sys/dev/qat/qat_api/common/utils/sal_string_parse.c
new file mode 100644
index 000000000000..b6161aa8d88c
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/sal_string_parse.c
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_string_parse.c
+ *
+ * @ingroup SalStringParse
+ *
+ * @description
+ * This file contains string parsing functions for both user space and kernel
+ * space
+ *
+ *****************************************************************************/
+#include "cpa.h"
+#include "lac_mem.h"
+#include "sal_string_parse.h"
+
+CpaStatus
+Sal_StringParsing(char *string1,
+ Cpa32U instanceNumber,
+ char *string2,
+ char *result)
+{
+ char instNumString[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ Cpa32U instNumStringLen = 0;
+
+ snprintf(instNumString,
+ SAL_CFG_MAX_VAL_LEN_IN_BYTES,
+ "%d",
+ instanceNumber);
+ instNumStringLen = strnlen(instNumString, SAL_CFG_MAX_VAL_LEN_IN_BYTES);
+ if ((strnlen(string1, SAL_CFG_MAX_VAL_LEN_IN_BYTES) + instNumStringLen +
+ strnlen(string2, SAL_CFG_MAX_VAL_LEN_IN_BYTES)) >
+ SAL_CFG_MAX_VAL_LEN_IN_BYTES) {
+ QAT_UTILS_LOG("Size of result too small.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ LAC_OS_BZERO(result, SAL_CFG_MAX_VAL_LEN_IN_BYTES);
+ snprintf(result,
+ SAL_CFG_MAX_VAL_LEN_IN_BYTES,
+ "%s%d%s",
+ string1,
+ instanceNumber,
+ string2);
+
+ return CPA_STATUS_SUCCESS;
+}
+
+Cpa64U
+Sal_Strtoul(const char *cp, char **endp, unsigned int cfgBase)
+{
+ Cpa64U ulResult = 0;
+
+ ulResult = (Cpa64U)simple_strtoull(cp, endp, cfgBase);
+
+ return ulResult;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/sal_user_process.c b/sys/dev/qat/qat_api/common/utils/sal_user_process.c
new file mode 100644
index 000000000000..09728f346c13
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/sal_user_process.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_user_process.c
+ *
+ * @ingroup SalUserProcess
+ *
+ * @description
+ * This file contains implementation of functions to set/get user process
+ * name
+ *
+ *****************************************************************************/
+
+#include "qat_utils.h"
+#include "lac_common.h"
+static char lacProcessName[LAC_USER_PROCESS_NAME_MAX_LEN + 1] =
+ LAC_KERNEL_PROCESS_NAME;
+
+/**< Process name used to obtain values from correct section of config file. */
+
+/*
+ * @ingroup LacCommon
+ * @description
+ * This function sets the process name
+ *
+ * @context
+ * This functions is called from module_init or from user space process
+ * initialisation function
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * No
+ *
+ * param[in] processName Process name to be set
+*/
+CpaStatus
+icpSetProcessName(const char *processName)
+{
+ LAC_CHECK_NULL_PARAM(processName);
+
+ if (strnlen(processName, LAC_USER_PROCESS_NAME_MAX_LEN) ==
+ LAC_USER_PROCESS_NAME_MAX_LEN) {
+ QAT_UTILS_LOG(
+ "Process name too long, maximum process name is %d>\n",
+ LAC_USER_PROCESS_NAME_MAX_LEN);
+ return CPA_STATUS_FAIL;
+ }
+
+ strncpy(lacProcessName, processName, LAC_USER_PROCESS_NAME_MAX_LEN);
+ lacProcessName[LAC_USER_PROCESS_NAME_MAX_LEN] = '\0';
+
+ return CPA_STATUS_SUCCESS;
+}
+
+/*
+ * @ingroup LacCommon
+ * @description
+ * This function gets the process name
+ *
+ * @context
+ * This functions is called from LAC context
+ *
+ * @assumptions
+ * None
+ * @sideEffects
+ * None
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+*/
+char *
+icpGetProcessName(void)
+{
+ return lacProcessName;
+}
diff --git a/sys/dev/qat/qat_api/common/utils/sal_versions.c b/sys/dev/qat/qat_api/common/utils/sal_versions.c
new file mode 100644
index 000000000000..8e274eb8705d
--- /dev/null
+++ b/sys/dev/qat/qat_api/common/utils/sal_versions.c
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* Copyright(c) 2007-2022 Intel Corporation */
+/* $FreeBSD$ */
+/**
+ *****************************************************************************
+ * @file sal_versions.c
+ *
+ * @ingroup SalVersions
+ *
+ * @description
+ * This file contains implementation of functions used to obtain version
+ * information
+ *
+ *****************************************************************************/
+
+#include "cpa.h"
+#include "qat_utils.h"
+
+#include "icp_accel_devices.h"
+#include "icp_adf_accel_mgr.h"
+#include "icp_adf_cfg.h"
+
+#include "lac_common.h"
+
+#include "icp_sal_versions.h"
+
+#define ICP_SAL_VERSIONS_ALL_CAP_MASK 0xFFFFFFFF
+/**< Mask used to get all devices from ADF */
+
+/**
+*******************************************************************************
+ * @ingroup SalVersions
+ * Fills in the version info structure
+ * @description
+ * This function obtains hardware and software information associated with
+ * a given device and fills in the version info structure
+ *
+ * @param[in] device Pointer to the device for which version information
+ * is to be obtained.
+ * @param[out] pVerInfo Pointer to a structure that will hold version
+ * information
+ *
+ * @context
+ * This function might sleep. It cannot be executed in a context that
+ * does not permit sleeping.
+ * @assumptions
+ * The system has been started
+ * @sideEffects
+ * None
+ * @blocking
+ * No
+ * @reentrant
+ * No
+ * @threadSafe
+ * Yes
+ *
+ * @return CPA_STATUS_SUCCESS Operation finished successfully
+ * @return CPA_STATUS_FAIL Operation failed
+ *
+ *****************************************************************************/
+static CpaStatus
+SalVersions_FillVersionInfo(icp_accel_dev_t *device,
+ icp_sal_dev_version_info_t *pVerInfo)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ char param_value[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
+ Cpa32S strSize = 0;
+
+ memset(pVerInfo, 0, sizeof(icp_sal_dev_version_info_t));
+ pVerInfo->devId = device->accelId;
+
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_HW_REV_ID_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ strSize = snprintf((char *)pVerInfo->hardwareVersion,
+ ICP_SAL_VERSIONS_HW_VERSION_SIZE,
+ "%s",
+ param_value);
+ LAC_CHECK_PARAM_RANGE(strSize, 1, ICP_SAL_VERSIONS_HW_VERSION_SIZE);
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_UOF_VER_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ strSize = snprintf((char *)pVerInfo->firmwareVersion,
+ ICP_SAL_VERSIONS_FW_VERSION_SIZE,
+ "%s",
+ param_value);
+ LAC_CHECK_PARAM_RANGE(strSize, 1, ICP_SAL_VERSIONS_FW_VERSION_SIZE);
+
+ memset(param_value, 0, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
+ status = icp_adf_cfgGetParamValue(device,
+ LAC_CFG_SECTION_GENERAL,
+ ICP_CFG_MMP_VER_KEY,
+ param_value);
+ LAC_CHECK_STATUS(status);
+
+ strSize = snprintf((char *)pVerInfo->mmpVersion,
+ ICP_SAL_VERSIONS_MMP_VERSION_SIZE,
+ "%s",
+ param_value);
+ LAC_CHECK_PARAM_RANGE(strSize, 1, ICP_SAL_VERSIONS_MMP_VERSION_SIZE);
+
+ snprintf((char *)pVerInfo->softwareVersion,
+ ICP_SAL_VERSIONS_SW_VERSION_SIZE,
+ "%d.%d.%d",
+ SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER,
+ SAL_INFO2_DRIVER_SW_VERSION_PATCH_NUMBER);
+
+ return status;
+}
+
+CpaStatus
+icp_sal_getDevVersionInfo(Cpa32U devId, icp_sal_dev_version_info_t *pVerInfo)
+{
+ CpaStatus status = CPA_STATUS_SUCCESS;
+ Cpa16U numInstances = 0;
+ icp_accel_dev_t **pAccel_dev = NULL;
+ Cpa16U num_accel_dev = 0, index = 0;
+ icp_accel_dev_t *pDevice = NULL;
+
+ LAC_CHECK_NULL_PARAM(pVerInfo);
+
+ status = icp_amgr_getNumInstances(&numInstances);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG("Error while getting number of devices.\n");
+ return CPA_STATUS_FAIL;
+ }
+
+ if (devId >= ADF_MAX_DEVICES) {
+ QAT_UTILS_LOG("Invalid devId\n");
+ return CPA_STATUS_INVALID_PARAM;
+ }
+
+ pAccel_dev =
+ malloc(numInstances * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK);
+
+ /* Get ADF to return all accel_devs */
+ status =
+ icp_amgr_getAllAccelDevByCapabilities(ICP_SAL_VERSIONS_ALL_CAP_MASK,
+ pAccel_dev,
+ &num_accel_dev);
+
+ if (CPA_STATUS_SUCCESS == status) {
+ for (index = 0; index < num_accel_dev; index++) {
+ pDevice = (icp_accel_dev_t *)pAccel_dev[index];
+
+ if (pDevice->accelId == devId) {
+ status = SalVersions_FillVersionInfo(pDevice,
+ pVerInfo);
+ if (CPA_STATUS_SUCCESS != status) {
+ QAT_UTILS_LOG(
+ "Error while filling in version info.\n");
+ }
+ break;
+ }
+ }
+
+ if (index == num_accel_dev) {
+ QAT_UTILS_LOG("Device %d not found or not started.\n",
+ devId);
+ status = CPA_STATUS_FAIL;
+ }
+ } else {
+ QAT_UTILS_LOG("Error while getting devices.\n");
+ }
+
+ free(pAccel_dev, M_QAT);
+ return status;
+}