#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/queue.h>
#include <getopt.h>
#include "channel_manager.h"
#include "channel_monitor.h"
#include "power_manager.h"
#include "vm_power_cli.h"
#include "oob_monitor.h"
#include "parse.h"
#ifdef RTE_NET_IXGBE
#endif
#ifdef RTE_NET_I40E
#endif
#ifdef RTE_NET_BNXT
#include <rte_pmd_bnxt.h>
#endif
#define RX_RING_SIZE 1024
#define TX_RING_SIZE 1024
#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32
static uint32_t enabled_port_mask;
static volatile bool force_quit;
static inline int
port_init(uint16_t port,
struct rte_mempool *mbuf_pool)
{
const uint16_t rx_rings = 1, tx_rings = 1;
int retval;
uint16_t q;
return -1;
if (retval != 0) {
printf("Error during getting device (port %u) info: %s\n",
port, strerror(-retval));
return retval;
}
if (retval != 0)
return retval;
for (q = 0; q < rx_rings; q++) {
if (retval < 0)
return retval;
}
for (q = 0; q < tx_rings; q++) {
if (retval < 0)
return retval;
}
if (retval < 0)
return retval;
struct rte_ether_addr addr;
if (retval != 0) {
printf("Failed to get device (port %u) MAC address: %s\n",
return retval;
}
printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
" %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
if (retval != 0)
return retval;
return 0;
}
static int
parse_portmask(const char *portmask)
{
char *end = NULL;
unsigned long pm;
pm = strtoul(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
return 0;
return pm;
}
static int
parse_args(int argc, char **argv)
{
int opt, ret, cnt, i;
char **argvopt;
uint16_t *oob_enable;
int option_index;
char *prgname = argv[0];
struct core_info *ci;
float branch_ratio;
static struct option lgopts[] = {
{ "mac-updating", no_argument, 0, 1},
{ "no-mac-updating", no_argument, 0, 0},
{ "core-branch-ratio", optional_argument, 0, 'b'},
{ "port-list", optional_argument, 0, 'p'},
{NULL, 0, 0, 0}
};
argvopt = argv;
ci = get_core_info();
while ((opt = getopt_long(argc, argvopt, "p:q:T:b:",
lgopts, &option_index)) != EOF) {
switch (opt) {
case 'p':
enabled_port_mask = parse_portmask(optarg);
if (enabled_port_mask == 0) {
printf("invalid portmask\n");
return -1;
}
break;
case 'b':
branch_ratio = BRANCH_RATIO_THRESHOLD;
oob_enable = malloc(ci->core_count * sizeof(uint16_t));
if (oob_enable == NULL) {
printf("Error - Unable to allocate memory\n");
return -1;
}
cnt = parse_set(optarg, oob_enable, ci->core_count);
if (cnt < 0) {
printf("Invalid core-list section in "
"core-branch-ratio matrix - [%s]\n",
optarg);
free(oob_enable);
break;
}
cnt = parse_branch_ratio(optarg, &branch_ratio);
if (cnt < 0) {
printf("Invalid branch-ratio section in "
"core-branch-ratio matrix - [%s]\n",
optarg);
free(oob_enable);
break;
}
if (branch_ratio <= 0.0 || branch_ratio > 100.0) {
printf("invalid branch ratio specified\n");
free(oob_enable);
return -1;
}
for (i = 0; i < ci->core_count; i++) {
if (oob_enable[i]) {
printf("***Using core %d "
"with branch ratio %f\n",
i, branch_ratio);
ci->cd[i].oob_enabled = 1;
ci->cd[i].global_enabled_cpus = 1;
ci->cd[i].branch_ratio_threshold =
branch_ratio;
}
}
free(oob_enable);
break;
case 0:
break;
default:
return -1;
}
}
if (optind >= 0)
argv[optind-1] = prgname;
ret = optind-1;
optind = 0;
return ret;
}
static void
check_all_ports_link_status(uint32_t port_mask)
{
#define CHECK_INTERVAL 100
#define MAX_CHECK_TIME 90
uint16_t portid, count, all_ports_up, print_flag = 0;
int ret;
printf("\nChecking link status");
fflush(stdout);
for (count = 0; count <= MAX_CHECK_TIME; count++) {
if (force_quit)
return;
all_ports_up = 1;
if (force_quit)
return;
if ((port_mask & (1 << portid)) == 0)
continue;
memset(&link, 0, sizeof(link));
if (ret < 0) {
all_ports_up = 0;
if (print_flag == 1)
printf("Port %u link get failed: %s\n",
continue;
}
if (print_flag == 1) {
sizeof(link_status_text), &link);
printf("Port %d %s\n", portid,
link_status_text);
continue;
}
all_ports_up = 0;
break;
}
}
if (print_flag == 1)
break;
if (all_ports_up == 0) {
printf(".");
fflush(stdout);
}
if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
print_flag = 1;
printf("done\n");
}
}
}
static int
{
if (channel_monitor_init() < 0) {
printf("Unable to initialize channel monitor\n");
return -1;
}
run_channel_monitor();
return 0;
}
static int
{
if (branch_monitor_init() < 0) {
printf("Unable to initialize core monitor\n");
return -1;
}
run_branch_monitor();
return 0;
}
static void
sig_handler(int signo)
{
printf("Received signal %d, exiting...\n", signo);
channel_monitor_exit();
channel_manager_exit();
power_manager_exit();
}
int
main(int argc, char **argv)
{
int ret;
unsigned lcore_id;
unsigned int nb_ports;
uint16_t portid;
struct core_info *ci;
ret = core_info_init();
if (ret < 0)
ci = get_core_info();
if (ret < 0)
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
argc -= ret;
argv += ret;
ret = parse_args(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE,
"Invalid arguments\n");
if (nb_ports > 0) {
NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0,
if (mbuf_pool == NULL)
rte_exit(EXIT_FAILURE,
"Cannot create mbuf pool\n");
struct rte_ether_addr eth;
int w, j;
int ret;
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
eth.addr_bytes[0] = 0xe0;
eth.addr_bytes[1] = 0xe0;
eth.addr_bytes[2] = 0xe0;
eth.addr_bytes[3] = 0xe0;
eth.addr_bytes[4] = portid + 0xf0;
if (port_init(portid, mbuf_pool) != 0)
"Cannot init port %"PRIu8 "\n",
portid);
for (w = 0; w < RTE_POWER_MAX_VFS; w++) {
eth.addr_bytes[5] = w + 0xf0;
ret = -ENOTSUP;
#ifdef RTE_NET_IXGBE
w, ð);
#endif
#ifdef RTE_NET_I40E
if (ret == -ENOTSUP)
portid, w, ð);
#endif
#ifdef RTE_NET_BNXT
if (ret == -ENOTSUP)
ret = rte_pmd_bnxt_set_vf_mac_addr(
portid, w, ð);
#endif
switch (ret) {
case 0:
printf("Port %d VF %d MAC: ",
portid, w);
for (j = 0; j < 5; j++) {
printf("%02x:",
eth.addr_bytes[j]);
}
printf("%02x\n", eth.addr_bytes[5]);
break;
}
printf("\n");
}
}
}
check_all_ports_link_status(enabled_port_mask);
if (lcore_id == RTE_MAX_LCORE) {
fprintf(stderr, "A minimum of three cores are required to run application\n");
return 0;
}
printf("Running channel monitor on lcore id %d\n", lcore_id);
if (lcore_id == RTE_MAX_LCORE) {
fprintf(stderr, "A minimum of three cores are required to run application\n");
return 0;
}
if (power_manager_init() < 0) {
fprintf(stderr, "Unable to initialize power manager\n");
return -1;
}
if (channel_manager_init(CHANNEL_MGR_DEFAULT_HV_PATH) < 0) {
fprintf(stderr, "Unable to initialize channel manager\n");
return -1;
}
add_host_channels();
printf("Running core monitor on lcore id %d\n", lcore_id);
run_cli(NULL);
branch_monitor_exit();
free(ci->cd);
return 0;
}