get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64973,
    "url": "http://patches.dpdk.org/api/patches/64973/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-38-git-send-email-matan@mellanox.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": "<1579539790-3882-38-git-send-email-matan@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1579539790-3882-38-git-send-email-matan@mellanox.com",
    "date": "2020-01-20T17:03:09",
    "name": "[v1,37/38] common/mlx5: support ROCE disable through Netlink",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "de02ed9924ef980b449e96ff75b9a0d3cdb0d791",
    "submitter": {
        "id": 796,
        "url": "http://patches.dpdk.org/api/people/796/?format=api",
        "name": "Matan Azrad",
        "email": "matan@mellanox.com"
    },
    "delegate": {
        "id": 2642,
        "url": "http://patches.dpdk.org/api/users/2642/?format=api",
        "username": "mcoquelin",
        "first_name": "Maxime",
        "last_name": "Coquelin",
        "email": "maxime.coquelin@redhat.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1579539790-3882-38-git-send-email-matan@mellanox.com/mbox/",
    "series": [
        {
            "id": 8223,
            "url": "http://patches.dpdk.org/api/series/8223/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8223",
            "date": "2020-01-20T17:02:37",
            "name": "Introduce mlx5 vDPA driver",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/8223/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/64973/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/64973/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 dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BE736A0526;\n\tMon, 20 Jan 2020 18:10:12 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 3139B1C10B;\n\tMon, 20 Jan 2020 18:04:17 +0100 (CET)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by dpdk.org (Postfix) with ESMTP id EC0CF1BF75\n for <dev@dpdk.org>; Mon, 20 Jan 2020 18:03:14 +0100 (CET)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n asafp@mellanox.com)\n with ESMTPS (AES256-SHA encrypted); 20 Jan 2020 19:03:14 +0200",
            "from pegasus07.mtr.labs.mlnx (pegasus07.mtr.labs.mlnx\n [10.210.16.112])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 00KH3BGu024424;\n Mon, 20 Jan 2020 19:03:14 +0200"
        ],
        "From": "Matan Azrad <matan@mellanox.com>",
        "To": "dev@dpdk.org",
        "Cc": "Maxime Coquelin <maxime.coquelin@redhat.com>,\n Thomas Monjalon <thomas@monjalon.net>",
        "Date": "Mon, 20 Jan 2020 17:03:09 +0000",
        "Message-Id": "<1579539790-3882-38-git-send-email-matan@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "References": "<1579539790-3882-1-git-send-email-matan@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v1 37/38] common/mlx5: support ROCE disable\n\tthrough Netlink",
        "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 <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": "Add new 4 Netlink commands to support enable/disable ROCE:\n        1. mlx5_nl_devlink_family_id_get to get the Devlink family ID of\n           Netlink general command.\n        2. mlx5_nl_enable_roce_get to get the ROCE current status.\n        3. mlx5_nl_driver_reload - to reload the device kernel driver.\n        4. mlx5_nl_enable_roce_set - to set the ROCE status.\n\nWhen the user changes the ROCE status, the IB device may disappear and\nappear again, so DPDK driver should wait for it and to restart itself.\n\nSigned-off-by: Matan Azrad <matan@mellanox.com>\n---\n drivers/common/mlx5/Makefile                    |   5 +\n drivers/common/mlx5/meson.build                 |   1 +\n drivers/common/mlx5/mlx5_nl.c                   | 366 +++++++++++++++++++++++-\n drivers/common/mlx5/mlx5_nl.h                   |   6 +\n drivers/common/mlx5/rte_common_mlx5_version.map |   4 +\n 5 files changed, 380 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/common/mlx5/Makefile b/drivers/common/mlx5/Makefile\nindex 60bec3f..c4b7999 100644\n--- a/drivers/common/mlx5/Makefile\n+++ b/drivers/common/mlx5/Makefile\n@@ -261,6 +261,11 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh\n \t\tenum IFLA_PHYS_PORT_NAME \\\n \t\t$(AUTOCONF_OUTPUT)\n \t$Q sh -- '$<' '$@' \\\n+\t\tHAVE_DEVLINK \\\n+\t\tlinux/devlink.h \\\n+\t\tdefine DEVLINK_GENL_NAME \\\n+\t\t$(AUTOCONF_OUTPUT)\n+\t$Q sh -- '$<' '$@' \\\n \t\tHAVE_SUPPORTED_40000baseKR4_Full \\\n \t\t/usr/include/linux/ethtool.h \\\n \t\tdefine SUPPORTED_40000baseKR4_Full \\\ndiff --git a/drivers/common/mlx5/meson.build b/drivers/common/mlx5/meson.build\nindex 46c7c3bb..6dad6e2 100644\n--- a/drivers/common/mlx5/meson.build\n+++ b/drivers/common/mlx5/meson.build\n@@ -168,6 +168,7 @@ if build\n \t\t'RDMA_NLDEV_ATTR_NDEV_INDEX' ],\n \t\t[ 'HAVE_MLX5_DR_FLOW_DUMP', 'infiniband/mlx5dv.h',\n \t\t'mlx5dv_dump_dr_domain'],\n+\t\t[ 'HAVE_DEVLINK', 'linux/devlink.h', 'DEVLINK_GENL_NAME' ],\n \t]\n \tconfig = configuration_data()\n \tforeach arg:has_sym_args\ndiff --git a/drivers/common/mlx5/mlx5_nl.c b/drivers/common/mlx5/mlx5_nl.c\nindex b4fc053..0d1efd2 100644\n--- a/drivers/common/mlx5/mlx5_nl.c\n+++ b/drivers/common/mlx5/mlx5_nl.c\n@@ -6,6 +6,7 @@\n #include <errno.h>\n #include <linux/if_link.h>\n #include <linux/rtnetlink.h>\n+#include <linux/genetlink.h>\n #include <net/if.h>\n #include <rdma/rdma_netlink.h>\n #include <stdbool.h>\n@@ -22,6 +23,10 @@\n \n #include \"mlx5_nl.h\"\n #include \"mlx5_common_utils.h\"\n+#ifdef HAVE_DEVLINK\n+#include <linux/devlink.h>\n+#endif\n+\n \n /* Size of the buffer to receive kernel messages */\n #define MLX5_NL_BUF_SIZE (32 * 1024)\n@@ -90,6 +95,59 @@\n #define IFLA_PHYS_PORT_NAME 38\n #endif\n \n+/*\n+ * Some Devlink defines may be missed in old kernel versions,\n+ * adjust used defines.\n+ */\n+#ifndef DEVLINK_GENL_NAME\n+#define DEVLINK_GENL_NAME \"devlink\"\n+#endif\n+#ifndef DEVLINK_GENL_VERSION\n+#define DEVLINK_GENL_VERSION 1\n+#endif\n+#ifndef DEVLINK_ATTR_BUS_NAME\n+#define DEVLINK_ATTR_BUS_NAME 1\n+#endif\n+#ifndef DEVLINK_ATTR_DEV_NAME\n+#define DEVLINK_ATTR_DEV_NAME 2\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM\n+#define DEVLINK_ATTR_PARAM 80\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_NAME\n+#define DEVLINK_ATTR_PARAM_NAME 81\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_TYPE\n+#define DEVLINK_ATTR_PARAM_TYPE 83\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_VALUES_LIST\n+#define DEVLINK_ATTR_PARAM_VALUES_LIST 84\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_VALUE\n+#define DEVLINK_ATTR_PARAM_VALUE 85\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_VALUE_DATA\n+#define DEVLINK_ATTR_PARAM_VALUE_DATA 86\n+#endif\n+#ifndef DEVLINK_ATTR_PARAM_VALUE_CMODE\n+#define DEVLINK_ATTR_PARAM_VALUE_CMODE 87\n+#endif\n+#ifndef DEVLINK_PARAM_CMODE_DRIVERINIT\n+#define DEVLINK_PARAM_CMODE_DRIVERINIT 1\n+#endif\n+#ifndef DEVLINK_CMD_RELOAD\n+#define DEVLINK_CMD_RELOAD 37\n+#endif\n+#ifndef DEVLINK_CMD_PARAM_GET\n+#define DEVLINK_CMD_PARAM_GET 38\n+#endif\n+#ifndef DEVLINK_CMD_PARAM_SET\n+#define DEVLINK_CMD_PARAM_SET 39\n+#endif\n+#ifndef NLA_FLAG\n+#define NLA_FLAG 6\n+#endif\n+\n /* Add/remove MAC address through Netlink */\n struct mlx5_nl_mac_addr {\n \tstruct rte_ether_addr (*mac)[];\n@@ -1241,8 +1299,8 @@ struct mlx5_nl_ifindex_data {\n \tstruct nlattr *nla = nl_msg_tail(nlh);\n \n \tnla->nla_type = type;\n-\tnla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr) + alen);\n-\tnlh->nlmsg_len = NLMSG_ALIGN(nlh->nlmsg_len) + nla->nla_len;\n+\tnla->nla_len = NLMSG_ALIGN(sizeof(struct nlattr)) + alen;\n+\tnlh->nlmsg_len += NLMSG_ALIGN(nla->nla_len);\n \n \tif (alen)\n \t\tmemcpy((uint8_t *)nla + sizeof(struct nlattr), data, alen);\n@@ -1335,3 +1393,307 @@ struct mlx5_nl_ifindex_data {\n \t}\n \treturn ret;\n }\n+\n+/**\n+ * Parse Netlink message to retrieve the general family ID.\n+ *\n+ * @param nh\n+ *   Pointer to Netlink Message Header.\n+ * @param arg\n+ *   PMD data register with this callback.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_nl_family_id_cb(struct nlmsghdr *nh, void *arg)\n+{\n+\n+\tstruct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len);\n+\tstruct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) +\n+\t\t\t\t\tNLMSG_ALIGN(sizeof(struct genlmsghdr)));\n+\n+\tfor (; nla->nla_len && nla < tail;\n+\t     nla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len))) {\n+\t\tif (nla->nla_type == CTRL_ATTR_FAMILY_ID) {\n+\t\t\t*(uint16_t *)arg = *(uint16_t *)(nla + 1);\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\treturn -EINVAL;\n+}\n+\n+#define MLX5_NL_MAX_ATTR_SIZE 100\n+/**\n+ * Get generic netlink family ID.\n+ *\n+ * @param[in] nlsk_fd\n+ *   Netlink socket file descriptor.\n+ * @param[in] name\n+ *   The family name.\n+ *\n+ * @return\n+ *   ID >= 0 on success and @p enable is updated, a negative errno value\n+ *   otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_nl_generic_family_id_get(int nlsk_fd, const char *name)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct genlmsghdr *genl;\n+\tuint32_t sn = MLX5_NL_SN_GENERATE;\n+\tint name_size = strlen(name) + 1;\n+\tint ret;\n+\tuint16_t id = -1;\n+\tuint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct genlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct nlattr)) +\n+\t\t    NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE)];\n+\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = (struct nlmsghdr *)buf;\n+\tnlh->nlmsg_len = sizeof(struct nlmsghdr);\n+\tnlh->nlmsg_type = GENL_ID_CTRL;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;\n+\tgenl = (struct genlmsghdr *)nl_msg_tail(nlh);\n+\tnlh->nlmsg_len += sizeof(struct genlmsghdr);\n+\tgenl->cmd = CTRL_CMD_GETFAMILY;\n+\tgenl->version = 1;\n+\tnl_attr_put(nlh, CTRL_ATTR_FAMILY_NAME, name, name_size);\n+\tret = mlx5_nl_send(nlsk_fd, nlh, sn);\n+\tif (ret >= 0)\n+\t\tret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_family_id_cb, &id);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(DEBUG, \"Failed to get Netlink %s family ID: %d.\", name,\n+\t\t\tret);\n+\t\treturn ret;\n+\t}\n+\tDRV_LOG(DEBUG, \"Netlink \\\"%s\\\" family ID is %u.\", name, id);\n+\treturn (int)id;\n+}\n+\n+/**\n+ * Get Devlink family ID.\n+ *\n+ * @param[in] nlsk_fd\n+ *   Netlink socket file descriptor.\n+ *\n+ * @return\n+ *   ID >= 0 on success and @p enable is updated, a negative errno value\n+ *   otherwise and rte_errno is set.\n+ */\n+\n+int\n+mlx5_nl_devlink_family_id_get(int nlsk_fd)\n+{\n+\treturn mlx5_nl_generic_family_id_get(nlsk_fd, DEVLINK_GENL_NAME);\n+}\n+\n+/**\n+ * Parse Netlink message to retrieve the ROCE enable status.\n+ *\n+ * @param nh\n+ *   Pointer to Netlink Message Header.\n+ * @param arg\n+ *   PMD data register with this callback.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_nl_roce_cb(struct nlmsghdr *nh, void *arg)\n+{\n+\n+\tint ret = -EINVAL;\n+\tint *enable = arg;\n+\tstruct nlattr *tail = RTE_PTR_ADD(nh, nh->nlmsg_len);\n+\tstruct nlattr *nla = RTE_PTR_ADD(nh, NLMSG_ALIGN(sizeof(*nh)) +\n+\t\t\t\t\tNLMSG_ALIGN(sizeof(struct genlmsghdr)));\n+\n+\twhile (nla->nla_len && nla < tail) {\n+\t\tswitch (nla->nla_type) {\n+\t\t/* Expected nested attributes case. */\n+\t\tcase DEVLINK_ATTR_PARAM:\n+\t\tcase DEVLINK_ATTR_PARAM_VALUES_LIST:\n+\t\tcase DEVLINK_ATTR_PARAM_VALUE:\n+\t\t\tret = 0;\n+\t\t\tnla += 1;\n+\t\t\tbreak;\n+\t\tcase DEVLINK_ATTR_PARAM_VALUE_DATA:\n+\t\t\t*enable = 1;\n+\t\t\treturn 0;\n+\t\tdefault:\n+\t\t\tnla = RTE_PTR_ADD(nla, NLMSG_ALIGN(nla->nla_len));\n+\t\t}\n+\t}\n+\t*enable = 0;\n+\treturn ret;\n+}\n+\n+/**\n+ * Get ROCE enable status through Netlink.\n+ *\n+ * @param[in] nlsk_fd\n+ *   Netlink socket file descriptor.\n+ * @param[in] family_id\n+ *   the Devlink family ID.\n+ * @param pci_addr\n+ *   The device PCI address.\n+ * @param[out] enable\n+ *   Where to store the enable status.\n+ *\n+ * @return\n+ *   0 on success and @p enable is updated, a negative errno value otherwise\n+ *   and rte_errno is set.\n+ */\n+int\n+mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr,\n+\t\t\tint *enable)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct genlmsghdr *genl;\n+\tuint32_t sn = MLX5_NL_SN_GENERATE;\n+\tint ret;\n+\tint cur_en;\n+\tuint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct genlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct nlattr)) * 4 +\n+\t\t    NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 4];\n+\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = (struct nlmsghdr *)buf;\n+\tnlh->nlmsg_len = sizeof(struct nlmsghdr);\n+\tnlh->nlmsg_type = family_id;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;\n+\tgenl = (struct genlmsghdr *)nl_msg_tail(nlh);\n+\tnlh->nlmsg_len += sizeof(struct genlmsghdr);\n+\tgenl->cmd = DEVLINK_CMD_PARAM_GET;\n+\tgenl->version = DEVLINK_GENL_VERSION;\n+\tnl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, \"pci\", 4);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, \"enable_roce\", 12);\n+\tret = mlx5_nl_send(nlsk_fd, nlh, sn);\n+\tif (ret >= 0)\n+\t\tret = mlx5_nl_recv(nlsk_fd, sn, mlx5_nl_roce_cb, &cur_en);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(DEBUG, \"Failed to get ROCE enable on device %s: %d.\",\n+\t\t\tpci_addr, ret);\n+\t\treturn ret;\n+\t}\n+\t*enable = cur_en;\n+\tDRV_LOG(DEBUG, \"ROCE is %sabled for device \\\"%s\\\".\",\n+\t\tcur_en ? \"en\" : \"dis\", pci_addr);\n+\treturn ret;\n+}\n+\n+/**\n+ * Reload mlx5 device kernel driver through Netlink.\n+ *\n+ * @param[in] nlsk_fd\n+ *   Netlink socket file descriptor.\n+ * @param[in] family_id\n+ *   the Devlink family ID.\n+ * @param pci_addr\n+ *   The device PCI address.\n+ * @param[out] enable\n+ *   The enable status to set.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct genlmsghdr *genl;\n+\tuint32_t sn = MLX5_NL_SN_GENERATE;\n+\tint ret;\n+\tuint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct genlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct nlattr)) * 2 +\n+\t\t    NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 2];\n+\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = (struct nlmsghdr *)buf;\n+\tnlh->nlmsg_len = sizeof(struct nlmsghdr);\n+\tnlh->nlmsg_type = family_id;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;\n+\tgenl = (struct genlmsghdr *)nl_msg_tail(nlh);\n+\tnlh->nlmsg_len += sizeof(struct genlmsghdr);\n+\tgenl->cmd = DEVLINK_CMD_RELOAD;\n+\tgenl->version = DEVLINK_GENL_VERSION;\n+\tnl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, \"pci\", 4);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1);\n+\tret = mlx5_nl_send(nlsk_fd, nlh, sn);\n+\tif (ret >= 0)\n+\t\tret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(DEBUG, \"Failed to reload %s device by Netlink - %d\",\n+\t\t\tpci_addr, ret);\n+\t\treturn ret;\n+\t}\n+\tDRV_LOG(DEBUG, \"Device \\\"%s\\\" was reloaded by Netlink successfully.\",\n+\t\tpci_addr);\n+\treturn 0;\n+}\n+\n+/**\n+ * Set ROCE enable status through Netlink.\n+ *\n+ * @param[in] nlsk_fd\n+ *   Netlink socket file descriptor.\n+ * @param[in] family_id\n+ *   the Devlink family ID.\n+ * @param pci_addr\n+ *   The device PCI address.\n+ * @param[out] enable\n+ *   The enable status to set.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+int\n+mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr,\n+\t\t\tint enable)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct genlmsghdr *genl;\n+\tuint32_t sn = MLX5_NL_SN_GENERATE;\n+\tint ret;\n+\tuint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct genlmsghdr)) +\n+\t\t    NLMSG_ALIGN(sizeof(struct nlattr)) * 6 +\n+\t\t    NLMSG_ALIGN(MLX5_NL_MAX_ATTR_SIZE) * 6];\n+\tuint8_t cmode = DEVLINK_PARAM_CMODE_DRIVERINIT;\n+\tuint8_t ptype = NLA_FLAG;\n+;\n+\n+\tmemset(buf, 0, sizeof(buf));\n+\tnlh = (struct nlmsghdr *)buf;\n+\tnlh->nlmsg_len = sizeof(struct nlmsghdr);\n+\tnlh->nlmsg_type = family_id;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;\n+\tgenl = (struct genlmsghdr *)nl_msg_tail(nlh);\n+\tnlh->nlmsg_len += sizeof(struct genlmsghdr);\n+\tgenl->cmd = DEVLINK_CMD_PARAM_SET;\n+\tgenl->version = DEVLINK_GENL_VERSION;\n+\tnl_attr_put(nlh, DEVLINK_ATTR_BUS_NAME, \"pci\", 4);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_DEV_NAME, pci_addr, strlen(pci_addr) + 1);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_PARAM_NAME, \"enable_roce\", 12);\n+\tnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_CMODE, &cmode, sizeof(cmode));\n+\tnl_attr_put(nlh, DEVLINK_ATTR_PARAM_TYPE, &ptype, sizeof(ptype));\n+\tif (enable)\n+\t\tnl_attr_put(nlh, DEVLINK_ATTR_PARAM_VALUE_DATA, NULL, 0);\n+\tret = mlx5_nl_send(nlsk_fd, nlh, sn);\n+\tif (ret >= 0)\n+\t\tret = mlx5_nl_recv(nlsk_fd, sn, NULL, NULL);\n+\tif (ret < 0) {\n+\t\tDRV_LOG(DEBUG, \"Failed to %sable ROCE for device %s by Netlink:\"\n+\t\t\t\" %d.\", enable ? \"en\" : \"dis\", pci_addr, ret);\n+\t\treturn ret;\n+\t}\n+\tDRV_LOG(DEBUG, \"Device %s ROCE was %sabled by Netlink successfully.\",\n+\t\tpci_addr, enable ? \"en\" : \"dis\");\n+\t/* Now, need to reload the driver. */\n+\treturn mlx5_nl_driver_reload(nlsk_fd, family_id, pci_addr);\n+}\ndiff --git a/drivers/common/mlx5/mlx5_nl.h b/drivers/common/mlx5/mlx5_nl.h\nindex 8e66a98..2c3f837 100644\n--- a/drivers/common/mlx5/mlx5_nl.h\n+++ b/drivers/common/mlx5/mlx5_nl.h\n@@ -53,5 +53,11 @@ void mlx5_nl_vlan_vmwa_delete(struct mlx5_nl_vlan_vmwa_context *vmwa,\n \t\t\t      uint32_t ifindex);\n uint32_t mlx5_nl_vlan_vmwa_create(struct mlx5_nl_vlan_vmwa_context *vmwa,\n \t\t\t\t  uint32_t ifindex, uint16_t tag);\n+int mlx5_nl_devlink_family_id_get(int nlsk_fd);\n+int mlx5_nl_enable_roce_get(int nlsk_fd, int family_id, const char *pci_addr,\n+\t\t\t    int *enable);\n+int mlx5_nl_driver_reload(int nlsk_fd, int family_id, const char *pci_addr);\n+int mlx5_nl_enable_roce_set(int nlsk_fd, int family_id, const char *pci_addr,\n+\t\t\t    int enable);\n \n #endif /* RTE_PMD_MLX5_NL_H_ */\ndiff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map\nindex 318a024..959f12c 100644\n--- a/drivers/common/mlx5/rte_common_mlx5_version.map\n+++ b/drivers/common/mlx5/rte_common_mlx5_version.map\n@@ -26,6 +26,10 @@ DPDK_20.02 {\n \tmlx5_dev_to_pci_addr;\n \n \tmlx5_nl_allmulti;\n+\tmlx5_nl_devlink_family_id_get;\n+\tmlx5_nl_driver_reload;\n+\tmlx5_nl_enable_roce_get;\n+\tmlx5_nl_enable_roce_set;\n \tmlx5_nl_ifindex;\n \tmlx5_nl_init;\n \tmlx5_nl_mac_addr_add;\n",
    "prefixes": [
        "v1",
        "37/38"
    ]
}