xref: /dpdk/drivers/net/mlx5/mlx5.c (revision d10b09db0a455a27f1f1fa5e4a0fa7b1350706a5)
1771fa900SAdrien Mazarguil /*-
2771fa900SAdrien Mazarguil  *   BSD LICENSE
3771fa900SAdrien Mazarguil  *
4771fa900SAdrien Mazarguil  *   Copyright 2015 6WIND S.A.
5771fa900SAdrien Mazarguil  *   Copyright 2015 Mellanox.
6771fa900SAdrien Mazarguil  *
7771fa900SAdrien Mazarguil  *   Redistribution and use in source and binary forms, with or without
8771fa900SAdrien Mazarguil  *   modification, are permitted provided that the following conditions
9771fa900SAdrien Mazarguil  *   are met:
10771fa900SAdrien Mazarguil  *
11771fa900SAdrien Mazarguil  *     * Redistributions of source code must retain the above copyright
12771fa900SAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer.
13771fa900SAdrien Mazarguil  *     * Redistributions in binary form must reproduce the above copyright
14771fa900SAdrien Mazarguil  *       notice, this list of conditions and the following disclaimer in
15771fa900SAdrien Mazarguil  *       the documentation and/or other materials provided with the
16771fa900SAdrien Mazarguil  *       distribution.
17771fa900SAdrien Mazarguil  *     * Neither the name of 6WIND S.A. nor the names of its
18771fa900SAdrien Mazarguil  *       contributors may be used to endorse or promote products derived
19771fa900SAdrien Mazarguil  *       from this software without specific prior written permission.
20771fa900SAdrien Mazarguil  *
21771fa900SAdrien Mazarguil  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22771fa900SAdrien Mazarguil  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23771fa900SAdrien Mazarguil  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24771fa900SAdrien Mazarguil  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25771fa900SAdrien Mazarguil  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26771fa900SAdrien Mazarguil  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27771fa900SAdrien Mazarguil  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28771fa900SAdrien Mazarguil  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29771fa900SAdrien Mazarguil  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30771fa900SAdrien Mazarguil  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31771fa900SAdrien Mazarguil  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32771fa900SAdrien Mazarguil  */
33771fa900SAdrien Mazarguil 
34771fa900SAdrien Mazarguil #include <stddef.h>
35771fa900SAdrien Mazarguil #include <unistd.h>
36771fa900SAdrien Mazarguil #include <string.h>
37771fa900SAdrien Mazarguil #include <assert.h>
38771fa900SAdrien Mazarguil #include <stdint.h>
39771fa900SAdrien Mazarguil #include <stdlib.h>
40e72dd09bSNélio Laranjeiro #include <errno.h>
41771fa900SAdrien Mazarguil #include <net/if.h>
42771fa900SAdrien Mazarguil 
43771fa900SAdrien Mazarguil /* Verbs header. */
44771fa900SAdrien Mazarguil /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
45771fa900SAdrien Mazarguil #ifdef PEDANTIC
46fc5b160fSBruce Richardson #pragma GCC diagnostic ignored "-Wpedantic"
47771fa900SAdrien Mazarguil #endif
48771fa900SAdrien Mazarguil #include <infiniband/verbs.h>
49771fa900SAdrien Mazarguil #ifdef PEDANTIC
50fc5b160fSBruce Richardson #pragma GCC diagnostic error "-Wpedantic"
51771fa900SAdrien Mazarguil #endif
52771fa900SAdrien Mazarguil 
53771fa900SAdrien Mazarguil #include <rte_malloc.h>
54ffc905f3SFerruh Yigit #include <rte_ethdev_driver.h>
55fdf91e0fSJan Blunck #include <rte_ethdev_pci.h>
56771fa900SAdrien Mazarguil #include <rte_pci.h>
57c752998bSGaetan Rivet #include <rte_bus_pci.h>
58771fa900SAdrien Mazarguil #include <rte_common.h>
59e72dd09bSNélio Laranjeiro #include <rte_kvargs.h>
60771fa900SAdrien Mazarguil 
61771fa900SAdrien Mazarguil #include "mlx5.h"
62771fa900SAdrien Mazarguil #include "mlx5_utils.h"
632e22920bSAdrien Mazarguil #include "mlx5_rxtx.h"
64771fa900SAdrien Mazarguil #include "mlx5_autoconf.h"
6513d57bd5SAdrien Mazarguil #include "mlx5_defs.h"
66771fa900SAdrien Mazarguil 
6799c12dccSNélio Laranjeiro /* Device parameter to enable RX completion queue compression. */
6899c12dccSNélio Laranjeiro #define MLX5_RXQ_CQE_COMP_EN "rxq_cqe_comp_en"
6999c12dccSNélio Laranjeiro 
702a66cf37SYaacov Hazan /* Device parameter to configure inline send. */
712a66cf37SYaacov Hazan #define MLX5_TXQ_INLINE "txq_inline"
722a66cf37SYaacov Hazan 
732a66cf37SYaacov Hazan /*
742a66cf37SYaacov Hazan  * Device parameter to configure the number of TX queues threshold for
752a66cf37SYaacov Hazan  * enabling inline send.
762a66cf37SYaacov Hazan  */
772a66cf37SYaacov Hazan #define MLX5_TXQS_MIN_INLINE "txqs_min_inline"
782a66cf37SYaacov Hazan 
79230189d9SNélio Laranjeiro /* Device parameter to enable multi-packet send WQEs. */
80230189d9SNélio Laranjeiro #define MLX5_TXQ_MPW_EN "txq_mpw_en"
81230189d9SNélio Laranjeiro 
826ce84bd8SYongseok Koh /* Device parameter to include 2 dsegs in the title WQEBB. */
836ce84bd8SYongseok Koh #define MLX5_TXQ_MPW_HDR_DSEG_EN "txq_mpw_hdr_dseg_en"
846ce84bd8SYongseok Koh 
856ce84bd8SYongseok Koh /* Device parameter to limit the size of inlining packet. */
866ce84bd8SYongseok Koh #define MLX5_TXQ_MAX_INLINE_LEN "txq_max_inline_len"
876ce84bd8SYongseok Koh 
885644d5b9SNelio Laranjeiro /* Device parameter to enable hardware Tx vector. */
895644d5b9SNelio Laranjeiro #define MLX5_TX_VEC_EN "tx_vec_en"
905644d5b9SNelio Laranjeiro 
915644d5b9SNelio Laranjeiro /* Device parameter to enable hardware Rx vector. */
925644d5b9SNelio Laranjeiro #define MLX5_RX_VEC_EN "rx_vec_en"
935644d5b9SNelio Laranjeiro 
9443e9d979SShachar Beiser #ifndef HAVE_IBV_MLX5_MOD_MPW
9543e9d979SShachar Beiser #define MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED (1 << 2)
9643e9d979SShachar Beiser #define MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW (1 << 3)
9743e9d979SShachar Beiser #endif
9843e9d979SShachar Beiser 
99523f5a74SYongseok Koh #ifndef HAVE_IBV_MLX5_MOD_CQE_128B_COMP
100523f5a74SYongseok Koh #define MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP (1 << 4)
101523f5a74SYongseok Koh #endif
102523f5a74SYongseok Koh 
103771fa900SAdrien Mazarguil /**
1044d803a72SOlga Shern  * Retrieve integer value from environment variable.
1054d803a72SOlga Shern  *
1064d803a72SOlga Shern  * @param[in] name
1074d803a72SOlga Shern  *   Environment variable name.
1084d803a72SOlga Shern  *
1094d803a72SOlga Shern  * @return
1104d803a72SOlga Shern  *   Integer value, 0 if the variable is not set.
1114d803a72SOlga Shern  */
1124d803a72SOlga Shern int
1134d803a72SOlga Shern mlx5_getenv_int(const char *name)
1144d803a72SOlga Shern {
1154d803a72SOlga Shern 	const char *val = getenv(name);
1164d803a72SOlga Shern 
1174d803a72SOlga Shern 	if (val == NULL)
1184d803a72SOlga Shern 		return 0;
1194d803a72SOlga Shern 	return atoi(val);
1204d803a72SOlga Shern }
1214d803a72SOlga Shern 
1224d803a72SOlga Shern /**
1231e3a39f7SXueming Li  * Verbs callback to allocate a memory. This function should allocate the space
1241e3a39f7SXueming Li  * according to the size provided residing inside a huge page.
1251e3a39f7SXueming Li  * Please note that all allocation must respect the alignment from libmlx5
1261e3a39f7SXueming Li  * (i.e. currently sysconf(_SC_PAGESIZE)).
1271e3a39f7SXueming Li  *
1281e3a39f7SXueming Li  * @param[in] size
1291e3a39f7SXueming Li  *   The size in bytes of the memory to allocate.
1301e3a39f7SXueming Li  * @param[in] data
1311e3a39f7SXueming Li  *   A pointer to the callback data.
1321e3a39f7SXueming Li  *
1331e3a39f7SXueming Li  * @return
1341e3a39f7SXueming Li  *   a pointer to the allocate space.
1351e3a39f7SXueming Li  */
1361e3a39f7SXueming Li static void *
1371e3a39f7SXueming Li mlx5_alloc_verbs_buf(size_t size, void *data)
1381e3a39f7SXueming Li {
1391e3a39f7SXueming Li 	struct priv *priv = data;
1401e3a39f7SXueming Li 	void *ret;
1411e3a39f7SXueming Li 	size_t alignment = sysconf(_SC_PAGESIZE);
142*d10b09dbSOlivier Matz 	unsigned int socket = SOCKET_ID_ANY;
1431e3a39f7SXueming Li 
144*d10b09dbSOlivier Matz 	if (priv->verbs_alloc_ctx.type == MLX5_VERBS_ALLOC_TYPE_TX_QUEUE) {
145*d10b09dbSOlivier Matz 		const struct mlx5_txq_ctrl *ctrl = priv->verbs_alloc_ctx.obj;
146*d10b09dbSOlivier Matz 
147*d10b09dbSOlivier Matz 		socket = ctrl->socket;
148*d10b09dbSOlivier Matz 	} else if (priv->verbs_alloc_ctx.type ==
149*d10b09dbSOlivier Matz 		   MLX5_VERBS_ALLOC_TYPE_RX_QUEUE) {
150*d10b09dbSOlivier Matz 		const struct mlx5_rxq_ctrl *ctrl = priv->verbs_alloc_ctx.obj;
151*d10b09dbSOlivier Matz 
152*d10b09dbSOlivier Matz 		socket = ctrl->socket;
153*d10b09dbSOlivier Matz 	}
1541e3a39f7SXueming Li 	assert(data != NULL);
155*d10b09dbSOlivier Matz 	ret = rte_malloc_socket(__func__, size, alignment, socket);
1561e3a39f7SXueming Li 	DEBUG("Extern alloc size: %lu, align: %lu: %p", size, alignment, ret);
1571e3a39f7SXueming Li 	return ret;
1581e3a39f7SXueming Li }
1591e3a39f7SXueming Li 
1601e3a39f7SXueming Li /**
1611e3a39f7SXueming Li  * Verbs callback to free a memory.
1621e3a39f7SXueming Li  *
1631e3a39f7SXueming Li  * @param[in] ptr
1641e3a39f7SXueming Li  *   A pointer to the memory to free.
1651e3a39f7SXueming Li  * @param[in] data
1661e3a39f7SXueming Li  *   A pointer to the callback data.
1671e3a39f7SXueming Li  */
1681e3a39f7SXueming Li static void
1691e3a39f7SXueming Li mlx5_free_verbs_buf(void *ptr, void *data __rte_unused)
1701e3a39f7SXueming Li {
1711e3a39f7SXueming Li 	assert(data != NULL);
1721e3a39f7SXueming Li 	DEBUG("Extern free request: %p", ptr);
1731e3a39f7SXueming Li 	rte_free(ptr);
1741e3a39f7SXueming Li }
1751e3a39f7SXueming Li 
1761e3a39f7SXueming Li /**
177771fa900SAdrien Mazarguil  * DPDK callback to close the device.
178771fa900SAdrien Mazarguil  *
179771fa900SAdrien Mazarguil  * Destroy all queues and objects, free memory.
180771fa900SAdrien Mazarguil  *
181771fa900SAdrien Mazarguil  * @param dev
182771fa900SAdrien Mazarguil  *   Pointer to Ethernet device structure.
183771fa900SAdrien Mazarguil  */
184771fa900SAdrien Mazarguil static void
185771fa900SAdrien Mazarguil mlx5_dev_close(struct rte_eth_dev *dev)
186771fa900SAdrien Mazarguil {
18701d79216SNélio Laranjeiro 	struct priv *priv = dev->data->dev_private;
1882e22920bSAdrien Mazarguil 	unsigned int i;
1896af6b973SNélio Laranjeiro 	int ret;
190771fa900SAdrien Mazarguil 
191771fa900SAdrien Mazarguil 	priv_lock(priv);
192771fa900SAdrien Mazarguil 	DEBUG("%p: closing device \"%s\"",
193771fa900SAdrien Mazarguil 	      (void *)dev,
194771fa900SAdrien Mazarguil 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
195ecc1c29dSAdrien Mazarguil 	/* In case mlx5_dev_stop() has not been called. */
196198a3c33SNelio Laranjeiro 	priv_dev_interrupt_handler_uninstall(priv, dev);
197272733b5SNélio Laranjeiro 	priv_dev_traffic_disable(priv, dev);
1982e22920bSAdrien Mazarguil 	/* Prevent crashes when queues are still in use. */
1992e22920bSAdrien Mazarguil 	dev->rx_pkt_burst = removed_rx_burst;
2002e22920bSAdrien Mazarguil 	dev->tx_pkt_burst = removed_tx_burst;
2012e22920bSAdrien Mazarguil 	if (priv->rxqs != NULL) {
2022e22920bSAdrien Mazarguil 		/* XXX race condition if mlx5_rx_burst() is still running. */
2032e22920bSAdrien Mazarguil 		usleep(1000);
204a1366b1aSNélio Laranjeiro 		for (i = 0; (i != priv->rxqs_n); ++i)
205a1366b1aSNélio Laranjeiro 			mlx5_priv_rxq_release(priv, i);
2062e22920bSAdrien Mazarguil 		priv->rxqs_n = 0;
2072e22920bSAdrien Mazarguil 		priv->rxqs = NULL;
2082e22920bSAdrien Mazarguil 	}
2092e22920bSAdrien Mazarguil 	if (priv->txqs != NULL) {
2102e22920bSAdrien Mazarguil 		/* XXX race condition if mlx5_tx_burst() is still running. */
2112e22920bSAdrien Mazarguil 		usleep(1000);
2126e78005aSNélio Laranjeiro 		for (i = 0; (i != priv->txqs_n); ++i)
2136e78005aSNélio Laranjeiro 			mlx5_priv_txq_release(priv, i);
2142e22920bSAdrien Mazarguil 		priv->txqs_n = 0;
2152e22920bSAdrien Mazarguil 		priv->txqs = NULL;
2162e22920bSAdrien Mazarguil 	}
217771fa900SAdrien Mazarguil 	if (priv->pd != NULL) {
218771fa900SAdrien Mazarguil 		assert(priv->ctx != NULL);
219771fa900SAdrien Mazarguil 		claim_zero(ibv_dealloc_pd(priv->pd));
220771fa900SAdrien Mazarguil 		claim_zero(ibv_close_device(priv->ctx));
221771fa900SAdrien Mazarguil 	} else
222771fa900SAdrien Mazarguil 		assert(priv->ctx == NULL);
22329c1d8bbSNélio Laranjeiro 	if (priv->rss_conf.rss_key != NULL)
22429c1d8bbSNélio Laranjeiro 		rte_free(priv->rss_conf.rss_key);
225634efbc2SNelio Laranjeiro 	if (priv->reta_idx != NULL)
226634efbc2SNelio Laranjeiro 		rte_free(priv->reta_idx);
227f8b9a3baSXueming Li 	priv_socket_uninit(priv);
228f5479b68SNélio Laranjeiro 	ret = mlx5_priv_hrxq_ibv_verify(priv);
229f5479b68SNélio Laranjeiro 	if (ret)
230f5479b68SNélio Laranjeiro 		WARN("%p: some Hash Rx queue still remain", (void *)priv);
2314c7a0f5fSNélio Laranjeiro 	ret = mlx5_priv_ind_table_ibv_verify(priv);
2324c7a0f5fSNélio Laranjeiro 	if (ret)
2334c7a0f5fSNélio Laranjeiro 		WARN("%p: some Indirection table still remain", (void *)priv);
23409cb5b58SNélio Laranjeiro 	ret = mlx5_priv_rxq_ibv_verify(priv);
23509cb5b58SNélio Laranjeiro 	if (ret)
23609cb5b58SNélio Laranjeiro 		WARN("%p: some Verbs Rx queue still remain", (void *)priv);
237a1366b1aSNélio Laranjeiro 	ret = mlx5_priv_rxq_verify(priv);
238a1366b1aSNélio Laranjeiro 	if (ret)
239a1366b1aSNélio Laranjeiro 		WARN("%p: some Rx Queues still remain", (void *)priv);
240faf2667fSNélio Laranjeiro 	ret = mlx5_priv_txq_ibv_verify(priv);
241faf2667fSNélio Laranjeiro 	if (ret)
242faf2667fSNélio Laranjeiro 		WARN("%p: some Verbs Tx queue still remain", (void *)priv);
2436e78005aSNélio Laranjeiro 	ret = mlx5_priv_txq_verify(priv);
2446e78005aSNélio Laranjeiro 	if (ret)
2456e78005aSNélio Laranjeiro 		WARN("%p: some Tx Queues still remain", (void *)priv);
2466af6b973SNélio Laranjeiro 	ret = priv_flow_verify(priv);
2476af6b973SNélio Laranjeiro 	if (ret)
2486af6b973SNélio Laranjeiro 		WARN("%p: some flows still remain", (void *)priv);
249f8fb87d5SNélio Laranjeiro 	ret = priv_mr_verify(priv);
250f8fb87d5SNélio Laranjeiro 	if (ret)
251f8fb87d5SNélio Laranjeiro 		WARN("%p: some Memory Region still remain", (void *)priv);
252771fa900SAdrien Mazarguil 	priv_unlock(priv);
253771fa900SAdrien Mazarguil 	memset(priv, 0, sizeof(*priv));
254771fa900SAdrien Mazarguil }
255771fa900SAdrien Mazarguil 
2560887aa7fSNélio Laranjeiro const struct eth_dev_ops mlx5_dev_ops = {
257e60fbd5bSAdrien Mazarguil 	.dev_configure = mlx5_dev_configure,
258e60fbd5bSAdrien Mazarguil 	.dev_start = mlx5_dev_start,
259e60fbd5bSAdrien Mazarguil 	.dev_stop = mlx5_dev_stop,
26062072098SOr Ami 	.dev_set_link_down = mlx5_set_link_down,
26162072098SOr Ami 	.dev_set_link_up = mlx5_set_link_up,
262771fa900SAdrien Mazarguil 	.dev_close = mlx5_dev_close,
2631bdbe1afSAdrien Mazarguil 	.promiscuous_enable = mlx5_promiscuous_enable,
2641bdbe1afSAdrien Mazarguil 	.promiscuous_disable = mlx5_promiscuous_disable,
2651bdbe1afSAdrien Mazarguil 	.allmulticast_enable = mlx5_allmulticast_enable,
2661bdbe1afSAdrien Mazarguil 	.allmulticast_disable = mlx5_allmulticast_disable,
267cb8faed7SAdrien Mazarguil 	.link_update = mlx5_link_update,
26887011737SAdrien Mazarguil 	.stats_get = mlx5_stats_get,
26987011737SAdrien Mazarguil 	.stats_reset = mlx5_stats_reset,
270a4193ae3SShahaf Shuler 	.xstats_get = mlx5_xstats_get,
271a4193ae3SShahaf Shuler 	.xstats_reset = mlx5_xstats_reset,
272a4193ae3SShahaf Shuler 	.xstats_get_names = mlx5_xstats_get_names,
273e60fbd5bSAdrien Mazarguil 	.dev_infos_get = mlx5_dev_infos_get,
27478a38edfSJianfeng Tan 	.dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
275e9086978SAdrien Mazarguil 	.vlan_filter_set = mlx5_vlan_filter_set,
2762e22920bSAdrien Mazarguil 	.rx_queue_setup = mlx5_rx_queue_setup,
2772e22920bSAdrien Mazarguil 	.tx_queue_setup = mlx5_tx_queue_setup,
2782e22920bSAdrien Mazarguil 	.rx_queue_release = mlx5_rx_queue_release,
2792e22920bSAdrien Mazarguil 	.tx_queue_release = mlx5_tx_queue_release,
28002d75430SAdrien Mazarguil 	.flow_ctrl_get = mlx5_dev_get_flow_ctrl,
28102d75430SAdrien Mazarguil 	.flow_ctrl_set = mlx5_dev_set_flow_ctrl,
2823318aef7SAdrien Mazarguil 	.mac_addr_remove = mlx5_mac_addr_remove,
2833318aef7SAdrien Mazarguil 	.mac_addr_add = mlx5_mac_addr_add,
28486977fccSDavid Marchand 	.mac_addr_set = mlx5_mac_addr_set,
285cf37ca95SAdrien Mazarguil 	.mtu_set = mlx5_dev_set_mtu,
286f3db9489SYaacov Hazan 	.vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
287f3db9489SYaacov Hazan 	.vlan_offload_set = mlx5_vlan_offload_set,
288634efbc2SNelio Laranjeiro 	.reta_update = mlx5_dev_rss_reta_update,
289634efbc2SNelio Laranjeiro 	.reta_query = mlx5_dev_rss_reta_query,
2902f97422eSNelio Laranjeiro 	.rss_hash_update = mlx5_rss_hash_update,
2912f97422eSNelio Laranjeiro 	.rss_hash_conf_get = mlx5_rss_hash_conf_get,
29276f5c99eSYaacov Hazan 	.filter_ctrl = mlx5_dev_filter_ctrl,
2938788fec1SOlivier Matz 	.rx_descriptor_status = mlx5_rx_descriptor_status,
2948788fec1SOlivier Matz 	.tx_descriptor_status = mlx5_tx_descriptor_status,
2953c7d44afSShahaf Shuler 	.rx_queue_intr_enable = mlx5_rx_intr_enable,
2963c7d44afSShahaf Shuler 	.rx_queue_intr_disable = mlx5_rx_intr_disable,
297d3e0f392SMatan Azrad 	.is_removed = mlx5_is_removed,
298771fa900SAdrien Mazarguil };
299771fa900SAdrien Mazarguil 
30087ec44ceSXueming Li static const struct eth_dev_ops mlx5_dev_sec_ops = {
30187ec44ceSXueming Li 	.stats_get = mlx5_stats_get,
30287ec44ceSXueming Li 	.stats_reset = mlx5_stats_reset,
30387ec44ceSXueming Li 	.xstats_get = mlx5_xstats_get,
30487ec44ceSXueming Li 	.xstats_reset = mlx5_xstats_reset,
30587ec44ceSXueming Li 	.xstats_get_names = mlx5_xstats_get_names,
30687ec44ceSXueming Li 	.dev_infos_get = mlx5_dev_infos_get,
30787ec44ceSXueming Li 	.rx_descriptor_status = mlx5_rx_descriptor_status,
30887ec44ceSXueming Li 	.tx_descriptor_status = mlx5_tx_descriptor_status,
30987ec44ceSXueming Li };
31087ec44ceSXueming Li 
3110887aa7fSNélio Laranjeiro /* Available operators in flow isolated mode. */
3120887aa7fSNélio Laranjeiro const struct eth_dev_ops mlx5_dev_ops_isolate = {
3130887aa7fSNélio Laranjeiro 	.dev_configure = mlx5_dev_configure,
3140887aa7fSNélio Laranjeiro 	.dev_start = mlx5_dev_start,
3150887aa7fSNélio Laranjeiro 	.dev_stop = mlx5_dev_stop,
3160887aa7fSNélio Laranjeiro 	.dev_set_link_down = mlx5_set_link_down,
3170887aa7fSNélio Laranjeiro 	.dev_set_link_up = mlx5_set_link_up,
3180887aa7fSNélio Laranjeiro 	.dev_close = mlx5_dev_close,
3190887aa7fSNélio Laranjeiro 	.link_update = mlx5_link_update,
3200887aa7fSNélio Laranjeiro 	.stats_get = mlx5_stats_get,
3210887aa7fSNélio Laranjeiro 	.stats_reset = mlx5_stats_reset,
3220887aa7fSNélio Laranjeiro 	.xstats_get = mlx5_xstats_get,
3230887aa7fSNélio Laranjeiro 	.xstats_reset = mlx5_xstats_reset,
3240887aa7fSNélio Laranjeiro 	.xstats_get_names = mlx5_xstats_get_names,
3250887aa7fSNélio Laranjeiro 	.dev_infos_get = mlx5_dev_infos_get,
3260887aa7fSNélio Laranjeiro 	.dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
3270887aa7fSNélio Laranjeiro 	.vlan_filter_set = mlx5_vlan_filter_set,
3280887aa7fSNélio Laranjeiro 	.rx_queue_setup = mlx5_rx_queue_setup,
3290887aa7fSNélio Laranjeiro 	.tx_queue_setup = mlx5_tx_queue_setup,
3300887aa7fSNélio Laranjeiro 	.rx_queue_release = mlx5_rx_queue_release,
3310887aa7fSNélio Laranjeiro 	.tx_queue_release = mlx5_tx_queue_release,
3320887aa7fSNélio Laranjeiro 	.flow_ctrl_get = mlx5_dev_get_flow_ctrl,
3330887aa7fSNélio Laranjeiro 	.flow_ctrl_set = mlx5_dev_set_flow_ctrl,
3340887aa7fSNélio Laranjeiro 	.mac_addr_remove = mlx5_mac_addr_remove,
3350887aa7fSNélio Laranjeiro 	.mac_addr_add = mlx5_mac_addr_add,
3360887aa7fSNélio Laranjeiro 	.mac_addr_set = mlx5_mac_addr_set,
3370887aa7fSNélio Laranjeiro 	.mtu_set = mlx5_dev_set_mtu,
3380887aa7fSNélio Laranjeiro 	.vlan_strip_queue_set = mlx5_vlan_strip_queue_set,
3390887aa7fSNélio Laranjeiro 	.vlan_offload_set = mlx5_vlan_offload_set,
3400887aa7fSNélio Laranjeiro 	.filter_ctrl = mlx5_dev_filter_ctrl,
3410887aa7fSNélio Laranjeiro 	.rx_descriptor_status = mlx5_rx_descriptor_status,
3420887aa7fSNélio Laranjeiro 	.tx_descriptor_status = mlx5_tx_descriptor_status,
3430887aa7fSNélio Laranjeiro 	.rx_queue_intr_enable = mlx5_rx_intr_enable,
3440887aa7fSNélio Laranjeiro 	.rx_queue_intr_disable = mlx5_rx_intr_disable,
345d3e0f392SMatan Azrad 	.is_removed = mlx5_is_removed,
3460887aa7fSNélio Laranjeiro };
3470887aa7fSNélio Laranjeiro 
348771fa900SAdrien Mazarguil static struct {
349771fa900SAdrien Mazarguil 	struct rte_pci_addr pci_addr; /* associated PCI address */
350771fa900SAdrien Mazarguil 	uint32_t ports; /* physical ports bitfield. */
351771fa900SAdrien Mazarguil } mlx5_dev[32];
352771fa900SAdrien Mazarguil 
353771fa900SAdrien Mazarguil /**
354771fa900SAdrien Mazarguil  * Get device index in mlx5_dev[] from PCI bus address.
355771fa900SAdrien Mazarguil  *
356771fa900SAdrien Mazarguil  * @param[in] pci_addr
357771fa900SAdrien Mazarguil  *   PCI bus address to look for.
358771fa900SAdrien Mazarguil  *
359771fa900SAdrien Mazarguil  * @return
360771fa900SAdrien Mazarguil  *   mlx5_dev[] index on success, -1 on failure.
361771fa900SAdrien Mazarguil  */
362771fa900SAdrien Mazarguil static int
363771fa900SAdrien Mazarguil mlx5_dev_idx(struct rte_pci_addr *pci_addr)
364771fa900SAdrien Mazarguil {
365771fa900SAdrien Mazarguil 	unsigned int i;
366771fa900SAdrien Mazarguil 	int ret = -1;
367771fa900SAdrien Mazarguil 
368771fa900SAdrien Mazarguil 	assert(pci_addr != NULL);
369771fa900SAdrien Mazarguil 	for (i = 0; (i != RTE_DIM(mlx5_dev)); ++i) {
370771fa900SAdrien Mazarguil 		if ((mlx5_dev[i].pci_addr.domain == pci_addr->domain) &&
371771fa900SAdrien Mazarguil 		    (mlx5_dev[i].pci_addr.bus == pci_addr->bus) &&
372771fa900SAdrien Mazarguil 		    (mlx5_dev[i].pci_addr.devid == pci_addr->devid) &&
373771fa900SAdrien Mazarguil 		    (mlx5_dev[i].pci_addr.function == pci_addr->function))
374771fa900SAdrien Mazarguil 			return i;
375771fa900SAdrien Mazarguil 		if ((mlx5_dev[i].ports == 0) && (ret == -1))
376771fa900SAdrien Mazarguil 			ret = i;
377771fa900SAdrien Mazarguil 	}
378771fa900SAdrien Mazarguil 	return ret;
379771fa900SAdrien Mazarguil }
380771fa900SAdrien Mazarguil 
381e72dd09bSNélio Laranjeiro /**
382e72dd09bSNélio Laranjeiro  * Verify and store value for device argument.
383e72dd09bSNélio Laranjeiro  *
384e72dd09bSNélio Laranjeiro  * @param[in] key
385e72dd09bSNélio Laranjeiro  *   Key argument to verify.
386e72dd09bSNélio Laranjeiro  * @param[in] val
387e72dd09bSNélio Laranjeiro  *   Value associated with key.
388e72dd09bSNélio Laranjeiro  * @param opaque
389e72dd09bSNélio Laranjeiro  *   User data.
390e72dd09bSNélio Laranjeiro  *
391e72dd09bSNélio Laranjeiro  * @return
392e72dd09bSNélio Laranjeiro  *   0 on success, negative errno value on failure.
393e72dd09bSNélio Laranjeiro  */
394e72dd09bSNélio Laranjeiro static int
395e72dd09bSNélio Laranjeiro mlx5_args_check(const char *key, const char *val, void *opaque)
396e72dd09bSNélio Laranjeiro {
3977fe24446SShahaf Shuler 	struct mlx5_dev_config *config = opaque;
39899c12dccSNélio Laranjeiro 	unsigned long tmp;
399e72dd09bSNélio Laranjeiro 
40099c12dccSNélio Laranjeiro 	errno = 0;
40199c12dccSNélio Laranjeiro 	tmp = strtoul(val, NULL, 0);
40299c12dccSNélio Laranjeiro 	if (errno) {
40399c12dccSNélio Laranjeiro 		WARN("%s: \"%s\" is not a valid integer", key, val);
40499c12dccSNélio Laranjeiro 		return errno;
40599c12dccSNélio Laranjeiro 	}
40699c12dccSNélio Laranjeiro 	if (strcmp(MLX5_RXQ_CQE_COMP_EN, key) == 0) {
4077fe24446SShahaf Shuler 		config->cqe_comp = !!tmp;
4082a66cf37SYaacov Hazan 	} else if (strcmp(MLX5_TXQ_INLINE, key) == 0) {
4097fe24446SShahaf Shuler 		config->txq_inline = tmp;
4102a66cf37SYaacov Hazan 	} else if (strcmp(MLX5_TXQS_MIN_INLINE, key) == 0) {
4117fe24446SShahaf Shuler 		config->txqs_inline = tmp;
412230189d9SNélio Laranjeiro 	} else if (strcmp(MLX5_TXQ_MPW_EN, key) == 0) {
4137fe24446SShahaf Shuler 		config->mps = !!tmp ? config->mps : 0;
4146ce84bd8SYongseok Koh 	} else if (strcmp(MLX5_TXQ_MPW_HDR_DSEG_EN, key) == 0) {
4157fe24446SShahaf Shuler 		config->mpw_hdr_dseg = !!tmp;
4166ce84bd8SYongseok Koh 	} else if (strcmp(MLX5_TXQ_MAX_INLINE_LEN, key) == 0) {
4177fe24446SShahaf Shuler 		config->inline_max_packet_sz = tmp;
4185644d5b9SNelio Laranjeiro 	} else if (strcmp(MLX5_TX_VEC_EN, key) == 0) {
4197fe24446SShahaf Shuler 		config->tx_vec_en = !!tmp;
4205644d5b9SNelio Laranjeiro 	} else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
4217fe24446SShahaf Shuler 		config->rx_vec_en = !!tmp;
42299c12dccSNélio Laranjeiro 	} else {
423e72dd09bSNélio Laranjeiro 		WARN("%s: unknown parameter", key);
424e72dd09bSNélio Laranjeiro 		return -EINVAL;
425e72dd09bSNélio Laranjeiro 	}
42699c12dccSNélio Laranjeiro 	return 0;
42799c12dccSNélio Laranjeiro }
428e72dd09bSNélio Laranjeiro 
429e72dd09bSNélio Laranjeiro /**
430e72dd09bSNélio Laranjeiro  * Parse device parameters.
431e72dd09bSNélio Laranjeiro  *
4327fe24446SShahaf Shuler  * @param config
4337fe24446SShahaf Shuler  *   Pointer to device configuration structure.
434e72dd09bSNélio Laranjeiro  * @param devargs
435e72dd09bSNélio Laranjeiro  *   Device arguments structure.
436e72dd09bSNélio Laranjeiro  *
437e72dd09bSNélio Laranjeiro  * @return
438e72dd09bSNélio Laranjeiro  *   0 on success, errno value on failure.
439e72dd09bSNélio Laranjeiro  */
440e72dd09bSNélio Laranjeiro static int
4417fe24446SShahaf Shuler mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
442e72dd09bSNélio Laranjeiro {
443e72dd09bSNélio Laranjeiro 	const char **params = (const char *[]){
44499c12dccSNélio Laranjeiro 		MLX5_RXQ_CQE_COMP_EN,
4452a66cf37SYaacov Hazan 		MLX5_TXQ_INLINE,
4462a66cf37SYaacov Hazan 		MLX5_TXQS_MIN_INLINE,
447230189d9SNélio Laranjeiro 		MLX5_TXQ_MPW_EN,
4486ce84bd8SYongseok Koh 		MLX5_TXQ_MPW_HDR_DSEG_EN,
4496ce84bd8SYongseok Koh 		MLX5_TXQ_MAX_INLINE_LEN,
4505644d5b9SNelio Laranjeiro 		MLX5_TX_VEC_EN,
4515644d5b9SNelio Laranjeiro 		MLX5_RX_VEC_EN,
452e72dd09bSNélio Laranjeiro 		NULL,
453e72dd09bSNélio Laranjeiro 	};
454e72dd09bSNélio Laranjeiro 	struct rte_kvargs *kvlist;
455e72dd09bSNélio Laranjeiro 	int ret = 0;
456e72dd09bSNélio Laranjeiro 	int i;
457e72dd09bSNélio Laranjeiro 
458e72dd09bSNélio Laranjeiro 	if (devargs == NULL)
459e72dd09bSNélio Laranjeiro 		return 0;
460e72dd09bSNélio Laranjeiro 	/* Following UGLY cast is done to pass checkpatch. */
461e72dd09bSNélio Laranjeiro 	kvlist = rte_kvargs_parse(devargs->args, params);
462e72dd09bSNélio Laranjeiro 	if (kvlist == NULL)
463e72dd09bSNélio Laranjeiro 		return 0;
464e72dd09bSNélio Laranjeiro 	/* Process parameters. */
465e72dd09bSNélio Laranjeiro 	for (i = 0; (params[i] != NULL); ++i) {
466e72dd09bSNélio Laranjeiro 		if (rte_kvargs_count(kvlist, params[i])) {
467e72dd09bSNélio Laranjeiro 			ret = rte_kvargs_process(kvlist, params[i],
4687fe24446SShahaf Shuler 						 mlx5_args_check, config);
469a67323e4SShahaf Shuler 			if (ret != 0) {
470a67323e4SShahaf Shuler 				rte_kvargs_free(kvlist);
471e72dd09bSNélio Laranjeiro 				return ret;
472e72dd09bSNélio Laranjeiro 			}
473e72dd09bSNélio Laranjeiro 		}
474a67323e4SShahaf Shuler 	}
475e72dd09bSNélio Laranjeiro 	rte_kvargs_free(kvlist);
476e72dd09bSNélio Laranjeiro 	return 0;
477e72dd09bSNélio Laranjeiro }
478e72dd09bSNélio Laranjeiro 
479fdf91e0fSJan Blunck static struct rte_pci_driver mlx5_driver;
480771fa900SAdrien Mazarguil 
481771fa900SAdrien Mazarguil /**
482771fa900SAdrien Mazarguil  * DPDK callback to register a PCI device.
483771fa900SAdrien Mazarguil  *
484771fa900SAdrien Mazarguil  * This function creates an Ethernet device for each port of a given
485771fa900SAdrien Mazarguil  * PCI device.
486771fa900SAdrien Mazarguil  *
487771fa900SAdrien Mazarguil  * @param[in] pci_drv
488771fa900SAdrien Mazarguil  *   PCI driver structure (mlx5_driver).
489771fa900SAdrien Mazarguil  * @param[in] pci_dev
490771fa900SAdrien Mazarguil  *   PCI device information.
491771fa900SAdrien Mazarguil  *
492771fa900SAdrien Mazarguil  * @return
493771fa900SAdrien Mazarguil  *   0 on success, negative errno value on failure.
494771fa900SAdrien Mazarguil  */
495771fa900SAdrien Mazarguil static int
496af424af8SShreyansh Jain mlx5_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
497771fa900SAdrien Mazarguil {
498771fa900SAdrien Mazarguil 	struct ibv_device **list;
499771fa900SAdrien Mazarguil 	struct ibv_device *ibv_dev;
500771fa900SAdrien Mazarguil 	int err = 0;
501771fa900SAdrien Mazarguil 	struct ibv_context *attr_ctx = NULL;
50243e9d979SShachar Beiser 	struct ibv_device_attr_ex device_attr;
50385e347dbSNélio Laranjeiro 	unsigned int sriov;
504e192ef80SYaacov Hazan 	unsigned int mps;
505523f5a74SYongseok Koh 	unsigned int cqe_comp;
506772d3435SXueming Li 	unsigned int tunnel_en = 0;
507771fa900SAdrien Mazarguil 	int idx;
508771fa900SAdrien Mazarguil 	int i;
50943e9d979SShachar Beiser 	struct mlx5dv_context attrs_out;
5109a761de8SOri Kam #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
5119a761de8SOri Kam 	struct ibv_counter_set_description cs_desc;
5129a761de8SOri Kam #endif
513771fa900SAdrien Mazarguil 
514771fa900SAdrien Mazarguil 	(void)pci_drv;
515fdf91e0fSJan Blunck 	assert(pci_drv == &mlx5_driver);
516771fa900SAdrien Mazarguil 	/* Get mlx5_dev[] index. */
517771fa900SAdrien Mazarguil 	idx = mlx5_dev_idx(&pci_dev->addr);
518771fa900SAdrien Mazarguil 	if (idx == -1) {
519771fa900SAdrien Mazarguil 		ERROR("this driver cannot support any more adapters");
520771fa900SAdrien Mazarguil 		return -ENOMEM;
521771fa900SAdrien Mazarguil 	}
522771fa900SAdrien Mazarguil 	DEBUG("using driver device index %d", idx);
523771fa900SAdrien Mazarguil 
524771fa900SAdrien Mazarguil 	/* Save PCI address. */
525771fa900SAdrien Mazarguil 	mlx5_dev[idx].pci_addr = pci_dev->addr;
526771fa900SAdrien Mazarguil 	list = ibv_get_device_list(&i);
527771fa900SAdrien Mazarguil 	if (list == NULL) {
528771fa900SAdrien Mazarguil 		assert(errno);
5295525aa8fSGaetan Rivet 		if (errno == ENOSYS)
5305525aa8fSGaetan Rivet 			ERROR("cannot list devices, is ib_uverbs loaded?");
531771fa900SAdrien Mazarguil 		return -errno;
532771fa900SAdrien Mazarguil 	}
533771fa900SAdrien Mazarguil 	assert(i >= 0);
534771fa900SAdrien Mazarguil 	/*
535771fa900SAdrien Mazarguil 	 * For each listed device, check related sysfs entry against
536771fa900SAdrien Mazarguil 	 * the provided PCI ID.
537771fa900SAdrien Mazarguil 	 */
538771fa900SAdrien Mazarguil 	while (i != 0) {
539771fa900SAdrien Mazarguil 		struct rte_pci_addr pci_addr;
540771fa900SAdrien Mazarguil 
541771fa900SAdrien Mazarguil 		--i;
542771fa900SAdrien Mazarguil 		DEBUG("checking device \"%s\"", list[i]->name);
543771fa900SAdrien Mazarguil 		if (mlx5_ibv_device_to_pci_addr(list[i], &pci_addr))
544771fa900SAdrien Mazarguil 			continue;
545771fa900SAdrien Mazarguil 		if ((pci_dev->addr.domain != pci_addr.domain) ||
546771fa900SAdrien Mazarguil 		    (pci_dev->addr.bus != pci_addr.bus) ||
547771fa900SAdrien Mazarguil 		    (pci_dev->addr.devid != pci_addr.devid) ||
548771fa900SAdrien Mazarguil 		    (pci_dev->addr.function != pci_addr.function))
549771fa900SAdrien Mazarguil 			continue;
55085e347dbSNélio Laranjeiro 		sriov = ((pci_dev->id.device_id ==
551771fa900SAdrien Mazarguil 		       PCI_DEVICE_ID_MELLANOX_CONNECTX4VF) ||
552771fa900SAdrien Mazarguil 		      (pci_dev->id.device_id ==
553528a9fbeSYongseok Koh 		       PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF) ||
554528a9fbeSYongseok Koh 		      (pci_dev->id.device_id ==
555528a9fbeSYongseok Koh 		       PCI_DEVICE_ID_MELLANOX_CONNECTX5VF) ||
556528a9fbeSYongseok Koh 		      (pci_dev->id.device_id ==
557528a9fbeSYongseok Koh 		       PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF));
558528a9fbeSYongseok Koh 		switch (pci_dev->id.device_id) {
559f5fde520SShahaf Shuler 		case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
560f5fde520SShahaf Shuler 			tunnel_en = 1;
561f5fde520SShahaf Shuler 			break;
562528a9fbeSYongseok Koh 		case PCI_DEVICE_ID_MELLANOX_CONNECTX4LX:
563528a9fbeSYongseok Koh 		case PCI_DEVICE_ID_MELLANOX_CONNECTX5:
564528a9fbeSYongseok Koh 		case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
565528a9fbeSYongseok Koh 		case PCI_DEVICE_ID_MELLANOX_CONNECTX5EX:
566528a9fbeSYongseok Koh 		case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
567f5fde520SShahaf Shuler 			tunnel_en = 1;
568528a9fbeSYongseok Koh 			break;
569528a9fbeSYongseok Koh 		default:
57043e9d979SShachar Beiser 			break;
571528a9fbeSYongseok Koh 		}
57285e347dbSNélio Laranjeiro 		INFO("PCI information matches, using device \"%s\""
57343e9d979SShachar Beiser 		     " (SR-IOV: %s)",
574e192ef80SYaacov Hazan 		     list[i]->name,
57543e9d979SShachar Beiser 		     sriov ? "true" : "false");
576771fa900SAdrien Mazarguil 		attr_ctx = ibv_open_device(list[i]);
577771fa900SAdrien Mazarguil 		err = errno;
578771fa900SAdrien Mazarguil 		break;
579771fa900SAdrien Mazarguil 	}
580771fa900SAdrien Mazarguil 	if (attr_ctx == NULL) {
581771fa900SAdrien Mazarguil 		ibv_free_device_list(list);
582771fa900SAdrien Mazarguil 		switch (err) {
583771fa900SAdrien Mazarguil 		case 0:
5845525aa8fSGaetan Rivet 			ERROR("cannot access device, is mlx5_ib loaded?");
5855525aa8fSGaetan Rivet 			return -ENODEV;
586771fa900SAdrien Mazarguil 		case EINVAL:
5875525aa8fSGaetan Rivet 			ERROR("cannot use device, are drivers up to date?");
5885525aa8fSGaetan Rivet 			return -EINVAL;
589771fa900SAdrien Mazarguil 		}
590771fa900SAdrien Mazarguil 		assert(err > 0);
591771fa900SAdrien Mazarguil 		return -err;
592771fa900SAdrien Mazarguil 	}
593771fa900SAdrien Mazarguil 	ibv_dev = list[i];
594771fa900SAdrien Mazarguil 
595771fa900SAdrien Mazarguil 	DEBUG("device opened");
59643e9d979SShachar Beiser 	/*
59743e9d979SShachar Beiser 	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
59843e9d979SShachar Beiser 	 * as all ConnectX-5 devices.
59943e9d979SShachar Beiser 	 */
60043e9d979SShachar Beiser 	mlx5dv_query_device(attr_ctx, &attrs_out);
601e589960cSYongseok Koh 	if (attrs_out.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
602e589960cSYongseok Koh 		if (attrs_out.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
603e589960cSYongseok Koh 			DEBUG("Enhanced MPW is supported");
60443e9d979SShachar Beiser 			mps = MLX5_MPW_ENHANCED;
60543e9d979SShachar Beiser 		} else {
606e589960cSYongseok Koh 			DEBUG("MPW is supported");
607e589960cSYongseok Koh 			mps = MLX5_MPW;
608e589960cSYongseok Koh 		}
609e589960cSYongseok Koh 	} else {
610e589960cSYongseok Koh 		DEBUG("MPW isn't supported");
61143e9d979SShachar Beiser 		mps = MLX5_MPW_DISABLED;
61243e9d979SShachar Beiser 	}
613523f5a74SYongseok Koh 	if (RTE_CACHE_LINE_SIZE == 128 &&
614523f5a74SYongseok Koh 	    !(attrs_out.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP))
615523f5a74SYongseok Koh 		cqe_comp = 0;
616523f5a74SYongseok Koh 	else
617523f5a74SYongseok Koh 		cqe_comp = 1;
61843e9d979SShachar Beiser 	if (ibv_query_device_ex(attr_ctx, NULL, &device_attr))
619771fa900SAdrien Mazarguil 		goto error;
62043e9d979SShachar Beiser 	INFO("%u port(s) detected", device_attr.orig_attr.phys_port_cnt);
621771fa900SAdrien Mazarguil 
62243e9d979SShachar Beiser 	for (i = 0; i < device_attr.orig_attr.phys_port_cnt; i++) {
623771fa900SAdrien Mazarguil 		uint32_t port = i + 1; /* ports are indexed from one */
624771fa900SAdrien Mazarguil 		uint32_t test = (1 << i);
625771fa900SAdrien Mazarguil 		struct ibv_context *ctx = NULL;
626771fa900SAdrien Mazarguil 		struct ibv_port_attr port_attr;
627771fa900SAdrien Mazarguil 		struct ibv_pd *pd = NULL;
628771fa900SAdrien Mazarguil 		struct priv *priv = NULL;
629771fa900SAdrien Mazarguil 		struct rte_eth_dev *eth_dev;
63043e9d979SShachar Beiser 		struct ibv_device_attr_ex device_attr_ex;
631771fa900SAdrien Mazarguil 		struct ether_addr mac;
63285e347dbSNélio Laranjeiro 		uint16_t num_vfs = 0;
6339a761de8SOri Kam 		struct ibv_device_attr_ex device_attr;
6347fe24446SShahaf Shuler 		struct mlx5_dev_config config = {
6357fe24446SShahaf Shuler 			.cqe_comp = cqe_comp,
6367fe24446SShahaf Shuler 			.mps = mps,
6377fe24446SShahaf Shuler 			.tunnel_en = tunnel_en,
6387fe24446SShahaf Shuler 			.tx_vec_en = 1,
6397fe24446SShahaf Shuler 			.rx_vec_en = 1,
6407fe24446SShahaf Shuler 			.mpw_hdr_dseg = 0,
64150b244a1SShahaf Shuler 			.txq_inline = MLX5_ARG_UNSET,
64250b244a1SShahaf Shuler 			.txqs_inline = MLX5_ARG_UNSET,
64350b244a1SShahaf Shuler 			.inline_max_packet_sz = MLX5_ARG_UNSET,
64450b244a1SShahaf Shuler 		};
645771fa900SAdrien Mazarguil 
646f8b9a3baSXueming Li 		mlx5_dev[idx].ports |= test;
647f8b9a3baSXueming Li 
64851e7fa8dSNélio Laranjeiro 		if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
649f8b9a3baSXueming Li 			/* from rte_ethdev.c */
650f8b9a3baSXueming Li 			char name[RTE_ETH_NAME_MAX_LEN];
651f8b9a3baSXueming Li 
652f8b9a3baSXueming Li 			snprintf(name, sizeof(name), "%s port %u",
653f8b9a3baSXueming Li 				 ibv_get_device_name(ibv_dev), port);
654f8b9a3baSXueming Li 			eth_dev = rte_eth_dev_attach_secondary(name);
655f8b9a3baSXueming Li 			if (eth_dev == NULL) {
656f8b9a3baSXueming Li 				ERROR("can not attach rte ethdev");
657f8b9a3baSXueming Li 				err = ENOMEM;
658f8b9a3baSXueming Li 				goto error;
659f8b9a3baSXueming Li 			}
660f8b9a3baSXueming Li 			eth_dev->device = &pci_dev->device;
66187ec44ceSXueming Li 			eth_dev->dev_ops = &mlx5_dev_sec_ops;
662f8b9a3baSXueming Li 			priv = eth_dev->data->dev_private;
663f8b9a3baSXueming Li 			/* Receive command fd from primary process */
664f8b9a3baSXueming Li 			err = priv_socket_connect(priv);
665f8b9a3baSXueming Li 			if (err < 0) {
666f8b9a3baSXueming Li 				err = -err;
667f8b9a3baSXueming Li 				goto error;
668f8b9a3baSXueming Li 			}
669f8b9a3baSXueming Li 			/* Remap UAR for Tx queues. */
670f8b9a3baSXueming Li 			err = priv_tx_uar_remap(priv, err);
671f8b9a3baSXueming Li 			if (err < 0) {
672f8b9a3baSXueming Li 				err = -err;
673f8b9a3baSXueming Li 				goto error;
674f8b9a3baSXueming Li 			}
6751cfa649bSShahaf Shuler 			/*
6761cfa649bSShahaf Shuler 			 * Ethdev pointer is still required as input since
6771cfa649bSShahaf Shuler 			 * the primary device is not accessible from the
6781cfa649bSShahaf Shuler 			 * secondary process.
6791cfa649bSShahaf Shuler 			 */
6801cfa649bSShahaf Shuler 			eth_dev->rx_pkt_burst =
6811cfa649bSShahaf Shuler 				priv_select_rx_function(priv, eth_dev);
6821cfa649bSShahaf Shuler 			eth_dev->tx_pkt_burst =
6831cfa649bSShahaf Shuler 				priv_select_tx_function(priv, eth_dev);
684f8b9a3baSXueming Li 			continue;
685f8b9a3baSXueming Li 		}
686f8b9a3baSXueming Li 
687771fa900SAdrien Mazarguil 		DEBUG("using port %u (%08" PRIx32 ")", port, test);
688771fa900SAdrien Mazarguil 
689771fa900SAdrien Mazarguil 		ctx = ibv_open_device(ibv_dev);
690e1c3e305SMatan Azrad 		if (ctx == NULL) {
691e1c3e305SMatan Azrad 			err = ENODEV;
692771fa900SAdrien Mazarguil 			goto port_error;
693e1c3e305SMatan Azrad 		}
694771fa900SAdrien Mazarguil 
6959a761de8SOri Kam 		ibv_query_device_ex(ctx, NULL, &device_attr);
696771fa900SAdrien Mazarguil 		/* Check port status. */
697771fa900SAdrien Mazarguil 		err = ibv_query_port(ctx, port, &port_attr);
698771fa900SAdrien Mazarguil 		if (err) {
699771fa900SAdrien Mazarguil 			ERROR("port query failed: %s", strerror(err));
700771fa900SAdrien Mazarguil 			goto port_error;
701771fa900SAdrien Mazarguil 		}
7021371f4dfSOr Ami 
7031371f4dfSOr Ami 		if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
7041371f4dfSOr Ami 			ERROR("port %d is not configured in Ethernet mode",
7051371f4dfSOr Ami 			      port);
706e1c3e305SMatan Azrad 			err = EINVAL;
7071371f4dfSOr Ami 			goto port_error;
7081371f4dfSOr Ami 		}
7091371f4dfSOr Ami 
710771fa900SAdrien Mazarguil 		if (port_attr.state != IBV_PORT_ACTIVE)
711771fa900SAdrien Mazarguil 			DEBUG("port %d is not active: \"%s\" (%d)",
712771fa900SAdrien Mazarguil 			      port, ibv_port_state_str(port_attr.state),
713771fa900SAdrien Mazarguil 			      port_attr.state);
714771fa900SAdrien Mazarguil 
715771fa900SAdrien Mazarguil 		/* Allocate protection domain. */
716771fa900SAdrien Mazarguil 		pd = ibv_alloc_pd(ctx);
717771fa900SAdrien Mazarguil 		if (pd == NULL) {
718771fa900SAdrien Mazarguil 			ERROR("PD allocation failure");
719771fa900SAdrien Mazarguil 			err = ENOMEM;
720771fa900SAdrien Mazarguil 			goto port_error;
721771fa900SAdrien Mazarguil 		}
722771fa900SAdrien Mazarguil 
723771fa900SAdrien Mazarguil 		mlx5_dev[idx].ports |= test;
724771fa900SAdrien Mazarguil 
725771fa900SAdrien Mazarguil 		/* from rte_ethdev.c */
726771fa900SAdrien Mazarguil 		priv = rte_zmalloc("ethdev private structure",
727771fa900SAdrien Mazarguil 				   sizeof(*priv),
728771fa900SAdrien Mazarguil 				   RTE_CACHE_LINE_SIZE);
729771fa900SAdrien Mazarguil 		if (priv == NULL) {
730771fa900SAdrien Mazarguil 			ERROR("priv allocation failure");
731771fa900SAdrien Mazarguil 			err = ENOMEM;
732771fa900SAdrien Mazarguil 			goto port_error;
733771fa900SAdrien Mazarguil 		}
734771fa900SAdrien Mazarguil 
735771fa900SAdrien Mazarguil 		priv->ctx = ctx;
73687ec44ceSXueming Li 		strncpy(priv->ibdev_path, priv->ctx->device->ibdev_path,
73787ec44ceSXueming Li 			sizeof(priv->ibdev_path));
738771fa900SAdrien Mazarguil 		priv->device_attr = device_attr;
739771fa900SAdrien Mazarguil 		priv->port = port;
740771fa900SAdrien Mazarguil 		priv->pd = pd;
741771fa900SAdrien Mazarguil 		priv->mtu = ETHER_MTU;
7427fe24446SShahaf Shuler 		err = mlx5_args(&config, pci_dev->device.devargs);
743e72dd09bSNélio Laranjeiro 		if (err) {
744e72dd09bSNélio Laranjeiro 			ERROR("failed to process device arguments: %s",
745e72dd09bSNélio Laranjeiro 			      strerror(err));
746e72dd09bSNélio Laranjeiro 			goto port_error;
747e72dd09bSNélio Laranjeiro 		}
74843e9d979SShachar Beiser 		if (ibv_query_device_ex(ctx, NULL, &device_attr_ex)) {
74943e9d979SShachar Beiser 			ERROR("ibv_query_device_ex() failed");
750771fa900SAdrien Mazarguil 			goto port_error;
751771fa900SAdrien Mazarguil 		}
752771fa900SAdrien Mazarguil 
7537fe24446SShahaf Shuler 		config.hw_csum = !!(device_attr_ex.device_cap_flags_ex &
75443e9d979SShachar Beiser 				    IBV_DEVICE_RAW_IP_CSUM);
755771fa900SAdrien Mazarguil 		DEBUG("checksum offloading is %ssupported",
7567fe24446SShahaf Shuler 		      (config.hw_csum ? "" : "not "));
757771fa900SAdrien Mazarguil 
75843e9d979SShachar Beiser #ifdef HAVE_IBV_DEVICE_VXLAN_SUPPORT
7597fe24446SShahaf Shuler 		config.hw_csum_l2tun =
7607fe24446SShahaf Shuler 				!!(exp_device_attr.exp_device_cap_flags &
76143e9d979SShachar Beiser 				   IBV_DEVICE_VXLAN_SUPPORT);
76243e9d979SShachar Beiser #endif
7634aa15eb1SNélio Laranjeiro 		DEBUG("Rx L2 tunnel checksum offloads are %ssupported",
7647fe24446SShahaf Shuler 		      (config.hw_csum_l2tun ? "" : "not "));
765771fa900SAdrien Mazarguil 
7669a761de8SOri Kam #ifdef HAVE_IBV_DEVICE_COUNTERS_SET_SUPPORT
76773b620f2SNelio Laranjeiro 		config.flow_counter_en = !!(device_attr.max_counter_sets);
7689a761de8SOri Kam 		ibv_describe_counter_set(ctx, 0, &cs_desc);
7699a761de8SOri Kam 		DEBUG("counter type = %d, num of cs = %ld, attributes = %d",
7709a761de8SOri Kam 		      cs_desc.counter_type, cs_desc.num_of_cs,
7719a761de8SOri Kam 		      cs_desc.attributes);
7729a761de8SOri Kam #endif
7737fe24446SShahaf Shuler 		config.ind_table_max_size =
77443e9d979SShachar Beiser 			device_attr_ex.rss_caps.max_rwq_indirection_table_size;
77513d57bd5SAdrien Mazarguil 		/* Remove this check once DPDK supports larger/variable
77613d57bd5SAdrien Mazarguil 		 * indirection tables. */
7777fe24446SShahaf Shuler 		if (config.ind_table_max_size >
778ec1fed22SYongseok Koh 				(unsigned int)ETH_RSS_RETA_SIZE_512)
7797fe24446SShahaf Shuler 			config.ind_table_max_size = ETH_RSS_RETA_SIZE_512;
78095e16ef3SNelio Laranjeiro 		DEBUG("maximum RX indirection table size is %u",
7817fe24446SShahaf Shuler 		      config.ind_table_max_size);
7827fe24446SShahaf Shuler 		config.hw_vlan_strip = !!(device_attr_ex.raw_packet_caps &
78343e9d979SShachar Beiser 					 IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
784f3db9489SYaacov Hazan 		DEBUG("VLAN stripping is %ssupported",
7857fe24446SShahaf Shuler 		      (config.hw_vlan_strip ? "" : "not "));
78695e16ef3SNelio Laranjeiro 
7877fe24446SShahaf Shuler 		config.hw_fcs_strip =
78843e9d979SShachar Beiser 				!!(device_attr_ex.orig_attr.device_cap_flags &
78943e9d979SShachar Beiser 				IBV_WQ_FLAGS_SCATTER_FCS);
7904d326709SOlga Shern 		DEBUG("FCS stripping configuration is %ssupported",
7917fe24446SShahaf Shuler 		      (config.hw_fcs_strip ? "" : "not "));
7924d326709SOlga Shern 
79343e9d979SShachar Beiser #ifdef HAVE_IBV_WQ_FLAG_RX_END_PADDING
7947fe24446SShahaf Shuler 		config.hw_padding = !!device_attr_ex.rx_pad_end_addr_align;
79543e9d979SShachar Beiser #endif
7964d803a72SOlga Shern 		DEBUG("hardware RX end alignment padding is %ssupported",
7977fe24446SShahaf Shuler 		      (config.hw_padding ? "" : "not "));
7984d803a72SOlga Shern 
79985e347dbSNélio Laranjeiro 		priv_get_num_vfs(priv, &num_vfs);
8007fe24446SShahaf Shuler 		config.sriov = (num_vfs || sriov);
8017fe24446SShahaf Shuler 		config.tso = ((device_attr_ex.tso_caps.max_tso > 0) &&
80243e9d979SShachar Beiser 			      (device_attr_ex.tso_caps.supported_qpts &
80343e9d979SShachar Beiser 			      (1 << IBV_QPT_RAW_PACKET)));
8047fe24446SShahaf Shuler 		if (config.tso)
8057fe24446SShahaf Shuler 			config.tso_max_payload_sz =
80643e9d979SShachar Beiser 					device_attr_ex.tso_caps.max_tso;
8077fe24446SShahaf Shuler 		if (config.mps && !mps) {
808230189d9SNélio Laranjeiro 			ERROR("multi-packet send not supported on this device"
809230189d9SNélio Laranjeiro 			      " (" MLX5_TXQ_MPW_EN ")");
810230189d9SNélio Laranjeiro 			err = ENOTSUP;
811230189d9SNélio Laranjeiro 			goto port_error;
812230189d9SNélio Laranjeiro 		}
8136ce84bd8SYongseok Koh 		INFO("%sMPS is %s",
8147fe24446SShahaf Shuler 		     config.mps == MLX5_MPW_ENHANCED ? "Enhanced " : "",
8157fe24446SShahaf Shuler 		     config.mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
8167fe24446SShahaf Shuler 		if (config.cqe_comp && !cqe_comp) {
817523f5a74SYongseok Koh 			WARN("Rx CQE compression isn't supported");
8187fe24446SShahaf Shuler 			config.cqe_comp = 0;
819523f5a74SYongseok Koh 		}
820771fa900SAdrien Mazarguil 		/* Configure the first MAC address by default. */
821771fa900SAdrien Mazarguil 		if (priv_get_mac(priv, &mac.addr_bytes)) {
822771fa900SAdrien Mazarguil 			ERROR("cannot get MAC address, is mlx5_en loaded?"
823771fa900SAdrien Mazarguil 			      " (errno: %s)", strerror(errno));
824e1c3e305SMatan Azrad 			err = ENODEV;
825771fa900SAdrien Mazarguil 			goto port_error;
826771fa900SAdrien Mazarguil 		}
827771fa900SAdrien Mazarguil 		INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
828771fa900SAdrien Mazarguil 		     priv->port,
829771fa900SAdrien Mazarguil 		     mac.addr_bytes[0], mac.addr_bytes[1],
830771fa900SAdrien Mazarguil 		     mac.addr_bytes[2], mac.addr_bytes[3],
831771fa900SAdrien Mazarguil 		     mac.addr_bytes[4], mac.addr_bytes[5]);
832771fa900SAdrien Mazarguil #ifndef NDEBUG
833771fa900SAdrien Mazarguil 		{
834771fa900SAdrien Mazarguil 			char ifname[IF_NAMESIZE];
835771fa900SAdrien Mazarguil 
836771fa900SAdrien Mazarguil 			if (priv_get_ifname(priv, &ifname) == 0)
837771fa900SAdrien Mazarguil 				DEBUG("port %u ifname is \"%s\"",
838771fa900SAdrien Mazarguil 				      priv->port, ifname);
839771fa900SAdrien Mazarguil 			else
840771fa900SAdrien Mazarguil 				DEBUG("port %u ifname is unknown", priv->port);
841771fa900SAdrien Mazarguil 		}
842771fa900SAdrien Mazarguil #endif
843771fa900SAdrien Mazarguil 		/* Get actual MTU if possible. */
844771fa900SAdrien Mazarguil 		priv_get_mtu(priv, &priv->mtu);
845771fa900SAdrien Mazarguil 		DEBUG("port %u MTU is %u", priv->port, priv->mtu);
846771fa900SAdrien Mazarguil 
847771fa900SAdrien Mazarguil 		/* from rte_ethdev.c */
848771fa900SAdrien Mazarguil 		{
849771fa900SAdrien Mazarguil 			char name[RTE_ETH_NAME_MAX_LEN];
850771fa900SAdrien Mazarguil 
851771fa900SAdrien Mazarguil 			snprintf(name, sizeof(name), "%s port %u",
852771fa900SAdrien Mazarguil 				 ibv_get_device_name(ibv_dev), port);
8536751f6deSDavid Marchand 			eth_dev = rte_eth_dev_allocate(name);
854771fa900SAdrien Mazarguil 		}
855771fa900SAdrien Mazarguil 		if (eth_dev == NULL) {
856771fa900SAdrien Mazarguil 			ERROR("can not allocate rte ethdev");
857771fa900SAdrien Mazarguil 			err = ENOMEM;
858771fa900SAdrien Mazarguil 			goto port_error;
859771fa900SAdrien Mazarguil 		}
860771fa900SAdrien Mazarguil 		eth_dev->data->dev_private = priv;
861a48deadaSOr Ami 		eth_dev->data->mac_addrs = priv->mac;
862eac901ceSJan Blunck 		eth_dev->device = &pci_dev->device;
863a48deadaSOr Ami 		rte_eth_copy_pci_info(eth_dev, pci_dev);
864fdf91e0fSJan Blunck 		eth_dev->device->driver = &mlx5_driver.driver;
865771fa900SAdrien Mazarguil 		priv->dev = eth_dev;
866771fa900SAdrien Mazarguil 		eth_dev->dev_ops = &mlx5_dev_ops;
867272733b5SNélio Laranjeiro 		/* Register MAC address. */
868272733b5SNélio Laranjeiro 		claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
869c8ffb8a9SNélio Laranjeiro 		TAILQ_INIT(&priv->flows);
8701b37f5d8SNélio Laranjeiro 		TAILQ_INIT(&priv->ctrl_flows);
871a48deadaSOr Ami 
8721e3a39f7SXueming Li 		/* Hint libmlx5 to use PMD allocator for data plane resources */
8731e3a39f7SXueming Li 		struct mlx5dv_ctx_allocators alctr = {
8741e3a39f7SXueming Li 			.alloc = &mlx5_alloc_verbs_buf,
8751e3a39f7SXueming Li 			.free = &mlx5_free_verbs_buf,
8761e3a39f7SXueming Li 			.data = priv,
8771e3a39f7SXueming Li 		};
8781e3a39f7SXueming Li 		mlx5dv_set_context_attr(ctx, MLX5DV_CTX_ATTR_BUF_ALLOCATORS,
8791e3a39f7SXueming Li 					(void *)((uintptr_t)&alctr));
8801e3a39f7SXueming Li 
881771fa900SAdrien Mazarguil 		/* Bring Ethernet device up. */
882771fa900SAdrien Mazarguil 		DEBUG("forcing Ethernet interface up");
883771fa900SAdrien Mazarguil 		priv_set_flags(priv, ~IFF_UP, IFF_UP);
8847fe24446SShahaf Shuler 		/* Store device configuration on private structure. */
8857fe24446SShahaf Shuler 		priv->config = config;
886771fa900SAdrien Mazarguil 		continue;
887771fa900SAdrien Mazarguil 
888771fa900SAdrien Mazarguil port_error:
88929c1d8bbSNélio Laranjeiro 		if (priv)
890771fa900SAdrien Mazarguil 			rte_free(priv);
891771fa900SAdrien Mazarguil 		if (pd)
892771fa900SAdrien Mazarguil 			claim_zero(ibv_dealloc_pd(pd));
893771fa900SAdrien Mazarguil 		if (ctx)
894771fa900SAdrien Mazarguil 			claim_zero(ibv_close_device(ctx));
895771fa900SAdrien Mazarguil 		break;
896771fa900SAdrien Mazarguil 	}
897771fa900SAdrien Mazarguil 
898771fa900SAdrien Mazarguil 	/*
899771fa900SAdrien Mazarguil 	 * XXX if something went wrong in the loop above, there is a resource
900771fa900SAdrien Mazarguil 	 * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
901771fa900SAdrien Mazarguil 	 * long as the dpdk does not provide a way to deallocate a ethdev and a
902771fa900SAdrien Mazarguil 	 * way to enumerate the registered ethdevs to free the previous ones.
903771fa900SAdrien Mazarguil 	 */
904771fa900SAdrien Mazarguil 
905771fa900SAdrien Mazarguil 	/* no port found, complain */
906771fa900SAdrien Mazarguil 	if (!mlx5_dev[idx].ports) {
907771fa900SAdrien Mazarguil 		err = ENODEV;
908771fa900SAdrien Mazarguil 		goto error;
909771fa900SAdrien Mazarguil 	}
910771fa900SAdrien Mazarguil 
911771fa900SAdrien Mazarguil error:
912771fa900SAdrien Mazarguil 	if (attr_ctx)
913771fa900SAdrien Mazarguil 		claim_zero(ibv_close_device(attr_ctx));
914771fa900SAdrien Mazarguil 	if (list)
915771fa900SAdrien Mazarguil 		ibv_free_device_list(list);
916771fa900SAdrien Mazarguil 	assert(err >= 0);
917771fa900SAdrien Mazarguil 	return -err;
918771fa900SAdrien Mazarguil }
919771fa900SAdrien Mazarguil 
920771fa900SAdrien Mazarguil static const struct rte_pci_id mlx5_pci_id_map[] = {
921771fa900SAdrien Mazarguil 	{
9221d1bc870SNélio Laranjeiro 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
9231d1bc870SNélio Laranjeiro 			       PCI_DEVICE_ID_MELLANOX_CONNECTX4)
924771fa900SAdrien Mazarguil 	},
925771fa900SAdrien Mazarguil 	{
9261d1bc870SNélio Laranjeiro 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
9271d1bc870SNélio Laranjeiro 			       PCI_DEVICE_ID_MELLANOX_CONNECTX4VF)
928771fa900SAdrien Mazarguil 	},
929771fa900SAdrien Mazarguil 	{
9301d1bc870SNélio Laranjeiro 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
9311d1bc870SNélio Laranjeiro 			       PCI_DEVICE_ID_MELLANOX_CONNECTX4LX)
932771fa900SAdrien Mazarguil 	},
933771fa900SAdrien Mazarguil 	{
9341d1bc870SNélio Laranjeiro 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
9351d1bc870SNélio Laranjeiro 			       PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF)
936771fa900SAdrien Mazarguil 	},
937771fa900SAdrien Mazarguil 	{
938528a9fbeSYongseok Koh 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
939528a9fbeSYongseok Koh 			       PCI_DEVICE_ID_MELLANOX_CONNECTX5)
940528a9fbeSYongseok Koh 	},
941528a9fbeSYongseok Koh 	{
942528a9fbeSYongseok Koh 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
943528a9fbeSYongseok Koh 			       PCI_DEVICE_ID_MELLANOX_CONNECTX5VF)
944528a9fbeSYongseok Koh 	},
945528a9fbeSYongseok Koh 	{
946528a9fbeSYongseok Koh 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
947528a9fbeSYongseok Koh 			       PCI_DEVICE_ID_MELLANOX_CONNECTX5EX)
948528a9fbeSYongseok Koh 	},
949528a9fbeSYongseok Koh 	{
950528a9fbeSYongseok Koh 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
951528a9fbeSYongseok Koh 			       PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF)
952528a9fbeSYongseok Koh 	},
953528a9fbeSYongseok Koh 	{
954771fa900SAdrien Mazarguil 		.vendor_id = 0
955771fa900SAdrien Mazarguil 	}
956771fa900SAdrien Mazarguil };
957771fa900SAdrien Mazarguil 
958fdf91e0fSJan Blunck static struct rte_pci_driver mlx5_driver = {
9592f3193cfSJan Viktorin 	.driver = {
9602f3193cfSJan Viktorin 		.name = MLX5_DRIVER_NAME
9612f3193cfSJan Viktorin 	},
962771fa900SAdrien Mazarguil 	.id_table = mlx5_pci_id_map,
963af424af8SShreyansh Jain 	.probe = mlx5_pci_probe,
9647d7d7ad1SMatan Azrad 	.drv_flags = RTE_PCI_DRV_INTR_LSC | RTE_PCI_DRV_INTR_RMV,
965771fa900SAdrien Mazarguil };
966771fa900SAdrien Mazarguil 
967771fa900SAdrien Mazarguil /**
968771fa900SAdrien Mazarguil  * Driver initialization routine.
969771fa900SAdrien Mazarguil  */
970c830cb29SDavid Marchand RTE_INIT(rte_mlx5_pmd_init);
971c830cb29SDavid Marchand static void
972c830cb29SDavid Marchand rte_mlx5_pmd_init(void)
973771fa900SAdrien Mazarguil {
974ea16068cSYongseok Koh 	/* Build the static table for ptype conversion. */
975ea16068cSYongseok Koh 	mlx5_set_ptype_table();
976771fa900SAdrien Mazarguil 	/*
977771fa900SAdrien Mazarguil 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
978771fa900SAdrien Mazarguil 	 * huge pages. Calling ibv_fork_init() during init allows
979771fa900SAdrien Mazarguil 	 * applications to use fork() safely for purposes other than
980771fa900SAdrien Mazarguil 	 * using this PMD, which is not supported in forked processes.
981771fa900SAdrien Mazarguil 	 */
982771fa900SAdrien Mazarguil 	setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
983161b93e5SYongseok Koh 	/* Match the size of Rx completion entry to the size of a cacheline. */
984161b93e5SYongseok Koh 	if (RTE_CACHE_LINE_SIZE == 128)
985161b93e5SYongseok Koh 		setenv("MLX5_CQE_SIZE", "128", 0);
986771fa900SAdrien Mazarguil 	ibv_fork_init();
9873dcfe039SThomas Monjalon 	rte_pci_register(&mlx5_driver);
988771fa900SAdrien Mazarguil }
989771fa900SAdrien Mazarguil 
99001f19227SShreyansh Jain RTE_PMD_EXPORT_NAME(net_mlx5, __COUNTER__);
99101f19227SShreyansh Jain RTE_PMD_REGISTER_PCI_TABLE(net_mlx5, mlx5_pci_id_map);
9920880c401SOlivier Matz RTE_PMD_REGISTER_KMOD_DEP(net_mlx5, "* ib_uverbs & mlx5_core & mlx5_ib");
993