xref: /dpdk/drivers/net/mlx5/mlx5_ethdev.c (revision 11c73de9ef63b7671b40e8164c01a8952b5323b4)
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>
141f37cb2bSDavid Marchand #include <bus_pci_driver.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);
1143ef18940SBing 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 	}
13286647d46SThomas Monjalon 	if (priv->ext_rxqs && rxqs_n >= RTE_PMD_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,
13686647d46SThomas Monjalon 			RTE_PMD_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 {
398*11c73de9SDariusz Sosnowski 	enum rte_eth_representor_type type;
399cb95feefSXueming Li 	uint16_t repr = info->port_name;
400*11c73de9SDariusz Sosnowski 	int32_t pf = info->pf_num;
401cb95feefSXueming Li 
402*11c73de9SDariusz Sosnowski 	switch (info->name_type) {
403*11c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
404*11c73de9SDariusz Sosnowski 		if (!info->representor)
405cb95feefSXueming Li 			return UINT16_MAX;
406*11c73de9SDariusz Sosnowski 		type = RTE_ETH_REPRESENTOR_PF;
407*11c73de9SDariusz Sosnowski 		pf = info->mpesw_owner;
408*11c73de9SDariusz Sosnowski 		break;
409*11c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFSF:
410cb95feefSXueming Li 		type = RTE_ETH_REPRESENTOR_SF;
411*11c73de9SDariusz Sosnowski 		break;
412*11c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFHPF:
41391766faeSXueming Li 		type = hpf_type;
414cb95feefSXueming Li 		repr = UINT16_MAX;
415*11c73de9SDariusz Sosnowski 		break;
416*11c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFVF:
417*11c73de9SDariusz Sosnowski 	default:
418*11c73de9SDariusz Sosnowski 		type = RTE_ETH_REPRESENTOR_VF;
419*11c73de9SDariusz Sosnowski 		break;
42091766faeSXueming Li 	}
421*11c73de9SDariusz Sosnowski 	return MLX5_REPRESENTOR_ID(pf, type, repr);
422cb95feefSXueming Li }
423cb95feefSXueming Li 
424cb95feefSXueming Li /**
425cb95feefSXueming Li  * DPDK callback to get information about representor.
426cb95feefSXueming Li  *
427cb95feefSXueming Li  * Representor ID bits definition:
428cb95feefSXueming Li  *   vf/sf: 12
429cb95feefSXueming Li  *   type: 2
430cb95feefSXueming Li  *   pf: 2
431cb95feefSXueming Li  *
432cb95feefSXueming Li  * @param dev
433cb95feefSXueming Li  *   Pointer to Ethernet device structure.
434cb95feefSXueming Li  * @param[out] info
435cb95feefSXueming Li  *   Nullable info structure output buffer.
436cb95feefSXueming Li  *
437cb95feefSXueming Li  * @return
438cb95feefSXueming Li  *   negative on error, or the number of representor ranges.
439cb95feefSXueming Li  */
440cb95feefSXueming Li int
441cb95feefSXueming Li mlx5_representor_info_get(struct rte_eth_dev *dev,
442cb95feefSXueming Li 			  struct rte_eth_representor_info *info)
443cb95feefSXueming Li {
444cb95feefSXueming Li 	struct mlx5_priv *priv = dev->data->dev_private;
445*11c73de9SDariusz Sosnowski 	int n_type = 5; /* Representor types: PF, VF, HPF@VF, SF and HPF@SF. */
446cb95feefSXueming Li 	int n_pf = 2; /* Number of PFs. */
447cb95feefSXueming Li 	int i = 0, pf;
44810eaf41dSViacheslav Galaktionov 	int n_entries;
449cb95feefSXueming Li 
450cb95feefSXueming Li 	if (info == NULL)
451cb95feefSXueming Li 		goto out;
45210eaf41dSViacheslav Galaktionov 
45310eaf41dSViacheslav Galaktionov 	n_entries = n_type * n_pf;
45410eaf41dSViacheslav Galaktionov 	if ((uint32_t)n_entries > info->nb_ranges_alloc)
45510eaf41dSViacheslav Galaktionov 		n_entries = info->nb_ranges_alloc;
45610eaf41dSViacheslav Galaktionov 
457cb95feefSXueming Li 	info->controller = 0;
458*11c73de9SDariusz Sosnowski 	info->pf = 0;
459*11c73de9SDariusz Sosnowski 	if (mlx5_is_port_on_mpesw_device(priv)) {
460*11c73de9SDariusz Sosnowski 		info->pf = priv->mpesw_port;
461*11c73de9SDariusz Sosnowski 		/* PF range, both ports will show the same information. */
462*11c73de9SDariusz Sosnowski 		info->ranges[i].type = RTE_ETH_REPRESENTOR_PF;
463*11c73de9SDariusz Sosnowski 		info->ranges[i].controller = 0;
464*11c73de9SDariusz Sosnowski 		info->ranges[i].pf = priv->mpesw_owner + 1;
465*11c73de9SDariusz Sosnowski 		info->ranges[i].vf = 0;
466*11c73de9SDariusz Sosnowski 		/*
467*11c73de9SDariusz Sosnowski 		 * The representor indexes should be the values set of "priv->mpesw_port".
468*11c73de9SDariusz Sosnowski 		 * In the real case now, only 1 PF/UPLINK representor is supported.
469*11c73de9SDariusz Sosnowski 		 * The port index will always be the value of "owner + 1".
470*11c73de9SDariusz Sosnowski 		 */
471*11c73de9SDariusz Sosnowski 		info->ranges[i].id_base =
472*11c73de9SDariusz Sosnowski 			MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,
473*11c73de9SDariusz Sosnowski 					    info->ranges[i].pf);
474*11c73de9SDariusz Sosnowski 		info->ranges[i].id_end =
475*11c73de9SDariusz Sosnowski 			MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,
476*11c73de9SDariusz Sosnowski 					    info->ranges[i].pf);
477*11c73de9SDariusz Sosnowski 		snprintf(info->ranges[i].name, sizeof(info->ranges[i].name),
478*11c73de9SDariusz Sosnowski 			 "pf%d", info->ranges[i].pf);
479*11c73de9SDariusz Sosnowski 		i++;
480*11c73de9SDariusz Sosnowski 	} else if (priv->pf_bond >= 0)
481*11c73de9SDariusz Sosnowski 		info->pf = priv->pf_bond;
482cb95feefSXueming Li 	for (pf = 0; pf < n_pf; ++pf) {
483cb95feefSXueming Li 		/* VF range. */
484cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
485cb95feefSXueming Li 		info->ranges[i].controller = 0;
486cb95feefSXueming Li 		info->ranges[i].pf = pf;
487cb95feefSXueming Li 		info->ranges[i].vf = 0;
488cb95feefSXueming Li 		info->ranges[i].id_base =
489cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
490cb95feefSXueming Li 		info->ranges[i].id_end =
491cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
492cb95feefSXueming Li 		snprintf(info->ranges[i].name,
493cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
494cb95feefSXueming Li 		i++;
49510eaf41dSViacheslav Galaktionov 		if (i == n_entries)
49610eaf41dSViacheslav Galaktionov 			break;
49791766faeSXueming Li 		/* HPF range of VF type. */
498cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
499cb95feefSXueming Li 		info->ranges[i].controller = 0;
500cb95feefSXueming Li 		info->ranges[i].pf = pf;
501cb95feefSXueming Li 		info->ranges[i].vf = UINT16_MAX;
502cb95feefSXueming Li 		info->ranges[i].id_base =
503cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
504cb95feefSXueming Li 		info->ranges[i].id_end =
505cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
506cb95feefSXueming Li 		snprintf(info->ranges[i].name,
507cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
508cb95feefSXueming Li 		i++;
50910eaf41dSViacheslav Galaktionov 		if (i == n_entries)
51010eaf41dSViacheslav Galaktionov 			break;
511cb95feefSXueming Li 		/* SF range. */
512cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
513cb95feefSXueming Li 		info->ranges[i].controller = 0;
514cb95feefSXueming Li 		info->ranges[i].pf = pf;
515cb95feefSXueming Li 		info->ranges[i].vf = 0;
516cb95feefSXueming Li 		info->ranges[i].id_base =
517cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
518cb95feefSXueming Li 		info->ranges[i].id_end =
519cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
520cb95feefSXueming Li 		snprintf(info->ranges[i].name,
521cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
522cb95feefSXueming Li 		i++;
52310eaf41dSViacheslav Galaktionov 		if (i == n_entries)
52410eaf41dSViacheslav Galaktionov 			break;
52591766faeSXueming Li 		/* HPF range of SF type. */
52691766faeSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
52791766faeSXueming Li 		info->ranges[i].controller = 0;
52891766faeSXueming Li 		info->ranges[i].pf = pf;
52991766faeSXueming Li 		info->ranges[i].vf = UINT16_MAX;
53091766faeSXueming Li 		info->ranges[i].id_base =
53191766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
53291766faeSXueming Li 		info->ranges[i].id_end =
53391766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
53491766faeSXueming Li 		snprintf(info->ranges[i].name,
53591766faeSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
53691766faeSXueming Li 		i++;
53710eaf41dSViacheslav Galaktionov 		if (i == n_entries)
53810eaf41dSViacheslav Galaktionov 			break;
539cb95feefSXueming Li 	}
54010eaf41dSViacheslav Galaktionov 	info->nb_ranges = i;
541cb95feefSXueming Li out:
542cb95feefSXueming Li 	return n_type * n_pf;
543cb95feefSXueming Li }
544cb95feefSXueming Li 
545cb95feefSXueming Li /**
546714bf46eSThomas Monjalon  * Get firmware version of a device.
547714bf46eSThomas Monjalon  *
548714bf46eSThomas Monjalon  * @param dev
549714bf46eSThomas Monjalon  *   Ethernet device port.
550714bf46eSThomas Monjalon  * @param fw_ver
551714bf46eSThomas Monjalon  *   String output allocated by caller.
552714bf46eSThomas Monjalon  * @param fw_size
553714bf46eSThomas Monjalon  *   Size of the output string, including terminating null byte.
554714bf46eSThomas Monjalon  *
555714bf46eSThomas Monjalon  * @return
556714bf46eSThomas Monjalon  *   0 on success, or the size of the non truncated string if too big.
557714bf46eSThomas Monjalon  */
5581256805dSOphir Munk int
5591256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
560714bf46eSThomas Monjalon {
561dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
56291d1cfafSMichael Baum 	struct mlx5_dev_cap *attr = &priv->sh->dev_cap;
563714bf46eSThomas Monjalon 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
564714bf46eSThomas Monjalon 
565714bf46eSThomas Monjalon 	if (fw_size < size)
566714bf46eSThomas Monjalon 		return size;
567714bf46eSThomas Monjalon 	if (fw_ver != NULL)
568714bf46eSThomas Monjalon 		strlcpy(fw_ver, attr->fw_ver, fw_size);
569714bf46eSThomas Monjalon 	return 0;
570714bf46eSThomas Monjalon }
571714bf46eSThomas Monjalon 
572714bf46eSThomas Monjalon /**
573fb732b0aSNélio Laranjeiro  * Get supported packet types.
574fb732b0aSNélio Laranjeiro  *
575fb732b0aSNélio Laranjeiro  * @param dev
576fb732b0aSNélio Laranjeiro  *   Pointer to Ethernet device structure.
577fb732b0aSNélio Laranjeiro  *
578fb732b0aSNélio Laranjeiro  * @return
579fb732b0aSNélio Laranjeiro  *   A pointer to the supported Packet types array.
580fb732b0aSNélio Laranjeiro  */
58178a38edfSJianfeng Tan const uint32_t *
58278a38edfSJianfeng Tan mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
58378a38edfSJianfeng Tan {
58478a38edfSJianfeng Tan 	static const uint32_t ptypes[] = {
58578a38edfSJianfeng Tan 		/* refers to rxq_cq_to_pkt_type() */
586ea16068cSYongseok Koh 		RTE_PTYPE_L2_ETHER,
587c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
588c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
589ea16068cSYongseok Koh 		RTE_PTYPE_L4_NONFRAG,
590ea16068cSYongseok Koh 		RTE_PTYPE_L4_FRAG,
591ea16068cSYongseok Koh 		RTE_PTYPE_L4_TCP,
592ea16068cSYongseok Koh 		RTE_PTYPE_L4_UDP,
593c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
594c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
595ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_NONFRAG,
596ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_FRAG,
597ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_TCP,
598ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_UDP,
59978a38edfSJianfeng Tan 		RTE_PTYPE_UNKNOWN
60078a38edfSJianfeng Tan 	};
60178a38edfSJianfeng Tan 
6026cb559d6SYongseok Koh 	if (dev->rx_pkt_burst == mlx5_rx_burst ||
6037d6bf6b8SYongseok Koh 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq ||
6040f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_vec ||
6050f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec)
60678a38edfSJianfeng Tan 		return ptypes;
60778a38edfSJianfeng Tan 	return NULL;
60878a38edfSJianfeng Tan }
60978a38edfSJianfeng Tan 
610e60fbd5bSAdrien Mazarguil /**
611cf37ca95SAdrien Mazarguil  * DPDK callback to change the MTU.
612cf37ca95SAdrien Mazarguil  *
613cf37ca95SAdrien Mazarguil  * @param dev
614cf37ca95SAdrien Mazarguil  *   Pointer to Ethernet device structure.
615cf37ca95SAdrien Mazarguil  * @param in_mtu
616cf37ca95SAdrien Mazarguil  *   New MTU.
617cf37ca95SAdrien Mazarguil  *
618cf37ca95SAdrien Mazarguil  * @return
619a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
620cf37ca95SAdrien Mazarguil  */
621cf37ca95SAdrien Mazarguil int
622cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
623cf37ca95SAdrien Mazarguil {
624dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
625a6d83b6aSNélio Laranjeiro 	uint16_t kern_mtu = 0;
626a6d83b6aSNélio Laranjeiro 	int ret;
627cf37ca95SAdrien Mazarguil 
628af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
629a0edafe4SNelio Laranjeiro 	if (ret)
630a6d83b6aSNélio Laranjeiro 		return ret;
631cf37ca95SAdrien Mazarguil 	/* Set kernel interface MTU first. */
632af4f09f2SNélio Laranjeiro 	ret = mlx5_set_mtu(dev, mtu);
633a0edafe4SNelio Laranjeiro 	if (ret)
634a6d83b6aSNélio Laranjeiro 		return ret;
635af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
636a0edafe4SNelio Laranjeiro 	if (ret)
637a6d83b6aSNélio Laranjeiro 		return ret;
638a0edafe4SNelio Laranjeiro 	if (kern_mtu == mtu) {
639a0edafe4SNelio Laranjeiro 		priv->mtu = mtu;
640a170a30dSNélio Laranjeiro 		DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
641a170a30dSNélio Laranjeiro 			dev->data->port_id, mtu);
642a0edafe4SNelio Laranjeiro 		return 0;
643a6d83b6aSNélio Laranjeiro 	}
644a6d83b6aSNélio Laranjeiro 	rte_errno = EAGAIN;
645a6d83b6aSNélio Laranjeiro 	return -rte_errno;
646cf37ca95SAdrien Mazarguil }
647cf37ca95SAdrien Mazarguil 
648cf37ca95SAdrien Mazarguil /**
649cdab90cbSNélio Laranjeiro  * Configure the RX function to use.
650cdab90cbSNélio Laranjeiro  *
651aee1b165SXueming Li  * @param dev
652af4f09f2SNélio Laranjeiro  *   Pointer to private data structure.
6531cfa649bSShahaf Shuler  *
6541cfa649bSShahaf Shuler  * @return
6551cfa649bSShahaf Shuler  *   Pointer to selected Rx burst function.
656cdab90cbSNélio Laranjeiro  */
6571cfa649bSShahaf Shuler eth_rx_burst_t
658af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev)
659cdab90cbSNélio Laranjeiro {
6601cfa649bSShahaf Shuler 	eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst;
6611cfa649bSShahaf Shuler 
6628e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(dev != NULL);
663af4f09f2SNélio Laranjeiro 	if (mlx5_check_vec_rx_support(dev) > 0) {
6640f20acbfSAlexander Kozyrev 		if (mlx5_mprq_enabled(dev)) {
6650f20acbfSAlexander Kozyrev 			rx_pkt_burst = mlx5_rx_burst_mprq_vec;
6660f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6670f20acbfSAlexander Kozyrev 				" MPRQ Rx function", dev->data->port_id);
6680f20acbfSAlexander Kozyrev 		} else {
6691cfa649bSShahaf Shuler 			rx_pkt_burst = mlx5_rx_burst_vec;
6700f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6710f20acbfSAlexander Kozyrev 				" SPRQ Rx function", dev->data->port_id);
6720f20acbfSAlexander Kozyrev 		}
6737d6bf6b8SYongseok Koh 	} else if (mlx5_mprq_enabled(dev)) {
6747d6bf6b8SYongseok Koh 		rx_pkt_burst = mlx5_rx_burst_mprq;
6750f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected MPRQ Rx function",
6760f20acbfSAlexander Kozyrev 			dev->data->port_id);
6770f20acbfSAlexander Kozyrev 	} else {
6780f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected SPRQ Rx function",
6790f20acbfSAlexander Kozyrev 			dev->data->port_id);
680cdab90cbSNélio Laranjeiro 	}
6811cfa649bSShahaf Shuler 	return rx_pkt_burst;
6826cb559d6SYongseok Koh }
683d3e0f392SMatan Azrad 
684d3e0f392SMatan Azrad /**
68509a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by port id.
6862e4c987aSOri Kam  *
6872e4c987aSOri Kam  * @param[in] port
6882e4c987aSOri Kam  *   Device port id.
6895e61bcddSViacheslav Ovsiienko  * @param[in] valid
6905e61bcddSViacheslav Ovsiienko  *   Device port id is valid, skip check. This flag is useful
6915e61bcddSViacheslav Ovsiienko  *   when trials are performed from probing and device is not
6925e61bcddSViacheslav Ovsiienko  *   flagged as valid yet (in attaching process).
6932e4c987aSOri Kam  * @param[out] es_domain_id
6942e4c987aSOri Kam  *   E-Switch domain id.
6952e4c987aSOri Kam  * @param[out] es_port_id
6962e4c987aSOri Kam  *   The port id of the port in the E-Switch.
6972e4c987aSOri Kam  *
6982e4c987aSOri Kam  * @return
69909a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
70009a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
7012e4c987aSOri Kam  */
70209a16bcaSViacheslav Ovsiienko struct mlx5_priv *
7035e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid)
7042e4c987aSOri Kam {
7052e4c987aSOri Kam 	struct rte_eth_dev *dev;
7062e4c987aSOri Kam 	struct mlx5_priv *priv;
7072e4c987aSOri Kam 
7082e4c987aSOri Kam 	if (port >= RTE_MAX_ETHPORTS) {
7092e4c987aSOri Kam 		rte_errno = EINVAL;
71009a16bcaSViacheslav Ovsiienko 		return NULL;
7112e4c987aSOri Kam 	}
7125e61bcddSViacheslav Ovsiienko 	if (!valid && !rte_eth_dev_is_valid_port(port)) {
7132e4c987aSOri Kam 		rte_errno = ENODEV;
71409a16bcaSViacheslav Ovsiienko 		return NULL;
7152e4c987aSOri Kam 	}
7162e4c987aSOri Kam 	dev = &rte_eth_devices[port];
7172e4c987aSOri Kam 	priv = dev->data->dev_private;
718cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
7192e4c987aSOri Kam 		rte_errno = EINVAL;
72009a16bcaSViacheslav Ovsiienko 		return NULL;
7212e4c987aSOri Kam 	}
72209a16bcaSViacheslav Ovsiienko 	return priv;
72309a16bcaSViacheslav Ovsiienko }
72409a16bcaSViacheslav Ovsiienko 
72509a16bcaSViacheslav Ovsiienko /**
72609a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by device instance.
72709a16bcaSViacheslav Ovsiienko  *
72809a16bcaSViacheslav Ovsiienko  * @param[in] port
72909a16bcaSViacheslav Ovsiienko  *   Device port id.
73009a16bcaSViacheslav Ovsiienko  * @param[out] es_domain_id
73109a16bcaSViacheslav Ovsiienko  *   E-Switch domain id.
73209a16bcaSViacheslav Ovsiienko  * @param[out] es_port_id
73309a16bcaSViacheslav Ovsiienko  *   The port id of the port in the E-Switch.
73409a16bcaSViacheslav Ovsiienko  *
73509a16bcaSViacheslav Ovsiienko  * @return
73609a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
73709a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
73809a16bcaSViacheslav Ovsiienko  */
73909a16bcaSViacheslav Ovsiienko struct mlx5_priv *
74009a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
74109a16bcaSViacheslav Ovsiienko {
74209a16bcaSViacheslav Ovsiienko 	struct mlx5_priv *priv;
74309a16bcaSViacheslav Ovsiienko 
74409a16bcaSViacheslav Ovsiienko 	priv = dev->data->dev_private;
745cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
74609a16bcaSViacheslav Ovsiienko 		rte_errno = EINVAL;
74709a16bcaSViacheslav Ovsiienko 		return NULL;
74809a16bcaSViacheslav Ovsiienko 	}
74909a16bcaSViacheslav Ovsiienko 	return priv;
7502e4c987aSOri Kam }
7512e4c987aSOri Kam 
7522e4c987aSOri Kam /**
753b6b3bf86SOri Kam  * DPDK callback to retrieve hairpin capabilities.
754b6b3bf86SOri Kam  *
755b6b3bf86SOri Kam  * @param dev
756b6b3bf86SOri Kam  *   Pointer to Ethernet device structure.
757b6b3bf86SOri Kam  * @param[out] cap
758b6b3bf86SOri Kam  *   Storage for hairpin capability data.
759b6b3bf86SOri Kam  *
760b6b3bf86SOri Kam  * @return
761b6b3bf86SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
762b6b3bf86SOri Kam  */
7631256805dSOphir Munk int
764b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
765b6b3bf86SOri Kam {
766b6b3bf86SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
7677274b417SDariusz Sosnowski 	struct mlx5_hca_attr *hca_attr;
768b6b3bf86SOri Kam 
769c4b86201SMichael Baum 	if (!mlx5_devx_obj_ops_en(priv->sh)) {
770b6b3bf86SOri Kam 		rte_errno = ENOTSUP;
771b6b3bf86SOri Kam 		return -rte_errno;
772b6b3bf86SOri Kam 	}
773b6b3bf86SOri Kam 	cap->max_nb_queues = UINT16_MAX;
774b6b3bf86SOri Kam 	cap->max_rx_2_tx = 1;
775b6b3bf86SOri Kam 	cap->max_tx_2_rx = 1;
776b6b3bf86SOri Kam 	cap->max_nb_desc = 8192;
7777274b417SDariusz Sosnowski 	hca_attr = &priv->sh->cdev->config.hca_attr;
778f2d43ff5SDariusz Sosnowski 	cap->rx_cap.locked_device_memory = hca_attr->hairpin_data_buffer_locked;
779f2d43ff5SDariusz Sosnowski 	cap->rx_cap.rte_memory = 0;
7807274b417SDariusz Sosnowski 	cap->tx_cap.locked_device_memory = 0;
7817274b417SDariusz Sosnowski 	cap->tx_cap.rte_memory = hca_attr->hairpin_sq_wq_in_host_mem;
782b6b3bf86SOri Kam 	return 0;
783b6b3bf86SOri Kam }
784