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