get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 8017,
    "url": "https://patches.dpdk.org/api/patches/8017/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1445875161-1808-2-git-send-email-remy.horton@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1445875161-1808-2-git-send-email-remy.horton@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1445875161-1808-2-git-send-email-remy.horton@intel.com",
    "date": "2015-10-26T15:59:20",
    "name": "[dpdk-dev,v2,1/2] example: User-space ethtool sample application",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "d6b275fb40ad1d6d44564592c7b3a6bab6dbf9bc",
    "submitter": {
        "id": 326,
        "url": "https://patches.dpdk.org/api/people/326/?format=api",
        "name": "Remy Horton",
        "email": "remy.horton@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1445875161-1808-2-git-send-email-remy.horton@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/8017/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/8017/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 9FE9E8D8A;\n\tMon, 26 Oct 2015 16:59:56 +0100 (CET)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n\tby dpdk.org (Postfix) with ESMTP id 63F645A71\n\tfor <dev@dpdk.org>; Mon, 26 Oct 2015 16:59:52 +0100 (CET)",
            "from orsmga003.jf.intel.com ([10.7.209.27])\n\tby fmsmga101.fm.intel.com with ESMTP; 26 Oct 2015 08:59:30 -0700",
            "from unknown (HELO localhost.ger.corp.intel.com) ([10.252.26.253])\n\tby orsmga003.jf.intel.com with ESMTP; 26 Oct 2015 08:59:27 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.20,201,1444719600\"; d=\"scan'208\";a=\"672006633\"",
        "From": "Remy Horton <remy.horton@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Mon, 26 Oct 2015 15:59:20 +0000",
        "Message-Id": "<1445875161-1808-2-git-send-email-remy.horton@intel.com>",
        "X-Mailer": "git-send-email 1.9.3",
        "In-Reply-To": "<1445875161-1808-1-git-send-email-remy.horton@intel.com>",
        "References": "<1445875161-1808-1-git-send-email-remy.horton@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 1/2] example: User-space ethtool sample\n\tapplication",
        "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": "Further enhancements to the userspace ethtool implementation that was\nsubmitted in 2.1 and packaged as a self-contained sample application.\nImplements an rte_ethtool shim layer based on rte_ethdev API, along\nwith a command prompt driven demonstration application.\n\nSigned-off-by: Remy Horton <remy.horton@intel.com>\n---\n examples/ethtool/Makefile          |  48 ++\n examples/ethtool/app/Makefile      |  54 +++\n examples/ethtool/app/ethapp.c      | 870 +++++++++++++++++++++++++++++++++++++\n examples/ethtool/app/ethapp.h      |  40 ++\n examples/ethtool/app/main.c        | 281 ++++++++++++\n examples/ethtool/lib/Makefile      |  57 +++\n examples/ethtool/lib/rte_ethtool.c | 421 ++++++++++++++++++\n examples/ethtool/lib/rte_ethtool.h | 410 +++++++++++++++++\n 8 files changed, 2181 insertions(+)\n create mode 100644 examples/ethtool/Makefile\n create mode 100644 examples/ethtool/app/Makefile\n create mode 100644 examples/ethtool/app/ethapp.c\n create mode 100644 examples/ethtool/app/ethapp.h\n create mode 100644 examples/ethtool/app/main.c\n create mode 100644 examples/ethtool/lib/Makefile\n create mode 100644 examples/ethtool/lib/rte_ethtool.c\n create mode 100644 examples/ethtool/lib/rte_ethtool.h",
    "diff": "diff --git a/examples/ethtool/Makefile b/examples/ethtool/Makefile\nnew file mode 100644\nindex 0000000..0505446\n--- /dev/null\n+++ b/examples/ethtool/Makefile\n@@ -0,0 +1,48 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2015 Intel Corporation. All rights reserved.\n+#   All rights reserved.\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 Intel Corporation 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+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, can be overwritten by command line or environment\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+ifneq ($(CONFIG_RTE_EXEC_ENV),\"linuxapp\")\n+$(error This application can only operate in a linuxapp environment, \\\n+please change the definition of the RTE_TARGET environment variable)\n+endif\n+\n+DIRS-y += lib app\n+\n+include $(RTE_SDK)/mk/rte.extsubdir.mk\ndiff --git a/examples/ethtool/app/Makefile b/examples/ethtool/app/Makefile\nnew file mode 100644\nindex 0000000..62c5828\n--- /dev/null\n+++ b/examples/ethtool/app/Makefile\n@@ -0,0 +1,54 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+#   All rights reserved.\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 Intel Corporation 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+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, can be overridden by command line or environment\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# binary name\n+APP = ethtool\n+\n+# all source are stored in SRCS-y\n+SRCS-y := main.c ethapp.c\n+\n+CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib\n+CFLAGS += $(WERROR_FLAGS)\n+\n+LDLIBS += -L$(subst app,lib,$(RTE_OUTPUT))/lib\n+LDLIBS += -lrte_ethtool\n+\n+\n+include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/ethtool/app/ethapp.c b/examples/ethtool/app/ethapp.c\nnew file mode 100644\nindex 0000000..13ff66f\n--- /dev/null\n+++ b/examples/ethtool/app/ethapp.c\n@@ -0,0 +1,870 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\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 Intel Corporation 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+#include <cmdline_parse.h>\n+#include <cmdline_parse_num.h>\n+#include <cmdline_parse_string.h>\n+#include <cmdline_parse_etheraddr.h>\n+#include <cmdline_socket.h>\n+#include <cmdline.h>\n+\n+#include \"rte_ethtool.h\"\n+#include \"ethapp.h\"\n+\n+#define EEPROM_DUMP_CHUNKSIZE 1024\n+\n+\n+struct pcmd_get_params {\n+\tcmdline_fixed_string_t cmd;\n+};\n+struct pcmd_int_params {\n+\tcmdline_fixed_string_t cmd;\n+\tuint16_t port;\n+};\n+struct pcmd_intstr_params {\n+\tcmdline_fixed_string_t cmd;\n+\tuint16_t port;\n+\tcmdline_fixed_string_t opt;\n+};\n+struct pcmd_intmac_params {\n+\tcmdline_fixed_string_t cmd;\n+\tuint16_t port;\n+\tstruct ether_addr mac;\n+};\n+struct pcmd_str_params {\n+\tcmdline_fixed_string_t cmd;\n+\tcmdline_fixed_string_t opt;\n+};\n+struct pcmd_vlan_params {\n+\tcmdline_fixed_string_t cmd;\n+\tuint16_t port;\n+\tcmdline_fixed_string_t mode;\n+\tuint16_t vid;\n+};\n+struct pcmd_intintint_params {\n+\tcmdline_fixed_string_t cmd;\n+\tuint16_t port;\n+\tuint16_t tx;\n+\tuint16_t rx;\n+};\n+\n+\n+/* Parameter-less commands */\n+cmdline_parse_token_string_t pcmd_quit_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, \"quit\");\n+cmdline_parse_token_string_t pcmd_stats_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, \"stats\");\n+cmdline_parse_token_string_t pcmd_drvinfo_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, \"drvinfo\");\n+cmdline_parse_token_string_t pcmd_link_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, \"link\");\n+\n+/* Commands taking just port id */\n+cmdline_parse_token_string_t pcmd_open_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, \"open\");\n+cmdline_parse_token_string_t pcmd_stop_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, \"stop\");\n+cmdline_parse_token_string_t pcmd_rxmode_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, \"rxmode\");\n+cmdline_parse_token_string_t pcmd_portstats_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, \"portstats\");\n+cmdline_parse_token_num_t pcmd_int_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16);\n+\n+/* Commands taking port id and string */\n+cmdline_parse_token_string_t pcmd_eeprom_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, \"eeprom\");\n+cmdline_parse_token_string_t pcmd_mtu_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, \"mtu\");\n+cmdline_parse_token_string_t pcmd_regs_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, \"regs\");\n+\n+cmdline_parse_token_num_t pcmd_intstr_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);\n+cmdline_parse_token_string_t pcmd_intstr_token_opt =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL);\n+\n+/* Commands taking port id and a MAC address string */\n+cmdline_parse_token_string_t pcmd_macaddr_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, \"macaddr\");\n+cmdline_parse_token_num_t pcmd_intmac_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16);\n+cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac =\n+\tTOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac);\n+\n+/* Command taking just a MAC address */\n+cmdline_parse_token_string_t pcmd_validate_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, \"validate\");\n+\n+\n+/* Commands taking port id and two integers */\n+cmdline_parse_token_string_t pcmd_ringparam_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd,\n+\t\t\"ringparam\");\n+cmdline_parse_token_num_t pcmd_intintint_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16);\n+cmdline_parse_token_num_t pcmd_intintint_token_tx =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16);\n+cmdline_parse_token_num_t pcmd_intintint_token_rx =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16);\n+\n+\n+/* Pause commands */\n+cmdline_parse_token_string_t pcmd_pause_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, \"pause\");\n+cmdline_parse_token_num_t pcmd_pause_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);\n+cmdline_parse_token_string_t pcmd_pause_token_opt =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_intstr_params,\n+\t\topt, \"all#tx#rx#none\");\n+\n+/* VLAN commands */\n+cmdline_parse_token_string_t pcmd_vlan_token_cmd =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, \"vlan\");\n+cmdline_parse_token_num_t pcmd_vlan_token_port =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16);\n+cmdline_parse_token_string_t pcmd_vlan_token_mode =\n+\tTOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, \"add#del\");\n+cmdline_parse_token_num_t pcmd_vlan_token_vid =\n+\tTOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16);\n+\n+\n+static void\n+pcmd_quit_callback(__attribute__((unused)) void *ptr_params,\n+\tstruct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tcmdline_quit(ctx);\n+}\n+\n+\n+static void\n+pcmd_drvinfo_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct ethtool_drvinfo info;\n+\tint id_port;\n+\n+\tfor (id_port = 0; id_port < rte_eth_dev_count(); id_port++) {\n+\t\tif (rte_ethtool_get_drvinfo(id_port, &info)) {\n+\t\t\tprintf(\"Error getting info for port %i\\n\", id_port);\n+\t\t\treturn;\n+\t\t}\n+\t\tprintf(\"Port %i driver: %s (ver: %s)\\n\",\n+\t\t\tid_port, info.driver, info.version\n+\t\t      );\n+\t}\n+}\n+\n+\n+static void\n+pcmd_link_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tint num_ports = rte_eth_dev_count();\n+\tint id_port, stat_port;\n+\n+\tfor (id_port = 0; id_port < num_ports; id_port++) {\n+\t\tif (!rte_eth_dev_is_valid_port(id_port))\n+\t\t\tcontinue;\n+\t\tstat_port = rte_ethtool_get_link(id_port);\n+\t\tswitch (stat_port) {\n+\t\tcase 0:\n+\t\t\tprintf(\"Port %i: Down\\n\", id_port);\n+\t\t\tbreak;\n+\t\tcase 1:\n+\t\t\tprintf(\"Port %i: Up\\n\", id_port);\n+\t\t\tbreak;\n+\t\tdefault:\n+\t\t\tprintf(\"Port %i: Error getting link status\\n\",\n+\t\t\t\tid_port\n+\t\t\t\t);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tprintf(\"\\n\");\n+}\n+\n+\n+static void\n+pcmd_regs_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_intstr_params *params = ptr_params;\n+\tint len_regs;\n+\tstruct ethtool_regs regs;\n+\tunsigned char *buf_data;\n+\tFILE *fp_regs;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tlen_regs = rte_ethtool_get_regs_len(params->port);\n+\tif (len_regs > 0) {\n+\t\tprintf(\"Port %i: %i bytes\\n\", params->port, len_regs);\n+\t\tbuf_data = malloc(len_regs);\n+\t\tif (buf_data == NULL) {\n+\t\t\tprintf(\"Error allocating %i bytes for buffer\\n\",\n+\t\t\t\tlen_regs);\n+\t\t\treturn;\n+\t\t}\n+\t\tif (!rte_ethtool_get_regs(params->port, &regs, buf_data)) {\n+\t\t\tfp_regs = fopen(params->opt, \"wb\");\n+\t\t\tif (fp_regs == NULL) {\n+\t\t\t\tprintf(\"Error opening '%s' for writing\\n\",\n+\t\t\t\t\tparams->opt);\n+\t\t\t} else {\n+\t\t\t\tif ((int)fwrite(buf_data,\n+\t\t\t\t\t\t1, len_regs,\n+\t\t\t\t\t\tfp_regs) != len_regs)\n+\t\t\t\t\tprintf(\"Error writing '%s'\\n\",\n+\t\t\t\t\t\tparams->opt);\n+\t\t\t\tfclose(fp_regs);\n+\t\t\t}\n+\t\t}\n+\t\tfree(buf_data);\n+\t} else if (len_regs == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error getting registers\\n\", params->port);\n+}\n+\n+\n+static void\n+pcmd_eeprom_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_intstr_params *params = ptr_params;\n+\tstruct ethtool_eeprom info_eeprom;\n+\tint len_eeprom;\n+\tint pos_eeprom;\n+\tint stat;\n+\tunsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];\n+\tFILE *fp_eeprom;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tlen_eeprom = rte_ethtool_get_eeprom_len(params->port);\n+\tif (len_eeprom > 0) {\n+\t\tfp_eeprom = fopen(params->opt, \"wb\");\n+\t\tif (fp_eeprom == NULL) {\n+\t\t\tprintf(\"Error opening '%s' for writing\\n\",\n+\t\t\t\tparams->opt);\n+\t\t\treturn;\n+\t\t}\n+\t\tprintf(\"Total EEPROM length: %i bytes\\n\", len_eeprom);\n+\t\tinfo_eeprom.len = EEPROM_DUMP_CHUNKSIZE;\n+\t\tfor (pos_eeprom = 0;\n+\t\t\t\tpos_eeprom < len_eeprom;\n+\t\t\t\tpos_eeprom += EEPROM_DUMP_CHUNKSIZE) {\n+\t\t\tinfo_eeprom.offset = pos_eeprom;\n+\t\t\tif (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom)\n+\t\t\t\tinfo_eeprom.len = len_eeprom - pos_eeprom;\n+\t\t\telse\n+\t\t\t\tinfo_eeprom.len = EEPROM_DUMP_CHUNKSIZE;\n+\t\t\tstat = rte_ethtool_get_eeprom(\n+\t\t\t\tparams->port, &info_eeprom, bytes_eeprom\n+\t\t\t\t);\n+\t\t\tif (stat != 0) {\n+\t\t\t\tprintf(\"EEPROM read error %i\\n\", stat);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (fwrite(bytes_eeprom,\n+\t\t\t\t\t1, info_eeprom.len,\n+\t\t\t\t\tfp_eeprom) != info_eeprom.len) {\n+\t\t\t\tprintf(\"Error writing '%s'\\n\", params->opt);\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tfclose(fp_eeprom);\n+\t} else if (len_eeprom == 0)\n+\t\tprintf(\"Port %i: Device does not have EEPROM\\n\", params->port);\n+\telse if (len_eeprom == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error getting EEPROM\\n\", params->port);\n+}\n+\n+\n+static void\n+pcmd_pause_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\tvoid *ptr_data)\n+{\n+\tstruct pcmd_intstr_params *params = ptr_params;\n+\tstruct ethtool_pauseparam info;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tif (ptr_data != NULL) {\n+\t\tstat = rte_ethtool_get_pauseparam(params->port, &info);\n+\t} else {\n+\t\tif (strcasecmp(\"all\", params->opt) == 0) {\n+\t\t\tinfo.tx_pause = 1;\n+\t\t\tinfo.rx_pause = 1;\n+\t\t} else if (strcasecmp(\"tx\", params->opt) == 0) {\n+\t\t\tinfo.tx_pause = 1;\n+\t\t\tinfo.rx_pause = 0;\n+\t\t} else if (strcasecmp(\"rx\", params->opt) == 0) {\n+\t\t\tinfo.tx_pause = 0;\n+\t\t\tinfo.rx_pause = 1;\n+\t\t} else {\n+\t\t\tinfo.tx_pause = 0;\n+\t\t\tinfo.rx_pause = 0;\n+\t\t}\n+\t\tstat = rte_ethtool_set_pauseparam(params->port, &info);\n+\t}\n+\tif (stat == 0) {\n+\t\tif (info.rx_pause && info.tx_pause)\n+\t\t\tprintf(\"Port %i: Tx & Rx Paused\\n\", params->port);\n+\t\telse if (info.rx_pause)\n+\t\t\tprintf(\"Port %i: Rx Paused\\n\", params->port);\n+\t\telse if (info.tx_pause)\n+\t\t\tprintf(\"Port %i: Tx Paused\\n\", params->port);\n+\t\telse\n+\t\t\tprintf(\"Port %i: Tx & Rx not paused\\n\", params->port);\n+\t} else if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error %i\\n\", params->port, stat);\n+}\n+\n+\n+static void\n+pcmd_open_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_int_params *params = ptr_params;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tlock_port(params->port);\n+\tstat = rte_ethtool_net_open(params->port);\n+\tmark_port_active(params->port);\n+\tunlock_port(params->port);\n+\tif (stat == 0)\n+\t\treturn;\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error opening device\\n\", params->port);\n+}\n+\n+static void\n+pcmd_stop_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_int_params *params = ptr_params;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tlock_port(params->port);\n+\tstat = rte_ethtool_net_stop(params->port);\n+\tmark_port_inactive(params->port);\n+\tunlock_port(params->port);\n+\tif (stat == 0)\n+\t\treturn;\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error stopping device\\n\", params->port);\n+}\n+\n+\n+static void\n+pcmd_rxmode_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_intstr_params *params = ptr_params;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tstat = rte_ethtool_net_set_rx_mode(params->port);\n+\tif (stat == 0)\n+\t\treturn;\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error setting rx mode\\n\", params->port);\n+}\n+\n+\n+static void\n+pcmd_macaddr_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\tvoid *ptr_data)\n+{\n+\tstruct pcmd_intmac_params *params = ptr_params;\n+\tstruct ether_addr mac_addr;\n+\tint stat;\n+\n+\tstat = 0;\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tif (ptr_data != NULL) {\n+\t\tstat = rte_ethtool_net_set_mac_addr(params->port,\n+\t\t\t&params->mac);\n+\t\tif (stat == 0) {\n+\t\t\tprintf(\"MAC address changed\\n\");\n+\t\t\treturn;\n+\t\t}\n+\t} else {\n+\t\tstat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr);\n+\t\tif (stat == 0) {\n+\t\t\tprintf(\n+\t\t\t\t\"Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\\n\",\n+\t\t\t\tparams->port,\n+\t\t\t\tmac_addr.addr_bytes[0],\n+\t\t\t\tmac_addr.addr_bytes[1],\n+\t\t\t\tmac_addr.addr_bytes[2],\n+\t\t\t\tmac_addr.addr_bytes[3],\n+\t\t\t\tmac_addr.addr_bytes[4],\n+\t\t\t\tmac_addr.addr_bytes[5]);\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\tif (stat == 0)\n+\t\treturn;\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error %i\\n\", params->port, stat);\n+}\n+\n+static void\n+pcmd_mtu_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_intstr_params *params = ptr_params;\n+\tint stat;\n+\tint new_mtu;\n+\tchar *ptr_parse_end;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tnew_mtu = atoi(params->opt);\n+\tnew_mtu = strtoul(params->opt, &ptr_parse_end, 10);\n+\tif (*ptr_parse_end != '\\0' ||\n+\t\t\tnew_mtu < ETHER_MIN_MTU ||\n+\t\t\tnew_mtu > ETHER_MAX_VLAN_FRAME_LEN) {\n+\t\tprintf(\"Port %i: Invalid MTU value\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tstat = rte_ethtool_net_change_mtu(params->port, new_mtu);\n+\tif (stat == 0)\n+\t\tprintf(\"Port %i: MTU set to %i\\n\", params->port, new_mtu);\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error setting MTU\\n\", params->port);\n+}\n+\n+\n+\n+static void pcmd_portstats_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_int_params *params = ptr_params;\n+\tstruct rte_eth_stats stat_info;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tstat = rte_ethtool_net_get_stats64(params->port, &stat_info);\n+\tif (stat == 0) {\n+\t\t/* Most of rte_eth_stats is deprecated.. */\n+\t\tprintf(\"Port %i stats\\n\", params->port);\n+\t\tprintf(\"   In: %\" PRIu64 \" (%\" PRIu64 \" bytes)\\n\"\n+\t\t\t\"  Out: %\"PRIu64\" (%\"PRIu64 \" bytes)\\n\"\n+\t\t\t\"  Err: %\"PRIu64\"\\n\",\n+\t\t\tstat_info.ipackets,\n+\t\t\tstat_info.ibytes,\n+\t\t\tstat_info.opackets,\n+\t\t\tstat_info.obytes,\n+\t\t\tstat_info.ierrors+stat_info.oerrors\n+\t\t      );\n+\t} else if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error fetching statistics\\n\", params->port);\n+}\n+\n+static void pcmd_ringparam_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\tvoid *ptr_data)\n+{\n+\tstruct pcmd_intintint_params *params = ptr_params;\n+\tstruct ethtool_ringparam ring_data;\n+\tstruct ethtool_ringparam ring_params;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tif (ptr_data == NULL) {\n+\t\tstat = rte_ethtool_get_ringparam(params->port, &ring_data);\n+\t\tif (stat == 0) {\n+\t\t\tprintf(\"Port %i ring paramaeters\\n\"\n+\t\t\t\t\"  Rx Pending: %i (%i max)\\n\"\n+\t\t\t\t\"  Tx Pending: %i (%i max)\\n\",\n+\t\t\t\tparams->port,\n+\t\t\t\tring_data.rx_pending,\n+\t\t\t\tring_data.tx_pending,\n+\t\t\t\tring_data.rx_max_pending,\n+\t\t\t\tring_data.tx_max_pending);\n+\t\t}\n+\t} else {\n+\t\tif (params->tx < 1 || params->rx < 1) {\n+\t\t\tprintf(\"Error: Invalid parameters\\n\");\n+\t\t\treturn;\n+\t\t}\n+\t\tmemset(&ring_params, 0, sizeof(struct ethtool_ringparam));\n+\t\tring_params.tx_pending = params->tx;\n+\t\tring_params.rx_pending = params->rx;\n+\t\tlock_port(params->port);\n+\t\tstat = rte_ethtool_set_ringparam(params->port, &ring_params);\n+\t\tunlock_port(params->port);\n+\t}\n+\tif (stat == 0)\n+\t\treturn;\n+\telse if (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse\n+\t\tprintf(\"Port %i: Error fetching statistics\\n\", params->port);\n+}\n+\n+static void pcmd_validate_callback(void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_intmac_params *params = ptr_params;\n+\n+\tif (rte_ethtool_net_validate_addr(0, &params->mac))\n+\t\tprintf(\"Address is unicast\\n\");\n+\telse\n+\t\tprintf(\"Address is not unicast\\n\");\n+}\n+\n+\n+static void pcmd_vlan_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tstruct pcmd_vlan_params *params = ptr_params;\n+\tint stat;\n+\n+\tif (!rte_eth_dev_is_valid_port(params->port)) {\n+\t\tprintf(\"Error: Invalid port number %i\\n\", params->port);\n+\t\treturn;\n+\t}\n+\tstat = 0;\n+\n+\tif (strcasecmp(\"add\", params->mode) == 0) {\n+\t\tstat = rte_ethtool_net_vlan_rx_add_vid(\n+\t\t\tparams->port, params->vid\n+\t\t\t);\n+\t\tif (stat == 0)\n+\t\t\tprintf(\"VLAN vid %i added\\n\", params->vid);\n+\n+\t} else if (strcasecmp(\"del\", params->mode) == 0) {\n+\t\tstat = rte_ethtool_net_vlan_rx_kill_vid(\n+\t\t\tparams->port, params->vid\n+\t\t\t);\n+\t\tif (stat == 0)\n+\t\t\tprintf(\"VLAN vid %i removed\\n\", params->vid);\n+\t} else {\n+\t\t/* Should not happen! */\n+\t\tprintf(\"Error: Bad mode %s\\n\", params->mode);\n+\t}\n+\tif (stat == -ENOTSUP)\n+\t\tprintf(\"Port %i: Operation not supported\\n\", params->port);\n+\telse if (stat == -ENOSYS)\n+\t\tprintf(\"Port %i: VLAN filtering disabled\\n\", params->port);\n+\telse if (stat != 0)\n+\t\tprintf(\"Port %i: Error changing VLAN setup (code %i)\\n\",\n+\t\t\tparams->port, -stat);\n+}\n+\n+\n+cmdline_parse_inst_t pcmd_quit = {\n+\t.f = pcmd_quit_callback,\n+\t.data = NULL,\n+\t.help_str = \"quit\\n     Exit program\",\n+\t.tokens = {(void *)&pcmd_quit_token_cmd, NULL},\n+};\n+cmdline_parse_inst_t pcmd_drvinfo = {\n+\t.f = pcmd_drvinfo_callback,\n+\t.data = NULL,\n+\t.help_str = \"drvinfo\\n     Print driver info\",\n+\t.tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},\n+};\n+cmdline_parse_inst_t pcmd_link = {\n+\t.f = pcmd_link_callback,\n+\t.data = NULL,\n+\t.help_str = \"link\\n     Print port link states\",\n+\t.tokens = {(void *)&pcmd_link_token_cmd, NULL},\n+};\n+cmdline_parse_inst_t pcmd_regs = {\n+\t.f = pcmd_regs_callback,\n+\t.data = NULL,\n+\t.help_str = \"regs <port_id> <filename>\\n\"\n+\t\t\"     Dump port register(s) to file\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_regs_token_cmd,\n+\t\t(void *)&pcmd_intstr_token_port,\n+\t\t(void *)&pcmd_intstr_token_opt,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_eeprom = {\n+\t.f = pcmd_eeprom_callback,\n+\t.data = NULL,\n+\t.help_str = \"eeprom <port_id> <filename>\\n    Dump EEPROM to file\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_eeprom_token_cmd,\n+\t\t(void *)&pcmd_intstr_token_port,\n+\t\t(void *)&pcmd_intstr_token_opt,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_pause_noopt = {\n+\t.f = pcmd_pause_callback,\n+\t.data = (void *)0x01,\n+\t.help_str = \"pause <port_id>\\n     Print port pause state\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_pause_token_cmd,\n+\t\t(void *)&pcmd_pause_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_pause = {\n+\t.f = pcmd_pause_callback,\n+\t.data = NULL,\n+\t.help_str =\n+\t\t\"pause <port_id> <all|tx|rx|none>\\n     Pause/unpause port\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_pause_token_cmd,\n+\t\t(void *)&pcmd_pause_token_port,\n+\t\t(void *)&pcmd_pause_token_opt,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_open = {\n+\t.f = pcmd_open_callback,\n+\t.data = NULL,\n+\t.help_str = \"open <port_id>\\n     Open port\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_open_token_cmd,\n+\t\t(void *)&pcmd_int_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_stop = {\n+\t.f = pcmd_stop_callback,\n+\t.data = NULL,\n+\t.help_str = \"stop <port_id>\\n     Stop port\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_stop_token_cmd,\n+\t\t(void *)&pcmd_int_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_rxmode = {\n+\t.f = pcmd_rxmode_callback,\n+\t.data = NULL,\n+\t.help_str = \"rxmode <port_id>\\n     Toggle port Rx mode\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_rxmode_token_cmd,\n+\t\t(void *)&pcmd_int_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_macaddr_get = {\n+\t.f = pcmd_macaddr_callback,\n+\t.data = NULL,\n+\t.help_str = \"macaddr <port_id>\\n\"\n+\t\t\"     Get MAC address\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_macaddr_token_cmd,\n+\t\t(void *)&pcmd_intstr_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_macaddr = {\n+\t.f = pcmd_macaddr_callback,\n+\t.data = (void *)0x01,\n+\t.help_str =\n+\t\t\"macaddr <port_id> <mac_addr>\\n\"\n+\t\t\"     Set MAC address\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_macaddr_token_cmd,\n+\t\t(void *)&pcmd_intmac_token_port,\n+\t\t(void *)&pcmd_intmac_token_mac,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_mtu = {\n+\t.f = pcmd_mtu_callback,\n+\t.data = NULL,\n+\t.help_str = \"mtu <port_id> <mtu_value>\\n\"\n+\t\t\"     Change MTU\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_mtu_token_cmd,\n+\t\t(void *)&pcmd_intstr_token_port,\n+\t\t(void *)&pcmd_intstr_token_opt,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_portstats = {\n+\t.f = pcmd_portstats_callback,\n+\t.data = NULL,\n+\t.help_str = \"portstats <port_id>\\n\"\n+\t\t\"     Print port eth statistics\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_portstats_token_cmd,\n+\t\t(void *)&pcmd_int_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_ringparam = {\n+\t.f = pcmd_ringparam_callback,\n+\t.data = NULL,\n+\t.help_str = \"ringparam <port_id>\\n\"\n+\t\t\"     Print ring parameters\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_ringparam_token_cmd,\n+\t\t(void *)&pcmd_intintint_token_port,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_ringparam_set = {\n+\t.f = pcmd_ringparam_callback,\n+\t.data = (void *)1,\n+\t.help_str = \"ringparam <port_id>\\n\"\n+\t\t\"     Set ring parameters\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_ringparam_token_cmd,\n+\t\t(void *)&pcmd_intintint_token_port,\n+\t\t(void *)&pcmd_intintint_token_tx,\n+\t\t(void *)&pcmd_intintint_token_rx,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_validate = {\n+\t.f = pcmd_validate_callback,\n+\t.data = NULL,\n+\t.help_str = \"validate <mac_addr>\\n\"\n+\t\t\"     Check that MAC address is valid unicast address\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_validate_token_cmd,\n+\t\t(void *)&pcmd_intmac_token_mac,\n+\t\tNULL\n+\t},\n+};\n+cmdline_parse_inst_t pcmd_vlan = {\n+\t.f = pcmd_vlan_callback,\n+\t.data = NULL,\n+\t.help_str = \"vlan <port_id> <add|del> <vlan_id>\\n\"\n+\t\t\"     Add/remove VLAN id\",\n+\t.tokens = {\n+\t\t(void *)&pcmd_vlan_token_cmd,\n+\t\t(void *)&pcmd_vlan_token_port,\n+\t\t(void *)&pcmd_vlan_token_mode,\n+\t\t(void *)&pcmd_vlan_token_vid,\n+\t\tNULL\n+\t},\n+};\n+\n+\n+cmdline_parse_ctx_t list_prompt_commands[] = {\n+\t(cmdline_parse_inst_t *)&pcmd_drvinfo,\n+\t(cmdline_parse_inst_t *)&pcmd_eeprom,\n+\t(cmdline_parse_inst_t *)&pcmd_link,\n+\t(cmdline_parse_inst_t *)&pcmd_macaddr_get,\n+\t(cmdline_parse_inst_t *)&pcmd_macaddr,\n+\t(cmdline_parse_inst_t *)&pcmd_mtu,\n+\t(cmdline_parse_inst_t *)&pcmd_open,\n+\t(cmdline_parse_inst_t *)&pcmd_pause_noopt,\n+\t(cmdline_parse_inst_t *)&pcmd_pause,\n+\t(cmdline_parse_inst_t *)&pcmd_portstats,\n+\t(cmdline_parse_inst_t *)&pcmd_regs,\n+\t(cmdline_parse_inst_t *)&pcmd_ringparam,\n+\t(cmdline_parse_inst_t *)&pcmd_ringparam_set,\n+\t(cmdline_parse_inst_t *)&pcmd_rxmode,\n+\t(cmdline_parse_inst_t *)&pcmd_stop,\n+\t(cmdline_parse_inst_t *)&pcmd_validate,\n+\t(cmdline_parse_inst_t *)&pcmd_vlan,\n+\t(cmdline_parse_inst_t *)&pcmd_quit,\n+\tNULL\n+};\n+\n+\n+void ethapp_main(void)\n+{\n+\tstruct cmdline *ctx_cmdline;\n+\n+\tctx_cmdline = cmdline_stdin_new(list_prompt_commands, \"EthApp> \");\n+\tcmdline_interact(ctx_cmdline);\n+\tcmdline_stdin_exit(ctx_cmdline);\n+}\ndiff --git a/examples/ethtool/app/ethapp.h b/examples/ethtool/app/ethapp.h\nnew file mode 100644\nindex 0000000..4d05441\n--- /dev/null\n+++ b/examples/ethtool/app/ethapp.h\n@@ -0,0 +1,40 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\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 Intel Corporation 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+\n+void ethapp_main(void);\n+void print_stats(void);\n+void lock_port(int idx_port);\n+void unlock_port(int idx_port);\n+void mark_port_inactive(int idx_port);\n+void mark_port_active(int idx_port);\ndiff --git a/examples/ethtool/app/main.c b/examples/ethtool/app/main.c\nnew file mode 100644\nindex 0000000..e8b04b8\n--- /dev/null\n+++ b/examples/ethtool/app/main.c\n@@ -0,0 +1,281 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\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 Intel Corporation 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+\n+#include <stdio.h>\n+#include <stdlib.h>\n+\n+#include <rte_common.h>\n+#include <rte_rwlock.h>\n+#include <rte_eal.h>\n+#include <rte_ethdev.h>\n+#include <rte_ether.h>\n+#include <rte_ip.h>\n+#include <rte_memory.h>\n+#include <rte_mempool.h>\n+#include <rte_mbuf.h>\n+\n+#include \"ethapp.h\"\n+\n+#define MAX_PORTS 4\n+#define MAX_BURST_LENGTH 32\n+#define PORT_RX_QUEUE_SIZE 128\n+#define PORT_TX_QUEUE_SIZE 256\n+#define PKTPOOL_SIZE 512\n+#define PKTPOOL_CACHE 32\n+\n+\n+struct app_txq {\n+\tstruct rte_mbuf *ptr_frames[MAX_BURST_LENGTH];\n+\tunsigned short cnt_frames;\n+};\n+\n+struct app_port {\n+\tstruct ether_addr mac_addr;\n+\tstruct app_txq tx_queue;\n+\trte_spinlock_t lock;\n+\tint port_active;\n+\tint exit_now;\n+\tint idx_port;\n+\tstruct rte_mempool *pkt_pool;\n+};\n+\n+struct app_config {\n+\tstruct app_port ports[MAX_PORTS];\n+};\n+\n+\n+struct app_config app_cfg;\n+\n+\n+void lock_port(int idx_port)\n+{\n+\tstruct app_port *ptr_port = &app_cfg.ports[idx_port];\n+\n+\trte_spinlock_lock(&ptr_port->lock);\n+}\n+\n+void unlock_port(int idx_port)\n+{\n+\tstruct app_port *ptr_port = &app_cfg.ports[idx_port];\n+\n+\trte_spinlock_unlock(&ptr_port->lock);\n+}\n+\n+void mark_port_active(int idx_port)\n+{\n+\tstruct app_port *ptr_port = &app_cfg.ports[idx_port];\n+\n+\tptr_port->port_active = 1;\n+}\n+\n+void mark_port_inactive(int idx_port)\n+{\n+\tstruct app_port *ptr_port = &app_cfg.ports[idx_port];\n+\n+\tptr_port->port_active = 0;\n+}\n+\n+\n+static void setup_ports(struct app_config *app_cfg, int cnt_ports)\n+{\n+\tint idx_port;\n+\tstruct rte_eth_conf cfg_port;\n+\tchar str_name[16];\n+\n+\tmemset(&cfg_port, 0, sizeof(cfg_port));\n+\tcfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;\n+\n+\tfor (idx_port = 0; idx_port < cnt_ports; idx_port++) {\n+\t\tstruct app_port *ptr_port = &app_cfg->ports[idx_port];\n+\n+\t\tsnprintf(str_name, 16, \"pkt_pool%i\", idx_port);\n+\t\tptr_port->pkt_pool = rte_pktmbuf_pool_create(\n+\t\t\tstr_name,\n+\t\t\tPKTPOOL_SIZE, PKTPOOL_CACHE,\n+\t\t\t0,\n+\t\t\tRTE_MBUF_DEFAULT_BUF_SIZE,\n+\t\t\trte_socket_id()\n+\t\t\t);\n+\t\tif (ptr_port->pkt_pool == NULL)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t\"rte_pktmbuf_pool_create failed\"\n+\t\t\t\t);\n+\n+\t\tprintf(\"Init port %i..\\n\", idx_port);\n+\t\tptr_port->tx_queue.cnt_frames = 0;\n+\t\tptr_port->exit_now = 0;\n+\t\tptr_port->port_active = 1;\n+\t\tptr_port->idx_port = idx_port;\n+\n+\t\tif (rte_eth_dev_configure(idx_port, 1, 1, &cfg_port) < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t \"rte_eth_dev_configure failed\");\n+\t\tif (rte_eth_rx_queue_setup(\n+\t\t\t    idx_port, 0, PORT_RX_QUEUE_SIZE,\n+\t\t\t    rte_eth_dev_socket_id(idx_port), NULL,\n+\t\t\t    ptr_port->pkt_pool) < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t \"rte_eth_rx_queue_setup failed\"\n+\t\t\t\t);\n+\t\tif (rte_eth_tx_queue_setup(\n+\t\t\t    idx_port, 0, PORT_TX_QUEUE_SIZE,\n+\t\t\t    rte_eth_dev_socket_id(idx_port), NULL) < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t \"rte_eth_tx_queue_setup failed\"\n+\t\t\t\t);\n+\t\tif (rte_eth_dev_start(idx_port) < 0)\n+\t\t\trte_exit(EXIT_FAILURE,\n+\t\t\t\t \"%s:%i: rte_eth_dev_start failed\",\n+\t\t\t\t __FILE__, __LINE__\n+\t\t\t\t);\n+\t\trte_eth_promiscuous_enable(idx_port);\n+\t\trte_eth_macaddr_get(idx_port, &ptr_port->mac_addr);\n+\t\trte_spinlock_init(&ptr_port->lock);\n+\t}\n+}\n+\n+static void process_frame(struct app_port *ptr_port,\n+\tstruct rte_mbuf *ptr_frame)\n+{\n+\tstruct ether_hdr *ptr_mac_hdr;\n+\n+\tptr_mac_hdr = rte_pktmbuf_mtod(ptr_frame, struct ether_hdr *);\n+\tether_addr_copy(&ptr_mac_hdr->s_addr, &ptr_mac_hdr->d_addr);\n+\trte_eth_macaddr_get(ptr_port->idx_port, &ptr_mac_hdr->s_addr);\n+\tptr_port->tx_queue.ptr_frames[ptr_port->tx_queue.cnt_frames++] =\n+\t\tptr_frame;\n+}\n+\n+static int slave_main(void *ptr_data)\n+{\n+\tstruct rte_mbuf *buf_recv_frames[MAX_BURST_LENGTH];\n+\tstruct app_port *ptr_port = ptr_data;\n+\tstruct rte_mbuf *ptr_frame;\n+\tstruct app_txq *ptr_txq = &ptr_port->tx_queue;\n+\tuint16_t cnt_recv_frames;\n+\tuint16_t cnt_backlog_frames;\n+\tuint16_t idx_frame;\n+\tuint16_t cnt_sent;\n+\n+\twhile (!ptr_port->exit_now) {\n+\t\trte_spinlock_lock(&ptr_port->lock);\n+\t\tif (ptr_port->port_active == 0) {\n+\t\t\trte_spinlock_unlock(&ptr_port->lock);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\t/* Incoming frames */\n+\t\tcnt_backlog_frames = ptr_txq->cnt_frames;\n+\t\tcnt_recv_frames = rte_eth_rx_burst(\n+\t\t\tptr_port->idx_port, 0,\n+\t\t\t&buf_recv_frames[ptr_txq->cnt_frames],\n+\t\t\tMAX_BURST_LENGTH - cnt_backlog_frames\n+\t\t\t);\n+\t\tif (cnt_recv_frames > 0) {\n+\t\t\tfor (idx_frame = 0;\n+\t\t\t\t\tidx_frame < cnt_recv_frames;\n+\t\t\t\t\tidx_frame++) {\n+\t\t\t\tptr_frame = buf_recv_frames[\n+\t\t\t\t\tidx_frame + cnt_backlog_frames];\n+\t\t\t\tprocess_frame(ptr_port, ptr_frame);\n+\t\t\t}\n+\t\t}\n+\n+\t\t/* Outgoing frames */\n+\t\tif (ptr_txq->cnt_frames > 0) {\n+\t\t\tcnt_sent = rte_eth_tx_burst(\n+\t\t\t\tptr_port->idx_port, 0,\n+\t\t\t\tptr_txq->ptr_frames,\n+\t\t\t\tptr_txq->cnt_frames\n+\t\t\t\t);\n+\t\t\t/* Shuffle up unsent frame pointers */\n+\t\t\tfor (idx_frame = cnt_sent;\n+\t\t\t\t\tidx_frame < ptr_txq->cnt_frames;\n+\t\t\t\t\tidx_frame++)\n+\t\t\t\tbuf_recv_frames[idx_frame - cnt_sent] =\n+\t\t\t\t\tbuf_recv_frames[idx_frame];\n+\t\t\tptr_txq->cnt_frames -= cnt_sent;\n+\t\t}\n+\t\trte_spinlock_unlock(&ptr_port->lock);\n+\n+\t} /* end for(;;) */\n+\n+\treturn 0;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tint cnt_args_parsed;\n+\tuint32_t idx_port;\n+\tuint32_t id_core;\n+\tuint32_t cnt_ports;\n+\tstruct app_port *ptr_port;\n+\n+\t/* Init runtime enviornment */\n+\tcnt_args_parsed = rte_eal_init(argc, argv);\n+\tif (cnt_args_parsed < 0)\n+\t\trte_exit(EXIT_FAILURE, \"rte_eal_init(): Failed\");\n+\n+\tcnt_ports = rte_eth_dev_count();\n+\tprintf(\"Eth NICs: %i\\n\", cnt_ports);\n+\tif (cnt_ports > MAX_PORTS) {\n+\t\tprintf(\"Warning: Using only %i of %i ports\\n\",\n+\t\t\tcnt_ports, MAX_PORTS\n+\t\t\t);\n+\t\tcnt_ports = MAX_PORTS;\n+\t}\n+\n+\tsetup_ports(&app_cfg, cnt_ports);\n+\n+\tif (rte_lcore_count() < cnt_ports + 1)\n+\t\trte_exit(EXIT_FAILURE, \"Not enough cores\");\n+\n+\n+\tfor (idx_port = 0; idx_port < cnt_ports; idx_port++) {\n+\t\tptr_port = &app_cfg.ports[idx_port];\n+\t\trte_eal_remote_launch(slave_main, ptr_port, idx_port + 1);\n+\t}\n+\n+\tethapp_main();\n+\n+\tfor (idx_port = 0; idx_port < cnt_ports; idx_port++)\n+\t\tapp_cfg.ports[idx_port].exit_now = 1;\n+\tRTE_LCORE_FOREACH_SLAVE(id_core) {\n+\t\tif (rte_eal_wait_lcore(id_core) < 0)\n+\t\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\ndiff --git a/examples/ethtool/lib/Makefile b/examples/ethtool/lib/Makefile\nnew file mode 100644\nindex 0000000..d7ee955\n--- /dev/null\n+++ b/examples/ethtool/lib/Makefile\n@@ -0,0 +1,57 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2015 Intel Corporation. All rights reserved.\n+#   All rights reserved.\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 Intel Corporation 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+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, can be overwritten by command line or environment\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+ifneq ($(CONFIG_RTE_EXEC_ENV),\"linuxapp\")\n+$(error This application can only operate in a linuxapp environment, \\\n+please change the definition of the RTE_TARGET environment variable)\n+endif\n+\n+# library name\n+LIB = librte_ethtool.a\n+\n+LIBABIVER := 1\n+\n+# all source are stored in SRC-Y\n+SRCS-y := rte_ethtool.c\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS)\n+\n+include $(RTE_SDK)/mk/rte.extlib.mk\ndiff --git a/examples/ethtool/lib/rte_ethtool.c b/examples/ethtool/lib/rte_ethtool.c\nnew file mode 100644\nindex 0000000..665f8b5\n--- /dev/null\n+++ b/examples/ethtool/lib/rte_ethtool.c\n@@ -0,0 +1,421 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\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 Intel Corporation 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+#include <stdio.h>\n+#include <string.h>\n+#include <stdint.h>\n+#include <rte_version.h>\n+#include <rte_ethdev.h>\n+#include <rte_ether.h>\n+#include \"rte_ethtool.h\"\n+\n+#define PKTPOOL_SIZE 512\n+#define PKTPOOL_CACHE 32\n+\n+\n+int\n+rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)\n+{\n+\tstruct rte_eth_dev_info dev_info;\n+\tint n;\n+\n+\tif (drvinfo == NULL)\n+\t\treturn -EINVAL;\n+\n+\tif (!rte_eth_dev_is_valid_port(port_id))\n+\t\treturn -ENODEV;\n+\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\trte_eth_dev_info_get(port_id, &dev_info);\n+\n+\tsnprintf(drvinfo->driver, sizeof(drvinfo->driver), \"%s\",\n+\t\tdev_info.driver_name);\n+\tsnprintf(drvinfo->version, sizeof(drvinfo->version), \"%s\",\n+\t\trte_version());\n+\tsnprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),\n+\t\t\"%04x:%02x:%02x.%x\",\n+\t\tdev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,\n+\t\tdev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function);\n+\n+\tn = rte_eth_dev_get_reg_length(port_id);\n+\tif (n > 0)\n+\t\tdrvinfo->regdump_len = n;\n+\telse\n+\t\tdrvinfo->regdump_len = 0;\n+\n+\tn = rte_eth_dev_get_eeprom_length(port_id);\n+\tif (n > 0)\n+\t\tdrvinfo->eedump_len = n;\n+\telse\n+\t\tdrvinfo->eedump_len = 0;\n+\n+\tdrvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);\n+\tdrvinfo->testinfo_len = 0;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_get_regs_len(uint8_t port_id)\n+{\n+\tint count_regs;\n+\n+\tcount_regs = rte_eth_dev_get_reg_length(port_id);\n+\tif (count_regs > 0)\n+\t\treturn count_regs * sizeof(uint32_t);\n+\treturn count_regs;\n+}\n+\n+int\n+rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs, void *data)\n+{\n+\tstruct rte_dev_reg_info reg_info;\n+\tint status;\n+\n+\tif (regs == NULL || data == NULL)\n+\t\treturn -EINVAL;\n+\n+\treg_info.data = data;\n+\treg_info.length = 0;\n+\n+\tstatus = rte_eth_dev_get_reg_info(port_id, &reg_info);\n+\tif (status)\n+\t\treturn status;\n+\tregs->version = reg_info.version;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_get_link(uint8_t port_id)\n+{\n+\tstruct rte_eth_link link;\n+\n+\tif (!rte_eth_dev_is_valid_port(port_id))\n+\t\treturn -ENODEV;\n+\trte_eth_link_get(port_id, &link);\n+\treturn link.link_status;\n+}\n+\n+int\n+rte_ethtool_get_eeprom_len(uint8_t port_id)\n+{\n+\treturn rte_eth_dev_get_eeprom_length(port_id);\n+}\n+\n+int\n+rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,\n+\tvoid *words)\n+{\n+\tstruct rte_dev_eeprom_info eeprom_info;\n+\tint status;\n+\n+\tif (eeprom == NULL || words == NULL || eeprom->offset >= eeprom->len)\n+\t\treturn -EINVAL;\n+\n+\teeprom_info.offset = eeprom->offset;\n+\teeprom_info.length = eeprom->len;\n+\teeprom_info.data = words;\n+\n+\tstatus = rte_eth_dev_get_eeprom(port_id, &eeprom_info);\n+\tif (status)\n+\t\treturn status;\n+\n+\teeprom->magic = eeprom_info.magic;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,\n+\tvoid *words)\n+{\n+\tstruct rte_dev_eeprom_info eeprom_info;\n+\tint status;\n+\n+\tif (eeprom == NULL || words == NULL || eeprom->offset >= eeprom->len)\n+\t\treturn -EINVAL;\n+\n+\teeprom_info.offset = eeprom->offset;\n+\teeprom_info.length = eeprom->len;\n+\teeprom_info.data = words;\n+\n+\tstatus = rte_eth_dev_set_eeprom(port_id, &eeprom_info);\n+\tif (status)\n+\t\treturn status;\n+\n+\teeprom->magic = eeprom_info.magic;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_get_pauseparam(uint8_t port_id,\n+\tstruct ethtool_pauseparam *pause_param)\n+{\n+\tstruct rte_eth_fc_conf fc_conf;\n+\tint status;\n+\n+\tif (pause_param == NULL)\n+\t\treturn -EINVAL;\n+\n+\tstatus = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);\n+\tif (status)\n+\t\treturn status;\n+\n+\tpause_param->tx_pause = 0;\n+\tpause_param->rx_pause = 0;\n+\tswitch (fc_conf.mode) {\n+\tcase RTE_FC_RX_PAUSE:\n+\t\tpause_param->rx_pause = 1;\n+\t\tbreak;\n+\tcase RTE_FC_TX_PAUSE:\n+\t\tpause_param->tx_pause = 1;\n+\t\tbreak;\n+\tcase RTE_FC_FULL:\n+\t\tpause_param->rx_pause = 1;\n+\t\tpause_param->tx_pause = 1;\n+\tdefault:\n+\t\t/* dummy block to avoid compiler warning */\n+\t\tbreak;\n+\t}\n+\tpause_param->autoneg = (uint32_t)fc_conf.autoneg;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_set_pauseparam(uint8_t port_id,\n+\tstruct ethtool_pauseparam *pause_param)\n+{\n+\tstruct rte_eth_fc_conf fc_conf;\n+\tint status;\n+\n+\tif (pause_param == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/*\n+\t * Read device flow control parameter first since\n+\t * ethtool set_pauseparam op doesn't have all the information.\n+\t * as defined in struct rte_eth_fc_conf.\n+\t * This API requires the device to support both\n+\t * rte_eth_dev_flow_ctrl_get and rte_eth_dev_flow_ctrl_set, otherwise\n+\t * return -ENOTSUP\n+\t */\n+\tstatus = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);\n+\tif (status)\n+\t\treturn status;\n+\n+\tfc_conf.autoneg = (uint8_t)pause_param->autoneg;\n+\n+\tif (pause_param->tx_pause) {\n+\t\tif (pause_param->rx_pause)\n+\t\t\tfc_conf.mode = RTE_FC_FULL;\n+\t\telse\n+\t\t\tfc_conf.mode = RTE_FC_TX_PAUSE;\n+\t} else {\n+\t\tif (pause_param->rx_pause)\n+\t\t\tfc_conf.mode = RTE_FC_RX_PAUSE;\n+\t\telse\n+\t\t\tfc_conf.mode = RTE_FC_NONE;\n+\t}\n+\n+\tstatus = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf);\n+\tif (status)\n+\t\treturn status;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_net_open(uint8_t port_id)\n+{\n+\trte_eth_dev_stop(port_id);\n+\n+\treturn rte_eth_dev_start(port_id);\n+}\n+\n+int\n+rte_ethtool_net_stop(uint8_t port_id)\n+{\n+\tif (!rte_eth_dev_is_valid_port(port_id))\n+\t\treturn -ENODEV;\n+\trte_eth_dev_stop(port_id);\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)\n+{\n+\tif (!rte_eth_dev_is_valid_port(port_id))\n+\t\treturn -ENODEV;\n+\tif (addr == NULL)\n+\t\treturn -EINVAL;\n+\trte_eth_macaddr_get(port_id, addr);\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)\n+{\n+\tif (addr == NULL)\n+\t\treturn -EINVAL;\n+\treturn rte_eth_dev_default_mac_addr_set(port_id, addr);\n+}\n+\n+int\n+rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,\n+\tstruct ether_addr *addr)\n+{\n+\tif (addr == NULL)\n+\t\treturn -EINVAL;\n+\treturn is_valid_assigned_ether_addr(addr);\n+}\n+\n+int\n+rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)\n+{\n+\treturn rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);\n+}\n+\n+int\n+rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)\n+{\n+\tif (stats == NULL)\n+\t\treturn -EINVAL;\n+\treturn rte_eth_stats_get(port_id, stats);\n+}\n+\n+int\n+rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)\n+{\n+\treturn rte_eth_dev_vlan_filter(port_id, vid, 1);\n+}\n+\n+int\n+rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)\n+{\n+\treturn rte_eth_dev_vlan_filter(port_id, vid, 0);\n+}\n+\n+/*\n+ * The set_rx_mode provides driver-specific rx mode setting.\n+ * This implementation implements rx mode setting based upon\n+ * ixgbe/igb drivers. Further improvement is to provide a\n+ * callback op field over struct rte_eth_dev::dev_ops so each\n+ * driver can register device-specific implementation\n+ */\n+int\n+rte_ethtool_net_set_rx_mode(uint8_t port_id)\n+{\n+\tuint16_t num_vfs;\n+\tstruct rte_eth_dev_info dev_info;\n+\tuint16_t vf;\n+\n+\tmemset(&dev_info, 0, sizeof(dev_info));\n+\trte_eth_dev_info_get(port_id, &dev_info);\n+\tnum_vfs = dev_info.max_vfs;\n+\n+\t/* Set VF vf_rx_mode, VF unsupport status is discard */\n+\tfor (vf = 0; vf < num_vfs; vf++)\n+\t\trte_eth_dev_set_vf_rxmode(port_id, vf,\n+\t\t\tETH_VMDQ_ACCEPT_UNTAG, 1);\n+\n+\t/* Enable Rx vlan filter, VF unspport status is discard */\n+\trte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);\n+\n+\treturn 0;\n+}\n+\n+\n+int\n+rte_ethtool_get_ringparam(uint8_t port_id,\n+\tstruct ethtool_ringparam *ring_param)\n+{\n+\tstruct rte_eth_dev_info dev_info;\n+\tstruct rte_eth_rxq_info rx_qinfo;\n+\tstruct rte_eth_txq_info tx_qinfo;\n+\tint stat;\n+\n+\tif (ring_param == NULL)\n+\t\treturn -EINVAL;\n+\n+\trte_eth_dev_info_get(port_id, &dev_info);\n+\n+\tstat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);\n+\tif (stat != 0)\n+\t\treturn stat;\n+\n+\tstat = rte_eth_tx_queue_info_get(port_id, 0, &tx_qinfo);\n+\tif (stat != 0)\n+\t\treturn stat;\n+\n+\tmemset(ring_param, 0, sizeof(*ring_param));\n+\tring_param->rx_pending = rx_qinfo.nb_desc;\n+\tring_param->rx_max_pending = dev_info.rx_desc_lim.nb_max;\n+\tring_param->tx_pending = tx_qinfo.nb_desc;\n+\tring_param->tx_max_pending = dev_info.tx_desc_lim.nb_max;\n+\n+\treturn 0;\n+}\n+\n+\n+int\n+rte_ethtool_set_ringparam(uint8_t port_id,\n+\tstruct ethtool_ringparam *ring_param)\n+{\n+\tstruct rte_eth_rxq_info rx_qinfo;\n+\tint stat;\n+\n+\tif (ring_param == NULL)\n+\t\treturn -EINVAL;\n+\n+\tstat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);\n+\tif (stat != 0)\n+\t\treturn stat;\n+\n+\trte_eth_dev_stop(port_id);\n+\n+\tstat = rte_eth_tx_queue_setup(port_id, 0, ring_param->tx_pending,\n+\t\trte_socket_id(), NULL);\n+\tif (stat != 0)\n+\t\treturn stat;\n+\n+\tstat = rte_eth_rx_queue_setup(port_id, 0, ring_param->rx_pending,\n+\t\trte_socket_id(), NULL, rx_qinfo.mp);\n+\tif (stat != 0)\n+\t\treturn stat;\n+\n+\treturn rte_eth_dev_start(port_id);\n+}\ndiff --git a/examples/ethtool/lib/rte_ethtool.h b/examples/ethtool/lib/rte_ethtool.h\nnew file mode 100644\nindex 0000000..2e79d45\n--- /dev/null\n+++ b/examples/ethtool/lib/rte_ethtool.h\n@@ -0,0 +1,410 @@\n+/*-\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ *   All rights reserved.\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 Intel Corporation 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+#ifndef _RTE_ETHTOOL_H_\n+#define _RTE_ETHTOOL_H_\n+\n+/*\n+ * This new interface is designed to provide a user-space shim layer for\n+ * Ethtool and Netdevice op API.\n+ *\n+ * rte_ethtool_get_driver:          ethtool_ops::get_driverinfo\n+ * rte_ethtool_get_link:            ethtool_ops::get_link\n+ * rte_ethtool_get_regs_len:        ethtool_ops::get_regs_len\n+ * rte_ethtool_get_regs:            ethtool_ops::get_regs\n+ * rte_ethtool_get_eeprom_len:      ethtool_ops::get_eeprom_len\n+ * rte_ethtool_get_eeprom:          ethtool_ops::get_eeprom\n+ * rte_ethtool_set_eeprom:          ethtool_ops::set_eeprom\n+ * rte_ethtool_get_pauseparam:      ethtool_ops::get_pauseparam\n+ * rte_ethtool_set_pauseparam:      ethtool_ops::set_pauseparam\n+ *\n+ * rte_ethtool_net_open:            net_device_ops::ndo_open\n+ * rte_ethtool_net_stop:            net_device_ops::ndo_stop\n+ * rte_ethtool_net_set_mac_addr:    net_device_ops::ndo_set_mac_address\n+ * rte_ethtool_net_validate_addr:   net_device_ops::ndo_validate_addr\n+ * rte_ethtool_net_change_mtu:      net_device_ops::rte_net_change_mtu\n+ * rte_ethtool_net_get_stats64:     net_device_ops::ndo_get_stats64\n+ * rte_ethtool_net_vlan_rx_add_vid  net_device_ops::ndo_vlan_rx_add_vid\n+ * rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid\n+ * rte_ethtool_net_set_rx_mode      net_device_ops::ndo_set_rx_mode\n+ *\n+ */\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+#include <rte_ethdev.h>\n+#include <linux/ethtool.h>\n+\n+/**\n+ * Retrieve the Ethernet device driver information according to\n+ * attributes described by ethtool data structure, ethtool_drvinfo.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param drvinfo\n+ *   A pointer to get driver information\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ */\n+int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo);\n+\n+/**\n+ * Retrieve the Ethernet device register length in bytes.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   - (> 0) # of device registers (in bytes) available for dump\n+ *   - (0) no registers available for dump.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_regs_len(uint8_t port_id);\n+\n+/**\n+ * Retrieve the Ethernet device register information according to\n+ * attributes described by ethtool data structure, ethtool_regs\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param reg\n+ *   A pointer to ethtool_regs that has register information\n+ * @param data\n+ *   A pointer to a buffer that is used to retrieve device register content\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,\n+\t\t\t    void *data);\n+\n+/**\n+ * Retrieve the Ethernet device link status\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   - (1) if link up.\n+ *   - (0) if link down.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_link(uint8_t port_id);\n+\n+/**\n+ * Retrieve the Ethernet device EEPROM size\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *\t - (> 0) device EEPROM size in bytes\n+ *   - (0) device has NO EEPROM\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_eeprom_len(uint8_t port_id);\n+\n+/**\n+ * Retrieve EEPROM content based upon eeprom range described in ethtool\n+ * data structure, ethtool_eeprom\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param eeprom\n+ *\t The pointer of ethtool_eeprom that provides eeprom range\n+ * @param words\n+ *\t A buffer that holds data read from eeprom\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,\n+\t\t\t      void *words);\n+\n+/**\n+ * Setting EEPROM content based upon eeprom range described in ethtool\n+ * data structure, ethtool_eeprom\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param eeprom\n+ *\t The pointer of ethtool_eeprom that provides eeprom range\n+ * @param words\n+ *\t A buffer that holds data to be written into eeprom\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,\n+\t\t\t      void *words);\n+\n+/**\n+ * Retrieve the Ethernet device pause frame configuration according to\n+ * parameter attributes desribed by ethtool data structure,\n+ * ethtool_pauseparam.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param pause_param\n+ *\t The pointer of ethtool_coalesce that gets pause frame\n+ *\t configuration parameters\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_get_pauseparam(uint8_t port_id,\n+\t\t\t\t   struct ethtool_pauseparam *pause_param);\n+\n+/**\n+ * Setting the Ethernet device pause frame configuration according to\n+ * parameter attributes desribed by ethtool data structure, ethtool_pauseparam.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param pause_param\n+ *\t The pointer of ethtool_coalesce that gets ring configuration parameters\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_set_pauseparam(uint8_t port_id,\n+\t\t\t\t   struct ethtool_pauseparam *param);\n+\n+/**\n+ * Start the Ethernet device.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_open(uint8_t port_id);\n+\n+/**\n+ * Stop the Ethernet device.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ */\n+int rte_ethtool_net_stop(uint8_t port_id);\n+\n+/**\n+ * Get the Ethernet device MAC address.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param addr\n+ *\t MAC address of the Ethernet device.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ */\n+int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);\n+\n+/**\n+ * Setting the Ethernet device MAC address.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param addr\n+ *\t The new MAC addr.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);\n+\n+/**\n+ * Validate if the provided MAC address is valid unicast address\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param addr\n+ *\t A pointer to a buffer (6-byte, 48bit) for the target MAC address\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);\n+\n+/**\n+ * Setting the Ethernet device maximum Tx unit.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param mtu\n+ *\t New MTU\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);\n+\n+/**\n+ * Retrieve the Ethernet device traffic statistics\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param stats\n+ *\t A pointer to struct rte_eth_stats for statistics parameters\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - (-EINVAL) if parameters invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);\n+\n+/**\n+ * Update the Ethernet device VLAN filter with new vid\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param vid\n+ *\t A new VLAN id\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);\n+\n+/**\n+ * Remove VLAN id from Ethernet device.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param vid\n+ *\t A new VLAN id\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);\n+\n+/**\n+ * Setting the Ethernet device rx mode.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ */\n+int rte_ethtool_net_set_rx_mode(uint8_t port_id);\n+\n+/**\n+ * Getting ring paramaters for Ethernet device.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param ring_param\n+ *   Pointer to struct ethrool_ringparam to receive parameters.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ * @note\n+ *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam\n+ *   are used, and the function only gets parameters for queue 0.\n+ */\n+int rte_ethtool_get_ringparam(uint8_t port_id,\n+\tstruct ethtool_ringparam *ring_param);\n+\n+/**\n+ * Setting ring paramaters for Ethernet device.\n+ *\n+ * @param port_id\n+ *   The port identifier of the Ethernet device.\n+ * @param ring_param\n+ *   Pointer to struct ethrool_ringparam with parameters to set.\n+ * @return\n+ *   - (0) if successful.\n+ *   - (-ENOTSUP) if hardware doesn't support.\n+ *   - (-ENODEV) if *port_id* invalid.\n+ *   - others depends on the specific operations implementation.\n+ * @note\n+ *   Only the tx_pending and rx_pending fields of struct ethtool_ringparam\n+ *   are used, and the function only sets parameters for queue 0.\n+ */\n+int rte_ethtool_set_ringparam(uint8_t port_id,\n+\tstruct ethtool_ringparam *ring_param);\n+\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_ETHTOOL_H_ */\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "1/2"
    ]
}