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