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