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