#include "qat_utils.h"
#include "icp_accel_devices.h"
#include "icp_adf_debug.h"
#include "icp_adf_init.h"
#include "lac_list.h"
#include "lac_sal_types.h"
#include "lac_buffer_desc.h"
#include "lac_mem.h"
#include "cpa_cy_common.h"
#define INVALID_PHYSICAL_ADDRESS 0
typedef enum lac_buff_write_op_e {
WRITE_NORMAL = 0,
WRITE_AND_GET_SIZE,
WRITE_AND_ALLOW_ZERO_BUFFER,
} lac_buff_write_op_t;
static CpaStatus
LacBuffDesc_CommonBufferListDescWrite(const CpaBufferList *pUserBufferList,
Cpa64U *pBufListAlignedPhyAddr,
CpaBoolean isPhysicalAddress,
Cpa64U *totalDataLenInBytes,
sal_service_t *pService,
lac_buff_write_op_t operationType)
{
Cpa32U numBuffers = 0;
icp_qat_addr_width_t bufListDescPhyAddr = 0;
icp_qat_addr_width_t bufListAlignedPhyAddr = 0;
CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
icp_buffer_list_desc_t *pBufferListDesc = NULL;
icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
if (WRITE_AND_GET_SIZE == operationType) {
*totalDataLenInBytes = 0;
}
numBuffers = pUserBufferList->numBuffers;
pCurrClientFlatBuffer = pUserBufferList->pBuffers;
bufListDescPhyAddr = (icp_qat_addr_width_t)LAC_OS_VIRT_TO_PHYS_EXTERNAL(
(*pService), pUserBufferList->pPrivateMetaData);
if (bufListDescPhyAddr == 0) {
QAT_UTILS_LOG(
"Unable to get the physical address of the metadata.\n");
return CPA_STATUS_FAIL;
}
bufListAlignedPhyAddr =
LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
ICP_DESCRIPTOR_ALIGNMENT_BYTES);
pBufferListDesc = (icp_buffer_list_desc_t *)(LAC_ARCH_UINT)(
(LAC_ARCH_UINT)pUserBufferList->pPrivateMetaData +
((LAC_ARCH_UINT)bufListAlignedPhyAddr -
(LAC_ARCH_UINT)bufListDescPhyAddr));
pCurrFlatBufDesc =
(icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
pBufferListDesc->numBuffers = numBuffers;
if (WRITE_AND_GET_SIZE != operationType) {
if (0 == numBuffers) {
pBufferListDesc->numBuffers = 1;
pCurrFlatBufDesc->dataLenInBytes = 0;
pCurrFlatBufDesc->phyBuffer = 0;
}
}
while (0 != numBuffers) {
pCurrFlatBufDesc->dataLenInBytes =
pCurrClientFlatBuffer->dataLenInBytes;
if (WRITE_AND_GET_SIZE == operationType) {
*totalDataLenInBytes +=
pCurrClientFlatBuffer->dataLenInBytes;
}
if (CPA_TRUE == isPhysicalAddress) {
pCurrFlatBufDesc->phyBuffer =
LAC_MEM_CAST_PTR_TO_UINT64(
(LAC_ARCH_UINT)(pCurrClientFlatBuffer->pData));
} else {
pCurrFlatBufDesc->phyBuffer =
LAC_MEM_CAST_PTR_TO_UINT64(
LAC_OS_VIRT_TO_PHYS_EXTERNAL(
(*pService), pCurrClientFlatBuffer->pData));
if (WRITE_AND_ALLOW_ZERO_BUFFER != operationType) {
if (INVALID_PHYSICAL_ADDRESS ==
pCurrFlatBufDesc->phyBuffer) {
QAT_UTILS_LOG(
"Unable to get the physical address of the client buffer.\n");
return CPA_STATUS_FAIL;
}
}
}
pCurrFlatBufDesc++;
pCurrClientFlatBuffer++;
numBuffers--;
}
*pBufListAlignedPhyAddr = bufListAlignedPhyAddr;
return CPA_STATUS_SUCCESS;
}
CpaStatus
LacBuffDesc_BufferListDescWriteAndAllowZeroBuffer(
const CpaBufferList *pUserBufferList,
Cpa64U *pBufListAlignedPhyAddr,
CpaBoolean isPhysicalAddress,
sal_service_t *pService)
{
return LacBuffDesc_CommonBufferListDescWrite(
pUserBufferList,
pBufListAlignedPhyAddr,
isPhysicalAddress,
NULL,
pService,
WRITE_AND_ALLOW_ZERO_BUFFER);
}
CpaStatus
LacBuffDesc_BufferListDescWrite(const CpaBufferList *pUserBufferList,
Cpa64U *pBufListAlignedPhyAddr,
CpaBoolean isPhysicalAddress,
sal_service_t *pService)
{
return LacBuffDesc_CommonBufferListDescWrite(pUserBufferList,
pBufListAlignedPhyAddr,
isPhysicalAddress,
NULL,
pService,
WRITE_NORMAL);
}
CpaStatus
LacBuffDesc_BufferListDescWriteAndGetSize(const CpaBufferList *pUserBufferList,
Cpa64U *pBufListAlignedPhyAddr,
CpaBoolean isPhysicalAddress,
Cpa64U *totalDataLenInBytes,
sal_service_t *pService)
{
Cpa32U numBuffers = 0;
icp_qat_addr_width_t bufListDescPhyAddr = 0;
icp_qat_addr_width_t bufListAlignedPhyAddr = 0;
CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
icp_buffer_list_desc_t *pBufferListDesc = NULL;
icp_flat_buffer_desc_t *pCurrFlatBufDesc = NULL;
*totalDataLenInBytes = 0;
numBuffers = pUserBufferList->numBuffers;
pCurrClientFlatBuffer = pUserBufferList->pBuffers;
bufListDescPhyAddr = (icp_qat_addr_width_t)LAC_OS_VIRT_TO_PHYS_EXTERNAL(
(*pService), pUserBufferList->pPrivateMetaData);
if (INVALID_PHYSICAL_ADDRESS == bufListDescPhyAddr) {
QAT_UTILS_LOG(
"Unable to get the physical address of the metadata.\n");
return CPA_STATUS_FAIL;
}
bufListAlignedPhyAddr =
LAC_ALIGN_POW2_ROUNDUP(bufListDescPhyAddr,
ICP_DESCRIPTOR_ALIGNMENT_BYTES);
pBufferListDesc = (icp_buffer_list_desc_t *)(LAC_ARCH_UINT)(
(LAC_ARCH_UINT)pUserBufferList->pPrivateMetaData +
((LAC_ARCH_UINT)bufListAlignedPhyAddr -
(LAC_ARCH_UINT)bufListDescPhyAddr));
pCurrFlatBufDesc =
(icp_flat_buffer_desc_t *)((pBufferListDesc->phyBuffers));
pBufferListDesc->numBuffers = numBuffers;
while (0 != numBuffers) {
pCurrFlatBufDesc->dataLenInBytes =
pCurrClientFlatBuffer->dataLenInBytes;
*totalDataLenInBytes += pCurrClientFlatBuffer->dataLenInBytes;
if (isPhysicalAddress == CPA_TRUE) {
pCurrFlatBufDesc->phyBuffer =
LAC_MEM_CAST_PTR_TO_UINT64(
(LAC_ARCH_UINT)(pCurrClientFlatBuffer->pData));
} else {
pCurrFlatBufDesc->phyBuffer =
LAC_MEM_CAST_PTR_TO_UINT64(
LAC_OS_VIRT_TO_PHYS_EXTERNAL(
(*pService), pCurrClientFlatBuffer->pData));
if (pCurrFlatBufDesc->phyBuffer == 0) {
QAT_UTILS_LOG(
"Unable to get the physical address of the client buffer.\n");
return CPA_STATUS_FAIL;
}
}
pCurrFlatBufDesc++;
pCurrClientFlatBuffer++;
numBuffers--;
}
*pBufListAlignedPhyAddr = bufListAlignedPhyAddr;
return CPA_STATUS_SUCCESS;
}
CpaStatus
LacBuffDesc_FlatBufferVerify(const CpaFlatBuffer *pUserFlatBuffer,
Cpa64U *pPktSize,
lac_aligment_shift_t alignmentShiftExpected)
{
LAC_CHECK_NULL_PARAM(pUserFlatBuffer);
LAC_CHECK_NULL_PARAM(pUserFlatBuffer->pData);
if (0 == pUserFlatBuffer->dataLenInBytes) {
QAT_UTILS_LOG("FlatBuffer empty\n");
return CPA_STATUS_INVALID_PARAM;
}
if (LAC_NO_ALIGNMENT_SHIFT != alignmentShiftExpected) {
if (!LAC_ADDRESS_ALIGNED(pUserFlatBuffer->pData,
alignmentShiftExpected)) {
QAT_UTILS_LOG(
"FlatBuffer not aligned correctly - expected alignment of %u bytes.\n",
1 << alignmentShiftExpected);
return CPA_STATUS_INVALID_PARAM;
}
}
*pPktSize += pUserFlatBuffer->dataLenInBytes;
return CPA_STATUS_SUCCESS;
}
CpaStatus
LacBuffDesc_FlatBufferVerifyNull(const CpaFlatBuffer *pUserFlatBuffer,
Cpa64U *pPktSize,
lac_aligment_shift_t alignmentShiftExpected)
{
LAC_CHECK_NULL_PARAM(pUserFlatBuffer);
if (0 != pUserFlatBuffer->dataLenInBytes) {
LAC_CHECK_NULL_PARAM(pUserFlatBuffer->pData);
}
if (LAC_NO_ALIGNMENT_SHIFT != alignmentShiftExpected) {
if (!LAC_ADDRESS_ALIGNED(pUserFlatBuffer->pData,
alignmentShiftExpected)) {
QAT_UTILS_LOG(
"FlatBuffer not aligned correctly - expected alignment of %u bytes.\n",
1 << alignmentShiftExpected);
return CPA_STATUS_INVALID_PARAM;
}
}
*pPktSize += pUserFlatBuffer->dataLenInBytes;
return CPA_STATUS_SUCCESS;
}
CpaStatus
LacBuffDesc_BufferListVerify(const CpaBufferList *pUserBufferList,
Cpa64U *pPktSize,
lac_aligment_shift_t alignmentShiftExpected)
{
CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
Cpa32U numBuffers = 0;
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_NULL_PARAM(pUserBufferList);
LAC_CHECK_NULL_PARAM(pUserBufferList->pBuffers);
LAC_CHECK_NULL_PARAM(pUserBufferList->pPrivateMetaData);
numBuffers = pUserBufferList->numBuffers;
if (0 == pUserBufferList->numBuffers) {
QAT_UTILS_LOG("Number of buffers is 0.\n");
return CPA_STATUS_INVALID_PARAM;
}
pCurrClientFlatBuffer = pUserBufferList->pBuffers;
*pPktSize = 0;
while (0 != numBuffers && status == CPA_STATUS_SUCCESS) {
status = LacBuffDesc_FlatBufferVerify(pCurrClientFlatBuffer,
pPktSize,
alignmentShiftExpected);
pCurrClientFlatBuffer++;
numBuffers--;
}
return status;
}
CpaStatus
LacBuffDesc_BufferListVerifyNull(const CpaBufferList *pUserBufferList,
Cpa64U *pPktSize,
lac_aligment_shift_t alignmentShiftExpected)
{
CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
Cpa32U numBuffers = 0;
CpaStatus status = CPA_STATUS_SUCCESS;
LAC_CHECK_NULL_PARAM(pUserBufferList);
LAC_CHECK_NULL_PARAM(pUserBufferList->pBuffers);
LAC_CHECK_NULL_PARAM(pUserBufferList->pPrivateMetaData);
numBuffers = pUserBufferList->numBuffers;
if (0 == pUserBufferList->numBuffers) {
QAT_UTILS_LOG("Number of buffers is 0.\n");
return CPA_STATUS_INVALID_PARAM;
}
pCurrClientFlatBuffer = pUserBufferList->pBuffers;
*pPktSize = 0;
while (0 != numBuffers && status == CPA_STATUS_SUCCESS) {
status =
LacBuffDesc_FlatBufferVerifyNull(pCurrClientFlatBuffer,
pPktSize,
alignmentShiftExpected);
pCurrClientFlatBuffer++;
numBuffers--;
}
return status;
}
void
LacBuffDesc_BufferListTotalSizeGet(const CpaBufferList *pUserBufferList,
Cpa64U *pPktSize)
{
CpaFlatBuffer *pCurrClientFlatBuffer = NULL;
Cpa32U numBuffers = 0;
pCurrClientFlatBuffer = pUserBufferList->pBuffers;
numBuffers = pUserBufferList->numBuffers;
*pPktSize = 0;
while (0 != numBuffers) {
*pPktSize += pCurrClientFlatBuffer->dataLenInBytes;
pCurrClientFlatBuffer++;
numBuffers--;
}
}
void
LacBuffDesc_BufferListZeroFromOffset(CpaBufferList *pBuffList,
Cpa32U offset,
Cpa32U lenToZero)
{
Cpa32U zeroLen = 0, sizeLeftToZero = 0;
Cpa64U currentBufferSize = 0;
CpaFlatBuffer *pBuffer = NULL;
Cpa8U *pZero = NULL;
pBuffer = pBuffList->pBuffers;
sizeLeftToZero = lenToZero;
while (sizeLeftToZero > 0) {
currentBufferSize = pBuffer->dataLenInBytes;
if (offset >= currentBufferSize) {
offset = offset - pBuffer->dataLenInBytes;
pBuffer++;
} else {
pZero = (Cpa8U *)pBuffer->pData + offset;
if (sizeLeftToZero >= pBuffer->dataLenInBytes) {
zeroLen = pBuffer->dataLenInBytes - offset;
} else {
zeroLen = sizeLeftToZero;
if ((zeroLen + offset) >=
pBuffer->dataLenInBytes) {
zeroLen =
pBuffer->dataLenInBytes - offset;
}
}
memset((void *)pZero, 0, zeroLen);
sizeLeftToZero = sizeLeftToZero - zeroLen;
offset = 0;
pBuffer++;
}
}
}