examples/ethtool: add user-space ethtool sample application
Further enhancements to the userspace ethtool implementation that was submitted in 2.1 and packaged as a self-contained sample application. Implements an rte_ethtool shim layer based on rte_ethdev API, along with a command prompt driven demonstration application. Signed-off-by: Remy Horton <remy.horton@intel.com>
This commit is contained in:
parent
341a1e0664
commit
bda68ab9d1
|
@ -521,6 +521,10 @@ M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
|
|||
F: examples/dpdk_qat/
|
||||
F: doc/guides/sample_app_ug/intel_quickassist.rst
|
||||
|
||||
M: Remy Horton <remy.horton@intel.com>
|
||||
F: examples/ethtool/
|
||||
F: doc/guides/sample_app_ug/ethtool.rst
|
||||
|
||||
F: examples/exception_path/
|
||||
F: doc/guides/sample_app_ug/exception_path.rst
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ New Features
|
|||
|
||||
* **Added port hotplug support to xenvirt.**
|
||||
|
||||
* **Added ethtool shim and sample application.**
|
||||
|
||||
|
||||
Resolved Issues
|
||||
---------------
|
||||
|
|
160
doc/guides/sample_app_ug/ethtool.rst
Normal file
160
doc/guides/sample_app_ug/ethtool.rst
Normal file
|
@ -0,0 +1,160 @@
|
|||
|
||||
.. BSD LICENSE
|
||||
Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Intel Corporation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Ethtool Sample Application
|
||||
==========================
|
||||
|
||||
The Ethtool sample application shows an implementation of an
|
||||
ethtool-like API and provides a console environment that allows
|
||||
its use to query and change Ethernet card parameters. The sample
|
||||
is based upon a simple L2 frame reflector.
|
||||
|
||||
Compiling the Application
|
||||
-------------------------
|
||||
|
||||
To compile the application:
|
||||
|
||||
#. Go to the sample application directory:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
export RTE_SDK=/path/to/rte_sdk
|
||||
cd ${RTE_SD}/examples/ethtool
|
||||
|
||||
#. Set the target (a default target is used if not specified). For example:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
export RTE_TARGET=x86_64-native-linuxapp-gcc
|
||||
|
||||
See the *DPDK Getting Started Guide* for possible RTE_TARGET values.
|
||||
|
||||
#. Build the application:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
make
|
||||
|
||||
Running the Application
|
||||
-----------------------
|
||||
|
||||
The application requires an available core for each port, plus one.
|
||||
The only available options are the standard ones for the EAL:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
./ethtool-app/ethtool-app/${RTE_TARGET}/ethtool [EAL options]
|
||||
|
||||
Refer to the *DPDK Getting Started Guide* for general information on
|
||||
running applications and the Environment Abstraction Layer (EAL)
|
||||
options.
|
||||
|
||||
Using the application
|
||||
---------------------
|
||||
|
||||
The application is console-driven using the cmdline DPDK interface:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
EthApp>
|
||||
|
||||
From this interface the available commands and descriptions of what
|
||||
they do as as follows:
|
||||
|
||||
* ``drvinfo``: Print driver info
|
||||
* ``eeprom``: Dump EEPROM to file
|
||||
* ``link``: Print port link states
|
||||
* ``macaddr``: Gets/sets MAC address
|
||||
* ``mtu``: Set NIC MTU
|
||||
* ``open``: Open port
|
||||
* ``pause``: Get/set port pause state
|
||||
* ``portstats``: Print port statistics
|
||||
* ``regs``: Dump port register(s) to file
|
||||
* ``ringparam``: Get/set ring parameters
|
||||
* ``rxmode``: Toggle port Rx mode
|
||||
* ``stop``: Stop port
|
||||
* ``validate``: Check that given MAC address is valid unicast address
|
||||
* ``vlan``: Add/remove VLAN id
|
||||
* ``quit``: Exit program
|
||||
|
||||
|
||||
Explanation
|
||||
-----------
|
||||
|
||||
The sample program has two parts: A background `packet reflector`_
|
||||
that runs on a slave core, and a foreground `Ethtool Shell`_ that
|
||||
runs on the master core. These are described below.
|
||||
|
||||
Packet Reflector
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The background packet reflector is intended to demonstrate basic
|
||||
packet processing on NIC ports controlled by the Ethtool shim.
|
||||
Each incoming MAC frame is rewritten so that it is returned to
|
||||
the sender, using the port in question's own MAC address as the
|
||||
source address, and is then sent out on the same port.
|
||||
|
||||
Ethtool Shell
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The foreground part of the Ethtool sample is a console-based
|
||||
interface that accepts commands as described in `using the
|
||||
application`_. Individual call-back functions handle the detail
|
||||
associated with each command, which make use of the functions
|
||||
defined in the `Ethtool interface`_ to the DPDK functions.
|
||||
|
||||
Ethtool interface
|
||||
-----------------
|
||||
|
||||
The Ethtool interface is built as a separate library, and implements
|
||||
the following functions:
|
||||
|
||||
- ``rte_ethtool_get_drvinfo()``
|
||||
- ``rte_ethtool_get_regs_len()``
|
||||
- ``rte_ethtool_get_regs()``
|
||||
- ``rte_ethtool_get_link()``
|
||||
- ``rte_ethtool_get_eeprom_len()``
|
||||
- ``rte_ethtool_get_eeprom()``
|
||||
- ``rte_ethtool_set_eeprom()``
|
||||
- ``rte_ethtool_get_pauseparam()``
|
||||
- ``rte_ethtool_set_pauseparam()``
|
||||
- ``rte_ethtool_net_open()``
|
||||
- ``rte_ethtool_net_stop()``
|
||||
- ``rte_ethtool_net_get_mac_addr()``
|
||||
- ``rte_ethtool_net_set_mac_addr()``
|
||||
- ``rte_ethtool_net_validate_addr()``
|
||||
- ``rte_ethtool_net_change_mtu()``
|
||||
- ``rte_ethtool_net_get_stats64()``
|
||||
- ``rte_ethtool_net_vlan_rx_add_vid()``
|
||||
- ``rte_ethtool_net_vlan_rx_kill_vid()``
|
||||
- ``rte_ethtool_net_set_rx_mode()``
|
||||
- ``rte_ethtool_get_ringparam()``
|
||||
- ``rte_ethtool_set_ringparam()``
|
|
@ -41,6 +41,7 @@ Sample Applications User Guide
|
|||
|
||||
intro
|
||||
cmd_line
|
||||
ethtool
|
||||
exception_path
|
||||
hello_world
|
||||
skeleton
|
||||
|
|
|
@ -43,6 +43,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += distributor
|
|||
ifneq ($(ICP_ROOT),)
|
||||
DIRS-y += dpdk_qat
|
||||
endif
|
||||
DIRS-y += ethtool
|
||||
DIRS-y += exception_path
|
||||
DIRS-y += helloworld
|
||||
DIRS-y += ip_pipeline
|
||||
|
|
48
examples/ethtool/Makefile
Normal file
48
examples/ethtool/Makefile
Normal file
|
@ -0,0 +1,48 @@
|
|||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ifeq ($(RTE_SDK),)
|
||||
$(error "Please define RTE_SDK environment variable")
|
||||
endif
|
||||
|
||||
# Default target, can be overwritten by command line or environment
|
||||
RTE_TARGET ?= x86_64-native-linuxapp-gcc
|
||||
|
||||
include $(RTE_SDK)/mk/rte.vars.mk
|
||||
|
||||
ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
|
||||
$(error This application can only operate in a linuxapp environment, \
|
||||
please change the definition of the RTE_TARGET environment variable)
|
||||
endif
|
||||
|
||||
DIRS-y += lib ethtool-app
|
||||
|
||||
include $(RTE_SDK)/mk/rte.extsubdir.mk
|
54
examples/ethtool/ethtool-app/Makefile
Normal file
54
examples/ethtool/ethtool-app/Makefile
Normal file
|
@ -0,0 +1,54 @@
|
|||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ifeq ($(RTE_SDK),)
|
||||
$(error "Please define RTE_SDK environment variable")
|
||||
endif
|
||||
|
||||
# Default target, can be overridden by command line or environment
|
||||
RTE_TARGET ?= x86_64-native-linuxapp-gcc
|
||||
|
||||
include $(RTE_SDK)/mk/rte.vars.mk
|
||||
|
||||
# binary name
|
||||
APP = ethtool
|
||||
|
||||
# all source are stored in SRCS-y
|
||||
SRCS-y := main.c ethapp.c
|
||||
|
||||
CFLAGS += -O3 -D_GNU_SOURCE -pthread -I$(SRCDIR)/../lib
|
||||
CFLAGS += $(WERROR_FLAGS)
|
||||
|
||||
LDLIBS += -L$(subst ethtool-app,lib,$(RTE_OUTPUT))/lib
|
||||
LDLIBS += -lrte_ethtool
|
||||
|
||||
|
||||
include $(RTE_SDK)/mk/rte.extapp.mk
|
873
examples/ethtool/ethtool-app/ethapp.c
Normal file
873
examples/ethtool/ethtool-app/ethapp.c
Normal file
|
@ -0,0 +1,873 @@
|
|||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <cmdline_parse.h>
|
||||
#include <cmdline_parse_num.h>
|
||||
#include <cmdline_parse_string.h>
|
||||
#include <cmdline_parse_etheraddr.h>
|
||||
#include <cmdline_socket.h>
|
||||
#include <cmdline.h>
|
||||
|
||||
#include "rte_ethtool.h"
|
||||
#include "ethapp.h"
|
||||
|
||||
#define EEPROM_DUMP_CHUNKSIZE 1024
|
||||
|
||||
|
||||
struct pcmd_get_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
};
|
||||
struct pcmd_int_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
uint16_t port;
|
||||
};
|
||||
struct pcmd_intstr_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
uint16_t port;
|
||||
cmdline_fixed_string_t opt;
|
||||
};
|
||||
struct pcmd_intmac_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
uint16_t port;
|
||||
struct ether_addr mac;
|
||||
};
|
||||
struct pcmd_str_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
cmdline_fixed_string_t opt;
|
||||
};
|
||||
struct pcmd_vlan_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
uint16_t port;
|
||||
cmdline_fixed_string_t mode;
|
||||
uint16_t vid;
|
||||
};
|
||||
struct pcmd_intintint_params {
|
||||
cmdline_fixed_string_t cmd;
|
||||
uint16_t port;
|
||||
uint16_t tx;
|
||||
uint16_t rx;
|
||||
};
|
||||
|
||||
|
||||
/* Parameter-less commands */
|
||||
cmdline_parse_token_string_t pcmd_quit_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "quit");
|
||||
cmdline_parse_token_string_t pcmd_stats_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "stats");
|
||||
cmdline_parse_token_string_t pcmd_drvinfo_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "drvinfo");
|
||||
cmdline_parse_token_string_t pcmd_link_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_get_params, cmd, "link");
|
||||
|
||||
/* Commands taking just port id */
|
||||
cmdline_parse_token_string_t pcmd_open_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "open");
|
||||
cmdline_parse_token_string_t pcmd_stop_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "stop");
|
||||
cmdline_parse_token_string_t pcmd_rxmode_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "rxmode");
|
||||
cmdline_parse_token_string_t pcmd_portstats_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_int_params, cmd, "portstats");
|
||||
cmdline_parse_token_num_t pcmd_int_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_int_params, port, UINT16);
|
||||
|
||||
/* Commands taking port id and string */
|
||||
cmdline_parse_token_string_t pcmd_eeprom_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "eeprom");
|
||||
cmdline_parse_token_string_t pcmd_mtu_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "mtu");
|
||||
cmdline_parse_token_string_t pcmd_regs_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "regs");
|
||||
|
||||
cmdline_parse_token_num_t pcmd_intstr_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
|
||||
cmdline_parse_token_string_t pcmd_intstr_token_opt =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, opt, NULL);
|
||||
|
||||
/* Commands taking port id and a MAC address string */
|
||||
cmdline_parse_token_string_t pcmd_macaddr_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "macaddr");
|
||||
cmdline_parse_token_num_t pcmd_intmac_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intmac_params, port, UINT16);
|
||||
cmdline_parse_token_etheraddr_t pcmd_intmac_token_mac =
|
||||
TOKEN_ETHERADDR_INITIALIZER(struct pcmd_intmac_params, mac);
|
||||
|
||||
/* Command taking just a MAC address */
|
||||
cmdline_parse_token_string_t pcmd_validate_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intmac_params, cmd, "validate");
|
||||
|
||||
|
||||
/* Commands taking port id and two integers */
|
||||
cmdline_parse_token_string_t pcmd_ringparam_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intintint_params, cmd,
|
||||
"ringparam");
|
||||
cmdline_parse_token_num_t pcmd_intintint_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, port, UINT16);
|
||||
cmdline_parse_token_num_t pcmd_intintint_token_tx =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, tx, UINT16);
|
||||
cmdline_parse_token_num_t pcmd_intintint_token_rx =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intintint_params, rx, UINT16);
|
||||
|
||||
|
||||
/* Pause commands */
|
||||
cmdline_parse_token_string_t pcmd_pause_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params, cmd, "pause");
|
||||
cmdline_parse_token_num_t pcmd_pause_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_intstr_params, port, UINT16);
|
||||
cmdline_parse_token_string_t pcmd_pause_token_opt =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_intstr_params,
|
||||
opt, "all#tx#rx#none");
|
||||
|
||||
/* VLAN commands */
|
||||
cmdline_parse_token_string_t pcmd_vlan_token_cmd =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, cmd, "vlan");
|
||||
cmdline_parse_token_num_t pcmd_vlan_token_port =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, port, UINT16);
|
||||
cmdline_parse_token_string_t pcmd_vlan_token_mode =
|
||||
TOKEN_STRING_INITIALIZER(struct pcmd_vlan_params, mode, "add#del");
|
||||
cmdline_parse_token_num_t pcmd_vlan_token_vid =
|
||||
TOKEN_NUM_INITIALIZER(struct pcmd_vlan_params, vid, UINT16);
|
||||
|
||||
|
||||
static void
|
||||
pcmd_quit_callback(__rte_unused void *ptr_params,
|
||||
struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
cmdline_quit(ctx);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_drvinfo_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct ethtool_drvinfo info;
|
||||
int id_port;
|
||||
|
||||
for (id_port = 0; id_port < rte_eth_dev_count(); id_port++) {
|
||||
if (rte_ethtool_get_drvinfo(id_port, &info)) {
|
||||
printf("Error getting info for port %i\n", id_port);
|
||||
return;
|
||||
}
|
||||
printf("Port %i driver: %s (ver: %s)\n",
|
||||
id_port, info.driver, info.version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_link_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
int num_ports = rte_eth_dev_count();
|
||||
int id_port, stat_port;
|
||||
|
||||
for (id_port = 0; id_port < num_ports; id_port++) {
|
||||
if (!rte_eth_dev_is_valid_port(id_port))
|
||||
continue;
|
||||
stat_port = rte_ethtool_get_link(id_port);
|
||||
switch (stat_port) {
|
||||
case 0:
|
||||
printf("Port %i: Down\n", id_port);
|
||||
break;
|
||||
case 1:
|
||||
printf("Port %i: Up\n", id_port);
|
||||
break;
|
||||
default:
|
||||
printf("Port %i: Error getting link status\n",
|
||||
id_port
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_regs_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_intstr_params *params = ptr_params;
|
||||
int len_regs;
|
||||
struct ethtool_regs regs;
|
||||
unsigned char *buf_data;
|
||||
FILE *fp_regs;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
len_regs = rte_ethtool_get_regs_len(params->port);
|
||||
if (len_regs > 0) {
|
||||
printf("Port %i: %i bytes\n", params->port, len_regs);
|
||||
buf_data = malloc(len_regs);
|
||||
if (buf_data == NULL) {
|
||||
printf("Error allocating %i bytes for buffer\n",
|
||||
len_regs);
|
||||
return;
|
||||
}
|
||||
if (!rte_ethtool_get_regs(params->port, ®s, buf_data)) {
|
||||
fp_regs = fopen(params->opt, "wb");
|
||||
if (fp_regs == NULL) {
|
||||
printf("Error opening '%s' for writing\n",
|
||||
params->opt);
|
||||
} else {
|
||||
if ((int)fwrite(buf_data,
|
||||
1, len_regs,
|
||||
fp_regs) != len_regs)
|
||||
printf("Error writing '%s'\n",
|
||||
params->opt);
|
||||
fclose(fp_regs);
|
||||
}
|
||||
}
|
||||
free(buf_data);
|
||||
} else if (len_regs == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error getting registers\n", params->port);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_eeprom_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_intstr_params *params = ptr_params;
|
||||
struct ethtool_eeprom info_eeprom;
|
||||
int len_eeprom;
|
||||
int pos_eeprom;
|
||||
int stat;
|
||||
unsigned char bytes_eeprom[EEPROM_DUMP_CHUNKSIZE];
|
||||
FILE *fp_eeprom;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
len_eeprom = rte_ethtool_get_eeprom_len(params->port);
|
||||
if (len_eeprom > 0) {
|
||||
fp_eeprom = fopen(params->opt, "wb");
|
||||
if (fp_eeprom == NULL) {
|
||||
printf("Error opening '%s' for writing\n",
|
||||
params->opt);
|
||||
return;
|
||||
}
|
||||
printf("Total EEPROM length: %i bytes\n", len_eeprom);
|
||||
info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
|
||||
for (pos_eeprom = 0;
|
||||
pos_eeprom < len_eeprom;
|
||||
pos_eeprom += EEPROM_DUMP_CHUNKSIZE) {
|
||||
info_eeprom.offset = pos_eeprom;
|
||||
if (pos_eeprom + EEPROM_DUMP_CHUNKSIZE > len_eeprom)
|
||||
info_eeprom.len = len_eeprom - pos_eeprom;
|
||||
else
|
||||
info_eeprom.len = EEPROM_DUMP_CHUNKSIZE;
|
||||
stat = rte_ethtool_get_eeprom(
|
||||
params->port, &info_eeprom, bytes_eeprom
|
||||
);
|
||||
if (stat != 0) {
|
||||
printf("EEPROM read error %i\n", stat);
|
||||
break;
|
||||
}
|
||||
if (fwrite(bytes_eeprom,
|
||||
1, info_eeprom.len,
|
||||
fp_eeprom) != info_eeprom.len) {
|
||||
printf("Error writing '%s'\n", params->opt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp_eeprom);
|
||||
} else if (len_eeprom == 0)
|
||||
printf("Port %i: Device does not have EEPROM\n", params->port);
|
||||
else if (len_eeprom == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error getting EEPROM\n", params->port);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_pause_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
void *ptr_data)
|
||||
{
|
||||
struct pcmd_intstr_params *params = ptr_params;
|
||||
struct ethtool_pauseparam info;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
if (ptr_data != NULL) {
|
||||
stat = rte_ethtool_get_pauseparam(params->port, &info);
|
||||
} else {
|
||||
if (strcasecmp("all", params->opt) == 0) {
|
||||
info.tx_pause = 1;
|
||||
info.rx_pause = 1;
|
||||
} else if (strcasecmp("tx", params->opt) == 0) {
|
||||
info.tx_pause = 1;
|
||||
info.rx_pause = 0;
|
||||
} else if (strcasecmp("rx", params->opt) == 0) {
|
||||
info.tx_pause = 0;
|
||||
info.rx_pause = 1;
|
||||
} else {
|
||||
info.tx_pause = 0;
|
||||
info.rx_pause = 0;
|
||||
}
|
||||
stat = rte_ethtool_set_pauseparam(params->port, &info);
|
||||
}
|
||||
if (stat == 0) {
|
||||
if (info.rx_pause && info.tx_pause)
|
||||
printf("Port %i: Tx & Rx Paused\n", params->port);
|
||||
else if (info.rx_pause)
|
||||
printf("Port %i: Rx Paused\n", params->port);
|
||||
else if (info.tx_pause)
|
||||
printf("Port %i: Tx Paused\n", params->port);
|
||||
else
|
||||
printf("Port %i: Tx & Rx not paused\n", params->port);
|
||||
} else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error %i\n", params->port, stat);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_open_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_int_params *params = ptr_params;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
lock_port(params->port);
|
||||
stat = rte_ethtool_net_open(params->port);
|
||||
mark_port_active(params->port);
|
||||
unlock_port(params->port);
|
||||
if (stat == 0)
|
||||
return;
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error opening device\n", params->port);
|
||||
}
|
||||
|
||||
static void
|
||||
pcmd_stop_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_int_params *params = ptr_params;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
lock_port(params->port);
|
||||
stat = rte_ethtool_net_stop(params->port);
|
||||
mark_port_inactive(params->port);
|
||||
unlock_port(params->port);
|
||||
if (stat == 0)
|
||||
return;
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error stopping device\n", params->port);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_rxmode_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_intstr_params *params = ptr_params;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
stat = rte_ethtool_net_set_rx_mode(params->port);
|
||||
if (stat == 0)
|
||||
return;
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error setting rx mode\n", params->port);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pcmd_macaddr_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
void *ptr_data)
|
||||
{
|
||||
struct pcmd_intmac_params *params = ptr_params;
|
||||
struct ether_addr mac_addr;
|
||||
int stat;
|
||||
|
||||
stat = 0;
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
if (ptr_data != NULL) {
|
||||
lock_port(params->port);
|
||||
stat = rte_ethtool_net_set_mac_addr(params->port,
|
||||
¶ms->mac);
|
||||
mark_port_newmac(params->port);
|
||||
unlock_port(params->port);
|
||||
if (stat == 0) {
|
||||
printf("MAC address changed\n");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
stat = rte_ethtool_net_get_mac_addr(params->port, &mac_addr);
|
||||
if (stat == 0) {
|
||||
printf(
|
||||
"Port %i MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
params->port,
|
||||
mac_addr.addr_bytes[0],
|
||||
mac_addr.addr_bytes[1],
|
||||
mac_addr.addr_bytes[2],
|
||||
mac_addr.addr_bytes[3],
|
||||
mac_addr.addr_bytes[4],
|
||||
mac_addr.addr_bytes[5]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (stat == 0)
|
||||
return;
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error %i\n", params->port, stat);
|
||||
}
|
||||
|
||||
static void
|
||||
pcmd_mtu_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_intstr_params *params = ptr_params;
|
||||
int stat;
|
||||
int new_mtu;
|
||||
char *ptr_parse_end;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
new_mtu = atoi(params->opt);
|
||||
new_mtu = strtoul(params->opt, &ptr_parse_end, 10);
|
||||
if (*ptr_parse_end != '\0' ||
|
||||
new_mtu < ETHER_MIN_MTU ||
|
||||
new_mtu > ETHER_MAX_JUMBO_FRAME_LEN) {
|
||||
printf("Port %i: Invalid MTU value\n", params->port);
|
||||
return;
|
||||
}
|
||||
stat = rte_ethtool_net_change_mtu(params->port, new_mtu);
|
||||
if (stat == 0)
|
||||
printf("Port %i: MTU set to %i\n", params->port, new_mtu);
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error setting MTU\n", params->port);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void pcmd_portstats_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_int_params *params = ptr_params;
|
||||
struct rte_eth_stats stat_info;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
stat = rte_ethtool_net_get_stats64(params->port, &stat_info);
|
||||
if (stat == 0) {
|
||||
/* Most of rte_eth_stats is deprecated.. */
|
||||
printf("Port %i stats\n", params->port);
|
||||
printf(" In: %" PRIu64 " (%" PRIu64 " bytes)\n"
|
||||
" Out: %"PRIu64" (%"PRIu64 " bytes)\n"
|
||||
" Err: %"PRIu64"\n",
|
||||
stat_info.ipackets,
|
||||
stat_info.ibytes,
|
||||
stat_info.opackets,
|
||||
stat_info.obytes,
|
||||
stat_info.ierrors+stat_info.oerrors
|
||||
);
|
||||
} else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error fetching statistics\n", params->port);
|
||||
}
|
||||
|
||||
static void pcmd_ringparam_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
void *ptr_data)
|
||||
{
|
||||
struct pcmd_intintint_params *params = ptr_params;
|
||||
struct ethtool_ringparam ring_data;
|
||||
struct ethtool_ringparam ring_params;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
if (ptr_data == NULL) {
|
||||
stat = rte_ethtool_get_ringparam(params->port, &ring_data);
|
||||
if (stat == 0) {
|
||||
printf("Port %i ring parameters\n"
|
||||
" Rx Pending: %i (%i max)\n"
|
||||
" Tx Pending: %i (%i max)\n",
|
||||
params->port,
|
||||
ring_data.rx_pending,
|
||||
ring_data.rx_max_pending,
|
||||
ring_data.tx_pending,
|
||||
ring_data.tx_max_pending);
|
||||
}
|
||||
} else {
|
||||
if (params->tx < 1 || params->rx < 1) {
|
||||
printf("Error: Invalid parameters\n");
|
||||
return;
|
||||
}
|
||||
memset(&ring_params, 0, sizeof(struct ethtool_ringparam));
|
||||
ring_params.tx_pending = params->tx;
|
||||
ring_params.rx_pending = params->rx;
|
||||
lock_port(params->port);
|
||||
stat = rte_ethtool_set_ringparam(params->port, &ring_params);
|
||||
unlock_port(params->port);
|
||||
}
|
||||
if (stat == 0)
|
||||
return;
|
||||
else if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else
|
||||
printf("Port %i: Error fetching statistics\n", params->port);
|
||||
}
|
||||
|
||||
static void pcmd_validate_callback(void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_intmac_params *params = ptr_params;
|
||||
|
||||
if (rte_ethtool_net_validate_addr(0, ¶ms->mac))
|
||||
printf("Address is unicast\n");
|
||||
else
|
||||
printf("Address is not unicast\n");
|
||||
}
|
||||
|
||||
|
||||
static void pcmd_vlan_callback(__rte_unused void *ptr_params,
|
||||
__rte_unused struct cmdline *ctx,
|
||||
__rte_unused void *ptr_data)
|
||||
{
|
||||
struct pcmd_vlan_params *params = ptr_params;
|
||||
int stat;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(params->port)) {
|
||||
printf("Error: Invalid port number %i\n", params->port);
|
||||
return;
|
||||
}
|
||||
stat = 0;
|
||||
|
||||
if (strcasecmp("add", params->mode) == 0) {
|
||||
stat = rte_ethtool_net_vlan_rx_add_vid(
|
||||
params->port, params->vid
|
||||
);
|
||||
if (stat == 0)
|
||||
printf("VLAN vid %i added\n", params->vid);
|
||||
|
||||
} else if (strcasecmp("del", params->mode) == 0) {
|
||||
stat = rte_ethtool_net_vlan_rx_kill_vid(
|
||||
params->port, params->vid
|
||||
);
|
||||
if (stat == 0)
|
||||
printf("VLAN vid %i removed\n", params->vid);
|
||||
} else {
|
||||
/* Should not happen! */
|
||||
printf("Error: Bad mode %s\n", params->mode);
|
||||
}
|
||||
if (stat == -ENOTSUP)
|
||||
printf("Port %i: Operation not supported\n", params->port);
|
||||
else if (stat == -ENOSYS)
|
||||
printf("Port %i: VLAN filtering disabled\n", params->port);
|
||||
else if (stat != 0)
|
||||
printf("Port %i: Error changing VLAN setup (code %i)\n",
|
||||
params->port, -stat);
|
||||
}
|
||||
|
||||
|
||||
cmdline_parse_inst_t pcmd_quit = {
|
||||
.f = pcmd_quit_callback,
|
||||
.data = NULL,
|
||||
.help_str = "quit\n Exit program",
|
||||
.tokens = {(void *)&pcmd_quit_token_cmd, NULL},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_drvinfo = {
|
||||
.f = pcmd_drvinfo_callback,
|
||||
.data = NULL,
|
||||
.help_str = "drvinfo\n Print driver info",
|
||||
.tokens = {(void *)&pcmd_drvinfo_token_cmd, NULL},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_link = {
|
||||
.f = pcmd_link_callback,
|
||||
.data = NULL,
|
||||
.help_str = "link\n Print port link states",
|
||||
.tokens = {(void *)&pcmd_link_token_cmd, NULL},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_regs = {
|
||||
.f = pcmd_regs_callback,
|
||||
.data = NULL,
|
||||
.help_str = "regs <port_id> <filename>\n"
|
||||
" Dump port register(s) to file",
|
||||
.tokens = {
|
||||
(void *)&pcmd_regs_token_cmd,
|
||||
(void *)&pcmd_intstr_token_port,
|
||||
(void *)&pcmd_intstr_token_opt,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_eeprom = {
|
||||
.f = pcmd_eeprom_callback,
|
||||
.data = NULL,
|
||||
.help_str = "eeprom <port_id> <filename>\n Dump EEPROM to file",
|
||||
.tokens = {
|
||||
(void *)&pcmd_eeprom_token_cmd,
|
||||
(void *)&pcmd_intstr_token_port,
|
||||
(void *)&pcmd_intstr_token_opt,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_pause_noopt = {
|
||||
.f = pcmd_pause_callback,
|
||||
.data = (void *)0x01,
|
||||
.help_str = "pause <port_id>\n Print port pause state",
|
||||
.tokens = {
|
||||
(void *)&pcmd_pause_token_cmd,
|
||||
(void *)&pcmd_pause_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_pause = {
|
||||
.f = pcmd_pause_callback,
|
||||
.data = NULL,
|
||||
.help_str =
|
||||
"pause <port_id> <all|tx|rx|none>\n Pause/unpause port",
|
||||
.tokens = {
|
||||
(void *)&pcmd_pause_token_cmd,
|
||||
(void *)&pcmd_pause_token_port,
|
||||
(void *)&pcmd_pause_token_opt,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_open = {
|
||||
.f = pcmd_open_callback,
|
||||
.data = NULL,
|
||||
.help_str = "open <port_id>\n Open port",
|
||||
.tokens = {
|
||||
(void *)&pcmd_open_token_cmd,
|
||||
(void *)&pcmd_int_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_stop = {
|
||||
.f = pcmd_stop_callback,
|
||||
.data = NULL,
|
||||
.help_str = "stop <port_id>\n Stop port",
|
||||
.tokens = {
|
||||
(void *)&pcmd_stop_token_cmd,
|
||||
(void *)&pcmd_int_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_rxmode = {
|
||||
.f = pcmd_rxmode_callback,
|
||||
.data = NULL,
|
||||
.help_str = "rxmode <port_id>\n Toggle port Rx mode",
|
||||
.tokens = {
|
||||
(void *)&pcmd_rxmode_token_cmd,
|
||||
(void *)&pcmd_int_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_macaddr_get = {
|
||||
.f = pcmd_macaddr_callback,
|
||||
.data = NULL,
|
||||
.help_str = "macaddr <port_id>\n"
|
||||
" Get MAC address",
|
||||
.tokens = {
|
||||
(void *)&pcmd_macaddr_token_cmd,
|
||||
(void *)&pcmd_intstr_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_macaddr = {
|
||||
.f = pcmd_macaddr_callback,
|
||||
.data = (void *)0x01,
|
||||
.help_str =
|
||||
"macaddr <port_id> <mac_addr>\n"
|
||||
" Set MAC address",
|
||||
.tokens = {
|
||||
(void *)&pcmd_macaddr_token_cmd,
|
||||
(void *)&pcmd_intmac_token_port,
|
||||
(void *)&pcmd_intmac_token_mac,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_mtu = {
|
||||
.f = pcmd_mtu_callback,
|
||||
.data = NULL,
|
||||
.help_str = "mtu <port_id> <mtu_value>\n"
|
||||
" Change MTU",
|
||||
.tokens = {
|
||||
(void *)&pcmd_mtu_token_cmd,
|
||||
(void *)&pcmd_intstr_token_port,
|
||||
(void *)&pcmd_intstr_token_opt,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_portstats = {
|
||||
.f = pcmd_portstats_callback,
|
||||
.data = NULL,
|
||||
.help_str = "portstats <port_id>\n"
|
||||
" Print port eth statistics",
|
||||
.tokens = {
|
||||
(void *)&pcmd_portstats_token_cmd,
|
||||
(void *)&pcmd_int_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_ringparam = {
|
||||
.f = pcmd_ringparam_callback,
|
||||
.data = NULL,
|
||||
.help_str = "ringparam <port_id>\n"
|
||||
" Print ring parameters",
|
||||
.tokens = {
|
||||
(void *)&pcmd_ringparam_token_cmd,
|
||||
(void *)&pcmd_intintint_token_port,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_ringparam_set = {
|
||||
.f = pcmd_ringparam_callback,
|
||||
.data = (void *)1,
|
||||
.help_str = "ringparam <port_id> <tx_param> <rx_param>\n"
|
||||
" Set ring parameters",
|
||||
.tokens = {
|
||||
(void *)&pcmd_ringparam_token_cmd,
|
||||
(void *)&pcmd_intintint_token_port,
|
||||
(void *)&pcmd_intintint_token_tx,
|
||||
(void *)&pcmd_intintint_token_rx,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_validate = {
|
||||
.f = pcmd_validate_callback,
|
||||
.data = NULL,
|
||||
.help_str = "validate <mac_addr>\n"
|
||||
" Check that MAC address is valid unicast address",
|
||||
.tokens = {
|
||||
(void *)&pcmd_validate_token_cmd,
|
||||
(void *)&pcmd_intmac_token_mac,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
cmdline_parse_inst_t pcmd_vlan = {
|
||||
.f = pcmd_vlan_callback,
|
||||
.data = NULL,
|
||||
.help_str = "vlan <port_id> <add|del> <vlan_id>\n"
|
||||
" Add/remove VLAN id",
|
||||
.tokens = {
|
||||
(void *)&pcmd_vlan_token_cmd,
|
||||
(void *)&pcmd_vlan_token_port,
|
||||
(void *)&pcmd_vlan_token_mode,
|
||||
(void *)&pcmd_vlan_token_vid,
|
||||
NULL
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
cmdline_parse_ctx_t list_prompt_commands[] = {
|
||||
(cmdline_parse_inst_t *)&pcmd_drvinfo,
|
||||
(cmdline_parse_inst_t *)&pcmd_eeprom,
|
||||
(cmdline_parse_inst_t *)&pcmd_link,
|
||||
(cmdline_parse_inst_t *)&pcmd_macaddr_get,
|
||||
(cmdline_parse_inst_t *)&pcmd_macaddr,
|
||||
(cmdline_parse_inst_t *)&pcmd_mtu,
|
||||
(cmdline_parse_inst_t *)&pcmd_open,
|
||||
(cmdline_parse_inst_t *)&pcmd_pause_noopt,
|
||||
(cmdline_parse_inst_t *)&pcmd_pause,
|
||||
(cmdline_parse_inst_t *)&pcmd_portstats,
|
||||
(cmdline_parse_inst_t *)&pcmd_regs,
|
||||
(cmdline_parse_inst_t *)&pcmd_ringparam,
|
||||
(cmdline_parse_inst_t *)&pcmd_ringparam_set,
|
||||
(cmdline_parse_inst_t *)&pcmd_rxmode,
|
||||
(cmdline_parse_inst_t *)&pcmd_stop,
|
||||
(cmdline_parse_inst_t *)&pcmd_validate,
|
||||
(cmdline_parse_inst_t *)&pcmd_vlan,
|
||||
(cmdline_parse_inst_t *)&pcmd_quit,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void ethapp_main(void)
|
||||
{
|
||||
struct cmdline *ctx_cmdline;
|
||||
|
||||
ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
|
||||
cmdline_interact(ctx_cmdline);
|
||||
cmdline_stdin_exit(ctx_cmdline);
|
||||
}
|
41
examples/ethtool/ethtool-app/ethapp.h
Normal file
41
examples/ethtool/ethtool-app/ethapp.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
void ethapp_main(void);
|
||||
void print_stats(void);
|
||||
void lock_port(int idx_port);
|
||||
void unlock_port(int idx_port);
|
||||
void mark_port_inactive(int idx_port);
|
||||
void mark_port_active(int idx_port);
|
||||
void mark_port_newmac(int idx_port);
|
305
examples/ethtool/ethtool-app/main.c
Normal file
305
examples/ethtool/ethtool-app/main.c
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rte_common.h>
|
||||
#include <rte_rwlock.h>
|
||||
#include <rte_eal.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_ether.h>
|
||||
#include <rte_ip.h>
|
||||
#include <rte_memory.h>
|
||||
#include <rte_mempool.h>
|
||||
#include <rte_mbuf.h>
|
||||
|
||||
#include "ethapp.h"
|
||||
|
||||
#define MAX_PORTS RTE_MAX_ETHPORTS
|
||||
#define MAX_BURST_LENGTH 32
|
||||
#define PORT_RX_QUEUE_SIZE 128
|
||||
#define PORT_TX_QUEUE_SIZE 256
|
||||
#define PKTPOOL_EXTRA_SIZE 512
|
||||
#define PKTPOOL_CACHE 32
|
||||
|
||||
|
||||
struct txq_port {
|
||||
uint16_t cnt_unsent;
|
||||
struct rte_mbuf *buf_frames[MAX_BURST_LENGTH];
|
||||
};
|
||||
|
||||
struct app_port {
|
||||
struct ether_addr mac_addr;
|
||||
struct txq_port txq;
|
||||
rte_spinlock_t lock;
|
||||
int port_active;
|
||||
int port_dirty;
|
||||
int idx_port;
|
||||
struct rte_mempool *pkt_pool;
|
||||
};
|
||||
|
||||
struct app_config {
|
||||
struct app_port ports[MAX_PORTS];
|
||||
int cnt_ports;
|
||||
int exit_now;
|
||||
};
|
||||
|
||||
|
||||
struct app_config app_cfg;
|
||||
|
||||
|
||||
void lock_port(int idx_port)
|
||||
{
|
||||
struct app_port *ptr_port = &app_cfg.ports[idx_port];
|
||||
|
||||
rte_spinlock_lock(&ptr_port->lock);
|
||||
}
|
||||
|
||||
void unlock_port(int idx_port)
|
||||
{
|
||||
struct app_port *ptr_port = &app_cfg.ports[idx_port];
|
||||
|
||||
rte_spinlock_unlock(&ptr_port->lock);
|
||||
}
|
||||
|
||||
void mark_port_active(int idx_port)
|
||||
{
|
||||
struct app_port *ptr_port = &app_cfg.ports[idx_port];
|
||||
|
||||
ptr_port->port_active = 1;
|
||||
}
|
||||
|
||||
void mark_port_inactive(int idx_port)
|
||||
{
|
||||
struct app_port *ptr_port = &app_cfg.ports[idx_port];
|
||||
|
||||
ptr_port->port_active = 0;
|
||||
}
|
||||
|
||||
void mark_port_newmac(int idx_port)
|
||||
{
|
||||
struct app_port *ptr_port = &app_cfg.ports[idx_port];
|
||||
|
||||
ptr_port->port_dirty = 1;
|
||||
}
|
||||
|
||||
static void setup_ports(struct app_config *app_cfg, int cnt_ports)
|
||||
{
|
||||
int idx_port;
|
||||
int size_pktpool;
|
||||
struct rte_eth_conf cfg_port;
|
||||
struct rte_eth_dev_info dev_info;
|
||||
char str_name[16];
|
||||
|
||||
memset(&cfg_port, 0, sizeof(cfg_port));
|
||||
cfg_port.txmode.mq_mode = ETH_MQ_TX_NONE;
|
||||
|
||||
for (idx_port = 0; idx_port < cnt_ports; idx_port++) {
|
||||
struct app_port *ptr_port = &app_cfg->ports[idx_port];
|
||||
|
||||
rte_eth_dev_info_get(idx_port, &dev_info);
|
||||
size_pktpool = dev_info.rx_desc_lim.nb_max +
|
||||
dev_info.tx_desc_lim.nb_max + PKTPOOL_EXTRA_SIZE;
|
||||
|
||||
snprintf(str_name, 16, "pkt_pool%i", idx_port);
|
||||
ptr_port->pkt_pool = rte_pktmbuf_pool_create(
|
||||
str_name,
|
||||
size_pktpool, PKTPOOL_CACHE,
|
||||
0,
|
||||
RTE_MBUF_DEFAULT_BUF_SIZE,
|
||||
rte_socket_id()
|
||||
);
|
||||
if (ptr_port->pkt_pool == NULL)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"rte_pktmbuf_pool_create failed"
|
||||
);
|
||||
|
||||
printf("Init port %i..\n", idx_port);
|
||||
ptr_port->port_active = 1;
|
||||
ptr_port->port_dirty = 0;
|
||||
ptr_port->idx_port = idx_port;
|
||||
|
||||
if (rte_eth_dev_configure(idx_port, 1, 1, &cfg_port) < 0)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"rte_eth_dev_configure failed");
|
||||
if (rte_eth_rx_queue_setup(
|
||||
idx_port, 0, PORT_RX_QUEUE_SIZE,
|
||||
rte_eth_dev_socket_id(idx_port), NULL,
|
||||
ptr_port->pkt_pool) < 0)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"rte_eth_rx_queue_setup failed"
|
||||
);
|
||||
if (rte_eth_tx_queue_setup(
|
||||
idx_port, 0, PORT_TX_QUEUE_SIZE,
|
||||
rte_eth_dev_socket_id(idx_port), NULL) < 0)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"rte_eth_tx_queue_setup failed"
|
||||
);
|
||||
if (rte_eth_dev_start(idx_port) < 0)
|
||||
rte_exit(EXIT_FAILURE,
|
||||
"%s:%i: rte_eth_dev_start failed",
|
||||
__FILE__, __LINE__
|
||||
);
|
||||
rte_eth_promiscuous_enable(idx_port);
|
||||
rte_eth_macaddr_get(idx_port, &ptr_port->mac_addr);
|
||||
rte_spinlock_init(&ptr_port->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_frame(struct app_port *ptr_port,
|
||||
struct rte_mbuf *ptr_frame)
|
||||
{
|
||||
struct ether_hdr *ptr_mac_hdr;
|
||||
|
||||
ptr_mac_hdr = rte_pktmbuf_mtod(ptr_frame, struct ether_hdr *);
|
||||
ether_addr_copy(&ptr_mac_hdr->s_addr, &ptr_mac_hdr->d_addr);
|
||||
ether_addr_copy(&ptr_port->mac_addr, &ptr_mac_hdr->s_addr);
|
||||
}
|
||||
|
||||
static int slave_main(__attribute__((unused)) void *ptr_data)
|
||||
{
|
||||
struct app_port *ptr_port;
|
||||
struct rte_mbuf *ptr_frame;
|
||||
struct txq_port *txq;
|
||||
|
||||
uint16_t cnt_recv_frames;
|
||||
uint16_t idx_frame;
|
||||
uint16_t cnt_sent;
|
||||
uint16_t idx_port;
|
||||
uint16_t lock_result;
|
||||
|
||||
while (app_cfg.exit_now == 0) {
|
||||
for (idx_port = 0; idx_port < app_cfg.cnt_ports; idx_port++) {
|
||||
/* Check that port is active and unlocked */
|
||||
ptr_port = &app_cfg.ports[idx_port];
|
||||
lock_result = rte_spinlock_trylock(&ptr_port->lock);
|
||||
if (lock_result == 0)
|
||||
continue;
|
||||
if (ptr_port->port_active == 0) {
|
||||
rte_spinlock_unlock(&ptr_port->lock);
|
||||
continue;
|
||||
}
|
||||
txq = &ptr_port->txq;
|
||||
|
||||
/* MAC address was updated */
|
||||
if (ptr_port->port_dirty == 1) {
|
||||
rte_eth_macaddr_get(ptr_port->idx_port,
|
||||
&ptr_port->mac_addr);
|
||||
ptr_port->port_dirty = 0;
|
||||
}
|
||||
|
||||
/* Incoming frames */
|
||||
cnt_recv_frames = rte_eth_rx_burst(
|
||||
ptr_port->idx_port, 0,
|
||||
&txq->buf_frames[txq->cnt_unsent],
|
||||
RTE_DIM(txq->buf_frames) - txq->cnt_unsent
|
||||
);
|
||||
if (cnt_recv_frames > 0) {
|
||||
for (idx_frame = 0;
|
||||
idx_frame < cnt_recv_frames;
|
||||
idx_frame++) {
|
||||
ptr_frame = txq->buf_frames[
|
||||
idx_frame + txq->cnt_unsent];
|
||||
process_frame(ptr_port, ptr_frame);
|
||||
}
|
||||
txq->cnt_unsent += cnt_recv_frames;
|
||||
}
|
||||
|
||||
/* Outgoing frames */
|
||||
if (txq->cnt_unsent > 0) {
|
||||
cnt_sent = rte_eth_tx_burst(
|
||||
ptr_port->idx_port, 0,
|
||||
txq->buf_frames,
|
||||
txq->cnt_unsent
|
||||
);
|
||||
/* Shuffle up unsent frame pointers */
|
||||
for (idx_frame = cnt_sent;
|
||||
idx_frame < txq->cnt_unsent;
|
||||
idx_frame++)
|
||||
txq->buf_frames[idx_frame - cnt_sent] =
|
||||
txq->buf_frames[idx_frame];
|
||||
txq->cnt_unsent -= cnt_sent;
|
||||
}
|
||||
rte_spinlock_unlock(&ptr_port->lock);
|
||||
} /* end for( idx_port ) */
|
||||
} /* end for(;;) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int cnt_args_parsed;
|
||||
uint32_t id_core;
|
||||
uint32_t cnt_ports;
|
||||
|
||||
/* Init runtime enviornment */
|
||||
cnt_args_parsed = rte_eal_init(argc, argv);
|
||||
if (cnt_args_parsed < 0)
|
||||
rte_exit(EXIT_FAILURE, "rte_eal_init(): Failed");
|
||||
|
||||
cnt_ports = rte_eth_dev_count();
|
||||
printf("Number of NICs: %i\n", cnt_ports);
|
||||
if (cnt_ports == 0)
|
||||
rte_exit(EXIT_FAILURE, "No available NIC ports!\n");
|
||||
if (cnt_ports > MAX_PORTS) {
|
||||
printf("Info: Using only %i of %i ports\n",
|
||||
cnt_ports, MAX_PORTS
|
||||
);
|
||||
cnt_ports = MAX_PORTS;
|
||||
}
|
||||
|
||||
setup_ports(&app_cfg, cnt_ports);
|
||||
|
||||
app_cfg.exit_now = 0;
|
||||
app_cfg.cnt_ports = cnt_ports;
|
||||
|
||||
if (rte_lcore_count() < 2)
|
||||
rte_exit(EXIT_FAILURE, "No available slave core!\n");
|
||||
/* Assume there is an available slave.. */
|
||||
id_core = rte_lcore_id();
|
||||
id_core = rte_get_next_lcore(id_core, 1, 1);
|
||||
rte_eal_remote_launch(slave_main, NULL, id_core);
|
||||
|
||||
ethapp_main();
|
||||
|
||||
app_cfg.exit_now = 1;
|
||||
RTE_LCORE_FOREACH_SLAVE(id_core) {
|
||||
if (rte_eal_wait_lcore(id_core) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
57
examples/ethtool/lib/Makefile
Normal file
57
examples/ethtool/lib/Makefile
Normal file
|
@ -0,0 +1,57 @@
|
|||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2015 Intel Corporation. All rights reserved.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ifeq ($(RTE_SDK),)
|
||||
$(error "Please define RTE_SDK environment variable")
|
||||
endif
|
||||
|
||||
# Default target, can be overwritten by command line or environment
|
||||
RTE_TARGET ?= x86_64-native-linuxapp-gcc
|
||||
|
||||
include $(RTE_SDK)/mk/rte.vars.mk
|
||||
|
||||
ifneq ($(CONFIG_RTE_EXEC_ENV),"linuxapp")
|
||||
$(error This application can only operate in a linuxapp environment, \
|
||||
please change the definition of the RTE_TARGET environment variable)
|
||||
endif
|
||||
|
||||
# library name
|
||||
LIB = librte_ethtool.a
|
||||
|
||||
LIBABIVER := 1
|
||||
|
||||
# all source are stored in SRC-Y
|
||||
SRCS-y := rte_ethtool.c
|
||||
|
||||
CFLAGS += -O3
|
||||
CFLAGS += $(WERROR_FLAGS)
|
||||
|
||||
include $(RTE_SDK)/mk/rte.extlib.mk
|
423
examples/ethtool/lib/rte_ethtool.c
Normal file
423
examples/ethtool/lib/rte_ethtool.c
Normal file
|
@ -0,0 +1,423 @@
|
|||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <rte_version.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <rte_ether.h>
|
||||
#include "rte_ethtool.h"
|
||||
|
||||
#define PKTPOOL_SIZE 512
|
||||
#define PKTPOOL_CACHE 32
|
||||
|
||||
|
||||
int
|
||||
rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo)
|
||||
{
|
||||
struct rte_eth_dev_info dev_info;
|
||||
int n;
|
||||
|
||||
if (drvinfo == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(port_id))
|
||||
return -ENODEV;
|
||||
|
||||
memset(&dev_info, 0, sizeof(dev_info));
|
||||
rte_eth_dev_info_get(port_id, &dev_info);
|
||||
|
||||
snprintf(drvinfo->driver, sizeof(drvinfo->driver), "%s",
|
||||
dev_info.driver_name);
|
||||
snprintf(drvinfo->version, sizeof(drvinfo->version), "%s",
|
||||
rte_version());
|
||||
snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
|
||||
"%04x:%02x:%02x.%x",
|
||||
dev_info.pci_dev->addr.domain, dev_info.pci_dev->addr.bus,
|
||||
dev_info.pci_dev->addr.devid, dev_info.pci_dev->addr.function);
|
||||
|
||||
n = rte_eth_dev_get_reg_length(port_id);
|
||||
if (n > 0)
|
||||
drvinfo->regdump_len = n;
|
||||
else
|
||||
drvinfo->regdump_len = 0;
|
||||
|
||||
n = rte_eth_dev_get_eeprom_length(port_id);
|
||||
if (n > 0)
|
||||
drvinfo->eedump_len = n;
|
||||
else
|
||||
drvinfo->eedump_len = 0;
|
||||
|
||||
drvinfo->n_stats = sizeof(struct rte_eth_stats) / sizeof(uint64_t);
|
||||
drvinfo->testinfo_len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_regs_len(uint8_t port_id)
|
||||
{
|
||||
int count_regs;
|
||||
|
||||
count_regs = rte_eth_dev_get_reg_length(port_id);
|
||||
if (count_regs > 0)
|
||||
return count_regs * sizeof(uint32_t);
|
||||
return count_regs;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs, void *data)
|
||||
{
|
||||
struct rte_dev_reg_info reg_info;
|
||||
int status;
|
||||
|
||||
if (regs == NULL || data == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
reg_info.data = data;
|
||||
reg_info.length = 0;
|
||||
|
||||
status = rte_eth_dev_get_reg_info(port_id, ®_info);
|
||||
if (status)
|
||||
return status;
|
||||
regs->version = reg_info.version;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_link(uint8_t port_id)
|
||||
{
|
||||
struct rte_eth_link link;
|
||||
|
||||
if (!rte_eth_dev_is_valid_port(port_id))
|
||||
return -ENODEV;
|
||||
rte_eth_link_get(port_id, &link);
|
||||
return link.link_status;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_eeprom_len(uint8_t port_id)
|
||||
{
|
||||
return rte_eth_dev_get_eeprom_length(port_id);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
|
||||
void *words)
|
||||
{
|
||||
struct rte_dev_eeprom_info eeprom_info;
|
||||
int status;
|
||||
|
||||
if (eeprom == NULL || words == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
eeprom_info.offset = eeprom->offset;
|
||||
eeprom_info.length = eeprom->len;
|
||||
eeprom_info.data = words;
|
||||
|
||||
status = rte_eth_dev_get_eeprom(port_id, &eeprom_info);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
eeprom->magic = eeprom_info.magic;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
|
||||
void *words)
|
||||
{
|
||||
struct rte_dev_eeprom_info eeprom_info;
|
||||
int status;
|
||||
|
||||
if (eeprom == NULL || words == NULL || eeprom->offset >= eeprom->len)
|
||||
return -EINVAL;
|
||||
|
||||
eeprom_info.offset = eeprom->offset;
|
||||
eeprom_info.length = eeprom->len;
|
||||
eeprom_info.data = words;
|
||||
|
||||
status = rte_eth_dev_set_eeprom(port_id, &eeprom_info);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
eeprom->magic = eeprom_info.magic;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_get_pauseparam(uint8_t port_id,
|
||||
struct ethtool_pauseparam *pause_param)
|
||||
{
|
||||
struct rte_eth_fc_conf fc_conf;
|
||||
int status;
|
||||
|
||||
if (pause_param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
pause_param->tx_pause = 0;
|
||||
pause_param->rx_pause = 0;
|
||||
switch (fc_conf.mode) {
|
||||
case RTE_FC_RX_PAUSE:
|
||||
pause_param->rx_pause = 1;
|
||||
break;
|
||||
case RTE_FC_TX_PAUSE:
|
||||
pause_param->tx_pause = 1;
|
||||
break;
|
||||
case RTE_FC_FULL:
|
||||
pause_param->rx_pause = 1;
|
||||
pause_param->tx_pause = 1;
|
||||
default:
|
||||
/* dummy block to avoid compiler warning */
|
||||
break;
|
||||
}
|
||||
pause_param->autoneg = (uint32_t)fc_conf.autoneg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_set_pauseparam(uint8_t port_id,
|
||||
struct ethtool_pauseparam *pause_param)
|
||||
{
|
||||
struct rte_eth_fc_conf fc_conf;
|
||||
int status;
|
||||
|
||||
if (pause_param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Read device flow control parameter first since
|
||||
* ethtool set_pauseparam op doesn't have all the information.
|
||||
* as defined in struct rte_eth_fc_conf.
|
||||
* This API requires the device to support both
|
||||
* rte_eth_dev_flow_ctrl_get and rte_eth_dev_flow_ctrl_set, otherwise
|
||||
* return -ENOTSUP
|
||||
*/
|
||||
status = rte_eth_dev_flow_ctrl_get(port_id, &fc_conf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
fc_conf.autoneg = (uint8_t)pause_param->autoneg;
|
||||
|
||||
if (pause_param->tx_pause) {
|
||||
if (pause_param->rx_pause)
|
||||
fc_conf.mode = RTE_FC_FULL;
|
||||
else
|
||||
fc_conf.mode = RTE_FC_TX_PAUSE;
|
||||
} else {
|
||||
if (pause_param->rx_pause)
|
||||
fc_conf.mode = RTE_FC_RX_PAUSE;
|
||||
else
|
||||
fc_conf.mode = RTE_FC_NONE;
|
||||
}
|
||||
|
||||
status = rte_eth_dev_flow_ctrl_set(port_id, &fc_conf);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_open(uint8_t port_id)
|
||||
{
|
||||
rte_eth_dev_stop(port_id);
|
||||
|
||||
return rte_eth_dev_start(port_id);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_stop(uint8_t port_id)
|
||||
{
|
||||
if (!rte_eth_dev_is_valid_port(port_id))
|
||||
return -ENODEV;
|
||||
rte_eth_dev_stop(port_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr)
|
||||
{
|
||||
if (!rte_eth_dev_is_valid_port(port_id))
|
||||
return -ENODEV;
|
||||
if (addr == NULL)
|
||||
return -EINVAL;
|
||||
rte_eth_macaddr_get(port_id, addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr)
|
||||
{
|
||||
if (addr == NULL)
|
||||
return -EINVAL;
|
||||
return rte_eth_dev_default_mac_addr_set(port_id, addr);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_validate_addr(uint8_t port_id __rte_unused,
|
||||
struct ether_addr *addr)
|
||||
{
|
||||
if (addr == NULL)
|
||||
return -EINVAL;
|
||||
return is_valid_assigned_ether_addr(addr);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_change_mtu(uint8_t port_id, int mtu)
|
||||
{
|
||||
if (mtu < 0 || mtu > UINT16_MAX)
|
||||
return -EINVAL;
|
||||
return rte_eth_dev_set_mtu(port_id, (uint16_t)mtu);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats)
|
||||
{
|
||||
if (stats == NULL)
|
||||
return -EINVAL;
|
||||
return rte_eth_stats_get(port_id, stats);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid)
|
||||
{
|
||||
return rte_eth_dev_vlan_filter(port_id, vid, 1);
|
||||
}
|
||||
|
||||
int
|
||||
rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid)
|
||||
{
|
||||
return rte_eth_dev_vlan_filter(port_id, vid, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The set_rx_mode provides driver-specific rx mode setting.
|
||||
* This implementation implements rx mode setting based upon
|
||||
* ixgbe/igb drivers. Further improvement is to provide a
|
||||
* callback op field over struct rte_eth_dev::dev_ops so each
|
||||
* driver can register device-specific implementation
|
||||
*/
|
||||
int
|
||||
rte_ethtool_net_set_rx_mode(uint8_t port_id)
|
||||
{
|
||||
uint16_t num_vfs;
|
||||
struct rte_eth_dev_info dev_info;
|
||||
uint16_t vf;
|
||||
|
||||
memset(&dev_info, 0, sizeof(dev_info));
|
||||
rte_eth_dev_info_get(port_id, &dev_info);
|
||||
num_vfs = dev_info.max_vfs;
|
||||
|
||||
/* Set VF vf_rx_mode, VF unsupport status is discard */
|
||||
for (vf = 0; vf < num_vfs; vf++)
|
||||
rte_eth_dev_set_vf_rxmode(port_id, vf,
|
||||
ETH_VMDQ_ACCEPT_UNTAG, 0);
|
||||
|
||||
/* Enable Rx vlan filter, VF unspport status is discard */
|
||||
rte_eth_dev_set_vlan_offload(port_id, ETH_VLAN_FILTER_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rte_ethtool_get_ringparam(uint8_t port_id,
|
||||
struct ethtool_ringparam *ring_param)
|
||||
{
|
||||
struct rte_eth_dev_info dev_info;
|
||||
struct rte_eth_rxq_info rx_qinfo;
|
||||
struct rte_eth_txq_info tx_qinfo;
|
||||
int stat;
|
||||
|
||||
if (ring_param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
rte_eth_dev_info_get(port_id, &dev_info);
|
||||
|
||||
stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
|
||||
if (stat != 0)
|
||||
return stat;
|
||||
|
||||
stat = rte_eth_tx_queue_info_get(port_id, 0, &tx_qinfo);
|
||||
if (stat != 0)
|
||||
return stat;
|
||||
|
||||
memset(ring_param, 0, sizeof(*ring_param));
|
||||
ring_param->rx_pending = rx_qinfo.nb_desc;
|
||||
ring_param->rx_max_pending = dev_info.rx_desc_lim.nb_max;
|
||||
ring_param->tx_pending = tx_qinfo.nb_desc;
|
||||
ring_param->tx_max_pending = dev_info.tx_desc_lim.nb_max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rte_ethtool_set_ringparam(uint8_t port_id,
|
||||
struct ethtool_ringparam *ring_param)
|
||||
{
|
||||
struct rte_eth_rxq_info rx_qinfo;
|
||||
int stat;
|
||||
|
||||
if (ring_param == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
stat = rte_eth_rx_queue_info_get(port_id, 0, &rx_qinfo);
|
||||
if (stat != 0)
|
||||
return stat;
|
||||
|
||||
rte_eth_dev_stop(port_id);
|
||||
|
||||
stat = rte_eth_tx_queue_setup(port_id, 0, ring_param->tx_pending,
|
||||
rte_socket_id(), NULL);
|
||||
if (stat != 0)
|
||||
return stat;
|
||||
|
||||
stat = rte_eth_rx_queue_setup(port_id, 0, ring_param->rx_pending,
|
||||
rte_socket_id(), NULL, rx_qinfo.mp);
|
||||
if (stat != 0)
|
||||
return stat;
|
||||
|
||||
return rte_eth_dev_start(port_id);
|
||||
}
|
410
examples/ethtool/lib/rte_ethtool.h
Normal file
410
examples/ethtool/lib/rte_ethtool.h
Normal file
|
@ -0,0 +1,410 @@
|
|||
/*-
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _RTE_ETHTOOL_H_
|
||||
#define _RTE_ETHTOOL_H_
|
||||
|
||||
/*
|
||||
* This new interface is designed to provide a user-space shim layer for
|
||||
* Ethtool and Netdevice op API.
|
||||
*
|
||||
* rte_ethtool_get_driver: ethtool_ops::get_driverinfo
|
||||
* rte_ethtool_get_link: ethtool_ops::get_link
|
||||
* rte_ethtool_get_regs_len: ethtool_ops::get_regs_len
|
||||
* rte_ethtool_get_regs: ethtool_ops::get_regs
|
||||
* rte_ethtool_get_eeprom_len: ethtool_ops::get_eeprom_len
|
||||
* rte_ethtool_get_eeprom: ethtool_ops::get_eeprom
|
||||
* rte_ethtool_set_eeprom: ethtool_ops::set_eeprom
|
||||
* rte_ethtool_get_pauseparam: ethtool_ops::get_pauseparam
|
||||
* rte_ethtool_set_pauseparam: ethtool_ops::set_pauseparam
|
||||
*
|
||||
* rte_ethtool_net_open: net_device_ops::ndo_open
|
||||
* rte_ethtool_net_stop: net_device_ops::ndo_stop
|
||||
* rte_ethtool_net_set_mac_addr: net_device_ops::ndo_set_mac_address
|
||||
* rte_ethtool_net_validate_addr: net_device_ops::ndo_validate_addr
|
||||
* rte_ethtool_net_change_mtu: net_device_ops::rte_net_change_mtu
|
||||
* rte_ethtool_net_get_stats64: net_device_ops::ndo_get_stats64
|
||||
* rte_ethtool_net_vlan_rx_add_vid net_device_ops::ndo_vlan_rx_add_vid
|
||||
* rte_ethtool_net_vlan_rx_kill_vid net_device_ops::ndo_vlan_rx_kill_vid
|
||||
* rte_ethtool_net_set_rx_mode net_device_ops::ndo_set_rx_mode
|
||||
*
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rte_ethdev.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device driver information according to
|
||||
* attributes described by ethtool data structure, ethtool_drvinfo.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param drvinfo
|
||||
* A pointer to get driver information
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
*/
|
||||
int rte_ethtool_get_drvinfo(uint8_t port_id, struct ethtool_drvinfo *drvinfo);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device register length in bytes.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (> 0) # of device registers (in bytes) available for dump
|
||||
* - (0) no registers available for dump.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_regs_len(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device register information according to
|
||||
* attributes described by ethtool data structure, ethtool_regs
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param reg
|
||||
* A pointer to ethtool_regs that has register information
|
||||
* @param data
|
||||
* A pointer to a buffer that is used to retrieve device register content
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_regs(uint8_t port_id, struct ethtool_regs *regs,
|
||||
void *data);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device link status
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (1) if link up.
|
||||
* - (0) if link down.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_link(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device EEPROM size
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (> 0) device EEPROM size in bytes
|
||||
* - (0) device has NO EEPROM
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_eeprom_len(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Retrieve EEPROM content based upon eeprom range described in ethtool
|
||||
* data structure, ethtool_eeprom
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param eeprom
|
||||
* The pointer of ethtool_eeprom that provides eeprom range
|
||||
* @param words
|
||||
* A buffer that holds data read from eeprom
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
|
||||
void *words);
|
||||
|
||||
/**
|
||||
* Setting EEPROM content based upon eeprom range described in ethtool
|
||||
* data structure, ethtool_eeprom
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param eeprom
|
||||
* The pointer of ethtool_eeprom that provides eeprom range
|
||||
* @param words
|
||||
* A buffer that holds data to be written into eeprom
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_set_eeprom(uint8_t port_id, struct ethtool_eeprom *eeprom,
|
||||
void *words);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device pause frame configuration according to
|
||||
* parameter attributes desribed by ethtool data structure,
|
||||
* ethtool_pauseparam.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param pause_param
|
||||
* The pointer of ethtool_coalesce that gets pause frame
|
||||
* configuration parameters
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_get_pauseparam(uint8_t port_id,
|
||||
struct ethtool_pauseparam *pause_param);
|
||||
|
||||
/**
|
||||
* Setting the Ethernet device pause frame configuration according to
|
||||
* parameter attributes desribed by ethtool data structure, ethtool_pauseparam.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param pause_param
|
||||
* The pointer of ethtool_coalesce that gets ring configuration parameters
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_set_pauseparam(uint8_t port_id,
|
||||
struct ethtool_pauseparam *param);
|
||||
|
||||
/**
|
||||
* Start the Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_open(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Stop the Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
*/
|
||||
int rte_ethtool_net_stop(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Get the Ethernet device MAC address.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param addr
|
||||
* MAC address of the Ethernet device.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
*/
|
||||
int rte_ethtool_net_get_mac_addr(uint8_t port_id, struct ether_addr *addr);
|
||||
|
||||
/**
|
||||
* Setting the Ethernet device MAC address.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param addr
|
||||
* The new MAC addr.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_set_mac_addr(uint8_t port_id, struct ether_addr *addr);
|
||||
|
||||
/**
|
||||
* Validate if the provided MAC address is valid unicast address
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param addr
|
||||
* A pointer to a buffer (6-byte, 48bit) for the target MAC address
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_validate_addr(uint8_t port_id, struct ether_addr *addr);
|
||||
|
||||
/**
|
||||
* Setting the Ethernet device maximum Tx unit.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param mtu
|
||||
* New MTU
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_change_mtu(uint8_t port_id, int mtu);
|
||||
|
||||
/**
|
||||
* Retrieve the Ethernet device traffic statistics
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param stats
|
||||
* A pointer to struct rte_eth_stats for statistics parameters
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - (-EINVAL) if parameters invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_get_stats64(uint8_t port_id, struct rte_eth_stats *stats);
|
||||
|
||||
/**
|
||||
* Update the Ethernet device VLAN filter with new vid
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param vid
|
||||
* A new VLAN id
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_vlan_rx_add_vid(uint8_t port_id, uint16_t vid);
|
||||
|
||||
/**
|
||||
* Remove VLAN id from Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param vid
|
||||
* A new VLAN id
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_vlan_rx_kill_vid(uint8_t port_id, uint16_t vid);
|
||||
|
||||
/**
|
||||
* Setting the Ethernet device rx mode.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
*/
|
||||
int rte_ethtool_net_set_rx_mode(uint8_t port_id);
|
||||
|
||||
/**
|
||||
* Getting ring paramaters for Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param ring_param
|
||||
* Pointer to struct ethrool_ringparam to receive parameters.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
* @note
|
||||
* Only the tx_pending and rx_pending fields of struct ethtool_ringparam
|
||||
* are used, and the function only gets parameters for queue 0.
|
||||
*/
|
||||
int rte_ethtool_get_ringparam(uint8_t port_id,
|
||||
struct ethtool_ringparam *ring_param);
|
||||
|
||||
/**
|
||||
* Setting ring paramaters for Ethernet device.
|
||||
*
|
||||
* @param port_id
|
||||
* The port identifier of the Ethernet device.
|
||||
* @param ring_param
|
||||
* Pointer to struct ethrool_ringparam with parameters to set.
|
||||
* @return
|
||||
* - (0) if successful.
|
||||
* - (-ENOTSUP) if hardware doesn't support.
|
||||
* - (-ENODEV) if *port_id* invalid.
|
||||
* - others depends on the specific operations implementation.
|
||||
* @note
|
||||
* Only the tx_pending and rx_pending fields of struct ethtool_ringparam
|
||||
* are used, and the function only sets parameters for queue 0.
|
||||
*/
|
||||
int rte_ethtool_set_ringparam(uint8_t port_id,
|
||||
struct ethtool_ringparam *ring_param);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RTE_ETHTOOL_H_ */
|
Loading…
Reference in a new issue