1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 /**
5  *****************************************************************************
6  * @file dc_dp.c
7  *
8  * @defgroup cpaDcDp Data Compression Data Plane API
9  *
10  * @ingroup cpaDcDp
11  *
12  * @description
13  *      Implementation of the Data Compression DP operations.
14  *
15  *****************************************************************************/
16 
17 /*
18 *******************************************************************************
19 * Include public/global header files
20 *******************************************************************************
21 */
22 #include "cpa.h"
23 #include "cpa_dc.h"
24 #include "cpa_dc_dp.h"
25 
26 #include "icp_qat_fw_comp.h"
27 
28 /*
29 *******************************************************************************
30 * Include private header files
31 *******************************************************************************
32 */
33 #include "dc_session.h"
34 #include "dc_datapath.h"
35 #include "lac_common.h"
36 #include "lac_mem.h"
37 #include "lac_mem_pools.h"
38 #include "sal_types_compression.h"
39 #include "lac_sal.h"
40 #include "lac_sync.h"
41 #include "sal_service_state.h"
42 #include "sal_qat_cmn_msg.h"
43 #include "icp_sal_poll.h"
44 #include "sal_hw_gen.h"
45 
46 /**
47  *****************************************************************************
48  * @ingroup cpaDcDp
49  *      Check that pOpData is valid
50  *
51  * @description
52  *      Check that all the parameters defined in the pOpData are valid
53  *
54  * @param[in]       pOpData          Pointer to a structure containing the
55  *                                   request parameters
56  *
57  * @retval CPA_STATUS_SUCCESS        Function executed successfully
58  * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in
59  *
60  *****************************************************************************/
61 static CpaStatus
62 dcDataPlaneParamCheck(const CpaDcDpOpData *pOpData)
63 {
64 	sal_compression_service_t *pService = NULL;
65 	dc_session_desc_t *pSessionDesc = NULL;
66 
67 	LAC_CHECK_NULL_PARAM(pOpData);
68 	LAC_CHECK_NULL_PARAM(pOpData->dcInstance);
69 	LAC_CHECK_NULL_PARAM(pOpData->pSessionHandle);
70 
71 	/* Ensure this is a compression instance */
72 	SAL_CHECK_INSTANCE_TYPE(pOpData->dcInstance,
73 				SAL_SERVICE_TYPE_COMPRESSION);
74 
75 	pService = (sal_compression_service_t *)(pOpData->dcInstance);
76 
77 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
78 	if (NULL == pSessionDesc) {
79 		QAT_UTILS_LOG("Session handle not as expected.\n");
80 		return CPA_STATUS_INVALID_PARAM;
81 	}
82 
83 	if (CPA_FALSE == pSessionDesc->isDcDp) {
84 		QAT_UTILS_LOG("The session type should be data plane.\n");
85 		return CPA_STATUS_INVALID_PARAM;
86 	}
87 
88 	/* Compressing zero byte is not supported */
89 	if ((CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) &&
90 	    (0 == pOpData->bufferLenToCompress)) {
91 		QAT_UTILS_LOG("The source buffer length to compress needs to "
92 			      "be greater than zero byte.\n");
93 		return CPA_STATUS_INVALID_PARAM;
94 	}
95 
96 	if (pOpData->sessDirection > CPA_DC_DIR_DECOMPRESS) {
97 		QAT_UTILS_LOG("Invalid direction of operation.\n");
98 		return CPA_STATUS_INVALID_PARAM;
99 	}
100 
101 	if (0 == pOpData->srcBuffer) {
102 		QAT_UTILS_LOG("Invalid srcBuffer\n");
103 		return CPA_STATUS_INVALID_PARAM;
104 	}
105 	if (0 == pOpData->destBuffer) {
106 		QAT_UTILS_LOG("Invalid destBuffer\n");
107 		return CPA_STATUS_INVALID_PARAM;
108 	}
109 	if (pOpData->srcBuffer == pOpData->destBuffer) {
110 		QAT_UTILS_LOG("In place operation is not supported.\n");
111 		return CPA_STATUS_INVALID_PARAM;
112 	}
113 	if (0 == pOpData->thisPhys) {
114 		QAT_UTILS_LOG("Invalid thisPhys\n");
115 		return CPA_STATUS_INVALID_PARAM;
116 	}
117 
118 	if ((CPA_TRUE != pOpData->compressAndVerify) &&
119 	    (CPA_FALSE != pOpData->compressAndVerify)) {
120 		QAT_UTILS_LOG("Invalid compressAndVerify\n");
121 		return CPA_STATUS_INVALID_PARAM;
122 	}
123 	if ((CPA_TRUE == pOpData->compressAndVerify) &&
124 	    !(pService->generic_service_info.dcExtendedFeatures &
125 	      DC_CNV_EXTENDED_CAPABILITY)) {
126 		QAT_UTILS_LOG("Invalid compressAndVerify, no CNV capability\n");
127 		return CPA_STATUS_UNSUPPORTED;
128 	}
129 	if ((CPA_TRUE != pOpData->compressAndVerifyAndRecover) &&
130 	    (CPA_FALSE != pOpData->compressAndVerifyAndRecover)) {
131 		QAT_UTILS_LOG("Invalid compressAndVerifyAndRecover\n");
132 		return CPA_STATUS_INVALID_PARAM;
133 	}
134 	if ((CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
135 	    (CPA_FALSE == pOpData->compressAndVerify)) {
136 		QAT_UTILS_LOG("CnVnR option set without setting CnV\n");
137 		return CPA_STATUS_INVALID_PARAM;
138 	}
139 	if ((CPA_TRUE == pOpData->compressAndVerifyAndRecover) &&
140 	    !(pService->generic_service_info.dcExtendedFeatures &
141 	      DC_CNVNR_EXTENDED_CAPABILITY)) {
142 		QAT_UTILS_LOG(
143 		    "Invalid CnVnR option set and no CnVnR capability.\n");
144 		return CPA_STATUS_UNSUPPORTED;
145 	}
146 
147 	if ((CPA_DP_BUFLIST == pOpData->srcBufferLen) &&
148 	    (CPA_DP_BUFLIST != pOpData->destBufferLen)) {
149 		QAT_UTILS_LOG(
150 		    "The source and destination buffers need to be of the same type (both flat buffers or buffer lists).\n");
151 		return CPA_STATUS_INVALID_PARAM;
152 	}
153 	if ((CPA_DP_BUFLIST != pOpData->srcBufferLen) &&
154 	    (CPA_DP_BUFLIST == pOpData->destBufferLen)) {
155 		QAT_UTILS_LOG(
156 		    "The source and destination buffers need to be of the same type (both flat buffers or buffer lists).\n");
157 		return CPA_STATUS_INVALID_PARAM;
158 	}
159 
160 	if (CPA_DP_BUFLIST != pOpData->srcBufferLen) {
161 		if (pOpData->srcBufferLen < pOpData->bufferLenToCompress) {
162 			QAT_UTILS_LOG(
163 			    "srcBufferLen is smaller than bufferLenToCompress.\n");
164 			return CPA_STATUS_INVALID_PARAM;
165 		}
166 
167 		if (pOpData->destBufferLen < pOpData->bufferLenForData) {
168 			QAT_UTILS_LOG(
169 			    "destBufferLen is smaller than bufferLenForData.\n");
170 			return CPA_STATUS_INVALID_PARAM;
171 		}
172 	} else {
173 		/* We are assuming that there is enough memory in the source and
174 		 * destination buffer lists. We only receive physical addresses
175 		 * of the buffers so we are unable to test it here */
176 		LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->srcBuffer);
177 		LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->destBuffer);
178 	}
179 
180 	LAC_CHECK_8_BYTE_ALIGNMENT(pOpData->thisPhys);
181 
182 	if ((CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) ||
183 	    (CPA_DC_DIR_COMBINED == pSessionDesc->sessDirection)) {
184 		if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
185 			/* Check if Intermediate Buffer Array pointer is NULL */
186 			if (isDcGen2x(pService) &&
187 			    ((0 == pService->pInterBuffPtrsArrayPhyAddr) ||
188 			     (NULL == pService->pInterBuffPtrsArray))) {
189 				QAT_UTILS_LOG(
190 				    "No intermediate buffer defined for this instance - see cpaDcStartInstance.\n");
191 				return CPA_STATUS_INVALID_PARAM;
192 			}
193 
194 			/* Ensure that the destination buffer length for data is
195 			 * greater
196 			 * or equal to 128B */
197 			if (pOpData->bufferLenForData <
198 			    DC_DEST_BUFFER_DYN_MIN_SIZE) {
199 				QAT_UTILS_LOG(
200 				    "Destination buffer length for data should be greater or equal to 128B.\n");
201 				return CPA_STATUS_INVALID_PARAM;
202 			}
203 		} else {
204 			/* Ensure that the destination buffer length for data is
205 			 * greater
206 			 * or equal to min output buffsize */
207 			if (pOpData->bufferLenForData <
208 			    pService->comp_device_data.minOutputBuffSize) {
209 				QAT_UTILS_LOG(
210 				    "Destination buffer size should be greater or equal to %d bytes.\n",
211 				    pService->comp_device_data
212 					.minOutputBuffSize);
213 				return CPA_STATUS_INVALID_PARAM;
214 			}
215 		}
216 	}
217 
218 	return CPA_STATUS_SUCCESS;
219 }
220 
221 CpaStatus
222 cpaDcDpGetSessionSize(CpaInstanceHandle dcInstance,
223 		      CpaDcSessionSetupData *pSessionData,
224 		      Cpa32U *pSessionSize)
225 {
226 	return dcGetSessionSize(dcInstance, pSessionData, pSessionSize, NULL);
227 }
228 
229 CpaStatus
230 cpaDcDpInitSession(CpaInstanceHandle dcInstance,
231 		   CpaDcSessionHandle pSessionHandle,
232 		   CpaDcSessionSetupData *pSessionData)
233 {
234 	CpaStatus status = CPA_STATUS_SUCCESS;
235 	dc_session_desc_t *pSessionDesc = NULL;
236 	sal_compression_service_t *pService = NULL;
237 
238 	LAC_CHECK_INSTANCE_HANDLE(dcInstance);
239 	SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
240 
241 	pService = (sal_compression_service_t *)dcInstance;
242 
243 	/* Check if SAL is initialised otherwise return an error */
244 	SAL_RUNNING_CHECK(pService);
245 
246 	/* Stateful is not supported */
247 	if (CPA_DC_STATELESS != pSessionData->sessState) {
248 		QAT_UTILS_LOG("Invalid sessState value\n");
249 		return CPA_STATUS_INVALID_PARAM;
250 	}
251 
252 	status =
253 	    dcInitSession(dcInstance, pSessionHandle, pSessionData, NULL, NULL);
254 	if (CPA_STATUS_SUCCESS == status) {
255 		pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
256 		pSessionDesc->isDcDp = CPA_TRUE;
257 
258 		ICP_QAT_FW_COMN_PTR_TYPE_SET(
259 		    pSessionDesc->reqCacheDecomp.comn_hdr.comn_req_flags,
260 		    DC_DP_QAT_PTR_TYPE);
261 		ICP_QAT_FW_COMN_PTR_TYPE_SET(
262 		    pSessionDesc->reqCacheComp.comn_hdr.comn_req_flags,
263 		    DC_DP_QAT_PTR_TYPE);
264 	}
265 
266 	return status;
267 }
268 
269 CpaStatus
270 cpaDcDpRemoveSession(const CpaInstanceHandle dcInstance,
271 		     CpaDcSessionHandle pSessionHandle)
272 {
273 	return cpaDcRemoveSession(dcInstance, pSessionHandle);
274 }
275 
276 CpaStatus
277 cpaDcDpRegCbFunc(const CpaInstanceHandle dcInstance,
278 		 const CpaDcDpCallbackFn pNewCb)
279 {
280 	sal_compression_service_t *pService = NULL;
281 
282 	LAC_CHECK_NULL_PARAM(dcInstance);
283 	SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
284 	LAC_CHECK_NULL_PARAM(pNewCb);
285 
286 	/* Check if SAL is initialised otherwise return an error */
287 	SAL_RUNNING_CHECK(dcInstance);
288 
289 	pService = (sal_compression_service_t *)dcInstance;
290 	pService->pDcDpCb = pNewCb;
291 
292 	return CPA_STATUS_SUCCESS;
293 }
294 
295 /**
296  *****************************************************************************
297  * @ingroup cpaDcDp
298  *
299  * @description
300  *      Writes the message to the ring
301  *
302  * @param[in]       pOpData          Pointer to a structure containing the
303  *                                   request parameters
304  * @param[in]       pCurrentQatMsg   Pointer to current QAT message on the ring
305  *
306  *****************************************************************************/
307 static void
308 dcDpWriteRingMsg(CpaDcDpOpData *pOpData, icp_qat_fw_comp_req_t *pCurrentQatMsg)
309 {
310 	icp_qat_fw_comp_req_t *pReqCache = NULL;
311 	dc_session_desc_t *pSessionDesc = NULL;
312 	Cpa8U bufferFormat;
313 
314 	Cpa8U cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV;
315 	Cpa8U cnvnrCompReq = ICP_QAT_FW_COMP_NO_CNV_RECOVERY;
316 	CpaBoolean cnvErrorInjection = ICP_QAT_FW_COMP_NO_CNV_DFX;
317 	sal_compression_service_t *pService = NULL;
318 
319 	pService = (sal_compression_service_t *)(pOpData->dcInstance);
320 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
321 
322 	if (CPA_DC_DIR_COMPRESS == pOpData->sessDirection) {
323 		pReqCache = &(pSessionDesc->reqCacheComp);
324 		/* CNV check */
325 		if (CPA_TRUE == pOpData->compressAndVerify) {
326 			cnvDecompReq = ICP_QAT_FW_COMP_CNV;
327 			if (isDcGen4x(pService)) {
328 				cnvErrorInjection =
329 				    pSessionDesc->cnvErrorInjection;
330 			}
331 
332 			/* CNVNR check */
333 			if (CPA_TRUE == pOpData->compressAndVerifyAndRecover) {
334 				cnvnrCompReq = ICP_QAT_FW_COMP_CNV_RECOVERY;
335 			}
336 		}
337 	} else {
338 		pReqCache = &(pSessionDesc->reqCacheDecomp);
339 	}
340 
341 	/* Fills in the template DC ET ring message - cached from the
342 	 * session descriptor */
343 	memcpy((void *)pCurrentQatMsg,
344 	       (void *)(pReqCache),
345 	       (LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES));
346 
347 	if (CPA_DP_BUFLIST == pOpData->srcBufferLen) {
348 		bufferFormat = QAT_COMN_PTR_TYPE_SGL;
349 	} else {
350 		bufferFormat = QAT_COMN_PTR_TYPE_FLAT;
351 	}
352 
353 	pCurrentQatMsg->comp_pars.req_par_flags |=
354 	    ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
355 		ICP_QAT_FW_COMP_NOT_SOP,
356 		ICP_QAT_FW_COMP_NOT_EOP,
357 		ICP_QAT_FW_COMP_NOT_BFINAL,
358 		cnvDecompReq,
359 		cnvnrCompReq,
360 		cnvErrorInjection,
361 		ICP_QAT_FW_COMP_CRC_MODE_LEGACY);
362 
363 	SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)pCurrentQatMsg,
364 			      pOpData,
365 			      bufferFormat,
366 			      pOpData->srcBuffer,
367 			      pOpData->destBuffer,
368 			      pOpData->srcBufferLen,
369 			      pOpData->destBufferLen);
370 
371 	pCurrentQatMsg->comp_pars.comp_len = pOpData->bufferLenToCompress;
372 	pCurrentQatMsg->comp_pars.out_buffer_sz = pOpData->bufferLenForData;
373 }
374 
375 CpaStatus
376 cpaDcDpEnqueueOp(CpaDcDpOpData *pOpData, const CpaBoolean performOpNow)
377 {
378 	icp_qat_fw_comp_req_t *pCurrentQatMsg = NULL;
379 	icp_comms_trans_handle trans_handle = NULL;
380 	dc_session_desc_t *pSessionDesc = NULL;
381 	CpaStatus status = CPA_STATUS_SUCCESS;
382 
383 	status = dcDataPlaneParamCheck(pOpData);
384 	if (CPA_STATUS_SUCCESS != status) {
385 		return status;
386 	}
387 
388 	if ((CPA_FALSE == pOpData->compressAndVerify) &&
389 	    (CPA_DC_DIR_COMPRESS == pOpData->sessDirection)) {
390 		return CPA_STATUS_UNSUPPORTED;
391 	}
392 
393 	/* Check if SAL is initialised otherwise return an error */
394 	SAL_RUNNING_CHECK(pOpData->dcInstance);
395 
396 	trans_handle = ((sal_compression_service_t *)pOpData->dcInstance)
397 			   ->trans_handle_compression_tx;
398 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData->pSessionHandle);
399 
400 	if ((CPA_DC_DIR_COMPRESS == pOpData->sessDirection) &&
401 	    (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection)) {
402 		QAT_UTILS_LOG(
403 		    "The session does not support this direction of operation.\n");
404 		return CPA_STATUS_INVALID_PARAM;
405 	} else if ((CPA_DC_DIR_DECOMPRESS == pOpData->sessDirection) &&
406 		   (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection)) {
407 		QAT_UTILS_LOG(
408 		    "The session does not support this direction of operation.\n");
409 		return CPA_STATUS_INVALID_PARAM;
410 	}
411 
412 	icp_adf_getSingleQueueAddr(trans_handle, (void **)&pCurrentQatMsg);
413 	if (NULL == pCurrentQatMsg) {
414 		return CPA_STATUS_RETRY;
415 	}
416 
417 	dcDpWriteRingMsg(pOpData, pCurrentQatMsg);
418 	pSessionDesc->pendingDpStatelessCbCount++;
419 
420 	if (CPA_TRUE == performOpNow) {
421 		SalQatMsg_updateQueueTail(trans_handle);
422 	}
423 
424 	return CPA_STATUS_SUCCESS;
425 }
426 
427 CpaStatus
428 cpaDcDpEnqueueOpBatch(const Cpa32U numberRequests,
429 		      CpaDcDpOpData *pOpData[],
430 		      const CpaBoolean performOpNow)
431 {
432 	icp_qat_fw_comp_req_t *pCurrentQatMsg = NULL;
433 	icp_comms_trans_handle trans_handle = NULL;
434 	dc_session_desc_t *pSessionDesc = NULL;
435 	Cpa32U i = 0;
436 	CpaStatus status = CPA_STATUS_SUCCESS;
437 	sal_compression_service_t *pService = NULL;
438 
439 	LAC_CHECK_NULL_PARAM(pOpData);
440 	LAC_CHECK_NULL_PARAM(pOpData[0]);
441 	LAC_CHECK_NULL_PARAM(pOpData[0]->dcInstance);
442 
443 	pService = (sal_compression_service_t *)(pOpData[0]->dcInstance);
444 	if ((numberRequests == 0) ||
445 	    (numberRequests > pService->maxNumCompConcurrentReq)) {
446 		QAT_UTILS_LOG(
447 		    "The number of requests needs to be between 1 and %d.\n",
448 		    pService->maxNumCompConcurrentReq);
449 		return CPA_STATUS_INVALID_PARAM;
450 	}
451 
452 	for (i = 0; i < numberRequests; i++) {
453 		status = dcDataPlaneParamCheck(pOpData[i]);
454 		if (CPA_STATUS_SUCCESS != status) {
455 			return status;
456 		}
457 
458 		/* Check that all instance handles and session handles are the
459 		 * same */
460 		if (pOpData[i]->dcInstance != pOpData[0]->dcInstance) {
461 			QAT_UTILS_LOG(
462 			    "All instance handles should be the same in the pOpData.\n");
463 			return CPA_STATUS_INVALID_PARAM;
464 		}
465 
466 		if (pOpData[i]->pSessionHandle != pOpData[0]->pSessionHandle) {
467 			QAT_UTILS_LOG(
468 			    "All session handles should be the same in the pOpData.\n");
469 			return CPA_STATUS_INVALID_PARAM;
470 		}
471 	}
472 
473 	for (i = 0; i < numberRequests; i++) {
474 		if ((CPA_FALSE == pOpData[i]->compressAndVerify) &&
475 		    (CPA_DC_DIR_COMPRESS == pOpData[i]->sessDirection)) {
476 			return CPA_STATUS_UNSUPPORTED;
477 		}
478 	}
479 
480 	/* Check if SAL is initialised otherwise return an error */
481 	SAL_RUNNING_CHECK(pOpData[0]->dcInstance);
482 
483 	trans_handle = ((sal_compression_service_t *)pOpData[0]->dcInstance)
484 			   ->trans_handle_compression_tx;
485 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pOpData[0]->pSessionHandle);
486 
487 	for (i = 0; i < numberRequests; i++) {
488 		if ((CPA_DC_DIR_COMPRESS == pOpData[i]->sessDirection) &&
489 		    (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection)) {
490 			QAT_UTILS_LOG(
491 			    "The session does not support this direction of operation.\n");
492 			return CPA_STATUS_INVALID_PARAM;
493 		} else if ((CPA_DC_DIR_DECOMPRESS ==
494 			    pOpData[i]->sessDirection) &&
495 			   (CPA_DC_DIR_COMPRESS ==
496 			    pSessionDesc->sessDirection)) {
497 			QAT_UTILS_LOG(
498 			    "The session does not support this direction of operation.\n");
499 			return CPA_STATUS_INVALID_PARAM;
500 		}
501 	}
502 
503 	icp_adf_getQueueMemory(trans_handle,
504 			       numberRequests,
505 			       (void **)&pCurrentQatMsg);
506 	if (NULL == pCurrentQatMsg) {
507 		return CPA_STATUS_RETRY;
508 	}
509 
510 	for (i = 0; i < numberRequests; i++) {
511 		dcDpWriteRingMsg(pOpData[i], pCurrentQatMsg);
512 		icp_adf_getQueueNext(trans_handle, (void **)&pCurrentQatMsg);
513 	}
514 
515 	pSessionDesc->pendingDpStatelessCbCount += numberRequests;
516 
517 	if (CPA_TRUE == performOpNow) {
518 		SalQatMsg_updateQueueTail(trans_handle);
519 	}
520 
521 	return CPA_STATUS_SUCCESS;
522 }
523 
524 CpaStatus
525 icp_sal_DcPollDpInstance(CpaInstanceHandle dcInstance, Cpa32U responseQuota)
526 {
527 	icp_comms_trans_handle trans_handle = NULL;
528 
529 	LAC_CHECK_INSTANCE_HANDLE(dcInstance);
530 	SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
531 
532 	/* Check if SAL is initialised otherwise return an error */
533 	SAL_RUNNING_CHECK(dcInstance);
534 
535 	trans_handle = ((sal_compression_service_t *)dcInstance)
536 			   ->trans_handle_compression_rx;
537 
538 	return icp_adf_pollQueue(trans_handle, responseQuota);
539 }
540 
541 CpaStatus
542 cpaDcDpPerformOpNow(CpaInstanceHandle dcInstance)
543 {
544 	icp_comms_trans_handle trans_handle = NULL;
545 
546 	LAC_CHECK_NULL_PARAM(dcInstance);
547 	SAL_CHECK_INSTANCE_TYPE(dcInstance, SAL_SERVICE_TYPE_COMPRESSION);
548 
549 	/* Check if SAL is initialised otherwise return an error */
550 	SAL_RUNNING_CHECK(dcInstance);
551 
552 	trans_handle = ((sal_compression_service_t *)dcInstance)
553 			   ->trans_handle_compression_tx;
554 
555 	if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
556 		SalQatMsg_updateQueueTail(trans_handle);
557 	}
558 
559 	return CPA_STATUS_SUCCESS;
560 }
561