xref: /dpdk/drivers/net/mlx5/mlx5_ethdev.c (revision ec4e11d41d129ebc7c395b567827492e56fb08b7)
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"
292b730263SAdrien Mazarguil 
302b730263SAdrien Mazarguil /**
31ccdcba53SNélio Laranjeiro  * Get the interface index from device name.
32ccdcba53SNélio Laranjeiro  *
33ccdcba53SNélio Laranjeiro  * @param[in] dev
34ccdcba53SNélio Laranjeiro  *   Pointer to Ethernet device.
35ccdcba53SNélio Laranjeiro  *
36ccdcba53SNélio Laranjeiro  * @return
373f8cb05dSAdrien Mazarguil  *   Nonzero interface index on success, zero otherwise and rte_errno is set.
38ccdcba53SNélio Laranjeiro  */
393f8cb05dSAdrien Mazarguil unsigned int
40ccdcba53SNélio Laranjeiro mlx5_ifindex(const struct rte_eth_dev *dev)
41ccdcba53SNélio Laranjeiro {
42fa2e14d4SViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
433f8cb05dSAdrien Mazarguil 	unsigned int ifindex;
44ccdcba53SNélio Laranjeiro 
458e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv);
468e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv->if_index);
47f5f4c482SXueming Li 	if (priv->master && priv->sh->bond.ifindex > 0)
48f5f4c482SXueming Li 		ifindex = priv->sh->bond.ifindex;
49f5f4c482SXueming Li 	else
50f5f4c482SXueming Li 		ifindex = priv->if_index;
513f8cb05dSAdrien Mazarguil 	if (!ifindex)
52fa2e14d4SViacheslav Ovsiienko 		rte_errno = ENXIO;
533f8cb05dSAdrien Mazarguil 	return ifindex;
54ccdcba53SNélio Laranjeiro }
55ccdcba53SNélio Laranjeiro 
56ccdcba53SNélio Laranjeiro /**
577b2423cdSNélio Laranjeiro  * DPDK callback for Ethernet device configuration.
58e60fbd5bSAdrien Mazarguil  *
59e60fbd5bSAdrien Mazarguil  * @param dev
60e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
61e60fbd5bSAdrien Mazarguil  *
62e60fbd5bSAdrien Mazarguil  * @return
63a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
64e60fbd5bSAdrien Mazarguil  */
657b2423cdSNélio Laranjeiro int
667b2423cdSNélio Laranjeiro mlx5_dev_configure(struct rte_eth_dev *dev)
67e60fbd5bSAdrien Mazarguil {
68dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
69e60fbd5bSAdrien Mazarguil 	unsigned int rxqs_n = dev->data->nb_rx_queues;
70e60fbd5bSAdrien Mazarguil 	unsigned int txqs_n = dev->data->nb_tx_queues;
7129c1d8bbSNélio Laranjeiro 	const uint8_t use_app_rss_key =
7221e3a974SShahaf Shuler 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
73a6d83b6aSNélio Laranjeiro 	int ret = 0;
74e60fbd5bSAdrien Mazarguil 
7529c1d8bbSNélio Laranjeiro 	if (use_app_rss_key &&
7629c1d8bbSNélio Laranjeiro 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
77c388a2f6SNelio Laranjeiro 	     MLX5_RSS_HASH_KEY_LEN)) {
78c388a2f6SNelio Laranjeiro 		DRV_LOG(ERR, "port %u RSS key len must be %s Bytes long",
79c388a2f6SNelio Laranjeiro 			dev->data->port_id, RTE_STR(MLX5_RSS_HASH_KEY_LEN));
80a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
81a6d83b6aSNélio Laranjeiro 		return -rte_errno;
8229c1d8bbSNélio Laranjeiro 	}
8329c1d8bbSNélio Laranjeiro 	priv->rss_conf.rss_key =
8483c2047cSSuanming Mou 		mlx5_realloc(priv->rss_conf.rss_key, MLX5_MEM_RTE,
8583c2047cSSuanming Mou 			    MLX5_RSS_HASH_KEY_LEN, 0, SOCKET_ID_ANY);
8629c1d8bbSNélio Laranjeiro 	if (!priv->rss_conf.rss_key) {
87a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory (%u)",
880f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
89a6d83b6aSNélio Laranjeiro 		rte_errno = ENOMEM;
90a6d83b6aSNélio Laranjeiro 		return -rte_errno;
9129c1d8bbSNélio Laranjeiro 	}
928b945a7fSPavan Nikhilesh 
93af270529SThomas Monjalon 	if ((dev->data->dev_conf.txmode.offloads &
94295968d1SFerruh Yigit 			RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) &&
95af270529SThomas Monjalon 			rte_mbuf_dyn_tx_timestamp_register(NULL, NULL) != 0) {
96af270529SThomas Monjalon 		DRV_LOG(ERR, "port %u cannot register Tx timestamp field/flag",
97af270529SThomas Monjalon 			dev->data->port_id);
98af270529SThomas Monjalon 		return -rte_errno;
99af270529SThomas Monjalon 	}
10029c1d8bbSNélio Laranjeiro 	memcpy(priv->rss_conf.rss_key,
10129c1d8bbSNélio Laranjeiro 	       use_app_rss_key ?
10229c1d8bbSNélio Laranjeiro 	       dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key :
10329c1d8bbSNélio Laranjeiro 	       rss_hash_default_key,
104c388a2f6SNelio Laranjeiro 	       MLX5_RSS_HASH_KEY_LEN);
105c388a2f6SNelio Laranjeiro 	priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN;
10629c1d8bbSNélio Laranjeiro 	priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
107e60fbd5bSAdrien Mazarguil 	priv->rxqs = (void *)dev->data->rx_queues;
108e60fbd5bSAdrien Mazarguil 	priv->txqs = (void *)dev->data->tx_queues;
109e60fbd5bSAdrien Mazarguil 	if (txqs_n != priv->txqs_n) {
110a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Tx queues number update: %u -> %u",
1110f99970bSNélio Laranjeiro 			dev->data->port_id, priv->txqs_n, txqs_n);
112e60fbd5bSAdrien Mazarguil 		priv->txqs_n = txqs_n;
113e60fbd5bSAdrien Mazarguil 	}
1147fe24446SShahaf Shuler 	if (rxqs_n > priv->config.ind_table_max_size) {
115a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
1160f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
117a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
118a6d83b6aSNélio Laranjeiro 		return -rte_errno;
119634efbc2SNelio Laranjeiro 	}
12009ba4c58SDekel Peled 	if (rxqs_n != priv->rxqs_n) {
121a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
1220f99970bSNélio Laranjeiro 			dev->data->port_id, priv->rxqs_n, rxqs_n);
123e60fbd5bSAdrien Mazarguil 		priv->rxqs_n = rxqs_n;
12463bd1629SOri Kam 	}
12563bd1629SOri Kam 	priv->skip_default_rss_reta = 0;
12663bd1629SOri Kam 	ret = mlx5_proc_priv_init(dev);
12763bd1629SOri Kam 	if (ret)
12863bd1629SOri Kam 		return ret;
12963bd1629SOri Kam 	return 0;
13063bd1629SOri Kam }
13163bd1629SOri Kam 
13263bd1629SOri Kam /**
13363bd1629SOri Kam  * Configure default RSS reta.
13463bd1629SOri Kam  *
13563bd1629SOri Kam  * @param dev
13663bd1629SOri Kam  *   Pointer to Ethernet device structure.
13763bd1629SOri Kam  *
13863bd1629SOri Kam  * @return
13963bd1629SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
14063bd1629SOri Kam  */
14163bd1629SOri Kam int
14263bd1629SOri Kam mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
14363bd1629SOri Kam {
14463bd1629SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
14563bd1629SOri Kam 	unsigned int rxqs_n = dev->data->nb_rx_queues;
14663bd1629SOri Kam 	unsigned int i;
14763bd1629SOri Kam 	unsigned int j;
14863bd1629SOri Kam 	unsigned int reta_idx_n;
14963bd1629SOri Kam 	int ret = 0;
15063bd1629SOri Kam 	unsigned int *rss_queue_arr = NULL;
15163bd1629SOri Kam 	unsigned int rss_queue_n = 0;
15263bd1629SOri Kam 
15363bd1629SOri Kam 	if (priv->skip_default_rss_reta)
15463bd1629SOri Kam 		return ret;
15583c2047cSSuanming Mou 	rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0,
15683c2047cSSuanming Mou 				    SOCKET_ID_ANY);
15763bd1629SOri Kam 	if (!rss_queue_arr) {
15863bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)",
15963bd1629SOri Kam 			dev->data->port_id, rxqs_n);
16063bd1629SOri Kam 		rte_errno = ENOMEM;
16163bd1629SOri Kam 		return -rte_errno;
16263bd1629SOri Kam 	}
16363bd1629SOri Kam 	for (i = 0, j = 0; i < rxqs_n; i++) {
16463bd1629SOri Kam 		struct mlx5_rxq_data *rxq_data;
16563bd1629SOri Kam 		struct mlx5_rxq_ctrl *rxq_ctrl;
16663bd1629SOri Kam 
16763bd1629SOri Kam 		rxq_data = (*priv->rxqs)[i];
16863bd1629SOri Kam 		rxq_ctrl = container_of(rxq_data, struct mlx5_rxq_ctrl, rxq);
169bf864e82STonghao Zhang 		if (rxq_ctrl && rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD)
17063bd1629SOri Kam 			rss_queue_arr[j++] = i;
17163bd1629SOri Kam 	}
17263bd1629SOri Kam 	rss_queue_n = j;
17363bd1629SOri Kam 	if (rss_queue_n > priv->config.ind_table_max_size) {
17463bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
17563bd1629SOri Kam 			dev->data->port_id, rss_queue_n);
17663bd1629SOri Kam 		rte_errno = EINVAL;
17783c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
17863bd1629SOri Kam 		return -rte_errno;
17963bd1629SOri Kam 	}
18063bd1629SOri Kam 	DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
18163bd1629SOri Kam 		dev->data->port_id, priv->rxqs_n, rxqs_n);
18263bd1629SOri Kam 	priv->rxqs_n = rxqs_n;
18309ba4c58SDekel Peled 	/*
18409ba4c58SDekel Peled 	 * If the requested number of RX queues is not a power of two,
18509ba4c58SDekel Peled 	 * use the maximum indirection table size for better balancing.
18609ba4c58SDekel Peled 	 * The result is always rounded to the next power of two.
18709ba4c58SDekel Peled 	 */
18863bd1629SOri Kam 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
1897fe24446SShahaf Shuler 				priv->config.ind_table_max_size :
19063bd1629SOri Kam 				rss_queue_n));
191a6d83b6aSNélio Laranjeiro 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
19263bd1629SOri Kam 	if (ret) {
19383c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
194a6d83b6aSNélio Laranjeiro 		return ret;
19563bd1629SOri Kam 	}
19609ba4c58SDekel Peled 	/*
19709ba4c58SDekel Peled 	 * When the number of RX queues is not a power of two,
19809ba4c58SDekel Peled 	 * the remaining table entries are padded with reused WQs
19909ba4c58SDekel Peled 	 * and hashes are not spread uniformly.
20009ba4c58SDekel Peled 	 */
201634efbc2SNelio Laranjeiro 	for (i = 0, j = 0; (i != reta_idx_n); ++i) {
20263bd1629SOri Kam 		(*priv->reta_idx)[i] = rss_queue_arr[j];
20363bd1629SOri Kam 		if (++j == rss_queue_n)
204634efbc2SNelio Laranjeiro 			j = 0;
205634efbc2SNelio Laranjeiro 	}
20683c2047cSSuanming Mou 	mlx5_free(rss_queue_arr);
207120dc4a7SYongseok Koh 	return ret;
208e60fbd5bSAdrien Mazarguil }
209e60fbd5bSAdrien Mazarguil 
210e60fbd5bSAdrien Mazarguil /**
211d11d651fSShahaf Shuler  * Sets default tuning parameters.
212d11d651fSShahaf Shuler  *
213d11d651fSShahaf Shuler  * @param dev
214d11d651fSShahaf Shuler  *   Pointer to Ethernet device.
215d11d651fSShahaf Shuler  * @param[out] info
216d11d651fSShahaf Shuler  *   Info structure output buffer.
217d11d651fSShahaf Shuler  */
218d11d651fSShahaf Shuler static void
219d11d651fSShahaf Shuler mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
220d11d651fSShahaf Shuler {
221dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
222d11d651fSShahaf Shuler 
223d11d651fSShahaf Shuler 	/* Minimum CPU utilization. */
224d11d651fSShahaf Shuler 	info->default_rxportconf.ring_size = 256;
225d11d651fSShahaf Shuler 	info->default_txportconf.ring_size = 256;
226f078ceb6SViacheslav Ovsiienko 	info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST;
227f078ceb6SViacheslav Ovsiienko 	info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST;
228295968d1SFerruh Yigit 	if ((priv->link_speed_capa & RTE_ETH_LINK_SPEED_200G) |
229295968d1SFerruh Yigit 		(priv->link_speed_capa & RTE_ETH_LINK_SPEED_100G)) {
230d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 16;
231d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 16;
232d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
233d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
234d11d651fSShahaf Shuler 			/* Max Throughput. */
235d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 2048;
236d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 2048;
237d11d651fSShahaf Shuler 		}
238d11d651fSShahaf Shuler 	} else {
239d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 8;
240d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 8;
241d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
242d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
243d11d651fSShahaf Shuler 			/* Max Throughput. */
244d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 4096;
245d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 4096;
246d11d651fSShahaf Shuler 		}
247d11d651fSShahaf Shuler 	}
248d11d651fSShahaf Shuler }
249d11d651fSShahaf Shuler 
250d11d651fSShahaf Shuler /**
251cb9cb61eSViacheslav Ovsiienko  * Sets tx mbuf limiting parameters.
252cb9cb61eSViacheslav Ovsiienko  *
253cb9cb61eSViacheslav Ovsiienko  * @param dev
254cb9cb61eSViacheslav Ovsiienko  *   Pointer to Ethernet device.
255cb9cb61eSViacheslav Ovsiienko  * @param[out] info
256cb9cb61eSViacheslav Ovsiienko  *   Info structure output buffer.
257cb9cb61eSViacheslav Ovsiienko  */
258cb9cb61eSViacheslav Ovsiienko static void
259cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
260cb9cb61eSViacheslav Ovsiienko {
261cb9cb61eSViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
262cb9cb61eSViacheslav Ovsiienko 	struct mlx5_dev_config *config = &priv->config;
263cb9cb61eSViacheslav Ovsiienko 	unsigned int inlen;
264cb9cb61eSViacheslav Ovsiienko 	uint16_t nb_max;
265cb9cb61eSViacheslav Ovsiienko 
266cb9cb61eSViacheslav Ovsiienko 	inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ?
267cb9cb61eSViacheslav Ovsiienko 		MLX5_SEND_DEF_INLINE_LEN :
268cb9cb61eSViacheslav Ovsiienko 		(unsigned int)config->txq_inline_max;
2698e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(config->txq_inline_min >= 0);
270cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min);
271cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX +
272cb9cb61eSViacheslav Ovsiienko 			       MLX5_ESEG_MIN_INLINE_SIZE -
273cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_CSEG_SIZE -
274cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_ESEG_SIZE -
275cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_DSEG_SIZE * 2);
276cb9cb61eSViacheslav Ovsiienko 	nb_max = (MLX5_WQE_SIZE_MAX +
277cb9cb61eSViacheslav Ovsiienko 		  MLX5_ESEG_MIN_INLINE_SIZE -
278cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_CSEG_SIZE -
279cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_ESEG_SIZE -
280cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_DSEG_SIZE -
281cb9cb61eSViacheslav Ovsiienko 		  inlen) / MLX5_WSEG_SIZE;
282cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_seg_max = nb_max;
283cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_mtu_seg_max = nb_max;
284cb9cb61eSViacheslav Ovsiienko }
285cb9cb61eSViacheslav Ovsiienko 
286cb9cb61eSViacheslav Ovsiienko /**
287e60fbd5bSAdrien Mazarguil  * DPDK callback to get information about the device.
288e60fbd5bSAdrien Mazarguil  *
289e60fbd5bSAdrien Mazarguil  * @param dev
290e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
291e60fbd5bSAdrien Mazarguil  * @param[out] info
292e60fbd5bSAdrien Mazarguil  *   Info structure output buffer.
293e60fbd5bSAdrien Mazarguil  */
294bdad90d1SIvan Ilchenko int
295e60fbd5bSAdrien Mazarguil mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
296e60fbd5bSAdrien Mazarguil {
297dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
2987fe24446SShahaf Shuler 	struct mlx5_dev_config *config = &priv->config;
299e60fbd5bSAdrien Mazarguil 	unsigned int max;
300e60fbd5bSAdrien Mazarguil 
301e60fbd5bSAdrien Mazarguil 	/* FIXME: we should ask the device for these values. */
302e60fbd5bSAdrien Mazarguil 	info->min_rx_bufsize = 32;
303e60fbd5bSAdrien Mazarguil 	info->max_rx_pktlen = 65536;
3041c7e57f9SDekel Peled 	info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE;
305e60fbd5bSAdrien Mazarguil 	/*
306e60fbd5bSAdrien Mazarguil 	 * Since we need one CQ per QP, the limit is the minimum number
307e60fbd5bSAdrien Mazarguil 	 * between the two values.
308e60fbd5bSAdrien Mazarguil 	 */
309e85f623eSOphir Munk 	max = RTE_MIN(priv->sh->device_attr.max_cq,
310e85f623eSOphir Munk 		      priv->sh->device_attr.max_qp);
311b689a781SThomas Monjalon 	/* max_rx_queues is uint16_t. */
312b689a781SThomas Monjalon 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
313e60fbd5bSAdrien Mazarguil 	info->max_rx_queues = max;
314e60fbd5bSAdrien Mazarguil 	info->max_tx_queues = max;
31518c01b98SNélio Laranjeiro 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
316af4f09f2SNélio Laranjeiro 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
3176c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
318ddb03843SViacheslav Ovsiienko 	info->rx_seg_capa.multi_pools = !config->mprq.enabled;
319ddb03843SViacheslav Ovsiienko 	info->rx_seg_capa.offset_allowed = !config->mprq.enabled;
3206c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.offset_align_log2 = 0;
32117ed314cSMatan Azrad 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
32217b843ebSShahaf Shuler 				 info->rx_queue_offload_capa);
323af4f09f2SNélio Laranjeiro 	info->tx_offload_capa = mlx5_get_tx_port_offloads(dev);
324*ec4e11d4SDmitry Kozlyuk 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
325fa2e14d4SViacheslav Ovsiienko 	info->if_index = mlx5_ifindex(dev);
326d365210eSYongseok Koh 	info->reta_size = priv->reta_idx_n ?
3277fe24446SShahaf Shuler 		priv->reta_idx_n : config->ind_table_max_size;
328c388a2f6SNelio Laranjeiro 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
32975ef62a9SNélio Laranjeiro 	info->speed_capa = priv->link_speed_capa;
330b233b027SShahaf Shuler 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
331d11d651fSShahaf Shuler 	mlx5_set_default_params(dev, info);
332cb9cb61eSViacheslav Ovsiienko 	mlx5_set_txlimit_params(dev, info);
3332b730263SAdrien Mazarguil 	info->switch_info.name = dev->data->name;
3342b730263SAdrien Mazarguil 	info->switch_info.domain_id = priv->domain_id;
3352b730263SAdrien Mazarguil 	info->switch_info.port_id = priv->representor_id;
3362b730263SAdrien Mazarguil 	if (priv->representor) {
337f7e95215SViacheslav Ovsiienko 		uint16_t port_id;
3382b730263SAdrien Mazarguil 
33956bb3c84SXueming Li 		MLX5_ETH_FOREACH_DEV(port_id, dev->device) {
340dbeba4cfSThomas Monjalon 			struct mlx5_priv *opriv =
341f7e95215SViacheslav Ovsiienko 				rte_eth_devices[port_id].data->dev_private;
3422b730263SAdrien Mazarguil 
3432b730263SAdrien Mazarguil 			if (!opriv ||
3442b730263SAdrien Mazarguil 			    opriv->representor ||
345f7e95215SViacheslav Ovsiienko 			    opriv->sh != priv->sh ||
3462b730263SAdrien Mazarguil 			    opriv->domain_id != priv->domain_id)
3472b730263SAdrien Mazarguil 				continue;
3482b730263SAdrien Mazarguil 			/*
3492b730263SAdrien Mazarguil 			 * Override switch name with that of the master
3502b730263SAdrien Mazarguil 			 * device.
3512b730263SAdrien Mazarguil 			 */
3522b730263SAdrien Mazarguil 			info->switch_info.name = opriv->dev_data->name;
3532b730263SAdrien Mazarguil 			break;
3542b730263SAdrien Mazarguil 		}
3552b730263SAdrien Mazarguil 	}
356bdad90d1SIvan Ilchenko 	return 0;
357e60fbd5bSAdrien Mazarguil }
358e60fbd5bSAdrien Mazarguil 
359fb732b0aSNélio Laranjeiro /**
360cb95feefSXueming Li  * Calculate representor ID from port switch info.
361cb95feefSXueming Li  *
362cb95feefSXueming Li  * Uint16 representor ID bits definition:
363cb95feefSXueming Li  *   pf: 2
364cb95feefSXueming Li  *   type: 2
365cb95feefSXueming Li  *   vf/sf: 12
366cb95feefSXueming Li  *
367cb95feefSXueming Li  * @param info
368cb95feefSXueming Li  *   Port switch info.
36991766faeSXueming Li  * @param hpf_type
37091766faeSXueming Li  *   Use this type if port is HPF.
371cb95feefSXueming Li  *
372cb95feefSXueming Li  * @return
373cb95feefSXueming Li  *   Encoded representor ID.
374cb95feefSXueming Li  */
375cb95feefSXueming Li uint16_t
37691766faeSXueming Li mlx5_representor_id_encode(const struct mlx5_switch_info *info,
37791766faeSXueming Li 			   enum rte_eth_representor_type hpf_type)
378cb95feefSXueming Li {
379cb95feefSXueming Li 	enum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF;
380cb95feefSXueming Li 	uint16_t repr = info->port_name;
381cb95feefSXueming Li 
382cb95feefSXueming Li 	if (info->representor == 0)
383cb95feefSXueming Li 		return UINT16_MAX;
384cb95feefSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF)
385cb95feefSXueming Li 		type = RTE_ETH_REPRESENTOR_SF;
38691766faeSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) {
38791766faeSXueming Li 		type = hpf_type;
388cb95feefSXueming Li 		repr = UINT16_MAX;
38991766faeSXueming Li 	}
390cb95feefSXueming Li 	return MLX5_REPRESENTOR_ID(info->pf_num, type, repr);
391cb95feefSXueming Li }
392cb95feefSXueming Li 
393cb95feefSXueming Li /**
394cb95feefSXueming Li  * DPDK callback to get information about representor.
395cb95feefSXueming Li  *
396cb95feefSXueming Li  * Representor ID bits definition:
397cb95feefSXueming Li  *   vf/sf: 12
398cb95feefSXueming Li  *   type: 2
399cb95feefSXueming Li  *   pf: 2
400cb95feefSXueming Li  *
401cb95feefSXueming Li  * @param dev
402cb95feefSXueming Li  *   Pointer to Ethernet device structure.
403cb95feefSXueming Li  * @param[out] info
404cb95feefSXueming Li  *   Nullable info structure output buffer.
405cb95feefSXueming Li  *
406cb95feefSXueming Li  * @return
407cb95feefSXueming Li  *   negative on error, or the number of representor ranges.
408cb95feefSXueming Li  */
409cb95feefSXueming Li int
410cb95feefSXueming Li mlx5_representor_info_get(struct rte_eth_dev *dev,
411cb95feefSXueming Li 			  struct rte_eth_representor_info *info)
412cb95feefSXueming Li {
413cb95feefSXueming Li 	struct mlx5_priv *priv = dev->data->dev_private;
41491766faeSXueming Li 	int n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */
415cb95feefSXueming Li 	int n_pf = 2; /* Number of PFs. */
416cb95feefSXueming Li 	int i = 0, pf;
41710eaf41dSViacheslav Galaktionov 	int n_entries;
418cb95feefSXueming Li 
419cb95feefSXueming Li 	if (info == NULL)
420cb95feefSXueming Li 		goto out;
42110eaf41dSViacheslav Galaktionov 
42210eaf41dSViacheslav Galaktionov 	n_entries = n_type * n_pf;
42310eaf41dSViacheslav Galaktionov 	if ((uint32_t)n_entries > info->nb_ranges_alloc)
42410eaf41dSViacheslav Galaktionov 		n_entries = info->nb_ranges_alloc;
42510eaf41dSViacheslav Galaktionov 
426cb95feefSXueming Li 	info->controller = 0;
427cb95feefSXueming Li 	info->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0;
428cb95feefSXueming Li 	for (pf = 0; pf < n_pf; ++pf) {
429cb95feefSXueming Li 		/* VF range. */
430cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
431cb95feefSXueming Li 		info->ranges[i].controller = 0;
432cb95feefSXueming Li 		info->ranges[i].pf = pf;
433cb95feefSXueming Li 		info->ranges[i].vf = 0;
434cb95feefSXueming Li 		info->ranges[i].id_base =
435cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
436cb95feefSXueming Li 		info->ranges[i].id_end =
437cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
438cb95feefSXueming Li 		snprintf(info->ranges[i].name,
439cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
440cb95feefSXueming Li 		i++;
44110eaf41dSViacheslav Galaktionov 		if (i == n_entries)
44210eaf41dSViacheslav Galaktionov 			break;
44391766faeSXueming Li 		/* HPF range of VF type. */
444cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
445cb95feefSXueming Li 		info->ranges[i].controller = 0;
446cb95feefSXueming Li 		info->ranges[i].pf = pf;
447cb95feefSXueming Li 		info->ranges[i].vf = UINT16_MAX;
448cb95feefSXueming Li 		info->ranges[i].id_base =
449cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
450cb95feefSXueming Li 		info->ranges[i].id_end =
451cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
452cb95feefSXueming Li 		snprintf(info->ranges[i].name,
453cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
454cb95feefSXueming Li 		i++;
45510eaf41dSViacheslav Galaktionov 		if (i == n_entries)
45610eaf41dSViacheslav Galaktionov 			break;
457cb95feefSXueming Li 		/* SF range. */
458cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
459cb95feefSXueming Li 		info->ranges[i].controller = 0;
460cb95feefSXueming Li 		info->ranges[i].pf = pf;
461cb95feefSXueming Li 		info->ranges[i].vf = 0;
462cb95feefSXueming Li 		info->ranges[i].id_base =
463cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
464cb95feefSXueming Li 		info->ranges[i].id_end =
465cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
466cb95feefSXueming Li 		snprintf(info->ranges[i].name,
467cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
468cb95feefSXueming Li 		i++;
46910eaf41dSViacheslav Galaktionov 		if (i == n_entries)
47010eaf41dSViacheslav Galaktionov 			break;
47191766faeSXueming Li 		/* HPF range of SF type. */
47291766faeSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
47391766faeSXueming Li 		info->ranges[i].controller = 0;
47491766faeSXueming Li 		info->ranges[i].pf = pf;
47591766faeSXueming Li 		info->ranges[i].vf = UINT16_MAX;
47691766faeSXueming Li 		info->ranges[i].id_base =
47791766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
47891766faeSXueming Li 		info->ranges[i].id_end =
47991766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
48091766faeSXueming Li 		snprintf(info->ranges[i].name,
48191766faeSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
48291766faeSXueming Li 		i++;
48310eaf41dSViacheslav Galaktionov 		if (i == n_entries)
48410eaf41dSViacheslav Galaktionov 			break;
485cb95feefSXueming Li 	}
48610eaf41dSViacheslav Galaktionov 	info->nb_ranges = i;
487cb95feefSXueming Li out:
488cb95feefSXueming Li 	return n_type * n_pf;
489cb95feefSXueming Li }
490cb95feefSXueming Li 
491cb95feefSXueming Li /**
492714bf46eSThomas Monjalon  * Get firmware version of a device.
493714bf46eSThomas Monjalon  *
494714bf46eSThomas Monjalon  * @param dev
495714bf46eSThomas Monjalon  *   Ethernet device port.
496714bf46eSThomas Monjalon  * @param fw_ver
497714bf46eSThomas Monjalon  *   String output allocated by caller.
498714bf46eSThomas Monjalon  * @param fw_size
499714bf46eSThomas Monjalon  *   Size of the output string, including terminating null byte.
500714bf46eSThomas Monjalon  *
501714bf46eSThomas Monjalon  * @return
502714bf46eSThomas Monjalon  *   0 on success, or the size of the non truncated string if too big.
503714bf46eSThomas Monjalon  */
5041256805dSOphir Munk int
5051256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
506714bf46eSThomas Monjalon {
507dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
508e85f623eSOphir Munk 	struct mlx5_dev_attr *attr = &priv->sh->device_attr;
509714bf46eSThomas Monjalon 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
510714bf46eSThomas Monjalon 
511714bf46eSThomas Monjalon 	if (fw_size < size)
512714bf46eSThomas Monjalon 		return size;
513714bf46eSThomas Monjalon 	if (fw_ver != NULL)
514714bf46eSThomas Monjalon 		strlcpy(fw_ver, attr->fw_ver, fw_size);
515714bf46eSThomas Monjalon 	return 0;
516714bf46eSThomas Monjalon }
517714bf46eSThomas Monjalon 
518714bf46eSThomas Monjalon /**
519fb732b0aSNélio Laranjeiro  * Get supported packet types.
520fb732b0aSNélio Laranjeiro  *
521fb732b0aSNélio Laranjeiro  * @param dev
522fb732b0aSNélio Laranjeiro  *   Pointer to Ethernet device structure.
523fb732b0aSNélio Laranjeiro  *
524fb732b0aSNélio Laranjeiro  * @return
525fb732b0aSNélio Laranjeiro  *   A pointer to the supported Packet types array.
526fb732b0aSNélio Laranjeiro  */
52778a38edfSJianfeng Tan const uint32_t *
52878a38edfSJianfeng Tan mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
52978a38edfSJianfeng Tan {
53078a38edfSJianfeng Tan 	static const uint32_t ptypes[] = {
53178a38edfSJianfeng Tan 		/* refers to rxq_cq_to_pkt_type() */
532ea16068cSYongseok Koh 		RTE_PTYPE_L2_ETHER,
533c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
534c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
535ea16068cSYongseok Koh 		RTE_PTYPE_L4_NONFRAG,
536ea16068cSYongseok Koh 		RTE_PTYPE_L4_FRAG,
537ea16068cSYongseok Koh 		RTE_PTYPE_L4_TCP,
538ea16068cSYongseok Koh 		RTE_PTYPE_L4_UDP,
539c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
540c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
541ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_NONFRAG,
542ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_FRAG,
543ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_TCP,
544ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_UDP,
54578a38edfSJianfeng Tan 		RTE_PTYPE_UNKNOWN
54678a38edfSJianfeng Tan 	};
54778a38edfSJianfeng Tan 
5486cb559d6SYongseok Koh 	if (dev->rx_pkt_burst == mlx5_rx_burst ||
5497d6bf6b8SYongseok Koh 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq ||
5500f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_vec ||
5510f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec)
55278a38edfSJianfeng Tan 		return ptypes;
55378a38edfSJianfeng Tan 	return NULL;
55478a38edfSJianfeng Tan }
55578a38edfSJianfeng Tan 
556e60fbd5bSAdrien Mazarguil /**
557cf37ca95SAdrien Mazarguil  * DPDK callback to change the MTU.
558cf37ca95SAdrien Mazarguil  *
559cf37ca95SAdrien Mazarguil  * @param dev
560cf37ca95SAdrien Mazarguil  *   Pointer to Ethernet device structure.
561cf37ca95SAdrien Mazarguil  * @param in_mtu
562cf37ca95SAdrien Mazarguil  *   New MTU.
563cf37ca95SAdrien Mazarguil  *
564cf37ca95SAdrien Mazarguil  * @return
565a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
566cf37ca95SAdrien Mazarguil  */
567cf37ca95SAdrien Mazarguil int
568cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
569cf37ca95SAdrien Mazarguil {
570dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
571a6d83b6aSNélio Laranjeiro 	uint16_t kern_mtu = 0;
572a6d83b6aSNélio Laranjeiro 	int ret;
573cf37ca95SAdrien Mazarguil 
574af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
575a0edafe4SNelio Laranjeiro 	if (ret)
576a6d83b6aSNélio Laranjeiro 		return ret;
577cf37ca95SAdrien Mazarguil 	/* Set kernel interface MTU first. */
578af4f09f2SNélio Laranjeiro 	ret = mlx5_set_mtu(dev, mtu);
579a0edafe4SNelio Laranjeiro 	if (ret)
580a6d83b6aSNélio Laranjeiro 		return ret;
581af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
582a0edafe4SNelio Laranjeiro 	if (ret)
583a6d83b6aSNélio Laranjeiro 		return ret;
584a0edafe4SNelio Laranjeiro 	if (kern_mtu == mtu) {
585a0edafe4SNelio Laranjeiro 		priv->mtu = mtu;
586a170a30dSNélio Laranjeiro 		DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
587a170a30dSNélio Laranjeiro 			dev->data->port_id, mtu);
588a0edafe4SNelio Laranjeiro 		return 0;
589a6d83b6aSNélio Laranjeiro 	}
590a6d83b6aSNélio Laranjeiro 	rte_errno = EAGAIN;
591a6d83b6aSNélio Laranjeiro 	return -rte_errno;
592cf37ca95SAdrien Mazarguil }
593cf37ca95SAdrien Mazarguil 
594cf37ca95SAdrien Mazarguil /**
595cdab90cbSNélio Laranjeiro  * Configure the RX function to use.
596cdab90cbSNélio Laranjeiro  *
597aee1b165SXueming Li  * @param dev
598af4f09f2SNélio Laranjeiro  *   Pointer to private data structure.
5991cfa649bSShahaf Shuler  *
6001cfa649bSShahaf Shuler  * @return
6011cfa649bSShahaf Shuler  *   Pointer to selected Rx burst function.
602cdab90cbSNélio Laranjeiro  */
6031cfa649bSShahaf Shuler eth_rx_burst_t
604af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev)
605cdab90cbSNélio Laranjeiro {
6061cfa649bSShahaf Shuler 	eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst;
6071cfa649bSShahaf Shuler 
6088e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(dev != NULL);
609af4f09f2SNélio Laranjeiro 	if (mlx5_check_vec_rx_support(dev) > 0) {
6100f20acbfSAlexander Kozyrev 		if (mlx5_mprq_enabled(dev)) {
6110f20acbfSAlexander Kozyrev 			rx_pkt_burst = mlx5_rx_burst_mprq_vec;
6120f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6130f20acbfSAlexander Kozyrev 				" MPRQ Rx function", dev->data->port_id);
6140f20acbfSAlexander Kozyrev 		} else {
6151cfa649bSShahaf Shuler 			rx_pkt_burst = mlx5_rx_burst_vec;
6160f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6170f20acbfSAlexander Kozyrev 				" SPRQ Rx function", dev->data->port_id);
6180f20acbfSAlexander Kozyrev 		}
6197d6bf6b8SYongseok Koh 	} else if (mlx5_mprq_enabled(dev)) {
6207d6bf6b8SYongseok Koh 		rx_pkt_burst = mlx5_rx_burst_mprq;
6210f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected MPRQ Rx function",
6220f20acbfSAlexander Kozyrev 			dev->data->port_id);
6230f20acbfSAlexander Kozyrev 	} else {
6240f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected SPRQ Rx function",
6250f20acbfSAlexander Kozyrev 			dev->data->port_id);
626cdab90cbSNélio Laranjeiro 	}
6271cfa649bSShahaf Shuler 	return rx_pkt_burst;
6286cb559d6SYongseok Koh }
629d3e0f392SMatan Azrad 
630d3e0f392SMatan Azrad /**
63109a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by port id.
6322e4c987aSOri Kam  *
6332e4c987aSOri Kam  * @param[in] port
6342e4c987aSOri Kam  *   Device port id.
6355e61bcddSViacheslav Ovsiienko  * @param[in] valid
6365e61bcddSViacheslav Ovsiienko  *   Device port id is valid, skip check. This flag is useful
6375e61bcddSViacheslav Ovsiienko  *   when trials are performed from probing and device is not
6385e61bcddSViacheslav Ovsiienko  *   flagged as valid yet (in attaching process).
6392e4c987aSOri Kam  * @param[out] es_domain_id
6402e4c987aSOri Kam  *   E-Switch domain id.
6412e4c987aSOri Kam  * @param[out] es_port_id
6422e4c987aSOri Kam  *   The port id of the port in the E-Switch.
6432e4c987aSOri Kam  *
6442e4c987aSOri Kam  * @return
64509a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
64609a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
6472e4c987aSOri Kam  */
64809a16bcaSViacheslav Ovsiienko struct mlx5_priv *
6495e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid)
6502e4c987aSOri Kam {
6512e4c987aSOri Kam 	struct rte_eth_dev *dev;
6522e4c987aSOri Kam 	struct mlx5_priv *priv;
6532e4c987aSOri Kam 
6542e4c987aSOri Kam 	if (port >= RTE_MAX_ETHPORTS) {
6552e4c987aSOri Kam 		rte_errno = EINVAL;
65609a16bcaSViacheslav Ovsiienko 		return NULL;
6572e4c987aSOri Kam 	}
6585e61bcddSViacheslav Ovsiienko 	if (!valid && !rte_eth_dev_is_valid_port(port)) {
6592e4c987aSOri Kam 		rte_errno = ENODEV;
66009a16bcaSViacheslav Ovsiienko 		return NULL;
6612e4c987aSOri Kam 	}
6622e4c987aSOri Kam 	dev = &rte_eth_devices[port];
6632e4c987aSOri Kam 	priv = dev->data->dev_private;
6642e4c987aSOri Kam 	if (!(priv->representor || priv->master)) {
6652e4c987aSOri Kam 		rte_errno = EINVAL;
66609a16bcaSViacheslav Ovsiienko 		return NULL;
6672e4c987aSOri Kam 	}
66809a16bcaSViacheslav Ovsiienko 	return priv;
66909a16bcaSViacheslav Ovsiienko }
67009a16bcaSViacheslav Ovsiienko 
67109a16bcaSViacheslav Ovsiienko /**
67209a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by device instance.
67309a16bcaSViacheslav Ovsiienko  *
67409a16bcaSViacheslav Ovsiienko  * @param[in] port
67509a16bcaSViacheslav Ovsiienko  *   Device port id.
67609a16bcaSViacheslav Ovsiienko  * @param[out] es_domain_id
67709a16bcaSViacheslav Ovsiienko  *   E-Switch domain id.
67809a16bcaSViacheslav Ovsiienko  * @param[out] es_port_id
67909a16bcaSViacheslav Ovsiienko  *   The port id of the port in the E-Switch.
68009a16bcaSViacheslav Ovsiienko  *
68109a16bcaSViacheslav Ovsiienko  * @return
68209a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
68309a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
68409a16bcaSViacheslav Ovsiienko  */
68509a16bcaSViacheslav Ovsiienko struct mlx5_priv *
68609a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
68709a16bcaSViacheslav Ovsiienko {
68809a16bcaSViacheslav Ovsiienko 	struct mlx5_priv *priv;
68909a16bcaSViacheslav Ovsiienko 
69009a16bcaSViacheslav Ovsiienko 	priv = dev->data->dev_private;
69109a16bcaSViacheslav Ovsiienko 	if (!(priv->representor || priv->master)) {
69209a16bcaSViacheslav Ovsiienko 		rte_errno = EINVAL;
69309a16bcaSViacheslav Ovsiienko 		return NULL;
69409a16bcaSViacheslav Ovsiienko 	}
69509a16bcaSViacheslav Ovsiienko 	return priv;
6962e4c987aSOri Kam }
6972e4c987aSOri Kam 
6982e4c987aSOri Kam /**
699b6b3bf86SOri Kam  * DPDK callback to retrieve hairpin capabilities.
700b6b3bf86SOri Kam  *
701b6b3bf86SOri Kam  * @param dev
702b6b3bf86SOri Kam  *   Pointer to Ethernet device structure.
703b6b3bf86SOri Kam  * @param[out] cap
704b6b3bf86SOri Kam  *   Storage for hairpin capability data.
705b6b3bf86SOri Kam  *
706b6b3bf86SOri Kam  * @return
707b6b3bf86SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
708b6b3bf86SOri Kam  */
7091256805dSOphir Munk int
710b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
711b6b3bf86SOri Kam {
712b6b3bf86SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
713b00f7603SMichael Baum 	struct mlx5_dev_config *config = &priv->config;
714b6b3bf86SOri Kam 
715b00f7603SMichael Baum 	if (!priv->sh->devx || !config->dest_tir || !config->dv_flow_en) {
716b6b3bf86SOri Kam 		rte_errno = ENOTSUP;
717b6b3bf86SOri Kam 		return -rte_errno;
718b6b3bf86SOri Kam 	}
719b6b3bf86SOri Kam 	cap->max_nb_queues = UINT16_MAX;
720b6b3bf86SOri Kam 	cap->max_rx_2_tx = 1;
721b6b3bf86SOri Kam 	cap->max_tx_2_rx = 1;
722b6b3bf86SOri Kam 	cap->max_nb_desc = 8192;
723b6b3bf86SOri Kam 	return 0;
724b6b3bf86SOri Kam }
725