get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 86767,
    "url": "http://patchwork.dpdk.org/api/patches/86767/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210118082408.82713-1-haiyue.wang@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": "<20210118082408.82713-1-haiyue.wang@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210118082408.82713-1-haiyue.wang@intel.com",
    "date": "2021-01-18T08:24:08",
    "name": "[v1] net/ice: refactor DCF VLAN handling",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "129edde255a0384ce443f35ba010569c22f3b618",
    "submitter": {
        "id": 1044,
        "url": "http://patchwork.dpdk.org/api/people/1044/?format=api",
        "name": "Wang, Haiyue",
        "email": "haiyue.wang@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/20210118082408.82713-1-haiyue.wang@intel.com/mbox/",
    "series": [
        {
            "id": 14804,
            "url": "http://patchwork.dpdk.org/api/series/14804/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=14804",
            "date": "2021-01-18T08:24:08",
            "name": "[v1] net/ice: refactor DCF VLAN handling",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/14804/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/86767/comments/",
    "check": "fail",
    "checks": "http://patchwork.dpdk.org/api/patches/86767/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 C86A6A0A03;\n\tMon, 18 Jan 2021 09:40:10 +0100 (CET)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 8AEB7140D73;\n\tMon, 18 Jan 2021 09:40:10 +0100 (CET)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n by mails.dpdk.org (Postfix) with ESMTP id BBBC9140D6C\n for <dev@dpdk.org>; Mon, 18 Jan 2021 09:40:07 +0100 (CET)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Jan 2021 00:39:59 -0800",
            "from npg-dpdk-haiyue-3.sh.intel.com ([10.67.118.189])\n by orsmga008.jf.intel.com with ESMTP; 18 Jan 2021 00:39:57 -0800"
        ],
        "IronPort-SDR": [
            "\n Ykd1TTiJd5EzRwY7OBTpSssR/BGNHU0Z0FqL7xbGuCc9gb9mlYOASJR4GI0ikQh7Ph5EgU2PRg\n hFRGdF4BuK5A==",
            "\n QSFEyg2S2c64iTOr5HvP1yk8nogEKwwMIJV16xuzHxO5XYmUlF4UcynoM9ubPDPavpJVzknG6r\n dwFecbaBgjVA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6000,8403,9867\"; a=\"240317225\"",
            "E=Sophos;i=\"5.79,355,1602572400\"; d=\"scan'208\";a=\"240317225\"",
            "E=Sophos;i=\"5.79,355,1602572400\"; d=\"scan'208\";a=\"383493104\""
        ],
        "X-ExtLoop1": "1",
        "From": "Haiyue Wang <haiyue.wang@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "qiming.yang@intel.com, qi.z.zhang@intel.com, qi.fu@intel.com,\n Haiyue Wang <haiyue.wang@intel.com>",
        "Date": "Mon, 18 Jan 2021 16:24:08 +0800",
        "Message-Id": "<20210118082408.82713-1-haiyue.wang@intel.com>",
        "X-Mailer": "git-send-email 2.30.0",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[dpdk-dev] [PATCH v1] net/ice: refactor DCF VLAN handling",
        "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": "Since DCF always configure the outer VLAN offloads for the target AVF,\nso rename the related variables to align with this design.\n\nAlso, the DCF needs to trace the AVF reset status to re-apply the VLAN\noffload setting, refactor the reset event handling to support this.\n\nChange the VF representor API 'ethdev' parameter to 'vf_rep_eth_dev' to\navoid introducing confusion with VF representor eth_dev ops name.\n\nSigned-off-by: Haiyue Wang <haiyue.wang@intel.com>\n---\n drivers/net/ice/ice_dcf_ethdev.c         |  47 ++++-\n drivers/net/ice/ice_dcf_ethdev.h         |  23 ++-\n drivers/net/ice/ice_dcf_parent.c         |  62 +++++--\n drivers/net/ice/ice_dcf_vf_representor.c | 218 +++++++++++++++++++----\n 4 files changed, 298 insertions(+), 52 deletions(-)",
    "diff": "diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c\nindex a9e78064d..f9025d189 100644\n--- a/drivers/net/ice/ice_dcf_ethdev.c\n+++ b/drivers/net/ice/ice_dcf_ethdev.c\n@@ -601,6 +601,9 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev)\n \t\treturn 0;\n \t}\n \n+\t/* Stop the VF representors for this device */\n+\tice_dcf_vf_repr_stop_all(dcf_ad);\n+\n \tice_dcf_stop_queues(dev);\n \n \trte_intr_efd_disable(intr_handle);\n@@ -849,6 +852,30 @@ ice_dcf_stats_reset(struct rte_eth_dev *dev)\n \treturn 0;\n }\n \n+static void\n+ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)\n+{\n+\tif (dcf_adapter->repr_infos) {\n+\t\trte_free(dcf_adapter->repr_infos);\n+\t\tdcf_adapter->repr_infos = NULL;\n+\t}\n+}\n+\n+static int\n+ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter)\n+{\n+\tdcf_adapter->repr_infos =\n+\t\t\trte_calloc(\"ice_dcf_rep_info\",\n+\t\t\t\t   dcf_adapter->real_hw.num_vfs,\n+\t\t\t\t   sizeof(dcf_adapter->repr_infos[0]), 0);\n+\tif (!dcf_adapter->repr_infos) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to alloc memory for VF representors\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int\n ice_dcf_dev_close(struct rte_eth_dev *dev)\n {\n@@ -857,6 +884,7 @@ ice_dcf_dev_close(struct rte_eth_dev *dev)\n \tif (rte_eal_process_type() != RTE_PROC_PRIMARY)\n \t\treturn 0;\n \n+\tice_dcf_free_repr_info(adapter);\n \tice_dcf_uninit_parent_adapter(dev);\n \tice_dcf_uninit_hw(dev, &adapter->real_hw);\n \n@@ -1000,21 +1028,26 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,\n \t\treturn -ENODEV;\n \n \tdcf_adapter = dcf_ethdev->data->dev_private;\n+\tret = ice_dcf_init_repr_info(dcf_adapter);\n+\tif (ret)\n+\t\treturn ret;\n \n \tif (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs ||\n \t    eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) {\n \t\tPMD_DRV_LOG(ERR, \"the number of port representors is too large: %u\",\n \t\t\t    eth_da.nb_representor_ports);\n+\t\tice_dcf_free_repr_info(dcf_adapter);\n \t\treturn -EINVAL;\n \t}\n \n \tdcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID;\n \n-\trepr_param.adapter = dcf_adapter;\n+\trepr_param.dcf_eth_dev = dcf_ethdev;\n \trepr_param.switch_domain_id = 0;\n \n \tfor (i = 0; i < eth_da.nb_representor_ports; i++) {\n \t\tuint16_t vf_id = eth_da.representor_ports[i];\n+\t\tstruct rte_eth_dev *vf_rep_eth_dev;\n \n \t\tif (vf_id >= dcf_adapter->real_hw.num_vfs) {\n \t\t\tPMD_DRV_LOG(ERR, \"VF ID %u is out of range (0 ~ %u)\",\n@@ -1041,6 +1074,18 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,\n \t\t\t\t    repr_name);\n \t\t\tbreak;\n \t\t}\n+\n+\t\tvf_rep_eth_dev = rte_eth_dev_allocated(repr_name);\n+\t\tif (!vf_rep_eth_dev) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Failed to find the ethdev for DCF VF representor: %s\",\n+\t\t\t\t    repr_name);\n+\t\t\tret = -ENODEV;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tdcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev;\n+\t\tdcf_adapter->num_reprs++;\n \t}\n \n \treturn ret;\ndiff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h\nindex 7695815e1..e7c9d7fe4 100644\n--- a/drivers/net/ice/ice_dcf_ethdev.h\n+++ b/drivers/net/ice/ice_dcf_ethdev.h\n@@ -17,30 +17,39 @@ struct ice_dcf_queue {\n \tuint64_t dummy;\n };\n \n+struct ice_dcf_repr_info {\n+\tstruct rte_eth_dev *vf_rep_eth_dev;\n+};\n+\n struct ice_dcf_adapter {\n \tstruct ice_adapter parent; /* Must be first */\n \tstruct ice_dcf_hw real_hw;\n+\n+\tint num_reprs;\n+\tstruct ice_dcf_repr_info *repr_infos;\n };\n \n struct ice_dcf_vf_repr_param {\n-\tstruct ice_dcf_adapter *adapter;\n+\tstruct rte_eth_dev *dcf_eth_dev;\n \tuint16_t switch_domain_id;\n \tuint16_t vf_id;\n };\n \n struct ice_dcf_vlan {\n+\tbool port_vlan_ena;\n+\tbool stripping_ena;\n+\n \tuint16_t tpid;\n \tuint16_t vid;\n };\n \n struct ice_dcf_vf_repr {\n-\tstruct ice_dcf_adapter *dcf_adapter;\n+\tstruct rte_eth_dev *dcf_eth_dev;\n \tstruct rte_ether_addr mac_addr;\n \tuint16_t switch_domain_id;\n \tuint16_t vf_id;\n \n-\tbool port_vlan_ena;\n-\tstruct ice_dcf_vlan port_vlan_info;\n+\tstruct ice_dcf_vlan outer_vlan_info; /* DCF always handle outer VLAN */\n };\n \n void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n@@ -48,7 +57,9 @@ void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev);\n void ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev);\n \n-int ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param);\n-int ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev);\n+int ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param);\n+int ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev);\n+int ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev);\n+void ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter);\n \n #endif /* _ICE_DCF_ETHDEV_H_ */\ndiff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c\nindex 7d565028f..ddf24d3f8 100644\n--- a/drivers/net/ice/ice_dcf_parent.c\n+++ b/drivers/net/ice/ice_dcf_parent.c\n@@ -14,6 +14,13 @@\n #define ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL\t100000 /* us */\n static rte_spinlock_t vsi_update_lock = RTE_SPINLOCK_INITIALIZER;\n \n+struct ice_dcf_reset_event_param {\n+\tstruct ice_dcf_hw *dcf_hw;\n+\n+\tbool vfr; /* VF reset event */\n+\tuint16_t vf_id; /* The reset VF ID */\n+};\n+\n static __rte_always_inline void\n ice_dcf_update_vsi_ctx(struct ice_hw *hw, uint16_t vsi_handle,\n \t\t       uint16_t vsi_map)\n@@ -110,31 +117,67 @@ ice_dcf_update_pf_vsi_map(struct ice_hw *hw, uint16_t pf_vsi_idx,\n static void*\n ice_dcf_vsi_update_service_handler(void *param)\n {\n-\tstruct ice_dcf_hw *hw = param;\n+\tstruct ice_dcf_reset_event_param *reset_param = param;\n+\tstruct ice_dcf_hw *hw = reset_param->dcf_hw;\n+\tstruct ice_dcf_adapter *adapter;\n \n \tusleep(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL);\n \n \trte_spinlock_lock(&vsi_update_lock);\n \n-\tif (!ice_dcf_handle_vsi_update_event(hw)) {\n-\t\tstruct ice_dcf_adapter *dcf_ad =\n-\t\t\tcontainer_of(hw, struct ice_dcf_adapter, real_hw);\n+\tadapter = container_of(hw, struct ice_dcf_adapter, real_hw);\n \n-\t\tice_dcf_update_vf_vsi_map(&dcf_ad->parent.hw,\n+\tif (!ice_dcf_handle_vsi_update_event(hw))\n+\t\tice_dcf_update_vf_vsi_map(&adapter->parent.hw,\n \t\t\t\t\t  hw->num_vfs, hw->vf_vsi_map);\n+\n+\tif (reset_param->vfr && adapter->repr_infos) {\n+\t\tstruct rte_eth_dev *vf_rep_eth_dev =\n+\t\t\tadapter->repr_infos[reset_param->vf_id].vf_rep_eth_dev;\n+\t\tif (vf_rep_eth_dev && vf_rep_eth_dev->data->dev_started) {\n+\t\t\tPMD_DRV_LOG(ERR, \"VF representor %u is resetting\",\n+\t\t\t\t    reset_param->vf_id);\n+\t\t\tice_dcf_vf_repr_init_vlan(vf_rep_eth_dev);\n+\t\t}\n \t}\n \n \trte_spinlock_unlock(&vsi_update_lock);\n \n+\tfree(param);\n+\n \treturn NULL;\n }\n \n+static void\n+start_vsi_reset_thread(struct ice_dcf_hw *dcf_hw, bool vfr, uint16_t vf_id)\n+{\n+\tstruct ice_dcf_reset_event_param *param;\n+\tpthread_t thread;\n+\tint ret;\n+\n+\tparam = malloc(sizeof(*param));\n+\tif (!param) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to allocate the memory for reset handling\");\n+\t\treturn;\n+\t}\n+\n+\tparam->dcf_hw = dcf_hw;\n+\tparam->vfr = vfr;\n+\tparam->vf_id = vf_id;\n+\n+\tret = pthread_create(&thread, NULL,\n+\t\t\t     ice_dcf_vsi_update_service_handler, param);\n+\tif (ret) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to start the thread for reset handling\");\n+\t\tfree(param);\n+\t}\n+}\n+\n void\n ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n \t\t\t    uint8_t *msg, uint16_t msglen)\n {\n \tstruct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg;\n-\tpthread_t thread;\n \n \tif (msglen < sizeof(struct virtchnl_pf_event)) {\n \t\tPMD_DRV_LOG(DEBUG, \"Invalid event message length : %u\", msglen);\n@@ -144,8 +187,7 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n \tswitch (pf_msg->event) {\n \tcase VIRTCHNL_EVENT_RESET_IMPENDING:\n \t\tPMD_DRV_LOG(DEBUG, \"VIRTCHNL_EVENT_RESET_IMPENDING event\");\n-\t\tpthread_create(&thread, NULL,\n-\t\t\t       ice_dcf_vsi_update_service_handler, dcf_hw);\n+\t\tstart_vsi_reset_thread(dcf_hw, false, 0);\n \t\tbreak;\n \tcase VIRTCHNL_EVENT_LINK_CHANGE:\n \t\tPMD_DRV_LOG(DEBUG, \"VIRTCHNL_EVENT_LINK_CHANGE event\");\n@@ -157,8 +199,8 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,\n \t\tPMD_DRV_LOG(DEBUG, \"VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE event : VF%u with VSI num %u\",\n \t\t\t    pf_msg->event_data.vf_vsi_map.vf_id,\n \t\t\t    pf_msg->event_data.vf_vsi_map.vsi_id);\n-\t\tpthread_create(&thread, NULL,\n-\t\t\t       ice_dcf_vsi_update_service_handler, dcf_hw);\n+\t\tstart_vsi_reset_thread(dcf_hw, true,\n+\t\t\t\t       pf_msg->event_data.vf_vsi_map.vf_id);\n \t\tbreak;\n \tdefault:\n \t\tPMD_DRV_LOG(ERR, \"Unknown event received %u\", pf_msg->event);\ndiff --git a/drivers/net/ice/ice_dcf_vf_representor.c b/drivers/net/ice/ice_dcf_vf_representor.c\nindex 09ca4df5a..970461f3e 100644\n--- a/drivers/net/ice/ice_dcf_vf_representor.c\n+++ b/drivers/net/ice/ice_dcf_vf_representor.c\n@@ -27,8 +27,10 @@ ice_dcf_vf_repr_tx_burst(__rte_unused void *txq,\n }\n \n static int\n-ice_dcf_vf_repr_dev_configure(__rte_unused struct rte_eth_dev *dev)\n+ice_dcf_vf_repr_dev_configure(struct rte_eth_dev *dev)\n {\n+\tice_dcf_vf_repr_init_vlan(dev);\n+\n \treturn 0;\n }\n \n@@ -106,13 +108,21 @@ ice_dcf_vf_repr_link_update(__rte_unused struct rte_eth_dev *ethdev,\n \treturn 0;\n }\n \n+static __rte_always_inline struct ice_dcf_hw *\n+ice_dcf_vf_repr_hw(struct ice_dcf_vf_repr *repr)\n+{\n+\tstruct ice_dcf_adapter *dcf_adapter =\n+\t\t\trepr->dcf_eth_dev->data->dev_private;\n+\n+\treturn &dcf_adapter->real_hw;\n+}\n+\n static int\n ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,\n \t\t\t     struct rte_eth_dev_info *dev_info)\n {\n \tstruct ice_dcf_vf_repr *repr = dev->data->dev_private;\n-\tstruct ice_dcf_hw *dcf_hw =\n-\t\t\t\t&repr->dcf_adapter->real_hw;\n+\tstruct ice_dcf_hw *dcf_hw = ice_dcf_vf_repr_hw(repr);\n \n \tdev_info->device = dev->device;\n \tdev_info->max_mac_addrs = 1;\n@@ -190,25 +200,82 @@ ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,\n \treturn 0;\n }\n \n+static __rte_always_inline bool\n+ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)\n+{\n+\treturn !!(ice_dcf_vf_repr_hw(repr)->vf_res->vf_cap_flags &\n+\t\t  VIRTCHNL_VF_OFFLOAD_VLAN_V2);\n+}\n+\n static int\n ice_dcf_vlan_offload_config(struct ice_dcf_vf_repr *repr,\n \t\t\t    struct virtchnl_dcf_vlan_offload *vlan_offload)\n {\n \tstruct dcf_virtchnl_cmd args;\n+\tint err;\n \n \tmemset(&args, 0, sizeof(args));\n \targs.v_op = VIRTCHNL_OP_DCF_VLAN_OFFLOAD;\n \targs.req_msg = (uint8_t *)vlan_offload;\n \targs.req_msglen = sizeof(*vlan_offload);\n \n-\treturn ice_dcf_execute_virtchnl_cmd(&repr->dcf_adapter->real_hw, &args);\n+\terr = ice_dcf_execute_virtchnl_cmd(ice_dcf_vf_repr_hw(repr), &args);\n+\tif (err)\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Failed to execute command of VIRTCHNL_OP_DCF_VLAN_OFFLOAD\");\n+\n+\treturn err;\n }\n \n-static __rte_always_inline bool\n-ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)\n+static int\n+ice_dcf_vf_repr_vlan_offload_set(struct rte_eth_dev *dev, int mask)\n {\n-\treturn !!(repr->dcf_adapter->real_hw.vf_res->vf_cap_flags &\n-\t\t  VIRTCHNL_VF_OFFLOAD_VLAN_V2);\n+\tstruct ice_dcf_vf_repr *repr = dev->data->dev_private;\n+\tstruct rte_eth_conf *dev_conf = &dev->data->dev_conf;\n+\tstruct virtchnl_dcf_vlan_offload vlan_offload;\n+\tint err;\n+\n+\tif (!ice_dcf_vlan_offload_ena(repr))\n+\t\treturn -ENOTSUP;\n+\n+\t/* Vlan stripping setting */\n+\tif (mask & ETH_VLAN_STRIP_MASK) {\n+\t\tbool enable = !!(dev_conf->rxmode.offloads &\n+\t\t\t\t DEV_RX_OFFLOAD_VLAN_STRIP);\n+\n+\t\tif (enable && repr->outer_vlan_info.port_vlan_ena) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Disable the port VLAN firstly\\n\");\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tmemset(&vlan_offload, 0, sizeof(vlan_offload));\n+\n+\t\tif (enable)\n+\t\t\tvlan_offload.vlan_flags =\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_STRIP_INTO_RX_DESC <<\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_STRIP_MODE_S;\n+\t\telse if (repr->outer_vlan_info.stripping_ena && !enable)\n+\t\t\tvlan_offload.vlan_flags =\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_STRIP_DISABLE <<\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_STRIP_MODE_S;\n+\n+\t\tif (vlan_offload.vlan_flags) {\n+\t\t\tvlan_offload.vf_id = repr->vf_id;\n+\t\t\tvlan_offload.tpid = repr->outer_vlan_info.tpid;\n+\t\t\tvlan_offload.vlan_flags |=\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_TYPE_OUTER <<\n+\t\t\t\t\tVIRTCHNL_DCF_VLAN_TYPE_S;\n+\n+\t\t\terr = ice_dcf_vlan_offload_config(repr, &vlan_offload);\n+\t\t\tif (err)\n+\t\t\t\treturn -EIO;\n+\n+\t\t\trepr->outer_vlan_info.stripping_ena = enable;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n }\n \n static int\n@@ -222,26 +289,39 @@ ice_dcf_vf_repr_vlan_pvid_set(struct rte_eth_dev *dev,\n \tif (!ice_dcf_vlan_offload_ena(repr))\n \t\treturn -ENOTSUP;\n \n-\tif (on && (pvid == 0 || pvid > RTE_ETHER_MAX_VLAN_ID))\n+\tif (repr->outer_vlan_info.stripping_ena) {\n+\t\tPMD_DRV_LOG(ERR,\n+\t\t\t    \"Disable the VLAN stripping firstly\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (pvid > RTE_ETHER_MAX_VLAN_ID)\n \t\treturn -EINVAL;\n \n \tmemset(&vlan_offload, 0, sizeof(vlan_offload));\n \n+\tif (on)\n+\t\tvlan_offload.vlan_flags =\n+\t\t\t\t(VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<\n+\t\t\t\t VIRTCHNL_DCF_VLAN_INSERT_MODE_S);\n+\telse\n+\t\tvlan_offload.vlan_flags =\n+\t\t\t\t(VIRTCHNL_DCF_VLAN_INSERT_DISABLE <<\n+\t\t\t\t VIRTCHNL_DCF_VLAN_INSERT_MODE_S);\n+\n \tvlan_offload.vf_id = repr->vf_id;\n-\tvlan_offload.tpid = repr->port_vlan_info.tpid;\n-\tvlan_offload.vlan_flags = (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<\n-\t\t\t\t   VIRTCHNL_DCF_VLAN_TYPE_S) |\n-\t\t\t\t  (VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<\n-\t\t\t\t   VIRTCHNL_DCF_VLAN_INSERT_MODE_S);\n-\tvlan_offload.vlan_id = on ? pvid : 0;\n+\tvlan_offload.tpid = repr->outer_vlan_info.tpid;\n+\tvlan_offload.vlan_flags |= (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<\n+\t\t\t\t    VIRTCHNL_DCF_VLAN_TYPE_S);\n+\tvlan_offload.vlan_id = pvid;\n \n \terr = ice_dcf_vlan_offload_config(repr, &vlan_offload);\n \tif (!err) {\n \t\tif (on) {\n-\t\t\trepr->port_vlan_ena = true;\n-\t\t\trepr->port_vlan_info.vid = pvid;\n+\t\t\trepr->outer_vlan_info.port_vlan_ena = true;\n+\t\t\trepr->outer_vlan_info.vid = pvid;\n \t\t} else {\n-\t\t\trepr->port_vlan_ena = false;\n+\t\t\trepr->outer_vlan_info.port_vlan_ena = false;\n \t\t}\n \t}\n \n@@ -272,13 +352,32 @@ ice_dcf_vf_repr_vlan_tpid_set(struct rte_eth_dev *dev,\n \t\treturn -EINVAL;\n \t}\n \n-\trepr->port_vlan_info.tpid = tpid;\n+\trepr->outer_vlan_info.tpid = tpid;\n \n-\tif (repr->port_vlan_ena)\n+\tif (repr->outer_vlan_info.port_vlan_ena) {\n \t\terr = ice_dcf_vf_repr_vlan_pvid_set(dev,\n-\t\t\t\t\t\t    repr->port_vlan_info.vid,\n+\t\t\t\t\t\t    repr->outer_vlan_info.vid,\n \t\t\t\t\t\t    true);\n-\treturn err;\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Failed to reset port VLAN : %d\\n\",\n+\t\t\t\t    err);\n+\t\t\treturn err;\n+\t\t}\n+\t}\n+\n+\tif (repr->outer_vlan_info.stripping_ena) {\n+\t\terr = ice_dcf_vf_repr_vlan_offload_set(dev,\n+\t\t\t\t\t\t       ETH_VLAN_STRIP_MASK);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR,\n+\t\t\t\t    \"Failed to reset VLAN stripping : %d\\n\",\n+\t\t\t\t    err);\n+\t\t\treturn err;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n }\n \n static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {\n@@ -294,31 +393,33 @@ static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {\n \t.allmulticast_enable  = ice_dcf_vf_repr_allmulticast_enable,\n \t.allmulticast_disable = ice_dcf_vf_repr_allmulticast_disable,\n \t.link_update          = ice_dcf_vf_repr_link_update,\n+\t.vlan_offload_set     = ice_dcf_vf_repr_vlan_offload_set,\n \t.vlan_pvid_set        = ice_dcf_vf_repr_vlan_pvid_set,\n \t.vlan_tpid_set        = ice_dcf_vf_repr_vlan_tpid_set,\n };\n \n int\n-ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)\n+ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param)\n {\n-\tstruct ice_dcf_vf_repr *repr = ethdev->data->dev_private;\n+\tstruct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;\n \tstruct ice_dcf_vf_repr_param *param = init_param;\n \n-\trepr->dcf_adapter = param->adapter;\n+\trepr->dcf_eth_dev = param->dcf_eth_dev;\n \trepr->switch_domain_id = param->switch_domain_id;\n \trepr->vf_id = param->vf_id;\n-\trepr->port_vlan_ena = false;\n-\trepr->port_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;\n+\trepr->outer_vlan_info.port_vlan_ena = false;\n+\trepr->outer_vlan_info.stripping_ena = false;\n+\trepr->outer_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;\n \n-\tethdev->dev_ops = &ice_dcf_vf_repr_dev_ops;\n+\tvf_rep_eth_dev->dev_ops = &ice_dcf_vf_repr_dev_ops;\n \n-\tethdev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;\n-\tethdev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;\n+\tvf_rep_eth_dev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;\n+\tvf_rep_eth_dev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;\n \n-\tethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;\n-\tethdev->data->representor_id = repr->vf_id;\n+\tvf_rep_eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;\n+\tvf_rep_eth_dev->data->representor_id = repr->vf_id;\n \n-\tethdev->data->mac_addrs = &repr->mac_addr;\n+\tvf_rep_eth_dev->data->mac_addrs = &repr->mac_addr;\n \n \trte_eth_random_addr(repr->mac_addr.addr_bytes);\n \n@@ -326,9 +427,56 @@ ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)\n }\n \n int\n-ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev)\n+ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev)\n {\n-\tethdev->data->mac_addrs = NULL;\n+\tvf_rep_eth_dev->data->mac_addrs = NULL;\n \n \treturn 0;\n }\n+\n+int\n+ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev)\n+{\n+\tstruct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;\n+\tint err;\n+\n+\terr = ice_dcf_vf_repr_vlan_offload_set(vf_rep_eth_dev,\n+\t\t\t\t\t       ETH_VLAN_STRIP_MASK);\n+\tif (err) {\n+\t\tPMD_DRV_LOG(ERR, \"Failed to set VLAN offload\");\n+\t\treturn err;\n+\t}\n+\n+\tif (repr->outer_vlan_info.port_vlan_ena) {\n+\t\terr = ice_dcf_vf_repr_vlan_pvid_set(vf_rep_eth_dev,\n+\t\t\t\t\t\t    repr->outer_vlan_info.vid,\n+\t\t\t\t\t\t    true);\n+\t\tif (err) {\n+\t\t\tPMD_DRV_LOG(ERR, \"Failed to enable port VLAN\");\n+\t\t\treturn err;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+void\n+ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter)\n+{\n+\tuint16_t vf_id;\n+\tint ret;\n+\n+\tif (!dcf_adapter->repr_infos)\n+\t\treturn;\n+\n+\tfor (vf_id = 0; vf_id < dcf_adapter->real_hw.num_vfs; vf_id++) {\n+\t\tstruct rte_eth_dev *vf_rep_eth_dev =\n+\t\t\t\tdcf_adapter->repr_infos[vf_id].vf_rep_eth_dev;\n+\t\tif (!vf_rep_eth_dev || vf_rep_eth_dev->data->dev_started == 0)\n+\t\t\tcontinue;\n+\n+\t\tret = ice_dcf_vf_repr_dev_stop(vf_rep_eth_dev);\n+\t\tif (!ret)\n+\t\t\tvf_rep_eth_dev->data->dev_started = 0;\n+\t}\n+}\n",
    "prefixes": [
        "v1"
    ]
}