static struct expr * parse_timecmp() { enum prop prop; enum op op; if (token("atime")) prop = PROP_ATIME; else if (token("ctime")) prop = PROP_CTIME; else if (token("mtime")) prop = PROP_MTIME; else if (token("date")) prop = PROP_DATE; else return parse_cmp(); op = parse_op(); if (!op) parse_error("invalid comparison at '%.15s'", pos); int64_t n; if (parse_num(&n) || parse_dur(&n)) { struct expr *e = mkexpr(op); e->a.prop = prop; e->b.num = n; return e; } return 0; }
static struct expr * parse_inner() { if (token("prune")) { struct expr *e = mkexpr(EXPR_PRUNE); return e; } else if (token("print")) { struct expr *e = mkexpr(EXPR_PRINT); return e; } else if (token("!")) { struct expr *e = parse_cmp(); struct expr *not = mkexpr(EXPR_NOT); not->a.expr = e; return not; } else if (token("(")) { struct expr *e = parse_or(); if (token(")")) return e; parse_error("missing ) at '%.15s'", pos); return 0; } else { parse_error("unknown expression at '%.15s'", pos); return 0; } }
int find_action(fds client, char *s) { bool (*schedule)(fds, _time, bool (*)(fds, char*), void *); t_client *info; t_module *module; t_mod_func *functions; if (!client || !s || !(info = client->trick) || !(module = info->_m) || !(functions = module->functions)) return (false); while (functions && (*functions).action) { if (parse_cmp(s, (*functions).command) && (*functions).action) { schedule = (void*)((*functions).relative ? scheduler_relative : scheduler_action); if ((*functions).delay <= 0.0) return (((int (*)(fds, char*))(*functions).action)(client, s)); else schedule(client, (*functions).delay, (*functions).action, s); scheduler_free(client); return (-1); } functions = &functions[1]; } return (false); }
static bool parse_not(ExprParseState *state) { if (state->token == TOKEN_NOT) { CHECK_ERROR(parse_next_token(state) && parse_not(state)); parse_add_func(state, OPCODE_FUNC1, 1, op_not); return true; } return parse_cmp(state); }
cmd_result_t ct_setup(int unit, args_t *args) { parse_table_t pt; char *subcmd; int rv; int db_idx = cur_db; COMPILER_REFERENCE(unit); if ((subcmd = ARG_GET(args)) == NULL) { cli_out("Next Hop is%s running\n", next_hop_running() ? "" : " not"); cli_out("ATP is%s running\n", atp_running() ? "" : " not"); return CMD_OK; } if (sal_strcasecmp(subcmd, "RX") == 0) { char *next_arg; if ((next_arg = ARG_GET(args)) == NULL) { return CMD_USAGE; } if (sal_strcasecmp(next_arg, "START")) { return CMD_USAGE; } if (pkt_preinit() < 0) { cli_out("Failed to start BCM RX\n"); return CMD_FAIL; } } else if (sal_strcasecmp(subcmd, "NEXTHOP") == 0) { int idx; const cpudb_key_t *key; int s_unit = 0, s_port = 0, duplex = 0; int did_print = FALSE; if (cputrans_trans_count() == 0) { cputrans_trans_add(&bcm_trans_ptr); } if (ARG_CUR(args) == NULL) { for (idx = 0; idx < next_hop_num_ports_get(); idx++) { if (next_hop_port_get(idx, &s_unit, &s_port, &duplex) == BCM_E_NONE) { cli_out("NH idx %d: Unit %d, Port %d: %sarked duplex.\n", idx, s_unit, s_port, duplex ? "M" : "Not m"); } else { cli_out("NH idx %d: INVALID?\n", idx); } did_print = TRUE; } for (idx = 0; idx < next_hop_max_entries_get(); idx++) { key = next_hop_key_get(idx); if (key != NULL) { cli_out("KEY %x:%x:%x:%x:%x:%x is in NH DB\n", (*key).key[0], (*key).key[1], (*key).key[2], (*key).key[3], (*key).key[4], (*key).key[5]); did_print = TRUE; } } if (!did_print) { cli_out("Next Hop database and ports empty\n"); } } else { int thrd_pri = -1; int rx_pri = -1; int nhvlan = -1, nhcos = -1, src_mod = -1; int add_ports = 0; const cpudb_base_t *base; parse_table_init(unit, &pt); parse_table_add(&pt, "DBidx", PQ_DFL|PQ_INT, 0, &db_idx, 0); parse_table_add(&pt, "THRDpri", PQ_DFL|PQ_INT, 0, &thrd_pri, 0); parse_table_add(&pt, "RXpri", PQ_DFL|PQ_INT, 0, &rx_pri, 0); parse_table_add(&pt, "COS", PQ_DFL|PQ_INT, 0, &nhcos, 0); parse_table_add(&pt, "VLAN", PQ_DFL|PQ_INT, 0, &nhvlan, 0); parse_table_add(&pt, "SrcMOD", PQ_DFL|PQ_INT, 0, &src_mod, 0); parse_table_add(&pt, "Add", PQ_DFL|PQ_INT, 0, &add_ports, 0); if (parse_arg_eq(args, &pt) < 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } if (db_idx < 0 || db_idx >= MAX_DBS || db_refs[db_idx] == CPUDB_REF_NULL) { cli_out("Bad db index: %d\n", db_idx); return CMD_FAIL; } if (db_refs[db_idx]->local_entry == NULL) { cli_out("No local DB entry in cpudb %d\n", db_idx); return CMD_FAIL; } if (nhcos >= 0) { next_hop_cos_set(nhcos); } if (nhvlan >= 0) { next_hop_vlan_set(nhvlan); /* Load the next hop mac addr into L2 tables */ rv = nh_tx_dest_install(TRUE, nhvlan); if (rv < 0) { cli_out("NH TX dest install failed: %s\n", bcm_errmsg(rv)); return CMD_FAIL; } } if (src_mod >= 0) { int mod, port; nh_tx_src_get(&mod, &port); mod = src_mod; nh_tx_src_set(mod, port); nh_tx_unknown_modid_set(src_mod); } if (pkt_preinit() < 0) { cli_out("NH: Pre-init failed\n"); return CMD_FAIL; } if (next_hop_running()) { cli_out("Next hop is running; stopping: %d\n", next_hop_stop()); } if (thrd_pri >= 0 || rx_pri >= 0) { if (next_hop_config_set(NULL, thrd_pri, rx_pri) < 0) { cli_out("Warning: config set failed\n"); } } base = &db_refs[db_idx]->local_entry->base; if (add_ports > 0) { int i, u, p; for (i = 0; i < base->num_stk_ports; i++) { bcm_port_encap_config_t mode; u = base->stk_ports[i].unit; p = base->stk_ports[i].port; rv = bcm_port_encap_config_get(u, p, &mode); if (BCM_FAILURE(rv)) { continue; } if (mode.encap == BCM_PORT_ENCAP_IEEE) { continue; } rv = next_hop_port_add(u, p, 1); if (rv < 0) { cli_out("nexthop add (%d.%d) failed: %s\n", u, p, bcm_errmsg(rv)); } } } rv = next_hop_start(base); if (rv < 0) { cli_out("ERROR: next_hop_start failed: %s\n", bcm_errmsg(rv)); } parse_arg_eq_done(&pt); } return CMD_OK; #if defined(BROADCOM_DEBUG) } else if (sal_strcasecmp(subcmd, "NHSHOW") == 0) { next_hop_dump(); return CMD_OK; #endif /* BROADCOM_DEBUG */ } else if (sal_strcasecmp(subcmd, "TXLIMIT") == 0) { int cos = -1; int limit = 0; int rv; parse_table_init(unit, &pt); parse_table_add(&pt, "COS", PQ_DFL|PQ_INT, 0, &cos, 0); parse_table_add(&pt, "Limit", PQ_DFL|PQ_INT, 0, &limit, 0); if (parse_arg_eq(args, &pt) < 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } if (cos == -1) { for (cos = 0; cos <= BCM_COS_MAX; cos++) { cputrans_tx_alloc_limit_get(cos, &limit); cli_out("Limit for COS %d currently %d\n", cos, limit); } parse_arg_eq_done(&pt); return CMD_OK; } rv = cputrans_tx_alloc_limit_set(cos, limit); if (rv < 0) { cli_out("WARNING: limit set returned %d: %s\n", rv, bcm_errmsg(rv)); } parse_arg_eq_done(&pt); return CMD_OK; } else if (sal_strcasecmp(subcmd, "ATP") == 0) { int tx_pri = -1; int rx_pri = -1; int atp_cos = -1, atp_vlan = -1; #if defined(BROADCOM_DEBUG) if ((subcmd = ARG_CUR(args)) != NULL) { if (sal_strcasecmp(subcmd, "SHOW") == 0) { ARG_NEXT(args); atp_dump(1); return CMD_OK; } } #endif /* BROADCOM_DEBUG */ #ifdef INCLUDE_ATPTRANS_SOCKET if ((subcmd = ARG_CUR(args)) != NULL) { if (parse_cmp("TRANSport", subcmd, '\0')) { ARG_NEXT(args); if ((subcmd = ARG_GET(args)) == NULL) { return CMD_USAGE; } if (db_idx < 0 || db_idx >= MAX_DBS || db_refs[db_idx] == CPUDB_REF_NULL) { cli_out("Bad or empty DB index: %d\n", db_idx); return CMD_FAIL; } if (db_refs[db_idx]->local_entry == NULL) { cli_out("No local DB entry in cpudb %d\n", db_idx); return CMD_FAIL; } if (parse_cmp("SOCKet", subcmd, '\0')) { return atptrans_socket_subcmd(unit, args, db_refs[db_idx]); } return CMD_USAGE; } } #endif /* INCLUDE_ATPTRANS_SOCKET */ if (cputrans_trans_count() == 0) { cputrans_trans_add(&bcm_trans_ptr); } if (pkt_preinit() < 0) { #ifdef INCLUDE_ATPTRANS_SOCKET /* If ATP over sockets is running, then device RX is not required for ATP */ if (!atptrans_socket_server_running()) { cli_out("ATP: Pre-init failed\n"); return CMD_FAIL; } #else cli_out("ATP: Pre-init failed\n"); return CMD_FAIL; #endif } parse_table_init(unit, &pt); parse_table_add(&pt, "DBidx", PQ_DFL|PQ_INT, 0, &db_idx, 0); parse_table_add(&pt, "TXPrio", PQ_DFL|PQ_INT, 0, &tx_pri, 0); parse_table_add(&pt, "RXPrio", PQ_DFL|PQ_INT, 0, &rx_pri, 0); parse_table_add(&pt, "COS", PQ_DFL|PQ_INT, 0, &atp_cos, 0); parse_table_add(&pt, "VLAN", PQ_DFL|PQ_INT, 0, &atp_vlan, 0); if (parse_arg_eq(args, &pt) < 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } if (db_idx < 0 || db_idx >= MAX_DBS || db_refs[db_idx] == CPUDB_REF_NULL) { cli_out("Bad db index: %d\n", db_idx); parse_arg_eq_done(&pt); return CMD_FAIL; } if (db_refs[db_idx]->local_entry == NULL) { cli_out("No local DB entry in cpudb %d\n", db_idx); parse_arg_eq_done(&pt); return CMD_FAIL; } atp_cos_vlan_set(atp_cos, atp_vlan); rv = atp_config_set(tx_pri, rx_pri, NULL); if (rv < 0) { cli_out("ERROR: ATP config set failed: %s\n", bcm_errmsg(rv)); } atp_db_update(db_refs[db_idx]); rv = atp_start(ATP_F_LEARN_SLF, ATP_UNITS_ALL, BCM_RCO_F_ALL_COS); if (rv < 0) { cli_out("ERROR: ATP start failed: %s\n", bcm_errmsg(rv)); } parse_arg_eq_done(&pt); #if defined(BROADCOM_DEBUG) } else if (sal_strcasecmp(subcmd, "C2C") == 0) { if ((subcmd = ARG_GET(args)) != NULL) { if (sal_strcasecmp(subcmd, "SHOW") == 0) { c2c_dump(); return CMD_OK; } } #endif /* BROADCOM_DEBUG */ } else if (sal_strcasecmp(subcmd, "STOP") == 0) { rv = atp_stop(); if (rv < 0) { cli_out("ERROR: ATP stop failed: %s\n", bcm_errmsg(rv)); } } else if (sal_strcasecmp(subcmd, "TIMEOUT") == 0) { int retry_us = -1, retries = -1; if (ARG_CUR(args) == NULL) { atp_timeout_get(&retry_us, &retries); cli_out("Retries occur after %d usecs and will be made %d times\n", retry_us, retries); } else { parse_table_init(unit, &pt); parse_table_add(&pt, "RetryTO", PQ_DFL|PQ_INT, 0, &retry_us, 0); parse_table_add(&pt, "RETRIES", PQ_DFL|PQ_INT, 0, &retries, 0); if (parse_arg_eq(args, &pt) < 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } cli_out("Retry set(%d, %d) returns %d\n", retry_us, retries, atp_timeout_set(retry_us, retries)); parse_arg_eq_done(&pt); } } else if (sal_strcasecmp(subcmd, "SEGLEN") == 0) { int seg_len = -1; char *next_arg; if ((next_arg = ARG_GET(args)) == NULL) { seg_len = atp_segment_len_get(); cli_out("Current segmentation length is %d\n", seg_len); } else { seg_len = strtoul(next_arg, NULL, 0); cli_out("Seg_len set(%d) returns %d\n", seg_len, atp_segment_len_set(seg_len)); } } else if (sal_strcasecmp(subcmd, "POOLSIZE") == 0) { int tx_pool, rx_pool; /* Get current pool sizes in case one is not specified */ atp_pool_size_get(&tx_pool, &rx_pool); if (ARG_CUR(args) == NULL) { cli_out("Current TX pool: %d. RX pool %d.\n", tx_pool, rx_pool); } else { parse_table_init(unit, &pt); parse_table_add(&pt, "TX", PQ_DFL|PQ_INT, 0, &tx_pool, 0); parse_table_add(&pt, "RX", PQ_DFL|PQ_INT, 0, &rx_pool, 0); if (parse_arg_eq(args, &pt) < 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } cli_out("Pool size set returns %d\n", atp_pool_size_set(tx_pool, rx_pool)); parse_arg_eq_done(&pt); } } else { cli_out("Subcommand not found: %s\n", subcmd); return CMD_USAGE; } return CMD_OK; }
STATIC cmd_result_t atptrans_socket_subcmd(int unit, args_t *args, cpudb_ref_t db_ref) { char *subcmd; parse_table_t pt; cpudb_key_t local_key; cpudb_key_t dest_key; bcm_ip_t dest_ip; int rv = BCM_E_NONE; if ((subcmd = ARG_GET(args)) == NULL) { cli_out("Need option\n"); return CMD_USAGE; } if (parse_cmp("INStall", subcmd, '\0')) { /* Get destination CPU key and IP address */ parse_table_init(unit, &pt); parse_table_add(&pt, "DestKey", PQ_DFL|PQ_KEY, 0, dest_key.key, 0); parse_table_add(&pt, "DestIP", PQ_DFL|PQ_IP, 0, (void *)&dest_ip, 0); if (parse_arg_eq(args, &pt) < 2) { parse_arg_eq_done(&pt); return CMD_USAGE; } /* Make sure local CPU is set */ CPUDB_KEY_COPY(local_key, db_refs[cur_db]->local_entry->base.key); atptrans_socket_local_cpu_key_set(local_key); /* Install socket for given dest CPU */ rv = atptrans_socket_install(dest_key, dest_ip, 0x0); if (BCM_FAILURE(rv)) { cli_out("Cannot install socket interface in ATP transport " "for CPU key " CPUDB_KEY_FMT_EOLN, CPUDB_KEY_DISP(dest_key)); } parse_arg_eq_done(&pt); } else if (parse_cmp("UNINStall", subcmd, '\0')) { parse_table_init(unit, &pt); parse_table_add(&pt, "DestKey", PQ_DFL|PQ_KEY, 0, dest_key.key, 0); if (parse_arg_eq(args, &pt) <= 0) { parse_arg_eq_done(&pt); return CMD_USAGE; } rv = atptrans_socket_uninstall(dest_key); parse_arg_eq_done(&pt); } else if (parse_cmp("SERVer", subcmd, '\0')) { if ((subcmd = ARG_GET(args)) == NULL) { cli_out("Need option\n"); return CMD_USAGE; } if (sal_strcasecmp(subcmd, "START") == 0) { rv = atptrans_socket_server_start(); } else if (sal_strcasecmp(subcmd, "STOP") == 0) { rv = atptrans_socket_server_stop(); } else { cli_out("Invalid argument: %s\n", subcmd); return CMD_USAGE; } #ifdef BROADCOM_DEBUG } else if (parse_cmp("SHOW", subcmd, '\0')) { atptrans_socket_show(); #endif /* BROADCOM_DEBUG */ } else { cli_out("Invalid option: %s\n", subcmd); return CMD_USAGE; } if (BCM_FAILURE(rv)) { if (rv == BCM_E_UNAVAIL) { cli_out("Socket interface not available for current system\n"); } else { cli_out("Command failed\n"); } } return rv; }
cmd_result_t if_robo_stg(int unit, args_t *a) { char *subcmd, *c; int r; bcm_stg_t stg = BCM_STG_INVALID; vlan_id_t vid; int state; pbmp_t pbmp; soc_port_t port; if (! sh_check_attached(ARG_CMD(a), unit)) { return CMD_FAIL; } if ((subcmd = ARG_GET(a)) == NULL) { return CMD_USAGE; } if (sal_strcasecmp(subcmd, "create") == 0) { if ((c = ARG_GET(a)) != NULL) { stg = parse_integer(c); } if (stg == BCM_STG_INVALID) { r = bcm_stg_create(unit, &stg); cli_out("Created spanning tree group %d\n", stg); } else { r = bcm_stg_create_id(unit, stg); } if (r < 0) { goto bcm_err; } return CMD_OK; } if (sal_strcasecmp(subcmd, "destroy") == 0) { if ((c = ARG_GET(a)) == NULL) { return CMD_USAGE; } stg = parse_integer(c); if ((r = bcm_stg_destroy(unit, stg)) < 0) { goto bcm_err; } return CMD_OK; } if (sal_strcasecmp(subcmd, "show") == 0) { bcm_stg_t *list; int count, i; if ((c = ARG_GET(a)) != NULL) { stg = parse_integer(c); } if (stg != BCM_STG_INVALID) { return do_robo_show_stg_vlans(unit, stg); } if ((r = bcm_stg_list(unit, &list, &count)) < 0) { goto bcm_err; } for (i = 0; i < count; i++) { if ((r = do_robo_show_stg_vlans(unit, list[i])) < 0) { bcm_stg_list_destroy(unit, list, count); goto bcm_err; } if ((r = do_robo_show_stg_stp(unit, list[i])) < 0) { bcm_stg_list_destroy(unit, list, count); goto bcm_err; } } bcm_stg_list_destroy(unit, list, count); return CMD_OK; } if (sal_strcasecmp(subcmd, "add") == 0) { if ((c = ARG_GET(a)) == NULL) { return CMD_USAGE; } stg = parse_integer(c); while ((c = ARG_GET(a)) != NULL) { vid = parse_integer(c); if ((r = bcm_stg_vlan_add(unit, stg, vid)) < 0) { goto bcm_err; } } return CMD_OK; } if (sal_strcasecmp(subcmd, "remove") == 0) { if ((c = ARG_GET(a)) == NULL) { return CMD_USAGE; } stg = parse_integer(c); while ((c = ARG_GET(a)) != NULL) { vid = parse_integer(c); if ((r = bcm_stg_vlan_remove(unit, stg, vid)) < 0) { goto bcm_err; } } return CMD_OK; } if (sal_strcasecmp(subcmd, "clear") == 0) { if ((c = ARG_GET(a)) == NULL) { return CMD_USAGE; } stg = parse_integer(c); if ((r = bcm_stg_vlan_remove_all(unit, stg)) < 0) { goto bcm_err; } return CMD_OK; } if (sal_strcasecmp(subcmd, "stp") == 0) { if ((c = ARG_GET(a)) == NULL) { bcm_stg_t *list; int count, i; if ((r = bcm_stg_list(unit, &list, &count)) < 0) { goto bcm_err; } for (i = 0; i < count; i++) { cli_out("STG %d:\n", list[i]); if ((r = do_robo_show_stg_stp(unit, list[i])) < 0) { bcm_stg_list_destroy(unit, list, count); goto bcm_err; } } bcm_stg_list_destroy(unit, list, count); return CMD_OK; } stg = parse_integer(c); if ((c = ARG_GET(a)) == NULL) { cli_out("STG %d:\n", stg); if ((r = do_robo_show_stg_stp(unit, stg)) < 0) { goto bcm_err; } return CMD_OK; } if (parse_pbmp(unit, c, &pbmp) < 0) { return CMD_USAGE; } if ((c = ARG_GET(a)) == NULL) { return CMD_USAGE; } for (state = 0; state < BCM_STG_STP_COUNT; state++) { if (parse_cmp(robo_forward_mode[state], c, '\0')) { break; } } if (state == BCM_STG_STP_COUNT) { return CMD_USAGE; } SOC_PBMP_AND(pbmp, PBMP_ALL(unit)); PBMP_ITER(pbmp, port) { if ((r = bcm_stg_stp_set(unit, stg, port, state)) < 0) { goto bcm_err; } } return CMD_OK; } if (sal_strcasecmp(subcmd, "default") == 0) { if ((c = ARG_GET(a)) != NULL) { stg = parse_integer(c); } if (stg == BCM_STG_INVALID) { if ((r = bcm_stg_default_get(unit, &stg)) < 0) { goto bcm_err; } cli_out("Default STG is %d\n", stg); } else { if ((r = bcm_stg_default_set(unit, stg)) < 0) { goto bcm_err; } cli_out("Default STG set to %d\n", stg); } return CMD_OK; } return CMD_USAGE; bcm_err: cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); return CMD_FAIL; }
cmd_result_t cmd_broadsync(int unit, args_t *args) { char *arg_string_p = NULL; int result; static bcm_time_if_t bs_id[BCM_MAX_NUM_UNITS] = {0}; static int bs_initialized[BCM_MAX_NUM_UNITS] = {0}; int arg_is_master = 0; arg_string_p = ARG_GET(args); if (arg_string_p == NULL) { return CMD_USAGE; } if (!sh_check_attached(ARG_CMD(args), unit)) { return CMD_FAIL; } if (parse_cmp("CONFig", arg_string_p, 0)) { parse_table_t parse_table; int n_args = 0; bcm_time_interface_t intf; int32 freq = ILLEGAL_OFFSET; int32 phase_sec = ILLEGAL_OFFSET; int32 phase_nsec = ILLEGAL_OFFSET; if (bs_initialized[unit]) { intf.id = bs_id[unit]; intf.flags = BCM_TIME_OFFSET | BCM_TIME_DRIFT | BCM_TIME_REF_CLOCK | BCM_TIME_HEARTBEAT; bcm_time_interface_get(unit, &intf); intf.flags = BCM_TIME_WITH_ID | BCM_TIME_REPLACE | BCM_TIME_ENABLE | BCM_TIME_SYNC_STAMPER | BCM_TIME_REF_CLOCK | BCM_TIME_HEARTBEAT; } else { intf.flags = BCM_TIME_ENABLE | BCM_TIME_SYNC_STAMPER | BCM_TIME_REF_CLOCK | BCM_TIME_HEARTBEAT; intf.id = 0; /* Time Interface Identifier */ intf.drift.isnegative = 0; /* Drift amount per 1 Sec */ COMPILER_64_ZERO(intf.drift.seconds); intf.drift.nanoseconds = 0; intf.offset.isnegative = 0; /* Offset */ COMPILER_64_ZERO(intf.offset.seconds); intf.offset.nanoseconds = 0; intf.accuracy.isnegative = 0; /* Accuracy */ COMPILER_64_ZERO(intf.accuracy.seconds); intf.accuracy.nanoseconds = 0; intf.clk_resolution = 1; /* Reference clock resolution in nsecs */ intf.bitclock_hz = 10000000; /* 10MHz default bitclock */ intf.heartbeat_hz = 4000; /* 4KHz default heartbeat */ } intf.flags &= ~(BCM_TIME_DRIFT); intf.flags &= ~(BCM_TIME_OFFSET); parse_table_init(unit, &parse_table); parse_table_add(&parse_table, "Master", PQ_DFL | PQ_BOOL | PQ_NO_EQ_OPT, (void*)0, &arg_is_master, NULL); parse_table_add(&parse_table, "BitClock", PQ_DFL | PQ_INT, NULL, &intf.bitclock_hz, NULL); parse_table_add(&parse_table, "HeartBeat", PQ_DFL | PQ_INT, NULL, &intf.heartbeat_hz, NULL); parse_table_add(&parse_table, "Freq", PQ_DFL | PQ_INT, NULL, &freq, NULL); parse_table_add(&parse_table, "PhaseSec", PQ_DFL | PQ_INT, NULL, &phase_sec, NULL); parse_table_add(&parse_table, "PhaseNSec", PQ_DFL | PQ_INT, NULL, &phase_nsec, NULL); n_args = parse_arg_eq(args, &parse_table); if ((n_args < 0) || (ARG_CNT(args) > 0)) { printk("Invalid option: %s\n", ARG_CUR(args)); CLEAN_UP_AND_RETURN(CMD_USAGE); } if (!arg_is_master) { intf.flags |= BCM_TIME_INPUT; } if (freq != ILLEGAL_OFFSET) { intf.flags |= BCM_TIME_DRIFT; intf.drift.isnegative = (freq < 0) ? 1 : 0; COMPILER_64_ZERO(intf.drift.seconds); freq = (freq < 0) ? (-freq) : (freq); intf.drift.nanoseconds = (uint32) freq; } if ((phase_sec != ILLEGAL_OFFSET) || (phase_nsec != ILLEGAL_OFFSET)) { /* Valid seconds or nanoseconds component of phase offset. */ intf.flags |= BCM_TIME_OFFSET; phase_sec = (phase_sec == ILLEGAL_OFFSET) ? 0 : phase_sec; phase_nsec = (phase_nsec == ILLEGAL_OFFSET) ? 0 : phase_nsec; /* Discard integer seconds, if any, from nanoseconds term. */ while (phase_nsec >= BS_NANOSECONDS_PER_SECOND) { phase_nsec -= BS_NANOSECONDS_PER_SECOND; } while (phase_nsec <= -BS_NANOSECONDS_PER_SECOND) { phase_nsec += BS_NANOSECONDS_PER_SECOND; } /* Reconcile different signs in seconds and nanoseconds terms. */ if (phase_sec > 0 && phase_nsec < 0) { --phase_sec; phase_nsec += BS_NANOSECONDS_PER_SECOND; } else if (phase_sec < 0 && phase_nsec > 0) { ++phase_sec; phase_nsec -= BS_NANOSECONDS_PER_SECOND; } intf.offset.isnegative = ((phase_sec < 0) || (phase_nsec < 0)) ? 1 : 0; phase_sec = (intf.offset.isnegative) ? (-phase_sec) : (phase_sec); phase_nsec = (intf.offset.isnegative) ? (-phase_nsec) : (phase_nsec); COMPILER_64_SET(intf.offset.seconds, 0, ((uint32)phase_sec)); intf.offset.nanoseconds = (uint32) phase_nsec; } else { /* Invalid seconds and nanoseconds component of phase offset. */ intf.flags &= ~(BCM_TIME_OFFSET); } result = bcm_time_interface_add(unit, &intf); if (BCM_FAILURE(result)) { printk("Command failed. %s\n", bcm_errmsg(result)); CLEAN_UP_AND_RETURN(CMD_FAIL); } bs_initialized[unit] = 1; bs_id[unit] = intf.id; CLEAN_UP_AND_RETURN(CMD_OK); } else if (parse_cmp("STATus", arg_string_p, 0)) { int status; if (!bs_initialized[unit]) { printk("BroadSync not initialized on unit %d\n", unit); return CMD_FAIL; } arg_string_p = ARG_GET(args); if (arg_string_p != NULL) { return CMD_USAGE; } _bcm_time_bs_status_get(0, &status); printk("Status = %d\n", status); } else if (parse_cmp("1PPS", arg_string_p, 0)) { if (!bs_initialized[unit]) { printk("BroadSync not initialized on unit %d\n", unit); return CMD_FAIL; } arg_string_p = ARG_GET(args); if (arg_string_p == NULL) { int enabled; if (BCM_FAILURE(bcm_time_heartbeat_enable_get(unit, bs_id[unit], &enabled))) { printk("Error getting heartbeat (1pps) enable status\n"); return CMD_FAIL; } else { printk("1PPS is %s\n", (enabled) ? "Enabled" : "Disabled"); return CMD_OK; } } if (parse_cmp(arg_string_p, "ON", 0)) { result = bcm_time_heartbeat_enable_set(unit, bs_id[unit], 1); } else if (parse_cmp(arg_string_p, "OFF", 0)) { result = bcm_time_heartbeat_enable_set(unit, bs_id[unit], 0); } else { return CMD_USAGE; } if (BCM_FAILURE(result)) { printk("Command failed. %s\n", bcm_errmsg(result)); return CMD_FAIL; } } else if (parse_cmp("DEBUG", arg_string_p, 0)) { arg_string_p = ARG_GET(args); if (arg_string_p == NULL) { uint32 flags; if (BCM_FAILURE(_bcm_mbox_debug_flag_get(&flags))) { printk("Error getting debug status\n"); } else { printk("Debug output is %s\n", (flags) ? "On" : "Off"); return CMD_OK; } } if (parse_cmp("ON", arg_string_p, 0)) { _bcm_mbox_debug_flag_set(0xff); } else if (parse_cmp(arg_string_p, "OFF", 0)) { _bcm_mbox_debug_flag_set(0); } else { return CMD_USAGE; } } else if (parse_cmp("LOG", arg_string_p, 0)) { parse_table_t parse_table; int arg_log_debug = 0; int arg_log_pll = 0; bcm_mac_t dest_mac = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* default to broadcast */ bcm_mac_t src_mac = {0x00, 0x10, 0x18, 0x00, 0x00, 0x01}; bcm_ip_t dest_ip = 0xffffffff; /* default to broadcast */ bcm_ip_t src_ip = (192L << 24) + (168L << 16) +(0L << 8) + 90; int udp_port = 0x4455; int tpid = 0x8100; int vlan = 1; int ttl = 1; uint64 udp_log_mask = COMPILER_64_INIT(0,0); uint64 log_debug_bit = COMPILER_64_INIT(0,0x01); uint64 log_pll_bit = COMPILER_64_INIT(0,0x40); int rv = 0; parse_table_init(unit, &parse_table); parse_table_add(&parse_table, "LogDebug", PQ_DFL | PQ_BOOL | PQ_NO_EQ_OPT, (void*)0, &arg_log_debug, NULL); parse_table_add(&parse_table, "LogPLL", PQ_DFL | PQ_BOOL | PQ_NO_EQ_OPT, (void*)0, &arg_log_pll, NULL); parse_table_add(&parse_table, "DestMAC", PQ_DFL | PQ_MAC, NULL, dest_mac, NULL); parse_table_add(&parse_table, "DestAddr", PQ_DFL | PQ_IP, NULL, &dest_ip, NULL); parse_table_add(&parse_table, "SrcMAC", PQ_DFL | PQ_MAC, NULL, src_mac, NULL); parse_table_add(&parse_table, "SrcAddr", PQ_DFL | PQ_IP, NULL, &src_ip, NULL); parse_table_add(&parse_table, "UDPPort", PQ_DFL | PQ_INT, NULL, &udp_port, NULL); parse_table_add(&parse_table, "Vlan", PQ_DFL | PQ_INT, NULL, &vlan, NULL); if (parse_arg_eq(args, &parse_table) < 0) { printk("%s: Invalid option %s\n", ARG_CMD(args), ARG_CUR(args)); } if (arg_log_debug) { COMPILER_64_OR(udp_log_mask, log_debug_bit); } if (arg_log_pll) { COMPILER_64_OR(udp_log_mask, log_pll_bit); } rv = _bcm_time_bs_log_configure(unit, 0xff, udp_log_mask, src_mac, dest_mac, tpid, vlan, ttl, src_ip, dest_ip, udp_port); if (rv != BCM_E_NONE) { printk("Failed setting log configuration: %s\n", bcm_errmsg(rv)); return CMD_FAIL; } } else { return CMD_USAGE; } return CMD_OK; }