get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/124905/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 124905,
    "url": "http://patchwork.dpdk.org/api/patches/124905/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230309143359.67789-3-kevin.osullivan@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20230309143359.67789-3-kevin.osullivan@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230309143359.67789-3-kevin.osullivan@intel.com",
    "date": "2023-03-09T14:33:59",
    "name": "[v2,2/2] crypto/qat: add cipher-crc offload support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d900b4c7cc5e72a421915a6d946c2c6eaaa02b64",
    "submitter": {
        "id": 2860,
        "url": "http://patchwork.dpdk.org/api/people/2860/?format=api",
        "name": "Kevin O'Sullivan",
        "email": "kevin.osullivan@intel.com"
    },
    "delegate": {
        "id": 6690,
        "url": "http://patchwork.dpdk.org/api/users/6690/?format=api",
        "username": "akhil",
        "first_name": "akhil",
        "last_name": "goyal",
        "email": "gakhil@marvell.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20230309143359.67789-3-kevin.osullivan@intel.com/mbox/",
    "series": [
        {
            "id": 27310,
            "url": "http://patchwork.dpdk.org/api/series/27310/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=27310",
            "date": "2023-03-09T14:33:57",
            "name": "crypto/qat: add cipher-crc offload feature",
            "version": 2,
            "mbox": "http://patchwork.dpdk.org/series/27310/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/124905/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/124905/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 9925241E22;\n\tThu,  9 Mar 2023 15:34:24 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id ADBF642D33;\n\tThu,  9 Mar 2023 15:34:15 +0100 (CET)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n by mails.dpdk.org (Postfix) with ESMTP id CBA2C42D1D\n for <dev@dpdk.org>; Thu,  9 Mar 2023 15:34:13 +0100 (CET)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 09 Mar 2023 06:34:13 -0800",
            "from silpixa00401033.ir.intel.com ([10.55.129.113])\n by fmsmga004.fm.intel.com with ESMTP; 09 Mar 2023 06:34:11 -0800"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1678372454; x=1709908454;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=REFlWVxxHx+8tR83zet93Cqm1sfkJDMswO/N4myfXfY=;\n b=ZwCFuGksOKDgCLNlVEQReD60YdVkyilWGQQajmwU6O452j6U5BfYnyG9\n mw3Mn3cQEAlPJngdxnw5BzIcCQpUZbCQJSA5VzkgS1uk74JMhAUJeJtPk\n CoOkSWEGjnc5uUYa0IzpiTIpYy3BDgyjI/yqzOziJGBKG//Gy5+XdvqX0\n SIXDsh0yJzo+5ZIADlUoJ+TYEXooDVisIAn8lxm6527JUgx+FdHf90PrQ\n Q38yQTLW/MJ4+GNiBjOTl45qtVQhnw05PyPSok7lhJH27mv4WHsmcFf5S\n Xsz9ONIYXPRePm0OAcX3k5N3NqDOAFHTMuCZ+dcwVFkEbCmRyyUS2G2Tu A==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6500,9779,10643\"; a=\"336467243\"",
            "E=Sophos;i=\"5.98,246,1673942400\"; d=\"scan'208\";a=\"336467243\"",
            "E=McAfee;i=\"6500,9779,10643\"; a=\"746334153\"",
            "E=Sophos;i=\"5.98,246,1673942400\"; d=\"scan'208\";a=\"746334153\""
        ],
        "X-ExtLoop1": "1",
        "From": "Kevin O'Sullivan <kevin.osullivan@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "kai.ji@intel.com, Kevin O'Sullivan <kevin.osullivan@intel.com>,\n David Coyle <david.coyle@intel.com>",
        "Subject": "[PATCH v2 2/2] crypto/qat: add cipher-crc offload support",
        "Date": "Thu,  9 Mar 2023 14:33:59 +0000",
        "Message-Id": "<20230309143359.67789-3-kevin.osullivan@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20230309143359.67789-1-kevin.osullivan@intel.com>",
        "References": "<20230308121258.88708-1-kevin.osullivan@intel.com>\n <20230309143359.67789-1-kevin.osullivan@intel.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "This patch adds support to the QAT symmetric crypto PMD for combined\ncipher-crc offload feature, primarily for DOCSIS, on gen2/gen3/gen4\nQAT devices.\n\nA new parameter called qat_sym_cipher_crc_enable has been\nadded to the PMD, which can be set on process start as follows:\n\n-a <qat pci bdf>,qat_sym_cipher_crc_enable=1\n\nWhen enabled, a capability check for the combined cipher-crc offload\nfeature is triggered to the QAT firmware during queue pair\ninitialization. If supported by the firmware, any subsequent runtime\nDOCSIS cipher-crc requests handled by the QAT PMD are offloaded to the\nQAT device by setting up the content descriptor and request\naccordingly.\n\nIf the combined DOCSIS cipher-crc feature is not supported by the\nfirmware, the CRC continues to be calculated within the PMD, with just\nthe cipher portion of the request being offloaded to the QAT device.\n\nSigned-off-by: Kevin O'Sullivan <kevin.osullivan@intel.com>\nSigned-off-by: David Coyle <david.coyle@intel.com>\n---\nv2: fixed centos compilation error for missing braces around\n    initializer\n---\n drivers/common/qat/qat_device.c              |  12 +-\n drivers/common/qat/qat_device.h              |   3 +-\n drivers/common/qat/qat_qp.c                  | 157 +++++++++++++++\n drivers/common/qat/qat_qp.h                  |   5 +\n drivers/crypto/qat/dev/qat_crypto_pmd_gen2.c |   2 +-\n drivers/crypto/qat/dev/qat_crypto_pmd_gens.h |  24 ++-\n drivers/crypto/qat/dev/qat_sym_pmd_gen1.c    |   4 +\n drivers/crypto/qat/qat_crypto.c              |  22 ++-\n drivers/crypto/qat/qat_crypto.h              |   1 +\n drivers/crypto/qat/qat_sym.c                 |   4 +\n drivers/crypto/qat/qat_sym.h                 |   7 +-\n drivers/crypto/qat/qat_sym_session.c         | 194 +++++++++++++++++++\n drivers/crypto/qat/qat_sym_session.h         |  21 +-\n 13 files changed, 441 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c\nindex 8bce2ac073..308c59c39f 100644\n--- a/drivers/common/qat/qat_device.c\n+++ b/drivers/common/qat/qat_device.c\n@@ -149,7 +149,16 @@ qat_dev_parse_cmd(const char *str, struct qat_dev_cmd_param\n \t\t\t} else {\n \t\t\t\tmemcpy(value_str, arg2, iter);\n \t\t\t\tvalue = strtol(value_str, NULL, 10);\n-\t\t\t\tif (value > MAX_QP_THRESHOLD_SIZE) {\n+\t\t\t\tif (strcmp(param,\n+\t\t\t\t\t SYM_CIPHER_CRC_ENABLE_NAME) == 0) {\n+\t\t\t\t\tif (value < 0 || value > 1) {\n+\t\t\t\t\t\tQAT_LOG(DEBUG, \"The value for\"\n+\t\t\t\t\t\t\" qat_sym_cipher_crc_enable\"\n+\t\t\t\t\t\t\" should be set to 0 or 1,\"\n+\t\t\t\t\t\t\" setting to 0\");\n+\t\t\t\t\t\tvalue = 0;\n+\t\t\t\t\t}\n+\t\t\t\t} else if (value > MAX_QP_THRESHOLD_SIZE) {\n \t\t\t\t\tQAT_LOG(DEBUG, \"Exceeded max size of\"\n \t\t\t\t\t\t\" threshold, setting to %d\",\n \t\t\t\t\t\tMAX_QP_THRESHOLD_SIZE);\n@@ -369,6 +378,7 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,\n \t\t\t{ SYM_ENQ_THRESHOLD_NAME, 0 },\n \t\t\t{ ASYM_ENQ_THRESHOLD_NAME, 0 },\n \t\t\t{ COMP_ENQ_THRESHOLD_NAME, 0 },\n+\t\t\t{ SYM_CIPHER_CRC_ENABLE_NAME, 0 },\n \t\t\t[QAT_CMD_SLICE_MAP_POS] = { QAT_CMD_SLICE_MAP, 0},\n \t\t\t{ NULL, 0 },\n \t};\ndiff --git a/drivers/common/qat/qat_device.h b/drivers/common/qat/qat_device.h\nindex bc3da04238..4188474dde 100644\n--- a/drivers/common/qat/qat_device.h\n+++ b/drivers/common/qat/qat_device.h\n@@ -21,8 +21,9 @@\n #define SYM_ENQ_THRESHOLD_NAME \"qat_sym_enq_threshold\"\n #define ASYM_ENQ_THRESHOLD_NAME \"qat_asym_enq_threshold\"\n #define COMP_ENQ_THRESHOLD_NAME \"qat_comp_enq_threshold\"\n+#define SYM_CIPHER_CRC_ENABLE_NAME \"qat_sym_cipher_crc_enable\"\n #define QAT_CMD_SLICE_MAP \"qat_cmd_slice_disable\"\n-#define QAT_CMD_SLICE_MAP_POS\t4\n+#define QAT_CMD_SLICE_MAP_POS\t5\n #define MAX_QP_THRESHOLD_SIZE\t32\n \n /**\ndiff --git a/drivers/common/qat/qat_qp.c b/drivers/common/qat/qat_qp.c\nindex 9cbd19a481..1ce89c265f 100644\n--- a/drivers/common/qat/qat_qp.c\n+++ b/drivers/common/qat/qat_qp.c\n@@ -11,6 +11,9 @@\n #include <bus_pci_driver.h>\n #include <rte_atomic.h>\n #include <rte_prefetch.h>\n+#ifdef RTE_LIB_SECURITY\n+#include <rte_ether.h>\n+#endif\n \n #include \"qat_logs.h\"\n #include \"qat_device.h\"\n@@ -957,6 +960,160 @@ qat_cq_get_fw_version(struct qat_qp *qp)\n \treturn -EINVAL;\n }\n \n+#ifdef BUILD_QAT_SYM\n+/* Sends an LA bulk req message to determine if a QAT device supports Cipher-CRC\n+ * offload. This assumes that there are no inflight messages, i.e. assumes\n+ * there's space  on the qp, one message is sent and only one response\n+ * collected. The status bit of the response and returned data are checked.\n+ * Returns:\n+ *     1 if status bit indicates success and returned data matches expected\n+ *     data (i.e. Cipher-CRC supported)\n+ *     0 if status bit indicates error or returned data does not match expected\n+ *     data (i.e. Cipher-CRC not supported)\n+ *     Negative error code in case of error\n+ */\n+int\n+qat_cq_get_fw_cipher_crc_cap(struct qat_qp *qp)\n+{\n+\tstruct qat_queue *queue = &(qp->tx_q);\n+\tuint8_t *base_addr = (uint8_t *)queue->base_addr;\n+\tstruct icp_qat_fw_la_bulk_req cipher_crc_cap_msg = {{0}};\n+\tstruct icp_qat_fw_comn_resp response = {{0}};\n+\tstruct icp_qat_fw_la_cipher_req_params *cipher_param;\n+\tstruct icp_qat_fw_la_auth_req_params *auth_param;\n+\tstruct qat_sym_session *session;\n+\tphys_addr_t phy_src_addr;\n+\tuint64_t *src_data_addr;\n+\tint ret;\n+\tuint8_t cipher_offset = 18;\n+\tuint8_t crc_offset = 6;\n+\tuint8_t ciphertext[34] = {\n+\t\t/* Outer protocol header */\n+\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t/* Ethernet frame */\n+\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t0x04, 0x03, 0x02, 0x01, 0xD6, 0xE2, 0x70, 0x5C,\n+\t\t0xE6, 0x4D, 0xCC, 0x8C, 0x47, 0xB7, 0x09, 0xD6,\n+\t\t/* CRC */\n+\t\t0x54, 0x85, 0xF8, 0x32\n+\t};\n+\tuint8_t plaintext[34] = {\n+\t\t/* Outer protocol header */\n+\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n+\t\t/* Ethernet frame */\n+\t\t0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x06, 0x05,\n+\t\t0x04, 0x03, 0x02, 0x01, 0x08, 0x00, 0xAA, 0xAA,\n+\t\t0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,\n+\t\t/* CRC */\n+\t\t0xFF, 0xFF, 0xFF, 0xFF\n+\t};\n+\tuint8_t key[16] = {\n+\t\t0x00, 0x00, 0x00, 0x00, 0xAA, 0xBB, 0xCC, 0xDD,\n+\t\t0xEE, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55\n+\t};\n+\tuint8_t iv[16] = {\n+\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,\n+\t\t0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11\n+\t};\n+\n+\tsession = rte_zmalloc(NULL, sizeof(struct qat_sym_session), 0);\n+\tif (session == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Verify the session physical address is known */\n+\trte_iova_t session_paddr = rte_mem_virt2iova(session);\n+\tif (session_paddr == 0 || session_paddr == RTE_BAD_IOVA) {\n+\t\tQAT_LOG(ERR, \"Session physical address unknown.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Prepare the LA bulk request */\n+\tret = qat_cipher_crc_cap_msg_sess_prepare(session,\n+\t\t\t\t\t\t  session_paddr,\n+\t\t\t\t\t\t  key,\n+\t\t\t\t\t\t  sizeof(key),\n+\t\t\t\t\t\t  qp->qat_dev_gen);\n+\tif (ret < 0) {\n+\t\trte_free(session);\n+\t\t/* Returning 0 here to allow qp setup to continue, but\n+\t\t * indicate that Cipher-CRC offload is not supported on the\n+\t\t * device\n+\t\t */\n+\t\treturn 0;\n+\t}\n+\n+\tcipher_crc_cap_msg = session->fw_req;\n+\n+\tsrc_data_addr = rte_zmalloc(NULL, sizeof(plaintext), 0);\n+\tif (src_data_addr == NULL) {\n+\t\trte_free(session);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\trte_memcpy(src_data_addr, plaintext, sizeof(plaintext));\n+\n+\tphy_src_addr = rte_mem_virt2iova(src_data_addr);\n+\tif (phy_src_addr == 0 || phy_src_addr == RTE_BAD_IOVA) {\n+\t\tQAT_LOG(ERR, \"Source physical address unknown.\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcipher_crc_cap_msg.comn_mid.src_data_addr = phy_src_addr;\n+\tcipher_crc_cap_msg.comn_mid.src_length = sizeof(plaintext);\n+\tcipher_crc_cap_msg.comn_mid.dest_data_addr = phy_src_addr;\n+\tcipher_crc_cap_msg.comn_mid.dst_length = sizeof(plaintext);\n+\n+\tcipher_param = (void *)&cipher_crc_cap_msg.serv_specif_rqpars;\n+\tauth_param = (void *)((uint8_t *)cipher_param +\n+\t\t\tICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);\n+\n+\trte_memcpy(cipher_param->u.cipher_IV_array, iv, sizeof(iv));\n+\n+\tcipher_param->cipher_offset = cipher_offset;\n+\tcipher_param->cipher_length = sizeof(plaintext) - cipher_offset;\n+\tauth_param->auth_off = crc_offset;\n+\tauth_param->auth_len = sizeof(plaintext) -\n+\t\t\t\tcrc_offset -\n+\t\t\t\tRTE_ETHER_CRC_LEN;\n+\n+\tICP_QAT_FW_LA_DIGEST_IN_BUFFER_SET(\n+\t\t\tcipher_crc_cap_msg.comn_hdr.serv_specif_flags,\n+\t\t\tICP_QAT_FW_LA_DIGEST_IN_BUFFER);\n+\n+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG\n+\tQAT_DP_HEXDUMP_LOG(DEBUG, \"LA Bulk request\", &cipher_crc_cap_msg,\n+\t\t\tsizeof(cipher_crc_cap_msg));\n+#endif\n+\n+\t/* Send the cipher_crc_cap_msg request */\n+\tmemcpy(base_addr + queue->tail,\n+\t       &cipher_crc_cap_msg,\n+\t       sizeof(cipher_crc_cap_msg));\n+\tqueue->tail = adf_modulo(queue->tail + queue->msg_size,\n+\t\t\tqueue->modulo_mask);\n+\ttxq_write_tail(qp->qat_dev_gen, qp, queue);\n+\n+\t/* Check for response and verify data is same as ciphertext */\n+\tif (qat_cq_dequeue_response(qp, &response)) {\n+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG\n+\t\tQAT_DP_HEXDUMP_LOG(DEBUG, \"LA response:\", &response,\n+\t\t\t\tsizeof(response));\n+#endif\n+\n+\t\tif (memcmp(src_data_addr, ciphertext, sizeof(ciphertext)) != 0)\n+\t\t\tret = 0; /* Cipher-CRC offload not supported */\n+\t\telse\n+\t\t\tret = 1;\n+\t} else {\n+\t\tret = -EINVAL;\n+\t}\n+\n+\trte_free(src_data_addr);\n+\trte_free(session);\n+\treturn ret;\n+}\n+#endif\n+\n __rte_weak int\n qat_comp_process_response(void **op __rte_unused, uint8_t *resp __rte_unused,\n \t\t\t  void *op_cookie __rte_unused,\ndiff --git a/drivers/common/qat/qat_qp.h b/drivers/common/qat/qat_qp.h\nindex 66f00943a5..d19fc387e4 100644\n--- a/drivers/common/qat/qat_qp.h\n+++ b/drivers/common/qat/qat_qp.h\n@@ -153,6 +153,11 @@ qat_qp_get_hw_data(struct qat_pci_device *qat_dev,\n int\n qat_cq_get_fw_version(struct qat_qp *qp);\n \n+#ifdef BUILD_QAT_SYM\n+int\n+qat_cq_get_fw_cipher_crc_cap(struct qat_qp *qp);\n+#endif\n+\n /* Needed for weak function*/\n int\n qat_comp_process_response(void **op __rte_unused, uint8_t *resp __rte_unused,\ndiff --git a/drivers/crypto/qat/dev/qat_crypto_pmd_gen2.c b/drivers/crypto/qat/dev/qat_crypto_pmd_gen2.c\nindex 60ca0fc0d2..1f3e2b1d99 100644\n--- a/drivers/crypto/qat/dev/qat_crypto_pmd_gen2.c\n+++ b/drivers/crypto/qat/dev/qat_crypto_pmd_gen2.c\n@@ -163,7 +163,7 @@ qat_sym_crypto_qp_setup_gen2(struct rte_cryptodev *dev, uint16_t qp_id,\n \t\tQAT_LOG(DEBUG, \"unknown QAT firmware version\");\n \n \t/* set capabilities based on the fw version */\n-\tqat_sym_private->internal_capabilities = QAT_SYM_CAP_VALID |\n+\tqat_sym_private->internal_capabilities |= QAT_SYM_CAP_VALID |\n \t\t\t((ret >= MIXED_CRYPTO_MIN_FW_VER) ?\n \t\t\t\t\tQAT_SYM_CAP_MIXED_CRYPTO : 0);\n \treturn 0;\ndiff --git a/drivers/crypto/qat/dev/qat_crypto_pmd_gens.h b/drivers/crypto/qat/dev/qat_crypto_pmd_gens.h\nindex 524c291340..70942906ea 100644\n--- a/drivers/crypto/qat/dev/qat_crypto_pmd_gens.h\n+++ b/drivers/crypto/qat/dev/qat_crypto_pmd_gens.h\n@@ -399,8 +399,13 @@ qat_sym_convert_op_to_vec_chain(struct rte_crypto_op *op,\n \t\tcipher_ofs = op->sym->cipher.data.offset >> 3;\n \t\tbreak;\n \tcase 0:\n-\t\tcipher_len = op->sym->cipher.data.length;\n-\t\tcipher_ofs = op->sym->cipher.data.offset;\n+\t\tif (ctx->bpi_ctx) {\n+\t\t\tcipher_len = qat_bpicipher_preprocess(ctx, op);\n+\t\t\tcipher_ofs = op->sym->cipher.data.offset;\n+\t\t} else {\n+\t\t\tcipher_len = op->sym->cipher.data.length;\n+\t\t\tcipher_ofs = op->sym->cipher.data.offset;\n+\t\t}\n \t\tbreak;\n \tdefault:\n \t\tQAT_DP_LOG(ERR,\n@@ -428,8 +433,10 @@ qat_sym_convert_op_to_vec_chain(struct rte_crypto_op *op,\n \n \tmax_len = RTE_MAX(cipher_ofs + cipher_len, auth_ofs + auth_len);\n \n-\t/* digest in buffer check. Needed only for wireless algos */\n-\tif (ret == 1) {\n+\t/* digest in buffer check. Needed only for wireless algos\n+\t * or combined cipher-crc operations\n+\t */\n+\tif (ret == 1 || ctx->bpi_ctx) {\n \t\t/* Handle digest-encrypted cases, i.e.\n \t\t * auth-gen-then-cipher-encrypt and\n \t\t * cipher-decrypt-then-auth-verify\n@@ -456,8 +463,9 @@ qat_sym_convert_op_to_vec_chain(struct rte_crypto_op *op,\n \t\t\t\t\tauth_len;\n \n \t\t/* Then check if digest-encrypted conditions are met */\n-\t\tif ((auth_ofs + auth_len < cipher_ofs + cipher_len) &&\n-\t\t\t\t(digest->iova == auth_end_iova))\n+\t\tif (((auth_ofs + auth_len < cipher_ofs + cipher_len) &&\n+\t\t\t\t(digest->iova == auth_end_iova)) ||\n+\t\t\t\tctx->bpi_ctx)\n \t\t\tmax_len = RTE_MAX(max_len, auth_ofs + auth_len +\n \t\t\t\t\tctx->digest_length);\n \t}\n@@ -691,9 +699,9 @@ enqueue_one_chain_job_gen1(struct qat_sym_session *ctx,\n \t\t\tauth_param->auth_len;\n \n \t/* Then check if digest-encrypted conditions are met */\n-\tif ((auth_param->auth_off + auth_param->auth_len <\n+\tif (((auth_param->auth_off + auth_param->auth_len <\n \t\tcipher_param->cipher_offset + cipher_param->cipher_length) &&\n-\t\t\t(digest->iova == auth_iova_end)) {\n+\t\t\t(digest->iova == auth_iova_end)) || ctx->bpi_ctx) {\n \t\t/* Handle partial digest encryption */\n \t\tif (cipher_param->cipher_offset + cipher_param->cipher_length <\n \t\t\tauth_param->auth_off + auth_param->auth_len +\ndiff --git a/drivers/crypto/qat/dev/qat_sym_pmd_gen1.c b/drivers/crypto/qat/dev/qat_sym_pmd_gen1.c\nindex 91d5cfa71d..590eaa0057 100644\n--- a/drivers/crypto/qat/dev/qat_sym_pmd_gen1.c\n+++ b/drivers/crypto/qat/dev/qat_sym_pmd_gen1.c\n@@ -1205,6 +1205,10 @@ qat_sym_crypto_set_session_gen1(void *cryptodev __rte_unused, void *session)\n \t} else if (ctx->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER) {\n \t\t/* do_auth = 0; do_cipher = 1; */\n \t\tbuild_request = qat_sym_build_op_cipher_gen1;\n+\t} else if (ctx->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_CRC) {\n+\t\t/* do_auth = 1; do_cipher = 1; */\n+\t\tbuild_request = qat_sym_build_op_chain_gen1;\n+\t\thandle_mixed = 1;\n \t}\n \n \tif (build_request)\ndiff --git a/drivers/crypto/qat/qat_crypto.c b/drivers/crypto/qat/qat_crypto.c\nindex 84c26a8062..861679373b 100644\n--- a/drivers/crypto/qat/qat_crypto.c\n+++ b/drivers/crypto/qat/qat_crypto.c\n@@ -172,5 +172,25 @@ qat_cryptodev_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,\n \t\t\tqat_asym_init_op_cookie(qp->op_cookies[i]);\n \t}\n \n-\treturn ret;\n+\tif (qat_private->cipher_crc_offload_enable) {\n+\t\tret = qat_cq_get_fw_cipher_crc_cap(qp);\n+\t\tif (ret < 0) {\n+\t\t\tqat_cryptodev_qp_release(dev, qp_id);\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t\tif (ret != 0)\n+\t\t\tQAT_LOG(DEBUG, \"Cipher CRC supported on QAT device\");\n+\t\telse\n+\t\t\tQAT_LOG(DEBUG, \"Cipher CRC not supported on QAT device\");\n+\n+\t\t/* Only send the cipher crc offload capability message once */\n+\t\tqat_private->cipher_crc_offload_enable = 0;\n+\t\t/* Set cipher crc offload indicator */\n+\t\tif (ret)\n+\t\t\tqat_private->internal_capabilities |=\n+\t\t\t\t\t\tQAT_SYM_CAP_CIPHER_CRC;\n+\t}\n+\n+\treturn 0;\n }\ndiff --git a/drivers/crypto/qat/qat_crypto.h b/drivers/crypto/qat/qat_crypto.h\nindex 6fe1326c51..e20f16236e 100644\n--- a/drivers/crypto/qat/qat_crypto.h\n+++ b/drivers/crypto/qat/qat_crypto.h\n@@ -36,6 +36,7 @@ struct qat_cryptodev_private {\n \t/* Shared memzone for storing capabilities */\n \tuint16_t min_enq_burst_threshold;\n \tuint32_t internal_capabilities; /* see flags QAT_SYM_CAP_xxx */\n+\tbool cipher_crc_offload_enable;\n \tenum qat_service_type service_type;\n };\n \ndiff --git a/drivers/crypto/qat/qat_sym.c b/drivers/crypto/qat/qat_sym.c\nindex 08e92191a3..345c845325 100644\n--- a/drivers/crypto/qat/qat_sym.c\n+++ b/drivers/crypto/qat/qat_sym.c\n@@ -279,6 +279,10 @@ qat_sym_dev_create(struct qat_pci_device *qat_pci_dev,\n \t\tif (!strcmp(qat_dev_cmd_param[i].name, SYM_ENQ_THRESHOLD_NAME))\n \t\t\tinternals->min_enq_burst_threshold =\n \t\t\t\t\tqat_dev_cmd_param[i].val;\n+\t\tif (!strcmp(qat_dev_cmd_param[i].name,\n+\t\t\t\tSYM_CIPHER_CRC_ENABLE_NAME))\n+\t\t\tinternals->cipher_crc_offload_enable =\n+\t\t\t\t\tqat_dev_cmd_param[i].val;\n \t\tif (!strcmp(qat_dev_cmd_param[i].name, QAT_IPSEC_MB_LIB))\n \t\t\tqat_ipsec_mb_lib = qat_dev_cmd_param[i].val;\n \t\tif (!strcmp(qat_dev_cmd_param[i].name, QAT_CMD_SLICE_MAP))\ndiff --git a/drivers/crypto/qat/qat_sym.h b/drivers/crypto/qat/qat_sym.h\nindex 9a4251e08b..3d841d0eba 100644\n--- a/drivers/crypto/qat/qat_sym.h\n+++ b/drivers/crypto/qat/qat_sym.h\n@@ -32,6 +32,7 @@\n \n /* Internal capabilities */\n #define QAT_SYM_CAP_MIXED_CRYPTO\t(1 << 0)\n+#define QAT_SYM_CAP_CIPHER_CRC\t\t(1 << 1)\n #define QAT_SYM_CAP_VALID\t\t(1 << 31)\n \n /**\n@@ -282,7 +283,8 @@ qat_sym_preprocess_requests(void **ops, uint16_t nb_ops)\n \t\t\tif (ctx == NULL || ctx->bpi_ctx == NULL)\n \t\t\t\tcontinue;\n \n-\t\t\tqat_crc_generate(ctx, op);\n+\t\t\tif (ctx->qat_cmd != ICP_QAT_FW_LA_CMD_CIPHER_CRC)\n+\t\t\t\tqat_crc_generate(ctx, op);\n \t\t}\n \t}\n }\n@@ -330,7 +332,8 @@ qat_sym_process_response(void **op, uint8_t *resp, void *op_cookie,\n \t\tif (sess->bpi_ctx) {\n \t\t\tqat_bpicipher_postprocess(sess, rx_op);\n #ifdef RTE_LIB_SECURITY\n-\t\t\tif (is_docsis_sec)\n+\t\t\tif (is_docsis_sec && sess->qat_cmd !=\n+\t\t\t\t\t\tICP_QAT_FW_LA_CMD_CIPHER_CRC)\n \t\t\t\tqat_crc_verify(sess, rx_op);\n #endif\n \t\t}\ndiff --git a/drivers/crypto/qat/qat_sym_session.c b/drivers/crypto/qat/qat_sym_session.c\nindex 466482d225..c0217654c1 100644\n--- a/drivers/crypto/qat/qat_sym_session.c\n+++ b/drivers/crypto/qat/qat_sym_session.c\n@@ -27,6 +27,7 @@\n #include <rte_crypto_sym.h>\n #ifdef RTE_LIB_SECURITY\n #include <rte_security_driver.h>\n+#include <rte_ether.h>\n #endif\n \n #include \"qat_logs.h\"\n@@ -68,6 +69,13 @@ static void ossl_legacy_provider_unload(void)\n \n extern int qat_ipsec_mb_lib;\n \n+#define ETH_CRC32_POLYNOMIAL    0x04c11db7\n+#define ETH_CRC32_INIT_VAL      0xffffffff\n+#define ETH_CRC32_XOR_OUT       0xffffffff\n+#define ETH_CRC32_POLYNOMIAL_BE RTE_BE32(ETH_CRC32_POLYNOMIAL)\n+#define ETH_CRC32_INIT_VAL_BE   RTE_BE32(ETH_CRC32_INIT_VAL)\n+#define ETH_CRC32_XOR_OUT_BE    RTE_BE32(ETH_CRC32_XOR_OUT)\n+\n /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */\n static const uint8_t sha1InitialState[] = {\n \t0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba,\n@@ -115,6 +123,10 @@ qat_sym_cd_cipher_set(struct qat_sym_session *cd,\n \t\t\t\t\t\tconst uint8_t *enckey,\n \t\t\t\t\t\tuint32_t enckeylen);\n \n+static int\n+qat_sym_cd_crc_set(struct qat_sym_session *cdesc,\n+\t\t\t\t\tenum qat_device_gen qat_dev_gen);\n+\n static int\n qat_sym_cd_auth_set(struct qat_sym_session *cdesc,\n \t\t\t\t\t\tconst uint8_t *authkey,\n@@ -122,6 +134,7 @@ qat_sym_cd_auth_set(struct qat_sym_session *cdesc,\n \t\t\t\t\t\tuint32_t aad_length,\n \t\t\t\t\t\tuint32_t digestsize,\n \t\t\t\t\t\tunsigned int operation);\n+\n static void\n qat_sym_session_init_common_hdr(struct qat_sym_session *session);\n \n@@ -630,6 +643,7 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev,\n \tcase ICP_QAT_FW_LA_CMD_MGF1:\n \tcase ICP_QAT_FW_LA_CMD_AUTH_PRE_COMP:\n \tcase ICP_QAT_FW_LA_CMD_CIPHER_PRE_COMP:\n+\tcase ICP_QAT_FW_LA_CMD_CIPHER_CRC:\n \tcase ICP_QAT_FW_LA_CMD_DELIMITER:\n \tQAT_LOG(ERR, \"Unsupported Service %u\",\n \t\tsession->qat_cmd);\n@@ -645,6 +659,45 @@ qat_sym_session_set_parameters(struct rte_cryptodev *dev,\n \t\t\t(void *)session);\n }\n \n+int\n+qat_cipher_crc_cap_msg_sess_prepare(struct qat_sym_session *session,\n+\t\t\t\t\trte_iova_t session_paddr,\n+\t\t\t\t\tconst uint8_t *cipherkey,\n+\t\t\t\t\tuint32_t cipherkeylen,\n+\t\t\t\t\tenum qat_device_gen qat_dev_gen)\n+{\n+\tint ret;\n+\n+\t/* Set content descriptor physical address */\n+\tsession->cd_paddr = session_paddr +\n+\t\t\t\toffsetof(struct qat_sym_session, cd);\n+\n+\t/* Set up some pre-requisite variables */\n+\tsession->qat_proto_flag = QAT_CRYPTO_PROTO_FLAG_NONE;\n+\tsession->is_ucs = 0;\n+\tsession->qat_cmd = ICP_QAT_FW_LA_CMD_CIPHER_CRC;\n+\tsession->qat_mode = ICP_QAT_HW_CIPHER_CBC_MODE;\n+\tsession->qat_cipher_alg = ICP_QAT_HW_CIPHER_ALGO_AES128;\n+\tsession->qat_dir = ICP_QAT_HW_CIPHER_ENCRYPT;\n+\tsession->is_auth = 1;\n+\tsession->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL;\n+\tsession->auth_mode = ICP_QAT_HW_AUTH_MODE0;\n+\tsession->auth_op = ICP_QAT_HW_AUTH_GENERATE;\n+\tsession->digest_length = RTE_ETHER_CRC_LEN;\n+\n+\tret = qat_sym_cd_cipher_set(session, cipherkey, cipherkeylen);\n+\tif (ret < 0)\n+\t\treturn -EINVAL;\n+\n+\tret = qat_sym_cd_crc_set(session, qat_dev_gen);\n+\tif (ret < 0)\n+\t\treturn -EINVAL;\n+\n+\tqat_sym_session_finalize(session);\n+\n+\treturn 0;\n+}\n+\n static int\n qat_sym_session_handle_single_pass(struct qat_sym_session *session,\n \t\tconst struct rte_crypto_aead_xform *aead_xform)\n@@ -1866,6 +1919,9 @@ int qat_sym_cd_cipher_set(struct qat_sym_session *cdesc,\n \t\tICP_QAT_FW_COMN_NEXT_ID_SET(hash_cd_ctrl,\n \t\t\t\t\tICP_QAT_FW_SLICE_DRAM_WR);\n \t\tcdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd;\n+\t} else if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_CRC) {\n+\t\tcd_pars->u.s.content_desc_addr = cdesc->cd_paddr;\n+\t\tcdesc->cd_cur_ptr = (uint8_t *)&cdesc->cd;\n \t} else if (cdesc->qat_cmd != ICP_QAT_FW_LA_CMD_HASH_CIPHER) {\n \t\tQAT_LOG(ERR, \"Invalid param, must be a cipher command.\");\n \t\treturn -EFAULT;\n@@ -2641,6 +2697,135 @@ qat_sec_session_check_docsis(struct rte_security_session_conf *conf)\n \treturn -EINVAL;\n }\n \n+static int\n+qat_sym_cd_crc_set(struct qat_sym_session *cdesc,\n+\t\tenum qat_device_gen qat_dev_gen)\n+{\n+\tstruct icp_qat_hw_gen2_crc_cd *crc_cd_gen2;\n+\tstruct icp_qat_hw_gen3_crc_cd *crc_cd_gen3;\n+\tstruct icp_qat_hw_gen4_crc_cd *crc_cd_gen4;\n+\tstruct icp_qat_fw_la_bulk_req *req_tmpl = &cdesc->fw_req;\n+\tstruct icp_qat_fw_comn_req_hdr_cd_pars *cd_pars = &req_tmpl->cd_pars;\n+\tvoid *ptr = &req_tmpl->cd_ctrl;\n+\tstruct icp_qat_fw_auth_cd_ctrl_hdr *crc_cd_ctrl = ptr;\n+\tstruct icp_qat_fw_la_auth_req_params *crc_param =\n+\t\t\t\t(struct icp_qat_fw_la_auth_req_params *)\n+\t\t\t\t((char *)&req_tmpl->serv_specif_rqpars +\n+\t\t\t\tICP_QAT_FW_HASH_REQUEST_PARAMETERS_OFFSET);\n+\tstruct icp_qat_fw_ucs_slice_cipher_config crc_cfg;\n+\tuint16_t crc_cfg_offset, cd_size;\n+\n+\tcrc_cfg_offset = cdesc->cd_cur_ptr - ((uint8_t *)&cdesc->cd);\n+\n+\tswitch (qat_dev_gen) {\n+\tcase QAT_GEN2:\n+\t\tcrc_cd_gen2 =\n+\t\t\t(struct icp_qat_hw_gen2_crc_cd *)cdesc->cd_cur_ptr;\n+\t\tcrc_cd_gen2->flags = 0;\n+\t\tcrc_cd_gen2->initial_crc = 0;\n+\t\tmemset(&crc_cd_gen2->reserved1,\n+\t\t\t0,\n+\t\t\tsizeof(crc_cd_gen2->reserved1));\n+\t\tmemset(&crc_cd_gen2->reserved2,\n+\t\t\t0,\n+\t\t\tsizeof(crc_cd_gen2->reserved2));\n+\t\tcdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen2_crc_cd);\n+\t\tbreak;\n+\tcase QAT_GEN3:\n+\t\tcrc_cd_gen3 =\n+\t\t\t(struct icp_qat_hw_gen3_crc_cd *)cdesc->cd_cur_ptr;\n+\t\tcrc_cd_gen3->flags = ICP_QAT_HW_GEN3_CRC_FLAGS_BUILD(1, 1);\n+\t\tcrc_cd_gen3->polynomial = ETH_CRC32_POLYNOMIAL;\n+\t\tcrc_cd_gen3->initial_crc = ETH_CRC32_INIT_VAL;\n+\t\tcrc_cd_gen3->xor_val = ETH_CRC32_XOR_OUT;\n+\t\tmemset(&crc_cd_gen3->reserved1,\n+\t\t\t0,\n+\t\t\tsizeof(crc_cd_gen3->reserved1));\n+\t\tmemset(&crc_cd_gen3->reserved2,\n+\t\t\t0,\n+\t\t\tsizeof(crc_cd_gen3->reserved2));\n+\t\tcrc_cd_gen3->reserved3 = 0;\n+\t\tcdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen3_crc_cd);\n+\t\tbreak;\n+\tcase QAT_GEN4:\n+\t\tcrc_cfg.mode = ICP_QAT_HW_CIPHER_ECB_MODE;\n+\t\tcrc_cfg.algo = ICP_QAT_HW_CIPHER_ALGO_NULL;\n+\t\tcrc_cfg.hash_cmp_val = 0;\n+\t\tcrc_cfg.dir = ICP_QAT_HW_CIPHER_ENCRYPT;\n+\t\tcrc_cfg.associated_data_len_in_bytes = 0;\n+\t\tcrc_cfg.crc_reflect_out =\n+\t\t\t\tICP_QAT_HW_CIPHER_UCS_REFLECT_OUT_ENABLED;\n+\t\tcrc_cfg.crc_reflect_in =\n+\t\t\t\tICP_QAT_HW_CIPHER_UCS_REFLECT_IN_ENABLED;\n+\t\tcrc_cfg.crc_encoding = ICP_QAT_HW_CIPHER_UCS_CRC32;\n+\n+\t\tcrc_cd_gen4 =\n+\t\t\t(struct icp_qat_hw_gen4_crc_cd *)cdesc->cd_cur_ptr;\n+\t\tcrc_cd_gen4->ucs_config[0] =\n+\t\t\tICP_QAT_HW_UCS_CIPHER_GEN4_BUILD_CONFIG_LOWER(crc_cfg);\n+\t\tcrc_cd_gen4->ucs_config[1] =\n+\t\t\tICP_QAT_HW_UCS_CIPHER_GEN4_BUILD_CONFIG_UPPER(crc_cfg);\n+\t\tcrc_cd_gen4->polynomial = ETH_CRC32_POLYNOMIAL_BE;\n+\t\tcrc_cd_gen4->initial_crc = ETH_CRC32_INIT_VAL_BE;\n+\t\tcrc_cd_gen4->xor_val = ETH_CRC32_XOR_OUT_BE;\n+\t\tcrc_cd_gen4->reserved1 = 0;\n+\t\tcrc_cd_gen4->reserved2 = 0;\n+\t\tcrc_cd_gen4->reserved3 = 0;\n+\t\tcdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_gen4_crc_cd);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tcrc_cd_ctrl->hash_cfg_offset = crc_cfg_offset >> 3;\n+\tcrc_cd_ctrl->hash_flags = ICP_QAT_FW_AUTH_HDR_FLAG_NO_NESTED;\n+\tcrc_cd_ctrl->inner_res_sz = cdesc->digest_length;\n+\tcrc_cd_ctrl->final_sz = cdesc->digest_length;\n+\tcrc_cd_ctrl->inner_state1_sz = 0;\n+\tcrc_cd_ctrl->inner_state2_sz  = 0;\n+\tcrc_cd_ctrl->inner_state2_offset = 0;\n+\tcrc_cd_ctrl->outer_prefix_sz = 0;\n+\tcrc_cd_ctrl->outer_config_offset = 0;\n+\tcrc_cd_ctrl->outer_state1_sz = 0;\n+\tcrc_cd_ctrl->outer_res_sz = 0;\n+\tcrc_cd_ctrl->outer_prefix_offset = 0;\n+\n+\tcrc_param->auth_res_sz = cdesc->digest_length;\n+\tcrc_param->u2.aad_sz = 0;\n+\tcrc_param->hash_state_sz = 0;\n+\n+\tcd_size = cdesc->cd_cur_ptr - (uint8_t *)&cdesc->cd;\n+\tcd_pars->u.s.content_desc_addr = cdesc->cd_paddr;\n+\tcd_pars->u.s.content_desc_params_sz = RTE_ALIGN_CEIL(cd_size, 8) >> 3;\n+\n+\treturn 0;\n+}\n+\n+static int\n+qat_sym_session_configure_crc(struct rte_cryptodev *dev,\n+\t\tconst struct rte_crypto_sym_xform *cipher_xform,\n+\t\tstruct qat_sym_session *session)\n+{\n+\tstruct qat_cryptodev_private *internals = dev->data->dev_private;\n+\tenum qat_device_gen qat_dev_gen = internals->qat_dev->qat_dev_gen;\n+\tint ret;\n+\n+\tsession->is_auth = 1;\n+\tsession->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL;\n+\tsession->auth_mode = ICP_QAT_HW_AUTH_MODE0;\n+\tsession->auth_op = cipher_xform->cipher.op ==\n+\t\t\t\tRTE_CRYPTO_CIPHER_OP_ENCRYPT ?\n+\t\t\t\t\tICP_QAT_HW_AUTH_GENERATE :\n+\t\t\t\t\tICP_QAT_HW_AUTH_VERIFY;\n+\tsession->digest_length = RTE_ETHER_CRC_LEN;\n+\n+\tret = qat_sym_cd_crc_set(session, qat_dev_gen);\n+\tif (ret < 0)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n static int\n qat_sec_session_set_docsis_parameters(struct rte_cryptodev *dev,\n \t\tstruct rte_security_session_conf *conf, void *session_private,\n@@ -2681,12 +2866,21 @@ qat_sec_session_set_docsis_parameters(struct rte_cryptodev *dev,\n \tif (qat_cmd_id != ICP_QAT_FW_LA_CMD_CIPHER) {\n \t\tQAT_LOG(ERR, \"Unsupported xform chain requested\");\n \t\treturn -ENOTSUP;\n+\t} else if (internals->internal_capabilities\n+\t\t\t\t\t& QAT_SYM_CAP_CIPHER_CRC) {\n+\t\tqat_cmd_id = ICP_QAT_FW_LA_CMD_CIPHER_CRC;\n \t}\n \tsession->qat_cmd = (enum icp_qat_fw_la_cmd_id)qat_cmd_id;\n \n \tret = qat_sym_session_configure_cipher(dev, xform, session);\n \tif (ret < 0)\n \t\treturn ret;\n+\n+\tif (qat_cmd_id == ICP_QAT_FW_LA_CMD_CIPHER_CRC) {\n+\t\tret = qat_sym_session_configure_crc(dev, xform, session);\n+\t\tif (ret < 0)\n+\t\t\treturn ret;\n+\t}\n \tqat_sym_session_finalize(session);\n \n \treturn qat_sym_gen_dev_ops[qat_dev_gen].set_session((void *)cdev,\ndiff --git a/drivers/crypto/qat/qat_sym_session.h b/drivers/crypto/qat/qat_sym_session.h\nindex 6322d7e3bc..9b5d11ac88 100644\n--- a/drivers/crypto/qat/qat_sym_session.h\n+++ b/drivers/crypto/qat/qat_sym_session.h\n@@ -46,6 +46,12 @@\n \t\t\t\t\tICP_QAT_HW_CIPHER_KEY_CONVERT, \\\n \t\t\t\t\tICP_QAT_HW_CIPHER_DECRYPT)\n \n+#define ICP_QAT_HW_GEN3_CRC_FLAGS_BUILD(ref_in, ref_out) \\\n+\t(((ref_in & QAT_GEN3_COMP_REFLECT_IN_MASK) << \\\n+\t\t\t\tQAT_GEN3_COMP_REFLECT_IN_BITPOS) | \\\n+\t((ref_out & QAT_GEN3_COMP_REFLECT_OUT_MASK) << \\\n+\t\t\t\tQAT_GEN3_COMP_REFLECT_OUT_BITPOS))\n+\n #define QAT_AES_CMAC_CONST_RB 0x87\n \n #define QAT_CRYPTO_SLICE_SPC\t1\n@@ -76,7 +82,12 @@ typedef int (*qat_sym_build_request_t)(void *in_op, struct qat_sym_session *ctx,\n /* Common content descriptor */\n struct qat_sym_cd {\n \tstruct icp_qat_hw_cipher_algo_blk cipher;\n-\tstruct icp_qat_hw_auth_algo_blk hash;\n+\tunion {\n+\t\tstruct icp_qat_hw_auth_algo_blk hash;\n+\t\tstruct icp_qat_hw_gen2_crc_cd crc_gen2;\n+\t\tstruct icp_qat_hw_gen3_crc_cd crc_gen3;\n+\t\tstruct icp_qat_hw_gen4_crc_cd crc_gen4;\n+\t};\n } __rte_packed __rte_cache_aligned;\n \n struct qat_sym_session {\n@@ -152,10 +163,18 @@ qat_sym_session_clear(struct rte_cryptodev *dev,\n unsigned int\n qat_sym_session_get_private_size(struct rte_cryptodev *dev);\n \n+int\n+qat_cipher_crc_cap_msg_sess_prepare(struct qat_sym_session *session,\n+\t\t\t\t\trte_iova_t session_paddr,\n+\t\t\t\t\tconst uint8_t *cipherkey,\n+\t\t\t\t\tuint32_t cipherkeylen,\n+\t\t\t\t\tenum qat_device_gen qat_dev_gen);\n+\n void\n qat_sym_sesssion_init_common_hdr(struct qat_sym_session *session,\n \t\t\t\t\tstruct icp_qat_fw_comn_req_hdr *header,\n \t\t\t\t\tenum qat_sym_proto_flag proto_flags);\n+\n int\n qat_sym_validate_aes_key(int key_len, enum icp_qat_hw_cipher_algo *alg);\n int\n",
    "prefixes": [
        "v2",
        "2/2"
    ]
}