xref: /dpdk/drivers/net/mlx5/mlx5_ethdev.c (revision cf004fd33acca27a506b65904564eaf1cde4eea7)
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"
302b730263SAdrien Mazarguil 
312b730263SAdrien Mazarguil /**
32ccdcba53SNélio Laranjeiro  * Get the interface index from device name.
33ccdcba53SNélio Laranjeiro  *
34ccdcba53SNélio Laranjeiro  * @param[in] dev
35ccdcba53SNélio Laranjeiro  *   Pointer to Ethernet device.
36ccdcba53SNélio Laranjeiro  *
37ccdcba53SNélio Laranjeiro  * @return
383f8cb05dSAdrien Mazarguil  *   Nonzero interface index on success, zero otherwise and rte_errno is set.
39ccdcba53SNélio Laranjeiro  */
403f8cb05dSAdrien Mazarguil unsigned int
41ccdcba53SNélio Laranjeiro mlx5_ifindex(const struct rte_eth_dev *dev)
42ccdcba53SNélio Laranjeiro {
43fa2e14d4SViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
443f8cb05dSAdrien Mazarguil 	unsigned int ifindex;
45ccdcba53SNélio Laranjeiro 
468e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv);
478e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(priv->if_index);
48f5f4c482SXueming Li 	if (priv->master && priv->sh->bond.ifindex > 0)
49f5f4c482SXueming Li 		ifindex = priv->sh->bond.ifindex;
50f5f4c482SXueming Li 	else
51f5f4c482SXueming Li 		ifindex = priv->if_index;
523f8cb05dSAdrien Mazarguil 	if (!ifindex)
53fa2e14d4SViacheslav Ovsiienko 		rte_errno = ENXIO;
543f8cb05dSAdrien Mazarguil 	return ifindex;
55ccdcba53SNélio Laranjeiro }
56ccdcba53SNélio Laranjeiro 
57ccdcba53SNélio Laranjeiro /**
587b2423cdSNélio Laranjeiro  * DPDK callback for Ethernet device configuration.
59e60fbd5bSAdrien Mazarguil  *
60e60fbd5bSAdrien Mazarguil  * @param dev
61e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
62e60fbd5bSAdrien Mazarguil  *
63e60fbd5bSAdrien Mazarguil  * @return
64a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
65e60fbd5bSAdrien Mazarguil  */
667b2423cdSNélio Laranjeiro int
677b2423cdSNélio Laranjeiro mlx5_dev_configure(struct rte_eth_dev *dev)
68e60fbd5bSAdrien Mazarguil {
69dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
70e60fbd5bSAdrien Mazarguil 	unsigned int rxqs_n = dev->data->nb_rx_queues;
71e60fbd5bSAdrien Mazarguil 	unsigned int txqs_n = dev->data->nb_tx_queues;
7229c1d8bbSNélio Laranjeiro 	const uint8_t use_app_rss_key =
7321e3a974SShahaf Shuler 		!!dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key;
74a6d83b6aSNélio Laranjeiro 	int ret = 0;
75e60fbd5bSAdrien Mazarguil 
7629c1d8bbSNélio Laranjeiro 	if (use_app_rss_key &&
7729c1d8bbSNélio Laranjeiro 	    (dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key_len !=
78c388a2f6SNelio Laranjeiro 	     MLX5_RSS_HASH_KEY_LEN)) {
79c388a2f6SNelio Laranjeiro 		DRV_LOG(ERR, "port %u RSS key len must be %s Bytes long",
80c388a2f6SNelio Laranjeiro 			dev->data->port_id, RTE_STR(MLX5_RSS_HASH_KEY_LEN));
81a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
82a6d83b6aSNélio Laranjeiro 		return -rte_errno;
8329c1d8bbSNélio Laranjeiro 	}
8429c1d8bbSNélio Laranjeiro 	priv->rss_conf.rss_key =
8583c2047cSSuanming Mou 		mlx5_realloc(priv->rss_conf.rss_key, MLX5_MEM_RTE,
8683c2047cSSuanming Mou 			    MLX5_RSS_HASH_KEY_LEN, 0, SOCKET_ID_ANY);
8729c1d8bbSNélio Laranjeiro 	if (!priv->rss_conf.rss_key) {
88a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot allocate RSS hash key memory (%u)",
890f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
90a6d83b6aSNélio Laranjeiro 		rte_errno = ENOMEM;
91a6d83b6aSNélio Laranjeiro 		return -rte_errno;
9229c1d8bbSNélio Laranjeiro 	}
938b945a7fSPavan Nikhilesh 
94af270529SThomas Monjalon 	if ((dev->data->dev_conf.txmode.offloads &
95295968d1SFerruh Yigit 			RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP) &&
96af270529SThomas Monjalon 			rte_mbuf_dyn_tx_timestamp_register(NULL, NULL) != 0) {
97af270529SThomas Monjalon 		DRV_LOG(ERR, "port %u cannot register Tx timestamp field/flag",
98af270529SThomas Monjalon 			dev->data->port_id);
99af270529SThomas Monjalon 		return -rte_errno;
100af270529SThomas Monjalon 	}
10129c1d8bbSNélio Laranjeiro 	memcpy(priv->rss_conf.rss_key,
10229c1d8bbSNélio Laranjeiro 	       use_app_rss_key ?
10329c1d8bbSNélio Laranjeiro 	       dev->data->dev_conf.rx_adv_conf.rss_conf.rss_key :
10429c1d8bbSNélio Laranjeiro 	       rss_hash_default_key,
105c388a2f6SNelio Laranjeiro 	       MLX5_RSS_HASH_KEY_LEN);
106c388a2f6SNelio Laranjeiro 	priv->rss_conf.rss_key_len = MLX5_RSS_HASH_KEY_LEN;
10729c1d8bbSNélio Laranjeiro 	priv->rss_conf.rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
1084cda06c3SXueming Li 	priv->rxq_privs = mlx5_realloc(priv->rxq_privs,
1094cda06c3SXueming Li 				       MLX5_MEM_RTE | MLX5_MEM_ZERO,
1104cda06c3SXueming Li 				       sizeof(void *) * rxqs_n, 0,
1114cda06c3SXueming Li 				       SOCKET_ID_ANY);
1124cda06c3SXueming Li 	if (priv->rxq_privs == NULL) {
1134cda06c3SXueming Li 		DRV_LOG(ERR, "port %u cannot allocate rxq private data",
1144cda06c3SXueming Li 			dev->data->port_id);
1154cda06c3SXueming Li 		rte_errno = ENOMEM;
1164cda06c3SXueming Li 		return -rte_errno;
1174cda06c3SXueming Li 	}
118e60fbd5bSAdrien Mazarguil 	priv->txqs = (void *)dev->data->tx_queues;
119e60fbd5bSAdrien Mazarguil 	if (txqs_n != priv->txqs_n) {
120a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Tx queues number update: %u -> %u",
1210f99970bSNélio Laranjeiro 			dev->data->port_id, priv->txqs_n, txqs_n);
122e60fbd5bSAdrien Mazarguil 		priv->txqs_n = txqs_n;
123e60fbd5bSAdrien Mazarguil 	}
1247fe24446SShahaf Shuler 	if (rxqs_n > priv->config.ind_table_max_size) {
125a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
1260f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
127a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
128a6d83b6aSNélio Laranjeiro 		return -rte_errno;
129634efbc2SNelio Laranjeiro 	}
13009ba4c58SDekel Peled 	if (rxqs_n != priv->rxqs_n) {
131a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
1320f99970bSNélio Laranjeiro 			dev->data->port_id, priv->rxqs_n, rxqs_n);
133e60fbd5bSAdrien Mazarguil 		priv->rxqs_n = rxqs_n;
13463bd1629SOri Kam 	}
13563bd1629SOri Kam 	priv->skip_default_rss_reta = 0;
13663bd1629SOri Kam 	ret = mlx5_proc_priv_init(dev);
13763bd1629SOri Kam 	if (ret)
13863bd1629SOri Kam 		return ret;
13963bd1629SOri Kam 	return 0;
14063bd1629SOri Kam }
14163bd1629SOri Kam 
14263bd1629SOri Kam /**
14363bd1629SOri Kam  * Configure default RSS reta.
14463bd1629SOri Kam  *
14563bd1629SOri Kam  * @param dev
14663bd1629SOri Kam  *   Pointer to Ethernet device structure.
14763bd1629SOri Kam  *
14863bd1629SOri Kam  * @return
14963bd1629SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
15063bd1629SOri Kam  */
15163bd1629SOri Kam int
15263bd1629SOri Kam mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
15363bd1629SOri Kam {
15463bd1629SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
15563bd1629SOri Kam 	unsigned int rxqs_n = dev->data->nb_rx_queues;
15663bd1629SOri Kam 	unsigned int i;
15763bd1629SOri Kam 	unsigned int j;
15863bd1629SOri Kam 	unsigned int reta_idx_n;
15963bd1629SOri Kam 	int ret = 0;
16063bd1629SOri Kam 	unsigned int *rss_queue_arr = NULL;
16163bd1629SOri Kam 	unsigned int rss_queue_n = 0;
16263bd1629SOri Kam 
16363bd1629SOri Kam 	if (priv->skip_default_rss_reta)
16463bd1629SOri Kam 		return ret;
16583c2047cSSuanming Mou 	rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0,
16683c2047cSSuanming Mou 				    SOCKET_ID_ANY);
16763bd1629SOri Kam 	if (!rss_queue_arr) {
16863bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)",
16963bd1629SOri Kam 			dev->data->port_id, rxqs_n);
17063bd1629SOri Kam 		rte_errno = ENOMEM;
17163bd1629SOri Kam 		return -rte_errno;
17263bd1629SOri Kam 	}
17363bd1629SOri Kam 	for (i = 0, j = 0; i < rxqs_n; i++) {
1745cf0707fSXueming Li 		struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, i);
17563bd1629SOri Kam 
176bf864e82STonghao Zhang 		if (rxq_ctrl && rxq_ctrl->type == MLX5_RXQ_TYPE_STANDARD)
17763bd1629SOri Kam 			rss_queue_arr[j++] = i;
17863bd1629SOri Kam 	}
17963bd1629SOri Kam 	rss_queue_n = j;
18063bd1629SOri Kam 	if (rss_queue_n > priv->config.ind_table_max_size) {
18163bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
18263bd1629SOri Kam 			dev->data->port_id, rss_queue_n);
18363bd1629SOri Kam 		rte_errno = EINVAL;
18483c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
18563bd1629SOri Kam 		return -rte_errno;
18663bd1629SOri Kam 	}
18763bd1629SOri Kam 	DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
18863bd1629SOri Kam 		dev->data->port_id, priv->rxqs_n, rxqs_n);
18963bd1629SOri Kam 	priv->rxqs_n = rxqs_n;
19009ba4c58SDekel Peled 	/*
19109ba4c58SDekel Peled 	 * If the requested number of RX queues is not a power of two,
19209ba4c58SDekel Peled 	 * use the maximum indirection table size for better balancing.
19309ba4c58SDekel Peled 	 * The result is always rounded to the next power of two.
19409ba4c58SDekel Peled 	 */
19563bd1629SOri Kam 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
1967fe24446SShahaf Shuler 				priv->config.ind_table_max_size :
19763bd1629SOri Kam 				rss_queue_n));
198a6d83b6aSNélio Laranjeiro 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
19963bd1629SOri Kam 	if (ret) {
20083c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
201a6d83b6aSNélio Laranjeiro 		return ret;
20263bd1629SOri Kam 	}
20309ba4c58SDekel Peled 	/*
20409ba4c58SDekel Peled 	 * When the number of RX queues is not a power of two,
20509ba4c58SDekel Peled 	 * the remaining table entries are padded with reused WQs
20609ba4c58SDekel Peled 	 * and hashes are not spread uniformly.
20709ba4c58SDekel Peled 	 */
208634efbc2SNelio Laranjeiro 	for (i = 0, j = 0; (i != reta_idx_n); ++i) {
20963bd1629SOri Kam 		(*priv->reta_idx)[i] = rss_queue_arr[j];
21063bd1629SOri Kam 		if (++j == rss_queue_n)
211634efbc2SNelio Laranjeiro 			j = 0;
212634efbc2SNelio Laranjeiro 	}
21383c2047cSSuanming Mou 	mlx5_free(rss_queue_arr);
214120dc4a7SYongseok Koh 	return ret;
215e60fbd5bSAdrien Mazarguil }
216e60fbd5bSAdrien Mazarguil 
217e60fbd5bSAdrien Mazarguil /**
218d11d651fSShahaf Shuler  * Sets default tuning parameters.
219d11d651fSShahaf Shuler  *
220d11d651fSShahaf Shuler  * @param dev
221d11d651fSShahaf Shuler  *   Pointer to Ethernet device.
222d11d651fSShahaf Shuler  * @param[out] info
223d11d651fSShahaf Shuler  *   Info structure output buffer.
224d11d651fSShahaf Shuler  */
225d11d651fSShahaf Shuler static void
226d11d651fSShahaf Shuler mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
227d11d651fSShahaf Shuler {
228dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
229d11d651fSShahaf Shuler 
230d11d651fSShahaf Shuler 	/* Minimum CPU utilization. */
231d11d651fSShahaf Shuler 	info->default_rxportconf.ring_size = 256;
232d11d651fSShahaf Shuler 	info->default_txportconf.ring_size = 256;
233f078ceb6SViacheslav Ovsiienko 	info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST;
234f078ceb6SViacheslav Ovsiienko 	info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST;
235295968d1SFerruh Yigit 	if ((priv->link_speed_capa & RTE_ETH_LINK_SPEED_200G) |
236295968d1SFerruh Yigit 		(priv->link_speed_capa & RTE_ETH_LINK_SPEED_100G)) {
237d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 16;
238d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 16;
239d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
240d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
241d11d651fSShahaf Shuler 			/* Max Throughput. */
242d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 2048;
243d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 2048;
244d11d651fSShahaf Shuler 		}
245d11d651fSShahaf Shuler 	} else {
246d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 8;
247d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 8;
248d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
249d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
250d11d651fSShahaf Shuler 			/* Max Throughput. */
251d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 4096;
252d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 4096;
253d11d651fSShahaf Shuler 		}
254d11d651fSShahaf Shuler 	}
255d11d651fSShahaf Shuler }
256d11d651fSShahaf Shuler 
257d11d651fSShahaf Shuler /**
258cb9cb61eSViacheslav Ovsiienko  * Sets tx mbuf limiting parameters.
259cb9cb61eSViacheslav Ovsiienko  *
260cb9cb61eSViacheslav Ovsiienko  * @param dev
261cb9cb61eSViacheslav Ovsiienko  *   Pointer to Ethernet device.
262cb9cb61eSViacheslav Ovsiienko  * @param[out] info
263cb9cb61eSViacheslav Ovsiienko  *   Info structure output buffer.
264cb9cb61eSViacheslav Ovsiienko  */
265cb9cb61eSViacheslav Ovsiienko static void
266cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
267cb9cb61eSViacheslav Ovsiienko {
268cb9cb61eSViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
269cb9cb61eSViacheslav Ovsiienko 	struct mlx5_dev_config *config = &priv->config;
270cb9cb61eSViacheslav Ovsiienko 	unsigned int inlen;
271cb9cb61eSViacheslav Ovsiienko 	uint16_t nb_max;
272cb9cb61eSViacheslav Ovsiienko 
273cb9cb61eSViacheslav Ovsiienko 	inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ?
274cb9cb61eSViacheslav Ovsiienko 		MLX5_SEND_DEF_INLINE_LEN :
275cb9cb61eSViacheslav Ovsiienko 		(unsigned int)config->txq_inline_max;
2768e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(config->txq_inline_min >= 0);
277cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min);
278cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX +
279cb9cb61eSViacheslav Ovsiienko 			       MLX5_ESEG_MIN_INLINE_SIZE -
280cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_CSEG_SIZE -
281cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_ESEG_SIZE -
282cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_DSEG_SIZE * 2);
283cb9cb61eSViacheslav Ovsiienko 	nb_max = (MLX5_WQE_SIZE_MAX +
284cb9cb61eSViacheslav Ovsiienko 		  MLX5_ESEG_MIN_INLINE_SIZE -
285cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_CSEG_SIZE -
286cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_ESEG_SIZE -
287cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_DSEG_SIZE -
288cb9cb61eSViacheslav Ovsiienko 		  inlen) / MLX5_WSEG_SIZE;
289cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_seg_max = nb_max;
290cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_mtu_seg_max = nb_max;
291cb9cb61eSViacheslav Ovsiienko }
292cb9cb61eSViacheslav Ovsiienko 
293cb9cb61eSViacheslav Ovsiienko /**
294e60fbd5bSAdrien Mazarguil  * DPDK callback to get information about the device.
295e60fbd5bSAdrien Mazarguil  *
296e60fbd5bSAdrien Mazarguil  * @param dev
297e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
298e60fbd5bSAdrien Mazarguil  * @param[out] info
299e60fbd5bSAdrien Mazarguil  *   Info structure output buffer.
300e60fbd5bSAdrien Mazarguil  */
301bdad90d1SIvan Ilchenko int
302e60fbd5bSAdrien Mazarguil mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
303e60fbd5bSAdrien Mazarguil {
304dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
3057fe24446SShahaf Shuler 	struct mlx5_dev_config *config = &priv->config;
306e60fbd5bSAdrien Mazarguil 	unsigned int max;
307e60fbd5bSAdrien Mazarguil 
308e60fbd5bSAdrien Mazarguil 	/* FIXME: we should ask the device for these values. */
309e60fbd5bSAdrien Mazarguil 	info->min_rx_bufsize = 32;
310e60fbd5bSAdrien Mazarguil 	info->max_rx_pktlen = 65536;
3111c7e57f9SDekel Peled 	info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE;
312e60fbd5bSAdrien Mazarguil 	/*
313e60fbd5bSAdrien Mazarguil 	 * Since we need one CQ per QP, the limit is the minimum number
314e60fbd5bSAdrien Mazarguil 	 * between the two values.
315e60fbd5bSAdrien Mazarguil 	 */
316e85f623eSOphir Munk 	max = RTE_MIN(priv->sh->device_attr.max_cq,
317e85f623eSOphir Munk 		      priv->sh->device_attr.max_qp);
318b689a781SThomas Monjalon 	/* max_rx_queues is uint16_t. */
319b689a781SThomas Monjalon 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
320e60fbd5bSAdrien Mazarguil 	info->max_rx_queues = max;
321e60fbd5bSAdrien Mazarguil 	info->max_tx_queues = max;
32218c01b98SNélio Laranjeiro 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
323af4f09f2SNélio Laranjeiro 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
3246c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
325ddb03843SViacheslav Ovsiienko 	info->rx_seg_capa.multi_pools = !config->mprq.enabled;
326ddb03843SViacheslav Ovsiienko 	info->rx_seg_capa.offset_allowed = !config->mprq.enabled;
3276c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.offset_align_log2 = 0;
32817ed314cSMatan Azrad 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
32917b843ebSShahaf Shuler 				 info->rx_queue_offload_capa);
330af4f09f2SNélio Laranjeiro 	info->tx_offload_capa = mlx5_get_tx_port_offloads(dev);
331ec4e11d4SDmitry Kozlyuk 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
332fa2e14d4SViacheslav Ovsiienko 	info->if_index = mlx5_ifindex(dev);
333d365210eSYongseok Koh 	info->reta_size = priv->reta_idx_n ?
3347fe24446SShahaf Shuler 		priv->reta_idx_n : config->ind_table_max_size;
335c388a2f6SNelio Laranjeiro 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
33675ef62a9SNélio Laranjeiro 	info->speed_capa = priv->link_speed_capa;
337b233b027SShahaf Shuler 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
338d11d651fSShahaf Shuler 	mlx5_set_default_params(dev, info);
339cb9cb61eSViacheslav Ovsiienko 	mlx5_set_txlimit_params(dev, info);
34053820561SMichael Baum 	if (priv->sh->cdev->config.hca_attr.mem_rq_rmp &&
34109c25553SXueming Li 	    priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new)
34209c25553SXueming Li 		info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE;
3432b730263SAdrien Mazarguil 	info->switch_info.name = dev->data->name;
3442b730263SAdrien Mazarguil 	info->switch_info.domain_id = priv->domain_id;
3452b730263SAdrien Mazarguil 	info->switch_info.port_id = priv->representor_id;
34609c25553SXueming Li 	info->switch_info.rx_domain = 0; /* No sub Rx domains. */
3472b730263SAdrien Mazarguil 	if (priv->representor) {
348f7e95215SViacheslav Ovsiienko 		uint16_t port_id;
3492b730263SAdrien Mazarguil 
35056bb3c84SXueming Li 		MLX5_ETH_FOREACH_DEV(port_id, dev->device) {
351dbeba4cfSThomas Monjalon 			struct mlx5_priv *opriv =
352f7e95215SViacheslav Ovsiienko 				rte_eth_devices[port_id].data->dev_private;
3532b730263SAdrien Mazarguil 
3542b730263SAdrien Mazarguil 			if (!opriv ||
3552b730263SAdrien Mazarguil 			    opriv->representor ||
356f7e95215SViacheslav Ovsiienko 			    opriv->sh != priv->sh ||
3572b730263SAdrien Mazarguil 			    opriv->domain_id != priv->domain_id)
3582b730263SAdrien Mazarguil 				continue;
3592b730263SAdrien Mazarguil 			/*
3602b730263SAdrien Mazarguil 			 * Override switch name with that of the master
3612b730263SAdrien Mazarguil 			 * device.
3622b730263SAdrien Mazarguil 			 */
3632b730263SAdrien Mazarguil 			info->switch_info.name = opriv->dev_data->name;
3642b730263SAdrien Mazarguil 			break;
3652b730263SAdrien Mazarguil 		}
3662b730263SAdrien Mazarguil 	}
367bdad90d1SIvan Ilchenko 	return 0;
368e60fbd5bSAdrien Mazarguil }
369e60fbd5bSAdrien Mazarguil 
370fb732b0aSNélio Laranjeiro /**
371cb95feefSXueming Li  * Calculate representor ID from port switch info.
372cb95feefSXueming Li  *
373cb95feefSXueming Li  * Uint16 representor ID bits definition:
374cb95feefSXueming Li  *   pf: 2
375cb95feefSXueming Li  *   type: 2
376cb95feefSXueming Li  *   vf/sf: 12
377cb95feefSXueming Li  *
378cb95feefSXueming Li  * @param info
379cb95feefSXueming Li  *   Port switch info.
38091766faeSXueming Li  * @param hpf_type
38191766faeSXueming Li  *   Use this type if port is HPF.
382cb95feefSXueming Li  *
383cb95feefSXueming Li  * @return
384cb95feefSXueming Li  *   Encoded representor ID.
385cb95feefSXueming Li  */
386cb95feefSXueming Li uint16_t
38791766faeSXueming Li mlx5_representor_id_encode(const struct mlx5_switch_info *info,
38891766faeSXueming Li 			   enum rte_eth_representor_type hpf_type)
389cb95feefSXueming Li {
390cb95feefSXueming Li 	enum rte_eth_representor_type type = RTE_ETH_REPRESENTOR_VF;
391cb95feefSXueming Li 	uint16_t repr = info->port_name;
392cb95feefSXueming Li 
393cb95feefSXueming Li 	if (info->representor == 0)
394cb95feefSXueming Li 		return UINT16_MAX;
395cb95feefSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFSF)
396cb95feefSXueming Li 		type = RTE_ETH_REPRESENTOR_SF;
39791766faeSXueming Li 	if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_PFHPF) {
39891766faeSXueming Li 		type = hpf_type;
399cb95feefSXueming Li 		repr = UINT16_MAX;
40091766faeSXueming Li 	}
401cb95feefSXueming Li 	return MLX5_REPRESENTOR_ID(info->pf_num, type, repr);
402cb95feefSXueming Li }
403cb95feefSXueming Li 
404cb95feefSXueming Li /**
405cb95feefSXueming Li  * DPDK callback to get information about representor.
406cb95feefSXueming Li  *
407cb95feefSXueming Li  * Representor ID bits definition:
408cb95feefSXueming Li  *   vf/sf: 12
409cb95feefSXueming Li  *   type: 2
410cb95feefSXueming Li  *   pf: 2
411cb95feefSXueming Li  *
412cb95feefSXueming Li  * @param dev
413cb95feefSXueming Li  *   Pointer to Ethernet device structure.
414cb95feefSXueming Li  * @param[out] info
415cb95feefSXueming Li  *   Nullable info structure output buffer.
416cb95feefSXueming Li  *
417cb95feefSXueming Li  * @return
418cb95feefSXueming Li  *   negative on error, or the number of representor ranges.
419cb95feefSXueming Li  */
420cb95feefSXueming Li int
421cb95feefSXueming Li mlx5_representor_info_get(struct rte_eth_dev *dev,
422cb95feefSXueming Li 			  struct rte_eth_representor_info *info)
423cb95feefSXueming Li {
424cb95feefSXueming Li 	struct mlx5_priv *priv = dev->data->dev_private;
42591766faeSXueming Li 	int n_type = 4; /* Representor types, VF, HPF@VF, SF and HPF@SF. */
426cb95feefSXueming Li 	int n_pf = 2; /* Number of PFs. */
427cb95feefSXueming Li 	int i = 0, pf;
42810eaf41dSViacheslav Galaktionov 	int n_entries;
429cb95feefSXueming Li 
430cb95feefSXueming Li 	if (info == NULL)
431cb95feefSXueming Li 		goto out;
43210eaf41dSViacheslav Galaktionov 
43310eaf41dSViacheslav Galaktionov 	n_entries = n_type * n_pf;
43410eaf41dSViacheslav Galaktionov 	if ((uint32_t)n_entries > info->nb_ranges_alloc)
43510eaf41dSViacheslav Galaktionov 		n_entries = info->nb_ranges_alloc;
43610eaf41dSViacheslav Galaktionov 
437cb95feefSXueming Li 	info->controller = 0;
438cb95feefSXueming Li 	info->pf = priv->pf_bond >= 0 ? priv->pf_bond : 0;
439cb95feefSXueming Li 	for (pf = 0; pf < n_pf; ++pf) {
440cb95feefSXueming Li 		/* VF range. */
441cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
442cb95feefSXueming Li 		info->ranges[i].controller = 0;
443cb95feefSXueming Li 		info->ranges[i].pf = pf;
444cb95feefSXueming Li 		info->ranges[i].vf = 0;
445cb95feefSXueming Li 		info->ranges[i].id_base =
446cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
447cb95feefSXueming Li 		info->ranges[i].id_end =
448cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
449cb95feefSXueming Li 		snprintf(info->ranges[i].name,
450cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
451cb95feefSXueming Li 		i++;
45210eaf41dSViacheslav Galaktionov 		if (i == n_entries)
45310eaf41dSViacheslav Galaktionov 			break;
45491766faeSXueming Li 		/* HPF range of VF type. */
455cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
456cb95feefSXueming Li 		info->ranges[i].controller = 0;
457cb95feefSXueming Li 		info->ranges[i].pf = pf;
458cb95feefSXueming Li 		info->ranges[i].vf = UINT16_MAX;
459cb95feefSXueming Li 		info->ranges[i].id_base =
460cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
461cb95feefSXueming Li 		info->ranges[i].id_end =
462cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
463cb95feefSXueming Li 		snprintf(info->ranges[i].name,
464cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
465cb95feefSXueming Li 		i++;
46610eaf41dSViacheslav Galaktionov 		if (i == n_entries)
46710eaf41dSViacheslav Galaktionov 			break;
468cb95feefSXueming Li 		/* SF range. */
469cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
470cb95feefSXueming Li 		info->ranges[i].controller = 0;
471cb95feefSXueming Li 		info->ranges[i].pf = pf;
472cb95feefSXueming Li 		info->ranges[i].vf = 0;
473cb95feefSXueming Li 		info->ranges[i].id_base =
474cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
475cb95feefSXueming Li 		info->ranges[i].id_end =
476cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
477cb95feefSXueming Li 		snprintf(info->ranges[i].name,
478cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
479cb95feefSXueming Li 		i++;
48010eaf41dSViacheslav Galaktionov 		if (i == n_entries)
48110eaf41dSViacheslav Galaktionov 			break;
48291766faeSXueming Li 		/* HPF range of SF type. */
48391766faeSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
48491766faeSXueming Li 		info->ranges[i].controller = 0;
48591766faeSXueming Li 		info->ranges[i].pf = pf;
48691766faeSXueming Li 		info->ranges[i].vf = UINT16_MAX;
48791766faeSXueming Li 		info->ranges[i].id_base =
48891766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
48991766faeSXueming Li 		info->ranges[i].id_end =
49091766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
49191766faeSXueming Li 		snprintf(info->ranges[i].name,
49291766faeSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
49391766faeSXueming Li 		i++;
49410eaf41dSViacheslav Galaktionov 		if (i == n_entries)
49510eaf41dSViacheslav Galaktionov 			break;
496cb95feefSXueming Li 	}
49710eaf41dSViacheslav Galaktionov 	info->nb_ranges = i;
498cb95feefSXueming Li out:
499cb95feefSXueming Li 	return n_type * n_pf;
500cb95feefSXueming Li }
501cb95feefSXueming Li 
502cb95feefSXueming Li /**
503714bf46eSThomas Monjalon  * Get firmware version of a device.
504714bf46eSThomas Monjalon  *
505714bf46eSThomas Monjalon  * @param dev
506714bf46eSThomas Monjalon  *   Ethernet device port.
507714bf46eSThomas Monjalon  * @param fw_ver
508714bf46eSThomas Monjalon  *   String output allocated by caller.
509714bf46eSThomas Monjalon  * @param fw_size
510714bf46eSThomas Monjalon  *   Size of the output string, including terminating null byte.
511714bf46eSThomas Monjalon  *
512714bf46eSThomas Monjalon  * @return
513714bf46eSThomas Monjalon  *   0 on success, or the size of the non truncated string if too big.
514714bf46eSThomas Monjalon  */
5151256805dSOphir Munk int
5161256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
517714bf46eSThomas Monjalon {
518dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
519e85f623eSOphir Munk 	struct mlx5_dev_attr *attr = &priv->sh->device_attr;
520714bf46eSThomas Monjalon 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
521714bf46eSThomas Monjalon 
522714bf46eSThomas Monjalon 	if (fw_size < size)
523714bf46eSThomas Monjalon 		return size;
524714bf46eSThomas Monjalon 	if (fw_ver != NULL)
525714bf46eSThomas Monjalon 		strlcpy(fw_ver, attr->fw_ver, fw_size);
526714bf46eSThomas Monjalon 	return 0;
527714bf46eSThomas Monjalon }
528714bf46eSThomas Monjalon 
529714bf46eSThomas Monjalon /**
530fb732b0aSNélio Laranjeiro  * Get supported packet types.
531fb732b0aSNélio Laranjeiro  *
532fb732b0aSNélio Laranjeiro  * @param dev
533fb732b0aSNélio Laranjeiro  *   Pointer to Ethernet device structure.
534fb732b0aSNélio Laranjeiro  *
535fb732b0aSNélio Laranjeiro  * @return
536fb732b0aSNélio Laranjeiro  *   A pointer to the supported Packet types array.
537fb732b0aSNélio Laranjeiro  */
53878a38edfSJianfeng Tan const uint32_t *
53978a38edfSJianfeng Tan mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
54078a38edfSJianfeng Tan {
54178a38edfSJianfeng Tan 	static const uint32_t ptypes[] = {
54278a38edfSJianfeng Tan 		/* refers to rxq_cq_to_pkt_type() */
543ea16068cSYongseok Koh 		RTE_PTYPE_L2_ETHER,
544c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
545c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
546ea16068cSYongseok Koh 		RTE_PTYPE_L4_NONFRAG,
547ea16068cSYongseok Koh 		RTE_PTYPE_L4_FRAG,
548ea16068cSYongseok Koh 		RTE_PTYPE_L4_TCP,
549ea16068cSYongseok Koh 		RTE_PTYPE_L4_UDP,
550c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
551c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
552ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_NONFRAG,
553ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_FRAG,
554ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_TCP,
555ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_UDP,
55678a38edfSJianfeng Tan 		RTE_PTYPE_UNKNOWN
55778a38edfSJianfeng Tan 	};
55878a38edfSJianfeng Tan 
5596cb559d6SYongseok Koh 	if (dev->rx_pkt_burst == mlx5_rx_burst ||
5607d6bf6b8SYongseok Koh 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq ||
5610f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_vec ||
5620f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec)
56378a38edfSJianfeng Tan 		return ptypes;
56478a38edfSJianfeng Tan 	return NULL;
56578a38edfSJianfeng Tan }
56678a38edfSJianfeng Tan 
567e60fbd5bSAdrien Mazarguil /**
568cf37ca95SAdrien Mazarguil  * DPDK callback to change the MTU.
569cf37ca95SAdrien Mazarguil  *
570cf37ca95SAdrien Mazarguil  * @param dev
571cf37ca95SAdrien Mazarguil  *   Pointer to Ethernet device structure.
572cf37ca95SAdrien Mazarguil  * @param in_mtu
573cf37ca95SAdrien Mazarguil  *   New MTU.
574cf37ca95SAdrien Mazarguil  *
575cf37ca95SAdrien Mazarguil  * @return
576a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
577cf37ca95SAdrien Mazarguil  */
578cf37ca95SAdrien Mazarguil int
579cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
580cf37ca95SAdrien Mazarguil {
581dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
582a6d83b6aSNélio Laranjeiro 	uint16_t kern_mtu = 0;
583a6d83b6aSNélio Laranjeiro 	int ret;
584cf37ca95SAdrien Mazarguil 
585af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
586a0edafe4SNelio Laranjeiro 	if (ret)
587a6d83b6aSNélio Laranjeiro 		return ret;
588cf37ca95SAdrien Mazarguil 	/* Set kernel interface MTU first. */
589af4f09f2SNélio Laranjeiro 	ret = mlx5_set_mtu(dev, mtu);
590a0edafe4SNelio Laranjeiro 	if (ret)
591a6d83b6aSNélio Laranjeiro 		return ret;
592af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
593a0edafe4SNelio Laranjeiro 	if (ret)
594a6d83b6aSNélio Laranjeiro 		return ret;
595a0edafe4SNelio Laranjeiro 	if (kern_mtu == mtu) {
596a0edafe4SNelio Laranjeiro 		priv->mtu = mtu;
597a170a30dSNélio Laranjeiro 		DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
598a170a30dSNélio Laranjeiro 			dev->data->port_id, mtu);
599a0edafe4SNelio Laranjeiro 		return 0;
600a6d83b6aSNélio Laranjeiro 	}
601a6d83b6aSNélio Laranjeiro 	rte_errno = EAGAIN;
602a6d83b6aSNélio Laranjeiro 	return -rte_errno;
603cf37ca95SAdrien Mazarguil }
604cf37ca95SAdrien Mazarguil 
605cf37ca95SAdrien Mazarguil /**
606cdab90cbSNélio Laranjeiro  * Configure the RX function to use.
607cdab90cbSNélio Laranjeiro  *
608aee1b165SXueming Li  * @param dev
609af4f09f2SNélio Laranjeiro  *   Pointer to private data structure.
6101cfa649bSShahaf Shuler  *
6111cfa649bSShahaf Shuler  * @return
6121cfa649bSShahaf Shuler  *   Pointer to selected Rx burst function.
613cdab90cbSNélio Laranjeiro  */
6141cfa649bSShahaf Shuler eth_rx_burst_t
615af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev)
616cdab90cbSNélio Laranjeiro {
6171cfa649bSShahaf Shuler 	eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst;
6181cfa649bSShahaf Shuler 
6198e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(dev != NULL);
620af4f09f2SNélio Laranjeiro 	if (mlx5_check_vec_rx_support(dev) > 0) {
6210f20acbfSAlexander Kozyrev 		if (mlx5_mprq_enabled(dev)) {
6220f20acbfSAlexander Kozyrev 			rx_pkt_burst = mlx5_rx_burst_mprq_vec;
6230f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6240f20acbfSAlexander Kozyrev 				" MPRQ Rx function", dev->data->port_id);
6250f20acbfSAlexander Kozyrev 		} else {
6261cfa649bSShahaf Shuler 			rx_pkt_burst = mlx5_rx_burst_vec;
6270f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6280f20acbfSAlexander Kozyrev 				" SPRQ Rx function", dev->data->port_id);
6290f20acbfSAlexander Kozyrev 		}
6307d6bf6b8SYongseok Koh 	} else if (mlx5_mprq_enabled(dev)) {
6317d6bf6b8SYongseok Koh 		rx_pkt_burst = mlx5_rx_burst_mprq;
6320f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected MPRQ Rx function",
6330f20acbfSAlexander Kozyrev 			dev->data->port_id);
6340f20acbfSAlexander Kozyrev 	} else {
6350f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected SPRQ Rx function",
6360f20acbfSAlexander Kozyrev 			dev->data->port_id);
637cdab90cbSNélio Laranjeiro 	}
6381cfa649bSShahaf Shuler 	return rx_pkt_burst;
6396cb559d6SYongseok Koh }
640d3e0f392SMatan Azrad 
641d3e0f392SMatan Azrad /**
64209a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by port id.
6432e4c987aSOri Kam  *
6442e4c987aSOri Kam  * @param[in] port
6452e4c987aSOri Kam  *   Device port id.
6465e61bcddSViacheslav Ovsiienko  * @param[in] valid
6475e61bcddSViacheslav Ovsiienko  *   Device port id is valid, skip check. This flag is useful
6485e61bcddSViacheslav Ovsiienko  *   when trials are performed from probing and device is not
6495e61bcddSViacheslav Ovsiienko  *   flagged as valid yet (in attaching process).
6502e4c987aSOri Kam  * @param[out] es_domain_id
6512e4c987aSOri Kam  *   E-Switch domain id.
6522e4c987aSOri Kam  * @param[out] es_port_id
6532e4c987aSOri Kam  *   The port id of the port in the E-Switch.
6542e4c987aSOri Kam  *
6552e4c987aSOri Kam  * @return
65609a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
65709a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
6582e4c987aSOri Kam  */
65909a16bcaSViacheslav Ovsiienko struct mlx5_priv *
6605e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid)
6612e4c987aSOri Kam {
6622e4c987aSOri Kam 	struct rte_eth_dev *dev;
6632e4c987aSOri Kam 	struct mlx5_priv *priv;
6642e4c987aSOri Kam 
6652e4c987aSOri Kam 	if (port >= RTE_MAX_ETHPORTS) {
6662e4c987aSOri Kam 		rte_errno = EINVAL;
66709a16bcaSViacheslav Ovsiienko 		return NULL;
6682e4c987aSOri Kam 	}
6695e61bcddSViacheslav Ovsiienko 	if (!valid && !rte_eth_dev_is_valid_port(port)) {
6702e4c987aSOri Kam 		rte_errno = ENODEV;
67109a16bcaSViacheslav Ovsiienko 		return NULL;
6722e4c987aSOri Kam 	}
6732e4c987aSOri Kam 	dev = &rte_eth_devices[port];
6742e4c987aSOri Kam 	priv = dev->data->dev_private;
675*cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
6762e4c987aSOri Kam 		rte_errno = EINVAL;
67709a16bcaSViacheslav Ovsiienko 		return NULL;
6782e4c987aSOri Kam 	}
67909a16bcaSViacheslav Ovsiienko 	return priv;
68009a16bcaSViacheslav Ovsiienko }
68109a16bcaSViacheslav Ovsiienko 
68209a16bcaSViacheslav Ovsiienko /**
68309a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by device instance.
68409a16bcaSViacheslav Ovsiienko  *
68509a16bcaSViacheslav Ovsiienko  * @param[in] port
68609a16bcaSViacheslav Ovsiienko  *   Device port id.
68709a16bcaSViacheslav Ovsiienko  * @param[out] es_domain_id
68809a16bcaSViacheslav Ovsiienko  *   E-Switch domain id.
68909a16bcaSViacheslav Ovsiienko  * @param[out] es_port_id
69009a16bcaSViacheslav Ovsiienko  *   The port id of the port in the E-Switch.
69109a16bcaSViacheslav Ovsiienko  *
69209a16bcaSViacheslav Ovsiienko  * @return
69309a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
69409a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
69509a16bcaSViacheslav Ovsiienko  */
69609a16bcaSViacheslav Ovsiienko struct mlx5_priv *
69709a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
69809a16bcaSViacheslav Ovsiienko {
69909a16bcaSViacheslav Ovsiienko 	struct mlx5_priv *priv;
70009a16bcaSViacheslav Ovsiienko 
70109a16bcaSViacheslav Ovsiienko 	priv = dev->data->dev_private;
702*cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
70309a16bcaSViacheslav Ovsiienko 		rte_errno = EINVAL;
70409a16bcaSViacheslav Ovsiienko 		return NULL;
70509a16bcaSViacheslav Ovsiienko 	}
70609a16bcaSViacheslav Ovsiienko 	return priv;
7072e4c987aSOri Kam }
7082e4c987aSOri Kam 
7092e4c987aSOri Kam /**
710b6b3bf86SOri Kam  * DPDK callback to retrieve hairpin capabilities.
711b6b3bf86SOri Kam  *
712b6b3bf86SOri Kam  * @param dev
713b6b3bf86SOri Kam  *   Pointer to Ethernet device structure.
714b6b3bf86SOri Kam  * @param[out] cap
715b6b3bf86SOri Kam  *   Storage for hairpin capability data.
716b6b3bf86SOri Kam  *
717b6b3bf86SOri Kam  * @return
718b6b3bf86SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
719b6b3bf86SOri Kam  */
7201256805dSOphir Munk int
721b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
722b6b3bf86SOri Kam {
723b6b3bf86SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
724b00f7603SMichael Baum 	struct mlx5_dev_config *config = &priv->config;
725b6b3bf86SOri Kam 
7266dc0cbc6SMichael Baum 	if (!priv->sh->cdev->config.devx || !config->dest_tir ||
7276dc0cbc6SMichael Baum 	    !config->dv_flow_en) {
728b6b3bf86SOri Kam 		rte_errno = ENOTSUP;
729b6b3bf86SOri Kam 		return -rte_errno;
730b6b3bf86SOri Kam 	}
731b6b3bf86SOri Kam 	cap->max_nb_queues = UINT16_MAX;
732b6b3bf86SOri Kam 	cap->max_rx_2_tx = 1;
733b6b3bf86SOri Kam 	cap->max_tx_2_rx = 1;
734b6b3bf86SOri Kam 	cap->max_nb_desc = 8192;
735b6b3bf86SOri Kam 	return 0;
736b6b3bf86SOri Kam }
737