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