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",
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)
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_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)
{