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