1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 
5 /**
6  ***************************************************************************
7  * @file lac_sym_dp.c
8  *    Implementation of the symmetric data plane API
9  *
10  * @ingroup cpaCySymDp
11  ***************************************************************************/
12 
13 /*
14 *******************************************************************************
15 * Include public/global header files
16 *******************************************************************************
17 */
18 
19 #include "cpa.h"
20 #include "cpa_cy_sym.h"
21 #include "cpa_cy_sym_dp.h"
22 
23 /*
24 *******************************************************************************
25 * Include private header files
26 *******************************************************************************
27 */
28 
29 #include "icp_accel_devices.h"
30 #include "icp_adf_init.h"
31 #include "icp_adf_transport.h"
32 #include "icp_adf_transport_dp.h"
33 #include "icp_adf_debug.h"
34 #include "icp_sal_poll.h"
35 
36 #include "qat_utils.h"
37 
38 #include "lac_mem.h"
39 #include "lac_log.h"
40 #include "lac_sym.h"
41 #include "lac_sym_qat_cipher.h"
42 #include "lac_list.h"
43 #include "lac_sal_types_crypto.h"
44 #include "sal_service_state.h"
45 #include "lac_sym_auth_enc.h"
46 
47 typedef void (*write_ringMsgFunc_t)(CpaCySymDpOpData *pRequest,
48 				    icp_qat_fw_la_bulk_req_t *pCurrentQatMsg);
49 
50 /**
51  *****************************************************************************
52  * @ingroup cpaCySymDp
53  *      Check that the operation data is valid
54  *
55  * @description
56  *      Check that all the parameters defined in the operation data are valid
57  *
58  * @param[in]       pRequest         Pointer to an operation data for crypto
59  *                                   data plane API
60  *
61  * @retval CPA_STATUS_SUCCESS        Function executed successfully
62  * @retval CPA_STATUS_INVALID_PARAM  Invalid parameter passed in
63  *
64  *****************************************************************************/
65 static CpaStatus
66 LacDp_EnqueueParamCheck(const CpaCySymDpOpData *pRequest)
67 {
68 	lac_session_desc_t *pSessionDesc = NULL;
69 	CpaCySymCipherAlgorithm cipher = 0;
70 	CpaCySymHashAlgorithm hash = 0;
71 	Cpa32U capabilitiesMask = 0;
72 
73 	LAC_CHECK_NULL_PARAM(pRequest);
74 	LAC_CHECK_NULL_PARAM(pRequest->instanceHandle);
75 	LAC_CHECK_NULL_PARAM(pRequest->sessionCtx);
76 
77 	/* Ensure this is a crypto instance */
78 	SAL_CHECK_INSTANCE_TYPE(pRequest->instanceHandle,
79 				(SAL_SERVICE_TYPE_CRYPTO |
80 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
81 
82 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
83 	if (NULL == pSessionDesc) {
84 		do {
85 			qatUtilsSleep(500);
86 			pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(
87 			    pRequest->sessionCtx);
88 		} while (NULL == pSessionDesc);
89 	}
90 	if (NULL == pSessionDesc) {
91 		LAC_INVALID_PARAM_LOG("Session context not as expected");
92 		return CPA_STATUS_INVALID_PARAM;
93 	}
94 
95 	if (CPA_FALSE == pSessionDesc->isDPSession) {
96 		LAC_INVALID_PARAM_LOG(
97 		    "Session not initialised for data plane API");
98 		return CPA_STATUS_INVALID_PARAM;
99 	}
100 
101 	/*check whether Payload size is zero for CHACHA-POLY */
102 	if ((CPA_CY_SYM_CIPHER_CHACHA == pSessionDesc->cipherAlgorithm) &&
103 	    (CPA_CY_SYM_HASH_POLY == pSessionDesc->hashAlgorithm) &&
104 	    (CPA_CY_SYM_OP_ALGORITHM_CHAINING == pSessionDesc->symOperation)) {
105 		if (!pRequest->messageLenToCipherInBytes) {
106 			LAC_INVALID_PARAM_LOG(
107 			    "Invalid messageLenToCipherInBytes for CHACHA-POLY");
108 			return CPA_STATUS_INVALID_PARAM;
109 		}
110 	}
111 
112 	if (0 == pRequest->srcBuffer) {
113 		LAC_INVALID_PARAM_LOG("Invalid srcBuffer");
114 		return CPA_STATUS_INVALID_PARAM;
115 	}
116 	if (0 == pRequest->dstBuffer) {
117 		LAC_INVALID_PARAM_LOG("Invalid destBuffer");
118 		return CPA_STATUS_INVALID_PARAM;
119 	}
120 	if (0 == pRequest->thisPhys) {
121 		LAC_INVALID_PARAM_LOG("Invalid thisPhys");
122 		return CPA_STATUS_INVALID_PARAM;
123 	}
124 
125 	/* Check that src buffer Len = dst buffer Len
126 	Note this also checks that they are of the same type */
127 	if (pRequest->srcBufferLen != pRequest->dstBufferLen) {
128 		LAC_INVALID_PARAM_LOG(
129 		    "Source and Destination buffer lengths need to be equal");
130 		return CPA_STATUS_INVALID_PARAM;
131 	}
132 
133 	/* digestVerify and digestIsAppended on Hash-Only operation not
134 	 * supported */
135 	if (pSessionDesc->digestIsAppended && pSessionDesc->digestVerify &&
136 	    (CPA_CY_SYM_OP_HASH == pSessionDesc->symOperation)) {
137 		LAC_INVALID_PARAM_LOG(
138 		    "digestVerify and digestIsAppended set "
139 		    "on Hash-Only operation is not supported");
140 		return CPA_STATUS_INVALID_PARAM;
141 	}
142 
143 	/* Cipher specific tests */
144 	if (CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) {
145 		/* Perform IV check */
146 		if ((LAC_CIPHER_IS_CTR_MODE(pSessionDesc->cipherAlgorithm) ||
147 		     LAC_CIPHER_IS_CBC_MODE(pSessionDesc->cipherAlgorithm) ||
148 		     LAC_CIPHER_IS_AES_F8(pSessionDesc->cipherAlgorithm)) &&
149 		    (!(LAC_CIPHER_IS_CCM(pSessionDesc->cipherAlgorithm)))) {
150 			Cpa32U ivLenInBytes = LacSymQat_CipherIvSizeBytesGet(
151 			    pSessionDesc->cipherAlgorithm);
152 			if (pRequest->ivLenInBytes != ivLenInBytes) {
153 				if (!(/* GCM with 12 byte IV is OK */
154 				      (LAC_CIPHER_IS_GCM(
155 					   pSessionDesc->cipherAlgorithm) &&
156 				       pRequest->ivLenInBytes ==
157 					   LAC_CIPHER_IV_SIZE_GCM_12))) {
158 					LAC_INVALID_PARAM_LOG(
159 					    "invalid cipher IV size");
160 					return CPA_STATUS_INVALID_PARAM;
161 				}
162 			}
163 			if (0 == pRequest->iv) {
164 				LAC_INVALID_PARAM_LOG("invalid iv of 0");
165 				return CPA_STATUS_INVALID_PARAM;
166 			}
167 
168 			/* pRequest->pIv is only used for CCM so is not checked
169 			 * here */
170 		} else if (LAC_CIPHER_IS_KASUMI(
171 			       pSessionDesc->cipherAlgorithm)) {
172 			if (LAC_CIPHER_KASUMI_F8_IV_LENGTH !=
173 			    pRequest->ivLenInBytes) {
174 				LAC_INVALID_PARAM_LOG("invalid cipher IV size");
175 				return CPA_STATUS_INVALID_PARAM;
176 			}
177 			if (0 == pRequest->iv) {
178 				LAC_INVALID_PARAM_LOG("invalid iv of 0");
179 				return CPA_STATUS_INVALID_PARAM;
180 			}
181 		} else if (LAC_CIPHER_IS_SNOW3G_UEA2(
182 			       pSessionDesc->cipherAlgorithm)) {
183 			if (ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ !=
184 			    pRequest->ivLenInBytes) {
185 				LAC_INVALID_PARAM_LOG("invalid cipher IV size");
186 				return CPA_STATUS_INVALID_PARAM;
187 			}
188 			if (0 == pRequest->iv) {
189 				LAC_INVALID_PARAM_LOG("invalid iv of 0");
190 				return CPA_STATUS_INVALID_PARAM;
191 			}
192 		} else if (LAC_CIPHER_IS_ZUC_EEA3(
193 			       pSessionDesc->cipherAlgorithm)) {
194 			if (ICP_QAT_HW_ZUC_3G_EEA3_IV_SZ !=
195 			    pRequest->ivLenInBytes) {
196 				LAC_INVALID_PARAM_LOG("invalid cipher IV size");
197 				return CPA_STATUS_INVALID_PARAM;
198 			}
199 			if (0 == pRequest->iv) {
200 				LAC_INVALID_PARAM_LOG("invalid iv of 0");
201 				return CPA_STATUS_INVALID_PARAM;
202 			}
203 		} else if (LAC_CIPHER_IS_CCM(pSessionDesc->cipherAlgorithm)) {
204 			if (CPA_STATUS_SUCCESS !=
205 			    LacSymAlgChain_CheckCCMData(
206 				pRequest->pAdditionalAuthData,
207 				pRequest->pIv,
208 				pRequest->messageLenToCipherInBytes,
209 				pRequest->ivLenInBytes)) {
210 				return CPA_STATUS_INVALID_PARAM;
211 			}
212 		}
213 
214 		/* Perform algorithm-specific checks */
215 		if (!(LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm) ||
216 		      LAC_CIPHER_IS_CTR_MODE(pSessionDesc->cipherAlgorithm) ||
217 		      LAC_CIPHER_IS_F8_MODE(pSessionDesc->cipherAlgorithm) ||
218 		      LAC_CIPHER_IS_SNOW3G_UEA2(
219 			  pSessionDesc->cipherAlgorithm) ||
220 		      LAC_CIPHER_IS_ZUC_EEA3(pSessionDesc->cipherAlgorithm))) {
221 			/* Mask & check below is based on assumption that block
222 			 * size is
223 			 * a power of 2. If data size is not a multiple of the
224 			 * block size,
225 			 * the "remainder" bits selected by the mask be non-zero
226 			 */
227 			if (pRequest->messageLenToCipherInBytes &
228 			    (LacSymQat_CipherBlockSizeBytesGet(
229 				 pSessionDesc->cipherAlgorithm) -
230 			     1)) {
231 				LAC_INVALID_PARAM_LOG(
232 				    "Data size must be block size multiple");
233 				return CPA_STATUS_INVALID_PARAM;
234 			}
235 		}
236 
237 		cipher = pSessionDesc->cipherAlgorithm;
238 		hash = pSessionDesc->hashAlgorithm;
239 		capabilitiesMask =
240 		    ((sal_crypto_service_t *)pRequest->instanceHandle)
241 			->generic_service_info.capabilitiesMask;
242 		if (LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
243 		    (LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes)) {
244 			/* For CHACHA and AES_GCM single pass there is an AAD
245 			 * buffer
246 			 * if aadLenInBytes is nonzero. AES_GMAC AAD is stored
247 			 * in
248 			 * source buffer, therefore there is no separate AAD
249 			 * buffer. */
250 			if ((0 != pSessionDesc->aadLenInBytes) &&
251 			    (CPA_CY_SYM_HASH_AES_GMAC !=
252 			     pSessionDesc->hashAlgorithm)) {
253 				LAC_CHECK_NULL_PARAM(
254 				    pRequest->pAdditionalAuthData);
255 			}
256 
257 			/* Ensure AAD length for AES_GMAC spc */
258 			if ((CPA_CY_SYM_HASH_AES_GMAC == hash) &&
259 			    (ICP_QAT_FW_SPC_AAD_SZ_MAX <
260 			     pRequest->messageLenToHashInBytes)) {
261 				LAC_INVALID_PARAM_LOG(
262 				    "aadLenInBytes for AES_GMAC");
263 				return CPA_STATUS_INVALID_PARAM;
264 			}
265 		}
266 	}
267 
268 	/* Hash specific tests */
269 	if (CPA_CY_SYM_OP_CIPHER != pSessionDesc->symOperation) {
270 		/* For CCM, snow3G and ZUC there is always an AAD buffer
271 		   For GCM there is an AAD buffer if aadLenInBytes is
272 		   nonzero */
273 		if ((CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) ||
274 		    (CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm &&
275 		     (0 != pSessionDesc->aadLenInBytes))) {
276 			LAC_CHECK_NULL_PARAM(pRequest->pAdditionalAuthData);
277 			if (0 == pRequest->additionalAuthData) {
278 				LAC_INVALID_PARAM_LOG(
279 				    "Invalid additionalAuthData");
280 				return CPA_STATUS_INVALID_PARAM;
281 			}
282 		} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
283 			       pSessionDesc->hashAlgorithm ||
284 			   CPA_CY_SYM_HASH_ZUC_EIA3 ==
285 			       pSessionDesc->hashAlgorithm) {
286 			if (0 == pRequest->additionalAuthData) {
287 				LAC_INVALID_PARAM_LOG(
288 				    "Invalid additionalAuthData");
289 				return CPA_STATUS_INVALID_PARAM;
290 			}
291 		}
292 
293 		if ((CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm) &&
294 		    (!pSessionDesc->digestIsAppended) &&
295 		    (0 == pRequest->digestResult)) {
296 			LAC_INVALID_PARAM_LOG("Invalid digestResult");
297 			return CPA_STATUS_INVALID_PARAM;
298 		}
299 
300 		if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm) {
301 			if ((pRequest->cryptoStartSrcOffsetInBytes +
302 			     pRequest->messageLenToCipherInBytes +
303 			     pSessionDesc->hashResultSize) >
304 			    pRequest->dstBufferLen) {
305 				LAC_INVALID_PARAM_LOG(
306 				    "CCM - Not enough room for"
307 				    " digest in destination buffer");
308 				return CPA_STATUS_INVALID_PARAM;
309 			}
310 		} else if (CPA_TRUE == pSessionDesc->digestIsAppended) {
311 			if (CPA_CY_SYM_HASH_AES_GMAC ==
312 			    pSessionDesc->hashAlgorithm) {
313 				if ((pRequest->hashStartSrcOffsetInBytes +
314 				     pRequest->messageLenToHashInBytes +
315 				     pSessionDesc->hashResultSize) >
316 				    pRequest->dstBufferLen) {
317 					LAC_INVALID_PARAM_LOG(
318 					    "Append Digest - Not enough room for"
319 					    " digest in destination buffer for "
320 					    "AES GMAC algorithm");
321 					return CPA_STATUS_INVALID_PARAM;
322 				}
323 			}
324 			if (CPA_CY_SYM_HASH_AES_GCM ==
325 			    pSessionDesc->hashAlgorithm) {
326 				if ((pRequest->cryptoStartSrcOffsetInBytes +
327 				     pRequest->messageLenToCipherInBytes +
328 				     pSessionDesc->hashResultSize) >
329 				    pRequest->dstBufferLen) {
330 					LAC_INVALID_PARAM_LOG(
331 					    "Append Digest - Not enough room "
332 					    "for digest in destination buffer"
333 					    " for GCM algorithm");
334 					return CPA_STATUS_INVALID_PARAM;
335 				}
336 			}
337 
338 			if ((pRequest->hashStartSrcOffsetInBytes +
339 			     pRequest->messageLenToHashInBytes +
340 			     pSessionDesc->hashResultSize) >
341 			    pRequest->dstBufferLen) {
342 				LAC_INVALID_PARAM_LOG(
343 				    "Append Digest - Not enough room for"
344 				    " digest in destination buffer");
345 				return CPA_STATUS_INVALID_PARAM;
346 			}
347 		}
348 		if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
349 			if (pRequest->messageLenToHashInBytes == 0 ||
350 			    pRequest->pAdditionalAuthData != NULL) {
351 				LAC_INVALID_PARAM_LOG(
352 				    "For AES_GMAC, AAD Length "
353 				    "(messageLenToHashInBytes) must be "
354 				    "non zero and pAdditionalAuthData "
355 				    "must be NULL");
356 				return CPA_STATUS_INVALID_PARAM;
357 			}
358 		}
359 	}
360 
361 	if (CPA_DP_BUFLIST != pRequest->srcBufferLen) {
362 		if ((CPA_CY_SYM_OP_HASH != pSessionDesc->symOperation) &&
363 		    ((pRequest->messageLenToCipherInBytes +
364 		      pRequest->cryptoStartSrcOffsetInBytes) >
365 		     pRequest->srcBufferLen)) {
366 			LAC_INVALID_PARAM_LOG(
367 			    "cipher len + offset greater than "
368 			    "srcBufferLen");
369 			return CPA_STATUS_INVALID_PARAM;
370 		} else if ((CPA_CY_SYM_OP_CIPHER !=
371 			    pSessionDesc->symOperation) &&
372 			   (CPA_CY_SYM_HASH_AES_CCM !=
373 			    pSessionDesc->hashAlgorithm) &&
374 			   (CPA_CY_SYM_HASH_AES_GCM !=
375 			    pSessionDesc->hashAlgorithm) &&
376 			   (CPA_CY_SYM_HASH_AES_GMAC !=
377 			    pSessionDesc->hashAlgorithm) &&
378 			   ((pRequest->messageLenToHashInBytes +
379 			     pRequest->hashStartSrcOffsetInBytes) >
380 			    pRequest->srcBufferLen)) {
381 			LAC_INVALID_PARAM_LOG(
382 			    "hash len + offset greater than srcBufferLen");
383 			return CPA_STATUS_INVALID_PARAM;
384 		}
385 	} else {
386 		LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->srcBuffer);
387 		LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->dstBuffer);
388 	}
389 
390 	LAC_CHECK_8_BYTE_ALIGNMENT(pRequest->thisPhys);
391 
392 	return CPA_STATUS_SUCCESS;
393 }
394 
395 /**
396  *****************************************************************************
397  * @ingroup cpaCySymDp
398  *      Write Message on the ring and write request params
399  *      This is the optimized version, which should not be used for
400  *      algorithm of CCM, GCM and RC4
401  *
402  * @description
403  *      Write Message on the ring and write request params
404  *
405  * @param[in/out]    pRequest       Pointer to operation data for crypto
406  *                                  data plane API
407  * @param[in/out]    pCurrentQatMsg Pointer to ring memory where msg will
408  *                                  be written
409  *
410  * @retval none
411  *
412  *****************************************************************************/
413 
414 void
415 LacDp_WriteRingMsgOpt(CpaCySymDpOpData *pRequest,
416 		      icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
417 {
418 	lac_session_desc_t *pSessionDesc =
419 	    LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
420 	Cpa8U *pMsgDummy = NULL;
421 	Cpa8U *pCacheDummyHdr = NULL;
422 	Cpa8U *pCacheDummyFtr = NULL;
423 
424 	pMsgDummy = (Cpa8U *)pCurrentQatMsg;
425 	/* Write Request */
426 	/*
427 	 * Fill in the header and footer bytes of the ET ring message - cached
428 	 * from
429 	 * the session descriptor.
430 	 */
431 	pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
432 	pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
433 
434 	memcpy(pMsgDummy,
435 	       pCacheDummyHdr,
436 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
437 	memset((pMsgDummy +
438 		(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
439 	       0,
440 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
441 	memcpy(pMsgDummy +
442 		   (LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
443 	       pCacheDummyFtr,
444 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
445 
446 	SalQatMsg_CmnMidWrite(pCurrentQatMsg,
447 			      pRequest,
448 			      (CPA_DP_BUFLIST == pRequest->srcBufferLen ?
449 				   QAT_COMN_PTR_TYPE_SGL :
450 				   QAT_COMN_PTR_TYPE_FLAT),
451 			      pRequest->srcBuffer,
452 			      pRequest->dstBuffer,
453 			      pRequest->srcBufferLen,
454 			      pRequest->dstBufferLen);
455 
456 	/* Write Request Params */
457 	if (pSessionDesc->isCipher) {
458 
459 		LacSymQat_CipherRequestParamsPopulate(
460 		    pCurrentQatMsg,
461 		    pRequest->cryptoStartSrcOffsetInBytes,
462 		    pRequest->messageLenToCipherInBytes,
463 		    pRequest->iv,
464 		    pRequest->pIv);
465 	}
466 
467 	if (pSessionDesc->isAuth) {
468 		lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
469 		    &(pSessionDesc->hashStateBufferInfo);
470 		icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
471 		    (icp_qat_fw_la_auth_req_params_t
472 			 *)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
473 			    ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
474 
475 		if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
476 			 pSessionDesc->hashAlgorithm &&
477 		     CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
478 		     CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
479 		     CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
480 		     CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
481 		    (pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
482 			/* prefixAadSzQuadWords > 0 when there is prefix data
483 		       - i.e. nested hash or HMAC no precompute cases
484 		       Note partials not supported on DP api so we do not need
485 		       dynamic hash state in this case */
486 			pRequest->additionalAuthData =
487 			    pHashStateBufferInfo->pDataPhys +
488 			    LAC_QUADWORDS_TO_BYTES(
489 				pHashStateBufferInfo->stateStorageSzQuadWords);
490 		}
491 
492 		/* The first 24 bytes in icp_qat_fw_la_auth_req_params_t can be
493 		 * copied directly from the op request data because they share a
494 		 * corresponding layout.  The remaining 4 bytes are taken
495 		 * from the session message template and use values
496 		 * preconfigured at
497 		 * sessionInit (updated per request for some specific cases
498 		 * below)
499 		 */
500 		memcpy(pAuthReqPars,
501 		       (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
502 		       ((unsigned long)&(pAuthReqPars->u2.inner_prefix_sz) -
503 			(unsigned long)pAuthReqPars));
504 
505 		if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
506 			pAuthReqPars->hash_state_sz =
507 			    LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
508 		} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
509 			       pSessionDesc->hashAlgorithm ||
510 			   CPA_CY_SYM_HASH_ZUC_EIA3 ==
511 			       pSessionDesc->hashAlgorithm) {
512 			pAuthReqPars->hash_state_sz =
513 			    LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
514 		}
515 	}
516 
517 }
518 
519 /**
520  *****************************************************************************
521  * @ingroup cpaCySymDp
522  *      Write Message on the ring and write request params
523  *
524  * @description
525  *      Write Message on the ring and write request params
526  *
527  * @param[in/out]    pRequest       Pointer to operation data for crypto
528  *                                  data plane API
529  * @param[in/out]    pCurrentQatMsg Pointer to ring memory where msg will
530  *                                  be written
531  *
532  * @retval none
533  *
534  *****************************************************************************/
535 
536 void
537 LacDp_WriteRingMsgFull(CpaCySymDpOpData *pRequest,
538 		       icp_qat_fw_la_bulk_req_t *pCurrentQatMsg)
539 {
540 	lac_session_desc_t *pSessionDesc =
541 	    LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
542 	Cpa8U *pMsgDummy = NULL;
543 	Cpa8U *pCacheDummyHdr = NULL;
544 	Cpa8U *pCacheDummyFtr = NULL;
545 	sal_qat_content_desc_info_t *pCdInfo = NULL;
546 	Cpa8U *pHwBlockBaseInDRAM = NULL;
547 	Cpa32U hwBlockOffsetInDRAM = 0;
548 	Cpa32U sizeInBytes = 0;
549 	CpaCySymCipherAlgorithm cipher = pSessionDesc->cipherAlgorithm;
550 	CpaCySymHashAlgorithm hash = pSessionDesc->hashAlgorithm;
551 	Cpa32U capabilitiesMask =
552 	    ((sal_crypto_service_t *)pRequest->instanceHandle)
553 		->generic_service_info.capabilitiesMask;
554 
555 	Cpa8U paddingLen = 0;
556 	Cpa8U blockLen = 0;
557 
558 	pMsgDummy = (Cpa8U *)pCurrentQatMsg;
559 	/* Write Request */
560 	/*
561 	 * Fill in the header and footer bytes of the ET ring message - cached
562 	 * from
563 	 * the session descriptor.
564 	 */
565 
566 	if (!pSessionDesc->isSinglePass &&
567 	    LAC_CIPHER_IS_SPC(cipher, hash, capabilitiesMask) &&
568 	    (LAC_CIPHER_SPC_IV_SIZE == pRequest->ivLenInBytes)) {
569 		pSessionDesc->isSinglePass = CPA_TRUE;
570 		pSessionDesc->isCipher = CPA_TRUE;
571 		pSessionDesc->isAuthEncryptOp = CPA_FALSE;
572 		pSessionDesc->isAuth = CPA_FALSE;
573 		pSessionDesc->symOperation = CPA_CY_SYM_OP_CIPHER;
574 		pSessionDesc->laCmdId = ICP_QAT_FW_LA_CMD_CIPHER;
575 		if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
576 			pSessionDesc->aadLenInBytes =
577 			    pRequest->messageLenToHashInBytes;
578 		}
579 		/* New bit position (13) for SINGLE PASS.
580 		 * The FW provides a specific macro to use to set the proto flag
581 		 */
582 		ICP_QAT_FW_LA_SINGLE_PASS_PROTO_FLAG_SET(
583 		    pSessionDesc->laCmdFlags, ICP_QAT_FW_LA_SINGLE_PASS_PROTO);
584 		ICP_QAT_FW_LA_PROTO_SET(pSessionDesc->laCmdFlags, 0);
585 
586 		pCdInfo = &(pSessionDesc->contentDescInfo);
587 		pHwBlockBaseInDRAM = (Cpa8U *)pCdInfo->pData;
588 		if (CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT ==
589 		    pSessionDesc->cipherDirection) {
590 			if (LAC_CIPHER_IS_GCM(cipher))
591 				hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
592 				    LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_GCM_SPC);
593 			else
594 				hwBlockOffsetInDRAM = LAC_QUADWORDS_TO_BYTES(
595 				    LAC_SYM_QAT_CIPHER_OFFSET_IN_DRAM_CHACHA_SPC);
596 		}
597 		/* construct cipherConfig in CD in DRAM */
598 		LacSymQat_CipherHwBlockPopulateCfgData(pSessionDesc,
599 						       pHwBlockBaseInDRAM +
600 							   hwBlockOffsetInDRAM,
601 						       &sizeInBytes);
602 		SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)&(
603 					  pSessionDesc->reqSpcCacheHdr),
604 				      ICP_QAT_FW_COMN_REQ_CPM_FW_LA,
605 				      pSessionDesc->laCmdId,
606 				      pSessionDesc->cmnRequestFlags,
607 				      pSessionDesc->laCmdFlags);
608 	} else if (CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm) {
609 		pSessionDesc->aadLenInBytes = pRequest->messageLenToHashInBytes;
610 	}
611 	if (pSessionDesc->isSinglePass) {
612 		pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqSpcCacheHdr);
613 		pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqSpcCacheFtr);
614 	} else {
615 		if (!pSessionDesc->useSymConstantsTable) {
616 			pCacheDummyHdr = (Cpa8U *)&(pSessionDesc->reqCacheHdr);
617 			pCacheDummyFtr = (Cpa8U *)&(pSessionDesc->reqCacheFtr);
618 		} else {
619 			pCacheDummyHdr =
620 			    (Cpa8U *)&(pSessionDesc->shramReqCacheHdr);
621 			pCacheDummyFtr =
622 			    (Cpa8U *)&(pSessionDesc->shramReqCacheFtr);
623 		}
624 	}
625 	memcpy(pMsgDummy,
626 	       pCacheDummyHdr,
627 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW));
628 	memset((pMsgDummy +
629 		(LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_HDR_IN_LW)),
630 	       0,
631 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_TO_CLEAR_IN_LW));
632 	memcpy(pMsgDummy +
633 		   (LAC_LONG_WORD_IN_BYTES * LAC_START_OF_CACHE_FTR_IN_LW),
634 	       pCacheDummyFtr,
635 	       (LAC_LONG_WORD_IN_BYTES * LAC_SIZE_OF_CACHE_FTR_IN_LW));
636 
637 	SalQatMsg_CmnMidWrite(pCurrentQatMsg,
638 			      pRequest,
639 			      (CPA_DP_BUFLIST == pRequest->srcBufferLen ?
640 				   QAT_COMN_PTR_TYPE_SGL :
641 				   QAT_COMN_PTR_TYPE_FLAT),
642 			      pRequest->srcBuffer,
643 			      pRequest->dstBuffer,
644 			      pRequest->srcBufferLen,
645 			      pRequest->dstBufferLen);
646 
647 	if (CPA_CY_SYM_HASH_AES_CCM == pSessionDesc->hashAlgorithm &&
648 	    pSessionDesc->isAuth == CPA_TRUE) {
649 		/* prepare IV and AAD for CCM */
650 		LacSymAlgChain_PrepareCCMData(
651 		    pSessionDesc,
652 		    pRequest->pAdditionalAuthData,
653 		    pRequest->pIv,
654 		    pRequest->messageLenToCipherInBytes,
655 		    pRequest->ivLenInBytes);
656 
657 		/* According to the API, for CCM and GCM,
658 		 * messageLenToHashInBytes
659 		 * and hashStartSrcOffsetInBytes are not initialized by the
660 		 * user and must be set by the driver
661 		 */
662 		pRequest->hashStartSrcOffsetInBytes =
663 		    pRequest->cryptoStartSrcOffsetInBytes;
664 		pRequest->messageLenToHashInBytes =
665 		    pRequest->messageLenToCipherInBytes;
666 	} else if (!pSessionDesc->isSinglePass &&
667 		   (CPA_CY_SYM_HASH_AES_GCM == pSessionDesc->hashAlgorithm ||
668 		    CPA_CY_SYM_HASH_AES_GMAC == pSessionDesc->hashAlgorithm)) {
669 		/* GCM case */
670 		if (CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm) {
671 			/* According to the API, for CCM and GCM,
672 			 * messageLenToHashInBytes and hashStartSrcOffsetInBytes
673 			 * are not initialized by the user and must be set
674 			 * by the driver
675 			 */
676 			pRequest->hashStartSrcOffsetInBytes =
677 			    pRequest->cryptoStartSrcOffsetInBytes;
678 			pRequest->messageLenToHashInBytes =
679 			    pRequest->messageLenToCipherInBytes;
680 
681 			LacSymAlgChain_PrepareGCMData(
682 			    pSessionDesc, pRequest->pAdditionalAuthData);
683 		}
684 
685 		if (LAC_CIPHER_IV_SIZE_GCM_12 == pRequest->ivLenInBytes) {
686 			ICP_QAT_FW_LA_GCM_IV_LEN_FLAG_SET(
687 			    pCurrentQatMsg->comn_hdr.serv_specif_flags,
688 			    ICP_QAT_FW_LA_GCM_IV_LEN_12_OCTETS);
689 		}
690 	}
691 
692 	/* Write Request Params */
693 	if (pSessionDesc->isCipher) {
694 		if (CPA_CY_SYM_CIPHER_ARC4 == pSessionDesc->cipherAlgorithm) {
695 			/* ARC4 does not have an IV but the field is used to
696 			 * store the
697 			 * initial state */
698 			pRequest->iv =
699 			    pSessionDesc->cipherARC4InitialStatePhysAddr;
700 		}
701 
702 		LacSymQat_CipherRequestParamsPopulate(
703 		    pCurrentQatMsg,
704 		    pRequest->cryptoStartSrcOffsetInBytes,
705 		    pRequest->messageLenToCipherInBytes,
706 		    pRequest->iv,
707 		    pRequest->pIv);
708 		if (pSessionDesc->isSinglePass) {
709 			icp_qat_fw_la_cipher_req_params_t *pCipherReqParams =
710 			    (icp_qat_fw_la_cipher_req_params_t
711 				 *)((Cpa8U *)&(
712 					pCurrentQatMsg->serv_specif_rqpars) +
713 				    ICP_QAT_FW_CIPHER_REQUEST_PARAMETERS_OFFSET);
714 
715 			pCipherReqParams->spc_aad_addr =
716 			    (uint64_t)pRequest->additionalAuthData;
717 			pCipherReqParams->spc_aad_sz =
718 			    pSessionDesc->aadLenInBytes;
719 
720 			pCipherReqParams->spc_auth_res_addr =
721 			    (uint64_t)pRequest->digestResult;
722 			pCipherReqParams->spc_auth_res_sz =
723 			    pSessionDesc->hashResultSize;
724 
725 			/* For CHACHA and AES_GCM single pass AAD buffer needs
726 			 * alignment
727 			 * if aadLenInBytes is nonzero.
728 			 * In case of AES-GMAC, AAD buffer passed in the src
729 			 * buffer.
730 			 */
731 			if (0 != pSessionDesc->aadLenInBytes &&
732 			    CPA_CY_SYM_HASH_AES_GMAC !=
733 				pSessionDesc->hashAlgorithm) {
734 				blockLen = LacSymQat_CipherBlockSizeBytesGet(
735 				    pSessionDesc->cipherAlgorithm);
736 				if ((pSessionDesc->aadLenInBytes % blockLen) !=
737 				    0) {
738 					paddingLen = blockLen -
739 					    (pSessionDesc->aadLenInBytes %
740 					     blockLen);
741 					memset(
742 					    &pRequest->pAdditionalAuthData
743 						 [pSessionDesc->aadLenInBytes],
744 					    0,
745 					    paddingLen);
746 				}
747 			}
748 		}
749 	}
750 
751 	if (pSessionDesc->isAuth) {
752 		lac_sym_qat_hash_state_buffer_info_t *pHashStateBufferInfo =
753 		    &(pSessionDesc->hashStateBufferInfo);
754 		icp_qat_fw_la_auth_req_params_t *pAuthReqPars =
755 		    (icp_qat_fw_la_auth_req_params_t
756 			 *)((Cpa8U *)&(pCurrentQatMsg->serv_specif_rqpars) +
757 			    ICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);
758 
759 		if ((CPA_CY_SYM_HASH_SNOW3G_UIA2 !=
760 			 pSessionDesc->hashAlgorithm &&
761 		     CPA_CY_SYM_HASH_AES_CCM != pSessionDesc->hashAlgorithm &&
762 		     CPA_CY_SYM_HASH_AES_GCM != pSessionDesc->hashAlgorithm &&
763 		     CPA_CY_SYM_HASH_AES_GMAC != pSessionDesc->hashAlgorithm &&
764 		     CPA_CY_SYM_HASH_ZUC_EIA3 != pSessionDesc->hashAlgorithm) &&
765 		    (pHashStateBufferInfo->prefixAadSzQuadWords > 0)) {
766 			/* prefixAadSzQuadWords > 0 when there is prefix data
767 		       - i.e. nested hash or HMAC no precompute cases
768 		       Note partials not supported on DP api so we do not need
769 		       dynamic hash state in this case */
770 			pRequest->additionalAuthData =
771 			    pHashStateBufferInfo->pDataPhys +
772 			    LAC_QUADWORDS_TO_BYTES(
773 				pHashStateBufferInfo->stateStorageSzQuadWords);
774 		}
775 
776 		/* The first 24 bytes in icp_qat_fw_la_auth_req_params_t can be
777 		 * copied directly from the op request data because they share a
778 		 * corresponding layout.  The remaining 4 bytes are taken
779 		 * from the session message template and use values
780 		 * preconfigured at
781 		 * sessionInit (updated per request for some specific cases
782 		 * below)
783 		 */
784 
785 		/* We force a specific compiler optimisation here.  The length
786 		 * to
787 		 * be copied turns out to be always 16, and by coding a memcpy
788 		 * with
789 		 * a literal value the compiler will compile inline code (in
790 		 * fact,
791 		 * only two vector instructions) to effect the copy.  This gives
792 		 * us
793 		 * a huge performance increase.
794 		 */
795 		unsigned long cplen =
796 		    (unsigned long)&(pAuthReqPars->u2.inner_prefix_sz) -
797 		    (unsigned long)pAuthReqPars;
798 		if (cplen == 16)
799 			memcpy(pAuthReqPars,
800 			       (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
801 			       16);
802 		else
803 			memcpy(pAuthReqPars,
804 			       (Cpa32U *)&(pRequest->hashStartSrcOffsetInBytes),
805 			       cplen);
806 
807 		if (CPA_TRUE == pSessionDesc->isAuthEncryptOp) {
808 			pAuthReqPars->hash_state_sz =
809 			    LAC_BYTES_TO_QUADWORDS(pAuthReqPars->u2.aad_sz);
810 		} else if (CPA_CY_SYM_HASH_SNOW3G_UIA2 ==
811 			       pSessionDesc->hashAlgorithm ||
812 			   CPA_CY_SYM_HASH_ZUC_EIA3 ==
813 			       pSessionDesc->hashAlgorithm) {
814 			pAuthReqPars->hash_state_sz =
815 			    LAC_BYTES_TO_QUADWORDS(pSessionDesc->aadLenInBytes);
816 		}
817 	}
818 
819 }
820 
821 CpaStatus
822 cpaCySymDpSessionCtxGetSize(const CpaInstanceHandle instanceHandle,
823 			    const CpaCySymSessionSetupData *pSessionSetupData,
824 			    Cpa32U *pSessionCtxSizeInBytes)
825 {
826 	CpaStatus status = CPA_STATUS_SUCCESS;
827 
828 	/* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
829 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
830 	/* All other param checks are common with trad api */
831 	/* Check for valid pointers */
832 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
833 	status = cpaCySymSessionCtxGetSize(instanceHandle,
834 					   pSessionSetupData,
835 					   pSessionCtxSizeInBytes);
836 
837 	return status;
838 }
839 
840 CpaStatus
841 cpaCySymDpSessionCtxGetDynamicSize(
842     const CpaInstanceHandle instanceHandle,
843     const CpaCySymSessionSetupData *pSessionSetupData,
844     Cpa32U *pSessionCtxSizeInBytes)
845 {
846 	CpaStatus status = CPA_STATUS_SUCCESS;
847 
848 	/* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
849 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
850 	/* All other param checks are common with trad api */
851 	/* Check for valid pointers */
852 	LAC_CHECK_NULL_PARAM(pSessionCtxSizeInBytes);
853 	status = cpaCySymSessionCtxGetDynamicSize(instanceHandle,
854 						  pSessionSetupData,
855 						  pSessionCtxSizeInBytes);
856 
857 	return status;
858 }
859 
860 /** @ingroup cpaCySymDp */
861 CpaStatus
862 cpaCySymDpInitSession(CpaInstanceHandle instanceHandle,
863 		      const CpaCySymSessionSetupData *pSessionSetupData,
864 		      CpaCySymDpSessionCtx sessionCtx)
865 {
866 	CpaStatus status = CPA_STATUS_FAIL;
867 	sal_service_t *pService = NULL;
868 
869 
870 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
871 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
872 				(SAL_SERVICE_TYPE_CRYPTO |
873 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
874 	LAC_CHECK_NULL_PARAM(pSessionSetupData);
875 	pService = (sal_service_t *)instanceHandle;
876 
877 	/* Check crypto service is running otherwise return an error */
878 	SAL_RUNNING_CHECK(pService);
879 
880 	status = LacSym_InitSession(instanceHandle,
881 				    NULL, /* Callback */
882 				    pSessionSetupData,
883 				    CPA_TRUE, /* isDPSession */
884 				    sessionCtx);
885 	return status;
886 }
887 
888 CpaStatus
889 cpaCySymDpRemoveSession(const CpaInstanceHandle instanceHandle,
890 			CpaCySymDpSessionCtx sessionCtx)
891 {
892 
893 	/* CPA_INSTANCE_HANDLE_SINGLE is not supported on DP apis */
894 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
895 /* All other param checks are common with trad api */
896 
897 	return cpaCySymRemoveSession(instanceHandle, sessionCtx);
898 }
899 
900 CpaStatus
901 cpaCySymDpRegCbFunc(const CpaInstanceHandle instanceHandle,
902 		    const CpaCySymDpCbFunc pSymDpCb)
903 {
904 	sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
905 
906 
907 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
908 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
909 				(SAL_SERVICE_TYPE_CRYPTO |
910 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
911 	LAC_CHECK_NULL_PARAM(pSymDpCb);
912 	SAL_RUNNING_CHECK(instanceHandle);
913 	pService->pSymDpCb = pSymDpCb;
914 
915 	return CPA_STATUS_SUCCESS;
916 }
917 
918 CpaStatus
919 cpaCySymDpEnqueueOp(CpaCySymDpOpData *pRequest, const CpaBoolean performOpNow)
920 {
921 	icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
922 	icp_comms_trans_handle trans_handle = NULL;
923 	lac_session_desc_t *pSessionDesc = NULL;
924 	write_ringMsgFunc_t callFunc;
925 
926 	CpaStatus status = CPA_STATUS_SUCCESS;
927 
928 
929 	LAC_CHECK_NULL_PARAM(pRequest);
930 	status = LacDp_EnqueueParamCheck(pRequest);
931 	if (CPA_STATUS_SUCCESS != status) {
932 		return status;
933 	}
934 
935 	trans_handle = ((sal_crypto_service_t *)pRequest->instanceHandle)
936 			   ->trans_handle_sym_tx;
937 
938 	pSessionDesc = LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequest->sessionCtx);
939 	icp_adf_getSingleQueueAddr(trans_handle, (void **)&pCurrentQatMsg);
940 	if (NULL == pCurrentQatMsg) {
941 		/*
942 		 * No space is available on the queue.
943 		 */
944 		return CPA_STATUS_RETRY;
945 	}
946 
947 	callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
948 
949 	LAC_CHECK_NULL_PARAM(callFunc);
950 
951 	callFunc(pRequest, pCurrentQatMsg);
952 
953 	qatUtilsAtomicInc(&(pSessionDesc->u.pendingDpCbCount));
954 
955 	if (CPA_TRUE == performOpNow) {
956 		SalQatMsg_updateQueueTail(trans_handle);
957 	}
958 
959 	return CPA_STATUS_SUCCESS;
960 }
961 
962 CpaStatus
963 cpaCySymDpPerformOpNow(const CpaInstanceHandle instanceHandle)
964 {
965 	icp_comms_trans_handle trans_handle = NULL;
966 
967 
968 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
969 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
970 				(SAL_SERVICE_TYPE_CRYPTO |
971 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
972 
973 	/* Check if SAL is initialised otherwise return an error */
974 	SAL_RUNNING_CHECK(instanceHandle);
975 
976 	trans_handle =
977 	    ((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_tx;
978 
979 	if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) {
980 		SalQatMsg_updateQueueTail(trans_handle);
981 	}
982 
983 	return CPA_STATUS_SUCCESS;
984 }
985 
986 CpaStatus
987 cpaCySymDpEnqueueOpBatch(const Cpa32U numberRequests,
988 			 CpaCySymDpOpData *pRequests[],
989 			 const CpaBoolean performOpNow)
990 {
991 	icp_qat_fw_la_bulk_req_t *pCurrentQatMsg = NULL;
992 	icp_comms_trans_handle trans_handle = NULL;
993 	lac_session_desc_t *pSessionDesc = NULL;
994 	write_ringMsgFunc_t callFunc;
995 	Cpa32U i = 0;
996 
997 	CpaStatus status = CPA_STATUS_SUCCESS;
998 	sal_crypto_service_t *pService = NULL;
999 
1000 
1001 	LAC_CHECK_NULL_PARAM(pRequests);
1002 	LAC_CHECK_NULL_PARAM(pRequests[0]);
1003 	LAC_CHECK_NULL_PARAM(pRequests[0]->instanceHandle);
1004 
1005 	pService = (sal_crypto_service_t *)(pRequests[0]->instanceHandle);
1006 
1007 	if ((0 == numberRequests) ||
1008 	    (numberRequests > pService->maxNumSymReqBatch)) {
1009 		LAC_INVALID_PARAM_LOG1(
1010 		    "The number of requests needs to be between 1 "
1011 		    "and %d",
1012 		    pService->maxNumSymReqBatch);
1013 		return CPA_STATUS_INVALID_PARAM;
1014 	}
1015 
1016 	for (i = 0; i < numberRequests; i++) {
1017 		status = LacDp_EnqueueParamCheck(pRequests[i]);
1018 		if (CPA_STATUS_SUCCESS != status) {
1019 			return status;
1020 		}
1021 
1022 		/* Check that all instance handles are the same */
1023 		if (pRequests[i]->instanceHandle !=
1024 		    pRequests[0]->instanceHandle) {
1025 			LAC_INVALID_PARAM_LOG(
1026 			    "All instance handles should be the same "
1027 			    "in the requests");
1028 			return CPA_STATUS_INVALID_PARAM;
1029 		}
1030 	}
1031 
1032 	trans_handle = ((sal_crypto_service_t *)pRequests[0]->instanceHandle)
1033 			   ->trans_handle_sym_tx;
1034 	pSessionDesc =
1035 	    LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[0]->sessionCtx);
1036 	icp_adf_getQueueMemory(trans_handle,
1037 			       numberRequests,
1038 			       (void **)&pCurrentQatMsg);
1039 	if (NULL == pCurrentQatMsg) {
1040 		/*
1041 		 * No space is available on the queue.
1042 		 */
1043 		return CPA_STATUS_RETRY;
1044 	}
1045 
1046 	for (i = 0; i < numberRequests; i++) {
1047 		pSessionDesc =
1048 		    LAC_SYM_SESSION_DESC_FROM_CTX_GET(pRequests[i]->sessionCtx);
1049 		callFunc = (write_ringMsgFunc_t)pSessionDesc->writeRingMsgFunc;
1050 		callFunc(pRequests[i], pCurrentQatMsg);
1051 		icp_adf_getQueueNext(trans_handle, (void **)&pCurrentQatMsg);
1052 		qatUtilsAtomicAdd(1, &(pSessionDesc->u.pendingDpCbCount));
1053 	}
1054 
1055 	if (CPA_TRUE == performOpNow) {
1056 		SalQatMsg_updateQueueTail(trans_handle);
1057 	}
1058 
1059 	return CPA_STATUS_SUCCESS;
1060 }
1061 
1062 CpaStatus
1063 icp_sal_CyPollDpInstance(const CpaInstanceHandle instanceHandle,
1064 			 const Cpa32U responseQuota)
1065 {
1066 	icp_comms_trans_handle trans_handle = NULL;
1067 
1068 	LAC_CHECK_INSTANCE_HANDLE(instanceHandle);
1069 	SAL_CHECK_INSTANCE_TYPE(instanceHandle,
1070 				(SAL_SERVICE_TYPE_CRYPTO |
1071 				 SAL_SERVICE_TYPE_CRYPTO_SYM));
1072 
1073 	/* Check if SAL is initialised otherwise return an error */
1074 	SAL_RUNNING_CHECK(instanceHandle);
1075 
1076 	trans_handle =
1077 	    ((sal_crypto_service_t *)instanceHandle)->trans_handle_sym_rx;
1078 
1079 	return icp_adf_pollQueue(trans_handle, responseQuota);
1080 }
1081