1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2010-2014 Intel Corporation
3a9643ea8Slogwang  */
4a9643ea8Slogwang 
5a9643ea8Slogwang #include <stdio.h>
6a9643ea8Slogwang #include <string.h>
7a9643ea8Slogwang #include <stdint.h>
8a9643ea8Slogwang #include <sys/epoll.h>
9a9643ea8Slogwang #include <fcntl.h>
10a9643ea8Slogwang #include <unistd.h>
11a9643ea8Slogwang #include <stdlib.h>
12a9643ea8Slogwang #include <signal.h>
13a9643ea8Slogwang #include <errno.h>
14a9643ea8Slogwang 
15a9643ea8Slogwang #include <sys/queue.h>
16a9643ea8Slogwang 
17a9643ea8Slogwang #include <rte_common.h>
18a9643ea8Slogwang #include <rte_eal.h>
19a9643ea8Slogwang #include <rte_launch.h>
20a9643ea8Slogwang #include <rte_log.h>
21a9643ea8Slogwang #include <rte_per_lcore.h>
22a9643ea8Slogwang #include <rte_lcore.h>
232bfe3f2eSlogwang #include <rte_ethdev.h>
242bfe3f2eSlogwang #include <getopt.h>
252bfe3f2eSlogwang #include <rte_cycles.h>
26a9643ea8Slogwang #include <rte_debug.h>
27a9643ea8Slogwang 
28a9643ea8Slogwang #include "channel_manager.h"
29a9643ea8Slogwang #include "channel_monitor.h"
30a9643ea8Slogwang #include "power_manager.h"
31a9643ea8Slogwang #include "vm_power_cli.h"
32d30ea906Sjfb8856606 #include "oob_monitor.h"
33d30ea906Sjfb8856606 #include "parse.h"
34*2d9fd380Sjfb8856606 #ifdef RTE_NET_IXGBE
352bfe3f2eSlogwang #include <rte_pmd_ixgbe.h>
361646932aSjfb8856606 #endif
37*2d9fd380Sjfb8856606 #ifdef RTE_NET_I40E
382bfe3f2eSlogwang #include <rte_pmd_i40e.h>
391646932aSjfb8856606 #endif
40*2d9fd380Sjfb8856606 #ifdef RTE_NET_BNXT
412bfe3f2eSlogwang #include <rte_pmd_bnxt.h>
421646932aSjfb8856606 #endif
43a9643ea8Slogwang 
44d30ea906Sjfb8856606 #define RX_RING_SIZE 1024
45d30ea906Sjfb8856606 #define TX_RING_SIZE 1024
462bfe3f2eSlogwang 
472bfe3f2eSlogwang #define NUM_MBUFS 8191
482bfe3f2eSlogwang #define MBUF_CACHE_SIZE 250
492bfe3f2eSlogwang #define BURST_SIZE 32
502bfe3f2eSlogwang 
512bfe3f2eSlogwang static uint32_t enabled_port_mask;
522bfe3f2eSlogwang static volatile bool force_quit;
532bfe3f2eSlogwang 
542bfe3f2eSlogwang /****************/
552bfe3f2eSlogwang static const struct rte_eth_conf port_conf_default = {
56d30ea906Sjfb8856606 	.rxmode = {
574418919fSjohnjiang 		.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
58d30ea906Sjfb8856606 	},
592bfe3f2eSlogwang };
602bfe3f2eSlogwang 
612bfe3f2eSlogwang static inline int
port_init(uint16_t port,struct rte_mempool * mbuf_pool)622bfe3f2eSlogwang port_init(uint16_t port, struct rte_mempool *mbuf_pool)
632bfe3f2eSlogwang {
642bfe3f2eSlogwang 	struct rte_eth_conf port_conf = port_conf_default;
652bfe3f2eSlogwang 	const uint16_t rx_rings = 1, tx_rings = 1;
662bfe3f2eSlogwang 	int retval;
672bfe3f2eSlogwang 	uint16_t q;
68d30ea906Sjfb8856606 	struct rte_eth_dev_info dev_info;
69d30ea906Sjfb8856606 	struct rte_eth_txconf txq_conf;
702bfe3f2eSlogwang 
71d30ea906Sjfb8856606 	if (!rte_eth_dev_is_valid_port(port))
722bfe3f2eSlogwang 		return -1;
732bfe3f2eSlogwang 
744418919fSjohnjiang 	retval = rte_eth_dev_info_get(port, &dev_info);
754418919fSjohnjiang 	if (retval != 0) {
764418919fSjohnjiang 		printf("Error during getting device (port %u) info: %s\n",
774418919fSjohnjiang 				port, strerror(-retval));
784418919fSjohnjiang 		return retval;
794418919fSjohnjiang 	}
804418919fSjohnjiang 
81d30ea906Sjfb8856606 	if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
82d30ea906Sjfb8856606 		port_conf.txmode.offloads |=
83d30ea906Sjfb8856606 			DEV_TX_OFFLOAD_MBUF_FAST_FREE;
84d30ea906Sjfb8856606 
852bfe3f2eSlogwang 	/* Configure the Ethernet device. */
862bfe3f2eSlogwang 	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
872bfe3f2eSlogwang 	if (retval != 0)
882bfe3f2eSlogwang 		return retval;
892bfe3f2eSlogwang 
902bfe3f2eSlogwang 	/* Allocate and set up 1 RX queue per Ethernet port. */
912bfe3f2eSlogwang 	for (q = 0; q < rx_rings; q++) {
922bfe3f2eSlogwang 		retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
932bfe3f2eSlogwang 				rte_eth_dev_socket_id(port), NULL, mbuf_pool);
942bfe3f2eSlogwang 		if (retval < 0)
952bfe3f2eSlogwang 			return retval;
962bfe3f2eSlogwang 	}
972bfe3f2eSlogwang 
98d30ea906Sjfb8856606 	txq_conf = dev_info.default_txconf;
99d30ea906Sjfb8856606 	txq_conf.offloads = port_conf.txmode.offloads;
1002bfe3f2eSlogwang 	/* Allocate and set up 1 TX queue per Ethernet port. */
1012bfe3f2eSlogwang 	for (q = 0; q < tx_rings; q++) {
1022bfe3f2eSlogwang 		retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
103d30ea906Sjfb8856606 				rte_eth_dev_socket_id(port), &txq_conf);
1042bfe3f2eSlogwang 		if (retval < 0)
1052bfe3f2eSlogwang 			return retval;
1062bfe3f2eSlogwang 	}
1072bfe3f2eSlogwang 
1082bfe3f2eSlogwang 	/* Start the Ethernet port. */
1092bfe3f2eSlogwang 	retval = rte_eth_dev_start(port);
1102bfe3f2eSlogwang 	if (retval < 0)
1112bfe3f2eSlogwang 		return retval;
1122bfe3f2eSlogwang 
1132bfe3f2eSlogwang 	/* Display the port MAC address. */
1144418919fSjohnjiang 	struct rte_ether_addr addr;
1154418919fSjohnjiang 	retval = rte_eth_macaddr_get(port, &addr);
1164418919fSjohnjiang 	if (retval != 0) {
1174418919fSjohnjiang 		printf("Failed to get device (port %u) MAC address: %s\n",
1184418919fSjohnjiang 				port, rte_strerror(-retval));
1194418919fSjohnjiang 		return retval;
1204418919fSjohnjiang 	}
1214418919fSjohnjiang 
1222bfe3f2eSlogwang 	printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
1232bfe3f2eSlogwang 			   " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
1242bfe3f2eSlogwang 			(unsigned int)port,
1252bfe3f2eSlogwang 			addr.addr_bytes[0], addr.addr_bytes[1],
1262bfe3f2eSlogwang 			addr.addr_bytes[2], addr.addr_bytes[3],
1272bfe3f2eSlogwang 			addr.addr_bytes[4], addr.addr_bytes[5]);
1282bfe3f2eSlogwang 
1292bfe3f2eSlogwang 	/* Enable RX in promiscuous mode for the Ethernet device. */
1304418919fSjohnjiang 	retval = rte_eth_promiscuous_enable(port);
1314418919fSjohnjiang 	if (retval != 0)
1324418919fSjohnjiang 		return retval;
1332bfe3f2eSlogwang 
1342bfe3f2eSlogwang 
1352bfe3f2eSlogwang 	return 0;
1362bfe3f2eSlogwang }
1372bfe3f2eSlogwang 
1382bfe3f2eSlogwang static int
parse_portmask(const char * portmask)1392bfe3f2eSlogwang parse_portmask(const char *portmask)
1402bfe3f2eSlogwang {
1412bfe3f2eSlogwang 	char *end = NULL;
1422bfe3f2eSlogwang 	unsigned long pm;
1432bfe3f2eSlogwang 
1442bfe3f2eSlogwang 	/* parse hexadecimal string */
1452bfe3f2eSlogwang 	pm = strtoul(portmask, &end, 16);
1462bfe3f2eSlogwang 	if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
147*2d9fd380Sjfb8856606 		return 0;
1482bfe3f2eSlogwang 
1492bfe3f2eSlogwang 	return pm;
1502bfe3f2eSlogwang }
1512bfe3f2eSlogwang /* Parse the argument given in the command line of the application */
1522bfe3f2eSlogwang static int
parse_args(int argc,char ** argv)1532bfe3f2eSlogwang parse_args(int argc, char **argv)
1542bfe3f2eSlogwang {
155d30ea906Sjfb8856606 	int opt, ret, cnt, i;
1562bfe3f2eSlogwang 	char **argvopt;
157d30ea906Sjfb8856606 	uint16_t *oob_enable;
1582bfe3f2eSlogwang 	int option_index;
1592bfe3f2eSlogwang 	char *prgname = argv[0];
160d30ea906Sjfb8856606 	struct core_info *ci;
161d30ea906Sjfb8856606 	float branch_ratio;
1622bfe3f2eSlogwang 	static struct option lgopts[] = {
1632bfe3f2eSlogwang 		{ "mac-updating", no_argument, 0, 1},
1642bfe3f2eSlogwang 		{ "no-mac-updating", no_argument, 0, 0},
165*2d9fd380Sjfb8856606 		{ "core-branch-ratio", optional_argument, 0, 'b'},
166d30ea906Sjfb8856606 		{ "port-list", optional_argument, 0, 'p'},
1672bfe3f2eSlogwang 		{NULL, 0, 0, 0}
1682bfe3f2eSlogwang 	};
1692bfe3f2eSlogwang 	argvopt = argv;
170d30ea906Sjfb8856606 	ci = get_core_info();
1712bfe3f2eSlogwang 
172*2d9fd380Sjfb8856606 	while ((opt = getopt_long(argc, argvopt, "p:q:T:b:",
1732bfe3f2eSlogwang 				  lgopts, &option_index)) != EOF) {
1742bfe3f2eSlogwang 
1752bfe3f2eSlogwang 		switch (opt) {
1762bfe3f2eSlogwang 		/* portmask */
1772bfe3f2eSlogwang 		case 'p':
1782bfe3f2eSlogwang 			enabled_port_mask = parse_portmask(optarg);
1792bfe3f2eSlogwang 			if (enabled_port_mask == 0) {
1802bfe3f2eSlogwang 				printf("invalid portmask\n");
1812bfe3f2eSlogwang 				return -1;
1822bfe3f2eSlogwang 			}
1832bfe3f2eSlogwang 			break;
184*2d9fd380Sjfb8856606 		case 'b':
185*2d9fd380Sjfb8856606 			branch_ratio = BRANCH_RATIO_THRESHOLD;
186d30ea906Sjfb8856606 			oob_enable = malloc(ci->core_count * sizeof(uint16_t));
187d30ea906Sjfb8856606 			if (oob_enable == NULL) {
188d30ea906Sjfb8856606 				printf("Error - Unable to allocate memory\n");
189d30ea906Sjfb8856606 				return -1;
190d30ea906Sjfb8856606 			}
191d30ea906Sjfb8856606 			cnt = parse_set(optarg, oob_enable, ci->core_count);
192d30ea906Sjfb8856606 			if (cnt < 0) {
193*2d9fd380Sjfb8856606 				printf("Invalid core-list section in "
194*2d9fd380Sjfb8856606 				       "core-branch-ratio matrix - [%s]\n",
195d30ea906Sjfb8856606 						optarg);
1961646932aSjfb8856606 				free(oob_enable);
197d30ea906Sjfb8856606 				break;
198d30ea906Sjfb8856606 			}
199*2d9fd380Sjfb8856606 			cnt = parse_branch_ratio(optarg, &branch_ratio);
200*2d9fd380Sjfb8856606 			if (cnt < 0) {
201*2d9fd380Sjfb8856606 				printf("Invalid branch-ratio section in "
202*2d9fd380Sjfb8856606 				       "core-branch-ratio matrix - [%s]\n",
203*2d9fd380Sjfb8856606 						optarg);
204*2d9fd380Sjfb8856606 				free(oob_enable);
205*2d9fd380Sjfb8856606 				break;
206*2d9fd380Sjfb8856606 			}
207*2d9fd380Sjfb8856606 			if (branch_ratio <= 0.0 || branch_ratio > 100.0) {
208*2d9fd380Sjfb8856606 				printf("invalid branch ratio specified\n");
209*2d9fd380Sjfb8856606 				free(oob_enable);
210*2d9fd380Sjfb8856606 				return -1;
211*2d9fd380Sjfb8856606 			}
212d30ea906Sjfb8856606 			for (i = 0; i < ci->core_count; i++) {
213d30ea906Sjfb8856606 				if (oob_enable[i]) {
214*2d9fd380Sjfb8856606 					printf("***Using core %d "
215*2d9fd380Sjfb8856606 					       "with branch ratio %f\n",
216*2d9fd380Sjfb8856606 					       i, branch_ratio);
217d30ea906Sjfb8856606 					ci->cd[i].oob_enabled = 1;
218d30ea906Sjfb8856606 					ci->cd[i].global_enabled_cpus = 1;
219*2d9fd380Sjfb8856606 					ci->cd[i].branch_ratio_threshold =
220*2d9fd380Sjfb8856606 								branch_ratio;
221d30ea906Sjfb8856606 				}
222d30ea906Sjfb8856606 			}
223d30ea906Sjfb8856606 			free(oob_enable);
224d30ea906Sjfb8856606 			break;
2252bfe3f2eSlogwang 		/* long options */
2262bfe3f2eSlogwang 		case 0:
2272bfe3f2eSlogwang 			break;
2282bfe3f2eSlogwang 
2292bfe3f2eSlogwang 		default:
2302bfe3f2eSlogwang 			return -1;
2312bfe3f2eSlogwang 		}
2322bfe3f2eSlogwang 	}
2332bfe3f2eSlogwang 
2342bfe3f2eSlogwang 	if (optind >= 0)
2352bfe3f2eSlogwang 		argv[optind-1] = prgname;
2362bfe3f2eSlogwang 
2372bfe3f2eSlogwang 	ret = optind-1;
2382bfe3f2eSlogwang 	optind = 0; /* reset getopt lib */
2392bfe3f2eSlogwang 	return ret;
2402bfe3f2eSlogwang }
2412bfe3f2eSlogwang 
2422bfe3f2eSlogwang static void
check_all_ports_link_status(uint32_t port_mask)243d30ea906Sjfb8856606 check_all_ports_link_status(uint32_t port_mask)
2442bfe3f2eSlogwang {
2452bfe3f2eSlogwang #define CHECK_INTERVAL 100 /* 100ms */
2462bfe3f2eSlogwang #define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
2472bfe3f2eSlogwang 	uint16_t portid, count, all_ports_up, print_flag = 0;
2482bfe3f2eSlogwang 	struct rte_eth_link link;
2494418919fSjohnjiang 	int ret;
250*2d9fd380Sjfb8856606 	char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
2512bfe3f2eSlogwang 
2522bfe3f2eSlogwang 	printf("\nChecking link status");
2532bfe3f2eSlogwang 	fflush(stdout);
2542bfe3f2eSlogwang 	for (count = 0; count <= MAX_CHECK_TIME; count++) {
2552bfe3f2eSlogwang 		if (force_quit)
2562bfe3f2eSlogwang 			return;
2572bfe3f2eSlogwang 		all_ports_up = 1;
258d30ea906Sjfb8856606 		RTE_ETH_FOREACH_DEV(portid) {
2592bfe3f2eSlogwang 			if (force_quit)
2602bfe3f2eSlogwang 				return;
2612bfe3f2eSlogwang 			if ((port_mask & (1 << portid)) == 0)
2622bfe3f2eSlogwang 				continue;
2632bfe3f2eSlogwang 			memset(&link, 0, sizeof(link));
2644418919fSjohnjiang 			ret = rte_eth_link_get_nowait(portid, &link);
2654418919fSjohnjiang 			if (ret < 0) {
2664418919fSjohnjiang 				all_ports_up = 0;
2674418919fSjohnjiang 				if (print_flag == 1)
2684418919fSjohnjiang 					printf("Port %u link get failed: %s\n",
2694418919fSjohnjiang 						portid, rte_strerror(-ret));
2704418919fSjohnjiang 				continue;
2714418919fSjohnjiang 			}
2722bfe3f2eSlogwang 			/* print link status if flag set */
2732bfe3f2eSlogwang 			if (print_flag == 1) {
274*2d9fd380Sjfb8856606 				rte_eth_link_to_str(link_status_text,
275*2d9fd380Sjfb8856606 					sizeof(link_status_text), &link);
276*2d9fd380Sjfb8856606 				printf("Port %d %s\n", portid,
277*2d9fd380Sjfb8856606 				       link_status_text);
2782bfe3f2eSlogwang 				continue;
2792bfe3f2eSlogwang 			}
2802bfe3f2eSlogwang 		       /* clear all_ports_up flag if any link down */
2812bfe3f2eSlogwang 			if (link.link_status == ETH_LINK_DOWN) {
2822bfe3f2eSlogwang 				all_ports_up = 0;
2832bfe3f2eSlogwang 				break;
2842bfe3f2eSlogwang 			}
2852bfe3f2eSlogwang 		}
2862bfe3f2eSlogwang 		/* after finally printing all link status, get out */
2872bfe3f2eSlogwang 		if (print_flag == 1)
2882bfe3f2eSlogwang 			break;
2892bfe3f2eSlogwang 
2902bfe3f2eSlogwang 		if (all_ports_up == 0) {
2912bfe3f2eSlogwang 			printf(".");
2922bfe3f2eSlogwang 			fflush(stdout);
2932bfe3f2eSlogwang 			rte_delay_ms(CHECK_INTERVAL);
2942bfe3f2eSlogwang 		}
2952bfe3f2eSlogwang 
2962bfe3f2eSlogwang 		/* set the print_flag if all ports up or timeout */
2972bfe3f2eSlogwang 		if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
2982bfe3f2eSlogwang 			print_flag = 1;
2992bfe3f2eSlogwang 			printf("done\n");
3002bfe3f2eSlogwang 		}
3012bfe3f2eSlogwang 	}
3022bfe3f2eSlogwang }
303a9643ea8Slogwang static int
run_monitor(__rte_unused void * arg)304*2d9fd380Sjfb8856606 run_monitor(__rte_unused void *arg)
305a9643ea8Slogwang {
306a9643ea8Slogwang 	if (channel_monitor_init() < 0) {
307a9643ea8Slogwang 		printf("Unable to initialize channel monitor\n");
308a9643ea8Slogwang 		return -1;
309a9643ea8Slogwang 	}
310a9643ea8Slogwang 	run_channel_monitor();
311a9643ea8Slogwang 	return 0;
312a9643ea8Slogwang }
313a9643ea8Slogwang 
314d30ea906Sjfb8856606 static int
run_core_monitor(__rte_unused void * arg)315*2d9fd380Sjfb8856606 run_core_monitor(__rte_unused void *arg)
316d30ea906Sjfb8856606 {
317d30ea906Sjfb8856606 	if (branch_monitor_init() < 0) {
318d30ea906Sjfb8856606 		printf("Unable to initialize core monitor\n");
319d30ea906Sjfb8856606 		return -1;
320d30ea906Sjfb8856606 	}
321d30ea906Sjfb8856606 	run_branch_monitor();
322d30ea906Sjfb8856606 	return 0;
323d30ea906Sjfb8856606 }
324d30ea906Sjfb8856606 
325a9643ea8Slogwang static void
sig_handler(int signo)326a9643ea8Slogwang sig_handler(int signo)
327a9643ea8Slogwang {
328a9643ea8Slogwang 	printf("Received signal %d, exiting...\n", signo);
329a9643ea8Slogwang 	channel_monitor_exit();
330a9643ea8Slogwang 	channel_manager_exit();
331a9643ea8Slogwang 	power_manager_exit();
332a9643ea8Slogwang 
333a9643ea8Slogwang }
334a9643ea8Slogwang 
335a9643ea8Slogwang int
main(int argc,char ** argv)336a9643ea8Slogwang main(int argc, char **argv)
337a9643ea8Slogwang {
338a9643ea8Slogwang 	int ret;
339a9643ea8Slogwang 	unsigned lcore_id;
3402bfe3f2eSlogwang 	unsigned int nb_ports;
3412bfe3f2eSlogwang 	struct rte_mempool *mbuf_pool;
3422bfe3f2eSlogwang 	uint16_t portid;
343d30ea906Sjfb8856606 	struct core_info *ci;
3442bfe3f2eSlogwang 
345a9643ea8Slogwang 
346d30ea906Sjfb8856606 	ret = core_info_init();
347d30ea906Sjfb8856606 	if (ret < 0)
348d30ea906Sjfb8856606 		rte_panic("Cannot allocate core info\n");
349d30ea906Sjfb8856606 
350d30ea906Sjfb8856606 	ci = get_core_info();
351d30ea906Sjfb8856606 
352a9643ea8Slogwang 	ret = rte_eal_init(argc, argv);
353a9643ea8Slogwang 	if (ret < 0)
354a9643ea8Slogwang 		rte_panic("Cannot init EAL\n");
355a9643ea8Slogwang 
356a9643ea8Slogwang 	signal(SIGINT, sig_handler);
357a9643ea8Slogwang 	signal(SIGTERM, sig_handler);
358a9643ea8Slogwang 
3592bfe3f2eSlogwang 	argc -= ret;
3602bfe3f2eSlogwang 	argv += ret;
3612bfe3f2eSlogwang 
3622bfe3f2eSlogwang 	/* parse application arguments (after the EAL ones) */
3632bfe3f2eSlogwang 	ret = parse_args(argc, argv);
3642bfe3f2eSlogwang 	if (ret < 0)
3652bfe3f2eSlogwang 		rte_exit(EXIT_FAILURE, "Invalid arguments\n");
3662bfe3f2eSlogwang 
367d30ea906Sjfb8856606 	nb_ports = rte_eth_dev_count_avail();
3682bfe3f2eSlogwang 
369d30ea906Sjfb8856606 	if (nb_ports > 0) {
370d30ea906Sjfb8856606 		mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
371d30ea906Sjfb8856606 				NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0,
372d30ea906Sjfb8856606 				RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
3732bfe3f2eSlogwang 
3742bfe3f2eSlogwang 		if (mbuf_pool == NULL)
3752bfe3f2eSlogwang 			rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
3762bfe3f2eSlogwang 
3772bfe3f2eSlogwang 		/* Initialize ports. */
378d30ea906Sjfb8856606 		RTE_ETH_FOREACH_DEV(portid) {
3794418919fSjohnjiang 			struct rte_ether_addr eth;
3802bfe3f2eSlogwang 			int w, j;
381d30ea906Sjfb8856606 			int ret;
3822bfe3f2eSlogwang 
3832bfe3f2eSlogwang 			if ((enabled_port_mask & (1 << portid)) == 0)
3842bfe3f2eSlogwang 				continue;
3852bfe3f2eSlogwang 
3862bfe3f2eSlogwang 			eth.addr_bytes[0] = 0xe0;
3872bfe3f2eSlogwang 			eth.addr_bytes[1] = 0xe0;
3882bfe3f2eSlogwang 			eth.addr_bytes[2] = 0xe0;
3892bfe3f2eSlogwang 			eth.addr_bytes[3] = 0xe0;
3902bfe3f2eSlogwang 			eth.addr_bytes[4] = portid + 0xf0;
3912bfe3f2eSlogwang 
3922bfe3f2eSlogwang 			if (port_init(portid, mbuf_pool) != 0)
393d30ea906Sjfb8856606 				rte_exit(EXIT_FAILURE,
394d30ea906Sjfb8856606 					"Cannot init port %"PRIu8 "\n",
3952bfe3f2eSlogwang 					portid);
3962bfe3f2eSlogwang 
3972bfe3f2eSlogwang 			for (w = 0; w < MAX_VFS; w++) {
3982bfe3f2eSlogwang 				eth.addr_bytes[5] = w + 0xf0;
3992bfe3f2eSlogwang 
4001646932aSjfb8856606 				ret = -ENOTSUP;
401*2d9fd380Sjfb8856606 #ifdef RTE_NET_IXGBE
4022bfe3f2eSlogwang 				ret = rte_pmd_ixgbe_set_vf_mac_addr(portid,
4032bfe3f2eSlogwang 							w, &eth);
4041646932aSjfb8856606 #endif
405*2d9fd380Sjfb8856606 #ifdef RTE_NET_I40E
4062bfe3f2eSlogwang 				if (ret == -ENOTSUP)
407d30ea906Sjfb8856606 					ret = rte_pmd_i40e_set_vf_mac_addr(
408d30ea906Sjfb8856606 							portid, w, &eth);
4091646932aSjfb8856606 #endif
410*2d9fd380Sjfb8856606 #ifdef RTE_NET_BNXT
4112bfe3f2eSlogwang 				if (ret == -ENOTSUP)
412d30ea906Sjfb8856606 					ret = rte_pmd_bnxt_set_vf_mac_addr(
413d30ea906Sjfb8856606 							portid, w, &eth);
4141646932aSjfb8856606 #endif
4152bfe3f2eSlogwang 
4162bfe3f2eSlogwang 				switch (ret) {
4172bfe3f2eSlogwang 				case 0:
4182bfe3f2eSlogwang 					printf("Port %d VF %d MAC: ",
4192bfe3f2eSlogwang 							portid, w);
420d30ea906Sjfb8856606 					for (j = 0; j < 5; j++) {
421d30ea906Sjfb8856606 						printf("%02x:",
422d30ea906Sjfb8856606 							eth.addr_bytes[j]);
423d30ea906Sjfb8856606 					}
424d30ea906Sjfb8856606 					printf("%02x\n", eth.addr_bytes[5]);
425d30ea906Sjfb8856606 					break;
4262bfe3f2eSlogwang 				}
4272bfe3f2eSlogwang 				printf("\n");
4282bfe3f2eSlogwang 			}
4292bfe3f2eSlogwang 		}
4302bfe3f2eSlogwang 	}
4312bfe3f2eSlogwang 
432d30ea906Sjfb8856606 	check_all_ports_link_status(enabled_port_mask);
433d30ea906Sjfb8856606 
434a9643ea8Slogwang 	lcore_id = rte_get_next_lcore(-1, 1, 0);
435a9643ea8Slogwang 	if (lcore_id == RTE_MAX_LCORE) {
436d30ea906Sjfb8856606 		RTE_LOG(ERR, EAL, "A minimum of three cores are required to run "
437a9643ea8Slogwang 				"application\n");
438a9643ea8Slogwang 		return 0;
439a9643ea8Slogwang 	}
440d30ea906Sjfb8856606 	printf("Running channel monitor on lcore id %d\n", lcore_id);
441a9643ea8Slogwang 	rte_eal_remote_launch(run_monitor, NULL, lcore_id);
442a9643ea8Slogwang 
443d30ea906Sjfb8856606 	lcore_id = rte_get_next_lcore(lcore_id, 1, 0);
444d30ea906Sjfb8856606 	if (lcore_id == RTE_MAX_LCORE) {
445d30ea906Sjfb8856606 		RTE_LOG(ERR, EAL, "A minimum of three cores are required to run "
446d30ea906Sjfb8856606 				"application\n");
447d30ea906Sjfb8856606 		return 0;
448d30ea906Sjfb8856606 	}
449a9643ea8Slogwang 	if (power_manager_init() < 0) {
450a9643ea8Slogwang 		printf("Unable to initialize power manager\n");
451a9643ea8Slogwang 		return -1;
452a9643ea8Slogwang 	}
453a9643ea8Slogwang 	if (channel_manager_init(CHANNEL_MGR_DEFAULT_HV_PATH) < 0) {
454a9643ea8Slogwang 		printf("Unable to initialize channel manager\n");
455a9643ea8Slogwang 		return -1;
456a9643ea8Slogwang 	}
457d30ea906Sjfb8856606 
4584418919fSjohnjiang 	add_host_channels();
459d30ea906Sjfb8856606 
460d30ea906Sjfb8856606 	printf("Running core monitor on lcore id %d\n", lcore_id);
461d30ea906Sjfb8856606 	rte_eal_remote_launch(run_core_monitor, NULL, lcore_id);
462d30ea906Sjfb8856606 
463a9643ea8Slogwang 	run_cli(NULL);
464a9643ea8Slogwang 
465d30ea906Sjfb8856606 	branch_monitor_exit();
466d30ea906Sjfb8856606 
467a9643ea8Slogwang 	rte_eal_mp_wait_lcore();
468d30ea906Sjfb8856606 
469d30ea906Sjfb8856606 	free(ci->cd);
470d30ea906Sjfb8856606 
471a9643ea8Slogwang 	return 0;
472a9643ea8Slogwang }
473