#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
/* Verbs headers do not support -pedantic. */
#ifdef PEDANTIC
/**
* DPDK callback for Ethernet device configuration.
*
- * Prepare the driver for a given number of TX and RX queues.
- *
* @param dev
* Pointer to Ethernet device structure.
*
static int
mlx4_dev_configure(struct rte_eth_dev *dev)
{
- struct priv *priv = dev->data->dev_private;
- unsigned int rxqs_n = dev->data->nb_rx_queues;
- unsigned int txqs_n = dev->data->nb_tx_queues;
-
- priv->rxqs = (void *)dev->data->rx_queues;
- priv->txqs = (void *)dev->data->tx_queues;
- if (txqs_n != priv->txqs_n) {
- INFO("%p: TX queues number update: %u -> %u",
- (void *)dev, priv->txqs_n, txqs_n);
- priv->txqs_n = txqs_n;
- }
- if (rxqs_n != priv->rxqs_n) {
- INFO("%p: Rx queues number update: %u -> %u",
- (void *)dev, priv->rxqs_n, rxqs_n);
- priv->rxqs_n = rxqs_n;
- }
+ (void)dev;
return 0;
}
mlx4_dev_close(struct rte_eth_dev *dev)
{
struct priv *priv = dev->data->dev_private;
- void *tmp;
unsigned int i;
if (priv == NULL)
(void *)dev,
((priv->ctx != NULL) ? priv->ctx->device->name : ""));
mlx4_mac_addr_del(priv);
- /*
- * Prevent crashes when queues are still in use. This is unfortunately
- * still required for DPDK 1.3 because some programs (such as testpmd)
- * never release them before closing the device.
- */
dev->rx_pkt_burst = mlx4_rx_burst_removed;
dev->tx_pkt_burst = mlx4_tx_burst_removed;
- if (priv->rxqs != NULL) {
- /* XXX race condition if mlx4_rx_burst() is still running. */
- usleep(1000);
- for (i = 0; (i != priv->rxqs_n); ++i) {
- tmp = (*priv->rxqs)[i];
- if (tmp == NULL)
- continue;
- (*priv->rxqs)[i] = NULL;
- mlx4_rxq_cleanup(tmp);
- rte_free(tmp);
- }
- priv->rxqs_n = 0;
- priv->rxqs = NULL;
- }
- if (priv->txqs != NULL) {
- /* XXX race condition if mlx4_tx_burst() is still running. */
- usleep(1000);
- for (i = 0; (i != priv->txqs_n); ++i) {
- tmp = (*priv->txqs)[i];
- if (tmp == NULL)
- continue;
- (*priv->txqs)[i] = NULL;
- mlx4_txq_cleanup(tmp);
- rte_free(tmp);
- }
- priv->txqs_n = 0;
- priv->txqs = NULL;
- }
+ for (i = 0; i != dev->data->nb_rx_queues; ++i)
+ mlx4_rx_queue_release(dev->data->rx_queues[i]);
+ for (i = 0; i != dev->data->nb_tx_queues; ++i)
+ mlx4_tx_queue_release(dev->data->tx_queues[i]);
if (priv->pd != NULL) {
assert(priv->ctx != NULL);
claim_zero(ibv_dealloc_pd(priv->pd));
unsigned int vf:1; /* This is a VF device. */
unsigned int intr_alarm:1; /* An interrupt alarm is scheduled. */
unsigned int isolated:1; /* Toggle isolated mode. */
- /* RX/TX queues. */
- unsigned int rxqs_n; /* RX queues array size. */
- unsigned int txqs_n; /* TX queues array size. */
- struct rxq *(*rxqs)[]; /* RX queues. */
- struct txq *(*txqs)[]; /* TX queues. */
struct rte_intr_handle intr_handle; /* Port interrupt handle. */
struct rte_flow_drop *flow_drop_queue; /* Flow drop queue. */
LIST_HEAD(mlx4_flows, rte_flow) flows;
void
mlx4_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
{
- struct priv *priv = dev->data->dev_private;
struct rte_eth_stats tmp;
unsigned int i;
unsigned int idx;
- if (priv == NULL)
- return;
memset(&tmp, 0, sizeof(tmp));
/* Add software counters. */
- for (i = 0; (i != priv->rxqs_n); ++i) {
- struct rxq *rxq = (*priv->rxqs)[i];
+ for (i = 0; i != dev->data->nb_rx_queues; ++i) {
+ struct rxq *rxq = dev->data->rx_queues[i];
if (rxq == NULL)
continue;
tmp.ierrors += rxq->stats.idropped;
tmp.rx_nombuf += rxq->stats.rx_nombuf;
}
- for (i = 0; (i != priv->txqs_n); ++i) {
- struct txq *txq = (*priv->txqs)[i];
+ for (i = 0; i != dev->data->nb_tx_queues; ++i) {
+ struct txq *txq = dev->data->tx_queues[i];
if (txq == NULL)
continue;
void
mlx4_stats_reset(struct rte_eth_dev *dev)
{
- struct priv *priv = dev->data->dev_private;
unsigned int i;
- unsigned int idx;
- if (priv == NULL)
- return;
- for (i = 0; (i != priv->rxqs_n); ++i) {
- if ((*priv->rxqs)[i] == NULL)
- continue;
- idx = (*priv->rxqs)[i]->stats.idx;
- (*priv->rxqs)[i]->stats =
- (struct mlx4_rxq_stats){ .idx = idx };
+ for (i = 0; i != dev->data->nb_rx_queues; ++i) {
+ struct rxq *rxq = dev->data->rx_queues[i];
+
+ if (rxq)
+ rxq->stats = (struct mlx4_rxq_stats){
+ .idx = rxq->stats.idx,
+ };
}
- for (i = 0; (i != priv->txqs_n); ++i) {
- if ((*priv->txqs)[i] == NULL)
- continue;
- idx = (*priv->txqs)[i]->stats.idx;
- (*priv->txqs)[i]->stats =
- (struct mlx4_txq_stats){ .idx = idx };
+ for (i = 0; i != dev->data->nb_tx_queues; ++i) {
+ struct txq *txq = dev->data->tx_queues[i];
+
+ if (txq)
+ txq->stats = (struct mlx4_txq_stats){
+ .idx = txq->stats.idx,
+ };
}
}
(const struct rte_flow_action_queue *)
actions->conf;
- if (!queue || (queue->index > (priv->rxqs_n - 1)))
+ if (!queue || (queue->index >
+ (priv->dev->data->nb_rx_queues - 1)))
goto exit_action_not_supported;
action.queue = 1;
} else {
if (action->drop) {
qp = priv->flow_drop_queue ? priv->flow_drop_queue->qp : NULL;
} else {
- struct rxq *rxq = (*priv->rxqs)[action->queue_id];
+ struct rxq *rxq = priv->dev->data->rx_queues[action->queue_id];
qp = rxq->qp;
rte_flow->qp = qp;
mlx4_rx_intr_vec_enable(struct priv *priv)
{
unsigned int i;
- unsigned int rxqs_n = priv->rxqs_n;
+ unsigned int rxqs_n = priv->dev->data->nb_rx_queues;
unsigned int n = RTE_MIN(rxqs_n, (uint32_t)RTE_MAX_RXTX_INTR_VEC_ID);
unsigned int count = 0;
struct rte_intr_handle *intr_handle = &priv->intr_handle;
return -rte_errno;
}
for (i = 0; i != n; ++i) {
- struct rxq *rxq = (*priv->rxqs)[i];
+ struct rxq *rxq = priv->dev->data->rx_queues[i];
/* Skip queues that cannot request interrupts. */
if (!rxq || !rxq->channel) {
int
mlx4_rx_intr_disable(struct rte_eth_dev *dev, uint16_t idx)
{
- struct priv *priv = dev->data->dev_private;
- struct rxq *rxq = (*priv->rxqs)[idx];
+ struct rxq *rxq = dev->data->rx_queues[idx];
struct ibv_cq *ev_cq;
void *ev_ctx;
int ret;
int
mlx4_rx_intr_enable(struct rte_eth_dev *dev, uint16_t idx)
{
- struct priv *priv = dev->data->dev_private;
- struct rxq *rxq = (*priv->rxqs)[idx];
+ struct rxq *rxq = dev->data->rx_queues[idx];
int ret;
if (!rxq || !rxq->channel)
struct rte_mempool *mp)
{
struct priv *priv = dev->data->dev_private;
- struct rxq *rxq = (*priv->rxqs)[idx];
+ struct rxq *rxq = dev->data->rx_queues[idx];
int ret;
DEBUG("%p: configuring queue %u for %u descriptors",
(void *)dev, idx, desc);
- if (idx >= priv->rxqs_n) {
+ if (idx >= dev->data->nb_rx_queues) {
rte_errno = EOVERFLOW;
ERROR("%p: queue index out of range (%u >= %u)",
- (void *)dev, idx, priv->rxqs_n);
+ (void *)dev, idx, dev->data->nb_rx_queues);
return -rte_errno;
}
if (rxq != NULL) {
rte_errno = EEXIST;
return -rte_errno;
}
- (*priv->rxqs)[idx] = NULL;
+ dev->data->rx_queues[idx] = NULL;
if (idx == 0)
mlx4_mac_addr_del(priv);
mlx4_rxq_cleanup(rxq);
rxq->stats.idx = idx;
DEBUG("%p: adding Rx queue %p to list",
(void *)dev, (void *)rxq);
- (*priv->rxqs)[idx] = rxq;
+ dev->data->rx_queues[idx] = rxq;
/* Update receive callback. */
dev->rx_pkt_burst = mlx4_rx_burst;
}
if (rxq == NULL)
return;
priv = rxq->priv;
- for (i = 0; (i != priv->rxqs_n); ++i)
- if ((*priv->rxqs)[i] == rxq) {
+ for (i = 0; i != priv->dev->data->nb_rx_queues; ++i)
+ if (priv->dev->data->rx_queues[i] == rxq) {
DEBUG("%p: removing Rx queue %p from list",
(void *)priv->dev, (void *)rxq);
- (*priv->rxqs)[i] = NULL;
+ priv->dev->data->rx_queues[i] = NULL;
if (i == 0)
mlx4_mac_addr_del(priv);
break;
return 0;
if (priv->isolated)
return 0;
- if (*priv->rxqs && (*priv->rxqs)[0])
- rxq = (*priv->rxqs)[0];
+ if (priv->dev->data->rx_queues && priv->dev->data->rx_queues[0])
+ rxq = priv->dev->data->rx_queues[0];
else
return 0;
unsigned int socket, const struct rte_eth_txconf *conf)
{
struct priv *priv = dev->data->dev_private;
- struct txq *txq = (*priv->txqs)[idx];
+ struct txq *txq = dev->data->tx_queues[idx];
int ret;
DEBUG("%p: configuring queue %u for %u descriptors",
(void *)dev, idx, desc);
- if (idx >= priv->txqs_n) {
+ if (idx >= dev->data->nb_tx_queues) {
rte_errno = EOVERFLOW;
ERROR("%p: queue index out of range (%u >= %u)",
- (void *)dev, idx, priv->txqs_n);
+ (void *)dev, idx, dev->data->nb_tx_queues);
return -rte_errno;
}
if (txq != NULL) {
rte_errno = EEXIST;
return -rte_errno;
}
- (*priv->txqs)[idx] = NULL;
+ dev->data->tx_queues[idx] = NULL;
mlx4_txq_cleanup(txq);
} else {
txq = rte_calloc_socket("TXQ", 1, sizeof(*txq), 0, socket);
txq->stats.idx = idx;
DEBUG("%p: adding Tx queue %p to list",
(void *)dev, (void *)txq);
- (*priv->txqs)[idx] = txq;
+ dev->data->tx_queues[idx] = txq;
/* Update send callback. */
dev->tx_pkt_burst = mlx4_tx_burst;
}
if (txq == NULL)
return;
priv = txq->priv;
- for (i = 0; (i != priv->txqs_n); ++i)
- if ((*priv->txqs)[i] == txq) {
+ for (i = 0; i != priv->dev->data->nb_tx_queues; ++i)
+ if (priv->dev->data->tx_queues[i] == txq) {
DEBUG("%p: removing Tx queue %p from list",
(void *)priv->dev, (void *)txq);
- (*priv->txqs)[i] = NULL;
+ priv->dev->data->tx_queues[i] = NULL;
break;
}
mlx4_txq_cleanup(txq);