xref: /freebsd/sys/dev/qat/qat_api/common/ctrl/sal_compression.c (revision 3a3af6b2a160bea72509a9d5ef84e25906b0478a)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 /**
5  *****************************************************************************
6  * @file sal_compression.c
7  *
8  * @ingroup SalCtrl
9  *
10  * @description
11  *    This file contains the sal implementation for compression.
12  *
13  *****************************************************************************/
14 
15 /* QAT-API includes */
16 #include "cpa.h"
17 #include "cpa_dc.h"
18 
19 /* QAT utils includes */
20 #include "qat_utils.h"
21 
22 /* ADF includes */
23 #include "icp_adf_init.h"
24 #include "icp_adf_transport.h"
25 #include "icp_accel_devices.h"
26 #include "icp_adf_cfg.h"
27 #include "icp_adf_accel_mgr.h"
28 #include "icp_adf_poll.h"
29 #include "icp_adf_debug.h"
30 #include "icp_adf_esram.h"
31 #include "icp_qat_hw.h"
32 
33 /* SAL includes */
34 #include "lac_mem.h"
35 #include "lac_common.h"
36 #include "lac_mem_pools.h"
37 #include "sal_statistics.h"
38 #include "lac_list.h"
39 #include "icp_sal_poll.h"
40 #include "sal_types_compression.h"
41 #include "dc_session.h"
42 #include "dc_datapath.h"
43 #include "dc_stats.h"
44 #include "lac_sal.h"
45 #include "lac_sal_ctrl.h"
46 #include "sal_string_parse.h"
47 #include "sal_service_state.h"
48 #include "lac_buffer_desc.h"
49 #include "icp_qat_fw_comp.h"
50 #include "icp_sal_versions.h"
51 
52 /* C string null terminator size */
53 #define SAL_NULL_TERM_SIZE 1
54 
55 /* Type to access extended features bit fields */
56 typedef struct dc_extended_features_s {
57 	unsigned is_cnv : 1; /* Bit<0> */
58 	unsigned padding : 7;
59 	unsigned is_cnvnr : 1; /* Bit<8> */
60 	unsigned not_used : 23;
61 } dc_extd_ftrs_t;
62 
63 /*
64  * Prints statistics for a compression instance
65  */
66 static int
67 SalCtrl_CompresionDebug(void *private_data, char *data, int size, int offset)
68 {
69 	sal_compression_service_t *pCompressionService =
70 	    (sal_compression_service_t *)private_data;
71 	CpaStatus status = CPA_STATUS_SUCCESS;
72 	CpaDcStats dcStats = { 0 };
73 	Cpa32S len = 0;
74 
75 	status = cpaDcGetStats(pCompressionService, &dcStats);
76 	if (status != CPA_STATUS_SUCCESS) {
77 		QAT_UTILS_LOG("cpaDcGetStats returned error.\n");
78 		return (-1);
79 	}
80 
81 	/* Engine Info */
82 	if (NULL != pCompressionService->debug_file) {
83 		len += snprintf(data + len,
84 				size - len,
85 				SEPARATOR BORDER
86 				" Statistics for Instance %24s | \n" SEPARATOR,
87 				pCompressionService->debug_file->name);
88 	}
89 
90 	/* Perform Info */
91 	len += snprintf(data + len,
92 			size - len,
93 			BORDER " DC comp Requests:               %16llu " BORDER
94 			       "\n" BORDER
95 			       " DC comp Request Errors:         %16llu " BORDER
96 			       "\n" BORDER
97 			       " DC comp Completed:              %16llu " BORDER
98 			       "\n" BORDER
99 			       " DC comp Completed Errors:       %16llu " BORDER
100 			       "\n" SEPARATOR,
101 			(long long unsigned int)dcStats.numCompRequests,
102 			(long long unsigned int)dcStats.numCompRequestsErrors,
103 			(long long unsigned int)dcStats.numCompCompleted,
104 			(long long unsigned int)dcStats.numCompCompletedErrors);
105 
106 	/* Perform Info */
107 	len += snprintf(
108 	    data + len,
109 	    size - len,
110 	    BORDER " DC decomp Requests:             %16llu " BORDER "\n" BORDER
111 		   " DC decomp Request Errors:       %16llu " BORDER "\n" BORDER
112 		   " DC decomp Completed:            %16llu " BORDER "\n" BORDER
113 		   " DC decomp Completed Errors:     %16llu " BORDER
114 		   "\n" SEPARATOR,
115 	    (long long unsigned int)dcStats.numDecompRequests,
116 	    (long long unsigned int)dcStats.numDecompRequestsErrors,
117 	    (long long unsigned int)dcStats.numDecompCompleted,
118 	    (long long unsigned int)dcStats.numDecompCompletedErrors);
119 	return 0;
120 }
121 
122 /* Initialise device specific information needed by compression service */
123 static CpaStatus
124 SalCtrl_CompressionInit_CompData(icp_accel_dev_t *device,
125 				 sal_compression_service_t *pCompService)
126 {
127 	switch (device->deviceType) {
128 	case DEVICE_DH895XCC:
129 	case DEVICE_DH895XCCVF:
130 		pCompService->generic_service_info.integrityCrcCheck =
131 		    CPA_FALSE;
132 		pCompService->numInterBuffs =
133 		    DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
134 		pCompService->comp_device_data.minOutputBuffSize =
135 		    DC_DEST_BUFFER_STA_MIN_SIZE;
136 		pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
137 		pCompService->comp_device_data.oddByteDecompInterim = CPA_FALSE;
138 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
139 		pCompService->comp_device_data.useDevRam =
140 		    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
141 		pCompService->comp_device_data.enableDmm =
142 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_DISABLED;
143 
144 		pCompService->comp_device_data.inflateContextSize =
145 		    DC_INFLATE_CONTEXT_SIZE;
146 		pCompService->comp_device_data.highestHwCompressionDepth =
147 		    ICP_QAT_HW_COMPRESSION_DEPTH_16;
148 
149 		pCompService->comp_device_data.windowSizeMask =
150 		    (1 << DC_8K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
151 		pCompService->comp_device_data.cnvnrSupported = CPA_FALSE;
152 		break;
153 	case DEVICE_C3XXX:
154 	case DEVICE_C3XXXVF:
155 	case DEVICE_200XX:
156 	case DEVICE_200XXVF:
157 		pCompService->generic_service_info.integrityCrcCheck =
158 		    CPA_FALSE;
159 		pCompService->numInterBuffs =
160 		    DC_QAT_MAX_NUM_INTER_BUFFERS_6COMP_SLICES;
161 		pCompService->comp_device_data.oddByteDecompNobFinal =
162 		    CPA_FALSE;
163 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
164 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
165 		pCompService->comp_device_data.useDevRam =
166 		    ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
167 		pCompService->comp_device_data.inflateContextSize =
168 		    DC_INFLATE_EH_CONTEXT_SIZE;
169 		pCompService->comp_device_data.highestHwCompressionDepth =
170 		    ICP_QAT_HW_COMPRESSION_DEPTH_16;
171 		pCompService->comp_device_data.windowSizeMask =
172 		    (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
173 		pCompService->comp_device_data.minOutputBuffSize =
174 		    DC_DEST_BUFFER_STA_MIN_SIZE;
175 		pCompService->comp_device_data.enableDmm =
176 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
177 
178 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
179 		break;
180 	case DEVICE_C62X:
181 	case DEVICE_C62XVF:
182 		pCompService->generic_service_info.integrityCrcCheck =
183 		    CPA_FALSE;
184 		pCompService->numInterBuffs =
185 		    DC_QAT_MAX_NUM_INTER_BUFFERS_10COMP_SLICES;
186 		pCompService->comp_device_data.oddByteDecompNobFinal =
187 		    CPA_FALSE;
188 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
189 		pCompService->comp_device_data.translatorOverflow = CPA_FALSE;
190 		pCompService->comp_device_data.useDevRam =
191 		    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
192 		pCompService->comp_device_data.inflateContextSize =
193 		    DC_INFLATE_EH_CONTEXT_SIZE;
194 		pCompService->comp_device_data.windowSizeMask =
195 		    (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
196 		pCompService->comp_device_data.minOutputBuffSize =
197 		    DC_DEST_BUFFER_STA_MIN_SIZE;
198 		pCompService->comp_device_data.enableDmm =
199 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
200 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
201 		break;
202 	case DEVICE_C4XXX:
203 	case DEVICE_C4XXXVF:
204 		pCompService->generic_service_info.integrityCrcCheck = CPA_TRUE;
205 		pCompService->numInterBuffs =
206 		    DC_QAT_MAX_NUM_INTER_BUFFERS_24COMP_SLICES;
207 		pCompService->comp_device_data.minOutputBuffSize =
208 		    DC_DEST_BUFFER_MIN_SIZE;
209 		pCompService->comp_device_data.oddByteDecompNobFinal = CPA_TRUE;
210 		pCompService->comp_device_data.oddByteDecompInterim = CPA_TRUE;
211 		pCompService->comp_device_data.translatorOverflow = CPA_TRUE;
212 		if (pCompService->generic_service_info.capabilitiesMask &
213 		    ICP_ACCEL_CAPABILITIES_INLINE) {
214 			pCompService->comp_device_data.useDevRam =
215 			    ICP_QAT_FW_COMP_DISABLE_SECURE_RAM_USED_AS_INTMD_BUF;
216 		} else {
217 			pCompService->comp_device_data.useDevRam =
218 			    ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF;
219 		}
220 		pCompService->comp_device_data.enableDmm =
221 		    ICP_QAT_HW_COMPRESSION_DELAYED_MATCH_ENABLED;
222 		pCompService->comp_device_data.inflateContextSize =
223 		    DC_INFLATE_EH_CONTEXT_SIZE;
224 		pCompService->comp_device_data.highestHwCompressionDepth =
225 		    ICP_QAT_HW_COMPRESSION_DEPTH_128;
226 		pCompService->comp_device_data.windowSizeMask =
227 		    (1 << DC_16K_WINDOW_SIZE | 1 << DC_32K_WINDOW_SIZE);
228 		pCompService->comp_device_data.cnvnrSupported = CPA_TRUE;
229 		break;
230 	default:
231 		QAT_UTILS_LOG("Unknown device type! - %d.\n",
232 			      device->deviceType);
233 		return CPA_STATUS_FAIL;
234 	}
235 	return CPA_STATUS_SUCCESS;
236 }
237 
238 CpaStatus
239 SalCtrl_CompressionInit(icp_accel_dev_t *device, sal_service_t *service)
240 {
241 	CpaStatus status = CPA_STATUS_SUCCESS;
242 	Cpa32U numCompConcurrentReq = 0;
243 	Cpa32U request_ring_id = 0;
244 	Cpa32U response_ring_id = 0;
245 
246 	char adfGetParam[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
247 	char compMemPool[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
248 	char temp_string[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
249 	char temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
250 	char *instance_name = NULL;
251 	sal_statistics_collection_t *pStatsCollection =
252 	    (sal_statistics_collection_t *)device->pQatStats;
253 	icp_resp_deliv_method rx_resp_type = ICP_RESP_TYPE_IRQ;
254 	sal_compression_service_t *pCompressionService =
255 	    (sal_compression_service_t *)service;
256 	Cpa32U msgSize = 0;
257 	char *section = DYN_SEC;
258 
259 	SAL_SERVICE_GOOD_FOR_INIT(pCompressionService);
260 
261 	pCompressionService->generic_service_info.state =
262 	    SAL_SERVICE_STATE_INITIALIZING;
263 
264 	if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
265 		section = icpGetProcessName();
266 	}
267 
268 	if (pStatsCollection == NULL) {
269 		return CPA_STATUS_FAIL;
270 	}
271 
272 	/* Get Config Info: Accel Num, bank Num, packageID,
273 				    coreAffinity, nodeAffinity and response mode
274 	   */
275 
276 	pCompressionService->acceleratorNum = 0;
277 
278 	/* Initialise device specific compression data */
279 	SalCtrl_CompressionInit_CompData(device, pCompressionService);
280 
281 	status = Sal_StringParsing(
282 	    "Dc",
283 	    pCompressionService->generic_service_info.instance,
284 	    "BankNumber",
285 	    temp_string);
286 	LAC_CHECK_STATUS(status);
287 	status =
288 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
289 	if (CPA_STATUS_SUCCESS != status) {
290 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
291 			      temp_string);
292 		return status;
293 	}
294 
295 	pCompressionService->bankNum =
296 	    Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
297 
298 	status = Sal_StringParsing(
299 	    "Dc",
300 	    pCompressionService->generic_service_info.instance,
301 	    "IsPolled",
302 	    temp_string);
303 	LAC_CHECK_STATUS(status);
304 	status =
305 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
306 	if (CPA_STATUS_SUCCESS != status) {
307 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
308 			      temp_string);
309 		return status;
310 	}
311 	pCompressionService->isPolled =
312 	    (Cpa8U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
313 
314 	/* User instances only support poll and epoll mode */
315 	if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
316 		QAT_UTILS_LOG(
317 		    "IsPolled %u is not supported for user instance %s.\n",
318 		    pCompressionService->isPolled,
319 		    temp_string);
320 		return CPA_STATUS_FAIL;
321 	}
322 
323 	if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
324 		rx_resp_type = ICP_RESP_TYPE_POLL;
325 	}
326 
327 	status = icp_adf_cfgGetParamValue(device,
328 					  LAC_CFG_SECTION_GENERAL,
329 					  ADF_DEV_PKG_ID,
330 					  adfGetParam);
331 	if (CPA_STATUS_SUCCESS != status) {
332 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
333 			      ADF_DEV_PKG_ID);
334 		return status;
335 	}
336 	pCompressionService->pkgID =
337 	    (Cpa16U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
338 
339 	status = icp_adf_cfgGetParamValue(device,
340 					  LAC_CFG_SECTION_GENERAL,
341 					  ADF_DEV_NODE_ID,
342 					  adfGetParam);
343 	if (CPA_STATUS_SUCCESS != status) {
344 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
345 			      ADF_DEV_NODE_ID);
346 		return status;
347 	}
348 	pCompressionService->nodeAffinity =
349 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
350 
351 	/* In case of interrupt instance, use the bank affinity set by adf_ctl
352 	 * Otherwise, use the instance affinity for backwards compatibility */
353 	if (SAL_RESP_POLL_CFG_FILE != pCompressionService->isPolled) {
354 		/* Next need to read the [AcceleratorX] section of the config
355 		 * file */
356 		status = Sal_StringParsing("Accelerator",
357 					   pCompressionService->acceleratorNum,
358 					   "",
359 					   temp_string2);
360 		LAC_CHECK_STATUS(status);
361 
362 		status = Sal_StringParsing("Bank",
363 					   pCompressionService->bankNum,
364 					   "CoreAffinity",
365 					   temp_string);
366 		LAC_CHECK_STATUS(status);
367 	} else {
368 		strncpy(temp_string2,
369 			section,
370 			sizeof(temp_string2) - SAL_NULL_TERM_SIZE);
371 		temp_string2[SAL_CFG_MAX_VAL_LEN_IN_BYTES -
372 			     SAL_NULL_TERM_SIZE] = '\0';
373 
374 		status = Sal_StringParsing(
375 		    "Dc",
376 		    pCompressionService->generic_service_info.instance,
377 		    "CoreAffinity",
378 		    temp_string);
379 		LAC_CHECK_STATUS(status);
380 	}
381 
382 	status = icp_adf_cfgGetParamValue(device,
383 					  temp_string2,
384 					  temp_string,
385 					  adfGetParam);
386 	if (CPA_STATUS_SUCCESS != status) {
387 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
388 			      temp_string);
389 		return status;
390 	}
391 	pCompressionService->coreAffinity =
392 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
393 
394 	status = Sal_StringParsing(
395 	    "Dc",
396 	    pCompressionService->generic_service_info.instance,
397 	    "NumConcurrentRequests",
398 	    temp_string);
399 	LAC_CHECK_STATUS(status);
400 	status =
401 	    icp_adf_cfgGetParamValue(device, section, temp_string, adfGetParam);
402 	if (CPA_STATUS_SUCCESS != status) {
403 		QAT_UTILS_LOG("Failed to get %s from configuration.\n",
404 			      temp_string);
405 		return status;
406 	}
407 
408 	numCompConcurrentReq =
409 	    (Cpa32U)Sal_Strtoul(adfGetParam, NULL, SAL_CFG_BASE_DEC);
410 	if (validateConcurrRequest(numCompConcurrentReq)) {
411 		QAT_UTILS_LOG(
412 		    "Invalid NumConcurrentRequests, valid values are: {64, 128, 256, ... 32768, 65536}.\n");
413 		return CPA_STATUS_FAIL;
414 	}
415 
416 	/* ADF does not allow us to completely fill the ring for batch requests
417 	 */
418 	pCompressionService->maxNumCompConcurrentReq =
419 	    (numCompConcurrentReq - SAL_BATCH_SUBMIT_FREE_SPACE);
420 
421 	/* 1. Create transport handles */
422 	status = Sal_StringParsing(
423 	    "Dc",
424 	    pCompressionService->generic_service_info.instance,
425 	    "RingTx",
426 	    temp_string);
427 	LAC_CHECK_STATUS(status);
428 
429 	msgSize = LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES;
430 	status = icp_adf_transCreateHandle(
431 	    device,
432 	    ICP_TRANS_TYPE_ETR,
433 	    section,
434 	    pCompressionService->acceleratorNum,
435 	    pCompressionService->bankNum,
436 	    temp_string,
437 	    lac_getRingType(SAL_RING_TYPE_DC),
438 	    NULL,
439 	    ICP_RESP_TYPE_NONE,
440 	    numCompConcurrentReq,
441 	    msgSize,
442 	    (icp_comms_trans_handle *)&(
443 		pCompressionService->trans_handle_compression_tx));
444 	LAC_CHECK_STATUS(status);
445 
446 	if (icp_adf_transGetRingNum(
447 		pCompressionService->trans_handle_compression_tx,
448 		&request_ring_id) != CPA_STATUS_SUCCESS) {
449 		icp_adf_transReleaseHandle(
450 		    pCompressionService->trans_handle_compression_tx);
451 
452 		QAT_UTILS_LOG("Failed to get DC TX ring number.\n");
453 		return CPA_STATUS_FAIL;
454 	}
455 
456 	status = Sal_StringParsing(
457 	    "Dc",
458 	    pCompressionService->generic_service_info.instance,
459 	    "RingRx",
460 	    temp_string);
461 	if (CPA_STATUS_SUCCESS != status) {
462 		icp_adf_transReleaseHandle(
463 		    pCompressionService->trans_handle_compression_tx);
464 		return status;
465 	}
466 
467 	msgSize = LAC_QAT_DC_RESP_SZ_LW * LAC_LONG_WORD_IN_BYTES;
468 	status = icp_adf_transCreateHandle(
469 	    device,
470 	    ICP_TRANS_TYPE_ETR,
471 	    section,
472 	    pCompressionService->acceleratorNum,
473 	    pCompressionService->bankNum,
474 	    temp_string,
475 	    lac_getRingType(SAL_RING_TYPE_NONE),
476 	    (icp_trans_callback)dcCompression_ProcessCallback,
477 	    rx_resp_type,
478 	    numCompConcurrentReq,
479 	    msgSize,
480 	    (icp_comms_trans_handle *)&(
481 		pCompressionService->trans_handle_compression_rx));
482 	if (CPA_STATUS_SUCCESS != status) {
483 		icp_adf_transReleaseHandle(
484 		    pCompressionService->trans_handle_compression_tx);
485 		return status;
486 	}
487 
488 	if (icp_adf_transGetRingNum(
489 		pCompressionService->trans_handle_compression_rx,
490 		&response_ring_id) != CPA_STATUS_SUCCESS) {
491 		icp_adf_transReleaseHandle(
492 		    pCompressionService->trans_handle_compression_tx);
493 
494 		icp_adf_transReleaseHandle(
495 		    pCompressionService->trans_handle_compression_rx);
496 
497 		QAT_UTILS_LOG("Failed to get DC RX ring number.\n");
498 		return CPA_STATUS_FAIL;
499 	}
500 
501 	/* 2. Allocates memory pools */
502 
503 	/* Valid initialisation value for a pool ID */
504 	pCompressionService->compression_mem_pool = LAC_MEM_POOL_INIT_POOL_ID;
505 
506 	status = Sal_StringParsing(
507 	    "Comp",
508 	    pCompressionService->generic_service_info.instance,
509 	    "_MemPool",
510 	    compMemPool);
511 	if (CPA_STATUS_SUCCESS != status) {
512 		icp_adf_transReleaseHandle(
513 		    pCompressionService->trans_handle_compression_tx);
514 
515 		icp_adf_transReleaseHandle(
516 		    pCompressionService->trans_handle_compression_rx);
517 
518 		return status;
519 	}
520 
521 	status = Lac_MemPoolCreate(&pCompressionService->compression_mem_pool,
522 				   compMemPool,
523 				   (numCompConcurrentReq + 1),
524 				   sizeof(dc_compression_cookie_t),
525 				   LAC_64BYTE_ALIGNMENT,
526 				   CPA_FALSE,
527 				   pCompressionService->nodeAffinity);
528 	if (CPA_STATUS_SUCCESS != status) {
529 		icp_adf_transReleaseHandle(
530 		    pCompressionService->trans_handle_compression_tx);
531 
532 		icp_adf_transReleaseHandle(
533 		    pCompressionService->trans_handle_compression_rx);
534 
535 		return status;
536 	}
537 
538 	/* Init compression statistics */
539 	status = dcStatsInit(pCompressionService);
540 	if (CPA_STATUS_SUCCESS != status) {
541 		Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
542 
543 		icp_adf_transReleaseHandle(
544 		    pCompressionService->trans_handle_compression_tx);
545 
546 		icp_adf_transReleaseHandle(
547 		    pCompressionService->trans_handle_compression_rx);
548 
549 		return status;
550 	}
551 	if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
552 		/* Get instance name for stats */
553 		instance_name = LAC_OS_MALLOC(ADF_CFG_MAX_VAL_LEN_IN_BYTES);
554 		if (NULL == instance_name) {
555 			Lac_MemPoolDestroy(
556 			    pCompressionService->compression_mem_pool);
557 
558 			icp_adf_transReleaseHandle(
559 			    pCompressionService->trans_handle_compression_tx);
560 
561 			icp_adf_transReleaseHandle(
562 			    pCompressionService->trans_handle_compression_rx);
563 
564 			return CPA_STATUS_RESOURCE;
565 		}
566 
567 		status = Sal_StringParsing(
568 		    "Dc",
569 		    pCompressionService->generic_service_info.instance,
570 		    "Name",
571 		    temp_string);
572 		if (CPA_STATUS_SUCCESS != status) {
573 			Lac_MemPoolDestroy(
574 			    pCompressionService->compression_mem_pool);
575 
576 			icp_adf_transReleaseHandle(
577 			    pCompressionService->trans_handle_compression_tx);
578 
579 			icp_adf_transReleaseHandle(
580 			    pCompressionService->trans_handle_compression_rx);
581 			LAC_OS_FREE(instance_name);
582 			return status;
583 		}
584 		status = icp_adf_cfgGetParamValue(device,
585 						  section,
586 						  temp_string,
587 						  adfGetParam);
588 		if (CPA_STATUS_SUCCESS != status) {
589 			QAT_UTILS_LOG("Failed to get %s from configuration.\n",
590 				      temp_string);
591 
592 			Lac_MemPoolDestroy(
593 			    pCompressionService->compression_mem_pool);
594 
595 			icp_adf_transReleaseHandle(
596 			    pCompressionService->trans_handle_compression_tx);
597 
598 			icp_adf_transReleaseHandle(
599 			    pCompressionService->trans_handle_compression_rx);
600 			LAC_OS_FREE(instance_name);
601 			return status;
602 		}
603 
604 		snprintf(instance_name,
605 			 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
606 			 "%s",
607 			 adfGetParam);
608 
609 		pCompressionService->debug_file =
610 		    LAC_OS_MALLOC(sizeof(debug_file_info_t));
611 		if (NULL == pCompressionService->debug_file) {
612 			Lac_MemPoolDestroy(
613 			    pCompressionService->compression_mem_pool);
614 
615 			icp_adf_transReleaseHandle(
616 			    pCompressionService->trans_handle_compression_tx);
617 
618 			icp_adf_transReleaseHandle(
619 			    pCompressionService->trans_handle_compression_rx);
620 			LAC_OS_FREE(instance_name);
621 			return CPA_STATUS_RESOURCE;
622 		}
623 
624 		memset(pCompressionService->debug_file,
625 		       0,
626 		       sizeof(debug_file_info_t));
627 		pCompressionService->debug_file->name = instance_name;
628 		pCompressionService->debug_file->seq_read =
629 		    SalCtrl_CompresionDebug;
630 		pCompressionService->debug_file->private_data =
631 		    pCompressionService;
632 		pCompressionService->debug_file->parent =
633 		    pCompressionService->generic_service_info.debug_parent_dir;
634 
635 		status = icp_adf_debugAddFile(device,
636 					      pCompressionService->debug_file);
637 		if (CPA_STATUS_SUCCESS != status) {
638 			Lac_MemPoolDestroy(
639 			    pCompressionService->compression_mem_pool);
640 
641 			icp_adf_transReleaseHandle(
642 			    pCompressionService->trans_handle_compression_tx);
643 
644 			icp_adf_transReleaseHandle(
645 			    pCompressionService->trans_handle_compression_rx);
646 			LAC_OS_FREE(instance_name);
647 			LAC_OS_FREE(pCompressionService->debug_file);
648 			return status;
649 		}
650 	}
651 	pCompressionService->generic_service_info.stats = pStatsCollection;
652 	pCompressionService->generic_service_info.state =
653 	    SAL_SERVICE_STATE_INITIALIZED;
654 
655 	return status;
656 }
657 
658 CpaStatus
659 SalCtrl_CompressionStart(icp_accel_dev_t *device, sal_service_t *service)
660 {
661 	CpaStatus status = CPA_STATUS_SUCCESS;
662 
663 	sal_compression_service_t *pCompressionService =
664 	    (sal_compression_service_t *)service;
665 
666 	if (SAL_SERVICE_STATE_INITIALIZED !=
667 	    pCompressionService->generic_service_info.state) {
668 		QAT_UTILS_LOG("Not in the correct state to call start.\n");
669 		return CPA_STATUS_FAIL;
670 	}
671 	/**************************************************************/
672 	/* Obtain Extended Features. I.e. Compress And Verify         */
673 	/**************************************************************/
674 	pCompressionService->generic_service_info.dcExtendedFeatures =
675 	    device->dcExtendedFeatures;
676 	pCompressionService->generic_service_info.state =
677 	    SAL_SERVICE_STATE_RUNNING;
678 
679 	return status;
680 }
681 
682 CpaStatus
683 SalCtrl_CompressionStop(icp_accel_dev_t *device, sal_service_t *service)
684 {
685 	sal_compression_service_t *pCompressionService =
686 	    (sal_compression_service_t *)service;
687 
688 	if (SAL_SERVICE_STATE_RUNNING !=
689 	    pCompressionService->generic_service_info.state) {
690 		QAT_UTILS_LOG("Not in the correct state to call stop.\n");
691 		return CPA_STATUS_FAIL;
692 	}
693 
694 	if (icp_adf_is_dev_in_reset(device)) {
695 		pCompressionService->generic_service_info.state =
696 		    SAL_SERVICE_STATE_RESTARTING;
697 		return CPA_STATUS_SUCCESS;
698 	}
699 
700 	pCompressionService->generic_service_info.state =
701 	    SAL_SERVICE_STATE_SHUTTING_DOWN;
702 	return CPA_STATUS_RETRY;
703 }
704 
705 CpaStatus
706 SalCtrl_CompressionShutdown(icp_accel_dev_t *device, sal_service_t *service)
707 {
708 	CpaStatus status = CPA_STATUS_SUCCESS;
709 
710 	sal_compression_service_t *pCompressionService =
711 	    (sal_compression_service_t *)service;
712 	sal_statistics_collection_t *pStatsCollection =
713 	    (sal_statistics_collection_t *)device->pQatStats;
714 
715 	if ((SAL_SERVICE_STATE_INITIALIZED !=
716 	     pCompressionService->generic_service_info.state) &&
717 	    (SAL_SERVICE_STATE_SHUTTING_DOWN !=
718 	     pCompressionService->generic_service_info.state) &&
719 	    (SAL_SERVICE_STATE_RESTARTING !=
720 	     pCompressionService->generic_service_info.state)) {
721 		QAT_UTILS_LOG("Not in the correct state to call shutdown.\n");
722 		return CPA_STATUS_FAIL;
723 	}
724 
725 	Lac_MemPoolDestroy(pCompressionService->compression_mem_pool);
726 
727 	status = icp_adf_transReleaseHandle(
728 	    pCompressionService->trans_handle_compression_tx);
729 	LAC_CHECK_STATUS(status);
730 
731 	status = icp_adf_transReleaseHandle(
732 	    pCompressionService->trans_handle_compression_rx);
733 	LAC_CHECK_STATUS(status);
734 
735 	if (CPA_TRUE == pStatsCollection->bDcStatsEnabled) {
736 		/* Clean stats */
737 		if (NULL != pCompressionService->debug_file) {
738 			icp_adf_debugRemoveFile(
739 			    pCompressionService->debug_file);
740 			LAC_OS_FREE(pCompressionService->debug_file->name);
741 			LAC_OS_FREE(pCompressionService->debug_file);
742 			pCompressionService->debug_file = NULL;
743 		}
744 	}
745 	pCompressionService->generic_service_info.stats = NULL;
746 	dcStatsFree(pCompressionService);
747 
748 	if (icp_adf_is_dev_in_reset(device)) {
749 		pCompressionService->generic_service_info.state =
750 		    SAL_SERVICE_STATE_RESTARTING;
751 		return CPA_STATUS_SUCCESS;
752 	}
753 	pCompressionService->generic_service_info.state =
754 	    SAL_SERVICE_STATE_SHUTDOWN;
755 	return status;
756 }
757 
758 CpaStatus
759 cpaDcGetStatusText(const CpaInstanceHandle dcInstance,
760 		   const CpaStatus errStatus,
761 		   Cpa8S *pStatusText)
762 {
763 	CpaStatus status = CPA_STATUS_SUCCESS;
764 
765 	LAC_CHECK_NULL_PARAM(pStatusText);
766 
767 	switch (errStatus) {
768 	case CPA_STATUS_SUCCESS:
769 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_SUCCESS);
770 		break;
771 	case CPA_STATUS_FAIL:
772 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FAIL);
773 		break;
774 	case CPA_STATUS_RETRY:
775 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RETRY);
776 		break;
777 	case CPA_STATUS_RESOURCE:
778 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_RESOURCE);
779 		break;
780 	case CPA_STATUS_INVALID_PARAM:
781 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_INVALID_PARAM);
782 		break;
783 	case CPA_STATUS_FATAL:
784 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_FATAL);
785 		break;
786 	case CPA_STATUS_UNSUPPORTED:
787 		LAC_COPY_STRING(pStatusText, CPA_STATUS_STR_UNSUPPORTED);
788 		break;
789 	default:
790 		status = CPA_STATUS_INVALID_PARAM;
791 		break;
792 	}
793 
794 	return status;
795 }
796 
797 CpaStatus
798 cpaDcGetNumIntermediateBuffers(CpaInstanceHandle dcInstance,
799 			       Cpa16U *pNumBuffers)
800 {
801 	CpaInstanceHandle insHandle = NULL;
802 	sal_compression_service_t *pService = NULL;
803 
804 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
805 		insHandle = dcGetFirstHandle();
806 	} else {
807 		insHandle = dcInstance;
808 	}
809 
810 	LAC_CHECK_NULL_PARAM(insHandle);
811 	LAC_CHECK_NULL_PARAM(pNumBuffers);
812 
813 	pService = (sal_compression_service_t *)insHandle;
814 	*pNumBuffers = pService->numInterBuffs;
815 
816 	return CPA_STATUS_SUCCESS;
817 }
818 
819 CpaStatus
820 cpaDcStartInstance(CpaInstanceHandle instanceHandle,
821 		   Cpa16U numBuffers,
822 		   CpaBufferList **pIntermediateBufferPtrsArray)
823 {
824 	icp_qat_addr_width_t *pInterBuffPtrsArray = NULL;
825 	icp_qat_addr_width_t pArrayBufferListDescPhyAddr = 0;
826 	icp_qat_addr_width_t bufListDescPhyAddr;
827 	icp_qat_addr_width_t bufListAlignedPhyAddr;
828 	CpaFlatBuffer *pClientCurrFlatBuffer = NULL;
829 	icp_buffer_list_desc_t *pBufferListDesc = NULL;
830 	icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
831 	CpaInstanceInfo2 info = { 0 };
832 	icp_accel_dev_t *dev = NULL;
833 	CpaStatus status = CPA_STATUS_SUCCESS;
834 	sal_compression_service_t *pService = NULL;
835 	CpaInstanceHandle insHandle = NULL;
836 	Cpa16U bufferIndex = 0;
837 	Cpa32U numFlatBuffers = 0;
838 	Cpa64U clientListSize = 0;
839 	CpaBufferList *pClientCurrentIntermediateBuffer = NULL;
840 	Cpa32U bufferIndex2 = 0;
841 	CpaBufferList **pTempIntermediateBufferPtrsArray;
842 	Cpa64U lastClientListSize = 0;
843 
844 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
845 		insHandle = dcGetFirstHandle();
846 	} else {
847 		insHandle = instanceHandle;
848 	}
849 	LAC_CHECK_NULL_PARAM(insHandle);
850 
851 	status = cpaDcInstanceGetInfo2(insHandle, &info);
852 	if (CPA_STATUS_SUCCESS != status) {
853 		QAT_UTILS_LOG("Can not get instance info.\n");
854 		return status;
855 	}
856 
857 	dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
858 	if (NULL == dev) {
859 		QAT_UTILS_LOG("Can not find device for the instance\n");
860 		return CPA_STATUS_FAIL;
861 	}
862 
863 	if (NULL == pIntermediateBufferPtrsArray) {
864 		/* Increment dev ref counter and return - DRAM is not used */
865 		icp_qa_dev_get(dev);
866 		return CPA_STATUS_SUCCESS;
867 	}
868 
869 	if (0 == numBuffers) {
870 		/* Increment dev ref counter and return - DRAM is not used */
871 		icp_qa_dev_get(dev);
872 		return CPA_STATUS_SUCCESS;
873 	}
874 
875 	pService = (sal_compression_service_t *)insHandle;
876 
877 	LAC_CHECK_NULL_PARAM(insHandle);
878 
879 	if ((numBuffers > 0) && (NULL == pIntermediateBufferPtrsArray)) {
880 		QAT_UTILS_LOG("Invalid Intermediate Buffers Array pointer\n");
881 		return CPA_STATUS_INVALID_PARAM;
882 	}
883 
884 	/* Check number of intermediate buffers allocated by user */
885 	if ((pService->numInterBuffs != numBuffers)) {
886 		QAT_UTILS_LOG("Invalid number of buffers\n");
887 		return CPA_STATUS_INVALID_PARAM;
888 	}
889 
890 	pTempIntermediateBufferPtrsArray = pIntermediateBufferPtrsArray;
891 	for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
892 		if (NULL == *pTempIntermediateBufferPtrsArray) {
893 			QAT_UTILS_LOG(
894 			    "Intermediate Buffer - Invalid Buffer List pointer\n");
895 			return CPA_STATUS_INVALID_PARAM;
896 		}
897 
898 		if (NULL == (*pTempIntermediateBufferPtrsArray)->pBuffers) {
899 			QAT_UTILS_LOG(
900 			    "Intermediate Buffer - Invalid Flat Buffer descriptor pointer\n");
901 			return CPA_STATUS_INVALID_PARAM;
902 		}
903 
904 		if (NULL ==
905 		    (*pTempIntermediateBufferPtrsArray)->pPrivateMetaData) {
906 			QAT_UTILS_LOG(
907 			    "Intermediate Buffer - Invalid Private MetaData descriptor pointer\n");
908 			return CPA_STATUS_INVALID_PARAM;
909 		}
910 
911 		clientListSize = 0;
912 		for (bufferIndex2 = 0; bufferIndex2 <
913 		     (*pTempIntermediateBufferPtrsArray)->numBuffers;
914 		     bufferIndex2++) {
915 
916 			if ((0 !=
917 			     (*pTempIntermediateBufferPtrsArray)
918 				 ->pBuffers[bufferIndex2]
919 				 .dataLenInBytes) &&
920 			    NULL ==
921 				(*pTempIntermediateBufferPtrsArray)
922 				    ->pBuffers[bufferIndex2]
923 				    .pData) {
924 				QAT_UTILS_LOG(
925 				    "Intermediate Buffer - Invalid Flat Buffer pointer\n");
926 				return CPA_STATUS_INVALID_PARAM;
927 			}
928 
929 			clientListSize += (*pTempIntermediateBufferPtrsArray)
930 					      ->pBuffers[bufferIndex2]
931 					      .dataLenInBytes;
932 		}
933 
934 		if (bufferIndex != 0) {
935 			if (lastClientListSize != clientListSize) {
936 				QAT_UTILS_LOG(
937 				    "SGLs have to be of the same size.\n");
938 				return CPA_STATUS_INVALID_PARAM;
939 			}
940 		} else {
941 			lastClientListSize = clientListSize;
942 		}
943 		pTempIntermediateBufferPtrsArray++;
944 	}
945 
946 	/* Allocate array of physical pointers to icp_buffer_list_desc_t */
947 	status = LAC_OS_CAMALLOC(&pInterBuffPtrsArray,
948 				 (numBuffers * sizeof(icp_qat_addr_width_t)),
949 				 LAC_64BYTE_ALIGNMENT,
950 				 pService->nodeAffinity);
951 	if (CPA_STATUS_SUCCESS != status) {
952 		QAT_UTILS_LOG("Can not allocate Intermediate Buffers array.\n");
953 		return status;
954 	}
955 
956 	/* Get physical address of the intermediate buffer pointers array */
957 	pArrayBufferListDescPhyAddr = LAC_MEM_CAST_PTR_TO_UINT64(
958 	    LAC_OS_VIRT_TO_PHYS_INTERNAL(pInterBuffPtrsArray));
959 
960 	pService->pInterBuffPtrsArray = pInterBuffPtrsArray;
961 	pService->pInterBuffPtrsArrayPhyAddr = pArrayBufferListDescPhyAddr;
962 
963 	/* Get the full size of the buffer list */
964 	/* Assumption: all the SGLs allocated by the user have the same size */
965 	clientListSize = 0;
966 	for (bufferIndex = 0;
967 	     bufferIndex < (*pIntermediateBufferPtrsArray)->numBuffers;
968 	     bufferIndex++) {
969 		clientListSize += ((*pIntermediateBufferPtrsArray)
970 				       ->pBuffers[bufferIndex]
971 				       .dataLenInBytes);
972 	}
973 	pService->minInterBuffSizeInBytes = clientListSize;
974 
975 	for (bufferIndex = 0; bufferIndex < numBuffers; bufferIndex++) {
976 
977 		/* Get pointer to the client Intermediate Buffer List
978 		 * (CpaBufferList) */
979 		pClientCurrentIntermediateBuffer =
980 		    *pIntermediateBufferPtrsArray;
981 
982 		/* Get number of flat buffers in the buffer list */
983 		numFlatBuffers = pClientCurrentIntermediateBuffer->numBuffers;
984 
985 		/* Get pointer to the client array of CpaFlatBuffers */
986 		pClientCurrFlatBuffer =
987 		    pClientCurrentIntermediateBuffer->pBuffers;
988 
989 		/* Calculate Physical address of current private SGL */
990 		bufListDescPhyAddr = LAC_OS_VIRT_TO_PHYS_EXTERNAL(
991 		    (*pService),
992 		    pClientCurrentIntermediateBuffer->pPrivateMetaData);
993 		if (bufListDescPhyAddr == 0) {
994 			QAT_UTILS_LOG(
995 			    "Unable to get the physical address of the metadata.\n");
996 			return CPA_STATUS_FAIL;
997 		}
998 
999 		/* Align SGL physical address */
1000 		bufListAlignedPhyAddr =
1001 		    LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
1002 					   ICP_DESCRIPTOR_ALIGNMENT_BYTES);
1003 
1004 		/* Set physical address of the Intermediate Buffer SGL in the
1005 		 * SGLs array
1006 		 */
1007 		*pInterBuffPtrsArray =
1008 		    LAC_MEM_CAST_PTR_TO_UINT64(bufListAlignedPhyAddr);
1009 
1010 		/* Calculate (virtual) offset to the buffer list descriptor */
1011 		pBufferListDesc =
1012 		    (icp_buffer_list_desc_t
1013 			 *)((LAC_ARCH_UINT)pClientCurrentIntermediateBuffer
1014 				->pPrivateMetaData +
1015 			    (LAC_ARCH_UINT)(bufListAlignedPhyAddr -
1016 					    bufListDescPhyAddr));
1017 
1018 		/* Set number of flat buffers in the physical Buffer List
1019 		 * descriptor */
1020 		pBufferListDesc->numBuffers = numFlatBuffers;
1021 
1022 		/* Go past the Buffer List descriptor to the list of buffer
1023 		 * descriptors
1024 		 */
1025 		pCurrFlatBufDesc =
1026 		    (icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
1027 
1028 		/* Loop for each flat buffer in the SGL */
1029 		while (0 != numFlatBuffers) {
1030 			/* Set length of the current flat buffer */
1031 			pCurrFlatBufDesc->dataLenInBytes =
1032 			    pClientCurrFlatBuffer->dataLenInBytes;
1033 
1034 			/* Set physical address of the flat buffer */
1035 			pCurrFlatBufDesc->phyBuffer =
1036 			    LAC_MEM_CAST_PTR_TO_UINT64(
1037 				LAC_OS_VIRT_TO_PHYS_EXTERNAL(
1038 				    (*pService), pClientCurrFlatBuffer->pData));
1039 
1040 			if (pCurrFlatBufDesc->phyBuffer == 0) {
1041 				QAT_UTILS_LOG(
1042 				    "Unable to get the physical address of the flat buffer.\n");
1043 				return CPA_STATUS_FAIL;
1044 			}
1045 
1046 			pCurrFlatBufDesc++;
1047 			pClientCurrFlatBuffer++;
1048 			numFlatBuffers--;
1049 		}
1050 		pIntermediateBufferPtrsArray++;
1051 		pInterBuffPtrsArray++;
1052 	}
1053 
1054 	pService->generic_service_info.isInstanceStarted = CPA_TRUE;
1055 
1056 	/* Increment dev ref counter */
1057 	icp_qa_dev_get(dev);
1058 	return CPA_STATUS_SUCCESS;
1059 }
1060 
1061 CpaStatus
1062 cpaDcStopInstance(CpaInstanceHandle instanceHandle)
1063 {
1064 	CpaInstanceHandle insHandle = NULL;
1065 	CpaInstanceInfo2 info = { 0 };
1066 	icp_accel_dev_t *dev = NULL;
1067 	CpaStatus status = CPA_STATUS_SUCCESS;
1068 	sal_compression_service_t *pService = NULL;
1069 
1070 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1071 		insHandle = dcGetFirstHandle();
1072 	} else {
1073 		insHandle = instanceHandle;
1074 	}
1075 
1076 	LAC_CHECK_NULL_PARAM(insHandle);
1077 	pService = (sal_compression_service_t *)insHandle;
1078 
1079 	/* Free Intermediate Buffer Pointers Array */
1080 	if (pService->pInterBuffPtrsArray != NULL) {
1081 		LAC_OS_CAFREE(pService->pInterBuffPtrsArray);
1082 		pService->pInterBuffPtrsArray = 0;
1083 	}
1084 
1085 	pService->pInterBuffPtrsArrayPhyAddr = 0;
1086 
1087 	status = cpaDcInstanceGetInfo2(insHandle, &info);
1088 	if (CPA_STATUS_SUCCESS != status) {
1089 		QAT_UTILS_LOG("Can not get instance info.\n");
1090 		return status;
1091 	}
1092 	dev = icp_adf_getAccelDevByAccelId(info.physInstId.packageId);
1093 	if (NULL == dev) {
1094 		QAT_UTILS_LOG("Can not find device for the instance.\n");
1095 		return CPA_STATUS_FAIL;
1096 	}
1097 
1098 	pService->generic_service_info.isInstanceStarted = CPA_FALSE;
1099 
1100 	/* Decrement dev ref counter */
1101 	icp_qa_dev_put(dev);
1102 	return CPA_STATUS_SUCCESS;
1103 }
1104 
1105 CpaStatus
1106 cpaDcGetNumInstances(Cpa16U *pNumInstances)
1107 {
1108 	CpaStatus status = CPA_STATUS_SUCCESS;
1109 	icp_accel_dev_t **pAdfInsts = NULL;
1110 	icp_accel_dev_t *dev_addr = NULL;
1111 	sal_t *base_addr = NULL;
1112 	sal_list_t *list_temp = NULL;
1113 	Cpa16U num_accel_dev = 0;
1114 	Cpa16U num = 0;
1115 	Cpa16U i = 0;
1116 
1117 	LAC_CHECK_NULL_PARAM(pNumInstances);
1118 
1119 	/* Get the number of accel_dev in the system */
1120 	status = icp_amgr_getNumInstances(&num_accel_dev);
1121 	LAC_CHECK_STATUS(status);
1122 
1123 	/* Allocate memory to store addr of accel_devs */
1124 	pAdfInsts =
1125 	    malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK);
1126 	num_accel_dev = 0;
1127 
1128 	/* Get ADF to return accel_devs with dc enabled */
1129 	status = icp_amgr_getAllAccelDevByCapabilities(
1130 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
1131 	if (CPA_STATUS_SUCCESS == status) {
1132 		for (i = 0; i < num_accel_dev; i++) {
1133 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1134 			if (NULL != dev_addr) {
1135 				base_addr = dev_addr->pSalHandle;
1136 				if (NULL != base_addr) {
1137 					list_temp =
1138 					    base_addr->compression_services;
1139 					while (NULL != list_temp) {
1140 						num++;
1141 						list_temp =
1142 						    SalList_next(list_temp);
1143 					}
1144 				}
1145 			}
1146 		}
1147 
1148 		*pNumInstances = num;
1149 	}
1150 
1151 	free(pAdfInsts, M_QAT);
1152 
1153 	return status;
1154 }
1155 
1156 CpaStatus
1157 cpaDcGetInstances(Cpa16U numInstances, CpaInstanceHandle *dcInstances)
1158 {
1159 	CpaStatus status = CPA_STATUS_SUCCESS;
1160 	icp_accel_dev_t **pAdfInsts = NULL;
1161 	icp_accel_dev_t *dev_addr = NULL;
1162 	sal_t *base_addr = NULL;
1163 	sal_list_t *list_temp = NULL;
1164 	Cpa16U num_accel_dev = 0;
1165 	Cpa16U index = 0;
1166 	Cpa16U i = 0;
1167 
1168 	LAC_CHECK_NULL_PARAM(dcInstances);
1169 	if (0 == numInstances) {
1170 		QAT_UTILS_LOG("numInstances is 0.\n");
1171 		return CPA_STATUS_INVALID_PARAM;
1172 	}
1173 
1174 	/* Get the number of accel_dev in the system */
1175 	status = icp_amgr_getNumInstances(&num_accel_dev);
1176 	LAC_CHECK_STATUS(status);
1177 
1178 	/* Allocate memory to store addr of accel_devs */
1179 	pAdfInsts =
1180 	    malloc(num_accel_dev * sizeof(icp_accel_dev_t *), M_QAT, M_WAITOK);
1181 
1182 	num_accel_dev = 0;
1183 	/* Get ADF to return accel_devs with dc enabled */
1184 	status = icp_amgr_getAllAccelDevByCapabilities(
1185 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, pAdfInsts, &num_accel_dev);
1186 
1187 	if (CPA_STATUS_SUCCESS == status) {
1188 		/* First check the number of instances in the system */
1189 		for (i = 0; i < num_accel_dev; i++) {
1190 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1191 			if (NULL != dev_addr) {
1192 				base_addr = dev_addr->pSalHandle;
1193 				if (NULL != base_addr) {
1194 					list_temp =
1195 					    base_addr->compression_services;
1196 					while (NULL != list_temp) {
1197 						if (index >
1198 						    (numInstances - 1)) {
1199 							break;
1200 						}
1201 
1202 						dcInstances[index] =
1203 						    SalList_getObject(
1204 							list_temp);
1205 						list_temp =
1206 						    SalList_next(list_temp);
1207 						index++;
1208 					}
1209 				}
1210 			}
1211 		}
1212 
1213 		if (numInstances > index) {
1214 			QAT_UTILS_LOG("Only %d dc instances available.\n",
1215 				      index);
1216 			status = CPA_STATUS_RESOURCE;
1217 		}
1218 	}
1219 
1220 	if (CPA_STATUS_SUCCESS == status) {
1221 		index = 0;
1222 		for (i = 0; i < num_accel_dev; i++) {
1223 			dev_addr = (icp_accel_dev_t *)pAdfInsts[i];
1224 			/* Note dev_addr cannot be NULL here as numInstances=0
1225 			   is not valid and if dev_addr=NULL then index=0 (which
1226 			   is less than numInstances and status is set to
1227 			   _RESOURCE
1228 			   above */
1229 			base_addr = dev_addr->pSalHandle;
1230 			if (NULL != base_addr) {
1231 				list_temp = base_addr->compression_services;
1232 				while (NULL != list_temp) {
1233 					if (index > (numInstances - 1)) {
1234 						break;
1235 					}
1236 
1237 					dcInstances[index] =
1238 					    SalList_getObject(list_temp);
1239 					list_temp = SalList_next(list_temp);
1240 					index++;
1241 				}
1242 			}
1243 		}
1244 	}
1245 
1246 	free(pAdfInsts, M_QAT);
1247 
1248 	return status;
1249 }
1250 
1251 CpaStatus
1252 cpaDcInstanceGetInfo2(const CpaInstanceHandle instanceHandle,
1253 		      CpaInstanceInfo2 *pInstanceInfo2)
1254 {
1255 	sal_compression_service_t *pCompressionService = NULL;
1256 	CpaInstanceHandle insHandle = NULL;
1257 	icp_accel_dev_t *dev = NULL;
1258 	CpaStatus status = CPA_STATUS_SUCCESS;
1259 	char keyStr[ADF_CFG_MAX_KEY_LEN_IN_BYTES] = { 0 };
1260 	char valStr[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
1261 	char *section = DYN_SEC;
1262 
1263 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1264 		insHandle = dcGetFirstHandle();
1265 	} else {
1266 		insHandle = instanceHandle;
1267 	}
1268 
1269 	LAC_CHECK_NULL_PARAM(insHandle);
1270 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1271 	LAC_CHECK_NULL_PARAM(pInstanceInfo2);
1272 
1273 	LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
1274 	pInstanceInfo2->accelerationServiceType =
1275 	    CPA_ACC_SVC_TYPE_DATA_COMPRESSION;
1276 
1277 	snprintf((char *)pInstanceInfo2->vendorName,
1278 		 CPA_INST_VENDOR_NAME_SIZE,
1279 		 "%s",
1280 		 SAL_INFO2_VENDOR_NAME);
1281 	pInstanceInfo2->vendorName[CPA_INST_VENDOR_NAME_SIZE - 1] = '\0';
1282 
1283 	snprintf((char *)pInstanceInfo2->swVersion,
1284 		 CPA_INST_SW_VERSION_SIZE,
1285 		 "Version %d.%d",
1286 		 SAL_INFO2_DRIVER_SW_VERSION_MAJ_NUMBER,
1287 		 SAL_INFO2_DRIVER_SW_VERSION_MIN_NUMBER);
1288 	pInstanceInfo2->swVersion[CPA_INST_SW_VERSION_SIZE - 1] = '\0';
1289 
1290 	/* Note we can safely read the contents of the compression service
1291 	   instance
1292 	   here because icp_amgr_getAccelDevByCapabilities() only returns devs
1293 	   that have started */
1294 	pCompressionService = (sal_compression_service_t *)insHandle;
1295 	pInstanceInfo2->physInstId.packageId = pCompressionService->pkgID;
1296 	pInstanceInfo2->physInstId.acceleratorId =
1297 	    pCompressionService->acceleratorNum;
1298 	pInstanceInfo2->physInstId.executionEngineId = 0;
1299 	pInstanceInfo2->physInstId.busAddress =
1300 	    icp_adf_get_busAddress(pInstanceInfo2->physInstId.packageId);
1301 
1302 	/* set coreAffinity to zero before use */
1303 	LAC_OS_BZERO(pInstanceInfo2->coreAffinity,
1304 		     sizeof(pInstanceInfo2->coreAffinity));
1305 	CPA_BITMAP_BIT_SET(pInstanceInfo2->coreAffinity,
1306 			   pCompressionService->coreAffinity);
1307 
1308 	pInstanceInfo2->nodeAffinity = pCompressionService->nodeAffinity;
1309 
1310 	if (CPA_TRUE ==
1311 	    pCompressionService->generic_service_info.isInstanceStarted) {
1312 		pInstanceInfo2->operState = CPA_OPER_STATE_UP;
1313 	} else {
1314 		pInstanceInfo2->operState = CPA_OPER_STATE_DOWN;
1315 	}
1316 
1317 	pInstanceInfo2->requiresPhysicallyContiguousMemory = CPA_TRUE;
1318 
1319 	if (SAL_RESP_POLL_CFG_FILE == pCompressionService->isPolled) {
1320 		pInstanceInfo2->isPolled = CPA_TRUE;
1321 	} else {
1322 		pInstanceInfo2->isPolled = CPA_FALSE;
1323 	}
1324 
1325 	pInstanceInfo2->isOffloaded = CPA_TRUE;
1326 	/* Get the instance name and part name from the config file */
1327 	dev = icp_adf_getAccelDevByAccelId(pCompressionService->pkgID);
1328 	if (NULL == dev) {
1329 		QAT_UTILS_LOG("Can not find device for the instance.\n");
1330 		LAC_OS_BZERO(pInstanceInfo2, sizeof(CpaInstanceInfo2));
1331 		return CPA_STATUS_FAIL;
1332 	}
1333 	snprintf((char *)pInstanceInfo2->partName,
1334 		 CPA_INST_PART_NAME_SIZE,
1335 		 SAL_INFO2_PART_NAME,
1336 		 dev->deviceName);
1337 	pInstanceInfo2->partName[CPA_INST_PART_NAME_SIZE - 1] = '\0';
1338 
1339 	if (CPA_FALSE == pCompressionService->generic_service_info.is_dyn) {
1340 		section = icpGetProcessName();
1341 	}
1342 
1343 	status = Sal_StringParsing(
1344 	    "Dc",
1345 	    pCompressionService->generic_service_info.instance,
1346 	    "Name",
1347 	    keyStr);
1348 	LAC_CHECK_STATUS(status);
1349 	status = icp_adf_cfgGetParamValue(dev, section, keyStr, valStr);
1350 	LAC_CHECK_STATUS(status);
1351 	strncpy((char *)pInstanceInfo2->instName,
1352 		valStr,
1353 		sizeof(pInstanceInfo2->instName) - 1);
1354 	pInstanceInfo2->instName[CPA_INST_NAME_SIZE - 1] = '\0';
1355 
1356 #if __GNUC__ >= 7
1357 #pragma GCC diagnostic push
1358 #pragma GCC diagnostic ignored "-Wformat-truncation"
1359 #endif
1360 	snprintf((char *)pInstanceInfo2->instID,
1361 		 CPA_INST_ID_SIZE,
1362 		 "%s_%s",
1363 		 section,
1364 		 valStr);
1365 #if __GNUC__ >= 7
1366 #pragma GCC diagnostic pop
1367 #endif
1368 
1369 	return CPA_STATUS_SUCCESS;
1370 }
1371 
1372 CpaStatus
1373 cpaDcQueryCapabilities(CpaInstanceHandle dcInstance,
1374 		       CpaDcInstanceCapabilities *pInstanceCapabilities)
1375 {
1376 	CpaInstanceHandle insHandle = NULL;
1377 	sal_compression_service_t *pService = NULL;
1378 	Cpa32U capabilitiesMask = 0;
1379 	dc_extd_ftrs_t *pExtendedFtrs = NULL;
1380 
1381 	if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) {
1382 		insHandle = dcGetFirstHandle();
1383 		if (NULL == insHandle) {
1384 			QAT_UTILS_LOG("Can not get the instance.\n");
1385 			return CPA_STATUS_FAIL;
1386 		}
1387 	} else {
1388 		insHandle = dcInstance;
1389 	}
1390 
1391 	pService = (sal_compression_service_t *)insHandle;
1392 
1393 	LAC_CHECK_NULL_PARAM(insHandle);
1394 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1395 	LAC_CHECK_NULL_PARAM(pInstanceCapabilities);
1396 
1397 	memset(pInstanceCapabilities, 0, sizeof(CpaDcInstanceCapabilities));
1398 
1399 	capabilitiesMask = pService->generic_service_info.capabilitiesMask;
1400 
1401 	/* Set compression capabilities */
1402 	if (capabilitiesMask & ICP_ACCEL_CAPABILITIES_CNV_INTEGRITY) {
1403 		pInstanceCapabilities->integrityCrcs = CPA_TRUE;
1404 	}
1405 
1406 	pInstanceCapabilities->endOfLastBlock = CPA_TRUE;
1407 	pInstanceCapabilities->statefulDeflateCompression = CPA_FALSE;
1408 	pInstanceCapabilities->statefulDeflateDecompression = CPA_TRUE;
1409 	pInstanceCapabilities->statelessDeflateCompression = CPA_TRUE;
1410 	pInstanceCapabilities->statelessDeflateDecompression = CPA_TRUE;
1411 	pInstanceCapabilities->checksumCRC32 = CPA_TRUE;
1412 	pInstanceCapabilities->checksumAdler32 = CPA_TRUE;
1413 	pInstanceCapabilities->dynamicHuffman = CPA_TRUE;
1414 	pInstanceCapabilities->precompiledHuffman = CPA_FALSE;
1415 	pInstanceCapabilities->dynamicHuffmanBufferReq = CPA_TRUE;
1416 	pInstanceCapabilities->autoSelectBestHuffmanTree = CPA_TRUE;
1417 
1418 	pInstanceCapabilities->validWindowSizeMaskCompression =
1419 	    pService->comp_device_data.windowSizeMask;
1420 	pInstanceCapabilities->validWindowSizeMaskDecompression =
1421 	    pService->comp_device_data.windowSizeMask;
1422 	pExtendedFtrs = (dc_extd_ftrs_t *)&(
1423 	    ((sal_service_t *)insHandle)->dcExtendedFeatures);
1424 	pInstanceCapabilities->batchAndPack = CPA_FALSE;
1425 	pInstanceCapabilities->compressAndVerify =
1426 	    (CpaBoolean)pExtendedFtrs->is_cnv;
1427 	pInstanceCapabilities->compressAndVerifyStrict = CPA_TRUE;
1428 	pInstanceCapabilities->compressAndVerifyAndRecover =
1429 	    (CpaBoolean)pExtendedFtrs->is_cnvnr;
1430 	return CPA_STATUS_SUCCESS;
1431 }
1432 
1433 CpaStatus
1434 cpaDcSetAddressTranslation(const CpaInstanceHandle instanceHandle,
1435 			   CpaVirtualToPhysical virtual2Physical)
1436 {
1437 	sal_service_t *pService = NULL;
1438 	CpaInstanceHandle insHandle = NULL;
1439 
1440 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle) {
1441 		insHandle = dcGetFirstHandle();
1442 	} else {
1443 		insHandle = instanceHandle;
1444 	}
1445 
1446 	LAC_CHECK_NULL_PARAM(insHandle);
1447 	SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION);
1448 	LAC_CHECK_NULL_PARAM(virtual2Physical);
1449 
1450 	pService = (sal_service_t *)insHandle;
1451 
1452 	pService->virt2PhysClient = virtual2Physical;
1453 
1454 	return CPA_STATUS_SUCCESS;
1455 }
1456 
1457 /**
1458  ******************************************************************************
1459  * @ingroup cpaDcCommon
1460  * Data compression specific polling function which polls a DC instance.
1461  *****************************************************************************/
1462 
1463 CpaStatus
1464 icp_sal_DcPollInstance(CpaInstanceHandle instanceHandle_in,
1465 		       Cpa32U response_quota)
1466 {
1467 	CpaStatus status = CPA_STATUS_SUCCESS;
1468 	sal_compression_service_t *dc_handle = NULL;
1469 	sal_service_t *gen_handle = NULL;
1470 	icp_comms_trans_handle trans_hndTable[DC_NUM_RX_RINGS];
1471 
1472 	if (CPA_INSTANCE_HANDLE_SINGLE == instanceHandle_in) {
1473 		dc_handle = (sal_compression_service_t *)dcGetFirstHandle();
1474 	} else {
1475 		dc_handle = (sal_compression_service_t *)instanceHandle_in;
1476 	}
1477 
1478 	LAC_CHECK_NULL_PARAM(dc_handle);
1479 	SAL_RUNNING_CHECK(dc_handle);
1480 
1481 	gen_handle = &(dc_handle->generic_service_info);
1482 	if (SAL_SERVICE_TYPE_COMPRESSION != gen_handle->type) {
1483 		QAT_UTILS_LOG("Instance handle type is incorrect.\n");
1484 		return CPA_STATUS_FAIL;
1485 	}
1486 
1487 	/*
1488 	 * From the instanceHandle we must get the trans_handle and send
1489 	 * down to adf for polling.
1490 	 * Populate our trans handle table with the appropriate handles.
1491 	 */
1492 	trans_hndTable[0] = dc_handle->trans_handle_compression_rx;
1493 
1494 	/* Call adf to do the polling. */
1495 	status = icp_adf_pollInstance(trans_hndTable,
1496 				      DC_NUM_RX_RINGS,
1497 				      response_quota);
1498 	return status;
1499 }
1500 
1501 /**
1502  ******************************************************************************
1503  * @ingroup cpaDcCommon
1504  *****************************************************************************/
1505 CpaStatus
1506 cpaDcInstanceSetNotificationCb(
1507     const CpaInstanceHandle instanceHandle,
1508     const CpaDcInstanceNotificationCbFunc pInstanceNotificationCb,
1509     void *pCallbackTag)
1510 {
1511 	CpaStatus status = CPA_STATUS_SUCCESS;
1512 	sal_service_t *gen_handle = instanceHandle;
1513 
1514 	LAC_CHECK_NULL_PARAM(gen_handle);
1515 	gen_handle->notification_cb = pInstanceNotificationCb;
1516 	gen_handle->cb_tag = pCallbackTag;
1517 	return status;
1518 }
1519 
1520 CpaInstanceHandle
1521 dcGetFirstHandle(void)
1522 {
1523 	CpaStatus status = CPA_STATUS_SUCCESS;
1524 	static icp_accel_dev_t *adfInsts[ADF_MAX_DEVICES] = { 0 };
1525 	CpaInstanceHandle dcInst = NULL;
1526 	icp_accel_dev_t *dev_addr = NULL;
1527 	sal_t *base_addr = NULL;
1528 	sal_list_t *list_temp = NULL;
1529 	Cpa16U i, num_dc = 0;
1530 
1531 	/* Only need 1 dev with compression enabled - so check all devices */
1532 	status = icp_amgr_getAllAccelDevByCapabilities(
1533 	    ICP_ACCEL_CAPABILITIES_COMPRESSION, adfInsts, &num_dc);
1534 	if ((0 == num_dc) || (CPA_STATUS_SUCCESS != status)) {
1535 		QAT_UTILS_LOG(
1536 		    "No compression devices enabled in the system.\n");
1537 		return dcInst;
1538 	}
1539 
1540 	for (i = 0; i < num_dc; i++) {
1541 		dev_addr = (icp_accel_dev_t *)adfInsts[i];
1542 		if (NULL != dev_addr) {
1543 			base_addr = dev_addr->pSalHandle;
1544 			if (NULL != base_addr) {
1545 				list_temp = base_addr->compression_services;
1546 				if (NULL != list_temp) {
1547 					dcInst = SalList_getObject(list_temp);
1548 					break;
1549 				}
1550 			}
1551 		}
1552 	}
1553 	return dcInst;
1554 }
1555