1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 /* $FreeBSD$ */ 4 /** 5 ***************************************************************************** 6 * @file dc_session.c 7 * 8 * @ingroup Dc_DataCompression 9 * 10 * @description 11 * Implementation of the Data Compression session operations. 12 * 13 *****************************************************************************/ 14 15 /* 16 ******************************************************************************* 17 * Include public/global header files 18 ******************************************************************************* 19 */ 20 #include "cpa.h" 21 #include "cpa_dc.h" 22 23 #include "icp_qat_fw.h" 24 #include "icp_qat_fw_comp.h" 25 #include "icp_qat_hw.h" 26 27 /* 28 ******************************************************************************* 29 * Include private header files 30 ******************************************************************************* 31 */ 32 #include "dc_session.h" 33 #include "dc_datapath.h" 34 #include "lac_mem_pools.h" 35 #include "sal_types_compression.h" 36 #include "lac_buffer_desc.h" 37 #include "sal_service_state.h" 38 #include "sal_qat_cmn_msg.h" 39 40 /** 41 ***************************************************************************** 42 * @ingroup Dc_DataCompression 43 * Check that pSessionData is valid 44 * 45 * @description 46 * Check that all the parameters defined in the pSessionData are valid 47 * 48 * @param[in] pSessionData Pointer to a user instantiated structure 49 * containing session data 50 * 51 * @retval CPA_STATUS_SUCCESS Function executed successfully 52 * @retval CPA_STATUS_FAIL Function failed to find device 53 * @retval CPA_STATUS_INVALID_PARAM Invalid parameter passed in 54 * @retval CPA_STATUS_UNSUPPORTED Unsupported algorithm/feature 55 * 56 *****************************************************************************/ 57 static CpaStatus 58 dcCheckSessionData(const CpaDcSessionSetupData *pSessionData, 59 CpaInstanceHandle dcInstance) 60 { 61 CpaDcInstanceCapabilities instanceCapabilities = { 0 }; 62 63 cpaDcQueryCapabilities(dcInstance, &instanceCapabilities); 64 65 if ((pSessionData->compLevel < CPA_DC_L1) || 66 (pSessionData->compLevel > CPA_DC_L9)) { 67 QAT_UTILS_LOG("Invalid compLevel value\n"); 68 return CPA_STATUS_INVALID_PARAM; 69 } 70 if ((pSessionData->autoSelectBestHuffmanTree < CPA_DC_ASB_DISABLED) || 71 (pSessionData->autoSelectBestHuffmanTree > 72 CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS)) { 73 QAT_UTILS_LOG("Invalid autoSelectBestHuffmanTree value\n"); 74 return CPA_STATUS_INVALID_PARAM; 75 } 76 if (pSessionData->compType != CPA_DC_DEFLATE) { 77 QAT_UTILS_LOG("Invalid compType value\n"); 78 return CPA_STATUS_INVALID_PARAM; 79 } 80 81 if ((pSessionData->huffType < CPA_DC_HT_STATIC) || 82 (pSessionData->huffType > CPA_DC_HT_FULL_DYNAMIC) || 83 (CPA_DC_HT_PRECOMP == pSessionData->huffType)) { 84 QAT_UTILS_LOG("Invalid huffType value\n"); 85 return CPA_STATUS_INVALID_PARAM; 86 } 87 88 if ((pSessionData->sessDirection < CPA_DC_DIR_COMPRESS) || 89 (pSessionData->sessDirection > CPA_DC_DIR_COMBINED)) { 90 QAT_UTILS_LOG("Invalid sessDirection value\n"); 91 return CPA_STATUS_INVALID_PARAM; 92 } 93 94 if ((pSessionData->sessState < CPA_DC_STATEFUL) || 95 (pSessionData->sessState > CPA_DC_STATELESS)) { 96 QAT_UTILS_LOG("Invalid sessState value\n"); 97 return CPA_STATUS_INVALID_PARAM; 98 } 99 100 if ((pSessionData->checksum < CPA_DC_NONE) || 101 (pSessionData->checksum > CPA_DC_ADLER32)) { 102 QAT_UTILS_LOG("Invalid checksum value\n"); 103 return CPA_STATUS_INVALID_PARAM; 104 } 105 106 return CPA_STATUS_SUCCESS; 107 } 108 109 /** 110 ***************************************************************************** 111 * @ingroup Dc_DataCompression 112 * Populate the compression hardware block 113 * 114 * @description 115 * This function will populate the compression hardware block and update 116 * the size in bytes of the block 117 * 118 * @param[in] pSessionDesc Pointer to the session descriptor 119 * @param[in] pCompConfig Pointer to slice config word 120 * @param[in] compDecomp Direction of the operation 121 * @param[in] enableDmm Delayed Match Mode 122 * 123 *****************************************************************************/ 124 static void 125 dcCompHwBlockPopulate(dc_session_desc_t *pSessionDesc, 126 icp_qat_hw_compression_config_t *pCompConfig, 127 dc_request_dir_t compDecomp, 128 icp_qat_hw_compression_delayed_match_t enableDmm) 129 { 130 icp_qat_hw_compression_direction_t dir = 131 ICP_QAT_HW_COMPRESSION_DIR_COMPRESS; 132 icp_qat_hw_compression_algo_t algo = 133 ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE; 134 icp_qat_hw_compression_depth_t depth = ICP_QAT_HW_COMPRESSION_DEPTH_1; 135 icp_qat_hw_compression_file_type_t filetype = 136 ICP_QAT_HW_COMPRESSION_FILE_TYPE_0; 137 138 /* Set the direction */ 139 if (DC_COMPRESSION_REQUEST == compDecomp) { 140 dir = ICP_QAT_HW_COMPRESSION_DIR_COMPRESS; 141 } else { 142 dir = ICP_QAT_HW_COMPRESSION_DIR_DECOMPRESS; 143 } 144 145 if (CPA_DC_DEFLATE == pSessionDesc->compType) { 146 algo = ICP_QAT_HW_COMPRESSION_ALGO_DEFLATE; 147 } else { 148 QAT_UTILS_LOG("Algorithm not supported for Compression\n"); 149 } 150 151 /* Set the depth */ 152 if (DC_DECOMPRESSION_REQUEST == compDecomp) { 153 depth = ICP_QAT_HW_COMPRESSION_DEPTH_1; 154 } else { 155 switch (pSessionDesc->compLevel) { 156 case CPA_DC_L1: 157 depth = ICP_QAT_HW_COMPRESSION_DEPTH_1; 158 break; 159 case CPA_DC_L2: 160 depth = ICP_QAT_HW_COMPRESSION_DEPTH_4; 161 break; 162 case CPA_DC_L3: 163 depth = ICP_QAT_HW_COMPRESSION_DEPTH_8; 164 break; 165 default: 166 depth = ICP_QAT_HW_COMPRESSION_DEPTH_16; 167 } 168 } 169 170 /* The file type is set to ICP_QAT_HW_COMPRESSION_FILE_TYPE_0. The other 171 * modes will be used in the future for precompiled huffman trees */ 172 filetype = ICP_QAT_HW_COMPRESSION_FILE_TYPE_0; 173 174 pCompConfig->val = ICP_QAT_HW_COMPRESSION_CONFIG_BUILD( 175 dir, enableDmm, algo, depth, filetype); 176 177 pCompConfig->reserved = 0; 178 } 179 180 /** 181 ***************************************************************************** 182 * @ingroup Dc_DataCompression 183 * Populate the compression content descriptor 184 * 185 * @description 186 * This function will populate the compression content descriptor 187 * 188 * @param[in] pService Pointer to the service 189 * @param[in] pSessionDesc Pointer to the session descriptor 190 * @param[in] contextBufferAddrPhys Physical address of the context buffer 191 * @param[out] pMsg Pointer to the compression message 192 * @param[in] nextSlice Next slice 193 * @param[in] compDecomp Direction of the operation 194 * 195 *****************************************************************************/ 196 static void 197 dcCompContentDescPopulate(sal_compression_service_t *pService, 198 dc_session_desc_t *pSessionDesc, 199 CpaPhysicalAddr contextBufferAddrPhys, 200 icp_qat_fw_comp_req_t *pMsg, 201 icp_qat_fw_slice_t nextSlice, 202 dc_request_dir_t compDecomp) 203 { 204 205 icp_qat_fw_comp_cd_hdr_t *pCompControlBlock = NULL; 206 icp_qat_hw_compression_config_t *pCompConfig = NULL; 207 CpaBoolean bankEnabled = CPA_FALSE; 208 209 pCompControlBlock = (icp_qat_fw_comp_cd_hdr_t *)&(pMsg->comp_cd_ctrl); 210 pCompConfig = 211 (icp_qat_hw_compression_config_t *)(pMsg->cd_pars.sl 212 .comp_slice_cfg_word); 213 214 ICP_QAT_FW_COMN_NEXT_ID_SET(pCompControlBlock, nextSlice); 215 ICP_QAT_FW_COMN_CURR_ID_SET(pCompControlBlock, ICP_QAT_FW_SLICE_COMP); 216 217 pCompControlBlock->comp_cfg_offset = 0; 218 219 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) && 220 (CPA_DC_DEFLATE == pSessionDesc->compType) && 221 (DC_DECOMPRESSION_REQUEST == compDecomp)) { 222 /* Enable A, B, C, D, and E (CAMs). */ 223 pCompControlBlock->ram_bank_flags = 224 ICP_QAT_FW_COMP_RAM_FLAGS_BUILD( 225 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank I */ 226 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank H */ 227 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank G */ 228 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank F */ 229 ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank E */ 230 ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank D */ 231 ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank C */ 232 ICP_QAT_FW_COMP_BANK_ENABLED, /* Bank B */ 233 ICP_QAT_FW_COMP_BANK_ENABLED); /* Bank A */ 234 bankEnabled = CPA_TRUE; 235 } else { 236 /* Disable all banks */ 237 pCompControlBlock->ram_bank_flags = 238 ICP_QAT_FW_COMP_RAM_FLAGS_BUILD( 239 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank I */ 240 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank H */ 241 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank G */ 242 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank F */ 243 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank E */ 244 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank D */ 245 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank C */ 246 ICP_QAT_FW_COMP_BANK_DISABLED, /* Bank B */ 247 ICP_QAT_FW_COMP_BANK_DISABLED); /* Bank A */ 248 } 249 250 if (DC_COMPRESSION_REQUEST == compDecomp) { 251 LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL( 252 pService->generic_service_info, 253 pCompControlBlock->comp_state_addr, 254 pSessionDesc->stateRegistersComp); 255 } else { 256 LAC_MEM_SHARED_WRITE_VIRT_TO_PHYS_PTR_EXTERNAL( 257 pService->generic_service_info, 258 pCompControlBlock->comp_state_addr, 259 pSessionDesc->stateRegistersDecomp); 260 } 261 262 if (CPA_TRUE == bankEnabled) { 263 pCompControlBlock->ram_banks_addr = contextBufferAddrPhys; 264 } else { 265 pCompControlBlock->ram_banks_addr = 0; 266 } 267 268 pCompControlBlock->resrvd = 0; 269 270 /* Populate Compression Hardware Setup Block */ 271 dcCompHwBlockPopulate(pSessionDesc, 272 pCompConfig, 273 compDecomp, 274 pService->comp_device_data.enableDmm); 275 } 276 277 /** 278 ***************************************************************************** 279 * @ingroup Dc_DataCompression 280 * Populate the translator content descriptor 281 * 282 * @description 283 * This function will populate the translator content descriptor 284 * 285 * @param[out] pMsg Pointer to the compression message 286 * @param[in] nextSlice Next slice 287 * 288 *****************************************************************************/ 289 static void 290 dcTransContentDescPopulate(icp_qat_fw_comp_req_t *pMsg, 291 icp_qat_fw_slice_t nextSlice) 292 { 293 294 icp_qat_fw_xlt_cd_hdr_t *pTransControlBlock = NULL; 295 pTransControlBlock = (icp_qat_fw_xlt_cd_hdr_t *)&(pMsg->u2.xlt_cd_ctrl); 296 297 ICP_QAT_FW_COMN_NEXT_ID_SET(pTransControlBlock, nextSlice); 298 ICP_QAT_FW_COMN_CURR_ID_SET(pTransControlBlock, ICP_QAT_FW_SLICE_XLAT); 299 300 pTransControlBlock->resrvd1 = 0; 301 pTransControlBlock->resrvd2 = 0; 302 pTransControlBlock->resrvd3 = 0; 303 } 304 305 /** 306 ***************************************************************************** 307 * @ingroup Dc_DataCompression 308 * Get the context size and the history size 309 * 310 * @description 311 * This function will get the size of the context buffer and the history 312 * buffer. The history buffer is a subset of the context buffer and its 313 * size is needed for stateful compression. 314 315 * @param[in] dcInstance DC Instance Handle 316 * 317 * @param[in] pSessionData Pointer to a user instantiated 318 * structure containing session data 319 * @param[out] pContextSize Pointer to the context size 320 * 321 * @retval CPA_STATUS_SUCCESS Function executed successfully 322 * 323 * 324 *****************************************************************************/ 325 static CpaStatus 326 dcGetContextSize(CpaInstanceHandle dcInstance, 327 CpaDcSessionSetupData *pSessionData, 328 Cpa32U *pContextSize) 329 { 330 sal_compression_service_t *pCompService = NULL; 331 332 pCompService = (sal_compression_service_t *)dcInstance; 333 334 *pContextSize = 0; 335 if ((CPA_DC_STATEFUL == pSessionData->sessState) && 336 (CPA_DC_DEFLATE == pSessionData->compType) && 337 (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection)) { 338 *pContextSize = 339 pCompService->comp_device_data.inflateContextSize; 340 } 341 return CPA_STATUS_SUCCESS; 342 } 343 344 CpaStatus 345 dcInitSession(CpaInstanceHandle dcInstance, 346 CpaDcSessionHandle pSessionHandle, 347 CpaDcSessionSetupData *pSessionData, 348 CpaBufferList *pContextBuffer, 349 CpaDcCallbackFn callbackFn) 350 { 351 CpaStatus status = CPA_STATUS_SUCCESS; 352 sal_compression_service_t *pService = NULL; 353 icp_qat_fw_comp_req_t *pReqCache = NULL; 354 dc_session_desc_t *pSessionDesc = NULL; 355 CpaPhysicalAddr contextAddrPhys = 0; 356 CpaPhysicalAddr physAddress = 0; 357 CpaPhysicalAddr physAddressAligned = 0; 358 Cpa32U minContextSize = 0, historySize = 0; 359 Cpa32U rpCmdFlags = 0; 360 icp_qat_fw_serv_specif_flags cmdFlags = 0; 361 Cpa8U secureRam = ICP_QAT_FW_COMP_ENABLE_SECURE_RAM_USED_AS_INTMD_BUF; 362 Cpa8U sessType = ICP_QAT_FW_COMP_STATELESS_SESSION; 363 Cpa8U autoSelectBest = ICP_QAT_FW_COMP_NOT_AUTO_SELECT_BEST; 364 Cpa8U enhancedAutoSelectBest = ICP_QAT_FW_COMP_NOT_ENH_AUTO_SELECT_BEST; 365 Cpa8U disableType0EnhancedAutoSelectBest = 366 ICP_QAT_FW_COMP_NOT_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST; 367 icp_qat_fw_la_cmd_id_t dcCmdId = 368 (icp_qat_fw_la_cmd_id_t)ICP_QAT_FW_COMP_CMD_STATIC; 369 icp_qat_fw_comn_flags cmnRequestFlags = 0; 370 dc_integrity_crc_fw_t *pDataIntegrityCrcs = NULL; 371 372 cmnRequestFlags = 373 ICP_QAT_FW_COMN_FLAGS_BUILD(DC_DEFAULT_QAT_PTR_TYPE, 374 QAT_COMN_CD_FLD_TYPE_16BYTE_DATA); 375 376 pService = (sal_compression_service_t *)dcInstance; 377 378 secureRam = pService->comp_device_data.useDevRam; 379 380 LAC_CHECK_NULL_PARAM(pSessionHandle); 381 LAC_CHECK_NULL_PARAM(pSessionData); 382 383 /* Check that the parameters defined in the pSessionData are valid for 384 * the 385 * device */ 386 if (CPA_STATUS_SUCCESS != 387 dcCheckSessionData(pSessionData, dcInstance)) { 388 return CPA_STATUS_INVALID_PARAM; 389 } 390 391 if ((CPA_DC_STATEFUL == pSessionData->sessState) && 392 (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection)) { 393 QAT_UTILS_LOG("Stateful sessions are not supported.\n"); 394 return CPA_STATUS_UNSUPPORTED; 395 } 396 397 if (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) { 398 /* Test if DRAM is available for the intermediate buffers */ 399 if ((NULL == pService->pInterBuffPtrsArray) && 400 (0 == pService->pInterBuffPtrsArrayPhyAddr)) { 401 if (CPA_DC_ASB_STATIC_DYNAMIC == 402 pSessionData->autoSelectBestHuffmanTree) { 403 /* Define the Huffman tree as static */ 404 pSessionData->huffType = CPA_DC_HT_STATIC; 405 } else { 406 QAT_UTILS_LOG( 407 "No buffer defined for this instance - see cpaDcStartInstance.\n"); 408 return CPA_STATUS_RESOURCE; 409 } 410 } 411 } 412 413 if ((CPA_DC_STATEFUL == pSessionData->sessState) && 414 (CPA_DC_DEFLATE == pSessionData->compType)) { 415 /* Get the size of the context buffer */ 416 status = 417 dcGetContextSize(dcInstance, pSessionData, &minContextSize); 418 419 if (CPA_STATUS_SUCCESS != status) { 420 QAT_UTILS_LOG( 421 "Unable to get the context size of the session.\n"); 422 return CPA_STATUS_FAIL; 423 } 424 425 /* If the minContextSize is zero it means we will not save or 426 * restore 427 * any history */ 428 if (0 != minContextSize) { 429 Cpa64U contextBuffSize = 0; 430 431 LAC_CHECK_NULL_PARAM(pContextBuffer); 432 433 if (LacBuffDesc_BufferListVerify( 434 pContextBuffer, 435 &contextBuffSize, 436 LAC_NO_ALIGNMENT_SHIFT) != CPA_STATUS_SUCCESS) { 437 return CPA_STATUS_INVALID_PARAM; 438 } 439 440 /* Ensure that the context buffer size is greater or 441 * equal 442 * to minContextSize */ 443 if (contextBuffSize < minContextSize) { 444 QAT_UTILS_LOG( 445 "Context buffer size should be greater or equal to %d.\n", 446 minContextSize); 447 return CPA_STATUS_INVALID_PARAM; 448 } 449 } 450 } 451 452 /* Re-align the session structure to 64 byte alignment */ 453 physAddress = 454 LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info, 455 (Cpa8U *)pSessionHandle + 456 sizeof(void *)); 457 458 if (physAddress == 0) { 459 QAT_UTILS_LOG( 460 "Unable to get the physical address of the session.\n"); 461 return CPA_STATUS_FAIL; 462 } 463 464 physAddressAligned = 465 (CpaPhysicalAddr)LAC_ALIGN_POW2_ROUNDUP(physAddress, 466 LAC_64BYTE_ALIGNMENT); 467 468 pSessionDesc = (dc_session_desc_t *) 469 /* Move the session pointer by the physical offset 470 between aligned and unaligned memory */ 471 ((Cpa8U *)pSessionHandle + sizeof(void *) + 472 (physAddressAligned - physAddress)); 473 474 /* Save the aligned pointer in the first bytes (size of LAC_ARCH_UINT) 475 * of the session memory */ 476 *((LAC_ARCH_UINT *)pSessionHandle) = (LAC_ARCH_UINT)pSessionDesc; 477 478 /* Zero the compression session */ 479 LAC_OS_BZERO(pSessionDesc, sizeof(dc_session_desc_t)); 480 481 /* Write the buffer descriptor for context/history */ 482 if (0 != minContextSize) { 483 status = LacBuffDesc_BufferListDescWrite( 484 pContextBuffer, 485 &contextAddrPhys, 486 CPA_FALSE, 487 &(pService->generic_service_info)); 488 489 if (status != CPA_STATUS_SUCCESS) { 490 return status; 491 } 492 493 pSessionDesc->pContextBuffer = pContextBuffer; 494 pSessionDesc->historyBuffSize = historySize; 495 } 496 497 pSessionDesc->cumulativeConsumedBytes = 0; 498 499 /* Initialise pSessionDesc */ 500 pSessionDesc->requestType = DC_REQUEST_FIRST; 501 pSessionDesc->huffType = pSessionData->huffType; 502 pSessionDesc->compType = pSessionData->compType; 503 pSessionDesc->checksumType = pSessionData->checksum; 504 pSessionDesc->autoSelectBestHuffmanTree = 505 pSessionData->autoSelectBestHuffmanTree; 506 pSessionDesc->sessDirection = pSessionData->sessDirection; 507 pSessionDesc->sessState = pSessionData->sessState; 508 pSessionDesc->compLevel = pSessionData->compLevel; 509 pSessionDesc->isDcDp = CPA_FALSE; 510 pSessionDesc->minContextSize = minContextSize; 511 pSessionDesc->isSopForCompressionProcessed = CPA_FALSE; 512 pSessionDesc->isSopForDecompressionProcessed = CPA_FALSE; 513 514 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 515 pSessionDesc->previousChecksum = 1; 516 } else { 517 pSessionDesc->previousChecksum = 0; 518 } 519 520 if (CPA_DC_STATEFUL == pSessionData->sessState) { 521 /* Init the spinlock used to lock the access to the number of 522 * stateful 523 * in-flight requests */ 524 status = LAC_SPINLOCK_INIT(&(pSessionDesc->sessionLock)); 525 if (CPA_STATUS_SUCCESS != status) { 526 QAT_UTILS_LOG( 527 "Spinlock init failed for sessionLock.\n"); 528 return CPA_STATUS_RESOURCE; 529 } 530 } 531 532 /* For asynchronous - use the user supplied callback 533 * for synchronous - use the internal synchronous callback */ 534 pSessionDesc->pCompressionCb = ((void *)NULL != (void *)callbackFn) ? 535 callbackFn : 536 LacSync_GenWakeupSyncCaller; 537 538 /* Reset the pending callback counters */ 539 qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount); 540 qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount); 541 pSessionDesc->pendingDpStatelessCbCount = 0; 542 543 if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) { 544 if (CPA_DC_HT_FULL_DYNAMIC == pSessionData->huffType) { 545 /* Populate the compression section of the content 546 * descriptor */ 547 dcCompContentDescPopulate(pService, 548 pSessionDesc, 549 contextAddrPhys, 550 &(pSessionDesc->reqCacheComp), 551 ICP_QAT_FW_SLICE_XLAT, 552 DC_COMPRESSION_REQUEST); 553 554 /* Populate the translator section of the content 555 * descriptor */ 556 dcTransContentDescPopulate( 557 &(pSessionDesc->reqCacheComp), 558 ICP_QAT_FW_SLICE_DRAM_WR); 559 560 if (0 != pService->pInterBuffPtrsArrayPhyAddr) { 561 pReqCache = &(pSessionDesc->reqCacheComp); 562 563 pReqCache->u1.xlt_pars.inter_buff_ptr = 564 pService->pInterBuffPtrsArrayPhyAddr; 565 } 566 } else { 567 dcCompContentDescPopulate(pService, 568 pSessionDesc, 569 contextAddrPhys, 570 &(pSessionDesc->reqCacheComp), 571 ICP_QAT_FW_SLICE_DRAM_WR, 572 DC_COMPRESSION_REQUEST); 573 } 574 } 575 576 /* Populate the compression section of the content descriptor for 577 * the decompression case or combined */ 578 if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) { 579 dcCompContentDescPopulate(pService, 580 pSessionDesc, 581 contextAddrPhys, 582 &(pSessionDesc->reqCacheDecomp), 583 ICP_QAT_FW_SLICE_DRAM_WR, 584 DC_DECOMPRESSION_REQUEST); 585 } 586 587 if (CPA_DC_STATEFUL == pSessionData->sessState) { 588 sessType = ICP_QAT_FW_COMP_STATEFUL_SESSION; 589 590 LAC_OS_BZERO(&pSessionDesc->stateRegistersComp, 591 sizeof(pSessionDesc->stateRegistersComp)); 592 593 LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp, 594 sizeof(pSessionDesc->stateRegistersDecomp)); 595 } 596 597 /* Get physical address of E2E CRC buffer */ 598 pSessionDesc->physDataIntegrityCrcs = (icp_qat_addr_width_t) 599 LAC_OS_VIRT_TO_PHYS_EXTERNAL(pService->generic_service_info, 600 &pSessionDesc->dataIntegrityCrcs); 601 if (0 == pSessionDesc->physDataIntegrityCrcs) { 602 QAT_UTILS_LOG( 603 "Unable to get the physical address of Data Integrity buffer.\n"); 604 return CPA_STATUS_FAIL; 605 } 606 /* Initialize default CRC parameters */ 607 pDataIntegrityCrcs = &pSessionDesc->dataIntegrityCrcs; 608 pDataIntegrityCrcs->crc32 = 0; 609 pDataIntegrityCrcs->adler32 = 1; 610 pDataIntegrityCrcs->oCrc32Cpr = DC_INVALID_CRC; 611 pDataIntegrityCrcs->iCrc32Cpr = DC_INVALID_CRC; 612 pDataIntegrityCrcs->oCrc32Xlt = DC_INVALID_CRC; 613 pDataIntegrityCrcs->iCrc32Xlt = DC_INVALID_CRC; 614 pDataIntegrityCrcs->xorFlags = DC_XOR_FLAGS_DEFAULT; 615 pDataIntegrityCrcs->crcPoly = DC_CRC_POLY_DEFAULT; 616 pDataIntegrityCrcs->xorOut = DC_XOR_OUT_DEFAULT; 617 618 /* Initialise seed checksums */ 619 pSessionDesc->seedSwCrc.swCrcI = 0; 620 pSessionDesc->seedSwCrc.swCrcO = 0; 621 622 /* Populate the cmdFlags */ 623 switch (pSessionDesc->autoSelectBestHuffmanTree) { 624 case CPA_DC_ASB_DISABLED: 625 break; 626 case CPA_DC_ASB_STATIC_DYNAMIC: 627 autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST; 628 break; 629 case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS: 630 autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST; 631 enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST; 632 break; 633 case CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_NO_HDRS: 634 autoSelectBest = ICP_QAT_FW_COMP_AUTO_SELECT_BEST; 635 enhancedAutoSelectBest = ICP_QAT_FW_COMP_ENH_AUTO_SELECT_BEST; 636 disableType0EnhancedAutoSelectBest = 637 ICP_QAT_FW_COMP_DISABLE_TYPE0_ENH_AUTO_SELECT_BEST; 638 break; 639 default: 640 break; 641 } 642 643 rpCmdFlags = ICP_QAT_FW_COMP_REQ_PARAM_FLAGS_BUILD( 644 ICP_QAT_FW_COMP_SOP, 645 ICP_QAT_FW_COMP_EOP, 646 ICP_QAT_FW_COMP_BFINAL, 647 ICP_QAT_FW_COMP_NO_CNV, 648 ICP_QAT_FW_COMP_NO_CNV_RECOVERY, 649 ICP_QAT_FW_COMP_CRC_MODE_LEGACY); 650 651 cmdFlags = 652 ICP_QAT_FW_COMP_FLAGS_BUILD(sessType, 653 autoSelectBest, 654 enhancedAutoSelectBest, 655 disableType0EnhancedAutoSelectBest, 656 secureRam); 657 658 if (CPA_DC_DIR_DECOMPRESS != pSessionData->sessDirection) { 659 if (CPA_DC_HT_FULL_DYNAMIC == pSessionDesc->huffType) { 660 dcCmdId = (icp_qat_fw_la_cmd_id_t)( 661 ICP_QAT_FW_COMP_CMD_DYNAMIC); 662 } 663 664 pReqCache = &(pSessionDesc->reqCacheComp); 665 pReqCache->comp_pars.req_par_flags = rpCmdFlags; 666 pReqCache->comp_pars.crc.legacy.initial_adler = 1; 667 pReqCache->comp_pars.crc.legacy.initial_crc32 = 0; 668 669 /* Populate header of the common request message */ 670 SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache, 671 ICP_QAT_FW_COMN_REQ_CPM_FW_COMP, 672 (uint8_t)dcCmdId, 673 cmnRequestFlags, 674 cmdFlags); 675 } 676 677 if (CPA_DC_DIR_COMPRESS != pSessionData->sessDirection) { 678 dcCmdId = 679 (icp_qat_fw_la_cmd_id_t)(ICP_QAT_FW_COMP_CMD_DECOMPRESS); 680 pReqCache = &(pSessionDesc->reqCacheDecomp); 681 pReqCache->comp_pars.req_par_flags = rpCmdFlags; 682 pReqCache->comp_pars.crc.legacy.initial_adler = 1; 683 pReqCache->comp_pars.crc.legacy.initial_crc32 = 0; 684 685 /* Populate header of the common request message */ 686 SalQatMsg_CmnHdrWrite((icp_qat_fw_comn_req_t *)pReqCache, 687 ICP_QAT_FW_COMN_REQ_CPM_FW_COMP, 688 (uint8_t)dcCmdId, 689 cmnRequestFlags, 690 cmdFlags); 691 } 692 693 return status; 694 } 695 696 CpaStatus 697 cpaDcInitSession(CpaInstanceHandle dcInstance, 698 CpaDcSessionHandle pSessionHandle, 699 CpaDcSessionSetupData *pSessionData, 700 CpaBufferList *pContextBuffer, 701 CpaDcCallbackFn callbackFn) 702 { 703 CpaInstanceHandle insHandle = NULL; 704 sal_compression_service_t *pService = NULL; 705 706 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 707 insHandle = dcGetFirstHandle(); 708 } else { 709 insHandle = dcInstance; 710 } 711 712 LAC_CHECK_INSTANCE_HANDLE(insHandle); 713 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 714 715 pService = (sal_compression_service_t *)insHandle; 716 717 /* Check if SAL is initialised otherwise return an error */ 718 SAL_RUNNING_CHECK(pService); 719 720 return dcInitSession(insHandle, 721 pSessionHandle, 722 pSessionData, 723 pContextBuffer, 724 callbackFn); 725 } 726 727 CpaStatus 728 cpaDcResetSession(const CpaInstanceHandle dcInstance, 729 CpaDcSessionHandle pSessionHandle) 730 { 731 CpaStatus status = CPA_STATUS_SUCCESS; 732 CpaInstanceHandle insHandle = NULL; 733 dc_session_desc_t *pSessionDesc = NULL; 734 Cpa64U numPendingStateless = 0; 735 Cpa64U numPendingStateful = 0; 736 icp_comms_trans_handle trans_handle = NULL; 737 LAC_CHECK_NULL_PARAM(pSessionHandle); 738 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 739 LAC_CHECK_NULL_PARAM(pSessionDesc); 740 741 if (CPA_TRUE == pSessionDesc->isDcDp) { 742 insHandle = dcInstance; 743 } else { 744 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 745 insHandle = dcGetFirstHandle(); 746 } else { 747 insHandle = dcInstance; 748 } 749 } 750 LAC_CHECK_NULL_PARAM(insHandle); 751 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 752 /* Check if SAL is running otherwise return an error */ 753 SAL_RUNNING_CHECK(insHandle); 754 if (CPA_TRUE == pSessionDesc->isDcDp) { 755 trans_handle = ((sal_compression_service_t *)dcInstance) 756 ->trans_handle_compression_tx; 757 if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) { 758 /* Process the remaining messages on the ring */ 759 SalQatMsg_updateQueueTail(trans_handle); 760 QAT_UTILS_LOG( 761 "There are remaining messages on the ring\n"); 762 return CPA_STATUS_RETRY; 763 } 764 765 /* Check if there are stateless pending requests */ 766 if (0 != pSessionDesc->pendingDpStatelessCbCount) { 767 QAT_UTILS_LOG( 768 "There are %llu stateless DP requests pending.\n", 769 (unsigned long long) 770 pSessionDesc->pendingDpStatelessCbCount); 771 return CPA_STATUS_RETRY; 772 } 773 } else { 774 numPendingStateless = 775 qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount)); 776 numPendingStateful = 777 qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount)); 778 /* Check if there are stateless pending requests */ 779 if (0 != numPendingStateless) { 780 QAT_UTILS_LOG( 781 "There are %llu stateless requests pending.\n", 782 (unsigned long long)numPendingStateless); 783 return CPA_STATUS_RETRY; 784 } 785 /* Check if there are stateful pending requests */ 786 if (0 != numPendingStateful) { 787 QAT_UTILS_LOG( 788 "There are %llu stateful requests pending.\n", 789 (unsigned long long)numPendingStateful); 790 return CPA_STATUS_RETRY; 791 } 792 793 /* Reset pSessionDesc */ 794 pSessionDesc->requestType = DC_REQUEST_FIRST; 795 pSessionDesc->cumulativeConsumedBytes = 0; 796 if (CPA_DC_ADLER32 == pSessionDesc->checksumType) { 797 pSessionDesc->previousChecksum = 1; 798 } else { 799 pSessionDesc->previousChecksum = 0; 800 } 801 } 802 /* Reset the pending callback counters */ 803 qatUtilsAtomicSet(0, &pSessionDesc->pendingStatelessCbCount); 804 qatUtilsAtomicSet(0, &pSessionDesc->pendingStatefulCbCount); 805 pSessionDesc->pendingDpStatelessCbCount = 0; 806 if (CPA_DC_STATEFUL == pSessionDesc->sessState) { 807 LAC_OS_BZERO(&pSessionDesc->stateRegistersComp, 808 sizeof(pSessionDesc->stateRegistersComp)); 809 LAC_OS_BZERO(&pSessionDesc->stateRegistersDecomp, 810 sizeof(pSessionDesc->stateRegistersDecomp)); 811 } 812 return status; 813 } 814 815 CpaStatus 816 cpaDcRemoveSession(const CpaInstanceHandle dcInstance, 817 CpaDcSessionHandle pSessionHandle) 818 { 819 CpaStatus status = CPA_STATUS_SUCCESS; 820 CpaInstanceHandle insHandle = NULL; 821 dc_session_desc_t *pSessionDesc = NULL; 822 Cpa64U numPendingStateless = 0; 823 Cpa64U numPendingStateful = 0; 824 icp_comms_trans_handle trans_handle = NULL; 825 826 LAC_CHECK_NULL_PARAM(pSessionHandle); 827 pSessionDesc = DC_SESSION_DESC_FROM_CTX_GET(pSessionHandle); 828 LAC_CHECK_NULL_PARAM(pSessionDesc); 829 830 if (CPA_TRUE == pSessionDesc->isDcDp) { 831 insHandle = dcInstance; 832 } else { 833 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 834 insHandle = dcGetFirstHandle(); 835 } else { 836 insHandle = dcInstance; 837 } 838 } 839 840 LAC_CHECK_NULL_PARAM(insHandle); 841 SAL_CHECK_INSTANCE_TYPE(insHandle, SAL_SERVICE_TYPE_COMPRESSION); 842 843 /* Check if SAL is running otherwise return an error */ 844 SAL_RUNNING_CHECK(insHandle); 845 846 if (CPA_TRUE == pSessionDesc->isDcDp) { 847 trans_handle = ((sal_compression_service_t *)insHandle) 848 ->trans_handle_compression_tx; 849 850 if (CPA_TRUE == icp_adf_queueDataToSend(trans_handle)) { 851 /* Process the remaining messages on the ring */ 852 SalQatMsg_updateQueueTail(trans_handle); 853 QAT_UTILS_LOG( 854 "There are remaining messages on the ring.\n"); 855 return CPA_STATUS_RETRY; 856 } 857 858 /* Check if there are stateless pending requests */ 859 if (0 != pSessionDesc->pendingDpStatelessCbCount) { 860 QAT_UTILS_LOG( 861 "There are %llu stateless DP requests pending.\n", 862 (unsigned long long) 863 pSessionDesc->pendingDpStatelessCbCount); 864 return CPA_STATUS_RETRY; 865 } 866 } else { 867 numPendingStateless = 868 qatUtilsAtomicGet(&(pSessionDesc->pendingStatelessCbCount)); 869 numPendingStateful = 870 qatUtilsAtomicGet(&(pSessionDesc->pendingStatefulCbCount)); 871 872 /* Check if there are stateless pending requests */ 873 if (0 != numPendingStateless) { 874 QAT_UTILS_LOG( 875 "There are %llu stateless requests pending.\n", 876 (unsigned long long)numPendingStateless); 877 status = CPA_STATUS_RETRY; 878 } 879 880 /* Check if there are stateful pending requests */ 881 if (0 != numPendingStateful) { 882 QAT_UTILS_LOG( 883 "There are %llu stateful requests pending.\n", 884 (unsigned long long)numPendingStateful); 885 status = CPA_STATUS_RETRY; 886 } 887 if ((CPA_DC_STATEFUL == pSessionDesc->sessState) && 888 (CPA_STATUS_SUCCESS == status)) { 889 if (CPA_STATUS_SUCCESS != 890 LAC_SPINLOCK_DESTROY( 891 &(pSessionDesc->sessionLock))) { 892 QAT_UTILS_LOG( 893 "Failed to destory session lock.\n"); 894 } 895 } 896 } 897 898 return status; 899 } 900 901 CpaStatus 902 dcGetSessionSize(CpaInstanceHandle dcInstance, 903 CpaDcSessionSetupData *pSessionData, 904 Cpa32U *pSessionSize, 905 Cpa32U *pContextSize) 906 { 907 908 CpaStatus status = CPA_STATUS_SUCCESS; 909 CpaInstanceHandle insHandle = NULL; 910 911 if (CPA_INSTANCE_HANDLE_SINGLE == dcInstance) { 912 insHandle = dcGetFirstHandle(); 913 } else { 914 insHandle = dcInstance; 915 } 916 917 /* Check parameters */ 918 LAC_CHECK_NULL_PARAM(insHandle); 919 LAC_CHECK_NULL_PARAM(pSessionData); 920 LAC_CHECK_NULL_PARAM(pSessionSize); 921 922 if (dcCheckSessionData(pSessionData, insHandle) != CPA_STATUS_SUCCESS) { 923 return CPA_STATUS_INVALID_PARAM; 924 } 925 926 /* Get session size for session data */ 927 *pSessionSize = sizeof(dc_session_desc_t) + LAC_64BYTE_ALIGNMENT + 928 sizeof(LAC_ARCH_UINT); 929 930 if (NULL != pContextSize) { 931 status = 932 dcGetContextSize(insHandle, pSessionData, pContextSize); 933 934 if (CPA_STATUS_SUCCESS != status) { 935 QAT_UTILS_LOG( 936 "Unable to get the context size of the session.\n"); 937 return CPA_STATUS_FAIL; 938 } 939 } 940 941 return CPA_STATUS_SUCCESS; 942 } 943 944 CpaStatus 945 cpaDcGetSessionSize(CpaInstanceHandle dcInstance, 946 CpaDcSessionSetupData *pSessionData, 947 Cpa32U *pSessionSize, 948 Cpa32U *pContextSize) 949 { 950 951 LAC_CHECK_NULL_PARAM(pContextSize); 952 953 return dcGetSessionSize(dcInstance, 954 pSessionData, 955 pSessionSize, 956 pContextSize); 957 } 958