/****************************************************************************
 *
 *   BSD LICENSE
 * 
 *   Copyright(c) 2007-2023 Intel Corporation. All rights reserved.
 *   All rights reserved.
 * 
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions
 *   are met:
 * 
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 * 
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 *  version: QAT20.L.1.2.30-00078
 *
 ***************************************************************************/

/**
 *****************************************************************************
 * @file dc_chain.h
 *
 * @ingroup Dc_Chaining
 *
 * @description
 *      Definition of the data compression and crypto chaining parameters.
 *
 *****************************************************************************/
#ifndef DC_CHAIN_H
#define DC_CHAIN_H

#include "sal_types_compression.h"
#include "icp_qat_fw_dc_chain.h"
#include "lac_sym_qat_hash_defs_lookup.h"
#include "cpa_dc_chain.h"
#include "lac_session.h"
#include "dc_session.h"

#define DC_CHAIN_TYPE_GET(pType) (*(CpaDcChainSessionType *)pType)

#define DC_COMP_SESSION_SIZE                                                   \
    (sizeof(dc_session_desc_t) + sizeof(LAC_ARCH_UINT) + LAC_64BYTE_ALIGNMENT)

#define FIRST_DC_CHAIN_ITEM 0
#define NOT_APPLICABLE 0

/* List of the different OpData types supported as defined in the DC Chain API
 * header file.
 */
typedef enum dc_chain_opdata_type_e
{
    DC_CHAIN_OPDATA_TYPE0 = 0,
    /**< Refer to the API definition for CpaDcChainOpData format */
    DC_CHAIN_OPDATA_TYPE1
    /**< Refer to the API definition for CpaDcChainOpData2 format */
} dc_chain_opdata_type_t;

typedef struct dc_chain_opdata_ext_s
{
    dc_chain_opdata_type_t opDataType;
    /**< Indicates the type of OpData being used */
    void *pOpData;
    /**< Pointer to the OpData structure being used */
} dc_chain_opdata_ext_t;

/* List of the different Result structure types supported as defined in the DC
 * Chain API header file.
 */
typedef enum dc_chain_results_type_e
{
    DC_CHAIN_RESULTS_TYPE0 = 0,
    /**< Refer to the API definition for CpaDcChainRqResults format */
    DC_CHAIN_RESULTS_TYPE1
    /**< Refer to the API definition for CpaDcChainRqVResults format */
} dc_chain_results_type_t;

typedef struct dc_chain_results_ext_s
{
    dc_chain_results_type_t resultsType;
    /**< Indicates the type of Results being used */
    void *pResults;
    /**< Pointer to the results structure being used */
} dc_chain_results_ext_t;

typedef struct dc_chain_cmd_tbl_s
{
    Cpa16U link0_key;
    /**< Session type key for first session in chaining */
    Cpa16U link1_key;
    /**< Session type key for second session in chaining */
    Cpa16U link2_key;
    /**< Session type key for third session in chaining */
    icp_qat_comp_chain_cmd_id_t cmd_id;
    /**< Chaining operation */
    icp_qat_comp_chain_20_cmd_id_t cmd_20_id;
    /**< Chaining 2.0 operation */
} dc_chain_cmd_tbl_t;

typedef struct dc_chain_cookie_s
{
    CpaInstanceHandle dcInstance;
    /**< Compression instance handle */
    CpaDcSessionHandle pSessionHandle;
    /**< Pointer to the session handle */
    icp_qat_fw_comp_chain_req_t request;
    /**< Compression chaining request */
    dc_chain_results_ext_t extResults;
    /**< Extensible results buffer holding consumed and produced data */
    void *pDcRspAddr;
    /**< chaining compression response buffer */
    void *pCyRspAddr;
    /**< chaining hash response buffer */
    void *pDcCookieAddr;
    /**< chaining compression cookie buffer */
    void *pCyCookieAddr;
    /**< chaining hash cookie buffer */
    void *callbackTag;
    /**< Opaque data supplied by the client */
} dc_chain_cookie_t;

