xref: /freebsd/sys/dev/qat/qat_api/common/compression/dc_session.c (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 /**
5  *****************************************************************************
6  * @file dc_session.c
7  *
8  * @ingroup Dc_DataCompression
9  *
10  * @description
11  *      Implementation of the Data Compression session operations.
12  *
13  *****************************************************************************/
14 
15 /*
16  *******************************************************************************
17  * Include public/global header files
18  *******************************************************************************
19  */
20 #include "cpa.h"
21 #include "cpa_dc.h"
22 
23 #include "icp_qat_fw.h"
24 #include "icp_qat_fw_comp.h"
25 #include "icp_qat_hw.h"
26 #include "icp_qat_hw_20_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_mem_pools.h"
36 #include "sal_types_compression.h"
37 #include "lac_buffer_desc.h"
38 #include "sal_service_state.h"
39 #include "sal_qat_cmn_msg.h"
40 #include "sal_hw_gen.h"
41 
42 /**
43  *****************************************************************************
44  * @ingroup Dc_DataCompression
45  *      Check that pSessionData is valid
46  *
47  * @description
48  *      Check that all the parameters defined in the pSessionData are valid
49  *
50  * @param[in]       pSessionData     Pointer to a user instantiated structure
51  *                                   containing session data
52  *
53  * @retval CPA_STATUS_SUCCESS        Function executed successfully
54  * @retval CPA_STATUS_FAIL           Function failed to find device
55  * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in
56  * @retval CPA_STATUS_UNSUPPORTED    Unsupported algorithm/feature
57  *
58  *****************************************************************************/
59 CpaStatus
60 dcCheckSessionData(const CpaDcSessionSetupData *pSessionData,
61 		   CpaInstanceHandle dcInstance)
62 {
63 	CpaDcInstanceCapabilities instanceCapabilities = { 0 };
64 
65 	cpaDcQueryCapabilities(dcInstance, &instanceCapabilities);
66 
67 	if ((pSessionData->compLevel < CPA_DC_L1) ||
68 	    (pSessionData->compLevel > CPA_DC_L12)) {
69 		QAT_UTILS_LOG("Invalid compLevel value\n");
70 		return CPA_STATUS_INVALID_PARAM;
71 	}
72 
73 	if ((pSessionData->autoSelectBestHuffmanTree < CPA_DC_ASB_DISABLED) ||
74 	    (pSessionData->autoSelectBestHuffmanTree > CPA_DC_ASB_ENABLED)) {
75 		QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n");
76 		return CPA_STATUS_INVALID_PARAM;
77 	}
78 	if (pSessionData->compType != CPA_DC_DEFLATE) {
79 		QAT_UTILS_LOG("Invalid compType value\n");
80 		return CPA_STATUS_INVALID_PARAM;
81 	}
82 
83 	if ((pSessionData->huffType < CPA_DC_HT_STATIC) ||
84 	    (pSessionData->huffType > CPA_DC_HT_FULL_DYNAMIC) ||
85 	    (CPA_DC_HT_PRECOMP == pSessionData->huffType)) {
86 		QAT_UTILS_LOG("Invalid huffType value\n");
87 		return CPA_STATUS_INVALID_PARAM;
88 	}
89 
90 	if ((pSessionData->sessDirection < CPA_DC_DIR_COMPRESS) ||
91 	    (pSessionData->sessDirection > CPA_DC_DIR_COMBINED)) {
92 		QAT_UTILS_LOG("Invalid sessDirection value\n");
93 		return CPA_STATUS_INVALID_PARAM;
94 	}
95 
96 	if ((pSessionData->sessState < CPA_DC_STATEFUL) ||
97 	    (pSessionData->sessState > CPA_DC_STATELESS)) {
98 		QAT_UTILS_LOG("Invalid sessState value\n");
99 		return CPA_STATUS_INVALID_PARAM;
100 	}
101 
102 	if ((pSessionData->checksum < CPA_DC_NONE) ||
103 	    (pSessionData->checksum > CPA_DC_ADLER32)) {
104 		QAT_UTILS_LOG("Invalid checksum value\n");
105 		return CPA_STATUS_INVALID_PARAM;
106 	}
107 
108 	return CPA_STATUS_SUCCESS;
109 }
110 
111 /**
112  *****************************************************************************
113  * @ingroup Dc_DataCompression
114  *      Populate the compression hardware block
115  *
116  * @description
117  *      This function will populate the compression hardware block and update
118  *      the size in bytes of the block
119  *
120  * @param[in]   pSessionDesc            Pointer to the session descriptor
121  * @param[in]   pCompConfig             Pointer to slice config word
122  * @param[in]   compDecomp              Direction of the operation
123  * @param[in]   enableDmm               Delayed Match Mode
124  *
125  *****************************************************************************/
126 static void
127 dcCompHwBlockPopulate(sal_compression_service_t *pService,
128 		      dc_session_desc_t *pSessionDesc,
129 		      icp_qat_hw_compression_config_t *pCompConfig,
130 		      dc_request_dir_t compDecomp)
131 {
132 	icp_qat_hw_compression_direction_t dir =
133 	    ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
134 	icp_qat_hw_compression_algo_t algo =
135 	    ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
136 	icp_qat_hw_compression_depth_t depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
137 	icp_qat_hw_compression_file_type_t filetype =
138 	    ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
139 	icp_qat_hw_compression_delayed_match_t dmm;
140 
141 	/* Set the direction */
142 	if (DC_COMPRESSION_REQUEST == compDecomp) {
143 		dir = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
144 	} else {
145 		dir = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS;
146 	}
147 
148 	if (CPA_DC_DEFLATE == pSessionDesc->compType) {
149 		algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
150 	} else {
151 		QAT_UTILS_LOG("Algorithm not supported for Compression\n");
152 	}
153 
154 	/* Set delay match mode */
155 	if (CPA_TRUE == pService->comp_device_data.enableDmm) {
156 		dmm = ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
157 	} else {
158 		dmm = ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED;
159 	}
160 
161 	/* Set the depth */
162 	if (DC_DECOMPRESSION_REQUEST == compDecomp) {
163 		depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
164 	} else {
165 		switch (pSessionDesc->compLevel) {
166 		case CPA_DC_L1:
167 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
168 			break;
169 		case CPA_DC_L2:
170 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_4;
171 			break;
172 		case CPA_DC_L3:
173 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_8;
174 			break;
175 		case CPA_DC_L4:
176 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_16;
177 			break;
178 		default:
179 			depth = pService->comp_device_data
180 				    .highestHwCompressionDepth;
181 			break;
182 		}
183 	}
184 
185 	/* The file type is set to ICP_QAT_HW_COMPRESSION_FILE_TYPE_0. The other
186 	 * modes will be used in the future for precompiled huffman trees */
187 	filetype = ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
188 
189 	pCompConfig->lower_val = ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(
190 	    dir, dmm, algo, depth, filetype);
191 
192 	/* Upper 32-bits of the configuration word do not need to be
193 	 * configured with legacy devices.
194 	 */
195 	pCompConfig->upper_val = 0;
196 }
197 
198 static void
199 dcCompHwBlockPopulateGen4(sal_compression_service_t *pService,
200 			  dc_session_desc_t *pSessionDesc,
201 			  icp_qat_hw_compression_config_t *pCompConfig,
202 			  dc_request_dir_t compDecomp)
203 {
204 	/* Compression related */
205 	if (DC_COMPRESSION_REQUEST == compDecomp) {
206 		icp_qat_hw_comp_20_config_csr_upper_t hw_comp_upper_csr;
207 		icp_qat_hw_comp_20_config_csr_lower_t hw_comp_lower_csr;
208 
209 		memset(&hw_comp_upper_csr, 0, sizeof hw_comp_upper_csr);
210 		memset(&hw_comp_lower_csr, 0, sizeof hw_comp_lower_csr);
211 
212 		/* Disable Literal + Length Limit Block Drop by default and
213 		 * enable it only for dynamic deflate compression.
214 		 */
215 		hw_comp_lower_csr.lllbd =
216 		    ICP_QAT_HW_COMP_20_LLLBD_CTRL_LLLBD_DISABLED;
217 
218 		switch (pSessionDesc->compType) {
219 		case CPA_DC_DEFLATE:
220 			/* DEFLATE algorithm settings */
221 			hw_comp_lower_csr.skip_ctrl =
222 			    ICP_QAT_HW_COMP_20_BYTE_SKIP_3BYTE_LITERAL;
223 
224 			if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
225 				hw_comp_lower_csr.algo =
226 				    ICP_QAT_HW_COMP_20_HW_COMP_FORMAT_ILZ77;
227 			} else /* Static DEFLATE */
228 			{
229 				hw_comp_lower_csr.algo =
230 				    ICP_QAT_HW_COMP_20_HW_COMP_FORMAT_DEFLATE;
231 				hw_comp_upper_csr.scb_ctrl =
232 				    ICP_QAT_HW_COMP_20_SCB_CONTROL_DISABLE;
233 			}
234 
235 			if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
236 				hw_comp_upper_csr.som_ctrl =
237 				    ICP_QAT_HW_COMP_20_SOM_CONTROL_REPLAY_MODE;
238 			}
239 			break;
240 		default:
241 			QAT_UTILS_LOG("Compression algorithm not supported\n");
242 			break;
243 		}
244 		/* Set the search depth */
245 		switch (pSessionDesc->compLevel) {
246 		case CPA_DC_L1:
247 		case CPA_DC_L2:
248 		case CPA_DC_L3:
249 		case CPA_DC_L4:
250 		case CPA_DC_L5:
251 			hw_comp_lower_csr.sd =
252 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_1;
253 			hw_comp_lower_csr.hash_col =
254 			    ICP_QAT_HW_COMP_20_SKIP_HASH_COLLISION_DONT_ALLOW;
255 			break;
256 		case CPA_DC_L6:
257 		case CPA_DC_L7:
258 		case CPA_DC_L8:
259 			hw_comp_lower_csr.sd =
260 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_6;
261 			break;
262 		case CPA_DC_L9:
263 			hw_comp_lower_csr.sd =
264 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_9;
265 			break;
266 		default:
267 			hw_comp_lower_csr.sd = pService->comp_device_data
268 						   .highestHwCompressionDepth;
269 			if ((CPA_DC_HT_FULL_DYNAMIC ==
270 			     pSessionDesc->huffType) &&
271 			    (CPA_DC_DEFLATE == pSessionDesc->compType)) {
272 				/* Enable Literal + Length Limit Block Drop
273 				 * with dynamic deflate compression when
274 				 * highest compression levels are selected.
275 				 */
276 				hw_comp_lower_csr.lllbd =
277 				    ICP_QAT_HW_COMP_20_LLLBD_CTRL_LLLBD_ENABLED;
278 			}
279 			break;
280 		}
281 		/* Same for all algorithms */
282 		hw_comp_lower_csr.abd = ICP_QAT_HW_COMP_20_ABD_ABD_DISABLED;
283 		hw_comp_lower_csr.hash_update =
284 		    ICP_QAT_HW_COMP_20_SKIP_HASH_UPDATE_DONT_ALLOW;
285 		hw_comp_lower_csr.edmm =
286 		    (CPA_TRUE == pService->comp_device_data.enableDmm) ?
287 		    ICP_QAT_HW_COMP_20_EXTENDED_DELAY_MATCH_MODE_EDMM_ENABLED :
288 		    ICP_QAT_HW_COMP_20_EXTENDED_DELAY_MATCH_MODE_EDMM_DISABLED;
289 
290 		/* Hard-coded HW-specific values */
291 		hw_comp_upper_csr.nice =
292 		    ICP_QAT_HW_COMP_20_CONFIG_CSR_NICE_PARAM_DEFAULT_VAL;
293 		hw_comp_upper_csr.lazy =
294 		    ICP_QAT_HW_COMP_20_CONFIG_CSR_LAZY_PARAM_DEFAULT_VAL;
295 
296 		pCompConfig->upper_val =
297 		    ICP_QAT_FW_COMP_20_BUILD_CONFIG_UPPER(hw_comp_upper_csr);
298 
299 		pCompConfig->lower_val =
300 		    ICP_QAT_FW_COMP_20_BUILD_CONFIG_LOWER(hw_comp_lower_csr);
301 	} else /* Decompress */
302 	{
303 		icp_qat_hw_decomp_20_config_csr_lower_t hw_decomp_lower_csr;
304 
305 		memset(&hw_decomp_lower_csr, 0, sizeof hw_decomp_lower_csr);
306 
307 		/* Set the algorithm */
308 		if (CPA_DC_DEFLATE == pSessionDesc->compType) {
309 			hw_decomp_lower_csr.algo =
310 			    ICP_QAT_HW_DECOMP_20_HW_DECOMP_FORMAT_DEFLATE;
311 		} else {
312 			QAT_UTILS_LOG("Algorithm not supported for "
313 				      "Decompression\n");
314 		}
315 
316 		pCompConfig->upper_val = 0;
317 		pCompConfig->lower_val =
318 		    ICP_QAT_FW_DECOMP_20_BUILD_CONFIG_LOWER(
319 			hw_decomp_lower_csr);
320 	}
321 }
322 
323 /**
324  *****************************************************************************
325  * @ingroup Dc_DataCompression
326  *      Populate the compression content descriptor
327  *
328  * @description
329  *      This function will populate the compression content descriptor
330  *
331  * @param[in]   pService                Pointer to the service
332  * @param[in]   pSessionDesc            Pointer to the session descriptor
333  * @param[in]   contextBufferAddrPhys   Physical address of the context buffer
334  * @param[out]  pMsg                    Pointer to the compression message
335  * @param[in]   nextSlice               Next slice
336  * @param[in]   compDecomp              Direction of the operation
337  *
338  *****************************************************************************/
339 static void
340 dcCompContentDescPopulate(sal_compression_service_t *pService,
341 			  dc_session_desc_t *pSessionDesc,
342 			  CpaPhysicalAddr contextBufferAddrPhys,
343 			  icp_qat_fw_comp_req_t *pMsg,
344 			  icp_qat_fw_slice_t nextSlice,
345 			  dc_request_dir_t compDecomp)
346 {
347 
348 	icp_qat_fw_comp_cd_hdr_t *pCompControlBlock = NULL;
349 	icp_qat_hw_compression_config_t *pCompConfig = NULL;
350 	CpaBoolean bankEnabled = CPA_FALSE;
351 
352 	pCompControlBlock = (icp_qat_fw_comp_cd_hdr_t *)&(pMsg->comp_cd_ctrl);
353 	pCompConfig =
354 	    (icp_qat_hw_compression_config_t *)(pMsg->cd_pars.sl
355 						    .comp_slice_cfg_word);
356 
357 	ICP_QAT_FW_COMN_NEXT_ID_SET(pCompControlBlock, nextSlice);
358 	ICP_QAT_FW_COMN_CURR_ID_SET(pCompControlBlock, ICP_QAT_FW_SLICE_COMP);
359 
360 	pCompControlBlock->comp_cfg_offset = 0;
361 
362 	if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
363 	    (CPA_DC_DEFLATE == pSessionDesc->compType) &&
364 	    (DC_DECOMPRESSION_REQUEST == compDecomp)) {
365 		/* Enable A, B, C, D, and E (CAMs).  */
366 		pCompControlBlock->ram_bank_flags =
367 		    ICP_QAT_FW_COMP_RAM_FLAGS_BUILD(
368 			ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank I */
369 			ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank H */
370 			ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank G */
371 			ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank F */
372 			ICP_QAT_FW_COMP_BANK_ENABLED,  /* Bank E */
373 			ICP_QAT_FW_COMP_BANK_ENABLED,  /* Bank D */
374 			ICP_QAT_FW_COMP_BANK_ENABLED,  /* Bank C */
375 			ICP_QAT_FW_COMP_BANK_ENABLED,  /* Bank B */
376 			ICP_QAT_FW_COMP_BANK_ENABLED); /* Bank A */
377 		bankEnabled = CPA_TRUE;
378 	} else {
379 		/* Disable all banks */
380 		pCompControlBlock->ram_bank_flags =
381 		    ICP_QAT_FW_COMP_RAM_FLAGS_BUILD(
382 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank I */
383 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank H */
384 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank G */
385 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank F */
386 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank E */
387 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank D */
388 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank C */
389 			ICP_QAT_FW_COMP_BANK_DISABLED,  /* Bank B */
390 			ICP_QAT_FW_COMP_BANK_DISABLED); /* Bank A */
391 	}
392 
393 	if (DC_COMPRESSION_REQUEST == compDecomp) {
394 		LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
395 		    pService->generic_service_info,
396 		    pCompControlBlock->comp_state_addr,
397 		    pSessionDesc->stateRegistersComp);
398 	} else {
399 		LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL(
400 		    pService->generic_service_info,
401 		    pCompControlBlock->comp_state_addr,
402 		    pSessionDesc->stateRegistersDecomp);
403 	}
404 
405 	if (CPA_TRUE == bankEnabled) {
406 		pCompControlBlock->ram_banks_addr = contextBufferAddrPhys;
407 	} else {
408 		pCompControlBlock->ram_banks_addr = 0;
409 	}
410 
411 	pCompControlBlock->resrvd = 0;
412 
413 	/* Populate Compression Hardware Setup Block */
414 	if (isDcGen4x(pService)) {
415 		dcCompHwBlockPopulateGen4(pService,
416 					  pSessionDesc,
417 					  pCompConfig,
418 					  compDecomp);
419 	} else if (isDcGen2x(pService)) {
420 		dcCompHwBlockPopulate(pService,
421 				      pSessionDesc,
422 				      pCompConfig,
423 				      compDecomp);
424 	} else {
425 		QAT_UTILS_LOG("Invalid QAT generation value\n");
426 	}
427 }
428 
429 /**
430  *****************************************************************************
431  * @ingroup Dc_DataCompression
432  *      Populate the translator content descriptor
433  *
434  * @description
435  *      This function will populate the translator content descriptor
436  *
437  * @param[out]  pMsg                     Pointer to the compression message
438  * @param[in]   nextSlice                Next slice
439  *
440  *****************************************************************************/
441 void
442 dcTransContentDescPopulate(icp_qat_fw_comp_req_t *pMsg,
443 			   icp_qat_fw_slice_t nextSlice)
444 {
445 
446 	icp_qat_fw_xlt_cd_hdr_t *pTransControlBlock = NULL;
447 	pTransControlBlock = (icp_qat_fw_xlt_cd_hdr_t *)&(pMsg->u2.xlt_cd_ctrl);
448 
449 	ICP_QAT_FW_COMN_NEXT_ID_SET(pTransControlBlock, nextSlice);
450 	ICP_QAT_FW_COMN_CURR_ID_SET(pTransControlBlock, ICP_QAT_FW_SLICE_XLAT);
451 
452 	pTransControlBlock->resrvd1 = 0;
453 	pTransControlBlock->resrvd2 = 0;
454 	pTransControlBlock->resrvd3 = 0;
455 }
456 
457 /**
458  *****************************************************************************
459  * @ingroup Dc_DataCompression
460  *      Get the context size and the history size
461  *
462  * @description
463  *      This function will get the size of the context buffer and the history
464  *      buffer. The history buffer is a subset of the context buffer and its
465  *      size is needed for stateful compression.
466 
467  * @param[in]   dcInstance         DC Instance Handle
468  *
469  * @param[in]   pSessionData       Pointer to a user instantiated
470  *                                 structure containing session data
471  * @param[out]  pContextSize       Pointer to the context size
472  *
473  * @retval CPA_STATUS_SUCCESS      Function executed successfully
474  *
475  *
476  *****************************************************************************/
477 static CpaStatus
478 dcGetContextSize(CpaInstanceHandle dcInstance,
479 		 CpaDcSessionSetupData *pSessionData,
480 		 Cpa32U *pContextSize)
481 {
482 	sal_compression_service_t *pCompService = NULL;
483 
484 	pCompService = (sal_compression_service_t *)dcInstance;
485 
486 	*pContextSize = 0;
487 	if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
488 	    (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection)) {
489 		switch (pSessionData->compType) {
490 		case CPA_DC_DEFLATE:
491 			*pContextSize =
492 			    pCompService->comp_device_data.inflateContextSize;
493 			break;
494 		default:
495 			QAT_UTILS_LOG("Invalid compression algorithm.");
496 			return CPA_STATUS_FAIL;
497 		}
498 	}
499 	return CPA_STATUS_SUCCESS;
500 }
501 
502 CpaStatus
503 dcGetCompressCommandId(sal_compression_service_t *pService,
504 		       CpaDcSessionSetupData *pSessionData,
505 		       Cpa8U *pDcCmdId)
506 {
507 	CpaStatus status = CPA_STATUS_SUCCESS;
508 	LAC_CHECK_NULL_PARAM(pService);
509 	LAC_CHECK_NULL_PARAM(pSessionData);
510 	LAC_CHECK_NULL_PARAM(pDcCmdId);
511 
512 	switch (pSessionData->compType) {
513 	case CPA_DC_DEFLATE:
514 		*pDcCmdId = (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) ?
515 		    ICP_QAT_FW_COMP_CMD_DYNAMIC :
516 		    ICP_QAT_FW_COMP_CMD_STATIC;
517 		break;
518 	default:
519 		QAT_UTILS_LOG("Algorithm not supported for "
520 			      "compression\n");
521 		status = CPA_STATUS_UNSUPPORTED;
522 		break;
523 	}
524 
525 	return status;
526 }
527 
528 CpaStatus
529 dcGetDecompressCommandId(sal_compression_service_t *pService,
530 			 CpaDcSessionSetupData *pSessionData,
531 			 Cpa8U *pDcCmdId)
532 {
533 	CpaStatus status = CPA_STATUS_SUCCESS;
534 	LAC_CHECK_NULL_PARAM(pService);
535 	LAC_CHECK_NULL_PARAM(pSessionData);
536 	LAC_CHECK_NULL_PARAM(pDcCmdId);
537 
538 	switch (pSessionData->compType) {
539 	case CPA_DC_DEFLATE:
540 		*pDcCmdId = ICP_QAT_FW_COMP_CMD_DECOMPRESS;
541 		break;
542 	default:
543 		QAT_UTILS_LOG("Algorithm not supported for "
544 			      "decompression\n");
545 		status = CPA_STATUS_UNSUPPORTED;
546 		break;
547 	}
548 
549 	return status;
550 }
551 
552 CpaStatus
553 dcInitSession(CpaInstanceHandle dcInstance,
554 	      CpaDcSessionHandle pSessionHandle,
555 	      CpaDcSessionSetupData *pSessionData,
556 	      CpaBufferList *pContextBuffer,
557 	      CpaDcCallbackFn callbackFn)
558 {
559 	CpaStatus status = CPA_STATUS_SUCCESS;
560 	sal_compression_service_t *pService = NULL;
561 	icp_qat_fw_comp_req_t *pReqCache = NULL;
562 	dc_session_desc_t *pSessionDesc = NULL;
563 	CpaPhysicalAddr contextAddrPhys = 0;
564 	CpaPhysicalAddr physAddress = 0;
565 	CpaPhysicalAddr physAddressAligned = 0;
566 	Cpa32U minContextSize = 0, historySize = 0;
567 	Cpa32U rpCmdFlags = 0;
568 	icp_qat_fw_serv_specif_flags cmdFlags = 0;
569 	Cpa8U secureRam = ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
570 	Cpa8U sessType = ICP_QAT_FW_COMP_STATELESS_SESSION;
571 	Cpa8U autoSelectBest = ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST;
572 	Cpa8U enhancedAutoSelectBest = ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST;
573 	Cpa8U disableType0EnhancedAutoSelectBest =
574 	    ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST;
575 	icp_qat_fw_la_cmd_id_t dcCmdId =
576 	    (icp_qat_fw_la_cmd_id_t)ICP_QAT_FW_COMP_CMD_STATIC;
577 	icp_qat_fw_comn_flags cmnRequestFlags = 0;
578 	dc_integrity_crc_fw_t *pDataIntegrityCrcs = NULL;
579 
580 	cmnRequestFlags =
581 	    ICP_QAT_FW_COMN_FLAGS_BUILD(DC_DEFAULT_QAT_PTR_TYPE,
582 					QAT_COMN_CD_FLD_TYPE_16BYTE_DATA);
583 
584 	pService = (sal_compression_service_t *)dcInstance;
585 
586 	secureRam = pService->comp_device_data.useDevRam;
587 
588 	LAC_CHECK_NULL_PARAM(pSessionHandle);
589 	LAC_CHECK_NULL_PARAM(pSessionData);
590 
591 	/* Check that the parameters defined in the pSessionData are valid for
592 	 * the
593 	 * device */
594 	if (CPA_STATUS_SUCCESS !=
595 	    dcCheckSessionData(pSessionData, dcInstance)) {
596 		return CPA_STATUS_INVALID_PARAM;
597 	}
598 
599 	if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
600 	    (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection)) {
601 		QAT_UTILS_LOG("Stateful sessions are not supported.\n");
602 		return CPA_STATUS_UNSUPPORTED;
603 	}
604 
605 	/* Check for Gen4 and stateful, return error if both exist */
606 	if ((isDcGen4x(pService)) &&
607 	    (CPA_DC_STATEFUL == pSessionData->sessState &&
608 	     CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection)) {
609 		QAT_UTILS_LOG("Stateful sessions are not supported for "
610 			      "compression direction");
611 		return CPA_STATUS_UNSUPPORTED;
612 	}
613 
614 	if ((isDcGen2x(pService)) &&
615 	    (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType)) {
616 		/* Test if DRAM is available for the intermediate buffers */
617 		if ((NULL == pService->pInterBuffPtrsArray) &&
618 		    (0 == pService->pInterBuffPtrsArrayPhyAddr)) {
619 			if (CPA_DC_ASB_STATIC_DYNAMIC ==
620 			    pSessionData->autoSelectBestHuffmanTree) {
621 				/* Define the Huffman tree as static */
622 				pSessionData->huffType = CPA_DC_HT_STATIC;
623 			} else {
624 				QAT_UTILS_LOG(
625 				    "No buffer defined for this instance - "
626 				    "see cpaDcStartInstance.\n");
627 				return CPA_STATUS_RESOURCE;
628 			}
629 		}
630 	}
631 
632 	if ((CPA_DC_STATEFUL == pSessionData->sessState) &&
633 	    (CPA_DC_DEFLATE == pSessionData->compType)) {
634 		/* Get the size of the context buffer */
635 		status =
636 		    dcGetContextSize(dcInstance, pSessionData, &minContextSize);
637 
638 		if (CPA_STATUS_SUCCESS != status) {
639 			QAT_UTILS_LOG(
640 			    "Unable to get the context size of the session.\n");
641 			return CPA_STATUS_FAIL;
642 		}
643 
644 		/* If the minContextSize is zero it means we will not save or
645 		 * restore
646 		 * any history */
647 		if (0 != minContextSize) {
648 			Cpa64U contextBuffSize = 0;
649 
650 			LAC_CHECK_NULL_PARAM(pContextBuffer);
651 
652 			if (LacBuffDesc_BufferListVerify(
653 				pContextBuffer,
654 				&contextBuffSize,
655 				LAC_NO_ALIGNMENT_SHIFT) != CPA_STATUS_SUCCESS) {
656 				return CPA_STATUS_INVALID_PARAM;
657 			}
658 
659 			/* Ensure that the context buffer size is greater or
660 			 * equal
661 			 * to minContextSize */
662 			if (contextBuffSize < minContextSize) {
663 				QAT_UTILS_LOG(
664 				    "Context buffer size should be greater or equal to %d.\n",
665 				    minContextSize);
666 				return CPA_STATUS_INVALID_PARAM;
667 			}
668 		}
669 	}
670 
671 	/* Re-align the session structure to 64 byte alignment */
672 	physAddress =
673 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
674 					 (Cpa8U *)pSessionHandle +
675 					     sizeof(void *));
676 
677 	if (physAddress == 0) {
678 		QAT_UTILS_LOG(
679 		    "Unable to get the physical address of the session.\n");
680 		return CPA_STATUS_FAIL;
681 	}
682 
683 	physAddressAligned =
684 	    (CpaPhysicalAddr)LAC_ALIGN_POW2_ROUNDUP(physAddress,
685 						    LAC_64BYTE_ALIGNMENT);
686 
687 	pSessionDesc = (dc_session_desc_t *)
688 	    /* Move the session pointer by the physical offset
689 	    between aligned and unaligned memory */
690 	    ((Cpa8U *)pSessionHandle + sizeof(void *) +
691 	     (physAddressAligned - physAddress));
692 
693 	/* Save the aligned pointer in the first bytes (size of LAC_ARCH_UINT)
694 	 * of the session memory */
695 	*((LAC_ARCH_UINT *)pSessionHandle) = (LAC_ARCH_UINT)pSessionDesc;
696 
697 	/* Zero the compression session */
698 	LAC_OS_BZERO(pSessionDesc, sizeof(dc_session_desc_t));
699 
700 	/* Write the buffer descriptor for context/history */
701 	if (0 != minContextSize) {
702 		status = LacBuffDesc_BufferListDescWrite(
703 		    pContextBuffer,
704 		    &contextAddrPhys,
705 		    CPA_FALSE,
706 		    &(pService->generic_service_info));
707 
708 		if (status != CPA_STATUS_SUCCESS) {
709 			return status;
710 		}
711 
712 		pSessionDesc->pContextBuffer = pContextBuffer;
713 		pSessionDesc->historyBuffSize = historySize;
714 	}
715 
716 	pSessionDesc->cumulativeConsumedBytes = 0;
717 
718 	/* Initialise pSessionDesc */
719 	pSessionDesc->requestType = DC_REQUEST_FIRST;
720 	pSessionDesc->huffType = pSessionData->huffType;
721 	pSessionDesc->compType = pSessionData->compType;
722 	pSessionDesc->checksumType = pSessionData->checksum;
723 	pSessionDesc->autoSelectBestHuffmanTree =
724 	    pSessionData->autoSelectBestHuffmanTree;
725 	pSessionDesc->sessDirection = pSessionData->sessDirection;
726 	pSessionDesc->sessState = pSessionData->sessState;
727 	pSessionDesc->compLevel = pSessionData->compLevel;
728 	pSessionDesc->isDcDp = CPA_FALSE;
729 	pSessionDesc->minContextSize = minContextSize;
730 	pSessionDesc->isSopForCompressionProcessed = CPA_FALSE;
731 	pSessionDesc->isSopForDecompressionProcessed = CPA_FALSE;
732 
733 	if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
734 		pSessionDesc->previousChecksum = 1;
735 	} else {
736 		pSessionDesc->previousChecksum = 0;
737 	}
738 
739 	if (CPA_DC_STATEFUL == pSessionData->sessState) {
740 		/* Init the spinlock used to lock the access to the number of
741 		 * stateful
742 		 * in-flight requests */
743 		status = LAC_SPINLOCK_INIT(&(pSessionDesc->sessionLock));
744 		if (CPA_STATUS_SUCCESS != status) {
745 			QAT_UTILS_LOG(
746 			    "Spinlock init failed for sessionLock.\n");
747 			return CPA_STATUS_RESOURCE;
748 		}
749 	}
750 
751 	/* For asynchronous - use the user supplied callback
752 	 * for synchronous - use the internal synchronous callback */
753 	pSessionDesc->pCompressionCb = ((void *)NULL != (void *)callbackFn) ?
754 	    callbackFn :
755 	    LacSync_GenWakeupSyncCaller;
756 
757 	/* Reset the pending callback counters */
758 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount);
759 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount);
760 	pSessionDesc->pendingDpStatelessCbCount = 0;
761 
762 	if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) {
763 		if ((isDcGen2x(pService)) &&
764 		    CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) {
765 			/* Populate the compression section of the content
766 			 * descriptor */
767 			dcCompContentDescPopulate(pService,
768 						  pSessionDesc,
769 						  contextAddrPhys,
770 						  &(pSessionDesc->reqCacheComp),
771 						  ICP_QAT_FW_SLICE_XLAT,
772 						  DC_COMPRESSION_REQUEST);
773 
774 			/* Populate the translator section of the content
775 			 * descriptor */
776 			dcTransContentDescPopulate(
777 			    &(pSessionDesc->reqCacheComp),
778 			    ICP_QAT_FW_SLICE_DRAM_WR);
779 
780 			if (0 != pService->pInterBuffPtrsArrayPhyAddr) {
781 				pReqCache = &(pSessionDesc->reqCacheComp);
782 
783 				pReqCache->u1.xlt_pars.inter_buff_ptr =
784 				    pService->pInterBuffPtrsArrayPhyAddr;
785 			}
786 		} else {
787 			dcCompContentDescPopulate(pService,
788 						  pSessionDesc,
789 						  contextAddrPhys,
790 						  &(pSessionDesc->reqCacheComp),
791 						  ICP_QAT_FW_SLICE_DRAM_WR,
792 						  DC_COMPRESSION_REQUEST);
793 		}
794 	}
795 
796 	/* Populate the compression section of the content descriptor for
797 	 * the decompression case or combined */
798 	if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) {
799 		dcCompContentDescPopulate(pService,
800 					  pSessionDesc,
801 					  contextAddrPhys,
802 					  &(pSessionDesc->reqCacheDecomp),
803 					  ICP_QAT_FW_SLICE_DRAM_WR,
804 					  DC_DECOMPRESSION_REQUEST);
805 	}
806 
807 	if (CPA_DC_STATEFUL == pSessionData->sessState) {
808 		sessType = ICP_QAT_FW_COMP_STATEFUL_SESSION;
809 
810 		LAC_OS_BZERO(&pSessionDesc->stateRegistersComp,
811 			     sizeof(pSessionDesc->stateRegistersComp));
812 
813 		LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp,
814 			     sizeof(pSessionDesc->stateRegistersDecomp));
815 	}
816 
817 	/* Get physical address of E2E CRC buffer */
818 	pSessionDesc->physDataIntegrityCrcs = (icp_qat_addr_width_t)
819 	    LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info,
820 					 &pSessionDesc->dataIntegrityCrcs);
821 	if (0 == pSessionDesc->physDataIntegrityCrcs) {
822 		QAT_UTILS_LOG(
823 		    "Unable to get the physical address of Data Integrity buffer.\n");
824 		return CPA_STATUS_FAIL;
825 	}
826 	/* Initialize default CRC parameters */
827 	pDataIntegrityCrcs = &pSessionDesc->dataIntegrityCrcs;
828 	pDataIntegrityCrcs->crc32 = 0;
829 	pDataIntegrityCrcs->adler32 = 1;
830 
831 	if (isDcGen2x(pService)) {
832 		pDataIntegrityCrcs->oCrc32Cpr = DC_INVALID_CRC;
833 		pDataIntegrityCrcs->iCrc32Cpr = DC_INVALID_CRC;
834 		pDataIntegrityCrcs->oCrc32Xlt = DC_INVALID_CRC;
835 		pDataIntegrityCrcs->iCrc32Xlt = DC_INVALID_CRC;
836 		pDataIntegrityCrcs->xorFlags = DC_XOR_FLAGS_DEFAULT;
837 		pDataIntegrityCrcs->crcPoly = DC_CRC_POLY_DEFAULT;
838 		pDataIntegrityCrcs->xorOut = DC_XOR_OUT_DEFAULT;
839 	} else {
840 		pDataIntegrityCrcs->iCrc64Cpr = DC_INVALID_CRC;
841 		pDataIntegrityCrcs->oCrc64Cpr = DC_INVALID_CRC;
842 		pDataIntegrityCrcs->iCrc64Xlt = DC_INVALID_CRC;
843 		pDataIntegrityCrcs->oCrc64Xlt = DC_INVALID_CRC;
844 		pDataIntegrityCrcs->crc64Poly = DC_CRC64_POLY_DEFAULT;
845 		pDataIntegrityCrcs->xor64Out = DC_XOR64_OUT_DEFAULT;
846 	}
847 
848 	/* Initialise seed checksums.
849 	 * It initializes swCrc32I, swCrc32O, too(union).
850 	 */
851 	pSessionDesc->seedSwCrc.swCrc64I = 0;
852 	pSessionDesc->seedSwCrc.swCrc64O = 0;
853 
854 	/* Populate the cmdFlags */
855 	switch (pSessionDesc->autoSelectBestHuffmanTree) {
856 	case CPA_DC_ASB_DISABLED:
857 		break;
858 	case CPA_DC_ASB_STATIC_DYNAMIC:
859 		autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
860 		break;
861 	case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS:
862 		autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
863 		enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST;
864 		break;
865 	case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS:
866 		autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
867 		enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST;
868 		disableType0EnhancedAutoSelectBest =
869 		    ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST;
870 		break;
871 	case CPA_DC_ASB_ENABLED:
872 		if (pService->comp_device_data.asbEnableSupport == CPA_FALSE) {
873 			autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST;
874 			enhancedAutoSelectBest =
875 			    ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST;
876 		}
877 		break;
878 	default:
879 		break;
880 	}
881 
882 	rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
883 	    ICP_QAT_FW_COMP_SOP,
884 	    ICP_QAT_FW_COMP_EOP,
885 	    ICP_QAT_FW_COMP_BFINAL,
886 	    ICP_QAT_FW_COMP_NO_CNV,
887 	    ICP_QAT_FW_COMP_NO_CNV_RECOVERY,
888 	    ICP_QAT_FW_COMP_NO_CNV_DFX,
889 	    ICP_QAT_FW_COMP_CRC_MODE_LEGACY);
890 
891 	cmdFlags =
892 	    ICP_QAT_FW_COMP_FLAGS_BUILD(sessType,
893 					autoSelectBest,
894 					enhancedAutoSelectBest,
895 					disableType0EnhancedAutoSelectBest,
896 					secureRam);
897 
898 	if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) {
899 		status = dcGetCompressCommandId(pService,
900 						pSessionData,
901 						(Cpa8U *)&dcCmdId);
902 		if (CPA_STATUS_SUCCESS != status) {
903 			QAT_UTILS_LOG(
904 			    "Couldn't get compress command ID for current "
905 			    "session data.");
906 
907 			return status;
908 		}
909 		pReqCache = &(pSessionDesc->reqCacheComp);
910 		pReqCache->comp_pars.req_par_flags = rpCmdFlags;
911 		pReqCache->comp_pars.crc.legacy.initial_adler = 1;
912 		pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
913 
914 		/* Populate header of the common request message */
915 		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
916 				      ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
917 				      (uint8_t)dcCmdId,
918 				      cmnRequestFlags,
919 				      cmdFlags);
920 	}
921 
922 	if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) {
923 		status = dcGetDecompressCommandId(pService,
924 						  pSessionData,
925 						  (Cpa8U *)&dcCmdId);
926 		if (CPA_STATUS_SUCCESS != status) {
927 			QAT_UTILS_LOG(
928 			    "Couldn't get decompress command ID for current "
929 			    "session data.");
930 
931 			return status;
932 		}
933 		pReqCache = &(pSessionDesc->reqCacheDecomp);
934 		pReqCache->comp_pars.req_par_flags = rpCmdFlags;
935 		pReqCache->comp_pars.crc.legacy.initial_adler = 1;
936 		pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
937 
938 		/* Populate header of the common request message */
939 		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
940 				      ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
941 				      (uint8_t)dcCmdId,
942 				      cmnRequestFlags,
943 				      cmdFlags);
944 	}
945 
946 	return status;
947 }
948 
949 CpaStatus
950 cpaDcInitSession(CpaInstanceHandle dcInstance,
951 		 CpaDcSessionHandle pSessionHandle,
952 		 CpaDcSessionSetupData *pSessionData,
953 		 CpaBufferList *pContextBuffer,
954 		 CpaDcCallbackFn callbackFn)
955 {
956 	CpaInstanceHandle insHandle = NULL;
957 	sal_compression_service_t *pService = NULL;
958 
959 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
960 		insHandle = dcGetFirstHandle();
961 	} else {
962 		insHandle = dcInstance;
963 	}
964 
965 	LAC_CHECK_INSTANCE_HANDLE(insHandle);
966 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
967 
968 	pService = (sal_compression_service_t *)insHandle;
969 
970 	/* Check if SAL is initialised otherwise return an error */
971 	SAL_RUNNING_CHECK(pService);
972 
973 	return dcInitSession(insHandle,
974 			     pSessionHandle,
975 			     pSessionData,
976 			     pContextBuffer,
977 			     callbackFn);
978 }
979 
980 CpaStatus
981 cpaDcResetSession(const CpaInstanceHandle dcInstance,
982 		  CpaDcSessionHandle pSessionHandle)
983 {
984 	CpaStatus status = CPA_STATUS_SUCCESS;
985 	CpaInstanceHandle insHandle = NULL;
986 	sal_compression_service_t *pService = NULL;
987 	dc_session_desc_t *pSessionDesc = NULL;
988 	Cpa64U numPendingStateless = 0;
989 	Cpa64U numPendingStateful = 0;
990 	icp_comms_trans_handle trans_handle = NULL;
991 	dc_integrity_crc_fw_t *pDataIntegrityCrcs = NULL;
992 	dc_sw_checksums_t *pSwCrcs = NULL;
993 
994 	LAC_CHECK_NULL_PARAM(pSessionHandle);
995 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
996 	LAC_CHECK_NULL_PARAM(pSessionDesc);
997 
998 	if (CPA_TRUE == pSessionDesc->isDcDp) {
999 		insHandle = dcInstance;
1000 	} else {
1001 		if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1002 			insHandle = dcGetFirstHandle();
1003 		} else {
1004 			insHandle = dcInstance;
1005 		}
1006 	}
1007 	LAC_CHECK_NULL_PARAM(insHandle);
1008 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1009 	/* Check if SAL is running otherwise return an error */
1010 	SAL_RUNNING_CHECK(insHandle);
1011 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1012 		trans_handle = ((sal_compression_service_t *)insHandle)
1013 				   ->trans_handle_compression_tx;
1014 		if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
1015 			/* Process the remaining messages on the ring */
1016 			SalQatMsg_updateQueueTail(trans_handle);
1017 			QAT_UTILS_LOG(
1018 			    "There are remaining messages on the ring\n");
1019 			return CPA_STATUS_RETRY;
1020 		}
1021 
1022 		/* Check if there are stateless pending requests */
1023 		if (0 != pSessionDesc->pendingDpStatelessCbCount) {
1024 			QAT_UTILS_LOG(
1025 			    "There are %llu stateless DP requests pending.\n",
1026 			    (unsigned long long)
1027 				pSessionDesc->pendingDpStatelessCbCount);
1028 			return CPA_STATUS_RETRY;
1029 		}
1030 	} else {
1031 		numPendingStateless =
1032 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
1033 		numPendingStateful =
1034 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
1035 		/* Check if there are stateless pending requests */
1036 		if (0 != numPendingStateless) {
1037 			QAT_UTILS_LOG(
1038 			    "There are %llu stateless requests pending.\n",
1039 			    (unsigned long long)numPendingStateless);
1040 			return CPA_STATUS_RETRY;
1041 		}
1042 		/* Check if there are stateful pending requests */
1043 		if (0 != numPendingStateful) {
1044 			QAT_UTILS_LOG(
1045 			    "There are %llu stateful requests pending.\n",
1046 			    (unsigned long long)numPendingStateful);
1047 			return CPA_STATUS_RETRY;
1048 		}
1049 
1050 		/* Reset pSessionDesc */
1051 		pSessionDesc->requestType = DC_REQUEST_FIRST;
1052 		pSessionDesc->cumulativeConsumedBytes = 0;
1053 		if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
1054 			pSessionDesc->previousChecksum = 1;
1055 		} else {
1056 			pSessionDesc->previousChecksum = 0;
1057 		}
1058 		pSessionDesc->cnvErrorInjection = ICP_QAT_FW_COMP_NO_CNV_DFX;
1059 
1060 		/* Reset integrity CRCs to default parameters. */
1061 		pDataIntegrityCrcs = &pSessionDesc->dataIntegrityCrcs;
1062 		memset(pDataIntegrityCrcs, 0, sizeof(dc_integrity_crc_fw_t));
1063 		pDataIntegrityCrcs->adler32 = 1;
1064 
1065 		pService = (sal_compression_service_t *)insHandle;
1066 		if (isDcGen2x(pService)) {
1067 			pDataIntegrityCrcs->xorFlags = DC_XOR_FLAGS_DEFAULT;
1068 			pDataIntegrityCrcs->crcPoly = DC_CRC_POLY_DEFAULT;
1069 			pDataIntegrityCrcs->xorOut = DC_XOR_OUT_DEFAULT;
1070 		} else {
1071 			pDataIntegrityCrcs->crc64Poly = DC_CRC64_POLY_DEFAULT;
1072 			pDataIntegrityCrcs->xor64Out = DC_XOR64_OUT_DEFAULT;
1073 		}
1074 
1075 		/* Reset seed SW checksums. */
1076 		pSwCrcs = &pSessionDesc->seedSwCrc;
1077 		memset(pSwCrcs, 0, sizeof(dc_sw_checksums_t));
1078 
1079 		/* Reset integrity SW checksums. */
1080 		pSwCrcs = &pSessionDesc->integritySwCrc;
1081 		memset(pSwCrcs, 0, sizeof(dc_sw_checksums_t));
1082 	}
1083 
1084 	/* Reset the pending callback counters */
1085 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount);
1086 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount);
1087 	pSessionDesc->pendingDpStatelessCbCount = 0;
1088 	if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1089 		LAC_OS_BZERO(&pSessionDesc->stateRegistersComp,
1090 			     sizeof(pSessionDesc->stateRegistersComp));
1091 		LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp,
1092 			     sizeof(pSessionDesc->stateRegistersDecomp));
1093 	}
1094 	return status;
1095 }
1096 
1097 CpaStatus
1098 cpaDcResetXXHashState(const CpaInstanceHandle dcInstance,
1099 		      CpaDcSessionHandle pSessionHandle)
1100 {
1101 	return CPA_STATUS_UNSUPPORTED;
1102 }
1103 
1104 CpaStatus
1105 cpaDcUpdateSession(const CpaInstanceHandle dcInstance,
1106 		   CpaDcSessionHandle pSessionHandle,
1107 		   CpaDcSessionUpdateData *pUpdateSessionData)
1108 {
1109 	return CPA_STATUS_UNSUPPORTED;
1110 }
1111 
1112 CpaStatus
1113 cpaDcRemoveSession(const CpaInstanceHandle dcInstance,
1114 		   CpaDcSessionHandle pSessionHandle)
1115 {
1116 	CpaStatus status = CPA_STATUS_SUCCESS;
1117 	CpaInstanceHandle insHandle = NULL;
1118 	dc_session_desc_t *pSessionDesc = NULL;
1119 	Cpa64U numPendingStateless = 0;
1120 	Cpa64U numPendingStateful = 0;
1121 	icp_comms_trans_handle trans_handle = NULL;
1122 
1123 	LAC_CHECK_NULL_PARAM(pSessionHandle);
1124 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1125 	LAC_CHECK_NULL_PARAM(pSessionDesc);
1126 
1127 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1128 		insHandle = dcInstance;
1129 	} else {
1130 		if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1131 			insHandle = dcGetFirstHandle();
1132 		} else {
1133 			insHandle = dcInstance;
1134 		}
1135 	}
1136 
1137 	LAC_CHECK_NULL_PARAM(insHandle);
1138 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1139 
1140 	/* Check if SAL is running otherwise return an error */
1141 	SAL_RUNNING_CHECK(insHandle);
1142 
1143 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1144 		trans_handle = ((sal_compression_service_t *)insHandle)
1145 				   ->trans_handle_compression_tx;
1146 
1147 		if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
1148 			/* Process the remaining messages on the ring */
1149 			SalQatMsg_updateQueueTail(trans_handle);
1150 			QAT_UTILS_LOG(
1151 			    "There are remaining messages on the ring.\n");
1152 			return CPA_STATUS_RETRY;
1153 		}
1154 
1155 		/* Check if there are stateless pending requests */
1156 		if (0 != pSessionDesc->pendingDpStatelessCbCount) {
1157 			QAT_UTILS_LOG(
1158 			    "There are %llu stateless DP requests pending.\n",
1159 			    (unsigned long long)
1160 				pSessionDesc->pendingDpStatelessCbCount);
1161 			return CPA_STATUS_RETRY;
1162 		}
1163 	} else {
1164 		numPendingStateless =
1165 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
1166 		numPendingStateful =
1167 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
1168 
1169 		/* Check if there are stateless pending requests */
1170 		if (0 != numPendingStateless) {
1171 			QAT_UTILS_LOG(
1172 			    "There are %llu stateless requests pending.\n",
1173 			    (unsigned long long)numPendingStateless);
1174 			status = CPA_STATUS_RETRY;
1175 		}
1176 
1177 		/* Check if there are stateful pending requests */
1178 		if (0 != numPendingStateful) {
1179 			QAT_UTILS_LOG(
1180 			    "There are %llu stateful requests pending.\n",
1181 			    (unsigned long long)numPendingStateful);
1182 			status = CPA_STATUS_RETRY;
1183 		}
1184 		if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
1185 		    (CPA_STATUS_SUCCESS == status)) {
1186 			LAC_SPINLOCK_DESTROY(&(pSessionDesc->sessionLock));
1187 		}
1188 	}
1189 
1190 	return status;
1191 }
1192 
1193 CpaStatus
1194 dcGetSessionSize(CpaInstanceHandle dcInstance,
1195 		 CpaDcSessionSetupData *pSessionData,
1196 		 Cpa32U *pSessionSize,
1197 		 Cpa32U *pContextSize)
1198 {
1199 
1200 	CpaStatus status = CPA_STATUS_SUCCESS;
1201 	CpaInstanceHandle insHandle = NULL;
1202 
1203 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1204 		insHandle = dcGetFirstHandle();
1205 	} else {
1206 		insHandle = dcInstance;
1207 	}
1208 
1209 	/* Check parameters */
1210 	LAC_CHECK_NULL_PARAM(insHandle);
1211 	LAC_CHECK_NULL_PARAM(pSessionData);
1212 	LAC_CHECK_NULL_PARAM(pSessionSize);
1213 
1214 	if (dcCheckSessionData(pSessionData, insHandle) != CPA_STATUS_SUCCESS) {
1215 		return CPA_STATUS_INVALID_PARAM;
1216 	}
1217 
1218 	/* Get session size for session data */
1219 	*pSessionSize = sizeof(dc_session_desc_t) + LAC_64BYTE_ALIGNMENT +
1220 	    sizeof(LAC_ARCH_UINT);
1221 
1222 	if (NULL != pContextSize) {
1223 		status =
1224 		    dcGetContextSize(insHandle, pSessionData, pContextSize);
1225 
1226 		if (CPA_STATUS_SUCCESS != status) {
1227 			QAT_UTILS_LOG(
1228 			    "Unable to get the context size of the session.\n");
1229 			return CPA_STATUS_FAIL;
1230 		}
1231 	}
1232 
1233 	return CPA_STATUS_SUCCESS;
1234 }
1235 
1236 CpaStatus
1237 cpaDcGetSessionSize(CpaInstanceHandle dcInstance,
1238 		    CpaDcSessionSetupData *pSessionData,
1239 		    Cpa32U *pSessionSize,
1240 		    Cpa32U *pContextSize)
1241 {
1242 
1243 	LAC_CHECK_NULL_PARAM(pContextSize);
1244 
1245 	return dcGetSessionSize(dcInstance,
1246 				pSessionData,
1247 				pSessionSize,
1248 				pContextSize);
1249 }
1250 
1251 CpaStatus
1252 dcSetCnvError(CpaInstanceHandle dcInstance, CpaDcSessionHandle pSessionHandle)
1253 {
1254 	LAC_CHECK_NULL_PARAM(pSessionHandle);
1255 
1256 	dc_session_desc_t *pSessionDesc = NULL;
1257 	CpaInstanceHandle insHandle = NULL;
1258 	sal_compression_service_t *pService = NULL;
1259 
1260 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1261 		insHandle = dcGetFirstHandle();
1262 	} else {
1263 		insHandle = dcInstance;
1264 	}
1265 
1266 	pService = (sal_compression_service_t *)insHandle;
1267 
1268 	if (isDcGen2x(pService)) {
1269 		QAT_UTILS_LOG("Unsupported compression feature.\n");
1270 		return CPA_STATUS_UNSUPPORTED;
1271 	}
1272 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1273 
1274 	LAC_CHECK_NULL_PARAM(pSessionDesc);
1275 
1276 	pSessionDesc->cnvErrorInjection = ICP_QAT_FW_COMP_CNV_DFX;
1277 
1278 	return CPA_STATUS_SUCCESS;
1279 }
1280