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_L9)) {
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 >
75 	     CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS)) {
76 		QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n");
77 		return CPA_STATUS_INVALID_PARAM;
78 	}
79 	if (pSessionData->compType != CPA_DC_DEFLATE) {
80 		QAT_UTILS_LOG("Invalid compType value\n");
81 		return CPA_STATUS_INVALID_PARAM;
82 	}
83 
84 	if ((pSessionData->huffType < CPA_DC_HT_STATIC) ||
85 	    (pSessionData->huffType > CPA_DC_HT_FULL_DYNAMIC) ||
86 	    (CPA_DC_HT_PRECOMP == pSessionData->huffType)) {
87 		QAT_UTILS_LOG("Invalid huffType value\n");
88 		return CPA_STATUS_INVALID_PARAM;
89 	}
90 
91 	if ((pSessionData->sessDirection < CPA_DC_DIR_COMPRESS) ||
92 	    (pSessionData->sessDirection > CPA_DC_DIR_COMBINED)) {
93 		QAT_UTILS_LOG("Invalid sessDirection value\n");
94 		return CPA_STATUS_INVALID_PARAM;
95 	}
96 
97 	if ((pSessionData->sessState < CPA_DC_STATEFUL) ||
98 	    (pSessionData->sessState > CPA_DC_STATELESS)) {
99 		QAT_UTILS_LOG("Invalid sessState value\n");
100 		return CPA_STATUS_INVALID_PARAM;
101 	}
102 
103 	if ((pSessionData->checksum < CPA_DC_NONE) ||
104 	    (pSessionData->checksum > CPA_DC_ADLER32)) {
105 		QAT_UTILS_LOG("Invalid checksum value\n");
106 		return CPA_STATUS_INVALID_PARAM;
107 	}
108 
109 	return CPA_STATUS_SUCCESS;
110 }
111 
112 /**
113  *****************************************************************************
114  * @ingroup Dc_DataCompression
115  *      Populate the compression hardware block
116  *
117  * @description
118  *      This function will populate the compression hardware block and update
119  *      the size in bytes of the block
120  *
121  * @param[in]   pSessionDesc            Pointer to the session descriptor
122  * @param[in]   pCompConfig             Pointer to slice config word
123  * @param[in]   compDecomp              Direction of the operation
124  * @param[in]   enableDmm               Delayed Match Mode
125  *
126  *****************************************************************************/
127 static void
128 dcCompHwBlockPopulate(sal_compression_service_t *pService,
129 		      dc_session_desc_t *pSessionDesc,
130 		      icp_qat_hw_compression_config_t *pCompConfig,
131 		      dc_request_dir_t compDecomp)
132 {
133 	icp_qat_hw_compression_direction_t dir =
134 	    ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
135 	icp_qat_hw_compression_algo_t algo =
136 	    ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
137 	icp_qat_hw_compression_depth_t depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
138 	icp_qat_hw_compression_file_type_t filetype =
139 	    ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
140 	icp_qat_hw_compression_delayed_match_t dmm;
141 
142 	/* Set the direction */
143 	if (DC_COMPRESSION_REQUEST == compDecomp) {
144 		dir = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS;
145 	} else {
146 		dir = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS;
147 	}
148 
149 	if (CPA_DC_DEFLATE == pSessionDesc->compType) {
150 		algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE;
151 	} else {
152 		QAT_UTILS_LOG("Algorithm not supported for Compression\n");
153 	}
154 
155 	/* Set delay match mode */
156 	if (CPA_TRUE == pService->comp_device_data.enableDmm) {
157 		dmm = ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
158 	} else {
159 		dmm = ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED;
160 	}
161 
162 	/* Set the depth */
163 	if (DC_DECOMPRESSION_REQUEST == compDecomp) {
164 		depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
165 	} else {
166 		switch (pSessionDesc->compLevel) {
167 		case CPA_DC_L1:
168 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_1;
169 			break;
170 		case CPA_DC_L2:
171 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_4;
172 			break;
173 		case CPA_DC_L3:
174 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_8;
175 			break;
176 		case CPA_DC_L4:
177 			depth = ICP_QAT_HW_COMPRESSION_DEPTH_16;
178 			break;
179 		default:
180 			depth = pService->comp_device_data
181 				    .highestHwCompressionDepth;
182 			break;
183 		}
184 	}
185 
186 	/* The file type is set to ICP_QAT_HW_COMPRESSION_FILE_TYPE_0. The other
187 	 * modes will be used in the future for precompiled huffman trees */
188 	filetype = ICP_QAT_HW_COMPRESSION_FILE_TYPE_0;
189 
190 	pCompConfig->lower_val = ICP_QAT_HW_COMPRESSION_CONFIG_BUILD(
191 	    dir, dmm, algo, depth, filetype);
192 
193 	/* Upper 32-bits of the configuration word do not need to be
194 	 * configured with legacy devices.
195 	 */
196 	pCompConfig->upper_val = 0;
197 }
198 
199 static void
200 dcCompHwBlockPopulateGen4(sal_compression_service_t *pService,
201 			  dc_session_desc_t *pSessionDesc,
202 			  icp_qat_hw_compression_config_t *pCompConfig,
203 			  dc_request_dir_t compDecomp)
204 {
205 	/* Compression related */
206 	if (DC_COMPRESSION_REQUEST == compDecomp) {
207 		icp_qat_hw_comp_20_config_csr_upper_t hw_comp_upper_csr;
208 		icp_qat_hw_comp_20_config_csr_lower_t hw_comp_lower_csr;
209 
210 		memset(&hw_comp_upper_csr, 0, sizeof hw_comp_upper_csr);
211 		memset(&hw_comp_lower_csr, 0, sizeof hw_comp_lower_csr);
212 
213 		/* Disable Literal + Length Limit Block Drop by default and
214 		 * enable it only for dynamic deflate compression.
215 		 */
216 		hw_comp_lower_csr.lllbd =
217 		    ICP_QAT_HW_COMP_20_LLLBD_CTRL_LLLBD_DISABLED;
218 
219 		switch (pSessionDesc->compType) {
220 		case CPA_DC_DEFLATE:
221 			/* DEFLATE algorithm settings */
222 			hw_comp_lower_csr.skip_ctrl =
223 			    ICP_QAT_HW_COMP_20_BYTE_SKIP_3BYTE_LITERAL;
224 
225 			if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) {
226 				hw_comp_lower_csr.algo =
227 				    ICP_QAT_HW_COMP_20_HW_COMP_FORMAT_ILZ77;
228 			} else /* Static DEFLATE */
229 			{
230 				hw_comp_lower_csr.algo =
231 				    ICP_QAT_HW_COMP_20_HW_COMP_FORMAT_DEFLATE;
232 				hw_comp_upper_csr.scb_ctrl =
233 				    ICP_QAT_HW_COMP_20_SCB_CONTROL_DISABLE;
234 			}
235 
236 			if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
237 				hw_comp_upper_csr.som_ctrl =
238 				    ICP_QAT_HW_COMP_20_SOM_CONTROL_REPLAY_MODE;
239 			}
240 			break;
241 		default:
242 			QAT_UTILS_LOG("Compression algorithm not supported\n");
243 			break;
244 		}
245 		/* Set the search depth */
246 		switch (pSessionDesc->compLevel) {
247 		case CPA_DC_L1:
248 		case CPA_DC_L2:
249 		case CPA_DC_L3:
250 		case CPA_DC_L4:
251 		case CPA_DC_L5:
252 			hw_comp_lower_csr.sd =
253 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_1;
254 			hw_comp_lower_csr.hash_col =
255 			    ICP_QAT_HW_COMP_20_SKIP_HASH_COLLISION_DONT_ALLOW;
256 			break;
257 		case CPA_DC_L6:
258 		case CPA_DC_L7:
259 		case CPA_DC_L8:
260 			hw_comp_lower_csr.sd =
261 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_6;
262 			break;
263 		case CPA_DC_L9:
264 			hw_comp_lower_csr.sd =
265 			    ICP_QAT_HW_COMP_20_SEARCH_DEPTH_LEVEL_9;
266 			break;
267 		default:
268 			hw_comp_lower_csr.sd = pService->comp_device_data
269 						   .highestHwCompressionDepth;
270 			if ((CPA_DC_HT_FULL_DYNAMIC ==
271 			     pSessionDesc->huffType) &&
272 			    (CPA_DC_DEFLATE == pSessionDesc->compType)) {
273 				/* Enable Literal + Length Limit Block Drop
274 				 * with dynamic deflate compression when
275 				 * highest compression levels are selected.
276 				 */
277 				hw_comp_lower_csr.lllbd =
278 				    ICP_QAT_HW_COMP_20_LLLBD_CTRL_LLLBD_ENABLED;
279 			}
280 			break;
281 		}
282 		/* Same for all algorithms */
283 		hw_comp_lower_csr.abd = ICP_QAT_HW_COMP_20_ABD_ABD_DISABLED;
284 		hw_comp_lower_csr.hash_update =
285 		    ICP_QAT_HW_COMP_20_SKIP_HASH_UPDATE_DONT_ALLOW;
286 		hw_comp_lower_csr.edmm =
287 		    (CPA_TRUE == 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 	default:
873 		break;
874 	}
875 
876 	rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(
877 	    ICP_QAT_FW_COMP_SOP,
878 	    ICP_QAT_FW_COMP_EOP,
879 	    ICP_QAT_FW_COMP_BFINAL,
880 	    ICP_QAT_FW_COMP_NO_CNV,
881 	    ICP_QAT_FW_COMP_NO_CNV_RECOVERY,
882 	    ICP_QAT_FW_COMP_NO_CNV_DFX,
883 	    ICP_QAT_FW_COMP_CRC_MODE_LEGACY);
884 
885 	cmdFlags =
886 	    ICP_QAT_FW_COMP_FLAGS_BUILD(sessType,
887 					autoSelectBest,
888 					enhancedAutoSelectBest,
889 					disableType0EnhancedAutoSelectBest,
890 					secureRam);
891 
892 	if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) {
893 		status = dcGetCompressCommandId(pService,
894 						pSessionData,
895 						(Cpa8U *)&dcCmdId);
896 		if (CPA_STATUS_SUCCESS != status) {
897 			QAT_UTILS_LOG(
898 			    "Couldn't get compress command ID for current "
899 			    "session data.");
900 
901 			return status;
902 		}
903 		pReqCache = &(pSessionDesc->reqCacheComp);
904 		pReqCache->comp_pars.req_par_flags = rpCmdFlags;
905 		pReqCache->comp_pars.crc.legacy.initial_adler = 1;
906 		pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
907 
908 		/* Populate header of the common request message */
909 		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
910 				      ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
911 				      (uint8_t)dcCmdId,
912 				      cmnRequestFlags,
913 				      cmdFlags);
914 	}
915 
916 	if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) {
917 		status = dcGetDecompressCommandId(pService,
918 						  pSessionData,
919 						  (Cpa8U *)&dcCmdId);
920 		if (CPA_STATUS_SUCCESS != status) {
921 			QAT_UTILS_LOG(
922 			    "Couldn't get decompress command ID for current "
923 			    "session data.");
924 
925 			return status;
926 		}
927 		pReqCache = &(pSessionDesc->reqCacheDecomp);
928 		pReqCache->comp_pars.req_par_flags = rpCmdFlags;
929 		pReqCache->comp_pars.crc.legacy.initial_adler = 1;
930 		pReqCache->comp_pars.crc.legacy.initial_crc32 = 0;
931 
932 		/* Populate header of the common request message */
933 		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache,
934 				      ICP_QAT_FW_COMN_REQ_CPM_FW_COMP,
935 				      (uint8_t)dcCmdId,
936 				      cmnRequestFlags,
937 				      cmdFlags);
938 	}
939 
940 	return status;
941 }
942 
943 CpaStatus
944 cpaDcInitSession(CpaInstanceHandle dcInstance,
945 		 CpaDcSessionHandle pSessionHandle,
946 		 CpaDcSessionSetupData *pSessionData,
947 		 CpaBufferList *pContextBuffer,
948 		 CpaDcCallbackFn callbackFn)
949 {
950 	CpaInstanceHandle insHandle = NULL;
951 	sal_compression_service_t *pService = NULL;
952 
953 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
954 		insHandle = dcGetFirstHandle();
955 	} else {
956 		insHandle = dcInstance;
957 	}
958 
959 	LAC_CHECK_INSTANCE_HANDLE(insHandle);
960 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
961 
962 	pService = (sal_compression_service_t *)insHandle;
963 
964 	/* Check if SAL is initialised otherwise return an error */
965 	SAL_RUNNING_CHECK(pService);
966 
967 	return dcInitSession(insHandle,
968 			     pSessionHandle,
969 			     pSessionData,
970 			     pContextBuffer,
971 			     callbackFn);
972 }
973 
974 CpaStatus
975 cpaDcResetSession(const CpaInstanceHandle dcInstance,
976 		  CpaDcSessionHandle pSessionHandle)
977 {
978 	CpaStatus status = CPA_STATUS_SUCCESS;
979 	CpaInstanceHandle insHandle = NULL;
980 	sal_compression_service_t *pService = NULL;
981 	dc_session_desc_t *pSessionDesc = NULL;
982 	Cpa64U numPendingStateless = 0;
983 	Cpa64U numPendingStateful = 0;
984 	icp_comms_trans_handle trans_handle = NULL;
985 	dc_integrity_crc_fw_t *pDataIntegrityCrcs = NULL;
986 	dc_sw_checksums_t *pSwCrcs = NULL;
987 
988 	LAC_CHECK_NULL_PARAM(pSessionHandle);
989 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
990 	LAC_CHECK_NULL_PARAM(pSessionDesc);
991 
992 	if (CPA_TRUE == pSessionDesc->isDcDp) {
993 		insHandle = dcInstance;
994 	} else {
995 		if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
996 			insHandle = dcGetFirstHandle();
997 		} else {
998 			insHandle = dcInstance;
999 		}
1000 	}
1001 	LAC_CHECK_NULL_PARAM(insHandle);
1002 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1003 	/* Check if SAL is running otherwise return an error */
1004 	SAL_RUNNING_CHECK(insHandle);
1005 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1006 		trans_handle = ((sal_compression_service_t *)insHandle)
1007 				   ->trans_handle_compression_tx;
1008 		if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
1009 			/* Process the remaining messages on the ring */
1010 			SalQatMsg_updateQueueTail(trans_handle);
1011 			QAT_UTILS_LOG(
1012 			    "There are remaining messages on the ring\n");
1013 			return CPA_STATUS_RETRY;
1014 		}
1015 
1016 		/* Check if there are stateless pending requests */
1017 		if (0 != pSessionDesc->pendingDpStatelessCbCount) {
1018 			QAT_UTILS_LOG(
1019 			    "There are %llu stateless DP requests pending.\n",
1020 			    (unsigned long long)
1021 				pSessionDesc->pendingDpStatelessCbCount);
1022 			return CPA_STATUS_RETRY;
1023 		}
1024 	} else {
1025 		numPendingStateless =
1026 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
1027 		numPendingStateful =
1028 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
1029 		/* Check if there are stateless pending requests */
1030 		if (0 != numPendingStateless) {
1031 			QAT_UTILS_LOG(
1032 			    "There are %llu stateless requests pending.\n",
1033 			    (unsigned long long)numPendingStateless);
1034 			return CPA_STATUS_RETRY;
1035 		}
1036 		/* Check if there are stateful pending requests */
1037 		if (0 != numPendingStateful) {
1038 			QAT_UTILS_LOG(
1039 			    "There are %llu stateful requests pending.\n",
1040 			    (unsigned long long)numPendingStateful);
1041 			return CPA_STATUS_RETRY;
1042 		}
1043 
1044 		/* Reset pSessionDesc */
1045 		pSessionDesc->requestType = DC_REQUEST_FIRST;
1046 		pSessionDesc->cumulativeConsumedBytes = 0;
1047 		if (CPA_DC_ADLER32 == pSessionDesc->checksumType) {
1048 			pSessionDesc->previousChecksum = 1;
1049 		} else {
1050 			pSessionDesc->previousChecksum = 0;
1051 		}
1052 		pSessionDesc->cnvErrorInjection = ICP_QAT_FW_COMP_NO_CNV_DFX;
1053 
1054 		/* Reset integrity CRCs to default parameters. */
1055 		pDataIntegrityCrcs = &pSessionDesc->dataIntegrityCrcs;
1056 		memset(pDataIntegrityCrcs, 0, sizeof(dc_integrity_crc_fw_t));
1057 		pDataIntegrityCrcs->adler32 = 1;
1058 
1059 		pService = (sal_compression_service_t *)insHandle;
1060 		if (isDcGen2x(pService)) {
1061 			pDataIntegrityCrcs->xorFlags = DC_XOR_FLAGS_DEFAULT;
1062 			pDataIntegrityCrcs->crcPoly = DC_CRC_POLY_DEFAULT;
1063 			pDataIntegrityCrcs->xorOut = DC_XOR_OUT_DEFAULT;
1064 		} else {
1065 			pDataIntegrityCrcs->crc64Poly = DC_CRC64_POLY_DEFAULT;
1066 			pDataIntegrityCrcs->xor64Out = DC_XOR64_OUT_DEFAULT;
1067 		}
1068 
1069 		/* Reset seed SW checksums. */
1070 		pSwCrcs = &pSessionDesc->seedSwCrc;
1071 		memset(pSwCrcs, 0, sizeof(dc_sw_checksums_t));
1072 
1073 		/* Reset integrity SW checksums. */
1074 		pSwCrcs = &pSessionDesc->integritySwCrc;
1075 		memset(pSwCrcs, 0, sizeof(dc_sw_checksums_t));
1076 	}
1077 
1078 	/* Reset the pending callback counters */
1079 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount);
1080 	qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount);
1081 	pSessionDesc->pendingDpStatelessCbCount = 0;
1082 	if (CPA_DC_STATEFUL == pSessionDesc->sessState) {
1083 		LAC_OS_BZERO(&pSessionDesc->stateRegistersComp,
1084 			     sizeof(pSessionDesc->stateRegistersComp));
1085 		LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp,
1086 			     sizeof(pSessionDesc->stateRegistersDecomp));
1087 	}
1088 	return status;
1089 }
1090 
1091 CpaStatus
1092 cpaDcRemoveSession(const CpaInstanceHandle dcInstance,
1093 		   CpaDcSessionHandle pSessionHandle)
1094 {
1095 	CpaStatus status = CPA_STATUS_SUCCESS;
1096 	CpaInstanceHandle insHandle = NULL;
1097 	dc_session_desc_t *pSessionDesc = NULL;
1098 	Cpa64U numPendingStateless = 0;
1099 	Cpa64U numPendingStateful = 0;
1100 	icp_comms_trans_handle trans_handle = NULL;
1101 
1102 	LAC_CHECK_NULL_PARAM(pSessionHandle);
1103 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1104 	LAC_CHECK_NULL_PARAM(pSessionDesc);
1105 
1106 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1107 		insHandle = dcInstance;
1108 	} else {
1109 		if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1110 			insHandle = dcGetFirstHandle();
1111 		} else {
1112 			insHandle = dcInstance;
1113 		}
1114 	}
1115 
1116 	LAC_CHECK_NULL_PARAM(insHandle);
1117 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1118 
1119 	/* Check if SAL is running otherwise return an error */
1120 	SAL_RUNNING_CHECK(insHandle);
1121 
1122 	if (CPA_TRUE == pSessionDesc->isDcDp) {
1123 		trans_handle = ((sal_compression_service_t *)insHandle)
1124 				   ->trans_handle_compression_tx;
1125 
1126 		if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
1127 			/* Process the remaining messages on the ring */
1128 			SalQatMsg_updateQueueTail(trans_handle);
1129 			QAT_UTILS_LOG(
1130 			    "There are remaining messages on the ring.\n");
1131 			return CPA_STATUS_RETRY;
1132 		}
1133 
1134 		/* Check if there are stateless pending requests */
1135 		if (0 != pSessionDesc->pendingDpStatelessCbCount) {
1136 			QAT_UTILS_LOG(
1137 			    "There are %llu stateless DP requests pending.\n",
1138 			    (unsigned long long)
1139 				pSessionDesc->pendingDpStatelessCbCount);
1140 			return CPA_STATUS_RETRY;
1141 		}
1142 	} else {
1143 		numPendingStateless =
1144 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount));
1145 		numPendingStateful =
1146 		    qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount));
1147 
1148 		/* Check if there are stateless pending requests */
1149 		if (0 != numPendingStateless) {
1150 			QAT_UTILS_LOG(
1151 			    "There are %llu stateless requests pending.\n",
1152 			    (unsigned long long)numPendingStateless);
1153 			status = CPA_STATUS_RETRY;
1154 		}
1155 
1156 		/* Check if there are stateful pending requests */
1157 		if (0 != numPendingStateful) {
1158 			QAT_UTILS_LOG(
1159 			    "There are %llu stateful requests pending.\n",
1160 			    (unsigned long long)numPendingStateful);
1161 			status = CPA_STATUS_RETRY;
1162 		}
1163 		if ((CPA_DC_STATEFUL == pSessionDesc->sessState) &&
1164 		    (CPA_STATUS_SUCCESS == status)) {
1165 			LAC_SPINLOCK_DESTROY(&(pSessionDesc->sessionLock));
1166 		}
1167 	}
1168 
1169 	return status;
1170 }
1171 
1172 CpaStatus
1173 dcGetSessionSize(CpaInstanceHandle dcInstance,
1174 		 CpaDcSessionSetupData *pSessionData,
1175 		 Cpa32U *pSessionSize,
1176 		 Cpa32U *pContextSize)
1177 {
1178 
1179 	CpaStatus status = CPA_STATUS_SUCCESS;
1180 	CpaInstanceHandle insHandle = NULL;
1181 
1182 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1183 		insHandle = dcGetFirstHandle();
1184 	} else {
1185 		insHandle = dcInstance;
1186 	}
1187 
1188 	/* Check parameters */
1189 	LAC_CHECK_NULL_PARAM(insHandle);
1190 	LAC_CHECK_NULL_PARAM(pSessionData);
1191 	LAC_CHECK_NULL_PARAM(pSessionSize);
1192 
1193 	if (dcCheckSessionData(pSessionData, insHandle) != CPA_STATUS_SUCCESS) {
1194 		return CPA_STATUS_INVALID_PARAM;
1195 	}
1196 
1197 	/* Get session size for session data */
1198 	*pSessionSize = sizeof(dc_session_desc_t) + LAC_64BYTE_ALIGNMENT +
1199 	    sizeof(LAC_ARCH_UINT);
1200 
1201 	if (NULL != pContextSize) {
1202 		status =
1203 		    dcGetContextSize(insHandle, pSessionData, pContextSize);
1204 
1205 		if (CPA_STATUS_SUCCESS != status) {
1206 			QAT_UTILS_LOG(
1207 			    "Unable to get the context size of the session.\n");
1208 			return CPA_STATUS_FAIL;
1209 		}
1210 	}
1211 
1212 	return CPA_STATUS_SUCCESS;
1213 }
1214 
1215 CpaStatus
1216 cpaDcGetSessionSize(CpaInstanceHandle dcInstance,
1217 		    CpaDcSessionSetupData *pSessionData,
1218 		    Cpa32U *pSessionSize,
1219 		    Cpa32U *pContextSize)
1220 {
1221 
1222 	LAC_CHECK_NULL_PARAM(pContextSize);
1223 
1224 	return dcGetSessionSize(dcInstance,
1225 				pSessionData,
1226 				pSessionSize,
1227 				pContextSize);
1228 }
1229 
1230 CpaStatus
1231 dcSetCnvError(CpaInstanceHandle dcInstance, CpaDcSessionHandle pSessionHandle)
1232 {
1233 	LAC_CHECK_NULL_PARAM(pSessionHandle);
1234 
1235 	dc_session_desc_t *pSessionDesc = NULL;
1236 	CpaInstanceHandle insHandle = NULL;
1237 	sal_compression_service_t *pService = NULL;
1238 
1239 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1240 		insHandle = dcGetFirstHandle();
1241 	} else {
1242 		insHandle = dcInstance;
1243 	}
1244 
1245 	pService = (sal_compression_service_t *)insHandle;
1246 
1247 	if (isDcGen2x(pService)) {
1248 		QAT_UTILS_LOG("Unsupported compression feature.\n");
1249 		return CPA_STATUS_UNSUPPORTED;
1250 	}
1251 	pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle);
1252 
1253 	LAC_CHECK_NULL_PARAM(pSessionDesc);
1254 
1255 	pSessionDesc->cnvErrorInjection = ICP_QAT_FW_COMP_CNV_DFX;
1256 
1257 	return CPA_STATUS_SUCCESS;
1258 }
1259