xref: /dpdk/drivers/net/mlx5/mlx5_ethdev.c (revision 4c3d7961d9002bb715a8ee76bcf464d633316d4c)
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 	}
1261944fbc3SSuanming Mou 	if (priv->ext_txqs && txqs_n >= MLX5_EXTERNAL_TX_QUEUE_ID_MIN) {
1271944fbc3SSuanming Mou 		DRV_LOG(ERR, "port %u cannot handle this many Tx queues (%u), "
1281944fbc3SSuanming Mou 			"the maximal number of internal Tx queues is %u",
1291944fbc3SSuanming Mou 			dev->data->port_id, txqs_n,
1301944fbc3SSuanming Mou 			MLX5_EXTERNAL_TX_QUEUE_ID_MIN - 1);
1311944fbc3SSuanming Mou 		rte_errno = EINVAL;
1321944fbc3SSuanming Mou 		return -rte_errno;
1331944fbc3SSuanming Mou 	}
13487af0d1eSMichael Baum 	if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) {
135a170a30dSNélio Laranjeiro 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
1360f99970bSNélio Laranjeiro 			dev->data->port_id, rxqs_n);
137a6d83b6aSNélio Laranjeiro 		rte_errno = EINVAL;
138a6d83b6aSNélio Laranjeiro 		return -rte_errno;
139634efbc2SNelio Laranjeiro 	}
14086647d46SThomas Monjalon 	if (priv->ext_rxqs && rxqs_n >= RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN) {
14180f872eeSMichael Baum 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u), "
14280f872eeSMichael Baum 			"the maximal number of internal Rx queues is %u",
14380f872eeSMichael Baum 			dev->data->port_id, rxqs_n,
14486647d46SThomas Monjalon 			RTE_PMD_MLX5_EXTERNAL_RX_QUEUE_ID_MIN - 1);
14580f872eeSMichael Baum 		rte_errno = EINVAL;
14680f872eeSMichael Baum 		return -rte_errno;
14780f872eeSMichael Baum 	}
14809ba4c58SDekel Peled 	if (rxqs_n != priv->rxqs_n) {
149a170a30dSNélio Laranjeiro 		DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
1500f99970bSNélio Laranjeiro 			dev->data->port_id, priv->rxqs_n, rxqs_n);
151e60fbd5bSAdrien Mazarguil 		priv->rxqs_n = rxqs_n;
15263bd1629SOri Kam 	}
15363bd1629SOri Kam 	priv->skip_default_rss_reta = 0;
15463bd1629SOri Kam 	ret = mlx5_proc_priv_init(dev);
15563bd1629SOri Kam 	if (ret)
15663bd1629SOri Kam 		return ret;
15710859ecfSDariusz Sosnowski 	ret = mlx5_dev_set_mtu(dev, dev->data->mtu);
15810859ecfSDariusz Sosnowski 	if (ret) {
15910859ecfSDariusz Sosnowski 		DRV_LOG(ERR, "port %u failed to set MTU to %u", dev->data->port_id,
16010859ecfSDariusz Sosnowski 			dev->data->mtu);
16110859ecfSDariusz Sosnowski 		return ret;
16210859ecfSDariusz Sosnowski 	}
16363bd1629SOri Kam 	return 0;
16463bd1629SOri Kam }
16563bd1629SOri Kam 
16663bd1629SOri Kam /**
16763bd1629SOri Kam  * Configure default RSS reta.
16863bd1629SOri Kam  *
16963bd1629SOri Kam  * @param dev
17063bd1629SOri Kam  *   Pointer to Ethernet device structure.
17163bd1629SOri Kam  *
17263bd1629SOri Kam  * @return
17363bd1629SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
17463bd1629SOri Kam  */
17563bd1629SOri Kam int
17663bd1629SOri Kam mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
17763bd1629SOri Kam {
17863bd1629SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
17963bd1629SOri Kam 	unsigned int rxqs_n = dev->data->nb_rx_queues;
18063bd1629SOri Kam 	unsigned int i;
18163bd1629SOri Kam 	unsigned int j;
18263bd1629SOri Kam 	unsigned int reta_idx_n;
18363bd1629SOri Kam 	int ret = 0;
18463bd1629SOri Kam 	unsigned int *rss_queue_arr = NULL;
18563bd1629SOri Kam 	unsigned int rss_queue_n = 0;
18663bd1629SOri Kam 
18763bd1629SOri Kam 	if (priv->skip_default_rss_reta)
18863bd1629SOri Kam 		return ret;
18983c2047cSSuanming Mou 	rss_queue_arr = mlx5_malloc(0, rxqs_n * sizeof(unsigned int), 0,
19083c2047cSSuanming Mou 				    SOCKET_ID_ANY);
19163bd1629SOri Kam 	if (!rss_queue_arr) {
19263bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot allocate RSS queue list (%u)",
19363bd1629SOri Kam 			dev->data->port_id, rxqs_n);
19463bd1629SOri Kam 		rte_errno = ENOMEM;
19563bd1629SOri Kam 		return -rte_errno;
19663bd1629SOri Kam 	}
19763bd1629SOri Kam 	for (i = 0, j = 0; i < rxqs_n; i++) {
1985cf0707fSXueming Li 		struct mlx5_rxq_ctrl *rxq_ctrl = mlx5_rxq_ctrl_get(dev, i);
19963bd1629SOri Kam 
200c06f77aeSMichael Baum 		if (rxq_ctrl && !rxq_ctrl->is_hairpin)
20163bd1629SOri Kam 			rss_queue_arr[j++] = i;
20263bd1629SOri Kam 	}
20363bd1629SOri Kam 	rss_queue_n = j;
20487af0d1eSMichael Baum 	if (rss_queue_n > priv->sh->dev_cap.ind_table_max_size) {
20563bd1629SOri Kam 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
20663bd1629SOri Kam 			dev->data->port_id, rss_queue_n);
20763bd1629SOri Kam 		rte_errno = EINVAL;
20883c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
20963bd1629SOri Kam 		return -rte_errno;
21063bd1629SOri Kam 	}
21163bd1629SOri Kam 	DRV_LOG(INFO, "port %u Rx queues number update: %u -> %u",
21263bd1629SOri Kam 		dev->data->port_id, priv->rxqs_n, rxqs_n);
21363bd1629SOri Kam 	priv->rxqs_n = rxqs_n;
21409ba4c58SDekel Peled 	/*
21509ba4c58SDekel Peled 	 * If the requested number of RX queues is not a power of two,
21609ba4c58SDekel Peled 	 * use the maximum indirection table size for better balancing.
21709ba4c58SDekel Peled 	 * The result is always rounded to the next power of two.
21809ba4c58SDekel Peled 	 */
21963bd1629SOri Kam 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
22087af0d1eSMichael Baum 				     priv->sh->dev_cap.ind_table_max_size :
22163bd1629SOri Kam 				     rss_queue_n));
222a6d83b6aSNélio Laranjeiro 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
22363bd1629SOri Kam 	if (ret) {
22483c2047cSSuanming Mou 		mlx5_free(rss_queue_arr);
225a6d83b6aSNélio Laranjeiro 		return ret;
22663bd1629SOri Kam 	}
22709ba4c58SDekel Peled 	/*
22809ba4c58SDekel Peled 	 * When the number of RX queues is not a power of two,
22909ba4c58SDekel Peled 	 * the remaining table entries are padded with reused WQs
23009ba4c58SDekel Peled 	 * and hashes are not spread uniformly.
23109ba4c58SDekel Peled 	 */
232634efbc2SNelio Laranjeiro 	for (i = 0, j = 0; (i != reta_idx_n); ++i) {
23363bd1629SOri Kam 		(*priv->reta_idx)[i] = rss_queue_arr[j];
23463bd1629SOri Kam 		if (++j == rss_queue_n)
235634efbc2SNelio Laranjeiro 			j = 0;
236634efbc2SNelio Laranjeiro 	}
23783c2047cSSuanming Mou 	mlx5_free(rss_queue_arr);
238120dc4a7SYongseok Koh 	return ret;
239e60fbd5bSAdrien Mazarguil }
240e60fbd5bSAdrien Mazarguil 
241e60fbd5bSAdrien Mazarguil /**
242d11d651fSShahaf Shuler  * Sets default tuning parameters.
243d11d651fSShahaf Shuler  *
244d11d651fSShahaf Shuler  * @param dev
245d11d651fSShahaf Shuler  *   Pointer to Ethernet device.
246d11d651fSShahaf Shuler  * @param[out] info
247d11d651fSShahaf Shuler  *   Info structure output buffer.
248d11d651fSShahaf Shuler  */
249d11d651fSShahaf Shuler static void
250d11d651fSShahaf Shuler mlx5_set_default_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
251d11d651fSShahaf Shuler {
252dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
253d11d651fSShahaf Shuler 
254d11d651fSShahaf Shuler 	/* Minimum CPU utilization. */
255d11d651fSShahaf Shuler 	info->default_rxportconf.ring_size = 256;
256d11d651fSShahaf Shuler 	info->default_txportconf.ring_size = 256;
257f078ceb6SViacheslav Ovsiienko 	info->default_rxportconf.burst_size = MLX5_RX_DEFAULT_BURST;
258f078ceb6SViacheslav Ovsiienko 	info->default_txportconf.burst_size = MLX5_TX_DEFAULT_BURST;
2593d57ec9fSThomas Monjalon 	if (priv->link_speed_capa >> rte_bsf32(RTE_ETH_LINK_SPEED_100G)) {
2603d57ec9fSThomas Monjalon 		/* if supports at least 100G */
261d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 16;
262d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 16;
263d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
264d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
265d11d651fSShahaf Shuler 			/* Max Throughput. */
266d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 2048;
267d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 2048;
268d11d651fSShahaf Shuler 		}
269d11d651fSShahaf Shuler 	} else {
270d11d651fSShahaf Shuler 		info->default_rxportconf.nb_queues = 8;
271d11d651fSShahaf Shuler 		info->default_txportconf.nb_queues = 8;
272d11d651fSShahaf Shuler 		if (dev->data->nb_rx_queues > 2 ||
273d11d651fSShahaf Shuler 		    dev->data->nb_tx_queues > 2) {
274d11d651fSShahaf Shuler 			/* Max Throughput. */
275d11d651fSShahaf Shuler 			info->default_rxportconf.ring_size = 4096;
276d11d651fSShahaf Shuler 			info->default_txportconf.ring_size = 4096;
277d11d651fSShahaf Shuler 		}
278d11d651fSShahaf Shuler 	}
279d11d651fSShahaf Shuler }
280d11d651fSShahaf Shuler 
281d11d651fSShahaf Shuler /**
282cb9cb61eSViacheslav Ovsiienko  * Sets tx mbuf limiting parameters.
283cb9cb61eSViacheslav Ovsiienko  *
284cb9cb61eSViacheslav Ovsiienko  * @param dev
285cb9cb61eSViacheslav Ovsiienko  *   Pointer to Ethernet device.
286cb9cb61eSViacheslav Ovsiienko  * @param[out] info
287cb9cb61eSViacheslav Ovsiienko  *   Info structure output buffer.
288cb9cb61eSViacheslav Ovsiienko  */
289cb9cb61eSViacheslav Ovsiienko static void
290cb9cb61eSViacheslav Ovsiienko mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
291cb9cb61eSViacheslav Ovsiienko {
292cb9cb61eSViacheslav Ovsiienko 	struct mlx5_priv *priv = dev->data->dev_private;
29345a6df80SMichael Baum 	struct mlx5_port_config *config = &priv->config;
294cb9cb61eSViacheslav Ovsiienko 	unsigned int inlen;
295cb9cb61eSViacheslav Ovsiienko 	uint16_t nb_max;
296cb9cb61eSViacheslav Ovsiienko 
297cb9cb61eSViacheslav Ovsiienko 	inlen = (config->txq_inline_max == MLX5_ARG_UNSET) ?
298cb9cb61eSViacheslav Ovsiienko 		MLX5_SEND_DEF_INLINE_LEN :
299cb9cb61eSViacheslav Ovsiienko 		(unsigned int)config->txq_inline_max;
3008e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(config->txq_inline_min >= 0);
301cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MAX(inlen, (unsigned int)config->txq_inline_min);
302cb9cb61eSViacheslav Ovsiienko 	inlen = RTE_MIN(inlen, MLX5_WQE_SIZE_MAX +
303cb9cb61eSViacheslav Ovsiienko 			       MLX5_ESEG_MIN_INLINE_SIZE -
304cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_CSEG_SIZE -
305cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_ESEG_SIZE -
306cb9cb61eSViacheslav Ovsiienko 			       MLX5_WQE_DSEG_SIZE * 2);
307cb9cb61eSViacheslav Ovsiienko 	nb_max = (MLX5_WQE_SIZE_MAX +
308cb9cb61eSViacheslav Ovsiienko 		  MLX5_ESEG_MIN_INLINE_SIZE -
309cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_CSEG_SIZE -
310cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_ESEG_SIZE -
311cb9cb61eSViacheslav Ovsiienko 		  MLX5_WQE_DSEG_SIZE -
312cb9cb61eSViacheslav Ovsiienko 		  inlen) / MLX5_WSEG_SIZE;
313cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_seg_max = nb_max;
314cb9cb61eSViacheslav Ovsiienko 	info->tx_desc_lim.nb_mtu_seg_max = nb_max;
315cb9cb61eSViacheslav Ovsiienko }
316cb9cb61eSViacheslav Ovsiienko 
317cb9cb61eSViacheslav Ovsiienko /**
318e60fbd5bSAdrien Mazarguil  * DPDK callback to get information about the device.
319e60fbd5bSAdrien Mazarguil  *
320e60fbd5bSAdrien Mazarguil  * @param dev
321e60fbd5bSAdrien Mazarguil  *   Pointer to Ethernet device structure.
322e60fbd5bSAdrien Mazarguil  * @param[out] info
323e60fbd5bSAdrien Mazarguil  *   Info structure output buffer.
324e60fbd5bSAdrien Mazarguil  */
325bdad90d1SIvan Ilchenko int
326e60fbd5bSAdrien Mazarguil mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
327e60fbd5bSAdrien Mazarguil {
328dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
329e60fbd5bSAdrien Mazarguil 	unsigned int max;
330e60fbd5bSAdrien Mazarguil 
331e60fbd5bSAdrien Mazarguil 	/* FIXME: we should ask the device for these values. */
332e60fbd5bSAdrien Mazarguil 	info->min_rx_bufsize = 32;
333e60fbd5bSAdrien Mazarguil 	info->max_rx_pktlen = 65536;
3341c7e57f9SDekel Peled 	info->max_lro_pkt_size = MLX5_MAX_LRO_SIZE;
335e60fbd5bSAdrien Mazarguil 	/*
336e60fbd5bSAdrien Mazarguil 	 * Since we need one CQ per QP, the limit is the minimum number
337e60fbd5bSAdrien Mazarguil 	 * between the two values.
338e60fbd5bSAdrien Mazarguil 	 */
33991d1cfafSMichael Baum 	max = RTE_MIN(priv->sh->dev_cap.max_cq, priv->sh->dev_cap.max_qp);
340b689a781SThomas Monjalon 	/* max_rx_queues is uint16_t. */
341b689a781SThomas Monjalon 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
342e60fbd5bSAdrien Mazarguil 	info->max_rx_queues = max;
343e60fbd5bSAdrien Mazarguil 	info->max_tx_queues = max;
34418c01b98SNélio Laranjeiro 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
345af4f09f2SNélio Laranjeiro 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
3466c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
34745a6df80SMichael Baum 	info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled;
34845a6df80SMichael Baum 	info->rx_seg_capa.offset_allowed = !priv->config.mprq.enabled;
3496c8f7f1cSViacheslav Ovsiienko 	info->rx_seg_capa.offset_align_log2 = 0;
35017ed314cSMatan Azrad 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
35117b843ebSShahaf Shuler 				 info->rx_queue_offload_capa);
352af4f09f2SNélio Laranjeiro 	info->tx_offload_capa = mlx5_get_tx_port_offloads(dev);
353ec4e11d4SDmitry Kozlyuk 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
354fa2e14d4SViacheslav Ovsiienko 	info->if_index = mlx5_ifindex(dev);
355d365210eSYongseok Koh 	info->reta_size = priv->reta_idx_n ?
35687af0d1eSMichael Baum 		priv->reta_idx_n : priv->sh->dev_cap.ind_table_max_size;
357c388a2f6SNelio Laranjeiro 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
35875ef62a9SNélio Laranjeiro 	info->speed_capa = priv->link_speed_capa;
359b233b027SShahaf Shuler 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
360d11d651fSShahaf Shuler 	mlx5_set_default_params(dev, info);
361cb9cb61eSViacheslav Ovsiienko 	mlx5_set_txlimit_params(dev, info);
362*4c3d7961SIgor Gutorov 	info->rx_desc_lim.nb_max =
363*4c3d7961SIgor Gutorov 		1 << priv->sh->cdev->config.hca_attr.log_max_wq_sz;
364*4c3d7961SIgor Gutorov 	info->tx_desc_lim.nb_max =
365*4c3d7961SIgor Gutorov 		1 << priv->sh->cdev->config.hca_attr.log_max_wq_sz;
36653820561SMichael Baum 	if (priv->sh->cdev->config.hca_attr.mem_rq_rmp &&
36709c25553SXueming Li 	    priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new)
36809c25553SXueming Li 		info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE;
3692b730263SAdrien Mazarguil 	info->switch_info.name = dev->data->name;
3702b730263SAdrien Mazarguil 	info->switch_info.domain_id = priv->domain_id;
3712b730263SAdrien Mazarguil 	info->switch_info.port_id = priv->representor_id;
37209c25553SXueming Li 	info->switch_info.rx_domain = 0; /* No sub Rx domains. */
3732b730263SAdrien Mazarguil 	if (priv->representor) {
374f7e95215SViacheslav Ovsiienko 		uint16_t port_id;
3752b730263SAdrien Mazarguil 
37656bb3c84SXueming Li 		MLX5_ETH_FOREACH_DEV(port_id, dev->device) {
377dbeba4cfSThomas Monjalon 			struct mlx5_priv *opriv =
378f7e95215SViacheslav Ovsiienko 				rte_eth_devices[port_id].data->dev_private;
3792b730263SAdrien Mazarguil 
3802b730263SAdrien Mazarguil 			if (!opriv ||
3812b730263SAdrien Mazarguil 			    opriv->representor ||
382f7e95215SViacheslav Ovsiienko 			    opriv->sh != priv->sh ||
3832b730263SAdrien Mazarguil 			    opriv->domain_id != priv->domain_id)
3842b730263SAdrien Mazarguil 				continue;
3852b730263SAdrien Mazarguil 			/*
3862b730263SAdrien Mazarguil 			 * Override switch name with that of the master
3872b730263SAdrien Mazarguil 			 * device.
3882b730263SAdrien Mazarguil 			 */
3892b730263SAdrien Mazarguil 			info->switch_info.name = opriv->dev_data->name;
3902b730263SAdrien Mazarguil 			break;
3912b730263SAdrien Mazarguil 		}
3922b730263SAdrien Mazarguil 	}
393bdad90d1SIvan Ilchenko 	return 0;
394e60fbd5bSAdrien Mazarguil }
395e60fbd5bSAdrien Mazarguil 
396fb732b0aSNélio Laranjeiro /**
397cb95feefSXueming Li  * Calculate representor ID from port switch info.
398cb95feefSXueming Li  *
399cb95feefSXueming Li  * Uint16 representor ID bits definition:
400cb95feefSXueming Li  *   pf: 2
401cb95feefSXueming Li  *   type: 2
402cb95feefSXueming Li  *   vf/sf: 12
403cb95feefSXueming Li  *
404cb95feefSXueming Li  * @param info
405cb95feefSXueming Li  *   Port switch info.
40691766faeSXueming Li  * @param hpf_type
40791766faeSXueming Li  *   Use this type if port is HPF.
408cb95feefSXueming Li  *
409cb95feefSXueming Li  * @return
410cb95feefSXueming Li  *   Encoded representor ID.
411cb95feefSXueming Li  */
412cb95feefSXueming Li uint16_t
41391766faeSXueming Li mlx5_representor_id_encode(const struct mlx5_switch_info *info,
41491766faeSXueming Li 			   enum rte_eth_representor_type hpf_type)
415cb95feefSXueming Li {
41611c73de9SDariusz Sosnowski 	enum rte_eth_representor_type type;
417cb95feefSXueming Li 	uint16_t repr = info->port_name;
41811c73de9SDariusz Sosnowski 	int32_t pf = info->pf_num;
419cb95feefSXueming Li 
42011c73de9SDariusz Sosnowski 	switch (info->name_type) {
42111c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
42211c73de9SDariusz Sosnowski 		if (!info->representor)
423cb95feefSXueming Li 			return UINT16_MAX;
42411c73de9SDariusz Sosnowski 		type = RTE_ETH_REPRESENTOR_PF;
42511c73de9SDariusz Sosnowski 		pf = info->mpesw_owner;
42611c73de9SDariusz Sosnowski 		break;
42711c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFSF:
428cb95feefSXueming Li 		type = RTE_ETH_REPRESENTOR_SF;
42911c73de9SDariusz Sosnowski 		break;
43011c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFHPF:
43191766faeSXueming Li 		type = hpf_type;
432cb95feefSXueming Li 		repr = UINT16_MAX;
43311c73de9SDariusz Sosnowski 		break;
43411c73de9SDariusz Sosnowski 	case MLX5_PHYS_PORT_NAME_TYPE_PFVF:
43511c73de9SDariusz Sosnowski 	default:
43611c73de9SDariusz Sosnowski 		type = RTE_ETH_REPRESENTOR_VF;
43711c73de9SDariusz Sosnowski 		break;
43891766faeSXueming Li 	}
43911c73de9SDariusz Sosnowski 	return MLX5_REPRESENTOR_ID(pf, type, repr);
440cb95feefSXueming Li }
441cb95feefSXueming Li 
442cb95feefSXueming Li /**
443cb95feefSXueming Li  * DPDK callback to get information about representor.
444cb95feefSXueming Li  *
445cb95feefSXueming Li  * Representor ID bits definition:
446cb95feefSXueming Li  *   vf/sf: 12
447cb95feefSXueming Li  *   type: 2
448cb95feefSXueming Li  *   pf: 2
449cb95feefSXueming Li  *
450cb95feefSXueming Li  * @param dev
451cb95feefSXueming Li  *   Pointer to Ethernet device structure.
452cb95feefSXueming Li  * @param[out] info
453cb95feefSXueming Li  *   Nullable info structure output buffer.
454cb95feefSXueming Li  *
455cb95feefSXueming Li  * @return
456cb95feefSXueming Li  *   negative on error, or the number of representor ranges.
457cb95feefSXueming Li  */
458cb95feefSXueming Li int
459cb95feefSXueming Li mlx5_representor_info_get(struct rte_eth_dev *dev,
460cb95feefSXueming Li 			  struct rte_eth_representor_info *info)
461cb95feefSXueming Li {
462cb95feefSXueming Li 	struct mlx5_priv *priv = dev->data->dev_private;
46311c73de9SDariusz Sosnowski 	int n_type = 5; /* Representor types: PF, VF, HPF@VF, SF and HPF@SF. */
464cb95feefSXueming Li 	int n_pf = 2; /* Number of PFs. */
465cb95feefSXueming Li 	int i = 0, pf;
46610eaf41dSViacheslav Galaktionov 	int n_entries;
467cb95feefSXueming Li 
468cb95feefSXueming Li 	if (info == NULL)
469cb95feefSXueming Li 		goto out;
47010eaf41dSViacheslav Galaktionov 
47110eaf41dSViacheslav Galaktionov 	n_entries = n_type * n_pf;
47210eaf41dSViacheslav Galaktionov 	if ((uint32_t)n_entries > info->nb_ranges_alloc)
47310eaf41dSViacheslav Galaktionov 		n_entries = info->nb_ranges_alloc;
47410eaf41dSViacheslav Galaktionov 
475cb95feefSXueming Li 	info->controller = 0;
47611c73de9SDariusz Sosnowski 	info->pf = 0;
47711c73de9SDariusz Sosnowski 	if (mlx5_is_port_on_mpesw_device(priv)) {
47811c73de9SDariusz Sosnowski 		info->pf = priv->mpesw_port;
47911c73de9SDariusz Sosnowski 		/* PF range, both ports will show the same information. */
48011c73de9SDariusz Sosnowski 		info->ranges[i].type = RTE_ETH_REPRESENTOR_PF;
48111c73de9SDariusz Sosnowski 		info->ranges[i].controller = 0;
48211c73de9SDariusz Sosnowski 		info->ranges[i].pf = priv->mpesw_owner + 1;
48311c73de9SDariusz Sosnowski 		info->ranges[i].vf = 0;
48411c73de9SDariusz Sosnowski 		/*
48511c73de9SDariusz Sosnowski 		 * The representor indexes should be the values set of "priv->mpesw_port".
48611c73de9SDariusz Sosnowski 		 * In the real case now, only 1 PF/UPLINK representor is supported.
48711c73de9SDariusz Sosnowski 		 * The port index will always be the value of "owner + 1".
48811c73de9SDariusz Sosnowski 		 */
48911c73de9SDariusz Sosnowski 		info->ranges[i].id_base =
49011c73de9SDariusz Sosnowski 			MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,
49111c73de9SDariusz Sosnowski 					    info->ranges[i].pf);
49211c73de9SDariusz Sosnowski 		info->ranges[i].id_end =
49311c73de9SDariusz Sosnowski 			MLX5_REPRESENTOR_ID(priv->mpesw_owner, info->ranges[i].type,
49411c73de9SDariusz Sosnowski 					    info->ranges[i].pf);
49511c73de9SDariusz Sosnowski 		snprintf(info->ranges[i].name, sizeof(info->ranges[i].name),
49611c73de9SDariusz Sosnowski 			 "pf%d", info->ranges[i].pf);
49711c73de9SDariusz Sosnowski 		i++;
49811c73de9SDariusz Sosnowski 	} else if (priv->pf_bond >= 0)
49911c73de9SDariusz Sosnowski 		info->pf = priv->pf_bond;
500cb95feefSXueming Li 	for (pf = 0; pf < n_pf; ++pf) {
501cb95feefSXueming Li 		/* VF range. */
502cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
503cb95feefSXueming Li 		info->ranges[i].controller = 0;
504cb95feefSXueming Li 		info->ranges[i].pf = pf;
505cb95feefSXueming Li 		info->ranges[i].vf = 0;
506cb95feefSXueming Li 		info->ranges[i].id_base =
507cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
508cb95feefSXueming Li 		info->ranges[i].id_end =
509cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
510cb95feefSXueming Li 		snprintf(info->ranges[i].name,
511cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
512cb95feefSXueming Li 		i++;
51310eaf41dSViacheslav Galaktionov 		if (i == n_entries)
51410eaf41dSViacheslav Galaktionov 			break;
51591766faeSXueming Li 		/* HPF range of VF type. */
516cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_VF;
517cb95feefSXueming Li 		info->ranges[i].controller = 0;
518cb95feefSXueming Li 		info->ranges[i].pf = pf;
519cb95feefSXueming Li 		info->ranges[i].vf = UINT16_MAX;
520cb95feefSXueming Li 		info->ranges[i].id_base =
521cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
522cb95feefSXueming Li 		info->ranges[i].id_end =
523cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
524cb95feefSXueming Li 		snprintf(info->ranges[i].name,
525cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dvf", pf);
526cb95feefSXueming Li 		i++;
52710eaf41dSViacheslav Galaktionov 		if (i == n_entries)
52810eaf41dSViacheslav Galaktionov 			break;
529cb95feefSXueming Li 		/* SF range. */
530cb95feefSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
531cb95feefSXueming Li 		info->ranges[i].controller = 0;
532cb95feefSXueming Li 		info->ranges[i].pf = pf;
533cb95feefSXueming Li 		info->ranges[i].vf = 0;
534cb95feefSXueming Li 		info->ranges[i].id_base =
535cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, 0);
536cb95feefSXueming Li 		info->ranges[i].id_end =
537cb95feefSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
538cb95feefSXueming Li 		snprintf(info->ranges[i].name,
539cb95feefSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
540cb95feefSXueming Li 		i++;
54110eaf41dSViacheslav Galaktionov 		if (i == n_entries)
54210eaf41dSViacheslav Galaktionov 			break;
54391766faeSXueming Li 		/* HPF range of SF type. */
54491766faeSXueming Li 		info->ranges[i].type = RTE_ETH_REPRESENTOR_SF;
54591766faeSXueming Li 		info->ranges[i].controller = 0;
54691766faeSXueming Li 		info->ranges[i].pf = pf;
54791766faeSXueming Li 		info->ranges[i].vf = UINT16_MAX;
54891766faeSXueming Li 		info->ranges[i].id_base =
54991766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
55091766faeSXueming Li 		info->ranges[i].id_end =
55191766faeSXueming Li 			MLX5_REPRESENTOR_ID(pf, info->ranges[i].type, -1);
55291766faeSXueming Li 		snprintf(info->ranges[i].name,
55391766faeSXueming Li 			 sizeof(info->ranges[i].name), "pf%dsf", pf);
55491766faeSXueming Li 		i++;
55510eaf41dSViacheslav Galaktionov 		if (i == n_entries)
55610eaf41dSViacheslav Galaktionov 			break;
557cb95feefSXueming Li 	}
55810eaf41dSViacheslav Galaktionov 	info->nb_ranges = i;
559cb95feefSXueming Li out:
560cb95feefSXueming Li 	return n_type * n_pf;
561cb95feefSXueming Li }
562cb95feefSXueming Li 
563cb95feefSXueming Li /**
564714bf46eSThomas Monjalon  * Get firmware version of a device.
565714bf46eSThomas Monjalon  *
566714bf46eSThomas Monjalon  * @param dev
567714bf46eSThomas Monjalon  *   Ethernet device port.
568714bf46eSThomas Monjalon  * @param fw_ver
569714bf46eSThomas Monjalon  *   String output allocated by caller.
570714bf46eSThomas Monjalon  * @param fw_size
571714bf46eSThomas Monjalon  *   Size of the output string, including terminating null byte.
572714bf46eSThomas Monjalon  *
573714bf46eSThomas Monjalon  * @return
574714bf46eSThomas Monjalon  *   0 on success, or the size of the non truncated string if too big.
575714bf46eSThomas Monjalon  */
5761256805dSOphir Munk int
5771256805dSOphir Munk mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
578714bf46eSThomas Monjalon {
579dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
58091d1cfafSMichael Baum 	struct mlx5_dev_cap *attr = &priv->sh->dev_cap;
581714bf46eSThomas Monjalon 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
582714bf46eSThomas Monjalon 
583714bf46eSThomas Monjalon 	if (fw_size < size)
584714bf46eSThomas Monjalon 		return size;
585714bf46eSThomas Monjalon 	if (fw_ver != NULL)
586714bf46eSThomas Monjalon 		strlcpy(fw_ver, attr->fw_ver, fw_size);
587714bf46eSThomas Monjalon 	return 0;
588714bf46eSThomas Monjalon }
589714bf46eSThomas Monjalon 
590714bf46eSThomas Monjalon /**
591fb732b0aSNélio Laranjeiro  * Get supported packet types.
592fb732b0aSNélio Laranjeiro  *
593fb732b0aSNélio Laranjeiro  * @param dev
594fb732b0aSNélio Laranjeiro  *   Pointer to Ethernet device structure.
595fb732b0aSNélio Laranjeiro  *
596fb732b0aSNélio Laranjeiro  * @return
597fb732b0aSNélio Laranjeiro  *   A pointer to the supported Packet types array.
598fb732b0aSNélio Laranjeiro  */
59978a38edfSJianfeng Tan const uint32_t *
600ba6a168aSSivaramakrishnan Venkat mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
60178a38edfSJianfeng Tan {
60278a38edfSJianfeng Tan 	static const uint32_t ptypes[] = {
60378a38edfSJianfeng Tan 		/* refers to rxq_cq_to_pkt_type() */
604ea16068cSYongseok Koh 		RTE_PTYPE_L2_ETHER,
605c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
606c4ba5434SNélio Laranjeiro 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
607ea16068cSYongseok Koh 		RTE_PTYPE_L4_NONFRAG,
608ea16068cSYongseok Koh 		RTE_PTYPE_L4_FRAG,
609ea16068cSYongseok Koh 		RTE_PTYPE_L4_TCP,
610ea16068cSYongseok Koh 		RTE_PTYPE_L4_UDP,
611c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
612c4ba5434SNélio Laranjeiro 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
613ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_NONFRAG,
614ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_FRAG,
615ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_TCP,
616ea16068cSYongseok Koh 		RTE_PTYPE_INNER_L4_UDP,
61778a38edfSJianfeng Tan 	};
61878a38edfSJianfeng Tan 
6196cb559d6SYongseok Koh 	if (dev->rx_pkt_burst == mlx5_rx_burst ||
6207d6bf6b8SYongseok Koh 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq ||
6210f20acbfSAlexander Kozyrev 	    dev->rx_pkt_burst == mlx5_rx_burst_vec ||
622ba6a168aSSivaramakrishnan Venkat 	    dev->rx_pkt_burst == mlx5_rx_burst_mprq_vec) {
623ba6a168aSSivaramakrishnan Venkat 		*no_of_elements = RTE_DIM(ptypes);
62478a38edfSJianfeng Tan 		return ptypes;
625ba6a168aSSivaramakrishnan Venkat 	}
62678a38edfSJianfeng Tan 	return NULL;
62778a38edfSJianfeng Tan }
62878a38edfSJianfeng Tan 
629e60fbd5bSAdrien Mazarguil /**
630cf37ca95SAdrien Mazarguil  * DPDK callback to change the MTU.
631cf37ca95SAdrien Mazarguil  *
632cf37ca95SAdrien Mazarguil  * @param dev
633cf37ca95SAdrien Mazarguil  *   Pointer to Ethernet device structure.
634cf37ca95SAdrien Mazarguil  * @param in_mtu
635cf37ca95SAdrien Mazarguil  *   New MTU.
636cf37ca95SAdrien Mazarguil  *
637cf37ca95SAdrien Mazarguil  * @return
638a6d83b6aSNélio Laranjeiro  *   0 on success, a negative errno value otherwise and rte_errno is set.
639cf37ca95SAdrien Mazarguil  */
640cf37ca95SAdrien Mazarguil int
641cf37ca95SAdrien Mazarguil mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
642cf37ca95SAdrien Mazarguil {
643dbeba4cfSThomas Monjalon 	struct mlx5_priv *priv = dev->data->dev_private;
644a6d83b6aSNélio Laranjeiro 	uint16_t kern_mtu = 0;
645a6d83b6aSNélio Laranjeiro 	int ret;
646cf37ca95SAdrien Mazarguil 
647af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
648a0edafe4SNelio Laranjeiro 	if (ret)
649a6d83b6aSNélio Laranjeiro 		return ret;
650cf37ca95SAdrien Mazarguil 	/* Set kernel interface MTU first. */
651af4f09f2SNélio Laranjeiro 	ret = mlx5_set_mtu(dev, mtu);
652a0edafe4SNelio Laranjeiro 	if (ret)
653a6d83b6aSNélio Laranjeiro 		return ret;
654af4f09f2SNélio Laranjeiro 	ret = mlx5_get_mtu(dev, &kern_mtu);
655a0edafe4SNelio Laranjeiro 	if (ret)
656a6d83b6aSNélio Laranjeiro 		return ret;
657a0edafe4SNelio Laranjeiro 	if (kern_mtu == mtu) {
658a0edafe4SNelio Laranjeiro 		priv->mtu = mtu;
659a170a30dSNélio Laranjeiro 		DRV_LOG(DEBUG, "port %u adapter MTU set to %u",
660a170a30dSNélio Laranjeiro 			dev->data->port_id, mtu);
661a0edafe4SNelio Laranjeiro 		return 0;
662a6d83b6aSNélio Laranjeiro 	}
663a6d83b6aSNélio Laranjeiro 	rte_errno = EAGAIN;
664a6d83b6aSNélio Laranjeiro 	return -rte_errno;
665cf37ca95SAdrien Mazarguil }
666cf37ca95SAdrien Mazarguil 
667cf37ca95SAdrien Mazarguil /**
668cdab90cbSNélio Laranjeiro  * Configure the RX function to use.
669cdab90cbSNélio Laranjeiro  *
670aee1b165SXueming Li  * @param dev
671af4f09f2SNélio Laranjeiro  *   Pointer to private data structure.
6721cfa649bSShahaf Shuler  *
6731cfa649bSShahaf Shuler  * @return
6741cfa649bSShahaf Shuler  *   Pointer to selected Rx burst function.
675cdab90cbSNélio Laranjeiro  */
6761cfa649bSShahaf Shuler eth_rx_burst_t
677af4f09f2SNélio Laranjeiro mlx5_select_rx_function(struct rte_eth_dev *dev)
678cdab90cbSNélio Laranjeiro {
6791cfa649bSShahaf Shuler 	eth_rx_burst_t rx_pkt_burst = mlx5_rx_burst;
6801cfa649bSShahaf Shuler 
6818e46d4e1SAlexander Kozyrev 	MLX5_ASSERT(dev != NULL);
682af4f09f2SNélio Laranjeiro 	if (mlx5_check_vec_rx_support(dev) > 0) {
6830f20acbfSAlexander Kozyrev 		if (mlx5_mprq_enabled(dev)) {
6840f20acbfSAlexander Kozyrev 			rx_pkt_burst = mlx5_rx_burst_mprq_vec;
6850f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6860f20acbfSAlexander Kozyrev 				" MPRQ Rx function", dev->data->port_id);
6870f20acbfSAlexander Kozyrev 		} else {
6881cfa649bSShahaf Shuler 			rx_pkt_burst = mlx5_rx_burst_vec;
6890f20acbfSAlexander Kozyrev 			DRV_LOG(DEBUG, "port %u selected vectorized"
6900f20acbfSAlexander Kozyrev 				" SPRQ Rx function", dev->data->port_id);
6910f20acbfSAlexander Kozyrev 		}
6927d6bf6b8SYongseok Koh 	} else if (mlx5_mprq_enabled(dev)) {
6937d6bf6b8SYongseok Koh 		rx_pkt_burst = mlx5_rx_burst_mprq;
6940f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected MPRQ Rx function",
6950f20acbfSAlexander Kozyrev 			dev->data->port_id);
6960f20acbfSAlexander Kozyrev 	} else {
6970f20acbfSAlexander Kozyrev 		DRV_LOG(DEBUG, "port %u selected SPRQ Rx function",
6980f20acbfSAlexander Kozyrev 			dev->data->port_id);
699cdab90cbSNélio Laranjeiro 	}
7001cfa649bSShahaf Shuler 	return rx_pkt_burst;
7016cb559d6SYongseok Koh }
702d3e0f392SMatan Azrad 
703d3e0f392SMatan Azrad /**
70409a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by port id.
7052e4c987aSOri Kam  *
7062e4c987aSOri Kam  * @param[in] port
7072e4c987aSOri Kam  *   Device port id.
7085e61bcddSViacheslav Ovsiienko  * @param[in] valid
7095e61bcddSViacheslav Ovsiienko  *   Device port id is valid, skip check. This flag is useful
7105e61bcddSViacheslav Ovsiienko  *   when trials are performed from probing and device is not
7115e61bcddSViacheslav Ovsiienko  *   flagged as valid yet (in attaching process).
7122e4c987aSOri Kam  * @param[out] es_domain_id
7132e4c987aSOri Kam  *   E-Switch domain id.
7142e4c987aSOri Kam  * @param[out] es_port_id
7152e4c987aSOri Kam  *   The port id of the port in the E-Switch.
7162e4c987aSOri Kam  *
7172e4c987aSOri Kam  * @return
71809a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
71909a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
7202e4c987aSOri Kam  */
72109a16bcaSViacheslav Ovsiienko struct mlx5_priv *
7225e61bcddSViacheslav Ovsiienko mlx5_port_to_eswitch_info(uint16_t port, bool valid)
7232e4c987aSOri Kam {
7242e4c987aSOri Kam 	struct rte_eth_dev *dev;
7252e4c987aSOri Kam 	struct mlx5_priv *priv;
7262e4c987aSOri Kam 
7272e4c987aSOri Kam 	if (port >= RTE_MAX_ETHPORTS) {
7282e4c987aSOri Kam 		rte_errno = EINVAL;
72909a16bcaSViacheslav Ovsiienko 		return NULL;
7302e4c987aSOri Kam 	}
7315e61bcddSViacheslav Ovsiienko 	if (!valid && !rte_eth_dev_is_valid_port(port)) {
7322e4c987aSOri Kam 		rte_errno = ENODEV;
73309a16bcaSViacheslav Ovsiienko 		return NULL;
7342e4c987aSOri Kam 	}
7352e4c987aSOri Kam 	dev = &rte_eth_devices[port];
7362e4c987aSOri Kam 	priv = dev->data->dev_private;
737cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
7382e4c987aSOri Kam 		rte_errno = EINVAL;
73909a16bcaSViacheslav Ovsiienko 		return NULL;
7402e4c987aSOri Kam 	}
74109a16bcaSViacheslav Ovsiienko 	return priv;
74209a16bcaSViacheslav Ovsiienko }
74309a16bcaSViacheslav Ovsiienko 
74409a16bcaSViacheslav Ovsiienko /**
74509a16bcaSViacheslav Ovsiienko  * Get the E-Switch parameters by device instance.
74609a16bcaSViacheslav Ovsiienko  *
74709a16bcaSViacheslav Ovsiienko  * @param[in] port
74809a16bcaSViacheslav Ovsiienko  *   Device port id.
74909a16bcaSViacheslav Ovsiienko  * @param[out] es_domain_id
75009a16bcaSViacheslav Ovsiienko  *   E-Switch domain id.
75109a16bcaSViacheslav Ovsiienko  * @param[out] es_port_id
75209a16bcaSViacheslav Ovsiienko  *   The port id of the port in the E-Switch.
75309a16bcaSViacheslav Ovsiienko  *
75409a16bcaSViacheslav Ovsiienko  * @return
75509a16bcaSViacheslav Ovsiienko  *   pointer to device private data structure containing data needed
75609a16bcaSViacheslav Ovsiienko  *   on success, NULL otherwise and rte_errno is set.
75709a16bcaSViacheslav Ovsiienko  */
75809a16bcaSViacheslav Ovsiienko struct mlx5_priv *
75909a16bcaSViacheslav Ovsiienko mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
76009a16bcaSViacheslav Ovsiienko {
76109a16bcaSViacheslav Ovsiienko 	struct mlx5_priv *priv;
76209a16bcaSViacheslav Ovsiienko 
76309a16bcaSViacheslav Ovsiienko 	priv = dev->data->dev_private;
764cf004fd3SMichael Baum 	if (!priv->sh->esw_mode) {
76509a16bcaSViacheslav Ovsiienko 		rte_errno = EINVAL;
76609a16bcaSViacheslav Ovsiienko 		return NULL;
76709a16bcaSViacheslav Ovsiienko 	}
76809a16bcaSViacheslav Ovsiienko 	return priv;
7692e4c987aSOri Kam }
7702e4c987aSOri Kam 
7712e4c987aSOri Kam /**
772b6b3bf86SOri Kam  * DPDK callback to retrieve hairpin capabilities.
773b6b3bf86SOri Kam  *
774b6b3bf86SOri Kam  * @param dev
775b6b3bf86SOri Kam  *   Pointer to Ethernet device structure.
776b6b3bf86SOri Kam  * @param[out] cap
777b6b3bf86SOri Kam  *   Storage for hairpin capability data.
778b6b3bf86SOri Kam  *
779b6b3bf86SOri Kam  * @return
780b6b3bf86SOri Kam  *   0 on success, a negative errno value otherwise and rte_errno is set.
781b6b3bf86SOri Kam  */
7821256805dSOphir Munk int
783b00f7603SMichael Baum mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
784b6b3bf86SOri Kam {
785b6b3bf86SOri Kam 	struct mlx5_priv *priv = dev->data->dev_private;
7867274b417SDariusz Sosnowski 	struct mlx5_hca_attr *hca_attr;
787b6b3bf86SOri Kam 
788c4b86201SMichael Baum 	if (!mlx5_devx_obj_ops_en(priv->sh)) {
789b6b3bf86SOri Kam 		rte_errno = ENOTSUP;
790b6b3bf86SOri Kam 		return -rte_errno;
791b6b3bf86SOri Kam 	}
792b6b3bf86SOri Kam 	cap->max_nb_queues = UINT16_MAX;
793b6b3bf86SOri Kam 	cap->max_rx_2_tx = 1;
794b6b3bf86SOri Kam 	cap->max_tx_2_rx = 1;
795b6b3bf86SOri Kam 	cap->max_nb_desc = 8192;
7967274b417SDariusz Sosnowski 	hca_attr = &priv->sh->cdev->config.hca_attr;
797f2d43ff5SDariusz Sosnowski 	cap->rx_cap.locked_device_memory = hca_attr->hairpin_data_buffer_locked;
798f2d43ff5SDariusz Sosnowski 	cap->rx_cap.rte_memory = 0;
7997274b417SDariusz Sosnowski 	cap->tx_cap.locked_device_memory = 0;
8007274b417SDariusz Sosnowski 	cap->tx_cap.rte_memory = hca_attr->hairpin_sq_wq_in_host_mem;
801b6b3bf86SOri Kam 	return 0;
802b6b3bf86SOri Kam }
8036a3446cfSDariusz Sosnowski 
8046a3446cfSDariusz Sosnowski /**
8056a3446cfSDariusz Sosnowski  * Indicate to ethdev layer, what configuration must be restored.
8066a3446cfSDariusz Sosnowski  *
8076a3446cfSDariusz Sosnowski  * @param[in] dev
8086a3446cfSDariusz Sosnowski  *   Pointer to Ethernet device structure.
8096a3446cfSDariusz Sosnowski  * @param[in] op
8106a3446cfSDariusz Sosnowski  *   Type of operation which might require.
8116a3446cfSDariusz Sosnowski  * @param[out] flags
8126a3446cfSDariusz Sosnowski  *   Restore flags will be stored here.
8136a3446cfSDariusz Sosnowski  */
8146a3446cfSDariusz Sosnowski uint64_t
8156a3446cfSDariusz Sosnowski mlx5_get_restore_flags(__rte_unused struct rte_eth_dev *dev,
8166a3446cfSDariusz Sosnowski 		       __rte_unused enum rte_eth_dev_operation op)
8176a3446cfSDariusz Sosnowski {
8186a3446cfSDariusz Sosnowski 	/* mlx5 PMD does not require any configuration restore. */
8196a3446cfSDariusz Sosnowski 	return 0;
8206a3446cfSDariusz Sosnowski }
821