get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 54598,
    "url": "http://patches.dpdk.org/api/patches/54598/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1560152324-20538-22-git-send-email-arybchenko@solarflare.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": "<1560152324-20538-22-git-send-email-arybchenko@solarflare.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1560152324-20538-22-git-send-email-arybchenko@solarflare.com",
    "date": "2019-06-10T07:38:36",
    "name": "[21/29] net/sfc/base: implement vSwitch create/destroy",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "5d66797e939cfc4b2801e38a00d8fa70535ceb3f",
    "submitter": {
        "id": 607,
        "url": "http://patches.dpdk.org/api/people/607/?format=api",
        "name": "Andrew Rybchenko",
        "email": "arybchenko@solarflare.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1560152324-20538-22-git-send-email-arybchenko@solarflare.com/mbox/",
    "series": [
        {
            "id": 4965,
            "url": "http://patches.dpdk.org/api/series/4965/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4965",
            "date": "2019-06-10T07:38:19",
            "name": "net/sfc/base: update base driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/4965/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/54598/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/54598/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 69C991BF0C;\n\tMon, 10 Jun 2019 09:39:26 +0200 (CEST)",
            "from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com\n\t[67.231.154.164]) by dpdk.org (Postfix) with ESMTP id C551D1BE99\n\tfor <dev@dpdk.org>; Mon, 10 Jun 2019 09:38:56 +0200 (CEST)",
            "from webmail.solarflare.com (webmail.solarflare.com\n\t[12.187.104.26])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby mx1-us5.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id\n\tD75084C0058\n\tfor <dev@dpdk.org>; Mon, 10 Jun 2019 07:38:55 +0000 (UTC)",
            "from ocex03.SolarFlarecom.com (10.20.40.36) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id 15.0.1395.4; Mon, 10 Jun 2019 00:38:51 -0700",
            "from opal.uk.solarflarecom.com (10.17.10.1) by\n\tocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server\n\t(TLS) id\n\t15.0.1395.4 via Frontend Transport; Mon, 10 Jun 2019 00:38:51 -0700",
            "from ukv-loginhost.uk.solarflarecom.com\n\t(ukv-loginhost.uk.solarflarecom.com [10.17.10.39])\n\tby opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id\n\tx5A7cou7008841; Mon, 10 Jun 2019 08:38:50 +0100",
            "from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1])\n\tby ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id\n\t0BEB01627D7; Mon, 10 Jun 2019 08:38:50 +0100 (BST)"
        ],
        "X-Virus-Scanned": "Proofpoint Essentials engine",
        "From": "Andrew Rybchenko <arybchenko@solarflare.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Gautam Dawar <gdawar@solarflare.com>",
        "Date": "Mon, 10 Jun 2019 08:38:36 +0100",
        "Message-ID": "<1560152324-20538-22-git-send-email-arybchenko@solarflare.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1560152324-20538-1-git-send-email-arybchenko@solarflare.com>",
        "References": "<1560152324-20538-1-git-send-email-arybchenko@solarflare.com>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "X-TM-AS-Product-Ver": "SMEX-12.5.0.1300-8.5.1010-24664.003",
        "X-TM-AS-Result": "No-7.145600-4.000000-10",
        "X-TMASE-MatchedRID": "+engLLOnT3btSrqhUiNirv3HILfxLV/969xONVZSrH3mWHHSYEnI8dWZ\n\tDZFp9sK+qHdHXw8EW4pTvVffeIwvQ8HVNeDWrWSGnFVnNmvv47vGzDycs+smMN9RlPzeVuQQqjq\n\tFxcD2zqTueEO1qlH4lCVURVaeV0Rggb1XSSpDa5DnZxuPj9aY+ytTx/ehjzxgj4jFvt2M5IKZu9\n\tGZpmUaWCqO1+vEcPReqb1YkDVelmHdXve1wYbDSiXTnAZkhKflQo4ZOAclX1K+GYmD5FwZEpKi/\n\t9O2b8wfIEbqlyPU4c5HhDA5WM1bF61mYT2CMxpdGjzBgnFZvQ66hgVvSdGKo3QWhLVqLFM1KDvv\n\tC6BqZx61DpGeEMqeQGzHwL0ty3zWGHO3b96QmYNAwvZYEy8IBdUtYzexhQ5/JLfQYoCQHFYTw7j\n\tCStQ0rmpecsbV1dfSKbxcKDI8Nr+9j8fJltl0iJ4CIKY/Hg3AGdQnQSTrKGPEQdG7H66TyMdRT5\n\tTQAJnAdDAOSXoybxqKeGZtJ2CYhChe8at/tBZ0IlAn8VS3Z3qeqD9WtJkSIw==",
        "X-TM-AS-User-Approved-Sender": "No",
        "X-TM-AS-User-Blocked-Sender": "No",
        "X-TMASE-Result": "10--7.145600-4.000000",
        "X-TMASE-Version": "SMEX-12.5.0.1300-8.5.1010-24664.003",
        "X-MDID": "1560152336-6kkX4IQLwkMf",
        "Subject": "[dpdk-dev] [PATCH 21/29] net/sfc/base: implement vSwitch\n\tcreate/destroy",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "From: Gautam Dawar <gdawar@solarflare.com>\n\nThe vSwitch create API takes an array of num_vports client driver\nallocated vPort config entries where entry at index 0 contains the PF\nconfiguration and rest num_vports-1 entries refer to vPort configuration\nfor VFs 0 to (num_vports-2). The required hierarchy\n(vswitch/vport/vadaptor) is created within this API. The destroy API\ntears down this hierarchy and releases memory for the vSwitch object.\n\nSigned-off-by: Gautam Dawar <gdawar@solarflare.com>\nSigned-off-by: Andrew Rybchenko <arybchenko@solarflare.com>\n---\n drivers/net/sfc/base/efx.h      |  40 ++++++\n drivers/net/sfc/base/efx_evb.c  | 269 +++++++++++++++++++++++++++++++++++++++-\n drivers/net/sfc/base/efx_impl.h |  16 +++\n 3 files changed, 324 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h\nindex 664efc8..492c8c6 100644\n--- a/drivers/net/sfc/base/efx.h\n+++ b/drivers/net/sfc/base/efx.h\n@@ -1411,6 +1411,9 @@ enum {\n \tuint32_t\t\tenc_assigned_port;\n } efx_nic_cfg_t;\n \n+#define\tEFX_VPORT_PCI_FUNCTION_IS_PF(configp) \\\n+\t((configp)->evc_function == 0xffff)\n+\n #define\tEFX_PCI_FUNCTION_IS_PF(_encp)\t((_encp)->enc_vf == 0xffff)\n #define\tEFX_PCI_FUNCTION_IS_VF(_encp)\t((_encp)->enc_vf != 0xffff)\n \n@@ -3369,6 +3372,31 @@ extern\t__checkReturn\t__success(return != B_FALSE)\tboolean_t\n #define\tEFX_FILTER_VID_UNSPEC\t0xffff\n #define\tEFX_DEFAULT_VSWITCH_ID\t1\n \n+/* Default VF VLAN ID on creation */\n+#define\t\tEFX_VF_VID_DEFAULT\tEFX_FILTER_VID_UNSPEC\n+#define\t\tEFX_VPORT_ID_INVALID\t0\n+\n+typedef struct efx_vport_config_s {\n+\t/* Either VF index or 0xffff for PF */\n+\tuint16_t\tevc_function;\n+\t/* VLAN ID of the associated function */\n+\tuint16_t\tevc_vid;\n+\t/* vport id shared with client driver */\n+\tefx_vport_id_t\tevc_vport_id;\n+\t/* MAC address of the associated function */\n+\tuint8_t\t\tevc_mac_addr[EFX_MAC_ADDR_LEN];\n+\t/*\n+\t * vports created with this flag set may only transfer traffic on the\n+\t * VLANs permitted by the vport. Also, an attempt to install filter with\n+\t * VLAN will be refused unless requesting function has VLAN privilege.\n+\t */\n+\tboolean_t\tevc_vlan_restrict;\n+\t/* Whether this function is assigned or not */\n+\tboolean_t\tevc_vport_assigned;\n+} efx_vport_config_t;\n+\n+typedef\tstruct\tefx_vswitch_s\tefx_vswitch_t;\n+\n extern\t__checkReturn\tefx_rc_t\n efx_evb_init(\n \t__in\t\tefx_nic_t *enp);\n@@ -3377,6 +3405,18 @@ extern\t__checkReturn\t__success(return != B_FALSE)\tboolean_t\n efx_evb_fini(\n \t__in\t\tefx_nic_t *enp);\n \n+extern\t__checkReturn\tefx_rc_t\n+efx_evb_vswitch_create(\n+\t__in\t\t\t\tefx_nic_t *enp,\n+\t__in\t\t\t\tuint32_t num_vports,\n+\t__inout_ecount(num_vports)\tefx_vport_config_t *vport_configp,\n+\t__deref_out\t\t\tefx_vswitch_t **evpp);\n+\n+extern\t__checkReturn\tefx_rc_t\n+efx_evb_vswitch_destroy(\n+\t__in\t\t\t\tefx_nic_t *enp,\n+\t__in\t\t\t\tefx_vswitch_t *evp);\n+\n #endif /* EFSYS_OPT_EVB */\n \n #ifdef\t__cplusplus\ndiff --git a/drivers/net/sfc/base/efx_evb.c b/drivers/net/sfc/base/efx_evb.c\nindex ff240f9..27b466f 100644\n--- a/drivers/net/sfc/base/efx_evb.c\n+++ b/drivers/net/sfc/base/efx_evb.c\n@@ -107,7 +107,7 @@\n \treturn (rc);\n }\n \n-\tvoid\n+\t\t\tvoid\n efx_evb_fini(\n \t__in\t\tefx_nic_t *enp)\n {\n@@ -125,4 +125,271 @@\n \tenp->en_mod_flags &= ~EFX_MOD_EVB;\n }\n \n+/*\n+ * efx_is_zero_eth_addr returns TRUE if the passed MAC address has all bytes\n+ * equal to zero. A vport is assigned a MAC address after creation and this\n+ * function checks if that has happened. It is called in the clean-up function\n+ * before calling eeo_vport_mac_addr_del to ensure that the vport actually had\n+ * an allocated MAC address.\n+ */\n+\n+__checkReturn\t\t\t\tboolean_t\n+efx_is_zero_eth_addr(\n+\t__in_bcount(EFX_MAC_ADDR_LEN)\tconst uint8_t *addrp)\n+{\n+\treturn (!(addrp[0] | addrp[1] | addrp[2] |\n+\t\taddrp[3] | addrp[4] | addrp[5]));\n+}\n+\n+static\t\t\tvoid\n+efx_evb_free_vport(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_vswitch_id_t vswitch_id,\n+\t__inout\t\tefx_vport_config_t *configp)\n+{\n+\tconst efx_evb_ops_t *eeop = enp->en_eeop;\n+\n+\t/* If any callback fails, continue clean-up with others functions */\n+\tif (EFX_VPORT_PCI_FUNCTION_IS_PF(configp)) {\n+\t\t/* free vadaptor */\n+\t\tif ((configp->evc_vport_id != EFX_VPORT_ID_INVALID) &&\n+\t\t    (eeop->eeo_vadaptor_free(enp, vswitch_id,\n+\t\t    configp->evc_vport_id) != 0)) {\n+\t\t\tEFSYS_PROBE2(eeo_vadaptor_free,\n+\t\t\t    uint16_t, configp->evc_function,\n+\t\t\t    uint32_t, configp->evc_vport_id);\n+\t\t}\n+\t} else {\n+\t\tif (configp->evc_vport_assigned == B_TRUE) {\n+\t\t\tif (eeop->eeo_vport_assign(enp, vswitch_id,\n+\t\t\t    EVB_PORT_ID_NULL,\n+\t\t\t    configp->evc_function) != 0) {\n+\t\t\t\tEFSYS_PROBE1(eeo_vport_assign,\n+\t\t\t\t    uint16_t, configp->evc_function);\n+\t\t\t}\n+\t\t\tconfigp->evc_vport_assigned = B_FALSE;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Call eeo_vport_mac_addr_del after checking that this vport is\n+\t * actually allocated a MAC address in call to efx_evb_configure_vport\n+\t */\n+\tif (!efx_is_zero_eth_addr(configp->evc_mac_addr)) {\n+\t\tif (eeop->eeo_vport_mac_addr_del(enp, vswitch_id,\n+\t\t    configp->evc_vport_id,\n+\t\t    configp->evc_mac_addr) != 0) {\n+\t\t\tEFSYS_PROBE1(eeo_vport_mac_addr_del,\n+\t\t\t    uint16_t, configp->evc_function);\n+\t\t}\n+\t\tmemset(configp->evc_mac_addr, 0x00, EFX_MAC_ADDR_LEN);\n+\t}\n+\n+\tif (configp->evc_vport_id != EFX_VPORT_ID_INVALID) {\n+\t\tif (eeop->eeo_vport_free(enp, vswitch_id,\n+\t\t    configp->evc_vport_id) != 0) {\n+\t\t\tEFSYS_PROBE1(eeo_vport_free,\n+\t\t\t    uint16_t, configp->evc_function);\n+\t\t}\n+\t\tconfigp->evc_vport_id = EFX_VPORT_ID_INVALID;\n+\t}\n+}\n+\n+static\t\t\t\t\tvoid\n+efx_evb_free_vports(\n+\t__in\t\t\t\tefx_nic_t *enp,\n+\t__in\t\t\t\tefx_vswitch_id_t vswitch_id,\n+\t__in\t\t\t\tuint32_t num_vports,\n+\t__inout_ecount(num_vports)\tefx_vport_config_t *vport_configp)\n+{\n+\tefx_vport_config_t *configp;\n+\tuint32_t i;\n+\n+\tif (vport_configp == NULL) {\n+\t\tEFSYS_PROBE(null_vport_config);\n+\t\treturn;\n+\t}\n+\n+\tfor (i = 0; i < num_vports; i++) {\n+\t\tconfigp = vport_configp + i;\n+\t\tefx_evb_free_vport(enp, vswitch_id, configp);\n+\t}\n+}\n+\n+static\t__checkReturn\tefx_rc_t\n+efx_evb_configure_vport(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_vswitch_id_t vswitch_id,\n+\t__in\t\tconst efx_evb_ops_t *eeop,\n+\t__inout\t\tefx_vport_config_t *configp)\n+{\n+\tefx_rc_t rc;\n+\tefx_vport_id_t vport_id;\n+\n+\tif ((rc = eeop->eeo_vport_alloc(enp, vswitch_id,\n+\t\t\tEFX_VPORT_TYPE_NORMAL, configp->evc_vid,\n+\t\t\tconfigp->evc_vlan_restrict, &vport_id)) != 0)\n+\t\tgoto fail1;\n+\n+\tconfigp->evc_vport_id = vport_id;\n+\n+\tif ((rc = eeop->eeo_vport_mac_addr_add(enp, vswitch_id,\n+\t\t\tconfigp->evc_vport_id,\n+\t\t\tconfigp->evc_mac_addr)) != 0)\n+\t\tgoto fail2;\n+\n+\tif (EFX_VPORT_PCI_FUNCTION_IS_PF(configp)) {\n+\t\tif ((rc = eeop->eeo_vadaptor_alloc(enp, vswitch_id,\n+\t\t\t\tconfigp->evc_vport_id)) != 0)\n+\t\t\tgoto fail3;\n+\t} else {\n+\t\tif ((rc = eeop->eeo_vport_assign(enp, vswitch_id,\n+\t\t\t\tconfigp->evc_vport_id,\n+\t\t\t\tconfigp->evc_function)) != 0)\n+\t\t\tgoto fail4;\n+\t\tconfigp->evc_vport_assigned = B_TRUE;\n+\t}\n+\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\t__checkReturn\t\t\tefx_rc_t\n+efx_evb_vswitch_create(\n+\t__in\t\t\t\tefx_nic_t *enp,\n+\t__in\t\t\t\tuint32_t num_vports,\n+\t__inout_ecount(num_vports)\tefx_vport_config_t *vport_configp,\n+\t__deref_out\t\t\tefx_vswitch_t **evpp)\n+{\n+\tefx_vswitch_t *evp;\n+\tefx_rc_t rc;\n+\tefx_vswitch_id_t vswitch_id;\n+\tefx_vport_config_t *configp;\n+\tconst efx_evb_ops_t *eeop = enp->en_eeop;\n+\tuint32_t i;\n+\n+\t/* vport_configp is a caller allocated array filled in with vports\n+\t * configuration. Index 0 carries the PF vport configuration and next\n+\t * num_vports - 1 indices carry VFs configuration.\n+\t */\n+\tEFSYS_ASSERT((num_vports != 0) && (vport_configp != NULL) &&\n+\t\t(evpp != NULL));\n+\tEFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_EVB);\n+\tEFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));\n+\n+\tif ((eeop->eeo_vswitch_alloc == NULL) ||\n+\t    (eeop->eeo_vport_alloc == NULL) ||\n+\t    (eeop->eeo_vport_free == NULL) ||\n+\t    (eeop->eeo_vport_mac_addr_add == NULL) ||\n+\t    (eeop->eeo_vport_mac_addr_del == NULL) ||\n+\t    (eeop->eeo_vadaptor_alloc == NULL) ||\n+\t    (eeop->eeo_vadaptor_free == NULL) ||\n+\t    (eeop->eeo_vport_assign == NULL) ||\n+\t    (eeop->eeo_vswitch_free == NULL)) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\t/* Allocate a vSwitch object */\n+\tEFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_vswitch_t), evp);\n+\n+\tif (evp == NULL) {\n+\t\trc = ENOMEM;\n+\t\tgoto fail2;\n+\t}\n+\n+\tif ((rc = eeop->eeo_vswitch_alloc(enp, &vswitch_id)) != 0)\n+\t\tgoto fail3;\n+\n+\tevp->ev_enp = enp;\n+\tevp->ev_num_vports = num_vports;\n+\tevp->ev_evcp = vport_configp;\n+\tevp->ev_vswitch_id = vswitch_id;\n+\n+\tfor (i = 0; i < num_vports; i++) {\n+\t\tconfigp = vport_configp + i;\n+\n+\t\tif ((rc = efx_evb_configure_vport(enp, vswitch_id, eeop,\n+\t\t\t\tconfigp)) != 0)\n+\t\t\tgoto fail4;\n+\t}\n+\n+\tenp->en_vswitchp = evp;\n+\t*evpp = evp;\n+\treturn (0);\n+\n+fail4:\n+\tEFSYS_PROBE(fail4);\n+\tefx_evb_free_vports(enp, vswitch_id, i + 1, vport_configp);\n+\t/* Free the vSwitch */\n+\teeop->eeo_vswitch_free(enp, vswitch_id);\n+\n+fail3:\n+\tEFSYS_PROBE(fail3);\n+\t/* Free the vSwitch object */\n+\tEFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_vswitch_t), evp);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\n+\treturn (rc);\n+}\n+\n+\n+\t__checkReturn\tefx_rc_t\n+efx_evb_vswitch_destroy(\n+\t__in\t\tefx_nic_t *enp,\n+\t__in\t\tefx_vswitch_t *evp)\n+{\n+\tconst efx_evb_ops_t *eeop = enp->en_eeop;\n+\tefx_vswitch_id_t vswitch_id;\n+\tefx_rc_t rc;\n+\n+\tEFSYS_ASSERT(evp != NULL);\n+\tEFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_EVB);\n+\n+\tif ((eeop->eeo_vport_mac_addr_del == NULL) ||\n+\t    (eeop->eeo_vadaptor_free == NULL) ||\n+\t    (eeop->eeo_vport_assign == NULL) ||\n+\t    (eeop->eeo_vport_free == NULL) ||\n+\t    (eeop->eeo_vswitch_free == NULL)) {\n+\t\trc = ENOTSUP;\n+\t\tgoto fail1;\n+\t}\n+\n+\tvswitch_id  = evp->ev_vswitch_id;\n+\tefx_evb_free_vports(enp, vswitch_id,\n+\t\tevp->ev_num_vports, evp->ev_evcp);\n+\n+\t/* Free the vSwitch object */\n+\tEFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_vswitch_t), evp);\n+\tenp->en_vswitchp = NULL;\n+\n+\t/* Free the vSwitch */\n+\tif ((rc = eeop->eeo_vswitch_free(enp, vswitch_id)) != 0)\n+\t\tgoto fail2;\n+\n+\treturn (0);\n+\n+fail2:\n+\tEFSYS_PROBE(fail2);\n+\n+fail1:\n+\tEFSYS_PROBE1(fail1, efx_rc_t, rc);\n+\treturn (rc);\n+}\n+\n #endif\ndiff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h\nindex ef6a97a..46d5389 100644\n--- a/drivers/net/sfc/base/efx_impl.h\n+++ b/drivers/net/sfc/base/efx_impl.h\n@@ -652,6 +652,17 @@\n \n #if EFSYS_OPT_EVB\n \n+struct efx_vswitch_s {\n+\tefx_nic_t\t\t*ev_enp;\n+\tefx_vswitch_id_t\tev_vswitch_id;\n+\tuint32_t\t\tev_num_vports;\n+\t/*\n+\t * Vport configuration array: index 0 to store PF configuration\n+\t * and next ev_num_vports-1 entries hold VFs configuration.\n+\t */\n+\tefx_vport_config_t\t*ev_evcp;\n+};\n+\n typedef struct efx_evb_ops_s {\n \tefx_rc_t\t(*eeo_init)(efx_nic_t *);\n \tvoid\t\t(*eeo_fini)(efx_nic_t *);\n@@ -674,6 +685,10 @@\n \t\t\t\t\t\tefx_vport_id_t, uint32_t);\n } efx_evb_ops_t;\n \n+extern __checkReturn\tboolean_t\n+efx_is_zero_eth_addr(\n+\t__in_bcount(EFX_MAC_ADDR_LEN)\tconst uint8_t *addrp);\n+\n #endif /* EFSYS_OPT_EVB */\n \n #define\tEFX_DRV_VER_MAX\t\t20\n@@ -776,6 +791,7 @@ struct efx_nic_s {\n #endif\t/* EFX_OPTS_EF10() */\n #if EFSYS_OPT_EVB\n \tconst efx_evb_ops_t\t*en_eeop;\n+\tstruct efx_vswitch_s    *en_vswitchp;\n #endif\t/* EFSYS_OPT_EVB */\n };\n \n",
    "prefixes": [
        "21/29"
    ]
}