xref: /dpdk/drivers/net/octeontx/octeontx_ethdev.c (revision 15bce35b7568b8a66089754566169a32e2e5d8bb)
1f7be70e5SJerin Jacob /*
2f7be70e5SJerin Jacob  *   BSD LICENSE
3f7be70e5SJerin Jacob  *
4f7be70e5SJerin Jacob  *   Copyright (C) Cavium Inc. 2017. All rights reserved.
5f7be70e5SJerin Jacob  *
6f7be70e5SJerin Jacob  *   Redistribution and use in source and binary forms, with or without
7f7be70e5SJerin Jacob  *   modification, are permitted provided that the following conditions
8f7be70e5SJerin Jacob  *   are met:
9f7be70e5SJerin Jacob  *
10f7be70e5SJerin Jacob  *     * Redistributions of source code must retain the above copyright
11f7be70e5SJerin Jacob  *       notice, this list of conditions and the following disclaimer.
12f7be70e5SJerin Jacob  *     * Redistributions in binary form must reproduce the above copyright
13f7be70e5SJerin Jacob  *       notice, this list of conditions and the following disclaimer in
14f7be70e5SJerin Jacob  *       the documentation and/or other materials provided with the
15f7be70e5SJerin Jacob  *       distribution.
16f7be70e5SJerin Jacob  *     * Neither the name of Cavium networks nor the names of its
17f7be70e5SJerin Jacob  *       contributors may be used to endorse or promote products derived
18f7be70e5SJerin Jacob  *       from this software without specific prior written permission.
19f7be70e5SJerin Jacob  *
20f7be70e5SJerin Jacob  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21f7be70e5SJerin Jacob  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22f7be70e5SJerin Jacob  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23f7be70e5SJerin Jacob  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24f7be70e5SJerin Jacob  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25f7be70e5SJerin Jacob  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26f7be70e5SJerin Jacob  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27f7be70e5SJerin Jacob  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28f7be70e5SJerin Jacob  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29f7be70e5SJerin Jacob  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30f7be70e5SJerin Jacob  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31f7be70e5SJerin Jacob  */
32f7be70e5SJerin Jacob #include <stdio.h>
33f7be70e5SJerin Jacob #include <stdarg.h>
34f7be70e5SJerin Jacob #include <stdbool.h>
35f7be70e5SJerin Jacob #include <stdint.h>
36f7be70e5SJerin Jacob #include <string.h>
37f7be70e5SJerin Jacob #include <unistd.h>
38f7be70e5SJerin Jacob 
39f7be70e5SJerin Jacob #include <rte_alarm.h>
40f7be70e5SJerin Jacob #include <rte_branch_prediction.h>
41f7be70e5SJerin Jacob #include <rte_debug.h>
42f7be70e5SJerin Jacob #include <rte_devargs.h>
43f7be70e5SJerin Jacob #include <rte_dev.h>
44f7be70e5SJerin Jacob #include <rte_kvargs.h>
45f7be70e5SJerin Jacob #include <rte_malloc.h>
46f7be70e5SJerin Jacob #include <rte_prefetch.h>
47f7be70e5SJerin Jacob #include <rte_vdev.h>
48f7be70e5SJerin Jacob 
49f7be70e5SJerin Jacob #include "octeontx_ethdev.h"
50f7be70e5SJerin Jacob #include "octeontx_logs.h"
51f7be70e5SJerin Jacob 
52f7be70e5SJerin Jacob struct octeontx_vdev_init_params {
53f7be70e5SJerin Jacob 	uint8_t	nr_port;
54f7be70e5SJerin Jacob };
55f7be70e5SJerin Jacob 
564fac7c0aSJerin Jacob enum octeontx_link_speed {
574fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_SGMII,
584fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_XAUI,
594fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_RXAUI,
604fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_10G_R,
614fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_40G_R,
624fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_RESERVE1,
634fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_QSGMII,
644fac7c0aSJerin Jacob 	OCTEONTX_LINK_SPEED_RESERVE2
654fac7c0aSJerin Jacob };
664fac7c0aSJerin Jacob 
67f7be70e5SJerin Jacob /* Parse integer from integer argument */
68f7be70e5SJerin Jacob static int
69f7be70e5SJerin Jacob parse_integer_arg(const char *key __rte_unused,
70f7be70e5SJerin Jacob 		const char *value, void *extra_args)
71f7be70e5SJerin Jacob {
72f7be70e5SJerin Jacob 	int *i = (int *)extra_args;
73f7be70e5SJerin Jacob 
74f7be70e5SJerin Jacob 	*i = atoi(value);
75f7be70e5SJerin Jacob 	if (*i < 0) {
76f7be70e5SJerin Jacob 		octeontx_log_err("argument has to be positive.");
77f7be70e5SJerin Jacob 		return -1;
78f7be70e5SJerin Jacob 	}
79f7be70e5SJerin Jacob 
80f7be70e5SJerin Jacob 	return 0;
81f7be70e5SJerin Jacob }
82f7be70e5SJerin Jacob 
83f7be70e5SJerin Jacob static int
84f7be70e5SJerin Jacob octeontx_parse_vdev_init_params(struct octeontx_vdev_init_params *params,
85f7be70e5SJerin Jacob 				struct rte_vdev_device *dev)
86f7be70e5SJerin Jacob {
87f7be70e5SJerin Jacob 	struct rte_kvargs *kvlist = NULL;
88f7be70e5SJerin Jacob 	int ret = 0;
89f7be70e5SJerin Jacob 
90f7be70e5SJerin Jacob 	static const char * const octeontx_vdev_valid_params[] = {
91f7be70e5SJerin Jacob 		OCTEONTX_VDEV_NR_PORT_ARG,
92f7be70e5SJerin Jacob 		NULL
93f7be70e5SJerin Jacob 	};
94f7be70e5SJerin Jacob 
95f7be70e5SJerin Jacob 	const char *input_args = rte_vdev_device_args(dev);
96f7be70e5SJerin Jacob 	if (params == NULL)
97f7be70e5SJerin Jacob 		return -EINVAL;
98f7be70e5SJerin Jacob 
99f7be70e5SJerin Jacob 
100f7be70e5SJerin Jacob 	if (input_args) {
101f7be70e5SJerin Jacob 		kvlist = rte_kvargs_parse(input_args,
102f7be70e5SJerin Jacob 				octeontx_vdev_valid_params);
103f7be70e5SJerin Jacob 		if (kvlist == NULL)
104f7be70e5SJerin Jacob 			return -1;
105f7be70e5SJerin Jacob 
106f7be70e5SJerin Jacob 		ret = rte_kvargs_process(kvlist,
107f7be70e5SJerin Jacob 					OCTEONTX_VDEV_NR_PORT_ARG,
108f7be70e5SJerin Jacob 					&parse_integer_arg,
109f7be70e5SJerin Jacob 					&params->nr_port);
110f7be70e5SJerin Jacob 		if (ret < 0)
111f7be70e5SJerin Jacob 			goto free_kvlist;
112f7be70e5SJerin Jacob 	}
113f7be70e5SJerin Jacob 
114f7be70e5SJerin Jacob free_kvlist:
115f7be70e5SJerin Jacob 	rte_kvargs_free(kvlist);
116f7be70e5SJerin Jacob 	return ret;
117f7be70e5SJerin Jacob }
118f7be70e5SJerin Jacob 
119f18b146cSJerin Jacob static int
120f18b146cSJerin Jacob octeontx_port_open(struct octeontx_nic *nic)
121f18b146cSJerin Jacob {
122f18b146cSJerin Jacob 	octeontx_mbox_bgx_port_conf_t bgx_port_conf;
123f18b146cSJerin Jacob 	int res;
124f18b146cSJerin Jacob 
125f18b146cSJerin Jacob 	res = 0;
126f18b146cSJerin Jacob 
127f18b146cSJerin Jacob 	PMD_INIT_FUNC_TRACE();
128f18b146cSJerin Jacob 
129f18b146cSJerin Jacob 	res = octeontx_bgx_port_open(nic->port_id, &bgx_port_conf);
130f18b146cSJerin Jacob 	if (res < 0) {
131f18b146cSJerin Jacob 		octeontx_log_err("failed to open port %d", res);
132f18b146cSJerin Jacob 		return res;
133f18b146cSJerin Jacob 	}
134f18b146cSJerin Jacob 
135f18b146cSJerin Jacob 	nic->node = bgx_port_conf.node;
136f18b146cSJerin Jacob 	nic->port_ena = bgx_port_conf.enable;
137f18b146cSJerin Jacob 	nic->base_ichan = bgx_port_conf.base_chan;
138f18b146cSJerin Jacob 	nic->base_ochan = bgx_port_conf.base_chan;
139f18b146cSJerin Jacob 	nic->num_ichans = bgx_port_conf.num_chans;
140f18b146cSJerin Jacob 	nic->num_ochans = bgx_port_conf.num_chans;
141f18b146cSJerin Jacob 	nic->mtu = bgx_port_conf.mtu;
142f18b146cSJerin Jacob 	nic->bpen = bgx_port_conf.bpen;
143f18b146cSJerin Jacob 	nic->fcs_strip = bgx_port_conf.fcs_strip;
144f18b146cSJerin Jacob 	nic->bcast_mode = bgx_port_conf.bcast_mode;
145f18b146cSJerin Jacob 	nic->mcast_mode = bgx_port_conf.mcast_mode;
146f18b146cSJerin Jacob 	nic->speed	= bgx_port_conf.mode;
147f18b146cSJerin Jacob 
148f18b146cSJerin Jacob 	memcpy(&nic->mac_addr[0], &bgx_port_conf.macaddr[0], ETHER_ADDR_LEN);
149f18b146cSJerin Jacob 
150f18b146cSJerin Jacob 	octeontx_log_dbg("port opened %d", nic->port_id);
151f18b146cSJerin Jacob 	return res;
152f18b146cSJerin Jacob }
153f18b146cSJerin Jacob 
154f18b146cSJerin Jacob static void
155f18b146cSJerin Jacob octeontx_port_close(struct octeontx_nic *nic)
156f18b146cSJerin Jacob {
157f18b146cSJerin Jacob 	PMD_INIT_FUNC_TRACE();
158f18b146cSJerin Jacob 
159f18b146cSJerin Jacob 	octeontx_bgx_port_close(nic->port_id);
160f18b146cSJerin Jacob 	octeontx_log_dbg("port closed %d", nic->port_id);
161f18b146cSJerin Jacob }
162f18b146cSJerin Jacob 
163*15bce35bSJerin Jacob static void
164*15bce35bSJerin Jacob octeontx_port_promisc_set(struct octeontx_nic *nic, int en)
165*15bce35bSJerin Jacob {
166*15bce35bSJerin Jacob 	struct rte_eth_dev *dev;
167*15bce35bSJerin Jacob 	int res;
168*15bce35bSJerin Jacob 
169*15bce35bSJerin Jacob 	res = 0;
170*15bce35bSJerin Jacob 	PMD_INIT_FUNC_TRACE();
171*15bce35bSJerin Jacob 	dev = nic->dev;
172*15bce35bSJerin Jacob 
173*15bce35bSJerin Jacob 	res = octeontx_bgx_port_promisc_set(nic->port_id, en);
174*15bce35bSJerin Jacob 	if (res < 0)
175*15bce35bSJerin Jacob 		octeontx_log_err("failed to set promiscuous mode %d",
176*15bce35bSJerin Jacob 				nic->port_id);
177*15bce35bSJerin Jacob 
178*15bce35bSJerin Jacob 	/* Set proper flag for the mode */
179*15bce35bSJerin Jacob 	dev->data->promiscuous = (en != 0) ? 1 : 0;
180*15bce35bSJerin Jacob 
181*15bce35bSJerin Jacob 	octeontx_log_dbg("port %d : promiscuous mode %s",
182*15bce35bSJerin Jacob 			nic->port_id, en ? "set" : "unset");
183*15bce35bSJerin Jacob }
184*15bce35bSJerin Jacob 
185f7be70e5SJerin Jacob static inline void
186f7be70e5SJerin Jacob devconf_set_default_sane_values(struct rte_event_dev_config *dev_conf,
187f7be70e5SJerin Jacob 				struct rte_event_dev_info *info)
188f7be70e5SJerin Jacob {
189f7be70e5SJerin Jacob 	memset(dev_conf, 0, sizeof(struct rte_event_dev_config));
190f7be70e5SJerin Jacob 	dev_conf->dequeue_timeout_ns = info->min_dequeue_timeout_ns;
191f7be70e5SJerin Jacob 
192f7be70e5SJerin Jacob 	dev_conf->nb_event_ports = info->max_event_ports;
193f7be70e5SJerin Jacob 	dev_conf->nb_event_queues = info->max_event_queues;
194f7be70e5SJerin Jacob 
195f7be70e5SJerin Jacob 	dev_conf->nb_event_queue_flows = info->max_event_queue_flows;
196f7be70e5SJerin Jacob 	dev_conf->nb_event_port_dequeue_depth =
197f7be70e5SJerin Jacob 			info->max_event_port_dequeue_depth;
198f7be70e5SJerin Jacob 	dev_conf->nb_event_port_enqueue_depth =
199f7be70e5SJerin Jacob 			info->max_event_port_enqueue_depth;
200f7be70e5SJerin Jacob 	dev_conf->nb_event_port_enqueue_depth =
201f7be70e5SJerin Jacob 			info->max_event_port_enqueue_depth;
202f7be70e5SJerin Jacob 	dev_conf->nb_events_limit =
203f7be70e5SJerin Jacob 			info->max_num_events;
204f7be70e5SJerin Jacob }
205f7be70e5SJerin Jacob 
2067742c55aSJerin Jacob static int
2077742c55aSJerin Jacob octeontx_dev_configure(struct rte_eth_dev *dev)
2087742c55aSJerin Jacob {
2097742c55aSJerin Jacob 	struct rte_eth_dev_data *data = dev->data;
2107742c55aSJerin Jacob 	struct rte_eth_conf *conf = &data->dev_conf;
2117742c55aSJerin Jacob 	struct rte_eth_rxmode *rxmode = &conf->rxmode;
2127742c55aSJerin Jacob 	struct rte_eth_txmode *txmode = &conf->txmode;
2137742c55aSJerin Jacob 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
2147742c55aSJerin Jacob 	int ret;
2157742c55aSJerin Jacob 
2167742c55aSJerin Jacob 	PMD_INIT_FUNC_TRACE();
2177742c55aSJerin Jacob 	RTE_SET_USED(conf);
2187742c55aSJerin Jacob 
2197742c55aSJerin Jacob 	if (!rte_eal_has_hugepages()) {
2207742c55aSJerin Jacob 		octeontx_log_err("huge page is not configured");
2217742c55aSJerin Jacob 		return -EINVAL;
2227742c55aSJerin Jacob 	}
2237742c55aSJerin Jacob 
2247742c55aSJerin Jacob 	if (txmode->mq_mode) {
2257742c55aSJerin Jacob 		octeontx_log_err("tx mq_mode DCB or VMDq not supported");
2267742c55aSJerin Jacob 		return -EINVAL;
2277742c55aSJerin Jacob 	}
2287742c55aSJerin Jacob 
2297742c55aSJerin Jacob 	if (rxmode->mq_mode != ETH_MQ_RX_NONE &&
2307742c55aSJerin Jacob 		rxmode->mq_mode != ETH_MQ_RX_RSS) {
2317742c55aSJerin Jacob 		octeontx_log_err("unsupported rx qmode %d", rxmode->mq_mode);
2327742c55aSJerin Jacob 		return -EINVAL;
2337742c55aSJerin Jacob 	}
2347742c55aSJerin Jacob 
2357742c55aSJerin Jacob 	if (!rxmode->hw_strip_crc) {
2367742c55aSJerin Jacob 		PMD_INIT_LOG(NOTICE, "can't disable hw crc strip");
2377742c55aSJerin Jacob 		rxmode->hw_strip_crc = 1;
2387742c55aSJerin Jacob 	}
2397742c55aSJerin Jacob 
2407742c55aSJerin Jacob 	if (rxmode->hw_ip_checksum) {
2417742c55aSJerin Jacob 		PMD_INIT_LOG(NOTICE, "rxcksum not supported");
2427742c55aSJerin Jacob 		rxmode->hw_ip_checksum = 0;
2437742c55aSJerin Jacob 	}
2447742c55aSJerin Jacob 
2457742c55aSJerin Jacob 	if (rxmode->split_hdr_size) {
2467742c55aSJerin Jacob 		octeontx_log_err("rxmode does not support split header");
2477742c55aSJerin Jacob 		return -EINVAL;
2487742c55aSJerin Jacob 	}
2497742c55aSJerin Jacob 
2507742c55aSJerin Jacob 	if (rxmode->hw_vlan_filter) {
2517742c55aSJerin Jacob 		octeontx_log_err("VLAN filter not supported");
2527742c55aSJerin Jacob 		return -EINVAL;
2537742c55aSJerin Jacob 	}
2547742c55aSJerin Jacob 
2557742c55aSJerin Jacob 	if (rxmode->hw_vlan_extend) {
2567742c55aSJerin Jacob 		octeontx_log_err("VLAN extended not supported");
2577742c55aSJerin Jacob 		return -EINVAL;
2587742c55aSJerin Jacob 	}
2597742c55aSJerin Jacob 
2607742c55aSJerin Jacob 	if (rxmode->enable_lro) {
2617742c55aSJerin Jacob 		octeontx_log_err("LRO not supported");
2627742c55aSJerin Jacob 		return -EINVAL;
2637742c55aSJerin Jacob 	}
2647742c55aSJerin Jacob 
2657742c55aSJerin Jacob 	if (conf->link_speeds & ETH_LINK_SPEED_FIXED) {
2667742c55aSJerin Jacob 		octeontx_log_err("setting link speed/duplex not supported");
2677742c55aSJerin Jacob 		return -EINVAL;
2687742c55aSJerin Jacob 	}
2697742c55aSJerin Jacob 
2707742c55aSJerin Jacob 	if (conf->dcb_capability_en) {
2717742c55aSJerin Jacob 		octeontx_log_err("DCB enable not supported");
2727742c55aSJerin Jacob 		return -EINVAL;
2737742c55aSJerin Jacob 	}
2747742c55aSJerin Jacob 
2757742c55aSJerin Jacob 	if (conf->fdir_conf.mode != RTE_FDIR_MODE_NONE) {
2767742c55aSJerin Jacob 		octeontx_log_err("flow director not supported");
2777742c55aSJerin Jacob 		return -EINVAL;
2787742c55aSJerin Jacob 	}
2797742c55aSJerin Jacob 
2807742c55aSJerin Jacob 	nic->num_tx_queues = dev->data->nb_tx_queues;
2817742c55aSJerin Jacob 
2827742c55aSJerin Jacob 	ret = octeontx_pko_channel_open(nic->port_id * PKO_VF_NUM_DQ,
2837742c55aSJerin Jacob 					nic->num_tx_queues,
2847742c55aSJerin Jacob 					nic->base_ochan);
2857742c55aSJerin Jacob 	if (ret) {
2867742c55aSJerin Jacob 		octeontx_log_err("failed to open channel %d no-of-txq %d",
2877742c55aSJerin Jacob 			   nic->base_ochan, nic->num_tx_queues);
2887742c55aSJerin Jacob 		return -EFAULT;
2897742c55aSJerin Jacob 	}
2907742c55aSJerin Jacob 
2917742c55aSJerin Jacob 	nic->pki.classifier_enable = false;
2927742c55aSJerin Jacob 	nic->pki.hash_enable = true;
2937742c55aSJerin Jacob 	nic->pki.initialized = false;
2947742c55aSJerin Jacob 
2957742c55aSJerin Jacob 	return 0;
2967742c55aSJerin Jacob }
2977742c55aSJerin Jacob 
298*15bce35bSJerin Jacob static void
299*15bce35bSJerin Jacob octeontx_dev_promisc_enable(struct rte_eth_dev *dev)
300*15bce35bSJerin Jacob {
301*15bce35bSJerin Jacob 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
302*15bce35bSJerin Jacob 
303*15bce35bSJerin Jacob 	PMD_INIT_FUNC_TRACE();
304*15bce35bSJerin Jacob 	octeontx_port_promisc_set(nic, 1);
305*15bce35bSJerin Jacob }
306*15bce35bSJerin Jacob 
307*15bce35bSJerin Jacob static void
308*15bce35bSJerin Jacob octeontx_dev_promisc_disable(struct rte_eth_dev *dev)
309*15bce35bSJerin Jacob {
310*15bce35bSJerin Jacob 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
311*15bce35bSJerin Jacob 
312*15bce35bSJerin Jacob 	PMD_INIT_FUNC_TRACE();
313*15bce35bSJerin Jacob 	octeontx_port_promisc_set(nic, 0);
314*15bce35bSJerin Jacob }
315*15bce35bSJerin Jacob 
3164fac7c0aSJerin Jacob static inline int
3174fac7c0aSJerin Jacob octeontx_atomic_write_link_status(struct rte_eth_dev *dev,
3184fac7c0aSJerin Jacob 				  struct rte_eth_link *link)
3194fac7c0aSJerin Jacob {
3204fac7c0aSJerin Jacob 	struct rte_eth_link *dst = &dev->data->dev_link;
3214fac7c0aSJerin Jacob 	struct rte_eth_link *src = link;
3224fac7c0aSJerin Jacob 
3234fac7c0aSJerin Jacob 	if (rte_atomic64_cmpset((uint64_t *)dst, *(uint64_t *)dst,
3244fac7c0aSJerin Jacob 		*(uint64_t *)src) == 0)
3254fac7c0aSJerin Jacob 		return -1;
3264fac7c0aSJerin Jacob 
3274fac7c0aSJerin Jacob 	return 0;
3284fac7c0aSJerin Jacob }
3294fac7c0aSJerin Jacob 
3304fac7c0aSJerin Jacob static int
3314fac7c0aSJerin Jacob octeontx_port_link_status(struct octeontx_nic *nic)
3324fac7c0aSJerin Jacob {
3334fac7c0aSJerin Jacob 	int res;
3344fac7c0aSJerin Jacob 
3354fac7c0aSJerin Jacob 	PMD_INIT_FUNC_TRACE();
3364fac7c0aSJerin Jacob 	res = octeontx_bgx_port_link_status(nic->port_id);
3374fac7c0aSJerin Jacob 	if (res < 0) {
3384fac7c0aSJerin Jacob 		octeontx_log_err("failed to get port %d link status",
3394fac7c0aSJerin Jacob 				nic->port_id);
3404fac7c0aSJerin Jacob 		return res;
3414fac7c0aSJerin Jacob 	}
3424fac7c0aSJerin Jacob 
3434fac7c0aSJerin Jacob 	nic->link_up = (uint8_t)res;
3444fac7c0aSJerin Jacob 	octeontx_log_dbg("port %d link status %d", nic->port_id, nic->link_up);
3454fac7c0aSJerin Jacob 
3464fac7c0aSJerin Jacob 	return res;
3474fac7c0aSJerin Jacob }
3484fac7c0aSJerin Jacob 
3494fac7c0aSJerin Jacob /*
3504fac7c0aSJerin Jacob  * Return 0 means link status changed, -1 means not changed
3514fac7c0aSJerin Jacob  */
3524fac7c0aSJerin Jacob static int
3534fac7c0aSJerin Jacob octeontx_dev_link_update(struct rte_eth_dev *dev,
3544fac7c0aSJerin Jacob 			 int wait_to_complete __rte_unused)
3554fac7c0aSJerin Jacob {
3564fac7c0aSJerin Jacob 	struct octeontx_nic *nic = octeontx_pmd_priv(dev);
3574fac7c0aSJerin Jacob 	struct rte_eth_link link;
3584fac7c0aSJerin Jacob 	int res;
3594fac7c0aSJerin Jacob 
3604fac7c0aSJerin Jacob 	res = 0;
3614fac7c0aSJerin Jacob 	PMD_INIT_FUNC_TRACE();
3624fac7c0aSJerin Jacob 
3634fac7c0aSJerin Jacob 	res = octeontx_port_link_status(nic);
3644fac7c0aSJerin Jacob 	if (res < 0) {
3654fac7c0aSJerin Jacob 		octeontx_log_err("failed to request link status %d", res);
3664fac7c0aSJerin Jacob 		return res;
3674fac7c0aSJerin Jacob 	}
3684fac7c0aSJerin Jacob 
3694fac7c0aSJerin Jacob 	link.link_status = nic->link_up;
3704fac7c0aSJerin Jacob 
3714fac7c0aSJerin Jacob 	switch (nic->speed) {
3724fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_SGMII:
3734fac7c0aSJerin Jacob 		link.link_speed = ETH_SPEED_NUM_1G;
3744fac7c0aSJerin Jacob 		break;
3754fac7c0aSJerin Jacob 
3764fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_XAUI:
3774fac7c0aSJerin Jacob 		link.link_speed = ETH_SPEED_NUM_10G;
3784fac7c0aSJerin Jacob 		break;
3794fac7c0aSJerin Jacob 
3804fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_RXAUI:
3814fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_10G_R:
3824fac7c0aSJerin Jacob 		link.link_speed = ETH_SPEED_NUM_10G;
3834fac7c0aSJerin Jacob 		break;
3844fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_QSGMII:
3854fac7c0aSJerin Jacob 		link.link_speed = ETH_SPEED_NUM_5G;
3864fac7c0aSJerin Jacob 		break;
3874fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_40G_R:
3884fac7c0aSJerin Jacob 		link.link_speed = ETH_SPEED_NUM_40G;
3894fac7c0aSJerin Jacob 		break;
3904fac7c0aSJerin Jacob 
3914fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_RESERVE1:
3924fac7c0aSJerin Jacob 	case OCTEONTX_LINK_SPEED_RESERVE2:
3934fac7c0aSJerin Jacob 	default:
3944fac7c0aSJerin Jacob 		octeontx_log_err("incorrect link speed %d", nic->speed);
3954fac7c0aSJerin Jacob 		break;
3964fac7c0aSJerin Jacob 	}
3974fac7c0aSJerin Jacob 
3984fac7c0aSJerin Jacob 	link.link_duplex = ETH_LINK_AUTONEG;
3994fac7c0aSJerin Jacob 	link.link_autoneg = ETH_LINK_SPEED_AUTONEG;
4004fac7c0aSJerin Jacob 
4014fac7c0aSJerin Jacob 	return octeontx_atomic_write_link_status(dev, &link);
4024fac7c0aSJerin Jacob }
4034fac7c0aSJerin Jacob 
4047c0347a2SJerin Jacob static void
4057c0347a2SJerin Jacob octeontx_dev_info(struct rte_eth_dev *dev,
4067c0347a2SJerin Jacob 		struct rte_eth_dev_info *dev_info)
4077c0347a2SJerin Jacob {
4087c0347a2SJerin Jacob 	RTE_SET_USED(dev);
4097c0347a2SJerin Jacob 
4107c0347a2SJerin Jacob 	/* Autonegotiation may be disabled */
4117c0347a2SJerin Jacob 	dev_info->speed_capa = ETH_LINK_SPEED_FIXED;
4127c0347a2SJerin Jacob 	dev_info->speed_capa |= ETH_LINK_SPEED_10M | ETH_LINK_SPEED_100M |
4137c0347a2SJerin Jacob 			ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
4147c0347a2SJerin Jacob 			ETH_LINK_SPEED_40G;
4157c0347a2SJerin Jacob 
4167c0347a2SJerin Jacob 	dev_info->driver_name = RTE_STR(rte_octeontx_pmd);
4177c0347a2SJerin Jacob 	dev_info->max_mac_addrs = 1;
4187c0347a2SJerin Jacob 	dev_info->max_rx_pktlen = PKI_MAX_PKTLEN;
4197c0347a2SJerin Jacob 	dev_info->max_rx_queues = 1;
4207c0347a2SJerin Jacob 	dev_info->max_tx_queues = PKO_MAX_NUM_DQ;
4217c0347a2SJerin Jacob 	dev_info->min_rx_bufsize = 0;
4227c0347a2SJerin Jacob 	dev_info->pci_dev = NULL;
4237c0347a2SJerin Jacob 
4247c0347a2SJerin Jacob 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
4257c0347a2SJerin Jacob 		.rx_free_thresh = 0,
4267c0347a2SJerin Jacob 		.rx_drop_en = 0,
4277c0347a2SJerin Jacob 	};
4287c0347a2SJerin Jacob 
4297c0347a2SJerin Jacob 	dev_info->default_txconf = (struct rte_eth_txconf) {
4307c0347a2SJerin Jacob 		.tx_free_thresh = 0,
4317c0347a2SJerin Jacob 		.txq_flags =
4327c0347a2SJerin Jacob 			ETH_TXQ_FLAGS_NOMULTSEGS |
4337c0347a2SJerin Jacob 			ETH_TXQ_FLAGS_NOOFFLOADS |
4347c0347a2SJerin Jacob 			ETH_TXQ_FLAGS_NOXSUMS,
4357c0347a2SJerin Jacob 	};
4367c0347a2SJerin Jacob 
4377c0347a2SJerin Jacob 	dev_info->tx_offload_capa = DEV_TX_OFFLOAD_MT_LOCKFREE;
4387c0347a2SJerin Jacob }
4397c0347a2SJerin Jacob 
440f18b146cSJerin Jacob /* Initialize and register driver with DPDK Application */
441f18b146cSJerin Jacob static const struct eth_dev_ops octeontx_dev_ops = {
4427742c55aSJerin Jacob 	.dev_configure		 = octeontx_dev_configure,
4437c0347a2SJerin Jacob 	.dev_infos_get		 = octeontx_dev_info,
444*15bce35bSJerin Jacob 	.promiscuous_enable	 = octeontx_dev_promisc_enable,
445*15bce35bSJerin Jacob 	.promiscuous_disable	 = octeontx_dev_promisc_disable,
4464fac7c0aSJerin Jacob 	.link_update		 = octeontx_dev_link_update,
447f18b146cSJerin Jacob };
448f18b146cSJerin Jacob 
449f7be70e5SJerin Jacob /* Create Ethdev interface per BGX LMAC ports */
450f7be70e5SJerin Jacob static int
451f7be70e5SJerin Jacob octeontx_create(struct rte_vdev_device *dev, int port, uint8_t evdev,
452f7be70e5SJerin Jacob 			int socket_id)
453f7be70e5SJerin Jacob {
454f18b146cSJerin Jacob 	int res;
455f18b146cSJerin Jacob 	char octtx_name[OCTEONTX_MAX_NAME_LEN];
456f18b146cSJerin Jacob 	struct octeontx_nic *nic = NULL;
457f18b146cSJerin Jacob 	struct rte_eth_dev *eth_dev = NULL;
458f18b146cSJerin Jacob 	struct rte_eth_dev_data *data = NULL;
459f18b146cSJerin Jacob 	const char *name = rte_vdev_device_name(dev);
460f7be70e5SJerin Jacob 
461f18b146cSJerin Jacob 	PMD_INIT_FUNC_TRACE();
462f18b146cSJerin Jacob 
463f18b146cSJerin Jacob 	sprintf(octtx_name, "%s_%d", name, port);
464f18b146cSJerin Jacob 	if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
465f18b146cSJerin Jacob 		eth_dev = rte_eth_dev_attach_secondary(octtx_name);
466f18b146cSJerin Jacob 		if (eth_dev == NULL)
467f7be70e5SJerin Jacob 			return -ENODEV;
468f18b146cSJerin Jacob 
469f18b146cSJerin Jacob 		return 0;
470f18b146cSJerin Jacob 	}
471f18b146cSJerin Jacob 
472f18b146cSJerin Jacob 	data = rte_zmalloc_socket(octtx_name, sizeof(*data), 0, socket_id);
473f18b146cSJerin Jacob 	if (data == NULL) {
474f18b146cSJerin Jacob 		octeontx_log_err("failed to allocate devdata");
475f18b146cSJerin Jacob 		res = -ENOMEM;
476f18b146cSJerin Jacob 		goto err;
477f18b146cSJerin Jacob 	}
478f18b146cSJerin Jacob 
479f18b146cSJerin Jacob 	nic = rte_zmalloc_socket(octtx_name, sizeof(*nic), 0, socket_id);
480f18b146cSJerin Jacob 	if (nic == NULL) {
481f18b146cSJerin Jacob 		octeontx_log_err("failed to allocate nic structure");
482f18b146cSJerin Jacob 		res = -ENOMEM;
483f18b146cSJerin Jacob 		goto err;
484f18b146cSJerin Jacob 	}
485f18b146cSJerin Jacob 
486f18b146cSJerin Jacob 	nic->port_id = port;
487f18b146cSJerin Jacob 	nic->evdev = evdev;
488f18b146cSJerin Jacob 
489f18b146cSJerin Jacob 	res = octeontx_port_open(nic);
490f18b146cSJerin Jacob 	if (res < 0)
491f18b146cSJerin Jacob 		goto err;
492f18b146cSJerin Jacob 
493f18b146cSJerin Jacob 	/* Rx side port configuration */
494f18b146cSJerin Jacob 	res = octeontx_pki_port_open(port);
495f18b146cSJerin Jacob 	if (res != 0) {
496f18b146cSJerin Jacob 		octeontx_log_err("failed to open PKI port %d", port);
497f18b146cSJerin Jacob 		res = -ENODEV;
498f18b146cSJerin Jacob 		goto err;
499f18b146cSJerin Jacob 	}
500f18b146cSJerin Jacob 
501f18b146cSJerin Jacob 	/* Reserve an ethdev entry */
502f18b146cSJerin Jacob 	eth_dev = rte_eth_dev_allocate(octtx_name);
503f18b146cSJerin Jacob 	if (eth_dev == NULL) {
504f18b146cSJerin Jacob 		octeontx_log_err("failed to allocate rte_eth_dev");
505f18b146cSJerin Jacob 		res = -ENOMEM;
506f18b146cSJerin Jacob 		goto err;
507f18b146cSJerin Jacob 	}
508f18b146cSJerin Jacob 
509f18b146cSJerin Jacob 	eth_dev->device = &dev->device;
510f18b146cSJerin Jacob 	eth_dev->intr_handle = NULL;
511f18b146cSJerin Jacob 	eth_dev->data->kdrv = RTE_KDRV_NONE;
512f18b146cSJerin Jacob 	eth_dev->data->numa_node = dev->device.numa_node;
513f18b146cSJerin Jacob 
514f18b146cSJerin Jacob 	rte_memcpy(data, (eth_dev)->data, sizeof(*data));
515f18b146cSJerin Jacob 	data->dev_private = nic;
516f18b146cSJerin Jacob 
517f18b146cSJerin Jacob 	data->port_id = eth_dev->data->port_id;
518f18b146cSJerin Jacob 	snprintf(data->name, sizeof(data->name), "%s", eth_dev->data->name);
519f18b146cSJerin Jacob 
520f18b146cSJerin Jacob 	nic->ev_queues = 1;
521f18b146cSJerin Jacob 	nic->ev_ports = 1;
522f18b146cSJerin Jacob 
523f18b146cSJerin Jacob 	data->dev_link.link_status = ETH_LINK_DOWN;
524f18b146cSJerin Jacob 	data->dev_started = 0;
525f18b146cSJerin Jacob 	data->promiscuous = 0;
526f18b146cSJerin Jacob 	data->all_multicast = 0;
527f18b146cSJerin Jacob 	data->scattered_rx = 0;
528f18b146cSJerin Jacob 
529f18b146cSJerin Jacob 	data->mac_addrs = rte_zmalloc_socket(octtx_name, ETHER_ADDR_LEN, 0,
530f18b146cSJerin Jacob 							socket_id);
531f18b146cSJerin Jacob 	if (data->mac_addrs == NULL) {
532f18b146cSJerin Jacob 		octeontx_log_err("failed to allocate memory for mac_addrs");
533f18b146cSJerin Jacob 		res = -ENOMEM;
534f18b146cSJerin Jacob 		goto err;
535f18b146cSJerin Jacob 	}
536f18b146cSJerin Jacob 
537f18b146cSJerin Jacob 	eth_dev->data = data;
538f18b146cSJerin Jacob 	eth_dev->dev_ops = &octeontx_dev_ops;
539f18b146cSJerin Jacob 
540f18b146cSJerin Jacob 	/* Finally save ethdev pointer to the NIC structure */
541f18b146cSJerin Jacob 	nic->dev = eth_dev;
542f18b146cSJerin Jacob 
543f18b146cSJerin Jacob 	if (nic->port_id != data->port_id) {
544f18b146cSJerin Jacob 		octeontx_log_err("eth_dev->port_id (%d) is diff to orig (%d)",
545f18b146cSJerin Jacob 				data->port_id, nic->port_id);
546f18b146cSJerin Jacob 		res = -EINVAL;
547f18b146cSJerin Jacob 		goto err;
548f18b146cSJerin Jacob 	}
549f18b146cSJerin Jacob 
550f18b146cSJerin Jacob 	/* Update port_id mac to eth_dev */
551f18b146cSJerin Jacob 	memcpy(data->mac_addrs, nic->mac_addr, ETHER_ADDR_LEN);
552f18b146cSJerin Jacob 
553f18b146cSJerin Jacob 	PMD_INIT_LOG(DEBUG, "ethdev info: ");
554f18b146cSJerin Jacob 	PMD_INIT_LOG(DEBUG, "port %d, port_ena %d ochan %d num_ochan %d tx_q %d",
555f18b146cSJerin Jacob 				nic->port_id, nic->port_ena,
556f18b146cSJerin Jacob 				nic->base_ochan, nic->num_ochans,
557f18b146cSJerin Jacob 				nic->num_tx_queues);
558f18b146cSJerin Jacob 	PMD_INIT_LOG(DEBUG, "speed %d mtu %d", nic->speed, nic->mtu);
559f18b146cSJerin Jacob 
560f18b146cSJerin Jacob 	return data->port_id;
561f18b146cSJerin Jacob 
562f18b146cSJerin Jacob err:
563f18b146cSJerin Jacob 	if (port)
564f18b146cSJerin Jacob 		octeontx_port_close(nic);
565f18b146cSJerin Jacob 
566f18b146cSJerin Jacob 	if (eth_dev != NULL) {
567f18b146cSJerin Jacob 		rte_free(eth_dev->data->mac_addrs);
568f18b146cSJerin Jacob 		rte_free(data);
569f18b146cSJerin Jacob 		rte_free(nic);
570f18b146cSJerin Jacob 		rte_eth_dev_release_port(eth_dev);
571f18b146cSJerin Jacob 	}
572f18b146cSJerin Jacob 
573f18b146cSJerin Jacob 	return res;
574f7be70e5SJerin Jacob }
575f7be70e5SJerin Jacob 
576f7be70e5SJerin Jacob /* Un initialize octeontx device */
577f7be70e5SJerin Jacob static int
578f7be70e5SJerin Jacob octeontx_remove(struct rte_vdev_device *dev)
579f7be70e5SJerin Jacob {
580f7be70e5SJerin Jacob 	char octtx_name[OCTEONTX_MAX_NAME_LEN];
581f7be70e5SJerin Jacob 	struct rte_eth_dev *eth_dev = NULL;
582f7be70e5SJerin Jacob 	struct octeontx_nic *nic = NULL;
583f7be70e5SJerin Jacob 	int i;
584f7be70e5SJerin Jacob 
585f7be70e5SJerin Jacob 	if (dev == NULL)
586f7be70e5SJerin Jacob 		return -EINVAL;
587f7be70e5SJerin Jacob 
588f7be70e5SJerin Jacob 	for (i = 0; i < OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT; i++) {
589f7be70e5SJerin Jacob 		sprintf(octtx_name, "eth_octeontx_%d", i);
590f7be70e5SJerin Jacob 
591f7be70e5SJerin Jacob 		/* reserve an ethdev entry */
592f7be70e5SJerin Jacob 		eth_dev = rte_eth_dev_allocated(octtx_name);
593f7be70e5SJerin Jacob 		if (eth_dev == NULL)
594f7be70e5SJerin Jacob 			return -ENODEV;
595f7be70e5SJerin Jacob 
596f7be70e5SJerin Jacob 		nic = octeontx_pmd_priv(eth_dev);
597f7be70e5SJerin Jacob 		rte_event_dev_stop(nic->evdev);
598f7be70e5SJerin Jacob 		PMD_INIT_LOG(INFO, "Closing octeontx device %s", octtx_name);
599f7be70e5SJerin Jacob 
600f7be70e5SJerin Jacob 		rte_free(eth_dev->data->mac_addrs);
601f7be70e5SJerin Jacob 		rte_free(eth_dev->data->dev_private);
602f7be70e5SJerin Jacob 		rte_free(eth_dev->data);
603f7be70e5SJerin Jacob 		rte_eth_dev_release_port(eth_dev);
604f7be70e5SJerin Jacob 		rte_event_dev_close(nic->evdev);
605f7be70e5SJerin Jacob 	}
606f7be70e5SJerin Jacob 
607f7be70e5SJerin Jacob 	/* Free FC resource */
608f7be70e5SJerin Jacob 	octeontx_pko_fc_free();
609f7be70e5SJerin Jacob 
610f7be70e5SJerin Jacob 	return 0;
611f7be70e5SJerin Jacob }
612f7be70e5SJerin Jacob 
613f7be70e5SJerin Jacob /* Initialize octeontx device */
614f7be70e5SJerin Jacob static int
615f7be70e5SJerin Jacob octeontx_probe(struct rte_vdev_device *dev)
616f7be70e5SJerin Jacob {
617f7be70e5SJerin Jacob 	const char *dev_name;
618f7be70e5SJerin Jacob 	static int probe_once;
619f7be70e5SJerin Jacob 	uint8_t socket_id, qlist;
620f7be70e5SJerin Jacob 	int tx_vfcnt, port_id, evdev, qnum, pnum, res, i;
621f7be70e5SJerin Jacob 	struct rte_event_dev_config dev_conf;
622f7be70e5SJerin Jacob 	const char *eventdev_name = "event_octeontx";
623f7be70e5SJerin Jacob 	struct rte_event_dev_info info;
624f7be70e5SJerin Jacob 
625f7be70e5SJerin Jacob 	struct octeontx_vdev_init_params init_params = {
626f7be70e5SJerin Jacob 		OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT
627f7be70e5SJerin Jacob 	};
628f7be70e5SJerin Jacob 
629f7be70e5SJerin Jacob 	dev_name = rte_vdev_device_name(dev);
630f7be70e5SJerin Jacob 	res = octeontx_parse_vdev_init_params(&init_params, dev);
631f7be70e5SJerin Jacob 	if (res < 0)
632f7be70e5SJerin Jacob 		return -EINVAL;
633f7be70e5SJerin Jacob 
634f7be70e5SJerin Jacob 	if (init_params.nr_port > OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT) {
635f7be70e5SJerin Jacob 		octeontx_log_err("nr_port (%d) > max (%d)", init_params.nr_port,
636f7be70e5SJerin Jacob 				OCTEONTX_VDEV_DEFAULT_MAX_NR_PORT);
637f7be70e5SJerin Jacob 		return -ENOTSUP;
638f7be70e5SJerin Jacob 	}
639f7be70e5SJerin Jacob 
640f7be70e5SJerin Jacob 	PMD_INIT_LOG(DEBUG, "initializing %s pmd", dev_name);
641f7be70e5SJerin Jacob 
642f7be70e5SJerin Jacob 	socket_id = rte_socket_id();
643f7be70e5SJerin Jacob 
644f7be70e5SJerin Jacob 	tx_vfcnt = octeontx_pko_vf_count();
645f7be70e5SJerin Jacob 
646f7be70e5SJerin Jacob 	if (tx_vfcnt < init_params.nr_port) {
647f7be70e5SJerin Jacob 		octeontx_log_err("not enough PKO (%d) for port number (%d)",
648f7be70e5SJerin Jacob 				tx_vfcnt, init_params.nr_port);
649f7be70e5SJerin Jacob 		return -EINVAL;
650f7be70e5SJerin Jacob 	}
651f7be70e5SJerin Jacob 	evdev = rte_event_dev_get_dev_id(eventdev_name);
652f7be70e5SJerin Jacob 	if (evdev < 0) {
653f7be70e5SJerin Jacob 		octeontx_log_err("eventdev %s not found", eventdev_name);
654f7be70e5SJerin Jacob 		return -ENODEV;
655f7be70e5SJerin Jacob 	}
656f7be70e5SJerin Jacob 
657f7be70e5SJerin Jacob 	res = rte_event_dev_info_get(evdev, &info);
658f7be70e5SJerin Jacob 	if (res < 0) {
659f7be70e5SJerin Jacob 		octeontx_log_err("failed to eventdev info %d", res);
660f7be70e5SJerin Jacob 		return -EINVAL;
661f7be70e5SJerin Jacob 	}
662f7be70e5SJerin Jacob 
663f7be70e5SJerin Jacob 	PMD_INIT_LOG(DEBUG, "max_queue %d max_port %d",
664f7be70e5SJerin Jacob 			info.max_event_queues, info.max_event_ports);
665f7be70e5SJerin Jacob 
666f7be70e5SJerin Jacob 	if (octeontx_pko_init_fc(tx_vfcnt))
667f7be70e5SJerin Jacob 		return -ENOMEM;
668f7be70e5SJerin Jacob 
669f7be70e5SJerin Jacob 	devconf_set_default_sane_values(&dev_conf, &info);
670f7be70e5SJerin Jacob 	res = rte_event_dev_configure(evdev, &dev_conf);
671f7be70e5SJerin Jacob 	if (res < 0)
672f7be70e5SJerin Jacob 		goto parse_error;
673f7be70e5SJerin Jacob 
674f7be70e5SJerin Jacob 	rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_PORT_COUNT,
675f7be70e5SJerin Jacob 			(uint32_t *)&pnum);
676f7be70e5SJerin Jacob 	rte_event_dev_attr_get(evdev, RTE_EVENT_DEV_ATTR_QUEUE_COUNT,
677f7be70e5SJerin Jacob 			(uint32_t *)&qnum);
678f7be70e5SJerin Jacob 	if (pnum < qnum) {
679f7be70e5SJerin Jacob 		octeontx_log_err("too few event ports (%d) for event_q(%d)",
680f7be70e5SJerin Jacob 				pnum, qnum);
681f7be70e5SJerin Jacob 		res = -EINVAL;
682f7be70e5SJerin Jacob 		goto parse_error;
683f7be70e5SJerin Jacob 	}
684f7be70e5SJerin Jacob 	if (pnum > qnum) {
685f7be70e5SJerin Jacob 		/*
686f7be70e5SJerin Jacob 		 * We don't poll on event ports
687f7be70e5SJerin Jacob 		 * that do not have any queues assigned.
688f7be70e5SJerin Jacob 		 */
689f7be70e5SJerin Jacob 		pnum = qnum;
690f7be70e5SJerin Jacob 		PMD_INIT_LOG(INFO,
691f7be70e5SJerin Jacob 			"reducing number of active event ports to %d", pnum);
692f7be70e5SJerin Jacob 	}
693f7be70e5SJerin Jacob 	for (i = 0; i < qnum; i++) {
694f7be70e5SJerin Jacob 		res = rte_event_queue_setup(evdev, i, NULL);
695f7be70e5SJerin Jacob 		if (res < 0) {
696f7be70e5SJerin Jacob 			octeontx_log_err("failed to setup event_q(%d): res %d",
697f7be70e5SJerin Jacob 					i, res);
698f7be70e5SJerin Jacob 			goto parse_error;
699f7be70e5SJerin Jacob 		}
700f7be70e5SJerin Jacob 	}
701f7be70e5SJerin Jacob 
702f7be70e5SJerin Jacob 	for (i = 0; i < pnum; i++) {
703f7be70e5SJerin Jacob 		res = rte_event_port_setup(evdev, i, NULL);
704f7be70e5SJerin Jacob 		if (res < 0) {
705f7be70e5SJerin Jacob 			res = -ENODEV;
706f7be70e5SJerin Jacob 			octeontx_log_err("failed to setup ev port(%d) res=%d",
707f7be70e5SJerin Jacob 						i, res);
708f7be70e5SJerin Jacob 			goto parse_error;
709f7be70e5SJerin Jacob 		}
710f7be70e5SJerin Jacob 		/* Link one queue to one event port */
711f7be70e5SJerin Jacob 		qlist = i;
712f7be70e5SJerin Jacob 		res = rte_event_port_link(evdev, i, &qlist, NULL, 1);
713f7be70e5SJerin Jacob 		if (res < 0) {
714f7be70e5SJerin Jacob 			res = -ENODEV;
715f7be70e5SJerin Jacob 			octeontx_log_err("failed to link port (%d): res=%d",
716f7be70e5SJerin Jacob 					i, res);
717f7be70e5SJerin Jacob 			goto parse_error;
718f7be70e5SJerin Jacob 		}
719f7be70e5SJerin Jacob 	}
720f7be70e5SJerin Jacob 
721f7be70e5SJerin Jacob 	/* Create ethdev interface */
722f7be70e5SJerin Jacob 	for (i = 0; i < init_params.nr_port; i++) {
723f7be70e5SJerin Jacob 		port_id = octeontx_create(dev, i, evdev, socket_id);
724f7be70e5SJerin Jacob 		if (port_id < 0) {
725f7be70e5SJerin Jacob 			octeontx_log_err("failed to create device %s",
726f7be70e5SJerin Jacob 					dev_name);
727f7be70e5SJerin Jacob 			res = -ENODEV;
728f7be70e5SJerin Jacob 			goto parse_error;
729f7be70e5SJerin Jacob 		}
730f7be70e5SJerin Jacob 
731f7be70e5SJerin Jacob 		PMD_INIT_LOG(INFO, "created ethdev %s for port %d", dev_name,
732f7be70e5SJerin Jacob 					port_id);
733f7be70e5SJerin Jacob 	}
734f7be70e5SJerin Jacob 
735f7be70e5SJerin Jacob 	if (probe_once) {
736f7be70e5SJerin Jacob 		octeontx_log_err("interface %s not supported", dev_name);
737f7be70e5SJerin Jacob 		octeontx_remove(dev);
738f7be70e5SJerin Jacob 		res = -ENOTSUP;
739f7be70e5SJerin Jacob 		goto parse_error;
740f7be70e5SJerin Jacob 	}
741f7be70e5SJerin Jacob 	probe_once = 1;
742f7be70e5SJerin Jacob 
743f7be70e5SJerin Jacob 	return 0;
744f7be70e5SJerin Jacob 
745f7be70e5SJerin Jacob parse_error:
746f7be70e5SJerin Jacob 	octeontx_pko_fc_free();
747f7be70e5SJerin Jacob 	return res;
748f7be70e5SJerin Jacob }
749f7be70e5SJerin Jacob 
750f7be70e5SJerin Jacob static struct rte_vdev_driver octeontx_pmd_drv = {
751f7be70e5SJerin Jacob 	.probe = octeontx_probe,
752f7be70e5SJerin Jacob 	.remove = octeontx_remove,
753f7be70e5SJerin Jacob };
754f7be70e5SJerin Jacob 
755f7be70e5SJerin Jacob RTE_PMD_REGISTER_VDEV(OCTEONTX_PMD, octeontx_pmd_drv);
756f7be70e5SJerin Jacob RTE_PMD_REGISTER_ALIAS(OCTEONTX_PMD, eth_octeontx);
757f7be70e5SJerin Jacob RTE_PMD_REGISTER_PARAM_STRING(OCTEONTX_PMD, "nr_port=<int> ");
758