xref: /dpdk/drivers/net/mlx5/mlx5_ethdev.c (revision 3ef18940ef13fe8cb307aba0dba2bc316fb873a2)
18fd92a66SOlivier Matz /* SPDX-License-Identifier: BSD-3-Clause
2771fa900SAdrien Mazarguil  * Copyright 2015 6WIND S.A.
35feecc57SShahaf Shuler  * Copyright 2015 Mellanox Technologies, Ltd
4771fa900SAdrien Mazarguil  */
5771fa900SAdrien Mazarguil 
6771fa900SAdrien Mazarguil #include <stddef.h>
7771fa900SAdrien Mazarguil #include <unistd.h>
8771fa900SAdrien Mazarguil #include <string.h>
91256805dSOphir Munk #include <stdint.h>
10771fa900SAdrien Mazarguil #include <stdlib.h>
11771fa900SAdrien Mazarguil #include <errno.h>
12771fa900SAdrien Mazarguil 
13df96fd0dSBruce Richardson #include <ethdev_driver.h>
14c752998bSGaetan Rivet #include <rte_bus_pci.h>
15771fa900SAdrien Mazarguil #include <rte_mbuf.h>
16771fa900SAdrien Mazarguil #include <rte_common.h>
17198a3c33SNelio Laranjeiro #include <rte_interrupts.h>
18a48deadaSOr Ami #include <rte_malloc.h>
19c022cb40SBruce Richardson #include <rte_string_fns.h>
20974f1e7eSYongseok Koh #include <rte_rwlock.h>
215897ac13SViacheslav Ovsiienko #include <rte_cycles.h>
22771fa900SAdrien Mazarguil 
2383c2047cSSuanming Mou #include <mlx5_malloc.h>
2483c2047cSSuanming Mou 
25e60fbd5bSAdrien Mazarguil #include "mlx5_rxtx.h"
26151cbe3aSMichael Baum #include "mlx5_rx.h"
27377b69fbSMichael Baum #include "mlx5_tx.h"
281256805dSOphir Munk #include "mlx5_autoconf.h"
2909c25553SXueming Li #include "mlx5_devx.h"
3080f872eeSMichael Baum #include "rte_pmd_mlx5.h"
312b730263SAdrien Mazarguil 
322b730263SAdrien Mazarguil /**
33ccdcba53SNélio Laranjeiro  * Get the interface index from device name.
34ccdcba53SNélio Laranjeiro  *
35ccdcba53SNélio Laranjeiro  * @param[in] dev
36ccdcba53SNélio Laranjeiro  *   Pointer to Ethernet device.
37ccdcba53SNélio Laranjeiro  *
38ccdcba53SNélio Laranjeiro  * @return
393f8cb05dSAdrien Mazarguil  *   Nonzero interface index on success, zero otherwise and rte_errno is set.
40ccdcba53SNélio Laranjeiro  */
413f8cb05dSAdrien Mazarguil unsigned int
42ccdcba53SNélio Laranjeiro mlx5_ifindex(const struct rte_eth_dev *dev)
43ccdcba53SNélio Laranjeiro {
44fa2e14d4SViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
453f8cb05dSAdrien Mazarguil 	unsigned int ifindex;
46ccdcba53SNélio Laranjeiro 
478e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv);
488e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv->if_index);
49f5f4c482SXueming Li 	if (priv->master && priv->sh->bond.ifindex > 0)
50f5f4c482SXueming Li 		ifindex = priv->sh->bond.ifindex;
51f5f4c482SXueming Li 	else
52f5f4c482SXueming Li 		ifindex = priv->if_index;
533f8cb05dSAdrien Mazarguil 	if (!ifindex)
54fa2e14d4SViacheslav Ovsiienko 		rte_errno = ENXIO;
553f8cb05dSAdrien Mazarguil 	return ifindex;
56ccdcba53SNélio Laranjeiro }
57ccdcba53SNélio Laranjeiro 
58ccdcba53SNélio Laranjeiro /**
597b2423cdSNélio Laranjeiro  * DPDK callback for Ethernet device configuration.
60e60fbd5bSAdrien Mazarguil  *
61e60fbd5bSAdrien Mazarguil  * @param dev
62e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
63e60fbd5bSAdrien Mazarguil  *
64e60fbd5bSAdrien Mazarguil  * @return
65a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
66e60fbd5bSAdrien Mazarguil  */
677b2423cdSNélio Laranjeiro int
687b2423cdSNélio Laranjeiro mlx5_dev_configure(struct rte_eth_dev *dev)
69e60fbd5bSAdrien Mazarguil {
70dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
71e60fbd5bSAdrien Mazarguil 	unsigned int rxqs_n = dev->data->nb_rx_queues;
72e60fbd5bSAdrien Mazarguil 	unsigned int txqs_n = dev->data->nb_tx_queues;
7329c1d8bbSNélio Laranjeiro 	const uint8_t use_app_rss_key =
7421e3a974SShahaf Shuler 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
75a6d83b6aSNélio Laranjeiro 	int ret = 0;
76e60fbd5bSAdrien Mazarguil 
7729c1d8bbSNélio Laranjeiro 	if (use_app_rss_key &&
7829c1d8bbSNélio Laranjeiro 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
79c388a2f6SNelio Laranjeiro 	     MLX5_RSS_HASH_KEY_LEN)) {
80c388a2f6SNelio Laranjeiro 		DRV_LOG(ERR, "port %u RSS key len must be %s Bytes long",
81c388a2f6SNelio Laranjeiro 			dev->data->port_id, RTE_STR(MLX5_RSS_HASH_KEY_LEN));
82a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
83a6d83b6aSNélio Laranjeiro 		return -rte_errno;
8429c1d8bbSNélio Laranjeiro 	}
8580f872eeSMichael Baum 	priv->rss_conf.rss_key = mlx5_realloc(priv->rss_conf.rss_key,
8680f872eeSMichael Baum 					      MLX5_MEM_RTE,
8780f872eeSMichael Baum 					      MLX5_RSS_HASH_KEY_LEN, 0,
8880f872eeSMichael Baum 					      SOCKET_ID_ANY);
8929c1d8bbSNélio Laranjeiro 	if (!priv->rss_conf.rss_key) {
90a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory (%u)",
910f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
92a6d83b6aSNélio Laranjeiro 		rte_errno = ENOMEM;
93a6d83b6aSNélio Laranjeiro 		return -rte_errno;
9429c1d8bbSNélio Laranjeiro 	}
958b945a7fSPavan Nikhilesh 
96af270529SThomas Monjalon 	if ((dev->data->dev_conf.txmode.offloads &
97295968d1SFerruh Yigit 			RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) &&
98af270529SThomas Monjalon 			rte_mbuf_dyn_tx_timestamp_register(NULL, NULL) != 0) {
99af270529SThomas Monjalon 		DRV_LOG(ERR, "port %u cannot register Tx timestamp field/flag",
100af270529SThomas Monjalon 			dev->data->port_id);
101af270529SThomas Monjalon 		return -rte_errno;
102af270529SThomas Monjalon 	}
10329c1d8bbSNélio Laranjeiro 	memcpy(priv->rss_conf.rss_key,
10429c1d8bbSNélio Laranjeiro 	       use_app_rss_key ?
10529c1d8bbSNélio Laranjeiro 	       dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key :
10629c1d8bbSNélio Laranjeiro 	       rss_hash_default_key,
107c388a2f6SNelio Laranjeiro 	       MLX5_RSS_HASH_KEY_LEN);
108c388a2f6SNelio Laranjeiro 	priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN;
10929c1d8bbSNélio Laranjeiro 	priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
1104cda06c3SXueming Li 	priv->rxq_privs = mlx5_realloc(priv->rxq_privs,
1114cda06c3SXueming Li 				       MLX5_MEM_RTE | MLX5_MEM_ZERO,
1124cda06c3SXueming Li 				       sizeof(void *) * rxqs_n, 0,
1134cda06c3SXueming Li 				       SOCKET_ID_ANY);
114*3ef18940SBing Zhao 	if (rxqs_n && priv->rxq_privs == NULL) {
1154cda06c3SXueming Li 		DRV_LOG(ERR, "port %u cannot allocate rxq private data",
1164cda06c3SXueming Li 			dev->data->port_id);
1174cda06c3SXueming Li 		rte_errno = ENOMEM;
1184cda06c3SXueming Li 		return -rte_errno;
1194cda06c3SXueming Li 	}
120e60fbd5bSAdrien Mazarguil 	priv->txqs = (void *)dev->data->tx_queues;
121e60fbd5bSAdrien Mazarguil 	if (txqs_n != priv->txqs_n) {
122a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Tx queues number update: %u -> %u",
1230f99970bSNélio Laranjeiro 			dev->data->port_id, priv->txqs_n, txqs_n);
124e60fbd5bSAdrien Mazarguil 		priv->txqs_n = txqs_n;
125e60fbd5bSAdrien Mazarguil 	}
12687af0d1eSMichael Baum 	if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) {
127a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
1280f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
129a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
130a6d83b6aSNélio Laranjeiro 		return -rte_errno;
131634efbc2SNelio Laranjeiro 	}
13280f872eeSMichael Baum 	if (priv->ext_rxqs && rxqs_n >= MLX5_EXTERNAL_RX_QUEUE_ID_MIN) {
13380f872eeSMichael Baum 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u), "
13480f872eeSMichael Baum 			"the maximal number of internal Rx queues is %u",
13580f872eeSMichael Baum 			dev->data->port_id, rxqs_n,
13680f872eeSMichael Baum 			MLX5_EXTERNAL_RX_QUEUE_ID_MIN - 1);
13780f872eeSMichael Baum 		rte_errno = EINVAL;
13880f872eeSMichael Baum 		return -rte_errno;
13980f872eeSMichael Baum 	}
14009ba4c58SDekel Peled 	if (rxqs_n != priv->rxqs_n) {
141a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
1420f99970bSNélio Laranjeiro 			dev->data->port_id, priv->rxqs_n, rxqs_n);
143e60fbd5bSAdrien Mazarguil 		priv->rxqs_n = rxqs_n;
14463bd1629SOri Kam 	}
14563bd1629SOri Kam 	priv->skip_default_rss_reta = 0;
14663bd1629SOri Kam 	ret = mlx5_proc_priv_init(dev);
14763bd1629SOri Kam 	if (ret)
14863bd1629SOri Kam 		return ret;
14963bd1629SOri Kam 	return 0;
15063bd1629SOri Kam }
15163bd1629SOri Kam 
15263bd1629SOri Kam /**
15363bd1629SOri Kam  * Configure default RSS reta.
15463bd1629SOri Kam  *
15563bd1629SOri Kam  * @param dev
15663bd1629SOri Kam  *   Pointer to Ethernet device structure.
15763bd1629SOri Kam  *
15863bd1629SOri Kam  * @return
15963bd1629SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
16063bd1629SOri Kam  */
16163bd1629SOri Kam int
16263bd1629SOri Kam mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
16363bd1629SOri Kam {
16463bd1629SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
16563bd1629SOri Kam 	unsigned int rxqs_n = dev->data->nb_rx_queues;
16663bd1629SOri Kam 	unsigned int i;
16763bd1629SOri Kam 	unsigned int j;
16863bd1629SOri Kam 	unsigned int reta_idx_n;
16963bd1629SOri Kam 	int ret = 0;
17063bd1629SOri Kam 	unsigned int *rss_queue_arr = NULL;
17163bd1629SOri Kam 	unsigned int rss_queue_n = 0;
17263bd1629SOri Kam 
17363bd1629SOri Kam 	if (priv->skip_default_rss_reta)
17463bd1629SOri Kam 		return ret;
17583c2047cSSuanming Mou 	rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0,
17683c2047cSSuanming Mou 				    SOCKET_ID_ANY);
17763bd1629SOri Kam 	if (!rss_queue_arr) {
17863bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)",
17963bd1629SOri Kam 			dev->data->port_id, rxqs_n);
18063bd1629SOri Kam 		rte_errno = ENOMEM;
18163bd1629SOri Kam 		return -rte_errno;
18263bd1629SOri Kam 	}
18363bd1629SOri Kam 	for (i = 0, j = 0; i < rxqs_n; i++) {
1845cf0707fSXueming Li 		struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, i);
18563bd1629SOri Kam 
186c06f77aeSMichael Baum 		if (rxq_ctrl && !rxq_ctrl->is_hairpin)
18763bd1629SOri Kam 			rss_queue_arr[j++] = i;
18863bd1629SOri Kam 	}
18963bd1629SOri Kam 	rss_queue_n = j;
19087af0d1eSMichael Baum 	if (rss_queue_n > priv->sh->dev_cap.ind_table_max_size) {
19163bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
19263bd1629SOri Kam 			dev->data->port_id, rss_queue_n);
19363bd1629SOri Kam 		rte_errno = EINVAL;
19483c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
19563bd1629SOri Kam 		return -rte_errno;
19663bd1629SOri Kam 	}
19763bd1629SOri Kam 	DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
19863bd1629SOri Kam 		dev->data->port_id, priv->rxqs_n, rxqs_n);
19963bd1629SOri Kam 	priv->rxqs_n = rxqs_n;
20009ba4c58SDekel Peled 	/*
20109ba4c58SDekel Peled 	 * If the requested number of RX queues is not a power of two,
20209ba4c58SDekel Peled 	 * use the maximum indirection table size for better balancing.
20309ba4c58SDekel Peled 	 * The result is always rounded to the next power of two.
20409ba4c58SDekel Peled 	 */
20563bd1629SOri Kam 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
20687af0d1eSMichael Baum 				     priv->sh->dev_cap.ind_table_max_size :
20763bd1629SOri Kam 				     rss_queue_n));
208a6d83b6aSNélio Laranjeiro 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
20963bd1629SOri Kam 	if (ret) {
21083c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
211a6d83b6aSNélio Laranjeiro 		return ret;
21263bd1629SOri Kam 	}
21309ba4c58SDekel Peled 	/*
21409ba4c58SDekel Peled 	 * When the number of RX queues is not a power of two,
21509ba4c58SDekel Peled 	 * the remaining table entries are padded with reused WQs
21609ba4c58SDekel Peled 	 * and hashes are not spread uniformly.
21709ba4c58SDekel Peled 	 */
218634efbc2SNelio Laranjeiro 	for (i = 0, j = 0; (i != reta_idx_n); ++i) {
21963bd1629SOri Kam 		(*priv->reta_idx)[i] = rss_queue_arr[j];
22063bd1629SOri Kam 		if (++j == rss_queue_n)
221634efbc2SNelio Laranjeiro 			j = 0;
222634efbc2SNelio Laranjeiro 	}
22383c2047cSSuanming Mou 	mlx5_free(rss_queue_arr);
224120dc4a7SYongseok Koh 	return ret;
225e60fbd5bSAdrien Mazarguil }
226e60fbd5bSAdrien Mazarguil 
227e60fbd5bSAdrien Mazarguil /**
228d11d651fSShahaf Shuler  * Sets default tuning parameters.
229d11d651fSShahaf Shuler  *
230d11d651fSShahaf Shuler  * @param dev
231d11d651fSShahaf Shuler  *   Pointer to Ethernet device.
232d11d651fSShahaf Shuler  * @param[out] info
233d11d651fSShahaf Shuler  *   Info structure output buffer.
234d11d651fSShahaf Shuler  */
235d11d651fSShahaf Shuler static void
236d11d651fSShahaf Shuler mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
237d11d651fSShahaf Shuler {
238dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
239d11d651fSShahaf Shuler 
240d11d651fSShahaf Shuler 	/* Minimum CPU utilization. */
241d11d651fSShahaf Shuler 	info->default_rxportconf.ring_size = 256;
242d11d651fSShahaf Shuler 	info->default_txportconf.ring_size = 256;
243f078ceb6SViacheslav Ovsiienko 	info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST;
244f078ceb6SViacheslav Ovsiienko 	info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST;
245295968d1SFerruh Yigit 	if ((priv->link_speed_capa & RTE_ETH_LINK_SPEED_200G) |
246295968d1SFerruh Yigit 		(priv->link_speed_capa & RTE_ETH_LINK_SPEED_100G)) {
247d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 16;
248d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 16;
249d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
250d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
251d11d651fSShahaf Shuler 			/* Max Throughput. */
252d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 2048;
253d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 2048;
254d11d651fSShahaf Shuler 		}
255d11d651fSShahaf Shuler 	} else {
256d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 8;
257d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 8;
258d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
259d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
260d11d651fSShahaf Shuler 			/* Max Throughput. */
261d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 4096;
262d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 4096;
263d11d651fSShahaf Shuler 		}
264d11d651fSShahaf Shuler 	}
265d11d651fSShahaf Shuler }
266d11d651fSShahaf Shuler 
267d11d651fSShahaf Shuler /**
268cb9cb61eSViacheslav Ovsiienko  * Sets tx mbuf limiting parameters.
269cb9cb61eSViacheslav Ovsiienko  *
270cb9cb61eSViacheslav Ovsiienko  * @param dev
271cb9cb61eSViacheslav Ovsiienko  *   Pointer to Ethernet device.
272cb9cb61eSViacheslav Ovsiienko  * @param[out] info
273cb9cb61eSViacheslav Ovsiienko  *   Info structure output buffer.
274cb9cb61eSViacheslav Ovsiienko  */
275cb9cb61eSViacheslav Ovsiienko static void
276cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
277cb9cb61eSViacheslav Ovsiienko {
278cb9cb61eSViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
27945a6df80SMichael Baum 	struct mlx5_port_config *config = &priv->config;
280cb9cb61eSViacheslav Ovsiienko 	unsigned int inlen;
281cb9cb61eSViacheslav Ovsiienko 	uint16_t nb_max;
282cb9cb61eSViacheslav Ovsiienko 
283cb9cb61eSViacheslav Ovsiienko 	inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ?
284cb9cb61eSViacheslav Ovsiienko 		MLX5_SEND_DEF_INLINE_LEN :
285cb9cb61eSViacheslav Ovsiienko 		(unsigned int)config->txq_inline_max;
2868e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(config->txq_inline_min >= 0);
287cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min);
288cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX +
289cb9cb61eSViacheslav Ovsiienko 			       MLX5_ESEG_MIN_INLINE_SIZE -
290cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_CSEG_SIZE -
291cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_ESEG_SIZE -
292cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_DSEG_SIZE * 2);
293cb9cb61eSViacheslav Ovsiienko 	nb_max = (MLX5_WQE_SIZE_MAX +
294cb9cb61eSViacheslav Ovsiienko 		  MLX5_ESEG_MIN_INLINE_SIZE -
295cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_CSEG_SIZE -
296cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_ESEG_SIZE -
297cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_DSEG_SIZE -
298cb9cb61eSViacheslav Ovsiienko 		  inlen) / MLX5_WSEG_SIZE;
299cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_seg_max = nb_max;
300cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_mtu_seg_max = nb_max;
301cb9cb61eSViacheslav Ovsiienko }
302cb9cb61eSViacheslav Ovsiienko 
303cb9cb61eSViacheslav Ovsiienko /**
304e60fbd5bSAdrien Mazarguil  * DPDK callback to get information about the device.
305e60fbd5bSAdrien Mazarguil  *
306e60fbd5bSAdrien Mazarguil  * @param dev
307e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
308e60fbd5bSAdrien Mazarguil  * @param[out] info
309e60fbd5bSAdrien Mazarguil  *   Info structure output buffer.
310e60fbd5bSAdrien Mazarguil  */
311bdad90d1SIvan Ilchenko int
312e60fbd5bSAdrien Mazarguil mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
313e60fbd5bSAdrien Mazarguil {
314dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
315e60fbd5bSAdrien Mazarguil 	unsigned int max;
316e60fbd5bSAdrien Mazarguil 
317e60fbd5bSAdrien Mazarguil 	/* FIXME: we should ask the device for these values. */
318e60fbd5bSAdrien Mazarguil 	info->min_rx_bufsize = 32;
319e60fbd5bSAdrien Mazarguil 	info->max_rx_pktlen = 65536;
3201c7e57f9SDekel Peled 	info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE;
321e60fbd5bSAdrien Mazarguil 	/*
322e60fbd5bSAdrien Mazarguil 	 * Since we need one CQ per QP, the limit is the minimum number
323e60fbd5bSAdrien Mazarguil 	 * between the two values.
324e60fbd5bSAdrien Mazarguil 	 */
32591d1cfafSMichael Baum 	max = RTE_MIN(priv->sh->dev_cap.max_cq, priv->sh->dev_cap.max_qp);
326b689a781SThomas Monjalon 	/* max_rx_queues is uint16_t. */
327b689a781SThomas Monjalon 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
328e60fbd5bSAdrien Mazarguil 	info->max_rx_queues = max;
329e60fbd5bSAdrien Mazarguil 	info->max_tx_queues = max;
33018c01b98SNélio Laranjeiro 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
331af4f09f2SNélio Laranjeiro 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
3326c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
33345a6df80SMichael Baum 	info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled;
33445a6df80SMichael Baum 	info->rx_seg_capa.offset_allowed = !priv->config.mprq.enabled;
3356c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.offset_align_log2 = 0;
33617ed314cSMatan Azrad 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
33717b843ebSShahaf Shuler 				 info->rx_queue_offload_capa);
338af4f09f2SNélio Laranjeiro 	info->tx_offload_capa = mlx5_get_tx_port_offloads(dev);
339ec4e11d4SDmitry Kozlyuk 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
340fa2e14d4SViacheslav Ovsiienko 	info->if_index = mlx5_ifindex(dev);
341d365210eSYongseok Koh 	info->reta_size = priv->reta_idx_n ?
34287af0d1eSMichael Baum 		priv->reta_idx_n : priv->sh->dev_cap.ind_table_max_size;
343c388a2f6SNelio Laranjeiro 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
34475ef62a9SNélio Laranjeiro 	info->speed_capa = priv->link_speed_capa;
345b233b027SShahaf Shuler 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
346d11d651fSShahaf Shuler 	mlx5_set_default_params(dev, info);
347cb9cb61eSViacheslav Ovsiienko 	mlx5_set_txlimit_params(dev, info);
34853820561SMichael Baum 	if (priv->sh->cdev->config.hca_attr.mem_rq_rmp &&
34909c25553SXueming Li 	    priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new)
35009c25553SXueming Li 		info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE;
3512b730263SAdrien Mazarguil 	info->switch_info.name = dev->data->name;
3522b730263SAdrien Mazarguil 	info->switch_info.domain_id = priv->domain_id;
3532b730263SAdrien Mazarguil 	info->switch_info.port_id = priv->representor_id;
35409c25553SXueming Li 	info->switch_info.rx_domain = 0; /* No sub Rx domains. */
3552b730263SAdrien Mazarguil 	if (priv->representor) {
356f7e95215SViacheslav Ovsiienko 		uint16_t port_id;
3572b730263SAdrien Mazarguil 
35856bb3c84SXueming Li 		MLX5_ETH_FOREACH_DEV(port_id, dev->device) {
359dbeba4cfSThomas Monjalon 			struct mlx5_priv *opriv =
360f7e95215SViacheslav Ovsiienko 				rte_eth_devices[port_id].data->dev_private;
3612b730263SAdrien Mazarguil 
3622b730263SAdrien Mazarguil 			if (!opriv ||
3632b730263SAdrien Mazarguil 			    opriv->representor ||
364f7e95215SViacheslav Ovsiienko 			    opriv->sh != priv->sh ||
3652b730263SAdrien Mazarguil 			    opriv->domain_id != priv->domain_id)
3662b730263SAdrien Mazarguil 				continue;
3672b730263SAdrien Mazarguil 			/*
3682b730263SAdrien Mazarguil 			 * Override switch name with that of the master
3692b730263SAdrien Mazarguil 			 * device.
3702b730263SAdrien Mazarguil 			 */
3712b730263SAdrien Mazarguil 			info->switch_info.name = opriv->dev_data->name;
3722b730263SAdrien Mazarguil 			break;
3732b730263SAdrien Mazarguil 		}
3742b730263SAdrien Mazarguil 	}
375bdad90d1SIvan Ilchenko 	return 0;
376e60fbd5bSAdrien Mazarguil }
377e60fbd5bSAdrien Mazarguil 
378fb732b0aSNélio Laranjeiro /**
379cb95feefSXueming Li  * Calculate representor ID from port switch info.
380cb95feefSXueming Li  *
381cb95feefSXueming Li  * Uint16 representor ID bits definition:
382cb95feefSXueming Li  *   pf: 2
383cb95feefSXueming Li  *   type: 2
384cb95feefSXueming Li  *   vf/sf: 12
385cb95feefSXueming Li  *
386cb95feefSXueming Li  * @param info
387cb95feefSXueming Li  *   Port switch info.
38891766faeSXueming Li  * @param hpf_type
38991766faeSXueming Li  *   Use this type if port is HPF.
390cb95feefSXueming Li  *
391cb95feefSXueming Li  * @return
392cb95feefSXueming Li  *   Encoded representor ID.
393cb95feefSXueming Li  */
394cb95feefSXueming Li uint16_t
39591766faeSXueming Li mlx5_representor_id_encode(const struct mlx5_switch_info *info,
39691766faeSXueming Li 			   enum rte_eth_representor_type hpf_type)
397cb95feefSXueming Li {
398cb95feefSXueming Li 	enum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF;
399cb95feefSXueming Li 	uint16_t repr = info->port_name;
400cb95feefSXueming Li 
401cb95feefSXueming Li 	if (info->representor == 0)
402cb95feefSXueming Li 		return UINT16_MAX;
403cb95feefSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF)
404cb95feefSXueming Li 		type = RTE_ETH_REPRESENTOR_SF;
40591766faeSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) {
40691766faeSXueming Li 		type = hpf_type;
407cb95feefSXueming Li 		repr = UINT16_MAX;
40891766faeSXueming Li 	}
409cb95feefSXueming Li 	return MLX5_REPRESENTOR_ID(info->pf_num, type, repr);
410cb95feefSXueming Li }
411cb95feefSXueming Li 
412cb95feefSXueming Li /**
413cb95feefSXueming Li  * DPDK callback to get information about representor.
414cb95feefSXueming Li  *
415cb95feefSXueming Li  * Representor ID bits definition:
416cb95feefSXueming Li  *   vf/sf: 12
417cb95feefSXueming Li  *   type: 2
418cb95feefSXueming Li  *   pf: 2
419cb95feefSXueming Li  *
420cb95feefSXueming Li  * @param dev
421cb95feefSXueming Li  *   Pointer to Ethernet device structure.
422cb95feefSXueming Li  * @param[out] info
423cb95feefSXueming Li  *   Nullable info structure output buffer.
424cb95feefSXueming Li  *
425cb95feefSXueming Li  * @return
426cb95feefSXueming Li  *   negative on error, or the number of representor ranges.
427cb95feefSXueming Li  */
428cb95feefSXueming Li int
429cb95feefSXueming Li mlx5_representor_info_get(struct rte_eth_dev *dev,
430cb95feefSXueming Li 			  struct rte_eth_representor_info *info)
431cb95feefSXueming Li {
432cb95feefSXueming Li 	struct mlx5_priv *priv = dev->data->dev_private;
43391766faeSXueming Li 	int n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */
434cb95feefSXueming Li 	int n_pf = 2; /* Number of PFs. */
435cb95feefSXueming Li 	int i = 0, pf;
43610eaf41dSViacheslav Galaktionov 	int n_entries;
437cb95feefSXueming Li 
438cb95feefSXueming Li 	if (info == NULL)
439cb95feefSXueming Li 		goto out;
44010eaf41dSViacheslav Galaktionov 
44110eaf41dSViacheslav Galaktionov 	n_entries = n_type * n_pf;
44210eaf41dSViacheslav Galaktionov 	if ((uint32_t)n_entries > info->nb_ranges_alloc)
44310eaf41dSViacheslav Galaktionov 		n_entries = info->nb_ranges_alloc;
44410eaf41dSViacheslav Galaktionov 
445cb95feefSXueming Li 	info->controller = 0;
446cb95feefSXueming Li 	info->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0;
447cb95feefSXueming Li 	for (pf = 0; pf < n_pf; ++pf) {
448cb95feefSXueming Li 		/* VF range. */
449cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
450cb95feefSXueming Li 		info->ranges[i].controller = 0;
451cb95feefSXueming Li 		info->ranges[i].pf = pf;
452cb95feefSXueming Li 		info->ranges[i].vf = 0;
453cb95feefSXueming Li 		info->ranges[i].id_base =
454cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
455cb95feefSXueming Li 		info->ranges[i].id_end =
456cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
457cb95feefSXueming Li 		snprintf(info->ranges[i].name,
458cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
459cb95feefSXueming Li 		i++;
46010eaf41dSViacheslav Galaktionov 		if (i == n_entries)
46110eaf41dSViacheslav Galaktionov 			break;
46291766faeSXueming Li 		/* HPF range of VF type. */
463cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
464cb95feefSXueming Li 		info->ranges[i].controller = 0;
465cb95feefSXueming Li 		info->ranges[i].pf = pf;
466cb95feefSXueming Li 		info->ranges[i].vf = UINT16_MAX;
467cb95feefSXueming Li 		info->ranges[i].id_base =
468cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
469cb95feefSXueming Li 		info->ranges[i].id_end =
470cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
471cb95feefSXueming Li 		snprintf(info->ranges[i].name,
472cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
473cb95feefSXueming Li 		i++;
47410eaf41dSViacheslav Galaktionov 		if (i == n_entries)
47510eaf41dSViacheslav Galaktionov 			break;
476cb95feefSXueming Li 		/* SF range. */
477cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
478cb95feefSXueming Li 		info->ranges[i].controller = 0;
479cb95feefSXueming Li 		info->ranges[i].pf = pf;
480cb95feefSXueming Li 		info->ranges[i].vf = 0;
481cb95feefSXueming Li 		info->ranges[i].id_base =
482cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
483cb95feefSXueming Li 		info->ranges[i].id_end =
484cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
485cb95feefSXueming Li 		snprintf(info->ranges[i].name,
486cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
487cb95feefSXueming Li 		i++;
48810eaf41dSViacheslav Galaktionov 		if (i == n_entries)
48910eaf41dSViacheslav Galaktionov 			break;
49091766faeSXueming Li 		/* HPF range of SF type. */
49191766faeSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
49291766faeSXueming Li 		info->ranges[i].controller = 0;
49391766faeSXueming Li 		info->ranges[i].pf = pf;
49491766faeSXueming Li 		info->ranges[i].vf = UINT16_MAX;
49591766faeSXueming Li 		info->ranges[i].id_base =
49691766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
49791766faeSXueming Li 		info->ranges[i].id_end =
49891766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
49991766faeSXueming Li 		snprintf(info->ranges[i].name,
50091766faeSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
50191766faeSXueming Li 		i++;
50210eaf41dSViacheslav Galaktionov 		if (i == n_entries)
50310eaf41dSViacheslav Galaktionov 			break;
504cb95feefSXueming Li 	}
50510eaf41dSViacheslav Galaktionov 	info->nb_ranges = i;
506cb95feefSXueming Li out:
507cb95feefSXueming Li 	return n_type * n_pf;
508cb95feefSXueming Li }
509cb95feefSXueming Li 
510cb95feefSXueming Li /**
511714bf46eSThomas Monjalon  * Get firmware version of a device.
512714bf46eSThomas Monjalon  *
513714bf46eSThomas Monjalon  * @param dev
514714bf46eSThomas Monjalon  *   Ethernet device port.
515714bf46eSThomas Monjalon  * @param fw_ver
516714bf46eSThomas Monjalon  *   String output allocated by caller.
517714bf46eSThomas Monjalon  * @param fw_size
518714bf46eSThomas Monjalon  *   Size of the output string, including terminating null byte.
519714bf46eSThomas Monjalon  *
520714bf46eSThomas Monjalon  * @return
521714bf46eSThomas Monjalon  *   0 on success, or the size of the non truncated string if too big.
522714bf46eSThomas Monjalon  */
5231256805dSOphir Munk int
5241256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
525714bf46eSThomas Monjalon {
526dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
52791d1cfafSMichael Baum 	struct mlx5_dev_cap *attr = &priv->sh->dev_cap;
528714bf46eSThomas Monjalon 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
529714bf46eSThomas Monjalon 
530714bf46eSThomas Monjalon 	if (fw_size < size)
531714bf46eSThomas Monjalon 		return size;
532714bf46eSThomas Monjalon 	if (fw_ver != NULL)
533714bf46eSThomas Monjalon 		strlcpy(fw_ver, attr->fw_ver, fw_size);
534714bf46eSThomas Monjalon 	return 0;
535714bf46eSThomas Monjalon }
536714bf46eSThomas Monjalon 
537714bf46eSThomas Monjalon /**
538fb732b0aSNélio Laranjeiro  * Get supported packet types.
539fb732b0aSNélio Laranjeiro  *
540fb732b0aSNélio Laranjeiro  * @param dev
541fb732b0aSNélio Laranjeiro  *   Pointer to Ethernet device structure.
542fb732b0aSNélio Laranjeiro  *
543fb732b0aSNélio Laranjeiro  * @return
544fb732b0aSNélio Laranjeiro  *   A pointer to the supported Packet types array.
545fb732b0aSNélio Laranjeiro  */
54678a38edfSJianfeng Tan const uint32_t *
54778a38edfSJianfeng Tan mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
54878a38edfSJianfeng Tan {
54978a38edfSJianfeng Tan 	static const uint32_t ptypes[] = {
55078a38edfSJianfeng Tan 		/* refers to rxq_cq_to_pkt_type() */
551ea16068cSYongseok Koh 		RTE_PTYPE_L2_ETHER,
552c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
553c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
554ea16068cSYongseok Koh 		RTE_PTYPE_L4_NONFRAG,
555ea16068cSYongseok Koh 		RTE_PTYPE_L4_FRAG,
556ea16068cSYongseok Koh 		RTE_PTYPE_L4_TCP,
557ea16068cSYongseok Koh 		RTE_PTYPE_L4_UDP,
558c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
559c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
560ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_NONFRAG,
561ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_FRAG,
562ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_TCP,
563ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_UDP,
56478a38edfSJianfeng Tan 		RTE_PTYPE_UNKNOWN
56578a38edfSJianfeng Tan 	};
56678a38edfSJianfeng Tan 
5676cb559d6SYongseok Koh 	if (dev->rx_pkt_burst == mlx5_rx_burst ||
5687d6bf6b8SYongseok Koh 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq ||
5690f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_vec ||
5700f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec)
57178a38edfSJianfeng Tan 		return ptypes;
57278a38edfSJianfeng Tan 	return NULL;
57378a38edfSJianfeng Tan }
57478a38edfSJianfeng Tan 
575e60fbd5bSAdrien Mazarguil /**
576cf37ca95SAdrien Mazarguil  * DPDK callback to change the MTU.
577cf37ca95SAdrien Mazarguil  *
578cf37ca95SAdrien Mazarguil  * @param dev
579cf37ca95SAdrien Mazarguil  *   Pointer to Ethernet device structure.
580cf37ca95SAdrien Mazarguil  * @param in_mtu
581cf37ca95SAdrien Mazarguil  *   New MTU.
582cf37ca95SAdrien Mazarguil  *
583cf37ca95SAdrien Mazarguil  * @return
584a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
585cf37ca95SAdrien Mazarguil  */
586cf37ca95SAdrien Mazarguil int
587cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
588cf37ca95SAdrien Mazarguil {
589dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
590a6d83b6aSNélio Laranjeiro 	uint16_t kern_mtu = 0;
591a6d83b6aSNélio Laranjeiro 	int ret;
592cf37ca95SAdrien Mazarguil 
593af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
594a0edafe4SNelio Laranjeiro 	if (ret)
595a6d83b6aSNélio Laranjeiro 		return ret;
596cf37ca95SAdrien Mazarguil 	/* Set kernel interface MTU first. */
597af4f09f2SNélio Laranjeiro 	ret = mlx5_set_mtu(dev, mtu);
598a0edafe4SNelio Laranjeiro 	if (ret)
599a6d83b6aSNélio Laranjeiro 		return ret;
600af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
601a0edafe4SNelio Laranjeiro 	if (ret)
602a6d83b6aSNélio Laranjeiro 		return ret;
603a0edafe4SNelio Laranjeiro 	if (kern_mtu == mtu) {
604a0edafe4SNelio Laranjeiro 		priv->mtu = mtu;
605a170a30dSNélio Laranjeiro 		DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
606a170a30dSNélio Laranjeiro 			dev->data->port_id, mtu);
607a0edafe4SNelio Laranjeiro 		return 0;
608a6d83b6aSNélio Laranjeiro 	}
609a6d83b6aSNélio Laranjeiro 	rte_errno = EAGAIN;
610a6d83b6aSNélio Laranjeiro 	return -rte_errno;
611cf37ca95SAdrien Mazarguil }
612cf37ca95SAdrien Mazarguil 
613cf37ca95SAdrien Mazarguil /**
614cdab90cbSNélio Laranjeiro  * Configure the RX function to use.
615cdab90cbSNélio Laranjeiro  *
616aee1b165SXueming Li  * @param dev
617af4f09f2SNélio Laranjeiro  *   Pointer to private data structure.
6181cfa649bSShahaf Shuler  *
6191cfa649bSShahaf Shuler  * @return
6201cfa649bSShahaf Shuler  *   Pointer to selected Rx burst function.
621cdab90cbSNélio Laranjeiro  */
6221cfa649bSShahaf Shuler eth_rx_burst_t
623af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev)
624cdab90cbSNélio Laranjeiro {
6251cfa649bSShahaf Shuler 	eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst;
6261cfa649bSShahaf Shuler 
6278e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(dev != NULL);
628af4f09f2SNélio Laranjeiro 	if (mlx5_check_vec_rx_support(dev) > 0) {
6290f20acbfSAlexander Kozyrev 		if (mlx5_mprq_enabled(dev)) {
6300f20acbfSAlexander Kozyrev 			rx_pkt_burst = mlx5_rx_burst_mprq_vec;
6310f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6320f20acbfSAlexander Kozyrev 				" MPRQ Rx function", dev->data->port_id);
6330f20acbfSAlexander Kozyrev 		} else {
6341cfa649bSShahaf Shuler 			rx_pkt_burst = mlx5_rx_burst_vec;
6350f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6360f20acbfSAlexander Kozyrev 				" SPRQ Rx function", dev->data->port_id);
6370f20acbfSAlexander Kozyrev 		}
6387d6bf6b8SYongseok Koh 	} else if (mlx5_mprq_enabled(dev)) {
6397d6bf6b8SYongseok Koh 		rx_pkt_burst = mlx5_rx_burst_mprq;
6400f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected MPRQ Rx function",
6410f20acbfSAlexander Kozyrev 			dev->data->port_id);
6420f20acbfSAlexander Kozyrev 	} else {
6430f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected SPRQ Rx function",
6440f20acbfSAlexander Kozyrev 			dev->data->port_id);
645cdab90cbSNélio Laranjeiro 	}
6461cfa649bSShahaf Shuler 	return rx_pkt_burst;
6476cb559d6SYongseok Koh }
648d3e0f392SMatan Azrad 
649d3e0f392SMatan Azrad /**
65009a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by port id.
6512e4c987aSOri Kam  *
6522e4c987aSOri Kam  * @param[in] port
6532e4c987aSOri Kam  *   Device port id.
6545e61bcddSViacheslav Ovsiienko  * @param[in] valid
6555e61bcddSViacheslav Ovsiienko  *   Device port id is valid, skip check. This flag is useful
6565e61bcddSViacheslav Ovsiienko  *   when trials are performed from probing and device is not
6575e61bcddSViacheslav Ovsiienko  *   flagged as valid yet (in attaching process).
6582e4c987aSOri Kam  * @param[out] es_domain_id
6592e4c987aSOri Kam  *   E-Switch domain id.
6602e4c987aSOri Kam  * @param[out] es_port_id
6612e4c987aSOri Kam  *   The port id of the port in the E-Switch.
6622e4c987aSOri Kam  *
6632e4c987aSOri Kam  * @return
66409a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
66509a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
6662e4c987aSOri Kam  */
66709a16bcaSViacheslav Ovsiienko struct mlx5_priv *
6685e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid)
6692e4c987aSOri Kam {
6702e4c987aSOri Kam 	struct rte_eth_dev *dev;
6712e4c987aSOri Kam 	struct mlx5_priv *priv;
6722e4c987aSOri Kam 
6732e4c987aSOri Kam 	if (port >= RTE_MAX_ETHPORTS) {
6742e4c987aSOri Kam 		rte_errno = EINVAL;
67509a16bcaSViacheslav Ovsiienko 		return NULL;
6762e4c987aSOri Kam 	}
6775e61bcddSViacheslav Ovsiienko 	if (!valid && !rte_eth_dev_is_valid_port(port)) {
6782e4c987aSOri Kam 		rte_errno = ENODEV;
67909a16bcaSViacheslav Ovsiienko 		return NULL;
6802e4c987aSOri Kam 	}
6812e4c987aSOri Kam 	dev = &rte_eth_devices[port];
6822e4c987aSOri Kam 	priv = dev->data->dev_private;
683cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
6842e4c987aSOri Kam 		rte_errno = EINVAL;
68509a16bcaSViacheslav Ovsiienko 		return NULL;
6862e4c987aSOri Kam 	}
68709a16bcaSViacheslav Ovsiienko 	return priv;
68809a16bcaSViacheslav Ovsiienko }
68909a16bcaSViacheslav Ovsiienko 
69009a16bcaSViacheslav Ovsiienko /**
69109a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by device instance.
69209a16bcaSViacheslav Ovsiienko  *
69309a16bcaSViacheslav Ovsiienko  * @param[in] port
69409a16bcaSViacheslav Ovsiienko  *   Device port id.
69509a16bcaSViacheslav Ovsiienko  * @param[out] es_domain_id
69609a16bcaSViacheslav Ovsiienko  *   E-Switch domain id.
69709a16bcaSViacheslav Ovsiienko  * @param[out] es_port_id
69809a16bcaSViacheslav Ovsiienko  *   The port id of the port in the E-Switch.
69909a16bcaSViacheslav Ovsiienko  *
70009a16bcaSViacheslav Ovsiienko  * @return
70109a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
70209a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
70309a16bcaSViacheslav Ovsiienko  */
70409a16bcaSViacheslav Ovsiienko struct mlx5_priv *
70509a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
70609a16bcaSViacheslav Ovsiienko {
70709a16bcaSViacheslav Ovsiienko 	struct mlx5_priv *priv;
70809a16bcaSViacheslav Ovsiienko 
70909a16bcaSViacheslav Ovsiienko 	priv = dev->data->dev_private;
710cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
71109a16bcaSViacheslav Ovsiienko 		rte_errno = EINVAL;
71209a16bcaSViacheslav Ovsiienko 		return NULL;
71309a16bcaSViacheslav Ovsiienko 	}
71409a16bcaSViacheslav Ovsiienko 	return priv;
7152e4c987aSOri Kam }
7162e4c987aSOri Kam 
7172e4c987aSOri Kam /**
718b6b3bf86SOri Kam  * DPDK callback to retrieve hairpin capabilities.
719b6b3bf86SOri Kam  *
720b6b3bf86SOri Kam  * @param dev
721b6b3bf86SOri Kam  *   Pointer to Ethernet device structure.
722b6b3bf86SOri Kam  * @param[out] cap
723b6b3bf86SOri Kam  *   Storage for hairpin capability data.
724b6b3bf86SOri Kam  *
725b6b3bf86SOri Kam  * @return
726b6b3bf86SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
727b6b3bf86SOri Kam  */
7281256805dSOphir Munk int
729b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
730b6b3bf86SOri Kam {
731b6b3bf86SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
732b6b3bf86SOri Kam 
733c4b86201SMichael Baum 	if (!mlx5_devx_obj_ops_en(priv->sh)) {
734b6b3bf86SOri Kam 		rte_errno = ENOTSUP;
735b6b3bf86SOri Kam 		return -rte_errno;
736b6b3bf86SOri Kam 	}
737b6b3bf86SOri Kam 	cap->max_nb_queues = UINT16_MAX;
738b6b3bf86SOri Kam 	cap->max_rx_2_tx = 1;
739b6b3bf86SOri Kam 	cap->max_tx_2_rx = 1;
740b6b3bf86SOri Kam 	cap->max_nb_desc = 8192;
741b6b3bf86SOri Kam 	return 0;
742b6b3bf86SOri Kam }
743