get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 7288,
    "url": "https://patches.dpdk.org/api/patches/7288/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1443593929-1804-3-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": "<1443593929-1804-3-git-send-email-remy.horton@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1443593929-1804-3-git-send-email-remy.horton@intel.com",
    "date": "2015-09-30T06:18:49",
    "name": "[dpdk-dev,v1,2/2] User-space ethtool sample application",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "8047bc9f667487a6b006dd6e791541139f383012",
    "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/1443593929-1804-3-git-send-email-remy.horton@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/7288/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/7288/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 4C84F8DAB;\n\tWed, 30 Sep 2015 08:19:00 +0200 (CEST)",
            "from mga02.intel.com (mga02.intel.com [134.134.136.20])\n\tby dpdk.org (Postfix) with ESMTP id 084868D91\n\tfor <dev@dpdk.org>; Wed, 30 Sep 2015 08:18:56 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga101.jf.intel.com with ESMTP; 29 Sep 2015 23:18:57 -0700",
            "from rhorton-mobl.ger.corp.intel.com (HELO localhost.ir.intel.com)\n\t([163.33.229.80])\n\tby orsmga002.jf.intel.com with ESMTP; 29 Sep 2015 23:18:55 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.17,611,1437462000\"; d=\"scan'208\";a=\"816032267\"",
        "From": "Remy Horton <remy.horton@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Wed, 30 Sep 2015 07:18:49 +0100",
        "Message-Id": "<1443593929-1804-3-git-send-email-remy.horton@intel.com>",
        "X-Mailer": "git-send-email 1.9.3",
        "In-Reply-To": "<1443593929-1804-1-git-send-email-remy.horton@intel.com>",
        "References": "<1443593929-1804-1-git-send-email-remy.horton@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v1 2/2] User-space ethtool sample application",
        "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 internal rte_ethtool shim layer based on rte_ethdev API,\nalong with a command prompt driven demonstration application.\n\nSigned-off-by: Remy Horton <remy.horton@intel.com>\n---\n examples/l2fwd/Makefile      |   2 +-\n examples/l2fwd/ethapp.c      | 792 +++++++++++++++++++++++++++++++++++++++++++\n examples/l2fwd/ethapp.h      |  38 +++\n examples/l2fwd/main.c        |  19 +-\n examples/l2fwd/rte_ethtool.c | 354 +++++++++++++++++++\n examples/l2fwd/rte_ethtool.h | 371 ++++++++++++++++++++\n 6 files changed, 1570 insertions(+), 6 deletions(-)\n create mode 100644 examples/l2fwd/ethapp.c\n create mode 100644 examples/l2fwd/ethapp.h\n create mode 100644 examples/l2fwd/rte_ethtool.c\n create mode 100644 examples/l2fwd/rte_ethtool.h",
    "diff": "diff --git a/examples/l2fwd/Makefile b/examples/l2fwd/Makefile\nindex 78feeeb..90e7512 100644\n--- a/examples/l2fwd/Makefile\n+++ b/examples/l2fwd/Makefile\n@@ -42,7 +42,7 @@ include $(RTE_SDK)/mk/rte.vars.mk\n APP = l2fwd\n \n # all source are stored in SRCS-y\n-SRCS-y := main.c\n+SRCS-y := main.c ethapp.c rte_ethtool.c\n \n CFLAGS += -O3\n CFLAGS += $(WERROR_FLAGS)\ndiff --git a/examples/l2fwd/ethapp.c b/examples/l2fwd/ethapp.c\nnew file mode 100644\nindex 0000000..90e0399\n--- /dev/null\n+++ b/examples/l2fwd/ethapp.c\n@@ -0,0 +1,792 @@\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+\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+\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+/* 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_stats_callback(__attribute__((unused)) void *ptr_params,\n+\t__attribute__((unused)) struct cmdline *ctx,\n+\t__attribute__((unused)) void *ptr_data)\n+{\n+\tprint_stats();\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+\tstat = rte_ethtool_net_open(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+\tstat = rte_ethtool_net_stop(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+\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_stats = {\n+\t.f = pcmd_stats_callback,\n+\t.data = NULL,\n+\t.help_str = \"stats\\n     Print l2fwd stats\",\n+\t.tokens = {(void *)&pcmd_stats_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|tx|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_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_rxmode,\n+\t(cmdline_parse_inst_t *)&pcmd_stats,\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/l2fwd/ethapp.h b/examples/l2fwd/ethapp.h\nnew file mode 100644\nindex 0000000..045922b\n--- /dev/null\n+++ b/examples/l2fwd/ethapp.h\n@@ -0,0 +1,38 @@\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+\n+\ndiff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c\nindex 2f0841d..82698f0 100644\n--- a/examples/l2fwd/main.c\n+++ b/examples/l2fwd/main.c\n@@ -68,6 +68,8 @@\n #include <rte_mempool.h>\n #include <rte_mbuf.h>\n \n+#include \"ethapp.h\"\n+\n #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1\n \n #define NB_MBUF   8192\n@@ -94,6 +96,8 @@ static uint32_t l2fwd_dst_ports[RTE_MAX_ETHPORTS];\n \n static unsigned int l2fwd_rx_queue_per_lcore = 1;\n \n+static int l2fwd_main_running = 1;\n+\n struct mbuf_table {\n \tunsigned len;\n \tstruct rte_mbuf *m_table[MAX_PKT_BURST];\n@@ -138,9 +142,8 @@ struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS];\n #define MAX_TIMER_PERIOD 86400 /* 1 day max */\n static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */\n \n-\n /* Print out statistics on packets dropped */\n-static void\n+void\n print_stats(void)\n {\n \tuint64_t total_packets_dropped, total_packets_tx, total_packets_rx;\n@@ -284,7 +287,7 @@ l2fwd_main_loop(void)\n \t\t\tportid);\n \t}\n \n-\twhile (1) {\n+\twhile (l2fwd_main_running) {\n \n \t\tcur_tsc = rte_rdtsc();\n \n@@ -603,7 +606,8 @@ main(int argc, char **argv)\n \t\tl2fwd_dst_ports[last_port] = last_port;\n \t}\n \n-\trx_lcore_id = 0;\n+\t/* Note: core id 0 (master) reserved for ethapp */\n+\trx_lcore_id = 1;\n \tqconf = NULL;\n \n \t/* Initialize the port/queue configuration of each logical core */\n@@ -706,7 +710,12 @@ main(int argc, char **argv)\n \tcheck_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask);\n \n \t/* launch per-lcore init on every lcore */\n-\trte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, CALL_MASTER);\n+\trte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, SKIP_MASTER);\n+\n+\t/* launch ethtool sample on master core */\n+\tethapp_main();\n+\n+\tl2fwd_main_running = 0;\n \tRTE_LCORE_FOREACH_SLAVE(lcore_id) {\n \t\tif (rte_eal_wait_lcore(lcore_id) < 0)\n \t\t\treturn -1;\ndiff --git a/examples/l2fwd/rte_ethtool.c b/examples/l2fwd/rte_ethtool.c\nnew file mode 100644\nindex 0000000..183fb20\n--- /dev/null\n+++ b/examples/l2fwd/rte_ethtool.c\n@@ -0,0 +1,354 @@\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_ethtool.h\"\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+}\ndiff --git a/examples/l2fwd/rte_ethtool.h b/examples/l2fwd/rte_ethtool.h\nnew file mode 100644\nindex 0000000..f5852e7\n--- /dev/null\n+++ b/examples/l2fwd/rte_ethtool.h\n@@ -0,0 +1,371 @@\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+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_ETHTOOL_H_ */\n",
    "prefixes": [
        "dpdk-dev",
        "v1",
        "2/2"
    ]
}