get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 96586,
    "url": "http://patchwork.dpdk.org/api/patches/96586/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210803083817.1243796-8-wenjun1.wu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210803083817.1243796-8-wenjun1.wu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210803083817.1243796-8-wenjun1.wu@intel.com",
    "date": "2021-08-03T08:38:02",
    "name": "[07/22] net/ice/base: support configuring device in double VLAN mode",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "295a0507cca00b688c7bed849f1ef92e58f497ba",
    "submitter": {
        "id": 2083,
        "url": "http://patchwork.dpdk.org/api/people/2083/?format=api",
        "name": "Wenjun Wu",
        "email": "wenjun1.wu@intel.com"
    },
    "delegate": {
        "id": 1540,
        "url": "http://patchwork.dpdk.org/api/users/1540/?format=api",
        "username": "qzhan15",
        "first_name": "Qi",
        "last_name": "Zhang",
        "email": "qi.z.zhang@intel.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210803083817.1243796-8-wenjun1.wu@intel.com/mbox/",
    "series": [
        {
            "id": 18158,
            "url": "http://patchwork.dpdk.org/api/series/18158/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=18158",
            "date": "2021-08-03T08:37:55",
            "name": "backport feature support to DPDK 20.11",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/18158/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/96586/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/96586/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 002C8A0C41;\n\tTue,  3 Aug 2021 10:57:56 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 9A687411E4;\n\tTue,  3 Aug 2021 10:57:21 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n by mails.dpdk.org (Postfix) with ESMTP id 68D07411BA\n for <dev@dpdk.org>; Tue,  3 Aug 2021 10:57:13 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 03 Aug 2021 01:56:57 -0700",
            "from wuwenjun.sh.intel.com ([10.67.110.197])\n by fmsmga008.fm.intel.com with ESMTP; 03 Aug 2021 01:56:55 -0700"
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10064\"; a=\"211764388\"",
            "E=Sophos;i=\"5.84,291,1620716400\"; d=\"scan'208\";a=\"211764388\"",
            "E=Sophos;i=\"5.84,291,1620716400\"; d=\"scan'208\";a=\"479396579\""
        ],
        "X-ExtLoop1": "1",
        "From": "Wenjun Wu <wenjun1.wu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Tue,  3 Aug 2021 16:38:02 +0800",
        "Message-Id": "<20210803083817.1243796-8-wenjun1.wu@intel.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20210803083817.1243796-1-wenjun1.wu@intel.com>",
        "References": "<20210803083817.1243796-1-wenjun1.wu@intel.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH 07/22] net/ice/base: support configuring device\n in double VLAN mode",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Qi Zhang <qi.z.zhang@intel.com>\n\n[ upstream commit 14e7a4b37b4f2f765b4da08019ffc9098d99a076 ]\n\nIn order to support configuring the device in Double VLAN Mode (DVM),\nthe DDP and FW have to support DVM. If both support DVM, the PF\nthat downloads the package needs to update the default recipes and set\nthe VLAN mode. This is done in ice_set_dvm().\n\nIn order to support updating the default recipes in DVM add support\nfor updating an existing switch recipe's lkup_idx and mask.\nThis is done by first calling the get recipe AQ (0x0292) with the\ndesired recipe ID. Then, if that is successful update one of the lookup\nindices (lkup_idx) and its associated mask if the mask is valid\notherwise the already existing mask will be used.\n\nSigned-off-by: Brett Creeley <brett.creeley@intel.com>\nSigned-off-by: Qi Zhang <qi.z.zhang@intel.com>\nAcked-by: Qiming Yang <qiming.yang@intel.com>\n---\n drivers/net/ice/base/ice_adminq_cmd.h |  36 ++++\n drivers/net/ice/base/ice_common.c     |   2 -\n drivers/net/ice/base/ice_flex_pipe.c  |   9 +-\n drivers/net/ice/base/ice_switch.c     |  58 ++++++\n drivers/net/ice/base/ice_switch.h     |  12 ++\n drivers/net/ice/base/ice_type.h       |   2 +-\n drivers/net/ice/base/ice_vlan_mode.c  | 284 ++++++++++++++++++++++++--\n drivers/net/ice/base/ice_vlan_mode.h  |  24 +--\n 8 files changed, 381 insertions(+), 46 deletions(-)",
    "diff": "diff --git a/drivers/net/ice/base/ice_adminq_cmd.h b/drivers/net/ice/base/ice_adminq_cmd.h\nindex c0617093d4..1bd4f2fc8d 100644\n--- a/drivers/net/ice/base/ice_adminq_cmd.h\n+++ b/drivers/net/ice/base/ice_adminq_cmd.h\n@@ -358,6 +358,40 @@ struct ice_aqc_get_allocd_res_desc {\n \t__le32 addr_low;\n };\n \n+/* Request buffer for Set VLAN Mode AQ command (indirect 0x020C) */\n+struct ice_aqc_set_vlan_mode {\n+\tu8 reserved;\n+\tu8 l2tag_prio_tagging;\n+#define ICE_AQ_VLAN_PRIO_TAG_S\t\t\t0\n+#define ICE_AQ_VLAN_PRIO_TAG_M\t\t\t(0x7 << ICE_AQ_VLAN_PRIO_TAG_S)\n+#define ICE_AQ_VLAN_PRIO_TAG_NOT_SUPPORTED\t0x0\n+#define ICE_AQ_VLAN_PRIO_TAG_STAG\t\t0x1\n+#define ICE_AQ_VLAN_PRIO_TAG_OUTER_CTAG\t\t0x2\n+#define ICE_AQ_VLAN_PRIO_TAG_OUTER_VLAN\t\t0x3\n+#define ICE_AQ_VLAN_PRIO_TAG_INNER_CTAG\t\t0x4\n+#define ICE_AQ_VLAN_PRIO_TAG_MAX\t\t0x4\n+#define ICE_AQ_VLAN_PRIO_TAG_ERROR\t\t0x7\n+\tu8 l2tag_reserved[64];\n+\tu8 rdma_packet;\n+#define ICE_AQ_VLAN_RDMA_TAG_S\t\t\t0\n+#define ICE_AQ_VLAN_RDMA_TAG_M\t\t\t(0x3F << ICE_AQ_VLAN_RDMA_TAG_S)\n+#define ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING\t0x10\n+#define ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING\t0x1A\n+\tu8 rdma_reserved[2];\n+\tu8 mng_vlan_prot_id;\n+#define ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER\t0x10\n+#define ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER\t0x11\n+\tu8 prot_id_reserved[30];\n+};\n+\n+/* Response buffer for Get VLAN Mode AQ command (indirect 0x020D) */\n+struct ice_aqc_get_vlan_mode {\n+\tu8 vlan_mode;\n+#define ICE_AQ_VLAN_MODE_DVM_ENA\tBIT(0)\n+\tu8 l2tag_prio_tagging;\n+\tu8 reserved[98];\n+};\n+\n /* Add VSI (indirect 0x0210)\n  * Update VSI (indirect 0x0211)\n  * Get VSI (indirect 0x0212)\n@@ -2905,6 +2939,8 @@ enum ice_adminq_opc {\n \tice_aqc_opc_alloc_res\t\t\t\t= 0x0208,\n \tice_aqc_opc_free_res\t\t\t\t= 0x0209,\n \tice_aqc_opc_get_allocd_res_desc\t\t\t= 0x020A,\n+\tice_aqc_opc_set_vlan_mode_parameters\t\t= 0x020C,\n+\tice_aqc_opc_get_vlan_mode_parameters\t\t= 0x020D,\n \n \t/* VSI commands */\n \tice_aqc_opc_add_vsi\t\t\t\t= 0x0210,\ndiff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c\nindex b5f1d8cce5..0f120ec6e0 100644\n--- a/drivers/net/ice/base/ice_common.c\n+++ b/drivers/net/ice/base/ice_common.c\n@@ -831,8 +831,6 @@ enum ice_status ice_init_hw(struct ice_hw *hw)\n \t\tgoto err_unroll_fltr_mgmt_struct;\n \tice_init_lock(&hw->tnl_lock);\n \n-\tice_init_vlan_mode_ops(hw);\n-\n \treturn ICE_SUCCESS;\n \n err_unroll_fltr_mgmt_struct:\ndiff --git a/drivers/net/ice/base/ice_flex_pipe.c b/drivers/net/ice/base/ice_flex_pipe.c\nindex e511b50a00..cced7b6352 100644\n--- a/drivers/net/ice/base/ice_flex_pipe.c\n+++ b/drivers/net/ice/base/ice_flex_pipe.c\n@@ -1073,6 +1073,7 @@ 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@@ -1090,8 +1091,12 @@ ice_download_pkg(struct ice_hw *hw, struct ice_seg *ice_seg)\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-\treturn ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array,\n-\t\t\t\t  LE32_TO_CPU(ice_buf_tbl->buf_count));\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_cache_vlan_mode(hw);\n+\n+\treturn status;\n }\n \n /**\ndiff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c\nindex 8d455f5995..df8319a7e7 100644\n--- a/drivers/net/ice/base/ice_switch.c\n+++ b/drivers/net/ice/base/ice_switch.c\n@@ -2768,6 +2768,64 @@ ice_aq_get_recipe(struct ice_hw *hw,\n \treturn status;\n }\n \n+/**\n+ * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx\n+ * @hw: pointer to the HW struct\n+ * @params: parameters used to update the default recipe\n+ *\n+ * This function only supports updating default recipes and it only supports\n+ * updating a single recipe based on the lkup_idx at a time.\n+ *\n+ * This is done as a read-modify-write operation. First, get the current recipe\n+ * contents based on the recipe's ID. Then modify the field vector index and\n+ * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update\n+ * the pre-existing recipe with the modifications.\n+ */\n+enum ice_status\n+ice_update_recipe_lkup_idx(struct ice_hw *hw,\n+\t\t\t   struct ice_update_recipe_lkup_idx_params *params)\n+{\n+\tstruct ice_aqc_recipe_data_elem *rcp_list;\n+\tu16 num_recps = ICE_MAX_NUM_RECIPES;\n+\tenum ice_status status;\n+\n+\trcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));\n+\tif (!rcp_list)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\t/* read current recipe list from firmware */\n+\trcp_list->recipe_indx = params->rid;\n+\tstatus = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_SW, \"Failed to get recipe %d, status %d\\n\",\n+\t\t\t  params->rid, status);\n+\t\tgoto error_out;\n+\t}\n+\n+\t/* only modify existing recipe's lkup_idx and mask if valid, while\n+\t * leaving all other fields the same, then update the recipe firmware\n+\t */\n+\trcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;\n+\tif (params->mask_valid)\n+\t\trcp_list->content.mask[params->lkup_idx] =\n+\t\t\tCPU_TO_LE16(params->mask);\n+\n+\tif (params->ignore_valid)\n+\t\trcp_list->content.lkup_indx[params->lkup_idx] |=\n+\t\t\tICE_AQ_RECIPE_LKUP_IGNORE;\n+\n+\tstatus = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);\n+\tif (status)\n+\t\tice_debug(hw, ICE_DBG_SW, \"Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\\n\",\n+\t\t\t  params->rid, params->lkup_idx, params->fv_idx,\n+\t\t\t  params->mask, params->mask_valid ? \"true\" : \"false\",\n+\t\t\t  status);\n+\n+error_out:\n+\tice_free(hw, rcp_list);\n+\treturn status;\n+}\n+\n /**\n  * ice_aq_map_recipe_to_profile - Map recipe to packet profile\n  * @hw: pointer to the HW struct\ndiff --git a/drivers/net/ice/base/ice_switch.h b/drivers/net/ice/base/ice_switch.h\nindex 392eb369c7..78e6be35a9 100644\n--- a/drivers/net/ice/base/ice_switch.h\n+++ b/drivers/net/ice/base/ice_switch.h\n@@ -202,6 +202,15 @@ struct ice_fltr_info {\n \tu8 lan_en;\t/* Indicate if packet can be forwarded to the uplink */\n };\n \n+struct ice_update_recipe_lkup_idx_params {\n+\tu16 rid;\n+\tu16 fv_idx;\n+\tbool ignore_valid;\n+\tu16 mask;\n+\tbool mask_valid;\n+\tu8 lkup_idx;\n+};\n+\n struct ice_adv_lkup_elem {\n \tenum ice_protocol_type type;\n \tunion ice_prot_hdr h_u;\t/* Header values */\n@@ -524,4 +533,7 @@ ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,\n void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw);\n void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw);\n bool ice_is_prof_rule(enum ice_sw_tunnel_type type);\n+enum ice_status\n+ice_update_recipe_lkup_idx(struct ice_hw *hw,\n+\t\t\t   struct ice_update_recipe_lkup_idx_params *params);\n #endif /* _ICE_SWITCH_H_ */\ndiff --git a/drivers/net/ice/base/ice_type.h b/drivers/net/ice/base/ice_type.h\nindex 996b58b743..a4a4427693 100644\n--- a/drivers/net/ice/base/ice_type.h\n+++ b/drivers/net/ice/base/ice_type.h\n@@ -986,7 +986,7 @@ struct ice_hw {\n \tice_declare_bitmap(fdir_perfect_fltr, ICE_FLTR_PTYPE_MAX);\n \tstruct ice_lock rss_locks;\t/* protect RSS configuration */\n \tstruct LIST_HEAD_TYPE rss_list_head;\n-\tstruct ice_vlan_mode_ops vlan_mode_ops;\n+\tu8 dvm_ena;\n };\n \n /* Statistics collected by each port, VSI, VEB, and S-channel */\ndiff --git a/drivers/net/ice/base/ice_vlan_mode.c b/drivers/net/ice/base/ice_vlan_mode.c\nindex c4e7a40295..c86e803c52 100644\n--- a/drivers/net/ice/base/ice_vlan_mode.c\n+++ b/drivers/net/ice/base/ice_vlan_mode.c\n@@ -55,21 +55,100 @@ ice_pkg_get_supported_vlan_mode(struct ice_hw *hw, bool *dvm)\n }\n \n /**\n- * ice_is_dvm_supported - check if double VLAN mode is supported based on DDP\n+ * ice_aq_get_vlan_mode - get the VLAN mode of the device\n+ * @hw: pointer to the HW structure\n+ * @get_params: structure FW fills in based on the current VLAN mode config\n+ *\n+ * Get VLAN Mode Parameters (0x020D)\n+ */\n+static enum ice_status\n+ice_aq_get_vlan_mode(struct ice_hw *hw,\n+\t\t     struct ice_aqc_get_vlan_mode *get_params)\n+{\n+\tstruct ice_aq_desc desc;\n+\n+\tif (!get_params)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc,\n+\t\t\t\t      ice_aqc_opc_get_vlan_mode_parameters);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, get_params, sizeof(*get_params),\n+\t\t\t       NULL);\n+}\n+\n+/**\n+ * ice_aq_is_dvm_ena - query FW to check if double VLAN mode is enabled\n+ * @hw: pointer to the HW structure\n+ *\n+ * Returns true if the hardware/firmware is configured in double VLAN mode,\n+ * else return false signaling that the hardware/firmware is configured in\n+ * single VLAN mode.\n+ *\n+ * Also, return false if this call fails for any reason (i.e. firmware doesn't\n+ * support this AQ call).\n+ */\n+static bool ice_aq_is_dvm_ena(struct ice_hw *hw)\n+{\n+\tstruct ice_aqc_get_vlan_mode get_params = { 0 };\n+\tenum ice_status status;\n+\n+\tstatus = ice_aq_get_vlan_mode(hw, &get_params);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_AQ, \"Failed to get VLAN mode, status %d\\n\",\n+\t\t\t  status);\n+\t\treturn false;\n+\t}\n+\n+\treturn (get_params.vlan_mode & ICE_AQ_VLAN_MODE_DVM_ENA);\n+}\n+\n+/**\n+ * ice_is_dvm_ena - check if double VLAN mode is enabled\n+ * @hw: pointer to the HW structure\n+ *\n+ * The device is configured in single or double VLAN mode on initialization and\n+ * this cannot be dynamically changed during runtime. Based on this there is no\n+ * need to make an AQ call every time the driver needs to know the VLAN mode.\n+ * Instead, use the cached VLAN mode.\n+ */\n+bool ice_is_dvm_ena(struct ice_hw *hw)\n+{\n+\treturn hw->dvm_ena;\n+}\n+\n+/**\n+ * ice_cache_vlan_mode - cache VLAN mode after DDP is downloaded\n+ * @hw: pointer to the HW structure\n+ *\n+ * This is only called after downloading the DDP and after the global\n+ * configuration lock has been released because all ports on a device need to\n+ * cache the VLAN mode.\n+ */\n+void ice_cache_vlan_mode(struct ice_hw *hw)\n+{\n+\thw->dvm_ena = ice_aq_is_dvm_ena(hw) ? true : false;\n+}\n+\n+/**\n+ * ice_is_dvm_supported - check if Double VLAN Mode is supported\n  * @hw: pointer to the hardware structure\n  *\n- * Returns true if DVM is supported and false if only SVM is supported. This\n- * function should only be called while the global config lock is held and after\n- * the package has been successfully downloaded.\n+ * Returns true if Double VLAN Mode (DVM) is supported and false if only Single\n+ * VLAN Mode (SVM) is supported. In order for DVM to be supported the DDP and\n+ * firmware must support it, otherwise only SVM is supported. This function\n+ * should only be called while the global config lock is held and after the\n+ * package has been successfully downloaded.\n  */\n static bool ice_is_dvm_supported(struct ice_hw *hw)\n {\n+\tstruct ice_aqc_get_vlan_mode get_vlan_mode = { 0 };\n \tenum ice_status status;\n \tbool pkg_supports_dvm;\n \n \tstatus = ice_pkg_get_supported_vlan_mode(hw, &pkg_supports_dvm);\n \tif (status) {\n-\t\tice_debug(hw, ICE_DBG_PKG, \"Failed to get supported VLAN mode, err %d\\n\",\n+\t\tice_debug(hw, ICE_DBG_PKG, \"Failed to get supported VLAN mode, status %d\\n\",\n \t\t\t  status);\n \t\treturn false;\n \t}\n@@ -77,28 +156,196 @@ static bool ice_is_dvm_supported(struct ice_hw *hw)\n \tif (!pkg_supports_dvm)\n \t\treturn false;\n \n+\t/* If firmware returns success, then it supports DVM, else it only\n+\t * supports SVM\n+\t */\n+\tstatus = ice_aq_get_vlan_mode(hw, &get_vlan_mode);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_NVM, \"Failed to get VLAN mode, status %d\\n\",\n+\t\t\t  status);\n+\t\treturn false;\n+\t}\n+\n \treturn true;\n }\n \n+#define ICE_EXTERNAL_VLAN_ID_FV_IDX\t\t\t11\n+#define ICE_SW_LKUP_VLAN_LOC_LKUP_IDX\t\t\t1\n+#define ICE_SW_LKUP_VLAN_PKT_FLAGS_LKUP_IDX\t\t2\n+#define ICE_SW_LKUP_PROMISC_VLAN_LOC_LKUP_IDX\t\t2\n+#define ICE_PKT_FLAGS_0_TO_15_FV_IDX\t\t\t1\n+#define ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK\t\t0xD000\n+static struct ice_update_recipe_lkup_idx_params ice_dvm_dflt_recipes[] = {\n+\t{\n+\t\t/* Update recipe ICE_SW_LKUP_VLAN to filter based on the\n+\t\t * outer/single VLAN in DVM\n+\t\t */\n+\t\t.rid = ICE_SW_LKUP_VLAN,\n+\t\t.fv_idx = ICE_EXTERNAL_VLAN_ID_FV_IDX,\n+\t\t.ignore_valid = true,\n+\t\t.mask = 0,\n+\t\t.mask_valid = false, /* use pre-existing mask */\n+\t\t.lkup_idx = ICE_SW_LKUP_VLAN_LOC_LKUP_IDX,\n+\t},\n+\t{\n+\t\t/* Update recipe ICE_SW_LKUP_VLAN to filter based on the VLAN\n+\t\t * packet flags to support VLAN filtering on multiple VLAN\n+\t\t * ethertypes (i.e. 0x8100 and 0x88a8) in DVM\n+\t\t */\n+\t\t.rid = ICE_SW_LKUP_VLAN,\n+\t\t.fv_idx = ICE_PKT_FLAGS_0_TO_15_FV_IDX,\n+\t\t.ignore_valid = false,\n+\t\t.mask = ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK,\n+\t\t.mask_valid = true,\n+\t\t.lkup_idx = ICE_SW_LKUP_VLAN_PKT_FLAGS_LKUP_IDX,\n+\t},\n+\t{\n+\t\t/* Update recipe ICE_SW_LKUP_PROMISC_VLAN to filter based on the\n+\t\t * outer/single VLAN in DVM\n+\t\t */\n+\t\t.rid = ICE_SW_LKUP_PROMISC_VLAN,\n+\t\t.fv_idx = ICE_EXTERNAL_VLAN_ID_FV_IDX,\n+\t\t.ignore_valid = true,\n+\t\t.mask = 0,\n+\t\t.mask_valid = false,  /* use pre-existing mask */\n+\t\t.lkup_idx = ICE_SW_LKUP_PROMISC_VLAN_LOC_LKUP_IDX,\n+\t},\n+};\n+\n /**\n- * ice_set_svm - set single VLAN mode\n+ * ice_dvm_update_dflt_recipes - update default switch recipes in DVM\n+ * @hw: hardware structure used to update the recipes\n+ */\n+static enum ice_status ice_dvm_update_dflt_recipes(struct ice_hw *hw)\n+{\n+\tunsigned long i;\n+\n+\tfor (i = 0; i < ARRAY_SIZE(ice_dvm_dflt_recipes); i++) {\n+\t\tstruct ice_update_recipe_lkup_idx_params *params;\n+\t\tenum ice_status status;\n+\n+\t\tparams = &ice_dvm_dflt_recipes[i];\n+\n+\t\tstatus = ice_update_recipe_lkup_idx(hw, params);\n+\t\tif (status) {\n+\t\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to update RID %d lkup_idx %d fv_idx %d mask_valid %s mask 0x%04x\\n\",\n+\t\t\t\t  params->rid, params->lkup_idx, params->fv_idx,\n+\t\t\t\t  params->mask_valid ? \"true\" : \"false\",\n+\t\t\t\t  params->mask);\n+\t\t\treturn status;\n+\t\t}\n+\t}\n+\n+\treturn ICE_SUCCESS;\n+}\n+\n+/**\n+ * ice_aq_set_vlan_mode - set the VLAN mode of the device\n  * @hw: pointer to the HW structure\n+ * @set_params: requested VLAN mode configuration\n+ *\n+ * Set VLAN Mode Parameters (0x020C)\n+ */\n+static enum ice_status\n+ice_aq_set_vlan_mode(struct ice_hw *hw,\n+\t\t     struct ice_aqc_set_vlan_mode *set_params)\n+{\n+\tu8 rdma_packet, mng_vlan_prot_id;\n+\tstruct ice_aq_desc desc;\n+\n+\tif (!set_params)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tif (set_params->l2tag_prio_tagging > ICE_AQ_VLAN_PRIO_TAG_MAX)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\trdma_packet = set_params->rdma_packet;\n+\tif (rdma_packet != ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING &&\n+\t    rdma_packet != ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tmng_vlan_prot_id = set_params->mng_vlan_prot_id;\n+\tif (mng_vlan_prot_id != ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER &&\n+\t    mng_vlan_prot_id != ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER)\n+\t\treturn ICE_ERR_PARAM;\n+\n+\tice_fill_dflt_direct_cmd_desc(&desc,\n+\t\t\t\t      ice_aqc_opc_set_vlan_mode_parameters);\n+\tdesc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);\n+\n+\treturn ice_aq_send_cmd(hw, &desc, set_params, sizeof(*set_params),\n+\t\t\t       NULL);\n+}\n+\n+/**\n+ * ice_set_dvm - sets up software and hardware for double VLAN mode\n+ * @hw: pointer to the hardware structure\n  */\n-static enum ice_status ice_set_svm_dflt(struct ice_hw *hw)\n+static enum ice_status ice_set_dvm(struct ice_hw *hw)\n {\n-\tice_debug(hw, ICE_DBG_TRACE, \"%s\\n\", __func__);\n+\tstruct ice_aqc_set_vlan_mode params = { 0 };\n+\tenum ice_status status;\n+\n+\tparams.l2tag_prio_tagging = ICE_AQ_VLAN_PRIO_TAG_OUTER_CTAG;\n+\tparams.rdma_packet = ICE_AQ_DVM_VLAN_RDMA_PKT_FLAG_SETTING;\n+\tparams.mng_vlan_prot_id = ICE_AQ_VLAN_MNG_PROTOCOL_ID_OUTER;\n+\n+\tstatus = ice_aq_set_vlan_mode(hw, &params);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to set double VLAN mode parameters, status %d\\n\",\n+\t\t\t  status);\n+\t\treturn status;\n+\t}\n \n-\treturn ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);\n+\tstatus = ice_dvm_update_dflt_recipes(hw);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to update default recipes for double VLAN mode, status %d\\n\",\n+\t\t\t  status);\n+\t\treturn status;\n+\t}\n+\n+\tstatus = ice_aq_set_port_params(hw->port_info, 0, false, false, true,\n+\t\t\t\t\tNULL);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to set port in double VLAN mode, status %d\\n\",\n+\t\t\t  status);\n+\t\treturn status;\n+\t}\n+\n+\treturn ICE_SUCCESS;\n }\n \n /**\n- * ice_init_vlan_mode_ops - initialize VLAN mode configuration ops\n+ * ice_set_svm - set single VLAN mode\n  * @hw: pointer to the HW structure\n  */\n-void ice_init_vlan_mode_ops(struct ice_hw *hw)\n+static enum ice_status ice_set_svm(struct ice_hw *hw)\n {\n-\thw->vlan_mode_ops.set_dvm = NULL;\n-\thw->vlan_mode_ops.set_svm = ice_set_svm_dflt;\n+\tstruct ice_aqc_set_vlan_mode *set_params;\n+\tenum ice_status status;\n+\n+\tstatus = ice_aq_set_port_params(hw->port_info, 0, false, false, false, NULL);\n+\tif (status) {\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to set port parameters for single VLAN mode\\n\");\n+\t\treturn status;\n+\t}\n+\n+\tset_params = (struct ice_aqc_set_vlan_mode *)\n+\t\tice_malloc(hw, sizeof(*set_params));\n+\tif (!set_params)\n+\t\treturn ICE_ERR_NO_MEMORY;\n+\n+\t/* default configuration for SVM configurations */\n+\tset_params->l2tag_prio_tagging = ICE_AQ_VLAN_PRIO_TAG_INNER_CTAG;\n+\tset_params->rdma_packet = ICE_AQ_SVM_VLAN_RDMA_PKT_FLAG_SETTING;\n+\tset_params->mng_vlan_prot_id = ICE_AQ_VLAN_MNG_PROTOCOL_ID_INNER;\n+\n+\tstatus = ice_aq_set_vlan_mode(hw, set_params);\n+\tif (status)\n+\t\tice_debug(hw, ICE_DBG_INIT, \"Failed to configure port in single VLAN mode\\n\");\n+\n+\tice_free(hw, set_params);\n+\treturn status;\n }\n \n /**\n@@ -107,16 +354,11 @@ void ice_init_vlan_mode_ops(struct ice_hw *hw)\n  */\n enum ice_status ice_set_vlan_mode(struct ice_hw *hw)\n {\n-\tenum ice_status status = ICE_ERR_NOT_IMPL;\n-\n \tif (!ice_is_dvm_supported(hw))\n \t\treturn ICE_SUCCESS;\n \n-\tif (hw->vlan_mode_ops.set_dvm)\n-\t\tstatus = hw->vlan_mode_ops.set_dvm(hw);\n-\n-\tif (status)\n-\t\treturn hw->vlan_mode_ops.set_svm(hw);\n+\tif (!ice_set_dvm(hw))\n+\t\treturn ICE_SUCCESS;\n \n-\treturn ICE_SUCCESS;\n+\treturn ice_set_svm(hw);\n }\ndiff --git a/drivers/net/ice/base/ice_vlan_mode.h b/drivers/net/ice/base/ice_vlan_mode.h\nindex 1b9db4d36f..134bd41635 100644\n--- a/drivers/net/ice/base/ice_vlan_mode.h\n+++ b/drivers/net/ice/base/ice_vlan_mode.h\n@@ -5,28 +5,12 @@\n #ifndef _ICE_VLAN_MODE_H_\n #define _ICE_VLAN_MODE_H_\n \n+#include \"ice_osdep.h\"\n+\n struct ice_hw;\n \n+bool ice_is_dvm_ena(struct ice_hw *hw);\n+void ice_cache_vlan_mode(struct ice_hw *hw);\n enum ice_status ice_set_vlan_mode(struct ice_hw *hw);\n-void ice_init_vlan_mode_ops(struct ice_hw *hw);\n-\n-/* This structure defines the VLAN mode configuration interface. It is used to set the VLAN mode.\n- *\n- * Note: These operations will be called while the global configuration lock is held.\n- *\n- * enum ice_status (*set_svm)(struct ice_hw *hw);\n- *\tThis function is called when the DDP and/or Firmware don't support double VLAN mode (DVM) or\n- *\tif the set_dvm op is not implemented and/or returns failure. It will set the device in\n- *\tsingle VLAN mode (SVM).\n- *\n- * enum ice_status (*set_dvm)(struct ice_hw *hw);\n- *\tThis function is called when the DDP and Firmware support double VLAN mode (DVM). It should\n- *\tbe implemented to set double VLAN mode. If it fails or remains unimplemented, set_svm will\n- *\tbe called as a fallback plan.\n- */\n-struct ice_vlan_mode_ops {\n-\tenum ice_status (*set_svm)(struct ice_hw *hw);\n-\tenum ice_status (*set_dvm)(struct ice_hw *hw);\n-};\n \n #endif /* _ICE_VLAN_MODE_H */\n",
    "prefixes": [
        "07/22"
    ]
}