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