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