xref: /freebsd-src/sys/dev/qat/qat_api/common/compression/dc_header_footer.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
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