#include <rte_string_fns.h>
#include <rte_kvargs.h>
#include <rte_class.h>
+#include <rte_ether.h>
-#include "rte_ether.h"
#include "rte_ethdev.h"
#include "rte_ethdev_driver.h"
#include "ethdev_profile.h"
RTE_RX_OFFLOAD_BIT2STR(KEEP_CRC),
RTE_RX_OFFLOAD_BIT2STR(SCTP_CKSUM),
RTE_RX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
+ RTE_RX_OFFLOAD_BIT2STR(RSS_HASH),
};
#undef RTE_RX_OFFLOAD_BIT2STR
RTE_TX_OFFLOAD_BIT2STR(UDP_TNL_TSO),
RTE_TX_OFFLOAD_BIT2STR(IP_TNL_TSO),
RTE_TX_OFFLOAD_BIT2STR(OUTER_UDP_CKSUM),
- RTE_TX_OFFLOAD_BIT2STR(MATCH_METADATA),
};
#undef RTE_TX_OFFLOAD_BIT2STR
return ret;
}
-void
+int
rte_eth_dev_owner_delete(const uint64_t owner_id)
{
uint16_t port_id;
+ int ret = 0;
rte_eth_dev_shared_data_prepare();
RTE_ETHDEV_LOG(ERR,
"Invalid owner id=%016"PRIx64"\n",
owner_id);
+ ret = -EINVAL;
}
rte_spinlock_unlock(&rte_eth_dev_shared_data->ownership_lock);
+
+ return ret;
}
int
return rte_eth_devices[port_id].security_ctx;
}
-uint16_t
-rte_eth_dev_count(void)
-{
- return rte_eth_dev_count_avail();
-}
-
uint16_t
rte_eth_dev_count_avail(void)
{
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_start, -ENOTSUP);
+ if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't start Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+ rx_queue_id, port_id);
+ return -EINVAL;
+ }
+
if (dev->data->rx_queue_state[rx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
RTE_ETHDEV_LOG(INFO,
"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_queue_stop, -ENOTSUP);
+ if (rte_eth_dev_is_rx_hairpin_queue(dev, rx_queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't stop Rx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+ rx_queue_id, port_id);
+ return -EINVAL;
+ }
+
if (dev->data->rx_queue_state[rx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
RTE_ETHDEV_LOG(INFO,
"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_start, -ENOTSUP);
+ if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't start Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+ tx_queue_id, port_id);
+ return -EINVAL;
+ }
+
if (dev->data->tx_queue_state[tx_queue_id] != RTE_ETH_QUEUE_STATE_STOPPED) {
RTE_ETHDEV_LOG(INFO,
"Queue %"PRIu16" of device with port_id=%"PRIu16" already started\n",
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_queue_stop, -ENOTSUP);
+ if (rte_eth_dev_is_tx_hairpin_queue(dev, tx_queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't stop Tx hairpin queue %"PRIu16" of device with port_id=%"PRIu16"\n",
+ tx_queue_id, port_id);
+ return -EINVAL;
+ }
+
if (dev->data->tx_queue_state[tx_queue_id] == RTE_ETH_QUEUE_STATE_STOPPED) {
RTE_ETHDEV_LOG(INFO,
"Queue %"PRIu16" of device with port_id=%"PRIu16" already stopped\n",
goto rollback;
}
+ dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
+ rte_eth_rss_hf_refine(dev_conf->rx_adv_conf.rss_conf.rss_hf);
+
/* Check that device supports requested rss hash functions. */
if ((dev_info.flow_type_rss_offloads |
dev_conf->rx_adv_conf.rss_conf.rss_hf) !=
goto rollback;
}
+ /* Check if Rx RSS distribution is disabled but RSS hash is enabled. */
+ if (((dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) == 0) &&
+ (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_RSS_HASH)) {
+ RTE_ETHDEV_LOG(ERR,
+ "Ethdev port_id=%u config invalid Rx mq_mode without RSS but %s offload is requested",
+ port_id,
+ rte_eth_dev_rx_offload_name(DEV_RX_OFFLOAD_RSS_HASH));
+ ret = -EINVAL;
+ goto rollback;
+ }
+
/*
* Setup new number of RX/TX queues and reconfigure device.
*/
}
}
-static void
+static int
rte_eth_dev_config_restore(struct rte_eth_dev *dev,
struct rte_eth_dev_info *dev_info, uint16_t port_id)
{
+ int ret;
+
if (!(*dev_info->dev_flags & RTE_ETH_DEV_NOLIVE_MAC_ADDR))
rte_eth_dev_mac_restore(dev, dev_info);
/* replay promiscuous configuration */
- if (rte_eth_promiscuous_get(port_id) == 1)
- rte_eth_promiscuous_enable(port_id);
- else if (rte_eth_promiscuous_get(port_id) == 0)
- rte_eth_promiscuous_disable(port_id);
+ /*
+ * use callbacks directly since we don't need port_id check and
+ * would like to bypass the same value set
+ */
+ if (rte_eth_promiscuous_get(port_id) == 1 &&
+ *dev->dev_ops->promiscuous_enable != NULL) {
+ ret = eth_err(port_id,
+ (*dev->dev_ops->promiscuous_enable)(dev));
+ if (ret != 0 && ret != -ENOTSUP) {
+ RTE_ETHDEV_LOG(ERR,
+ "Failed to enable promiscuous mode for device (port %u): %s\n",
+ port_id, rte_strerror(-ret));
+ return ret;
+ }
+ } else if (rte_eth_promiscuous_get(port_id) == 0 &&
+ *dev->dev_ops->promiscuous_disable != NULL) {
+ ret = eth_err(port_id,
+ (*dev->dev_ops->promiscuous_disable)(dev));
+ if (ret != 0 && ret != -ENOTSUP) {
+ RTE_ETHDEV_LOG(ERR,
+ "Failed to disable promiscuous mode for device (port %u): %s\n",
+ port_id, rte_strerror(-ret));
+ return ret;
+ }
+ }
/* replay all multicast configuration */
- if (rte_eth_allmulticast_get(port_id) == 1)
- rte_eth_allmulticast_enable(port_id);
- else if (rte_eth_allmulticast_get(port_id) == 0)
- rte_eth_allmulticast_disable(port_id);
+ /*
+ * use callbacks directly since we don't need port_id check and
+ * would like to bypass the same value set
+ */
+ if (rte_eth_allmulticast_get(port_id) == 1 &&
+ *dev->dev_ops->allmulticast_enable != NULL) {
+ ret = eth_err(port_id,
+ (*dev->dev_ops->allmulticast_enable)(dev));
+ if (ret != 0 && ret != -ENOTSUP) {
+ RTE_ETHDEV_LOG(ERR,
+ "Failed to enable allmulticast mode for device (port %u): %s\n",
+ port_id, rte_strerror(-ret));
+ return ret;
+ }
+ } else if (rte_eth_allmulticast_get(port_id) == 0 &&
+ *dev->dev_ops->allmulticast_disable != NULL) {
+ ret = eth_err(port_id,
+ (*dev->dev_ops->allmulticast_disable)(dev));
+ if (ret != 0 && ret != -ENOTSUP) {
+ RTE_ETHDEV_LOG(ERR,
+ "Failed to disable allmulticast mode for device (port %u): %s\n",
+ port_id, rte_strerror(-ret));
+ return ret;
+ }
+ }
+
+ return 0;
}
int
else
return eth_err(port_id, diag);
- rte_eth_dev_config_restore(dev, &dev_info, port_id);
+ ret = rte_eth_dev_config_restore(dev, &dev_info, port_id);
+ if (ret != 0) {
+ RTE_ETHDEV_LOG(ERR,
+ "Error during restoring configuration for device (port %u): %s\n",
+ port_id, rte_strerror(-ret));
+ rte_eth_dev_stop(port_id);
+ return ret;
+ }
if (dev->data->dev_conf.intr_conf.lsc == 0) {
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
return eth_err(port_id, ret);
}
+int
+rte_eth_rx_hairpin_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
+ uint16_t nb_rx_desc,
+ const struct rte_eth_hairpin_conf *conf)
+{
+ int ret;
+ struct rte_eth_dev *dev;
+ struct rte_eth_hairpin_cap cap;
+ void **rxq;
+ int i;
+ int count;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+
+ dev = &rte_eth_devices[port_id];
+ if (rx_queue_id >= dev->data->nb_rx_queues) {
+ RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", rx_queue_id);
+ return -EINVAL;
+ }
+ ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
+ if (ret != 0)
+ return ret;
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_hairpin_queue_setup,
+ -ENOTSUP);
+ /* if nb_rx_desc is zero use max number of desc from the driver. */
+ if (nb_rx_desc == 0)
+ nb_rx_desc = cap.max_nb_desc;
+ if (nb_rx_desc > cap.max_nb_desc) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for nb_rx_desc(=%hu), should be: <= %hu",
+ nb_rx_desc, cap.max_nb_desc);
+ return -EINVAL;
+ }
+ if (conf->peer_count > cap.max_rx_2_tx) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for number of peers for Rx queue(=%hu), should be: <= %hu",
+ conf->peer_count, cap.max_rx_2_tx);
+ return -EINVAL;
+ }
+ if (conf->peer_count == 0) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for number of peers for Rx queue(=%hu), should be: > 0",
+ conf->peer_count);
+ return -EINVAL;
+ }
+ for (i = 0, count = 0; i < dev->data->nb_rx_queues &&
+ cap.max_nb_queues != UINT16_MAX; i++) {
+ if (i == rx_queue_id || rte_eth_dev_is_rx_hairpin_queue(dev, i))
+ count++;
+ }
+ if (count > cap.max_nb_queues) {
+ RTE_ETHDEV_LOG(ERR, "To many Rx hairpin queues max is %d",
+ cap.max_nb_queues);
+ return -EINVAL;
+ }
+ if (dev->data->dev_started)
+ return -EBUSY;
+ rxq = dev->data->rx_queues;
+ if (rxq[rx_queue_id] != NULL) {
+ 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;
+ }
+ ret = (*dev->dev_ops->rx_hairpin_queue_setup)(dev, rx_queue_id,
+ nb_rx_desc, conf);
+ if (ret == 0)
+ dev->data->rx_queue_state[rx_queue_id] =
+ RTE_ETH_QUEUE_STATE_HAIRPIN;
+ return eth_err(port_id, ret);
+}
+
int
rte_eth_tx_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
uint16_t nb_tx_desc, unsigned int socket_id,
tx_queue_id, nb_tx_desc, socket_id, &local_conf));
}
+int
+rte_eth_tx_hairpin_queue_setup(uint16_t port_id, uint16_t tx_queue_id,
+ uint16_t nb_tx_desc,
+ const struct rte_eth_hairpin_conf *conf)
+{
+ struct rte_eth_dev *dev;
+ struct rte_eth_hairpin_cap cap;
+ void **txq;
+ int i;
+ int count;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+ dev = &rte_eth_devices[port_id];
+ if (tx_queue_id >= dev->data->nb_tx_queues) {
+ RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", tx_queue_id);
+ return -EINVAL;
+ }
+ ret = rte_eth_dev_hairpin_capability_get(port_id, &cap);
+ if (ret != 0)
+ return ret;
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_hairpin_queue_setup,
+ -ENOTSUP);
+ /* if nb_rx_desc is zero use max number of desc from the driver. */
+ if (nb_tx_desc == 0)
+ nb_tx_desc = cap.max_nb_desc;
+ if (nb_tx_desc > cap.max_nb_desc) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for nb_tx_desc(=%hu), should be: <= %hu",
+ nb_tx_desc, cap.max_nb_desc);
+ return -EINVAL;
+ }
+ if (conf->peer_count > cap.max_tx_2_rx) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for number of peers for Tx queue(=%hu), should be: <= %hu",
+ conf->peer_count, cap.max_tx_2_rx);
+ return -EINVAL;
+ }
+ if (conf->peer_count == 0) {
+ RTE_ETHDEV_LOG(ERR,
+ "Invalid value for number of peers for Tx queue(=%hu), should be: > 0",
+ conf->peer_count);
+ return -EINVAL;
+ }
+ for (i = 0, count = 0; i < dev->data->nb_tx_queues &&
+ cap.max_nb_queues != UINT16_MAX; i++) {
+ if (i == tx_queue_id || rte_eth_dev_is_tx_hairpin_queue(dev, i))
+ count++;
+ }
+ if (count > cap.max_nb_queues) {
+ RTE_ETHDEV_LOG(ERR, "To many Tx hairpin queues max is %d",
+ cap.max_nb_queues);
+ return -EINVAL;
+ }
+ if (dev->data->dev_started)
+ return -EBUSY;
+ txq = dev->data->tx_queues;
+ if (txq[tx_queue_id] != NULL) {
+ 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;
+ }
+ ret = (*dev->dev_ops->tx_hairpin_queue_setup)
+ (dev, tx_queue_id, nb_tx_desc, conf);
+ if (ret == 0)
+ dev->data->tx_queue_state[tx_queue_id] =
+ RTE_ETH_QUEUE_STATE_HAIRPIN;
+ return eth_err(port_id, ret);
+}
+
void
rte_eth_tx_buffer_drop_callback(struct rte_mbuf **pkts, uint16_t unsent,
void *userdata __rte_unused)
return eth_err(port_id, ret);
}
-void
+int
rte_eth_promiscuous_enable(uint16_t port_id)
{
struct rte_eth_dev *dev;
+ int diag = 0;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_enable);
- (*dev->dev_ops->promiscuous_enable)(dev);
- dev->data->promiscuous = 1;
+ if (dev->data->promiscuous == 1)
+ return 0;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_enable, -ENOTSUP);
+
+ diag = (*dev->dev_ops->promiscuous_enable)(dev);
+ dev->data->promiscuous = (diag == 0) ? 1 : 0;
+
+ return eth_err(port_id, diag);
}
-void
+int
rte_eth_promiscuous_disable(uint16_t port_id)
{
struct rte_eth_dev *dev;
+ int diag = 0;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- RTE_FUNC_PTR_OR_RET(*dev->dev_ops->promiscuous_disable);
+ if (dev->data->promiscuous == 0)
+ return 0;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->promiscuous_disable, -ENOTSUP);
+
dev->data->promiscuous = 0;
- (*dev->dev_ops->promiscuous_disable)(dev);
+ diag = (*dev->dev_ops->promiscuous_disable)(dev);
+ if (diag != 0)
+ dev->data->promiscuous = 1;
+
+ return eth_err(port_id, diag);
}
int
return dev->data->promiscuous;
}
-void
+int
rte_eth_allmulticast_enable(uint16_t port_id)
{
struct rte_eth_dev *dev;
+ int diag;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_enable);
- (*dev->dev_ops->allmulticast_enable)(dev);
- dev->data->all_multicast = 1;
+ if (dev->data->all_multicast == 1)
+ return 0;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_enable, -ENOTSUP);
+ diag = (*dev->dev_ops->allmulticast_enable)(dev);
+ dev->data->all_multicast = (diag == 0) ? 1 : 0;
+
+ return eth_err(port_id, diag);
}
-void
+int
rte_eth_allmulticast_disable(uint16_t port_id)
{
struct rte_eth_dev *dev;
+ int diag;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- RTE_FUNC_PTR_OR_RET(*dev->dev_ops->allmulticast_disable);
+ if (dev->data->all_multicast == 0)
+ return 0;
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->allmulticast_disable, -ENOTSUP);
dev->data->all_multicast = 0;
- (*dev->dev_ops->allmulticast_disable)(dev);
+ diag = (*dev->dev_ops->allmulticast_disable)(dev);
+ if (diag != 0)
+ dev->data->all_multicast = 1;
+
+ return eth_err(port_id, diag);
}
int
return dev->data->all_multicast;
}
-void
+int
rte_eth_link_get(uint16_t port_id, struct rte_eth_link *eth_link)
{
struct rte_eth_dev *dev;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
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_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
(*dev->dev_ops->link_update)(dev, 1);
*eth_link = dev->data->dev_link;
}
+
+ return 0;
}
-void
+int
rte_eth_link_get_nowait(uint16_t port_id, struct rte_eth_link *eth_link)
{
struct rte_eth_dev *dev;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
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_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->link_update, -ENOTSUP);
(*dev->dev_ops->link_update)(dev, 0);
*eth_link = dev->data->dev_link;
}
+
+ return 0;
}
int
rte_eth_stats_reset(uint16_t port_id)
{
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->stats_reset, -ENOTSUP);
- (*dev->dev_ops->stats_reset)(dev);
+ ret = (*dev->dev_ops->stats_reset)(dev);
+ if (ret != 0)
+ return eth_err(port_id, ret);
+
dev->data->rx_mbuf_alloc_failed = 0;
return 0;
}
/* reset ethdev extended statistics */
-void
+int
rte_eth_xstats_reset(uint16_t port_id)
{
struct rte_eth_dev *dev;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
/* implemented by the driver */
- if (dev->dev_ops->xstats_reset != NULL) {
- (*dev->dev_ops->xstats_reset)(dev);
- return;
- }
+ if (dev->dev_ops->xstats_reset != NULL)
+ return eth_err(port_id, (*dev->dev_ops->xstats_reset)(dev));
/* fallback to default */
- rte_eth_stats_reset(port_id);
+ return rte_eth_stats_reset(port_id);
}
static int
.nb_seg_max = UINT16_MAX,
.nb_mtu_seg_max = UINT16_MAX,
};
+ int diag;
/*
* Init dev_info before port_id check since caller does not have
dev_info->max_mtu = UINT16_MAX;
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_infos_get, -ENOTSUP);
- (*dev->dev_ops->dev_infos_get)(dev, dev_info);
+ diag = (*dev->dev_ops->dev_infos_get)(dev, dev_info);
+ if (diag != 0) {
+ /* Cleanup already filled in device information */
+ memset(dev_info, 0, sizeof(struct rte_eth_dev_info));
+ return eth_err(port_id, diag);
+ }
+
dev_info->driver_name = dev->device->driver->name;
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
return j;
}
-void
+int
+rte_eth_dev_set_ptypes(uint16_t port_id, uint32_t ptype_mask,
+ uint32_t *set_ptypes, unsigned int num)
+{
+ const uint32_t valid_ptype_masks[] = {
+ RTE_PTYPE_L2_MASK,
+ RTE_PTYPE_L3_MASK,
+ RTE_PTYPE_L4_MASK,
+ RTE_PTYPE_TUNNEL_MASK,
+ RTE_PTYPE_INNER_L2_MASK,
+ RTE_PTYPE_INNER_L3_MASK,
+ RTE_PTYPE_INNER_L4_MASK,
+ };
+ const uint32_t *all_ptypes;
+ struct rte_eth_dev *dev;
+ uint32_t unused_mask;
+ unsigned int i, j;
+ int ret;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+ dev = &rte_eth_devices[port_id];
+
+ if (num > 0 && set_ptypes == NULL)
+ return -EINVAL;
+
+ if (*dev->dev_ops->dev_supported_ptypes_get == NULL ||
+ *dev->dev_ops->dev_ptypes_set == NULL) {
+ ret = 0;
+ goto ptype_unknown;
+ }
+
+ if (ptype_mask == 0) {
+ ret = (*dev->dev_ops->dev_ptypes_set)(dev,
+ ptype_mask);
+ goto ptype_unknown;
+ }
+
+ unused_mask = ptype_mask;
+ for (i = 0; i < RTE_DIM(valid_ptype_masks); i++) {
+ uint32_t mask = ptype_mask & valid_ptype_masks[i];
+ if (mask && mask != valid_ptype_masks[i]) {
+ ret = -EINVAL;
+ goto ptype_unknown;
+ }
+ unused_mask &= ~valid_ptype_masks[i];
+ }
+
+ if (unused_mask) {
+ ret = -EINVAL;
+ goto ptype_unknown;
+ }
+
+ all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
+ if (all_ptypes == NULL) {
+ ret = 0;
+ goto ptype_unknown;
+ }
+
+ /*
+ * Accommodate as many set_ptypes as possible. If the supplied
+ * set_ptypes array is insufficient fill it partially.
+ */
+ for (i = 0, j = 0; set_ptypes != NULL &&
+ (all_ptypes[i] != RTE_PTYPE_UNKNOWN); ++i) {
+ if (ptype_mask & all_ptypes[i]) {
+ if (j < num - 1) {
+ set_ptypes[j] = all_ptypes[i];
+ j++;
+ continue;
+ }
+ break;
+ }
+ }
+
+ if (set_ptypes != NULL && j < num)
+ set_ptypes[j] = RTE_PTYPE_UNKNOWN;
+
+ return (*dev->dev_ops->dev_ptypes_set)(dev, ptype_mask);
+
+ptype_unknown:
+ if (num > 0)
+ set_ptypes[0] = RTE_PTYPE_UNKNOWN;
+
+ return ret;
+}
+
+int
rte_eth_macaddr_get(uint16_t port_id, struct rte_ether_addr *mac_addr)
{
struct rte_eth_dev *dev;
- RTE_ETH_VALID_PORTID_OR_RET(port_id);
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
rte_ether_addr_copy(&dev->data->mac_addrs[0], mac_addr);
-}
+ return 0;
+}
int
rte_eth_dev_get_mtu(uint16_t port_id, uint16_t *mtu)
ret |= ETH_VLAN_EXTEND_OFFLOAD;
if (*dev_offloads & DEV_RX_OFFLOAD_QINQ_STRIP)
- ret |= DEV_RX_OFFLOAD_QINQ_STRIP;
+ ret |= ETH_QINQ_STRIP_OFFLOAD;
return ret;
}
if (ret != 0)
return ret;
+ rss_conf->rss_hf = rte_eth_rss_hf_refine(rss_conf->rss_hf);
+
dev = &rte_eth_devices[port_id];
if ((dev_info.flow_type_rss_offloads | rss_conf->rss_hf) !=
dev_info.flow_type_rss_offloads) {
rte_errno = ENOTSUP;
return NULL;
#endif
+ struct rte_eth_dev *dev;
+
/* check input parameters */
if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
queue_id >= rte_eth_devices[port_id].data->nb_rx_queues) {
rte_errno = EINVAL;
return NULL;
}
+ dev = &rte_eth_devices[port_id];
+ if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
if (cb == NULL) {
rte_errno = ENOTSUP;
return NULL;
#endif
+ struct rte_eth_dev *dev;
+
/* check input parameters */
if (!rte_eth_dev_is_valid_port(port_id) || fn == NULL ||
queue_id >= rte_eth_devices[port_id].data->nb_tx_queues) {
return NULL;
}
+ dev = &rte_eth_devices[port_id];
+ if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
+
struct rte_eth_rxtx_callback *cb = rte_zmalloc(NULL, sizeof(*cb), 0);
if (cb == NULL) {
return -EINVAL;
}
+ if (rte_eth_dev_is_rx_hairpin_queue(dev, queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't get hairpin Rx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
+ queue_id, port_id);
+ return -EINVAL;
+ }
+
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rxq_info_get, -ENOTSUP);
memset(qinfo, 0, sizeof(*qinfo));
return -EINVAL;
}
+ if (rte_eth_dev_is_tx_hairpin_queue(dev, queue_id)) {
+ RTE_ETHDEV_LOG(INFO,
+ "Can't get hairpin Tx queue %"PRIu16" info of device with port_id=%"PRIu16"\n",
+ queue_id, port_id);
+ return -EINVAL;
+ }
+
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->txq_info_get, -ENOTSUP);
memset(qinfo, 0, sizeof(*qinfo));
return 0;
}
+int
+rte_eth_rx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
+ struct rte_eth_burst_mode *mode)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+ if (mode == NULL)
+ return -EINVAL;
+
+ dev = &rte_eth_devices[port_id];
+
+ if (queue_id >= dev->data->nb_rx_queues) {
+ RTE_ETHDEV_LOG(ERR, "Invalid RX queue_id=%u\n", queue_id);
+ return -EINVAL;
+ }
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->rx_burst_mode_get, -ENOTSUP);
+ memset(mode, 0, sizeof(*mode));
+ return eth_err(port_id,
+ dev->dev_ops->rx_burst_mode_get(dev, queue_id, mode));
+}
+
+int
+rte_eth_tx_burst_mode_get(uint16_t port_id, uint16_t queue_id,
+ struct rte_eth_burst_mode *mode)
+{
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+ if (mode == NULL)
+ return -EINVAL;
+
+ dev = &rte_eth_devices[port_id];
+
+ if (queue_id >= dev->data->nb_tx_queues) {
+ RTE_ETHDEV_LOG(ERR, "Invalid TX queue_id=%u\n", queue_id);
+ return -EINVAL;
+ }
+
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->tx_burst_mode_get, -ENOTSUP);
+ memset(mode, 0, sizeof(*mode));
+ return eth_err(port_id,
+ dev->dev_ops->tx_burst_mode_get(dev, queue_id, mode));
+}
+
int
rte_eth_dev_set_mc_addr_list(uint16_t port_id,
struct rte_ether_addr *mc_addr_set,
return 0;
}
+int
+rte_eth_dev_hairpin_capability_get(uint16_t port_id,
+ struct rte_eth_hairpin_cap *cap)
+{
+ struct rte_eth_dev *dev;
+
+ 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->hairpin_cap_get, -ENOTSUP);
+ memset(cap, 0, sizeof(*cap));
+ return eth_err(port_id, (*dev->dev_ops->hairpin_cap_get)(dev, cap));
+}
+
+int
+rte_eth_dev_is_rx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ if (dev->data->rx_queue_state[queue_id] ==
+ RTE_ETH_QUEUE_STATE_HAIRPIN)
+ return 1;
+ return 0;
+}
+
+int
+rte_eth_dev_is_tx_hairpin_queue(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ if (dev->data->tx_queue_state[queue_id] ==
+ RTE_ETH_QUEUE_STATE_HAIRPIN)
+ return 1;
+ return 0;
+}
+
int
rte_eth_dev_pool_ops_supported(uint16_t port_id, const char *pool)
{