1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 /** 5 ***************************************************************************** 6 * @file dc_buffers.c 7 * 8 * @defgroup Dc_DataCompression DC Data Compression 9 * 10 * @ingroup Dc_DataCompression 11 * 12 * @description 13 * Implementation of the buffer management operations for 14 * Data Compression service. 15 * 16 *****************************************************************************/ 17 18 /* 19 ******************************************************************************* 20 * Include public/global header files 21 ******************************************************************************* 22 */ 23 #include "cpa.h" 24 #include "cpa_dc.h" 25 #include "cpa_dc_bp.h" 26 27 #include "sal_types_compression.h" 28 #include "icp_qat_fw_comp.h" 29 #include "sal_hw_gen.h" 30 31 #define CPA_DC_CEIL_DIV(x, y) (((x) + (y)-1) / (y)) 32 #define DC_DEST_BUFF_EXTRA_DEFLATE_GEN2 (55) 33 #define DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_STATIC (1029) 34 #define DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_DYN (512) 35 #define DC_DEST_BUFF_MIN_EXTRA_BYTES(x) ((x < 8) ? (8 - x) : 0) 36 #define DC_BUF_MAX_SIZE (0xFFFFFFFF) 37 38 CpaStatus 39 cpaDcBufferListGetMetaSize(const CpaInstanceHandle instanceHandle, 40 Cpa32U numBuffers, 41 Cpa32U *pSizeInBytes) 42 { 43 CpaInstanceHandle insHandle = NULL; 44 45 if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) { 46 insHandle = dcGetFirstHandle(); 47 } else { 48 insHandle = instanceHandle; 49 } 50 51 LAC_CHECK_INSTANCE_HANDLE(insHandle); 52 LAC_CHECK_NULL_PARAM(pSizeInBytes); 53 54 /* Ensure this is a compression instance */ 55 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 56 57 if (0 == numBuffers) { 58 QAT_UTILS_LOG("Number of buffers is 0.\n"); 59 return CPA_STATUS_INVALID_PARAM; 60 } 61 62 *pSizeInBytes = (sizeof(icp_buffer_list_desc_t) + 63 (sizeof(icp_flat_buffer_desc_t) * (numBuffers + 1)) + 64 ICP_DESCRIPTOR_ALIGNMENT_BYTES); 65 66 return CPA_STATUS_SUCCESS; 67 } 68 69 CpaStatus 70 cpaDcBnpBufferListGetMetaSize(const CpaInstanceHandle instanceHandle, 71 Cpa32U numJobs, 72 Cpa32U *pSizeInBytes) 73 { 74 return CPA_STATUS_UNSUPPORTED; 75 } 76 77 static inline CpaStatus 78 dcDeflateBoundGen2(CpaDcHuffType huffType, Cpa32U inputSize, Cpa32U *outputSize) 79 { 80 Cpa64U inBufferSize = inputSize; 81 Cpa64U outBufferSize = 0; 82 83 /* Formula for GEN2 deflate: 84 * ceil(9 * Total input bytes / 8) + 55 bytes. 85 * 55 bytes is the skid pad value for GEN2 devices. 86 * Adding extra bytes = `DC_DEST_BUFF_MIN_EXTRA_BYTES(inputSize)` 87 * when calculated value from `CPA_DC_CEIL_DIV(9 * inputSize, 8) + 88 * DC_DEST_BUFF_EXTRA_DEFLATE_GEN2` is less than 64 bytes to 89 * achieve a safer output buffer size of 64 bytes. 90 */ 91 outBufferSize = CPA_DC_CEIL_DIV(9 * inBufferSize, 8) + 92 DC_DEST_BUFF_EXTRA_DEFLATE_GEN2 + 93 DC_DEST_BUFF_MIN_EXTRA_BYTES(inputSize); 94 95 if (outBufferSize > DC_BUF_MAX_SIZE) 96 *outputSize = DC_BUF_MAX_SIZE; 97 else 98 *outputSize = (Cpa32U)outBufferSize; 99 100 return CPA_STATUS_SUCCESS; 101 } 102 103 static inline CpaStatus 104 dcDeflateBoundGen4(CpaDcHuffType huffType, Cpa32U inputSize, Cpa32U *outputSize) 105 { 106 Cpa64U outputSizeLong; 107 Cpa64U inputSizeLong = (Cpa64U)inputSize; 108 109 switch (huffType) { 110 case CPA_DC_HT_STATIC: 111 /* Formula for GEN4 static deflate: 112 * ceil((9*sourceLen)/8) + 5 + 1024. */ 113 outputSizeLong = CPA_DC_CEIL_DIV(9 * inputSizeLong, 8) + 114 DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_STATIC; 115 break; 116 case CPA_DC_HT_FULL_DYNAMIC: 117 /* Formula for GEN4 dynamic deflate: 118 * Ceil ((9*sourceLen)/8)▒| + 119 * ((((8/7) * sourceLen)/ 16KB) * (150+5)) + 512 120 */ 121 outputSizeLong = DC_DEST_BUFF_EXTRA_DEFLATE_GEN4_DYN; 122 outputSizeLong += CPA_DC_CEIL_DIV(9 * inputSizeLong, 8); 123 outputSizeLong += ((8 * inputSizeLong * 155) / 7) / (16 * 1024); 124 break; 125 default: 126 return CPA_STATUS_INVALID_PARAM; 127 } 128 129 /* Avoid output size overflow */ 130 if (outputSizeLong & 0xffffffff00000000UL) 131 return CPA_STATUS_INVALID_PARAM; 132 133 *outputSize = (Cpa32U)outputSizeLong; 134 return CPA_STATUS_SUCCESS; 135 } 136 137 CpaStatus 138 cpaDcDeflateCompressBound(const CpaInstanceHandle dcInstance, 139 CpaDcHuffType huffType, 140 Cpa32U inputSize, 141 Cpa32U *outputSize) 142 { 143 sal_compression_service_t *pService = NULL; 144 CpaInstanceHandle insHandle = NULL; 145 146 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 147 insHandle = dcGetFirstHandle(); 148 } else { 149 insHandle = dcInstance; 150 } 151 152 LAC_CHECK_INSTANCE_HANDLE(insHandle); 153 LAC_CHECK_NULL_PARAM(outputSize); 154 /* Ensure this is a compression instance */ 155 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 156 if (!inputSize) { 157 QAT_UTILS_LOG( 158 "The input size needs to be greater than zero.\n"); 159 return CPA_STATUS_INVALID_PARAM; 160 } 161 162 if ((CPA_DC_HT_STATIC != huffType) && 163 (CPA_DC_HT_FULL_DYNAMIC != huffType)) { 164 QAT_UTILS_LOG("Invalid huffType value.\n"); 165 return CPA_STATUS_INVALID_PARAM; 166 } 167 168 pService = (sal_compression_service_t *)insHandle; 169 if (isDcGen4x(pService)) { 170 return dcDeflateBoundGen4(huffType, inputSize, outputSize); 171 } else { 172 return dcDeflateBoundGen2(huffType, inputSize, outputSize); 173 } 174 } 175 176 CpaStatus 177 cpaDcLZ4CompressBound(const CpaInstanceHandle dcInstance, 178 Cpa32U inputSize, 179 Cpa32U *outputSize) 180 { 181 return CPA_STATUS_UNSUPPORTED; 182 } 183 184 CpaStatus 185 cpaDcLZ4SCompressBound(const CpaInstanceHandle dcInstance, 186 Cpa32U inputSize, 187 Cpa32U *outputSize) 188 { 189 return CPA_STATUS_UNSUPPORTED; 190 } 191