xref: /dpdk/drivers/net/mlx5/mlx5_trigger.c (revision 1b37f5d898349d70aaf1b8427694ca5b7a669d8f)
1e60fbd5bSAdrien Mazarguil /*-
2e60fbd5bSAdrien Mazarguil  *   BSD LICENSE
3e60fbd5bSAdrien Mazarguil  *
4e60fbd5bSAdrien Mazarguil  *   Copyright 2015 6WIND S.A.
5e60fbd5bSAdrien Mazarguil  *   Copyright 2015 Mellanox.
6e60fbd5bSAdrien Mazarguil  *
7e60fbd5bSAdrien Mazarguil  *   Redistribution and use in source and binary forms, with or without
8e60fbd5bSAdrien Mazarguil  *   modification, are permitted provided that the following conditions
9e60fbd5bSAdrien Mazarguil  *   are met:
10e60fbd5bSAdrien Mazarguil  *
11e60fbd5bSAdrien Mazarguil  *     * Redistributions of source code must retain the above copyright
12e60fbd5bSAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer.
13e60fbd5bSAdrien Mazarguil  *     * Redistributions in binary form must reproduce the above copyright
14e60fbd5bSAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer in
15e60fbd5bSAdrien Mazarguil  *       the documentation and/or other materials provided with the
16e60fbd5bSAdrien Mazarguil  *       distribution.
17e60fbd5bSAdrien Mazarguil  *     * Neither the name of 6WIND S.A. nor the names of its
18e60fbd5bSAdrien Mazarguil  *       contributors may be used to endorse or promote products derived
19e60fbd5bSAdrien Mazarguil  *       from this software without specific prior written permission.
20e60fbd5bSAdrien Mazarguil  *
21e60fbd5bSAdrien Mazarguil  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22e60fbd5bSAdrien Mazarguil  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23e60fbd5bSAdrien Mazarguil  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24e60fbd5bSAdrien Mazarguil  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25e60fbd5bSAdrien Mazarguil  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26e60fbd5bSAdrien Mazarguil  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27e60fbd5bSAdrien Mazarguil  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28e60fbd5bSAdrien Mazarguil  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29e60fbd5bSAdrien Mazarguil  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30e60fbd5bSAdrien Mazarguil  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31e60fbd5bSAdrien Mazarguil  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32e60fbd5bSAdrien Mazarguil  */
333f2fe392SNélio Laranjeiro #include <unistd.h>
34e60fbd5bSAdrien Mazarguil 
35e60fbd5bSAdrien Mazarguil #include <rte_ether.h>
36e60fbd5bSAdrien Mazarguil #include <rte_ethdev.h>
37198a3c33SNelio Laranjeiro #include <rte_interrupts.h>
38198a3c33SNelio Laranjeiro #include <rte_alarm.h>
39e60fbd5bSAdrien Mazarguil 
40e60fbd5bSAdrien Mazarguil #include "mlx5.h"
41e60fbd5bSAdrien Mazarguil #include "mlx5_rxtx.h"
42e60fbd5bSAdrien Mazarguil #include "mlx5_utils.h"
43e60fbd5bSAdrien Mazarguil 
446e78005aSNélio Laranjeiro static void
456e78005aSNélio Laranjeiro priv_txq_stop(struct priv *priv)
466e78005aSNélio Laranjeiro {
476e78005aSNélio Laranjeiro 	unsigned int i;
486e78005aSNélio Laranjeiro 
496e78005aSNélio Laranjeiro 	for (i = 0; i != priv->txqs_n; ++i)
506e78005aSNélio Laranjeiro 		mlx5_priv_txq_release(priv, i);
516e78005aSNélio Laranjeiro }
526e78005aSNélio Laranjeiro 
536e78005aSNélio Laranjeiro static int
546e78005aSNélio Laranjeiro priv_txq_start(struct priv *priv)
556e78005aSNélio Laranjeiro {
566e78005aSNélio Laranjeiro 	unsigned int i;
576e78005aSNélio Laranjeiro 	int ret = 0;
586e78005aSNélio Laranjeiro 
596e78005aSNélio Laranjeiro 	/* Add memory regions to Tx queues. */
606e78005aSNélio Laranjeiro 	for (i = 0; i != priv->txqs_n; ++i) {
616e78005aSNélio Laranjeiro 		unsigned int idx = 0;
626e78005aSNélio Laranjeiro 		struct mlx5_mr *mr;
636e78005aSNélio Laranjeiro 		struct mlx5_txq_ctrl *txq_ctrl = mlx5_priv_txq_get(priv, i);
646e78005aSNélio Laranjeiro 
656e78005aSNélio Laranjeiro 		if (!txq_ctrl)
666e78005aSNélio Laranjeiro 			continue;
676e78005aSNélio Laranjeiro 		LIST_FOREACH(mr, &priv->mr, next)
686e78005aSNélio Laranjeiro 			priv_txq_mp2mr_reg(priv, &txq_ctrl->txq, mr->mp, idx++);
696e78005aSNélio Laranjeiro 		txq_alloc_elts(txq_ctrl);
706e78005aSNélio Laranjeiro 		txq_ctrl->ibv = mlx5_priv_txq_ibv_new(priv, i);
716e78005aSNélio Laranjeiro 		if (!txq_ctrl->ibv) {
726e78005aSNélio Laranjeiro 			ret = ENOMEM;
736e78005aSNélio Laranjeiro 			goto error;
746e78005aSNélio Laranjeiro 		}
756e78005aSNélio Laranjeiro 	}
766e78005aSNélio Laranjeiro 	return -ret;
776e78005aSNélio Laranjeiro error:
786e78005aSNélio Laranjeiro 	priv_txq_stop(priv);
796e78005aSNélio Laranjeiro 	return -ret;
806e78005aSNélio Laranjeiro }
816e78005aSNélio Laranjeiro 
82a1366b1aSNélio Laranjeiro static void
83a1366b1aSNélio Laranjeiro priv_rxq_stop(struct priv *priv)
84a1366b1aSNélio Laranjeiro {
85a1366b1aSNélio Laranjeiro 	unsigned int i;
86a1366b1aSNélio Laranjeiro 
87a1366b1aSNélio Laranjeiro 	for (i = 0; i != priv->rxqs_n; ++i)
88a1366b1aSNélio Laranjeiro 		mlx5_priv_rxq_release(priv, i);
89a1366b1aSNélio Laranjeiro }
90a1366b1aSNélio Laranjeiro 
91a1366b1aSNélio Laranjeiro static int
92a1366b1aSNélio Laranjeiro priv_rxq_start(struct priv *priv)
93a1366b1aSNélio Laranjeiro {
94a1366b1aSNélio Laranjeiro 	unsigned int i;
95a1366b1aSNélio Laranjeiro 	int ret = 0;
96a1366b1aSNélio Laranjeiro 
97a1366b1aSNélio Laranjeiro 	for (i = 0; i != priv->rxqs_n; ++i) {
98a1366b1aSNélio Laranjeiro 		struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_priv_rxq_get(priv, i);
99a1366b1aSNélio Laranjeiro 
100a1366b1aSNélio Laranjeiro 		if (!rxq_ctrl)
101a1366b1aSNélio Laranjeiro 			continue;
102a1366b1aSNélio Laranjeiro 		ret = rxq_alloc_elts(rxq_ctrl);
103a1366b1aSNélio Laranjeiro 		if (ret)
104a1366b1aSNélio Laranjeiro 			goto error;
105a1366b1aSNélio Laranjeiro 		rxq_ctrl->ibv = mlx5_priv_rxq_ibv_new(priv, i);
106a1366b1aSNélio Laranjeiro 		if (!rxq_ctrl->ibv) {
107a1366b1aSNélio Laranjeiro 			ret = ENOMEM;
108a1366b1aSNélio Laranjeiro 			goto error;
109a1366b1aSNélio Laranjeiro 		}
110a1366b1aSNélio Laranjeiro 	}
111a1366b1aSNélio Laranjeiro 	return -ret;
112a1366b1aSNélio Laranjeiro error:
113a1366b1aSNélio Laranjeiro 	priv_rxq_stop(priv);
114a1366b1aSNélio Laranjeiro 	return -ret;
115a1366b1aSNélio Laranjeiro }
116a1366b1aSNélio Laranjeiro 
117e60fbd5bSAdrien Mazarguil /**
118e60fbd5bSAdrien Mazarguil  * DPDK callback to start the device.
119e60fbd5bSAdrien Mazarguil  *
120e60fbd5bSAdrien Mazarguil  * Simulate device start by attaching all configured flows.
121e60fbd5bSAdrien Mazarguil  *
122e60fbd5bSAdrien Mazarguil  * @param dev
123e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
124e60fbd5bSAdrien Mazarguil  *
125e60fbd5bSAdrien Mazarguil  * @return
126e60fbd5bSAdrien Mazarguil  *   0 on success, negative errno value on failure.
127e60fbd5bSAdrien Mazarguil  */
128e60fbd5bSAdrien Mazarguil int
129e60fbd5bSAdrien Mazarguil mlx5_dev_start(struct rte_eth_dev *dev)
130e60fbd5bSAdrien Mazarguil {
131e60fbd5bSAdrien Mazarguil 	struct priv *priv = dev->data->dev_private;
1326e78005aSNélio Laranjeiro 	struct mlx5_mr *mr = NULL;
133ecc1c29dSAdrien Mazarguil 	int err;
134e60fbd5bSAdrien Mazarguil 
135a48deadaSOr Ami 	if (mlx5_is_secondary())
136a48deadaSOr Ami 		return -E_RTE_SECONDARY;
137a48deadaSOr Ami 
138e60fbd5bSAdrien Mazarguil 	priv_lock(priv);
139ecc1c29dSAdrien Mazarguil 	DEBUG("%p: allocating and configuring hash RX queues", (void *)dev);
1406e78005aSNélio Laranjeiro 	rte_mempool_walk(mlx5_mp2mr_iter, priv);
1416e78005aSNélio Laranjeiro 	err = priv_txq_start(priv);
1426e78005aSNélio Laranjeiro 	if (err) {
1436e78005aSNélio Laranjeiro 		ERROR("%p: TXQ allocation failed: %s",
1446e78005aSNélio Laranjeiro 		      (void *)dev, strerror(err));
1456e78005aSNélio Laranjeiro 		goto error;
1466e78005aSNélio Laranjeiro 	}
1476e78005aSNélio Laranjeiro 	/* Update send callback. */
1486e78005aSNélio Laranjeiro 	priv_dev_select_tx_function(priv, dev);
149a1366b1aSNélio Laranjeiro 	err = priv_rxq_start(priv);
150a1366b1aSNélio Laranjeiro 	if (err) {
151a1366b1aSNélio Laranjeiro 		ERROR("%p: RXQ allocation failed: %s",
152a1366b1aSNélio Laranjeiro 		      (void *)dev, strerror(err));
153a1366b1aSNélio Laranjeiro 		goto error;
154a1366b1aSNélio Laranjeiro 	}
155a1366b1aSNélio Laranjeiro 	/* Update receive callback. */
156a1366b1aSNélio Laranjeiro 	priv_dev_select_rx_function(priv, dev);
157ecc1c29dSAdrien Mazarguil 	err = priv_create_hash_rxqs(priv);
158ecc1c29dSAdrien Mazarguil 	if (!err)
159083c2dd3SYaacov Hazan 		err = priv_rehash_flows(priv);
160ecc1c29dSAdrien Mazarguil 	else {
161ecc1c29dSAdrien Mazarguil 		ERROR("%p: an error occurred while configuring hash RX queues:"
162ecc1c29dSAdrien Mazarguil 		      " %s",
163ecc1c29dSAdrien Mazarguil 		      (void *)priv, strerror(err));
164c8d4ee50SNélio Laranjeiro 		goto error;
165c8d4ee50SNélio Laranjeiro 	}
166*1b37f5d8SNélio Laranjeiro 	if (dev->data->promiscuous)
167*1b37f5d8SNélio Laranjeiro 		mlx5_promiscuous_enable(dev);
168*1b37f5d8SNélio Laranjeiro 	err = priv_flow_start(priv, &priv->ctrl_flows);
169*1b37f5d8SNélio Laranjeiro 	if (err) {
170*1b37f5d8SNélio Laranjeiro 		ERROR("%p: an error occurred while configuring control flows:"
171*1b37f5d8SNélio Laranjeiro 		      " %s",
172*1b37f5d8SNélio Laranjeiro 		      (void *)priv, strerror(err));
173*1b37f5d8SNélio Laranjeiro 		goto error;
174*1b37f5d8SNélio Laranjeiro 	}
175*1b37f5d8SNélio Laranjeiro 	err = priv_flow_start(priv, &priv->flows);
176c8d4ee50SNélio Laranjeiro 	if (err) {
177c8d4ee50SNélio Laranjeiro 		ERROR("%p: an error occurred while configuring flows:"
178c8d4ee50SNélio Laranjeiro 		      " %s",
179c8d4ee50SNélio Laranjeiro 		      (void *)priv, strerror(err));
180c8d4ee50SNélio Laranjeiro 		goto error;
181c8d4ee50SNélio Laranjeiro 	}
182e1016cb7SAdrien Mazarguil 	err = priv_rx_intr_vec_enable(priv);
183e1016cb7SAdrien Mazarguil 	if (err) {
184e1016cb7SAdrien Mazarguil 		ERROR("%p: RX interrupt vector creation failed",
185e1016cb7SAdrien Mazarguil 		      (void *)priv);
186e1016cb7SAdrien Mazarguil 		goto error;
1873c7d44afSShahaf Shuler 	}
188e1016cb7SAdrien Mazarguil 	priv_dev_interrupt_handler_install(priv, dev);
189c8d4ee50SNélio Laranjeiro 	priv_xstats_init(priv);
190c8d4ee50SNélio Laranjeiro 	priv_unlock(priv);
191c8d4ee50SNélio Laranjeiro 	return 0;
192c8d4ee50SNélio Laranjeiro error:
193e60fbd5bSAdrien Mazarguil 	/* Rollback. */
1946e78005aSNélio Laranjeiro 	LIST_FOREACH(mr, &priv->mr, next)
1956e78005aSNélio Laranjeiro 		priv_mr_release(priv, mr);
1960d218674SAdrien Mazarguil 	priv_special_flow_disable_all(priv);
197ecc1c29dSAdrien Mazarguil 	priv_mac_addrs_disable(priv);
198ecc1c29dSAdrien Mazarguil 	priv_destroy_hash_rxqs(priv);
199*1b37f5d8SNélio Laranjeiro 	priv_flow_stop(priv, &priv->flows);
200*1b37f5d8SNélio Laranjeiro 	priv_flow_flush(priv, &priv->ctrl_flows);
201a1366b1aSNélio Laranjeiro 	priv_rxq_stop(priv);
2026e78005aSNélio Laranjeiro 	priv_txq_stop(priv);
2035e0fbcf9SYongseok Koh 	priv_unlock(priv);
204ecc1c29dSAdrien Mazarguil 	return -err;
205e60fbd5bSAdrien Mazarguil }
206e60fbd5bSAdrien Mazarguil 
207e60fbd5bSAdrien Mazarguil /**
208e60fbd5bSAdrien Mazarguil  * DPDK callback to stop the device.
209e60fbd5bSAdrien Mazarguil  *
210e60fbd5bSAdrien Mazarguil  * Simulate device stop by detaching all configured flows.
211e60fbd5bSAdrien Mazarguil  *
212e60fbd5bSAdrien Mazarguil  * @param dev
213e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
214e60fbd5bSAdrien Mazarguil  */
215e60fbd5bSAdrien Mazarguil void
216e60fbd5bSAdrien Mazarguil mlx5_dev_stop(struct rte_eth_dev *dev)
217e60fbd5bSAdrien Mazarguil {
218e60fbd5bSAdrien Mazarguil 	struct priv *priv = dev->data->dev_private;
2196e78005aSNélio Laranjeiro 	struct mlx5_mr *mr;
220e60fbd5bSAdrien Mazarguil 
221a48deadaSOr Ami 	if (mlx5_is_secondary())
222a48deadaSOr Ami 		return;
223a48deadaSOr Ami 
224e60fbd5bSAdrien Mazarguil 	priv_lock(priv);
2253f2fe392SNélio Laranjeiro 	dev->data->dev_started = 0;
2263f2fe392SNélio Laranjeiro 	/* Prevent crashes when queues are still in use. */
2273f2fe392SNélio Laranjeiro 	dev->rx_pkt_burst = removed_rx_burst;
2283f2fe392SNélio Laranjeiro 	dev->tx_pkt_burst = removed_tx_burst;
2293f2fe392SNélio Laranjeiro 	rte_wmb();
2303f2fe392SNélio Laranjeiro 	usleep(1000 * priv->rxqs_n);
231ecc1c29dSAdrien Mazarguil 	DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev);
2320d218674SAdrien Mazarguil 	priv_special_flow_disable_all(priv);
233ecc1c29dSAdrien Mazarguil 	priv_mac_addrs_disable(priv);
234ecc1c29dSAdrien Mazarguil 	priv_destroy_hash_rxqs(priv);
235*1b37f5d8SNélio Laranjeiro 	priv_flow_stop(priv, &priv->flows);
236*1b37f5d8SNélio Laranjeiro 	priv_flow_flush(priv, &priv->ctrl_flows);
237e1016cb7SAdrien Mazarguil 	priv_rx_intr_vec_disable(priv);
238*1b37f5d8SNélio Laranjeiro 	priv_dev_interrupt_handler_uninstall(priv, dev);
2396e78005aSNélio Laranjeiro 	priv_txq_stop(priv);
240a1366b1aSNélio Laranjeiro 	priv_rxq_stop(priv);
2416e78005aSNélio Laranjeiro 	LIST_FOREACH(mr, &priv->mr, next) {
2426e78005aSNélio Laranjeiro 		priv_mr_release(priv, mr);
2436e78005aSNélio Laranjeiro 	}
244e60fbd5bSAdrien Mazarguil 	priv_unlock(priv);
245e60fbd5bSAdrien Mazarguil }
246