1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 /**
4 *****************************************************************************
5 * @file dc_datapath.c
6 *
7 * @defgroup Dc_DataCompression DC Data Compression
8 *
9 * @ingroup Dc_DataCompression
10 *
11 * @description
12 * Implementation of the Data Compression datapath operations.
13 *
14 *****************************************************************************/
15
16 /*
17 *******************************************************************************
18 * Include public/global header files
19 *******************************************************************************
20 */
21 #include "cpa.h"
22 #include "cpa_dc.h"
23 #include "cpa_dc_dp.h"
24
25 /*
26 *******************************************************************************
27 * Include private header files
28 *******************************************************************************
29 */
30 #include "dc_session.h"
31 #include "dc_datapath.h"
32 #include "sal_statistics.h"
33 #include "lac_common.h"
34 #include "lac_mem.h"
35 #include "lac_mem_pools.h"
36 #include "sal_types_compression.h"
37 #include "dc_stats.h"
38 #include "lac_buffer_desc.h"
39 #include "lac_sal.h"
40 #include "lac_log.h"
41 #include "lac_sync.h"
42 #include "sal_service_state.h"
43 #include "sal_qat_cmn_msg.h"
44 #include "sal_hw_gen.h"
45 #include "dc_error_counter.h"
46 #define DC_COMP_MAX_BUFF_SIZE (1024 * 64)
47
48 static QatUtilsAtomic dcErrorCount[MAX_DC_ERROR_TYPE];
49
50 void
dcErrorLog(CpaDcReqStatus dcError)51 dcErrorLog(CpaDcReqStatus dcError)
52 {
53 Cpa32U absError = 0;
54
55 absError = abs(dcError);
56 if ((dcError < CPA_DC_OK) && (absError < MAX_DC_ERROR_TYPE)) {
57 qatUtilsAtomicInc(&(dcErrorCount[absError]));
58 }
59 }
60
61 Cpa64U
getDcErrorCounter(CpaDcReqStatus dcError)62 getDcErrorCounter(CpaDcReqStatus dcError)
63 {
64 Cpa32U absError = 0;
65
66 absError = abs(dcError);
67 if (!(dcError >= CPA_DC_OK || dcError < CPA_DC_EMPTY_DYM_BLK)) {
68 return (Cpa64U)qatUtilsAtomicGet(&dcErrorCount[absError]);
69 }
70
71 return 0;
72 }
73
74 static inline void
dcUpdateXltOverflowChecksumsGen4(const dc_compression_cookie_t * pCookie,const icp_qat_fw_resp_comp_pars_t * pRespPars,CpaDcRqResults * pDcResults)75 dcUpdateXltOverflowChecksumsGen4(const dc_compression_cookie_t *pCookie,
76 const icp_qat_fw_resp_comp_pars_t *pRespPars,
77 CpaDcRqResults *pDcResults)
78 {
79 dc_session_desc_t *pSessionDesc =
80 DC_SESSION_DESC_FROM_CTX_GET(pCookie->pSessionHandle);
81
82 /* Recompute CRC checksum when either the checksum type
83 * is CPA_DC_CRC32 or when the integrity CRCs are enabled.
84 */
85 if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
86 pDcResults->checksum = pRespPars->crc.legacy.curr_crc32;
87
88 /* No need to recalculate the swCrc64I here as this will get
89 * handled later in dcHandleIntegrityChecksumsGen4.
90 */
91 } else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
92 pDcResults->checksum = pRespPars->crc.legacy.curr_adler_32;
93 }
94 }
95
96 void
dcCompression_ProcessCallback(void * pRespMsg)97 dcCompression_ProcessCallback(void *pRespMsg)
98 {
99 CpaStatus status = CPA_STATUS_SUCCESS;
100 icp_qat_fw_comp_resp_t *pCompRespMsg = NULL;
101 void *callbackTag = NULL;
102 Cpa64U *pReqData = NULL;
103 CpaDcDpOpData *pResponse = NULL;
104 CpaDcRqResults *pResults = NULL;
105 CpaDcCallbackFn pCbFunc = NULL;
106 dc_session_desc_t *pSessionDesc = NULL;
107 sal_compression_service_t *pService = NULL;
108 dc_compression_cookie_t *pCookie = NULL;
109 CpaDcOpData *pOpData = NULL;
110 CpaBoolean cmpPass = CPA_TRUE, xlatPass = CPA_TRUE;
111 CpaBoolean isDcDp = CPA_FALSE;
112 CpaBoolean integrityCrcCheck = CPA_FALSE;
113 CpaBoolean verifyHwIntegrityCrcs = CPA_FALSE;
114 Cpa8U cmpErr = ERR_CODE_NO_ERROR, xlatErr = ERR_CODE_NO_ERROR;
115 dc_request_dir_t compDecomp = DC_COMPRESSION_REQUEST;
116 Cpa8U opStatus = ICP_QAT_FW_COMN_STATUS_FLAG_OK;
117 Cpa8U hdrFlags = 0;
118
119 /* Cast response message to compression response message type */
120 pCompRespMsg = (icp_qat_fw_comp_resp_t *)pRespMsg;
121 if (!(pCompRespMsg)) {
122 QAT_UTILS_LOG("pCompRespMsg is NULL\n");
123 return;
124 }
125 /* Extract request data pointer from the opaque data */
126 LAC_MEM_SHARED_READ_TO_PTR(pCompRespMsg->opaque_data, pReqData);
127 if (!(pReqData)) {
128 QAT_UTILS_LOG("pReqData is NULL\n");
129 return;
130 }
131
132 /* Extract fields from the request data structure */
133 pCookie = (dc_compression_cookie_t *)pReqData;
134
135 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pCookie->pSessionHandle);
136 pService = (sal_compression_service_t *)(pCookie->dcInstance);
137
138 isDcDp = pSessionDesc->isDcDp;
139 if (CPA_TRUE == isDcDp) {
140 pResponse = (CpaDcDpOpData *)pReqData;
141 pResults = &(pResponse->results);
142
143 if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
144 compDecomp = DC_DECOMPRESSION_REQUEST;
145 }
146 pCookie = NULL;
147 } else {
148 pResults = pCookie->pResults;
149 callbackTag = pCookie->callbackTag;
150 pCbFunc = pCookie->pSessionDesc->pCompressionCb;
151 compDecomp = pCookie->compDecomp;
152 pOpData = pCookie->pDcOpData;
153 }
154
155 opStatus = pCompRespMsg->comn_resp.comn_status;
156
157 if (NULL != pOpData) {
158 verifyHwIntegrityCrcs = pOpData->verifyHwIntegrityCrcs;
159 integrityCrcCheck = pOpData->integrityCrcCheck;
160 }
161
162 hdrFlags = pCompRespMsg->comn_resp.hdr_flags;
163
164 /* Get the cmp error code */
165 cmpErr = pCompRespMsg->comn_resp.comn_error.s1.cmp_err_code;
166 if (ICP_QAT_FW_COMN_RESP_UNSUPPORTED_REQUEST_STAT_GET(opStatus)) {
167 /* Compression not supported by firmware, set produced/consumed
168 to zero
169 and call the cb function with status CPA_STATUS_UNSUPPORTED
170 */
171 QAT_UTILS_LOG("Compression feature not supported\n");
172 status = CPA_STATUS_UNSUPPORTED;
173 pResults->status = (Cpa8S)cmpErr;
174 pResults->consumed = 0;
175 pResults->produced = 0;
176 if (CPA_TRUE == isDcDp) {
177 if (pResponse)
178 pResponse->responseStatus =
179 CPA_STATUS_UNSUPPORTED;
180 (pService->pDcDpCb)(pResponse);
181 } else {
182 /* Free the memory pool */
183 Lac_MemPoolEntryFree(pCookie);
184 pCookie = NULL;
185
186 if (NULL != pCbFunc) {
187 pCbFunc(callbackTag, status);
188 }
189 }
190 if (DC_COMPRESSION_REQUEST == compDecomp) {
191 COMPRESSION_STAT_INC(numCompCompletedErrors, pService);
192 } else {
193 COMPRESSION_STAT_INC(numDecompCompletedErrors,
194 pService);
195 }
196 return;
197 } else {
198 /* Check compression response status */
199 cmpPass =
200 (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
201 ICP_QAT_FW_COMN_RESP_CMP_STAT_GET(opStatus));
202 }
203
204 if (isDcGen2x(pService)) {
205 /* QAT1.7 and QAT 1.8 hardware */
206 if (CPA_DC_INCOMPLETE_FILE_ERR == (Cpa8S)cmpErr) {
207 cmpPass = CPA_TRUE;
208 cmpErr = ERR_CODE_NO_ERROR;
209 }
210 } else {
211 /* QAT2.0 hardware cancels the incomplete file errors
212 * only for DEFLATE algorithm.
213 * Decompression direction is not tested in the callback as
214 * the request does not allow it.
215 */
216 if ((pSessionDesc->compType == CPA_DC_DEFLATE) &&
217 (CPA_DC_INCOMPLETE_FILE_ERR == (Cpa8S)cmpErr)) {
218 cmpPass = CPA_TRUE;
219 cmpErr = ERR_CODE_NO_ERROR;
220 }
221 }
222 /* log the slice hang and endpoint push/pull error inside the response
223 */
224 if (ERR_CODE_SSM_ERROR == (Cpa8S)cmpErr) {
225 QAT_UTILS_LOG(
226 "Slice hang detected on the compression slice.\n");
227 } else if (ERR_CODE_ENDPOINT_ERROR == (Cpa8S)cmpErr) {
228 QAT_UTILS_LOG(
229 "PCIe End Point Push/Pull or TI/RI Parity error detected.\n");
230 }
231
232 /* We return the compression error code for now. We would need to update
233 * the API if we decide to return both error codes */
234 pResults->status = (Cpa8S)cmpErr;
235
236 /* Check the translator status */
237 if ((DC_COMPRESSION_REQUEST == compDecomp) &&
238 (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) {
239 /* Check translator response status */
240 xlatPass =
241 (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK ==
242 ICP_QAT_FW_COMN_RESP_XLAT_STAT_GET(opStatus));
243
244 /* Get the translator error code */
245 xlatErr = pCompRespMsg->comn_resp.comn_error.s1.xlat_err_code;
246
247 /* Return a fatal error or a potential error in the translator
248 * slice if the compression slice did not return any error */
249 if ((CPA_DC_OK == pResults->status) ||
250 (CPA_DC_FATALERR == (Cpa8S)xlatErr)) {
251 pResults->status = (Cpa8S)xlatErr;
252 }
253 }
254 /* Update dc error counter */
255 dcErrorLog(pResults->status);
256
257 if (CPA_FALSE == isDcDp) {
258 /* In case of any error for an end of packet request, we need to
259 * update
260 * the request type for the following request */
261 if (CPA_DC_FLUSH_FINAL == pCookie->flushFlag && cmpPass &&
262 xlatPass) {
263 pSessionDesc->requestType = DC_REQUEST_FIRST;
264 } else {
265 pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT;
266 }
267 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) ||
268 ((CPA_DC_STATELESS == pSessionDesc->sessState) &&
269 (DC_COMPRESSION_REQUEST == compDecomp))) {
270 /* Overflow is a valid use case for Traditional API
271 * only. Stateful Overflow is supported in both
272 * compression and decompression direction. Stateless
273 * Overflow is supported only in compression direction.
274 */
275 if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr)
276 cmpPass = CPA_TRUE;
277
278 if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) {
279 if (isDcGen4x(pService) &&
280 (CPA_TRUE ==
281 pService->comp_device_data
282 .translatorOverflow)) {
283 pResults->consumed =
284 pCompRespMsg->comp_resp_pars
285 .input_byte_counter;
286
287 dcUpdateXltOverflowChecksumsGen4(
288 pCookie,
289 &pCompRespMsg->comp_resp_pars,
290 pResults);
291 }
292 xlatPass = CPA_TRUE;
293 }
294 }
295 } else {
296 if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr) {
297 cmpPass = CPA_FALSE;
298 }
299 if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) {
300 /* XLT overflow is not valid for Data Plane requests */
301 xlatPass = CPA_FALSE;
302 }
303 }
304
305 if ((CPA_TRUE == cmpPass) && (CPA_TRUE == xlatPass)) {
306 /* Extract the response from the firmware */
307 pResults->consumed =
308 pCompRespMsg->comp_resp_pars.input_byte_counter;
309 pResults->produced =
310 pCompRespMsg->comp_resp_pars.output_byte_counter;
311 pSessionDesc->cumulativeConsumedBytes += pResults->consumed;
312
313 /* Handle Checksum for end to end data integrity. */
314 if (CPA_TRUE ==
315 pService->generic_service_info.integrityCrcCheck &&
316 CPA_TRUE == integrityCrcCheck) {
317 pSessionDesc->previousChecksum =
318 pSessionDesc->seedSwCrc.swCrc32I;
319 } else if (CPA_DC_OVERFLOW != (Cpa8S)xlatErr) {
320 if (CPA_DC_CRC32 == pSessionDesc->checksumType) {
321 pResults->checksum =
322 pCompRespMsg->comp_resp_pars.crc.legacy
323 .curr_crc32;
324 } else if (CPA_DC_ADLER32 ==
325 pSessionDesc->checksumType) {
326 pResults->checksum =
327 pCompRespMsg->comp_resp_pars.crc.legacy
328 .curr_adler_32;
329 }
330 pSessionDesc->previousChecksum = pResults->checksum;
331 }
332
333 if (DC_DECOMPRESSION_REQUEST == compDecomp) {
334 pResults->endOfLastBlock =
335 (ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_SET ==
336 ICP_QAT_FW_COMN_RESP_CMP_END_OF_LAST_BLK_FLAG_GET(
337 opStatus));
338 } else {
339 /* Check if returned data is a stored block
340 * in compression direction
341 */
342 pResults->dataUncompressed =
343 ICP_QAT_FW_COMN_HDR_ST_BLK_FLAG_GET(hdrFlags);
344 }
345
346 /* Save the checksum for the next request */
347 if ((CPA_DC_OVERFLOW != (Cpa8S)xlatErr) &&
348 (CPA_TRUE == verifyHwIntegrityCrcs)) {
349 pSessionDesc->previousChecksum =
350 pSessionDesc->seedSwCrc.swCrc32I;
351 }
352
353 /* Check if a CNV recovery happened and
354 * increase stats counter
355 */
356 if ((DC_COMPRESSION_REQUEST == compDecomp) &&
357 ICP_QAT_FW_COMN_HDR_CNV_FLAG_GET(hdrFlags) &&
358 ICP_QAT_FW_COMN_HDR_CNVNR_FLAG_GET(hdrFlags)) {
359 COMPRESSION_STAT_INC(numCompCnvErrorsRecovered,
360 pService);
361 }
362
363 if (CPA_TRUE == isDcDp) {
364 if (pResponse)
365 pResponse->responseStatus = CPA_STATUS_SUCCESS;
366 } else {
367 if (DC_COMPRESSION_REQUEST == compDecomp) {
368 COMPRESSION_STAT_INC(numCompCompleted,
369 pService);
370 } else {
371 COMPRESSION_STAT_INC(numDecompCompleted,
372 pService);
373 }
374 }
375 } else {
376 #ifdef ICP_DC_RETURN_COUNTERS_ON_ERROR
377 /* Extract the response from the firmware */
378 pResults->consumed =
379 pCompRespMsg->comp_resp_pars.input_byte_counter;
380 pResults->produced =
381 pCompRespMsg->comp_resp_pars.output_byte_counter;
382
383 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
384 pSessionDesc->cumulativeConsumedBytes +=
385 pResults->consumed;
386 } else {
387 /* In the stateless case all requests have both SOP and
388 * EOP set */
389 pSessionDesc->cumulativeConsumedBytes =
390 pResults->consumed;
391 }
392 #else
393 pResults->consumed = 0;
394 pResults->produced = 0;
395 #endif
396 if (CPA_DC_OVERFLOW == pResults->status &&
397 CPA_DC_STATELESS == pSessionDesc->sessState) {
398 /* This error message will be returned by Data Plane API
399 * in both
400 * compression and decompression direction. With
401 * Traditional API
402 * this error message will be returned only in stateless
403 * decompression direction */
404 QAT_UTILS_LOG(
405 "Unrecoverable error: stateless overflow. You may need to increase the size of your destination buffer.\n");
406 }
407
408 if (CPA_TRUE == isDcDp) {
409 if (pResponse)
410 pResponse->responseStatus = CPA_STATUS_FAIL;
411 } else {
412 if (CPA_DC_OK != pResults->status &&
413 CPA_DC_INCOMPLETE_FILE_ERR != pResults->status) {
414 status = CPA_STATUS_FAIL;
415 }
416
417 if (DC_COMPRESSION_REQUEST == compDecomp) {
418 COMPRESSION_STAT_INC(numCompCompletedErrors,
419 pService);
420 } else {
421 COMPRESSION_STAT_INC(numDecompCompletedErrors,
422 pService);
423 }
424 }
425 }
426
427 if (CPA_TRUE == isDcDp) {
428 /* Decrement number of stateless pending callbacks for session
429 */
430 pSessionDesc->pendingDpStatelessCbCount--;
431 (pService->pDcDpCb)(pResponse);
432 } else {
433 /* Decrement number of pending callbacks for session */
434 if (CPA_DC_STATELESS == pSessionDesc->sessState) {
435 qatUtilsAtomicDec(
436 &(pCookie->pSessionDesc->pendingStatelessCbCount));
437 } else if (0 !=
438 qatUtilsAtomicGet(&pCookie->pSessionDesc
439 ->pendingStatefulCbCount)) {
440 qatUtilsAtomicDec(
441 &(pCookie->pSessionDesc->pendingStatefulCbCount));
442 }
443
444 /* Free the memory pool */
445 Lac_MemPoolEntryFree(pCookie);
446 pCookie = NULL;
447
448 if (NULL != pCbFunc) {
449 pCbFunc(callbackTag, status);
450 }
451 }
452 }
453
454 /**
455 *****************************************************************************
456 * @ingroup Dc_DataCompression
457 * Check that all the parameters in the pOpData structure are valid
458 *
459 * @description
460 * Check that all the parameters in the pOpData structure are valid
461 *
462 * @param[in] pService Pointer to the compression service
463 * @param[in] pOpData Pointer to request information structure
464 * holding parameters for cpaDcCompress2 and
465 * CpaDcDecompressData2
466 * @retval CPA_STATUS_SUCCESS Function executed successfully
467 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
468 *
469 *****************************************************************************/
470 CpaStatus
dcCheckOpData(sal_compression_service_t * pService,CpaDcOpData * pOpData)471 dcCheckOpData(sal_compression_service_t *pService, CpaDcOpData *pOpData)
472 {
473 CpaDcSkipMode skipMode = 0;
474
475 if ((pOpData->flushFlag < CPA_DC_FLUSH_NONE) ||
476 (pOpData->flushFlag > CPA_DC_FLUSH_FULL)) {
477 LAC_INVALID_PARAM_LOG("Invalid flushFlag value");
478 return CPA_STATUS_INVALID_PARAM;
479 }
480
481 skipMode = pOpData->inputSkipData.skipMode;
482 if ((skipMode < CPA_DC_SKIP_DISABLED) ||
483 (skipMode > CPA_DC_SKIP_STRIDE)) {
484 LAC_INVALID_PARAM_LOG("Invalid input skip mode value");
485 return CPA_STATUS_INVALID_PARAM;
486 }
487
488 skipMode = pOpData->outputSkipData.skipMode;
489 if ((skipMode < CPA_DC_SKIP_DISABLED) ||
490 (skipMode > CPA_DC_SKIP_STRIDE)) {
491 LAC_INVALID_PARAM_LOG("Invalid output skip mode value");
492 return CPA_STATUS_INVALID_PARAM;
493 }
494
495 if (pOpData->integrityCrcCheck == CPA_FALSE &&
496 pOpData->verifyHwIntegrityCrcs == CPA_TRUE) {
497 LAC_INVALID_PARAM_LOG(
498 "integrityCrcCheck must be set to true"
499 "in order to enable verifyHwIntegrityCrcs");
500 return CPA_STATUS_INVALID_PARAM;
501 }
502
503 if (pOpData->integrityCrcCheck != CPA_TRUE &&
504 pOpData->integrityCrcCheck != CPA_FALSE) {
505 LAC_INVALID_PARAM_LOG("Invalid integrityCrcCheck value");
506 return CPA_STATUS_INVALID_PARAM;
507 }
508
509 if (pOpData->verifyHwIntegrityCrcs != CPA_TRUE &&
510 pOpData->verifyHwIntegrityCrcs != CPA_FALSE) {
511 LAC_INVALID_PARAM_LOG("Invalid verifyHwIntegrityCrcs value");
512 return CPA_STATUS_INVALID_PARAM;
513 }
514
515 if (pOpData->compressAndVerify != CPA_TRUE &&
516 pOpData->compressAndVerify != CPA_FALSE) {
517 LAC_INVALID_PARAM_LOG("Invalid cnv decompress check value");
518 return CPA_STATUS_INVALID_PARAM;
519 }
520
521 if (CPA_TRUE == pOpData->integrityCrcCheck &&
522 CPA_FALSE == pService->generic_service_info.integrityCrcCheck) {
523 LAC_INVALID_PARAM_LOG("Integrity CRC check is not "
524 "supported on this device");
525 return CPA_STATUS_INVALID_PARAM;
526 }
527
528 if (CPA_TRUE == pOpData->integrityCrcCheck &&
529 NULL == pOpData->pCrcData) {
530 LAC_INVALID_PARAM_LOG("Integrity CRC data structure "
531 "not initialized in CpaDcOpData");
532 return CPA_STATUS_INVALID_PARAM;
533 }
534
535 return CPA_STATUS_SUCCESS;
536 }
537
538 /**
539 *****************************************************************************
540 * @ingroup Dc_DataCompression
541 * Check the compression source buffer for Batch and Pack API.
542 *
543 * @description
544 * Check that all the parameters used for Pack compression
545 * request are valid. This function essentially checks the source buffer
546 * parameters and results structure parameters.
547 *
548 * @param[in] pSessionHandle Session handle
549 * @param[in] pSrcBuff Pointer to data buffer for compression
550 * @param[in] pDestBuff Pointer to buffer space allocated for
551 * output data
552 * @param[in] pResults Pointer to results structure
553 * @param[in] flushFlag Indicates the type of flush to be
554 * performed
555 * @param[in] srcBuffSize Size of the source buffer
556 *
557 * @retval CPA_STATUS_SUCCESS Function executed successfully
558 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
559 *
560 *****************************************************************************/
561 static CpaStatus
dcCheckSourceData(CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,Cpa64U srcBuffSize,CpaDcSkipData * skipData)562 dcCheckSourceData(CpaDcSessionHandle pSessionHandle,
563 CpaBufferList *pSrcBuff,
564 CpaBufferList *pDestBuff,
565 CpaDcRqResults *pResults,
566 CpaDcFlush flushFlag,
567 Cpa64U srcBuffSize,
568 CpaDcSkipData *skipData)
569 {
570 dc_session_desc_t *pSessionDesc = NULL;
571
572 LAC_CHECK_NULL_PARAM(pSessionHandle);
573 LAC_CHECK_NULL_PARAM(pSrcBuff);
574 LAC_CHECK_NULL_PARAM(pDestBuff);
575 LAC_CHECK_NULL_PARAM(pResults);
576
577 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
578 if (NULL == pSessionDesc) {
579 LAC_INVALID_PARAM_LOG("Session handle not as expected");
580 return CPA_STATUS_INVALID_PARAM;
581 }
582
583 if ((flushFlag < CPA_DC_FLUSH_NONE) ||
584 (flushFlag > CPA_DC_FLUSH_FULL)) {
585 LAC_INVALID_PARAM_LOG("Invalid flushFlag value");
586 return CPA_STATUS_INVALID_PARAM;
587 }
588
589 if (pSrcBuff == pDestBuff) {
590 LAC_INVALID_PARAM_LOG("In place operation not supported");
591 return CPA_STATUS_INVALID_PARAM;
592 }
593
594 /* Compressing zero bytes is not supported for stateless sessions
595 * for non Batch and Pack requests */
596 if ((CPA_DC_STATELESS == pSessionDesc->sessState) &&
597 (0 == srcBuffSize) && (NULL == skipData)) {
598 LAC_INVALID_PARAM_LOG(
599 "The source buffer size needs to be greater than "
600 "zero bytes for stateless sessions");
601 return CPA_STATUS_INVALID_PARAM;
602 }
603
604 if (srcBuffSize > DC_BUFFER_MAX_SIZE) {
605 LAC_INVALID_PARAM_LOG(
606 "The source buffer size needs to be less than or "
607 "equal to 2^32-1 bytes");
608 return CPA_STATUS_INVALID_PARAM;
609 }
610
611 return CPA_STATUS_SUCCESS;
612 }
613
614 /**
615 *****************************************************************************
616 * @ingroup Dc_DataCompression
617 * Check the compression or decompression function parameters.
618 *
619 * @description
620 * Check that all the parameters used for a Batch and Pack compression
621 * request are valid. This function essentially checks the destination
622 * buffer parameters and intermediate buffer parameters.
623 *
624 * @param[in] pService Pointer to the compression service
625 * @param[in] pSessionHandle Session handle
626 * @param[in] pDestBuff Pointer to buffer space allocated for
627 * output data
628 * @param[in] compDecomp Direction of the operation
629 *
630 * @retval CPA_STATUS_SUCCESS Function executed successfully
631 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
632 *
633 *****************************************************************************/
634 static CpaStatus
dcCheckDestinationData(sal_compression_service_t * pService,CpaDcSessionHandle pSessionHandle,CpaBufferList * pDestBuff,dc_request_dir_t compDecomp)635 dcCheckDestinationData(sal_compression_service_t *pService,
636 CpaDcSessionHandle pSessionHandle,
637 CpaBufferList *pDestBuff,
638 dc_request_dir_t compDecomp)
639 {
640 dc_session_desc_t *pSessionDesc = NULL;
641 Cpa64U destBuffSize = 0;
642
643 LAC_CHECK_NULL_PARAM(pSessionHandle);
644 LAC_CHECK_NULL_PARAM(pDestBuff);
645
646 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
647 if (NULL == pSessionDesc) {
648 LAC_INVALID_PARAM_LOG("Session handle not as expected");
649 return CPA_STATUS_INVALID_PARAM;
650 }
651
652 if (LacBuffDesc_BufferListVerify(pDestBuff,
653 &destBuffSize,
654 LAC_NO_ALIGNMENT_SHIFT) !=
655 CPA_STATUS_SUCCESS) {
656 LAC_INVALID_PARAM_LOG(
657 "Invalid destination buffer list parameter");
658 return CPA_STATUS_INVALID_PARAM;
659 }
660
661 if (destBuffSize > DC_BUFFER_MAX_SIZE) {
662 LAC_INVALID_PARAM_LOG(
663 "The destination buffer size needs to be less "
664 "than or equal to 2^32-1 bytes");
665 return CPA_STATUS_INVALID_PARAM;
666 }
667
668 if (CPA_TRUE == pSessionDesc->isDcDp) {
669 LAC_INVALID_PARAM_LOG(
670 "The session type should not be data plane");
671 return CPA_STATUS_INVALID_PARAM;
672 }
673
674 if (DC_COMPRESSION_REQUEST == compDecomp) {
675 if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
676
677 /* Check if intermediate buffers are supported */
678 if ((isDcGen2x(pService)) &&
679 ((0 == pService->pInterBuffPtrsArrayPhyAddr) ||
680 (NULL == pService->pInterBuffPtrsArray))) {
681 LAC_LOG_ERROR(
682 "No intermediate buffer defined for this instance "
683 "- see cpaDcStartInstance");
684 return CPA_STATUS_INVALID_PARAM;
685 }
686
687 /* Ensure that the destination buffer size is greater or
688 * equal to 128B */
689 if (destBuffSize < DC_DEST_BUFFER_DYN_MIN_SIZE) {
690 LAC_INVALID_PARAM_LOG(
691 "Destination buffer size should be "
692 "greater or equal to 128B");
693 return CPA_STATUS_INVALID_PARAM;
694 }
695 } else
696 {
697 /* Ensure that the destination buffer size is greater or
698 * equal to devices min output buff size */
699 if (destBuffSize <
700 pService->comp_device_data.minOutputBuffSize) {
701 LAC_INVALID_PARAM_LOG1(
702 "Destination buffer size should be "
703 "greater or equal to %d bytes",
704 pService->comp_device_data
705 .minOutputBuffSize);
706 return CPA_STATUS_INVALID_PARAM;
707 }
708 }
709 } else {
710 /* Ensure that the destination buffer size is greater than
711 * 0 bytes */
712 if (destBuffSize < DC_DEST_BUFFER_DEC_MIN_SIZE) {
713 LAC_INVALID_PARAM_LOG(
714 "Destination buffer size should be "
715 "greater than 0 bytes");
716 return CPA_STATUS_INVALID_PARAM;
717 }
718 }
719 return CPA_STATUS_SUCCESS;
720 }
721
722 /**
723 *****************************************************************************
724 * @ingroup Dc_DataCompression
725 * Populate the compression request parameters
726 *
727 * @description
728 * This function will populate the compression request parameters
729 *
730 * @param[out] pCompReqParams Pointer to the compression request parameters
731 * @param[in] pCookie Pointer to the compression cookie
732 *
733 *****************************************************************************/
734 static void
dcCompRequestParamsPopulate(icp_qat_fw_comp_req_params_t * pCompReqParams,dc_compression_cookie_t * pCookie)735 dcCompRequestParamsPopulate(icp_qat_fw_comp_req_params_t *pCompReqParams,
736 dc_compression_cookie_t *pCookie)
737 {
738 pCompReqParams->comp_len = pCookie->srcTotalDataLenInBytes;
739 pCompReqParams->out_buffer_sz = pCookie->dstTotalDataLenInBytes;
740 }
741
742 /**
743 *****************************************************************************
744 * @ingroup Dc_DataCompression
745 * Create the requests for compression or decompression
746 *
747 * @description
748 * Create the requests for compression or decompression. This function
749 * will update the cookie will all required information.
750 *
751 * @param{out] pCookie Pointer to the compression cookie
752 * @param[in] pService Pointer to the compression service
753 * @param[in] pSessionDesc Pointer to the session descriptor
754 * @param[in pSessionHandle Session handle
755 * @param[in] pSrcBuff Pointer to data buffer for compression
756 * @param[in] pDestBuff Pointer to buffer space for data after
757 * compression
758 * @param[in] pResults Pointer to results structure
759 * @param[in] flushFlag Indicates the type of flush to be
760 * performed
761 * @param[in] pOpData Pointer to request information structure
762 * holding parameters for cpaDcCompress2
763 * and CpaDcDecompressData2
764 * @param[in] callbackTag Pointer to the callback tag
765 * @param[in] compDecomp Direction of the operation
766 * @param[in] compressAndVerify Compress and Verify
767 *
768 * @retval CPA_STATUS_SUCCESS Function executed successfully
769 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
770 *
771 *****************************************************************************/
772 static CpaStatus
dcCreateRequest(dc_compression_cookie_t * pCookie,sal_compression_service_t * pService,dc_session_desc_t * pSessionDesc,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,CpaDcOpData * pOpData,void * callbackTag,dc_request_dir_t compDecomp,dc_cnv_mode_t cnvMode)773 dcCreateRequest(dc_compression_cookie_t *pCookie,
774 sal_compression_service_t *pService,
775 dc_session_desc_t *pSessionDesc,
776 CpaDcSessionHandle pSessionHandle,
777 CpaBufferList *pSrcBuff,
778 CpaBufferList *pDestBuff,
779 CpaDcRqResults *pResults,
780 CpaDcFlush flushFlag,
781 CpaDcOpData *pOpData,
782 void *callbackTag,
783 dc_request_dir_t compDecomp,
784 dc_cnv_mode_t cnvMode)
785 {
786 icp_qat_fw_comp_req_t *pMsg = NULL;
787 icp_qat_fw_comp_req_params_t *pCompReqParams = NULL;
788 Cpa64U srcAddrPhys = 0, dstAddrPhys = 0;
789 Cpa64U srcTotalDataLenInBytes = 0, dstTotalDataLenInBytes = 0;
790
791 Cpa32U rpCmdFlags = 0;
792 Cpa8U sop = ICP_QAT_FW_COMP_SOP;
793 Cpa8U eop = ICP_QAT_FW_COMP_EOP;
794 Cpa8U bFinal = ICP_QAT_FW_COMP_NOT_BFINAL;
795 Cpa8U crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY;
796 Cpa8U cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
797 Cpa8U cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
798 CpaBoolean cnvErrorInjection = ICP_QAT_FW_COMP_NO_CNV_DFX;
799 CpaBoolean integrityCrcCheck = CPA_FALSE;
800 CpaStatus status = CPA_STATUS_SUCCESS;
801 CpaDcFlush flush = CPA_DC_FLUSH_NONE;
802 Cpa32U initial_adler = 1;
803 Cpa32U initial_crc32 = 0;
804 icp_qat_fw_comp_req_t *pReqCache = NULL;
805
806 /* Write the buffer descriptors */
807 status = LacBuffDesc_BufferListDescWriteAndGetSize(
808 pSrcBuff,
809 &srcAddrPhys,
810 CPA_FALSE,
811 &srcTotalDataLenInBytes,
812 &(pService->generic_service_info));
813 if (status != CPA_STATUS_SUCCESS) {
814 return status;
815 }
816
817 status = LacBuffDesc_BufferListDescWriteAndGetSize(
818 pDestBuff,
819 &dstAddrPhys,
820 CPA_FALSE,
821 &dstTotalDataLenInBytes,
822 &(pService->generic_service_info));
823 if (status != CPA_STATUS_SUCCESS) {
824 return status;
825 }
826
827 /* Populate the compression cookie */
828 pCookie->dcInstance = pService;
829 pCookie->pSessionHandle = pSessionHandle;
830 pCookie->callbackTag = callbackTag;
831 pCookie->pSessionDesc = pSessionDesc;
832 pCookie->pDcOpData = pOpData;
833 pCookie->pResults = pResults;
834 pCookie->compDecomp = compDecomp;
835 pCookie->pUserSrcBuff = NULL;
836 pCookie->pUserDestBuff = NULL;
837
838 /* Extract flush flag from either the opData or from the
839 * parameter. Opdata have been introduce with APIs
840 * cpaDcCompressData2 and cpaDcDecompressData2 */
841 if (NULL != pOpData) {
842 flush = pOpData->flushFlag;
843 integrityCrcCheck = pOpData->integrityCrcCheck;
844 } else {
845 flush = flushFlag;
846 }
847 pCookie->flushFlag = flush;
848
849 /* The firmware expects the length in bytes for source and destination
850 * to be Cpa32U parameters. However the total data length could be
851 * bigger as allocated by the user. We ensure that this is not the case
852 * in dcCheckSourceData and cast the values to Cpa32U here */
853 pCookie->srcTotalDataLenInBytes = (Cpa32U)srcTotalDataLenInBytes;
854 if ((isDcGen2x(pService)) && (DC_COMPRESSION_REQUEST == compDecomp) &&
855 (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) {
856 if (pService->minInterBuffSizeInBytes <
857 (Cpa32U)dstTotalDataLenInBytes) {
858 pCookie->dstTotalDataLenInBytes =
859 (Cpa32U)(pService->minInterBuffSizeInBytes);
860 } else {
861 pCookie->dstTotalDataLenInBytes =
862 (Cpa32U)dstTotalDataLenInBytes;
863 }
864 } else
865 {
866 pCookie->dstTotalDataLenInBytes =
867 (Cpa32U)dstTotalDataLenInBytes;
868 }
869
870 /* Device can not decompress an odd byte decompression request
871 * if bFinal is not set
872 */
873 if (CPA_TRUE != pService->comp_device_data.oddByteDecompNobFinal) {
874 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
875 (CPA_DC_FLUSH_FINAL != flushFlag) &&
876 (DC_DECOMPRESSION_REQUEST == compDecomp) &&
877 (pCookie->srcTotalDataLenInBytes & 0x1)) {
878 pCookie->srcTotalDataLenInBytes--;
879 }
880 }
881 /* Device can not decompress odd byte interim requests */
882 if (CPA_TRUE != pService->comp_device_data.oddByteDecompInterim) {
883 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
884 (CPA_DC_FLUSH_FINAL != flushFlag) &&
885 (CPA_DC_FLUSH_FULL != flushFlag) &&
886 (DC_DECOMPRESSION_REQUEST == compDecomp) &&
887 (pCookie->srcTotalDataLenInBytes & 0x1)) {
888 pCookie->srcTotalDataLenInBytes--;
889 }
890 }
891
892 pMsg = (icp_qat_fw_comp_req_t *)&pCookie->request;
893
894 if (DC_COMPRESSION_REQUEST == compDecomp) {
895 pReqCache = &(pSessionDesc->reqCacheComp);
896 } else {
897 pReqCache = &(pSessionDesc->reqCacheDecomp);
898 }
899
900 /* Fills the msg from the template cached in the session descriptor */
901 memcpy((void *)pMsg,
902 (void *)(pReqCache),
903 LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES);
904
905 if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
906 initial_adler = 1;
907 initial_crc32 = 0;
908
909 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
910 pSessionDesc->previousChecksum = initial_adler;
911 } else {
912 pSessionDesc->previousChecksum = initial_crc32;
913 }
914 } else if (CPA_DC_STATELESS == pSessionDesc->sessState) {
915 pSessionDesc->previousChecksum = pResults->checksum;
916
917 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
918 initial_adler = pSessionDesc->previousChecksum;
919 } else {
920 initial_crc32 = pSessionDesc->previousChecksum;
921 }
922 }
923
924 /* Backup source and destination buffer addresses,
925 * CRC calculations both for CNV and translator overflow
926 * will be performed on them in the callback function.
927 */
928 pCookie->pUserSrcBuff = pSrcBuff;
929 pCookie->pUserDestBuff = pDestBuff;
930
931 /*
932 * Due to implementation of CNV support and need for backwards
933 * compatibility certain fields in the request and response structs had
934 * been changed, moved or placed in unions cnvMode flag signifies fields
935 * to be selected from req/res
936 *
937 * Doing extended crc checks makes sense only when we want to do the
938 * actual CNV
939 */
940 if (CPA_TRUE == pService->generic_service_info.integrityCrcCheck &&
941 CPA_TRUE == integrityCrcCheck) {
942 pMsg->comp_pars.crc.crc_data_addr =
943 pSessionDesc->physDataIntegrityCrcs;
944 crcMode = ICP_QAT_FW_COMP_CRC_MODE_E2E;
945 } else {
946 /* Legacy request structure */
947 pMsg->comp_pars.crc.legacy.initial_adler = initial_adler;
948 pMsg->comp_pars.crc.legacy.initial_crc32 = initial_crc32;
949 crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY;
950 }
951
952 /* Populate the cmdFlags */
953 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
954 pSessionDesc->previousRequestType = pSessionDesc->requestType;
955
956 if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
957 /* Update the request type for following requests */
958 pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT;
959
960 /* Reinitialise the cumulative amount of consumed bytes
961 */
962 pSessionDesc->cumulativeConsumedBytes = 0;
963
964 if (DC_COMPRESSION_REQUEST == compDecomp) {
965 pSessionDesc->isSopForCompressionProcessed =
966 CPA_TRUE;
967 } else if (DC_DECOMPRESSION_REQUEST == compDecomp) {
968 pSessionDesc->isSopForDecompressionProcessed =
969 CPA_TRUE;
970 }
971 } else {
972 if (DC_COMPRESSION_REQUEST == compDecomp) {
973 if (CPA_TRUE ==
974 pSessionDesc
975 ->isSopForCompressionProcessed) {
976 sop = ICP_QAT_FW_COMP_NOT_SOP;
977 } else {
978 pSessionDesc
979 ->isSopForCompressionProcessed =
980 CPA_TRUE;
981 }
982 } else if (DC_DECOMPRESSION_REQUEST == compDecomp) {
983 if (CPA_TRUE ==
984 pSessionDesc
985 ->isSopForDecompressionProcessed) {
986 sop = ICP_QAT_FW_COMP_NOT_SOP;
987 } else {
988 pSessionDesc
989 ->isSopForDecompressionProcessed =
990 CPA_TRUE;
991 }
992 }
993 }
994
995 if ((CPA_DC_FLUSH_FINAL == flush) ||
996 (CPA_DC_FLUSH_FULL == flush)) {
997 /* Update the request type for following requests */
998 pSessionDesc->requestType = DC_REQUEST_FIRST;
999 } else {
1000 eop = ICP_QAT_FW_COMP_NOT_EOP;
1001 }
1002 } else {
1003 if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
1004 /* Reinitialise the cumulative amount of consumed bytes
1005 */
1006 pSessionDesc->cumulativeConsumedBytes = 0;
1007 }
1008 }
1009
1010 /* (LW 14 - 15) */
1011 pCompReqParams = &(pMsg->comp_pars);
1012 dcCompRequestParamsPopulate(pCompReqParams, pCookie);
1013 if (CPA_DC_FLUSH_FINAL == flush) {
1014 bFinal = ICP_QAT_FW_COMP_BFINAL;
1015 }
1016
1017 switch (cnvMode) {
1018 case DC_CNVNR:
1019 cnvRecovery = ICP_QAT_FW_COMP_CNV_RECOVERY;
1020 /* Fall through is intended here, because for CNVNR
1021 * cnvDecompReq also needs to be set */
1022 case DC_CNV:
1023 cnvDecompReq = ICP_QAT_FW_COMP_CNV;
1024 if (isDcGen4x(pService)) {
1025 cnvErrorInjection = pSessionDesc->cnvErrorInjection;
1026 }
1027 break;
1028 case DC_NO_CNV:
1029 cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
1030 cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
1031 break;
1032 }
1033
1034 /* LW 18 */
1035 rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(sop,
1036 eop,
1037 bFinal,
1038 cnvDecompReq,
1039 cnvRecovery,
1040 cnvErrorInjection,
1041 crcMode);
1042
1043 pMsg->comp_pars.req_par_flags = rpCmdFlags;
1044
1045 /* Populates the QAT common request middle part of the message
1046 * (LW 6 to 11) */
1047 SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)pMsg,
1048 pCookie,
1049 DC_DEFAULT_QAT_PTR_TYPE,
1050 srcAddrPhys,
1051 dstAddrPhys,
1052 0,
1053 0);
1054
1055 return CPA_STATUS_SUCCESS;
1056 }
1057
1058 /**
1059 *****************************************************************************
1060 * @ingroup Dc_DataCompression
1061 * Send a compression request to QAT
1062 *
1063 * @description
1064 * Send the requests for compression or decompression to QAT
1065 *
1066 * @param{in] pCookie Pointer to the compression cookie
1067 * @param[in] pService Pointer to the compression service
1068 * @param[in] pSessionDesc Pointer to the session descriptor
1069 * @param[in] compDecomp Direction of the operation
1070 *
1071 * @retval CPA_STATUS_SUCCESS Function executed successfully
1072 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in
1073 *
1074 *****************************************************************************/
1075 static CpaStatus
dcSendRequest(dc_compression_cookie_t * pCookie,sal_compression_service_t * pService,dc_session_desc_t * pSessionDesc,dc_request_dir_t compDecomp)1076 dcSendRequest(dc_compression_cookie_t *pCookie,
1077 sal_compression_service_t *pService,
1078 dc_session_desc_t *pSessionDesc,
1079 dc_request_dir_t compDecomp)
1080 {
1081 CpaStatus status = CPA_STATUS_SUCCESS;
1082
1083 /* Send to QAT */
1084 status = icp_adf_transPutMsg(pService->trans_handle_compression_tx,
1085 (void *)&(pCookie->request),
1086 LAC_QAT_DC_REQ_SZ_LW);
1087
1088 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
1089 (CPA_STATUS_RETRY == status)) {
1090 /* reset requestType after receiving an retry on
1091 * the stateful request */
1092 pSessionDesc->requestType = pSessionDesc->previousRequestType;
1093 }
1094
1095 return status;
1096 }
1097
1098 /**
1099 *****************************************************************************
1100 * @ingroup Dc_DataCompression
1101 * Process the synchronous and asynchronous case for compression or
1102 * decompression
1103 *
1104 * @description
1105 * Process the synchronous and asynchronous case for compression or
1106 * decompression. This function will then create and send the request to
1107 * the firmware.
1108 *
1109 * @param[in] pService Pointer to the compression service
1110 * @param[in] pSessionDesc Pointer to the session descriptor
1111 * @param[in] dcInstance Instance handle derived from discovery
1112 * functions
1113 * @param[in] pSessionHandle Session handle
1114 * @param[in] numRequests Number of operations in the batch request
1115 * @param[in] pBatchOpData Address of the list of jobs to be processed
1116 * @param[in] pSrcBuff Pointer to data buffer for compression
1117 * @param[in] pDestBuff Pointer to buffer space for data after
1118 * compression
1119 * @param[in] pResults Pointer to results structure
1120 * @param[in] flushFlag Indicates the type of flush to be
1121 * performed
1122 * @param[in] pOpData Pointer to request information structure
1123 * holding parameters for cpaDcCompress2 and
1124 * CpaDcDecompressData2
1125 * @param[in] callbackTag Pointer to the callback tag
1126 * @param[in] compDecomp Direction of the operation
1127 * @param[in] isAsyncMode Used to know if synchronous or asynchronous
1128 * mode
1129 * @param[in] cnvMode CNV Mode
1130 *
1131 * @retval CPA_STATUS_SUCCESS Function executed successfully
1132 * @retval CPA_STATUS_RETRY Retry operation
1133 * @retval CPA_STATUS_FAIL Function failed
1134 * @retval CPA_STATUS_RESOURCE Resource error
1135 *
1136 *****************************************************************************/
1137 static CpaStatus
dcCompDecompData(sal_compression_service_t * pService,dc_session_desc_t * pSessionDesc,CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,CpaDcOpData * pOpData,void * callbackTag,dc_request_dir_t compDecomp,CpaBoolean isAsyncMode,dc_cnv_mode_t cnvMode)1138 dcCompDecompData(sal_compression_service_t *pService,
1139 dc_session_desc_t *pSessionDesc,
1140 CpaInstanceHandle dcInstance,
1141 CpaDcSessionHandle pSessionHandle,
1142 CpaBufferList *pSrcBuff,
1143 CpaBufferList *pDestBuff,
1144 CpaDcRqResults *pResults,
1145 CpaDcFlush flushFlag,
1146 CpaDcOpData *pOpData,
1147 void *callbackTag,
1148 dc_request_dir_t compDecomp,
1149 CpaBoolean isAsyncMode,
1150 dc_cnv_mode_t cnvMode)
1151 {
1152 CpaStatus status = CPA_STATUS_SUCCESS;
1153 dc_compression_cookie_t *pCookie = NULL;
1154
1155 if ((LacSync_GenWakeupSyncCaller == pSessionDesc->pCompressionCb) &&
1156 isAsyncMode == CPA_TRUE) {
1157 lac_sync_op_data_t *pSyncCallbackData = NULL;
1158
1159 status = LacSync_CreateSyncCookie(&pSyncCallbackData);
1160
1161 if (CPA_STATUS_SUCCESS == status) {
1162 status = dcCompDecompData(pService,
1163 pSessionDesc,
1164 dcInstance,
1165 pSessionHandle,
1166 pSrcBuff,
1167 pDestBuff,
1168 pResults,
1169 flushFlag,
1170 pOpData,
1171 pSyncCallbackData,
1172 compDecomp,
1173 CPA_FALSE,
1174 cnvMode);
1175 } else {
1176 return status;
1177 }
1178
1179 if (CPA_STATUS_SUCCESS == status) {
1180 CpaStatus syncStatus = CPA_STATUS_SUCCESS;
1181
1182 syncStatus =
1183 LacSync_WaitForCallback(pSyncCallbackData,
1184 DC_SYNC_CALLBACK_TIMEOUT,
1185 &status,
1186 NULL);
1187
1188 /* If callback doesn't come back */
1189 if (CPA_STATUS_SUCCESS != syncStatus) {
1190 if (DC_COMPRESSION_REQUEST == compDecomp) {
1191 COMPRESSION_STAT_INC(
1192 numCompCompletedErrors, pService);
1193 } else {
1194 COMPRESSION_STAT_INC(
1195 numDecompCompletedErrors, pService);
1196 }
1197 LAC_LOG_ERROR("Callback timed out");
1198 status = syncStatus;
1199 }
1200 } else {
1201 /* As the Request was not sent the Callback will never
1202 * be called, so need to indicate that we're finished
1203 * with cookie so it can be destroyed. */
1204 LacSync_SetSyncCookieComplete(pSyncCallbackData);
1205 }
1206
1207 LacSync_DestroySyncCookie(&pSyncCallbackData);
1208 return status;
1209 }
1210
1211 /* Allocate the compression cookie
1212 * The memory is freed in callback or in sendRequest if an error occurs
1213 */
1214 pCookie = (dc_compression_cookie_t *)Lac_MemPoolEntryAlloc(
1215 pService->compression_mem_pool);
1216 if (NULL == pCookie) {
1217 LAC_LOG_ERROR("Cannot get mem pool entry for compression");
1218 status = CPA_STATUS_RESOURCE;
1219 } else if ((void *)CPA_STATUS_RETRY == pCookie) {
1220 pCookie = NULL;
1221 status = CPA_STATUS_RETRY;
1222 }
1223
1224 if (CPA_STATUS_SUCCESS == status) {
1225 status = dcCreateRequest(pCookie,
1226 pService,
1227 pSessionDesc,
1228 pSessionHandle,
1229 pSrcBuff,
1230 pDestBuff,
1231 pResults,
1232 flushFlag,
1233 pOpData,
1234 callbackTag,
1235 compDecomp,
1236 cnvMode);
1237 }
1238
1239 if (CPA_STATUS_SUCCESS == status) {
1240 /* Increment number of pending callbacks for session */
1241 if (CPA_DC_STATELESS == pSessionDesc->sessState) {
1242 qatUtilsAtomicInc(
1243 &(pSessionDesc->pendingStatelessCbCount));
1244 }
1245 status =
1246 dcSendRequest(pCookie, pService, pSessionDesc, compDecomp);
1247 }
1248
1249 if (CPA_STATUS_SUCCESS == status) {
1250 if (DC_COMPRESSION_REQUEST == compDecomp) {
1251 COMPRESSION_STAT_INC(numCompRequests, pService);
1252 } else {
1253 COMPRESSION_STAT_INC(numDecompRequests, pService);
1254 }
1255 } else {
1256 if (DC_COMPRESSION_REQUEST == compDecomp) {
1257 COMPRESSION_STAT_INC(numCompRequestsErrors, pService);
1258 } else {
1259 COMPRESSION_STAT_INC(numDecompRequestsErrors, pService);
1260 }
1261
1262 /* Decrement number of pending callbacks for session */
1263 if (CPA_DC_STATELESS == pSessionDesc->sessState) {
1264 qatUtilsAtomicDec(
1265 &(pSessionDesc->pendingStatelessCbCount));
1266 } else {
1267 qatUtilsAtomicDec(
1268 &(pSessionDesc->pendingStatefulCbCount));
1269 }
1270
1271 /* Free the memory pool */
1272 if (NULL != pCookie) {
1273 if (status != CPA_STATUS_UNSUPPORTED) {
1274 /* Free the memory pool */
1275 Lac_MemPoolEntryFree(pCookie);
1276 pCookie = NULL;
1277 }
1278 }
1279 }
1280
1281 return status;
1282 }
1283
1284 /**
1285 *****************************************************************************
1286 * @ingroup Dc_DataCompression
1287 * Handle zero length compression or decompression requests
1288 *
1289 * @description
1290 * Handle zero length compression or decompression requests
1291 *
1292 * @param[in] pService Pointer to the compression service
1293 * @param[in] pSessionDesc Pointer to the session descriptor
1294 * @param[in] pResults Pointer to results structure
1295 * @param[in] flushFlag Indicates the type of flush to be
1296 * performed
1297 * @param[in] callbackTag User supplied value to help correlate
1298 * the callback with its associated request
1299 * @param[in] compDecomp Direction of the operation
1300 *
1301 * @retval CPA_TRUE Zero length SOP or MOP processed
1302 * @retval CPA_FALSE Zero length EOP
1303 *
1304 *****************************************************************************/
1305 static CpaStatus
dcZeroLengthRequests(sal_compression_service_t * pService,dc_session_desc_t * pSessionDesc,CpaDcRqResults * pResults,CpaDcFlush flushFlag,void * callbackTag,dc_request_dir_t compDecomp)1306 dcZeroLengthRequests(sal_compression_service_t *pService,
1307 dc_session_desc_t *pSessionDesc,
1308 CpaDcRqResults *pResults,
1309 CpaDcFlush flushFlag,
1310 void *callbackTag,
1311 dc_request_dir_t compDecomp)
1312 {
1313 CpaBoolean status = CPA_FALSE;
1314 CpaDcCallbackFn pCbFunc = pSessionDesc->pCompressionCb;
1315
1316 if (DC_REQUEST_FIRST == pSessionDesc->requestType) {
1317 /* Reinitialise the cumulative amount of consumed bytes */
1318 pSessionDesc->cumulativeConsumedBytes = 0;
1319
1320 /* Zero length SOP */
1321 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
1322 pResults->checksum = 1;
1323 } else {
1324 pResults->checksum = 0;
1325 }
1326
1327 status = CPA_TRUE;
1328 } else if ((CPA_DC_FLUSH_NONE == flushFlag) ||
1329 (CPA_DC_FLUSH_SYNC == flushFlag)) {
1330 /* Zero length MOP */
1331 pResults->checksum = pSessionDesc->previousChecksum;
1332 status = CPA_TRUE;
1333 }
1334
1335 if (CPA_TRUE == status) {
1336 pResults->status = CPA_DC_OK;
1337 pResults->produced = 0;
1338 pResults->consumed = 0;
1339
1340 /* Increment statistics */
1341 if (DC_COMPRESSION_REQUEST == compDecomp) {
1342 COMPRESSION_STAT_INC(numCompRequests, pService);
1343 COMPRESSION_STAT_INC(numCompCompleted, pService);
1344 } else {
1345 COMPRESSION_STAT_INC(numDecompRequests, pService);
1346 COMPRESSION_STAT_INC(numDecompCompleted, pService);
1347 }
1348
1349 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1350
1351 if ((NULL != pCbFunc) &&
1352 (LacSync_GenWakeupSyncCaller != pCbFunc)) {
1353 pCbFunc(callbackTag, CPA_STATUS_SUCCESS);
1354 }
1355
1356 return CPA_TRUE;
1357 }
1358
1359 return CPA_FALSE;
1360 }
1361
1362 static CpaStatus
dcParamCheck(CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,sal_compression_service_t * pService,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,dc_session_desc_t * pSessionDesc,CpaDcFlush flushFlag,Cpa64U srcBuffSize)1363 dcParamCheck(CpaInstanceHandle dcInstance,
1364 CpaDcSessionHandle pSessionHandle,
1365 sal_compression_service_t *pService,
1366 CpaBufferList *pSrcBuff,
1367 CpaBufferList *pDestBuff,
1368 CpaDcRqResults *pResults,
1369 dc_session_desc_t *pSessionDesc,
1370 CpaDcFlush flushFlag,
1371 Cpa64U srcBuffSize)
1372 {
1373
1374 if (dcCheckSourceData(pSessionHandle,
1375 pSrcBuff,
1376 pDestBuff,
1377 pResults,
1378 flushFlag,
1379 srcBuffSize,
1380 NULL) != CPA_STATUS_SUCCESS) {
1381 return CPA_STATUS_INVALID_PARAM;
1382 }
1383 if (dcCheckDestinationData(
1384 pService, pSessionHandle, pDestBuff, DC_COMPRESSION_REQUEST) !=
1385 CPA_STATUS_SUCCESS) {
1386 return CPA_STATUS_INVALID_PARAM;
1387 }
1388 if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) {
1389 LAC_INVALID_PARAM_LOG("Invalid sessDirection value");
1390 return CPA_STATUS_INVALID_PARAM;
1391 }
1392 return CPA_STATUS_SUCCESS;
1393 }
1394
1395 CpaStatus
cpaDcCompressData(CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,void * callbackTag)1396 cpaDcCompressData(CpaInstanceHandle dcInstance,
1397 CpaDcSessionHandle pSessionHandle,
1398 CpaBufferList *pSrcBuff,
1399 CpaBufferList *pDestBuff,
1400 CpaDcRqResults *pResults,
1401 CpaDcFlush flushFlag,
1402 void *callbackTag)
1403 {
1404 sal_compression_service_t *pService = NULL;
1405 dc_session_desc_t *pSessionDesc = NULL;
1406 CpaInstanceHandle insHandle = NULL;
1407 Cpa64U srcBuffSize = 0;
1408
1409 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1410 insHandle = dcGetFirstHandle();
1411 } else {
1412 insHandle = dcInstance;
1413 }
1414
1415 pService = (sal_compression_service_t *)insHandle;
1416
1417 LAC_CHECK_NULL_PARAM(insHandle);
1418 LAC_CHECK_NULL_PARAM(pSessionHandle);
1419
1420 /* Check if SAL is initialised otherwise return an error */
1421 SAL_RUNNING_CHECK(insHandle);
1422
1423 /* This check is outside the parameter checking as it is needed to
1424 * manage zero length requests */
1425 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
1426 &srcBuffSize,
1427 LAC_NO_ALIGNMENT_SHIFT) !=
1428 CPA_STATUS_SUCCESS) {
1429 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
1430 return CPA_STATUS_INVALID_PARAM;
1431 }
1432
1433 /* Ensure this is a compression instance */
1434 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1435
1436 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1437 if (CPA_STATUS_SUCCESS !=
1438 dcParamCheck(insHandle,
1439 pSessionHandle,
1440 pService,
1441 pSrcBuff,
1442 pDestBuff,
1443 pResults,
1444 pSessionDesc,
1445 flushFlag,
1446 srcBuffSize)) {
1447 return CPA_STATUS_INVALID_PARAM;
1448 }
1449 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1450 LAC_INVALID_PARAM_LOG(
1451 "Invalid session state, stateful sessions "
1452 "are not supported");
1453 return CPA_STATUS_UNSUPPORTED;
1454 }
1455
1456 if (!(pService->generic_service_info.dcExtendedFeatures &
1457 DC_CNV_EXTENDED_CAPABILITY)) {
1458 LAC_INVALID_PARAM_LOG(
1459 "CompressAndVerify feature not supported");
1460 return CPA_STATUS_UNSUPPORTED;
1461 }
1462
1463 if (!(pService->generic_service_info.dcExtendedFeatures &
1464 DC_CNVNR_EXTENDED_CAPABILITY)) {
1465 LAC_INVALID_PARAM_LOG(
1466 "CompressAndVerifyAndRecovery feature not supported");
1467 return CPA_STATUS_UNSUPPORTED;
1468 }
1469
1470 return dcCompDecompData(pService,
1471 pSessionDesc,
1472 insHandle,
1473 pSessionHandle,
1474 pSrcBuff,
1475 pDestBuff,
1476 pResults,
1477 flushFlag,
1478 NULL,
1479 callbackTag,
1480 DC_COMPRESSION_REQUEST,
1481 CPA_TRUE,
1482 DC_CNVNR);
1483 }
1484
1485 CpaStatus
cpaDcCompressData2(CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcOpData * pOpData,CpaDcRqResults * pResults,void * callbackTag)1486 cpaDcCompressData2(CpaInstanceHandle dcInstance,
1487 CpaDcSessionHandle pSessionHandle,
1488 CpaBufferList *pSrcBuff,
1489 CpaBufferList *pDestBuff,
1490 CpaDcOpData *pOpData,
1491 CpaDcRqResults *pResults,
1492 void *callbackTag)
1493 {
1494 sal_compression_service_t *pService = NULL;
1495 dc_session_desc_t *pSessionDesc = NULL;
1496 CpaInstanceHandle insHandle = NULL;
1497 Cpa64U srcBuffSize = 0;
1498 dc_cnv_mode_t cnvMode = DC_NO_CNV;
1499
1500 LAC_CHECK_NULL_PARAM(pOpData);
1501
1502 if (((CPA_TRUE != pOpData->compressAndVerify) &&
1503 (CPA_FALSE != pOpData->compressAndVerify)) ||
1504 ((CPA_FALSE != pOpData->compressAndVerifyAndRecover) &&
1505 (CPA_TRUE != pOpData->compressAndVerifyAndRecover))) {
1506 return CPA_STATUS_INVALID_PARAM;
1507 }
1508
1509 if ((CPA_FALSE == pOpData->compressAndVerify) &&
1510 (CPA_TRUE == pOpData->compressAndVerifyAndRecover)) {
1511 return CPA_STATUS_INVALID_PARAM;
1512 }
1513
1514 if ((CPA_TRUE == pOpData->compressAndVerify) &&
1515 (CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
1516 (CPA_FALSE == pOpData->integrityCrcCheck)) {
1517 return cpaDcCompressData(dcInstance,
1518 pSessionHandle,
1519 pSrcBuff,
1520 pDestBuff,
1521 pResults,
1522 pOpData->flushFlag,
1523 callbackTag);
1524 }
1525
1526 if (CPA_FALSE == pOpData->compressAndVerify) {
1527 LAC_INVALID_PARAM_LOG(
1528 "Data compression without verification not allowed");
1529 return CPA_STATUS_UNSUPPORTED;
1530 }
1531
1532 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1533 insHandle = dcGetFirstHandle();
1534 } else {
1535 insHandle = dcInstance;
1536 }
1537
1538 pService = (sal_compression_service_t *)insHandle;
1539
1540 LAC_CHECK_NULL_PARAM(insHandle);
1541 LAC_CHECK_NULL_PARAM(pSessionHandle);
1542 LAC_CHECK_NULL_PARAM(pOpData);
1543
1544 /* Check if SAL is initialised otherwise return an error */
1545 SAL_RUNNING_CHECK(insHandle);
1546
1547 /* This check is outside the parameter checking as it is needed to
1548 * manage zero length requests */
1549 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
1550 &srcBuffSize,
1551 LAC_NO_ALIGNMENT_SHIFT) !=
1552 CPA_STATUS_SUCCESS) {
1553 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
1554 return CPA_STATUS_INVALID_PARAM;
1555 }
1556
1557 /* Ensure this is a compression instance */
1558 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1559
1560 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1561
1562 if (CPA_TRUE == pOpData->compressAndVerify &&
1563 CPA_DC_STATEFUL == pSessionDesc->sessState) {
1564 LAC_INVALID_PARAM_LOG(
1565 "Invalid session state, stateful sessions "
1566 "not supported with CNV");
1567 return CPA_STATUS_UNSUPPORTED;
1568 }
1569
1570 if (!(pService->generic_service_info.dcExtendedFeatures &
1571 DC_CNV_EXTENDED_CAPABILITY) &&
1572 (CPA_TRUE == pOpData->compressAndVerify)) {
1573 LAC_INVALID_PARAM_LOG(
1574 "CompressAndVerify feature not supported");
1575 return CPA_STATUS_UNSUPPORTED;
1576 }
1577
1578 if (CPA_STATUS_SUCCESS !=
1579 dcParamCheck(insHandle,
1580 pSessionHandle,
1581 pService,
1582 pSrcBuff,
1583 pDestBuff,
1584 pResults,
1585 pSessionDesc,
1586 pOpData->flushFlag,
1587 srcBuffSize)) {
1588 return CPA_STATUS_INVALID_PARAM;
1589 }
1590 if (CPA_STATUS_SUCCESS != dcCheckOpData(pService, pOpData)) {
1591 return CPA_STATUS_INVALID_PARAM;
1592 }
1593 if (CPA_TRUE != pOpData->compressAndVerify) {
1594 if (srcBuffSize > DC_COMP_MAX_BUFF_SIZE) {
1595 LAC_LOG_ERROR(
1596 "Compression payload greater than 64KB is "
1597 "unsupported, when CnV is disabled\n");
1598 return CPA_STATUS_UNSUPPORTED;
1599 }
1600 }
1601
1602 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1603 /* Lock the session to check if there are in-flight stateful
1604 * requests */
1605 LAC_SPINLOCK(&(pSessionDesc->sessionLock));
1606
1607 /* Check if there is already one in-flight stateful request */
1608 if (0 !=
1609 qatUtilsAtomicGet(
1610 &(pSessionDesc->pendingStatefulCbCount))) {
1611 LAC_LOG_ERROR(
1612 "Only one in-flight stateful request supported");
1613 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1614 return CPA_STATUS_RETRY;
1615 }
1616
1617 if (0 == srcBuffSize) {
1618 if (CPA_TRUE ==
1619 dcZeroLengthRequests(pService,
1620 pSessionDesc,
1621 pResults,
1622 pOpData->flushFlag,
1623 callbackTag,
1624 DC_COMPRESSION_REQUEST)) {
1625 return CPA_STATUS_SUCCESS;
1626 }
1627 }
1628
1629 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount));
1630 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1631 }
1632
1633 if (CPA_TRUE == pOpData->compressAndVerify) {
1634 cnvMode = DC_CNV;
1635 }
1636
1637 return dcCompDecompData(pService,
1638 pSessionDesc,
1639 insHandle,
1640 pSessionHandle,
1641 pSrcBuff,
1642 pDestBuff,
1643 pResults,
1644 pOpData->flushFlag,
1645 pOpData,
1646 callbackTag,
1647 DC_COMPRESSION_REQUEST,
1648 CPA_TRUE,
1649 cnvMode);
1650 }
1651
1652 static CpaStatus
dcDecompressDataCheck(CpaInstanceHandle insHandle,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,Cpa64U * srcBufferSize)1653 dcDecompressDataCheck(CpaInstanceHandle insHandle,
1654 CpaDcSessionHandle pSessionHandle,
1655 CpaBufferList *pSrcBuff,
1656 CpaBufferList *pDestBuff,
1657 CpaDcRqResults *pResults,
1658 CpaDcFlush flushFlag,
1659 Cpa64U *srcBufferSize)
1660 {
1661 sal_compression_service_t *pService = NULL;
1662 dc_session_desc_t *pSessionDesc = NULL;
1663 Cpa64U srcBuffSize = 0;
1664
1665 pService = (sal_compression_service_t *)insHandle;
1666
1667 LAC_CHECK_NULL_PARAM(insHandle);
1668
1669 /* Check if SAL is initialised otherwise return an error */
1670 SAL_RUNNING_CHECK(insHandle);
1671
1672 /* This check is outside the parameter checking as it is needed to
1673 * manage zero length requests */
1674 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff,
1675 &srcBuffSize,
1676 LAC_NO_ALIGNMENT_SHIFT) !=
1677 CPA_STATUS_SUCCESS) {
1678 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter");
1679 return CPA_STATUS_INVALID_PARAM;
1680 }
1681
1682 /* Ensure this is a compression instance */
1683 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1684
1685 if (dcCheckSourceData(pSessionHandle,
1686 pSrcBuff,
1687 pDestBuff,
1688 pResults,
1689 flushFlag,
1690 srcBuffSize,
1691 NULL) != CPA_STATUS_SUCCESS) {
1692 return CPA_STATUS_INVALID_PARAM;
1693 }
1694 if (dcCheckDestinationData(pService,
1695 pSessionHandle,
1696 pDestBuff,
1697 DC_DECOMPRESSION_REQUEST) !=
1698 CPA_STATUS_SUCCESS) {
1699 return CPA_STATUS_INVALID_PARAM;
1700 }
1701 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1702
1703 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) {
1704 LAC_INVALID_PARAM_LOG("Invalid sessDirection value");
1705 return CPA_STATUS_INVALID_PARAM;
1706 }
1707
1708 *srcBufferSize = srcBuffSize;
1709
1710 return CPA_STATUS_SUCCESS;
1711 }
1712
1713 CpaStatus
cpaDcDecompressData(CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcRqResults * pResults,CpaDcFlush flushFlag,void * callbackTag)1714 cpaDcDecompressData(CpaInstanceHandle dcInstance,
1715 CpaDcSessionHandle pSessionHandle,
1716 CpaBufferList *pSrcBuff,
1717 CpaBufferList *pDestBuff,
1718 CpaDcRqResults *pResults,
1719 CpaDcFlush flushFlag,
1720 void *callbackTag)
1721 {
1722 sal_compression_service_t *pService = NULL;
1723 dc_session_desc_t *pSessionDesc = NULL;
1724 CpaInstanceHandle insHandle = NULL;
1725 Cpa64U srcBuffSize = 0;
1726 CpaStatus status = CPA_STATUS_SUCCESS;
1727
1728 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1729 insHandle = dcGetFirstHandle();
1730 } else {
1731 insHandle = dcInstance;
1732 }
1733
1734 status = dcDecompressDataCheck(insHandle,
1735 pSessionHandle,
1736 pSrcBuff,
1737 pDestBuff,
1738 pResults,
1739 flushFlag,
1740 &srcBuffSize);
1741 if (CPA_STATUS_SUCCESS != status) {
1742 return status;
1743 }
1744
1745 pService = (sal_compression_service_t *)insHandle;
1746
1747 /* Check if SAL is initialised otherwise return an error */
1748 SAL_RUNNING_CHECK(insHandle);
1749
1750 /* This check is outside the parameter checking as it is needed to
1751 * manage zero length requests */
1752 if (CPA_STATUS_SUCCESS !=
1753 LacBuffDesc_BufferListVerifyNull(pSrcBuff,
1754 &srcBuffSize,
1755 LAC_NO_ALIGNMENT_SHIFT)) {
1756 QAT_UTILS_LOG("Invalid source buffer list parameter");
1757 return CPA_STATUS_INVALID_PARAM;
1758 }
1759
1760 /* Ensure this is a compression instance */
1761 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1762
1763 if (dcCheckSourceData(pSessionHandle,
1764 pSrcBuff,
1765 pDestBuff,
1766 pResults,
1767 flushFlag,
1768 srcBuffSize,
1769 NULL) != CPA_STATUS_SUCCESS) {
1770 return CPA_STATUS_INVALID_PARAM;
1771 }
1772 if (dcCheckDestinationData(pService,
1773 pSessionHandle,
1774 pDestBuff,
1775 DC_DECOMPRESSION_REQUEST) !=
1776 CPA_STATUS_SUCCESS) {
1777 return CPA_STATUS_INVALID_PARAM;
1778 }
1779 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1780
1781 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) {
1782 QAT_UTILS_LOG("Invalid sessDirection value");
1783 return CPA_STATUS_INVALID_PARAM;
1784 }
1785
1786 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1787 /* Lock the session to check if there are in-flight stateful
1788 * requests */
1789 LAC_SPINLOCK(&(pSessionDesc->sessionLock));
1790
1791 /* Check if there is already one in-flight stateful request */
1792 if (0 !=
1793 qatUtilsAtomicGet(
1794 &(pSessionDesc->pendingStatefulCbCount))) {
1795 LAC_LOG_ERROR(
1796 "Only one in-flight stateful request supported");
1797 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1798 return CPA_STATUS_RETRY;
1799 }
1800
1801 /* Gen 4 handle 0 len requests in FW */
1802 if (isDcGen2x(pService)) {
1803 if ((0 == srcBuffSize) ||
1804 ((1 == srcBuffSize) &&
1805 (CPA_DC_FLUSH_FINAL != flushFlag) &&
1806 (CPA_DC_FLUSH_FULL != flushFlag))) {
1807 if (CPA_TRUE ==
1808 dcZeroLengthRequests(
1809 pService,
1810 pSessionDesc,
1811 pResults,
1812 flushFlag,
1813 callbackTag,
1814 DC_DECOMPRESSION_REQUEST)) {
1815 return CPA_STATUS_SUCCESS;
1816 }
1817 }
1818 }
1819
1820 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount));
1821 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1822 }
1823
1824 return dcCompDecompData(pService,
1825 pSessionDesc,
1826 insHandle,
1827 pSessionHandle,
1828 pSrcBuff,
1829 pDestBuff,
1830 pResults,
1831 flushFlag,
1832 NULL,
1833 callbackTag,
1834 DC_DECOMPRESSION_REQUEST,
1835 CPA_TRUE,
1836 DC_NO_CNV);
1837 }
1838
1839 CpaStatus
cpaDcDecompressData2(CpaInstanceHandle dcInstance,CpaDcSessionHandle pSessionHandle,CpaBufferList * pSrcBuff,CpaBufferList * pDestBuff,CpaDcOpData * pOpData,CpaDcRqResults * pResults,void * callbackTag)1840 cpaDcDecompressData2(CpaInstanceHandle dcInstance,
1841 CpaDcSessionHandle pSessionHandle,
1842 CpaBufferList *pSrcBuff,
1843 CpaBufferList *pDestBuff,
1844 CpaDcOpData *pOpData,
1845 CpaDcRqResults *pResults,
1846 void *callbackTag)
1847 {
1848 sal_compression_service_t *pService = NULL;
1849 dc_session_desc_t *pSessionDesc = NULL;
1850 CpaInstanceHandle insHandle = NULL;
1851 CpaStatus status = CPA_STATUS_SUCCESS;
1852 Cpa64U srcBuffSize = 0;
1853 LAC_CHECK_NULL_PARAM(pOpData);
1854
1855 if (CPA_FALSE == pOpData->integrityCrcCheck) {
1856
1857 return cpaDcDecompressData(dcInstance,
1858 pSessionHandle,
1859 pSrcBuff,
1860 pDestBuff,
1861 pResults,
1862 pOpData->flushFlag,
1863 callbackTag);
1864 }
1865
1866 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1867 insHandle = dcGetFirstHandle();
1868 } else {
1869 insHandle = dcInstance;
1870 }
1871
1872 status = dcDecompressDataCheck(insHandle,
1873 pSessionHandle,
1874 pSrcBuff,
1875 pDestBuff,
1876 pResults,
1877 pOpData->flushFlag,
1878 &srcBuffSize);
1879 if (CPA_STATUS_SUCCESS != status) {
1880 return status;
1881 }
1882
1883 pService = (sal_compression_service_t *)insHandle;
1884
1885 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1886
1887 LAC_CHECK_NULL_PARAM(insHandle);
1888
1889 /* Check if SAL is initialised otherwise return an error */
1890 SAL_RUNNING_CHECK(insHandle);
1891
1892 /* This check is outside the parameter checking as it is needed to
1893 * manage zero length requests */
1894 if (CPA_STATUS_SUCCESS !=
1895 LacBuffDesc_BufferListVerifyNull(pSrcBuff,
1896 &srcBuffSize,
1897 LAC_NO_ALIGNMENT_SHIFT)) {
1898 QAT_UTILS_LOG("Invalid source buffer list parameter");
1899 return CPA_STATUS_INVALID_PARAM;
1900 }
1901
1902 /* Ensure this is a compression instance */
1903 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1904
1905 if (CPA_STATUS_SUCCESS !=
1906 dcCheckSourceData(pSessionHandle,
1907 pSrcBuff,
1908 pDestBuff,
1909 pResults,
1910 CPA_DC_FLUSH_NONE,
1911 srcBuffSize,
1912 NULL)) {
1913 return CPA_STATUS_INVALID_PARAM;
1914 }
1915 if (CPA_STATUS_SUCCESS !=
1916 dcCheckDestinationData(pService,
1917 pSessionHandle,
1918 pDestBuff,
1919 DC_DECOMPRESSION_REQUEST)) {
1920 return CPA_STATUS_INVALID_PARAM;
1921 }
1922
1923 if (CPA_STATUS_SUCCESS != dcCheckOpData(pService, pOpData)) {
1924 return CPA_STATUS_INVALID_PARAM;
1925 }
1926
1927 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) {
1928 QAT_UTILS_LOG("Invalid sessDirection value");
1929 return CPA_STATUS_INVALID_PARAM;
1930 }
1931
1932 if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1933 /* Lock the session to check if there are in-flight stateful
1934 * requests */
1935 LAC_SPINLOCK(&(pSessionDesc->sessionLock));
1936
1937 /* Check if there is already one in-flight stateful request */
1938 if (0 !=
1939 qatUtilsAtomicGet(
1940 &(pSessionDesc->pendingStatefulCbCount))) {
1941 LAC_LOG_ERROR(
1942 "Only one in-flight stateful request supported");
1943 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1944 return CPA_STATUS_RETRY;
1945 }
1946
1947 /* Gen 4 handle 0 len requests in FW */
1948 if (isDcGen2x(pService)) {
1949 if ((0 == srcBuffSize) ||
1950 ((1 == srcBuffSize) &&
1951 (CPA_DC_FLUSH_FINAL != pOpData->flushFlag) &&
1952 (CPA_DC_FLUSH_FULL != pOpData->flushFlag))) {
1953 if (CPA_TRUE ==
1954 dcZeroLengthRequests(
1955 pService,
1956 pSessionDesc,
1957 pResults,
1958 pOpData->flushFlag,
1959 callbackTag,
1960 DC_DECOMPRESSION_REQUEST)) {
1961 return CPA_STATUS_SUCCESS;
1962 }
1963 }
1964 }
1965 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount));
1966 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock));
1967 }
1968
1969 return dcCompDecompData(pService,
1970 pSessionDesc,
1971 insHandle,
1972 pSessionHandle,
1973 pSrcBuff,
1974 pDestBuff,
1975 pResults,
1976 pOpData->flushFlag,
1977 pOpData,
1978 callbackTag,
1979 DC_DECOMPRESSION_REQUEST,
1980 CPA_TRUE,
1981 DC_NO_CNV);
1982 }
1983