xref: /dpdk/examples/l2fwd-event/main.c (revision 4ed890495594a71e618d62fd975c5868915eb4a1)
14ff45798SPavan Nikhilesh /* SPDX-License-Identifier: BSD-3-Clause
24ff45798SPavan Nikhilesh  * Copyright(C) 2019 Marvell International Ltd.
34ff45798SPavan Nikhilesh  */
44ff45798SPavan Nikhilesh 
5092454d9SPavan Nikhilesh #include <rte_string_fns.h>
6092454d9SPavan Nikhilesh 
71b2143aaSPavan Nikhilesh #include "l2fwd_event.h"
84ff45798SPavan Nikhilesh #include "l2fwd_poll.h"
94ff45798SPavan Nikhilesh 
104ff45798SPavan Nikhilesh /* display usage */
114ff45798SPavan Nikhilesh static void
l2fwd_event_usage(const char * prgname)124ff45798SPavan Nikhilesh l2fwd_event_usage(const char *prgname)
134ff45798SPavan Nikhilesh {
144ff45798SPavan Nikhilesh 	printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n"
154ff45798SPavan Nikhilesh 	       "  -p PORTMASK: hexadecimal bitmask of ports to configure\n"
164ff45798SPavan Nikhilesh 	       "  -q NQ: number of queue (=ports) per lcore (default is 1)\n"
174ff45798SPavan Nikhilesh 	       "  -T PERIOD: statistics will be refreshed each PERIOD seconds "
184ff45798SPavan Nikhilesh 	       "		(0 to disable, 10 default, 86400 maximum)\n"
194ff45798SPavan Nikhilesh 	       "  --[no-]mac-updating: Enable or disable MAC addresses updating (enabled by default)\n"
204ff45798SPavan Nikhilesh 	       "      When enabled:\n"
214ff45798SPavan Nikhilesh 	       "       - The source MAC address is replaced by the TX port MAC address\n"
221b2143aaSPavan Nikhilesh 	       "       - The destination MAC address is replaced by 02:00:00:00:00:TX_PORT_ID\n"
231b2143aaSPavan Nikhilesh 	       "  --mode: Packet transfer mode for I/O, poll or eventdev\n"
241b2143aaSPavan Nikhilesh 	       "          Default mode = eventdev\n"
251b2143aaSPavan Nikhilesh 	       "  --eventq-sched: Event queue schedule type, ordered, atomic or parallel.\n"
261b2143aaSPavan Nikhilesh 	       "                  Default: atomic\n"
27092454d9SPavan Nikhilesh 	       "                  Valid only if --mode=eventdev\n"
28796b07e9SShijith Thotton 	       "  --event-vector:  Enable event vectorization.\n"
29796b07e9SShijith Thotton 	       "  --event-vector-size: Max vector size if event vectorization is enabled.\n"
30796b07e9SShijith Thotton 	       "  --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\n"
31092454d9SPavan Nikhilesh 	       "  --config: Configure forwarding port pair mapping\n"
32092454d9SPavan Nikhilesh 	       "	    Default: alternate port pairs\n\n",
334ff45798SPavan Nikhilesh 	       prgname);
344ff45798SPavan Nikhilesh }
354ff45798SPavan Nikhilesh 
364ff45798SPavan Nikhilesh static int
l2fwd_event_parse_portmask(const char * portmask)374ff45798SPavan Nikhilesh l2fwd_event_parse_portmask(const char *portmask)
384ff45798SPavan Nikhilesh {
394ff45798SPavan Nikhilesh 	char *end = NULL;
404ff45798SPavan Nikhilesh 	unsigned long pm;
414ff45798SPavan Nikhilesh 
424ff45798SPavan Nikhilesh 	/* parse hexadecimal string */
434ff45798SPavan Nikhilesh 	pm = strtoul(portmask, &end, 16);
444ff45798SPavan Nikhilesh 	if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
45ce6b8c31SSarosh Arif 		return 0;
464ff45798SPavan Nikhilesh 
474ff45798SPavan Nikhilesh 	return pm;
484ff45798SPavan Nikhilesh }
494ff45798SPavan Nikhilesh 
504ff45798SPavan Nikhilesh static unsigned int
l2fwd_event_parse_nqueue(const char * q_arg)514ff45798SPavan Nikhilesh l2fwd_event_parse_nqueue(const char *q_arg)
524ff45798SPavan Nikhilesh {
534ff45798SPavan Nikhilesh 	char *end = NULL;
544ff45798SPavan Nikhilesh 	unsigned long n;
554ff45798SPavan Nikhilesh 
564ff45798SPavan Nikhilesh 	/* parse hexadecimal string */
574ff45798SPavan Nikhilesh 	n = strtoul(q_arg, &end, 10);
584ff45798SPavan Nikhilesh 	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
594ff45798SPavan Nikhilesh 		return 0;
604ff45798SPavan Nikhilesh 	if (n == 0)
614ff45798SPavan Nikhilesh 		return 0;
624ff45798SPavan Nikhilesh 	if (n >= MAX_RX_QUEUE_PER_LCORE)
634ff45798SPavan Nikhilesh 		return 0;
644ff45798SPavan Nikhilesh 
654ff45798SPavan Nikhilesh 	return n;
664ff45798SPavan Nikhilesh }
674ff45798SPavan Nikhilesh 
684ff45798SPavan Nikhilesh static int
l2fwd_event_parse_timer_period(const char * q_arg)694ff45798SPavan Nikhilesh l2fwd_event_parse_timer_period(const char *q_arg)
704ff45798SPavan Nikhilesh {
714ff45798SPavan Nikhilesh 	char *end = NULL;
724ff45798SPavan Nikhilesh 	int n;
734ff45798SPavan Nikhilesh 
744ff45798SPavan Nikhilesh 	/* parse number string */
754ff45798SPavan Nikhilesh 	n = strtol(q_arg, &end, 10);
764ff45798SPavan Nikhilesh 	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0'))
774ff45798SPavan Nikhilesh 		return -1;
784ff45798SPavan Nikhilesh 	if (n >= MAX_TIMER_PERIOD)
794ff45798SPavan Nikhilesh 		return -1;
804ff45798SPavan Nikhilesh 
814ff45798SPavan Nikhilesh 	return n;
824ff45798SPavan Nikhilesh }
834ff45798SPavan Nikhilesh 
841b2143aaSPavan Nikhilesh static void
l2fwd_event_parse_mode(const char * optarg,struct l2fwd_resources * rsrc)851b2143aaSPavan Nikhilesh l2fwd_event_parse_mode(const char *optarg,
861b2143aaSPavan Nikhilesh 		       struct l2fwd_resources *rsrc)
871b2143aaSPavan Nikhilesh {
881b2143aaSPavan Nikhilesh 	if (!strncmp(optarg, "poll", 4))
891b2143aaSPavan Nikhilesh 		rsrc->event_mode = false;
901b2143aaSPavan Nikhilesh 	else if (!strncmp(optarg, "eventdev", 8))
911b2143aaSPavan Nikhilesh 		rsrc->event_mode = true;
921b2143aaSPavan Nikhilesh }
931b2143aaSPavan Nikhilesh 
941b2143aaSPavan Nikhilesh static void
l2fwd_event_parse_eventq_sched(const char * optarg,struct l2fwd_resources * rsrc)951b2143aaSPavan Nikhilesh l2fwd_event_parse_eventq_sched(const char *optarg,
961b2143aaSPavan Nikhilesh 			       struct l2fwd_resources *rsrc)
971b2143aaSPavan Nikhilesh {
981b2143aaSPavan Nikhilesh 	if (!strncmp(optarg, "ordered", 7))
991b2143aaSPavan Nikhilesh 		rsrc->sched_type = RTE_SCHED_TYPE_ORDERED;
1001b2143aaSPavan Nikhilesh 	else if (!strncmp(optarg, "atomic", 6))
1011b2143aaSPavan Nikhilesh 		rsrc->sched_type = RTE_SCHED_TYPE_ATOMIC;
1021b2143aaSPavan Nikhilesh 	else if (!strncmp(optarg, "parallel", 8))
1031b2143aaSPavan Nikhilesh 		rsrc->sched_type = RTE_SCHED_TYPE_PARALLEL;
1041b2143aaSPavan Nikhilesh }
1051b2143aaSPavan Nikhilesh 
106092454d9SPavan Nikhilesh static int
l2fwd_parse_port_pair_config(const char * q_arg,struct l2fwd_resources * rsrc)107092454d9SPavan Nikhilesh l2fwd_parse_port_pair_config(const char *q_arg, struct l2fwd_resources *rsrc)
108092454d9SPavan Nikhilesh {
109092454d9SPavan Nikhilesh 	enum fieldnames {
110092454d9SPavan Nikhilesh 		FLD_PORT1 = 0,
111092454d9SPavan Nikhilesh 		FLD_PORT2,
112092454d9SPavan Nikhilesh 		_NUM_FLD
113092454d9SPavan Nikhilesh 	};
114092454d9SPavan Nikhilesh 	const char *p, *p0 = q_arg;
115092454d9SPavan Nikhilesh 	uint16_t int_fld[_NUM_FLD];
116092454d9SPavan Nikhilesh 	char *str_fld[_NUM_FLD];
117092454d9SPavan Nikhilesh 	uint16_t port_pair = 0;
118092454d9SPavan Nikhilesh 	unsigned int size;
119092454d9SPavan Nikhilesh 	char s[256];
120092454d9SPavan Nikhilesh 	char *end;
121092454d9SPavan Nikhilesh 	int i;
122092454d9SPavan Nikhilesh 
123092454d9SPavan Nikhilesh 	while ((p = strchr(p0, '(')) != NULL) {
124092454d9SPavan Nikhilesh 		++p;
125092454d9SPavan Nikhilesh 		p0 = strchr(p, ')');
126092454d9SPavan Nikhilesh 		if (p0 == NULL)
127092454d9SPavan Nikhilesh 			return -1;
128092454d9SPavan Nikhilesh 
129092454d9SPavan Nikhilesh 		size = p0 - p;
130092454d9SPavan Nikhilesh 		if (size >= sizeof(s))
131092454d9SPavan Nikhilesh 			return -1;
132092454d9SPavan Nikhilesh 
133092454d9SPavan Nikhilesh 		memcpy(s, p, size);
134092454d9SPavan Nikhilesh 		if (rte_strsplit(s, sizeof(s), str_fld,
135092454d9SPavan Nikhilesh 					_NUM_FLD, ',') != _NUM_FLD)
136092454d9SPavan Nikhilesh 			return -1;
137092454d9SPavan Nikhilesh 
138092454d9SPavan Nikhilesh 		for (i = 0; i < _NUM_FLD; i++) {
139092454d9SPavan Nikhilesh 			errno = 0;
140092454d9SPavan Nikhilesh 			int_fld[i] = strtoul(str_fld[i], &end, 0);
141092454d9SPavan Nikhilesh 			if (errno != 0 || end == str_fld[i] ||
142092454d9SPavan Nikhilesh 			    int_fld[i] >= RTE_MAX_ETHPORTS)
143092454d9SPavan Nikhilesh 				return -1;
144092454d9SPavan Nikhilesh 		}
145092454d9SPavan Nikhilesh 
146092454d9SPavan Nikhilesh 		if (port_pair >= RTE_MAX_ETHPORTS / 2) {
147092454d9SPavan Nikhilesh 			printf("exceeded max number of port pair params: Current %d Max = %d\n",
148092454d9SPavan Nikhilesh 			       port_pair, RTE_MAX_ETHPORTS / 2);
149092454d9SPavan Nikhilesh 			return -1;
150092454d9SPavan Nikhilesh 		}
151092454d9SPavan Nikhilesh 
152092454d9SPavan Nikhilesh 		if ((rsrc->dst_ports[int_fld[FLD_PORT1]] != UINT32_MAX) ||
153092454d9SPavan Nikhilesh 			(rsrc->dst_ports[int_fld[FLD_PORT2]] != UINT32_MAX)) {
154092454d9SPavan Nikhilesh 			printf("Duplicate port pair (%d,%d) config\n",
155092454d9SPavan Nikhilesh 					int_fld[FLD_PORT1], int_fld[FLD_PORT2]);
156092454d9SPavan Nikhilesh 			return -1;
157092454d9SPavan Nikhilesh 		}
158092454d9SPavan Nikhilesh 
159092454d9SPavan Nikhilesh 		rsrc->dst_ports[int_fld[FLD_PORT1]] = int_fld[FLD_PORT2];
160092454d9SPavan Nikhilesh 		rsrc->dst_ports[int_fld[FLD_PORT2]] = int_fld[FLD_PORT1];
161092454d9SPavan Nikhilesh 
162092454d9SPavan Nikhilesh 		port_pair++;
163092454d9SPavan Nikhilesh 	}
164092454d9SPavan Nikhilesh 
165092454d9SPavan Nikhilesh 	rsrc->port_pairs = true;
166092454d9SPavan Nikhilesh 
167092454d9SPavan Nikhilesh 	return 0;
168092454d9SPavan Nikhilesh }
169092454d9SPavan Nikhilesh 
1704ff45798SPavan Nikhilesh static const char short_options[] =
1714ff45798SPavan Nikhilesh 	"p:"  /* portmask */
1724ff45798SPavan Nikhilesh 	"q:"  /* number of queues */
1734ff45798SPavan Nikhilesh 	"T:"  /* timer period */
1744ff45798SPavan Nikhilesh 	;
1754ff45798SPavan Nikhilesh 
1764ff45798SPavan Nikhilesh #define CMD_LINE_OPT_MAC_UPDATING "mac-updating"
1774ff45798SPavan Nikhilesh #define CMD_LINE_OPT_NO_MAC_UPDATING "no-mac-updating"
1781b2143aaSPavan Nikhilesh #define CMD_LINE_OPT_MODE "mode"
1791b2143aaSPavan Nikhilesh #define CMD_LINE_OPT_EVENTQ_SCHED "eventq-sched"
180092454d9SPavan Nikhilesh #define CMD_LINE_OPT_PORT_PAIR_CONF "config"
181796b07e9SShijith Thotton #define CMD_LINE_OPT_ENABLE_VECTOR "event-vector"
182796b07e9SShijith Thotton #define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size"
183796b07e9SShijith Thotton #define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo"
1844ff45798SPavan Nikhilesh 
1854ff45798SPavan Nikhilesh enum {
1864ff45798SPavan Nikhilesh 	/* long options mapped to a short option */
1874ff45798SPavan Nikhilesh 
1884ff45798SPavan Nikhilesh 	/* first long only option value must be >= 256, so that we won't
1894ff45798SPavan Nikhilesh 	 * conflict with short options
1904ff45798SPavan Nikhilesh 	 */
1914ff45798SPavan Nikhilesh 	CMD_LINE_OPT_MIN_NUM = 256,
1921b2143aaSPavan Nikhilesh 	CMD_LINE_OPT_MODE_NUM,
1931b2143aaSPavan Nikhilesh 	CMD_LINE_OPT_EVENTQ_SCHED_NUM,
194092454d9SPavan Nikhilesh 	CMD_LINE_OPT_PORT_PAIR_CONF_NUM,
195796b07e9SShijith Thotton 	CMD_LINE_OPT_ENABLE_VECTOR_NUM,
196796b07e9SShijith Thotton 	CMD_LINE_OPT_VECTOR_SIZE_NUM,
197796b07e9SShijith Thotton 	CMD_LINE_OPT_VECTOR_TMO_NS_NUM
1984ff45798SPavan Nikhilesh };
1994ff45798SPavan Nikhilesh 
2004ff45798SPavan Nikhilesh /* Parse the argument given in the command line of the application */
2014ff45798SPavan Nikhilesh static int
l2fwd_event_parse_args(int argc,char ** argv,struct l2fwd_resources * rsrc)202092454d9SPavan Nikhilesh l2fwd_event_parse_args(int argc, char **argv, struct l2fwd_resources *rsrc)
2034ff45798SPavan Nikhilesh {
2044ff45798SPavan Nikhilesh 	int mac_updating = 1;
2054ff45798SPavan Nikhilesh 	struct option lgopts[] = {
2064ff45798SPavan Nikhilesh 		{ CMD_LINE_OPT_MAC_UPDATING, no_argument, &mac_updating, 1},
2074ff45798SPavan Nikhilesh 		{ CMD_LINE_OPT_NO_MAC_UPDATING, no_argument, &mac_updating, 0},
2081b2143aaSPavan Nikhilesh 		{ CMD_LINE_OPT_MODE, required_argument, NULL,
2091b2143aaSPavan Nikhilesh 							CMD_LINE_OPT_MODE_NUM},
2101b2143aaSPavan Nikhilesh 		{ CMD_LINE_OPT_EVENTQ_SCHED, required_argument, NULL,
2111b2143aaSPavan Nikhilesh 						CMD_LINE_OPT_EVENTQ_SCHED_NUM},
212092454d9SPavan Nikhilesh 		{ CMD_LINE_OPT_PORT_PAIR_CONF, required_argument, NULL,
213092454d9SPavan Nikhilesh 					CMD_LINE_OPT_PORT_PAIR_CONF_NUM},
214796b07e9SShijith Thotton 		{CMD_LINE_OPT_ENABLE_VECTOR, no_argument, NULL,
215796b07e9SShijith Thotton 					CMD_LINE_OPT_ENABLE_VECTOR_NUM},
216796b07e9SShijith Thotton 		{CMD_LINE_OPT_VECTOR_SIZE, required_argument, NULL,
217796b07e9SShijith Thotton 					CMD_LINE_OPT_VECTOR_SIZE_NUM},
218796b07e9SShijith Thotton 		{CMD_LINE_OPT_VECTOR_TMO_NS, required_argument, NULL,
219796b07e9SShijith Thotton 					CMD_LINE_OPT_VECTOR_TMO_NS_NUM},
2204ff45798SPavan Nikhilesh 		{NULL, 0, 0, 0}
2214ff45798SPavan Nikhilesh 	};
2224ff45798SPavan Nikhilesh 	int opt, ret, timer_secs;
2234ff45798SPavan Nikhilesh 	char *prgname = argv[0];
224092454d9SPavan Nikhilesh 	uint16_t port_id;
2254ff45798SPavan Nikhilesh 	int option_index;
226092454d9SPavan Nikhilesh 	char **argvopt;
227092454d9SPavan Nikhilesh 
2289a212dc0SConor Fogarty 	/* Reset l2fwd_dst_ports. 8< */
229092454d9SPavan Nikhilesh 	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
230092454d9SPavan Nikhilesh 		rsrc->dst_ports[port_id] = UINT32_MAX;
2314ff45798SPavan Nikhilesh 
2324ff45798SPavan Nikhilesh 	argvopt = argv;
2334ff45798SPavan Nikhilesh 	while ((opt = getopt_long(argc, argvopt, short_options,
2344ff45798SPavan Nikhilesh 				  lgopts, &option_index)) != EOF) {
2354ff45798SPavan Nikhilesh 
2364ff45798SPavan Nikhilesh 		switch (opt) {
2374ff45798SPavan Nikhilesh 		/* portmask */
2384ff45798SPavan Nikhilesh 		case 'p':
2394ff45798SPavan Nikhilesh 			rsrc->enabled_port_mask =
2404ff45798SPavan Nikhilesh 					l2fwd_event_parse_portmask(optarg);
2414ff45798SPavan Nikhilesh 			if (rsrc->enabled_port_mask == 0) {
2424ff45798SPavan Nikhilesh 				printf("invalid portmask\n");
2434ff45798SPavan Nikhilesh 				l2fwd_event_usage(prgname);
2444ff45798SPavan Nikhilesh 				return -1;
2454ff45798SPavan Nikhilesh 			}
2464ff45798SPavan Nikhilesh 			break;
2474ff45798SPavan Nikhilesh 
2484ff45798SPavan Nikhilesh 		/* nqueue */
2494ff45798SPavan Nikhilesh 		case 'q':
2504ff45798SPavan Nikhilesh 			rsrc->rx_queue_per_lcore =
2514ff45798SPavan Nikhilesh 					l2fwd_event_parse_nqueue(optarg);
2524ff45798SPavan Nikhilesh 			if (rsrc->rx_queue_per_lcore == 0) {
2534ff45798SPavan Nikhilesh 				printf("invalid queue number\n");
2544ff45798SPavan Nikhilesh 				l2fwd_event_usage(prgname);
2554ff45798SPavan Nikhilesh 				return -1;
2564ff45798SPavan Nikhilesh 			}
2574ff45798SPavan Nikhilesh 			break;
2584ff45798SPavan Nikhilesh 
2594ff45798SPavan Nikhilesh 		/* timer period */
2604ff45798SPavan Nikhilesh 		case 'T':
2614ff45798SPavan Nikhilesh 			timer_secs = l2fwd_event_parse_timer_period(optarg);
2624ff45798SPavan Nikhilesh 			if (timer_secs < 0) {
2634ff45798SPavan Nikhilesh 				printf("invalid timer period\n");
2644ff45798SPavan Nikhilesh 				l2fwd_event_usage(prgname);
2654ff45798SPavan Nikhilesh 				return -1;
2664ff45798SPavan Nikhilesh 			}
2674ff45798SPavan Nikhilesh 			rsrc->timer_period = timer_secs;
2684ff45798SPavan Nikhilesh 			/* convert to number of cycles */
2694ff45798SPavan Nikhilesh 			rsrc->timer_period *= rte_get_timer_hz();
2704ff45798SPavan Nikhilesh 			break;
2714ff45798SPavan Nikhilesh 
2721b2143aaSPavan Nikhilesh 		case CMD_LINE_OPT_MODE_NUM:
2731b2143aaSPavan Nikhilesh 			l2fwd_event_parse_mode(optarg, rsrc);
2741b2143aaSPavan Nikhilesh 			break;
2751b2143aaSPavan Nikhilesh 
2761b2143aaSPavan Nikhilesh 		case CMD_LINE_OPT_EVENTQ_SCHED_NUM:
2771b2143aaSPavan Nikhilesh 			l2fwd_event_parse_eventq_sched(optarg, rsrc);
2781b2143aaSPavan Nikhilesh 			break;
2791b2143aaSPavan Nikhilesh 
280092454d9SPavan Nikhilesh 		case CMD_LINE_OPT_PORT_PAIR_CONF_NUM:
281092454d9SPavan Nikhilesh 			ret = l2fwd_parse_port_pair_config(optarg, rsrc);
282092454d9SPavan Nikhilesh 			if (ret) {
283092454d9SPavan Nikhilesh 				printf("Invalid port pair config\n");
284092454d9SPavan Nikhilesh 				l2fwd_event_usage(prgname);
285092454d9SPavan Nikhilesh 				return -1;
286092454d9SPavan Nikhilesh 			}
287092454d9SPavan Nikhilesh 			break;
288796b07e9SShijith Thotton 		case CMD_LINE_OPT_ENABLE_VECTOR_NUM:
289796b07e9SShijith Thotton 			printf("event vectorization is enabled\n");
290796b07e9SShijith Thotton 			rsrc->evt_vec.enabled = 1;
291796b07e9SShijith Thotton 			break;
292796b07e9SShijith Thotton 		case CMD_LINE_OPT_VECTOR_SIZE_NUM:
293796b07e9SShijith Thotton 			rsrc->evt_vec.size = strtol(optarg, NULL, 10);
294796b07e9SShijith Thotton 			break;
295796b07e9SShijith Thotton 		case CMD_LINE_OPT_VECTOR_TMO_NS_NUM:
296796b07e9SShijith Thotton 			rsrc->evt_vec.timeout_ns = strtoull(optarg, NULL, 10);
297796b07e9SShijith Thotton 			break;
298092454d9SPavan Nikhilesh 
2994ff45798SPavan Nikhilesh 		/* long options */
3004ff45798SPavan Nikhilesh 		case 0:
3014ff45798SPavan Nikhilesh 			break;
3024ff45798SPavan Nikhilesh 
3034ff45798SPavan Nikhilesh 		default:
3044ff45798SPavan Nikhilesh 			l2fwd_event_usage(prgname);
3054ff45798SPavan Nikhilesh 			return -1;
3064ff45798SPavan Nikhilesh 		}
3074ff45798SPavan Nikhilesh 	}
3084ff45798SPavan Nikhilesh 
3094ff45798SPavan Nikhilesh 	rsrc->mac_updating = mac_updating;
3104ff45798SPavan Nikhilesh 
311796b07e9SShijith Thotton 	if (rsrc->evt_vec.enabled && !rsrc->evt_vec.size) {
312796b07e9SShijith Thotton 		rsrc->evt_vec.size = VECTOR_SIZE_DEFAULT;
313796b07e9SShijith Thotton 		printf("vector size set to default (%" PRIu16 ")\n",
314796b07e9SShijith Thotton 		       rsrc->evt_vec.size);
315796b07e9SShijith Thotton 	}
316796b07e9SShijith Thotton 
317796b07e9SShijith Thotton 	if (rsrc->evt_vec.enabled && !rsrc->evt_vec.timeout_ns) {
318796b07e9SShijith Thotton 		rsrc->evt_vec.timeout_ns = VECTOR_TMO_NS_DEFAULT;
319796b07e9SShijith Thotton 		printf("vector timeout set to default (%" PRIu64 " ns)\n",
320796b07e9SShijith Thotton 		       rsrc->evt_vec.timeout_ns);
321796b07e9SShijith Thotton 	}
322796b07e9SShijith Thotton 
3234ff45798SPavan Nikhilesh 	if (optind >= 0)
3244ff45798SPavan Nikhilesh 		argv[optind-1] = prgname;
3254ff45798SPavan Nikhilesh 
3264ff45798SPavan Nikhilesh 	ret = optind-1;
3274ff45798SPavan Nikhilesh 	optind = 1; /* reset getopt lib */
3284ff45798SPavan Nikhilesh 	return ret;
3299a212dc0SConor Fogarty 	/* >8 End of reset l2fwd_dst_ports. */
3304ff45798SPavan Nikhilesh }
3314ff45798SPavan Nikhilesh 
332092454d9SPavan Nikhilesh /*
333092454d9SPavan Nikhilesh  * Check port pair config with enabled port mask,
334092454d9SPavan Nikhilesh  * and for valid port pair combinations.
335092454d9SPavan Nikhilesh  */
336092454d9SPavan Nikhilesh static int
check_port_pair_config(struct l2fwd_resources * rsrc)337092454d9SPavan Nikhilesh check_port_pair_config(struct l2fwd_resources *rsrc)
338092454d9SPavan Nikhilesh {
339092454d9SPavan Nikhilesh 	uint32_t port_pair_mask = 0;
340092454d9SPavan Nikhilesh 	uint32_t portid;
341092454d9SPavan Nikhilesh 	uint16_t index;
342092454d9SPavan Nikhilesh 
343092454d9SPavan Nikhilesh 	for (index = 0; index < rte_eth_dev_count_avail(); index++) {
344092454d9SPavan Nikhilesh 		if ((rsrc->enabled_port_mask & (1 << index)) == 0 ||
345092454d9SPavan Nikhilesh 		    (port_pair_mask & (1 << index)))
346092454d9SPavan Nikhilesh 			continue;
347092454d9SPavan Nikhilesh 
348092454d9SPavan Nikhilesh 		portid = rsrc->dst_ports[index];
349092454d9SPavan Nikhilesh 		if (portid == UINT32_MAX) {
350092454d9SPavan Nikhilesh 			printf("port %u is enabled in but no valid port pair\n",
351092454d9SPavan Nikhilesh 			       index);
352092454d9SPavan Nikhilesh 			return -1;
353092454d9SPavan Nikhilesh 		}
354092454d9SPavan Nikhilesh 
355092454d9SPavan Nikhilesh 		if (!rte_eth_dev_is_valid_port(index)) {
356092454d9SPavan Nikhilesh 			printf("port %u is not valid\n", index);
357092454d9SPavan Nikhilesh 			return -1;
358092454d9SPavan Nikhilesh 		}
359092454d9SPavan Nikhilesh 
360092454d9SPavan Nikhilesh 		if (!rte_eth_dev_is_valid_port(portid)) {
361092454d9SPavan Nikhilesh 			printf("port %u is not valid\n", portid);
362092454d9SPavan Nikhilesh 			return -1;
363092454d9SPavan Nikhilesh 		}
364092454d9SPavan Nikhilesh 
365092454d9SPavan Nikhilesh 		if (port_pair_mask & (1 << portid) &&
366092454d9SPavan Nikhilesh 				rsrc->dst_ports[portid] != index) {
367092454d9SPavan Nikhilesh 			printf("port %u is used in other port pairs\n", portid);
368092454d9SPavan Nikhilesh 			return -1;
369092454d9SPavan Nikhilesh 		}
370092454d9SPavan Nikhilesh 
371092454d9SPavan Nikhilesh 		port_pair_mask |= (1 << portid);
372092454d9SPavan Nikhilesh 		port_pair_mask |= (1 << index);
373092454d9SPavan Nikhilesh 	}
374092454d9SPavan Nikhilesh 
375092454d9SPavan Nikhilesh 	return 0;
376092454d9SPavan Nikhilesh }
377092454d9SPavan Nikhilesh 
3784ff45798SPavan Nikhilesh static int
l2fwd_launch_one_lcore(void * args)3794ff45798SPavan Nikhilesh l2fwd_launch_one_lcore(void *args)
3804ff45798SPavan Nikhilesh {
3814ff45798SPavan Nikhilesh 	struct l2fwd_resources *rsrc = args;
3824ff45798SPavan Nikhilesh 	struct l2fwd_poll_resources *poll_rsrc = rsrc->poll_rsrc;
383080f57bcSPavan Nikhilesh 	struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc;
3844ff45798SPavan Nikhilesh 
385080f57bcSPavan Nikhilesh 	if (rsrc->event_mode)
386080f57bcSPavan Nikhilesh 		evt_rsrc->ops.l2fwd_event_loop(rsrc);
387080f57bcSPavan Nikhilesh 	else
3884ff45798SPavan Nikhilesh 		poll_rsrc->poll_main_loop(rsrc);
3894ff45798SPavan Nikhilesh 
3904ff45798SPavan Nikhilesh 	return 0;
3914ff45798SPavan Nikhilesh }
3924ff45798SPavan Nikhilesh 
3934ff45798SPavan Nikhilesh /* Check the link status of all ports in up to 9s, and print them finally */
3944ff45798SPavan Nikhilesh static void
check_all_ports_link_status(struct l2fwd_resources * rsrc,uint32_t port_mask)3954ff45798SPavan Nikhilesh check_all_ports_link_status(struct l2fwd_resources *rsrc,
3964ff45798SPavan Nikhilesh 			    uint32_t port_mask)
3974ff45798SPavan Nikhilesh {
3984ff45798SPavan Nikhilesh #define CHECK_INTERVAL 100 /* 100ms */
3994ff45798SPavan Nikhilesh #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
4004ff45798SPavan Nikhilesh 	uint16_t port_id;
4014ff45798SPavan Nikhilesh 	uint8_t count, all_ports_up, print_flag = 0;
4024ff45798SPavan Nikhilesh 	struct rte_eth_link link;
4038b33aa7eSPavan Nikhilesh 	int ret;
404db4e8135SIvan Dyukov 	char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
4054ff45798SPavan Nikhilesh 
4064ff45798SPavan Nikhilesh 	printf("\nChecking link status...");
4074ff45798SPavan Nikhilesh 	fflush(stdout);
4084ff45798SPavan Nikhilesh 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
4094ff45798SPavan Nikhilesh 		if (rsrc->force_quit)
4104ff45798SPavan Nikhilesh 			return;
4114ff45798SPavan Nikhilesh 		all_ports_up = 1;
4124ff45798SPavan Nikhilesh 		RTE_ETH_FOREACH_DEV(port_id) {
4134ff45798SPavan Nikhilesh 			if (rsrc->force_quit)
4144ff45798SPavan Nikhilesh 				return;
4154ff45798SPavan Nikhilesh 			if ((port_mask & (1 << port_id)) == 0)
4164ff45798SPavan Nikhilesh 				continue;
4174ff45798SPavan Nikhilesh 			memset(&link, 0, sizeof(link));
4188b33aa7eSPavan Nikhilesh 			ret = rte_eth_link_get_nowait(port_id, &link);
4198b33aa7eSPavan Nikhilesh 			if (ret < 0) {
4208b33aa7eSPavan Nikhilesh 				all_ports_up = 0;
4218b33aa7eSPavan Nikhilesh 				if (print_flag == 1)
4228b33aa7eSPavan Nikhilesh 					printf("Port %u link get failed: %s\n",
4238b33aa7eSPavan Nikhilesh 						port_id, rte_strerror(-ret));
4248b33aa7eSPavan Nikhilesh 				continue;
4258b33aa7eSPavan Nikhilesh 			}
4264ff45798SPavan Nikhilesh 			/* print link status if flag set */
4274ff45798SPavan Nikhilesh 			if (print_flag == 1) {
428db4e8135SIvan Dyukov 				rte_eth_link_to_str(link_status_text,
429db4e8135SIvan Dyukov 					sizeof(link_status_text), &link);
430db4e8135SIvan Dyukov 				printf("Port %d %s\n", port_id,
431db4e8135SIvan Dyukov 				       link_status_text);
4324ff45798SPavan Nikhilesh 				continue;
4334ff45798SPavan Nikhilesh 			}
4344ff45798SPavan Nikhilesh 			/* clear all_ports_up flag if any link down */
435295968d1SFerruh Yigit 			if (link.link_status == RTE_ETH_LINK_DOWN) {
4364ff45798SPavan Nikhilesh 				all_ports_up = 0;
4374ff45798SPavan Nikhilesh 				break;
4384ff45798SPavan Nikhilesh 			}
4394ff45798SPavan Nikhilesh 		}
4404ff45798SPavan Nikhilesh 		/* after finally printing all link status, get out */
4414ff45798SPavan Nikhilesh 		if (print_flag == 1)
4424ff45798SPavan Nikhilesh 			break;
4434ff45798SPavan Nikhilesh 
4444ff45798SPavan Nikhilesh 		if (all_ports_up == 0) {
4454ff45798SPavan Nikhilesh 			printf(".");
4464ff45798SPavan Nikhilesh 			fflush(stdout);
4474ff45798SPavan Nikhilesh 			rte_delay_ms(CHECK_INTERVAL);
4484ff45798SPavan Nikhilesh 		}
4494ff45798SPavan Nikhilesh 
4504ff45798SPavan Nikhilesh 		/* set the print_flag if all ports up or timeout */
4514ff45798SPavan Nikhilesh 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
4524ff45798SPavan Nikhilesh 			print_flag = 1;
4534ff45798SPavan Nikhilesh 			printf("done\n");
4544ff45798SPavan Nikhilesh 		}
4554ff45798SPavan Nikhilesh 	}
4564ff45798SPavan Nikhilesh }
4574ff45798SPavan Nikhilesh 
4584ff45798SPavan Nikhilesh /* Print out statistics on packets dropped */
4594ff45798SPavan Nikhilesh static void
print_stats(struct l2fwd_resources * rsrc)4604ff45798SPavan Nikhilesh print_stats(struct l2fwd_resources *rsrc)
4614ff45798SPavan Nikhilesh {
4624ff45798SPavan Nikhilesh 	uint64_t total_packets_dropped, total_packets_tx, total_packets_rx;
4634ff45798SPavan Nikhilesh 	uint32_t port_id;
4644ff45798SPavan Nikhilesh 
4654ff45798SPavan Nikhilesh 	total_packets_dropped = 0;
4664ff45798SPavan Nikhilesh 	total_packets_tx = 0;
4674ff45798SPavan Nikhilesh 	total_packets_rx = 0;
4684ff45798SPavan Nikhilesh 
4694ff45798SPavan Nikhilesh 	const char clr[] = {27, '[', '2', 'J', '\0' };
4704ff45798SPavan Nikhilesh 	const char topLeft[] = {27, '[', '1', ';', '1', 'H', '\0' };
4714ff45798SPavan Nikhilesh 
4724ff45798SPavan Nikhilesh 		/* Clear screen and move to top left */
4734ff45798SPavan Nikhilesh 	printf("%s%s", clr, topLeft);
4744ff45798SPavan Nikhilesh 
4754ff45798SPavan Nikhilesh 	printf("\nPort statistics ====================================");
4764ff45798SPavan Nikhilesh 
4774ff45798SPavan Nikhilesh 	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
4784ff45798SPavan Nikhilesh 		/* skip disabled ports */
4794ff45798SPavan Nikhilesh 		if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
4804ff45798SPavan Nikhilesh 			continue;
4814ff45798SPavan Nikhilesh 		printf("\nStatistics for port %u ------------------------------"
482080f57bcSPavan Nikhilesh 			   "\nPackets sent: %29"PRIu64
483080f57bcSPavan Nikhilesh 			   "\nPackets received: %25"PRIu64
484080f57bcSPavan Nikhilesh 			   "\nPackets dropped: %26"PRIu64,
4854ff45798SPavan Nikhilesh 			   port_id,
4864ff45798SPavan Nikhilesh 			   rsrc->port_stats[port_id].tx,
4874ff45798SPavan Nikhilesh 			   rsrc->port_stats[port_id].rx,
4884ff45798SPavan Nikhilesh 			   rsrc->port_stats[port_id].dropped);
4894ff45798SPavan Nikhilesh 
4904ff45798SPavan Nikhilesh 		total_packets_dropped +=
4914ff45798SPavan Nikhilesh 					rsrc->port_stats[port_id].dropped;
4924ff45798SPavan Nikhilesh 		total_packets_tx += rsrc->port_stats[port_id].tx;
4934ff45798SPavan Nikhilesh 		total_packets_rx += rsrc->port_stats[port_id].rx;
4944ff45798SPavan Nikhilesh 	}
495080f57bcSPavan Nikhilesh 
496080f57bcSPavan Nikhilesh 	if (rsrc->event_mode) {
497080f57bcSPavan Nikhilesh 		struct l2fwd_event_resources *evt_rsrc = rsrc->evt_rsrc;
498080f57bcSPavan Nikhilesh 		struct rte_event_eth_rx_adapter_stats rx_adptr_stats;
499080f57bcSPavan Nikhilesh 		struct rte_event_eth_tx_adapter_stats tx_adptr_stats;
500080f57bcSPavan Nikhilesh 		int ret, i;
501080f57bcSPavan Nikhilesh 
502080f57bcSPavan Nikhilesh 		for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++) {
503080f57bcSPavan Nikhilesh 			ret = rte_event_eth_rx_adapter_stats_get(
504080f57bcSPavan Nikhilesh 					evt_rsrc->rx_adptr.rx_adptr[i],
505080f57bcSPavan Nikhilesh 					&rx_adptr_stats);
506080f57bcSPavan Nikhilesh 			if (ret < 0)
507080f57bcSPavan Nikhilesh 				continue;
508080f57bcSPavan Nikhilesh 			printf("\nRx adapter[%d] statistics===================="
509080f57bcSPavan Nikhilesh 				   "\nReceive queue poll count: %17"PRIu64
510080f57bcSPavan Nikhilesh 				   "\nReceived packet count: %20"PRIu64
511080f57bcSPavan Nikhilesh 				   "\nEventdev enqueue count: %19"PRIu64
512080f57bcSPavan Nikhilesh 				   "\nEventdev enqueue retry count: %13"PRIu64
513080f57bcSPavan Nikhilesh 				   "\nReceived packet dropped count: %12"PRIu64
514080f57bcSPavan Nikhilesh 				   "\nRx enqueue start timestamp: %15"PRIu64
515080f57bcSPavan Nikhilesh 				   "\nRx enqueue block cycles: %18"PRIu64
516080f57bcSPavan Nikhilesh 				   "\nRx enqueue unblock timestamp: %13"PRIu64,
517080f57bcSPavan Nikhilesh 				   evt_rsrc->rx_adptr.rx_adptr[i],
518080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_poll_count,
519080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_packets,
520080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_enq_count,
521080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_enq_retry,
522080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_dropped,
523080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_enq_start_ts,
524080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_enq_block_cycles,
525080f57bcSPavan Nikhilesh 				   rx_adptr_stats.rx_enq_end_ts);
526080f57bcSPavan Nikhilesh 		}
527080f57bcSPavan Nikhilesh 		for (i = 0; i <  evt_rsrc->tx_adptr.nb_tx_adptr; i++) {
528080f57bcSPavan Nikhilesh 			ret = rte_event_eth_tx_adapter_stats_get(
529080f57bcSPavan Nikhilesh 					evt_rsrc->tx_adptr.tx_adptr[i],
530080f57bcSPavan Nikhilesh 					&tx_adptr_stats);
531080f57bcSPavan Nikhilesh 			if (ret < 0)
532080f57bcSPavan Nikhilesh 				continue;
533080f57bcSPavan Nikhilesh 			printf("\nTx adapter[%d] statistics===================="
534080f57bcSPavan Nikhilesh 				   "\nNumber of transmit retries: %15"PRIu64
535080f57bcSPavan Nikhilesh 				   "\nNumber of packets transmitted: %12"PRIu64
536080f57bcSPavan Nikhilesh 				   "\nNumber of packets dropped: %16"PRIu64,
537080f57bcSPavan Nikhilesh 				   evt_rsrc->tx_adptr.tx_adptr[i],
538080f57bcSPavan Nikhilesh 				   tx_adptr_stats.tx_retry,
539080f57bcSPavan Nikhilesh 				   tx_adptr_stats.tx_packets,
540080f57bcSPavan Nikhilesh 				   tx_adptr_stats.tx_dropped);
541080f57bcSPavan Nikhilesh 		}
542080f57bcSPavan Nikhilesh 	}
543080f57bcSPavan Nikhilesh 	printf("\nAggregate lcore statistics ========================="
544080f57bcSPavan Nikhilesh 		   "\nTotal packets sent: %23"PRIu64
545080f57bcSPavan Nikhilesh 		   "\nTotal packets received: %19"PRIu64
546080f57bcSPavan Nikhilesh 		   "\nTotal packets dropped: %20"PRIu64,
5474ff45798SPavan Nikhilesh 		   total_packets_tx,
5484ff45798SPavan Nikhilesh 		   total_packets_rx,
5494ff45798SPavan Nikhilesh 		   total_packets_dropped);
5504ff45798SPavan Nikhilesh 	printf("\n====================================================\n");
5513ee6f706SGeorgiy Levashov 
5523ee6f706SGeorgiy Levashov 	fflush(stdout);
5534ff45798SPavan Nikhilesh }
5544ff45798SPavan Nikhilesh 
5554ff45798SPavan Nikhilesh static void
l2fwd_event_print_stats(struct l2fwd_resources * rsrc)5564ff45798SPavan Nikhilesh l2fwd_event_print_stats(struct l2fwd_resources *rsrc)
5574ff45798SPavan Nikhilesh {
5584ff45798SPavan Nikhilesh 	uint64_t prev_tsc = 0, diff_tsc, cur_tsc, timer_tsc = 0;
5594ff45798SPavan Nikhilesh 	const uint64_t timer_period = rsrc->timer_period;
5604ff45798SPavan Nikhilesh 
5614ff45798SPavan Nikhilesh 	while (!rsrc->force_quit) {
5624ff45798SPavan Nikhilesh 		/* if timer is enabled */
5634ff45798SPavan Nikhilesh 		if (timer_period > 0) {
5644ff45798SPavan Nikhilesh 			cur_tsc = rte_rdtsc();
5654ff45798SPavan Nikhilesh 			diff_tsc = cur_tsc - prev_tsc;
5664ff45798SPavan Nikhilesh 
5674ff45798SPavan Nikhilesh 			/* advance the timer */
5684ff45798SPavan Nikhilesh 			timer_tsc += diff_tsc;
5694ff45798SPavan Nikhilesh 
5704ff45798SPavan Nikhilesh 			/* if timer has reached its timeout */
5714ff45798SPavan Nikhilesh 			if (unlikely(timer_tsc >= timer_period)) {
5724ff45798SPavan Nikhilesh 				print_stats(rsrc);
5734ff45798SPavan Nikhilesh 				/* reset the timer */
5744ff45798SPavan Nikhilesh 				timer_tsc = 0;
5754ff45798SPavan Nikhilesh 			}
5764ff45798SPavan Nikhilesh 			prev_tsc = cur_tsc;
5774ff45798SPavan Nikhilesh 		}
5784ff45798SPavan Nikhilesh 	}
5794ff45798SPavan Nikhilesh }
5804ff45798SPavan Nikhilesh 
5814ff45798SPavan Nikhilesh 
5824ff45798SPavan Nikhilesh static void
signal_handler(int signum)5834ff45798SPavan Nikhilesh signal_handler(int signum)
5844ff45798SPavan Nikhilesh {
5854ff45798SPavan Nikhilesh 	struct l2fwd_resources *rsrc = l2fwd_get_rsrc();
5864ff45798SPavan Nikhilesh 	if (signum == SIGINT || signum == SIGTERM) {
5874ff45798SPavan Nikhilesh 		printf("\n\nSignal %d received, preparing to exit...\n",
5884ff45798SPavan Nikhilesh 				signum);
5894ff45798SPavan Nikhilesh 		rsrc->force_quit = true;
5904ff45798SPavan Nikhilesh 	}
5914ff45798SPavan Nikhilesh }
5924ff45798SPavan Nikhilesh 
5934ff45798SPavan Nikhilesh int
main(int argc,char ** argv)5944ff45798SPavan Nikhilesh main(int argc, char **argv)
5954ff45798SPavan Nikhilesh {
5964ff45798SPavan Nikhilesh 	struct l2fwd_resources *rsrc;
5974ff45798SPavan Nikhilesh 	uint16_t nb_ports_available = 0;
5984ff45798SPavan Nikhilesh 	uint32_t nb_ports_in_mask = 0;
5994ff45798SPavan Nikhilesh 	uint16_t port_id, last_port;
6004ff45798SPavan Nikhilesh 	uint32_t nb_mbufs;
6014ff45798SPavan Nikhilesh 	uint16_t nb_ports;
6023dd1f9fbSPavan Nikhilesh 	int i, ret;
6034ff45798SPavan Nikhilesh 
6049a212dc0SConor Fogarty 	/* Init EAL. 8< */
6054ff45798SPavan Nikhilesh 	ret = rte_eal_init(argc, argv);
6064ff45798SPavan Nikhilesh 	if (ret < 0)
6074ff45798SPavan Nikhilesh 		rte_panic("Invalid EAL arguments\n");
6084ff45798SPavan Nikhilesh 	argc -= ret;
6094ff45798SPavan Nikhilesh 	argv += ret;
6104ff45798SPavan Nikhilesh 
6114ff45798SPavan Nikhilesh 	rsrc = l2fwd_get_rsrc();
6124ff45798SPavan Nikhilesh 
6134ff45798SPavan Nikhilesh 	signal(SIGINT, signal_handler);
6144ff45798SPavan Nikhilesh 	signal(SIGTERM, signal_handler);
6154ff45798SPavan Nikhilesh 
6164ff45798SPavan Nikhilesh 	/* parse application arguments (after the EAL ones) */
6174ff45798SPavan Nikhilesh 	ret = l2fwd_event_parse_args(argc, argv, rsrc);
6184ff45798SPavan Nikhilesh 	if (ret < 0)
6194ff45798SPavan Nikhilesh 		rte_panic("Invalid L2FWD arguments\n");
6209a212dc0SConor Fogarty 	/* >8 End of init EAL. */
6214ff45798SPavan Nikhilesh 
6224ff45798SPavan Nikhilesh 	printf("MAC updating %s\n", rsrc->mac_updating ? "enabled" :
6234ff45798SPavan Nikhilesh 			"disabled");
6244ff45798SPavan Nikhilesh 
6254ff45798SPavan Nikhilesh 	nb_ports = rte_eth_dev_count_avail();
6264ff45798SPavan Nikhilesh 	if (nb_ports == 0)
6274ff45798SPavan Nikhilesh 		rte_panic("No Ethernet ports - bye\n");
6284ff45798SPavan Nikhilesh 
6294ff45798SPavan Nikhilesh 	/* check port mask to possible port mask */
6304ff45798SPavan Nikhilesh 	if (rsrc->enabled_port_mask & ~((1 << nb_ports) - 1))
6314ff45798SPavan Nikhilesh 		rte_panic("Invalid portmask; possible (0x%x)\n",
6324ff45798SPavan Nikhilesh 			(1 << nb_ports) - 1);
6334ff45798SPavan Nikhilesh 
634092454d9SPavan Nikhilesh 	if (!rsrc->port_pairs) {
6354ff45798SPavan Nikhilesh 		last_port = 0;
6364ff45798SPavan Nikhilesh 		/*
637092454d9SPavan Nikhilesh 		 * Each logical core is assigned a dedicated TX queue on each
638092454d9SPavan Nikhilesh 		 * port.
6394ff45798SPavan Nikhilesh 		 */
6404ff45798SPavan Nikhilesh 		RTE_ETH_FOREACH_DEV(port_id) {
6414ff45798SPavan Nikhilesh 			/* skip ports that are not enabled */
6424ff45798SPavan Nikhilesh 			if ((rsrc->enabled_port_mask & (1 << port_id)) == 0)
6434ff45798SPavan Nikhilesh 				continue;
6444ff45798SPavan Nikhilesh 
6454ff45798SPavan Nikhilesh 			if (nb_ports_in_mask % 2) {
6464ff45798SPavan Nikhilesh 				rsrc->dst_ports[port_id] = last_port;
6474ff45798SPavan Nikhilesh 				rsrc->dst_ports[last_port] = port_id;
6484ff45798SPavan Nikhilesh 			} else {
6494ff45798SPavan Nikhilesh 				last_port = port_id;
6504ff45798SPavan Nikhilesh 			}
6514ff45798SPavan Nikhilesh 
6524ff45798SPavan Nikhilesh 			nb_ports_in_mask++;
6534ff45798SPavan Nikhilesh 		}
6544ff45798SPavan Nikhilesh 		if (nb_ports_in_mask % 2) {
6554ff45798SPavan Nikhilesh 			printf("Notice: odd number of ports in portmask.\n");
6564ff45798SPavan Nikhilesh 			rsrc->dst_ports[last_port] = last_port;
6574ff45798SPavan Nikhilesh 		}
658092454d9SPavan Nikhilesh 	} else {
659092454d9SPavan Nikhilesh 		if (check_port_pair_config(rsrc) < 0)
660092454d9SPavan Nikhilesh 			rte_panic("Invalid port pair config\n");
661092454d9SPavan Nikhilesh 	}
6624ff45798SPavan Nikhilesh 
663*4ed89049SDavid Marchand 	nb_mbufs = RTE_MAX(nb_ports * (RX_DESC_DEFAULT +
664*4ed89049SDavid Marchand 				       TX_DESC_DEFAULT +
6654ff45798SPavan Nikhilesh 				       MAX_PKT_BURST + rte_lcore_count() *
6664ff45798SPavan Nikhilesh 				       MEMPOOL_CACHE_SIZE), 8192U);
6674ff45798SPavan Nikhilesh 
6689a212dc0SConor Fogarty 	/* Create the mbuf pool. 8< */
6694ff45798SPavan Nikhilesh 	rsrc->pktmbuf_pool = rte_pktmbuf_pool_create("mbuf_pool",
6704ff45798SPavan Nikhilesh 			nb_mbufs, MEMPOOL_CACHE_SIZE, 0,
6714ff45798SPavan Nikhilesh 			RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
6724ff45798SPavan Nikhilesh 	if (rsrc->pktmbuf_pool == NULL)
6734ff45798SPavan Nikhilesh 		rte_panic("Cannot init mbuf pool\n");
6749a212dc0SConor Fogarty 	/* >8 End of creation of mbuf pool. */
6754ff45798SPavan Nikhilesh 
676796b07e9SShijith Thotton 	if (rsrc->evt_vec.enabled) {
677796b07e9SShijith Thotton 		unsigned int nb_vec, vec_size;
678796b07e9SShijith Thotton 
679796b07e9SShijith Thotton 		vec_size = rsrc->evt_vec.size;
680796b07e9SShijith Thotton 		nb_vec = (nb_mbufs + vec_size - 1) / vec_size;
68131edfc4aSPavan Nikhilesh 		nb_vec = RTE_MAX(512U, nb_vec);
68231edfc4aSPavan Nikhilesh 		nb_vec += rte_lcore_count() * 32;
683796b07e9SShijith Thotton 		rsrc->evt_vec_pool = rte_event_vector_pool_create(
68431edfc4aSPavan Nikhilesh 			"vector_pool", nb_vec, 32, vec_size, rte_socket_id());
685796b07e9SShijith Thotton 		if (rsrc->evt_vec_pool == NULL)
686796b07e9SShijith Thotton 			rte_panic("Cannot init event vector pool\n");
687796b07e9SShijith Thotton 	}
688796b07e9SShijith Thotton 
6894ff45798SPavan Nikhilesh 	nb_ports_available = l2fwd_event_init_ports(rsrc);
6904ff45798SPavan Nikhilesh 	if (!nb_ports_available)
6914ff45798SPavan Nikhilesh 		rte_panic("All available ports are disabled. Please set portmask.\n");
6924ff45798SPavan Nikhilesh 
6931b2143aaSPavan Nikhilesh 	/* Configure eventdev parameters if required */
6941b2143aaSPavan Nikhilesh 	if (rsrc->event_mode)
6951b2143aaSPavan Nikhilesh 		l2fwd_event_resource_setup(rsrc);
6961b2143aaSPavan Nikhilesh 	else
6974ff45798SPavan Nikhilesh 		l2fwd_poll_resource_setup(rsrc);
6984ff45798SPavan Nikhilesh 
6994ff45798SPavan Nikhilesh 	/* initialize port stats */
7004ff45798SPavan Nikhilesh 	memset(&rsrc->port_stats, 0,
7014ff45798SPavan Nikhilesh 					sizeof(struct l2fwd_port_statistics));
7024ff45798SPavan Nikhilesh 
7034ff45798SPavan Nikhilesh 	/* All settings are done. Now enable eth devices */
7044ff45798SPavan Nikhilesh 	RTE_ETH_FOREACH_DEV(port_id) {
7054ff45798SPavan Nikhilesh 		/* skip ports that are not enabled */
7064ff45798SPavan Nikhilesh 		if ((rsrc->enabled_port_mask &
7074ff45798SPavan Nikhilesh 					(1 << port_id)) == 0)
7084ff45798SPavan Nikhilesh 			continue;
7094ff45798SPavan Nikhilesh 
7104ff45798SPavan Nikhilesh 		ret = rte_eth_dev_start(port_id);
7114ff45798SPavan Nikhilesh 		if (ret < 0)
7124ff45798SPavan Nikhilesh 			rte_panic("rte_eth_dev_start:err=%d, port=%u\n", ret,
7134ff45798SPavan Nikhilesh 				  port_id);
7144ff45798SPavan Nikhilesh 	}
7154ff45798SPavan Nikhilesh 
716bcb6f841SPavan Nikhilesh 	if (rsrc->event_mode)
717bcb6f841SPavan Nikhilesh 		l2fwd_event_service_setup(rsrc);
718bcb6f841SPavan Nikhilesh 
7194ff45798SPavan Nikhilesh 	check_all_ports_link_status(rsrc, rsrc->enabled_port_mask);
7204ff45798SPavan Nikhilesh 
7214ff45798SPavan Nikhilesh 	/* launch per-lcore init on every lcore */
7224ff45798SPavan Nikhilesh 	rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, rsrc,
723cb056611SStephen Hemminger 				 SKIP_MAIN);
7244ff45798SPavan Nikhilesh 	l2fwd_event_print_stats(rsrc);
7253dd1f9fbSPavan Nikhilesh 	if (rsrc->event_mode) {
7263dd1f9fbSPavan Nikhilesh 		struct l2fwd_event_resources *evt_rsrc =
7273dd1f9fbSPavan Nikhilesh 							rsrc->evt_rsrc;
7283dd1f9fbSPavan Nikhilesh 		for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++)
7293dd1f9fbSPavan Nikhilesh 			rte_event_eth_rx_adapter_stop(
7303dd1f9fbSPavan Nikhilesh 				evt_rsrc->rx_adptr.rx_adptr[i]);
7313dd1f9fbSPavan Nikhilesh 		for (i = 0; i < evt_rsrc->tx_adptr.nb_tx_adptr; i++)
7323dd1f9fbSPavan Nikhilesh 			rte_event_eth_tx_adapter_stop(
7333dd1f9fbSPavan Nikhilesh 				evt_rsrc->tx_adptr.tx_adptr[i]);
7343dd1f9fbSPavan Nikhilesh 
7353dd1f9fbSPavan Nikhilesh 		RTE_ETH_FOREACH_DEV(port_id) {
7363dd1f9fbSPavan Nikhilesh 			if ((rsrc->enabled_port_mask &
7373dd1f9fbSPavan Nikhilesh 							(1 << port_id)) == 0)
7383dd1f9fbSPavan Nikhilesh 				continue;
739b55efbabSIvan Ilchenko 			ret = rte_eth_dev_stop(port_id);
740b55efbabSIvan Ilchenko 			if (ret < 0)
741b55efbabSIvan Ilchenko 				printf("rte_eth_dev_stop:err=%d, port=%u\n",
742b55efbabSIvan Ilchenko 				       ret, port_id);
7433dd1f9fbSPavan Nikhilesh 		}
7443dd1f9fbSPavan Nikhilesh 
7453dd1f9fbSPavan Nikhilesh 		rte_eal_mp_wait_lcore();
7463dd1f9fbSPavan Nikhilesh 		RTE_ETH_FOREACH_DEV(port_id) {
7473dd1f9fbSPavan Nikhilesh 			if ((rsrc->enabled_port_mask &
7483dd1f9fbSPavan Nikhilesh 							(1 << port_id)) == 0)
7493dd1f9fbSPavan Nikhilesh 				continue;
7503dd1f9fbSPavan Nikhilesh 			rte_eth_dev_close(port_id);
7513dd1f9fbSPavan Nikhilesh 		}
7523dd1f9fbSPavan Nikhilesh 
7533dd1f9fbSPavan Nikhilesh 		rte_event_dev_stop(evt_rsrc->event_d_id);
7543dd1f9fbSPavan Nikhilesh 		rte_event_dev_close(evt_rsrc->event_d_id);
7553dd1f9fbSPavan Nikhilesh 
7563dd1f9fbSPavan Nikhilesh 	} else {
7574ff45798SPavan Nikhilesh 		rte_eal_mp_wait_lcore();
7584ff45798SPavan Nikhilesh 
7594ff45798SPavan Nikhilesh 		RTE_ETH_FOREACH_DEV(port_id) {
7604ff45798SPavan Nikhilesh 			if ((rsrc->enabled_port_mask &
7614ff45798SPavan Nikhilesh 							(1 << port_id)) == 0)
7624ff45798SPavan Nikhilesh 				continue;
7634ff45798SPavan Nikhilesh 			printf("Closing port %d...", port_id);
764b55efbabSIvan Ilchenko 			ret = rte_eth_dev_stop(port_id);
765b55efbabSIvan Ilchenko 			if (ret < 0)
766b55efbabSIvan Ilchenko 				printf("rte_eth_dev_stop:err=%d, port=%u\n",
767b55efbabSIvan Ilchenko 				       ret, port_id);
7684ff45798SPavan Nikhilesh 			rte_eth_dev_close(port_id);
7694ff45798SPavan Nikhilesh 			printf(" Done\n");
7704ff45798SPavan Nikhilesh 		}
7713dd1f9fbSPavan Nikhilesh 	}
77210aa3757SChengchang Tang 
77310aa3757SChengchang Tang 	/* clean up the EAL */
77410aa3757SChengchang Tang 	rte_eal_cleanup();
7754ff45798SPavan Nikhilesh 	printf("Bye...\n");
7764ff45798SPavan Nikhilesh 
7774ff45798SPavan Nikhilesh 	return 0;
7784ff45798SPavan Nikhilesh }
779