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)
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];
}
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;
}
+static struct rte_eth_dev *
+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->state = RTE_ETH_DEV_ATTACHED;
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ eth_dev_last_created_port = port_id;
+ nb_ports++;
+
+ return eth_dev;
+}
+
struct rte_eth_dev *
rte_eth_dev_allocate(const char *name)
{
return NULL;
}
- eth_dev = &rte_eth_devices[port_id];
- eth_dev->data = &rte_eth_dev_data[port_id];
- memset(eth_dev->data, 0, sizeof(*eth_dev->data));
+ 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;
- TAILQ_INIT(&(eth_dev->link_intr_cbs));
- eth_dev->attached = DEV_ATTACHED;
- eth_dev_last_created_port = port_id;
- nb_ports++;
return eth_dev;
}
-int
-rte_eth_dev_release_port(struct rte_eth_dev *eth_dev)
-{
- if (eth_dev == NULL)
- return -EINVAL;
-
- eth_dev->attached = DEV_DETACHED;
- nb_ports--;
- return 0;
-}
-
-int
-rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev)
+/*
+ * Attach to a port already registered by the primary process, which
+ * makes sure that the same device would have the same port id both
+ * in the primary and secondary process.
+ */
+struct rte_eth_dev *
+rte_eth_dev_attach_secondary(const char *name)
{
- struct eth_driver *eth_drv;
+ uint8_t i;
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));
-
- eth_dev = rte_eth_dev_allocate(ethdev_name);
- if (eth_dev == NULL)
- return -ENOMEM;
+ if (rte_eth_dev_data == NULL)
+ rte_eth_dev_data_alloc();
- if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
- 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");
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
+ if (strcmp(rte_eth_dev_data[i].name, name) == 0)
+ break;
+ }
+ if (i == RTE_MAX_ETHPORTS) {
+ RTE_PMD_DEBUG_TRACE(
+ "device %s is not driven by the primary process\n",
+ name);
+ return NULL;
}
- eth_dev->pci_dev = pci_dev;
- eth_dev->driver = eth_drv;
- /* Invoke PMD device initialization function */
- diag = (*eth_drv->eth_dev_init)(eth_dev);
- if (diag == 0)
- return 0;
+ eth_dev = eth_dev_get(i);
+ RTE_ASSERT(eth_dev->data->port_id == i);
- 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;
+ return eth_dev;
}
int
-rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
+rte_eth_dev_release_port(struct rte_eth_dev *eth_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 -EINVAL;
+ eth_dev->state = RTE_ETH_DEV_UNUSED;
+ nb_ports--;
return 0;
}
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;
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))) {
case RTE_KDRV_UIO_GENERIC:
case RTE_KDRV_NIC_UIO:
case RTE_KDRV_NONE:
- break;
case RTE_KDRV_VFIO:
+ break;
default:
return -ENOTSUP;
}
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;
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;
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);
}
}
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);
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;
{
struct rte_eth_dev *dev;
struct rte_eth_dev_info dev_info;
+ void **txq;
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
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;
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)
{
}
}
- for (i = 0; i < count + xcount; i++)
+ for (i = 0; i < count; i++)
xstats[i].id = i;
+ /* add an offset to driver-specific stats */
+ for ( ; i < count + xcount; i++)
+ xstats[i].id += count;
return count + xcount;
}
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)
{
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;
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;
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
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)
{
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) {
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);
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,
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;
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);
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;
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)