X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_ethdev%2Frte_ethdev.c;h=c73d263c2f9150a7ec8a099757d66e09e20a05cb;hb=6b1f8e4f9b9337c81987336ae5204c7730b19d29;hp=e19dbd838b44027bbb17d392e14ab99ee33a3273;hpb=1fe3eef5e9bd7d116374a7f4db7ef71663e95707;p=dpdk.git diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c index e19dbd838b..c73d263c2f 100644 --- a/lib/librte_ethdev/rte_ethdev.c +++ b/lib/librte_ethdev/rte_ethdev.c @@ -2,18 +2,14 @@ * Copyright(c) 2010-2017 Intel Corporation */ -#include -#include #include -#include -#include -#include -#include #include +#include #include #include -#include -#include +#include +#include +#include #include #include @@ -41,7 +37,7 @@ #include "rte_ethdev_trace.h" #include "rte_ethdev.h" -#include "rte_ethdev_driver.h" +#include "ethdev_driver.h" #include "ethdev_profile.h" #include "ethdev_private.h" @@ -193,13 +189,14 @@ int rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) { int ret; - struct rte_devargs devargs = {.args = NULL}; + struct rte_devargs devargs; const char *bus_param_key; char *bus_str = NULL; char *cls_str = NULL; int str_size; memset(iter, 0, sizeof(*iter)); + memset(&devargs, 0, sizeof(devargs)); /* * The devargs string may use various syntaxes: @@ -244,8 +241,6 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) goto error; } iter->cls_str = cls_str; - free(devargs.args); /* allocated by rte_devargs_parse() */ - devargs.args = NULL; iter->bus = devargs.bus; if (iter->bus->dev_iterate == NULL) { @@ -278,13 +273,14 @@ rte_eth_iterator_init(struct rte_dev_iterator *iter, const char *devargs_str) end: iter->cls = rte_class_find_by_name("eth"); + rte_devargs_reset(&devargs); return 0; error: if (ret == -ENOTSUP) RTE_ETHDEV_LOG(ERR, "Bus %s does not support iterating.\n", iter->bus->name); - free(devargs.args); + rte_devargs_reset(&devargs); free(bus_str); free(cls_str); return ret; @@ -1292,8 +1288,10 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, struct rte_eth_dev *dev; struct rte_eth_dev_info dev_info; struct rte_eth_conf orig_conf; + uint16_t overhead_len; int diag; int ret; + uint16_t old_mtu; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); @@ -1319,10 +1317,20 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, memcpy(&dev->data->dev_conf, dev_conf, sizeof(dev->data->dev_conf)); + /* Backup mtu for rollback */ + old_mtu = dev->data->mtu; + ret = rte_eth_dev_info_get(port_id, &dev_info); if (ret != 0) goto rollback; + /* Get the real Ethernet overhead length */ + if (dev_info.max_mtu != UINT16_MAX && + dev_info.max_rx_pktlen > dev_info.max_mtu) + overhead_len = dev_info.max_rx_pktlen - dev_info.max_mtu; + else + overhead_len = RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; + /* If number of queues specified by application for both Rx and Tx is * zero, use driver preferred values. This cannot be done individually * as it is valid for either Tx or Rx (but not both) to be zero. @@ -1409,12 +1417,17 @@ rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, ret = -EINVAL; goto rollback; } + + /* Scale the MTU size to adapt max_rx_pkt_len */ + dev->data->mtu = dev->data->dev_conf.rxmode.max_rx_pkt_len - + overhead_len; } else { - if (dev_conf->rxmode.max_rx_pkt_len < RTE_ETHER_MIN_LEN || - dev_conf->rxmode.max_rx_pkt_len > RTE_ETHER_MAX_LEN) + uint16_t pktlen = dev_conf->rxmode.max_rx_pkt_len; + if (pktlen < RTE_ETHER_MIN_MTU + overhead_len || + pktlen > RTE_ETHER_MTU + overhead_len) /* Use default value */ dev->data->dev_conf.rxmode.max_rx_pkt_len = - RTE_ETHER_MAX_LEN; + RTE_ETHER_MTU + overhead_len; } /* @@ -1549,6 +1562,8 @@ reset_queues: eth_dev_tx_queue_config(dev, 0); rollback: memcpy(&dev->data->dev_conf, &orig_conf, sizeof(dev->data->dev_conf)); + if (old_mtu != dev->data->mtu) + dev->data->mtu = old_mtu; rte_ethdev_trace_configure(port_id, nb_rx_q, nb_tx_q, dev_conf, ret); return ret; @@ -1801,7 +1816,7 @@ rte_eth_dev_close(uint16_t port_id) rte_ethdev_trace_close(port_id); *lasterr = rte_eth_dev_release_port(dev); - return eth_err(port_id, firsterr); + return firsterr; } int @@ -5267,6 +5282,8 @@ rte_eth_dev_get_reg_info(uint16_t port_id, struct rte_dev_reg_info *info) struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + if (info == NULL) + return -EINVAL; dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_reg, -ENOTSUP); @@ -5291,6 +5308,8 @@ rte_eth_dev_get_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + if (info == NULL) + return -EINVAL; dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_eeprom, -ENOTSUP); @@ -5303,6 +5322,8 @@ rte_eth_dev_set_eeprom(uint16_t port_id, struct rte_dev_eeprom_info *info) struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + if (info == NULL) + return -EINVAL; dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_eeprom, -ENOTSUP); @@ -5316,6 +5337,8 @@ rte_eth_dev_get_module_info(uint16_t port_id, struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + if (modinfo == NULL) + return -EINVAL; dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_info, -ENOTSUP); @@ -5329,6 +5352,8 @@ rte_eth_dev_get_module_eeprom(uint16_t port_id, struct rte_eth_dev *dev; RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + if (info == NULL || info->data == NULL || info->length == 0) + return -EINVAL; dev = &rte_eth_devices[port_id]; RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_module_eeprom, -ENOTSUP); @@ -5570,9 +5595,14 @@ rte_eth_devargs_parse(const char *dargs, struct rte_eth_devargs *eth_da) for (i = 0; i < args.count; i++) { pair = &args.pairs[i]; if (strcmp("representor", pair->key) == 0) { - result = rte_eth_devargs_parse_list(pair->value, - rte_eth_devargs_parse_representor_ports, - eth_da); + if (eth_da->type != RTE_ETH_REPRESENTOR_NONE) { + RTE_LOG(ERR, EAL, "duplicated representor key: %s\n", + dargs); + result = -1; + goto parse_cleanup; + } + result = rte_eth_devargs_parse_representor_ports( + pair->value, eth_da); if (result < 0) goto parse_cleanup; } @@ -5585,6 +5615,99 @@ parse_cleanup: return result; } +int +rte_eth_representor_id_get(const struct rte_eth_dev *ethdev, + enum rte_eth_representor_type type, + int controller, int pf, int representor_port, + uint16_t *repr_id) +{ + int ret, n, i, count; + struct rte_eth_representor_info *info = NULL; + size_t size; + + if (type == RTE_ETH_REPRESENTOR_NONE) + return 0; + if (repr_id == NULL) + return -EINVAL; + + /* Get PMD representor range info. */ + ret = rte_eth_representor_info_get(ethdev->data->port_id, NULL); + if (ret == -ENOTSUP && type == RTE_ETH_REPRESENTOR_VF && + controller == -1 && pf == -1) { + /* Direct mapping for legacy VF representor. */ + *repr_id = representor_port; + return 0; + } else if (ret < 0) { + return ret; + } + n = ret; + size = sizeof(*info) + n * sizeof(info->ranges[0]); + info = calloc(1, size); + if (info == NULL) + return -ENOMEM; + ret = rte_eth_representor_info_get(ethdev->data->port_id, info); + if (ret < 0) + goto out; + + /* Default controller and pf to caller. */ + if (controller == -1) + controller = info->controller; + if (pf == -1) + pf = info->pf; + + /* Locate representor ID. */ + ret = -ENOENT; + for (i = 0; i < n; ++i) { + if (info->ranges[i].type != type) + continue; + if (info->ranges[i].controller != controller) + continue; + if (info->ranges[i].id_end < info->ranges[i].id_base) { + RTE_LOG(WARNING, EAL, "Port %hu invalid representor ID Range %u - %u, entry %d\n", + ethdev->data->port_id, info->ranges[i].id_base, + info->ranges[i].id_end, i); + continue; + + } + count = info->ranges[i].id_end - info->ranges[i].id_base + 1; + switch (info->ranges[i].type) { + case RTE_ETH_REPRESENTOR_PF: + if (pf < info->ranges[i].pf || + pf >= info->ranges[i].pf + count) + continue; + *repr_id = info->ranges[i].id_base + + (pf - info->ranges[i].pf); + ret = 0; + goto out; + case RTE_ETH_REPRESENTOR_VF: + if (info->ranges[i].pf != pf) + continue; + if (representor_port < info->ranges[i].vf || + representor_port >= info->ranges[i].vf + count) + continue; + *repr_id = info->ranges[i].id_base + + (representor_port - info->ranges[i].vf); + ret = 0; + goto out; + case RTE_ETH_REPRESENTOR_SF: + if (info->ranges[i].pf != pf) + continue; + if (representor_port < info->ranges[i].sf || + representor_port >= info->ranges[i].sf + count) + continue; + *repr_id = info->ranges[i].id_base + + (representor_port - info->ranges[i].sf); + ret = 0; + goto out; + default: + break; + } + } +out: + free(info); + return ret; +} + static int eth_dev_handle_port_list(const char *cmd __rte_unused, const char *params __rte_unused, @@ -5720,7 +5843,7 @@ eth_dev_handle_port_link_status(const char *cmd __rte_unused, if (!rte_eth_dev_is_valid_port(port_id)) return -1; - ret = rte_eth_link_get(port_id, &link); + ret = rte_eth_link_get_nowait(port_id, &link); if (ret < 0) return -1; @@ -5792,6 +5915,20 @@ rte_eth_hairpin_queue_peer_unbind(uint16_t cur_port, uint16_t cur_queue, direction); } +int +rte_eth_representor_info_get(uint16_t port_id, + struct rte_eth_representor_info *info) +{ + struct rte_eth_dev *dev; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->representor_info_get, -ENOTSUP); + return eth_err(port_id, (*dev->dev_ops->representor_info_get)(dev, + info)); +} + RTE_LOG_REGISTER(rte_eth_dev_logtype, lib.ethdev, INFO); RTE_INIT(ethdev_init_telemetry)