1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3
4 /**
5 ***************************************************************************
6 * @file lac_sym_queue.c Functions for sending/queuing symmetric requests
7 *
8 * @ingroup LacSym
9 *
10 ***************************************************************************/
11
12 /*
13 *******************************************************************************
14 * Include public/global header files
15 *******************************************************************************
16 */
17 #include "cpa.h"
18 #include "cpa_cy_sym.h"
19
20 /*
21 *******************************************************************************
22 * Include private header files
23 *******************************************************************************
24 */
25 #include "icp_accel_devices.h"
26 #include "icp_adf_init.h"
27 #include "icp_adf_debug.h"
28 #include "icp_adf_transport.h"
29 #include "lac_sym_queue.h"
30 #include "lac_sym_qat.h"
31 #include "lac_session.h"
32 #include "lac_sym.h"
33 #include "lac_log.h"
34 #include "icp_qat_fw_la.h"
35 #include "lac_sal_types_crypto.h"
36
37 #define GetSingleBitFromByte(byte, bit) ((byte) & (1 << (bit)))
38
39 /*
40 *******************************************************************************
41 * Define public/global function definitions
42 *******************************************************************************
43 */
44
45 CpaStatus
LacSymQueue_RequestSend(const CpaInstanceHandle instanceHandle,lac_sym_bulk_cookie_t * pRequest,lac_session_desc_t * pSessionDesc)46 LacSymQueue_RequestSend(const CpaInstanceHandle instanceHandle,
47 lac_sym_bulk_cookie_t *pRequest,
48 lac_session_desc_t *pSessionDesc)
49 {
50 CpaStatus status = CPA_STATUS_SUCCESS;
51 CpaBoolean enqueued = CPA_FALSE;
52 sal_crypto_service_t *pService = (sal_crypto_service_t *)instanceHandle;
53 /* Enqueue the message instead of sending directly if:
54 * (i) a blocking operation is in progress
55 * (ii) there are previous requests already in the queue
56 */
57 if ((CPA_FALSE == pSessionDesc->nonBlockingOpsInProgress) ||
58 (NULL != pSessionDesc->pRequestQueueTail)) {
59 LAC_SPINLOCK(&pSessionDesc->requestQueueLock);
60
61 /* Re-check blockingOpsInProgress and pRequestQueueTail in case
62 * either
63 * changed before the lock was acquired. The lock is shared
64 * with
65 * the callback context which drains this queue
66 */
67 if ((CPA_FALSE == pSessionDesc->nonBlockingOpsInProgress) ||
68 (NULL != pSessionDesc->pRequestQueueTail)) {
69 /* Enqueue the message and exit */
70 /* The FIFO queue is made up of a head and tail pointer.
71 * The head pointer points to the first/oldest, entry
72 * in the queue, and the tail pointer points to the
73 * last/newest
74 * entry in the queue
75 */
76
77 if (NULL != pSessionDesc->pRequestQueueTail) {
78 /* Queue is non-empty. Add this request to the
79 * list */
80 pSessionDesc->pRequestQueueTail->pNext =
81 pRequest;
82 } else {
83 /* Queue is empty. Initialise the head pointer
84 * as well */
85 pSessionDesc->pRequestQueueHead = pRequest;
86 }
87
88 pSessionDesc->pRequestQueueTail = pRequest;
89
90 /* request is queued, don't send to QAT here */
91 enqueued = CPA_TRUE;
92 }
93 LAC_SPINUNLOCK(&pSessionDesc->requestQueueLock);
94 }
95
96 if (CPA_FALSE == enqueued) {
97 /* If we send a partial packet request, set the
98 * blockingOpsInProgress
99 * flag for the session to indicate that subsequent requests
100 * must be
101 * queued up until this request completes
102 *
103 * @assumption
104 * If we have got here it means that there were no previous
105 * blocking
106 * operations in progress and, since multiple partial packet
107 * requests
108 * on a given session cannot be issued concurrently, there
109 * should be
110 * no need for a critical section around the following code
111 */
112 if (CPA_CY_SYM_PACKET_TYPE_FULL !=
113 pRequest->pOpData->packetType) {
114 /* Select blocking operations which this reqest will
115 * complete */
116 pSessionDesc->nonBlockingOpsInProgress = CPA_FALSE;
117 }
118
119 /* At this point, we're clear to send the request. For cipher
120 * requests,
121 * we need to check if the session IV needs to be updated. This
122 * can
123 * only be done when no other partials are in flight for this
124 * session,
125 * to ensure the cipherPartialOpState buffer in the session
126 * descriptor
127 * is not currently in use
128 */
129 if (CPA_TRUE == pRequest->updateSessionIvOnSend) {
130 if (LAC_CIPHER_IS_ARC4(pSessionDesc->cipherAlgorithm)) {
131 memcpy(pSessionDesc->cipherPartialOpState,
132 pSessionDesc->cipherARC4InitialState,
133 LAC_CIPHER_ARC4_STATE_LEN_BYTES);
134 } else {
135 memcpy(pSessionDesc->cipherPartialOpState,
136 pRequest->pOpData->pIv,
137 pRequest->pOpData->ivLenInBytes);
138 }
139 }
140
141 /* Send to QAT */
142 status = icp_adf_transPutMsg(pService->trans_handle_sym_tx,
143 (void *)&(pRequest->qatMsg),
144 LAC_QAT_SYM_REQ_SZ_LW);
145
146 /* if fail to send request, we need to change
147 * nonBlockingOpsInProgress
148 * to CPA_TRUE
149 */
150 if ((CPA_STATUS_SUCCESS != status) &&
151 (CPA_CY_SYM_PACKET_TYPE_FULL !=
152 pRequest->pOpData->packetType)) {
153 pSessionDesc->nonBlockingOpsInProgress = CPA_TRUE;
154 }
155 }
156 return status;
157 }
158