xref: /dpdk/drivers/net/mlx4/mlx4.c (revision f0897131)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2012 6WIND S.A.
3  * Copyright 2012 Mellanox Technologies, Ltd
4  */
5 
6 /**
7  * @file
8  * mlx4 driver initialization.
9  */
10 
11 #include <assert.h>
12 #include <dlfcn.h>
13 #include <errno.h>
14 #include <inttypes.h>
15 #include <stddef.h>
16 #include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/mman.h>
21 #include <unistd.h>
22 
23 /* Verbs headers do not support -pedantic. */
24 #ifdef PEDANTIC
25 #pragma GCC diagnostic ignored "-Wpedantic"
26 #endif
27 #include <infiniband/verbs.h>
28 #ifdef PEDANTIC
29 #pragma GCC diagnostic error "-Wpedantic"
30 #endif
31 
32 #include <rte_common.h>
33 #include <rte_config.h>
34 #include <rte_dev.h>
35 #include <rte_errno.h>
36 #include <rte_ethdev_driver.h>
37 #include <rte_ethdev_pci.h>
38 #include <rte_ether.h>
39 #include <rte_flow.h>
40 #include <rte_interrupts.h>
41 #include <rte_kvargs.h>
42 #include <rte_malloc.h>
43 #include <rte_mbuf.h>
44 
45 #include "mlx4.h"
46 #include "mlx4_glue.h"
47 #include "mlx4_flow.h"
48 #include "mlx4_mr.h"
49 #include "mlx4_rxtx.h"
50 #include "mlx4_utils.h"
51 
52 static const char *MZ_MLX4_PMD_SHARED_DATA = "mlx4_pmd_shared_data";
53 
54 /* Shared memory between primary and secondary processes. */
55 struct mlx4_shared_data *mlx4_shared_data;
56 
57 /* Spinlock for mlx4_shared_data allocation. */
58 static rte_spinlock_t mlx4_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
59 
60 /* Process local data for secondary processes. */
61 static struct mlx4_local_data mlx4_local_data;
62 
63 /** Configuration structure for device arguments. */
64 struct mlx4_conf {
65 	struct {
66 		uint32_t present; /**< Bit-field for existing ports. */
67 		uint32_t enabled; /**< Bit-field for user-enabled ports. */
68 	} ports;
69 	int mr_ext_memseg_en;
70 	/** Whether memseg should be extended for MR creation. */
71 };
72 
73 /* Available parameters list. */
74 const char *pmd_mlx4_init_params[] = {
75 	MLX4_PMD_PORT_KVARG,
76 	MLX4_MR_EXT_MEMSEG_EN_KVARG,
77 	NULL,
78 };
79 
80 static void mlx4_dev_stop(struct rte_eth_dev *dev);
81 
82 /**
83  * Initialize shared data between primary and secondary process.
84  *
85  * A memzone is reserved by primary process and secondary processes attach to
86  * the memzone.
87  *
88  * @return
89  *   0 on success, a negative errno value otherwise and rte_errno is set.
90  */
91 static int
92 mlx4_init_shared_data(void)
93 {
94 	const struct rte_memzone *mz;
95 	int ret = 0;
96 
97 	rte_spinlock_lock(&mlx4_shared_data_lock);
98 	if (mlx4_shared_data == NULL) {
99 		if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
100 			/* Allocate shared memory. */
101 			mz = rte_memzone_reserve(MZ_MLX4_PMD_SHARED_DATA,
102 						 sizeof(*mlx4_shared_data),
103 						 SOCKET_ID_ANY, 0);
104 			if (mz == NULL) {
105 				ERROR("Cannot allocate mlx4 shared data\n");
106 				ret = -rte_errno;
107 				goto error;
108 			}
109 			mlx4_shared_data = mz->addr;
110 			memset(mlx4_shared_data, 0, sizeof(*mlx4_shared_data));
111 			rte_spinlock_init(&mlx4_shared_data->lock);
112 		} else {
113 			/* Lookup allocated shared memory. */
114 			mz = rte_memzone_lookup(MZ_MLX4_PMD_SHARED_DATA);
115 			if (mz == NULL) {
116 				ERROR("Cannot attach mlx4 shared data\n");
117 				ret = -rte_errno;
118 				goto error;
119 			}
120 			mlx4_shared_data = mz->addr;
121 			memset(&mlx4_local_data, 0, sizeof(mlx4_local_data));
122 		}
123 	}
124 error:
125 	rte_spinlock_unlock(&mlx4_shared_data_lock);
126 	return ret;
127 }
128 
129 #ifdef HAVE_IBV_MLX4_BUF_ALLOCATORS
130 /**
131  * Verbs callback to allocate a memory. This function should allocate the space
132  * according to the size provided residing inside a huge page.
133  * Please note that all allocation must respect the alignment from libmlx4
134  * (i.e. currently sysconf(_SC_PAGESIZE)).
135  *
136  * @param[in] size
137  *   The size in bytes of the memory to allocate.
138  * @param[in] data
139  *   A pointer to the callback data.
140  *
141  * @return
142  *   Allocated buffer, NULL otherwise and rte_errno is set.
143  */
144 static void *
145 mlx4_alloc_verbs_buf(size_t size, void *data)
146 {
147 	struct mlx4_priv *priv = data;
148 	void *ret;
149 	size_t alignment = sysconf(_SC_PAGESIZE);
150 	unsigned int socket = SOCKET_ID_ANY;
151 
152 	if (priv->verbs_alloc_ctx.type == MLX4_VERBS_ALLOC_TYPE_TX_QUEUE) {
153 		const struct txq *txq = priv->verbs_alloc_ctx.obj;
154 
155 		socket = txq->socket;
156 	} else if (priv->verbs_alloc_ctx.type ==
157 		   MLX4_VERBS_ALLOC_TYPE_RX_QUEUE) {
158 		const struct rxq *rxq = priv->verbs_alloc_ctx.obj;
159 
160 		socket = rxq->socket;
161 	}
162 	assert(data != NULL);
163 	ret = rte_malloc_socket(__func__, size, alignment, socket);
164 	if (!ret && size)
165 		rte_errno = ENOMEM;
166 	return ret;
167 }
168 
169 /**
170  * Verbs callback to free a memory.
171  *
172  * @param[in] ptr
173  *   A pointer to the memory to free.
174  * @param[in] data
175  *   A pointer to the callback data.
176  */
177 static void
178 mlx4_free_verbs_buf(void *ptr, void *data __rte_unused)
179 {
180 	assert(data != NULL);
181 	rte_free(ptr);
182 }
183 #endif
184 
185 /**
186  * Initialize process private data structure.
187  *
188  * @param dev
189  *   Pointer to Ethernet device structure.
190  *
191  * @return
192  *   0 on success, a negative errno value otherwise and rte_errno is set.
193  */
194 static int
195 mlx4_proc_priv_init(struct rte_eth_dev *dev)
196 {
197 	struct mlx4_proc_priv *ppriv;
198 	size_t ppriv_size;
199 
200 	/*
201 	 * UAR register table follows the process private structure. BlueFlame
202 	 * registers for Tx queues are stored in the table.
203 	 */
204 	ppriv_size = sizeof(struct mlx4_proc_priv) +
205 		     dev->data->nb_tx_queues * sizeof(void *);
206 	ppriv = rte_malloc_socket("mlx4_proc_priv", ppriv_size,
207 				  RTE_CACHE_LINE_SIZE, dev->device->numa_node);
208 	if (!ppriv) {
209 		rte_errno = ENOMEM;
210 		return -rte_errno;
211 	}
212 	ppriv->uar_table_sz = ppriv_size;
213 	dev->process_private = ppriv;
214 	return 0;
215 }
216 
217 /**
218  * Un-initialize process private data structure.
219  *
220  * @param dev
221  *   Pointer to Ethernet device structure.
222  */
223 static void
224 mlx4_proc_priv_uninit(struct rte_eth_dev *dev)
225 {
226 	if (!dev->process_private)
227 		return;
228 	rte_free(dev->process_private);
229 	dev->process_private = NULL;
230 }
231 
232 /**
233  * DPDK callback for Ethernet device configuration.
234  *
235  * @param dev
236  *   Pointer to Ethernet device structure.
237  *
238  * @return
239  *   0 on success, negative errno value otherwise and rte_errno is set.
240  */
241 static int
242 mlx4_dev_configure(struct rte_eth_dev *dev)
243 {
244 	struct mlx4_priv *priv = dev->data->dev_private;
245 	struct rte_flow_error error;
246 	int ret;
247 
248 	/* Prepare internal flow rules. */
249 	ret = mlx4_flow_sync(priv, &error);
250 	if (ret) {
251 		ERROR("cannot set up internal flow rules (code %d, \"%s\"),"
252 		      " flow error type %d, cause %p, message: %s",
253 		      -ret, strerror(-ret), error.type, error.cause,
254 		      error.message ? error.message : "(unspecified)");
255 		goto exit;
256 	}
257 	ret = mlx4_intr_install(priv);
258 	if (ret) {
259 		ERROR("%p: interrupt handler installation failed",
260 		      (void *)dev);
261 		goto exit;
262 	}
263 	ret = mlx4_proc_priv_init(dev);
264 	if (ret) {
265 		ERROR("%p: process private data allocation failed",
266 		      (void *)dev);
267 		goto exit;
268 	}
269 exit:
270 	return ret;
271 }
272 
273 /**
274  * DPDK callback to start the device.
275  *
276  * Simulate device start by initializing common RSS resources and attaching
277  * all configured flows.
278  *
279  * @param dev
280  *   Pointer to Ethernet device structure.
281  *
282  * @return
283  *   0 on success, negative errno value otherwise and rte_errno is set.
284  */
285 static int
286 mlx4_dev_start(struct rte_eth_dev *dev)
287 {
288 	struct mlx4_priv *priv = dev->data->dev_private;
289 	struct rte_flow_error error;
290 	int ret;
291 
292 	if (priv->started)
293 		return 0;
294 	DEBUG("%p: attaching configured flows to all RX queues", (void *)dev);
295 	priv->started = 1;
296 	ret = mlx4_rss_init(priv);
297 	if (ret) {
298 		ERROR("%p: cannot initialize RSS resources: %s",
299 		      (void *)dev, strerror(-ret));
300 		goto err;
301 	}
302 #ifndef NDEBUG
303 	mlx4_mr_dump_dev(dev);
304 #endif
305 	ret = mlx4_rxq_intr_enable(priv);
306 	if (ret) {
307 		ERROR("%p: interrupt handler installation failed",
308 		     (void *)dev);
309 		goto err;
310 	}
311 	ret = mlx4_flow_sync(priv, &error);
312 	if (ret) {
313 		ERROR("%p: cannot attach flow rules (code %d, \"%s\"),"
314 		      " flow error type %d, cause %p, message: %s",
315 		      (void *)dev,
316 		      -ret, strerror(-ret), error.type, error.cause,
317 		      error.message ? error.message : "(unspecified)");
318 		goto err;
319 	}
320 	rte_wmb();
321 	dev->tx_pkt_burst = mlx4_tx_burst;
322 	dev->rx_pkt_burst = mlx4_rx_burst;
323 	/* Enable datapath on secondary process. */
324 	mlx4_mp_req_start_rxtx(dev);
325 	return 0;
326 err:
327 	mlx4_dev_stop(dev);
328 	return ret;
329 }
330 
331 /**
332  * DPDK callback to stop the device.
333  *
334  * Simulate device stop by detaching all configured flows.
335  *
336  * @param dev
337  *   Pointer to Ethernet device structure.
338  */
339 static void
340 mlx4_dev_stop(struct rte_eth_dev *dev)
341 {
342 	struct mlx4_priv *priv = dev->data->dev_private;
343 
344 	if (!priv->started)
345 		return;
346 	DEBUG("%p: detaching flows from all RX queues", (void *)dev);
347 	priv->started = 0;
348 	dev->tx_pkt_burst = mlx4_tx_burst_removed;
349 	dev->rx_pkt_burst = mlx4_rx_burst_removed;
350 	rte_wmb();
351 	/* Disable datapath on secondary process. */
352 	mlx4_mp_req_stop_rxtx(dev);
353 	mlx4_flow_sync(priv, NULL);
354 	mlx4_rxq_intr_disable(priv);
355 	mlx4_rss_deinit(priv);
356 }
357 
358 /**
359  * DPDK callback to close the device.
360  *
361  * Destroy all queues and objects, free memory.
362  *
363  * @param dev
364  *   Pointer to Ethernet device structure.
365  */
366 static void
367 mlx4_dev_close(struct rte_eth_dev *dev)
368 {
369 	struct mlx4_priv *priv = dev->data->dev_private;
370 	unsigned int i;
371 
372 	DEBUG("%p: closing device \"%s\"",
373 	      (void *)dev,
374 	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
375 	dev->rx_pkt_burst = mlx4_rx_burst_removed;
376 	dev->tx_pkt_burst = mlx4_tx_burst_removed;
377 	rte_wmb();
378 	/* Disable datapath on secondary process. */
379 	mlx4_mp_req_stop_rxtx(dev);
380 	mlx4_flow_clean(priv);
381 	mlx4_rss_deinit(priv);
382 	for (i = 0; i != dev->data->nb_rx_queues; ++i)
383 		mlx4_rx_queue_release(dev->data->rx_queues[i]);
384 	for (i = 0; i != dev->data->nb_tx_queues; ++i)
385 		mlx4_tx_queue_release(dev->data->tx_queues[i]);
386 	mlx4_proc_priv_uninit(dev);
387 	mlx4_mr_release(dev);
388 	if (priv->pd != NULL) {
389 		assert(priv->ctx != NULL);
390 		claim_zero(mlx4_glue->dealloc_pd(priv->pd));
391 		claim_zero(mlx4_glue->close_device(priv->ctx));
392 	} else
393 		assert(priv->ctx == NULL);
394 	mlx4_intr_uninstall(priv);
395 	memset(priv, 0, sizeof(*priv));
396 }
397 
398 static const struct eth_dev_ops mlx4_dev_ops = {
399 	.dev_configure = mlx4_dev_configure,
400 	.dev_start = mlx4_dev_start,
401 	.dev_stop = mlx4_dev_stop,
402 	.dev_set_link_down = mlx4_dev_set_link_down,
403 	.dev_set_link_up = mlx4_dev_set_link_up,
404 	.dev_close = mlx4_dev_close,
405 	.link_update = mlx4_link_update,
406 	.promiscuous_enable = mlx4_promiscuous_enable,
407 	.promiscuous_disable = mlx4_promiscuous_disable,
408 	.allmulticast_enable = mlx4_allmulticast_enable,
409 	.allmulticast_disable = mlx4_allmulticast_disable,
410 	.mac_addr_remove = mlx4_mac_addr_remove,
411 	.mac_addr_add = mlx4_mac_addr_add,
412 	.mac_addr_set = mlx4_mac_addr_set,
413 	.set_mc_addr_list = mlx4_set_mc_addr_list,
414 	.stats_get = mlx4_stats_get,
415 	.stats_reset = mlx4_stats_reset,
416 	.fw_version_get = mlx4_fw_version_get,
417 	.dev_infos_get = mlx4_dev_infos_get,
418 	.dev_supported_ptypes_get = mlx4_dev_supported_ptypes_get,
419 	.vlan_filter_set = mlx4_vlan_filter_set,
420 	.rx_queue_setup = mlx4_rx_queue_setup,
421 	.tx_queue_setup = mlx4_tx_queue_setup,
422 	.rx_queue_release = mlx4_rx_queue_release,
423 	.tx_queue_release = mlx4_tx_queue_release,
424 	.flow_ctrl_get = mlx4_flow_ctrl_get,
425 	.flow_ctrl_set = mlx4_flow_ctrl_set,
426 	.mtu_set = mlx4_mtu_set,
427 	.filter_ctrl = mlx4_filter_ctrl,
428 	.rx_queue_intr_enable = mlx4_rx_intr_enable,
429 	.rx_queue_intr_disable = mlx4_rx_intr_disable,
430 	.is_removed = mlx4_is_removed,
431 };
432 
433 /* Available operations from secondary process. */
434 static const struct eth_dev_ops mlx4_dev_sec_ops = {
435 	.stats_get = mlx4_stats_get,
436 	.stats_reset = mlx4_stats_reset,
437 	.fw_version_get = mlx4_fw_version_get,
438 	.dev_infos_get = mlx4_dev_infos_get,
439 };
440 
441 /**
442  * Get PCI information from struct ibv_device.
443  *
444  * @param device
445  *   Pointer to Ethernet device structure.
446  * @param[out] pci_addr
447  *   PCI bus address output buffer.
448  *
449  * @return
450  *   0 on success, negative errno value otherwise and rte_errno is set.
451  */
452 static int
453 mlx4_ibv_device_to_pci_addr(const struct ibv_device *device,
454 			    struct rte_pci_addr *pci_addr)
455 {
456 	FILE *file;
457 	char line[32];
458 	MKSTR(path, "%s/device/uevent", device->ibdev_path);
459 
460 	file = fopen(path, "rb");
461 	if (file == NULL) {
462 		rte_errno = errno;
463 		return -rte_errno;
464 	}
465 	while (fgets(line, sizeof(line), file) == line) {
466 		size_t len = strlen(line);
467 		int ret;
468 
469 		/* Truncate long lines. */
470 		if (len == (sizeof(line) - 1))
471 			while (line[(len - 1)] != '\n') {
472 				ret = fgetc(file);
473 				if (ret == EOF)
474 					break;
475 				line[(len - 1)] = ret;
476 			}
477 		/* Extract information. */
478 		if (sscanf(line,
479 			   "PCI_SLOT_NAME="
480 			   "%" SCNx32 ":%" SCNx8 ":%" SCNx8 ".%" SCNx8 "\n",
481 			   &pci_addr->domain,
482 			   &pci_addr->bus,
483 			   &pci_addr->devid,
484 			   &pci_addr->function) == 4) {
485 			ret = 0;
486 			break;
487 		}
488 	}
489 	fclose(file);
490 	return 0;
491 }
492 
493 /**
494  * Verify and store value for device argument.
495  *
496  * @param[in] key
497  *   Key argument to verify.
498  * @param[in] val
499  *   Value associated with key.
500  * @param[in, out] conf
501  *   Shared configuration data.
502  *
503  * @return
504  *   0 on success, negative errno value otherwise and rte_errno is set.
505  */
506 static int
507 mlx4_arg_parse(const char *key, const char *val, struct mlx4_conf *conf)
508 {
509 	unsigned long tmp;
510 
511 	errno = 0;
512 	tmp = strtoul(val, NULL, 0);
513 	if (errno) {
514 		rte_errno = errno;
515 		WARN("%s: \"%s\" is not a valid integer", key, val);
516 		return -rte_errno;
517 	}
518 	if (strcmp(MLX4_PMD_PORT_KVARG, key) == 0) {
519 		uint32_t ports = rte_log2_u32(conf->ports.present + 1);
520 
521 		if (tmp >= ports) {
522 			ERROR("port index %lu outside range [0,%" PRIu32 ")",
523 			      tmp, ports);
524 			return -EINVAL;
525 		}
526 		if (!(conf->ports.present & (1 << tmp))) {
527 			rte_errno = EINVAL;
528 			ERROR("invalid port index %lu", tmp);
529 			return -rte_errno;
530 		}
531 		conf->ports.enabled |= 1 << tmp;
532 	} else if (strcmp(MLX4_MR_EXT_MEMSEG_EN_KVARG, key) == 0) {
533 		conf->mr_ext_memseg_en = !!tmp;
534 	} else {
535 		rte_errno = EINVAL;
536 		WARN("%s: unknown parameter", key);
537 		return -rte_errno;
538 	}
539 	return 0;
540 }
541 
542 /**
543  * Parse device parameters.
544  *
545  * @param devargs
546  *   Device arguments structure.
547  *
548  * @return
549  *   0 on success, negative errno value otherwise and rte_errno is set.
550  */
551 static int
552 mlx4_args(struct rte_devargs *devargs, struct mlx4_conf *conf)
553 {
554 	struct rte_kvargs *kvlist;
555 	unsigned int arg_count;
556 	int ret = 0;
557 	int i;
558 
559 	if (devargs == NULL)
560 		return 0;
561 	kvlist = rte_kvargs_parse(devargs->args, pmd_mlx4_init_params);
562 	if (kvlist == NULL) {
563 		rte_errno = EINVAL;
564 		ERROR("failed to parse kvargs");
565 		return -rte_errno;
566 	}
567 	/* Process parameters. */
568 	for (i = 0; pmd_mlx4_init_params[i]; ++i) {
569 		arg_count = rte_kvargs_count(kvlist, pmd_mlx4_init_params[i]);
570 		while (arg_count-- > 0) {
571 			ret = rte_kvargs_process(kvlist,
572 						 pmd_mlx4_init_params[i],
573 						 (int (*)(const char *,
574 							  const char *,
575 							  void *))
576 						 mlx4_arg_parse,
577 						 conf);
578 			if (ret != 0)
579 				goto free_kvlist;
580 		}
581 	}
582 free_kvlist:
583 	rte_kvargs_free(kvlist);
584 	return ret;
585 }
586 
587 /**
588  * Interpret RSS capabilities reported by device.
589  *
590  * This function returns the set of usable Verbs RSS hash fields, kernel
591  * quirks taken into account.
592  *
593  * @param ctx
594  *   Verbs context.
595  * @param pd
596  *   Verbs protection domain.
597  * @param device_attr_ex
598  *   Extended device attributes to interpret.
599  *
600  * @return
601  *   Usable RSS hash fields mask in Verbs format.
602  */
603 static uint64_t
604 mlx4_hw_rss_sup(struct ibv_context *ctx, struct ibv_pd *pd,
605 		struct ibv_device_attr_ex *device_attr_ex)
606 {
607 	uint64_t hw_rss_sup = device_attr_ex->rss_caps.rx_hash_fields_mask;
608 	struct ibv_cq *cq = NULL;
609 	struct ibv_wq *wq = NULL;
610 	struct ibv_rwq_ind_table *ind = NULL;
611 	struct ibv_qp *qp = NULL;
612 
613 	if (!hw_rss_sup) {
614 		WARN("no RSS capabilities reported; disabling support for UDP"
615 		     " RSS and inner VXLAN RSS");
616 		return IBV_RX_HASH_SRC_IPV4 | IBV_RX_HASH_DST_IPV4 |
617 			IBV_RX_HASH_SRC_IPV6 | IBV_RX_HASH_DST_IPV6 |
618 			IBV_RX_HASH_SRC_PORT_TCP | IBV_RX_HASH_DST_PORT_TCP;
619 	}
620 	if (!(hw_rss_sup & IBV_RX_HASH_INNER))
621 		return hw_rss_sup;
622 	/*
623 	 * Although reported as supported, missing code in some Linux
624 	 * versions (v4.15, v4.16) prevents the creation of hash QPs with
625 	 * inner capability.
626 	 *
627 	 * There is no choice but to attempt to instantiate a temporary RSS
628 	 * context in order to confirm its support.
629 	 */
630 	cq = mlx4_glue->create_cq(ctx, 1, NULL, NULL, 0);
631 	wq = cq ? mlx4_glue->create_wq
632 		(ctx,
633 		 &(struct ibv_wq_init_attr){
634 			.wq_type = IBV_WQT_RQ,
635 			.max_wr = 1,
636 			.max_sge = 1,
637 			.pd = pd,
638 			.cq = cq,
639 		 }) : NULL;
640 	ind = wq ? mlx4_glue->create_rwq_ind_table
641 		(ctx,
642 		 &(struct ibv_rwq_ind_table_init_attr){
643 			.log_ind_tbl_size = 0,
644 			.ind_tbl = &wq,
645 			.comp_mask = 0,
646 		 }) : NULL;
647 	qp = ind ? mlx4_glue->create_qp_ex
648 		(ctx,
649 		 &(struct ibv_qp_init_attr_ex){
650 			.comp_mask =
651 				(IBV_QP_INIT_ATTR_PD |
652 				 IBV_QP_INIT_ATTR_RX_HASH |
653 				 IBV_QP_INIT_ATTR_IND_TABLE),
654 			.qp_type = IBV_QPT_RAW_PACKET,
655 			.pd = pd,
656 			.rwq_ind_tbl = ind,
657 			.rx_hash_conf = {
658 				.rx_hash_function = IBV_RX_HASH_FUNC_TOEPLITZ,
659 				.rx_hash_key_len = MLX4_RSS_HASH_KEY_SIZE,
660 				.rx_hash_key = mlx4_rss_hash_key_default,
661 				.rx_hash_fields_mask = hw_rss_sup,
662 			},
663 		 }) : NULL;
664 	if (!qp) {
665 		WARN("disabling unusable inner RSS capability due to kernel"
666 		     " quirk");
667 		hw_rss_sup &= ~IBV_RX_HASH_INNER;
668 	} else {
669 		claim_zero(mlx4_glue->destroy_qp(qp));
670 	}
671 	if (ind)
672 		claim_zero(mlx4_glue->destroy_rwq_ind_table(ind));
673 	if (wq)
674 		claim_zero(mlx4_glue->destroy_wq(wq));
675 	if (cq)
676 		claim_zero(mlx4_glue->destroy_cq(cq));
677 	return hw_rss_sup;
678 }
679 
680 static struct rte_pci_driver mlx4_driver;
681 
682 /**
683  * PMD global initialization.
684  *
685  * Independent from individual device, this function initializes global
686  * per-PMD data structures distinguishing primary and secondary processes.
687  * Hence, each initialization is called once per a process.
688  *
689  * @return
690  *   0 on success, a negative errno value otherwise and rte_errno is set.
691  */
692 static int
693 mlx4_init_once(void)
694 {
695 	struct mlx4_shared_data *sd;
696 	struct mlx4_local_data *ld = &mlx4_local_data;
697 
698 	if (mlx4_init_shared_data())
699 		return -rte_errno;
700 	sd = mlx4_shared_data;
701 	assert(sd);
702 	rte_spinlock_lock(&sd->lock);
703 	switch (rte_eal_process_type()) {
704 	case RTE_PROC_PRIMARY:
705 		if (sd->init_done)
706 			break;
707 		LIST_INIT(&sd->mem_event_cb_list);
708 		rte_rwlock_init(&sd->mem_event_rwlock);
709 		rte_mem_event_callback_register("MLX4_MEM_EVENT_CB",
710 						mlx4_mr_mem_event_cb, NULL);
711 		mlx4_mp_init_primary();
712 		sd->init_done = true;
713 		break;
714 	case RTE_PROC_SECONDARY:
715 		if (ld->init_done)
716 			break;
717 		mlx4_mp_init_secondary();
718 		++sd->secondary_cnt;
719 		ld->init_done = true;
720 		break;
721 	default:
722 		break;
723 	}
724 	rte_spinlock_unlock(&sd->lock);
725 	return 0;
726 }
727 
728 /**
729  * DPDK callback to register a PCI device.
730  *
731  * This function creates an Ethernet device for each port of a given
732  * PCI device.
733  *
734  * @param[in] pci_drv
735  *   PCI driver structure (mlx4_driver).
736  * @param[in] pci_dev
737  *   PCI device information.
738  *
739  * @return
740  *   0 on success, negative errno value otherwise and rte_errno is set.
741  */
742 static int
743 mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
744 {
745 	struct ibv_device **list;
746 	struct ibv_device *ibv_dev;
747 	int err = 0;
748 	struct ibv_context *attr_ctx = NULL;
749 	struct ibv_device_attr device_attr;
750 	struct ibv_device_attr_ex device_attr_ex;
751 	struct mlx4_conf conf = {
752 		.ports.present = 0,
753 		.mr_ext_memseg_en = 1,
754 	};
755 	unsigned int vf;
756 	int i;
757 
758 	(void)pci_drv;
759 	err = mlx4_init_once();
760 	if (err) {
761 		ERROR("unable to init PMD global data: %s",
762 		      strerror(rte_errno));
763 		return -rte_errno;
764 	}
765 	assert(pci_drv == &mlx4_driver);
766 	list = mlx4_glue->get_device_list(&i);
767 	if (list == NULL) {
768 		rte_errno = errno;
769 		assert(rte_errno);
770 		if (rte_errno == ENOSYS)
771 			ERROR("cannot list devices, is ib_uverbs loaded?");
772 		return -rte_errno;
773 	}
774 	assert(i >= 0);
775 	/*
776 	 * For each listed device, check related sysfs entry against
777 	 * the provided PCI ID.
778 	 */
779 	while (i != 0) {
780 		struct rte_pci_addr pci_addr;
781 
782 		--i;
783 		DEBUG("checking device \"%s\"", list[i]->name);
784 		if (mlx4_ibv_device_to_pci_addr(list[i], &pci_addr))
785 			continue;
786 		if ((pci_dev->addr.domain != pci_addr.domain) ||
787 		    (pci_dev->addr.bus != pci_addr.bus) ||
788 		    (pci_dev->addr.devid != pci_addr.devid) ||
789 		    (pci_dev->addr.function != pci_addr.function))
790 			continue;
791 		vf = (pci_dev->id.device_id ==
792 		      PCI_DEVICE_ID_MELLANOX_CONNECTX3VF);
793 		INFO("PCI information matches, using device \"%s\" (VF: %s)",
794 		     list[i]->name, (vf ? "true" : "false"));
795 		attr_ctx = mlx4_glue->open_device(list[i]);
796 		err = errno;
797 		break;
798 	}
799 	if (attr_ctx == NULL) {
800 		mlx4_glue->free_device_list(list);
801 		switch (err) {
802 		case 0:
803 			rte_errno = ENODEV;
804 			ERROR("cannot access device, is mlx4_ib loaded?");
805 			return -rte_errno;
806 		case EINVAL:
807 			rte_errno = EINVAL;
808 			ERROR("cannot use device, are drivers up to date?");
809 			return -rte_errno;
810 		}
811 		assert(err > 0);
812 		rte_errno = err;
813 		return -rte_errno;
814 	}
815 	ibv_dev = list[i];
816 	DEBUG("device opened");
817 	if (mlx4_glue->query_device(attr_ctx, &device_attr)) {
818 		err = ENODEV;
819 		goto error;
820 	}
821 	INFO("%u port(s) detected", device_attr.phys_port_cnt);
822 	conf.ports.present |= (UINT64_C(1) << device_attr.phys_port_cnt) - 1;
823 	if (mlx4_args(pci_dev->device.devargs, &conf)) {
824 		ERROR("failed to process device arguments");
825 		err = EINVAL;
826 		goto error;
827 	}
828 	/* Use all ports when none are defined */
829 	if (!conf.ports.enabled)
830 		conf.ports.enabled = conf.ports.present;
831 	/* Retrieve extended device attributes. */
832 	if (mlx4_glue->query_device_ex(attr_ctx, NULL, &device_attr_ex)) {
833 		err = ENODEV;
834 		goto error;
835 	}
836 	assert(device_attr.max_sge >= MLX4_MAX_SGE);
837 	for (i = 0; i < device_attr.phys_port_cnt; i++) {
838 		uint32_t port = i + 1; /* ports are indexed from one */
839 		struct ibv_context *ctx = NULL;
840 		struct ibv_port_attr port_attr;
841 		struct ibv_pd *pd = NULL;
842 		struct mlx4_priv *priv = NULL;
843 		struct rte_eth_dev *eth_dev = NULL;
844 		struct ether_addr mac;
845 		char name[RTE_ETH_NAME_MAX_LEN];
846 
847 		/* If port is not enabled, skip. */
848 		if (!(conf.ports.enabled & (1 << i)))
849 			continue;
850 		DEBUG("using port %u", port);
851 		ctx = mlx4_glue->open_device(ibv_dev);
852 		if (ctx == NULL) {
853 			err = ENODEV;
854 			goto port_error;
855 		}
856 		snprintf(name, sizeof(name), "%s port %u",
857 			 mlx4_glue->get_device_name(ibv_dev), port);
858 		if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
859 			eth_dev = rte_eth_dev_attach_secondary(name);
860 			if (eth_dev == NULL) {
861 				ERROR("can not attach rte ethdev");
862 				rte_errno = ENOMEM;
863 				err = rte_errno;
864 				goto error;
865 			}
866 			priv = eth_dev->data->dev_private;
867 			if (!priv->verbs_alloc_ctx.enabled) {
868 				ERROR("secondary process is not supported"
869 				      " due to lack of external allocator"
870 				      " from Verbs");
871 				rte_errno = ENOTSUP;
872 				err = rte_errno;
873 				goto error;
874 			}
875 			eth_dev->device = &pci_dev->device;
876 			eth_dev->dev_ops = &mlx4_dev_sec_ops;
877 			err = mlx4_proc_priv_init(eth_dev);
878 			if (err)
879 				goto error;
880 			/* Receive command fd from primary process. */
881 			err = mlx4_mp_req_verbs_cmd_fd(eth_dev);
882 			if (err < 0) {
883 				err = rte_errno;
884 				goto error;
885 			}
886 			/* Remap UAR for Tx queues. */
887 			err = mlx4_tx_uar_init_secondary(eth_dev, err);
888 			if (err) {
889 				err = rte_errno;
890 				goto error;
891 			}
892 			/*
893 			 * Ethdev pointer is still required as input since
894 			 * the primary device is not accessible from the
895 			 * secondary process.
896 			 */
897 			eth_dev->tx_pkt_burst = mlx4_tx_burst;
898 			eth_dev->rx_pkt_burst = mlx4_rx_burst;
899 			claim_zero(mlx4_glue->close_device(ctx));
900 			rte_eth_copy_pci_info(eth_dev, pci_dev);
901 			rte_eth_dev_probing_finish(eth_dev);
902 			continue;
903 		}
904 		/* Check port status. */
905 		err = mlx4_glue->query_port(ctx, port, &port_attr);
906 		if (err) {
907 			err = ENODEV;
908 			ERROR("port query failed: %s", strerror(err));
909 			goto port_error;
910 		}
911 		if (port_attr.link_layer != IBV_LINK_LAYER_ETHERNET) {
912 			err = ENOTSUP;
913 			ERROR("port %d is not configured in Ethernet mode",
914 			      port);
915 			goto port_error;
916 		}
917 		if (port_attr.state != IBV_PORT_ACTIVE)
918 			DEBUG("port %d is not active: \"%s\" (%d)",
919 			      port, mlx4_glue->port_state_str(port_attr.state),
920 			      port_attr.state);
921 		/* Make asynchronous FD non-blocking to handle interrupts. */
922 		err = mlx4_fd_set_non_blocking(ctx->async_fd);
923 		if (err) {
924 			ERROR("cannot make asynchronous FD non-blocking: %s",
925 			      strerror(err));
926 			goto port_error;
927 		}
928 		/* Allocate protection domain. */
929 		pd = mlx4_glue->alloc_pd(ctx);
930 		if (pd == NULL) {
931 			err = ENOMEM;
932 			ERROR("PD allocation failure");
933 			goto port_error;
934 		}
935 		/* from rte_ethdev.c */
936 		priv = rte_zmalloc("ethdev private structure",
937 				   sizeof(*priv),
938 				   RTE_CACHE_LINE_SIZE);
939 		if (priv == NULL) {
940 			err = ENOMEM;
941 			ERROR("priv allocation failure");
942 			goto port_error;
943 		}
944 		priv->ctx = ctx;
945 		priv->device_attr = device_attr;
946 		priv->port = port;
947 		priv->pd = pd;
948 		priv->mtu = ETHER_MTU;
949 		priv->vf = vf;
950 		priv->hw_csum =	!!(device_attr.device_cap_flags &
951 				   IBV_DEVICE_RAW_IP_CSUM);
952 		DEBUG("checksum offloading is %ssupported",
953 		      (priv->hw_csum ? "" : "not "));
954 		/* Only ConnectX-3 Pro supports tunneling. */
955 		priv->hw_csum_l2tun =
956 			priv->hw_csum &&
957 			(device_attr.vendor_part_id ==
958 			 PCI_DEVICE_ID_MELLANOX_CONNECTX3PRO);
959 		DEBUG("L2 tunnel checksum offloads are %ssupported",
960 		      priv->hw_csum_l2tun ? "" : "not ");
961 		priv->hw_rss_sup = mlx4_hw_rss_sup(priv->ctx, priv->pd,
962 						   &device_attr_ex);
963 		DEBUG("supported RSS hash fields mask: %016" PRIx64,
964 		      priv->hw_rss_sup);
965 		priv->hw_rss_max_qps =
966 			device_attr_ex.rss_caps.max_rwq_indirection_table_size;
967 		DEBUG("MAX RSS queues %d", priv->hw_rss_max_qps);
968 		priv->hw_fcs_strip = !!(device_attr_ex.raw_packet_caps &
969 					IBV_RAW_PACKET_CAP_SCATTER_FCS);
970 		DEBUG("FCS stripping toggling is %ssupported",
971 		      priv->hw_fcs_strip ? "" : "not ");
972 		priv->tso =
973 			((device_attr_ex.tso_caps.max_tso > 0) &&
974 			 (device_attr_ex.tso_caps.supported_qpts &
975 			  (1 << IBV_QPT_RAW_PACKET)));
976 		if (priv->tso)
977 			priv->tso_max_payload_sz =
978 					device_attr_ex.tso_caps.max_tso;
979 		DEBUG("TSO is %ssupported",
980 		      priv->tso ? "" : "not ");
981 		priv->mr_ext_memseg_en = conf.mr_ext_memseg_en;
982 		/* Configure the first MAC address by default. */
983 		err = mlx4_get_mac(priv, &mac.addr_bytes);
984 		if (err) {
985 			ERROR("cannot get MAC address, is mlx4_en loaded?"
986 			      " (error: %s)", strerror(err));
987 			goto port_error;
988 		}
989 		INFO("port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
990 		     priv->port,
991 		     mac.addr_bytes[0], mac.addr_bytes[1],
992 		     mac.addr_bytes[2], mac.addr_bytes[3],
993 		     mac.addr_bytes[4], mac.addr_bytes[5]);
994 		/* Register MAC address. */
995 		priv->mac[0] = mac;
996 #ifndef NDEBUG
997 		{
998 			char ifname[IF_NAMESIZE];
999 
1000 			if (mlx4_get_ifname(priv, &ifname) == 0)
1001 				DEBUG("port %u ifname is \"%s\"",
1002 				      priv->port, ifname);
1003 			else
1004 				DEBUG("port %u ifname is unknown", priv->port);
1005 		}
1006 #endif
1007 		/* Get actual MTU if possible. */
1008 		mlx4_mtu_get(priv, &priv->mtu);
1009 		DEBUG("port %u MTU is %u", priv->port, priv->mtu);
1010 		eth_dev = rte_eth_dev_allocate(name);
1011 		if (eth_dev == NULL) {
1012 			err = ENOMEM;
1013 			ERROR("can not allocate rte ethdev");
1014 			goto port_error;
1015 		}
1016 		eth_dev->data->dev_private = priv;
1017 		eth_dev->data->mac_addrs = priv->mac;
1018 		eth_dev->device = &pci_dev->device;
1019 		rte_eth_copy_pci_info(eth_dev, pci_dev);
1020 		/* Initialize local interrupt handle for current port. */
1021 		priv->intr_handle = (struct rte_intr_handle){
1022 			.fd = -1,
1023 			.type = RTE_INTR_HANDLE_EXT,
1024 		};
1025 		/*
1026 		 * Override ethdev interrupt handle pointer with private
1027 		 * handle instead of that of the parent PCI device used by
1028 		 * default. This prevents it from being shared between all
1029 		 * ports of the same PCI device since each of them is
1030 		 * associated its own Verbs context.
1031 		 *
1032 		 * Rx interrupts in particular require this as the PMD has
1033 		 * no control over the registration of queue interrupts
1034 		 * besides setting up eth_dev->intr_handle, the rest is
1035 		 * handled by rte_intr_rx_ctl().
1036 		 */
1037 		eth_dev->intr_handle = &priv->intr_handle;
1038 		priv->dev_data = eth_dev->data;
1039 		eth_dev->dev_ops = &mlx4_dev_ops;
1040 #ifdef HAVE_IBV_MLX4_BUF_ALLOCATORS
1041 		/* Hint libmlx4 to use PMD allocator for data plane resources */
1042 		struct mlx4dv_ctx_allocators alctr = {
1043 			.alloc = &mlx4_alloc_verbs_buf,
1044 			.free = &mlx4_free_verbs_buf,
1045 			.data = priv,
1046 		};
1047 		err = mlx4_glue->dv_set_context_attr
1048 			(ctx, MLX4DV_SET_CTX_ATTR_BUF_ALLOCATORS,
1049 			 (void *)((uintptr_t)&alctr));
1050 		if (err)
1051 			WARN("Verbs external allocator is not supported");
1052 		else
1053 			priv->verbs_alloc_ctx.enabled = 1;
1054 #endif
1055 		/* Bring Ethernet device up. */
1056 		DEBUG("forcing Ethernet interface up");
1057 		mlx4_dev_set_link_up(eth_dev);
1058 		/* Update link status once if waiting for LSC. */
1059 		if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
1060 			mlx4_link_update(eth_dev, 0);
1061 		/*
1062 		 * Once the device is added to the list of memory event
1063 		 * callback, its global MR cache table cannot be expanded
1064 		 * on the fly because of deadlock. If it overflows, lookup
1065 		 * should be done by searching MR list linearly, which is slow.
1066 		 */
1067 		err = mlx4_mr_btree_init(&priv->mr.cache,
1068 					 MLX4_MR_BTREE_CACHE_N * 2,
1069 					 eth_dev->device->numa_node);
1070 		if (err) {
1071 			/* rte_errno is already set. */
1072 			goto port_error;
1073 		}
1074 		/* Add device to memory callback list. */
1075 		rte_rwlock_write_lock(&mlx4_shared_data->mem_event_rwlock);
1076 		LIST_INSERT_HEAD(&mlx4_shared_data->mem_event_cb_list,
1077 				 priv, mem_event_cb);
1078 		rte_rwlock_write_unlock(&mlx4_shared_data->mem_event_rwlock);
1079 		rte_eth_dev_probing_finish(eth_dev);
1080 		continue;
1081 port_error:
1082 		rte_free(priv);
1083 		if (eth_dev != NULL)
1084 			eth_dev->data->dev_private = NULL;
1085 		if (pd)
1086 			claim_zero(mlx4_glue->dealloc_pd(pd));
1087 		if (ctx)
1088 			claim_zero(mlx4_glue->close_device(ctx));
1089 		if (eth_dev != NULL) {
1090 			/* mac_addrs must not be freed because part of dev_private */
1091 			eth_dev->data->mac_addrs = NULL;
1092 			rte_eth_dev_release_port(eth_dev);
1093 		}
1094 		break;
1095 	}
1096 	/*
1097 	 * XXX if something went wrong in the loop above, there is a resource
1098 	 * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
1099 	 * long as the dpdk does not provide a way to deallocate a ethdev and a
1100 	 * way to enumerate the registered ethdevs to free the previous ones.
1101 	 */
1102 error:
1103 	if (attr_ctx)
1104 		claim_zero(mlx4_glue->close_device(attr_ctx));
1105 	if (list)
1106 		mlx4_glue->free_device_list(list);
1107 	if (err)
1108 		rte_errno = err;
1109 	return -err;
1110 }
1111 
1112 static const struct rte_pci_id mlx4_pci_id_map[] = {
1113 	{
1114 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
1115 			       PCI_DEVICE_ID_MELLANOX_CONNECTX3)
1116 	},
1117 	{
1118 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
1119 			       PCI_DEVICE_ID_MELLANOX_CONNECTX3PRO)
1120 	},
1121 	{
1122 		RTE_PCI_DEVICE(PCI_VENDOR_ID_MELLANOX,
1123 			       PCI_DEVICE_ID_MELLANOX_CONNECTX3VF)
1124 	},
1125 	{
1126 		.vendor_id = 0
1127 	}
1128 };
1129 
1130 static struct rte_pci_driver mlx4_driver = {
1131 	.driver = {
1132 		.name = MLX4_DRIVER_NAME
1133 	},
1134 	.id_table = mlx4_pci_id_map,
1135 	.probe = mlx4_pci_probe,
1136 	.drv_flags = RTE_PCI_DRV_INTR_LSC |
1137 		     RTE_PCI_DRV_INTR_RMV,
1138 };
1139 
1140 #ifdef RTE_IBVERBS_LINK_DLOPEN
1141 
1142 /**
1143  * Suffix RTE_EAL_PMD_PATH with "-glue".
1144  *
1145  * This function performs a sanity check on RTE_EAL_PMD_PATH before
1146  * suffixing its last component.
1147  *
1148  * @param buf[out]
1149  *   Output buffer, should be large enough otherwise NULL is returned.
1150  * @param size
1151  *   Size of @p out.
1152  *
1153  * @return
1154  *   Pointer to @p buf or @p NULL in case suffix cannot be appended.
1155  */
1156 static char *
1157 mlx4_glue_path(char *buf, size_t size)
1158 {
1159 	static const char *const bad[] = { "/", ".", "..", NULL };
1160 	const char *path = RTE_EAL_PMD_PATH;
1161 	size_t len = strlen(path);
1162 	size_t off;
1163 	int i;
1164 
1165 	while (len && path[len - 1] == '/')
1166 		--len;
1167 	for (off = len; off && path[off - 1] != '/'; --off)
1168 		;
1169 	for (i = 0; bad[i]; ++i)
1170 		if (!strncmp(path + off, bad[i], (int)(len - off)))
1171 			goto error;
1172 	i = snprintf(buf, size, "%.*s-glue", (int)len, path);
1173 	if (i == -1 || (size_t)i >= size)
1174 		goto error;
1175 	return buf;
1176 error:
1177 	ERROR("unable to append \"-glue\" to last component of"
1178 	      " RTE_EAL_PMD_PATH (\"" RTE_EAL_PMD_PATH "\"),"
1179 	      " please re-configure DPDK");
1180 	return NULL;
1181 }
1182 
1183 /**
1184  * Initialization routine for run-time dependency on rdma-core.
1185  */
1186 static int
1187 mlx4_glue_init(void)
1188 {
1189 	char glue_path[sizeof(RTE_EAL_PMD_PATH) - 1 + sizeof("-glue")];
1190 	const char *path[] = {
1191 		/*
1192 		 * A basic security check is necessary before trusting
1193 		 * MLX4_GLUE_PATH, which may override RTE_EAL_PMD_PATH.
1194 		 */
1195 		(geteuid() == getuid() && getegid() == getgid() ?
1196 		 getenv("MLX4_GLUE_PATH") : NULL),
1197 		/*
1198 		 * When RTE_EAL_PMD_PATH is set, use its glue-suffixed
1199 		 * variant, otherwise let dlopen() look up libraries on its
1200 		 * own.
1201 		 */
1202 		(*RTE_EAL_PMD_PATH ?
1203 		 mlx4_glue_path(glue_path, sizeof(glue_path)) : ""),
1204 	};
1205 	unsigned int i = 0;
1206 	void *handle = NULL;
1207 	void **sym;
1208 	const char *dlmsg;
1209 
1210 	while (!handle && i != RTE_DIM(path)) {
1211 		const char *end;
1212 		size_t len;
1213 		int ret;
1214 
1215 		if (!path[i]) {
1216 			++i;
1217 			continue;
1218 		}
1219 		end = strpbrk(path[i], ":;");
1220 		if (!end)
1221 			end = path[i] + strlen(path[i]);
1222 		len = end - path[i];
1223 		ret = 0;
1224 		do {
1225 			char name[ret + 1];
1226 
1227 			ret = snprintf(name, sizeof(name), "%.*s%s" MLX4_GLUE,
1228 				       (int)len, path[i],
1229 				       (!len || *(end - 1) == '/') ? "" : "/");
1230 			if (ret == -1)
1231 				break;
1232 			if (sizeof(name) != (size_t)ret + 1)
1233 				continue;
1234 			DEBUG("looking for rdma-core glue as \"%s\"", name);
1235 			handle = dlopen(name, RTLD_LAZY);
1236 			break;
1237 		} while (1);
1238 		path[i] = end + 1;
1239 		if (!*end)
1240 			++i;
1241 	}
1242 	if (!handle) {
1243 		rte_errno = EINVAL;
1244 		dlmsg = dlerror();
1245 		if (dlmsg)
1246 			WARN("cannot load glue library: %s", dlmsg);
1247 		goto glue_error;
1248 	}
1249 	sym = dlsym(handle, "mlx4_glue");
1250 	if (!sym || !*sym) {
1251 		rte_errno = EINVAL;
1252 		dlmsg = dlerror();
1253 		if (dlmsg)
1254 			ERROR("cannot resolve glue symbol: %s", dlmsg);
1255 		goto glue_error;
1256 	}
1257 	mlx4_glue = *sym;
1258 	return 0;
1259 glue_error:
1260 	if (handle)
1261 		dlclose(handle);
1262 	WARN("cannot initialize PMD due to missing run-time"
1263 	     " dependency on rdma-core libraries (libibverbs,"
1264 	     " libmlx4)");
1265 	return -rte_errno;
1266 }
1267 
1268 #endif
1269 
1270 /**
1271  * Driver initialization routine.
1272  */
1273 RTE_INIT(rte_mlx4_pmd_init)
1274 {
1275 	/*
1276 	 * MLX4_DEVICE_FATAL_CLEANUP tells ibv_destroy functions we
1277 	 * want to get success errno value in case of calling them
1278 	 * when the device was removed.
1279 	 */
1280 	setenv("MLX4_DEVICE_FATAL_CLEANUP", "1", 1);
1281 	/*
1282 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
1283 	 * huge pages. Calling ibv_fork_init() during init allows
1284 	 * applications to use fork() safely for purposes other than
1285 	 * using this PMD, which is not supported in forked processes.
1286 	 */
1287 	setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
1288 #ifdef RTE_IBVERBS_LINK_DLOPEN
1289 	if (mlx4_glue_init())
1290 		return;
1291 	assert(mlx4_glue);
1292 #endif
1293 #ifndef NDEBUG
1294 	/* Glue structure must not contain any NULL pointers. */
1295 	{
1296 		unsigned int i;
1297 
1298 		for (i = 0; i != sizeof(*mlx4_glue) / sizeof(void *); ++i)
1299 			assert(((const void *const *)mlx4_glue)[i]);
1300 	}
1301 #endif
1302 	if (strcmp(mlx4_glue->version, MLX4_GLUE_VERSION)) {
1303 		ERROR("rdma-core glue \"%s\" mismatch: \"%s\" is required",
1304 		      mlx4_glue->version, MLX4_GLUE_VERSION);
1305 		return;
1306 	}
1307 	mlx4_glue->fork_init();
1308 	rte_pci_register(&mlx4_driver);
1309 }
1310 
1311 RTE_PMD_EXPORT_NAME(net_mlx4, __COUNTER__);
1312 RTE_PMD_REGISTER_PCI_TABLE(net_mlx4, mlx4_pci_id_map);
1313 RTE_PMD_REGISTER_KMOD_DEP(net_mlx4,
1314 	"* ib_uverbs & mlx4_en & mlx4_core & mlx4_ib");
1315