#include "cpa.h"
#include "cpa_dc.h"
#include "cpa_dc_bp.h"
#include "sal_types_compression.h"
#include "icp_qat_fw_comp.h"
#include "sal_hw_gen.h"
#define CPA_DC_CEIL_DIV(x, y) (((x) + (y)-1) / (y))
#define DC_DEST_BUFF_EXTRA_DEFLATE_GEN2 (55)
#define DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_STATIC (1029)
#define DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_DYN (512)
#define DC_DEST_BUFF_MIN_EXTRA_BYTES(x) ((x < 8) ? (8 - x) : 0)
#define DC_BUF_MAX_SIZE (0xFFFFFFFF)
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);
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)
{
Cpa64U inBufferSize = inputSize;
Cpa64U outBufferSize = 0;
outBufferSize = CPA_DC_CEIL_DIV(9 * inBufferSize, 8) +
DC_DEST_BUFF_EXTRA_DEFLATE_GEN2 +
DC_DEST_BUFF_MIN_EXTRA_BYTES(inputSize);
if (outBufferSize > DC_BUF_MAX_SIZE)
*outputSize = DC_BUF_MAX_SIZE;
else
*outputSize = (Cpa32U)outBufferSize;
return CPA_STATUS_SUCCESS;
}
static inline CpaStatus
dcDeflateBoundGen4(CpaDcHuffType huffType, Cpa32U inputSize, Cpa32U *outputSize)
{
Cpa64U outputSizeLong;
Cpa64U inputSizeLong = (Cpa64U)inputSize;
switch (huffType) {
case CPA_DC_HT_STATIC:
outputSizeLong = CPA_DC_CEIL_DIV(9 * inputSizeLong, 8) +
DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_STATIC;
break;
case CPA_DC_HT_FULL_DYNAMIC:
outputSizeLong = DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_DYN;
outputSizeLong += CPA_DC_CEIL_DIV(9 * inputSizeLong, 8);
outputSizeLong += ((8 * inputSizeLong * 155) / 7) / (16 * 1024);
break;
default:
return CPA_STATUS_INVALID_PARAM;
}
if (outputSizeLong & 0xffffffff00000000UL)
return CPA_STATUS_INVALID_PARAM;
*outputSize = (Cpa32U)outputSizeLong;
return CPA_STATUS_SUCCESS;
}
CpaStatus
cpaDcDeflateCompressBound(const CpaInstanceHandle dcInstance,
CpaDcHuffType huffType,
Cpa32U inputSize,
Cpa32U *outputSize)
{
sal_compression_service_t *pService = NULL;
CpaInstanceHandle insHandle = NULL;
if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
insHandle = dcGetFirstHandle();
} else {
insHandle = dcInstance;
}
LAC_CHECK_INSTANCE_HANDLE(insHandle);
LAC_CHECK_NULL_PARAM(outputSize);
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;
}
pService = (sal_compression_service_t *)insHandle;
if (isDcGen4x(pService)) {
return dcDeflateBoundGen4(huffType, inputSize, outputSize);
} else {
return dcDeflateBoundGen2(huffType, inputSize, outputSize);
}
}
CpaStatus
cpaDcLZ4CompressBound(const CpaInstanceHandle dcInstance,
Cpa32U inputSize,
Cpa32U *outputSize)
{
return CPA_STATUS_UNSUPPORTED;
}
CpaStatus
cpaDcLZ4SCompressBound(const CpaInstanceHandle dcInstance,
Cpa32U inputSize,
Cpa32U *outputSize)
{
return CPA_STATUS_UNSUPPORTED;
}