xref: /freebsd/sys/dev/qat/qat_api/common/compression/dc_datapath.c (revision ded037e65e5239671b1292ec987a2e0894b217b5)
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