| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| All Rights Reserved |
| |
| Unless you and Broadcom execute a separate written software license |
| agreement governing use of this software, this software is licensed |
| to you under the terms of the GNU General Public License version 2 |
| (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| with the following added to such license: |
| |
| As a special exception, the copyright holders of this software give |
| you permission to link this software with independent modules, and |
| to copy and distribute the resulting executable under terms of your |
| choice, provided that you also meet, for each linked independent |
| module, the terms and conditions of the license of that module. |
| An independent module is a module which is not derived from this |
| software. The special exception does not apply to any modifications |
| of the software. |
| |
| Not withstanding the above, under no circumstances may you combine |
| this software in any way with any other Broadcom software provided |
| under a license other than the GPL, without Broadcom's express prior |
| written consent. |
| |
| :> |
| */ |
| |
| #include <bcmolt_host_api.h> |
| #include <bcmolt_board.h> |
| #include <bcmolt_board_cli.h> |
| #include <bcmolt_user_appl_cli.h> |
| #include <bcmolt_user_appl_ex_cli.h> |
| #include <bcmolt_user_appl_epon_oam.h> |
| #if defined(LINUX_KERNEL_SPACE) |
| #include <bcmolt_dev_log_linux.h> |
| #endif |
| #include <bcmolt_dev_selector.h> |
| #include <bcm_api_cli.h> |
| #include <bcmolt_api_proxy.h> |
| #include <bcmolt_remote_cli.h> |
| #include <bcmolt_image_transfer.h> |
| |
| #ifdef SIMULATION_BUILD |
| static void using_inband_set(bcmos_bool using_inband){} |
| static bcmos_bool using_inband_get(void) |
| { |
| return BCMOS_FALSE; |
| } |
| extern uint32_t bcmtr_host_ip; |
| extern uint16_t bcmtr_host_udp_port; |
| extern uint32_t bcmtr_olt_ip[BCMTR_MAX_OLTS]; |
| extern uint16_t bcmtr_olt_udp_port[BCMTR_MAX_OLTS]; |
| #else |
| #include <bcmtr_plugin.h> |
| #endif |
| |
| |
| #define CLI_HOST_PROMPT_FORMAT "BCM.%u> " |
| |
| static bcmcli_session *current_session; |
| |
| //#if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) |
| //extern uint32_t bcmtr_host_ip; |
| //extern uint16_t bcmtr_host_udp_port; |
| //extern uint32_t bcmtr_olt_ip[BCMTR_MAX_OLTS]; |
| //extern uint16_t bcmtr_olt_udp_port[BCMTR_MAX_OLTS]; |
| //#endif |
| |
| #ifdef ENABLE_LOG |
| static int nologger=0; |
| #endif |
| |
| static int _cmd_using_inband(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms) |
| { |
| bcmcli_session_print(sess, "Maple management using %s\n", (using_inband_get())? "In-Band" : "PCIe"); |
| return 0; |
| } |
| |
| static int _cli_help(const char *cmd) |
| { |
| const char *p; |
| |
| while ((p = strchr(cmd, '/'))) |
| { |
| cmd = p + 1; |
| } |
| |
| fprintf(stderr, |
| "%s [-l <level>]" |
| #if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) |
| " [-p udp_port_device1] [-p udp_port_device2] ...\n" |
| "OR\n" |
| " [-olt ip_device1:port_device1] [-olt ip_device2:port_device2] ...\n" |
| " [-listen ip:port]\n" |
| #endif |
| #ifdef ENABLE_LOG |
| " [-nl]\n" |
| #endif |
| " [-ne]\n" |
| " [-dev]\n" |
| " [-if_mask mask]\n" |
| " [-proxy proxy_port_device1] [-proxy proxy_port_device2] ...\n" |
| " [-ud]\n" |
| " [-on_ready cmd]\n", cmd); |
| fprintf(stderr, |
| "\t\t level == guest | admin | debug\n" |
| #ifdef ENABLE_LOG |
| "\t\t -nl - disable kernel logger integration\n" |
| #endif |
| "\t\t -ne - disable line editing\n" |
| "\t\t -dev - device ID to auto-register for indications and run proxy on (default 0)\n" |
| "\t\t -if_mask - PON NI mask to apply to auto-registration of indications\n" |
| "\t\t -proxy - run the API proxy listening on this UDP port\n" |
| "\t\t -ud - use a unix domain connection to a user space device control" |
| "\t\t -on_ready - command for API proxy to execute after receiving device ready indication\n"); |
| return -EINVAL; |
| } |
| |
| /* quit command handler */ |
| static int _cmd_quit(bcmcli_session *sess, const bcmcli_cmd_parm parm[], uint16_t nParms) |
| { |
| bcmcli_stop(sess); |
| bcmcli_session_print(sess, "Maple CLI terminated by 'Quit' command\n"); |
| return 0; |
| } |
| |
| #if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) |
| /* parse ip:port */ |
| static bcmos_errno _parse_ip_port(const char *s, uint32_t *ip, uint16_t *port) |
| { |
| int n; |
| uint32_t ip1, ip2, ip3, ip4, pp; |
| |
| n = sscanf(s, "%u.%u.%u.%u:%u", &ip1, &ip2, &ip3, &ip4, &pp); |
| if (n != 5 || ip1 > 0xff || ip2 > 0xff || ip3 > 0xff || ip4 > 0xff || pp > 0xffff) |
| { |
| fprintf(stderr, "Can't parse %s. Must be ip_address:port\n", s); |
| return BCM_ERR_PARM; |
| } |
| *ip = (ip1 << 24) | (ip2 << 16) | (ip3 << 8) | ip4; |
| *port = pp; |
| return BCM_ERR_OK; |
| } |
| #endif |
| |
| /* Try to learn system mode */ |
| static bcmolt_system_mode _get_system_mode(bcmolt_devid dev) |
| { |
| bcmolt_device_key key = {}; |
| bcmolt_device_cfg dev_cfg; |
| bcmos_errno rc; |
| |
| BCMOLT_CFG_INIT(&dev_cfg, device, key); |
| BCMOLT_CFG_PROP_GET(&dev_cfg, device, system_mode); |
| rc = bcmolt_cfg_get(dev, &dev_cfg.hdr); |
| if (rc != BCM_ERR_OK) |
| { |
| bcmos_printf("Device %u: failed to read system mode (%s). Waiting for configuration\n", |
| (unsigned)dev, bcmos_strerror(rc)); |
| return BCMOLT_SYSTEM_MODE__NUM_OF; |
| } |
| bcmos_printf("Device %u: System mode: %s\n", |
| (unsigned)dev, bcmolt_system_mode_name(dev_cfg.data.system_mode)); |
| return dev_cfg.data.system_mode; |
| } |
| |
| #ifdef ENABLE_LOG |
| static int dev_log_time_to_str_cb(uint32_t time_stamp, char *time_str, int time_str_size) |
| { |
| return snprintf(time_str, time_str_size, "%u", time_stamp / 1000); /* convert from usec to msec. */ |
| } |
| |
| static bcmos_errno bcm_init_logger(void) |
| { |
| #define DEV_LOG_SIZE1 1<<11 |
| #define DEV_LOG_SIZE2 1<<13 |
| #define DEV_LOG_QUEUE_SIZE 1000 |
| |
| static uint8_t logger_buf1[DEV_LOG_SIZE1]; |
| static uint8_t logger_buf2[DEV_LOG_SIZE2]; |
| bcmos_errno err; |
| void *addresses[DEV_LOG_MAX_FILES] = {logger_buf1, logger_buf2}; |
| uint32_t sizes[DEV_LOG_MAX_FILES] = {sizeof(logger_buf1), sizeof(logger_buf2)}; |
| uint32_t flags[DEV_LOG_MAX_FILES] = {BCM_DEV_LOG_FILE_FLAG_STOP_WHEN_FULL, BCM_DEV_LOG_FILE_FLAG_WRAP_AROUND}; |
| |
| err = bcm_dev_log_init_default_logger(addresses, sizes, flags, BCM_SIZEOFARRAY(addresses), 0x4000, TASK_PRIORITY_DEV_LOG, DEV_LOG_QUEUE_SIZE); |
| BCMOS_TRACE_CHECK_RETURN(err, err, "bcm_dev_log_initialize_dev_logger_default()\n"); |
| |
| bcm_dev_log_level_set_style(DEV_LOG_LEVEL_FATAL, BCM_DEV_LOG_STYLE_BOLD); |
| bcm_dev_log_level_set_style(DEV_LOG_LEVEL_ERROR, BCM_DEV_LOG_STYLE_BOLD); |
| |
| bcm_dev_log_set_time_to_str_cb(dev_log_time_to_str_cb); |
| |
| #if defined(LINUX_KERNEL_SPACE) |
| if (!nologger) |
| { |
| err = bcm_dev_log_linux_init(); |
| BCMOS_TRACE_CHECK_RETURN(err, err, "bcm_dev_log_linux_init()\n"); |
| } |
| #endif |
| |
| BCM_LOG(INFO, def_log_id, "Hello Logger\n"); |
| |
| return BCM_ERR_OK; |
| } |
| #endif |
| |
| static void handle_system_mode_change(bcmolt_devid dev) |
| { |
| bcmcli_entry *cur_dir = bcmcli_dir_get(current_session); |
| char old_dir_name[32] = ""; |
| bcmolt_system_mode system_mode; |
| |
| bcmolt_system_mode_get(dev, &system_mode); |
| bcm_common_gpon_init(system_mode); |
| |
| if (dev == current_device) |
| { |
| if (cur_dir) |
| strncpy(old_dir_name, bcmcli_token_name(cur_dir), sizeof(old_dir_name) - 1); |
| |
| api_cli_set_commands(current_session); |
| |
| /* Restore current CLI directory */ |
| cur_dir = bcmcli_dir_find(NULL, old_dir_name); |
| if (cur_dir) |
| bcmcli_dir_set(current_session, cur_dir); |
| } |
| |
| bcmolt_user_appl_cli_handle_system_mode_change(dev); |
| } |
| |
| static void cli_get_prompt(bcmcli_session *session, char *buf, uint32_t max_len) |
| { |
| snprintf(buf, max_len, CLI_HOST_PROMPT_FORMAT, current_device); |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| bcmcli_session_parm mon_session_parm; |
| #ifndef SIMULATION_BUILD |
| uint32_t fpga_version; |
| #endif |
| int noedit = 0; |
| int rc; |
| int i; |
| bcmolt_host_init_params params = |
| { |
| #ifdef ENABLE_LOG |
| .logger_init_cb = bcm_init_logger, |
| #endif |
| .run_dev_ctrl = BCMOS_FALSE |
| }; |
| bcmolt_devid device = 0; |
| bcmos_bool specific_device = BCMOS_FALSE; |
| bcmos_bool run_proxy = BCMOS_FALSE; |
| bcmos_bool run_remote_cli = BCMOS_FALSE; |
| uint32_t proxy_port[BCMTR_MAX_OLTS] = {}; |
| uint32_t remote_cli_port = 0; |
| int cur_proxy_dev = 0; |
| char *on_ready_cmd = NULL; |
| struct bcmolt_rx_cfg rx_cfg = |
| { |
| .obj_type = BCMOLT_OBJECT_ANY, |
| .flags = BCMOLT_AUTO_FLAGS_NONE, |
| }; |
| #if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) |
| int cur_olt = 0; |
| #endif |
| |
| (void)noedit; /* prevent warning */ |
| |
| memset(&mon_session_parm, 0, sizeof(mon_session_parm)); |
| mon_session_parm.get_prompt = cli_get_prompt; |
| mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN; |
| |
| for (i = 1; i < argc; i++) |
| { |
| if (!strcmp(argv[i], "-l")) |
| { |
| ++i; |
| if (!strcmp(argv[i], "admin")) |
| mon_session_parm.access_right = BCMCLI_ACCESS_ADMIN; |
| else if (!strcmp(argv[i], "guest")) |
| mon_session_parm.access_right = BCMCLI_ACCESS_GUEST; |
| else if (!strcmp(argv[i], "debug")) |
| mon_session_parm.access_right = BCMCLI_ACCESS_DEBUG; |
| else |
| return _cli_help(argv[0]); |
| } |
| else if (!strcmp(argv[i], "-ne")) |
| { |
| noedit = 1; |
| } |
| #ifdef ENABLE_LOG |
| else if (!strcmp(argv[i], "-nl")) |
| { |
| nologger = 1; |
| } |
| #endif |
| #if defined(SIMULATION_BUILD) && defined(LINUX_USER_SPACE) |
| else if (!strcmp(argv[i], "-p")) |
| { |
| if (cur_olt >= BCMTR_MAX_OLTS) |
| { |
| printf("Too many -p and/or -olt options\n"); |
| return -1; |
| } |
| ++i; |
| bcmtr_olt_udp_port[cur_olt] = strtol(argv[i], NULL, 0); |
| ++cur_olt; |
| } |
| else if (!strcmp(argv[i], "-olt")) |
| { |
| if (cur_olt >= BCMTR_MAX_OLTS) |
| { |
| printf("Too many -p and/or -olt options\n"); |
| return -1; |
| } |
| ++i; |
| if (_parse_ip_port(argv[i], &bcmtr_olt_ip[cur_olt], &bcmtr_olt_udp_port[cur_olt]) != BCM_ERR_OK) |
| return -1; |
| ++cur_olt; |
| } |
| else if (!strcmp(argv[i], "-listen")) |
| { |
| ++i; |
| if (_parse_ip_port(argv[i], &bcmtr_host_ip, &bcmtr_host_udp_port) != BCM_ERR_OK) |
| return -1; |
| } |
| #endif |
| else if (!strcmp(argv[i], "-dev")) |
| { |
| ++i; |
| device = (bcmolt_devid)strtoul(argv[i], NULL, 0); |
| if (device >= BCMTR_MAX_OLTS) |
| { |
| printf("Invalid device ID\n"); |
| return -1; |
| } |
| current_device = device; |
| specific_device = BCMOS_TRUE; |
| } |
| else if (!strcmp(argv[i], "-if_mask")) |
| { |
| ++i; |
| rx_cfg.pon_ni_mask = (uint32_t)strtoul(argv[i], NULL, 0); |
| } |
| else if (!strcmp(argv[i], "-proxy")) |
| { |
| if (cur_proxy_dev >= BCMTR_MAX_OLTS) |
| { |
| printf("Too many -proxy options\n"); |
| return -1; |
| } |
| ++i; |
| run_proxy = BCMOS_TRUE; |
| proxy_port[cur_proxy_dev] = (uint32_t)strtoul(argv[i], NULL, 0); |
| if (proxy_port[cur_proxy_dev] > 0xffff) |
| { |
| printf("Invalid proxy port %u\n", (unsigned)proxy_port[cur_proxy_dev]); |
| return -1; |
| } |
| ++cur_proxy_dev; |
| } |
| else if (!strcmp(argv[i], "-remote")) |
| { |
| ++i; |
| run_remote_cli = BCMOS_TRUE; |
| remote_cli_port = (uint32_t)strtoul(argv[i], NULL, 0); |
| } |
| else if (!strcmp(argv[i], "-ud")) |
| { |
| using_inband_set(BCMOS_TRUE); |
| } |
| else if (!strcmp(argv[i], "-on_ready")) |
| { |
| ++i; |
| on_ready_cmd = argv[i]; |
| } |
| else |
| { |
| return _cli_help(argv[0]); |
| } |
| } |
| |
| rc = bcmolt_host_init(¶ms); |
| BUG_ON(rc); |
| |
| bcmos_trace_level_set(BCMOS_TRACE_LEVEL_DEBUG); |
| |
| if (noedit) |
| { |
| mon_session_parm.line_edit_mode = BCMCLI_LINE_EDIT_DISABLE; |
| } |
| if (bcmcli_session_open(&mon_session_parm, ¤t_session)) |
| { |
| printf("Can't open CLI session\n"); |
| return -EINVAL; |
| } |
| |
| /* Try to learn system mode for all devices */ |
| if (specific_device) |
| { |
| bcmolt_system_mode_set(current_device, _get_system_mode(current_device)); |
| } |
| else |
| { |
| for (i = 0; i < BCMTR_MAX_OLTS; i++) |
| bcmolt_system_mode_set(i, _get_system_mode(i)); |
| } |
| |
| /* Init device selector */ |
| rc = bcmolt_dev_sel_init(NULL); |
| |
| /* Add Maple API commands */ |
| rc = rc ? rc : api_cli_init(NULL, current_session); |
| |
| /* (x)GPON init. Does nothing if system mode is not (x)GPON */ |
| if (rc == BCM_ERR_OK) |
| { |
| bcmolt_system_mode system_mode = BCMOLT_SYSTEM_MODE__NUM_OF; |
| bcmolt_system_mode_get(current_device, &system_mode); |
| bcm_common_gpon_init(system_mode); |
| } |
| |
| /* Add transport commands */ |
| rc = rc ? rc : bcmtr_cli_init(); |
| |
| /* Add capture, log, debug commands */ |
| rc = rc ? rc : bcmtr_cld_init(current_session); |
| |
| /* Initialize embedded CLI module */ |
| rc = rc ? rc : bcm_embedded_cli_init(); |
| |
| rc = rc ? rc : bcmos_cli_init(NULL); |
| |
| rc = rc ? rc : bcmolt_user_appl_cli_init(NULL); |
| |
| rc = rc ? rc : bcmolt_user_appl_ex_cli_init(); |
| |
| |
| #if defined(LINUX_KERNEL_SPACE) |
| rc = rc ? rc : bcm_board_init(); |
| rc = rc ? rc : bcm_board_cli_init(NULL); |
| #endif |
| |
| #ifdef ENABLE_LOG |
| /* logger CLI directory */ |
| bcm_dev_log_cli_init(NULL); |
| #endif |
| |
| if (run_proxy) |
| { |
| /* If executing for specific device, run only 1 proxy instance. |
| * Otherwise, create as many instances as requested |
| */ |
| if (specific_device) |
| rc = rc ? rc : bcmolt_api_proxy_init(NULL, device, proxy_port[0], on_ready_cmd); |
| else |
| { |
| for (i = 0; i < cur_proxy_dev; i++) |
| { |
| rc = rc ? rc : bcmolt_api_proxy_init(NULL, i, proxy_port[i], on_ready_cmd); |
| } |
| } |
| } |
| |
| if (run_remote_cli) |
| { |
| rc = rc ? rc : bcmolt_remote_cli_init(NULL, device, remote_cli_port); |
| } |
| |
| /* Add other commands, e.g., access to embedded CLI */ |
| if (rc) |
| return rc; |
| |
| rx_cfg.rx_cb = bcmolt_user_appl_indication_cb; |
| rc = bcmolt_auto_rx_cb_set(device, &rx_cfg); |
| BUG_ON(BCM_ERR_OK != rc); |
| rx_cfg.rx_cb = bcmolt_user_appl_proxy_rx_cb; |
| rc = bcmolt_proxy_rx_cb_set(device, &rx_cfg); |
| BUG_ON(BCM_ERR_OK != rc); |
| |
| bcmolt_user_mftp_init(); |
| |
| sm_change_cb = handle_system_mode_change; |
| |
| BCMCLI_MAKE_CMD_NOPARM(NULL, "quit", "Quit", _cmd_quit); |
| BCMCLI_MAKE_CMD_NOPARM(NULL, "using_inband", "Using In Band", _cmd_using_inband); |
| |
| #ifndef SIMULATION_BUILD |
| bcm_board_fpga_version_get(&fpga_version); |
| bcmcli_session_print(current_session, "FPGA version: %d\n", fpga_version); |
| #endif |
| |
| /* Process user input until EOF or quit command */ |
| bcmcli_driver(current_session); |
| |
| #if defined(LINUX_KERNEL_SPACE) |
| bcm_board_uninit(); |
| #endif |
| bcmtr_exit(); |
| bcmcli_session_close(current_session); |
| bcmcli_token_destroy(NULL); |
| |
| if (run_proxy) |
| { |
| bcmolt_api_proxy_stop(); |
| } |
| |
| if (run_remote_cli) |
| { |
| bcmolt_remote_cli_stop(); |
| } |
| |
| return 0; |
| } |