get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 115048,
    "url": "http://patches.dpdk.org/api/patches/115048/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20220815073206.2917968-21-qi.z.zhang@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.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": "<20220815073206.2917968-21-qi.z.zhang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220815073206.2917968-21-qi.z.zhang@intel.com",
    "date": "2022-08-15T07:31:16",
    "name": "[v2,20/70] net/ice/base: refactor DDP code",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "547c05d5a1a853a35495bed039c119358cde1120",
    "submitter": {
        "id": 504,
        "url": "http://patches.dpdk.org/api/people/504/?format=api",
        "name": "Qi Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patches.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20220815073206.2917968-21-qi.z.zhang@intel.com/mbox/",
    "series": [
        {
            "id": 24308,
            "url": "http://patches.dpdk.org/api/series/24308/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=24308",
            "date": "2022-08-15T07:30:56",
            "name": "ice base code update",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/24308/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/115048/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/115048/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 C62C7A00C3;\n\tMon, 15 Aug 2022 01:24:13 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 4FE6042C1F;\n\tMon, 15 Aug 2022 01:22:51 +0200 (CEST)",
            "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n by mails.dpdk.org (Postfix) with ESMTP id 8DF7842C2D\n for <dev@dpdk.org>; Mon, 15 Aug 2022 01:22:49 +0200 (CEST)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 14 Aug 2022 16:22:49 -0700",
            "from dpdk-qzhan15-test02.sh.intel.com ([10.67.115.4])\n by orsmga008.jf.intel.com with ESMTP; 14 Aug 2022 16:22:46 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1660519369; x=1692055369;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=Py4+41VfqBj0cywDot0nHI6x2E8DUKQEMB6FVZq6LuA=;\n b=lnZ0KdHIU2YgPU6H0SOcI2ex64iep3UjCypgCj+INeJ6g9h4xCNSrnfv\n JQbMkcileIPvbRs4vVvDnMDwENC852UsCQjbDkmo/eCLSMlcYcKkbkt6L\n TmCdwjLA+fVBuD7SJG5z72OZd5S6W1JmM5522H/xxLQdQ3fKqfUWpj4MZ\n K9fPXLgwRGAaziq6ivXYcP+PgdXDnrzu/aLBzcHyeGRqhJCsuDf8ccz7M\n mXkp4uLm7Pfd5CFIfJLGUu/Q4dTsM/mwKFMkkCrLUkjmVF6EmEWTCTJeM\n Xr192TvVWTcskpdP1JHLgWL4UvpM2nWyLBhzX8jKyjer5vdowwvGMPixD Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6400,9594,10439\"; a=\"291857944\"",
            "E=Sophos;i=\"5.93,237,1654585200\"; d=\"scan'208\";a=\"291857944\"",
            "E=Sophos;i=\"5.93,237,1654585200\"; d=\"scan'208\";a=\"635283105\""
        ],
        "X-ExtLoop1": "1",
        "From": "Qi Zhang <qi.z.zhang@intel.com>",
        "To": "qiming.yang@intel.com",
        "Cc": "dev@dpdk.org, Qi Zhang <qi.z.zhang@intel.com>,\n Sergey Temerkhanov <sergey.temerkhanov@intel.com>,\n Wojciech Drewek <wojciech.drewek@intel.com>,\n Dan Nowlin <dan.nowlin@intel.com>",
        "Subject": "[PATCH v2 20/70] net/ice/base: refactor DDP code",
        "Date": "Mon, 15 Aug 2022 03:31:16 -0400",
        "Message-Id": "<20220815073206.2917968-21-qi.z.zhang@intel.com>",
        "X-Mailer": "git-send-email 2.31.1",
        "In-Reply-To": "<20220815073206.2917968-1-qi.z.zhang@intel.com>",
        "References": "<20220815071306.2910599-1-qi.z.zhang@intel.com>\n <20220815073206.2917968-1-qi.z.zhang@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "Move DDP related into ice_ddp.c.\nRefactor status flow for DDP load.\nAslo added support for DDP signature segments.\n\nSigned-off-by: Sergey Temerkhanov <sergey.temerkhanov@intel.com>\nSigned-off-by: Wojciech Drewek <wojciech.drewek@intel.com>\nSigned-off-by: Dan Nowlin <dan.nowlin@intel.com>\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\n---\n drivers/net/ice/base/ice_adminq_cmd.h |   32 +\n drivers/net/ice/base/ice_bitops.h     |    5 +-\n drivers/net/ice/base/ice_ddp.c        | 2475 +++++++++++++++++++++++++\n drivers/net/ice/base/ice_ddp.h        |  466 +++++\n drivers/net/ice/base/ice_defs.h       |   49 +\n drivers/net/ice/base/ice_flex_pipe.c  | 2175 ++--------------------\n drivers/net/ice/base/ice_flex_pipe.h  |   57 +-\n drivers/net/ice/base/ice_flex_type.h  |  286 +--\n drivers/net/ice/base/ice_switch.c     |   36 +-\n drivers/net/ice/base/ice_type.h       |   54 +-\n drivers/net/ice/base/ice_vlan_mode.c  |    1 +\n drivers/net/ice/base/meson.build      |    1 +\n 12 files changed, 3233 insertions(+), 2404 deletions(-)\n create mode 100644 drivers/net/ice/base/ice_ddp.c\n create mode 100644 drivers/net/ice/base/ice_ddp.h\n create mode 100644 drivers/net/ice/base/ice_defs.h",
    "diff": "diff --git a/drivers/net/ice/base/ice_adminq_cmd.h b/drivers/net/ice/base/ice_adminq_cmd.h\nindex 517af4b6ef..8f7e13096c 100644\n--- a/drivers/net/ice/base/ice_adminq_cmd.h\n+++ b/drivers/net/ice/base/ice_adminq_cmd.h\n@@ -9,10 +9,19 @@\n  * descriptor format. It is shared between Firmware and Software.\n  */\n \n+#include \"ice_osdep.h\"\n+#include \"ice_defs.h\"\n+#include \"ice_bitops.h\"\n+\n #define ICE_MAX_VSI\t\t\t768\n #define ICE_AQC_TOPO_MAX_LEVEL_NUM\t0x9\n #define ICE_AQ_SET_MAC_FRAME_SIZE_MAX\t9728\n \n+enum ice_aq_res_access_type {\n+\tICE_RES_READ = 1,\n+\tICE_RES_WRITE\n+};\n+\n struct ice_aqc_generic {\n \t__le32 param0;\n \t__le32 param1;\n@@ -1035,6 +1044,24 @@ struct ice_aqc_get_topo {\n \t__le32 addr_low;\n };\n \n+/* Get/Set Tx Topology (indirect 0x0418/0x0417) */\n+struct ice_aqc_get_set_tx_topo {\n+\tu8 set_flags;\n+#define ICE_AQC_TX_TOPO_FLAGS_CORRER\t\tBIT(0)\n+#define ICE_AQC_TX_TOPO_FLAGS_SRC_RAM\t\tBIT(1)\n+#define ICE_AQC_TX_TOPO_FLAGS_SET_PSM\t\tBIT(2)\n+#define ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW\t\tBIT(4)\n+#define ICE_AQC_TX_TOPO_FLAGS_ISSUED\t\tBIT(5)\n+\tu8 get_flags;\n+#define ICE_AQC_TX_TOPO_GET_NO_UPDATE\t\t0\n+#define ICE_AQC_TX_TOPO_GET_PSM\t\t\t1\n+#define ICE_AQC_TX_TOPO_GET_RAM\t\t\t2\n+\t__le16 reserved1;\n+\t__le32 reserved2;\n+\t__le32 addr_high;\n+\t__le32 addr_low;\n+};\n+\n /* Update TSE (indirect 0x0403)\n  * Get TSE (indirect 0x0404)\n  * Add TSE (indirect 0x0401)\n@@ -3008,6 +3035,7 @@ struct ice_aq_desc {\n \t\tstruct ice_aqc_clear_health_status clear_health_status;\n \t\tstruct ice_aqc_prog_topo_dev_nvm prog_topo_dev_nvm;\n \t\tstruct ice_aqc_read_topo_dev_nvm read_topo_dev_nvm;\n+\t\tstruct ice_aqc_get_set_tx_topo get_set_tx_topo;\n \t} params;\n };\n \n@@ -3164,6 +3192,10 @@ enum ice_adminq_opc {\n \tice_aqc_opc_query_node_to_root\t\t\t= 0x0413,\n \tice_aqc_opc_cfg_l2_node_cgd\t\t\t= 0x0414,\n \tice_aqc_opc_remove_rl_profiles\t\t\t= 0x0415,\n+\tice_aqc_opc_set_tx_topo\t\t\t\t= 0x0417,\n+\tice_aqc_opc_get_tx_topo\t\t\t\t= 0x0418,\n+\tice_aqc_opc_cfg_node_attr\t\t\t= 0x0419,\n+\tice_aqc_opc_query_node_attr\t\t\t= 0x041A,\n \n \t/* PHY commands */\n \tice_aqc_opc_get_phy_caps\t\t\t= 0x0600,\ndiff --git a/drivers/net/ice/base/ice_bitops.h b/drivers/net/ice/base/ice_bitops.h\nindex 21ec2014e1..8060c103fa 100644\n--- a/drivers/net/ice/base/ice_bitops.h\n+++ b/drivers/net/ice/base/ice_bitops.h\n@@ -5,6 +5,9 @@\n #ifndef _ICE_BITOPS_H_\n #define _ICE_BITOPS_H_\n \n+#include \"ice_defs.h\"\n+#include \"ice_osdep.h\"\n+\n /* Define the size of the bitmap chunk */\n typedef u32 ice_bitmap_t;\n \n@@ -13,7 +16,7 @@ typedef u32 ice_bitmap_t;\n /* Determine which chunk a bit belongs in */\n #define BIT_CHUNK(nr)\t\t((nr) / BITS_PER_CHUNK)\n /* How many chunks are required to store this many bits */\n-#define BITS_TO_CHUNKS(sz)\tDIVIDE_AND_ROUND_UP((sz), BITS_PER_CHUNK)\n+#define BITS_TO_CHUNKS(sz)\t(((sz) + BITS_PER_CHUNK - 1) / BITS_PER_CHUNK)\n /* Which bit inside a chunk this bit corresponds to */\n #define BIT_IN_CHUNK(nr)\t((nr) % BITS_PER_CHUNK)\n /* How many bits are valid in the last chunk, assumes nr > 0 */\ndiff --git a/drivers/net/ice/base/ice_ddp.c b/drivers/net/ice/base/ice_ddp.c\nnew file mode 100644\nindex 0000000000..d1cae48047\n--- /dev/null\n+++ b/drivers/net/ice/base/ice_ddp.c\n@@ -0,0 +1,2475 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2001-2022 Intel Corporation\n+ */\n+\n+#include \"ice_ddp.h\"\n+#include \"ice_type.h\"\n+#include \"ice_common.h\"\n+#include \"ice_sched.h\"\n+\n+/**\n+ * ice_aq_download_pkg\n+ * @hw: pointer to the hardware structure\n+ * @pkg_buf: the package buffer to transfer\n+ * @buf_size: the size of the package buffer\n+ * @last_buf: last buffer indicator\n+ * @error_offset: returns error offset\n+ * @error_info: returns error information\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Download Package (0x0C40)\n+ */\n+static enum ice_status\n+ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,\n+\t\t    u16 buf_size, bool last_buf, u32 *error_offset,\n+\t\t    u32 *error_info, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_download_pkg *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tif (error_offset)\n+\t\t*error_offset = 0;\n+\tif (error_info)\n+\t\t*error_info = 0;\n+\n+\tcmd = &desc.params.download_pkg;\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg);\n+\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n+\n+\tif (last_buf)\n+\t\tcmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;\n+\n+\tstatus = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n+\tif (status == ICE_ERR_AQ_ERROR) {\n+\t\t/* Read error from buffer only when the FW returned an error */\n+\t\tstruct ice_aqc_download_pkg_resp *resp;\n+\n+\t\tresp = (struct ice_aqc_download_pkg_resp *)pkg_buf;\n+\t\tif (error_offset)\n+\t\t\t*error_offset = LE32_TO_CPU(resp->error_offset);\n+\t\tif (error_info)\n+\t\t\t*error_info = LE32_TO_CPU(resp->error_info);\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_aq_upload_section\n+ * @hw: pointer to the hardware structure\n+ * @pkg_buf: the package buffer which will receive the section\n+ * @buf_size: the size of the package buffer\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Upload Section (0x0C41)\n+ */\n+enum ice_status\n+ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,\n+\t\t      u16 buf_size, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aq_desc desc;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section);\n+\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n+}\n+\n+/**\n+ * ice_aq_update_pkg\n+ * @hw: pointer to the hardware structure\n+ * @pkg_buf: the package cmd buffer\n+ * @buf_size: the size of the package cmd buffer\n+ * @last_buf: last buffer indicator\n+ * @error_offset: returns error offset\n+ * @error_info: returns error information\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Update Package (0x0C42)\n+ */\n+static enum ice_status\n+ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, u16 buf_size,\n+\t\t  bool last_buf, u32 *error_offset, u32 *error_info,\n+\t\t  struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aqc_download_pkg *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tif (error_offset)\n+\t\t*error_offset = 0;\n+\tif (error_info)\n+\t\t*error_info = 0;\n+\n+\tcmd = &desc.params.download_pkg;\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg);\n+\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n+\n+\tif (last_buf)\n+\t\tcmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;\n+\n+\tstatus = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n+\tif (status == ICE_ERR_AQ_ERROR) {\n+\t\t/* Read error from buffer only when the FW returned an error */\n+\t\tstruct ice_aqc_download_pkg_resp *resp;\n+\n+\t\tresp = (struct ice_aqc_download_pkg_resp *)pkg_buf;\n+\t\tif (error_offset)\n+\t\t\t*error_offset = LE32_TO_CPU(resp->error_offset);\n+\t\tif (error_info)\n+\t\t\t*error_info = LE32_TO_CPU(resp->error_info);\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_find_seg_in_pkg\n+ * @hw: pointer to the hardware structure\n+ * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK)\n+ * @pkg_hdr: pointer to the package header to be searched\n+ *\n+ * This function searches a package file for a particular segment type. On\n+ * success it returns a pointer to the segment header, otherwise it will\n+ * return NULL.\n+ */\n+struct ice_generic_seg_hdr *\n+ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,\n+\t\t    struct ice_pkg_hdr *pkg_hdr)\n+{\n+\tu32 i;\n+\n+\tice_debug(hw, ICE_DBG_PKG, \"Package format version: %d.%d.%d.%d\\n\",\n+\t\t  pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor,\n+\t\t  pkg_hdr->pkg_format_ver.update,\n+\t\t  pkg_hdr->pkg_format_ver.draft);\n+\n+\t/* Search all package segments for the requested segment type */\n+\tfor (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {\n+\t\tstruct ice_generic_seg_hdr *seg;\n+\n+\t\tseg = (struct ice_generic_seg_hdr *)\n+\t\t\t((u8 *)pkg_hdr + LE32_TO_CPU(pkg_hdr->seg_offset[i]));\n+\n+\t\tif (LE32_TO_CPU(seg->seg_type) == seg_type)\n+\t\t\treturn seg;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+/**\n+ * ice_get_pkg_seg_by_idx\n+ * @pkg_hdr: pointer to the package header to be searched\n+ * @idx: index of segment\n+ */\n+static struct ice_generic_seg_hdr *\n+ice_get_pkg_seg_by_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)\n+{\n+\tstruct ice_generic_seg_hdr *seg = NULL;\n+\n+\tif (idx < LE32_TO_CPU(pkg_hdr->seg_count))\n+\t\tseg = (struct ice_generic_seg_hdr *)\n+\t\t\t((u8 *)pkg_hdr +\n+\t\t\t LE32_TO_CPU(pkg_hdr->seg_offset[idx]));\n+\n+\treturn seg;\n+}\n+\n+/**\n+ * ice_is_signing_seg_at_idx - determine if segment is a signing segment\n+ * @pkg_hdr: pointer to package header\n+ * @idx: segment index\n+ */\n+static bool ice_is_signing_seg_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)\n+{\n+\tstruct ice_generic_seg_hdr *seg;\n+\tbool retval = false;\n+\n+\tseg = ice_get_pkg_seg_by_idx(pkg_hdr, idx);\n+\tif (seg)\n+\t\tretval = LE32_TO_CPU(seg->seg_type) == SEGMENT_TYPE_SIGNING;\n+\n+\treturn retval;\n+}\n+\n+/**\n+ * ice_is_signing_seg_type_at_idx\n+ * @pkg_hdr: pointer to package header\n+ * @idx: segment index\n+ * @seg_id: segment id that is expected\n+ * @sign_type: signing type\n+ *\n+ * Determine if a segment is a signing segment of the correct type\n+ */\n+static bool\n+ice_is_signing_seg_type_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx,\n+\t\t\t       u32 seg_id, u32 sign_type)\n+{\n+\tbool result = false;\n+\n+\tif (ice_is_signing_seg_at_idx(pkg_hdr, idx)) {\n+\t\tstruct ice_sign_seg *seg;\n+\n+\t\tseg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr,\n+\t\t\t\t\t\t\t\t    idx);\n+\t\tif (seg && LE32_TO_CPU(seg->seg_id) == seg_id &&\n+\t\t    LE32_TO_CPU(seg->sign_type) == sign_type)\n+\t\t\tresult = true;\n+\t}\n+\n+\treturn result;\n+}\n+\n+/**\n+ * ice_update_pkg_no_lock\n+ * @hw: pointer to the hardware structure\n+ * @bufs: pointer to an array of buffers\n+ * @count: the number of buffers in the array\n+ */\n+enum ice_status\n+ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n+{\n+\tenum ice_status status = ICE_SUCCESS;\n+\tu32 i;\n+\n+\tfor (i = 0; i < count; i++) {\n+\t\tstruct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i);\n+\t\tbool last = ((i + 1) == count);\n+\t\tu32 offset, info;\n+\n+\t\tstatus = ice_aq_update_pkg(hw, bh, LE16_TO_CPU(bh->data_end),\n+\t\t\t\t\t   last, &offset, &info, NULL);\n+\n+\t\tif (status) {\n+\t\t\tice_debug(hw, ICE_DBG_PKG, \"Update pkg failed: err %d off %d inf %d\\n\",\n+\t\t\t\t  status, offset, info);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_update_pkg\n+ * @hw: pointer to the hardware structure\n+ * @bufs: pointer to an array of buffers\n+ * @count: the number of buffers in the array\n+ *\n+ * Obtains change lock and updates package.\n+ */\n+enum ice_status\n+ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n+{\n+\tenum ice_status status;\n+\n+\tstatus = ice_acquire_change_lock(hw, ICE_RES_WRITE);\n+\tif (status)\n+\t\treturn status;\n+\n+\tstatus = ice_update_pkg_no_lock(hw, bufs, count);\n+\n+\tice_release_change_lock(hw);\n+\n+\treturn status;\n+}\n+\n+static enum ice_ddp_state\n+ice_map_aq_err_to_ddp_state(enum ice_aq_err aq_err)\n+{\n+\tswitch (aq_err) {\n+\tcase ICE_AQ_RC_ENOSEC:\n+\t\treturn ICE_DDP_PKG_NO_SEC_MANIFEST;\n+\tcase ICE_AQ_RC_EBADSIG:\n+\t\treturn ICE_DDP_PKG_FILE_SIGNATURE_INVALID;\n+\tcase ICE_AQ_RC_ESVN:\n+\t\treturn ICE_DDP_PKG_SECURE_VERSION_NBR_TOO_LOW;\n+\tcase ICE_AQ_RC_EBADMAN:\n+\t\treturn ICE_DDP_PKG_MANIFEST_INVALID;\n+\tcase ICE_AQ_RC_EBADBUF:\n+\t\treturn ICE_DDP_PKG_BUFFER_INVALID;\n+\tdefault:\n+\t\treturn ICE_DDP_PKG_ERR;\n+\t}\n+}\n+\n+/**\n+ * ice_is_buffer_metadata - determine if package buffer is a metadata buffer\n+ * @buf: pointer to buffer header\n+ */\n+static bool ice_is_buffer_metadata(struct ice_buf_hdr *buf)\n+{\n+\tbool metadata = false;\n+\n+\tif (LE32_TO_CPU(buf->section_entry[0].type) & ICE_METADATA_BUF)\n+\t\tmetadata = true;\n+\n+\treturn metadata;\n+}\n+\n+/**\n+ * ice_is_last_download_buffer\n+ * @buf: pointer to current buffer header\n+ * @idx: index of the buffer in the current sequence\n+ * @count: the buffer count in the current sequence\n+ *\n+ * Note: this routine should only be called if the buffer is not the last buffer\n+ */\n+static bool\n+ice_is_last_download_buffer(struct ice_buf_hdr *buf, u32 idx, u32 count)\n+{\n+\tbool last = ((idx + 1) == count);\n+\n+\t/* A set metadata flag in the next buffer will signal that the current\n+\t * buffer will be the last buffer downloaded\n+\t */\n+\tif (!last) {\n+\t\tstruct ice_buf *next_buf = ((struct ice_buf *)buf) + 1;\n+\n+\t\tlast = ice_is_buffer_metadata((struct ice_buf_hdr *)next_buf);\n+\t}\n+\n+\treturn last;\n+}\n+\n+/**\n+ * ice_dwnld_cfg_bufs_no_lock\n+ * @hw: pointer to the hardware structure\n+ * @bufs: pointer to an array of buffers\n+ * @start: buffer index of first buffer to download\n+ * @count: the number of buffers to download\n+ * @indicate_last: if true, then set last buffer flag on last buffer download\n+ *\n+ * Downloads package configuration buffers to the firmware. Metadata buffers\n+ * are skipped, and the first metadata buffer found indicates that the rest\n+ * of the buffers are all metadata buffers.\n+ */\n+static enum ice_ddp_state\n+ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start,\n+\t\t\t   u32 count, bool indicate_last)\n+{\n+\tenum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;\n+\tstruct ice_buf_hdr *bh;\n+\tenum ice_aq_err err;\n+\tu32 offset, info, i;\n+\n+\tif (!bufs || !count)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\t/* If the first buffer's first section has its metadata bit set\n+\t * then there are no buffers to be downloaded, and the operation is\n+\t * considered a success.\n+\t */\n+\tbh = (struct ice_buf_hdr *)(bufs + start);\n+\tif (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)\n+\t\treturn ICE_DDP_PKG_SUCCESS;\n+\n+\tfor (i = 0; i < count; i++) {\n+\t\tenum ice_status status;\n+\t\tbool last = false;\n+\n+\t\tbh = (struct ice_buf_hdr *)(bufs + start + i);\n+\n+\t\tif (indicate_last)\n+\t\t\tlast = ice_is_last_download_buffer(bh, i, count);\n+\n+\t\tstatus = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last,\n+\t\t\t\t\t     &offset, &info, NULL);\n+\n+\t\t/* Save AQ status from download package */\n+\t\tif (status) {\n+\t\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg download failed: err %d off %d inf %d\\n\",\n+\t\t\t\t  status, offset, info);\n+\t\t\terr = hw->adminq.sq_last_status;\n+\t\t\tstate = ice_map_aq_err_to_ddp_state(err);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (last)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_aq_get_pkg_info_list\n+ * @hw: pointer to the hardware structure\n+ * @pkg_info: the buffer which will receive the information list\n+ * @buf_size: the size of the pkg_info information buffer\n+ * @cd: pointer to command details structure or NULL\n+ *\n+ * Get Package Info List (0x0C43)\n+ */\n+static enum ice_status\n+ice_aq_get_pkg_info_list(struct ice_hw *hw,\n+\t\t\t struct ice_aqc_get_pkg_info_resp *pkg_info,\n+\t\t\t u16 buf_size, struct ice_sq_cd *cd)\n+{\n+\tstruct ice_aq_desc desc;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd);\n+}\n+\n+/**\n+ * ice_has_signing_seg - determine if package has a signing segment\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to the driver's package hdr\n+ */\n+static bool ice_has_signing_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)\n+{\n+\tstruct ice_generic_seg_hdr *seg_hdr;\n+\n+\tseg_hdr = (struct ice_generic_seg_hdr *)\n+\t\tice_find_seg_in_pkg(hw, SEGMENT_TYPE_SIGNING, pkg_hdr);\n+\n+\treturn seg_hdr ? true : false;\n+}\n+\n+/**\n+ * ice_get_pkg_segment_id - get correct package segment id, based on device\n+ * @mac_type: MAC type of the device\n+ */\n+static u32 ice_get_pkg_segment_id(enum ice_mac_type mac_type)\n+{\n+\tu32 seg_id;\n+\n+\tswitch (mac_type) {\n+\tcase ICE_MAC_GENERIC:\n+\tcase ICE_MAC_GENERIC_3K:\n+\tdefault:\n+\t\tseg_id = SEGMENT_TYPE_ICE_E810;\n+\t\tbreak;\n+\t}\n+\n+\treturn seg_id;\n+}\n+\n+/**\n+ * ice_get_pkg_sign_type - get package segment sign type, based on device\n+ * @mac_type: MAC type of the device\n+ */\n+static u32 ice_get_pkg_sign_type(enum ice_mac_type mac_type)\n+{\n+\tu32 sign_type;\n+\n+\tswitch (mac_type) {\n+\tcase ICE_MAC_GENERIC_3K:\n+\t\tsign_type = SEGMENT_SIGN_TYPE_RSA3K;\n+\t\tbreak;\n+\tcase ICE_MAC_GENERIC:\n+\tdefault:\n+\t\tsign_type = SEGMENT_SIGN_TYPE_RSA2K;\n+\t\tbreak;\n+\t}\n+\n+\treturn sign_type;\n+}\n+\n+/**\n+ * ice_get_signing_req - get correct package requirements, based on device\n+ * @hw: pointer to the hardware structure\n+ */\n+static void ice_get_signing_req(struct ice_hw *hw)\n+{\n+\thw->pkg_seg_id = ice_get_pkg_segment_id(hw->mac_type);\n+\thw->pkg_sign_type = ice_get_pkg_sign_type(hw->mac_type);\n+}\n+\n+/**\n+ * ice_download_pkg_sig_seg - download a signature segment\n+ * @hw: pointer to the hardware structure\n+ * @seg: pointer to signature segment\n+ */\n+static enum ice_ddp_state\n+ice_download_pkg_sig_seg(struct ice_hw *hw, struct ice_sign_seg *seg)\n+{\n+\tenum ice_ddp_state state;\n+\n+\tstate = ice_dwnld_cfg_bufs_no_lock(hw, seg->buf_tbl.buf_array, 0,\n+\t\t\t\t\t   LE32_TO_CPU(seg->buf_tbl.buf_count),\n+\t\t\t\t\t   false);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_download_pkg_config_seg - download a config segment\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to package header\n+ * @idx: segment index\n+ * @start: starting buffer\n+ * @count: buffer count\n+ *\n+ * Note: idx must reference a ICE segment\n+ */\n+static enum ice_ddp_state\n+ice_download_pkg_config_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,\n+\t\t\t    u32 idx, u32 start, u32 count)\n+{\n+\tstruct ice_buf_table *bufs;\n+\tenum ice_ddp_state state;\n+\tstruct ice_seg *seg;\n+\tu32 buf_count;\n+\n+\tseg = (struct ice_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);\n+\tif (!seg)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tbufs = ice_find_buf_table(seg);\n+\tbuf_count = LE32_TO_CPU(bufs->buf_count);\n+\n+\tif (start >= buf_count || start + count > buf_count)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tstate = ice_dwnld_cfg_bufs_no_lock(hw, bufs->buf_array, start, count,\n+\t\t\t\t\t   true);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_dwnld_sign_and_cfg_segs - download a signing segment and config segment\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to package header\n+ * @idx: segment index (must be a signature segment)\n+ *\n+ * Note: idx must reference a signature segment\n+ */\n+static enum ice_ddp_state\n+ice_dwnld_sign_and_cfg_segs(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,\n+\t\t\t    u32 idx)\n+{\n+\tenum ice_ddp_state state;\n+\tstruct ice_sign_seg *seg;\n+\tu32 conf_idx;\n+\tu32 start;\n+\tu32 count;\n+\n+\tseg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);\n+\tif (!seg) {\n+\t\tstate = ICE_DDP_PKG_ERR;\n+\t\tgoto exit;\n+\t}\n+\n+\tconf_idx = LE32_TO_CPU(seg->signed_seg_idx);\n+\tstart = LE32_TO_CPU(seg->signed_buf_start);\n+\tcount = LE32_TO_CPU(seg->signed_buf_count);\n+\n+\tstate = ice_download_pkg_sig_seg(hw, seg);\n+\tif (state)\n+\t\tgoto exit;\n+\n+\tstate = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,\n+\t\t\t\t\t    count);\n+\n+exit:\n+\treturn state;\n+}\n+\n+/**\n+ * ice_match_signing_seg - determine if a matching signing segment exists\n+ * @pkg_hdr: pointer to package header\n+ * @seg_id: segment id that is expected\n+ * @sign_type: signing type\n+ */\n+static bool\n+ice_match_signing_seg(struct ice_pkg_hdr *pkg_hdr, u32 seg_id, u32 sign_type)\n+{\n+\tbool match = false;\n+\tu32 i;\n+\n+\tfor (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {\n+\t\tif (ice_is_signing_seg_type_at_idx(pkg_hdr, i, seg_id,\n+\t\t\t\t\t\t   sign_type)) {\n+\t\t\tmatch = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\treturn match;\n+}\n+\n+/**\n+ * ice_post_dwnld_pkg_actions - perform post download package actions\n+ * @hw: pointer to the hardware structure\n+ */\n+static enum ice_ddp_state\n+ice_post_dwnld_pkg_actions(struct ice_hw *hw)\n+{\n+\tenum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;\n+\tenum ice_status status;\n+\n+\tstatus = ice_set_vlan_mode(hw);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Failed to set VLAN mode: err %d\\n\",\n+\t\t\t  status);\n+\t\tstate = ICE_DDP_PKG_ERR;\n+\t}\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_download_pkg_with_sig_seg - download package using signature segments\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to package header\n+ */\n+static enum ice_ddp_state\n+ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)\n+{\n+\tenum ice_aq_err aq_err = hw->adminq.sq_last_status;\n+\tenum ice_ddp_state state = ICE_DDP_PKG_ERR;\n+\tenum ice_status status;\n+\tu32 i;\n+\n+\tice_debug(hw, ICE_DBG_INIT, \"Segment ID %d\\n\", hw->pkg_seg_id);\n+\tice_debug(hw, ICE_DBG_INIT, \"Signature type %d\\n\", hw->pkg_sign_type);\n+\n+\tstatus = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);\n+\tif (status) {\n+\t\tif (status == ICE_ERR_AQ_NO_WORK)\n+\t\t\tstate = ICE_DDP_PKG_ALREADY_LOADED;\n+\t\telse\n+\t\t\tstate = ice_map_aq_err_to_ddp_state(aq_err);\n+\t\treturn state;\n+\t}\n+\n+\tfor (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {\n+\t\tif (!ice_is_signing_seg_type_at_idx(pkg_hdr, i, hw->pkg_seg_id,\n+\t\t\t\t\t\t    hw->pkg_sign_type))\n+\t\t\tcontinue;\n+\n+\t\tstate = ice_dwnld_sign_and_cfg_segs(hw, pkg_hdr, i);\n+\t\tif (state)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (!state)\n+\t\tstate = ice_post_dwnld_pkg_actions(hw);\n+\n+\tice_release_global_cfg_lock(hw);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_dwnld_cfg_bufs\n+ * @hw: pointer to the hardware structure\n+ * @bufs: pointer to an array of buffers\n+ * @count: the number of buffers in the array\n+ *\n+ * Obtains global config lock and downloads the package configuration buffers\n+ * to the firmware.\n+ */\n+static enum ice_ddp_state\n+ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n+{\n+\tenum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;\n+\tenum ice_status status;\n+\tstruct ice_buf_hdr *bh;\n+\n+\tif (!bufs || !count)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\t/* If the first buffer's first section has its metadata bit set\n+\t * then there are no buffers to be downloaded, and the operation is\n+\t * considered a success.\n+\t */\n+\tbh = (struct ice_buf_hdr *)bufs;\n+\tif (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)\n+\t\treturn ICE_DDP_PKG_SUCCESS;\n+\n+\tstatus = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);\n+\tif (status) {\n+\t\tif (status == ICE_ERR_AQ_NO_WORK)\n+\t\t\treturn ICE_DDP_PKG_ALREADY_LOADED;\n+\t\treturn ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status);\n+\t}\n+\n+\tstate = ice_dwnld_cfg_bufs_no_lock(hw, bufs, 0, count, true);\n+\tif (!state)\n+\t\tstate = ice_post_dwnld_pkg_actions(hw);\n+\n+\tice_release_global_cfg_lock(hw);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_download_pkg_without_sig_seg\n+ * @hw: pointer to the hardware structure\n+ * @ice_seg: pointer to the segment of the package to be downloaded\n+ *\n+ * Handles the download of a complete package without signature segment.\n+ */\n+static enum ice_ddp_state\n+ice_download_pkg_without_sig_seg(struct ice_hw *hw, struct ice_seg *ice_seg)\n+{\n+\tstruct ice_buf_table *ice_buf_tbl;\n+\tenum ice_ddp_state state;\n+\n+\tice_debug(hw, ICE_DBG_PKG, \"Segment format version: %d.%d.%d.%d\\n\",\n+\t\t  ice_seg->hdr.seg_format_ver.major,\n+\t\t  ice_seg->hdr.seg_format_ver.minor,\n+\t\t  ice_seg->hdr.seg_format_ver.update,\n+\t\t  ice_seg->hdr.seg_format_ver.draft);\n+\n+\tice_debug(hw, ICE_DBG_PKG, \"Seg: type 0x%X, size %d, name %s\\n\",\n+\t\t  LE32_TO_CPU(ice_seg->hdr.seg_type),\n+\t\t  LE32_TO_CPU(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id);\n+\n+\tice_buf_tbl = ice_find_buf_table(ice_seg);\n+\n+\tice_debug(hw, ICE_DBG_PKG, \"Seg buf count: %d\\n\",\n+\t\t  LE32_TO_CPU(ice_buf_tbl->buf_count));\n+\n+\tstate = ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array,\n+\t\t\t\t   LE32_TO_CPU(ice_buf_tbl->buf_count));\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_download_pkg\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to package header\n+ * @ice_seg: pointer to the segment of the package to be downloaded\n+ *\n+ * Handles the download of a complete package.\n+ */\n+static enum ice_ddp_state\n+ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,\n+\t\t struct ice_seg *ice_seg)\n+{\n+\tenum ice_ddp_state state;\n+\n+\tif (hw->pkg_has_signing_seg)\n+\t\tstate = ice_download_pkg_with_sig_seg(hw, pkg_hdr);\n+\telse\n+\t\tstate = ice_download_pkg_without_sig_seg(hw, ice_seg);\n+\n+\tice_post_pkg_dwnld_vlan_mode_cfg(hw);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_init_pkg_info\n+ * @hw: pointer to the hardware structure\n+ * @pkg_hdr: pointer to the driver's package hdr\n+ *\n+ * Saves off the package details into the HW structure.\n+ */\n+static enum ice_ddp_state\n+ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)\n+{\n+\tstruct ice_generic_seg_hdr *seg_hdr;\n+\n+\tif (!pkg_hdr)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\thw->pkg_has_signing_seg = ice_has_signing_seg(hw, pkg_hdr);\n+\tice_get_signing_req(hw);\n+\n+\tice_debug(hw, ICE_DBG_INIT, \"Pkg using segment id: 0x%08X\\n\",\n+\t\t  hw->pkg_seg_id);\n+\n+\tseg_hdr = (struct ice_generic_seg_hdr *)\n+\t\tice_find_seg_in_pkg(hw, hw->pkg_seg_id, pkg_hdr);\n+\tif (seg_hdr) {\n+\t\tstruct ice_meta_sect *meta;\n+\t\tstruct ice_pkg_enum state;\n+\n+\t\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\t\t/* Get package information from the Metadata Section */\n+\t\tmeta = (struct ice_meta_sect *)\n+\t\t\tice_pkg_enum_section((struct ice_seg *)seg_hdr, &state,\n+\t\t\t\t\t     ICE_SID_METADATA);\n+\t\tif (!meta) {\n+\t\t\tice_debug(hw, ICE_DBG_INIT, \"Did not find ice metadata section in package\\n\");\n+\t\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\t\t}\n+\n+\t\thw->pkg_ver = meta->ver;\n+\t\tice_memcpy(hw->pkg_name, meta->name, sizeof(meta->name),\n+\t\t\t   ICE_NONDMA_TO_NONDMA);\n+\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg: %d.%d.%d.%d, %s\\n\",\n+\t\t\t  meta->ver.major, meta->ver.minor, meta->ver.update,\n+\t\t\t  meta->ver.draft, meta->name);\n+\n+\t\thw->ice_seg_fmt_ver = seg_hdr->seg_format_ver;\n+\t\tice_memcpy(hw->ice_seg_id, seg_hdr->seg_id,\n+\t\t\t   sizeof(hw->ice_seg_id), ICE_NONDMA_TO_NONDMA);\n+\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Ice Seg: %d.%d.%d.%d, %s\\n\",\n+\t\t\t  seg_hdr->seg_format_ver.major,\n+\t\t\t  seg_hdr->seg_format_ver.minor,\n+\t\t\t  seg_hdr->seg_format_ver.update,\n+\t\t\t  seg_hdr->seg_format_ver.draft,\n+\t\t\t  seg_hdr->seg_id);\n+\t} else {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Did not find ice segment in driver package\\n\");\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\t}\n+\n+\treturn ICE_DDP_PKG_SUCCESS;\n+}\n+\n+/**\n+ * ice_get_pkg_info\n+ * @hw: pointer to the hardware structure\n+ *\n+ * Store details of the package currently loaded in HW into the HW structure.\n+ */\n+enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)\n+{\n+\tenum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;\n+\tstruct ice_aqc_get_pkg_info_resp *pkg_info;\n+\tu16 size;\n+\tu32 i;\n+\n+\tsize = ice_struct_size(pkg_info, pkg_info, ICE_PKG_CNT);\n+\tpkg_info = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);\n+\tif (!pkg_info)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tif (ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL)) {\n+\t\tstate = ICE_DDP_PKG_ERR;\n+\t\tgoto init_pkg_free_alloc;\n+\t}\n+\n+\tfor (i = 0; i < LE32_TO_CPU(pkg_info->count); i++) {\n+#define ICE_PKG_FLAG_COUNT\t4\n+\t\tchar flags[ICE_PKG_FLAG_COUNT + 1] = { 0 };\n+\t\tu8 place = 0;\n+\n+\t\tif (pkg_info->pkg_info[i].is_active) {\n+\t\t\tflags[place++] = 'A';\n+\t\t\thw->active_pkg_ver = pkg_info->pkg_info[i].ver;\n+\t\t\thw->active_track_id =\n+\t\t\t\tLE32_TO_CPU(pkg_info->pkg_info[i].track_id);\n+\t\t\tice_memcpy(hw->active_pkg_name,\n+\t\t\t\t   pkg_info->pkg_info[i].name,\n+\t\t\t\t   sizeof(pkg_info->pkg_info[i].name),\n+\t\t\t\t   ICE_NONDMA_TO_NONDMA);\n+\t\t\thw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm;\n+\t\t}\n+\t\tif (pkg_info->pkg_info[i].is_active_at_boot)\n+\t\t\tflags[place++] = 'B';\n+\t\tif (pkg_info->pkg_info[i].is_modified)\n+\t\t\tflags[place++] = 'M';\n+\t\tif (pkg_info->pkg_info[i].is_in_nvm)\n+\t\t\tflags[place++] = 'N';\n+\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg[%d]: %d.%d.%d.%d,%s,%s\\n\",\n+\t\t\t  i, pkg_info->pkg_info[i].ver.major,\n+\t\t\t  pkg_info->pkg_info[i].ver.minor,\n+\t\t\t  pkg_info->pkg_info[i].ver.update,\n+\t\t\t  pkg_info->pkg_info[i].ver.draft,\n+\t\t\t  pkg_info->pkg_info[i].name, flags);\n+\t}\n+\n+init_pkg_free_alloc:\n+\tice_free(hw, pkg_info);\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_label_enum_handler\n+ * @sect_type: section type\n+ * @section: pointer to section\n+ * @index: index of the label entry to be returned\n+ * @offset: pointer to receive absolute offset, always zero for label sections\n+ *\n+ * This is a callback function that can be passed to ice_pkg_enum_entry.\n+ * Handles enumeration of individual label entries.\n+ */\n+static void *\n+ice_label_enum_handler(u32 __ALWAYS_UNUSED sect_type, void *section, u32 index,\n+\t\t       u32 *offset)\n+{\n+\tstruct ice_label_section *labels;\n+\n+\tif (!section)\n+\t\treturn NULL;\n+\n+\tif (index > ICE_MAX_LABELS_IN_BUF)\n+\t\treturn NULL;\n+\n+\tif (offset)\n+\t\t*offset = 0;\n+\n+\tlabels = (struct ice_label_section *)section;\n+\tif (index >= LE16_TO_CPU(labels->count))\n+\t\treturn NULL;\n+\n+\treturn labels->label + index;\n+}\n+\n+/**\n+ * ice_enum_labels\n+ * @ice_seg: pointer to the ice segment (NULL on subsequent calls)\n+ * @type: the section type that will contain the label (0 on subsequent calls)\n+ * @state: ice_pkg_enum structure that will hold the state of the enumeration\n+ * @value: pointer to a value that will return the label's value if found\n+ *\n+ * Enumerates a list of labels in the package. The caller will call\n+ * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call\n+ * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL\n+ * the end of the list has been reached.\n+ */\n+static char *\n+ice_enum_labels(struct ice_seg *ice_seg, u32 type, struct ice_pkg_enum *state,\n+\t\tu16 *value)\n+{\n+\tstruct ice_label *label;\n+\n+\t/* Check for valid label section on first call */\n+\tif (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST))\n+\t\treturn NULL;\n+\n+\tlabel = (struct ice_label *)ice_pkg_enum_entry(ice_seg, state, type,\n+\t\t\t\t\t\t       NULL,\n+\t\t\t\t\t\t       ice_label_enum_handler);\n+\tif (!label)\n+\t\treturn NULL;\n+\n+\t*value = LE16_TO_CPU(label->value);\n+\treturn label->name;\n+}\n+\n+/**\n+ * ice_verify_pkg - verify package\n+ * @pkg: pointer to the package buffer\n+ * @len: size of the package buffer\n+ *\n+ * Verifies various attributes of the package file, including length, format\n+ * version, and the requirement of at least one segment.\n+ */\n+enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)\n+{\n+\tu32 seg_count;\n+\tu32 i;\n+\n+\tif (len < ice_struct_size(pkg, seg_offset, 1))\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\n+\tif (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||\n+\t    pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||\n+\t    pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||\n+\t    pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\n+\t/* pkg must have at least one segment */\n+\tseg_count = LE32_TO_CPU(pkg->seg_count);\n+\tif (seg_count < 1)\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\n+\t/* make sure segment array fits in package length */\n+\tif (len < ice_struct_size(pkg, seg_offset, seg_count))\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\n+\t/* all segments must fit within length */\n+\tfor (i = 0; i < seg_count; i++) {\n+\t\tu32 off = LE32_TO_CPU(pkg->seg_offset[i]);\n+\t\tstruct ice_generic_seg_hdr *seg;\n+\n+\t\t/* segment header must fit */\n+\t\tif (len < off + sizeof(*seg))\n+\t\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\n+\t\tseg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);\n+\n+\t\t/* segment body must fit */\n+\t\tif (len < off + LE32_TO_CPU(seg->seg_size))\n+\t\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\t}\n+\n+\treturn ICE_DDP_PKG_SUCCESS;\n+}\n+\n+/**\n+ * ice_free_seg - free package segment pointer\n+ * @hw: pointer to the hardware structure\n+ *\n+ * Frees the package segment pointer in the proper manner, depending on if the\n+ * segment was allocated or just the passed in pointer was stored.\n+ */\n+void ice_free_seg(struct ice_hw *hw)\n+{\n+\tif (hw->pkg_copy) {\n+\t\tice_free(hw, hw->pkg_copy);\n+\t\thw->pkg_copy = NULL;\n+\t\thw->pkg_size = 0;\n+\t}\n+\thw->seg = NULL;\n+}\n+\n+/**\n+ * ice_chk_pkg_version - check package version for compatibility with driver\n+ * @pkg_ver: pointer to a version structure to check\n+ *\n+ * Check to make sure that the package about to be downloaded is compatible with\n+ * the driver. To be compatible, the major and minor components of the package\n+ * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR\n+ * definitions.\n+ */\n+static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)\n+{\n+\tif (pkg_ver->major > ICE_PKG_SUPP_VER_MAJ ||\n+\t    (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&\n+\t     pkg_ver->minor > ICE_PKG_SUPP_VER_MNR))\n+\t\treturn ICE_DDP_PKG_FILE_VERSION_TOO_HIGH;\n+\telse if (pkg_ver->major < ICE_PKG_SUPP_VER_MAJ ||\n+\t\t (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&\n+\t\t  pkg_ver->minor < ICE_PKG_SUPP_VER_MNR))\n+\t\treturn ICE_DDP_PKG_FILE_VERSION_TOO_LOW;\n+\n+\treturn ICE_DDP_PKG_SUCCESS;\n+}\n+\n+/**\n+ * ice_chk_pkg_compat\n+ * @hw: pointer to the hardware structure\n+ * @ospkg: pointer to the package hdr\n+ * @seg: pointer to the package segment hdr\n+ *\n+ * This function checks the package version compatibility with driver and NVM\n+ */\n+static enum ice_ddp_state\n+ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,\n+\t\t   struct ice_seg **seg)\n+{\n+\tstruct ice_aqc_get_pkg_info_resp *pkg;\n+\tenum ice_ddp_state state;\n+\tu16 size;\n+\tu32 i;\n+\n+\t/* Check package version compatibility */\n+\tstate = ice_chk_pkg_version(&hw->pkg_ver);\n+\tif (state) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Package version check failed.\\n\");\n+\t\treturn state;\n+\t}\n+\n+\t/* find ICE segment in given package */\n+\t*seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, hw->pkg_seg_id,\n+\t\t\t\t\t\t     ospkg);\n+\tif (!*seg) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"no ice segment in package.\\n\");\n+\t\treturn ICE_DDP_PKG_INVALID_FILE;\n+\t}\n+\n+\t/* Check if FW is compatible with the OS package */\n+\tsize = ice_struct_size(pkg, pkg_info, ICE_PKG_CNT);\n+\tpkg = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);\n+\tif (!pkg)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tif (ice_aq_get_pkg_info_list(hw, pkg, size, NULL)) {\n+\t\tstate = ICE_DDP_PKG_ERR;\n+\t\tgoto fw_ddp_compat_free_alloc;\n+\t}\n+\n+\tfor (i = 0; i < LE32_TO_CPU(pkg->count); i++) {\n+\t\t/* loop till we find the NVM package */\n+\t\tif (!pkg->pkg_info[i].is_in_nvm)\n+\t\t\tcontinue;\n+\t\tif ((*seg)->hdr.seg_format_ver.major !=\n+\t\t\tpkg->pkg_info[i].ver.major ||\n+\t\t    (*seg)->hdr.seg_format_ver.minor >\n+\t\t\tpkg->pkg_info[i].ver.minor) {\n+\t\t\tstate = ICE_DDP_PKG_FW_MISMATCH;\n+\t\t\tice_debug(hw, ICE_DBG_INIT, \"OS package is not compatible with NVM.\\n\");\n+\t\t}\n+\t\t/* done processing NVM package so break */\n+\t\tbreak;\n+\t}\n+fw_ddp_compat_free_alloc:\n+\tice_free(hw, pkg);\n+\treturn state;\n+}\n+\n+/**\n+ * ice_sw_fv_handler\n+ * @sect_type: section type\n+ * @section: pointer to section\n+ * @index: index of the field vector entry to be returned\n+ * @offset: ptr to variable that receives the offset in the field vector table\n+ *\n+ * This is a callback function that can be passed to ice_pkg_enum_entry.\n+ * This function treats the given section as of type ice_sw_fv_section and\n+ * enumerates offset field. \"offset\" is an index into the field vector table.\n+ */\n+static void *\n+ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)\n+{\n+\tstruct ice_sw_fv_section *fv_section =\n+\t\t(struct ice_sw_fv_section *)section;\n+\n+\tif (!section || sect_type != ICE_SID_FLD_VEC_SW)\n+\t\treturn NULL;\n+\tif (index >= LE16_TO_CPU(fv_section->count))\n+\t\treturn NULL;\n+\tif (offset)\n+\t\t/* \"index\" passed in to this function is relative to a given\n+\t\t * 4k block. To get to the true index into the field vector\n+\t\t * table need to add the relative index to the base_offset\n+\t\t * field of this section\n+\t\t */\n+\t\t*offset = LE16_TO_CPU(fv_section->base_offset) + index;\n+\treturn fv_section->fv + index;\n+}\n+\n+/**\n+ * ice_get_prof_index_max - get the max profile index for used profile\n+ * @hw: pointer to the HW struct\n+ *\n+ * Calling this function will get the max profile index for used profile\n+ * and store the index number in struct ice_switch_info *switch_info\n+ * in hw for following use.\n+ */\n+static int ice_get_prof_index_max(struct ice_hw *hw)\n+{\n+\tu16 prof_index = 0, j, max_prof_index = 0;\n+\tstruct ice_pkg_enum state;\n+\tstruct ice_seg *ice_seg;\n+\tbool flag = false;\n+\tstruct ice_fv *fv;\n+\tu32 offset;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tif (!hw->seg)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_seg = hw->seg;\n+\n+\tdo {\n+\t\tfv = (struct ice_fv *)\n+\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n+\t\t\t\t\t   &offset, ice_sw_fv_handler);\n+\t\tif (!fv)\n+\t\t\tbreak;\n+\t\tice_seg = NULL;\n+\n+\t\t/* in the profile that not be used, the prot_id is set to 0xff\n+\t\t * and the off is set to 0x1ff for all the field vectors.\n+\t\t */\n+\t\tfor (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)\n+\t\t\tif (fv->ew[j].prot_id != ICE_PROT_INVALID ||\n+\t\t\t    fv->ew[j].off != ICE_FV_OFFSET_INVAL)\n+\t\t\t\tflag = true;\n+\t\tif (flag && prof_index > max_prof_index)\n+\t\t\tmax_prof_index = prof_index;\n+\n+\t\tprof_index++;\n+\t\tflag = false;\n+\t} while (fv);\n+\n+\thw->switch_info->max_used_prof_index = max_prof_index;\n+\n+\treturn ICE_SUCCESS;\n+}\n+\n+/**\n+ * ice_get_ddp_pkg_state - get DDP pkg state after download\n+ * @hw: pointer to the HW struct\n+ * @already_loaded: indicates if pkg was already loaded onto the device\n+ *\n+ */\n+static enum ice_ddp_state\n+ice_get_ddp_pkg_state(struct ice_hw *hw, bool already_loaded)\n+{\n+\tif (hw->pkg_ver.major == hw->active_pkg_ver.major &&\n+\t    hw->pkg_ver.minor == hw->active_pkg_ver.minor &&\n+\t    hw->pkg_ver.update == hw->active_pkg_ver.update &&\n+\t    hw->pkg_ver.draft == hw->active_pkg_ver.draft &&\n+\t    !memcmp(hw->pkg_name, hw->active_pkg_name, sizeof(hw->pkg_name))) {\n+\t\tif (already_loaded)\n+\t\t\treturn ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED;\n+\t\telse\n+\t\t\treturn ICE_DDP_PKG_SUCCESS;\n+\t} else if (hw->active_pkg_ver.major != ICE_PKG_SUPP_VER_MAJ ||\n+\t\t   hw->active_pkg_ver.minor != ICE_PKG_SUPP_VER_MNR) {\n+\t\treturn ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED;\n+\t} else if (hw->active_pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&\n+\t\t   hw->active_pkg_ver.minor == ICE_PKG_SUPP_VER_MNR) {\n+\t\treturn ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED;\n+\t} else {\n+\t\treturn ICE_DDP_PKG_ERR;\n+\t}\n+}\n+\n+/**\n+ * ice_init_pkg_regs - initialize additional package registers\n+ * @hw: pointer to the hardware structure\n+ */\n+static void ice_init_pkg_regs(struct ice_hw *hw)\n+{\n+#define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF\n+#define ICE_SW_BLK_INP_MASK_H 0x0000FFFF\n+#define ICE_SW_BLK_IDX\t0\n+\tif (hw->dcf_enabled)\n+\t\treturn;\n+\n+\t/* setup Switch block input mask, which is 48-bits in two parts */\n+\twr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L);\n+\twr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H);\n+}\n+\n+/**\n+ * ice_hw_ptype_ena - check if the PTYPE is enabled or not\n+ * @hw: pointer to the HW structure\n+ * @ptype: the hardware PTYPE\n+ */\n+bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype)\n+{\n+\treturn ptype < ICE_FLOW_PTYPE_MAX &&\n+\t       ice_is_bit_set(hw->hw_ptype, ptype);\n+}\n+\n+/**\n+ * ice_marker_ptype_tcam_handler\n+ * @sect_type: section type\n+ * @section: pointer to section\n+ * @index: index of the Marker PType TCAM entry to be returned\n+ * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections\n+ *\n+ * This is a callback function that can be passed to ice_pkg_enum_entry.\n+ * Handles enumeration of individual Marker PType TCAM entries.\n+ */\n+static void *\n+ice_marker_ptype_tcam_handler(u32 sect_type, void *section, u32 index,\n+\t\t\t      u32 *offset)\n+{\n+\tstruct ice_marker_ptype_tcam_section *marker_ptype;\n+\n+\tif (!section)\n+\t\treturn NULL;\n+\n+\tif (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE)\n+\t\treturn NULL;\n+\n+\tif (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF)\n+\t\treturn NULL;\n+\n+\tif (offset)\n+\t\t*offset = 0;\n+\n+\tmarker_ptype = (struct ice_marker_ptype_tcam_section *)section;\n+\tif (index >= LE16_TO_CPU(marker_ptype->count))\n+\t\treturn NULL;\n+\n+\treturn marker_ptype->tcam + index;\n+}\n+\n+/**\n+ * ice_fill_hw_ptype - fill the enabled PTYPE bit information\n+ * @hw: pointer to the HW structure\n+ */\n+static void\n+ice_fill_hw_ptype(struct ice_hw *hw)\n+{\n+\tstruct ice_marker_ptype_tcam_entry *tcam;\n+\tstruct ice_seg *seg = hw->seg;\n+\tstruct ice_pkg_enum state;\n+\n+\tice_zero_bitmap(hw->hw_ptype, ICE_FLOW_PTYPE_MAX);\n+\tif (!seg)\n+\t\treturn;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tdo {\n+\t\ttcam = (struct ice_marker_ptype_tcam_entry *)\n+\t\t\tice_pkg_enum_entry(seg, &state,\n+\t\t\t\t\t   ICE_SID_RXPARSER_MARKER_PTYPE, NULL,\n+\t\t\t\t\t   ice_marker_ptype_tcam_handler);\n+\t\tif (tcam &&\n+\t\t    LE16_TO_CPU(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX &&\n+\t\t    LE16_TO_CPU(tcam->ptype) < ICE_FLOW_PTYPE_MAX)\n+\t\t\tice_set_bit(LE16_TO_CPU(tcam->ptype), hw->hw_ptype);\n+\n+\t\tseg = NULL;\n+\t} while (tcam);\n+}\n+\n+/**\n+ * ice_init_pkg - initialize/download package\n+ * @hw: pointer to the hardware structure\n+ * @buf: pointer to the package buffer\n+ * @len: size of the package buffer\n+ *\n+ * This function initializes a package. The package contains HW tables\n+ * required to do packet processing. First, the function extracts package\n+ * information such as version. Then it finds the ice configuration segment\n+ * within the package; this function then saves a copy of the segment pointer\n+ * within the supplied package buffer. Next, the function will cache any hints\n+ * from the package, followed by downloading the package itself. Note, that if\n+ * a previous PF driver has already downloaded the package successfully, then\n+ * the current driver will not have to download the package again.\n+ *\n+ * The local package contents will be used to query default behavior and to\n+ * update specific sections of the HW's version of the package (e.g. to update\n+ * the parse graph to understand new protocols).\n+ *\n+ * This function stores a pointer to the package buffer memory, and it is\n+ * expected that the supplied buffer will not be freed immediately. If the\n+ * package buffer needs to be freed, such as when read from a file, use\n+ * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this\n+ * case.\n+ */\n+enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)\n+{\n+\tbool already_loaded = false;\n+\tenum ice_ddp_state state;\n+\tstruct ice_pkg_hdr *pkg;\n+\tstruct ice_seg *seg;\n+\n+\tif (!buf || !len)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tpkg = (struct ice_pkg_hdr *)buf;\n+\tstate = ice_verify_pkg(pkg, len);\n+\tif (state) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"failed to verify pkg (err: %d)\\n\",\n+\t\t\t  state);\n+\t\treturn state;\n+\t}\n+\n+\t/* initialize package info */\n+\tstate = ice_init_pkg_info(hw, pkg);\n+\tif (state)\n+\t\treturn state;\n+\n+\t/* For packages with signing segments, must be a matching segment */\n+\tif (hw->pkg_has_signing_seg)\n+\t\tif (!ice_match_signing_seg(pkg, hw->pkg_seg_id,\n+\t\t\t\t\t   hw->pkg_sign_type))\n+\t\t\treturn ICE_DDP_PKG_ERR;\n+\n+\t/* before downloading the package, check package version for\n+\t * compatibility with driver\n+\t */\n+\tstate = ice_chk_pkg_compat(hw, pkg, &seg);\n+\tif (state)\n+\t\treturn state;\n+\n+\t/* initialize package hints and then download package */\n+\tice_init_pkg_hints(hw, seg);\n+\tstate = ice_download_pkg(hw, pkg, seg);\n+\n+\tif (state == ICE_DDP_PKG_ALREADY_LOADED) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"package previously loaded - no work.\\n\");\n+\t\talready_loaded = true;\n+\t}\n+\n+\t/* Get information on the package currently loaded in HW, then make sure\n+\t * the driver is compatible with this version.\n+\t */\n+\tif (!state || state == ICE_DDP_PKG_ALREADY_LOADED) {\n+\t\tstate = ice_get_pkg_info(hw);\n+\t\tif (!state)\n+\t\t\tstate = ice_get_ddp_pkg_state(hw, already_loaded);\n+\t}\n+\n+\tif (ice_is_init_pkg_successful(state)) {\n+\t\thw->seg = seg;\n+\t\t/* on successful package download update other required\n+\t\t * registers to support the package and fill HW tables\n+\t\t * with package content.\n+\t\t */\n+\t\tice_init_pkg_regs(hw);\n+\t\tice_fill_blk_tbls(hw);\n+\t\tice_fill_hw_ptype(hw);\n+\t\tice_get_prof_index_max(hw);\n+\t} else {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"package load failed, %d\\n\",\n+\t\t\t  state);\n+\t}\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_copy_and_init_pkg - initialize/download a copy of the package\n+ * @hw: pointer to the hardware structure\n+ * @buf: pointer to the package buffer\n+ * @len: size of the package buffer\n+ *\n+ * This function copies the package buffer, and then calls ice_init_pkg() to\n+ * initialize the copied package contents.\n+ *\n+ * The copying is necessary if the package buffer supplied is constant, or if\n+ * the memory may disappear shortly after calling this function.\n+ *\n+ * If the package buffer resides in the data segment and can be modified, the\n+ * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg().\n+ *\n+ * However, if the package buffer needs to be copied first, such as when being\n+ * read from a file, the caller should use ice_copy_and_init_pkg().\n+ *\n+ * This function will first copy the package buffer, before calling\n+ * ice_init_pkg(). The caller is free to immediately destroy the original\n+ * package buffer, as the new copy will be managed by this function and\n+ * related routines.\n+ */\n+enum ice_ddp_state\n+ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)\n+{\n+\tenum ice_ddp_state state;\n+\tu8 *buf_copy;\n+\n+\tif (!buf || !len)\n+\t\treturn ICE_DDP_PKG_ERR;\n+\n+\tbuf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA);\n+\n+\tstate = ice_init_pkg(hw, buf_copy, len);\n+\tif (!ice_is_init_pkg_successful(state)) {\n+\t\t/* Free the copy, since we failed to initialize the package */\n+\t\tice_free(hw, buf_copy);\n+\t} else {\n+\t\t/* Track the copied pkg so we can free it later */\n+\t\thw->pkg_copy = buf_copy;\n+\t\thw->pkg_size = len;\n+\t}\n+\n+\treturn state;\n+}\n+\n+/**\n+ * ice_is_init_pkg_successful - check if DDP init was successful\n+ * @state: state of the DDP pkg after download\n+ */\n+bool ice_is_init_pkg_successful(enum ice_ddp_state state)\n+{\n+\tswitch (state) {\n+\tcase ICE_DDP_PKG_SUCCESS:\n+\tcase ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED:\n+\tcase ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED:\n+\t\treturn true;\n+\tdefault:\n+\t\treturn false;\n+\t}\n+}\n+\n+/**\n+ * ice_pkg_buf_alloc\n+ * @hw: pointer to the HW structure\n+ *\n+ * Allocates a package buffer and returns a pointer to the buffer header.\n+ * Note: all package contents must be in Little Endian form.\n+ */\n+struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)\n+{\n+\tstruct ice_buf_build *bld;\n+\tstruct ice_buf_hdr *buf;\n+\n+\tbld = (struct ice_buf_build *)ice_malloc(hw, sizeof(*bld));\n+\tif (!bld)\n+\t\treturn NULL;\n+\n+\tbuf = (struct ice_buf_hdr *)bld;\n+\tbuf->data_end = CPU_TO_LE16(offsetof(struct ice_buf_hdr,\n+\t\t\t\t\t     section_entry));\n+\treturn bld;\n+}\n+\n+/**\n+ * ice_get_sw_prof_type - determine switch profile type\n+ * @hw: pointer to the HW structure\n+ * @fv: pointer to the switch field vector\n+ */\n+static enum ice_prof_type\n+ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)\n+{\n+\tbool valid_prof = false;\n+\tu16 i;\n+\n+\tfor (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {\n+\t\tif (fv->ew[i].off != ICE_NAN_OFFSET)\n+\t\t\tvalid_prof = true;\n+\n+\t\t/* UDP tunnel will have UDP_OF protocol ID and VNI offset */\n+\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&\n+\t\t    fv->ew[i].off == ICE_VNI_OFFSET)\n+\t\t\treturn ICE_PROF_TUN_UDP;\n+\n+\t\t/* GRE tunnel will have GRE protocol */\n+\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)\n+\t\t\treturn ICE_PROF_TUN_GRE;\n+\n+\t\t/* PPPOE tunnel will have PPPOE protocol */\n+\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE)\n+\t\t\treturn ICE_PROF_TUN_PPPOE;\n+\t}\n+\n+\treturn valid_prof ? ICE_PROF_NON_TUN : ICE_PROF_INVALID;\n+}\n+\n+/**\n+ * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type\n+ * @hw: pointer to hardware structure\n+ * @req_profs: type of profiles requested\n+ * @bm: pointer to memory for returning the bitmap of field vectors\n+ */\n+void\n+ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,\n+\t\t     ice_bitmap_t *bm)\n+{\n+\tstruct ice_pkg_enum state;\n+\tstruct ice_seg *ice_seg;\n+\tstruct ice_fv *fv;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\tice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);\n+\tice_seg = hw->seg;\n+\tdo {\n+\t\tenum ice_prof_type prof_type;\n+\t\tu32 offset;\n+\n+\t\tfv = (struct ice_fv *)\n+\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n+\t\t\t\t\t   &offset, ice_sw_fv_handler);\n+\t\tice_seg = NULL;\n+\n+\t\tif (fv) {\n+\t\t\t/* Determine field vector type */\n+\t\t\tprof_type = ice_get_sw_prof_type(hw, fv);\n+\n+\t\t\tif (req_profs & prof_type)\n+\t\t\t\tice_set_bit((u16)offset, bm);\n+\t\t}\n+\t} while (fv);\n+}\n+\n+/**\n+ * ice_get_sw_fv_list\n+ * @hw: pointer to the HW structure\n+ * @lkups: lookup elements or match criteria for the advanced recipe, one\n+ *\t   structure per protocol header\n+ * @bm: bitmap of field vectors to consider\n+ * @fv_list: Head of a list\n+ *\n+ * Finds all the field vector entries from switch block that contain\n+ * a given protocol ID and offset and returns a list of structures of type\n+ * \"ice_sw_fv_list_entry\". Every structure in the list has a field vector\n+ * definition and profile ID information\n+ * NOTE: The caller of the function is responsible for freeing the memory\n+ * allocated for every list entry.\n+ */\n+enum ice_status\n+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,\n+\t\t   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)\n+{\n+\tstruct ice_sw_fv_list_entry *fvl;\n+\tstruct ice_sw_fv_list_entry *tmp;\n+\tstruct ice_pkg_enum state;\n+\tstruct ice_seg *ice_seg;\n+\tstruct ice_fv *fv;\n+\tu32 offset;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tif (!lkups->n_val_words || !hw->seg)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_seg = hw->seg;\n+\tdo {\n+\t\tu16 i;\n+\n+\t\tfv = (struct ice_fv *)\n+\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n+\t\t\t\t\t   &offset, ice_sw_fv_handler);\n+\t\tif (!fv)\n+\t\t\tbreak;\n+\t\tice_seg = NULL;\n+\n+\t\t/* If field vector is not in the bitmap list, then skip this\n+\t\t * profile.\n+\t\t */\n+\t\tif (!ice_is_bit_set(bm, (u16)offset))\n+\t\t\tcontinue;\n+\n+\t\tfor (i = 0; i < lkups->n_val_words; i++) {\n+\t\t\tint j;\n+\n+\t\t\tfor (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)\n+\t\t\t\tif (fv->ew[j].prot_id ==\n+\t\t\t\t    lkups->fv_words[i].prot_id &&\n+\t\t\t\t    fv->ew[j].off == lkups->fv_words[i].off)\n+\t\t\t\t\tbreak;\n+\t\t\tif (j >= hw->blk[ICE_BLK_SW].es.fvw)\n+\t\t\t\tbreak;\n+\t\t\tif (i + 1 == lkups->n_val_words) {\n+\t\t\t\tfvl = (struct ice_sw_fv_list_entry *)\n+\t\t\t\t\tice_malloc(hw, sizeof(*fvl));\n+\t\t\t\tif (!fvl)\n+\t\t\t\t\tgoto err;\n+\t\t\t\tfvl->fv_ptr = fv;\n+\t\t\t\tfvl->profile_id = offset;\n+\t\t\t\tLIST_ADD(&fvl->list_entry, fv_list);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t} while (fv);\n+\tif (LIST_EMPTY(fv_list))\n+\t\treturn ICE_ERR_CFG;\n+\treturn ICE_SUCCESS;\n+\n+err:\n+\tLIST_FOR_EACH_ENTRY_SAFE(fvl, tmp, fv_list, ice_sw_fv_list_entry,\n+\t\t\t\t list_entry) {\n+\t\tLIST_DEL(&fvl->list_entry);\n+\t\tice_free(hw, fvl);\n+\t}\n+\n+\treturn ICE_ERR_NO_MEMORY;\n+}\n+\n+/**\n+ * ice_init_prof_result_bm - Initialize the profile result index bitmap\n+ * @hw: pointer to hardware structure\n+ */\n+void ice_init_prof_result_bm(struct ice_hw *hw)\n+{\n+\tstruct ice_pkg_enum state;\n+\tstruct ice_seg *ice_seg;\n+\tstruct ice_fv *fv;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tif (!hw->seg)\n+\t\treturn;\n+\n+\tice_seg = hw->seg;\n+\tdo {\n+\t\tu32 off;\n+\t\tu16 i;\n+\n+\t\tfv = (struct ice_fv *)\n+\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n+\t\t\t\t\t   &off, ice_sw_fv_handler);\n+\t\tice_seg = NULL;\n+\t\tif (!fv)\n+\t\t\tbreak;\n+\n+\t\tice_zero_bitmap(hw->switch_info->prof_res_bm[off],\n+\t\t\t\tICE_MAX_FV_WORDS);\n+\n+\t\t/* Determine empty field vector indices, these can be\n+\t\t * used for recipe results. Skip index 0, since it is\n+\t\t * always used for Switch ID.\n+\t\t */\n+\t\tfor (i = 1; i < ICE_MAX_FV_WORDS; i++)\n+\t\t\tif (fv->ew[i].prot_id == ICE_PROT_INVALID &&\n+\t\t\t    fv->ew[i].off == ICE_FV_OFFSET_INVAL)\n+\t\t\t\tice_set_bit(i,\n+\t\t\t\t\t    hw->switch_info->prof_res_bm[off]);\n+\t} while (fv);\n+}\n+\n+/**\n+ * ice_pkg_buf_free\n+ * @hw: pointer to the HW structure\n+ * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ *\n+ * Frees a package buffer\n+ */\n+void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)\n+{\n+\tice_free(hw, bld);\n+}\n+\n+/**\n+ * ice_pkg_buf_reserve_section\n+ * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ * @count: the number of sections to reserve\n+ *\n+ * Reserves one or more section table entries in a package buffer. This routine\n+ * can be called multiple times as long as they are made before calling\n+ * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section()\n+ * is called once, the number of sections that can be allocated will not be able\n+ * to be increased; not using all reserved sections is fine, but this will\n+ * result in some wasted space in the buffer.\n+ * Note: all package contents must be in Little Endian form.\n+ */\n+enum ice_status\n+ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count)\n+{\n+\tstruct ice_buf_hdr *buf;\n+\tu16 section_count;\n+\tu16 data_end;\n+\n+\tif (!bld)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tbuf = (struct ice_buf_hdr *)&bld->buf;\n+\n+\t/* already an active section, can't increase table size */\n+\tsection_count = LE16_TO_CPU(buf->section_count);\n+\tif (section_count > 0)\n+\t\treturn ICE_ERR_CFG;\n+\n+\tif (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT)\n+\t\treturn ICE_ERR_CFG;\n+\tbld->reserved_section_table_entries += count;\n+\n+\tdata_end = LE16_TO_CPU(buf->data_end) +\n+\t\tFLEX_ARRAY_SIZE(buf, section_entry, count);\n+\tbuf->data_end = CPU_TO_LE16(data_end);\n+\n+\treturn ICE_SUCCESS;\n+}\n+\n+/**\n+ * ice_pkg_buf_alloc_section\n+ * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ * @type: the section type value\n+ * @size: the size of the section to reserve (in bytes)\n+ *\n+ * Reserves memory in the buffer for a section's content and updates the\n+ * buffers' status accordingly. This routine returns a pointer to the first\n+ * byte of the section start within the buffer, which is used to fill in the\n+ * section contents.\n+ * Note: all package contents must be in Little Endian form.\n+ */\n+void *\n+ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size)\n+{\n+\tstruct ice_buf_hdr *buf;\n+\tu16 sect_count;\n+\tu16 data_end;\n+\n+\tif (!bld || !type || !size)\n+\t\treturn NULL;\n+\n+\tbuf = (struct ice_buf_hdr *)&bld->buf;\n+\n+\t/* check for enough space left in buffer */\n+\tdata_end = LE16_TO_CPU(buf->data_end);\n+\n+\t/* section start must align on 4 byte boundary */\n+\tdata_end = ICE_ALIGN(data_end, 4);\n+\n+\tif ((data_end + size) > ICE_MAX_S_DATA_END)\n+\t\treturn NULL;\n+\n+\t/* check for more available section table entries */\n+\tsect_count = LE16_TO_CPU(buf->section_count);\n+\tif (sect_count < bld->reserved_section_table_entries) {\n+\t\tvoid *section_ptr = ((u8 *)buf) + data_end;\n+\n+\t\tbuf->section_entry[sect_count].offset = CPU_TO_LE16(data_end);\n+\t\tbuf->section_entry[sect_count].size = CPU_TO_LE16(size);\n+\t\tbuf->section_entry[sect_count].type = CPU_TO_LE32(type);\n+\n+\t\tdata_end += size;\n+\t\tbuf->data_end = CPU_TO_LE16(data_end);\n+\n+\t\tbuf->section_count = CPU_TO_LE16(sect_count + 1);\n+\t\treturn section_ptr;\n+\t}\n+\n+\t/* no free section table entries */\n+\treturn NULL;\n+}\n+\n+/**\n+ * ice_pkg_buf_alloc_single_section\n+ * @hw: pointer to the HW structure\n+ * @type: the section type value\n+ * @size: the size of the section to reserve (in bytes)\n+ * @section: returns pointer to the section\n+ *\n+ * Allocates a package buffer with a single section.\n+ * Note: all package contents must be in Little Endian form.\n+ */\n+struct ice_buf_build *\n+ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,\n+\t\t\t\t void **section)\n+{\n+\tstruct ice_buf_build *buf;\n+\n+\tif (!section)\n+\t\treturn NULL;\n+\n+\tbuf = ice_pkg_buf_alloc(hw);\n+\tif (!buf)\n+\t\treturn NULL;\n+\n+\tif (ice_pkg_buf_reserve_section(buf, 1))\n+\t\tgoto ice_pkg_buf_alloc_single_section_err;\n+\n+\t*section = ice_pkg_buf_alloc_section(buf, type, size);\n+\tif (!*section)\n+\t\tgoto ice_pkg_buf_alloc_single_section_err;\n+\n+\treturn buf;\n+\n+ice_pkg_buf_alloc_single_section_err:\n+\tice_pkg_buf_free(hw, buf);\n+\treturn NULL;\n+}\n+\n+/**\n+ * ice_pkg_buf_get_active_sections\n+ * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ *\n+ * Returns the number of active sections. Before using the package buffer\n+ * in an update package command, the caller should make sure that there is at\n+ * least one active section - otherwise, the buffer is not legal and should\n+ * not be used.\n+ * Note: all package contents must be in Little Endian form.\n+ */\n+u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld)\n+{\n+\tstruct ice_buf_hdr *buf;\n+\n+\tif (!bld)\n+\t\treturn 0;\n+\n+\tbuf = (struct ice_buf_hdr *)&bld->buf;\n+\treturn LE16_TO_CPU(buf->section_count);\n+}\n+\n+/**\n+ * ice_pkg_buf\n+ * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ *\n+ * Return a pointer to the buffer's header\n+ */\n+struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)\n+{\n+\tif (bld)\n+\t\treturn &bld->buf;\n+\n+\treturn NULL;\n+}\n+\n+/**\n+ * ice_find_buf_table\n+ * @ice_seg: pointer to the ice segment\n+ *\n+ * Returns the address of the buffer table within the ice segment.\n+ */\n+struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)\n+{\n+\tstruct ice_nvm_table *nvms;\n+\n+\tnvms = (struct ice_nvm_table *)\n+\t\t(ice_seg->device_table +\n+\t\t LE32_TO_CPU(ice_seg->device_table_count));\n+\n+\treturn (_FORCE_ struct ice_buf_table *)\n+\t\t(nvms->vers + LE32_TO_CPU(nvms->table_count));\n+}\n+\n+/**\n+ * ice_pkg_val_buf\n+ * @buf: pointer to the ice buffer\n+ *\n+ * This helper function validates a buffer's header.\n+ */\n+static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)\n+{\n+\tstruct ice_buf_hdr *hdr;\n+\tu16 section_count;\n+\tu16 data_end;\n+\n+\thdr = (struct ice_buf_hdr *)buf->buf;\n+\t/* verify data */\n+\tsection_count = LE16_TO_CPU(hdr->section_count);\n+\tif (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)\n+\t\treturn NULL;\n+\n+\tdata_end = LE16_TO_CPU(hdr->data_end);\n+\tif (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END)\n+\t\treturn NULL;\n+\n+\treturn hdr;\n+}\n+\n+/**\n+ * ice_pkg_enum_buf\n+ * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n+ * @state: pointer to the enum state\n+ *\n+ * This function will enumerate all the buffers in the ice segment. The first\n+ * call is made with the ice_seg parameter non-NULL; on subsequent calls,\n+ * ice_seg is set to NULL which continues the enumeration. When the function\n+ * returns a NULL pointer, then the end of the buffers has been reached, or an\n+ * unexpected value has been detected (for example an invalid section count or\n+ * an invalid buffer end value).\n+ */\n+struct ice_buf_hdr *\n+ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state)\n+{\n+\tif (ice_seg) {\n+\t\tstate->buf_table = ice_find_buf_table(ice_seg);\n+\t\tif (!state->buf_table)\n+\t\t\treturn NULL;\n+\n+\t\tstate->buf_idx = 0;\n+\t\treturn ice_pkg_val_buf(state->buf_table->buf_array);\n+\t}\n+\n+\tif (++state->buf_idx < LE32_TO_CPU(state->buf_table->buf_count))\n+\t\treturn ice_pkg_val_buf(state->buf_table->buf_array +\n+\t\t\t\t       state->buf_idx);\n+\telse\n+\t\treturn NULL;\n+}\n+\n+/**\n+ * ice_pkg_advance_sect\n+ * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n+ * @state: pointer to the enum state\n+ *\n+ * This helper function will advance the section within the ice segment,\n+ * also advancing the buffer if needed.\n+ */\n+bool\n+ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state)\n+{\n+\tif (!ice_seg && !state->buf)\n+\t\treturn false;\n+\n+\tif (!ice_seg && state->buf)\n+\t\tif (++state->sect_idx < LE16_TO_CPU(state->buf->section_count))\n+\t\t\treturn true;\n+\n+\tstate->buf = ice_pkg_enum_buf(ice_seg, state);\n+\tif (!state->buf)\n+\t\treturn false;\n+\n+\t/* start of new buffer, reset section index */\n+\tstate->sect_idx = 0;\n+\treturn true;\n+}\n+\n+/**\n+ * ice_pkg_enum_section\n+ * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n+ * @state: pointer to the enum state\n+ * @sect_type: section type to enumerate\n+ *\n+ * This function will enumerate all the sections of a particular type in the\n+ * ice segment. The first call is made with the ice_seg parameter non-NULL;\n+ * on subsequent calls, ice_seg is set to NULL which continues the enumeration.\n+ * When the function returns a NULL pointer, then the end of the matching\n+ * sections has been reached.\n+ */\n+void *\n+ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n+\t\t     u32 sect_type)\n+{\n+\tu16 offset, size;\n+\n+\tif (ice_seg)\n+\t\tstate->type = sect_type;\n+\n+\tif (!ice_pkg_advance_sect(ice_seg, state))\n+\t\treturn NULL;\n+\n+\t/* scan for next matching section */\n+\twhile (state->buf->section_entry[state->sect_idx].type !=\n+\t       CPU_TO_LE32(state->type))\n+\t\tif (!ice_pkg_advance_sect(NULL, state))\n+\t\t\treturn NULL;\n+\n+\t/* validate section */\n+\toffset = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);\n+\tif (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF)\n+\t\treturn NULL;\n+\n+\tsize = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].size);\n+\tif (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ)\n+\t\treturn NULL;\n+\n+\t/* make sure the section fits in the buffer */\n+\tif (offset + size > ICE_PKG_BUF_SIZE)\n+\t\treturn NULL;\n+\n+\tstate->sect_type =\n+\t\tLE32_TO_CPU(state->buf->section_entry[state->sect_idx].type);\n+\n+\t/* calc pointer to this section */\n+\tstate->sect = ((u8 *)state->buf) +\n+\t\tLE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);\n+\n+\treturn state->sect;\n+}\n+\n+/**\n+ * ice_pkg_enum_entry\n+ * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n+ * @state: pointer to the enum state\n+ * @sect_type: section type to enumerate\n+ * @offset: pointer to variable that receives the offset in the table (optional)\n+ * @handler: function that handles access to the entries into the section type\n+ *\n+ * This function will enumerate all the entries in particular section type in\n+ * the ice segment. The first call is made with the ice_seg parameter non-NULL;\n+ * on subsequent calls, ice_seg is set to NULL which continues the enumeration.\n+ * When the function returns a NULL pointer, then the end of the entries has\n+ * been reached.\n+ *\n+ * Since each section may have a different header and entry size, the handler\n+ * function is needed to determine the number and location entries in each\n+ * section.\n+ *\n+ * The offset parameter is optional, but should be used for sections that\n+ * contain an offset for each section table. For such cases, the section handler\n+ * function must return the appropriate offset + index to give the absolution\n+ * offset for each entry. For example, if the base for a section's header\n+ * indicates a base offset of 10, and the index for the entry is 2, then\n+ * section handler function should set the offset to 10 + 2 = 12.\n+ */\n+void *\n+ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n+\t\t   u32 sect_type, u32 *offset,\n+\t\t   void *(*handler)(u32 sect_type, void *section,\n+\t\t\t\t    u32 index, u32 *offset))\n+{\n+\tvoid *entry;\n+\n+\tif (ice_seg) {\n+\t\tif (!handler)\n+\t\t\treturn NULL;\n+\n+\t\tif (!ice_pkg_enum_section(ice_seg, state, sect_type))\n+\t\t\treturn NULL;\n+\n+\t\tstate->entry_idx = 0;\n+\t\tstate->handler = handler;\n+\t} else {\n+\t\tstate->entry_idx++;\n+\t}\n+\n+\tif (!state->handler)\n+\t\treturn NULL;\n+\n+\t/* get entry */\n+\tentry = state->handler(state->sect_type, state->sect, state->entry_idx,\n+\t\t\t       offset);\n+\tif (!entry) {\n+\t\t/* end of a section, look for another section of this type */\n+\t\tif (!ice_pkg_enum_section(NULL, state, 0))\n+\t\t\treturn NULL;\n+\n+\t\tstate->entry_idx = 0;\n+\t\tentry = state->handler(state->sect_type, state->sect,\n+\t\t\t\t       state->entry_idx, offset);\n+\t}\n+\n+\treturn entry;\n+}\n+\n+/**\n+ * ice_boost_tcam_handler\n+ * @sect_type: section type\n+ * @section: pointer to section\n+ * @index: index of the boost TCAM entry to be returned\n+ * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections\n+ *\n+ * This is a callback function that can be passed to ice_pkg_enum_entry.\n+ * Handles enumeration of individual boost TCAM entries.\n+ */\n+static void *\n+ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset)\n+{\n+\tstruct ice_boost_tcam_section *boost;\n+\n+\tif (!section)\n+\t\treturn NULL;\n+\n+\tif (sect_type != ICE_SID_RXPARSER_BOOST_TCAM)\n+\t\treturn NULL;\n+\n+\tif (index > ICE_MAX_BST_TCAMS_IN_BUF)\n+\t\treturn NULL;\n+\n+\tif (offset)\n+\t\t*offset = 0;\n+\n+\tboost = (struct ice_boost_tcam_section *)section;\n+\tif (index >= LE16_TO_CPU(boost->count))\n+\t\treturn NULL;\n+\n+\treturn boost->tcam + index;\n+}\n+\n+/**\n+ * ice_find_boost_entry\n+ * @ice_seg: pointer to the ice segment (non-NULL)\n+ * @addr: Boost TCAM address of entry to search for\n+ * @entry: returns pointer to the entry\n+ *\n+ * Finds a particular Boost TCAM entry and returns a pointer to that entry\n+ * if it is found. The ice_seg parameter must not be NULL since the first call\n+ * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure.\n+ */\n+static enum ice_status\n+ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr,\n+\t\t     struct ice_boost_tcam_entry **entry)\n+{\n+\tstruct ice_boost_tcam_entry *tcam;\n+\tstruct ice_pkg_enum state;\n+\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tif (!ice_seg)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tdo {\n+\t\ttcam = (struct ice_boost_tcam_entry *)\n+\t\t       ice_pkg_enum_entry(ice_seg, &state,\n+\t\t\t\t\t  ICE_SID_RXPARSER_BOOST_TCAM, NULL,\n+\t\t\t\t\t  ice_boost_tcam_handler);\n+\t\tif (tcam && LE16_TO_CPU(tcam->addr) == addr) {\n+\t\t\t*entry = tcam;\n+\t\t\treturn ICE_SUCCESS;\n+\t\t}\n+\n+\t\tice_seg = NULL;\n+\t} while (tcam);\n+\n+\t*entry = NULL;\n+\treturn ICE_ERR_CFG;\n+}\n+\n+/**\n+ * ice_init_pkg_hints\n+ * @hw: pointer to the HW structure\n+ * @ice_seg: pointer to the segment of the package scan (non-NULL)\n+ *\n+ * This function will scan the package and save off relevant information\n+ * (hints or metadata) for driver use. The ice_seg parameter must not be NULL\n+ * since the first call to ice_enum_labels requires a pointer to an actual\n+ * ice_seg structure.\n+ */\n+void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg)\n+{\n+\tstruct ice_pkg_enum state;\n+\tchar *label_name;\n+\tu16 val;\n+\tint i;\n+\n+\tice_memset(&hw->tnl, 0, sizeof(hw->tnl), ICE_NONDMA_MEM);\n+\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n+\n+\tif (!ice_seg)\n+\t\treturn;\n+\n+\tlabel_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state,\n+\t\t\t\t     &val);\n+\n+\twhile (label_name) {\n+/* TODO: Replace !strnsmp() with wrappers like match_some_pre() */\n+\t\tif (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE)))\n+\t\t\t/* check for a tunnel entry */\n+\t\t\tice_add_tunnel_hint(hw, label_name, val);\n+\n+\t\t/* check for a dvm mode entry */\n+\t\telse if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE)))\n+\t\t\tice_add_dvm_hint(hw, val, true);\n+\n+\t\t/* check for a svm mode entry */\n+\t\telse if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE)))\n+\t\t\tice_add_dvm_hint(hw, val, false);\n+\n+\t\tlabel_name = ice_enum_labels(NULL, 0, &state, &val);\n+\t}\n+\n+\t/* Cache the appropriate boost TCAM entry pointers for tunnels */\n+\tfor (i = 0; i < hw->tnl.count; i++) {\n+\t\tice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr,\n+\t\t\t\t     &hw->tnl.tbl[i].boost_entry);\n+\t\tif (hw->tnl.tbl[i].boost_entry)\n+\t\t\thw->tnl.tbl[i].valid = true;\n+\t}\n+\n+\t/* Cache the appropriate boost TCAM entry pointers for DVM and SVM */\n+\tfor (i = 0; i < hw->dvm_upd.count; i++)\n+\t\tice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr,\n+\t\t\t\t     &hw->dvm_upd.tbl[i].boost_entry);\n+}\n+\n+/**\n+ * ice_acquire_global_cfg_lock\n+ * @hw: pointer to the HW structure\n+ * @access: access type (read or write)\n+ *\n+ * This function will request ownership of the global config lock for reading\n+ * or writing of the package. When attempting to obtain write access, the\n+ * caller must check for the following two return values:\n+ *\n+ * ICE_SUCCESS        - Means the caller has acquired the global config lock\n+ *                      and can perform writing of the package.\n+ * ICE_ERR_AQ_NO_WORK - Indicates another driver has already written the\n+ *                      package or has found that no update was necessary; in\n+ *                      this case, the caller can just skip performing any\n+ *                      update of the package.\n+ */\n+enum ice_status\n+ice_acquire_global_cfg_lock(struct ice_hw *hw,\n+\t\t\t    enum ice_aq_res_access_type access)\n+{\n+\tenum ice_status status;\n+\n+\tstatus = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access,\n+\t\t\t\t ICE_GLOBAL_CFG_LOCK_TIMEOUT);\n+\n+\tif (status == ICE_ERR_AQ_NO_WORK)\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Global config lock: No work to do\\n\");\n+\n+\treturn status;\n+}\n+\n+/**\n+ * ice_release_global_cfg_lock\n+ * @hw: pointer to the HW structure\n+ *\n+ * This function will release the global config lock.\n+ */\n+void ice_release_global_cfg_lock(struct ice_hw *hw)\n+{\n+\tice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID);\n+}\n+\n+/**\n+ * ice_acquire_change_lock\n+ * @hw: pointer to the HW structure\n+ * @access: access type (read or write)\n+ *\n+ * This function will request ownership of the change lock.\n+ */\n+enum ice_status\n+ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access)\n+{\n+\treturn ice_acquire_res(hw, ICE_CHANGE_LOCK_RES_ID, access,\n+\t\t\t       ICE_CHANGE_LOCK_TIMEOUT);\n+}\n+\n+/**\n+ * ice_release_change_lock\n+ * @hw: pointer to the HW structure\n+ *\n+ * This function will release the change lock using the proper Admin Command.\n+ */\n+void ice_release_change_lock(struct ice_hw *hw)\n+{\n+\tice_release_res(hw, ICE_CHANGE_LOCK_RES_ID);\n+}\n+\n+/**\n+ * ice_get_set_tx_topo - get or set tx topology\n+ * @hw: pointer to the HW struct\n+ * @buf: pointer to tx topology buffer\n+ * @buf_size: buffer size\n+ * @cd: pointer to command details structure or NULL\n+ * @flags: pointer to descriptor flags\n+ * @set: 0-get, 1-set topology\n+ *\n+ * The function will get or set tx topology\n+ */\n+static enum ice_status\n+ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,\n+\t\t    struct ice_sq_cd *cd, u8 *flags, bool set)\n+{\n+\tstruct ice_aqc_get_set_tx_topo *cmd;\n+\tstruct ice_aq_desc desc;\n+\tenum ice_status status;\n+\n+\tcmd = &desc.params.get_set_tx_topo;\n+\tif (set) {\n+\t\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_tx_topo);\n+\t\tcmd->set_flags = ICE_AQC_TX_TOPO_FLAGS_ISSUED;\n+\t\t/* requested to update a new topology, not a default topolgy */\n+\t\tif (buf)\n+\t\t\tcmd->set_flags |= ICE_AQC_TX_TOPO_FLAGS_SRC_RAM |\n+\t\t\t\t\t  ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW;\n+\t} else {\n+\t\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_tx_topo);\n+\t\tcmd->get_flags = ICE_AQC_TX_TOPO_GET_RAM;\n+\t}\n+\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n+\tstatus = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);\n+\tif (status)\n+\t\treturn status;\n+\t/* read the return flag values (first byte) for get operation */\n+\tif (!set && flags)\n+\t\t*flags = desc.params.get_set_tx_topo.set_flags;\n+\n+\treturn ICE_SUCCESS;\n+}\n+\n+/**\n+ * ice_cfg_tx_topo - Initialize new tx topology if available\n+ * @hw: pointer to the HW struct\n+ * @buf: pointer to Tx topology buffer\n+ * @len: buffer size\n+ *\n+ * The function will apply the new Tx topology from the package buffer\n+ * if available.\n+ */\n+enum ice_status ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)\n+{\n+\tu8 *current_topo, *new_topo = NULL;\n+\tstruct ice_run_time_cfg_seg *seg;\n+\tstruct ice_buf_hdr *section;\n+\tstruct ice_pkg_hdr *pkg_hdr;\n+\tenum ice_ddp_state state;\n+\tu16 i, size = 0, offset;\n+\tenum ice_status status;\n+\tu32 reg = 0;\n+\tu8 flags;\n+\n+\tif (!buf || !len)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\t/* Does FW support new Tx topology mode ? */\n+\tif (!hw->func_caps.common_cap.tx_sched_topo_comp_mode_en) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"FW doesn't support compatibility mode\\n\");\n+\t\treturn ICE_ERR_NOT_SUPPORTED;\n+\t}\n+\n+\tcurrent_topo = (u8 *)ice_malloc(hw, ICE_AQ_MAX_BUF_LEN);\n+\tif (!current_topo)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\t/* get the current Tx topology */\n+\tstatus = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL,\n+\t\t\t\t     &flags, false);\n+\tice_free(hw, current_topo);\n+\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Get current topology is failed\\n\");\n+\t\treturn status;\n+\t}\n+\n+\t/* Is default topology already applied ? */\n+\tif (!(flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&\n+\t    hw->num_tx_sched_layers == 9) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Loaded default topology\\n\");\n+\t\t/* Already default topology is loaded */\n+\t\treturn ICE_ERR_ALREADY_EXISTS;\n+\t}\n+\n+\t/* Is new topology already applied ? */\n+\tif ((flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&\n+\t    hw->num_tx_sched_layers == 5) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Loaded new topology\\n\");\n+\t\t/* Already new topology is loaded */\n+\t\treturn ICE_ERR_ALREADY_EXISTS;\n+\t}\n+\n+\t/* Is set topology issued already ? */\n+\tif (flags & ICE_AQC_TX_TOPO_FLAGS_ISSUED) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Update tx topology was done by another PF\\n\");\n+\t\t/* add a small delay before exiting */\n+\t\tfor (i = 0; i < 20; i++)\n+\t\t\tice_msec_delay(100, true);\n+\t\treturn ICE_ERR_ALREADY_EXISTS;\n+\t}\n+\n+\t/* Change the topology from new to default (5 to 9) */\n+\tif (!(flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&\n+\t    hw->num_tx_sched_layers == 5) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Change topology from 5 to 9 layers\\n\");\n+\t\tgoto update_topo;\n+\t}\n+\n+\tpkg_hdr = (struct ice_pkg_hdr *)buf;\n+\tstate = ice_verify_pkg(pkg_hdr, len);\n+\tif (state) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"failed to verify pkg (err: %d)\\n\",\n+\t\t\t  state);\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\t/* find run time configuration segment */\n+\tseg = (struct ice_run_time_cfg_seg *)\n+\t\tice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);\n+\tif (!seg) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"5 layer topology segment is missing\\n\");\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\tif (LE32_TO_CPU(seg->buf_table.buf_count) < ICE_MIN_S_COUNT) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"5 layer topology segment count(%d) is wrong\\n\",\n+\t\t\t  seg->buf_table.buf_count);\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\tsection = ice_pkg_val_buf(seg->buf_table.buf_array);\n+\n+\tif (!section || LE32_TO_CPU(section->section_entry[0].type) !=\n+\t\tICE_SID_TX_5_LAYER_TOPO) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"5 layer topology section type is wrong\\n\");\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\tsize = LE16_TO_CPU(section->section_entry[0].size);\n+\toffset = LE16_TO_CPU(section->section_entry[0].offset);\n+\tif (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"5 layer topology section size is wrong\\n\");\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\t/* make sure the section fits in the buffer */\n+\tif (offset + size > ICE_PKG_BUF_SIZE) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"5 layer topology buffer > 4K\\n\");\n+\t\treturn ICE_ERR_CFG;\n+\t}\n+\n+\t/* Get the new topology buffer */\n+\tnew_topo = ((u8 *)section) + offset;\n+\n+update_topo:\n+\t/* acquire global lock to make sure that set topology issued\n+\t * by one PF\n+\t */\n+\tstatus = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, ICE_RES_WRITE,\n+\t\t\t\t ICE_GLOBAL_CFG_LOCK_TIMEOUT);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to acquire global lock\\n\");\n+\t\treturn status;\n+\t}\n+\n+\t/* check reset was triggered already or not */\n+\treg = rd32(hw, GLGEN_RSTAT);\n+\tif (reg & GLGEN_RSTAT_DEVSTATE_M) {\n+\t\t/* Reset is in progress, re-init the hw again */\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Reset is in progress. layer topology might be applied already\\n\");\n+\t\tice_check_reset(hw);\n+\t\treturn ICE_SUCCESS;\n+\t}\n+\n+\t/* set new topology */\n+\tstatus = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Set tx topology is failed\\n\");\n+\t\treturn status;\n+\t}\n+\n+\t/* new topology is updated, delay 1 second before issuing the CORRER */\n+\tfor (i = 0; i < 10; i++)\n+\t\tice_msec_delay(100, true);\n+\tice_reset(hw, ICE_RESET_CORER);\n+\t/* CORER will clear the global lock, so no explicit call\n+\t * required for release\n+\t */\n+\treturn ICE_SUCCESS;\n+}\ndiff --git a/drivers/net/ice/base/ice_ddp.h b/drivers/net/ice/base/ice_ddp.h\nnew file mode 100644\nindex 0000000000..53bbbe2a5a\n--- /dev/null\n+++ b/drivers/net/ice/base/ice_ddp.h\n@@ -0,0 +1,466 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2001-2022 Intel Corporation\n+ */\n+\n+#ifndef _ICE_DDP_H_\n+#define _ICE_DDP_H_\n+\n+#include \"ice_osdep.h\"\n+#include \"ice_adminq_cmd.h\"\n+#include \"ice_controlq.h\"\n+#include \"ice_status.h\"\n+#include \"ice_flex_type.h\"\n+#include \"ice_protocol_type.h\"\n+\n+/* Package minimal version supported */\n+#define ICE_PKG_SUPP_VER_MAJ\t1\n+#define ICE_PKG_SUPP_VER_MNR\t3\n+\n+/* Package format version */\n+#define ICE_PKG_FMT_VER_MAJ\t1\n+#define ICE_PKG_FMT_VER_MNR\t0\n+#define ICE_PKG_FMT_VER_UPD\t0\n+#define ICE_PKG_FMT_VER_DFT\t0\n+\n+#define ICE_PKG_CNT 4\n+\n+enum ice_ddp_state {\n+\t/* Indicates that this call to ice_init_pkg\n+\t * successfully loaded the requested DDP package\n+\t */\n+\tICE_DDP_PKG_SUCCESS\t\t\t\t= 0,\n+\n+\t/* Generic error for already loaded errors, it is mapped later to\n+\t * the more specific one (one of the next 3)\n+\t */\n+\tICE_DDP_PKG_ALREADY_LOADED\t\t\t= -1,\n+\n+\t/* Indicates that a DDP package of the same version has already been\n+\t * loaded onto the device by a previous call or by another PF\n+\t */\n+\tICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED\t\t= -2,\n+\n+\t/* The device has a DDP package that is not supported by the driver */\n+\tICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED\t= -3,\n+\n+\t/* The device has a compatible package\n+\t * (but different from the request) already loaded\n+\t */\n+\tICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED\t\t= -4,\n+\n+\t/* The firmware loaded on the device is not compatible with\n+\t * the DDP package loaded\n+\t */\n+\tICE_DDP_PKG_FW_MISMATCH\t\t\t\t= -5,\n+\n+\t/* The DDP package file is invalid */\n+\tICE_DDP_PKG_INVALID_FILE\t\t\t= -6,\n+\n+\t/* The version of the DDP package provided is higher than\n+\t * the driver supports\n+\t */\n+\tICE_DDP_PKG_FILE_VERSION_TOO_HIGH\t\t= -7,\n+\n+\t/* The version of the DDP package provided is lower than the\n+\t * driver supports\n+\t */\n+\tICE_DDP_PKG_FILE_VERSION_TOO_LOW\t\t= -8,\n+\n+\t/* Missing security manifest in DDP pkg */\n+\tICE_DDP_PKG_NO_SEC_MANIFEST\t\t\t= -9,\n+\n+\t/* The RSA signature of the DDP package file provided is invalid */\n+\tICE_DDP_PKG_FILE_SIGNATURE_INVALID\t\t= -10,\n+\n+\t/* The DDP package file security revision is too low and not\n+\t * supported by firmware\n+\t */\n+\tICE_DDP_PKG_SECURE_VERSION_NBR_TOO_LOW\t\t= -11,\n+\n+\t/* Manifest hash mismatch */\n+\tICE_DDP_PKG_MANIFEST_INVALID\t\t\t= -12,\n+\n+\t/* Buffer hash mismatches manifest */\n+\tICE_DDP_PKG_BUFFER_INVALID\t\t\t= -13,\n+\n+\t/* Other errors */\n+\tICE_DDP_PKG_ERR\t\t\t\t\t= -14,\n+};\n+\n+/* Package and segment headers and tables */\n+struct ice_pkg_hdr {\n+\tstruct ice_pkg_ver pkg_format_ver;\n+\t__le32 seg_count;\n+\t__le32 seg_offset[STRUCT_HACK_VAR_LEN];\n+};\n+\n+/* Package signing algorithm types */\n+#define SEGMENT_SIGN_TYPE_INVALID\t0x00000000\n+#define SEGMENT_SIGN_TYPE_RSA2K\t\t0x00000001\n+#define SEGMENT_SIGN_TYPE_RSA3K\t\t0x00000002\n+#define SEGMENT_SIGN_TYPE_RSA3K_SBB\t0x00000003 /* Secure Boot Block */\n+\n+/* generic segment */\n+struct ice_generic_seg_hdr {\n+#define\tSEGMENT_TYPE_INVALID\t0x00000000\n+#define SEGMENT_TYPE_METADATA\t0x00000001\n+#define SEGMENT_TYPE_ICE_E810\t0x00000010\n+#define SEGMENT_TYPE_SIGNING\t0x00001001\n+#define SEGMENT_TYPE_ICE_RUN_TIME_CFG 0x00000020\n+\t__le32 seg_type;\n+\tstruct ice_pkg_ver seg_format_ver;\n+\t__le32 seg_size;\n+\tchar seg_id[ICE_PKG_NAME_SIZE];\n+};\n+\n+/* ice specific segment */\n+\n+union ice_device_id {\n+\tstruct {\n+\t\t__le16 device_id;\n+\t\t__le16 vendor_id;\n+\t} dev_vend_id;\n+\t__le32 id;\n+};\n+\n+struct ice_device_id_entry {\n+\tunion ice_device_id device;\n+\tunion ice_device_id sub_device;\n+};\n+\n+struct ice_seg {\n+\tstruct ice_generic_seg_hdr hdr;\n+\t__le32 device_table_count;\n+\tstruct ice_device_id_entry device_table[STRUCT_HACK_VAR_LEN];\n+};\n+\n+struct ice_nvm_table {\n+\t__le32 table_count;\n+\t__le32 vers[STRUCT_HACK_VAR_LEN];\n+};\n+\n+struct ice_buf {\n+#define ICE_PKG_BUF_SIZE\t4096\n+\tu8 buf[ICE_PKG_BUF_SIZE];\n+};\n+\n+struct ice_buf_table {\n+\t__le32 buf_count;\n+\tstruct ice_buf buf_array[STRUCT_HACK_VAR_LEN];\n+};\n+\n+struct ice_run_time_cfg_seg {\n+\tstruct ice_generic_seg_hdr hdr;\n+\tu8 rsvd[8];\n+\tstruct ice_buf_table buf_table;\n+};\n+\n+/* global metadata specific segment */\n+struct ice_global_metadata_seg {\n+\tstruct ice_generic_seg_hdr hdr;\n+\tstruct ice_pkg_ver pkg_ver;\n+\t__le32 rsvd;\n+\tchar pkg_name[ICE_PKG_NAME_SIZE];\n+};\n+\n+#define ICE_MIN_S_OFF\t\t12\n+#define ICE_MAX_S_OFF\t\t4095\n+#define ICE_MIN_S_SZ\t\t1\n+#define ICE_MAX_S_SZ\t\t4084\n+\n+struct ice_sign_seg {\n+\tstruct ice_generic_seg_hdr hdr;\n+\t__le32 seg_id;\n+\t__le32 sign_type;\n+\t__le32 signed_seg_idx;\n+\t__le32 signed_buf_start;\n+\t__le32 signed_buf_count;\n+#define ICE_SIGN_SEG_RESERVED_COUNT\t44\n+\tu8 reserved[ICE_SIGN_SEG_RESERVED_COUNT];\n+\tstruct ice_buf_table buf_tbl;\n+};\n+\n+/* section information */\n+struct ice_section_entry {\n+\t__le32 type;\n+\t__le16 offset;\n+\t__le16 size;\n+};\n+\n+#define ICE_MIN_S_COUNT\t\t1\n+#define ICE_MAX_S_COUNT\t\t511\n+#define ICE_MIN_S_DATA_END\t12\n+#define ICE_MAX_S_DATA_END\t4096\n+\n+#define ICE_METADATA_BUF\t0x80000000\n+\n+struct ice_buf_hdr {\n+\t__le16 section_count;\n+\t__le16 data_end;\n+\tstruct ice_section_entry section_entry[STRUCT_HACK_VAR_LEN];\n+};\n+\n+#define ICE_MAX_ENTRIES_IN_BUF(hd_sz, ent_sz) ((ICE_PKG_BUF_SIZE - \\\n+\tice_struct_size((struct ice_buf_hdr *)0, section_entry, 1) - (hd_sz)) /\\\n+\t(ent_sz))\n+\n+/* ice package section IDs */\n+#define ICE_SID_METADATA\t\t1\n+#define ICE_SID_XLT0_SW\t\t\t10\n+#define ICE_SID_XLT_KEY_BUILDER_SW\t11\n+#define ICE_SID_XLT1_SW\t\t\t12\n+#define ICE_SID_XLT2_SW\t\t\t13\n+#define ICE_SID_PROFID_TCAM_SW\t\t14\n+#define ICE_SID_PROFID_REDIR_SW\t\t15\n+#define ICE_SID_FLD_VEC_SW\t\t16\n+#define ICE_SID_CDID_KEY_BUILDER_SW\t17\n+#define ICE_SID_CDID_REDIR_SW\t\t18\n+\n+#define ICE_SID_XLT0_ACL\t\t20\n+#define ICE_SID_XLT_KEY_BUILDER_ACL\t21\n+#define ICE_SID_XLT1_ACL\t\t22\n+#define ICE_SID_XLT2_ACL\t\t23\n+#define ICE_SID_PROFID_TCAM_ACL\t\t24\n+#define ICE_SID_PROFID_REDIR_ACL\t25\n+#define ICE_SID_FLD_VEC_ACL\t\t26\n+#define ICE_SID_CDID_KEY_BUILDER_ACL\t27\n+#define ICE_SID_CDID_REDIR_ACL\t\t28\n+\n+#define ICE_SID_XLT0_FD\t\t\t30\n+#define ICE_SID_XLT_KEY_BUILDER_FD\t31\n+#define ICE_SID_XLT1_FD\t\t\t32\n+#define ICE_SID_XLT2_FD\t\t\t33\n+#define ICE_SID_PROFID_TCAM_FD\t\t34\n+#define ICE_SID_PROFID_REDIR_FD\t\t35\n+#define ICE_SID_FLD_VEC_FD\t\t36\n+#define ICE_SID_CDID_KEY_BUILDER_FD\t37\n+#define ICE_SID_CDID_REDIR_FD\t\t38\n+\n+#define ICE_SID_XLT0_RSS\t\t40\n+#define ICE_SID_XLT_KEY_BUILDER_RSS\t41\n+#define ICE_SID_XLT1_RSS\t\t42\n+#define ICE_SID_XLT2_RSS\t\t43\n+#define ICE_SID_PROFID_TCAM_RSS\t\t44\n+#define ICE_SID_PROFID_REDIR_RSS\t45\n+#define ICE_SID_FLD_VEC_RSS\t\t46\n+#define ICE_SID_CDID_KEY_BUILDER_RSS\t47\n+#define ICE_SID_CDID_REDIR_RSS\t\t48\n+\n+#define ICE_SID_RXPARSER_CAM\t\t50\n+#define ICE_SID_RXPARSER_NOMATCH_CAM\t51\n+#define ICE_SID_RXPARSER_IMEM\t\t52\n+#define ICE_SID_RXPARSER_XLT0_BUILDER\t53\n+#define ICE_SID_RXPARSER_NODE_PTYPE\t54\n+#define ICE_SID_RXPARSER_MARKER_PTYPE\t55\n+#define ICE_SID_RXPARSER_BOOST_TCAM\t56\n+#define ICE_SID_RXPARSER_PROTO_GRP\t57\n+#define ICE_SID_RXPARSER_METADATA_INIT\t58\n+#define ICE_SID_RXPARSER_XLT0\t\t59\n+\n+#define ICE_SID_TXPARSER_CAM\t\t60\n+#define ICE_SID_TXPARSER_NOMATCH_CAM\t61\n+#define ICE_SID_TXPARSER_IMEM\t\t62\n+#define ICE_SID_TXPARSER_XLT0_BUILDER\t63\n+#define ICE_SID_TXPARSER_NODE_PTYPE\t64\n+#define ICE_SID_TXPARSER_MARKER_PTYPE\t65\n+#define ICE_SID_TXPARSER_BOOST_TCAM\t66\n+#define ICE_SID_TXPARSER_PROTO_GRP\t67\n+#define ICE_SID_TXPARSER_METADATA_INIT\t68\n+#define ICE_SID_TXPARSER_XLT0\t\t69\n+\n+#define ICE_SID_RXPARSER_INIT_REDIR\t70\n+#define ICE_SID_TXPARSER_INIT_REDIR\t71\n+#define ICE_SID_RXPARSER_MARKER_GRP\t72\n+#define ICE_SID_TXPARSER_MARKER_GRP\t73\n+#define ICE_SID_RXPARSER_LAST_PROTO\t74\n+#define ICE_SID_TXPARSER_LAST_PROTO\t75\n+#define ICE_SID_RXPARSER_PG_SPILL\t76\n+#define ICE_SID_TXPARSER_PG_SPILL\t77\n+#define ICE_SID_RXPARSER_NOMATCH_SPILL\t78\n+#define ICE_SID_TXPARSER_NOMATCH_SPILL\t79\n+\n+#define ICE_SID_XLT0_PE\t\t\t80\n+#define ICE_SID_XLT_KEY_BUILDER_PE\t81\n+#define ICE_SID_XLT1_PE\t\t\t82\n+#define ICE_SID_XLT2_PE\t\t\t83\n+#define ICE_SID_PROFID_TCAM_PE\t\t84\n+#define ICE_SID_PROFID_REDIR_PE\t\t85\n+#define ICE_SID_FLD_VEC_PE\t\t86\n+#define ICE_SID_CDID_KEY_BUILDER_PE\t87\n+#define ICE_SID_CDID_REDIR_PE\t\t88\n+\n+#define ICE_SID_RXPARSER_FLAG_REDIR\t97\n+\n+/* Label Metadata section IDs */\n+#define ICE_SID_LBL_FIRST\t\t0x80000010\n+#define ICE_SID_LBL_RXPARSER_IMEM\t0x80000010\n+#define ICE_SID_LBL_TXPARSER_IMEM\t0x80000011\n+#define ICE_SID_LBL_RESERVED_12\t\t0x80000012\n+#define ICE_SID_LBL_RESERVED_13\t\t0x80000013\n+#define ICE_SID_LBL_RXPARSER_MARKER\t0x80000014\n+#define ICE_SID_LBL_TXPARSER_MARKER\t0x80000015\n+#define ICE_SID_LBL_PTYPE\t\t0x80000016\n+#define ICE_SID_LBL_PROTOCOL_ID\t\t0x80000017\n+#define ICE_SID_LBL_RXPARSER_TMEM\t0x80000018\n+#define ICE_SID_LBL_TXPARSER_TMEM\t0x80000019\n+#define ICE_SID_LBL_RXPARSER_PG\t\t0x8000001A\n+#define ICE_SID_LBL_TXPARSER_PG\t\t0x8000001B\n+#define ICE_SID_LBL_RXPARSER_M_TCAM\t0x8000001C\n+#define ICE_SID_LBL_TXPARSER_M_TCAM\t0x8000001D\n+#define ICE_SID_LBL_SW_PROFID_TCAM\t0x8000001E\n+#define ICE_SID_LBL_ACL_PROFID_TCAM\t0x8000001F\n+#define ICE_SID_LBL_PE_PROFID_TCAM\t0x80000020\n+#define ICE_SID_LBL_RSS_PROFID_TCAM\t0x80000021\n+#define ICE_SID_LBL_FD_PROFID_TCAM\t0x80000022\n+#define ICE_SID_LBL_FLAG\t\t0x80000023\n+#define ICE_SID_LBL_REG\t\t\t0x80000024\n+#define ICE_SID_LBL_SW_PTG\t\t0x80000025\n+#define ICE_SID_LBL_ACL_PTG\t\t0x80000026\n+#define ICE_SID_LBL_PE_PTG\t\t0x80000027\n+#define ICE_SID_LBL_RSS_PTG\t\t0x80000028\n+#define ICE_SID_LBL_FD_PTG\t\t0x80000029\n+#define ICE_SID_LBL_SW_VSIG\t\t0x8000002A\n+#define ICE_SID_LBL_ACL_VSIG\t\t0x8000002B\n+#define ICE_SID_LBL_PE_VSIG\t\t0x8000002C\n+#define ICE_SID_LBL_RSS_VSIG\t\t0x8000002D\n+#define ICE_SID_LBL_FD_VSIG\t\t0x8000002E\n+#define ICE_SID_LBL_PTYPE_META\t\t0x8000002F\n+#define ICE_SID_LBL_SW_PROFID\t\t0x80000030\n+#define ICE_SID_LBL_ACL_PROFID\t\t0x80000031\n+#define ICE_SID_LBL_PE_PROFID\t\t0x80000032\n+#define ICE_SID_LBL_RSS_PROFID\t\t0x80000033\n+#define ICE_SID_LBL_FD_PROFID\t\t0x80000034\n+#define ICE_SID_LBL_RXPARSER_MARKER_GRP\t0x80000035\n+#define ICE_SID_LBL_TXPARSER_MARKER_GRP\t0x80000036\n+#define ICE_SID_LBL_RXPARSER_PROTO\t0x80000037\n+#define ICE_SID_LBL_TXPARSER_PROTO\t0x80000038\n+/* The following define MUST be updated to reflect the last label section ID */\n+#define ICE_SID_LBL_LAST\t\t0x80000038\n+\n+/* Label ICE runtime configuration section IDs */\n+#define ICE_SID_TX_5_LAYER_TOPO\t\t0x10\n+\n+enum ice_block {\n+\tICE_BLK_SW = 0,\n+\tICE_BLK_ACL,\n+\tICE_BLK_FD,\n+\tICE_BLK_RSS,\n+\tICE_BLK_PE,\n+\tICE_BLK_COUNT\n+};\n+\n+enum ice_sect {\n+\tICE_XLT0 = 0,\n+\tICE_XLT_KB,\n+\tICE_XLT1,\n+\tICE_XLT2,\n+\tICE_PROF_TCAM,\n+\tICE_PROF_REDIR,\n+\tICE_VEC_TBL,\n+\tICE_CDID_KB,\n+\tICE_CDID_REDIR,\n+\tICE_SECT_COUNT\n+};\n+\n+/* package buffer building */\n+\n+struct ice_buf_build {\n+\tstruct ice_buf buf;\n+\tu16 reserved_section_table_entries;\n+};\n+\n+struct ice_pkg_enum {\n+\tstruct ice_buf_table *buf_table;\n+\tu32 buf_idx;\n+\n+\tu32 type;\n+\tstruct ice_buf_hdr *buf;\n+\tu32 sect_idx;\n+\tvoid *sect;\n+\tu32 sect_type;\n+\n+\tu32 entry_idx;\n+\tvoid *(*handler)(u32 sect_type, void *section, u32 index, u32 *offset);\n+};\n+\n+/* package Marker PType TCAM entry */\n+struct ice_marker_ptype_tcam_entry {\n+#define ICE_MARKER_PTYPE_TCAM_ADDR_MAX\t1024\n+\t__le16 addr;\n+\t__le16 ptype;\n+\tu8 keys[20];\n+};\n+\n+struct ice_marker_ptype_tcam_section {\n+\t__le16 count;\n+\t__le16 reserved;\n+\tstruct ice_marker_ptype_tcam_entry tcam[STRUCT_HACK_VAR_LEN];\n+};\n+\n+#define ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF ICE_MAX_ENTRIES_IN_BUF( \\\n+\tice_struct_size((struct ice_marker_ptype_tcam_section *)0, tcam, 1) - \\\n+\tsizeof(struct ice_marker_ptype_tcam_entry), \\\n+\tsizeof(struct ice_marker_ptype_tcam_entry))\n+\n+struct ice_hw;\n+\n+enum ice_status\n+ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access);\n+void ice_release_change_lock(struct ice_hw *hw);\n+\n+struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw);\n+void *\n+ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size);\n+enum ice_status\n+ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count);\n+enum ice_status\n+ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,\n+\t\t   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list);\n+u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld);\n+\n+enum ice_status\n+ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count);\n+enum ice_status\n+ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count);\n+void ice_release_global_cfg_lock(struct ice_hw *hw);\n+struct ice_generic_seg_hdr *\n+ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,\n+\t\t    struct ice_pkg_hdr *pkg_hdr);\n+enum ice_ddp_state\n+ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len);\n+enum ice_ddp_state\n+ice_get_pkg_info(struct ice_hw *hw);\n+void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg);\n+struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg);\n+enum ice_status\n+ice_acquire_global_cfg_lock(struct ice_hw *hw,\n+\t\t\t    enum ice_aq_res_access_type access);\n+\n+struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg);\n+struct ice_buf_hdr *\n+ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state);\n+bool\n+ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state);\n+void *\n+ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n+\t\t   u32 sect_type, u32 *offset,\n+\t\t   void *(*handler)(u32 sect_type, void *section,\n+\t\t\t\t    u32 index, u32 *offset));\n+void *\n+ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n+\t\t     u32 sect_type);\n+enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);\n+enum ice_ddp_state\n+ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);\n+bool ice_is_init_pkg_successful(enum ice_ddp_state state);\n+void ice_free_seg(struct ice_hw *hw);\n+\n+struct ice_buf_build *\n+ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,\n+\t\t\t\t void **section);\n+struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld);\n+void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld);\n+\n+enum ice_status ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len);\n+\n+#endif /* _ICE_DDP_H_ */\ndiff --git a/drivers/net/ice/base/ice_defs.h b/drivers/net/ice/base/ice_defs.h\nnew file mode 100644\nindex 0000000000..6e886f6aac\n--- /dev/null\n+++ b/drivers/net/ice/base/ice_defs.h\n@@ -0,0 +1,49 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2001-2022 Intel Corporation\n+ */\n+\n+#ifndef _ICE_DEFS_H_\n+#define _ICE_DEFS_H_\n+\n+#define ETH_ALEN\t6\n+\n+#define ETH_HEADER_LEN\t14\n+\n+#define BIT(a) (1UL << (a))\n+#define BIT_ULL(a) (1ULL << (a))\n+\n+#define BITS_PER_BYTE\t8\n+\n+#define _FORCE_\n+\n+#define ICE_BYTES_PER_WORD\t2\n+#define ICE_BYTES_PER_DWORD\t4\n+#define ICE_MAX_TRAFFIC_CLASS\t8\n+\n+/**\n+ * ROUND_UP - round up to next arbitrary multiple (not a power of 2)\n+ * @a: value to round up\n+ * @b: arbitrary multiple\n+ *\n+ * Round up to the next multiple of the arbitrary b.\n+ * Note, when b is a power of 2 use ICE_ALIGN() instead.\n+ */\n+#define ROUND_UP(a, b)\t((b) * DIVIDE_AND_ROUND_UP((a), (b)))\n+\n+#define MIN_T(_t, _a, _b)\tmin((_t)(_a), (_t)(_b))\n+\n+#define IS_ASCII(_ch)\t((_ch) < 0x80)\n+\n+#define STRUCT_HACK_VAR_LEN\n+/**\n+ * ice_struct_size - size of struct with C99 flexible array member\n+ * @ptr: pointer to structure\n+ * @field: flexible array member (last member of the structure)\n+ * @num: number of elements of that flexible array member\n+ */\n+#define ice_struct_size(ptr, field, num) \\\n+\t(sizeof(*(ptr)) + sizeof(*(ptr)->field) * (num))\n+\n+#define FLEX_ARRAY_SIZE(_ptr, _mem, cnt) ((cnt) * sizeof(_ptr->_mem[0]))\n+\n+#endif /* _ICE_DEFS_H_ */\ndiff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c\nindex 3918169001..a43d7ef76b 100644\n--- a/drivers/net/ice/base/ice_flex_pipe.c\n+++ b/drivers/net/ice/base/ice_flex_pipe.c\n@@ -3,6 +3,7 @@\n  */\n \n #include \"ice_common.h\"\n+#include \"ice_ddp.h\"\n #include \"ice_flex_pipe.h\"\n #include \"ice_protocol_type.h\"\n #include \"ice_flow.h\"\n@@ -106,2049 +107,224 @@ static u32 ice_sect_id(enum ice_block blk, enum ice_sect sect)\n }\n \n /**\n- * ice_pkg_val_buf\n- * @buf: pointer to the ice buffer\n- *\n- * This helper function validates a buffer's header.\n- */\n-static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)\n-{\n-\tstruct ice_buf_hdr *hdr;\n-\tu16 section_count;\n-\tu16 data_end;\n-\n-\thdr = (struct ice_buf_hdr *)buf->buf;\n-\t/* verify data */\n-\tsection_count = LE16_TO_CPU(hdr->section_count);\n-\tif (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)\n-\t\treturn NULL;\n-\n-\tdata_end = LE16_TO_CPU(hdr->data_end);\n-\tif (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END)\n-\t\treturn NULL;\n-\n-\treturn hdr;\n-}\n-\n-/**\n- * ice_find_buf_table\n- * @ice_seg: pointer to the ice segment\n- *\n- * Returns the address of the buffer table within the ice segment.\n- */\n-static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)\n-{\n-\tstruct ice_nvm_table *nvms;\n-\n-\tnvms = (struct ice_nvm_table *)\n-\t\t(ice_seg->device_table +\n-\t\t LE32_TO_CPU(ice_seg->device_table_count));\n-\n-\treturn (_FORCE_ struct ice_buf_table *)\n-\t\t(nvms->vers + LE32_TO_CPU(nvms->table_count));\n-}\n-\n-/**\n- * ice_pkg_enum_buf\n- * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n- * @state: pointer to the enum state\n- *\n- * This function will enumerate all the buffers in the ice segment. The first\n- * call is made with the ice_seg parameter non-NULL; on subsequent calls,\n- * ice_seg is set to NULL which continues the enumeration. When the function\n- * returns a NULL pointer, then the end of the buffers has been reached, or an\n- * unexpected value has been detected (for example an invalid section count or\n- * an invalid buffer end value).\n- */\n-static struct ice_buf_hdr *\n-ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state)\n-{\n-\tif (ice_seg) {\n-\t\tstate->buf_table = ice_find_buf_table(ice_seg);\n-\t\tif (!state->buf_table)\n-\t\t\treturn NULL;\n-\n-\t\tstate->buf_idx = 0;\n-\t\treturn ice_pkg_val_buf(state->buf_table->buf_array);\n-\t}\n-\n-\tif (++state->buf_idx < LE32_TO_CPU(state->buf_table->buf_count))\n-\t\treturn ice_pkg_val_buf(state->buf_table->buf_array +\n-\t\t\t\t       state->buf_idx);\n-\telse\n-\t\treturn NULL;\n-}\n-\n-/**\n- * ice_pkg_advance_sect\n- * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n- * @state: pointer to the enum state\n- *\n- * This helper function will advance the section within the ice segment,\n- * also advancing the buffer if needed.\n- */\n-static bool\n-ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state)\n-{\n-\tif (!ice_seg && !state->buf)\n-\t\treturn false;\n-\n-\tif (!ice_seg && state->buf)\n-\t\tif (++state->sect_idx < LE16_TO_CPU(state->buf->section_count))\n-\t\t\treturn true;\n-\n-\tstate->buf = ice_pkg_enum_buf(ice_seg, state);\n-\tif (!state->buf)\n-\t\treturn false;\n-\n-\t/* start of new buffer, reset section index */\n-\tstate->sect_idx = 0;\n-\treturn true;\n-}\n-\n-/**\n- * ice_pkg_enum_section\n- * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n- * @state: pointer to the enum state\n- * @sect_type: section type to enumerate\n- *\n- * This function will enumerate all the sections of a particular type in the\n- * ice segment. The first call is made with the ice_seg parameter non-NULL;\n- * on subsequent calls, ice_seg is set to NULL which continues the enumeration.\n- * When the function returns a NULL pointer, then the end of the matching\n- * sections has been reached.\n- */\n-void *\n-ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n-\t\t     u32 sect_type)\n-{\n-\tu16 offset, size;\n-\n-\tif (ice_seg)\n-\t\tstate->type = sect_type;\n-\n-\tif (!ice_pkg_advance_sect(ice_seg, state))\n-\t\treturn NULL;\n-\n-\t/* scan for next matching section */\n-\twhile (state->buf->section_entry[state->sect_idx].type !=\n-\t       CPU_TO_LE32(state->type))\n-\t\tif (!ice_pkg_advance_sect(NULL, state))\n-\t\t\treturn NULL;\n-\n-\t/* validate section */\n-\toffset = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);\n-\tif (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF)\n-\t\treturn NULL;\n-\n-\tsize = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].size);\n-\tif (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ)\n-\t\treturn NULL;\n-\n-\t/* make sure the section fits in the buffer */\n-\tif (offset + size > ICE_PKG_BUF_SIZE)\n-\t\treturn NULL;\n-\n-\tstate->sect_type =\n-\t\tLE32_TO_CPU(state->buf->section_entry[state->sect_idx].type);\n-\n-\t/* calc pointer to this section */\n-\tstate->sect = ((u8 *)state->buf) +\n-\t\tLE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);\n-\n-\treturn state->sect;\n-}\n-\n-/**\n- * ice_pkg_enum_entry\n- * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)\n- * @state: pointer to the enum state\n- * @sect_type: section type to enumerate\n- * @offset: pointer to variable that receives the offset in the table (optional)\n- * @handler: function that handles access to the entries into the section type\n- *\n- * This function will enumerate all the entries in particular section type in\n- * the ice segment. The first call is made with the ice_seg parameter non-NULL;\n- * on subsequent calls, ice_seg is set to NULL which continues the enumeration.\n- * When the function returns a NULL pointer, then the end of the entries has\n- * been reached.\n- *\n- * Since each section may have a different header and entry size, the handler\n- * function is needed to determine the number and location entries in each\n- * section.\n- *\n- * The offset parameter is optional, but should be used for sections that\n- * contain an offset for each section table. For such cases, the section handler\n- * function must return the appropriate offset + index to give the absolution\n- * offset for each entry. For example, if the base for a section's header\n- * indicates a base offset of 10, and the index for the entry is 2, then\n- * section handler function should set the offset to 10 + 2 = 12.\n- */\n-void *\n-ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n-\t\t   u32 sect_type, u32 *offset,\n-\t\t   void *(*handler)(u32 sect_type, void *section,\n-\t\t\t\t    u32 index, u32 *offset))\n-{\n-\tvoid *entry;\n-\n-\tif (ice_seg) {\n-\t\tif (!handler)\n-\t\t\treturn NULL;\n-\n-\t\tif (!ice_pkg_enum_section(ice_seg, state, sect_type))\n-\t\t\treturn NULL;\n-\n-\t\tstate->entry_idx = 0;\n-\t\tstate->handler = handler;\n-\t} else {\n-\t\tstate->entry_idx++;\n-\t}\n-\n-\tif (!state->handler)\n-\t\treturn NULL;\n-\n-\t/* get entry */\n-\tentry = state->handler(state->sect_type, state->sect, state->entry_idx,\n-\t\t\t       offset);\n-\tif (!entry) {\n-\t\t/* end of a section, look for another section of this type */\n-\t\tif (!ice_pkg_enum_section(NULL, state, 0))\n-\t\t\treturn NULL;\n-\n-\t\tstate->entry_idx = 0;\n-\t\tentry = state->handler(state->sect_type, state->sect,\n-\t\t\t\t       state->entry_idx, offset);\n-\t}\n-\n-\treturn entry;\n-}\n-\n-/**\n- * ice_hw_ptype_ena - check if the PTYPE is enabled or not\n- * @hw: pointer to the HW structure\n- * @ptype: the hardware PTYPE\n- */\n-bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype)\n-{\n-\treturn ptype < ICE_FLOW_PTYPE_MAX &&\n-\t       ice_is_bit_set(hw->hw_ptype, ptype);\n-}\n-\n-/**\n- * ice_marker_ptype_tcam_handler\n- * @sect_type: section type\n- * @section: pointer to section\n- * @index: index of the Marker PType TCAM entry to be returned\n- * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections\n- *\n- * This is a callback function that can be passed to ice_pkg_enum_entry.\n- * Handles enumeration of individual Marker PType TCAM entries.\n- */\n-static void *\n-ice_marker_ptype_tcam_handler(u32 sect_type, void *section, u32 index,\n-\t\t\t      u32 *offset)\n-{\n-\tstruct ice_marker_ptype_tcam_section *marker_ptype;\n-\n-\tif (!section)\n-\t\treturn NULL;\n-\n-\tif (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE)\n-\t\treturn NULL;\n-\n-\tif (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF)\n-\t\treturn NULL;\n-\n-\tif (offset)\n-\t\t*offset = 0;\n-\n-\tmarker_ptype = (struct ice_marker_ptype_tcam_section *)section;\n-\tif (index >= LE16_TO_CPU(marker_ptype->count))\n-\t\treturn NULL;\n-\n-\treturn marker_ptype->tcam + index;\n-}\n-\n-/**\n- * ice_fill_hw_ptype - fill the enabled PTYPE bit information\n- * @hw: pointer to the HW structure\n- */\n-static void\n-ice_fill_hw_ptype(struct ice_hw *hw)\n-{\n-\tstruct ice_marker_ptype_tcam_entry *tcam;\n-\tstruct ice_seg *seg = hw->seg;\n-\tstruct ice_pkg_enum state;\n-\n-\tice_zero_bitmap(hw->hw_ptype, ICE_FLOW_PTYPE_MAX);\n-\tif (!seg)\n-\t\treturn;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tdo {\n-\t\ttcam = (struct ice_marker_ptype_tcam_entry *)\n-\t\t\tice_pkg_enum_entry(seg, &state,\n-\t\t\t\t\t   ICE_SID_RXPARSER_MARKER_PTYPE, NULL,\n-\t\t\t\t\t   ice_marker_ptype_tcam_handler);\n-\t\tif (tcam &&\n-\t\t    LE16_TO_CPU(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX &&\n-\t\t    LE16_TO_CPU(tcam->ptype) < ICE_FLOW_PTYPE_MAX)\n-\t\t\tice_set_bit(LE16_TO_CPU(tcam->ptype), hw->hw_ptype);\n-\n-\t\tseg = NULL;\n-\t} while (tcam);\n-}\n-\n-/**\n- * ice_boost_tcam_handler\n- * @sect_type: section type\n- * @section: pointer to section\n- * @index: index of the boost TCAM entry to be returned\n- * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections\n- *\n- * This is a callback function that can be passed to ice_pkg_enum_entry.\n- * Handles enumeration of individual boost TCAM entries.\n- */\n-static void *\n-ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset)\n-{\n-\tstruct ice_boost_tcam_section *boost;\n-\n-\tif (!section)\n-\t\treturn NULL;\n-\n-\tif (sect_type != ICE_SID_RXPARSER_BOOST_TCAM)\n-\t\treturn NULL;\n-\n-\tif (index > ICE_MAX_BST_TCAMS_IN_BUF)\n-\t\treturn NULL;\n-\n-\tif (offset)\n-\t\t*offset = 0;\n-\n-\tboost = (struct ice_boost_tcam_section *)section;\n-\tif (index >= LE16_TO_CPU(boost->count))\n-\t\treturn NULL;\n-\n-\treturn boost->tcam + index;\n-}\n-\n-/**\n- * ice_find_boost_entry\n- * @ice_seg: pointer to the ice segment (non-NULL)\n- * @addr: Boost TCAM address of entry to search for\n- * @entry: returns pointer to the entry\n- *\n- * Finds a particular Boost TCAM entry and returns a pointer to that entry\n- * if it is found. The ice_seg parameter must not be NULL since the first call\n- * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure.\n- */\n-static enum ice_status\n-ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr,\n-\t\t     struct ice_boost_tcam_entry **entry)\n-{\n-\tstruct ice_boost_tcam_entry *tcam;\n-\tstruct ice_pkg_enum state;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tif (!ice_seg)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\tdo {\n-\t\ttcam = (struct ice_boost_tcam_entry *)\n-\t\t       ice_pkg_enum_entry(ice_seg, &state,\n-\t\t\t\t\t  ICE_SID_RXPARSER_BOOST_TCAM, NULL,\n-\t\t\t\t\t  ice_boost_tcam_handler);\n-\t\tif (tcam && LE16_TO_CPU(tcam->addr) == addr) {\n-\t\t\t*entry = tcam;\n-\t\t\treturn ICE_SUCCESS;\n-\t\t}\n-\n-\t\tice_seg = NULL;\n-\t} while (tcam);\n-\n-\t*entry = NULL;\n-\treturn ICE_ERR_CFG;\n-}\n-\n-/**\n- * ice_label_enum_handler\n- * @sect_type: section type\n- * @section: pointer to section\n- * @index: index of the label entry to be returned\n- * @offset: pointer to receive absolute offset, always zero for label sections\n- *\n- * This is a callback function that can be passed to ice_pkg_enum_entry.\n- * Handles enumeration of individual label entries.\n- */\n-static void *\n-ice_label_enum_handler(u32 __ALWAYS_UNUSED sect_type, void *section, u32 index,\n-\t\t       u32 *offset)\n-{\n-\tstruct ice_label_section *labels;\n-\n-\tif (!section)\n-\t\treturn NULL;\n-\n-\tif (index > ICE_MAX_LABELS_IN_BUF)\n-\t\treturn NULL;\n-\n-\tif (offset)\n-\t\t*offset = 0;\n-\n-\tlabels = (struct ice_label_section *)section;\n-\tif (index >= LE16_TO_CPU(labels->count))\n-\t\treturn NULL;\n-\n-\treturn labels->label + index;\n-}\n-\n-/**\n- * ice_enum_labels\n- * @ice_seg: pointer to the ice segment (NULL on subsequent calls)\n- * @type: the section type that will contain the label (0 on subsequent calls)\n- * @state: ice_pkg_enum structure that will hold the state of the enumeration\n- * @value: pointer to a value that will return the label's value if found\n- *\n- * Enumerates a list of labels in the package. The caller will call\n- * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call\n- * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL\n- * the end of the list has been reached.\n- */\n-static char *\n-ice_enum_labels(struct ice_seg *ice_seg, u32 type, struct ice_pkg_enum *state,\n-\t\tu16 *value)\n-{\n-\tstruct ice_label *label;\n-\n-\t/* Check for valid label section on first call */\n-\tif (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST))\n-\t\treturn NULL;\n-\n-\tlabel = (struct ice_label *)ice_pkg_enum_entry(ice_seg, state, type,\n-\t\t\t\t\t\t       NULL,\n-\t\t\t\t\t\t       ice_label_enum_handler);\n-\tif (!label)\n-\t\treturn NULL;\n-\n-\t*value = LE16_TO_CPU(label->value);\n-\treturn label->name;\n-}\n-\n-/**\n- * ice_add_tunnel_hint\n- * @hw: pointer to the HW structure\n- * @label_name: label text\n- * @val: value of the tunnel port boost entry\n- */\n-static void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val)\n-{\n-\tif (hw->tnl.count < ICE_TUNNEL_MAX_ENTRIES) {\n-\t\tu16 i;\n-\n-\t\tfor (i = 0; tnls[i].type != TNL_LAST; i++) {\n-\t\t\tsize_t len = strlen(tnls[i].label_prefix);\n-\n-\t\t\t/* Look for matching label start, before continuing */\n-\t\t\tif (strncmp(label_name, tnls[i].label_prefix, len))\n-\t\t\t\tcontinue;\n-\n-\t\t\t/* Make sure this label matches our PF. Note that the PF\n-\t\t\t * character ('0' - '7') will be located where our\n-\t\t\t * prefix string's null terminator is located.\n-\t\t\t */\n-\t\t\tif ((label_name[len] - '0') == hw->pf_id) {\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].type = tnls[i].type;\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].valid = false;\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].in_use = false;\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].marked = false;\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].boost_addr = val;\n-\t\t\t\thw->tnl.tbl[hw->tnl.count].port = 0;\n-\t\t\t\thw->tnl.count++;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t}\n-}\n-\n-/**\n- * ice_add_dvm_hint\n- * @hw: pointer to the HW structure\n- * @val: value of the boost entry\n- * @enable: true if entry needs to be enabled, or false if needs to be disabled\n- */\n-static void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable)\n-{\n-\tif (hw->dvm_upd.count < ICE_DVM_MAX_ENTRIES) {\n-\t\thw->dvm_upd.tbl[hw->dvm_upd.count].boost_addr = val;\n-\t\thw->dvm_upd.tbl[hw->dvm_upd.count].enable = enable;\n-\t\thw->dvm_upd.count++;\n-\t}\n-}\n-\n-/**\n- * ice_init_pkg_hints\n- * @hw: pointer to the HW structure\n- * @ice_seg: pointer to the segment of the package scan (non-NULL)\n- *\n- * This function will scan the package and save off relevant information\n- * (hints or metadata) for driver use. The ice_seg parameter must not be NULL\n- * since the first call to ice_enum_labels requires a pointer to an actual\n- * ice_seg structure.\n- */\n-static void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg)\n-{\n-\tstruct ice_pkg_enum state;\n-\tchar *label_name;\n-\tu16 val;\n-\tint i;\n-\n-\tice_memset(&hw->tnl, 0, sizeof(hw->tnl), ICE_NONDMA_MEM);\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tif (!ice_seg)\n-\t\treturn;\n-\n-\tlabel_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state,\n-\t\t\t\t     &val);\n-\n-\twhile (label_name) {\n-\t\tif (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE)))\n-\t\t\t/* check for a tunnel entry */\n-\t\t\tice_add_tunnel_hint(hw, label_name, val);\n-\n-\t\t/* check for a dvm mode entry */\n-\t\telse if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE)))\n-\t\t\tice_add_dvm_hint(hw, val, true);\n-\n-\t\t/* check for a svm mode entry */\n-\t\telse if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE)))\n-\t\t\tice_add_dvm_hint(hw, val, false);\n-\n-\t\tlabel_name = ice_enum_labels(NULL, 0, &state, &val);\n-\t}\n-\n-\t/* Cache the appropriate boost TCAM entry pointers for tunnels */\n-\tfor (i = 0; i < hw->tnl.count; i++) {\n-\t\tice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr,\n-\t\t\t\t     &hw->tnl.tbl[i].boost_entry);\n-\t\tif (hw->tnl.tbl[i].boost_entry)\n-\t\t\thw->tnl.tbl[i].valid = true;\n-\t}\n-\n-\t/* Cache the appropriate boost TCAM entry pointers for DVM and SVM */\n-\tfor (i = 0; i < hw->dvm_upd.count; i++)\n-\t\tice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr,\n-\t\t\t\t     &hw->dvm_upd.tbl[i].boost_entry);\n-}\n-\n-/* Key creation */\n-\n-#define ICE_DC_KEY\t0x1\t/* don't care */\n-#define ICE_DC_KEYINV\t0x1\n-#define ICE_NM_KEY\t0x0\t/* never match */\n-#define ICE_NM_KEYINV\t0x0\n-#define ICE_0_KEY\t0x1\t/* match 0 */\n-#define ICE_0_KEYINV\t0x0\n-#define ICE_1_KEY\t0x0\t/* match 1 */\n-#define ICE_1_KEYINV\t0x1\n-\n-/**\n- * ice_gen_key_word - generate 16-bits of a key/mask word\n- * @val: the value\n- * @valid: valid bits mask (change only the valid bits)\n- * @dont_care: don't care mask\n- * @nvr_mtch: never match mask\n- * @key: pointer to an array of where the resulting key portion\n- * @key_inv: pointer to an array of where the resulting key invert portion\n- *\n- * This function generates 16-bits from a 8-bit value, an 8-bit don't care mask\n- * and an 8-bit never match mask. The 16-bits of output are divided into 8 bits\n- * of key and 8 bits of key invert.\n- *\n- *     '0' =    b01, always match a 0 bit\n- *     '1' =    b10, always match a 1 bit\n- *     '?' =    b11, don't care bit (always matches)\n- *     '~' =    b00, never match bit\n- *\n- * Input:\n- *          val:         b0  1  0  1  0  1\n- *          dont_care:   b0  0  1  1  0  0\n- *          never_mtch:  b0  0  0  0  1  1\n- *          ------------------------------\n- * Result:  key:        b01 10 11 11 00 00\n- */\n-static enum ice_status\n-ice_gen_key_word(u8 val, u8 valid, u8 dont_care, u8 nvr_mtch, u8 *key,\n-\t\t u8 *key_inv)\n-{\n-\tu8 in_key = *key, in_key_inv = *key_inv;\n-\tu8 i;\n-\n-\t/* 'dont_care' and 'nvr_mtch' masks cannot overlap */\n-\tif ((dont_care ^ nvr_mtch) != (dont_care | nvr_mtch))\n-\t\treturn ICE_ERR_CFG;\n-\n-\t*key = 0;\n-\t*key_inv = 0;\n-\n-\t/* encode the 8 bits into 8-bit key and 8-bit key invert */\n-\tfor (i = 0; i < 8; i++) {\n-\t\t*key >>= 1;\n-\t\t*key_inv >>= 1;\n-\n-\t\tif (!(valid & 0x1)) { /* change only valid bits */\n-\t\t\t*key |= (in_key & 0x1) << 7;\n-\t\t\t*key_inv |= (in_key_inv & 0x1) << 7;\n-\t\t} else if (dont_care & 0x1) { /* don't care bit */\n-\t\t\t*key |= ICE_DC_KEY << 7;\n-\t\t\t*key_inv |= ICE_DC_KEYINV << 7;\n-\t\t} else if (nvr_mtch & 0x1) { /* never match bit */\n-\t\t\t*key |= ICE_NM_KEY << 7;\n-\t\t\t*key_inv |= ICE_NM_KEYINV << 7;\n-\t\t} else if (val & 0x01) { /* exact 1 match */\n-\t\t\t*key |= ICE_1_KEY << 7;\n-\t\t\t*key_inv |= ICE_1_KEYINV << 7;\n-\t\t} else { /* exact 0 match */\n-\t\t\t*key |= ICE_0_KEY << 7;\n-\t\t\t*key_inv |= ICE_0_KEYINV << 7;\n-\t\t}\n-\n-\t\tdont_care >>= 1;\n-\t\tnvr_mtch >>= 1;\n-\t\tvalid >>= 1;\n-\t\tval >>= 1;\n-\t\tin_key >>= 1;\n-\t\tin_key_inv >>= 1;\n-\t}\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_bits_max_set - determine if the number of bits set is within a maximum\n- * @mask: pointer to the byte array which is the mask\n- * @size: the number of bytes in the mask\n- * @max: the max number of set bits\n- *\n- * This function determines if there are at most 'max' number of bits set in an\n- * array. Returns true if the number for bits set is <= max or will return false\n- * otherwise.\n- */\n-static bool ice_bits_max_set(const u8 *mask, u16 size, u16 max)\n-{\n-\tu16 count = 0;\n-\tu16 i;\n-\n-\t/* check each byte */\n-\tfor (i = 0; i < size; i++) {\n-\t\t/* if 0, go to next byte */\n-\t\tif (!mask[i])\n-\t\t\tcontinue;\n-\n-\t\t/* We know there is at least one set bit in this byte because of\n-\t\t * the above check; if we already have found 'max' number of\n-\t\t * bits set, then we can return failure now.\n-\t\t */\n-\t\tif (count == max)\n-\t\t\treturn false;\n-\n-\t\t/* count the bits in this byte, checking threshold */\n-\t\tcount += ice_hweight8(mask[i]);\n-\t\tif (count > max)\n-\t\t\treturn false;\n-\t}\n-\n-\treturn true;\n-}\n-\n-/**\n- * ice_set_key - generate a variable sized key with multiples of 16-bits\n- * @key: pointer to where the key will be stored\n- * @size: the size of the complete key in bytes (must be even)\n- * @val: array of 8-bit values that makes up the value portion of the key\n- * @upd: array of 8-bit masks that determine what key portion to update\n- * @dc: array of 8-bit masks that make up the don't care mask\n- * @nm: array of 8-bit masks that make up the never match mask\n- * @off: the offset of the first byte in the key to update\n- * @len: the number of bytes in the key update\n- *\n- * This function generates a key from a value, a don't care mask and a never\n- * match mask.\n- * upd, dc, and nm are optional parameters, and can be NULL:\n- *\tupd == NULL --> upd mask is all 1's (update all bits)\n- *\tdc == NULL --> dc mask is all 0's (no don't care bits)\n- *\tnm == NULL --> nm mask is all 0's (no never match bits)\n- */\n-enum ice_status\n-ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off,\n-\t    u16 len)\n-{\n-\tu16 half_size;\n-\tu16 i;\n-\n-\t/* size must be a multiple of 2 bytes. */\n-\tif (size % 2)\n-\t\treturn ICE_ERR_CFG;\n-\thalf_size = size / 2;\n-\n-\tif (off + len > half_size)\n-\t\treturn ICE_ERR_CFG;\n-\n-\t/* Make sure at most one bit is set in the never match mask. Having more\n-\t * than one never match mask bit set will cause HW to consume excessive\n-\t * power otherwise; this is a power management efficiency check.\n-\t */\n-#define ICE_NVR_MTCH_BITS_MAX\t1\n-\tif (nm && !ice_bits_max_set(nm, len, ICE_NVR_MTCH_BITS_MAX))\n-\t\treturn ICE_ERR_CFG;\n-\n-\tfor (i = 0; i < len; i++)\n-\t\tif (ice_gen_key_word(val[i], upd ? upd[i] : 0xff,\n-\t\t\t\t     dc ? dc[i] : 0, nm ? nm[i] : 0,\n-\t\t\t\t     key + off + i, key + half_size + off + i))\n-\t\t\treturn ICE_ERR_CFG;\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_acquire_global_cfg_lock\n- * @hw: pointer to the HW structure\n- * @access: access type (read or write)\n- *\n- * This function will request ownership of the global config lock for reading\n- * or writing of the package. When attempting to obtain write access, the\n- * caller must check for the following two return values:\n- *\n- * ICE_SUCCESS        - Means the caller has acquired the global config lock\n- *                      and can perform writing of the package.\n- * ICE_ERR_AQ_NO_WORK - Indicates another driver has already written the\n- *                      package or has found that no update was necessary; in\n- *                      this case, the caller can just skip performing any\n- *                      update of the package.\n- */\n-static enum ice_status\n-ice_acquire_global_cfg_lock(struct ice_hw *hw,\n-\t\t\t    enum ice_aq_res_access_type access)\n-{\n-\tenum ice_status status;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\tstatus = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access,\n-\t\t\t\t ICE_GLOBAL_CFG_LOCK_TIMEOUT);\n-\n-\tif (status == ICE_ERR_AQ_NO_WORK)\n-\t\tice_debug(hw, ICE_DBG_PKG, \"Global config lock: No work to do\\n\");\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_release_global_cfg_lock\n- * @hw: pointer to the HW structure\n- *\n- * This function will release the global config lock.\n- */\n-static void ice_release_global_cfg_lock(struct ice_hw *hw)\n-{\n-\tice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID);\n-}\n-\n-/**\n- * ice_acquire_change_lock\n- * @hw: pointer to the HW structure\n- * @access: access type (read or write)\n- *\n- * This function will request ownership of the change lock.\n- */\n-enum ice_status\n-ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access)\n-{\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\treturn ice_acquire_res(hw, ICE_CHANGE_LOCK_RES_ID, access,\n-\t\t\t       ICE_CHANGE_LOCK_TIMEOUT);\n-}\n-\n-/**\n- * ice_release_change_lock\n- * @hw: pointer to the HW structure\n- *\n- * This function will release the change lock using the proper Admin Command.\n- */\n-void ice_release_change_lock(struct ice_hw *hw)\n-{\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\tice_release_res(hw, ICE_CHANGE_LOCK_RES_ID);\n-}\n-\n-/**\n- * ice_aq_download_pkg\n- * @hw: pointer to the hardware structure\n- * @pkg_buf: the package buffer to transfer\n- * @buf_size: the size of the package buffer\n- * @last_buf: last buffer indicator\n- * @error_offset: returns error offset\n- * @error_info: returns error information\n- * @cd: pointer to command details structure or NULL\n- *\n- * Download Package (0x0C40)\n- */\n-static enum ice_status\n-ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,\n-\t\t    u16 buf_size, bool last_buf, u32 *error_offset,\n-\t\t    u32 *error_info, struct ice_sq_cd *cd)\n-{\n-\tstruct ice_aqc_download_pkg *cmd;\n-\tstruct ice_aq_desc desc;\n-\tenum ice_status status;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\tif (error_offset)\n-\t\t*error_offset = 0;\n-\tif (error_info)\n-\t\t*error_info = 0;\n-\n-\tcmd = &desc.params.download_pkg;\n-\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg);\n-\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n-\n-\tif (last_buf)\n-\t\tcmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;\n-\n-\tstatus = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n-\tif (status == ICE_ERR_AQ_ERROR) {\n-\t\t/* Read error from buffer only when the FW returned an error */\n-\t\tstruct ice_aqc_download_pkg_resp *resp;\n-\n-\t\tresp = (struct ice_aqc_download_pkg_resp *)pkg_buf;\n-\t\tif (error_offset)\n-\t\t\t*error_offset = LE32_TO_CPU(resp->error_offset);\n-\t\tif (error_info)\n-\t\t\t*error_info = LE32_TO_CPU(resp->error_info);\n-\t}\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_aq_upload_section\n- * @hw: pointer to the hardware structure\n- * @pkg_buf: the package buffer which will receive the section\n- * @buf_size: the size of the package buffer\n- * @cd: pointer to command details structure or NULL\n- *\n- * Upload Section (0x0C41)\n- */\n-enum ice_status\n-ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,\n-\t\t      u16 buf_size, struct ice_sq_cd *cd)\n-{\n-\tstruct ice_aq_desc desc;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section);\n-\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n-\n-\treturn ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n-}\n-\n-/**\n- * ice_aq_update_pkg\n- * @hw: pointer to the hardware structure\n- * @pkg_buf: the package cmd buffer\n- * @buf_size: the size of the package cmd buffer\n- * @last_buf: last buffer indicator\n- * @error_offset: returns error offset\n- * @error_info: returns error information\n- * @cd: pointer to command details structure or NULL\n- *\n- * Update Package (0x0C42)\n- */\n-static enum ice_status\n-ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, u16 buf_size,\n-\t\t  bool last_buf, u32 *error_offset, u32 *error_info,\n-\t\t  struct ice_sq_cd *cd)\n-{\n-\tstruct ice_aqc_download_pkg *cmd;\n-\tstruct ice_aq_desc desc;\n-\tenum ice_status status;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\tif (error_offset)\n-\t\t*error_offset = 0;\n-\tif (error_info)\n-\t\t*error_info = 0;\n-\n-\tcmd = &desc.params.download_pkg;\n-\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg);\n-\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n-\n-\tif (last_buf)\n-\t\tcmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;\n-\n-\tstatus = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);\n-\tif (status == ICE_ERR_AQ_ERROR) {\n-\t\t/* Read error from buffer only when the FW returned an error */\n-\t\tstruct ice_aqc_download_pkg_resp *resp;\n-\n-\t\tresp = (struct ice_aqc_download_pkg_resp *)pkg_buf;\n-\t\tif (error_offset)\n-\t\t\t*error_offset = LE32_TO_CPU(resp->error_offset);\n-\t\tif (error_info)\n-\t\t\t*error_info = LE32_TO_CPU(resp->error_info);\n-\t}\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_find_seg_in_pkg\n- * @hw: pointer to the hardware structure\n- * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK)\n- * @pkg_hdr: pointer to the package header to be searched\n- *\n- * This function searches a package file for a particular segment type. On\n- * success it returns a pointer to the segment header, otherwise it will\n- * return NULL.\n- */\n-static struct ice_generic_seg_hdr *\n-ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,\n-\t\t    struct ice_pkg_hdr *pkg_hdr)\n-{\n-\tu32 i;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\tice_debug(hw, ICE_DBG_PKG, \"Package format version: %d.%d.%d.%d\\n\",\n-\t\t  pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor,\n-\t\t  pkg_hdr->pkg_format_ver.update,\n-\t\t  pkg_hdr->pkg_format_ver.draft);\n-\n-\t/* Search all package segments for the requested segment type */\n-\tfor (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {\n-\t\tstruct ice_generic_seg_hdr *seg;\n-\n-\t\tseg = (struct ice_generic_seg_hdr *)\n-\t\t\t((u8 *)pkg_hdr + LE32_TO_CPU(pkg_hdr->seg_offset[i]));\n-\n-\t\tif (LE32_TO_CPU(seg->seg_type) == seg_type)\n-\t\t\treturn seg;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-/**\n- * ice_update_pkg_no_lock\n- * @hw: pointer to the hardware structure\n- * @bufs: pointer to an array of buffers\n- * @count: the number of buffers in the array\n- */\n-static enum ice_status\n-ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n-{\n-\tenum ice_status status = ICE_SUCCESS;\n-\tu32 i;\n-\n-\tfor (i = 0; i < count; i++) {\n-\t\tstruct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i);\n-\t\tbool last = ((i + 1) == count);\n-\t\tu32 offset, info;\n-\n-\t\tstatus = ice_aq_update_pkg(hw, bh, LE16_TO_CPU(bh->data_end),\n-\t\t\t\t\t   last, &offset, &info, NULL);\n-\n-\t\tif (status) {\n-\t\t\tice_debug(hw, ICE_DBG_PKG, \"Update pkg failed: err %d off %d inf %d\\n\",\n-\t\t\t\t  status, offset, info);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_update_pkg\n- * @hw: pointer to the hardware structure\n- * @bufs: pointer to an array of buffers\n- * @count: the number of buffers in the array\n- *\n- * Obtains change lock and updates package.\n- */\n-enum ice_status\n-ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n-{\n-\tenum ice_status status;\n-\n-\tstatus = ice_acquire_change_lock(hw, ICE_RES_WRITE);\n-\tif (status)\n-\t\treturn status;\n-\n-\tstatus = ice_update_pkg_no_lock(hw, bufs, count);\n-\n-\tice_release_change_lock(hw);\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_dwnld_cfg_bufs\n- * @hw: pointer to the hardware structure\n- * @bufs: pointer to an array of buffers\n- * @count: the number of buffers in the array\n- *\n- * Obtains global config lock and downloads the package configuration buffers\n- * to the firmware. Metadata buffers are skipped, and the first metadata buffer\n- * found indicates that the rest of the buffers are all metadata buffers.\n- */\n-static enum ice_status\n-ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)\n-{\n-\tenum ice_status status;\n-\tstruct ice_buf_hdr *bh;\n-\tu32 offset, info, i;\n-\n-\tif (!bufs || !count)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\t/* If the first buffer's first section has its metadata bit set\n-\t * then there are no buffers to be downloaded, and the operation is\n-\t * considered a success.\n-\t */\n-\tbh = (struct ice_buf_hdr *)bufs;\n-\tif (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)\n-\t\treturn ICE_SUCCESS;\n-\n-\t/* reset pkg_dwnld_status in case this function is called in the\n-\t * reset/rebuild flow\n-\t */\n-\thw->pkg_dwnld_status = ICE_AQ_RC_OK;\n-\n-\tstatus = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);\n-\tif (status) {\n-\t\tif (status == ICE_ERR_AQ_NO_WORK)\n-\t\t\thw->pkg_dwnld_status = ICE_AQ_RC_EEXIST;\n-\t\telse\n-\t\t\thw->pkg_dwnld_status = hw->adminq.sq_last_status;\n-\t\treturn status;\n-\t}\n-\n-\tfor (i = 0; i < count; i++) {\n-\t\tbool last = ((i + 1) == count);\n-\n-\t\tif (!last) {\n-\t\t\t/* check next buffer for metadata flag */\n-\t\t\tbh = (struct ice_buf_hdr *)(bufs + i + 1);\n-\n-\t\t\t/* A set metadata flag in the next buffer will signal\n-\t\t\t * that the current buffer will be the last buffer\n-\t\t\t * downloaded\n-\t\t\t */\n-\t\t\tif (LE16_TO_CPU(bh->section_count))\n-\t\t\t\tif (LE32_TO_CPU(bh->section_entry[0].type) &\n-\t\t\t\t    ICE_METADATA_BUF)\n-\t\t\t\t\tlast = true;\n-\t\t}\n-\n-\t\tbh = (struct ice_buf_hdr *)(bufs + i);\n-\n-\t\tstatus = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last,\n-\t\t\t\t\t     &offset, &info, NULL);\n-\n-\t\t/* Save AQ status from download package */\n-\t\thw->pkg_dwnld_status = hw->adminq.sq_last_status;\n-\t\tif (status) {\n-\t\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg download failed: err %d off %d inf %d\\n\",\n-\t\t\t\t  status, offset, info);\n-\t\t\tbreak;\n-\t\t}\n-\n-\t\tif (last)\n-\t\t\tbreak;\n-\t}\n-\n-\tif (!status) {\n-\t\tstatus = ice_set_vlan_mode(hw);\n-\t\tif (status)\n-\t\t\tice_debug(hw, ICE_DBG_PKG, \"Failed to set VLAN mode: err %d\\n\",\n-\t\t\t\t  status);\n-\t}\n-\n-\tice_release_global_cfg_lock(hw);\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_aq_get_pkg_info_list\n- * @hw: pointer to the hardware structure\n- * @pkg_info: the buffer which will receive the information list\n- * @buf_size: the size of the pkg_info information buffer\n- * @cd: pointer to command details structure or NULL\n- *\n- * Get Package Info List (0x0C43)\n- */\n-static enum ice_status\n-ice_aq_get_pkg_info_list(struct ice_hw *hw,\n-\t\t\t struct ice_aqc_get_pkg_info_resp *pkg_info,\n-\t\t\t u16 buf_size, struct ice_sq_cd *cd)\n-{\n-\tstruct ice_aq_desc desc;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\tice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list);\n-\n-\treturn ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd);\n-}\n-\n-/**\n- * ice_download_pkg\n- * @hw: pointer to the hardware structure\n- * @ice_seg: pointer to the segment of the package to be downloaded\n- *\n- * Handles the download of a complete package.\n- */\n-static enum ice_status\n-ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)\n-{\n-\tstruct ice_buf_table *ice_buf_tbl;\n-\tenum ice_status status;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\tice_debug(hw, ICE_DBG_PKG, \"Segment format version: %d.%d.%d.%d\\n\",\n-\t\t  ice_seg->hdr.seg_format_ver.major,\n-\t\t  ice_seg->hdr.seg_format_ver.minor,\n-\t\t  ice_seg->hdr.seg_format_ver.update,\n-\t\t  ice_seg->hdr.seg_format_ver.draft);\n-\n-\tice_debug(hw, ICE_DBG_PKG, \"Seg: type 0x%X, size %d, name %s\\n\",\n-\t\t  LE32_TO_CPU(ice_seg->hdr.seg_type),\n-\t\t  LE32_TO_CPU(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id);\n-\n-\tice_buf_tbl = ice_find_buf_table(ice_seg);\n-\n-\tice_debug(hw, ICE_DBG_PKG, \"Seg buf count: %d\\n\",\n-\t\t  LE32_TO_CPU(ice_buf_tbl->buf_count));\n-\n-\tstatus = ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array,\n-\t\t\t\t    LE32_TO_CPU(ice_buf_tbl->buf_count));\n-\n-\tice_post_pkg_dwnld_vlan_mode_cfg(hw);\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_init_pkg_info\n- * @hw: pointer to the hardware structure\n- * @pkg_hdr: pointer to the driver's package hdr\n- *\n- * Saves off the package details into the HW structure.\n- */\n-static enum ice_status\n-ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)\n-{\n-\tstruct ice_generic_seg_hdr *seg_hdr;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\tif (!pkg_hdr)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\thw->pkg_seg_id = SEGMENT_TYPE_ICE_E810;\n-\n-\tice_debug(hw, ICE_DBG_INIT, \"Pkg using segment id: 0x%08X\\n\",\n-\t\t  hw->pkg_seg_id);\n-\n-\tseg_hdr = (struct ice_generic_seg_hdr *)\n-\t\tice_find_seg_in_pkg(hw, hw->pkg_seg_id, pkg_hdr);\n-\tif (seg_hdr) {\n-\t\tstruct ice_meta_sect *meta;\n-\t\tstruct ice_pkg_enum state;\n-\n-\t\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\t\t/* Get package information from the Metadata Section */\n-\t\tmeta = (struct ice_meta_sect *)\n-\t\t\tice_pkg_enum_section((struct ice_seg *)seg_hdr, &state,\n-\t\t\t\t\t     ICE_SID_METADATA);\n-\t\tif (!meta) {\n-\t\t\tice_debug(hw, ICE_DBG_INIT, \"Did not find ice metadata section in package\\n\");\n-\t\t\treturn ICE_ERR_CFG;\n-\t\t}\n-\n-\t\thw->pkg_ver = meta->ver;\n-\t\tice_memcpy(hw->pkg_name, meta->name, sizeof(meta->name),\n-\t\t\t   ICE_NONDMA_TO_NONDMA);\n-\n-\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg: %d.%d.%d.%d, %s\\n\",\n-\t\t\t  meta->ver.major, meta->ver.minor, meta->ver.update,\n-\t\t\t  meta->ver.draft, meta->name);\n-\n-\t\thw->ice_seg_fmt_ver = seg_hdr->seg_format_ver;\n-\t\tice_memcpy(hw->ice_seg_id, seg_hdr->seg_id,\n-\t\t\t   sizeof(hw->ice_seg_id), ICE_NONDMA_TO_NONDMA);\n-\n-\t\tice_debug(hw, ICE_DBG_PKG, \"Ice Seg: %d.%d.%d.%d, %s\\n\",\n-\t\t\t  seg_hdr->seg_format_ver.major,\n-\t\t\t  seg_hdr->seg_format_ver.minor,\n-\t\t\t  seg_hdr->seg_format_ver.update,\n-\t\t\t  seg_hdr->seg_format_ver.draft,\n-\t\t\t  seg_hdr->seg_id);\n-\t} else {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"Did not find ice segment in driver package\\n\");\n-\t\treturn ICE_ERR_CFG;\n-\t}\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_get_pkg_info\n- * @hw: pointer to the hardware structure\n- *\n- * Store details of the package currently loaded in HW into the HW structure.\n- */\n-static enum ice_status ice_get_pkg_info(struct ice_hw *hw)\n-{\n-\tstruct ice_aqc_get_pkg_info_resp *pkg_info;\n-\tenum ice_status status;\n-\tu16 size;\n-\tu32 i;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\tsize = ice_struct_size(pkg_info, pkg_info, ICE_PKG_CNT);\n-\tpkg_info = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);\n-\tif (!pkg_info)\n-\t\treturn ICE_ERR_NO_MEMORY;\n-\n-\tstatus = ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL);\n-\tif (status)\n-\t\tgoto init_pkg_free_alloc;\n-\n-\tfor (i = 0; i < LE32_TO_CPU(pkg_info->count); i++) {\n-#define ICE_PKG_FLAG_COUNT\t4\n-\t\tchar flags[ICE_PKG_FLAG_COUNT + 1] = { 0 };\n-\t\tu8 place = 0;\n-\n-\t\tif (pkg_info->pkg_info[i].is_active) {\n-\t\t\tflags[place++] = 'A';\n-\t\t\thw->active_pkg_ver = pkg_info->pkg_info[i].ver;\n-\t\t\thw->active_track_id =\n-\t\t\t\tLE32_TO_CPU(pkg_info->pkg_info[i].track_id);\n-\t\t\tice_memcpy(hw->active_pkg_name,\n-\t\t\t\t   pkg_info->pkg_info[i].name,\n-\t\t\t\t   sizeof(pkg_info->pkg_info[i].name),\n-\t\t\t\t   ICE_NONDMA_TO_NONDMA);\n-\t\t\thw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm;\n-\t\t}\n-\t\tif (pkg_info->pkg_info[i].is_active_at_boot)\n-\t\t\tflags[place++] = 'B';\n-\t\tif (pkg_info->pkg_info[i].is_modified)\n-\t\t\tflags[place++] = 'M';\n-\t\tif (pkg_info->pkg_info[i].is_in_nvm)\n-\t\t\tflags[place++] = 'N';\n-\n-\t\tice_debug(hw, ICE_DBG_PKG, \"Pkg[%d]: %d.%d.%d.%d,%s,%s\\n\",\n-\t\t\t  i, pkg_info->pkg_info[i].ver.major,\n-\t\t\t  pkg_info->pkg_info[i].ver.minor,\n-\t\t\t  pkg_info->pkg_info[i].ver.update,\n-\t\t\t  pkg_info->pkg_info[i].ver.draft,\n-\t\t\t  pkg_info->pkg_info[i].name, flags);\n-\t}\n-\n-init_pkg_free_alloc:\n-\tice_free(hw, pkg_info);\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_verify_pkg - verify package\n- * @pkg: pointer to the package buffer\n- * @len: size of the package buffer\n- *\n- * Verifies various attributes of the package file, including length, format\n- * version, and the requirement of at least one segment.\n- */\n-static enum ice_status ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)\n-{\n-\tu32 seg_count;\n-\tu32 i;\n-\n-\tif (len < ice_struct_size(pkg, seg_offset, 1))\n-\t\treturn ICE_ERR_BUF_TOO_SHORT;\n-\n-\tif (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||\n-\t    pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||\n-\t    pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||\n-\t    pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)\n-\t\treturn ICE_ERR_CFG;\n-\n-\t/* pkg must have at least one segment */\n-\tseg_count = LE32_TO_CPU(pkg->seg_count);\n-\tif (seg_count < 1)\n-\t\treturn ICE_ERR_CFG;\n-\n-\t/* make sure segment array fits in package length */\n-\tif (len < ice_struct_size(pkg, seg_offset, seg_count))\n-\t\treturn ICE_ERR_BUF_TOO_SHORT;\n-\n-\t/* all segments must fit within length */\n-\tfor (i = 0; i < seg_count; i++) {\n-\t\tu32 off = LE32_TO_CPU(pkg->seg_offset[i]);\n-\t\tstruct ice_generic_seg_hdr *seg;\n-\n-\t\t/* segment header must fit */\n-\t\tif (len < off + sizeof(*seg))\n-\t\t\treturn ICE_ERR_BUF_TOO_SHORT;\n-\n-\t\tseg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);\n-\n-\t\t/* segment body must fit */\n-\t\tif (len < off + LE32_TO_CPU(seg->seg_size))\n-\t\t\treturn ICE_ERR_BUF_TOO_SHORT;\n-\t}\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_free_seg - free package segment pointer\n- * @hw: pointer to the hardware structure\n- *\n- * Frees the package segment pointer in the proper manner, depending on if the\n- * segment was allocated or just the passed in pointer was stored.\n- */\n-void ice_free_seg(struct ice_hw *hw)\n-{\n-\tif (hw->pkg_copy) {\n-\t\tice_free(hw, hw->pkg_copy);\n-\t\thw->pkg_copy = NULL;\n-\t\thw->pkg_size = 0;\n-\t}\n-\thw->seg = NULL;\n-}\n-\n-/**\n- * ice_init_pkg_regs - initialize additional package registers\n- * @hw: pointer to the hardware structure\n- */\n-static void ice_init_pkg_regs(struct ice_hw *hw)\n-{\n-#define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF\n-#define ICE_SW_BLK_INP_MASK_H 0x0000FFFF\n-#define ICE_SW_BLK_IDX\t0\n-\tif (hw->dcf_enabled)\n-\t\treturn;\n-\n-\t/* setup Switch block input mask, which is 48-bits in two parts */\n-\twr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L);\n-\twr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H);\n-}\n-\n-/**\n- * ice_chk_pkg_version - check package version for compatibility with driver\n- * @pkg_ver: pointer to a version structure to check\n- *\n- * Check to make sure that the package about to be downloaded is compatible with\n- * the driver. To be compatible, the major and minor components of the package\n- * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR\n- * definitions.\n- */\n-static enum ice_status ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)\n-{\n-\tif (pkg_ver->major != ICE_PKG_SUPP_VER_MAJ ||\n-\t    pkg_ver->minor != ICE_PKG_SUPP_VER_MNR)\n-\t\treturn ICE_ERR_NOT_SUPPORTED;\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_chk_pkg_compat\n- * @hw: pointer to the hardware structure\n- * @ospkg: pointer to the package hdr\n- * @seg: pointer to the package segment hdr\n- *\n- * This function checks the package version compatibility with driver and NVM\n- */\n-static enum ice_status\n-ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,\n-\t\t   struct ice_seg **seg)\n-{\n-\tstruct ice_aqc_get_pkg_info_resp *pkg;\n-\tenum ice_status status;\n-\tu16 size;\n-\tu32 i;\n-\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n-\n-\t/* Check package version compatibility */\n-\tstatus = ice_chk_pkg_version(&hw->pkg_ver);\n-\tif (status) {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"Package version check failed.\\n\");\n-\t\treturn status;\n-\t}\n-\n-\t/* find ICE segment in given package */\n-\t*seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, hw->pkg_seg_id,\n-\t\t\t\t\t\t     ospkg);\n-\tif (!*seg) {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"no ice segment in package.\\n\");\n-\t\treturn ICE_ERR_CFG;\n-\t}\n-\n-\t/* Check if FW is compatible with the OS package */\n-\tsize = ice_struct_size(pkg, pkg_info, ICE_PKG_CNT);\n-\tpkg = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);\n-\tif (!pkg)\n-\t\treturn ICE_ERR_NO_MEMORY;\n-\n-\tstatus = ice_aq_get_pkg_info_list(hw, pkg, size, NULL);\n-\tif (status)\n-\t\tgoto fw_ddp_compat_free_alloc;\n-\n-\tfor (i = 0; i < LE32_TO_CPU(pkg->count); i++) {\n-\t\t/* loop till we find the NVM package */\n-\t\tif (!pkg->pkg_info[i].is_in_nvm)\n-\t\t\tcontinue;\n-\t\tif ((*seg)->hdr.seg_format_ver.major !=\n-\t\t\tpkg->pkg_info[i].ver.major ||\n-\t\t    (*seg)->hdr.seg_format_ver.minor >\n-\t\t\tpkg->pkg_info[i].ver.minor) {\n-\t\t\tstatus = ICE_ERR_FW_DDP_MISMATCH;\n-\t\t\tice_debug(hw, ICE_DBG_INIT, \"OS package is not compatible with NVM.\\n\");\n-\t\t}\n-\t\t/* done processing NVM package so break */\n-\t\tbreak;\n-\t}\n-fw_ddp_compat_free_alloc:\n-\tice_free(hw, pkg);\n-\treturn status;\n-}\n-\n-/**\n- * ice_sw_fv_handler\n- * @sect_type: section type\n- * @section: pointer to section\n- * @index: index of the field vector entry to be returned\n- * @offset: ptr to variable that receives the offset in the field vector table\n- *\n- * This is a callback function that can be passed to ice_pkg_enum_entry.\n- * This function treats the given section as of type ice_sw_fv_section and\n- * enumerates offset field. \"offset\" is an index into the field vector table.\n- */\n-static void *\n-ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)\n-{\n-\tstruct ice_sw_fv_section *fv_section =\n-\t\t(struct ice_sw_fv_section *)section;\n-\n-\tif (!section || sect_type != ICE_SID_FLD_VEC_SW)\n-\t\treturn NULL;\n-\tif (index >= LE16_TO_CPU(fv_section->count))\n-\t\treturn NULL;\n-\tif (offset)\n-\t\t/* \"index\" passed in to this function is relative to a given\n-\t\t * 4k block. To get to the true index into the field vector\n-\t\t * table need to add the relative index to the base_offset\n-\t\t * field of this section\n-\t\t */\n-\t\t*offset = LE16_TO_CPU(fv_section->base_offset) + index;\n-\treturn fv_section->fv + index;\n-}\n-\n-/**\n- * ice_get_prof_index_max - get the max profile index for used profile\n- * @hw: pointer to the HW struct\n- *\n- * Calling this function will get the max profile index for used profile\n- * and store the index number in struct ice_switch_info *switch_info\n- * in hw for following use.\n- */\n-static int ice_get_prof_index_max(struct ice_hw *hw)\n-{\n-\tu16 prof_index = 0, j, max_prof_index = 0;\n-\tstruct ice_pkg_enum state;\n-\tstruct ice_seg *ice_seg;\n-\tbool flag = false;\n-\tstruct ice_fv *fv;\n-\tu32 offset;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tif (!hw->seg)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\tice_seg = hw->seg;\n-\n-\tdo {\n-\t\tfv = (struct ice_fv *)\n-\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n-\t\t\t\t\t   &offset, ice_sw_fv_handler);\n-\t\tif (!fv)\n-\t\t\tbreak;\n-\t\tice_seg = NULL;\n-\n-\t\t/* in the profile that not be used, the prot_id is set to 0xff\n-\t\t * and the off is set to 0x1ff for all the field vectors.\n-\t\t */\n-\t\tfor (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)\n-\t\t\tif (fv->ew[j].prot_id != ICE_PROT_INVALID ||\n-\t\t\t    fv->ew[j].off != ICE_FV_OFFSET_INVAL)\n-\t\t\t\tflag = true;\n-\t\tif (flag && prof_index > max_prof_index)\n-\t\t\tmax_prof_index = prof_index;\n-\n-\t\tprof_index++;\n-\t\tflag = false;\n-\t} while (fv);\n-\n-\thw->switch_info->max_used_prof_index = max_prof_index;\n-\n-\treturn ICE_SUCCESS;\n-}\n-\n-/**\n- * ice_init_pkg - initialize/download package\n- * @hw: pointer to the hardware structure\n- * @buf: pointer to the package buffer\n- * @len: size of the package buffer\n- *\n- * This function initializes a package. The package contains HW tables\n- * required to do packet processing. First, the function extracts package\n- * information such as version. Then it finds the ice configuration segment\n- * within the package; this function then saves a copy of the segment pointer\n- * within the supplied package buffer. Next, the function will cache any hints\n- * from the package, followed by downloading the package itself. Note, that if\n- * a previous PF driver has already downloaded the package successfully, then\n- * the current driver will not have to download the package again.\n- *\n- * The local package contents will be used to query default behavior and to\n- * update specific sections of the HW's version of the package (e.g. to update\n- * the parse graph to understand new protocols).\n- *\n- * This function stores a pointer to the package buffer memory, and it is\n- * expected that the supplied buffer will not be freed immediately. If the\n- * package buffer needs to be freed, such as when read from a file, use\n- * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this\n- * case.\n- */\n-enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)\n-{\n-\tstruct ice_pkg_hdr *pkg;\n-\tenum ice_status status;\n-\tstruct ice_seg *seg;\n-\n-\tif (!buf || !len)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\tpkg = (struct ice_pkg_hdr *)buf;\n-\tstatus = ice_verify_pkg(pkg, len);\n-\tif (status) {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"failed to verify pkg (err: %d)\\n\",\n-\t\t\t  status);\n-\t\treturn status;\n-\t}\n-\n-\t/* initialize package info */\n-\tstatus = ice_init_pkg_info(hw, pkg);\n-\tif (status)\n-\t\treturn status;\n-\n-\t/* before downloading the package, check package version for\n-\t * compatibility with driver\n-\t */\n-\tstatus = ice_chk_pkg_compat(hw, pkg, &seg);\n-\tif (status)\n-\t\treturn status;\n-\n-\t/* initialize package hints and then download package */\n-\tice_init_pkg_hints(hw, seg);\n-\tstatus = ice_download_pkg(hw, seg);\n-\tif (status == ICE_ERR_AQ_NO_WORK) {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"package previously loaded - no work.\\n\");\n-\t\tstatus = ICE_SUCCESS;\n-\t}\n-\n-\t/* Get information on the package currently loaded in HW, then make sure\n-\t * the driver is compatible with this version.\n-\t */\n-\tif (!status) {\n-\t\tstatus = ice_get_pkg_info(hw);\n-\t\tif (!status)\n-\t\t\tstatus = ice_chk_pkg_version(&hw->active_pkg_ver);\n-\t}\n-\n-\tif (!status) {\n-\t\thw->seg = seg;\n-\t\t/* on successful package download update other required\n-\t\t * registers to support the package and fill HW tables\n-\t\t * with package content.\n-\t\t */\n-\t\tice_init_pkg_regs(hw);\n-\t\tice_fill_blk_tbls(hw);\n-\t\tice_fill_hw_ptype(hw);\n-\t\tice_get_prof_index_max(hw);\n-\t} else {\n-\t\tice_debug(hw, ICE_DBG_INIT, \"package load failed, %d\\n\",\n-\t\t\t  status);\n-\t}\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_copy_and_init_pkg - initialize/download a copy of the package\n- * @hw: pointer to the hardware structure\n- * @buf: pointer to the package buffer\n- * @len: size of the package buffer\n- *\n- * This function copies the package buffer, and then calls ice_init_pkg() to\n- * initialize the copied package contents.\n- *\n- * The copying is necessary if the package buffer supplied is constant, or if\n- * the memory may disappear shortly after calling this function.\n- *\n- * If the package buffer resides in the data segment and can be modified, the\n- * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg().\n- *\n- * However, if the package buffer needs to be copied first, such as when being\n- * read from a file, the caller should use ice_copy_and_init_pkg().\n- *\n- * This function will first copy the package buffer, before calling\n- * ice_init_pkg(). The caller is free to immediately destroy the original\n- * package buffer, as the new copy will be managed by this function and\n- * related routines.\n- */\n-enum ice_status ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len)\n-{\n-\tenum ice_status status;\n-\tu8 *buf_copy;\n-\n-\tif (!buf || !len)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\tbuf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA);\n-\n-\tstatus = ice_init_pkg(hw, buf_copy, len);\n-\tif (status) {\n-\t\t/* Free the copy, since we failed to initialize the package */\n-\t\tice_free(hw, buf_copy);\n-\t} else {\n-\t\t/* Track the copied pkg so we can free it later */\n-\t\thw->pkg_copy = buf_copy;\n-\t\thw->pkg_size = len;\n-\t}\n-\n-\treturn status;\n-}\n-\n-/**\n- * ice_pkg_buf_alloc\n- * @hw: pointer to the HW structure\n- *\n- * Allocates a package buffer and returns a pointer to the buffer header.\n- * Note: all package contents must be in Little Endian form.\n- */\n-static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)\n-{\n-\tstruct ice_buf_build *bld;\n-\tstruct ice_buf_hdr *buf;\n-\n-\tbld = (struct ice_buf_build *)ice_malloc(hw, sizeof(*bld));\n-\tif (!bld)\n-\t\treturn NULL;\n-\n-\tbuf = (struct ice_buf_hdr *)bld;\n-\tbuf->data_end = CPU_TO_LE16(offsetof(struct ice_buf_hdr,\n-\t\t\t\t\t     section_entry));\n-\treturn bld;\n-}\n-\n-/**\n- * ice_get_sw_prof_type - determine switch profile type\n- * @hw: pointer to the HW structure\n- * @fv: pointer to the switch field vector\n- */\n-static enum ice_prof_type\n-ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)\n-{\n-\tu16 i;\n-\tbool valid_prof = false;\n-\n-\tfor (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {\n-\t\tif (fv->ew[i].off != ICE_NAN_OFFSET)\n-\t\t\tvalid_prof = true;\n-\n-\t\t/* UDP tunnel will have UDP_OF protocol ID and VNI offset */\n-\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&\n-\t\t    fv->ew[i].off == ICE_VNI_OFFSET)\n-\t\t\treturn ICE_PROF_TUN_UDP;\n-\n-\t\t/* GRE tunnel will have GRE protocol */\n-\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)\n-\t\t\treturn ICE_PROF_TUN_GRE;\n-\n-\t\t/* PPPOE tunnel will have PPPOE protocol */\n-\t\tif (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE)\n-\t\t\treturn ICE_PROF_TUN_PPPOE;\n-\t}\n-\n-\treturn valid_prof ? ICE_PROF_NON_TUN : ICE_PROF_INVALID;\n-}\n-\n-/**\n- * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type\n- * @hw: pointer to hardware structure\n- * @req_profs: type of profiles requested\n- * @bm: pointer to memory for returning the bitmap of field vectors\n- */\n-void\n-ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,\n-\t\t     ice_bitmap_t *bm)\n-{\n-\tstruct ice_pkg_enum state;\n-\tstruct ice_seg *ice_seg;\n-\tstruct ice_fv *fv;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\tice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);\n-\tice_seg = hw->seg;\n-\tdo {\n-\t\tenum ice_prof_type prof_type;\n-\t\tu32 offset;\n-\n-\t\tfv = (struct ice_fv *)\n-\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n-\t\t\t\t\t   &offset, ice_sw_fv_handler);\n-\t\tice_seg = NULL;\n-\n-\t\tif (fv) {\n-\t\t\t/* Determine field vector type */\n-\t\t\tprof_type = ice_get_sw_prof_type(hw, fv);\n-\n-\t\t\tif (req_profs & prof_type)\n-\t\t\t\tice_set_bit((u16)offset, bm);\n-\t\t}\n-\t} while (fv);\n-}\n-\n-/**\n- * ice_get_sw_fv_list\n+ * ice_add_tunnel_hint\n  * @hw: pointer to the HW structure\n- * @prot_ids: field vector to search for with a given protocol ID\n- * @ids_cnt: lookup/protocol count\n- * @bm: bitmap of field vectors to consider\n- * @fv_list: Head of a list\n- *\n- * Finds all the field vector entries from switch block that contain\n- * a given protocol ID and returns a list of structures of type\n- * \"ice_sw_fv_list_entry\". Every structure in the list has a field vector\n- * definition and profile ID information\n- * NOTE: The caller of the function is responsible for freeing the memory\n- * allocated for every list entry.\n+ * @label_name: label text\n+ * @val: value of the tunnel port boost entry\n  */\n-enum ice_status\n-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,\n-\t\t   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)\n+void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val)\n {\n-\tstruct ice_sw_fv_list_entry *fvl;\n-\tstruct ice_sw_fv_list_entry *tmp;\n-\tstruct ice_pkg_enum state;\n-\tstruct ice_seg *ice_seg;\n-\tstruct ice_fv *fv;\n-\tu32 offset;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tif (!ids_cnt || !hw->seg)\n-\t\treturn ICE_ERR_PARAM;\n-\n-\tice_seg = hw->seg;\n-\tdo {\n+\tif (hw->tnl.count < ICE_TUNNEL_MAX_ENTRIES) {\n \t\tu16 i;\n \n-\t\tfv = (struct ice_fv *)\n-\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n-\t\t\t\t\t   &offset, ice_sw_fv_handler);\n-\t\tif (!fv)\n-\t\t\tbreak;\n-\t\tice_seg = NULL;\n-\n-\t\t/* If field vector is not in the bitmap list, then skip this\n-\t\t * profile.\n-\t\t */\n-\t\tif (!ice_is_bit_set(bm, (u16)offset))\n-\t\t\tcontinue;\n+\t\tfor (i = 0; tnls[i].type != TNL_LAST; i++) {\n+\t\t\tsize_t len = strlen(tnls[i].label_prefix);\n \n-\t\tfor (i = 0; i < ids_cnt; i++) {\n-\t\t\tint j;\n+\t\t\t/* Look for matching label start, before continuing */\n+\t\t\tif (strncmp(label_name, tnls[i].label_prefix, len))\n+\t\t\t\tcontinue;\n \n-\t\t\t/* This code assumes that if a switch field vector line\n-\t\t\t * has a matching protocol, then this line will contain\n-\t\t\t * the entries necessary to represent every field in\n-\t\t\t * that protocol header.\n+\t\t\t/* Make sure this label matches our PF. Note that the PF\n+\t\t\t * character ('0' - '7') will be located where our\n+\t\t\t * prefix string's null terminator is located.\n \t\t\t */\n-\t\t\tfor (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)\n-\t\t\t\tif (fv->ew[j].prot_id == prot_ids[i])\n-\t\t\t\t\tbreak;\n-\t\t\tif (j >= hw->blk[ICE_BLK_SW].es.fvw)\n-\t\t\t\tbreak;\n-\t\t\tif (i + 1 == ids_cnt) {\n-\t\t\t\tfvl = (struct ice_sw_fv_list_entry *)\n-\t\t\t\t\tice_malloc(hw, sizeof(*fvl));\n-\t\t\t\tif (!fvl)\n-\t\t\t\t\tgoto err;\n-\t\t\t\tfvl->fv_ptr = fv;\n-\t\t\t\tfvl->profile_id = offset;\n-\t\t\t\tLIST_ADD(&fvl->list_entry, fv_list);\n+\t\t\tif ((label_name[len] - '0') == hw->pf_id) {\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].type = tnls[i].type;\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].valid = false;\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].in_use = false;\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].marked = false;\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].boost_addr = val;\n+\t\t\t\thw->tnl.tbl[hw->tnl.count].port = 0;\n+\t\t\t\thw->tnl.count++;\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n-\t} while (fv);\n-\tif (LIST_EMPTY(fv_list))\n-\t\treturn ICE_ERR_CFG;\n-\treturn ICE_SUCCESS;\n-\n-err:\n-\tLIST_FOR_EACH_ENTRY_SAFE(fvl, tmp, fv_list, ice_sw_fv_list_entry,\n-\t\t\t\t list_entry) {\n-\t\tLIST_DEL(&fvl->list_entry);\n-\t\tice_free(hw, fvl);\n \t}\n-\n-\treturn ICE_ERR_NO_MEMORY;\n }\n \n /**\n- * ice_init_prof_result_bm - Initialize the profile result index bitmap\n- * @hw: pointer to hardware structure\n+ * ice_add_dvm_hint\n+ * @hw: pointer to the HW structure\n+ * @val: value of the boost entry\n+ * @enable: true if entry needs to be enabled, or false if needs to be disabled\n  */\n-void ice_init_prof_result_bm(struct ice_hw *hw)\n+void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable)\n {\n-\tstruct ice_pkg_enum state;\n-\tstruct ice_seg *ice_seg;\n-\tstruct ice_fv *fv;\n-\n-\tice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);\n-\n-\tif (!hw->seg)\n-\t\treturn;\n-\n-\tice_seg = hw->seg;\n-\tdo {\n-\t\tu32 off;\n-\t\tu16 i;\n-\n-\t\tfv = (struct ice_fv *)\n-\t\t\tice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,\n-\t\t\t\t\t   &off, ice_sw_fv_handler);\n-\t\tice_seg = NULL;\n-\t\tif (!fv)\n-\t\t\tbreak;\n+\tif (hw->dvm_upd.count < ICE_DVM_MAX_ENTRIES) {\n+\t\thw->dvm_upd.tbl[hw->dvm_upd.count].boost_addr = val;\n+\t\thw->dvm_upd.tbl[hw->dvm_upd.count].enable = enable;\n+\t\thw->dvm_upd.count++;\n+\t}\n+}\n \n-\t\tice_zero_bitmap(hw->switch_info->prof_res_bm[off],\n-\t\t\t\tICE_MAX_FV_WORDS);\n+/* Key creation */\n \n-\t\t/* Determine empty field vector indices, these can be\n-\t\t * used for recipe results. Skip index 0, since it is\n-\t\t * always used for Switch ID.\n-\t\t */\n-\t\tfor (i = 1; i < ICE_MAX_FV_WORDS; i++)\n-\t\t\tif (fv->ew[i].prot_id == ICE_PROT_INVALID &&\n-\t\t\t    fv->ew[i].off == ICE_FV_OFFSET_INVAL)\n-\t\t\t\tice_set_bit(i,\n-\t\t\t\t\t    hw->switch_info->prof_res_bm[off]);\n-\t} while (fv);\n-}\n+#define ICE_DC_KEY\t0x1\t/* don't care */\n+#define ICE_DC_KEYINV\t0x1\n+#define ICE_NM_KEY\t0x0\t/* never match */\n+#define ICE_NM_KEYINV\t0x0\n+#define ICE_0_KEY\t0x1\t/* match 0 */\n+#define ICE_0_KEYINV\t0x0\n+#define ICE_1_KEY\t0x0\t/* match 1 */\n+#define ICE_1_KEYINV\t0x1\n \n /**\n- * ice_pkg_buf_free\n- * @hw: pointer to the HW structure\n- * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n+ * ice_gen_key_word - generate 16-bits of a key/mask word\n+ * @val: the value\n+ * @valid: valid bits mask (change only the valid bits)\n+ * @dont_care: don't care mask\n+ * @nvr_mtch: never match mask\n+ * @key: pointer to an array of where the resulting key portion\n+ * @key_inv: pointer to an array of where the resulting key invert portion\n  *\n- * Frees a package buffer\n- */\n-void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)\n-{\n-\tice_free(hw, bld);\n-}\n-\n-/**\n- * ice_pkg_buf_reserve_section\n- * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n- * @count: the number of sections to reserve\n+ * This function generates 16-bits from a 8-bit value, an 8-bit don't care mask\n+ * and an 8-bit never match mask. The 16-bits of output are divided into 8 bits\n+ * of key and 8 bits of key invert.\n+ *\n+ *     '0' =    b01, always match a 0 bit\n+ *     '1' =    b10, always match a 1 bit\n+ *     '?' =    b11, don't care bit (always matches)\n+ *     '~' =    b00, never match bit\n  *\n- * Reserves one or more section table entries in a package buffer. This routine\n- * can be called multiple times as long as they are made before calling\n- * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section()\n- * is called once, the number of sections that can be allocated will not be able\n- * to be increased; not using all reserved sections is fine, but this will\n- * result in some wasted space in the buffer.\n- * Note: all package contents must be in Little Endian form.\n+ * Input:\n+ *          val:         b0  1  0  1  0  1\n+ *          dont_care:   b0  0  1  1  0  0\n+ *          never_mtch:  b0  0  0  0  1  1\n+ *          ------------------------------\n+ * Result:  key:        b01 10 11 11 00 00\n  */\n static enum ice_status\n-ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count)\n+ice_gen_key_word(u8 val, u8 valid, u8 dont_care, u8 nvr_mtch, u8 *key,\n+\t\t u8 *key_inv)\n {\n-\tstruct ice_buf_hdr *buf;\n-\tu16 section_count;\n-\tu16 data_end;\n+\tu8 in_key = *key, in_key_inv = *key_inv;\n+\tu8 i;\n \n-\tif (!bld)\n-\t\treturn ICE_ERR_PARAM;\n+\t/* 'dont_care' and 'nvr_mtch' masks cannot overlap */\n+\tif ((dont_care ^ nvr_mtch) != (dont_care | nvr_mtch))\n+\t\treturn ICE_ERR_CFG;\n \n-\tbuf = (struct ice_buf_hdr *)&bld->buf;\n+\t*key = 0;\n+\t*key_inv = 0;\n \n-\t/* already an active section, can't increase table size */\n-\tsection_count = LE16_TO_CPU(buf->section_count);\n-\tif (section_count > 0)\n-\t\treturn ICE_ERR_CFG;\n+\t/* encode the 8 bits into 8-bit key and 8-bit key invert */\n+\tfor (i = 0; i < 8; i++) {\n+\t\t*key >>= 1;\n+\t\t*key_inv >>= 1;\n \n-\tif (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT)\n-\t\treturn ICE_ERR_CFG;\n-\tbld->reserved_section_table_entries += count;\n+\t\tif (!(valid & 0x1)) { /* change only valid bits */\n+\t\t\t*key |= (in_key & 0x1) << 7;\n+\t\t\t*key_inv |= (in_key_inv & 0x1) << 7;\n+\t\t} else if (dont_care & 0x1) { /* don't care bit */\n+\t\t\t*key |= ICE_DC_KEY << 7;\n+\t\t\t*key_inv |= ICE_DC_KEYINV << 7;\n+\t\t} else if (nvr_mtch & 0x1) { /* never match bit */\n+\t\t\t*key |= ICE_NM_KEY << 7;\n+\t\t\t*key_inv |= ICE_NM_KEYINV << 7;\n+\t\t} else if (val & 0x01) { /* exact 1 match */\n+\t\t\t*key |= ICE_1_KEY << 7;\n+\t\t\t*key_inv |= ICE_1_KEYINV << 7;\n+\t\t} else { /* exact 0 match */\n+\t\t\t*key |= ICE_0_KEY << 7;\n+\t\t\t*key_inv |= ICE_0_KEYINV << 7;\n+\t\t}\n \n-\tdata_end = LE16_TO_CPU(buf->data_end) +\n-\t\tFLEX_ARRAY_SIZE(buf, section_entry, count);\n-\tbuf->data_end = CPU_TO_LE16(data_end);\n+\t\tdont_care >>= 1;\n+\t\tnvr_mtch >>= 1;\n+\t\tvalid >>= 1;\n+\t\tval >>= 1;\n+\t\tin_key >>= 1;\n+\t\tin_key_inv >>= 1;\n+\t}\n \n \treturn ICE_SUCCESS;\n }\n \n /**\n- * ice_pkg_buf_alloc_section\n- * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n- * @type: the section type value\n- * @size: the size of the section to reserve (in bytes)\n+ * ice_bits_max_set - determine if the number of bits set is within a maximum\n+ * @mask: pointer to the byte array which is the mask\n+ * @size: the number of bytes in the mask\n+ * @max: the max number of set bits\n  *\n- * Reserves memory in the buffer for a section's content and updates the\n- * buffers' status accordingly. This routine returns a pointer to the first\n- * byte of the section start within the buffer, which is used to fill in the\n- * section contents.\n- * Note: all package contents must be in Little Endian form.\n+ * This function determines if there are at most 'max' number of bits set in an\n+ * array. Returns true if the number for bits set is <= max or will return false\n+ * otherwise.\n  */\n-static void *\n-ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size)\n+static bool ice_bits_max_set(const u8 *mask, u16 size, u16 max)\n {\n-\tstruct ice_buf_hdr *buf;\n-\tu16 sect_count;\n-\tu16 data_end;\n-\n-\tif (!bld || !type || !size)\n-\t\treturn NULL;\n-\n-\tbuf = (struct ice_buf_hdr *)&bld->buf;\n-\n-\t/* check for enough space left in buffer */\n-\tdata_end = LE16_TO_CPU(buf->data_end);\n-\n-\t/* section start must align on 4 byte boundary */\n-\tdata_end = ICE_ALIGN(data_end, 4);\n-\n-\tif ((data_end + size) > ICE_MAX_S_DATA_END)\n-\t\treturn NULL;\n-\n-\t/* check for more available section table entries */\n-\tsect_count = LE16_TO_CPU(buf->section_count);\n-\tif (sect_count < bld->reserved_section_table_entries) {\n-\t\tvoid *section_ptr = ((u8 *)buf) + data_end;\n+\tu16 count = 0;\n+\tu16 i;\n \n-\t\tbuf->section_entry[sect_count].offset = CPU_TO_LE16(data_end);\n-\t\tbuf->section_entry[sect_count].size = CPU_TO_LE16(size);\n-\t\tbuf->section_entry[sect_count].type = CPU_TO_LE32(type);\n+\t/* check each byte */\n+\tfor (i = 0; i < size; i++) {\n+\t\t/* if 0, go to next byte */\n+\t\tif (!mask[i])\n+\t\t\tcontinue;\n \n-\t\tdata_end += size;\n-\t\tbuf->data_end = CPU_TO_LE16(data_end);\n+\t\t/* We know there is at least one set bit in this byte because of\n+\t\t * the above check; if we already have found 'max' number of\n+\t\t * bits set, then we can return failure now.\n+\t\t */\n+\t\tif (count == max)\n+\t\t\treturn false;\n \n-\t\tbuf->section_count = CPU_TO_LE16(sect_count + 1);\n-\t\treturn section_ptr;\n+\t\t/* count the bits in this byte, checking threshold */\n+\t\tcount += ice_hweight8(mask[i]);\n+\t\tif (count > max)\n+\t\t\treturn false;\n \t}\n \n-\t/* no free section table entries */\n-\treturn NULL;\n+\treturn true;\n }\n \n /**\n- * ice_pkg_buf_alloc_single_section\n- * @hw: pointer to the HW structure\n- * @type: the section type value\n- * @size: the size of the section to reserve (in bytes)\n- * @section: returns pointer to the section\n+ * ice_set_key - generate a variable sized key with multiples of 16-bits\n+ * @key: pointer to where the key will be stored\n+ * @size: the size of the complete key in bytes (must be even)\n+ * @val: array of 8-bit values that makes up the value portion of the key\n+ * @upd: array of 8-bit masks that determine what key portion to update\n+ * @dc: array of 8-bit masks that make up the don't care mask\n+ * @nm: array of 8-bit masks that make up the never match mask\n+ * @off: the offset of the first byte in the key to update\n+ * @len: the number of bytes in the key update\n  *\n- * Allocates a package buffer with a single section.\n- * Note: all package contents must be in Little Endian form.\n+ * This function generates a key from a value, a don't care mask and a never\n+ * match mask.\n+ * upd, dc, and nm are optional parameters, and can be NULL:\n+ *\tupd == NULL --> upd mask is all 1's (update all bits)\n+ *\tdc == NULL --> dc mask is all 0's (no don't care bits)\n+ *\tnm == NULL --> nm mask is all 0's (no never match bits)\n  */\n-struct ice_buf_build *\n-ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,\n-\t\t\t\t void **section)\n+enum ice_status\n+ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off,\n+\t    u16 len)\n {\n-\tstruct ice_buf_build *buf;\n-\n-\tif (!section)\n-\t\treturn NULL;\n-\n-\tbuf = ice_pkg_buf_alloc(hw);\n-\tif (!buf)\n-\t\treturn NULL;\n-\n-\tif (ice_pkg_buf_reserve_section(buf, 1))\n-\t\tgoto ice_pkg_buf_alloc_single_section_err;\n-\n-\t*section = ice_pkg_buf_alloc_section(buf, type, size);\n-\tif (!*section)\n-\t\tgoto ice_pkg_buf_alloc_single_section_err;\n-\n-\treturn buf;\n-\n-ice_pkg_buf_alloc_single_section_err:\n-\tice_pkg_buf_free(hw, buf);\n-\treturn NULL;\n-}\n+\tu16 half_size;\n+\tu16 i;\n \n-/**\n- * ice_pkg_buf_get_active_sections\n- * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n- *\n- * Returns the number of active sections. Before using the package buffer\n- * in an update package command, the caller should make sure that there is at\n- * least one active section - otherwise, the buffer is not legal and should\n- * not be used.\n- * Note: all package contents must be in Little Endian form.\n- */\n-static u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld)\n-{\n-\tstruct ice_buf_hdr *buf;\n+\t/* size must be a multiple of 2 bytes. */\n+\tif (size % 2)\n+\t\treturn ICE_ERR_CFG;\n+\thalf_size = size / 2;\n \n-\tif (!bld)\n-\t\treturn 0;\n+\tif (off + len > half_size)\n+\t\treturn ICE_ERR_CFG;\n \n-\tbuf = (struct ice_buf_hdr *)&bld->buf;\n-\treturn LE16_TO_CPU(buf->section_count);\n-}\n+\t/* Make sure at most one bit is set in the never match mask. Having more\n+\t * than one never match mask bit set will cause HW to consume excessive\n+\t * power otherwise; this is a power management efficiency check.\n+\t */\n+#define ICE_NVR_MTCH_BITS_MAX\t1\n+\tif (nm && !ice_bits_max_set(nm, len, ICE_NVR_MTCH_BITS_MAX))\n+\t\treturn ICE_ERR_CFG;\n \n-/**\n- * ice_pkg_buf\n- * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())\n- *\n- * Return a pointer to the buffer's header\n- */\n-struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)\n-{\n-\tif (!bld)\n-\t\treturn NULL;\n+\tfor (i = 0; i < len; i++)\n+\t\tif (ice_gen_key_word(val[i], upd ? upd[i] : 0xff,\n+\t\t\t\t     dc ? dc[i] : 0, nm ? nm[i] : 0,\n+\t\t\t\t     key + off + i, key + half_size + off + i))\n+\t\t\treturn ICE_ERR_CFG;\n \n-\treturn &bld->buf;\n+\treturn ICE_SUCCESS;\n }\n \n /**\n@@ -3956,6 +2132,18 @@ static void ice_fill_tbl(struct ice_hw *hw, enum ice_block block_id, u32 sid)\n \t}\n }\n \n+/**\n+ * ice_init_flow_profs - init flow profile locks and list heads\n+ * @hw: pointer to the hardware structure\n+ * @blk_idx: HW block index\n+ */\n+static\n+void ice_init_flow_profs(struct ice_hw *hw, u8 blk_idx)\n+{\n+\tice_init_lock(&hw->fl_profs_locks[blk_idx]);\n+\tINIT_LIST_HEAD(&hw->fl_profs[blk_idx]);\n+}\n+\n /**\n  * ice_fill_blk_tbls - Read package context for tables\n  * @hw: pointer to the hardware structure\n@@ -4098,17 +2286,6 @@ void ice_free_hw_tbls(struct ice_hw *hw)\n \tice_memset(hw->blk, 0, sizeof(hw->blk), ICE_NONDMA_MEM);\n }\n \n-/**\n- * ice_init_flow_profs - init flow profile locks and list heads\n- * @hw: pointer to the hardware structure\n- * @blk_idx: HW block index\n- */\n-static void ice_init_flow_profs(struct ice_hw *hw, u8 blk_idx)\n-{\n-\tice_init_lock(&hw->fl_profs_locks[blk_idx]);\n-\tINIT_LIST_HEAD(&hw->fl_profs[blk_idx]);\n-}\n-\n /**\n  * ice_clear_hw_tbls - clear HW tables and flow profiles\n  * @hw: pointer to the hardware structure\ndiff --git a/drivers/net/ice/base/ice_flex_pipe.h b/drivers/net/ice/base/ice_flex_pipe.h\nindex ab897de4f3..aab765e68f 100644\n--- a/drivers/net/ice/base/ice_flex_pipe.h\n+++ b/drivers/net/ice/base/ice_flex_pipe.h\n@@ -7,23 +7,6 @@\n \n #include \"ice_type.h\"\n \n-/* Package minimal version supported */\n-#define ICE_PKG_SUPP_VER_MAJ\t1\n-#define ICE_PKG_SUPP_VER_MNR\t3\n-\n-/* Package format version */\n-#define ICE_PKG_FMT_VER_MAJ\t1\n-#define ICE_PKG_FMT_VER_MNR\t0\n-#define ICE_PKG_FMT_VER_UPD\t0\n-#define ICE_PKG_FMT_VER_DFT\t0\n-\n-#define ICE_PKG_CNT 4\n-\n-enum ice_status\n-ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count);\n-enum ice_status\n-ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access);\n-void ice_release_change_lock(struct ice_hw *hw);\n enum ice_status\n ice_find_prot_off(struct ice_hw *hw, enum ice_block blk, u8 prof, u8 fv_idx,\n \t\t  u8 *prot, u16 *off);\n@@ -36,12 +19,6 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type type,\n void\n ice_init_prof_result_bm(struct ice_hw *hw);\n enum ice_status\n-ice_get_sw_fv_list(struct ice_hw *hw, u8 *prot_ids, u16 ids_cnt,\n-\t\t   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list);\n-enum ice_status\n-ice_pkg_buf_unreserve_section(struct ice_buf_build *bld, u16 count);\n-u16 ice_pkg_buf_get_free_space(struct ice_buf_build *bld);\n-enum ice_status\n ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,\n \t\t      u16 buf_size, struct ice_sq_cd *cd);\n bool\n@@ -79,31 +56,31 @@ ice_rem_prof_id_flow(struct ice_hw *hw, enum ice_block blk, u16 vsi, u64 hdl);\n enum ice_status\n ice_flow_assoc_hw_prof(struct ice_hw *hw, enum ice_block blk,\n \t\t       u16 dest_vsi_handle, u16 fdir_vsi_handle, int id);\n-enum ice_status ice_init_pkg(struct ice_hw *hw, u8 *buff, u32 len);\n-enum ice_status\n-ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len);\n enum ice_status ice_init_hw_tbls(struct ice_hw *hw);\n-void ice_free_seg(struct ice_hw *hw);\n void ice_fill_blk_tbls(struct ice_hw *hw);\n void ice_clear_hw_tbls(struct ice_hw *hw);\n void ice_free_hw_tbls(struct ice_hw *hw);\n enum ice_status\n ice_rem_prof(struct ice_hw *hw, enum ice_block blk, u64 id);\n-struct ice_buf_build *\n-ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,\n-\t\t\t\t void **section);\n-struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld);\n-void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld);\n \n enum ice_status\n ice_set_key(u8 *key, u16 size, u8 *val, u8 *upd, u8 *dc, u8 *nm, u16 off,\n \t    u16 len);\n-void *\n-ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n-\t\t   u32 sect_type, u32 *offset,\n-\t\t   void *(*handler)(u32 sect_type, void *section,\n-\t\t\t\t    u32 index, u32 *offset));\n-void *\n-ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,\n-\t\t     u32 sect_type);\n+\n+void ice_fill_blk_tbls(struct ice_hw *hw);\n+\n+/* To support tunneling entries by PF, the package will append the PF number to\n+ * the label; for example TNL_VXLAN_PF0, TNL_VXLAN_PF1, TNL_VXLAN_PF2, etc.\n+ */\n+#define ICE_TNL_PRE\t\"TNL_\"\n+/* For supporting double VLAN mode, it is necessary to enable or disable certain\n+ * boost tcam entries. The metadata labels names that match the following\n+ * prefixes will be saved to allow enabling double VLAN mode.\n+ */\n+#define ICE_DVM_PRE\t\"BOOST_MAC_VLAN_DVM\"\t/* enable these entries */\n+#define ICE_SVM_PRE\t\"BOOST_MAC_VLAN_SVM\"\t/* disable these entries */\n+\n+void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val);\n+void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable);\n+\n #endif /* _ICE_FLEX_PIPE_H_ */\ndiff --git a/drivers/net/ice/base/ice_flex_type.h b/drivers/net/ice/base/ice_flex_type.h\nindex 09a02fe9ac..d45653b637 100644\n--- a/drivers/net/ice/base/ice_flex_type.h\n+++ b/drivers/net/ice/base/ice_flex_type.h\n@@ -14,6 +14,7 @@ struct ice_fv_word {\n \tu16 off;\t\t/* Offset within the protocol header */\n \tu8 resvrd;\n };\n+\n #pragma pack()\n \n #define ICE_MAX_NUM_PROFILES 256\n@@ -23,251 +24,6 @@ struct ice_fv {\n \tstruct ice_fv_word ew[ICE_MAX_FV_WORDS];\n };\n \n-/* Package and segment headers and tables */\n-struct ice_pkg_hdr {\n-\tstruct ice_pkg_ver pkg_format_ver;\n-\t__le32 seg_count;\n-\t__le32 seg_offset[STRUCT_HACK_VAR_LEN];\n-};\n-\n-/* generic segment */\n-struct ice_generic_seg_hdr {\n-#define SEGMENT_TYPE_METADATA\t0x00000001\n-#define SEGMENT_TYPE_ICE_E810\t0x00000010\n-\t__le32 seg_type;\n-\tstruct ice_pkg_ver seg_format_ver;\n-\t__le32 seg_size;\n-\tchar seg_id[ICE_PKG_NAME_SIZE];\n-};\n-\n-/* ice specific segment */\n-\n-union ice_device_id {\n-\tstruct {\n-\t\t__le16 device_id;\n-\t\t__le16 vendor_id;\n-\t} dev_vend_id;\n-\t__le32 id;\n-};\n-\n-struct ice_device_id_entry {\n-\tunion ice_device_id device;\n-\tunion ice_device_id sub_device;\n-};\n-\n-struct ice_seg {\n-\tstruct ice_generic_seg_hdr hdr;\n-\t__le32 device_table_count;\n-\tstruct ice_device_id_entry device_table[STRUCT_HACK_VAR_LEN];\n-};\n-\n-struct ice_nvm_table {\n-\t__le32 table_count;\n-\t__le32 vers[STRUCT_HACK_VAR_LEN];\n-};\n-\n-struct ice_buf {\n-#define ICE_PKG_BUF_SIZE\t4096\n-\tu8 buf[ICE_PKG_BUF_SIZE];\n-};\n-\n-struct ice_buf_table {\n-\t__le32 buf_count;\n-\tstruct ice_buf buf_array[STRUCT_HACK_VAR_LEN];\n-};\n-\n-/* global metadata specific segment */\n-struct ice_global_metadata_seg {\n-\tstruct ice_generic_seg_hdr hdr;\n-\tstruct ice_pkg_ver pkg_ver;\n-\t__le32 rsvd;\n-\tchar pkg_name[ICE_PKG_NAME_SIZE];\n-};\n-\n-#define ICE_MIN_S_OFF\t\t12\n-#define ICE_MAX_S_OFF\t\t4095\n-#define ICE_MIN_S_SZ\t\t1\n-#define ICE_MAX_S_SZ\t\t4084\n-\n-/* section information */\n-struct ice_section_entry {\n-\t__le32 type;\n-\t__le16 offset;\n-\t__le16 size;\n-};\n-\n-#define ICE_MIN_S_COUNT\t\t1\n-#define ICE_MAX_S_COUNT\t\t511\n-#define ICE_MIN_S_DATA_END\t12\n-#define ICE_MAX_S_DATA_END\t4096\n-\n-#define ICE_METADATA_BUF\t0x80000000\n-\n-struct ice_buf_hdr {\n-\t__le16 section_count;\n-\t__le16 data_end;\n-\tstruct ice_section_entry section_entry[STRUCT_HACK_VAR_LEN];\n-};\n-\n-#define ICE_MAX_ENTRIES_IN_BUF(hd_sz, ent_sz) ((ICE_PKG_BUF_SIZE - \\\n-\tice_struct_size((struct ice_buf_hdr *)0, section_entry, 1) - (hd_sz)) /\\\n-\t(ent_sz))\n-\n-/* ice package section IDs */\n-#define ICE_SID_METADATA\t\t1\n-#define ICE_SID_XLT0_SW\t\t\t10\n-#define ICE_SID_XLT_KEY_BUILDER_SW\t11\n-#define ICE_SID_XLT1_SW\t\t\t12\n-#define ICE_SID_XLT2_SW\t\t\t13\n-#define ICE_SID_PROFID_TCAM_SW\t\t14\n-#define ICE_SID_PROFID_REDIR_SW\t\t15\n-#define ICE_SID_FLD_VEC_SW\t\t16\n-#define ICE_SID_CDID_KEY_BUILDER_SW\t17\n-#define ICE_SID_CDID_REDIR_SW\t\t18\n-\n-#define ICE_SID_XLT0_ACL\t\t20\n-#define ICE_SID_XLT_KEY_BUILDER_ACL\t21\n-#define ICE_SID_XLT1_ACL\t\t22\n-#define ICE_SID_XLT2_ACL\t\t23\n-#define ICE_SID_PROFID_TCAM_ACL\t\t24\n-#define ICE_SID_PROFID_REDIR_ACL\t25\n-#define ICE_SID_FLD_VEC_ACL\t\t26\n-#define ICE_SID_CDID_KEY_BUILDER_ACL\t27\n-#define ICE_SID_CDID_REDIR_ACL\t\t28\n-\n-#define ICE_SID_XLT0_FD\t\t\t30\n-#define ICE_SID_XLT_KEY_BUILDER_FD\t31\n-#define ICE_SID_XLT1_FD\t\t\t32\n-#define ICE_SID_XLT2_FD\t\t\t33\n-#define ICE_SID_PROFID_TCAM_FD\t\t34\n-#define ICE_SID_PROFID_REDIR_FD\t\t35\n-#define ICE_SID_FLD_VEC_FD\t\t36\n-#define ICE_SID_CDID_KEY_BUILDER_FD\t37\n-#define ICE_SID_CDID_REDIR_FD\t\t38\n-\n-#define ICE_SID_XLT0_RSS\t\t40\n-#define ICE_SID_XLT_KEY_BUILDER_RSS\t41\n-#define ICE_SID_XLT1_RSS\t\t42\n-#define ICE_SID_XLT2_RSS\t\t43\n-#define ICE_SID_PROFID_TCAM_RSS\t\t44\n-#define ICE_SID_PROFID_REDIR_RSS\t45\n-#define ICE_SID_FLD_VEC_RSS\t\t46\n-#define ICE_SID_CDID_KEY_BUILDER_RSS\t47\n-#define ICE_SID_CDID_REDIR_RSS\t\t48\n-\n-#define ICE_SID_RXPARSER_CAM\t\t50\n-#define ICE_SID_RXPARSER_NOMATCH_CAM\t51\n-#define ICE_SID_RXPARSER_IMEM\t\t52\n-#define ICE_SID_RXPARSER_XLT0_BUILDER\t53\n-#define ICE_SID_RXPARSER_NODE_PTYPE\t54\n-#define ICE_SID_RXPARSER_MARKER_PTYPE\t55\n-#define ICE_SID_RXPARSER_BOOST_TCAM\t56\n-#define ICE_SID_RXPARSER_PROTO_GRP\t57\n-#define ICE_SID_RXPARSER_METADATA_INIT\t58\n-#define ICE_SID_RXPARSER_XLT0\t\t59\n-\n-#define ICE_SID_TXPARSER_CAM\t\t60\n-#define ICE_SID_TXPARSER_NOMATCH_CAM\t61\n-#define ICE_SID_TXPARSER_IMEM\t\t62\n-#define ICE_SID_TXPARSER_XLT0_BUILDER\t63\n-#define ICE_SID_TXPARSER_NODE_PTYPE\t64\n-#define ICE_SID_TXPARSER_MARKER_PTYPE\t65\n-#define ICE_SID_TXPARSER_BOOST_TCAM\t66\n-#define ICE_SID_TXPARSER_PROTO_GRP\t67\n-#define ICE_SID_TXPARSER_METADATA_INIT\t68\n-#define ICE_SID_TXPARSER_XLT0\t\t69\n-\n-#define ICE_SID_RXPARSER_INIT_REDIR\t70\n-#define ICE_SID_TXPARSER_INIT_REDIR\t71\n-#define ICE_SID_RXPARSER_MARKER_GRP\t72\n-#define ICE_SID_TXPARSER_MARKER_GRP\t73\n-#define ICE_SID_RXPARSER_LAST_PROTO\t74\n-#define ICE_SID_TXPARSER_LAST_PROTO\t75\n-#define ICE_SID_RXPARSER_PG_SPILL\t76\n-#define ICE_SID_TXPARSER_PG_SPILL\t77\n-#define ICE_SID_RXPARSER_NOMATCH_SPILL\t78\n-#define ICE_SID_TXPARSER_NOMATCH_SPILL\t79\n-\n-#define ICE_SID_XLT0_PE\t\t\t80\n-#define ICE_SID_XLT_KEY_BUILDER_PE\t81\n-#define ICE_SID_XLT1_PE\t\t\t82\n-#define ICE_SID_XLT2_PE\t\t\t83\n-#define ICE_SID_PROFID_TCAM_PE\t\t84\n-#define ICE_SID_PROFID_REDIR_PE\t\t85\n-#define ICE_SID_FLD_VEC_PE\t\t86\n-#define ICE_SID_CDID_KEY_BUILDER_PE\t87\n-#define ICE_SID_CDID_REDIR_PE\t\t88\n-\n-#define ICE_SID_RXPARSER_FLAG_REDIR\t97\n-\n-/* Label Metadata section IDs */\n-#define ICE_SID_LBL_FIRST\t\t0x80000010\n-#define ICE_SID_LBL_RXPARSER_IMEM\t0x80000010\n-#define ICE_SID_LBL_TXPARSER_IMEM\t0x80000011\n-#define ICE_SID_LBL_RESERVED_12\t\t0x80000012\n-#define ICE_SID_LBL_RESERVED_13\t\t0x80000013\n-#define ICE_SID_LBL_RXPARSER_MARKER\t0x80000014\n-#define ICE_SID_LBL_TXPARSER_MARKER\t0x80000015\n-#define ICE_SID_LBL_PTYPE\t\t0x80000016\n-#define ICE_SID_LBL_PROTOCOL_ID\t\t0x80000017\n-#define ICE_SID_LBL_RXPARSER_TMEM\t0x80000018\n-#define ICE_SID_LBL_TXPARSER_TMEM\t0x80000019\n-#define ICE_SID_LBL_RXPARSER_PG\t\t0x8000001A\n-#define ICE_SID_LBL_TXPARSER_PG\t\t0x8000001B\n-#define ICE_SID_LBL_RXPARSER_M_TCAM\t0x8000001C\n-#define ICE_SID_LBL_TXPARSER_M_TCAM\t0x8000001D\n-#define ICE_SID_LBL_SW_PROFID_TCAM\t0x8000001E\n-#define ICE_SID_LBL_ACL_PROFID_TCAM\t0x8000001F\n-#define ICE_SID_LBL_PE_PROFID_TCAM\t0x80000020\n-#define ICE_SID_LBL_RSS_PROFID_TCAM\t0x80000021\n-#define ICE_SID_LBL_FD_PROFID_TCAM\t0x80000022\n-#define ICE_SID_LBL_FLAG\t\t0x80000023\n-#define ICE_SID_LBL_REG\t\t\t0x80000024\n-#define ICE_SID_LBL_SW_PTG\t\t0x80000025\n-#define ICE_SID_LBL_ACL_PTG\t\t0x80000026\n-#define ICE_SID_LBL_PE_PTG\t\t0x80000027\n-#define ICE_SID_LBL_RSS_PTG\t\t0x80000028\n-#define ICE_SID_LBL_FD_PTG\t\t0x80000029\n-#define ICE_SID_LBL_SW_VSIG\t\t0x8000002A\n-#define ICE_SID_LBL_ACL_VSIG\t\t0x8000002B\n-#define ICE_SID_LBL_PE_VSIG\t\t0x8000002C\n-#define ICE_SID_LBL_RSS_VSIG\t\t0x8000002D\n-#define ICE_SID_LBL_FD_VSIG\t\t0x8000002E\n-#define ICE_SID_LBL_PTYPE_META\t\t0x8000002F\n-#define ICE_SID_LBL_SW_PROFID\t\t0x80000030\n-#define ICE_SID_LBL_ACL_PROFID\t\t0x80000031\n-#define ICE_SID_LBL_PE_PROFID\t\t0x80000032\n-#define ICE_SID_LBL_RSS_PROFID\t\t0x80000033\n-#define ICE_SID_LBL_FD_PROFID\t\t0x80000034\n-#define ICE_SID_LBL_RXPARSER_MARKER_GRP\t0x80000035\n-#define ICE_SID_LBL_TXPARSER_MARKER_GRP\t0x80000036\n-#define ICE_SID_LBL_RXPARSER_PROTO\t0x80000037\n-#define ICE_SID_LBL_TXPARSER_PROTO\t0x80000038\n-/* The following define MUST be updated to reflect the last label section ID */\n-#define ICE_SID_LBL_LAST\t\t0x80000038\n-\n-enum ice_block {\n-\tICE_BLK_SW = 0,\n-\tICE_BLK_ACL,\n-\tICE_BLK_FD,\n-\tICE_BLK_RSS,\n-\tICE_BLK_PE,\n-\tICE_BLK_COUNT\n-};\n-\n-enum ice_sect {\n-\tICE_XLT0 = 0,\n-\tICE_XLT_KB,\n-\tICE_XLT1,\n-\tICE_XLT2,\n-\tICE_PROF_TCAM,\n-\tICE_PROF_REDIR,\n-\tICE_VEC_TBL,\n-\tICE_CDID_KB,\n-\tICE_CDID_REDIR,\n-\tICE_SECT_COUNT\n-};\n-\n /* Packet Type (PTYPE) values */\n #define ICE_PTYPE_MAC_PAY\t\t\t1\n #define ICE_MAC_PTP\t\t\t\t2\n@@ -662,25 +418,6 @@ struct ice_boost_tcam_section {\n \tsizeof(struct ice_boost_tcam_entry), \\\n \tsizeof(struct ice_boost_tcam_entry))\n \n-/* package Marker PType TCAM entry */\n-struct ice_marker_ptype_tcam_entry {\n-#define ICE_MARKER_PTYPE_TCAM_ADDR_MAX\t1024\n-\t__le16 addr;\n-\t__le16 ptype;\n-\tu8 keys[20];\n-};\n-\n-struct ice_marker_ptype_tcam_section {\n-\t__le16 count;\n-\t__le16 reserved;\n-\tstruct ice_marker_ptype_tcam_entry tcam[STRUCT_HACK_VAR_LEN];\n-};\n-\n-#define ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF ICE_MAX_ENTRIES_IN_BUF( \\\n-\tice_struct_size((struct ice_marker_ptype_tcam_section *)0, tcam, 1) - \\\n-\tsizeof(struct ice_marker_ptype_tcam_entry), \\\n-\tsizeof(struct ice_marker_ptype_tcam_entry))\n-\n struct ice_xlt1_section {\n \t__le16 count;\n \t__le16 offset;\n@@ -699,27 +436,6 @@ struct ice_prof_redir_section {\n \tu8 redir_value[STRUCT_HACK_VAR_LEN];\n };\n \n-/* package buffer building */\n-\n-struct ice_buf_build {\n-\tstruct ice_buf buf;\n-\tu16 reserved_section_table_entries;\n-};\n-\n-struct ice_pkg_enum {\n-\tstruct ice_buf_table *buf_table;\n-\tu32 buf_idx;\n-\n-\tu32 type;\n-\tstruct ice_buf_hdr *buf;\n-\tu32 sect_idx;\n-\tvoid *sect;\n-\tu32 sect_type;\n-\n-\tu32 entry_idx;\n-\tvoid *(*handler)(u32 sect_type, void *section, u32 index, u32 *offset);\n-};\n-\n /* Tunnel enabling */\n \n enum ice_tunnel_type {\ndiff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c\nindex 513623a0a4..ad61dde397 100644\n--- a/drivers/net/ice/base/ice_switch.c\n+++ b/drivers/net/ice/base/ice_switch.c\n@@ -7417,37 +7417,18 @@ ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,\n  * @hw: pointer to hardware structure\n  * @lkups: lookup elements or match criteria for the advanced recipe, one\n  *\t   structure per protocol header\n- * @lkups_cnt: number of protocols\n  * @bm: bitmap of field vectors to consider\n  * @fv_list: pointer to a list that holds the returned field vectors\n  */\n static enum ice_status\n-ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,\n+ice_get_fv(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,\n \t   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)\n {\n-\tenum ice_status status;\n-\tu8 *prot_ids;\n-\tu16 i;\n-\n-\tif (!lkups_cnt)\n+\tif (!lkups->n_val_words)\n \t\treturn ICE_SUCCESS;\n \n-\tprot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids));\n-\tif (!prot_ids)\n-\t\treturn ICE_ERR_NO_MEMORY;\n-\n-\tfor (i = 0; i < lkups_cnt; i++)\n-\t\tif (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {\n-\t\t\tstatus = ICE_ERR_CFG;\n-\t\t\tgoto free_mem;\n-\t\t}\n-\n \t/* Find field vectors that include all specified protocol types */\n-\tstatus = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);\n-\n-free_mem:\n-\tice_free(hw, prot_ids);\n-\treturn status;\n+\treturn ice_get_sw_fv_list(hw, lkups, bm, fv_list);\n }\n \n /**\n@@ -7840,16 +7821,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,\n \t */\n \tice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);\n \n-\t/* If it is a packet to match any, add a lookup element to match direction\n-\t * flag of source interface.\n-\t */\n-\tif (rinfo->tun_type == ICE_SW_TUN_AND_NON_TUN &&\n-\t    lkups_cnt < ICE_MAX_CHAIN_WORDS) {\n-\t\tlkups[lkups_cnt].type = ICE_FLG_DIR;\n-\t\tlkups_cnt++;\n-\t}\n-\n-\tstatus = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);\n+\tstatus = ice_get_fv(hw, lkup_exts, fv_bitmap, &rm->fv_list);\n \tif (status)\n \t\tgoto err_unroll;\n \ndiff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h\nindex a17accff19..d94fdcda67 100644\n--- a/drivers/net/ice/base/ice_type.h\n+++ b/drivers/net/ice/base/ice_type.h\n@@ -5,54 +5,15 @@\n #ifndef _ICE_TYPE_H_\n #define _ICE_TYPE_H_\n \n-#define ETH_ALEN\t6\n-\n-#define ETH_HEADER_LEN\t14\n-\n-#define BIT(a) (1UL << (a))\n-#define BIT_ULL(a) (1ULL << (a))\n-\n-#define BITS_PER_BYTE\t8\n-\n-#define _FORCE_\n-\n-#define ICE_BYTES_PER_WORD\t2\n-#define ICE_BYTES_PER_DWORD\t4\n-#define ICE_MAX_TRAFFIC_CLASS\t8\n-\n-/**\n- * ROUND_UP - round up to next arbitrary multiple (not a power of 2)\n- * @a: value to round up\n- * @b: arbitrary multiple\n- *\n- * Round up to the next multiple of the arbitrary b.\n- * Note, when b is a power of 2 use ICE_ALIGN() instead.\n- */\n-#define ROUND_UP(a, b)\t((b) * DIVIDE_AND_ROUND_UP((a), (b)))\n-\n-#define MIN_T(_t, _a, _b)\tmin((_t)(_a), (_t)(_b))\n-\n-#define IS_ASCII(_ch)\t((_ch) < 0x80)\n-\n-#define STRUCT_HACK_VAR_LEN\n-/**\n- * ice_struct_size - size of struct with C99 flexible array member\n- * @ptr: pointer to structure\n- * @field: flexible array member (last member of the structure)\n- * @num: number of elements of that flexible array member\n- */\n-#define ice_struct_size(ptr, field, num) \\\n-\t(sizeof(*(ptr)) + sizeof(*(ptr)->field) * (num))\n-\n-#define FLEX_ARRAY_SIZE(_ptr, _mem, cnt) ((cnt) * sizeof(_ptr->_mem[0]))\n-\n+#include \"ice_defs.h\"\n #include \"ice_status.h\"\n #include \"ice_hw_autogen.h\"\n #include \"ice_devids.h\"\n #include \"ice_osdep.h\"\n #include \"ice_bitops.h\" /* Must come before ice_controlq.h */\n-#include \"ice_controlq.h\"\n #include \"ice_lan_tx_rx.h\"\n+#include \"ice_ddp.h\"\n+#include \"ice_controlq.h\"\n #include \"ice_flex_type.h\"\n #include \"ice_protocol_type.h\"\n #include \"ice_sbq_cmd.h\"\n@@ -191,11 +152,6 @@ enum ice_aq_res_ids {\n #define ICE_CHANGE_LOCK_TIMEOUT\t\t1000\n #define ICE_GLOBAL_CFG_LOCK_TIMEOUT\t3000\n \n-enum ice_aq_res_access_type {\n-\tICE_RES_READ = 1,\n-\tICE_RES_WRITE\n-};\n-\n struct ice_driver_ver {\n \tu8 major_ver;\n \tu8 minor_ver;\n@@ -248,6 +204,7 @@ enum ice_mac_type {\n \tICE_MAC_UNKNOWN = 0,\n \tICE_MAC_E810,\n \tICE_MAC_GENERIC,\n+\tICE_MAC_GENERIC_3K,\n };\n \n /* Media Types */\n@@ -636,6 +593,7 @@ struct ice_hw_common_caps {\n #define ICE_EXT_TOPO_DEV_IMG_LOAD_EN\tBIT(0)\n \tbool ext_topo_dev_img_prog_en[ICE_EXT_TOPO_DEV_IMG_COUNT];\n #define ICE_EXT_TOPO_DEV_IMG_PROG_EN\tBIT(1)\n+\tbool tx_sched_topo_comp_mode_en;\n };\n \n /* IEEE 1588 TIME_SYNC specific info */\n@@ -1247,7 +1205,9 @@ struct ice_hw {\n \t/* Active package version (currently active) */\n \tstruct ice_pkg_ver active_pkg_ver;\n \tu32 pkg_seg_id;\n+\tu32 pkg_sign_type;\n \tu32 active_track_id;\n+\tu8 pkg_has_signing_seg:1;\n \tu8 active_pkg_name[ICE_PKG_NAME_SIZE];\n \tu8 active_pkg_in_nvm;\n \ndiff --git a/drivers/net/ice/base/ice_vlan_mode.c b/drivers/net/ice/base/ice_vlan_mode.c\nindex 29c6509fc5..d1003a5a89 100644\n--- a/drivers/net/ice/base/ice_vlan_mode.c\n+++ b/drivers/net/ice/base/ice_vlan_mode.c\n@@ -4,6 +4,7 @@\n \n #include \"ice_common.h\"\n \n+#include \"ice_ddp.h\"\n /**\n  * ice_pkg_get_supported_vlan_mode - chk if DDP supports Double VLAN mode (DVM)\n  * @hw: pointer to the HW struct\ndiff --git a/drivers/net/ice/base/meson.build b/drivers/net/ice/base/meson.build\nindex 3cf4ce05fa..41ed2d96c6 100644\n--- a/drivers/net/ice/base/meson.build\n+++ b/drivers/net/ice/base/meson.build\n@@ -26,6 +26,7 @@ sources = [\n         'ice_flg_rd.c',\n         'ice_xlt_kb.c',\n         'ice_parser_rt.c',\n+        'ice_ddp.c',\n ]\n \n error_cflags = [\n",
    "prefixes": [
        "v2",
        "20/70"
    ]
}