uint16_t
rte_eth_dev_count(void)
+{
+ return rte_eth_dev_count_avail();
+}
+
+uint16_t
+rte_eth_dev_count_avail(void)
{
uint16_t p;
uint16_t count;
return count;
}
+uint16_t
+rte_eth_dev_count_total(void)
+{
+ uint16_t port, count = 0;
+
+ for (port = 0; port < RTE_MAX_ETHPORTS; port++)
+ if (rte_eth_devices[port].state != RTE_ETH_DEV_UNUSED)
+ count++;
+
+ return count;
+}
+
int
rte_eth_dev_get_name_by_port(uint16_t port_id, char *name)
{
int
rte_eth_dev_attach(const char *devargs, uint16_t *port_id)
{
+ int current = rte_eth_dev_count_total();
+ struct rte_devargs da;
int ret = -1;
- int current = rte_eth_dev_count();
- char *name = NULL;
- char *args = NULL;
+
+ memset(&da, 0, sizeof(da));
if ((devargs == NULL) || (port_id == NULL)) {
ret = -EINVAL;
goto err;
}
- /* parse devargs, then retrieve device name and args */
- if (rte_eal_parse_devargs_str(devargs, &name, &args))
+ /* parse devargs */
+ if (rte_devargs_parse(&da, "%s", devargs))
goto err;
- ret = rte_eal_dev_attach(name, args);
+ ret = rte_eal_hotplug_add(da.bus->name, da.name, da.args);
if (ret < 0)
goto err;
/* no point looking at the port count if no port exists */
- if (!rte_eth_dev_count()) {
- ethdev_log(ERR, "No port found for device (%s)", name);
+ if (!rte_eth_dev_count_total()) {
+ ethdev_log(ERR, "No port found for device (%s)", da.name);
ret = -1;
goto err;
}
/* if nothing happened, there is a bug here, since some driver told us
* it did attach a device, but did not create a port.
+ * FIXME: race condition in case of plug-out of another device
*/
- if (current == rte_eth_dev_count()) {
+ if (current == rte_eth_dev_count_total()) {
ret = -1;
goto err;
}
ret = 0;
err:
- free(name);
- free(args);
+ free(da.args);
return ret;
}
/* detach the device, then store the name of the device */
int
-rte_eth_dev_detach(uint16_t port_id, char *name)
+rte_eth_dev_detach(uint16_t port_id, char *name __rte_unused)
{
+ struct rte_device *dev;
+ struct rte_bus *bus;
uint32_t dev_flags;
int ret = -1;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
- if (name == NULL) {
- ret = -EINVAL;
- goto err;
- }
-
dev_flags = rte_eth_devices[port_id].data->dev_flags;
if (dev_flags & RTE_ETH_DEV_BONDED_SLAVE) {
ethdev_log(ERR,
"Port %" PRIu16 " is bonded, cannot detach", port_id);
- ret = -ENOTSUP;
- goto err;
+ return -ENOTSUP;
}
- snprintf(name, sizeof(rte_eth_devices[port_id].data->name),
- "%s", rte_eth_devices[port_id].data->name);
+ dev = rte_eth_devices[port_id].device;
+ if (dev == NULL)
+ return -EINVAL;
- ret = rte_eal_dev_detach(rte_eth_devices[port_id].device);
+ bus = rte_bus_find_by_device(dev);
+ if (bus == NULL)
+ return -ENOENT;
+
+ ret = rte_eal_hotplug_remove(bus->name, dev->name);
if (ret < 0)
- goto err;
+ return ret;
rte_eth_dev_release_port(&rte_eth_devices[port_id]);
return 0;
-
-err:
- return ret;
}
static int
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+ dev = &rte_eth_devices[port_id];
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
+ (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
+
+ /* 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.
+ * If driver does not provide any preferred valued, fall back on
+ * EAL defaults.
+ */
+ if (nb_rx_q == 0 && nb_tx_q == 0) {
+ nb_rx_q = dev_info.default_rxportconf.nb_queues;
+ if (nb_rx_q == 0)
+ nb_rx_q = RTE_ETH_DEV_FALLBACK_RX_NBQUEUES;
+ nb_tx_q = dev_info.default_txportconf.nb_queues;
+ if (nb_tx_q == 0)
+ nb_tx_q = RTE_ETH_DEV_FALLBACK_TX_NBQUEUES;
+ }
+
if (nb_rx_q > RTE_MAX_QUEUES_PER_PORT) {
RTE_PMD_DEBUG_TRACE(
"Number of RX queues requested (%u) is greater than max supported(%d)\n",
return -EINVAL;
}
- dev = &rte_eth_devices[port_id];
-
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_configure, -ENOTSUP);
* than the maximum number of RX and TX queues supported by the
* configured device.
*/
- (*dev->dev_ops->dev_infos_get)(dev, &dev_info);
-
- if (nb_rx_q == 0 && nb_tx_q == 0) {
- RTE_PMD_DEBUG_TRACE("ethdev port_id=%d both rx and tx queue cannot be 0\n", port_id);
- return -EINVAL;
- }
-
if (nb_rx_q > dev_info.max_rx_queues) {
RTE_PMD_DEBUG_TRACE("ethdev port_id=%d nb_rx_queues=%d > %d\n",
port_id, nb_rx_q, dev_info.max_rx_queues);
return -EINVAL;
}
+ /* Use default specified by driver, if nb_rx_desc is zero */
+ if (nb_rx_desc == 0) {
+ nb_rx_desc = dev_info.default_rxportconf.ring_size;
+ /* If driver default is also zero, fall back on EAL default */
+ if (nb_rx_desc == 0)
+ nb_rx_desc = RTE_ETH_DEV_FALLBACK_RX_RINGSIZE;
+ }
+
if (nb_rx_desc > dev_info.rx_desc_lim.nb_max ||
nb_rx_desc < dev_info.rx_desc_lim.nb_min ||
nb_rx_desc % dev_info.rx_desc_lim.nb_align != 0) {
rte_eth_dev_info_get(port_id, &dev_info);
+ /* Use default specified by driver, if nb_tx_desc is zero */
+ if (nb_tx_desc == 0) {
+ nb_tx_desc = dev_info.default_txportconf.ring_size;
+ /* If driver default is zero, fall back on EAL default */
+ if (nb_tx_desc == 0)
+ nb_tx_desc = RTE_ETH_DEV_FALLBACK_TX_RINGSIZE;
+ }
if (nb_tx_desc > dev_info.tx_desc_lim.nb_max ||
nb_tx_desc < dev_info.tx_desc_lim.nb_min ||
nb_tx_desc % dev_info.tx_desc_lim.nb_align != 0) {
RTE_ETH_VALID_PORTID_OR_RET(port_id);
dev = &rte_eth_devices[port_id];
- if (dev->data->dev_conf.intr_conf.lsc)
+ if (dev->data->dev_conf.intr_conf.lsc &&
+ dev->data->dev_started)
rte_eth_linkstatus_get(dev, eth_link);
else {
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
RTE_ETH_VALID_PORTID_OR_RET(port_id);
dev = &rte_eth_devices[port_id];
- if (dev->data->dev_conf.intr_conf.lsc)
+ if (dev->data->dev_conf.intr_conf.lsc &&
+ dev->data->dev_started)
rte_eth_linkstatus_get(dev, eth_link);
else {
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->link_update);
rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct ether_addr *addr)
{
struct rte_eth_dev *dev;
+ int ret;
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->mac_addr_set, -ENOTSUP);
+ ret = (*dev->dev_ops->mac_addr_set)(dev, addr);
+ if (ret < 0)
+ return ret;
+
/* Update default address in NIC data structure */
ether_addr_copy(addr, &dev->data->mac_addrs[0]);
- (*dev->dev_ops->mac_addr_set)(dev, addr);
-
return 0;
}