Process ethtool messages and rend response back to kernel. Signed-off-by: Ferruh Yigit <ferruh.yi...@intel.com> --- lib/librte_ctrl_if/rte_ctrl_process.c | 223 ++++++++++++++++++++++++++++++++++ lib/librte_ctrl_if/rte_ctrl_process.h | 4 + lib/librte_ctrl_if/rte_nl.c | 4 + 3 files changed, 231 insertions(+)
diff --git a/lib/librte_ctrl_if/rte_ctrl_process.c b/lib/librte_ctrl_if/rte_ctrl_process.c index cfb243f64..55fd54351 100644 --- a/lib/librte_ctrl_if/rte_ctrl_process.c +++ b/lib/librte_ctrl_if/rte_ctrl_process.c @@ -38,8 +38,231 @@ #include <rte_version.h> #include <rte_ethdev.h> +#include <rte_ethtool.h> #include "rte_ctrl_process.h" +#define ETHTOOL_GEEPROM_LEN 99 +#define ETHTOOL_GREGS_LEN 98 +#define ETHTOOL_GSSET_COUNT 97 + +static int +get_settings(uint8_t port_id __rte_unused, void *data, size_t *data_len) +{ + struct ethtool_cmd *ecmd = data; + + /* No PMD equivalent, added to make get pauseparam work */ + memset(ecmd, 0, sizeof(struct ethtool_cmd)); + + *data_len = sizeof(struct ethtool_cmd); + return 0; +} + +static int +get_drvinfo(uint8_t port_id, void *data, size_t *data_len) +{ + struct ethtool_drvinfo *info = data; + int ret; + + ret = rte_ethtool_get_drvinfo(port_id, info); + if (ret < 0) + return ret; + + *data_len = sizeof(struct ethtool_drvinfo); + + return 0; +} + +static int +get_reg_len(uint8_t port_id, void *data, size_t *data_len) +{ + int reg_length = 0; + + reg_length = rte_ethtool_get_regs_len(port_id); + if (reg_length < 0) + return reg_length; + + *(int *)data = reg_length; + *data_len = sizeof(int); + + return 0; +} + +static int +get_reg_len_internal(uint8_t port_id, size_t *reg_length) +{ + size_t reg_length_out_len; + + return get_reg_len(port_id, reg_length, ®_length_out_len); +} + +static int +get_reg(uint8_t port_id, void *in_data, void *out_data, size_t *out_data_len) +{ + size_t reg_length; + struct ethtool_regs *ethtool_regs = in_data; + int ret; + + ret = get_reg_len_internal(port_id, ®_length); + /* not enough space in out data buffer */ + if (ret < 0 || reg_length > ethtool_regs->len) + return -1; + + ret = rte_ethtool_get_regs(port_id, ethtool_regs, out_data); + if (ret < 0) + return ret; + + *out_data_len = reg_length; + + return 0; +} + +static int +get_link(uint8_t port_id, void *data, size_t *data_len) +{ + int ret; + + ret = rte_ethtool_get_link(port_id); + + *(int *)data = ret; + *data_len = sizeof(size_t); + + return 0; +} + +static int +get_eeprom_length(uint8_t port_id, void *data, size_t *data_len) +{ + int eeprom_length = 0; + + eeprom_length = rte_ethtool_get_eeprom_len(port_id); + if (eeprom_length < 0) + return eeprom_length; + + *(int *)data = eeprom_length; + *data_len = sizeof(int); + + return 0; +} + +static int +get_eeprom(uint8_t port_id, void *in_data, void *out_data, + size_t *out_data_len) +{ + struct ethtool_eeprom *eeprom = in_data; + int ret; + + ret = rte_ethtool_get_eeprom(port_id, eeprom, out_data); + if (ret < 0) + return ret; + + *out_data_len = eeprom->len; + + return 0; +} + +static int +set_eeprom(uint8_t port_id, void *in_data) +{ + struct ethtool_eeprom *eeprom = in_data; + int ret; + + ret = rte_ethtool_set_eeprom(port_id, eeprom, eeprom->data); + if (ret != 0) + return -1; + + return 0; +} + +static int +get_ringparam(uint8_t port_id, void *data, size_t *data_len) +{ + struct ethtool_ringparam *ringparam = data; + int ret; + + ret = rte_ethtool_get_ringparam(port_id, ringparam); + if (ret < 0) + return ret; + + *data_len = sizeof(struct ethtool_ringparam); + + return 0; +} + +static int +set_ringparam(uint8_t port_id, void *data) +{ + struct ethtool_ringparam *ringparam = data; + int ret; + + ret = rte_ethtool_set_ringparam(port_id, ringparam); + if (ret != 0) + return -1; + + return 0; +} + +static int +get_pauseparam(uint8_t port_id, void *data, size_t *data_len) +{ + struct ethtool_pauseparam *pauseparam = data; + int ret; + + ret = rte_ethtool_get_pauseparam(port_id, pauseparam); + if (ret < 0) + return ret; + + *data_len = sizeof(struct ethtool_pauseparam); + + return 0; +} + +static int +set_pauseparam(uint8_t port_id, void *data) +{ + struct ethtool_pauseparam *pauseparam = data; + + return rte_ethtool_set_pauseparam(port_id, pauseparam); +} + +int +rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data, + void *out_data, size_t *out_data_len) +{ + if (!rte_eth_dev_is_valid_port(port_id)) + return -ENODEV; + + switch (cmd_id) { + case ETHTOOL_GSET: + return get_settings(port_id, out_data, out_data_len); + case ETHTOOL_GDRVINFO: + return get_drvinfo(port_id, out_data, out_data_len); + case ETHTOOL_GREGS_LEN: + return get_reg_len(port_id, out_data, out_data_len); + case ETHTOOL_GREGS: + return get_reg(port_id, in_data, out_data, out_data_len); + case ETHTOOL_GLINK: + return get_link(port_id, out_data, out_data_len); + case ETHTOOL_GEEPROM_LEN: + return get_eeprom_length(port_id, out_data, out_data_len); + case ETHTOOL_GEEPROM: + return get_eeprom(port_id, in_data, out_data, out_data_len); + case ETHTOOL_SEEPROM: + return set_eeprom(port_id, in_data); + case ETHTOOL_GRINGPARAM: + return get_ringparam(port_id, out_data, out_data_len); + case ETHTOOL_SRINGPARAM: + return set_ringparam(port_id, in_data); + case ETHTOOL_GPAUSEPARAM: + return get_pauseparam(port_id, out_data, out_data_len); + case ETHTOOL_SPAUSEPARAM: + return set_pauseparam(port_id, in_data); + default: + return -EOPNOTSUPP; + } + + return 0; +} + static int set_mtu(uint8_t port_id, void *in_data) { diff --git a/lib/librte_ctrl_if/rte_ctrl_process.h b/lib/librte_ctrl_if/rte_ctrl_process.h index 3dd690a8e..a61735f0d 100644 --- a/lib/librte_ctrl_if/rte_ctrl_process.h +++ b/lib/librte_ctrl_if/rte_ctrl_process.h @@ -38,8 +38,12 @@ extern "C" { #endif +#include <linux/ethtool.h> + #include <exec-env/unci.h> +int rte_eth_dev_ethtool_process(uint32_t cmd_id, uint8_t port_id, void *in_data, + void *out_data, size_t *out_data_len); int rte_eth_dev_control_process(uint32_t cmd_id, uint8_t port_id, void *in_data, void *out_data, size_t *out_data_len); diff --git a/lib/librte_ctrl_if/rte_nl.c b/lib/librte_ctrl_if/rte_nl.c index 1648dc706..43abcbd35 100644 --- a/lib/librte_ctrl_if/rte_nl.c +++ b/lib/librte_ctrl_if/rte_nl.c @@ -142,6 +142,10 @@ process_msg(struct unci_nl_msg *msg) msg->err = rte_eth_dev_control_process(msg->cmd_id, msg->port_id, msg->input_buffer, msg->output_buffer, &msg->output_buffer_len); + } else { + msg->err = rte_eth_dev_ethtool_process(msg->cmd_id, + msg->port_id, msg->input_buffer, + msg->output_buffer, &msg->output_buffer_len); } if (msg->err) -- 2.13.0