xref: /dpdk/drivers/net/octeontx/octeontx_ethdev.c (revision 4fac7c0a147e4eae91aa527ee51ad70616b14182)
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (C) Cavium Inc. 2017. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Cavium networks nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <string.h>
37 #include <unistd.h>
38 
39 #include <rte_alarm.h>
40 #include <rte_branch_prediction.h>
41 #include <rte_debug.h>
42 #include <rte_devargs.h>
43 #include <rte_dev.h>
44 #include <rte_kvargs.h>
45 #include <rte_malloc.h>
46 #include <rte_prefetch.h>
47 #include <rte_vdev.h>
48 
49 #include "octeontx_ethdev.h"
50 #include "octeontx_logs.h"
51 
52 struct octeontx_vdev_init_params {
53 	uint8_t	nr_port;
54 };
55 
56 enum octeontx_link_speed {
57 	OCTEONTX_LINK_SPEED_SGMII,
58 	OCTEONTX_LINK_SPEED_XAUI,
59 	OCTEONTX_LINK_SPEED_RXAUI,
60 	OCTEONTX_LINK_SPEED_10G_R,
61 	OCTEONTX_LINK_SPEED_40G_R,
62 	OCTEONTX_LINK_SPEED_RESERVE1,
63 	OCTEONTX_LINK_SPEED_QSGMII,
64 	OCTEONTX_LINK_SPEED_RESERVE2
65 };
66 
67 /* Parse integer from integer argument */
68 static int
69 parse_integer_arg(const char *key __rte_unused,
70 		const char *value, void *extra_args)
71 {
72 	int *i = (int *)extra_args;
73 
74 	*i = atoi(value);
75 	if (*i < 0) {
76 		octeontx_log_err("argument has to be positive.");
77 		return -1;
78 	}
79 
80 	return 0;
81 }
82 
83 static int
84 octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
85 				struct rte_vdev_device *dev)
86 {
87 	struct rte_kvargs *kvlist = NULL;
88 	int ret = 0;
89 
90 	static const char * const octeontx_vdev_valid_params[] = {
91 		OCTEONTX_VDEV_NR_PORT_ARG,
92 		NULL
93 	};
94 
95 	const char *input_args = rte_vdev_device_args(dev);
96 	if (params == NULL)
97 		return -EINVAL;
98 
99 
100 	if (input_args) {
101 		kvlist = rte_kvargs_parse(input_args,
102 				octeontx_vdev_valid_params);
103 		if (kvlist == NULL)
104 			return -1;
105 
106 		ret = rte_kvargs_process(kvlist,
107 					OCTEONTX_VDEV_NR_PORT_ARG,
108 					&parse_integer_arg,
109 					&params->nr_port);
110 		if (ret < 0)
111 			goto free_kvlist;
112 	}
113 
114 free_kvlist:
115 	rte_kvargs_free(kvlist);
116 	return ret;
117 }
118 
119 static int
120 octeontx_port_open(struct octeontx_nic *nic)
121 {
122 	octeontx_mbox_bgx_port_conf_t bgx_port_conf;
123 	int res;
124 
125 	res = 0;
126 
127 	PMD_INIT_FUNC_TRACE();
128 
129 	res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf);
130 	if (res < 0) {
131 		octeontx_log_err("failed to open port %d", res);
132 		return res;
133 	}
134 
135 	nic->node = bgx_port_conf.node;
136 	nic->port_ena = bgx_port_conf.enable;
137 	nic->base_ichan = bgx_port_conf.base_chan;
138 	nic->base_ochan = bgx_port_conf.base_chan;
139 	nic->num_ichans = bgx_port_conf.num_chans;
140 	nic->num_ochans = bgx_port_conf.num_chans;
141 	nic->mtu = bgx_port_conf.mtu;
142 	nic->bpen = bgx_port_conf.bpen;
143 	nic->fcs_strip = bgx_port_conf.fcs_strip;
144 	nic->bcast_mode = bgx_port_conf.bcast_mode;
145 	nic->mcast_mode = bgx_port_conf.mcast_mode;
146 	nic->speed	= bgx_port_conf.mode;
147 
148 	memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN);
149 
150 	octeontx_log_dbg("port opened %d", nic->port_id);
151 	return res;
152 }
153 
154 static void
155 octeontx_port_close(struct octeontx_nic *nic)
156 {
157 	PMD_INIT_FUNC_TRACE();
158 
159 	octeontx_bgx_port_close(nic->port_id);
160 	octeontx_log_dbg("port closed %d", nic->port_id);
161 }
162 
163 static inline void
164 devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
165 				struct rte_event_dev_info *info)
166 {
167 	memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
168 	dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
169 
170 	dev_conf->nb_event_ports = info->max_event_ports;
171 	dev_conf->nb_event_queues = info->max_event_queues;
172 
173 	dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
174 	dev_conf->nb_event_port_dequeue_depth =
175 			info->max_event_port_dequeue_depth;
176 	dev_conf->nb_event_port_enqueue_depth =
177 			info->max_event_port_enqueue_depth;
178 	dev_conf->nb_event_port_enqueue_depth =
179 			info->max_event_port_enqueue_depth;
180 	dev_conf->nb_events_limit =
181 			info->max_num_events;
182 }
183 
184 static int
185 octeontx_dev_configure(struct rte_eth_dev *dev)
186 {
187 	struct rte_eth_dev_data *data = dev->data;
188 	struct rte_eth_conf *conf = &data->dev_conf;
189 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
190 	struct rte_eth_txmode *txmode = &conf->txmode;
191 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
192 	int ret;
193 
194 	PMD_INIT_FUNC_TRACE();
195 	RTE_SET_USED(conf);
196 
197 	if (!rte_eal_has_hugepages()) {
198 		octeontx_log_err("huge page is not configured");
199 		return -EINVAL;
200 	}
201 
202 	if (txmode->mq_mode) {
203 		octeontx_log_err("tx mq_mode DCB or VMDq not supported");
204 		return -EINVAL;
205 	}
206 
207 	if (rxmode->mq_mode != ETH_MQ_RX_NONE &&
208 		rxmode->mq_mode != ETH_MQ_RX_RSS) {
209 		octeontx_log_err("unsupported rx qmode %d", rxmode->mq_mode);
210 		return -EINVAL;
211 	}
212 
213 	if (!rxmode->hw_strip_crc) {
214 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
215 		rxmode->hw_strip_crc = 1;
216 	}
217 
218 	if (rxmode->hw_ip_checksum) {
219 		PMD_INIT_LOG(NOTICE, "rxcksum not supported");
220 		rxmode->hw_ip_checksum = 0;
221 	}
222 
223 	if (rxmode->split_hdr_size) {
224 		octeontx_log_err("rxmode does not support split header");
225 		return -EINVAL;
226 	}
227 
228 	if (rxmode->hw_vlan_filter) {
229 		octeontx_log_err("VLAN filter not supported");
230 		return -EINVAL;
231 	}
232 
233 	if (rxmode->hw_vlan_extend) {
234 		octeontx_log_err("VLAN extended not supported");
235 		return -EINVAL;
236 	}
237 
238 	if (rxmode->enable_lro) {
239 		octeontx_log_err("LRO not supported");
240 		return -EINVAL;
241 	}
242 
243 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
244 		octeontx_log_err("setting link speed/duplex not supported");
245 		return -EINVAL;
246 	}
247 
248 	if (conf->dcb_capability_en) {
249 		octeontx_log_err("DCB enable not supported");
250 		return -EINVAL;
251 	}
252 
253 	if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) {
254 		octeontx_log_err("flow director not supported");
255 		return -EINVAL;
256 	}
257 
258 	nic->num_tx_queues = dev->data->nb_tx_queues;
259 
260 	ret = octeontx_pko_channel_open(nic->port_id * PKO_VF_NUM_DQ,
261 					nic->num_tx_queues,
262 					nic->base_ochan);
263 	if (ret) {
264 		octeontx_log_err("failed to open channel %d no-of-txq %d",
265 			   nic->base_ochan, nic->num_tx_queues);
266 		return -EFAULT;
267 	}
268 
269 	nic->pki.classifier_enable = false;
270 	nic->pki.hash_enable = true;
271 	nic->pki.initialized = false;
272 
273 	return 0;
274 }
275 
276 static inline int
277 octeontx_atomic_write_link_status(struct rte_eth_dev *dev,
278 				  struct rte_eth_link *link)
279 {
280 	struct rte_eth_link *dst = &dev->data->dev_link;
281 	struct rte_eth_link *src = link;
282 
283 	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
284 		*(uint64_t *)src) == 0)
285 		return -1;
286 
287 	return 0;
288 }
289 
290 static int
291 octeontx_port_link_status(struct octeontx_nic *nic)
292 {
293 	int res;
294 
295 	PMD_INIT_FUNC_TRACE();
296 	res = octeontx_bgx_port_link_status(nic->port_id);
297 	if (res < 0) {
298 		octeontx_log_err("failed to get port %d link status",
299 				nic->port_id);
300 		return res;
301 	}
302 
303 	nic->link_up = (uint8_t)res;
304 	octeontx_log_dbg("port %d link status %d", nic->port_id, nic->link_up);
305 
306 	return res;
307 }
308 
309 /*
310  * Return 0 means link status changed, -1 means not changed
311  */
312 static int
313 octeontx_dev_link_update(struct rte_eth_dev *dev,
314 			 int wait_to_complete __rte_unused)
315 {
316 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
317 	struct rte_eth_link link;
318 	int res;
319 
320 	res = 0;
321 	PMD_INIT_FUNC_TRACE();
322 
323 	res = octeontx_port_link_status(nic);
324 	if (res < 0) {
325 		octeontx_log_err("failed to request link status %d", res);
326 		return res;
327 	}
328 
329 	link.link_status = nic->link_up;
330 
331 	switch (nic->speed) {
332 	case OCTEONTX_LINK_SPEED_SGMII:
333 		link.link_speed = ETH_SPEED_NUM_1G;
334 		break;
335 
336 	case OCTEONTX_LINK_SPEED_XAUI:
337 		link.link_speed = ETH_SPEED_NUM_10G;
338 		break;
339 
340 	case OCTEONTX_LINK_SPEED_RXAUI:
341 	case OCTEONTX_LINK_SPEED_10G_R:
342 		link.link_speed = ETH_SPEED_NUM_10G;
343 		break;
344 	case OCTEONTX_LINK_SPEED_QSGMII:
345 		link.link_speed = ETH_SPEED_NUM_5G;
346 		break;
347 	case OCTEONTX_LINK_SPEED_40G_R:
348 		link.link_speed = ETH_SPEED_NUM_40G;
349 		break;
350 
351 	case OCTEONTX_LINK_SPEED_RESERVE1:
352 	case OCTEONTX_LINK_SPEED_RESERVE2:
353 	default:
354 		octeontx_log_err("incorrect link speed %d", nic->speed);
355 		break;
356 	}
357 
358 	link.link_duplex = ETH_LINK_AUTONEG;
359 	link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
360 
361 	return octeontx_atomic_write_link_status(dev, &link);
362 }
363 
364 static void
365 octeontx_dev_info(struct rte_eth_dev *dev,
366 		struct rte_eth_dev_info *dev_info)
367 {
368 	RTE_SET_USED(dev);
369 
370 	/* Autonegotiation may be disabled */
371 	dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
372 	dev_info->speed_capa |= ETH_LINK_SPEED_10M | ETH_LINK_SPEED_100M |
373 			ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
374 			ETH_LINK_SPEED_40G;
375 
376 	dev_info->driver_name = RTE_STR(rte_octeontx_pmd);
377 	dev_info->max_mac_addrs = 1;
378 	dev_info->max_rx_pktlen = PKI_MAX_PKTLEN;
379 	dev_info->max_rx_queues = 1;
380 	dev_info->max_tx_queues = PKO_MAX_NUM_DQ;
381 	dev_info->min_rx_bufsize = 0;
382 	dev_info->pci_dev = NULL;
383 
384 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
385 		.rx_free_thresh = 0,
386 		.rx_drop_en = 0,
387 	};
388 
389 	dev_info->default_txconf = (struct rte_eth_txconf) {
390 		.tx_free_thresh = 0,
391 		.txq_flags =
392 			ETH_TXQ_FLAGS_NOMULTSEGS |
393 			ETH_TXQ_FLAGS_NOOFFLOADS |
394 			ETH_TXQ_FLAGS_NOXSUMS,
395 	};
396 
397 	dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MT_LOCKFREE;
398 }
399 
400 /* Initialize and register driver with DPDK Application */
401 static const struct eth_dev_ops octeontx_dev_ops = {
402 	.dev_configure		 = octeontx_dev_configure,
403 	.dev_infos_get		 = octeontx_dev_info,
404 	.link_update		 = octeontx_dev_link_update,
405 };
406 
407 /* Create Ethdev interface per BGX LMAC ports */
408 static int
409 octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
410 			int socket_id)
411 {
412 	int res;
413 	char octtx_name[OCTEONTX_MAX_NAME_LEN];
414 	struct octeontx_nic *nic = NULL;
415 	struct rte_eth_dev *eth_dev = NULL;
416 	struct rte_eth_dev_data *data = NULL;
417 	const char *name = rte_vdev_device_name(dev);
418 
419 	PMD_INIT_FUNC_TRACE();
420 
421 	sprintf(octtx_name, "%s_%d", name, port);
422 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
423 		eth_dev = rte_eth_dev_attach_secondary(octtx_name);
424 		if (eth_dev == NULL)
425 			return -ENODEV;
426 
427 		return 0;
428 	}
429 
430 	data = rte_zmalloc_socket(octtx_name, sizeof(*data), 0, socket_id);
431 	if (data == NULL) {
432 		octeontx_log_err("failed to allocate devdata");
433 		res = -ENOMEM;
434 		goto err;
435 	}
436 
437 	nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id);
438 	if (nic == NULL) {
439 		octeontx_log_err("failed to allocate nic structure");
440 		res = -ENOMEM;
441 		goto err;
442 	}
443 
444 	nic->port_id = port;
445 	nic->evdev = evdev;
446 
447 	res = octeontx_port_open(nic);
448 	if (res < 0)
449 		goto err;
450 
451 	/* Rx side port configuration */
452 	res = octeontx_pki_port_open(port);
453 	if (res != 0) {
454 		octeontx_log_err("failed to open PKI port %d", port);
455 		res = -ENODEV;
456 		goto err;
457 	}
458 
459 	/* Reserve an ethdev entry */
460 	eth_dev = rte_eth_dev_allocate(octtx_name);
461 	if (eth_dev == NULL) {
462 		octeontx_log_err("failed to allocate rte_eth_dev");
463 		res = -ENOMEM;
464 		goto err;
465 	}
466 
467 	eth_dev->device = &dev->device;
468 	eth_dev->intr_handle = NULL;
469 	eth_dev->data->kdrv = RTE_KDRV_NONE;
470 	eth_dev->data->numa_node = dev->device.numa_node;
471 
472 	rte_memcpy(data, (eth_dev)->data, sizeof(*data));
473 	data->dev_private = nic;
474 
475 	data->port_id = eth_dev->data->port_id;
476 	snprintf(data->name, sizeof(data->name), "%s", eth_dev->data->name);
477 
478 	nic->ev_queues = 1;
479 	nic->ev_ports = 1;
480 
481 	data->dev_link.link_status = ETH_LINK_DOWN;
482 	data->dev_started = 0;
483 	data->promiscuous = 0;
484 	data->all_multicast = 0;
485 	data->scattered_rx = 0;
486 
487 	data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0,
488 							socket_id);
489 	if (data->mac_addrs == NULL) {
490 		octeontx_log_err("failed to allocate memory for mac_addrs");
491 		res = -ENOMEM;
492 		goto err;
493 	}
494 
495 	eth_dev->data = data;
496 	eth_dev->dev_ops = &octeontx_dev_ops;
497 
498 	/* Finally save ethdev pointer to the NIC structure */
499 	nic->dev = eth_dev;
500 
501 	if (nic->port_id != data->port_id) {
502 		octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)",
503 				data->port_id, nic->port_id);
504 		res = -EINVAL;
505 		goto err;
506 	}
507 
508 	/* Update port_id mac to eth_dev */
509 	memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN);
510 
511 	PMD_INIT_LOG(DEBUG, "ethdev info: ");
512 	PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
513 				nic->port_id, nic->port_ena,
514 				nic->base_ochan, nic->num_ochans,
515 				nic->num_tx_queues);
516 	PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu);
517 
518 	return data->port_id;
519 
520 err:
521 	if (port)
522 		octeontx_port_close(nic);
523 
524 	if (eth_dev != NULL) {
525 		rte_free(eth_dev->data->mac_addrs);
526 		rte_free(data);
527 		rte_free(nic);
528 		rte_eth_dev_release_port(eth_dev);
529 	}
530 
531 	return res;
532 }
533 
534 /* Un initialize octeontx device */
535 static int
536 octeontx_remove(struct rte_vdev_device *dev)
537 {
538 	char octtx_name[OCTEONTX_MAX_NAME_LEN];
539 	struct rte_eth_dev *eth_dev = NULL;
540 	struct octeontx_nic *nic = NULL;
541 	int i;
542 
543 	if (dev == NULL)
544 		return -EINVAL;
545 
546 	for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
547 		sprintf(octtx_name, "eth_octeontx_%d", i);
548 
549 		/* reserve an ethdev entry */
550 		eth_dev = rte_eth_dev_allocated(octtx_name);
551 		if (eth_dev == NULL)
552 			return -ENODEV;
553 
554 		nic = octeontx_pmd_priv(eth_dev);
555 		rte_event_dev_stop(nic->evdev);
556 		PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
557 
558 		rte_free(eth_dev->data->mac_addrs);
559 		rte_free(eth_dev->data->dev_private);
560 		rte_free(eth_dev->data);
561 		rte_eth_dev_release_port(eth_dev);
562 		rte_event_dev_close(nic->evdev);
563 	}
564 
565 	/* Free FC resource */
566 	octeontx_pko_fc_free();
567 
568 	return 0;
569 }
570 
571 /* Initialize octeontx device */
572 static int
573 octeontx_probe(struct rte_vdev_device *dev)
574 {
575 	const char *dev_name;
576 	static int probe_once;
577 	uint8_t socket_id, qlist;
578 	int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
579 	struct rte_event_dev_config dev_conf;
580 	const char *eventdev_name = "event_octeontx";
581 	struct rte_event_dev_info info;
582 
583 	struct octeontx_vdev_init_params init_params = {
584 		OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
585 	};
586 
587 	dev_name = rte_vdev_device_name(dev);
588 	res = octeontx_parse_vdev_init_params(&init_params, dev);
589 	if (res < 0)
590 		return -EINVAL;
591 
592 	if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
593 		octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
594 				OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
595 		return -ENOTSUP;
596 	}
597 
598 	PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
599 
600 	socket_id = rte_socket_id();
601 
602 	tx_vfcnt = octeontx_pko_vf_count();
603 
604 	if (tx_vfcnt < init_params.nr_port) {
605 		octeontx_log_err("not enough PKO (%d) for port number (%d)",
606 				tx_vfcnt, init_params.nr_port);
607 		return -EINVAL;
608 	}
609 	evdev = rte_event_dev_get_dev_id(eventdev_name);
610 	if (evdev < 0) {
611 		octeontx_log_err("eventdev %s not found", eventdev_name);
612 		return -ENODEV;
613 	}
614 
615 	res = rte_event_dev_info_get(evdev, &info);
616 	if (res < 0) {
617 		octeontx_log_err("failed to eventdev info %d", res);
618 		return -EINVAL;
619 	}
620 
621 	PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
622 			info.max_event_queues, info.max_event_ports);
623 
624 	if (octeontx_pko_init_fc(tx_vfcnt))
625 		return -ENOMEM;
626 
627 	devconf_set_default_sane_values(&dev_conf, &info);
628 	res = rte_event_dev_configure(evdev, &dev_conf);
629 	if (res < 0)
630 		goto parse_error;
631 
632 	rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
633 			(uint32_t *)&pnum);
634 	rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
635 			(uint32_t *)&qnum);
636 	if (pnum < qnum) {
637 		octeontx_log_err("too few event ports (%d) for event_q(%d)",
638 				pnum, qnum);
639 		res = -EINVAL;
640 		goto parse_error;
641 	}
642 	if (pnum > qnum) {
643 		/*
644 		 * We don't poll on event ports
645 		 * that do not have any queues assigned.
646 		 */
647 		pnum = qnum;
648 		PMD_INIT_LOG(INFO,
649 			"reducing number of active event ports to %d", pnum);
650 	}
651 	for (i = 0; i < qnum; i++) {
652 		res = rte_event_queue_setup(evdev, i, NULL);
653 		if (res < 0) {
654 			octeontx_log_err("failed to setup event_q(%d): res %d",
655 					i, res);
656 			goto parse_error;
657 		}
658 	}
659 
660 	for (i = 0; i < pnum; i++) {
661 		res = rte_event_port_setup(evdev, i, NULL);
662 		if (res < 0) {
663 			res = -ENODEV;
664 			octeontx_log_err("failed to setup ev port(%d) res=%d",
665 						i, res);
666 			goto parse_error;
667 		}
668 		/* Link one queue to one event port */
669 		qlist = i;
670 		res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
671 		if (res < 0) {
672 			res = -ENODEV;
673 			octeontx_log_err("failed to link port (%d): res=%d",
674 					i, res);
675 			goto parse_error;
676 		}
677 	}
678 
679 	/* Create ethdev interface */
680 	for (i = 0; i < init_params.nr_port; i++) {
681 		port_id = octeontx_create(dev, i, evdev, socket_id);
682 		if (port_id < 0) {
683 			octeontx_log_err("failed to create device %s",
684 					dev_name);
685 			res = -ENODEV;
686 			goto parse_error;
687 		}
688 
689 		PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
690 					port_id);
691 	}
692 
693 	if (probe_once) {
694 		octeontx_log_err("interface %s not supported", dev_name);
695 		octeontx_remove(dev);
696 		res = -ENOTSUP;
697 		goto parse_error;
698 	}
699 	probe_once = 1;
700 
701 	return 0;
702 
703 parse_error:
704 	octeontx_pko_fc_free();
705 	return res;
706 }
707 
708 static struct rte_vdev_driver octeontx_pmd_drv = {
709 	.probe = octeontx_probe,
710 	.remove = octeontx_remove,
711 };
712 
713 RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
714 RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
715 RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");
716