1*78ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
2*78ee8d1cSJulian Grajkowski /* Copyright(c) 2007-2022 Intel Corporation */
3*78ee8d1cSJulian Grajkowski /**
4*78ee8d1cSJulian Grajkowski *****************************************************************************
5*78ee8d1cSJulian Grajkowski * @file dc_header_footer.c
6*78ee8d1cSJulian Grajkowski *
7*78ee8d1cSJulian Grajkowski * @ingroup Dc_DataCompression
8*78ee8d1cSJulian Grajkowski *
9*78ee8d1cSJulian Grajkowski * @description
10*78ee8d1cSJulian Grajkowski * Implementation of the Data Compression header and footer operations.
11*78ee8d1cSJulian Grajkowski *
12*78ee8d1cSJulian Grajkowski *****************************************************************************/
13*78ee8d1cSJulian Grajkowski
14*78ee8d1cSJulian Grajkowski /*
15*78ee8d1cSJulian Grajkowski *******************************************************************************
16*78ee8d1cSJulian Grajkowski * Include public/global header files
17*78ee8d1cSJulian Grajkowski *******************************************************************************
18*78ee8d1cSJulian Grajkowski */
19*78ee8d1cSJulian Grajkowski #include "cpa.h"
20*78ee8d1cSJulian Grajkowski #include "cpa_dc.h"
21*78ee8d1cSJulian Grajkowski #include "icp_adf_init.h"
22*78ee8d1cSJulian Grajkowski
23*78ee8d1cSJulian Grajkowski /*
24*78ee8d1cSJulian Grajkowski *******************************************************************************
25*78ee8d1cSJulian Grajkowski * Include private header files
26*78ee8d1cSJulian Grajkowski *******************************************************************************
27*78ee8d1cSJulian Grajkowski */
28*78ee8d1cSJulian Grajkowski #include "dc_header_footer.h"
29*78ee8d1cSJulian Grajkowski #include "dc_session.h"
30*78ee8d1cSJulian Grajkowski #include "dc_datapath.h"
31*78ee8d1cSJulian Grajkowski
32*78ee8d1cSJulian Grajkowski CpaStatus
cpaDcGenerateHeader(CpaDcSessionHandle pSessionHandle,CpaFlatBuffer * pDestBuff,Cpa32U * count)33*78ee8d1cSJulian Grajkowski cpaDcGenerateHeader(CpaDcSessionHandle pSessionHandle,
34*78ee8d1cSJulian Grajkowski CpaFlatBuffer *pDestBuff,
35*78ee8d1cSJulian Grajkowski Cpa32U *count)
36*78ee8d1cSJulian Grajkowski {
37*78ee8d1cSJulian Grajkowski dc_session_desc_t *pSessionDesc = NULL;
38*78ee8d1cSJulian Grajkowski
39*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pSessionHandle);
40*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pDestBuff);
41*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pDestBuff->pData);
42*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(count);
43*78ee8d1cSJulian Grajkowski
44*78ee8d1cSJulian Grajkowski pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
45*78ee8d1cSJulian Grajkowski
46*78ee8d1cSJulian Grajkowski if (NULL == pSessionDesc) {
47*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG("Session handle not as expected\n");
48*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
49*78ee8d1cSJulian Grajkowski }
50*78ee8d1cSJulian Grajkowski
51*78ee8d1cSJulian Grajkowski if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
52*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG("Invalid session direction\n");
53*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
54*78ee8d1cSJulian Grajkowski }
55*78ee8d1cSJulian Grajkowski
56*78ee8d1cSJulian Grajkowski if (CPA_DC_DEFLATE == pSessionDesc->compType) {
57*78ee8d1cSJulian Grajkowski /* Adding a Gzip header */
58*78ee8d1cSJulian Grajkowski if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
59*78ee8d1cSJulian Grajkowski Cpa8U *pDest = pDestBuff->pData;
60*78ee8d1cSJulian Grajkowski
61*78ee8d1cSJulian Grajkowski if (pDestBuff->dataLenInBytes < DC_GZIP_HEADER_SIZE) {
62*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG(
63*78ee8d1cSJulian Grajkowski "The dataLenInBytes of the dest buffer is too small.\n");
64*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
65*78ee8d1cSJulian Grajkowski }
66*78ee8d1cSJulian Grajkowski
67*78ee8d1cSJulian Grajkowski pDest[0] = DC_GZIP_ID1; /* ID1 */
68*78ee8d1cSJulian Grajkowski pDest[1] = DC_GZIP_ID2; /* ID2 */
69*78ee8d1cSJulian Grajkowski pDest[2] =
70*78ee8d1cSJulian Grajkowski 0x08; /* CM = 8 denotes "deflate" compression */
71*78ee8d1cSJulian Grajkowski pDest[3] = 0x00; /* FLG = 0 denotes "No extra fields" */
72*78ee8d1cSJulian Grajkowski pDest[4] = 0x00;
73*78ee8d1cSJulian Grajkowski pDest[5] = 0x00;
74*78ee8d1cSJulian Grajkowski pDest[6] = 0x00;
75*78ee8d1cSJulian Grajkowski pDest[7] = 0x00; /* MTIME = 0x00 means time stamp not
76*78ee8d1cSJulian Grajkowski available */
77*78ee8d1cSJulian Grajkowski
78*78ee8d1cSJulian Grajkowski /* XFL = 4 - compressor used fastest compression, */
79*78ee8d1cSJulian Grajkowski /* XFL = 2 - compressor used maximum compression. */
80*78ee8d1cSJulian Grajkowski pDest[8] = 0;
81*78ee8d1cSJulian Grajkowski if (CPA_DC_L1 == pSessionDesc->compLevel)
82*78ee8d1cSJulian Grajkowski pDest[8] = DC_GZIP_FAST_COMP;
83*78ee8d1cSJulian Grajkowski else if (CPA_DC_L4 >= pSessionDesc->compLevel)
84*78ee8d1cSJulian Grajkowski pDest[8] = DC_GZIP_MAX_COMP;
85*78ee8d1cSJulian Grajkowski
86*78ee8d1cSJulian Grajkowski pDest[9] =
87*78ee8d1cSJulian Grajkowski DC_GZIP_FILESYSTYPE; /* OS = 0 means FAT filesystem
88*78ee8d1cSJulian Grajkowski (MS-DOS, OS/2, NT/Win32), 3 - Unix */
89*78ee8d1cSJulian Grajkowski
90*78ee8d1cSJulian Grajkowski /* Set to the number of bytes added to the buffer */
91*78ee8d1cSJulian Grajkowski *count = DC_GZIP_HEADER_SIZE;
92*78ee8d1cSJulian Grajkowski }
93*78ee8d1cSJulian Grajkowski
94*78ee8d1cSJulian Grajkowski /* Adding a Zlib header */
95*78ee8d1cSJulian Grajkowski else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
96*78ee8d1cSJulian Grajkowski Cpa8U *pDest = pDestBuff->pData;
97*78ee8d1cSJulian Grajkowski Cpa16U header = 0, level = 0;
98*78ee8d1cSJulian Grajkowski
99*78ee8d1cSJulian Grajkowski if (pDestBuff->dataLenInBytes < DC_ZLIB_HEADER_SIZE) {
100*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG(
101*78ee8d1cSJulian Grajkowski "The dataLenInBytes of the dest buffer is too small.\n");
102*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
103*78ee8d1cSJulian Grajkowski }
104*78ee8d1cSJulian Grajkowski
105*78ee8d1cSJulian Grajkowski /* CMF = CM | CMINFO.
106*78ee8d1cSJulian Grajkowski CM = 8 denotes "deflate" compression,
107*78ee8d1cSJulian Grajkowski CMINFO = 7 indicates a 32K window size */
108*78ee8d1cSJulian Grajkowski /* Depending on the device, at compression levels above
109*78ee8d1cSJulian Grajkowski L1, the
110*78ee8d1cSJulian Grajkowski window size can be 8 or 16K bytes.
111*78ee8d1cSJulian Grajkowski The file will decompress ok if a greater window size
112*78ee8d1cSJulian Grajkowski is specified
113*78ee8d1cSJulian Grajkowski in the header. */
114*78ee8d1cSJulian Grajkowski header =
115*78ee8d1cSJulian Grajkowski (DC_ZLIB_CM_DEFLATE +
116*78ee8d1cSJulian Grajkowski (DC_32K_WINDOW_SIZE << DC_ZLIB_WINDOWSIZE_OFFSET))
117*78ee8d1cSJulian Grajkowski << LAC_NUM_BITS_IN_BYTE;
118*78ee8d1cSJulian Grajkowski
119*78ee8d1cSJulian Grajkowski switch (pSessionDesc->compLevel) {
120*78ee8d1cSJulian Grajkowski case CPA_DC_L1:
121*78ee8d1cSJulian Grajkowski level = DC_ZLIB_LEVEL_0;
122*78ee8d1cSJulian Grajkowski break;
123*78ee8d1cSJulian Grajkowski case CPA_DC_L2:
124*78ee8d1cSJulian Grajkowski level = DC_ZLIB_LEVEL_1;
125*78ee8d1cSJulian Grajkowski break;
126*78ee8d1cSJulian Grajkowski case CPA_DC_L3:
127*78ee8d1cSJulian Grajkowski level = DC_ZLIB_LEVEL_2;
128*78ee8d1cSJulian Grajkowski break;
129*78ee8d1cSJulian Grajkowski default:
130*78ee8d1cSJulian Grajkowski level = DC_ZLIB_LEVEL_3;
131*78ee8d1cSJulian Grajkowski }
132*78ee8d1cSJulian Grajkowski
133*78ee8d1cSJulian Grajkowski /* Bits 6 - 7: FLEVEL, compression level */
134*78ee8d1cSJulian Grajkowski header |= level << DC_ZLIB_FLEVEL_OFFSET;
135*78ee8d1cSJulian Grajkowski
136*78ee8d1cSJulian Grajkowski /* The header has to be a multiple of 31 */
137*78ee8d1cSJulian Grajkowski header += DC_ZLIB_HEADER_OFFSET -
138*78ee8d1cSJulian Grajkowski (header % DC_ZLIB_HEADER_OFFSET);
139*78ee8d1cSJulian Grajkowski
140*78ee8d1cSJulian Grajkowski pDest[0] = (Cpa8U)(header >> LAC_NUM_BITS_IN_BYTE);
141*78ee8d1cSJulian Grajkowski pDest[1] = (Cpa8U)header;
142*78ee8d1cSJulian Grajkowski
143*78ee8d1cSJulian Grajkowski /* Set to the number of bytes added to the buffer */
144*78ee8d1cSJulian Grajkowski *count = DC_ZLIB_HEADER_SIZE;
145*78ee8d1cSJulian Grajkowski }
146*78ee8d1cSJulian Grajkowski
147*78ee8d1cSJulian Grajkowski /* If deflate but no checksum required */
148*78ee8d1cSJulian Grajkowski else {
149*78ee8d1cSJulian Grajkowski *count = 0;
150*78ee8d1cSJulian Grajkowski }
151*78ee8d1cSJulian Grajkowski } else {
152*78ee8d1cSJulian Grajkowski /* There is no header for other compressed data */
153*78ee8d1cSJulian Grajkowski *count = 0;
154*78ee8d1cSJulian Grajkowski }
155*78ee8d1cSJulian Grajkowski return CPA_STATUS_SUCCESS;
156*78ee8d1cSJulian Grajkowski }
157*78ee8d1cSJulian Grajkowski
158*78ee8d1cSJulian Grajkowski CpaStatus
cpaDcGenerateFooter(CpaDcSessionHandle pSessionHandle,CpaFlatBuffer * pDestBuff,CpaDcRqResults * pRes)159*78ee8d1cSJulian Grajkowski cpaDcGenerateFooter(CpaDcSessionHandle pSessionHandle,
160*78ee8d1cSJulian Grajkowski CpaFlatBuffer *pDestBuff,
161*78ee8d1cSJulian Grajkowski CpaDcRqResults *pRes)
162*78ee8d1cSJulian Grajkowski {
163*78ee8d1cSJulian Grajkowski dc_session_desc_t *pSessionDesc = NULL;
164*78ee8d1cSJulian Grajkowski
165*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pSessionHandle);
166*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pDestBuff);
167*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pDestBuff->pData);
168*78ee8d1cSJulian Grajkowski LAC_CHECK_NULL_PARAM(pRes);
169*78ee8d1cSJulian Grajkowski
170*78ee8d1cSJulian Grajkowski pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
171*78ee8d1cSJulian Grajkowski
172*78ee8d1cSJulian Grajkowski if (NULL == pSessionDesc) {
173*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG("Session handle not as expected\n");
174*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
175*78ee8d1cSJulian Grajkowski }
176*78ee8d1cSJulian Grajkowski
177*78ee8d1cSJulian Grajkowski if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
178*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG("Invalid session direction\n");
179*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
180*78ee8d1cSJulian Grajkowski }
181*78ee8d1cSJulian Grajkowski
182*78ee8d1cSJulian Grajkowski if (CPA_DC_DEFLATE == pSessionDesc->compType) {
183*78ee8d1cSJulian Grajkowski if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
184*78ee8d1cSJulian Grajkowski Cpa8U *pDest = pDestBuff->pData;
185*78ee8d1cSJulian Grajkowski Cpa32U crc32 = pRes->checksum;
186*78ee8d1cSJulian Grajkowski Cpa64U totalLenBeforeCompress =
187*78ee8d1cSJulian Grajkowski pSessionDesc->cumulativeConsumedBytes;
188*78ee8d1cSJulian Grajkowski
189*78ee8d1cSJulian Grajkowski if (pDestBuff->dataLenInBytes < DC_GZIP_FOOTER_SIZE) {
190*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG(
191*78ee8d1cSJulian Grajkowski "The dataLenInBytes of the dest buffer is too small.\n");
192*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
193*78ee8d1cSJulian Grajkowski }
194*78ee8d1cSJulian Grajkowski
195*78ee8d1cSJulian Grajkowski /* Crc32 of the uncompressed data */
196*78ee8d1cSJulian Grajkowski pDest[0] = (Cpa8U)crc32;
197*78ee8d1cSJulian Grajkowski pDest[1] = (Cpa8U)(crc32 >> LAC_NUM_BITS_IN_BYTE);
198*78ee8d1cSJulian Grajkowski pDest[2] = (Cpa8U)(crc32 >> 2 * LAC_NUM_BITS_IN_BYTE);
199*78ee8d1cSJulian Grajkowski pDest[3] = (Cpa8U)(crc32 >> 3 * LAC_NUM_BITS_IN_BYTE);
200*78ee8d1cSJulian Grajkowski
201*78ee8d1cSJulian Grajkowski /* Length of the uncompressed data */
202*78ee8d1cSJulian Grajkowski pDest[4] = (Cpa8U)totalLenBeforeCompress;
203*78ee8d1cSJulian Grajkowski pDest[5] = (Cpa8U)(totalLenBeforeCompress >>
204*78ee8d1cSJulian Grajkowski LAC_NUM_BITS_IN_BYTE);
205*78ee8d1cSJulian Grajkowski pDest[6] = (Cpa8U)(totalLenBeforeCompress >>
206*78ee8d1cSJulian Grajkowski 2 * LAC_NUM_BITS_IN_BYTE);
207*78ee8d1cSJulian Grajkowski pDest[7] = (Cpa8U)(totalLenBeforeCompress >>
208*78ee8d1cSJulian Grajkowski 3 * LAC_NUM_BITS_IN_BYTE);
209*78ee8d1cSJulian Grajkowski
210*78ee8d1cSJulian Grajkowski /* Increment produced by the number of bytes added to
211*78ee8d1cSJulian Grajkowski * the buffer */
212*78ee8d1cSJulian Grajkowski pRes->produced += DC_GZIP_FOOTER_SIZE;
213*78ee8d1cSJulian Grajkowski } else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
214*78ee8d1cSJulian Grajkowski Cpa8U *pDest = pDestBuff->pData;
215*78ee8d1cSJulian Grajkowski Cpa32U adler32 = pRes->checksum;
216*78ee8d1cSJulian Grajkowski
217*78ee8d1cSJulian Grajkowski if (pDestBuff->dataLenInBytes < DC_ZLIB_FOOTER_SIZE) {
218*78ee8d1cSJulian Grajkowski QAT_UTILS_LOG(
219*78ee8d1cSJulian Grajkowski "The dataLenInBytes of the dest buffer is too small.\n");
220*78ee8d1cSJulian Grajkowski return CPA_STATUS_INVALID_PARAM;
221*78ee8d1cSJulian Grajkowski }
222*78ee8d1cSJulian Grajkowski
223*78ee8d1cSJulian Grajkowski /* Adler32 of the uncompressed data */
224*78ee8d1cSJulian Grajkowski pDest[0] = (Cpa8U)(adler32 >> 3 * LAC_NUM_BITS_IN_BYTE);
225*78ee8d1cSJulian Grajkowski pDest[1] = (Cpa8U)(adler32 >> 2 * LAC_NUM_BITS_IN_BYTE);
226*78ee8d1cSJulian Grajkowski pDest[2] = (Cpa8U)(adler32 >> LAC_NUM_BITS_IN_BYTE);
227*78ee8d1cSJulian Grajkowski pDest[3] = (Cpa8U)adler32;
228*78ee8d1cSJulian Grajkowski
229*78ee8d1cSJulian Grajkowski /* Increment produced by the number of bytes added to
230*78ee8d1cSJulian Grajkowski * the buffer */
231*78ee8d1cSJulian Grajkowski pRes->produced += DC_ZLIB_FOOTER_SIZE;
232*78ee8d1cSJulian Grajkowski }
233*78ee8d1cSJulian Grajkowski }
234*78ee8d1cSJulian Grajkowski
235*78ee8d1cSJulian Grajkowski return CPA_STATUS_SUCCESS;
236*78ee8d1cSJulian Grajkowski }
237