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 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