get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 8455,
    "url": "http://patches.dpdk.org/api/patches/8455/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1446231162-8075-5-git-send-email-adrien.mazarguil@6wind.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": "<1446231162-8075-5-git-send-email-adrien.mazarguil@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1446231162-8075-5-git-send-email-adrien.mazarguil@6wind.com",
    "date": "2015-10-30T18:52:33",
    "name": "[dpdk-dev,v2,04/13] mlx5: add device configure/start/stop",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "4d0333763d614574fc27ac065fac15b868d97430",
    "submitter": {
        "id": 165,
        "url": "http://patches.dpdk.org/api/people/165/?format=api",
        "name": "Adrien Mazarguil",
        "email": "adrien.mazarguil@6wind.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1446231162-8075-5-git-send-email-adrien.mazarguil@6wind.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/8455/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/8455/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 [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id AF4A5922D;\n\tFri, 30 Oct 2015 19:53:30 +0100 (CET)",
            "from mail-wi0-f178.google.com (mail-wi0-f178.google.com\n\t[209.85.212.178]) by dpdk.org (Postfix) with ESMTP id 4E8B491E4\n\tfor <dev@dpdk.org>; Fri, 30 Oct 2015 19:53:20 +0100 (CET)",
            "by wicll6 with SMTP id ll6so16587431wic.1\n\tfor <dev@dpdk.org>; Fri, 30 Oct 2015 11:53:20 -0700 (PDT)",
            "from 6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by smtp.gmail.com with ESMTPSA id\n\tr13sm4220365wmg.12.2015.10.30.11.53.18\n\t(version=TLSv1.2 cipher=RC4-SHA bits=128/128);\n\tFri, 30 Oct 2015 11:53:19 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=6wind_com.20150623.gappssmtp.com; s=20150623;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=eBq5h80ooREwF287eiqOG+8d5MuHqxiB7cDJDrQ6AB4=;\n\tb=cmCVUxecJmOMsLWbOsOCnrpsHxWgInwFQOzx4/a2dN/0uWgAgLXwiddvhbWQjbZ4gD\n\t8PkElOxXjsdBGOXxUo6skXybpGhbAOvsjfllpfM4zDymsKFK5JI0GErUjOeX5RGrv/fH\n\tCjhDRDwIVGrV4pciwJ/OrHilRyGyHtvmFoU86g09TfQwBOKDlS7Y3gT+HnaVfcuEY62Z\n\tPIBqMNo5r2P/Xjvs37U1/RXkDQkkYhFvVj4V3ZtpSBTZDVVh2xaDocOUP/hvtmAJoLxz\n\tYJuqzaZk+t1LcOo+yW2NXunRBTfjtBzPUetKB5NaI7nFiz+CPi370Sk4QtTuF30Q+pk9\n\t/vRA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=eBq5h80ooREwF287eiqOG+8d5MuHqxiB7cDJDrQ6AB4=;\n\tb=BBlBmWDOk9yX4j9tVZeWH5mwOFRk7wRkfmTQ6uHkNCfdo2BSJL+GJZ6gCIYmFd+DEJ\n\tEG/Wle6vdm+LFOSPIse28nDhdMxWKLpUfmuieYkEhSI58wz7jcJyrRE4dTBX9BQnlPpu\n\ts9gYsvotyI66MMXw/tI8djTa8xMQpxXUGk+McGSWbIrbdv5o7DE/XyVv9b7QOSVV2m+O\n\tBNa9D3U/TmoCpN/zzFnklGzBnzQlqPwiD/LuWjFn87NuK5TtEEczwt+eID4NfzJaztE+\n\tsz5JcZ7WhfMxsd3Svaq41dp8Y0tu+tycCnMOav7UIGj8WtJ0shHAOzdTbV55CSrx0F7u\n\tU0kQ==",
        "X-Gm-Message-State": "ALoCoQnBP0KEnMX1lGNhJXii9wlsHZmdsVBULkmWa2AgYAuDW7Zlc2j72lfTgmdl8SobLFzIIYBu",
        "X-Received": "by 10.194.77.79 with SMTP id q15mr11999230wjw.102.1446231200049; \n\tFri, 30 Oct 2015 11:53:20 -0700 (PDT)",
        "From": "Adrien Mazarguil <adrien.mazarguil@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 30 Oct 2015 19:52:33 +0100",
        "Message-Id": "<1446231162-8075-5-git-send-email-adrien.mazarguil@6wind.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1446231162-8075-1-git-send-email-adrien.mazarguil@6wind.com>",
        "References": "<1444067589-29513-1-git-send-email-adrien.mazarguil@6wind.com>\n\t<1446231162-8075-1-git-send-email-adrien.mazarguil@6wind.com>",
        "Cc": "Francesco Santoro <francesco.santoro@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH v2 04/13] mlx5: add device configure/start/stop",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit adds the remaining missing callbacks to make mlx5 usable.\nLike mlx4, device start and stop are implemented on top of MAC RX flows.\n\nSigned-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>\nSigned-off-by: Francesco Santoro <francesco.santoro@6wind.com>\nSigned-off-by: Didier Pallard <didier.pallard@6wind.com>\n---\n drivers/net/mlx5/Makefile       |   1 +\n drivers/net/mlx5/mlx5.c         |   4 ++\n drivers/net/mlx5/mlx5.h         |   7 ++\n drivers/net/mlx5/mlx5_ethdev.c  | 148 ++++++++++++++++++++++++++++++++++++++++\n drivers/net/mlx5/mlx5_trigger.c | 146 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 306 insertions(+)\n create mode 100644 drivers/net/mlx5/mlx5_trigger.c",
    "diff": "diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile\nindex 7b9c57b..028c22c 100644\n--- a/drivers/net/mlx5/Makefile\n+++ b/drivers/net/mlx5/Makefile\n@@ -45,6 +45,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxq.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_txq.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_rxtx.c\n+SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_trigger.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_ethdev.c\n SRCS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5_mac.c\n \ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex a241c28..aafa70b 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -129,7 +129,11 @@ mlx5_dev_close(struct rte_eth_dev *dev)\n }\n \n static const struct eth_dev_ops mlx5_dev_ops = {\n+\t.dev_configure = mlx5_dev_configure,\n+\t.dev_start = mlx5_dev_start,\n+\t.dev_stop = mlx5_dev_stop,\n \t.dev_close = mlx5_dev_close,\n+\t.dev_infos_get = mlx5_dev_infos_get,\n \t.rx_queue_setup = mlx5_rx_queue_setup,\n \t.tx_queue_setup = mlx5_tx_queue_setup,\n \t.rx_queue_release = mlx5_rx_queue_release,\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 6ab31ad..3f47a15 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -160,6 +160,8 @@ int priv_get_ifname(const struct priv *, char (*)[IF_NAMESIZE]);\n int priv_ifreq(const struct priv *, int req, struct ifreq *);\n int priv_get_mtu(struct priv *, uint16_t *);\n int priv_set_flags(struct priv *, unsigned int, unsigned int);\n+int mlx5_dev_configure(struct rte_eth_dev *);\n+void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);\n int mlx5_ibv_device_to_pci_addr(const struct ibv_device *,\n \t\t\t\tstruct rte_pci_addr *);\n \n@@ -174,4 +176,9 @@ int priv_mac_addr_add(struct priv *, unsigned int,\n void mlx5_mac_addr_add(struct rte_eth_dev *, struct ether_addr *, uint32_t,\n \t\t       uint32_t);\n \n+/* mlx5_trigger.c */\n+\n+int mlx5_dev_start(struct rte_eth_dev *);\n+void mlx5_dev_stop(struct rte_eth_dev *);\n+\n #endif /* RTE_PMD_MLX5_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c\nindex b6c7d7a..6b13cec 100644\n--- a/drivers/net/mlx5/mlx5_ethdev.c\n+++ b/drivers/net/mlx5/mlx5_ethdev.c\n@@ -32,6 +32,7 @@\n  */\n \n #include <stddef.h>\n+#include <assert.h>\n #include <unistd.h>\n #include <stdint.h>\n #include <stdio.h>\n@@ -58,6 +59,7 @@\n #endif\n \n #include \"mlx5.h\"\n+#include \"mlx5_rxtx.h\"\n #include \"mlx5_utils.h\"\n \n /**\n@@ -370,6 +372,152 @@ priv_set_flags(struct priv *priv, unsigned int keep, unsigned int flags)\n }\n \n /**\n+ * Ethernet device configuration.\n+ *\n+ * Prepare the driver for a given number of TX and RX queues.\n+ * Allocate parent RSS queue when several RX queues are requested.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, errno value on failure.\n+ */\n+static int\n+dev_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct priv *priv = dev->data->dev_private;\n+\tunsigned int rxqs_n = dev->data->nb_rx_queues;\n+\tunsigned int txqs_n = dev->data->nb_tx_queues;\n+\tunsigned int tmp;\n+\tint ret;\n+\n+\tpriv->rxqs = (void *)dev->data->rx_queues;\n+\tpriv->txqs = (void *)dev->data->tx_queues;\n+\tif (txqs_n != priv->txqs_n) {\n+\t\tINFO(\"%p: TX queues number update: %u -> %u\",\n+\t\t     (void *)dev, priv->txqs_n, txqs_n);\n+\t\tpriv->txqs_n = txqs_n;\n+\t}\n+\tif (rxqs_n == priv->rxqs_n)\n+\t\treturn 0;\n+\tINFO(\"%p: RX queues number update: %u -> %u\",\n+\t     (void *)dev, priv->rxqs_n, rxqs_n);\n+\t/* If RSS is enabled, disable it first. */\n+\tif (priv->rss) {\n+\t\tunsigned int i;\n+\n+\t\t/* Only if there are no remaining child RX queues. */\n+\t\tfor (i = 0; (i != priv->rxqs_n); ++i)\n+\t\t\tif ((*priv->rxqs)[i] != NULL)\n+\t\t\t\treturn EINVAL;\n+\t\trxq_cleanup(&priv->rxq_parent);\n+\t\tpriv->rss = 0;\n+\t\tpriv->rxqs_n = 0;\n+\t}\n+\tif (rxqs_n <= 1) {\n+\t\t/* Nothing else to do. */\n+\t\tpriv->rxqs_n = rxqs_n;\n+\t\treturn 0;\n+\t}\n+\t/* Allocate a new RSS parent queue if supported by hardware. */\n+\tif (!priv->hw_rss) {\n+\t\tERROR(\"%p: only a single RX queue can be configured when\"\n+\t\t      \" hardware doesn't support RSS\",\n+\t\t      (void *)dev);\n+\t\treturn EINVAL;\n+\t}\n+\t/* Fail if hardware doesn't support that many RSS queues. */\n+\tif (rxqs_n >= priv->max_rss_tbl_sz) {\n+\t\tERROR(\"%p: only %u RX queues can be configured for RSS\",\n+\t\t      (void *)dev, priv->max_rss_tbl_sz);\n+\t\treturn EINVAL;\n+\t}\n+\tpriv->rss = 1;\n+\ttmp = priv->rxqs_n;\n+\tpriv->rxqs_n = rxqs_n;\n+\tret = rxq_setup(dev, &priv->rxq_parent, 0, 0, NULL, NULL);\n+\tif (!ret)\n+\t\treturn 0;\n+\t/* Failure, rollback. */\n+\tpriv->rss = 0;\n+\tpriv->rxqs_n = tmp;\n+\tassert(ret > 0);\n+\treturn ret;\n+}\n+\n+/**\n+ * DPDK callback for Ethernet device configuration.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+int\n+mlx5_dev_configure(struct rte_eth_dev *dev)\n+{\n+\tstruct priv *priv = dev->data->dev_private;\n+\tint ret;\n+\n+\tpriv_lock(priv);\n+\tret = dev_configure(dev);\n+\tassert(ret >= 0);\n+\tpriv_unlock(priv);\n+\treturn -ret;\n+}\n+\n+/**\n+ * DPDK callback to get information about the device.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ * @param[out] info\n+ *   Info structure output buffer.\n+ */\n+void\n+mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)\n+{\n+\tstruct priv *priv = dev->data->dev_private;\n+\tunsigned int max;\n+\tchar ifname[IF_NAMESIZE];\n+\n+\tpriv_lock(priv);\n+\t/* FIXME: we should ask the device for these values. */\n+\tinfo->min_rx_bufsize = 32;\n+\tinfo->max_rx_pktlen = 65536;\n+\t/*\n+\t * Since we need one CQ per QP, the limit is the minimum number\n+\t * between the two values.\n+\t */\n+\tmax = ((priv->device_attr.max_cq > priv->device_attr.max_qp) ?\n+\t       priv->device_attr.max_qp : priv->device_attr.max_cq);\n+\t/* If max >= 65535 then max = 0, max_rx_queues is uint16_t. */\n+\tif (max >= 65535)\n+\t\tmax = 65535;\n+\tinfo->max_rx_queues = max;\n+\tinfo->max_tx_queues = max;\n+\t/* Last array entry is reserved for broadcast. */\n+\tinfo->max_mac_addrs = (RTE_DIM(priv->mac) - 1);\n+\tinfo->rx_offload_capa =\n+\t\t(priv->hw_csum ?\n+\t\t (DEV_RX_OFFLOAD_IPV4_CKSUM |\n+\t\t  DEV_RX_OFFLOAD_UDP_CKSUM |\n+\t\t  DEV_RX_OFFLOAD_TCP_CKSUM) :\n+\t\t 0);\n+\tinfo->tx_offload_capa =\n+\t\t(priv->hw_csum ?\n+\t\t (DEV_TX_OFFLOAD_IPV4_CKSUM |\n+\t\t  DEV_TX_OFFLOAD_UDP_CKSUM |\n+\t\t  DEV_TX_OFFLOAD_TCP_CKSUM) :\n+\t\t 0);\n+\tif (priv_get_ifname(priv, &ifname) == 0)\n+\t\tinfo->if_index = if_nametoindex(ifname);\n+\tpriv_unlock(priv);\n+}\n+\n+/**\n  * Get PCI information from struct ibv_device.\n  *\n  * @param device\ndiff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c\nnew file mode 100644\nindex 0000000..f5d965f\n--- /dev/null\n+++ b/drivers/net/mlx5/mlx5_trigger.c\n@@ -0,0 +1,146 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright 2015 6WIND S.A.\n+ *   Copyright 2015 Mellanox.\n+ *\n+ *   Redistribution and use in source and binary forms, with or without\n+ *   modification, are permitted provided that the following conditions\n+ *   are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright\n+ *       notice, this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in\n+ *       the documentation and/or other materials provided with the\n+ *       distribution.\n+ *     * Neither the name of 6WIND S.A. nor the names of its\n+ *       contributors may be used to endorse or promote products derived\n+ *       from this software without specific prior written permission.\n+ *\n+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ *   \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+/* DPDK headers don't like -pedantic. */\n+#ifdef PEDANTIC\n+#pragma GCC diagnostic ignored \"-pedantic\"\n+#endif\n+#include <rte_ether.h>\n+#include <rte_ethdev.h>\n+#ifdef PEDANTIC\n+#pragma GCC diagnostic error \"-pedantic\"\n+#endif\n+\n+#include \"mlx5.h\"\n+#include \"mlx5_rxtx.h\"\n+#include \"mlx5_utils.h\"\n+\n+/**\n+ * DPDK callback to start the device.\n+ *\n+ * Simulate device start by attaching all configured flows.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ *\n+ * @return\n+ *   0 on success, negative errno value on failure.\n+ */\n+int\n+mlx5_dev_start(struct rte_eth_dev *dev)\n+{\n+\tstruct priv *priv = dev->data->dev_private;\n+\tunsigned int i = 0;\n+\tunsigned int r;\n+\tstruct rxq *rxq;\n+\n+\tpriv_lock(priv);\n+\tif (priv->started) {\n+\t\tpriv_unlock(priv);\n+\t\treturn 0;\n+\t}\n+\tDEBUG(\"%p: attaching configured flows to all RX queues\", (void *)dev);\n+\tpriv->started = 1;\n+\tif (priv->rss) {\n+\t\trxq = &priv->rxq_parent;\n+\t\tr = 1;\n+\t} else {\n+\t\trxq = (*priv->rxqs)[0];\n+\t\tr = priv->rxqs_n;\n+\t}\n+\t/* Iterate only once when RSS is enabled. */\n+\tdo {\n+\t\tint ret;\n+\n+\t\t/* Ignore nonexistent RX queues. */\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\t\tret = rxq_mac_addrs_add(rxq);\n+\t\tif (!ret)\n+\t\t\tcontinue;\n+\t\tWARN(\"%p: QP flow attachment failed: %s\",\n+\t\t     (void *)dev, strerror(ret));\n+\t\t/* Rollback. */\n+\t\twhile (i != 0) {\n+\t\t\trxq = (*priv->rxqs)[--i];\n+\t\t\tif (rxq != NULL) {\n+\t\t\t\trxq_mac_addrs_del(rxq);\n+\t\t\t}\n+\t\t}\n+\t\tpriv->started = 0;\n+\t\tpriv_unlock(priv);\n+\t\treturn -ret;\n+\t} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));\n+\tpriv_unlock(priv);\n+\treturn 0;\n+}\n+\n+/**\n+ * DPDK callback to stop the device.\n+ *\n+ * Simulate device stop by detaching all configured flows.\n+ *\n+ * @param dev\n+ *   Pointer to Ethernet device structure.\n+ */\n+void\n+mlx5_dev_stop(struct rte_eth_dev *dev)\n+{\n+\tstruct priv *priv = dev->data->dev_private;\n+\tunsigned int i = 0;\n+\tunsigned int r;\n+\tstruct rxq *rxq;\n+\n+\tpriv_lock(priv);\n+\tif (!priv->started) {\n+\t\tpriv_unlock(priv);\n+\t\treturn;\n+\t}\n+\tDEBUG(\"%p: detaching flows from all RX queues\", (void *)dev);\n+\tpriv->started = 0;\n+\tif (priv->rss) {\n+\t\trxq = &priv->rxq_parent;\n+\t\tr = 1;\n+\t} else {\n+\t\trxq = (*priv->rxqs)[0];\n+\t\tr = priv->rxqs_n;\n+\t}\n+\t/* Iterate only once when RSS is enabled. */\n+\tdo {\n+\t\t/* Ignore nonexistent RX queues. */\n+\t\tif (rxq == NULL)\n+\t\t\tcontinue;\n+\t\trxq_mac_addrs_del(rxq);\n+\t} while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));\n+\tpriv_unlock(priv);\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "04/13"
    ]
}