/* DPDK headers don't like -pedantic. */
#ifdef PEDANTIC
-#pragma GCC diagnostic ignored "-pedantic"
+#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include <rte_ether.h>
#include <rte_ethdev.h>
+#include <rte_interrupts.h>
+#include <rte_alarm.h>
#ifdef PEDANTIC
-#pragma GCC diagnostic error "-pedantic"
+#pragma GCC diagnostic error "-Wpedantic"
#endif
#include "mlx5.h"
mlx5_dev_start(struct rte_eth_dev *dev)
{
struct priv *priv = dev->data->dev_private;
- unsigned int i = 0;
- unsigned int r;
- struct rxq *rxq;
+ int err;
+
+ if (mlx5_is_secondary())
+ return -E_RTE_SECONDARY;
priv_lock(priv);
if (priv->started) {
priv_unlock(priv);
return 0;
}
- DEBUG("%p: attaching configured flows to all RX queues", (void *)dev);
- priv->started = 1;
- if (priv->rss) {
- rxq = &priv->rxq_parent;
- r = 1;
- } else {
- rxq = (*priv->rxqs)[0];
- r = priv->rxqs_n;
+ DEBUG("%p: allocating and configuring hash RX queues", (void *)dev);
+ err = priv_create_hash_rxqs(priv);
+ if (!err)
+ err = priv_rehash_flows(priv);
+ if (!err)
+ priv->started = 1;
+ else {
+ ERROR("%p: an error occurred while configuring hash RX queues:"
+ " %s",
+ (void *)priv, strerror(err));
+ goto error;
}
- /* Iterate only once when RSS is enabled. */
- do {
- int ret;
-
- /* Ignore nonexistent RX queues. */
- if (rxq == NULL)
- continue;
- ret = rxq_mac_addrs_add(rxq);
- if (!ret)
- continue;
- WARN("%p: QP flow attachment failed: %s",
- (void *)dev, strerror(ret));
- /* Rollback. */
- while (i != 0) {
- rxq = (*priv->rxqs)[--i];
- if (rxq != NULL) {
- rxq_mac_addrs_del(rxq);
- }
- }
+ if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE)
+ priv_fdir_enable(priv);
+ err = priv_flow_start(priv);
+ if (err) {
priv->started = 0;
- priv_unlock(priv);
- return -ret;
- } while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
+ ERROR("%p: an error occurred while configuring flows:"
+ " %s",
+ (void *)priv, strerror(err));
+ goto error;
+ }
+ priv_dev_interrupt_handler_install(priv, dev);
+ if (dev->data->dev_conf.intr_conf.rxq) {
+ err = priv_intr_efd_enable(priv);
+ if (!err)
+ err = priv_create_intr_vec(priv);
+ }
+ priv_xstats_init(priv);
priv_unlock(priv);
return 0;
+error:
+ /* Rollback. */
+ priv_special_flow_disable_all(priv);
+ priv_mac_addrs_disable(priv);
+ priv_destroy_hash_rxqs(priv);
+ priv_flow_stop(priv);
+ priv_unlock(priv);
+ return -err;
}
/**
mlx5_dev_stop(struct rte_eth_dev *dev)
{
struct priv *priv = dev->data->dev_private;
- unsigned int i = 0;
- unsigned int r;
- struct rxq *rxq;
+
+ if (mlx5_is_secondary())
+ return;
priv_lock(priv);
if (!priv->started) {
priv_unlock(priv);
return;
}
- DEBUG("%p: detaching flows from all RX queues", (void *)dev);
- priv->started = 0;
- if (priv->rss) {
- rxq = &priv->rxq_parent;
- r = 1;
- } else {
- rxq = (*priv->rxqs)[0];
- r = priv->rxqs_n;
+ DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev);
+ priv_special_flow_disable_all(priv);
+ priv_mac_addrs_disable(priv);
+ priv_destroy_hash_rxqs(priv);
+ priv_fdir_disable(priv);
+ priv_flow_stop(priv);
+ priv_dev_interrupt_handler_uninstall(priv, dev);
+ if (priv->dev->data->dev_conf.intr_conf.rxq) {
+ priv_destroy_intr_vec(priv);
+ priv_intr_efd_disable(priv);
}
- /* Iterate only once when RSS is enabled. */
- do {
- /* Ignore nonexistent RX queues. */
- if (rxq == NULL)
- continue;
- rxq_mac_addrs_del(rxq);
- } while ((--r) && ((rxq = (*priv->rxqs)[++i]), i));
+ priv->started = 0;
priv_unlock(priv);
}