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