1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 /** 5 ***************************************************************************** 6 * @file dc_datapath.c 7 * 8 * @defgroup Dc_DataCompression DC Data Compression 9 * 10 * @ingroup Dc_DataCompression 11 * 12 * @description 13 * Implementation of the Data Compression datapath operations. 14 * 15 *****************************************************************************/ 16 17 /* 18 ******************************************************************************* 19 * Include public/global header files 20 ******************************************************************************* 21 */ 22 #include "cpa.h" 23 #include "cpa_dc.h" 24 #include "cpa_dc_dp.h" 25 26 /* 27 ******************************************************************************* 28 * Include private header files 29 ******************************************************************************* 30 */ 31 #include "dc_session.h" 32 #include "dc_datapath.h" 33 #include "sal_statistics.h" 34 #include "lac_common.h" 35 #include "lac_mem.h" 36 #include "lac_mem_pools.h" 37 #include "sal_types_compression.h" 38 #include "dc_stats.h" 39 #include "lac_buffer_desc.h" 40 #include "lac_sal.h" 41 #include "lac_log.h" 42 #include "lac_sync.h" 43 #include "sal_service_state.h" 44 #include "sal_qat_cmn_msg.h" 45 #include "sal_hw_gen.h" 46 #include "dc_error_counter.h" 47 #define DC_COMP_MAX_BUFF_SIZE (1024 * 64) 48 49 static QatUtilsAtomic dcErrorCount[MAX_DC_ERROR_TYPE]; 50 51 void 52 dcErrorLog(CpaDcReqStatus dcError) 53 { 54 Cpa32U absError = 0; 55 56 absError = abs(dcError); 57 if ((dcError < CPA_DC_OK) && (absError < MAX_DC_ERROR_TYPE)) { 58 qatUtilsAtomicInc(&(dcErrorCount[absError])); 59 } 60 } 61 62 Cpa64U 63 getDcErrorCounter(CpaDcReqStatus dcError) 64 { 65 Cpa32U absError = 0; 66 67 absError = abs(dcError); 68 if (!(dcError >= CPA_DC_OK || dcError < CPA_DC_EMPTY_DYM_BLK)) { 69 return (Cpa64U)qatUtilsAtomicGet(&dcErrorCount[absError]); 70 } 71 72 return 0; 73 } 74 75 static inline void 76 dcUpdateXltOverflowChecksumsGen4(const dc_compression_cookie_t *pCookie, 77 const icp_qat_fw_resp_comp_pars_t *pRespPars, 78 CpaDcRqResults *pDcResults) 79 { 80 dc_session_desc_t *pSessionDesc = 81 DC_SESSION_DESC_FROM_CTX_GET(pCookie->pSessionHandle); 82 83 /* Recompute CRC checksum when either the checksum type 84 * is CPA_DC_CRC32 or when the integrity CRCs are enabled. 85 */ 86 if (CPA_DC_CRC32 == pSessionDesc->checksumType) { 87 pDcResults->checksum = pRespPars->crc.legacy.curr_crc32; 88 89 /* No need to recalculate the swCrc64I here as this will get 90 * handled later in dcHandleIntegrityChecksumsGen4. 91 */ 92 } else if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 93 pDcResults->checksum = pRespPars->crc.legacy.curr_adler_32; 94 } 95 } 96 97 void 98 dcCompression_ProcessCallback(void *pRespMsg) 99 { 100 CpaStatus status = CPA_STATUS_SUCCESS; 101 icp_qat_fw_comp_resp_t *pCompRespMsg = NULL; 102 void *callbackTag = NULL; 103 Cpa64U *pReqData = NULL; 104 CpaDcDpOpData *pResponse = NULL; 105 CpaDcRqResults *pResults = NULL; 106 CpaDcCallbackFn pCbFunc = NULL; 107 dc_session_desc_t *pSessionDesc = NULL; 108 sal_compression_service_t *pService = NULL; 109 dc_compression_cookie_t *pCookie = NULL; 110 CpaDcOpData *pOpData = NULL; 111 CpaBoolean cmpPass = CPA_TRUE, xlatPass = CPA_TRUE; 112 CpaBoolean isDcDp = CPA_FALSE; 113 CpaBoolean integrityCrcCheck = CPA_FALSE; 114 CpaBoolean verifyHwIntegrityCrcs = CPA_FALSE; 115 Cpa8U cmpErr = ERR_CODE_NO_ERROR, xlatErr = ERR_CODE_NO_ERROR; 116 dc_request_dir_t compDecomp = DC_COMPRESSION_REQUEST; 117 Cpa8U opStatus = ICP_QAT_FW_COMN_STATUS_FLAG_OK; 118 Cpa8U hdrFlags = 0; 119 120 /* Cast response message to compression response message type */ 121 pCompRespMsg = (icp_qat_fw_comp_resp_t *)pRespMsg; 122 123 /* Extract request data pointer from the opaque data */ 124 LAC_MEM_SHARED_READ_TO_PTR(pCompRespMsg->opaque_data, pReqData); 125 126 /* Extract fields from the request data structure */ 127 pCookie = (dc_compression_cookie_t *)pReqData; 128 if (!pCookie) 129 return; 130 131 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pCookie->pSessionHandle); 132 pService = (sal_compression_service_t *)(pCookie->dcInstance); 133 134 isDcDp = pSessionDesc->isDcDp; 135 if (CPA_TRUE == isDcDp) { 136 pResponse = (CpaDcDpOpData *)pReqData; 137 pResults = &(pResponse->results); 138 139 if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) { 140 compDecomp = DC_DECOMPRESSION_REQUEST; 141 } 142 pCookie = NULL; 143 } else { 144 pResults = pCookie->pResults; 145 callbackTag = pCookie->callbackTag; 146 pCbFunc = pCookie->pSessionDesc->pCompressionCb; 147 compDecomp = pCookie->compDecomp; 148 pOpData = pCookie->pDcOpData; 149 } 150 151 opStatus = pCompRespMsg->comn_resp.comn_status; 152 153 if (NULL != pOpData) { 154 verifyHwIntegrityCrcs = pOpData->verifyHwIntegrityCrcs; 155 } 156 157 hdrFlags = pCompRespMsg->comn_resp.hdr_flags; 158 159 /* Get the cmp error code */ 160 cmpErr = pCompRespMsg->comn_resp.comn_error.s1.cmp_err_code; 161 if (ICP_QAT_FW_COMN_RESP_UNSUPPORTED_REQUEST_STAT_GET(opStatus)) { 162 /* Compression not supported by firmware, set produced/consumed 163 to zero 164 and call the cb function with status CPA_STATUS_UNSUPPORTED 165 */ 166 QAT_UTILS_LOG("Compression feature not supported\n"); 167 status = CPA_STATUS_UNSUPPORTED; 168 pResults->status = (Cpa8S)cmpErr; 169 pResults->consumed = 0; 170 pResults->produced = 0; 171 if (CPA_TRUE == isDcDp) { 172 if (pResponse) 173 pResponse->responseStatus = 174 CPA_STATUS_UNSUPPORTED; 175 (pService->pDcDpCb)(pResponse); 176 } else { 177 /* Free the memory pool */ 178 if (NULL != pCookie) { 179 Lac_MemPoolEntryFree(pCookie); 180 pCookie = NULL; 181 } 182 if (NULL != pCbFunc) { 183 pCbFunc(callbackTag, status); 184 } 185 } 186 if (DC_COMPRESSION_REQUEST == compDecomp) { 187 COMPRESSION_STAT_INC(numCompCompletedErrors, pService); 188 } else { 189 COMPRESSION_STAT_INC(numDecompCompletedErrors, 190 pService); 191 } 192 return; 193 } else { 194 /* Check compression response status */ 195 cmpPass = 196 (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK == 197 ICP_QAT_FW_COMN_RESP_CMP_STAT_GET(opStatus)); 198 } 199 200 if (isDcGen2x(pService)) { 201 /* QAT1.7 and QAT 1.8 hardware */ 202 if (CPA_DC_INCOMPLETE_FILE_ERR == (Cpa8S)cmpErr) { 203 cmpPass = CPA_TRUE; 204 cmpErr = ERR_CODE_NO_ERROR; 205 } 206 } else { 207 /* QAT2.0 hardware cancels the incomplete file errors 208 * only for DEFLATE algorithm. 209 * Decompression direction is not tested in the callback as 210 * the request does not allow it. 211 */ 212 if ((pSessionDesc->compType == CPA_DC_DEFLATE) && 213 (CPA_DC_INCOMPLETE_FILE_ERR == (Cpa8S)cmpErr)) { 214 cmpPass = CPA_TRUE; 215 cmpErr = ERR_CODE_NO_ERROR; 216 } 217 } 218 /* log the slice hang and endpoint push/pull error inside the response 219 */ 220 if (ERR_CODE_SSM_ERROR == (Cpa8S)cmpErr) { 221 QAT_UTILS_LOG( 222 "Slice hang detected on the compression slice.\n"); 223 } else if (ERR_CODE_ENDPOINT_ERROR == (Cpa8S)cmpErr) { 224 QAT_UTILS_LOG( 225 "PCIe End Point Push/Pull or TI/RI Parity error detected.\n"); 226 } 227 228 /* We return the compression error code for now. We would need to update 229 * the API if we decide to return both error codes */ 230 pResults->status = (Cpa8S)cmpErr; 231 232 /* Check the translator status */ 233 if ((DC_COMPRESSION_REQUEST == compDecomp) && 234 (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) { 235 /* Check translator response status */ 236 xlatPass = 237 (CpaBoolean)(ICP_QAT_FW_COMN_STATUS_FLAG_OK == 238 ICP_QAT_FW_COMN_RESP_XLAT_STAT_GET(opStatus)); 239 240 /* Get the translator error code */ 241 xlatErr = pCompRespMsg->comn_resp.comn_error.s1.xlat_err_code; 242 243 /* Return a fatal error or a potential error in the translator 244 * slice if the compression slice did not return any error */ 245 if ((CPA_DC_OK == pResults->status) || 246 (CPA_DC_FATALERR == (Cpa8S)xlatErr)) { 247 pResults->status = (Cpa8S)xlatErr; 248 } 249 } 250 /* Update dc error counter */ 251 dcErrorLog(pResults->status); 252 253 if (CPA_FALSE == isDcDp) { 254 /* In case of any error for an end of packet request, we need to 255 * update 256 * the request type for the following request */ 257 if (CPA_DC_FLUSH_FINAL == pCookie->flushFlag && cmpPass && 258 xlatPass) { 259 pSessionDesc->requestType = DC_REQUEST_FIRST; 260 } else { 261 pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT; 262 } 263 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) || 264 ((CPA_DC_STATELESS == pSessionDesc->sessState) && 265 (DC_COMPRESSION_REQUEST == compDecomp))) { 266 /* Overflow is a valid use case for Traditional API 267 * only. Stateful Overflow is supported in both 268 * compression and decompression direction. Stateless 269 * Overflow is supported only in compression direction. 270 */ 271 if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr) 272 cmpPass = CPA_TRUE; 273 274 if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) { 275 if (isDcGen4x(pService) && 276 (CPA_TRUE == 277 pService->comp_device_data 278 .translatorOverflow)) { 279 pResults->consumed = 280 pCompRespMsg->comp_resp_pars 281 .input_byte_counter; 282 283 dcUpdateXltOverflowChecksumsGen4( 284 pCookie, 285 &pCompRespMsg->comp_resp_pars, 286 pResults); 287 } 288 xlatPass = CPA_TRUE; 289 } 290 } 291 } else { 292 if (CPA_DC_OVERFLOW == (Cpa8S)cmpErr) { 293 cmpPass = CPA_FALSE; 294 } 295 if (CPA_DC_OVERFLOW == (Cpa8S)xlatErr) { 296 /* XLT overflow is not valid for Data Plane requests */ 297 xlatPass = CPA_FALSE; 298 } 299 } 300 301 if ((CPA_TRUE == cmpPass) && (CPA_TRUE == xlatPass)) { 302 /* Extract the response from the firmware */ 303 pResults->consumed = 304 pCompRespMsg->comp_resp_pars.input_byte_counter; 305 pResults->produced = 306 pCompRespMsg->comp_resp_pars.output_byte_counter; 307 pSessionDesc->cumulativeConsumedBytes += pResults->consumed; 308 309 /* Handle Checksum for end to end data integrity. */ 310 if (CPA_TRUE == 311 pService->generic_service_info.integrityCrcCheck && 312 CPA_TRUE == integrityCrcCheck) { 313 pSessionDesc->previousChecksum = 314 pSessionDesc->seedSwCrc.swCrc32I; 315 } else if (CPA_DC_OVERFLOW != (Cpa8S)xlatErr) { 316 if (CPA_DC_CRC32 == pSessionDesc->checksumType) { 317 pResults->checksum = 318 pCompRespMsg->comp_resp_pars.crc.legacy 319 .curr_crc32; 320 } else if (CPA_DC_ADLER32 == 321 pSessionDesc->checksumType) { 322 pResults->checksum = 323 pCompRespMsg->comp_resp_pars.crc.legacy 324 .curr_adler_32; 325 } 326 pSessionDesc->previousChecksum = pResults->checksum; 327 } 328 329 if (DC_DECOMPRESSION_REQUEST == compDecomp) { 330 pResults->endOfLastBlock = 331 (ICP_QAT_FW_COMN_STATUS_CMP_END_OF_LAST_BLK_FLAG_SET == 332 ICP_QAT_FW_COMN_RESP_CMP_END_OF_LAST_BLK_FLAG_GET( 333 opStatus)); 334 } 335 336 /* Save the checksum for the next request */ 337 if ((CPA_DC_OVERFLOW != (Cpa8S)xlatErr) && 338 (CPA_TRUE == verifyHwIntegrityCrcs)) { 339 pSessionDesc->previousChecksum = 340 pSessionDesc->seedSwCrc.swCrc32I; 341 } 342 343 /* Check if a CNV recovery happened and 344 * increase stats counter 345 */ 346 if ((DC_COMPRESSION_REQUEST == compDecomp) && 347 ICP_QAT_FW_COMN_HDR_CNV_FLAG_GET(hdrFlags) && 348 ICP_QAT_FW_COMN_HDR_CNVNR_FLAG_GET(hdrFlags)) { 349 COMPRESSION_STAT_INC(numCompCnvErrorsRecovered, 350 pService); 351 } 352 353 if (CPA_TRUE == isDcDp) { 354 if (pResponse) 355 pResponse->responseStatus = CPA_STATUS_SUCCESS; 356 } else { 357 if (DC_COMPRESSION_REQUEST == compDecomp) { 358 COMPRESSION_STAT_INC(numCompCompleted, 359 pService); 360 } else { 361 COMPRESSION_STAT_INC(numDecompCompleted, 362 pService); 363 } 364 } 365 } else { 366 #ifdef ICP_DC_RETURN_COUNTERS_ON_ERROR 367 /* Extract the response from the firmware */ 368 pResults->consumed = 369 pCompRespMsg->comp_resp_pars.input_byte_counter; 370 pResults->produced = 371 pCompRespMsg->comp_resp_pars.output_byte_counter; 372 373 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 374 pSessionDesc->cumulativeConsumedBytes += 375 pResults->consumed; 376 } else { 377 /* In the stateless case all requests have both SOP and 378 * EOP set */ 379 pSessionDesc->cumulativeConsumedBytes = 380 pResults->consumed; 381 } 382 #else 383 pResults->consumed = 0; 384 pResults->produced = 0; 385 #endif 386 if (CPA_DC_OVERFLOW == pResults->status && 387 CPA_DC_STATELESS == pSessionDesc->sessState) { 388 /* This error message will be returned by Data Plane API 389 * in both 390 * compression and decompression direction. With 391 * Traditional API 392 * this error message will be returned only in stateless 393 * decompression direction */ 394 QAT_UTILS_LOG( 395 "Unrecoverable error: stateless overflow. You may need to increase the size of your destination buffer.\n"); 396 } 397 398 if (CPA_TRUE == isDcDp) { 399 if (pResponse) 400 pResponse->responseStatus = CPA_STATUS_FAIL; 401 } else { 402 if (CPA_DC_OK != pResults->status && 403 CPA_DC_INCOMPLETE_FILE_ERR != pResults->status) { 404 status = CPA_STATUS_FAIL; 405 } 406 407 if (DC_COMPRESSION_REQUEST == compDecomp) { 408 COMPRESSION_STAT_INC(numCompCompletedErrors, 409 pService); 410 } else { 411 COMPRESSION_STAT_INC(numDecompCompletedErrors, 412 pService); 413 } 414 } 415 } 416 417 if (CPA_TRUE == isDcDp) { 418 /* Decrement number of stateless pending callbacks for session 419 */ 420 pSessionDesc->pendingDpStatelessCbCount--; 421 (pService->pDcDpCb)(pResponse); 422 } else { 423 /* Decrement number of pending callbacks for session */ 424 if (CPA_DC_STATELESS == pSessionDesc->sessState) { 425 qatUtilsAtomicDec( 426 &(pCookie->pSessionDesc->pendingStatelessCbCount)); 427 } else if (0 != 428 qatUtilsAtomicGet(&pCookie->pSessionDesc 429 ->pendingStatefulCbCount)) { 430 qatUtilsAtomicDec( 431 &(pCookie->pSessionDesc->pendingStatefulCbCount)); 432 } 433 434 /* Free the memory pool */ 435 if (NULL != pCookie) { 436 Lac_MemPoolEntryFree(pCookie); 437 pCookie = NULL; 438 } 439 440 if (NULL != pCbFunc) { 441 pCbFunc(callbackTag, status); 442 } 443 } 444 } 445 446 /** 447 ***************************************************************************** 448 * @ingroup Dc_DataCompression 449 * Check that all the parameters in the pOpData structure are valid 450 * 451 * @description 452 * Check that all the parameters in the pOpData structure are valid 453 * 454 * @param[in] pService Pointer to the compression service 455 * @param[in] pOpData Pointer to request information structure 456 * holding parameters for cpaDcCompress2 and 457 * CpaDcDecompressData2 458 * @retval CPA_STATUS_SUCCESS Function executed successfully 459 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 460 * 461 *****************************************************************************/ 462 CpaStatus 463 dcCheckOpData(sal_compression_service_t *pService, CpaDcOpData *pOpData) 464 { 465 CpaDcSkipMode skipMode = 0; 466 467 if ((pOpData->flushFlag < CPA_DC_FLUSH_NONE) || 468 (pOpData->flushFlag > CPA_DC_FLUSH_FULL)) { 469 LAC_INVALID_PARAM_LOG("Invalid flushFlag value"); 470 return CPA_STATUS_INVALID_PARAM; 471 } 472 473 skipMode = pOpData->inputSkipData.skipMode; 474 if ((skipMode < CPA_DC_SKIP_DISABLED) || 475 (skipMode > CPA_DC_SKIP_STRIDE)) { 476 LAC_INVALID_PARAM_LOG("Invalid input skip mode value"); 477 return CPA_STATUS_INVALID_PARAM; 478 } 479 480 skipMode = pOpData->outputSkipData.skipMode; 481 if ((skipMode < CPA_DC_SKIP_DISABLED) || 482 (skipMode > CPA_DC_SKIP_STRIDE)) { 483 LAC_INVALID_PARAM_LOG("Invalid output skip mode value"); 484 return CPA_STATUS_INVALID_PARAM; 485 } 486 487 if (pOpData->integrityCrcCheck == CPA_FALSE && 488 pOpData->verifyHwIntegrityCrcs == CPA_TRUE) { 489 LAC_INVALID_PARAM_LOG( 490 "integrityCrcCheck must be set to true" 491 "in order to enable verifyHwIntegrityCrcs"); 492 return CPA_STATUS_INVALID_PARAM; 493 } 494 495 if (pOpData->integrityCrcCheck != CPA_TRUE && 496 pOpData->integrityCrcCheck != CPA_FALSE) { 497 LAC_INVALID_PARAM_LOG("Invalid integrityCrcCheck value"); 498 return CPA_STATUS_INVALID_PARAM; 499 } 500 501 if (pOpData->verifyHwIntegrityCrcs != CPA_TRUE && 502 pOpData->verifyHwIntegrityCrcs != CPA_FALSE) { 503 LAC_INVALID_PARAM_LOG("Invalid verifyHwIntegrityCrcs value"); 504 return CPA_STATUS_INVALID_PARAM; 505 } 506 507 if (pOpData->compressAndVerify != CPA_TRUE && 508 pOpData->compressAndVerify != CPA_FALSE) { 509 LAC_INVALID_PARAM_LOG("Invalid cnv decompress check value"); 510 return CPA_STATUS_INVALID_PARAM; 511 } 512 513 if (CPA_TRUE == pOpData->integrityCrcCheck && 514 CPA_FALSE == pService->generic_service_info.integrityCrcCheck) { 515 LAC_INVALID_PARAM_LOG("Integrity CRC check is not " 516 "supported on this device"); 517 return CPA_STATUS_INVALID_PARAM; 518 } 519 520 if (CPA_TRUE == pOpData->integrityCrcCheck && 521 NULL == pOpData->pCrcData) { 522 LAC_INVALID_PARAM_LOG("Integrity CRC data structure " 523 "not intialized in CpaDcOpData"); 524 return CPA_STATUS_INVALID_PARAM; 525 } 526 527 return CPA_STATUS_SUCCESS; 528 } 529 530 /** 531 ***************************************************************************** 532 * @ingroup Dc_DataCompression 533 * Check the compression source buffer for Batch and Pack API. 534 * 535 * @description 536 * Check that all the parameters used for Pack compression 537 * request are valid. This function essentially checks the source buffer 538 * parameters and results structure parameters. 539 * 540 * @param[in] pSessionHandle Session handle 541 * @param[in] pSrcBuff Pointer to data buffer for compression 542 * @param[in] pDestBuff Pointer to buffer space allocated for 543 * output data 544 * @param[in] pResults Pointer to results structure 545 * @param[in] flushFlag Indicates the type of flush to be 546 * performed 547 * @param[in] srcBuffSize Size of the source buffer 548 * 549 * @retval CPA_STATUS_SUCCESS Function executed successfully 550 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 551 * 552 *****************************************************************************/ 553 static CpaStatus 554 dcCheckSourceData(CpaDcSessionHandle pSessionHandle, 555 CpaBufferList *pSrcBuff, 556 CpaBufferList *pDestBuff, 557 CpaDcRqResults *pResults, 558 CpaDcFlush flushFlag, 559 Cpa64U srcBuffSize, 560 CpaDcSkipData *skipData) 561 { 562 dc_session_desc_t *pSessionDesc = NULL; 563 564 LAC_CHECK_NULL_PARAM(pSessionHandle); 565 LAC_CHECK_NULL_PARAM(pSrcBuff); 566 LAC_CHECK_NULL_PARAM(pDestBuff); 567 LAC_CHECK_NULL_PARAM(pResults); 568 569 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 570 if (NULL == pSessionDesc) { 571 LAC_INVALID_PARAM_LOG("Session handle not as expected"); 572 return CPA_STATUS_INVALID_PARAM; 573 } 574 575 if ((flushFlag < CPA_DC_FLUSH_NONE) || 576 (flushFlag > CPA_DC_FLUSH_FULL)) { 577 LAC_INVALID_PARAM_LOG("Invalid flushFlag value"); 578 return CPA_STATUS_INVALID_PARAM; 579 } 580 581 if (pSrcBuff == pDestBuff) { 582 LAC_INVALID_PARAM_LOG("In place operation not supported"); 583 return CPA_STATUS_INVALID_PARAM; 584 } 585 586 /* Compressing zero bytes is not supported for stateless sessions 587 * for non Batch and Pack requests */ 588 if ((CPA_DC_STATELESS == pSessionDesc->sessState) && 589 (0 == srcBuffSize) && (NULL == skipData)) { 590 LAC_INVALID_PARAM_LOG( 591 "The source buffer size needs to be greater than " 592 "zero bytes for stateless sessions"); 593 return CPA_STATUS_INVALID_PARAM; 594 } 595 596 if (srcBuffSize > DC_BUFFER_MAX_SIZE) { 597 LAC_INVALID_PARAM_LOG( 598 "The source buffer size needs to be less than or " 599 "equal to 2^32-1 bytes"); 600 return CPA_STATUS_INVALID_PARAM; 601 } 602 603 return CPA_STATUS_SUCCESS; 604 } 605 606 /** 607 ***************************************************************************** 608 * @ingroup Dc_DataCompression 609 * Check the compression or decompression function parameters. 610 * 611 * @description 612 * Check that all the parameters used for a Batch and Pack compression 613 * request are valid. This function essentially checks the destination 614 * buffer parameters and intermediate buffer parameters. 615 * 616 * @param[in] pService Pointer to the compression service 617 * @param[in] pSessionHandle Session handle 618 * @param[in] pDestBuff Pointer to buffer space allocated for 619 * output data 620 * @param[in] compDecomp Direction of the operation 621 * 622 * @retval CPA_STATUS_SUCCESS Function executed successfully 623 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 624 * 625 *****************************************************************************/ 626 static CpaStatus 627 dcCheckDestinationData(sal_compression_service_t *pService, 628 CpaDcSessionHandle pSessionHandle, 629 CpaBufferList *pDestBuff, 630 dc_request_dir_t compDecomp) 631 { 632 dc_session_desc_t *pSessionDesc = NULL; 633 Cpa64U destBuffSize = 0; 634 635 LAC_CHECK_NULL_PARAM(pSessionHandle); 636 LAC_CHECK_NULL_PARAM(pDestBuff); 637 638 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 639 if (NULL == pSessionDesc) { 640 LAC_INVALID_PARAM_LOG("Session handle not as expected"); 641 return CPA_STATUS_INVALID_PARAM; 642 } 643 644 if (LacBuffDesc_BufferListVerify(pDestBuff, 645 &destBuffSize, 646 LAC_NO_ALIGNMENT_SHIFT) != 647 CPA_STATUS_SUCCESS) { 648 LAC_INVALID_PARAM_LOG( 649 "Invalid destination buffer list parameter"); 650 return CPA_STATUS_INVALID_PARAM; 651 } 652 653 if (destBuffSize > DC_BUFFER_MAX_SIZE) { 654 LAC_INVALID_PARAM_LOG( 655 "The destination buffer size needs to be less " 656 "than or equal to 2^32-1 bytes"); 657 return CPA_STATUS_INVALID_PARAM; 658 } 659 660 if (CPA_TRUE == pSessionDesc->isDcDp) { 661 LAC_INVALID_PARAM_LOG( 662 "The session type should not be data plane"); 663 return CPA_STATUS_INVALID_PARAM; 664 } 665 666 if (DC_COMPRESSION_REQUEST == compDecomp) { 667 if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) { 668 669 /* Check if intermediate buffers are supported */ 670 if ((isDcGen2x(pService)) && 671 ((0 == pService->pInterBuffPtrsArrayPhyAddr) || 672 (NULL == pService->pInterBuffPtrsArray))) { 673 LAC_LOG_ERROR( 674 "No intermediate buffer defined for this instance " 675 "- see cpaDcStartInstance"); 676 return CPA_STATUS_INVALID_PARAM; 677 } 678 679 /* Ensure that the destination buffer size is greater or 680 * equal to 128B */ 681 if (destBuffSize < DC_DEST_BUFFER_DYN_MIN_SIZE) { 682 LAC_INVALID_PARAM_LOG( 683 "Destination buffer size should be " 684 "greater or equal to 128B"); 685 return CPA_STATUS_INVALID_PARAM; 686 } 687 } else 688 { 689 /* Ensure that the destination buffer size is greater or 690 * equal to devices min output buff size */ 691 if (destBuffSize < 692 pService->comp_device_data.minOutputBuffSize) { 693 LAC_INVALID_PARAM_LOG1( 694 "Destination buffer size should be " 695 "greater or equal to %d bytes", 696 pService->comp_device_data 697 .minOutputBuffSize); 698 return CPA_STATUS_INVALID_PARAM; 699 } 700 } 701 } else { 702 /* Ensure that the destination buffer size is greater than 703 * 0 bytes */ 704 if (destBuffSize < DC_DEST_BUFFER_DEC_MIN_SIZE) { 705 LAC_INVALID_PARAM_LOG( 706 "Destination buffer size should be " 707 "greater than 0 bytes"); 708 return CPA_STATUS_INVALID_PARAM; 709 } 710 } 711 return CPA_STATUS_SUCCESS; 712 } 713 714 /** 715 ***************************************************************************** 716 * @ingroup Dc_DataCompression 717 * Populate the compression request parameters 718 * 719 * @description 720 * This function will populate the compression request parameters 721 * 722 * @param[out] pCompReqParams Pointer to the compression request parameters 723 * @param[in] pCookie Pointer to the compression cookie 724 * 725 *****************************************************************************/ 726 static void 727 dcCompRequestParamsPopulate(icp_qat_fw_comp_req_params_t *pCompReqParams, 728 dc_compression_cookie_t *pCookie) 729 { 730 pCompReqParams->comp_len = pCookie->srcTotalDataLenInBytes; 731 pCompReqParams->out_buffer_sz = pCookie->dstTotalDataLenInBytes; 732 } 733 734 /** 735 ***************************************************************************** 736 * @ingroup Dc_DataCompression 737 * Create the requests for compression or decompression 738 * 739 * @description 740 * Create the requests for compression or decompression. This function 741 * will update the cookie will all required information. 742 * 743 * @param{out] pCookie Pointer to the compression cookie 744 * @param[in] pService Pointer to the compression service 745 * @param[in] pSessionDesc Pointer to the session descriptor 746 * @param[in pSessionHandle Session handle 747 * @param[in] pSrcBuff Pointer to data buffer for compression 748 * @param[in] pDestBuff Pointer to buffer space for data after 749 * compression 750 * @param[in] pResults Pointer to results structure 751 * @param[in] flushFlag Indicates the type of flush to be 752 * performed 753 * @param[in] pOpData Pointer to request information structure 754 * holding parameters for cpaDcCompress2 755 * and CpaDcDecompressData2 756 * @param[in] callbackTag Pointer to the callback tag 757 * @param[in] compDecomp Direction of the operation 758 * @param[in] compressAndVerify Compress and Verify 759 * 760 * @retval CPA_STATUS_SUCCESS Function executed successfully 761 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 762 * 763 *****************************************************************************/ 764 static CpaStatus 765 dcCreateRequest(dc_compression_cookie_t *pCookie, 766 sal_compression_service_t *pService, 767 dc_session_desc_t *pSessionDesc, 768 CpaDcSessionHandle pSessionHandle, 769 CpaBufferList *pSrcBuff, 770 CpaBufferList *pDestBuff, 771 CpaDcRqResults *pResults, 772 CpaDcFlush flushFlag, 773 CpaDcOpData *pOpData, 774 void *callbackTag, 775 dc_request_dir_t compDecomp, 776 dc_cnv_mode_t cnvMode) 777 { 778 icp_qat_fw_comp_req_t *pMsg = NULL; 779 icp_qat_fw_comp_req_params_t *pCompReqParams = NULL; 780 Cpa64U srcAddrPhys = 0, dstAddrPhys = 0; 781 Cpa64U srcTotalDataLenInBytes = 0, dstTotalDataLenInBytes = 0; 782 783 Cpa32U rpCmdFlags = 0; 784 Cpa8U sop = ICP_QAT_FW_COMP_SOP; 785 Cpa8U eop = ICP_QAT_FW_COMP_EOP; 786 Cpa8U bFinal = ICP_QAT_FW_COMP_NOT_BFINAL; 787 Cpa8U crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY; 788 Cpa8U cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV; 789 Cpa8U cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY; 790 CpaBoolean cnvErrorInjection = ICP_QAT_FW_COMP_NO_CNV_DFX; 791 CpaBoolean integrityCrcCheck = CPA_FALSE; 792 CpaStatus status = CPA_STATUS_SUCCESS; 793 CpaDcFlush flush = CPA_DC_FLUSH_NONE; 794 Cpa32U initial_adler = 1; 795 Cpa32U initial_crc32 = 0; 796 icp_qat_fw_comp_req_t *pReqCache = NULL; 797 798 /* Write the buffer descriptors */ 799 status = LacBuffDesc_BufferListDescWriteAndGetSize( 800 pSrcBuff, 801 &srcAddrPhys, 802 CPA_FALSE, 803 &srcTotalDataLenInBytes, 804 &(pService->generic_service_info)); 805 if (status != CPA_STATUS_SUCCESS) { 806 return status; 807 } 808 809 status = LacBuffDesc_BufferListDescWriteAndGetSize( 810 pDestBuff, 811 &dstAddrPhys, 812 CPA_FALSE, 813 &dstTotalDataLenInBytes, 814 &(pService->generic_service_info)); 815 if (status != CPA_STATUS_SUCCESS) { 816 return status; 817 } 818 819 /* Populate the compression cookie */ 820 pCookie->dcInstance = pService; 821 pCookie->pSessionHandle = pSessionHandle; 822 pCookie->callbackTag = callbackTag; 823 pCookie->pSessionDesc = pSessionDesc; 824 pCookie->pDcOpData = pOpData; 825 pCookie->pResults = pResults; 826 pCookie->compDecomp = compDecomp; 827 pCookie->pUserSrcBuff = NULL; 828 pCookie->pUserDestBuff = NULL; 829 830 /* Extract flush flag from either the opData or from the 831 * parameter. Opdata have been introduce with APIs 832 * cpaDcCompressData2 and cpaDcDecompressData2 */ 833 if (NULL != pOpData) { 834 flush = pOpData->flushFlag; 835 integrityCrcCheck = pOpData->integrityCrcCheck; 836 } else { 837 flush = flushFlag; 838 } 839 pCookie->flushFlag = flush; 840 841 /* The firmware expects the length in bytes for source and destination 842 * to be Cpa32U parameters. However the total data length could be 843 * bigger as allocated by the user. We ensure that this is not the case 844 * in dcCheckSourceData and cast the values to Cpa32U here */ 845 pCookie->srcTotalDataLenInBytes = (Cpa32U)srcTotalDataLenInBytes; 846 if ((isDcGen2x(pService)) && (DC_COMPRESSION_REQUEST == compDecomp) && 847 (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType)) { 848 if (pService->minInterBuffSizeInBytes < 849 (Cpa32U)dstTotalDataLenInBytes) { 850 pCookie->dstTotalDataLenInBytes = 851 (Cpa32U)(pService->minInterBuffSizeInBytes); 852 } else { 853 pCookie->dstTotalDataLenInBytes = 854 (Cpa32U)dstTotalDataLenInBytes; 855 } 856 } else 857 { 858 pCookie->dstTotalDataLenInBytes = 859 (Cpa32U)dstTotalDataLenInBytes; 860 } 861 862 /* Device can not decompress an odd byte decompression request 863 * if bFinal is not set 864 */ 865 if (CPA_TRUE != pService->comp_device_data.oddByteDecompNobFinal) { 866 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) && 867 (CPA_DC_FLUSH_FINAL != flushFlag) && 868 (DC_DECOMPRESSION_REQUEST == compDecomp) && 869 (pCookie->srcTotalDataLenInBytes & 0x1)) { 870 pCookie->srcTotalDataLenInBytes--; 871 } 872 } 873 /* Device can not decompress odd byte interim requests */ 874 if (CPA_TRUE != pService->comp_device_data.oddByteDecompInterim) { 875 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) && 876 (CPA_DC_FLUSH_FINAL != flushFlag) && 877 (CPA_DC_FLUSH_FULL != flushFlag) && 878 (DC_DECOMPRESSION_REQUEST == compDecomp) && 879 (pCookie->srcTotalDataLenInBytes & 0x1)) { 880 pCookie->srcTotalDataLenInBytes--; 881 } 882 } 883 884 pMsg = (icp_qat_fw_comp_req_t *)&pCookie->request; 885 886 if (DC_COMPRESSION_REQUEST == compDecomp) { 887 pReqCache = &(pSessionDesc->reqCacheComp); 888 } else { 889 pReqCache = &(pSessionDesc->reqCacheDecomp); 890 } 891 892 /* Fills the msg from the template cached in the session descriptor */ 893 memcpy((void *)pMsg, 894 (void *)(pReqCache), 895 LAC_QAT_DC_REQ_SZ_LW * LAC_LONG_WORD_IN_BYTES); 896 897 if (DC_REQUEST_FIRST == pSessionDesc->requestType) { 898 initial_adler = 1; 899 initial_crc32 = 0; 900 901 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 902 pSessionDesc->previousChecksum = initial_adler; 903 } else { 904 pSessionDesc->previousChecksum = initial_crc32; 905 } 906 } else if (CPA_DC_STATELESS == pSessionDesc->sessState) { 907 pSessionDesc->previousChecksum = pResults->checksum; 908 909 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 910 initial_adler = pSessionDesc->previousChecksum; 911 } else { 912 initial_crc32 = pSessionDesc->previousChecksum; 913 } 914 } 915 916 /* Backup source and destination buffer addresses, 917 * CRC calculations both for CNV and translator overflow 918 * will be performed on them in the callback function. 919 */ 920 pCookie->pUserSrcBuff = pSrcBuff; 921 pCookie->pUserDestBuff = pDestBuff; 922 923 /* 924 * Due to implementation of CNV support and need for backwards 925 * compatibility certain fields in the request and response structs had 926 * been changed, moved or placed in unions cnvMode flag signifies fields 927 * to be selected from req/res 928 * 929 * Doing extended crc checks makes sense only when we want to do the 930 * actual CNV 931 */ 932 if (CPA_TRUE == pService->generic_service_info.integrityCrcCheck && 933 CPA_TRUE == integrityCrcCheck) { 934 pMsg->comp_pars.crc.crc_data_addr = 935 pSessionDesc->physDataIntegrityCrcs; 936 crcMode = ICP_QAT_FW_COMP_CRC_MODE_E2E; 937 } else { 938 /* Legacy request structure */ 939 pMsg->comp_pars.crc.legacy.initial_adler = initial_adler; 940 pMsg->comp_pars.crc.legacy.initial_crc32 = initial_crc32; 941 crcMode = ICP_QAT_FW_COMP_CRC_MODE_LEGACY; 942 } 943 944 /* Populate the cmdFlags */ 945 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 946 pSessionDesc->previousRequestType = pSessionDesc->requestType; 947 948 if (DC_REQUEST_FIRST == pSessionDesc->requestType) { 949 /* Update the request type for following requests */ 950 pSessionDesc->requestType = DC_REQUEST_SUBSEQUENT; 951 952 /* Reinitialise the cumulative amount of consumed bytes 953 */ 954 pSessionDesc->cumulativeConsumedBytes = 0; 955 956 if (DC_COMPRESSION_REQUEST == compDecomp) { 957 pSessionDesc->isSopForCompressionProcessed = 958 CPA_TRUE; 959 } else if (DC_DECOMPRESSION_REQUEST == compDecomp) { 960 pSessionDesc->isSopForDecompressionProcessed = 961 CPA_TRUE; 962 } 963 } else { 964 if (DC_COMPRESSION_REQUEST == compDecomp) { 965 if (CPA_TRUE == 966 pSessionDesc 967 ->isSopForCompressionProcessed) { 968 sop = ICP_QAT_FW_COMP_NOT_SOP; 969 } else { 970 pSessionDesc 971 ->isSopForCompressionProcessed = 972 CPA_TRUE; 973 } 974 } else if (DC_DECOMPRESSION_REQUEST == compDecomp) { 975 if (CPA_TRUE == 976 pSessionDesc 977 ->isSopForDecompressionProcessed) { 978 sop = ICP_QAT_FW_COMP_NOT_SOP; 979 } else { 980 pSessionDesc 981 ->isSopForDecompressionProcessed = 982 CPA_TRUE; 983 } 984 } 985 } 986 987 if ((CPA_DC_FLUSH_FINAL == flush) || 988 (CPA_DC_FLUSH_FULL == flush)) { 989 /* Update the request type for following requests */ 990 pSessionDesc->requestType = DC_REQUEST_FIRST; 991 } else { 992 eop = ICP_QAT_FW_COMP_NOT_EOP; 993 } 994 } else { 995 if (DC_REQUEST_FIRST == pSessionDesc->requestType) { 996 /* Reinitialise the cumulative amount of consumed bytes 997 */ 998 pSessionDesc->cumulativeConsumedBytes = 0; 999 } 1000 } 1001 1002 /* (LW 14 - 15) */ 1003 pCompReqParams = &(pMsg->comp_pars); 1004 dcCompRequestParamsPopulate(pCompReqParams, pCookie); 1005 if (CPA_DC_FLUSH_FINAL == flush) { 1006 bFinal = ICP_QAT_FW_COMP_BFINAL; 1007 } 1008 1009 switch (cnvMode) { 1010 case DC_CNVNR: 1011 cnvRecovery = ICP_QAT_FW_COMP_CNV_RECOVERY; 1012 /* Fall through is intended here, because for CNVNR 1013 * cnvDecompReq also needs to be set */ 1014 case DC_CNV: 1015 cnvDecompReq = ICP_QAT_FW_COMP_CNV; 1016 if (isDcGen4x(pService)) { 1017 cnvErrorInjection = pSessionDesc->cnvErrorInjection; 1018 } 1019 break; 1020 case DC_NO_CNV: 1021 cnvDecompReq = ICP_QAT_FW_COMP_NO_CNV; 1022 cnvRecovery = ICP_QAT_FW_COMP_NO_CNV_RECOVERY; 1023 break; 1024 } 1025 1026 /* LW 18 */ 1027 rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD(sop, 1028 eop, 1029 bFinal, 1030 cnvDecompReq, 1031 cnvRecovery, 1032 cnvErrorInjection, 1033 crcMode); 1034 1035 pMsg->comp_pars.req_par_flags = rpCmdFlags; 1036 1037 /* Populates the QAT common request middle part of the message 1038 * (LW 6 to 11) */ 1039 SalQatMsg_CmnMidWrite((icp_qat_fw_la_bulk_req_t *)pMsg, 1040 pCookie, 1041 DC_DEFAULT_QAT_PTR_TYPE, 1042 srcAddrPhys, 1043 dstAddrPhys, 1044 0, 1045 0); 1046 1047 return CPA_STATUS_SUCCESS; 1048 } 1049 1050 /** 1051 ***************************************************************************** 1052 * @ingroup Dc_DataCompression 1053 * Send a compression request to QAT 1054 * 1055 * @description 1056 * Send the requests for compression or decompression to QAT 1057 * 1058 * @param{in] pCookie Pointer to the compression cookie 1059 * @param[in] pService Pointer to the compression service 1060 * @param[in] pSessionDesc Pointer to the session descriptor 1061 * @param[in] compDecomp Direction of the operation 1062 * 1063 * @retval CPA_STATUS_SUCCESS Function executed successfully 1064 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 1065 * 1066 *****************************************************************************/ 1067 static CpaStatus 1068 dcSendRequest(dc_compression_cookie_t *pCookie, 1069 sal_compression_service_t *pService, 1070 dc_session_desc_t *pSessionDesc, 1071 dc_request_dir_t compDecomp) 1072 { 1073 CpaStatus status = CPA_STATUS_SUCCESS; 1074 1075 /* Send to QAT */ 1076 status = icp_adf_transPutMsg(pService->trans_handle_compression_tx, 1077 (void *)&(pCookie->request), 1078 LAC_QAT_DC_REQ_SZ_LW); 1079 1080 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) && 1081 (CPA_STATUS_RETRY == status)) { 1082 /* reset requestType after receiving an retry on 1083 * the stateful request */ 1084 pSessionDesc->requestType = pSessionDesc->previousRequestType; 1085 } 1086 1087 return status; 1088 } 1089 1090 /** 1091 ***************************************************************************** 1092 * @ingroup Dc_DataCompression 1093 * Process the synchronous and asynchronous case for compression or 1094 * decompression 1095 * 1096 * @description 1097 * Process the synchronous and asynchronous case for compression or 1098 * decompression. This function will then create and send the request to 1099 * the firmware. 1100 * 1101 * @param[in] pService Pointer to the compression service 1102 * @param[in] pSessionDesc Pointer to the session descriptor 1103 * @param[in] dcInstance Instance handle derived from discovery 1104 * functions 1105 * @param[in] pSessionHandle Session handle 1106 * @param[in] numRequests Number of operations in the batch request 1107 * @param[in] pBatchOpData Address of the list of jobs to be processed 1108 * @param[in] pSrcBuff Pointer to data buffer for compression 1109 * @param[in] pDestBuff Pointer to buffer space for data after 1110 * compression 1111 * @param[in] pResults Pointer to results structure 1112 * @param[in] flushFlag Indicates the type of flush to be 1113 * performed 1114 * @param[in] pOpData Pointer to request information structure 1115 * holding parameters for cpaDcCompress2 and 1116 * CpaDcDecompressData2 1117 * @param[in] callbackTag Pointer to the callback tag 1118 * @param[in] compDecomp Direction of the operation 1119 * @param[in] isAsyncMode Used to know if synchronous or asynchronous 1120 * mode 1121 * @param[in] cnvMode CNV Mode 1122 * 1123 * @retval CPA_STATUS_SUCCESS Function executed successfully 1124 * @retval CPA_STATUS_RETRY Retry operation 1125 * @retval CPA_STATUS_FAIL Function failed 1126 * @retval CPA_STATUS_RESOURCE Resource error 1127 * 1128 *****************************************************************************/ 1129 static CpaStatus 1130 dcCompDecompData(sal_compression_service_t *pService, 1131 dc_session_desc_t *pSessionDesc, 1132 CpaInstanceHandle dcInstance, 1133 CpaDcSessionHandle pSessionHandle, 1134 CpaBufferList *pSrcBuff, 1135 CpaBufferList *pDestBuff, 1136 CpaDcRqResults *pResults, 1137 CpaDcFlush flushFlag, 1138 CpaDcOpData *pOpData, 1139 void *callbackTag, 1140 dc_request_dir_t compDecomp, 1141 CpaBoolean isAsyncMode, 1142 dc_cnv_mode_t cnvMode) 1143 { 1144 CpaStatus status = CPA_STATUS_SUCCESS; 1145 dc_compression_cookie_t *pCookie = NULL; 1146 1147 if ((LacSync_GenWakeupSyncCaller == pSessionDesc->pCompressionCb) && 1148 isAsyncMode == CPA_TRUE) { 1149 lac_sync_op_data_t *pSyncCallbackData = NULL; 1150 1151 status = LacSync_CreateSyncCookie(&pSyncCallbackData); 1152 1153 if (CPA_STATUS_SUCCESS == status) { 1154 status = dcCompDecompData(pService, 1155 pSessionDesc, 1156 dcInstance, 1157 pSessionHandle, 1158 pSrcBuff, 1159 pDestBuff, 1160 pResults, 1161 flushFlag, 1162 pOpData, 1163 pSyncCallbackData, 1164 compDecomp, 1165 CPA_FALSE, 1166 cnvMode); 1167 } else { 1168 return status; 1169 } 1170 1171 if (CPA_STATUS_SUCCESS == status) { 1172 CpaStatus syncStatus = CPA_STATUS_SUCCESS; 1173 1174 syncStatus = 1175 LacSync_WaitForCallback(pSyncCallbackData, 1176 DC_SYNC_CALLBACK_TIMEOUT, 1177 &status, 1178 NULL); 1179 1180 /* If callback doesn't come back */ 1181 if (CPA_STATUS_SUCCESS != syncStatus) { 1182 if (DC_COMPRESSION_REQUEST == compDecomp) { 1183 COMPRESSION_STAT_INC( 1184 numCompCompletedErrors, pService); 1185 } else { 1186 COMPRESSION_STAT_INC( 1187 numDecompCompletedErrors, pService); 1188 } 1189 LAC_LOG_ERROR("Callback timed out"); 1190 status = syncStatus; 1191 } 1192 } else { 1193 /* As the Request was not sent the Callback will never 1194 * be called, so need to indicate that we're finished 1195 * with cookie so it can be destroyed. */ 1196 LacSync_SetSyncCookieComplete(pSyncCallbackData); 1197 } 1198 1199 LacSync_DestroySyncCookie(&pSyncCallbackData); 1200 return status; 1201 } 1202 1203 /* Allocate the compression cookie 1204 * The memory is freed in callback or in sendRequest if an error occurs 1205 */ 1206 pCookie = (dc_compression_cookie_t *)Lac_MemPoolEntryAlloc( 1207 pService->compression_mem_pool); 1208 if (NULL == pCookie) { 1209 LAC_LOG_ERROR("Cannot get mem pool entry for compression"); 1210 status = CPA_STATUS_RESOURCE; 1211 } else if ((void *)CPA_STATUS_RETRY == pCookie) { 1212 pCookie = NULL; 1213 status = CPA_STATUS_RETRY; 1214 } 1215 1216 if (CPA_STATUS_SUCCESS == status) { 1217 status = dcCreateRequest(pCookie, 1218 pService, 1219 pSessionDesc, 1220 pSessionHandle, 1221 pSrcBuff, 1222 pDestBuff, 1223 pResults, 1224 flushFlag, 1225 pOpData, 1226 callbackTag, 1227 compDecomp, 1228 cnvMode); 1229 } 1230 1231 if (CPA_STATUS_SUCCESS == status) { 1232 /* Increment number of pending callbacks for session */ 1233 if (CPA_DC_STATELESS == pSessionDesc->sessState) { 1234 qatUtilsAtomicInc( 1235 &(pSessionDesc->pendingStatelessCbCount)); 1236 } 1237 status = 1238 dcSendRequest(pCookie, pService, pSessionDesc, compDecomp); 1239 } 1240 1241 if (CPA_STATUS_SUCCESS == status) { 1242 if (DC_COMPRESSION_REQUEST == compDecomp) { 1243 COMPRESSION_STAT_INC(numCompRequests, pService); 1244 } else { 1245 COMPRESSION_STAT_INC(numDecompRequests, pService); 1246 } 1247 } else { 1248 if (DC_COMPRESSION_REQUEST == compDecomp) { 1249 COMPRESSION_STAT_INC(numCompRequestsErrors, pService); 1250 } else { 1251 COMPRESSION_STAT_INC(numDecompRequestsErrors, pService); 1252 } 1253 1254 /* Decrement number of pending callbacks for session */ 1255 if (CPA_DC_STATELESS == pSessionDesc->sessState) { 1256 qatUtilsAtomicDec( 1257 &(pSessionDesc->pendingStatelessCbCount)); 1258 } else { 1259 qatUtilsAtomicDec( 1260 &(pSessionDesc->pendingStatefulCbCount)); 1261 } 1262 1263 /* Free the memory pool */ 1264 if (NULL != pCookie) { 1265 if (status != CPA_STATUS_UNSUPPORTED) { 1266 /* Free the memory pool */ 1267 Lac_MemPoolEntryFree(pCookie); 1268 pCookie = NULL; 1269 } 1270 } 1271 } 1272 1273 return status; 1274 } 1275 1276 /** 1277 ***************************************************************************** 1278 * @ingroup Dc_DataCompression 1279 * Handle zero length compression or decompression requests 1280 * 1281 * @description 1282 * Handle zero length compression or decompression requests 1283 * 1284 * @param[in] pService Pointer to the compression service 1285 * @param[in] pSessionDesc Pointer to the session descriptor 1286 * @param[in] pResults Pointer to results structure 1287 * @param[in] flushFlag Indicates the type of flush to be 1288 * performed 1289 * @param[in] callbackTag User supplied value to help correlate 1290 * the callback with its associated request 1291 * @param[in] compDecomp Direction of the operation 1292 * 1293 * @retval CPA_TRUE Zero length SOP or MOP processed 1294 * @retval CPA_FALSE Zero length EOP 1295 * 1296 *****************************************************************************/ 1297 static CpaStatus 1298 dcZeroLengthRequests(sal_compression_service_t *pService, 1299 dc_session_desc_t *pSessionDesc, 1300 CpaDcRqResults *pResults, 1301 CpaDcFlush flushFlag, 1302 void *callbackTag, 1303 dc_request_dir_t compDecomp) 1304 { 1305 CpaBoolean status = CPA_FALSE; 1306 CpaDcCallbackFn pCbFunc = pSessionDesc->pCompressionCb; 1307 1308 if (DC_REQUEST_FIRST == pSessionDesc->requestType) { 1309 /* Reinitialise the cumulative amount of consumed bytes */ 1310 pSessionDesc->cumulativeConsumedBytes = 0; 1311 1312 /* Zero length SOP */ 1313 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 1314 pResults->checksum = 1; 1315 } else { 1316 pResults->checksum = 0; 1317 } 1318 1319 status = CPA_TRUE; 1320 } else if ((CPA_DC_FLUSH_NONE == flushFlag) || 1321 (CPA_DC_FLUSH_SYNC == flushFlag)) { 1322 /* Zero length MOP */ 1323 pResults->checksum = pSessionDesc->previousChecksum; 1324 status = CPA_TRUE; 1325 } 1326 1327 if (CPA_TRUE == status) { 1328 pResults->status = CPA_DC_OK; 1329 pResults->produced = 0; 1330 pResults->consumed = 0; 1331 1332 /* Increment statistics */ 1333 if (DC_COMPRESSION_REQUEST == compDecomp) { 1334 COMPRESSION_STAT_INC(numCompRequests, pService); 1335 COMPRESSION_STAT_INC(numCompCompleted, pService); 1336 } else { 1337 COMPRESSION_STAT_INC(numDecompRequests, pService); 1338 COMPRESSION_STAT_INC(numDecompCompleted, pService); 1339 } 1340 1341 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1342 1343 if ((NULL != pCbFunc) && 1344 (LacSync_GenWakeupSyncCaller != pCbFunc)) { 1345 pCbFunc(callbackTag, CPA_STATUS_SUCCESS); 1346 } 1347 1348 return CPA_TRUE; 1349 } 1350 1351 return CPA_FALSE; 1352 } 1353 1354 static CpaStatus 1355 dcParamCheck(CpaInstanceHandle dcInstance, 1356 CpaDcSessionHandle pSessionHandle, 1357 sal_compression_service_t *pService, 1358 CpaBufferList *pSrcBuff, 1359 CpaBufferList *pDestBuff, 1360 CpaDcRqResults *pResults, 1361 dc_session_desc_t *pSessionDesc, 1362 CpaDcFlush flushFlag, 1363 Cpa64U srcBuffSize) 1364 { 1365 1366 if (dcCheckSourceData(pSessionHandle, 1367 pSrcBuff, 1368 pDestBuff, 1369 pResults, 1370 flushFlag, 1371 srcBuffSize, 1372 NULL) != CPA_STATUS_SUCCESS) { 1373 return CPA_STATUS_INVALID_PARAM; 1374 } 1375 if (dcCheckDestinationData( 1376 pService, pSessionHandle, pDestBuff, DC_COMPRESSION_REQUEST) != 1377 CPA_STATUS_SUCCESS) { 1378 return CPA_STATUS_INVALID_PARAM; 1379 } 1380 if (CPA_DC_DIR_DECOMPRESS == pSessionDesc->sessDirection) { 1381 LAC_INVALID_PARAM_LOG("Invalid sessDirection value"); 1382 return CPA_STATUS_INVALID_PARAM; 1383 } 1384 return CPA_STATUS_SUCCESS; 1385 } 1386 1387 CpaStatus 1388 cpaDcCompressData(CpaInstanceHandle dcInstance, 1389 CpaDcSessionHandle pSessionHandle, 1390 CpaBufferList *pSrcBuff, 1391 CpaBufferList *pDestBuff, 1392 CpaDcRqResults *pResults, 1393 CpaDcFlush flushFlag, 1394 void *callbackTag) 1395 { 1396 sal_compression_service_t *pService = NULL; 1397 dc_session_desc_t *pSessionDesc = NULL; 1398 CpaInstanceHandle insHandle = NULL; 1399 Cpa64U srcBuffSize = 0; 1400 1401 1402 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 1403 insHandle = dcGetFirstHandle(); 1404 } else { 1405 insHandle = dcInstance; 1406 } 1407 1408 pService = (sal_compression_service_t *)insHandle; 1409 1410 LAC_CHECK_NULL_PARAM(insHandle); 1411 LAC_CHECK_NULL_PARAM(pSessionHandle); 1412 1413 /* Check if SAL is initialised otherwise return an error */ 1414 SAL_RUNNING_CHECK(insHandle); 1415 1416 /* This check is outside the parameter checking as it is needed to 1417 * manage zero length requests */ 1418 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff, 1419 &srcBuffSize, 1420 LAC_NO_ALIGNMENT_SHIFT) != 1421 CPA_STATUS_SUCCESS) { 1422 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter"); 1423 return CPA_STATUS_INVALID_PARAM; 1424 } 1425 1426 /* Ensure this is a compression instance */ 1427 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 1428 1429 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 1430 if (CPA_STATUS_SUCCESS != 1431 dcParamCheck(insHandle, 1432 pSessionHandle, 1433 pService, 1434 pSrcBuff, 1435 pDestBuff, 1436 pResults, 1437 pSessionDesc, 1438 flushFlag, 1439 srcBuffSize)) { 1440 return CPA_STATUS_INVALID_PARAM; 1441 } 1442 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 1443 LAC_INVALID_PARAM_LOG( 1444 "Invalid session state, stateful sessions " 1445 "are not supported"); 1446 return CPA_STATUS_UNSUPPORTED; 1447 } 1448 1449 if (!(pService->generic_service_info.dcExtendedFeatures & 1450 DC_CNV_EXTENDED_CAPABILITY)) { 1451 LAC_INVALID_PARAM_LOG( 1452 "CompressAndVerify feature not supported"); 1453 return CPA_STATUS_UNSUPPORTED; 1454 } 1455 1456 if (!(pService->generic_service_info.dcExtendedFeatures & 1457 DC_CNVNR_EXTENDED_CAPABILITY)) { 1458 LAC_INVALID_PARAM_LOG( 1459 "CompressAndVerifyAndRecovery feature not supported"); 1460 return CPA_STATUS_UNSUPPORTED; 1461 } 1462 1463 return dcCompDecompData(pService, 1464 pSessionDesc, 1465 insHandle, 1466 pSessionHandle, 1467 pSrcBuff, 1468 pDestBuff, 1469 pResults, 1470 flushFlag, 1471 NULL, 1472 callbackTag, 1473 DC_COMPRESSION_REQUEST, 1474 CPA_TRUE, 1475 DC_CNVNR); 1476 } 1477 1478 CpaStatus 1479 cpaDcCompressData2(CpaInstanceHandle dcInstance, 1480 CpaDcSessionHandle pSessionHandle, 1481 CpaBufferList *pSrcBuff, 1482 CpaBufferList *pDestBuff, 1483 CpaDcOpData *pOpData, 1484 CpaDcRqResults *pResults, 1485 void *callbackTag) 1486 { 1487 sal_compression_service_t *pService = NULL; 1488 dc_session_desc_t *pSessionDesc = NULL; 1489 CpaInstanceHandle insHandle = NULL; 1490 Cpa64U srcBuffSize = 0; 1491 dc_cnv_mode_t cnvMode = DC_NO_CNV; 1492 1493 LAC_CHECK_NULL_PARAM(pOpData); 1494 1495 if (((CPA_TRUE != pOpData->compressAndVerify) && 1496 (CPA_FALSE != pOpData->compressAndVerify)) || 1497 ((CPA_FALSE != pOpData->compressAndVerifyAndRecover) && 1498 (CPA_TRUE != pOpData->compressAndVerifyAndRecover))) { 1499 return CPA_STATUS_INVALID_PARAM; 1500 } 1501 1502 if ((CPA_FALSE == pOpData->compressAndVerify) && 1503 (CPA_TRUE == pOpData->compressAndVerifyAndRecover)) { 1504 return CPA_STATUS_INVALID_PARAM; 1505 } 1506 1507 1508 if ((CPA_TRUE == pOpData->compressAndVerify) && 1509 (CPA_TRUE == pOpData->compressAndVerifyAndRecover) && 1510 (CPA_FALSE == pOpData->integrityCrcCheck)) { 1511 return cpaDcCompressData(dcInstance, 1512 pSessionHandle, 1513 pSrcBuff, 1514 pDestBuff, 1515 pResults, 1516 pOpData->flushFlag, 1517 callbackTag); 1518 } 1519 1520 if (CPA_FALSE == pOpData->compressAndVerify) { 1521 LAC_INVALID_PARAM_LOG( 1522 "Data compression without verification not allowed"); 1523 return CPA_STATUS_UNSUPPORTED; 1524 } 1525 1526 1527 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 1528 insHandle = dcGetFirstHandle(); 1529 } else { 1530 insHandle = dcInstance; 1531 } 1532 1533 pService = (sal_compression_service_t *)insHandle; 1534 1535 LAC_CHECK_NULL_PARAM(insHandle); 1536 LAC_CHECK_NULL_PARAM(pSessionHandle); 1537 LAC_CHECK_NULL_PARAM(pOpData); 1538 1539 /* Check if SAL is initialised otherwise return an error */ 1540 SAL_RUNNING_CHECK(insHandle); 1541 1542 /* This check is outside the parameter checking as it is needed to 1543 * manage zero length requests */ 1544 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff, 1545 &srcBuffSize, 1546 LAC_NO_ALIGNMENT_SHIFT) != 1547 CPA_STATUS_SUCCESS) { 1548 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter"); 1549 return CPA_STATUS_INVALID_PARAM; 1550 } 1551 1552 /* Ensure this is a compression instance */ 1553 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 1554 1555 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 1556 1557 if (CPA_TRUE == pOpData->compressAndVerify && 1558 CPA_DC_STATEFUL == pSessionDesc->sessState) { 1559 LAC_INVALID_PARAM_LOG( 1560 "Invalid session state, stateful sessions " 1561 "not supported with CNV"); 1562 return CPA_STATUS_UNSUPPORTED; 1563 } 1564 1565 if (!(pService->generic_service_info.dcExtendedFeatures & 1566 DC_CNV_EXTENDED_CAPABILITY) && 1567 (CPA_TRUE == pOpData->compressAndVerify)) { 1568 LAC_INVALID_PARAM_LOG( 1569 "CompressAndVerify feature not supported"); 1570 return CPA_STATUS_UNSUPPORTED; 1571 } 1572 1573 if (CPA_STATUS_SUCCESS != 1574 dcParamCheck(insHandle, 1575 pSessionHandle, 1576 pService, 1577 pSrcBuff, 1578 pDestBuff, 1579 pResults, 1580 pSessionDesc, 1581 pOpData->flushFlag, 1582 srcBuffSize)) { 1583 return CPA_STATUS_INVALID_PARAM; 1584 } 1585 if (CPA_STATUS_SUCCESS != dcCheckOpData(pService, pOpData)) { 1586 return CPA_STATUS_INVALID_PARAM; 1587 } 1588 if (CPA_TRUE != pOpData->compressAndVerify) { 1589 if (srcBuffSize > DC_COMP_MAX_BUFF_SIZE) { 1590 LAC_LOG_ERROR( 1591 "Compression payload greater than 64KB is " 1592 "unsupported, when CnV is disabled\n"); 1593 return CPA_STATUS_UNSUPPORTED; 1594 } 1595 } 1596 1597 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 1598 /* Lock the session to check if there are in-flight stateful 1599 * requests */ 1600 LAC_SPINLOCK(&(pSessionDesc->sessionLock)); 1601 1602 /* Check if there is already one in-flight stateful request */ 1603 if (0 != 1604 qatUtilsAtomicGet( 1605 &(pSessionDesc->pendingStatefulCbCount))) { 1606 LAC_LOG_ERROR( 1607 "Only one in-flight stateful request supported"); 1608 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1609 return CPA_STATUS_RETRY; 1610 } 1611 1612 if (0 == srcBuffSize) { 1613 if (CPA_TRUE == 1614 dcZeroLengthRequests(pService, 1615 pSessionDesc, 1616 pResults, 1617 pOpData->flushFlag, 1618 callbackTag, 1619 DC_COMPRESSION_REQUEST)) { 1620 return CPA_STATUS_SUCCESS; 1621 } 1622 } 1623 1624 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount)); 1625 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1626 } 1627 1628 if (CPA_TRUE == pOpData->compressAndVerify) { 1629 cnvMode = DC_CNV; 1630 } 1631 1632 return dcCompDecompData(pService, 1633 pSessionDesc, 1634 insHandle, 1635 pSessionHandle, 1636 pSrcBuff, 1637 pDestBuff, 1638 pResults, 1639 pOpData->flushFlag, 1640 pOpData, 1641 callbackTag, 1642 DC_COMPRESSION_REQUEST, 1643 CPA_TRUE, 1644 cnvMode); 1645 } 1646 1647 static CpaStatus 1648 dcDecompressDataCheck(CpaInstanceHandle insHandle, 1649 CpaDcSessionHandle pSessionHandle, 1650 CpaBufferList *pSrcBuff, 1651 CpaBufferList *pDestBuff, 1652 CpaDcRqResults *pResults, 1653 CpaDcFlush flushFlag, 1654 Cpa64U *srcBufferSize) 1655 { 1656 sal_compression_service_t *pService = NULL; 1657 dc_session_desc_t *pSessionDesc = NULL; 1658 Cpa64U srcBuffSize = 0; 1659 1660 pService = (sal_compression_service_t *)insHandle; 1661 1662 LAC_CHECK_NULL_PARAM(insHandle); 1663 1664 /* Check if SAL is initialised otherwise return an error */ 1665 SAL_RUNNING_CHECK(insHandle); 1666 1667 /* This check is outside the parameter checking as it is needed to 1668 * manage zero length requests */ 1669 if (LacBuffDesc_BufferListVerifyNull(pSrcBuff, 1670 &srcBuffSize, 1671 LAC_NO_ALIGNMENT_SHIFT) != 1672 CPA_STATUS_SUCCESS) { 1673 LAC_INVALID_PARAM_LOG("Invalid source buffer list parameter"); 1674 return CPA_STATUS_INVALID_PARAM; 1675 } 1676 1677 /* Ensure this is a compression instance */ 1678 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 1679 1680 if (dcCheckSourceData(pSessionHandle, 1681 pSrcBuff, 1682 pDestBuff, 1683 pResults, 1684 flushFlag, 1685 srcBuffSize, 1686 NULL) != CPA_STATUS_SUCCESS) { 1687 return CPA_STATUS_INVALID_PARAM; 1688 } 1689 if (dcCheckDestinationData(pService, 1690 pSessionHandle, 1691 pDestBuff, 1692 DC_DECOMPRESSION_REQUEST) != 1693 CPA_STATUS_SUCCESS) { 1694 return CPA_STATUS_INVALID_PARAM; 1695 } 1696 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 1697 1698 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) { 1699 LAC_INVALID_PARAM_LOG("Invalid sessDirection value"); 1700 return CPA_STATUS_INVALID_PARAM; 1701 } 1702 1703 1704 *srcBufferSize = srcBuffSize; 1705 1706 return CPA_STATUS_SUCCESS; 1707 } 1708 1709 CpaStatus 1710 cpaDcDecompressData(CpaInstanceHandle dcInstance, 1711 CpaDcSessionHandle pSessionHandle, 1712 CpaBufferList *pSrcBuff, 1713 CpaBufferList *pDestBuff, 1714 CpaDcRqResults *pResults, 1715 CpaDcFlush flushFlag, 1716 void *callbackTag) 1717 { 1718 sal_compression_service_t *pService = NULL; 1719 dc_session_desc_t *pSessionDesc = NULL; 1720 CpaInstanceHandle insHandle = NULL; 1721 Cpa64U srcBuffSize = 0; 1722 CpaStatus status = CPA_STATUS_SUCCESS; 1723 1724 1725 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 1726 insHandle = dcGetFirstHandle(); 1727 } else { 1728 insHandle = dcInstance; 1729 } 1730 1731 status = dcDecompressDataCheck(insHandle, 1732 pSessionHandle, 1733 pSrcBuff, 1734 pDestBuff, 1735 pResults, 1736 flushFlag, 1737 &srcBuffSize); 1738 if (CPA_STATUS_SUCCESS != status) { 1739 return status; 1740 } 1741 1742 pService = (sal_compression_service_t *)insHandle; 1743 1744 /* Check if SAL is initialised otherwise return an error */ 1745 SAL_RUNNING_CHECK(insHandle); 1746 1747 /* This check is outside the parameter checking as it is needed to 1748 * manage zero length requests */ 1749 if (CPA_STATUS_SUCCESS != 1750 LacBuffDesc_BufferListVerifyNull(pSrcBuff, 1751 &srcBuffSize, 1752 LAC_NO_ALIGNMENT_SHIFT)) { 1753 QAT_UTILS_LOG("Invalid source buffer list parameter"); 1754 return CPA_STATUS_INVALID_PARAM; 1755 } 1756 1757 /* Ensure this is a compression instance */ 1758 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 1759 1760 if (dcCheckSourceData(pSessionHandle, 1761 pSrcBuff, 1762 pDestBuff, 1763 pResults, 1764 flushFlag, 1765 srcBuffSize, 1766 NULL) != CPA_STATUS_SUCCESS) { 1767 return CPA_STATUS_INVALID_PARAM; 1768 } 1769 if (dcCheckDestinationData(pService, 1770 pSessionHandle, 1771 pDestBuff, 1772 DC_DECOMPRESSION_REQUEST) != 1773 CPA_STATUS_SUCCESS) { 1774 return CPA_STATUS_INVALID_PARAM; 1775 } 1776 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 1777 1778 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) { 1779 QAT_UTILS_LOG("Invalid sessDirection value"); 1780 return CPA_STATUS_INVALID_PARAM; 1781 } 1782 1783 1784 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 1785 /* Lock the session to check if there are in-flight stateful 1786 * requests */ 1787 LAC_SPINLOCK(&(pSessionDesc->sessionLock)); 1788 1789 /* Check if there is already one in-flight stateful request */ 1790 if (0 != 1791 qatUtilsAtomicGet( 1792 &(pSessionDesc->pendingStatefulCbCount))) { 1793 LAC_LOG_ERROR( 1794 "Only one in-flight stateful request supported"); 1795 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1796 return CPA_STATUS_RETRY; 1797 } 1798 1799 /* Gen 4 handle 0 len requests in FW */ 1800 if (isDcGen2x(pService)) { 1801 if ((0 == srcBuffSize) || 1802 ((1 == srcBuffSize) && 1803 (CPA_DC_FLUSH_FINAL != flushFlag) && 1804 (CPA_DC_FLUSH_FULL != flushFlag))) { 1805 if (CPA_TRUE == 1806 dcZeroLengthRequests( 1807 pService, 1808 pSessionDesc, 1809 pResults, 1810 flushFlag, 1811 callbackTag, 1812 DC_DECOMPRESSION_REQUEST)) { 1813 return CPA_STATUS_SUCCESS; 1814 } 1815 } 1816 } 1817 1818 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount)); 1819 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1820 } 1821 1822 return dcCompDecompData(pService, 1823 pSessionDesc, 1824 insHandle, 1825 pSessionHandle, 1826 pSrcBuff, 1827 pDestBuff, 1828 pResults, 1829 flushFlag, 1830 NULL, 1831 callbackTag, 1832 DC_DECOMPRESSION_REQUEST, 1833 CPA_TRUE, 1834 DC_NO_CNV); 1835 } 1836 1837 CpaStatus 1838 cpaDcDecompressData2(CpaInstanceHandle dcInstance, 1839 CpaDcSessionHandle pSessionHandle, 1840 CpaBufferList *pSrcBuff, 1841 CpaBufferList *pDestBuff, 1842 CpaDcOpData *pOpData, 1843 CpaDcRqResults *pResults, 1844 void *callbackTag) 1845 { 1846 sal_compression_service_t *pService = NULL; 1847 dc_session_desc_t *pSessionDesc = NULL; 1848 CpaInstanceHandle insHandle = NULL; 1849 CpaStatus status = CPA_STATUS_SUCCESS; 1850 Cpa64U srcBuffSize = 0; 1851 LAC_CHECK_NULL_PARAM(pOpData); 1852 1853 if (CPA_FALSE == pOpData->integrityCrcCheck) { 1854 1855 return cpaDcDecompressData(dcInstance, 1856 pSessionHandle, 1857 pSrcBuff, 1858 pDestBuff, 1859 pResults, 1860 pOpData->flushFlag, 1861 callbackTag); 1862 } 1863 1864 1865 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 1866 insHandle = dcGetFirstHandle(); 1867 } else { 1868 insHandle = dcInstance; 1869 } 1870 1871 status = dcDecompressDataCheck(insHandle, 1872 pSessionHandle, 1873 pSrcBuff, 1874 pDestBuff, 1875 pResults, 1876 pOpData->flushFlag, 1877 &srcBuffSize); 1878 if (CPA_STATUS_SUCCESS != status) { 1879 return status; 1880 } 1881 1882 pService = (sal_compression_service_t *)insHandle; 1883 1884 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 1885 1886 LAC_CHECK_NULL_PARAM(insHandle); 1887 1888 /* Check if SAL is initialised otherwise return an error */ 1889 SAL_RUNNING_CHECK(insHandle); 1890 1891 /* This check is outside the parameter checking as it is needed to 1892 * manage zero length requests */ 1893 if (CPA_STATUS_SUCCESS != 1894 LacBuffDesc_BufferListVerifyNull(pSrcBuff, 1895 &srcBuffSize, 1896 LAC_NO_ALIGNMENT_SHIFT)) { 1897 QAT_UTILS_LOG("Invalid source buffer list parameter"); 1898 return CPA_STATUS_INVALID_PARAM; 1899 } 1900 1901 /* Ensure this is a compression instance */ 1902 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 1903 1904 if (CPA_STATUS_SUCCESS != 1905 dcCheckSourceData(pSessionHandle, 1906 pSrcBuff, 1907 pDestBuff, 1908 pResults, 1909 CPA_DC_FLUSH_NONE, 1910 srcBuffSize, 1911 NULL)) { 1912 return CPA_STATUS_INVALID_PARAM; 1913 } 1914 if (CPA_STATUS_SUCCESS != 1915 dcCheckDestinationData(pService, 1916 pSessionHandle, 1917 pDestBuff, 1918 DC_DECOMPRESSION_REQUEST)) { 1919 return CPA_STATUS_INVALID_PARAM; 1920 } 1921 1922 if (CPA_STATUS_SUCCESS != dcCheckOpData(pService, pOpData)) { 1923 return CPA_STATUS_INVALID_PARAM; 1924 } 1925 1926 if (CPA_DC_DIR_COMPRESS == pSessionDesc->sessDirection) { 1927 QAT_UTILS_LOG("Invalid sessDirection value"); 1928 return CPA_STATUS_INVALID_PARAM; 1929 } 1930 1931 1932 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 1933 /* Lock the session to check if there are in-flight stateful 1934 * requests */ 1935 LAC_SPINLOCK(&(pSessionDesc->sessionLock)); 1936 1937 /* Check if there is already one in-flight stateful request */ 1938 if (0 != 1939 qatUtilsAtomicGet( 1940 &(pSessionDesc->pendingStatefulCbCount))) { 1941 LAC_LOG_ERROR( 1942 "Only one in-flight stateful request supported"); 1943 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1944 return CPA_STATUS_RETRY; 1945 } 1946 1947 /* Gen 4 handle 0 len requests in FW */ 1948 if (isDcGen2x(pService)) { 1949 if ((0 == srcBuffSize) || 1950 ((1 == srcBuffSize) && 1951 (CPA_DC_FLUSH_FINAL != pOpData->flushFlag) && 1952 (CPA_DC_FLUSH_FULL != pOpData->flushFlag))) { 1953 if (CPA_TRUE == 1954 dcZeroLengthRequests( 1955 pService, 1956 pSessionDesc, 1957 pResults, 1958 pOpData->flushFlag, 1959 callbackTag, 1960 DC_DECOMPRESSION_REQUEST)) { 1961 return CPA_STATUS_SUCCESS; 1962 } 1963 } 1964 } 1965 qatUtilsAtomicInc(&(pSessionDesc->pendingStatefulCbCount)); 1966 LAC_SPINUNLOCK(&(pSessionDesc->sessionLock)); 1967 } 1968 1969 return dcCompDecompData(pService, 1970 pSessionDesc, 1971 insHandle, 1972 pSessionHandle, 1973 pSrcBuff, 1974 pDestBuff, 1975 pResults, 1976 pOpData->flushFlag, 1977 pOpData, 1978 callbackTag, 1979 DC_DECOMPRESSION_REQUEST, 1980 CPA_TRUE, 1981 DC_NO_CNV); 1982 } 1983