aboutsummaryrefslogtreecommitdiffstats
path: root/lib/librte_ether/rte_ethdev.c
diff options
context:
space:
mode:
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>2017-05-16 14:51:32 +0200
committerChristian Ehrhardt <christian.ehrhardt@canonical.com>2017-05-16 16:20:45 +0200
commit7595afa4d30097c1177b69257118d8ad89a539be (patch)
tree4bfeadc905c977e45e54a90c42330553b8942e4e /lib/librte_ether/rte_ethdev.c
parentce3d555e43e3795b5d9507fcfc76b7a0a92fd0d6 (diff)
Imported Upstream version 17.05
Change-Id: Id1e419c5a214e4a18739663b91f0f9a549f1fdc6 Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Diffstat (limited to 'lib/librte_ether/rte_ethdev.c')
-rw-r--r--lib/librte_ether/rte_ethdev.c769
1 files changed, 451 insertions, 318 deletions
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 5a317594..83898a8f 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -138,10 +138,18 @@ enum {
STAT_QMAP_RX
};
-enum {
- DEV_DETACHED = 0,
- DEV_ATTACHED
-};
+uint8_t
+rte_eth_find_next(uint8_t port_id)
+{
+ while (port_id < RTE_MAX_ETHPORTS &&
+ rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED)
+ port_id++;
+
+ if (port_id >= RTE_MAX_ETHPORTS)
+ return RTE_MAX_ETHPORTS;
+
+ return port_id;
+}
static void
rte_eth_dev_data_alloc(void)
@@ -170,7 +178,7 @@ rte_eth_dev_allocated(const char *name)
unsigned i;
for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
- if ((rte_eth_devices[i].attached == DEV_ATTACHED) &&
+ if ((rte_eth_devices[i].state == RTE_ETH_DEV_ATTACHED) &&
strcmp(rte_eth_devices[i].data->name, name) == 0)
return &rte_eth_devices[i];
}
@@ -183,7 +191,7 @@ rte_eth_dev_find_free_port(void)
unsigned i;
for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
- if (rte_eth_devices[i].attached == DEV_DETACHED)
+ if (rte_eth_devices[i].state == RTE_ETH_DEV_UNUSED)
return i;
}
return RTE_MAX_ETHPORTS;
@@ -195,7 +203,8 @@ eth_dev_get(uint8_t port_id)
struct rte_eth_dev *eth_dev = &rte_eth_devices[port_id];
eth_dev->data = &rte_eth_dev_data[port_id];
- eth_dev->attached = DEV_ATTACHED;
+ eth_dev->state = RTE_ETH_DEV_ATTACHED;
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
eth_dev_last_created_port = port_id;
nb_ports++;
@@ -224,9 +233,11 @@ rte_eth_dev_allocate(const char *name)
return NULL;
}
+ memset(&rte_eth_dev_data[port_id], 0, sizeof(struct rte_eth_dev_data));
eth_dev = eth_dev_get(port_id);
snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
eth_dev->data->port_id = port_id;
+ eth_dev->data->mtu = ETHER_MTU;
return eth_dev;
}
@@ -236,8 +247,8 @@ rte_eth_dev_allocate(const char *name)
* makes sure that the same device would have the same port id both
* in the primary and secondary process.
*/
-static struct rte_eth_dev *
-eth_dev_attach_secondary(const char *name)
+struct rte_eth_dev *
+rte_eth_dev_attach_secondary(const char *name)
{
uint8_t i;
struct rte_eth_dev *eth_dev;
@@ -268,121 +279,16 @@ rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
if (eth_dev == NULL)
return -EINVAL;
- eth_dev->attached = DEV_DETACHED;
+ eth_dev->state = RTE_ETH_DEV_UNUSED;
nb_ports--;
return 0;
}
int
-rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev)
-{
- struct eth_driver *eth_drv;
- struct rte_eth_dev *eth_dev;
- char ethdev_name[RTE_ETH_NAME_MAX_LEN];
-
- int diag;
-
- eth_drv = (struct eth_driver *)pci_drv;
-
- rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
- sizeof(ethdev_name));
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- eth_dev = rte_eth_dev_allocate(ethdev_name);
- if (eth_dev == NULL)
- return -ENOMEM;
-
- eth_dev->data->dev_private = rte_zmalloc("ethdev private structure",
- eth_drv->dev_private_size,
- RTE_CACHE_LINE_SIZE);
- if (eth_dev->data->dev_private == NULL)
- rte_panic("Cannot allocate memzone for private port data\n");
- } else {
- eth_dev = eth_dev_attach_secondary(ethdev_name);
- if (eth_dev == NULL) {
- /*
- * if we failed to attach a device, it means the
- * device is skipped in primary process, due to
- * some errors. If so, we return a positive value,
- * to let EAL skip it for the secondary process
- * as well.
- */
- return 1;
- }
- }
- eth_dev->pci_dev = pci_dev;
- eth_dev->driver = eth_drv;
- eth_dev->data->rx_mbuf_alloc_failed = 0;
-
- /* init user callbacks */
- TAILQ_INIT(&(eth_dev->link_intr_cbs));
-
- /*
- * Set the default MTU.
- */
- eth_dev->data->mtu = ETHER_MTU;
-
- /* Invoke PMD device initialization function */
- diag = (*eth_drv->eth_dev_init)(eth_dev);
- if (diag == 0)
- return 0;
-
- RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(vendor_id=0x%x device_id=0x%x) failed\n",
- pci_drv->driver.name,
- (unsigned) pci_dev->id.vendor_id,
- (unsigned) pci_dev->id.device_id);
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
- rte_free(eth_dev->data->dev_private);
- rte_eth_dev_release_port(eth_dev);
- return diag;
-}
-
-int
-rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
-{
- const struct eth_driver *eth_drv;
- struct rte_eth_dev *eth_dev;
- char ethdev_name[RTE_ETH_NAME_MAX_LEN];
- int ret;
-
- if (pci_dev == NULL)
- return -EINVAL;
-
- rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
- sizeof(ethdev_name));
-
- eth_dev = rte_eth_dev_allocated(ethdev_name);
- if (eth_dev == NULL)
- return -ENODEV;
-
- eth_drv = (const struct eth_driver *)pci_dev->driver;
-
- /* Invoke PMD device uninit function */
- if (*eth_drv->eth_dev_uninit) {
- ret = (*eth_drv->eth_dev_uninit)(eth_dev);
- if (ret)
- return ret;
- }
-
- /* free ether device */
- rte_eth_dev_release_port(eth_dev);
-
- if (rte_eal_process_type() == RTE_PROC_PRIMARY)
- rte_free(eth_dev->data->dev_private);
-
- eth_dev->pci_dev = NULL;
- eth_dev->driver = NULL;
- eth_dev->data = NULL;
-
- return 0;
-}
-
-int
rte_eth_dev_is_valid_port(uint8_t port_id)
{
if (port_id >= RTE_MAX_ETHPORTS ||
- rte_eth_devices[port_id].attached != DEV_ATTACHED)
+ rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED)
return 0;
else
return 1;
@@ -434,9 +340,7 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)
return -ENODEV;
*port_id = RTE_MAX_ETHPORTS;
-
- for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-
+ RTE_ETH_FOREACH_DEV(i) {
if (!strncmp(name,
rte_eth_dev_data[i].name, strlen(name))) {
@@ -460,8 +364,8 @@ rte_eth_dev_is_detachable(uint8_t port_id)
case RTE_KDRV_UIO_GENERIC:
case RTE_KDRV_NIC_UIO:
case RTE_KDRV_NONE:
- break;
case RTE_KDRV_VFIO:
+ break;
default:
return -ENOTSUP;
}
@@ -588,6 +492,9 @@ rte_eth_dev_rx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
for (i = nb_queues; i < old_nb_queues; i++)
(*dev->dev_ops->rx_queue_release)(rxq[i]);
+
+ rte_free(dev->data->rx_queues);
+ dev->data->rx_queues = NULL;
}
dev->data->nb_rx_queues = nb_queues;
return 0;
@@ -739,6 +646,9 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
for (i = nb_queues; i < old_nb_queues; i++)
(*dev->dev_ops->tx_queue_release)(txq[i]);
+
+ rte_free(dev->data->tx_queues);
+ dev->data->tx_queues = NULL;
}
dev->data->nb_tx_queues = nb_queues;
return 0;
@@ -839,16 +749,19 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
return -EINVAL;
}
- /*
- * If link state interrupt is enabled, check that the
- * device supports it.
- */
+ /* Check that the device supports requested interrupts */
if ((dev_conf->intr_conf.lsc == 1) &&
(!(dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC))) {
RTE_PMD_DEBUG_TRACE("driver %s does not support lsc\n",
dev->data->drv_name);
return -EINVAL;
}
+ if ((dev_conf->intr_conf.rmv == 1) &&
+ (!(dev->data->dev_flags & RTE_ETH_DEV_INTR_RMV))) {
+ RTE_PMD_DEBUG_TRACE("driver %s does not support rmv\n",
+ dev->data->drv_name);
+ return -EINVAL;
+ }
/*
* If jumbo frames are enabled, check that the maximum RX packet
@@ -909,39 +822,61 @@ rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
return 0;
}
+void
+_rte_eth_dev_reset(struct rte_eth_dev *dev)
+{
+ if (dev->data->dev_started) {
+ RTE_PMD_DEBUG_TRACE(
+ "port %d must be stopped to allow reset\n",
+ dev->data->port_id);
+ return;
+ }
+
+ rte_eth_dev_rx_queue_config(dev, 0);
+ rte_eth_dev_tx_queue_config(dev, 0);
+
+ memset(&dev->data->dev_conf, 0, sizeof(dev->data->dev_conf));
+}
+
static void
rte_eth_dev_config_restore(uint8_t port_id)
{
struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
- struct ether_addr addr;
+ struct ether_addr *addr;
uint16_t i;
uint32_t pool = 0;
+ uint64_t pool_mask;
dev = &rte_eth_devices[port_id];
rte_eth_dev_info_get(port_id, &dev_info);
- if (RTE_ETH_DEV_SRIOV(dev).active)
- pool = RTE_ETH_DEV_SRIOV(dev).def_vmdq_idx;
-
- /* replay MAC address configuration */
- for (i = 0; i < dev_info.max_mac_addrs; i++) {
- addr = dev->data->mac_addrs[i];
-
- /* skip zero address */
- if (is_zero_ether_addr(&addr))
- continue;
-
- /* add address to the hardware */
- if (*dev->dev_ops->mac_addr_add &&
- (dev->data->mac_pool_sel[i] & (1ULL << pool)))
- (*dev->dev_ops->mac_addr_add)(dev, &addr, i, pool);
- else {
- RTE_PMD_DEBUG_TRACE("port %d: MAC address array not supported\n",
- port_id);
- /* exit the loop but not return an error */
- break;
+ /* replay MAC address configuration including default MAC */
+ addr = &dev->data->mac_addrs[0];
+ if (*dev->dev_ops->mac_addr_set != NULL)
+ (*dev->dev_ops->mac_addr_set)(dev, addr);
+ else if (*dev->dev_ops->mac_addr_add != NULL)
+ (*dev->dev_ops->mac_addr_add)(dev, addr, 0, pool);
+
+ if (*dev->dev_ops->mac_addr_add != NULL) {
+ for (i = 1; i < dev_info.max_mac_addrs; i++) {
+ addr = &dev->data->mac_addrs[i];
+
+ /* skip zero address */
+ if (is_zero_ether_addr(addr))
+ continue;
+
+ pool = 0;
+ pool_mask = dev->data->mac_pool_sel[i];
+
+ do {
+ if (pool_mask & 1ULL)
+ (*dev->dev_ops->mac_addr_add)(dev,
+ addr, i, pool);
+ pool_mask >>= 1;
+ pool++;
+ } while (pool_mask);
}
}
@@ -1051,8 +986,10 @@ rte_eth_dev_close(uint8_t port_id)
dev->data->dev_started = 0;
(*dev->dev_ops->dev_close)(dev);
+ dev->data->nb_rx_queues = 0;
rte_free(dev->data->rx_queues);
dev->data->rx_queues = NULL;
+ dev->data->nb_tx_queues = 0;
rte_free(dev->data->tx_queues);
dev->data->tx_queues = NULL;
}
@@ -1067,6 +1004,7 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
uint32_t mbp_buf_size;
struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
+ void **rxq;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
@@ -1125,6 +1063,14 @@ rte_eth_rx_queue_setup(uint8_t port_id, uint16_t rx_queue_id,
return -EINVAL;
}
+ rxq = dev->data->rx_queues;
+ if (rxq[rx_queue_id]) {
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_release,
+ -ENOTSUP);
+ (*dev->dev_ops->rx_queue_release)(rxq[rx_queue_id]);
+ rxq[rx_queue_id] = NULL;
+ }
+
if (rx_conf == NULL)
rx_conf = &dev_info.default_rxconf;
@@ -1146,6 +1092,7 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
{
struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
+ void **txq;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
@@ -1178,6 +1125,14 @@ rte_eth_tx_queue_setup(uint8_t port_id, uint16_t tx_queue_id,
return -EINVAL;
}
+ txq = dev->data->tx_queues;
+ if (txq[tx_queue_id]) {
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_release,
+ -ENOTSUP);
+ (*dev->dev_ops->tx_queue_release)(txq[tx_queue_id]);
+ txq[tx_queue_id] = NULL;
+ }
+
if (tx_conf == NULL)
tx_conf = &dev_info.default_txconf;
@@ -1234,6 +1189,20 @@ rte_eth_tx_buffer_init(struct rte_eth_dev_tx_buffer *buffer, uint16_t size)
return ret;
}
+int
+rte_eth_tx_done_cleanup(uint8_t port_id, uint16_t queue_id, uint32_t free_cnt)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+
+ /* Validate Input Data. Bail if not valid or not supported. */
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_done_cleanup, -ENOTSUP);
+
+ /* Call driver to free pending mbufs. */
+ return (*dev->dev_ops->tx_done_cleanup)(dev->data->tx_queues[queue_id],
+ free_cnt);
+}
+
void
rte_eth_promiscuous_enable(uint8_t port_id)
{
@@ -1393,12 +1362,19 @@ get_xstats_count(uint8_t port_id)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
dev = &rte_eth_devices[port_id];
+ if (dev->dev_ops->xstats_get_names_by_id != NULL) {
+ count = (*dev->dev_ops->xstats_get_names_by_id)(dev, NULL,
+ NULL, 0);
+ if (count < 0)
+ return count;
+ }
if (dev->dev_ops->xstats_get_names != NULL) {
count = (*dev->dev_ops->xstats_get_names)(dev, NULL, 0);
if (count < 0)
return count;
} else
count = 0;
+
count += RTE_NB_STATS;
count += RTE_MIN(dev->data->nb_rx_queues, RTE_ETHDEV_QUEUE_STAT_CNTRS) *
RTE_NB_RXQ_STATS;
@@ -1408,9 +1384,170 @@ get_xstats_count(uint8_t port_id)
}
int
+rte_eth_xstats_get_id_by_name(uint8_t port_id, const char *xstat_name,
+ uint64_t *id)
+{
+ int cnt_xstats, idx_xstat;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+ if (!id) {
+ RTE_PMD_DEBUG_TRACE("Error: id pointer is NULL\n");
+ return -ENOMEM;
+ }
+
+ if (!xstat_name) {
+ RTE_PMD_DEBUG_TRACE("Error: xstat_name pointer is NULL\n");
+ return -ENOMEM;
+ }
+
+ /* Get count */
+ cnt_xstats = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
+ if (cnt_xstats < 0) {
+ RTE_PMD_DEBUG_TRACE("Error: Cannot get count of xstats\n");
+ return -ENODEV;
+ }
+
+ /* Get id-name lookup table */
+ struct rte_eth_xstat_name xstats_names[cnt_xstats];
+
+ if (cnt_xstats != rte_eth_xstats_get_names_by_id(
+ port_id, xstats_names, cnt_xstats, NULL)) {
+ RTE_PMD_DEBUG_TRACE("Error: Cannot get xstats lookup\n");
+ return -1;
+ }
+
+ for (idx_xstat = 0; idx_xstat < cnt_xstats; idx_xstat++) {
+ if (!strcmp(xstats_names[idx_xstat].name, xstat_name)) {
+ *id = idx_xstat;
+ return 0;
+ };
+ }
+
+ return -EINVAL;
+}
+
+int
+rte_eth_xstats_get_names_by_id(uint8_t port_id,
+ struct rte_eth_xstat_name *xstats_names, unsigned int size,
+ uint64_t *ids)
+{
+ /* Get all xstats */
+ if (!ids) {
+ struct rte_eth_dev *dev;
+ int cnt_used_entries;
+ int cnt_expected_entries;
+ int cnt_driver_entries;
+ uint32_t idx, id_queue;
+ uint16_t num_q;
+
+ cnt_expected_entries = get_xstats_count(port_id);
+ if (xstats_names == NULL || cnt_expected_entries < 0 ||
+ (int)size < cnt_expected_entries)
+ return cnt_expected_entries;
+
+ /* port_id checked in get_xstats_count() */
+ dev = &rte_eth_devices[port_id];
+ cnt_used_entries = 0;
+
+ for (idx = 0; idx < RTE_NB_STATS; idx++) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "%s", rte_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+ num_q = RTE_MIN(dev->data->nb_rx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
+ for (idx = 0; idx < RTE_NB_RXQ_STATS; idx++) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "rx_q%u%s",
+ id_queue,
+ rte_rxq_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+
+ }
+ num_q = RTE_MIN(dev->data->nb_tx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ for (id_queue = 0; id_queue < num_q; id_queue++) {
+ for (idx = 0; idx < RTE_NB_TXQ_STATS; idx++) {
+ snprintf(xstats_names[cnt_used_entries].name,
+ sizeof(xstats_names[0].name),
+ "tx_q%u%s",
+ id_queue,
+ rte_txq_stats_strings[idx].name);
+ cnt_used_entries++;
+ }
+ }
+
+ if (dev->dev_ops->xstats_get_names_by_id != NULL) {
+ /* If there are any driver-specific xstats, append them
+ * to end of list.
+ */
+ cnt_driver_entries =
+ (*dev->dev_ops->xstats_get_names_by_id)(
+ dev,
+ xstats_names + cnt_used_entries,
+ NULL,
+ size - cnt_used_entries);
+ if (cnt_driver_entries < 0)
+ return cnt_driver_entries;
+ cnt_used_entries += cnt_driver_entries;
+
+ } else if (dev->dev_ops->xstats_get_names != NULL) {
+ /* If there are any driver-specific xstats, append them
+ * to end of list.
+ */
+ cnt_driver_entries = (*dev->dev_ops->xstats_get_names)(
+ dev,
+ xstats_names + cnt_used_entries,
+ size - cnt_used_entries);
+ if (cnt_driver_entries < 0)
+ return cnt_driver_entries;
+ cnt_used_entries += cnt_driver_entries;
+ }
+
+ return cnt_used_entries;
+ }
+ /* Get only xstats given by IDS */
+ else {
+ uint16_t len, i;
+ struct rte_eth_xstat_name *xstats_names_copy;
+
+ len = rte_eth_xstats_get_names_by_id(port_id, NULL, 0, NULL);
+
+ xstats_names_copy =
+ malloc(sizeof(struct rte_eth_xstat_name) * len);
+ if (!xstats_names_copy) {
+ RTE_PMD_DEBUG_TRACE(
+ "ERROR: can't allocate memory for values_copy\n");
+ free(xstats_names_copy);
+ return -1;
+ }
+
+ rte_eth_xstats_get_names_by_id(port_id, xstats_names_copy,
+ len, NULL);
+
+ for (i = 0; i < size; i++) {
+ if (ids[i] >= len) {
+ RTE_PMD_DEBUG_TRACE(
+ "ERROR: id value isn't valid\n");
+ return -1;
+ }
+ strcpy(xstats_names[i].name,
+ xstats_names_copy[ids[i]].name);
+ }
+ free(xstats_names_copy);
+ return size;
+ }
+}
+
+int
rte_eth_xstats_get_names(uint8_t port_id,
struct rte_eth_xstat_name *xstats_names,
- unsigned size)
+ unsigned int size)
{
struct rte_eth_dev *dev;
int cnt_used_entries;
@@ -1474,13 +1611,139 @@ rte_eth_xstats_get_names(uint8_t port_id,
/* retrieve ethdev extended statistics */
int
+rte_eth_xstats_get_by_id(uint8_t port_id, const uint64_t *ids, uint64_t *values,
+ unsigned int n)
+{
+ /* If need all xstats */
+ if (!ids) {
+ struct rte_eth_stats eth_stats;
+ struct rte_eth_dev *dev;
+ unsigned int count = 0, i, q;
+ signed int xcount = 0;
+ uint64_t val, *stats_ptr;
+ uint16_t nb_rxqs, nb_txqs;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ nb_rxqs = RTE_MIN(dev->data->nb_rx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+ nb_txqs = RTE_MIN(dev->data->nb_tx_queues,
+ RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+ /* Return generic statistics */
+ count = RTE_NB_STATS + (nb_rxqs * RTE_NB_RXQ_STATS) +
+ (nb_txqs * RTE_NB_TXQ_STATS);
+
+
+ /* implemented by the driver */
+ if (dev->dev_ops->xstats_get_by_id != NULL) {
+ /* Retrieve the xstats from the driver at the end of the
+ * xstats struct. Retrieve all xstats.
+ */
+ xcount = (*dev->dev_ops->xstats_get_by_id)(dev,
+ NULL,
+ values ? values + count : NULL,
+ (n > count) ? n - count : 0);
+
+ if (xcount < 0)
+ return xcount;
+ /* implemented by the driver */
+ } else if (dev->dev_ops->xstats_get != NULL) {
+ /* Retrieve the xstats from the driver at the end of the
+ * xstats struct. Retrieve all xstats.
+ * Compatibility for PMD without xstats_get_by_ids
+ */
+ unsigned int size = (n > count) ? n - count : 1;
+ struct rte_eth_xstat xstats[size];
+
+ xcount = (*dev->dev_ops->xstats_get)(dev,
+ values ? xstats : NULL, size);
+
+ if (xcount < 0)
+ return xcount;
+
+ if (values != NULL)
+ for (i = 0 ; i < (unsigned int)xcount; i++)
+ values[i + count] = xstats[i].value;
+ }
+
+ if (n < count + xcount || values == NULL)
+ return count + xcount;
+
+ /* now fill the xstats structure */
+ count = 0;
+ rte_eth_stats_get(port_id, &eth_stats);
+
+ /* global stats */
+ for (i = 0; i < RTE_NB_STATS; i++) {
+ stats_ptr = RTE_PTR_ADD(&eth_stats,
+ rte_stats_strings[i].offset);
+ val = *stats_ptr;
+ values[count++] = val;
+ }
+
+ /* per-rxq stats */
+ for (q = 0; q < nb_rxqs; q++) {
+ for (i = 0; i < RTE_NB_RXQ_STATS; i++) {
+ stats_ptr = RTE_PTR_ADD(&eth_stats,
+ rte_rxq_stats_strings[i].offset +
+ q * sizeof(uint64_t));
+ val = *stats_ptr;
+ values[count++] = val;
+ }
+ }
+
+ /* per-txq stats */
+ for (q = 0; q < nb_txqs; q++) {
+ for (i = 0; i < RTE_NB_TXQ_STATS; i++) {
+ stats_ptr = RTE_PTR_ADD(&eth_stats,
+ rte_txq_stats_strings[i].offset +
+ q * sizeof(uint64_t));
+ val = *stats_ptr;
+ values[count++] = val;
+ }
+ }
+
+ return count + xcount;
+ }
+ /* Need only xstats given by IDS array */
+ else {
+ uint16_t i, size;
+ uint64_t *values_copy;
+
+ size = rte_eth_xstats_get_by_id(port_id, NULL, NULL, 0);
+
+ values_copy = malloc(sizeof(*values_copy) * size);
+ if (!values_copy) {
+ RTE_PMD_DEBUG_TRACE(
+ "ERROR: can't allocate memory for values_copy\n");
+ return -1;
+ }
+
+ rte_eth_xstats_get_by_id(port_id, NULL, values_copy, size);
+
+ for (i = 0; i < n; i++) {
+ if (ids[i] >= size) {
+ RTE_PMD_DEBUG_TRACE(
+ "ERROR: id value isn't valid\n");
+ return -1;
+ }
+ values[i] = values_copy[ids[i]];
+ }
+ free(values_copy);
+ return n;
+ }
+}
+
+int
rte_eth_xstats_get(uint8_t port_id, struct rte_eth_xstat *xstats,
- unsigned n)
+ unsigned int n)
{
struct rte_eth_stats eth_stats;
struct rte_eth_dev *dev;
- unsigned count = 0, i, q;
- signed xcount = 0;
+ unsigned int count = 0, i, q;
+ signed int xcount = 0;
uint64_t val, *stats_ptr;
uint16_t nb_rxqs, nb_txqs;
@@ -1606,6 +1869,18 @@ rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t rx_queue_id,
STAT_QMAP_RX);
}
+int
+rte_eth_dev_fw_version_get(uint8_t port_id, char *fw_version, size_t fw_size)
+{
+ 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->fw_version_get, -ENOTSUP);
+ return (*dev->dev_ops->fw_version_get)(dev, fw_version, fw_size);
+}
+
void
rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
{
@@ -1625,7 +1900,6 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
- dev_info->pci_dev = dev->pci_dev;
dev_info->driver_name = dev->data->drv_name;
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -1883,13 +2157,7 @@ rte_eth_check_reta_mask(struct rte_eth_rss_reta_entry64 *reta_conf,
if (!reta_conf)
return -EINVAL;
- if (reta_size != RTE_ALIGN(reta_size, RTE_RETA_GROUP_SIZE)) {
- RTE_PMD_DEBUG_TRACE("Invalid reta size, should be %u aligned\n",
- RTE_RETA_GROUP_SIZE);
- return -EINVAL;
- }
-
- num = reta_size / RTE_RETA_GROUP_SIZE;
+ num = (reta_size + RTE_RETA_GROUP_SIZE - 1) / RTE_RETA_GROUP_SIZE;
for (i = 0; i < num; i++) {
if (reta_conf[i].mask)
return 0;
@@ -2101,6 +2369,7 @@ rte_eth_dev_mac_addr_add(uint8_t port_id, struct ether_addr *addr,
struct rte_eth_dev *dev;
int index;
uint64_t pool_mask;
+ int ret;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
@@ -2133,15 +2402,17 @@ rte_eth_dev_mac_addr_add(uint8_t port_id, struct ether_addr *addr,
}
/* Update NIC */
- (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
+ ret = (*dev->dev_ops->mac_addr_add)(dev, addr, index, pool);
- /* Update address in NIC data structure */
- ether_addr_copy(addr, &dev->data->mac_addrs[index]);
+ if (ret == 0) {
+ /* Update address in NIC data structure */
+ ether_addr_copy(addr, &dev->data->mac_addrs[index]);
- /* Update pool bitmap in NIC data structure */
- dev->data->mac_pool_sel[index] |= (1ULL << pool);
+ /* Update pool bitmap in NIC data structure */
+ dev->data->mac_pool_sel[index] |= (1ULL << pool);
+ }
- return 0;
+ return ret;
}
int
@@ -2194,32 +2465,6 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
return 0;
}
-int
-rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf,
- uint16_t rx_mode, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("set VF RX mode:invalid VF id %d\n", vf);
- return -EINVAL;
- }
-
- if (rx_mode == 0) {
- RTE_PMD_DEBUG_TRACE("set VF RX mode:mode mask ca not be zero\n");
- return -EINVAL;
- }
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx_mode, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rx_mode)(dev, vf, rx_mode, on);
-}
/*
* Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
@@ -2309,76 +2554,6 @@ rte_eth_dev_uc_all_hash_table_set(uint8_t port_id, uint8_t on)
return (*dev->dev_ops->uc_all_hash_table_set)(dev, on);
}
-int
-rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("port %d: invalid vf id\n", port_id);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("set pool tx:invalid pool id=%d\n", vf);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_tx, -ENOTSUP);
- return (*dev->dev_ops->set_vf_tx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
- uint64_t vf_mask, uint8_t vlan_on)
-{
- struct rte_eth_dev *dev;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
-
- if (vlan_id > ETHER_MAX_VLAN_ID) {
- RTE_PMD_DEBUG_TRACE("VF VLAN filter:invalid VLAN id=%d\n",
- vlan_id);
- return -EINVAL;
- }
-
- if (vf_mask == 0) {
- RTE_PMD_DEBUG_TRACE("VF VLAN filter:pool_mask can not be 0\n");
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_filter, -ENOTSUP);
- return (*dev->dev_ops->set_vf_vlan_filter)(dev, vlan_id,
- vf_mask, vlan_on);
-}
-
int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
uint16_t tx_rate)
{
@@ -2409,45 +2584,12 @@ int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
return (*dev->dev_ops->set_queue_rate_limit)(dev, queue_idx, tx_rate);
}
-int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate,
- uint64_t q_msk)
-{
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
- struct rte_eth_link link;
-
- if (q_msk == 0)
- return 0;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
- link = dev->data->dev_link;
-
- if (vf > dev_info.max_vfs) {
- RTE_PMD_DEBUG_TRACE("set VF rate limit:port %d: "
- "invalid vf id=%d\n", port_id, vf);
- return -EINVAL;
- }
-
- if (tx_rate > link.link_speed) {
- RTE_PMD_DEBUG_TRACE("set VF rate limit:invalid tx_rate=%d, "
- "bigger than link speed= %d\n",
- tx_rate, link.link_speed);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rate_limit, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rate_limit)(dev, vf, tx_rate, q_msk);
-}
-
int
rte_eth_mirror_rule_set(uint8_t port_id,
struct rte_eth_mirror_conf *mirror_conf,
uint8_t rule_id, uint8_t on)
{
- struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
if (mirror_conf->rule_type == 0) {
@@ -2483,7 +2625,7 @@ rte_eth_mirror_rule_set(uint8_t port_id,
int
rte_eth_mirror_rule_reset(uint8_t port_id, uint8_t rule_id)
{
- struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ struct rte_eth_dev *dev;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
@@ -2590,7 +2732,7 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
dev_cb = *cb_lst;
cb_lst->active = 1;
if (cb_arg != NULL)
- dev_cb.cb_arg = (void *) cb_arg;
+ dev_cb.cb_arg = cb_arg;
rte_spinlock_unlock(&rte_eth_dev_cb_lock);
dev_cb.cb_fn(dev->data->port_id, dev_cb.event,
@@ -2613,7 +2755,13 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- intr_handle = &dev->pci_dev->intr_handle;
+
+ if (!dev->intr_handle) {
+ RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+ return -ENOTSUP;
+ }
+
+ intr_handle = dev->intr_handle;
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
@@ -2641,7 +2789,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
const struct rte_memzone *mz;
snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- dev->driver->pci_drv.driver.name, ring_name,
+ dev->data->drv_name, ring_name,
dev->data->port_id, queue_id);
mz = rte_memzone_lookup(z_name);
@@ -2673,7 +2821,12 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
return -EINVAL;
}
- intr_handle = &dev->pci_dev->intr_handle;
+ if (!dev->intr_handle) {
+ RTE_PMD_DEBUG_TRACE("RX Intr handle unset\n");
+ return -ENOTSUP;
+ }
+
+ intr_handle = dev->intr_handle;
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
@@ -3266,26 +3419,6 @@ rte_eth_dev_get_dcb_info(uint8_t port_id,
return (*dev->dev_ops->get_dcb_info)(dev, dcb_info);
}
-void
-rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_dev)
-{
- if ((eth_dev == NULL) || (pci_dev == NULL)) {
- RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p pci_dev=%p\n",
- eth_dev, pci_dev);
- return;
- }
-
- eth_dev->data->dev_flags = 0;
- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
- eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
- if (pci_dev->driver->drv_flags & RTE_PCI_DRV_DETACHABLE)
- eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
-
- eth_dev->data->kdrv = pci_dev->kdrv;
- eth_dev->data->numa_node = pci_dev->device.numa_node;
- eth_dev->data->drv_name = pci_dev->driver->driver.name;
-}
-
int
rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
struct rte_eth_l2_tunnel_conf *l2_tunnel)