typedef struct dc_chain_session_head_s
{
    union {
        icp_qat_comp_chain_req_hdr_t comn_hdr;
        /**< Compression chaining header for Gen2 */
        icp_qat_fw_comn_req_hdr_t comn_hdr2;
        /**< Compression chaining header for non Gen2 */
    } hdr;
    Cpa16U numLinks;
    dc_session_desc_t *pDcSessionDesc;
    lac_session_desc_t *pCySessionDesc;
    CpaDcCallbackFn pdcChainCb;
    /**< Callback function defined for the traditional compression session */
    OsalAtomic pendingChainCbCount;
    /**< Keeps track of number of pending requests on stateless session */
} dc_chain_session_head_t;

/**
 *****************************************************************************
 * @ingroup Dc_Chaining
 *      Initialize chaining service
 *
 * @description
 *      Initialize chaining service, it will be call by
 *      compression service initialization API
 *
 * @param[in,out]       pCompService     Compression service
 * @param[out]          pChainService    Chaining service
 *
 * @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
 *
 *****************************************************************************/
CpaStatus dcChainServiceInit(sal_compression_service_t *pCompService,
                             sal_dc_chain_service_t *pChainService);
/**
 *****************************************************************************
 * @ingroup Dc_Chaining
 *      Shutdown chaining service
 *
 * @description
 *      Shutdown chaining service, it will be called by
 *      compression shutdown API
 *
 * @param[in,out]       pCompService     Compression service
 * @param[in]           pChainService    Chaining service
 *
 * @retval none
 *
 *****************************************************************************/
void dcChainServiceShutdown(sal_compression_service_t *pCompService,
                            sal_dc_chain_service_t *pChainService);

/**
 *****************************************************************************
 * @ingroup Dc_Chaining
 *      Initialization for chaining sessions
 *
 * @description
 *      Initialization for chaining sessions
 *
 * @param[in]         dcInstance    Instance handle derived from discovery
 *                                  functions.
 * @param[in,out]   pSessionHandle  Pointer to a session handle.
 * @param[in,out]   pSessionData    Pointer to an array of
 *                                  CpaDcChainSessionSetupData structures.
 *                                  There should be numSessions entries in the
 *                                  array.
 * @param[in]         numSessions   Number of sessions for the chaining
 * @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 to find device
 * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in
 *
 *****************************************************************************/
CpaStatus dcChainInitSessions(CpaInstanceHandle dcInstance,
                              CpaDcSessionHandle pSessionHandle,
                              CpaDcChainSessionSetupData *pSessionData,
                              Cpa8U numSessions,
                              CpaDcCallbackFn callbackFn);

/**
 *****************************************************************************
 * @ingroup Dc_Chaining
 *      Chaining perform operation
 *
 * @description
 *      Chaining perform operation, it is called at cpaDcChainPerformOp,
 *      which is used to perform chaining requests.
 *
 * @param[in]       dcInstance         Instance handle derived from discovery
 *                                     functions.
 * @param[in]       pSessionHandle     Pointer to a session handle.
 * @param[in]       pSrcBuff           Source buffer
 * @param[in]       pDestBuff          Destination buffer
 * @param[in]       pInterBuff         Pointer to intermediate buffer to be
 *                                     used as internal staging area for
 *                                     chaining operations.
 * @param[in]       operation          Chaining operation
 * @param[in]       numOperations      Number of operations for the chaining
 * @param[in]       pChainOpDataExt    Extensible chaining operation data
 * @param[in,out]   pResultsExt        Extensible chaining response result
 * @param[in]       callbackTag        For synchronous operation this callback
 *                                     shall be a null pointer.
 *
 * @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_RESOURCE       Failed to allocate required resources
 * @retval CPA_STATUS_RETRY          Request re-submission needed
 *
 *****************************************************************************/
CpaStatus dcChainPerformOp(CpaInstanceHandle dcInstance,
                           CpaDcSessionHandle pSessionHandle,
                           CpaBufferList *pSrcBuff,
                           CpaBufferList *pDestBuff,
                           CpaBufferList *pInterBuff,
                           CpaDcChainOperations operation,
                           Cpa8U numOperations,
                           dc_chain_opdata_ext_t *pChainOpDataExt,
                           dc_chain_results_ext_t *pResultsExt,
                           void *callbackTag);

/**
 *****************************************************************************
 * @ingroup Dc_Chaining
 *      Chaining response callback
 *
 * @description
 *      Chaining response callback
 *
 * @param[in]       pRespMsg         Chaining response discriptor
 *
 * @retval none
 *
 *****************************************************************************/
void dcChainProcessResults(void *pRespMsg);

#endif /* DC_CHAIN_H */
