int bcmx_rx_register(const char *name, bcm_rx_cb_f fn, int priority, void *cookie, uint32 flags) { int unit, i; int rv = BCM_E_NONE, tmp_rv; rx_callout_t *rco, *prev, *next; BCMX_RX_INIT_CHECK; #if defined(BROADCOM_DEBUG) if (flags & BCM_RCO_F_INTR) { BCMX_DEBUG(BCMX_DBG_WARN, ("BCMX RX: Intr RX handler will " "not receive tunnelled pkts: %s\n", name)); } #endif /* BROADCOM_DEBUG */ BCMX_CONFIG_LOCK; rco = bcmx_rco_find(fn, priority, &prev); if (rco != NULL) { BCMX_CONFIG_UNLOCK; return BCM_E_NONE; } rco = sal_alloc(sizeof(rx_callout_t), "bcmx_rx_reg"); if (rco == NULL) { BCMX_CONFIG_UNLOCK; return BCM_E_MEMORY; } if (prev == NULL) { next = bcmx_rco; bcmx_rco = rco; } else { next = (rx_callout_t *)prev->rco_next; prev->rco_next = rco; } SETUP_RCO(rco, name, fn, priority, cookie, next, flags); for (i = 0; i < 16; i++) { if ((flags & BCM_RCO_F_COS_ACCEPT_MASK) & BCM_RCO_F_COS_ACCEPT(i)) { SETUP_RCO_COS_SET(rco, i); } } BCMX_CONFIG_UNLOCK; if (_bcmx_rx_running) { rv = BCM_E_UNAVAIL; BCMX_UNIT_ITER(unit, i) { tmp_rv = bcm_rx_register(unit, name, fn, priority, cookie, flags); BCM_IF_ERROR_RETURN(BCMX_RX_SET_ERROR_CHECK(unit, tmp_rv, &rv)); } }
int bcm_pkt_clear(int unit, bcm_pkt_t *pkt, bcm_pkt_blk_t *blks, int blk_count, uint32 flags, bcm_pkt_t **pkt_buf) { int rv, i; int bytes = 0; int local_alloc = FALSE; UNIT_VALID(unit); if (pkt == NULL) { /* Allocate new packet */ local_alloc = TRUE; if ((pkt = sal_alloc(sizeof(bcm_pkt_t), "pkt_setup")) == NULL) { *pkt_buf = NULL; return BCM_E_MEMORY; } } sal_memset(pkt, 0, sizeof(bcm_pkt_t)); pkt->unit = unit; if (blk_count == 0) { /* * Permit allocation of an empty packet structure. * A single buffer can be added alter using the * BCM_PKT_ONE_BUF_SETUP macro. */ bcm_pkt_flags_init(unit, pkt, flags); } else { for (i = 0; i < blk_count; i++) { bytes += blks[i].len; } if (bytes < BCM_PKT_ALLOC_MIN) { *pkt_buf = NULL; if (local_alloc) { sal_free(pkt); } return BCM_E_MEMORY; } pkt->pkt_data = blks; pkt->blk_count = blk_count; rv = bcm_pkt_flags_len_setup(unit, pkt, bytes, -1, flags); if (BCM_FAILURE(rv)) { *pkt_buf = NULL; if (local_alloc) { sal_free(pkt); } return rv; } } *pkt_buf = pkt; return BCM_E_NONE; }
/* * Function : soc_robo_regaddrlist_alloc * * Purpose : * Allocate the register info structure and link to the registers list. * * Parameters : * addrlist : pointer of the registers list * * Return : * SOC_E_NONE : success. * SOC_E_MEMORY : memory allocation fail. * * Note : * * */ int soc_robo_regaddrlist_alloc(soc_regaddrlist_t *addrlist) { if ((addrlist->ainfo = sal_alloc(_SOC_ROBO_MAX_REGLIST * sizeof(soc_regaddrinfo_t), "regaddrlist")) == NULL) { return SOC_E_MEMORY; } addrlist->count = 0; return SOC_E_NONE; }
cmd_result_t test_parameters(int u, args_t *a) /* * Function: test_parameters * Purpose: Set the parameters for the specified tests. * Parameters: u - unit number * a - arguments, expects tuples of the form: * [Test name/#] Arguments. * if arguments is null string ("") then previously * set arguments are discarded and defaults used. * Returns: cmd_result_t. */ { char *tid, *p; /* Testid, parameters */ test_t *t; /* Test pointer */ COMPILER_REFERENCE(u); if (0 == ARG_CNT(a)) { return(CMD_USAGE); } while (NULL != (tid = ARG_GET(a))) { p = ARG_GET(a); /* Parameter */ t = test_find(tid); if (NULL == t) { cli_out("%s: Error: Unable to find test: %s\n", ARG_CMD(a), tid); return(CMD_FAIL); } if (!p || !*p) { /* Clear parameter */ if (!t->t_override_string) { cli_out("%s: Warning: No arguments to clear for test: %s\n", ARG_CMD(a), t->t_name); continue; } sal_free(t->t_override_string); t->t_override_string = NULL; } else { /* Set Arguments */ if (t->t_override_string) { sal_free(t->t_override_string); } if (!(t->t_override_string = (char *)sal_alloc(strlen(p) + 1, "test_parm"))) { cli_out("%s: Error: Out of memory\n", ARG_CMD(a)); return(CMD_FAIL); } sal_strcpy(t->t_override_string, p); cli_out("%s: Parameter set: %s(\"%s\")\n", ARG_CMD(a), t->t_name, t->t_override_string); } } return(CMD_OK); }
/* * First time through, everything 0 (BSS), so set up defaults. */ xd->hdr_mode = 0; xd->xd_unit = unit; xd->xd_init = TRUE; xd->xd_state = XD_IDLE; xd->xd_file = NULL; xd->xd_pkt_len = 68; xd->xd_pat = 0x12345678; xd->xd_pat_inc = 1; SOC_PBMP_ASSIGN(xd->pkt_info.tx_pbmp, PBMP_ALL(unit)); SOC_PBMP_ASSIGN(xd->xd_ppsm_pbm, PBMP_ALL(unit)); xd->xd_vlan = 0x1; xd->xd_prio = 0; xd->xd_ppsm = 0; #if defined(BCM_TB_SUPPORT) || defined(BCM_POLAR_SUPPORT) xd->pkt_info.prio_int = 0; #endif /* BCM_TB_SUPPORT || BCM_POLAR_SUPPORT */ #ifdef BCM_TB_SUPPORT xd->pkt_info.multicast_group= -1; xd->pkt_info.color = bcmColorGreen; xd->pkt_info.flow_id= 0; xd->pkt_info.filter_enable= 0; #endif /* BCM_TB_SUPPORT */ xd->xd_cbk_enable = 0; xd->pkt_info.call_back = NULL; ENET_SET_MACADDR(xd->xd_mac_dst, default_mac_dst); ENET_SET_MACADDR(xd->xd_mac_src, default_mac_src); xd->xd_crc = 1; /* Re-gen CRC by default */ if (xd->pkt_info.pkt_data) { /* Has been setup before */ soc_cm_sfree(unit, xd->pkt_info.alloc_ptr); xd->pkt_info.pkt_data = NULL; } xd->pkt_info.flags = 0; if ((xd->pkt_info.alloc_ptr = (uint8 *)soc_cm_salloc(unit, xd->xd_pkt_len, "TX")) == NULL) { cli_out("WARNING: Could not allocate tx buffer. Memory error.\n"); xd->xd_init = FALSE; xd->pkt_info.pkt_data = NULL; xd->pkt_info._pkt_data.len = 0; } else { xd->pkt_info._pkt_data.data = xd->pkt_info.alloc_ptr; xd->pkt_info.pkt_data = &xd->pkt_info._pkt_data; xd->pkt_info.blk_count = 1; xd->pkt_info._pkt_data.len = xd->xd_pkt_len; } } #if 0 /*David*/ STATIC bcm_pkt_t *txrx_pkt_alloc(int unit, int nblocks, int *sizes, int flags) { bcm_pkt_t *pkt; int i, j; if (!(pkt = sal_alloc(sizeof(bcm_pkt_t), "txrx pkt"))) { return NULL; } pkt->blk_count = nblocks; if (nblocks == 1) { pkt->pkt_data = &pkt->_pkt_data; } else { if (!(pkt->pkt_data = sal_alloc(sizeof(bcm_pkt_blk_t) * nblocks, "tx pdata"))) { sal_free(pkt); return NULL; } } for (i = 0; i < nblocks; i++) { pkt->pkt_data[i].len = sizes[i]; if (!(pkt->pkt_data[i].data = soc_cm_salloc(unit, sizes[i], "txrx data"))) { for (j = 0; j < i; j++) { soc_cm_sfree(unit, pkt->pkt_data[j].data); } if (nblocks > 1) { sal_free(pkt->pkt_data); } sal_free(pkt); return NULL; } } pkt->unit = unit; pkt->flags = flags; return pkt; }
int printk_file_open(char *filename, int append) { #ifndef NO_FILEIO if (file_nm) { printk_file_close(); } if ((file_fp = sal_fopen(filename, append ? "a" : "w")) == 0) { perror("Error opening file"); return -1; } file_nm = sal_strcpy((char *)sal_alloc(sal_strlen(filename) + 1, __FILE__), filename); #endif /* NO_FILEIO */ return 0; }
sal_sem_t sal_sem_create(char *desc, int binary, int initial_count) { sem_ctrl_t *s; if ((s = sal_alloc(sizeof(*s), desc)) != 0) { sema_init(&s->sem, initial_count); s->binary = binary; if (s->binary) { init_waitqueue_head(&s->wq); } } return (sal_sem_t) s; }
/* * Function: * sal_config_parse * Purpose: * Parse a single input line. * Parameters: * str - pointer to null terminated input line. * Returns: * NULL - failed to parse * !NULL - pointer to sc entry. * Notes: * Does not modify input line. */ static sc_t * sal_config_parse(char *str) { sc_t *sc; sc = (sc_t *)sal_alloc(sizeof(sc_t), "config parse"); if (!sc || !sal_config_get_lvalue(str, sc) || !sal_config_get_rvalue(str, sc)) { return NULL; } sc->sc_next = NULL; return sc; }
int bcm_esw_auth_init(int unit) { bcm_port_t port; int rv = BCM_E_NONE, max_num_port = 0; if (!SOC_UNIT_VALID(unit)) { return BCM_E_UNIT; } if (!(soc_feature(unit, soc_feature_field))) { return (BCM_E_UNAVAIL); } if (auth_cntl[unit] != NULL) { rv = bcm_esw_auth_detach(unit); BCM_IF_ERROR_RETURN(rv); } max_num_port = SOC_MAX_NUM_PORTS; #ifdef BCM_KATANA2_SUPPORT if (soc_feature(unit, soc_feature_linkphy_coe) || soc_feature(unit, soc_feature_subtag_coe)) { max_num_port = SOC_MAX_NUM_PP_PORTS; } #endif auth_cntl[unit] = sal_alloc(max_num_port * sizeof(bcm_auth_cntl_t), "auth_cntl"); if (auth_cntl[unit] == NULL) { return BCM_E_MEMORY; } sal_memset(auth_cntl[unit], 0, max_num_port * sizeof(bcm_auth_cntl_t)); for (port = 0; port < max_num_port; port++) { auth_cntl[unit][port].mode = BCM_AUTH_MODE_UNCONTROLLED; if (soc_feature(unit, soc_feature_field)) { BCM_IF_ERROR_RETURN(_auth_field_remove_all(unit, port)); } } rv = bcm_esw_linkscan_register(unit, _auth_linkscan_cb); BCM_IF_ERROR_RETURN(rv); cb_cntl[unit].registered = TRUE; return BCM_E_NONE; }
void _ct_echo_async(int unit, cpudb_key_t dest_key, char *str, int depth, int mode, int cte_flags, int minlen) { void *cookie = NULL; _echo_cb_async_t *async_data = NULL; _echo_payload_t payload; int rv = BCM_E_NONE; int verbose = cte_flags & CTE_FLAGS_VERBOSE; if (!_ct_echo_pkt_create(&payload, str, mode, cte_flags, minlen)) { return; } payload.pkt_flags |= CTE_FLAGS_ASYNC_FREE; if ((async_data = sal_alloc(sizeof(*async_data), "ct-echo")) == NULL) { cli_out("Could not alloc memory for async data\n"); return; } async_data->unit = unit; cookie = (void *)async_data; if (verbose) { cli_out("CT echo: Sending out %s echo request to CPU key " CPUDB_KEY_FMT ", depth %d, flags 0x%x\n", cte_mode_list[mode], CPUDB_KEY_DISP(dest_key), depth, payload.pkt_flags); } rv = _send_echo_pkt(ECHO_BASE_CLI_ID + mode, payload.payload_buf, payload.payload_len, depth, payload.pkt_flags, mode, verbose, dest_key, cookie); /* * Free buffers if atp tx was not successful. When atp tx is * successful , buffers are freed by the callback routine. */ if (BCM_FAILURE(rv)) { cli_out("%s tx returns %d (%s)\n", cte_mode_list[mode], rv, bcm_errmsg(rv)); sal_dma_free(payload.pkt_buf); sal_free(async_data); } else { cli_out("Echo sent successfully\n"); } }
int _bcm_tr2_port_vpd_bitmap_alloc(int unit) { int num_profiles; if (vpd_bitmap[unit]) { sal_free(vpd_bitmap[unit]); vpd_bitmap[unit] = NULL; } num_profiles = soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm) / soc_mem_index_count(unit, VLAN_PROTOCOLm); vpd_bitmap[unit] = sal_alloc(SHR_BITALLOCSIZE(num_profiles), "vpd_bitmap"); if (vpd_bitmap[unit] == NULL) { return BCM_E_MEMORY; } sal_memset(vpd_bitmap[unit], 0, SHR_BITALLOCSIZE(num_profiles)); return BCM_E_NONE; }
STATIC int _auth_maclist_insert(auth_mac_t **list, bcm_mac_t mac, auth_mac_p *ins) { auth_mac_p entry = NULL; if (_auth_maclist_lookup(list, mac, &entry) > 0) { return BCM_E_EXISTS; } if ((entry = sal_alloc(sizeof(auth_mac_t), "maclist")) == NULL) { return BCM_E_MEMORY; } sal_memset(entry, 0, sizeof(auth_mac_t)); sal_memcpy(entry->mac, mac, sizeof(bcm_mac_t)); entry->next = *list; *list = entry; *ins = entry; return BCM_E_NONE; }
int phy_null_init(int unit, soc_port_t port) { if (unit < SOC_MAX_NUM_DEVICES) { if (NULL == saved_data[unit]) { saved_data[unit] = sal_alloc(sizeof(*saved_data[unit]), "NULL PHY driver data"); if (NULL == saved_data[unit]) { return SOC_E_MEMORY; } sal_memset(saved_data[unit], 0, sizeof(*saved_data[unit])); } if (SOC_PORT_VALID(unit, port)) { saved_data[unit]->speed[port] = 0; _phy_null_port_ability_init(unit, port, &(saved_data[unit]->null_phy_ability[port])); } } return SOC_E_NONE; }
STATIC int _bcm_regex_report_init(int unit) { _bcm_ft_report_ctrl_t *rctrl = _bcm_ft_report_ctrl[unit]; LOG_VERBOSE(BSL_LS_BCM_INTR, (BSL_META_U(unit, " _bcm_regex_report_init\n"))); if (rctrl == NULL) { rctrl = sal_alloc(sizeof(_bcm_ft_report_ctrl_t), "Re_Report_ctrl Data"); if (rctrl == NULL) { return BCM_E_MEMORY; } sal_memset(rctrl, 0, sizeof(_bcm_ft_report_ctrl_t)); _bcm_ft_report_ctrl[unit] = rctrl; rctrl->pid = SAL_THREAD_ERROR; } return BCM_E_NONE; }
static int _bcm_pkt_data_alloc(int unit, int size, bcm_pkt_blk_t *pkt_data) { int aunit; int rv = BCM_E_MEMORY; /* allocation unit, which may not be the same as unit */ aunit = _bcm_pkt_allocator_unit(unit); BCM_UNIT_BUSY(aunit); /* If aunit == NO_ALLOCATOR_UNIT, use a heap allocator, because there are no DMAable devices available. */ pkt_data->data = (aunit == NO_ALLOCATOR_UNIT) ? sal_alloc(size, "pkt alloc data") : soc_cm_salloc(aunit, size, "pkt alloc data"); if (pkt_data->data) { pkt_data->len = size; rv = BCM_E_NONE; } BCM_UNIT_IDLE(aunit); return rv; }
/** * Function: * ces_test_create_service() * Purpose: * Create a CES service * Parameters: * unit - (IN) Unit number. * service - CES service number * Returns: * Nothing * Notes: */ int ces_test_create_service(int unit, bcm_ces_service_t service, bcm_ces_encapsulation_t encap, int vlan, int ip_version, bcm_port_t port, uint32 start, uint32 end) { bcm_ces_service_config_t *config; uint8 mac[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; uint8 ipv6Address[16] = {0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }; int rc = 0; int i; uint32 num_slots; if (start == 0) num_slots = 0; else num_slots = end - start + 1; /* * Setup service configuration. In this instance it will be: * * encap: ETH loopback to self * vlan: None * Strict header: MAC * TDM Port: Second (tdm port 40) */ config = (bcm_ces_service_config_t *)sal_alloc(sizeof(bcm_ces_service_config_t), "CES Config"); if (config == NULL) return BCM_E_MEMORY; sal_memset(config, 0, sizeof(bcm_ces_service_config_t)); /* * Channel maps */ config->ingress_channel_map.first = 0; /* The first entry is at index 0 */ if (num_slots == 0) { config->ingress_channel_map.size = 1; /* One entry in the table */ config->ingress_channel_map.circuit_id[0] = port; /* TDM port */ config->ingress_channel_map.slot[0] = 0; /* Setting slot zero indicates that the whole T1 is used */ } else { config->ingress_channel_map.size = num_slots; /* One entry in the table */ for (i = 0; i < num_slots; i++) { config->ingress_channel_map.circuit_id[i] = port; /* TDM port */ config->ingress_channel_map.slot[i] = start; start++; } } /* * The egress map is a copy of the ingress map */ sal_memcpy(&config->egress_channel_map, &config->ingress_channel_map, sizeof(bcm_ces_channel_map_t)); /* * Ingress channel config */ config->ingress_channel_config.dba = FALSE; config->ingress_channel_config.auto_r_bit = TRUE; config->ingress_channel_config.mef_len_support = FALSE; config->ingress_channel_config.pbf_size = 2048; /* * Egress channel config */ config->egress_channel_config.packet_sync_selector = 0; config->egress_channel_config.rtp_exists = FALSE; config->egress_channel_config.frames_per_packet = BCM_CES_FRAMES_PER_PACKET; config->egress_channel_config.jbf_ring_size = BCM_CES_JBF_RING_SIZE; config->egress_channel_config.jbf_win_size = BCM_CES_JBF_WINDOW_SIZE; config->egress_channel_config.jbf_bop = BCM_CES_JBF_BREAK_OUT_POINT; /* * Packet header */ config->encapsulation = encap; config->header.encapsulation = encap; sal_memcpy(config->header.eth.source, mac, sizeof(mac)); sal_memcpy(config->header.eth.destination, mac, sizeof(mac)); switch(encap) { case bcmCesEncapsulationEth: config->header.vc_label = 0xAA00 + service; /* * Strict header */ sal_memcpy(config->strict_data.eth.source, mac, sizeof(mac)); break; case bcmCesEncapsulationIp: if (ip_version == bcmCesIpV4) { config->header.ip_version = bcmCesIpV4; config->header.ipv4.source = 0x0a0a0a0a; config->header.ipv4.destination = 0x0a0a0a0a; config->header.ipv4.ttl = 10; config->strict_data.ipv4.source = config->header.ipv4.destination; } else if (ip_version == bcmCesIpV6) { config->header.ip_version = bcmCesIpV6; sal_memcpy(config->header.ipv6.source, ipv6Address, sizeof(ip6_addr_t)); sal_memcpy(config->header.ipv6.destination, ipv6Address, sizeof(ip6_addr_t)); config->header.ipv6.hop_limit = 255; sal_memcpy(config->strict_data.ipv6.source, config->header.ipv6.destination, sizeof(ip6_addr_t)); } config->header.udp.source = 0xAA00 + service; config->header.udp.destination = 0xAA00 + service; config->strict_data.ip_version = config->header.ip_version; break; case bcmCesEncapsulationMpls: config->header.vc_label = 0xAA00 + service; config->header.mpls_count = 1; config->header.mpls[0].label = 0xAA00 + service; config->header.mpls[0].experimental = 0x12345678; config->header.mpls[0].ttl = 10; break; case bcmCesEncapsulationL2tp: config->encapsulation = bcmCesEncapsulationL2tp; config->header.encapsulation = bcmCesEncapsulationL2tp; if (ip_version == bcmCesIpV4) { config->header.ip_version = bcmCesIpV4; config->header.ipv4.source = 0x0a0a0a0a; config->header.ipv4.destination = 0x0a0a0a0a; config->header.ipv4.ttl = 10; config->strict_data.ipv4.source = config->header.ipv4.destination; } else if (ip_version == bcmCesIpV6) { config->header.ip_version = bcmCesIpV6; sal_memcpy(config->header.ipv6.source, ipv6Address, sizeof(ip6_addr_t)); sal_memcpy(config->header.ipv6.destination, ipv6Address, sizeof(ip6_addr_t)); config->header.ipv6.hop_limit = 255; sal_memcpy(config->strict_data.ipv6.source, config->header.ipv6.destination, sizeof(ip6_addr_t)); } config->header.vc_label = 0xAA00 + service; config->header.l2tpv3_count = 1; config->header.l2tpv3.udp_mode = 1; /* Using UDP */ config->header.l2tpv3.header = 0x30000; /* Header */ config->header.l2tpv3.session_local_id = 0xAA00 + service; /* Session local ID */ config->header.l2tpv3.session_peer_id = 0xAA00 + service; /* Session peer ID */ config->header.l2tpv3.local_cookie1 = 1; /* Local cookie 1 */ config->header.l2tpv3.local_cookie2 = 2; /* Local cookie 2 */ config->header.l2tpv3.peer_cookie1 = 1; /* Peer cookie 1 */ config->header.l2tpv3.peer_cookie2 = 2; /* Peer cookie 2 */ config->header.udp.destination = 1701; config->header.udp.source = 1701; /* * Strict header */ config->strict_data.encapsulation = bcmCesEncapsulationL2tp; config->strict_data.l2tpv3_count = config->header.l2tpv3_count; config->strict_data.l2tpv3.local_cookie1 = config->header.l2tpv3.local_cookie1; config->strict_data.ip_version = config->header.ip_version; break; } /* * VLAN? */ if (vlan) { config->header.vlan_count = 1; config->header.vlan[0].vid = 5; config->header.vlan[0].priority = 1; config->strict_data.vlan_count = 1; config->strict_data.vlan[0].vid = config->header.vlan[0].vid; } /* * Create service */ rc = bcm_ces_service_create(unit, BCM_CES_WITH_ID, config, &service); if (rc != BCM_E_NONE) { return -1; } sal_free(config); return rc; }
/** * Function: * ces_test_prbs() * Purpose: * Run a PRBS test on the specified service. * Parameters: * unit - (IN) Unit number. * service - CES service number * Returns: * Nothing * Notes: */ int ces_test_prbs(int unit, bcm_ces_service_t service, uint32 time) { bcm_ces_service_config_t *config; int rc; int status; int j; int lock_stable; config = (bcm_ces_service_config_t *)sal_alloc(sizeof(bcm_ces_service_config_t), "CES Config"); if (config == NULL) { printk("Out of memory\n"); return -1; } /* * Get service configuration */ rc = bcm_ces_service_config_get(unit, service, config); if (rc != BCM_E_NONE) { sal_free(config); return rc; } /* * Enable PRBS */ rc = bcm_esw_ces_framer_prbs_set(unit, config->egress_channel_map.circuit_id[0], 1, 2, config->ingress_channel_map.slot[0], config->ingress_channel_map.slot[0] + config->ingress_channel_map.size - 1); /* * Test */ j = 0; status = 0x0100; lock_stable = 0; printk("Waiting for PRBS pattern lock..."); do { sal_sleep(1); j++; bcm_esw_ces_framer_prbs_status(unit, config->egress_channel_map.circuit_id[0], &status); if (status) { lock_stable = 0; } else { lock_stable++; } } while (j < BCM_CES_TEST_LOCK_LOOP_COUNT && lock_stable < BCM_CES_TEST_LOCK_STABLE_COUNT); if (status == 0) { printk("Locked, checking stability for %d seconds...", time); for (j = 0; j < time; j++) { sal_sleep(1); bcm_esw_ces_framer_prbs_status(unit, config->egress_channel_map.circuit_id[0], &status); if (status) { if (status & 0x0100) { printk(" Loss of lock"); rc = BCM_CES_TEST_E_PRBS_NO_LOCK; } else { printk(" Errors:%d", (0x00FF & status)); rc = BCM_CES_TEST_E_PRBS_ERRORS; } break; } } if (!status) { printk("OK"); } } else { if (status & 0x0100) { printk(" No pattern lock"); rc = BCM_CES_TEST_E_PRBS_NO_LOCK; } else { printk(" Errors:%d", (0x00FF & status)); rc = BCM_CES_TEST_E_PRBS_ERRORS; } } printk("\n"); /* * Turn off PRBS */ #if 0 bcm_esw_ces_framer_prbs_set(unit, config->egress_channel_map.circuit_id[0], 1, 0, 0, 0); #else printk("<<<< PRBS STILL ON >>>>\n"); #endif sal_free(config); return rc; }
int _cmd_multicast_traverse_cb(int unit, bcm_multicast_t group, uint32 flags, void *user_data) { int rv, i, port_count; bcm_gport_t *port_array = NULL; bcm_if_t *encap_id_array = NULL; int port_max = 0; /* first, get the port count. * port_max = 0, port_array & encap_id_array = NULL */ rv = bcm_multicast_egress_get(unit, group, port_max, port_array, encap_id_array, &port_count); if (rv < 0) { cli_out("%s ERROR: egress port count get failed - %s\n", ARG_CMD((args_t *)user_data), bcm_errmsg(rv)); return rv; } if (port_count == 0) { return BCM_E_NONE; } /* allocate proper size port_array & encap_id_array */ port_array = (bcm_gport_t *)sal_alloc(sizeof(bcm_gport_t) * port_count, "_cmd_multicast_traverse_cb : port_array"); if (port_array == NULL) { cli_out("%s ERROR: port_array mem alloc failed\n", ARG_CMD((args_t *)user_data)); return BCM_E_MEMORY; } encap_id_array = (bcm_if_t *)sal_alloc(sizeof(bcm_if_t) *port_count, "_cmd_multicast_traverse_cb : encap_id_array"); if (encap_id_array == NULL) { cli_out("%s ERROR: encap_id_array mem alloc failed\n", ARG_CMD((args_t *)user_data)); sal_free(port_array); return BCM_E_MEMORY; } rv = bcm_multicast_egress_get(unit, group, port_count, port_array, encap_id_array, &port_count); if (rv < 0) { cli_out("%s ERROR: egress get failure - %s\n", ARG_CMD((args_t *)user_data), bcm_errmsg(rv)); sal_free(port_array); sal_free(encap_id_array); return rv; } if (_BCM_MULTICAST_TYPE_GET(group) >= COUNTOF(cmd_multicast_parse_type)) { cli_out("Group 0x%x (%s)\n", group, "UNKNOWN"); } else { cli_out("Group 0x%x (%s)\n", group, cmd_multicast_parse_type[_BCM_MULTICAST_TYPE_GET(group)]); } for (i = 0; i < port_count; i++) { cli_out("\tport %s, encap id %d\n", mod_port_name(unit, -1, port_array[i]), encap_id_array[i]); } sal_free(port_array); sal_free(encap_id_array); return BCM_E_NONE; }
char * sal_readline(char *prompt, char *buf, int bufsize, char *defl) { char *s, *full_prompt, *cont_prompt; #ifdef INCLUDE_EDITLINE extern void rl_prompt_set(CONST char *prompt); #else char *t; #endif int len; if (bufsize == 0) return NULL; cont_prompt = prompt[0] ? "? " : ""; full_prompt = sal_alloc(sal_strlen(prompt) + (defl ? sal_strlen(defl) : 0) + 8, __FILE__); sal_strcpy(full_prompt, prompt); if (defl) sal_sprintf(full_prompt + sal_strlen(full_prompt), "[%s] ", defl); #ifdef INCLUDE_EDITLINE printk_file("%s", full_prompt); s = readline(full_prompt); #else /* !INCLUDE_EDITLINE */ t = sal_alloc(bufsize, __FILE__); #if defined(KEYSTONE) && defined(__ECOS) diag_printf("%s", full_prompt); #else printk("%s", full_prompt); #endif if ((s = sal_console_gets(t, bufsize)) == 0) { sal_free(t); } else { s[bufsize - 1] = 0; if ((t = strchr(s, '\n')) != 0) { *t = 0; /* Replace garbage characters with spaces */ } for (t = s; *t; t++) { if (*t < 32 && *t != 7 && *t != 9) { *t = ' '; } } } #endif /* !INCLUDE_EDITLINE */ if (s == 0) { /* Handle Control-D */ buf[0] = 0; /* EOF */ buf = 0; goto done; } else { printk_file("%s\n", s); } len = 0; if (s[0] == 0) { if (defl && buf != defl) { if ((len = sal_strlen(defl)) >= bufsize) { len = bufsize - 1; } sal_memcpy(buf, defl, len); } } else { if ((len = sal_strlen(s)) >= bufsize) { len = bufsize - 1; printk("WARNING: input line truncated to %d chars\n", len); } sal_memcpy(buf, s, len); } buf[len] = 0; sal_free(s); /* * If line ends in a backslash, perform a continuation prompt. */ if (sal_strlen(buf) != 0) { /* * Ensure that there is atleast one character available */ s = buf + sal_strlen(buf) - 1; if (*s == '\\' && sal_readline(cont_prompt, s, bufsize - (s - buf), 0) == 0) { buf = 0; } } done: #ifdef INCLUDE_EDITLINE rl_prompt_set(NULL); #endif sal_free(full_prompt); return buf; }
int shr_mem_avl_realloc(shr_mem_avl_t *mem_avl, int size, unsigned int addr) { shr_mem_avl_entry_pt curr_entry; shr_mem_avl_entry_pt split_entry; void *pTmpVoid; int nStatus; assert(mem_avl != 0); if (0 == size) { /* * What does realloc do here? */ return( -1 ); } /* use loose search to find target block */ curr_entry = _shr_mem_avl_dll_search(mem_avl, addr, 1); if (NULL == curr_entry) { /* * This is bad, we couldn't find a * block containing this address */ return( -1 ); } /* verify size and availability */ if ( ((curr_entry->addr + curr_entry->size - 1) < (addr + size - 1)) || (curr_entry->used) ) { return( -1 ); } /* * Remove the node from the free tree */ /* * ENHANCEME: do something with the status from avl_remove */ nStatus = _shr_mem_avl_remove(mem_avl, curr_entry); assert(nStatus >= 0); /* * We have a 'free' block of memory. The starting address of this * block may not matched the target. If not, split off the first * portian and place it back into the free tree */ if (addr > curr_entry->addr) { /* * The search returned a free block that contains the * desired block. The start address is not a match so we * need to split off the portion prior to the target * address and add it back to the free tree. */ pTmpVoid = NULL; pTmpVoid = sal_alloc(sizeof(*split_entry), "mem_avl"); if (NULL == pTmpVoid) { /* OOSM */ return( -1 ); } split_entry = (shr_mem_avl_entry_pt)pTmpVoid; sal_memset(split_entry, 0, sizeof(*split_entry)); split_entry->size = addr - curr_entry->addr; split_entry->addr = curr_entry->addr; split_entry->next = NULL; split_entry->prev = NULL; split_entry->self = split_entry; /* * Since we're splitting, we have to update the 'allocated' node's * size and address appropriately */ curr_entry->addr = addr; curr_entry->size = curr_entry->size - split_entry->size; /* * ENHANCEME: do something with the status from avl_insert */ nStatus = shr_avl_insert(mem_avl->tree, _shr_mem_avl_compare, (shr_avl_datum_t*)split_entry); assert(nStatus >= 0); _shr_mem_avl_dll_insert(mem_avl, split_entry); } if (size < curr_entry->size) { /* * The search returned a free block that is greater than * what we need. We need to split off the unused lines, * and add that back to the free tree. */ pTmpVoid = NULL; pTmpVoid = sal_alloc(sizeof(*split_entry), "mem_avl"); if (NULL == pTmpVoid) { /* OOSM */ return( -1 ); } split_entry = (shr_mem_avl_entry_pt)pTmpVoid; sal_memset(split_entry, 0, sizeof(*split_entry)); split_entry->size = curr_entry->size - size; split_entry->addr = curr_entry->addr + size; split_entry->next = NULL; split_entry->prev = NULL; split_entry->self = split_entry; /* * Since we're splitting, we have to update the 'allocated' node's * size appropriately */ curr_entry->size = size; /* * ENHANCEME: do something with the status from avl_insert */ nStatus = shr_avl_insert(mem_avl->tree, _shr_mem_avl_compare, (shr_avl_datum_t*)split_entry); assert(nStatus >= 0); _shr_mem_avl_dll_insert(mem_avl, split_entry); } /* * Now take care of the block we're interested in */ curr_entry->used = 1; return( 0 ); }
/* * Function: * _bcm_esw_stat_flex_create_ingress_uncompress_mode * Description: * Creates New Flex Ingress Uncompressed Mode * * Parameters: * unit - (IN) unit number * uncmprsd_attr_selectors - (IN) Flex attributes * mode - (OUT) Flex mode * total_counters - (OUT) Total Counters associated with new * flex uncompressed mode * * Return Value: * BCM_E_XXX * Notes: * */ static bcm_error_t _bcm_esw_stat_flex_create_ingress_uncompress_mode( int unit, bcm_stat_flex_ing_uncmprsd_attr_selectors_t *uncmprsd_attr_selectors, bcm_stat_flex_mode_t *mode, uint32 *total_counters) { bcm_stat_flex_mode_t mode_l=0; bcm_stat_flex_ing_pkt_attr_bits_t pkt_attr_bits={0}; uint32 total_ingress_bits=0; uint32 index=0; bcm_stat_flex_ingress_mode_t *flex_ingress_mode=NULL; bcm_stat_flex_ing_uncmprsd_attr_selectors_t uncmprsd_attr_selectors_l; uint32 num_flex_ingress_pools; num_flex_ingress_pools = SOC_INFO(unit).num_flex_ingress_pools; flex_ingress_mode = sal_alloc(sizeof(bcm_stat_flex_ingress_mode_t), "flex_ingress_mode"); if (flex_ingress_mode == NULL) { return BCM_E_MEMORY; } for (index =0; index < BCM_STAT_FLEX_COUNTER_MAX_MODE; index++) { if (_bcm_esw_stat_flex_get_ingress_mode_info( unit, index, flex_ingress_mode) == BCM_E_NONE) { if (flex_ingress_mode->ing_attr.packet_attr_type != bcmStatFlexPacketAttrTypeUncompressed) { continue; } uncmprsd_attr_selectors_l = flex_ingress_mode->ing_attr. uncmprsd_attr_selectors; if (sal_memcmp(&uncmprsd_attr_selectors_l,uncmprsd_attr_selectors, sizeof(uncmprsd_attr_selectors_l)) == 0) { *total_counters = flex_ingress_mode->total_counters; *mode=index; sal_free(flex_ingress_mode); return BCM_E_EXISTS; } } } sal_free(flex_ingress_mode); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_available_mode( unit, bcmStatFlexDirectionIngress, &mode_l)); /* Step2: Packet Attribute selection */ if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_CNG_ATTR_BITS) { pkt_attr_bits.cng = ing_pkt_attr_bits_g.cng; pkt_attr_bits.cng_mask = ing_pkt_attr_bits_g.cng_mask; pkt_attr_bits.cng_pos = ing_pkt_attr_bits_g.cng_pos; total_ingress_bits +=pkt_attr_bits.cng; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IFP_CNG_ATTR_BITS) { pkt_attr_bits.ifp_cng = ing_pkt_attr_bits_g.ifp_cng ; pkt_attr_bits.ifp_cng_mask = ing_pkt_attr_bits_g.ifp_cng_mask; pkt_attr_bits.ifp_cng_pos = ing_pkt_attr_bits_g.ifp_cng_pos; total_ingress_bits +=pkt_attr_bits.ifp_cng; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INT_PRI_ATTR_BITS) { pkt_attr_bits.int_pri = ing_pkt_attr_bits_g.int_pri ; pkt_attr_bits.int_pri_mask = ing_pkt_attr_bits_g.int_pri_mask ; pkt_attr_bits.int_pri_pos = ing_pkt_attr_bits_g.int_pri_pos ; total_ingress_bits +=pkt_attr_bits.int_pri; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_VLAN_FORMAT_ATTR_BITS) { pkt_attr_bits.vlan_format = ing_pkt_attr_bits_g.vlan_format ; pkt_attr_bits.vlan_format_mask = ing_pkt_attr_bits_g.vlan_format_mask ; pkt_attr_bits.vlan_format_pos = ing_pkt_attr_bits_g.vlan_format_pos ; total_ingress_bits +=pkt_attr_bits.vlan_format; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_OUTER_DOT1P_ATTR_BITS) { pkt_attr_bits.outer_dot1p = ing_pkt_attr_bits_g.outer_dot1p; pkt_attr_bits.outer_dot1p_mask = ing_pkt_attr_bits_g.outer_dot1p_mask; pkt_attr_bits.outer_dot1p_pos = ing_pkt_attr_bits_g.outer_dot1p_pos; total_ingress_bits +=pkt_attr_bits.outer_dot1p; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INNER_DOT1P_ATTR_BITS) { pkt_attr_bits.inner_dot1p = ing_pkt_attr_bits_g.inner_dot1p ; pkt_attr_bits.inner_dot1p_mask = ing_pkt_attr_bits_g.inner_dot1p_mask ; pkt_attr_bits.inner_dot1p_pos = ing_pkt_attr_bits_g.inner_dot1p_pos ; total_ingress_bits += pkt_attr_bits.inner_dot1p; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_INGRESS_PORT_ATTR_BITS) { pkt_attr_bits.ing_port = ing_pkt_attr_bits_g.ing_port; pkt_attr_bits.ing_port_mask = ing_pkt_attr_bits_g.ing_port_mask ; pkt_attr_bits.ing_port_pos = ing_pkt_attr_bits_g.ing_port_pos ; total_ingress_bits += pkt_attr_bits.ing_port; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_TOS_ATTR_BITS) { pkt_attr_bits.tos = ing_pkt_attr_bits_g.tos ; pkt_attr_bits.tos_mask = ing_pkt_attr_bits_g.tos_mask ; pkt_attr_bits.tos_pos = ing_pkt_attr_bits_g.tos_pos ; total_ingress_bits += pkt_attr_bits.tos; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_PKT_RESOLUTION_ATTR_BITS) { pkt_attr_bits.pkt_resolution = ing_pkt_attr_bits_g.pkt_resolution ; pkt_attr_bits.pkt_resolution_mask= ing_pkt_attr_bits_g. pkt_resolution_mask; pkt_attr_bits.pkt_resolution_pos= ing_pkt_attr_bits_g. pkt_resolution_pos; total_ingress_bits +=pkt_attr_bits.pkt_resolution ; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_SVP_TYPE_ATTR_BITS) { pkt_attr_bits.svp_type = ing_pkt_attr_bits_g.svp_type ; pkt_attr_bits.svp_type_mask = ing_pkt_attr_bits_g.svp_type_mask ; pkt_attr_bits.svp_type_pos = ing_pkt_attr_bits_g.svp_type_pos ; total_ingress_bits +=pkt_attr_bits.svp_type; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_DROP_ATTR_BITS) { pkt_attr_bits.drop = ing_pkt_attr_bits_g.drop ; pkt_attr_bits.drop_mask = ing_pkt_attr_bits_g.drop_mask ; pkt_attr_bits.drop_pos = ing_pkt_attr_bits_g.drop_pos ; total_ingress_bits += pkt_attr_bits.drop; } if (uncmprsd_attr_selectors->uncmprsd_attr_bits_selector & BCM_STAT_FLEX_ING_UNCOMPRESSED_USE_IP_PKT_ATTR_BITS) { pkt_attr_bits.ip_pkt = ing_pkt_attr_bits_g.ip_pkt ; pkt_attr_bits.ip_pkt_mask = ing_pkt_attr_bits_g.ip_pkt_mask; pkt_attr_bits.ip_pkt_pos = ing_pkt_attr_bits_g.ip_pkt_pos; total_ingress_bits += pkt_attr_bits.ip_pkt; } if (total_ingress_bits > 8) { return BCM_E_PARAM; } /* Step3: Packet Attribute filling */ BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_ingress_selector_keys(unit, bcmStatFlexPacketAttrTypeUncompressed, _ingress_pkt_selector_key_reg[mode_l], pkt_attr_bits)); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_ingress_selector_keys(unit, bcmStatFlexPacketAttrTypeUncompressed, _ingress_pkt_selector_key_reg[mode_l+4], pkt_attr_bits)); /* Step4: Offset table filling */ for (index=0;index < num_flex_ingress_pools ; index++) { BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_offset_table(unit, bcmStatFlexDirectionIngress, ING_FLEX_CTR_OFFSET_TABLE_0m+index, mode_l, 256, uncmprsd_attr_selectors->offset_table_map)); } /* Step5: Final: reserve mode and return */ *total_counters = uncmprsd_attr_selectors->total_counters; *mode=mode_l; return BCM_E_NONE; }
/* * Function: * _bcm_esw_stat_flex_create_ingress_compress_mode * Description: * Creates New Flex Ingress Compressed Mode * Parameters: * unit - (IN) unit number * cmprsd_attr_selectors - (IN) Flex Compressed Attribute Selector * mode - (OUT) Flex mode * total_counters - (OUT) Total Counters associated with new * Return Value: * BCM_E_XXX * Notes: * */ static bcm_error_t _bcm_esw_stat_flex_create_ingress_compress_mode( int unit, bcm_stat_flex_ing_cmprsd_attr_selectors_t *cmprsd_attr_selectors, bcm_stat_flex_mode_t *mode, uint32 *total_counters) { bcm_stat_flex_mode_t mode_l=0; bcm_stat_flex_ing_pkt_attr_bits_t pkt_attr_bits={0}; uint32 total_ingress_bits=0; uint32 index=0; bcm_stat_flex_ingress_mode_t *flex_ingress_mode=NULL; bcm_stat_flex_ing_pkt_attr_bits_t pkt_attr_bits_exist={0}; uint32 num_flex_ingress_pools; /*soc_mem_info_t *mem_info; */ uint32 pri_cnf_map_used=0; uint32 pkt_pri_map_used=0; uint32 port_map_used=0; uint32 tos_map_used=0; uint32 pkt_res_map_used=0; uint32 alloc_size=0; ing_flex_ctr_pkt_pri_map_entry_t *pkt_pri_map_dma=NULL; uint32 pkt_pri_map_value=0; ing_flex_ctr_pkt_res_map_entry_t *pkt_res_map_dma=NULL; uint32 pkt_res_map_value=0; ing_flex_ctr_port_map_entry_t *port_map_dma=NULL; uint32 port_map_value=0; ing_flex_ctr_pri_cng_map_entry_t *pri_cng_map_dma=NULL; uint32 pri_cng_map_value=0; ing_flex_ctr_tos_map_entry_t *tos_map_dma=NULL; uint32 tos_map_value=0; num_flex_ingress_pools = SOC_INFO(unit).num_flex_ingress_pools; flex_ingress_mode = sal_alloc(sizeof(bcm_stat_flex_ingress_mode_t), "flex_ingress_mode"); if (flex_ingress_mode == NULL) { return BCM_E_MEMORY; } for (index =0 ; index < BCM_STAT_FLEX_COUNTER_MAX_MODE ; index++) { sal_memset(flex_ingress_mode,0,sizeof(bcm_stat_flex_ingress_mode_t)); if (_bcm_esw_stat_flex_get_ingress_mode_info( unit, index, flex_ingress_mode) == BCM_E_NONE) { if (flex_ingress_mode->ing_attr.packet_attr_type != bcmStatFlexPacketAttrTypeCompressed) { continue; } pkt_attr_bits_exist = flex_ingress_mode->ing_attr. cmprsd_attr_selectors.pkt_attr_bits; if ((pkt_attr_bits_exist.cng == cmprsd_attr_selectors->pkt_attr_bits.cng) && (pkt_attr_bits_exist.ifp_cng == cmprsd_attr_selectors->pkt_attr_bits.ifp_cng) && (pkt_attr_bits_exist.int_pri == cmprsd_attr_selectors->pkt_attr_bits.int_pri) && (pkt_attr_bits_exist.vlan_format == cmprsd_attr_selectors->pkt_attr_bits.vlan_format) && (pkt_attr_bits_exist.outer_dot1p == cmprsd_attr_selectors->pkt_attr_bits.outer_dot1p) && (pkt_attr_bits_exist.inner_dot1p == cmprsd_attr_selectors->pkt_attr_bits.inner_dot1p) && (pkt_attr_bits_exist.ing_port == cmprsd_attr_selectors->pkt_attr_bits.ing_port) && (pkt_attr_bits_exist.tos == cmprsd_attr_selectors->pkt_attr_bits.tos) && (pkt_attr_bits_exist.pkt_resolution == cmprsd_attr_selectors->pkt_attr_bits.pkt_resolution) && (pkt_attr_bits_exist.svp_type == cmprsd_attr_selectors->pkt_attr_bits.svp_type) && (pkt_attr_bits_exist.drop == cmprsd_attr_selectors->pkt_attr_bits.drop) && (pkt_attr_bits_exist.ip_pkt == cmprsd_attr_selectors->pkt_attr_bits.ip_pkt)) { *total_counters = flex_ingress_mode->total_counters; *mode=index; sal_free(flex_ingress_mode); return BCM_E_EXISTS; } if ((pkt_attr_bits_exist.cng) || (pkt_attr_bits_exist.ifp_cng) || (pkt_attr_bits_exist.int_pri)) { pri_cnf_map_used=1; } if ((pkt_attr_bits_exist.vlan_format) || (pkt_attr_bits_exist.outer_dot1p) || (pkt_attr_bits_exist.inner_dot1p)) { pkt_pri_map_used=1; } if (pkt_attr_bits_exist.ing_port) { port_map_used=1; } if (pkt_attr_bits_exist.tos) { tos_map_used=1; } if ((pkt_attr_bits_exist.pkt_resolution) || (pkt_attr_bits_exist.svp_type) || (pkt_attr_bits_exist.drop)) { pkt_res_map_used=1; } } } sal_free(flex_ingress_mode); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_available_mode( unit, bcmStatFlexDirectionIngress, &mode_l)); if (cmprsd_attr_selectors->pkt_attr_bits.cng !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.cng > ing_pkt_attr_bits_g.cng) { return BCM_E_PARAM; } if (pri_cnf_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.cng; } if (cmprsd_attr_selectors->pkt_attr_bits.ifp_cng !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.ifp_cng > ing_pkt_attr_bits_g.ifp_cng) { return BCM_E_PARAM; } if (pri_cnf_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.ifp_cng; } if (cmprsd_attr_selectors->pkt_attr_bits.int_pri !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.int_pri > ing_pkt_attr_bits_g.int_pri) { return BCM_E_PARAM; } if (pri_cnf_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.int_pri; } if (cmprsd_attr_selectors->pkt_attr_bits.vlan_format !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.vlan_format > ing_pkt_attr_bits_g.vlan_format) { return BCM_E_PARAM; } if (pkt_pri_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.vlan_format; } if (cmprsd_attr_selectors->pkt_attr_bits.outer_dot1p !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.outer_dot1p > ing_pkt_attr_bits_g.outer_dot1p) { return BCM_E_PARAM; } if (pkt_pri_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.outer_dot1p ; } if (cmprsd_attr_selectors->pkt_attr_bits.inner_dot1p !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.inner_dot1p > ing_pkt_attr_bits_g.inner_dot1p) { return BCM_E_PARAM; } if (pkt_pri_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.inner_dot1p ; } if (cmprsd_attr_selectors->pkt_attr_bits.ing_port !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.ing_port > ing_pkt_attr_bits_g.ing_port) { return BCM_E_PARAM; } if (port_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.ing_port ; } if (cmprsd_attr_selectors->pkt_attr_bits.tos !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.tos > ing_pkt_attr_bits_g.tos) { return BCM_E_PARAM; } if (tos_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.tos ; } if (cmprsd_attr_selectors->pkt_attr_bits.pkt_resolution !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.pkt_resolution > ing_pkt_attr_bits_g.pkt_resolution) { return BCM_E_PARAM; } if (pkt_res_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits. pkt_resolution ; } if (cmprsd_attr_selectors->pkt_attr_bits.svp_type !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.svp_type > ing_pkt_attr_bits_g.svp_type) { return BCM_E_PARAM; } if (pkt_res_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.svp_type ; } if (cmprsd_attr_selectors->pkt_attr_bits.drop !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.drop > ing_pkt_attr_bits_g.drop) { return BCM_E_PARAM; } if (pkt_res_map_used==1) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.drop ; } if (cmprsd_attr_selectors->pkt_attr_bits.ip_pkt !=0) { if (cmprsd_attr_selectors->pkt_attr_bits.ip_pkt > ing_pkt_attr_bits_g.ip_pkt) { return BCM_E_PARAM; } total_ingress_bits +=cmprsd_attr_selectors->pkt_attr_bits.ip_pkt ; } if (total_ingress_bits > 8) { return BCM_E_PARAM; } pkt_attr_bits = cmprsd_attr_selectors->pkt_attr_bits; /* Step3: Fill up map array */ if ((pkt_attr_bits.cng != 0) || (pkt_attr_bits.ifp_cng) || (pkt_attr_bits.int_pri)) { alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_PRI_CNG_MAPm) * sizeof(ing_flex_ctr_pri_cng_map_entry_t); pri_cng_map_dma=soc_cm_salloc( unit,alloc_size, "pri_cng_map"); if (pri_cng_map_dma == NULL) { return BCM_E_MEMORY; } sal_memset(pri_cng_map_dma, 0,alloc_size); if (soc_mem_read_range( unit, ING_FLEX_CTR_PRI_CNG_MAPm, MEM_BLOCK_ANY, soc_mem_index_min(unit,ING_FLEX_CTR_PRI_CNG_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PRI_CNG_MAPm), pri_cng_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pri_cng_map_dma); return BCM_E_INTERNAL; } for (index=0; index< soc_mem_index_count(unit,ING_FLEX_CTR_PRI_CNG_MAPm); index++) { pri_cng_map_value=cmprsd_attr_selectors->pri_cnf_attr_map[index]; soc_mem_field_set( unit, ING_FLEX_CTR_PRI_CNG_MAPm, (uint32 *)&pri_cng_map_dma[index], PRI_CNG_FNf, &pri_cng_map_value); } if (soc_mem_write_range( unit, ING_FLEX_CTR_PRI_CNG_MAPm, MEM_BLOCK_ALL, soc_mem_index_min(unit,ING_FLEX_CTR_PRI_CNG_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PRI_CNG_MAPm), pri_cng_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pri_cng_map_dma); return BCM_E_INTERNAL; } soc_cm_sfree(unit,pri_cng_map_dma); } if ((pkt_attr_bits.vlan_format != 0) || (pkt_attr_bits.outer_dot1p) || (pkt_attr_bits.inner_dot1p)) { /* Sanity Check */ alloc_size = soc_mem_index_count(unit, ING_FLEX_CTR_PKT_PRI_MAPm) * sizeof(ing_flex_ctr_pkt_pri_map_entry_t); pkt_pri_map_dma = soc_cm_salloc( unit,alloc_size, "pkt_pri_map"); if (pkt_pri_map_dma == NULL) { return BCM_E_MEMORY; } sal_memset(pkt_pri_map_dma, 0,alloc_size); if (soc_mem_read_range( unit, ING_FLEX_CTR_PKT_PRI_MAPm, MEM_BLOCK_ANY, soc_mem_index_min(unit,ING_FLEX_CTR_PKT_PRI_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PKT_PRI_MAPm), pkt_pri_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pkt_pri_map_dma); return BCM_E_INTERNAL; } for (index=0; index< soc_mem_index_count(unit, ING_FLEX_CTR_PKT_PRI_MAPm); index++) { pkt_pri_map_value= cmprsd_attr_selectors->pkt_pri_attr_map[index]; soc_mem_field_set( unit, ING_FLEX_CTR_PKT_PRI_MAPm, (uint32 *)&pkt_pri_map_dma[index], PKT_PRI_FNf, &pkt_pri_map_value); } if (soc_mem_write_range( unit, ING_FLEX_CTR_PKT_PRI_MAPm, MEM_BLOCK_ALL, soc_mem_index_min(unit,ING_FLEX_CTR_PKT_PRI_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PKT_PRI_MAPm), pkt_pri_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pkt_pri_map_dma); return BCM_E_INTERNAL; } soc_cm_sfree(unit,pkt_pri_map_dma); } if (pkt_attr_bits.ing_port != 0){ alloc_size = soc_mem_index_count(unit, ING_FLEX_CTR_PORT_MAPm) * sizeof(ing_flex_ctr_port_map_entry_t); port_map_dma = soc_cm_salloc( unit,alloc_size, "port_map"); if (port_map_dma == NULL) { return BCM_E_MEMORY; } sal_memset(port_map_dma, 0,alloc_size); if (soc_mem_read_range( unit, ING_FLEX_CTR_PORT_MAPm, MEM_BLOCK_ANY, soc_mem_index_min(unit,ING_FLEX_CTR_PORT_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PORT_MAPm), port_map_dma) != BCM_E_NONE) { soc_cm_sfree(unit,port_map_dma); return BCM_E_INTERNAL; } for (index=0; index< soc_mem_index_count(unit, ING_FLEX_CTR_PORT_MAPm); index++) { port_map_value = cmprsd_attr_selectors->port_attr_map[index]; soc_mem_field_set( unit, ING_FLEX_CTR_PORT_MAPm, (uint32 *)&port_map_dma[index], PORT_FNf, &port_map_value); } if (soc_mem_write_range( unit, ING_FLEX_CTR_PORT_MAPm, MEM_BLOCK_ALL, soc_mem_index_min(unit,ING_FLEX_CTR_PORT_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PORT_MAPm), port_map_dma) != BCM_E_NONE) { soc_cm_sfree(unit,port_map_dma); return BCM_E_INTERNAL; } soc_cm_sfree(unit,port_map_dma); } if (pkt_attr_bits.tos != 0){ alloc_size = soc_mem_index_count(unit,ING_FLEX_CTR_TOS_MAPm) * sizeof(ing_flex_ctr_tos_map_entry_t); tos_map_dma = soc_cm_salloc( unit,alloc_size, "tos_map"); if (tos_map_dma == NULL) { return BCM_E_MEMORY; } sal_memset(tos_map_dma, 0,alloc_size); if (soc_mem_read_range( unit, ING_FLEX_CTR_TOS_MAPm, MEM_BLOCK_ANY, soc_mem_index_min(unit,ING_FLEX_CTR_TOS_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_TOS_MAPm), tos_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,tos_map_dma); return BCM_E_INTERNAL; } for (index=0; index< soc_mem_index_count(unit,ING_FLEX_CTR_TOS_MAPm); index++) { tos_map_value = cmprsd_attr_selectors->tos_attr_map[index]; soc_mem_field_set( unit, ING_FLEX_CTR_TOS_MAPm, (uint32 *)&tos_map_dma[index], TOS_FNf, &tos_map_value); } if (soc_mem_write_range( unit, ING_FLEX_CTR_TOS_MAPm, MEM_BLOCK_ALL, soc_mem_index_min(unit,ING_FLEX_CTR_TOS_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_TOS_MAPm), tos_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,tos_map_dma); return BCM_E_INTERNAL; } soc_cm_sfree(unit,tos_map_dma); } if ((pkt_attr_bits.pkt_resolution != 0) || (pkt_attr_bits.svp_type) || (pkt_attr_bits.drop)){ alloc_size = soc_mem_index_count(unit, ING_FLEX_CTR_PKT_RES_MAPm) * sizeof(ing_flex_ctr_pkt_res_map_entry_t); pkt_res_map_dma= soc_cm_salloc( unit, alloc_size, "pkt_res_map"); if (pkt_res_map_dma == NULL) { return BCM_E_MEMORY; } sal_memset(pkt_res_map_dma, 0,alloc_size); if (soc_mem_read_range( unit, ING_FLEX_CTR_PKT_RES_MAPm, MEM_BLOCK_ANY, soc_mem_index_min(unit,ING_FLEX_CTR_PKT_RES_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PKT_RES_MAPm), pkt_res_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pkt_res_map_dma); return BCM_E_INTERNAL; } for (index=0; index< soc_mem_index_count(unit, ING_FLEX_CTR_PKT_RES_MAPm); index++) { pkt_res_map_value = cmprsd_attr_selectors->pkt_res_attr_map[index]; soc_mem_field_set( unit, ING_FLEX_CTR_PKT_RES_MAPm, (uint32 *)&pkt_res_map_dma[index], PKT_RES_FNf, &pkt_res_map_value); } if (soc_mem_write_range(unit, ING_FLEX_CTR_PKT_RES_MAPm, MEM_BLOCK_ALL, soc_mem_index_min(unit,ING_FLEX_CTR_PKT_RES_MAPm), soc_mem_index_max(unit,ING_FLEX_CTR_PKT_RES_MAPm), pkt_res_map_dma) != BCM_E_NONE){ soc_cm_sfree(unit,pkt_res_map_dma); return BCM_E_INTERNAL; } soc_cm_sfree(unit,pkt_res_map_dma); } /* Step4: Packet Attribute filling */ BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_ingress_selector_keys( unit, bcmStatFlexPacketAttrTypeCompressed, _ingress_pkt_selector_key_reg[mode_l], pkt_attr_bits)); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_ingress_selector_keys( unit, bcmStatFlexPacketAttrTypeCompressed, _ingress_pkt_selector_key_reg[mode_l+4], pkt_attr_bits)); /* Step5: Offset table filling */ for (index=0;index < num_flex_ingress_pools ; index++) { BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_offset_table( unit, bcmStatFlexDirectionIngress, ING_FLEX_CTR_OFFSET_TABLE_0m+index, mode_l, 256, cmprsd_attr_selectors->offset_table_map)); } /* Step6: Final: reserve mode and return */ *total_counters = cmprsd_attr_selectors->total_counters; *mode=mode_l; return BCM_E_NONE; }
int shr_mem_avl_malloc(shr_mem_avl_t *mem_avl, int size, unsigned int *addr) { shr_mem_avl_entry_t entry; shr_mem_avl_entry_pt curr_entry; shr_mem_avl_entry_pt split_entry; void *pTmpVoid; int nStatus; shr_avl_datum_t *pDatumSearch, *pDatum; assert(mem_avl != 0); assert(addr); if (0 == size) { /* * What does malloc do here? */ return( -1 ); } /* * Need to search the tree to find the best fit. */ sal_memset(&entry, 0, sizeof(entry)); entry.size = size; pDatumSearch = (shr_avl_datum_t *) &entry; pDatum = _shr_mem_avl_avl_search(mem_avl->tree, pDatumSearch); if (NULL == pDatum) { /* OOM */ return( -1 ); } curr_entry = ((shr_mem_avl_entry_pt)(pDatum))->self; if (size > curr_entry->size) { /* OOM */ return( -1 ); } /* * Remove the node from the free tree */ /* * ENHANCEME: do something with the status from avl_remove */ nStatus = _shr_mem_avl_remove(mem_avl, curr_entry); assert(nStatus >= 0); /* * We have a 'free' block of memory. It may be larger than we need, * if it is, we need to split off the extra and put that back into * the free tree */ if (size < curr_entry->size) { /* * The search returned a free block that is greater than * what we need. We need to split off the unused lines, * and add that back to the free tree. */ pTmpVoid = NULL; pTmpVoid = sal_alloc(sizeof(*split_entry), "mem_avl"); if (NULL == pTmpVoid) { /* OOSM */ return( -1 ); } split_entry = (shr_mem_avl_entry_pt)pTmpVoid; sal_memset(split_entry, 0, sizeof(*split_entry)); split_entry->size = curr_entry->size - size; split_entry->addr = curr_entry->addr + entry.size; split_entry->next = NULL; split_entry->prev = NULL; split_entry->self = split_entry; /* * Since we're splitting, we have to update the 'allocated' node's * size appropriately */ curr_entry->size = size; /* * ENHANCEME: do something with the status from avl_insert */ nStatus = shr_avl_insert(mem_avl->tree, _shr_mem_avl_compare, (shr_avl_datum_t*)split_entry); assert(nStatus >= 0); _shr_mem_avl_dll_insert(mem_avl, split_entry); } /* * Now take care of the block we're interested in */ *addr = curr_entry->addr; curr_entry->used = 1; return( 0 ); }
/* * Function: * _bcm_esw_stat_flex_create_ingress_udf_mode * Description: * Creates New Flex Ingress UDF(User Defined Field) Mode * Parameters: * unit - (IN) unit number * udf_pkt_attr_selectors - (IN) Flex attributes * mode - (OUT) Flex mode * total_counters - (OUT) Total Counters associated with new * Return Value: * BCM_E_XXX * Notes: * Not being used currently */ static bcm_error_t _bcm_esw_stat_flex_create_ingress_udf_mode( int unit, bcm_stat_flex_udf_pkt_attr_selectors_t *udf_pkt_attr_selectors, bcm_stat_flex_mode_t *mode, uint32 *total_counters) { bcm_stat_flex_mode_t mode_l=0; uint32 total_udf_bits=0; uint32 index=0; bcm_stat_flex_ingress_mode_t *flex_ingress_mode=NULL; bcm_stat_flex_udf_pkt_attr_bits_t udf_pkt_attr_bits_l; uint32 num_flex_ingress_pools; num_flex_ingress_pools=SOC_INFO(unit).num_flex_ingress_pools; flex_ingress_mode = sal_alloc(sizeof(bcm_stat_flex_ingress_mode_t), "flex_ingress_mode"); if (flex_ingress_mode == NULL) { return BCM_E_MEMORY; } for (index =0 ; index < BCM_STAT_FLEX_COUNTER_MAX_MODE ; index++) { sal_memset(flex_ingress_mode,0,sizeof(bcm_stat_flex_ingress_mode_t)); if (_bcm_esw_stat_flex_get_ingress_mode_info( unit, index, flex_ingress_mode) == BCM_E_NONE) { if (flex_ingress_mode->ing_attr.packet_attr_type != bcmStatFlexPacketAttrTypeUdf) { continue; } udf_pkt_attr_bits_l = flex_ingress_mode->ing_attr. udf_pkt_attr_selectors.udf_pkt_attr_bits; if ((udf_pkt_attr_bits_l.udf0== udf_pkt_attr_selectors->udf_pkt_attr_bits.udf0) && (udf_pkt_attr_bits_l.udf1== udf_pkt_attr_selectors->udf_pkt_attr_bits.udf1)) { *total_counters = flex_ingress_mode->total_counters; *mode=index; sal_free(flex_ingress_mode); return BCM_E_EXISTS; } } } sal_free(flex_ingress_mode); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_available_mode( unit, bcmStatFlexDirectionIngress, &mode_l)); /* Step2: Packet Attribute filling */ BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_udf_selector_keys( unit, bcmStatFlexDirectionIngress, _ingress_pkt_selector_key_reg[mode_l], udf_pkt_attr_selectors, &total_udf_bits)); BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_udf_selector_keys( unit, bcmStatFlexDirectionIngress, _ingress_pkt_selector_key_reg[mode_l+4], udf_pkt_attr_selectors, &total_udf_bits)); /* Step3: Offset table filling */ for (index=0;index < num_flex_ingress_pools ; index++) { BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_update_offset_table( unit, bcmStatFlexDirectionIngress, ING_FLEX_CTR_OFFSET_TABLE_0m+index, mode_l, 256, NULL)); } /* Step4: Final: reserve mode and return */ *total_counters = (1 << total_udf_bits); *mode=mode_l; return BCM_E_NONE; }
int sal_config_set(char *name, char *value) { sc_t *sc, *psc; char *newval; char *wildcard = NULL; char *sc_wildcard; int length; sc_hash_t hash; if (name == NULL || *name == '\0') { return -1; } SC_HASH(name, hash); sc = sal_config_list[hash]; psc = NULL; while (sc != NULL) { if (sal_strcmp(sc->sc_name, name) == 0) { break; } psc = sc; sc = sc->sc_next; } if (sc != NULL) { /* found */ if (value == NULL) { /* delete */ if (sal_config_list[hash] == sc) { sal_config_list[hash] = sc->sc_next; } else { if (psc !=NULL) { psc->sc_next = sc->sc_next; } } FREE_SC(sc); return 0; } else { /* replace */ newval = sal_alloc(strlen(value) + 1, "config value"); if (newval == NULL) { return -1; } sal_strncpy(newval, value, strlen(value)); newval[strlen(value)] = '\0'; sal_free(sc->sc_value); sc->sc_value = newval; return 0; } } /* not found, delete */ if (value == NULL) { int i; wildcard = wildcard_search(name, wildcard, &length); if (wildcard != NULL) { sc_wildcard = sal_alloc((length + 1), "sc_wildcard"); *(sc_wildcard+length) = 0; for (i = 0; i < MAX_CONFIG_HASH_COUNT; i++) { sc = sal_config_list[i]; psc = NULL; while (sc != NULL){ sc_wildcard = sal_strncpy(sc_wildcard, sc->sc_name, length); sc_wildcard[length] = '\0'; if (sal_strcmp(sc_wildcard, wildcard) == 0) { if (sal_config_list[i] == sc) { sal_config_list[i] = sc->sc_next; FREE_SC(sc); sc = sal_config_list[i]; psc = NULL; } else { if (psc !=NULL) { psc->sc_next = sc->sc_next; } FREE_SC(sc); if (psc !=NULL) { sc = psc->sc_next; } } } else { psc = sc; sc = sc->sc_next; } } } sal_free(wildcard); sal_free(sc_wildcard); return 0; } else { return -1; } } /* not found, add */ if ((sc = sal_alloc(sizeof(sc_t), "config set")) == NULL) { return -1; } sc->sc_name = sal_alloc(strlen(name) + 1, "config name"); sc->sc_value = sal_alloc(strlen(value) + 1, "config value"); if (sc->sc_name == NULL || sc->sc_value == NULL) { FREE_SC(sc); return -1; } sal_strncpy(sc->sc_name, name, strlen(name)); sc->sc_name[strlen(name)] = '\0'; sal_strncpy(sc->sc_value, value, strlen(value)); sc->sc_value[strlen(value)] = '\0'; sc->sc_hash = hash; sc->sc_next = sal_config_list[hash]; sal_config_list[hash] = sc; return 0; }
cmd_result_t cmd_bsc(int unit, args_t *a) { char *function, *tmp; int retv, chan, devno, len, i; uint8 *buf; uint32 addr, data, rlen; if (!sh_check_attached(ARG_CMD(a), unit)) return CMD_FAIL; function = ARG_GET(a); if (!function) { return CMD_USAGE; } else if (!sal_strncasecmp(function, "setmux", sal_strlen(function))) { tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } chan = parse_integer(tmp); if ((chan < 0) || (chan > 7)) { return CMD_USAGE; } soc_bsc_setmux(unit, chan); } else if (!sal_strncasecmp(function, "readmax", sal_strlen(function))) { soc_bsc_readmax(unit); } else if (!sal_strncasecmp(function, "readdpm", sal_strlen(function))) { soc_bsc_readdpm(unit); } else if (!sal_strncasecmp(function,"probe", sal_strlen(function))) { retv = soc_bsc_probe(unit); /* Will attach if not yet attached */ if (retv < 0) { LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "%s: ERROR: probe failed: %s\n"), ARG_CMD(a), bcm_errmsg(retv))); } else { cli_out("%s: detected %d device%s\n", ARG_CMD(a), retv, retv==1 ? "" : "s"); } } else if (!sal_strncasecmp(function,"show", sal_strlen(function))) { soc_bsc_show(unit); /* Will attach if not yet attached */ } else if (!sal_strncasecmp(function,"epr", sal_strlen(function))) { char buf_tmp[17]; buf_tmp[16] = '\0'; buf_tmp[0] = '\0'; tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); tmp = ARG_GET(a); if (tmp) { len = parse_integer(tmp); } else { len = 0x20; } if (addr + len > AT24C64_DEVICE_RW_SIZE) { cli_out("at24c64_read error: addr + len > %d\n", AT24C64_DEVICE_RW_SIZE); return CMD_OK; } buf = (uint8*)sal_alloc(len, "bsc"); if (buf == NULL) { cli_out("No memory\n"); return CMD_OK; } devno = soc_bsc_devopen(unit, BSC_AT24C32_NAME); if (devno < 0) { cli_out("%s: cannot open I2C device %s: %s\n", ARG_CMD(a), BSC_AT24C32_NAME, bcm_errmsg(devno)); sal_free(buf); return CMD_FAIL; } cli_out("0x%04x:", addr); rlen = len; retv = soc_eep24c64_read(unit, devno, addr, buf, &rlen); if ((rlen != len) || (retv != SOC_E_NONE)) { sal_free(buf); return CMD_OK; } for (i = 0; i < len; i++) { data = buf[i]; if (i && ((i % 8) == 0)) { cli_out(" "); } if (i && ((i % 16) == 0)) { cli_out("%s", buf_tmp); cli_out("\n0x%04x:", addr + i); buf_tmp[0] = '\0'; } buf_tmp[i % 16] = (isprint(data)) ? buf[i] : '.'; cli_out(" %02x", data); } if (i && (i % 16)) { buf_tmp[i % 16] = '\0'; } cli_out(" %s", buf_tmp); sal_free(buf); cli_out("\n"); } else if (!sal_strncasecmp(function,"epw", sal_strlen(function))) { tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } devno = soc_bsc_devopen(unit, BSC_AT24C32_NAME); if (devno < 0) { cli_out("%s: cannot open I2C device %s: %s\n", ARG_CMD(a), BSC_AT24C32_NAME, bcm_errmsg(devno)); return CMD_FAIL; } retv = soc_eep24c64_write(unit, devno, addr, (uint8 *)tmp, sal_strlen(tmp)); } else if (!sal_strncasecmp(function,"eptest", sal_strlen(function))) { devno = soc_bsc_devopen(unit, BSC_AT24C32_NAME); if (devno < 0) { cli_out("%s: cannot open I2C device %s: %s\n", ARG_CMD(a), BSC_AT24C32_NAME, bcm_errmsg(devno)); return CMD_FAIL; } soc_eep24c64_test(unit, devno); } else if (!sal_strncasecmp(function,"sfpread", sal_strlen(function))) { char sfp_dev_name[16]; tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); sal_sprintf(sfp_dev_name, "%s%d", BSC_SFP_NAME, addr); tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); tmp = ARG_GET(a); if (tmp) { len = parse_integer(tmp); } else { len = 0x20; } if (addr + len > SFP_DEVICE_SIZE) { cli_out("sfp_read error: addr + len > %d\n", SFP_DEVICE_SIZE); return CMD_OK; } buf = (uint8*)sal_alloc(len, "bsc"); if (buf == NULL) { cli_out("No memory\n"); return CMD_OK; } devno = soc_bsc_devopen(unit, sfp_dev_name); if (devno < 0) { cli_out("%s: cannot open I2C device %s: %s\n", ARG_CMD(a), sfp_dev_name, bcm_errmsg(devno)); sal_free(buf); return CMD_FAIL; } cli_out("0x%04x:", addr); rlen = len; retv = soc_sfp_read(unit, devno, addr, buf, &rlen); if ((rlen != len) || (retv != SOC_E_NONE)) { sal_free(buf); return CMD_OK; } for (i = 0; i < len; i++) { data = buf[i]; if (i && ((i % 8) == 0)) { cli_out(" "); } if (i && ((i % 16) == 0)) { cli_out("\n0x%04x:", addr + i); } cli_out(" %02x", data); } sal_free(buf); cli_out("\n"); } else if (!sal_strncasecmp(function,"sfpwrite", sal_strlen(function))) { char sfp_dev_name[16]; uint8 db; tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); sal_sprintf(sfp_dev_name, "%s%d", BSC_SFP_NAME, addr); tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } addr = parse_integer(tmp); tmp = ARG_GET(a); if (!tmp) { return CMD_USAGE; } db = (uint8)parse_integer(tmp); devno = soc_bsc_devopen(unit, sfp_dev_name); if (devno < 0) { cli_out("%s: cannot open I2C device %s: %s\n", ARG_CMD(a), sfp_dev_name, bcm_errmsg(devno)); return CMD_FAIL; } retv = soc_sfp_write(unit, devno, addr, (uint8 *)&db, 1); } else { return CMD_USAGE; } return CMD_OK; }
int bcm_xgs3_mcast_init(int unit) { if (L2MC_USED(unit) != NULL) { sal_free(L2MC_USED(unit)); } L2MC_SIZE(unit) = 0; L2MC_L2MEM(unit) = soc_feature(unit, soc_feature_ism_memory) ? L2_ENTRY_1m: L2Xm; L2MC_MCMEM(unit) = L2MCm; #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { int mc_base, mc_size; #ifdef BCM_WARM_BOOT_SUPPORT if (SOC_WARM_BOOT(unit)) { uint32 mc_ctrl; soc_control_t *soc = SOC_CONTROL(unit); /* Recover the mcast size settings */ SOC_IF_ERROR_RETURN (READ_MC_CONTROL_1r(unit, &mc_ctrl)); soc->higig2_bcast_size = soc_reg_field_get(unit, MC_CONTROL_1r, mc_ctrl, HIGIG2_BC_SIZEf); SOC_IF_ERROR_RETURN (READ_MC_CONTROL_2r(unit, &mc_ctrl)); soc->higig2_mcast_size = soc_reg_field_get(unit, MC_CONTROL_2r, mc_ctrl, HIGIG2_L2MC_SIZEf); SOC_IF_ERROR_RETURN (READ_MC_CONTROL_3r(unit, &mc_ctrl)); soc->higig2_ipmc_size = soc_reg_field_get(unit, MC_CONTROL_3r, mc_ctrl, HIGIG2_IPMC_SIZEf); if (SOC_REG_FIELD_VALID(unit, MC_CONTROL_5r, SHARED_TABLE_L2MC_SIZEf) && SOC_REG_FIELD_VALID(unit, MC_CONTROL_5r, SHARED_TABLE_IPMC_SIZEf)) { SOC_IF_ERROR_RETURN (READ_MC_CONTROL_5r(unit, &mc_ctrl)); soc->mcast_size = soc_reg_field_get(unit, MC_CONTROL_5r, mc_ctrl, SHARED_TABLE_L2MC_SIZEf); soc->ipmc_size = soc_reg_field_get(unit, MC_CONTROL_5r, mc_ctrl, SHARED_TABLE_IPMC_SIZEf); } } #endif /* BCM_WARM_BOOT_SUPPORT */ SOC_IF_ERROR_RETURN (soc_hbx_mcast_size_get(unit, &mc_base, &mc_size)); L2MC_SIZE(unit) = mc_size; } #endif if (L2MC_SIZE(unit) <= 0) { L2MC_SIZE(unit) = soc_mem_index_count(unit, L2MC_MCMEM(unit)); } L2MC_USED(unit) = sal_alloc(sizeof(int) * L2MC_SIZE(unit), "L2MC"); if (L2MC_USED(unit) == NULL) { return BCM_E_MEMORY; } sal_memset(L2MC_USED(unit), 0, sizeof(int) * L2MC_SIZE(unit)); #ifdef BCM_WARM_BOOT_SUPPORT if (SOC_WARM_BOOT(unit)) { l2x_entry_t *l2_entry, *l2_table; l2mc_entry_t *l2mc_entry, *l2mc_table; int index, index_min, index_max, l2mc_tbl_sz, l2_tbl_sz; sal_mac_addr_t mcmac; /* * Go through L2 table to get MC use counts */ #ifdef BCM_TRIUMPH3_SUPPORT if (soc_feature(unit, soc_feature_ism_memory)) { _bcm_tr3_mcast_l2_table_recover(unit); } else #endif /* BCM_TRIUMPH3_SUPPORT */ { index_min = soc_mem_index_min(unit, L2MC_L2MEM(unit)); index_max = soc_mem_index_max(unit, L2MC_L2MEM(unit)); l2_tbl_sz = sizeof(l2x_entry_t) * (index_max - index_min + 1); l2_table = soc_cm_salloc(unit, l2_tbl_sz, "l2 tbl dma"); if (l2_table == NULL) { sal_free(L2MC_USED(unit)); return BCM_E_MEMORY; } memset((void *)l2_table, 0, l2_tbl_sz); if (soc_mem_read_range(unit, L2MC_L2MEM(unit), MEM_BLOCK_ANY, index_min, index_max, l2_table) < 0) { sal_free(L2MC_USED(unit)); soc_cm_sfree(unit, l2_table); return SOC_E_INTERNAL; } for (index = index_min; index <= index_max; index++) { int l2mc_idx; l2mc_entry_t mc_entry; l2_entry = soc_mem_table_idx_to_pointer(unit, L2MC_L2MEM(unit), l2x_entry_t *, l2_table, index); if (!soc_mem_field32_get(unit, L2MC_L2MEM(unit), l2_entry, VALIDf)) { continue; } #ifdef BCM_TRX_SUPPORT /* We're already traversing the L2 memory here, so * check for non-bridge items */ if ((FALSE == SOC_CONTROL(unit)->l2x_ppa_bypass) && soc_feature(unit, soc_feature_ppa_bypass) && (soc_mem_field32_get(unit, L2MC_L2MEM(unit), l2_entry, KEY_TYPEf) != TR_L2_HASH_KEY_TYPE_BRIDGE)) { SOC_CONTROL(unit)->l2x_ppa_bypass = TRUE; } if (soc_mem_field_valid(unit, L2MC_L2MEM(unit), KEY_TYPEf) && (soc_mem_field32_get(unit, L2MC_L2MEM(unit), l2_entry, KEY_TYPEf) != TR_L2_HASH_KEY_TYPE_BRIDGE)) { /* The field L2MC_PTRf is only valid for key type BRIDGE */ continue; } #endif /* BCM_TRX_SUPPORT */ soc_L2Xm_mac_addr_get(unit, l2_entry, MAC_ADDRf, mcmac); if (!BCM_MAC_IS_MCAST(mcmac)) { continue; } l2mc_idx = soc_mem_field32_get(unit, L2MC_L2MEM(unit), l2_entry, L2MC_PTRf); sal_memset(&mc_entry, 0, sizeof(l2mc_entry_t)); if (soc_mem_read(unit, L2MC_MCMEM(unit), MEM_BLOCK_ANY, l2mc_idx, &mc_entry) < 0) { sal_free(L2MC_USED(unit)); soc_cm_sfree(unit, l2_table); return SOC_E_INTERNAL; } if (!soc_mem_field32_get(unit, L2MC_MCMEM(unit), &mc_entry, VALIDf)) { continue; } L2MC_USED_SET(unit, l2mc_idx); } soc_cm_sfree(unit, l2_table); } /* * But then L2 table may not have indices populated for * all valid L2MC entries.. * Go through L2MC table to search for existing entries */ index_min = soc_mem_index_min(unit, L2MC_MCMEM(unit)); index_max = index_min + L2MC_SIZE(unit) - 1; l2mc_tbl_sz = sizeof(l2mc_entry_t) * L2MC_SIZE(unit); l2mc_table = soc_cm_salloc(unit, l2mc_tbl_sz, "l2mc tbl dma"); if (l2mc_table == NULL) { sal_free(L2MC_USED(unit)); return BCM_E_MEMORY; } memset((void *)l2mc_table, 0, l2mc_tbl_sz); if (soc_mem_read_range(unit, L2MC_MCMEM(unit), MEM_BLOCK_ANY, index_min, index_max, l2mc_table) < 0) { sal_free(L2MC_USED(unit)); soc_cm_sfree(unit, l2mc_table); return SOC_E_INTERNAL; } for (index = index_min; index <= index_max; index++) { l2mc_entry = soc_mem_table_idx_to_pointer(unit, L2MC_MCMEM(unit), l2mc_entry_t *, l2mc_table, index); if (!soc_mem_field32_get(unit, L2MC_MCMEM(unit), l2mc_entry, VALIDf)) { continue; } if (!L2MC_USED_ISSET(unit, index)) { L2MC_USED_SET(unit, index); } } soc_cm_sfree(unit, l2mc_table); return L2MC_SIZE(unit); } #endif /* BCM_WARM_BOOT_SUPPORT */ if (!SAL_BOOT_BCMSIM && !SAL_BOOT_QUICKTURN) { SOC_IF_ERROR_RETURN (soc_mem_clear(unit, L2MC_MCMEM(unit), MEM_BLOCK_ALL, FALSE)); } /* Delete all multicast entries from L2 */ if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_BCMSIM) { #ifdef BCM_TRIDENT_SUPPORT if (soc_feature(unit, soc_feature_l2_bulk_control) && !SAL_BOOT_PLISIM) { #ifdef BCM_TRIUMPH3_SUPPORT if (soc_feature(unit, soc_feature_ism_memory)) { BCM_IF_ERROR_RETURN (bcm_tr3_l2_addr_delete_mcast(unit, TRUE)); } else #endif /* BCM_TRIUMPH3_SUPPORT */ { l2_bulk_match_mask_entry_t match_mask; l2_bulk_match_data_entry_t match_data; bcm_mac_t mac_mask; int field_len; BCM_IF_ERROR_RETURN (soc_reg_field32_modify(unit, L2_BULK_CONTROLr, REG_PORT_ANY, ACTIONf, 1)); sal_memset(&match_mask, 0, sizeof(match_mask)); sal_memset(&match_data, 0, sizeof(match_data)); soc_mem_field32_set(unit, L2_BULK_MATCH_MASKm, &match_mask, VALIDf, 1); soc_mem_field32_set(unit, L2_BULK_MATCH_DATAm, &match_data, VALIDf, 1); field_len = soc_mem_field_length(unit, L2_BULK_MATCH_MASKm, KEY_TYPEf); soc_mem_field32_set(unit, L2_BULK_MATCH_MASKm, &match_mask, KEY_TYPEf, (1 << field_len) - 1); /* KEY_TYPE field in data is 0 */ sal_memset(&mac_mask, 0, sizeof(mac_mask)); mac_mask[0] = 1; /* bit 40 */ soc_mem_mac_addr_set(unit, L2_BULK_MATCH_MASKm, &match_mask, MAC_ADDRf, mac_mask); soc_mem_mac_addr_set(unit, L2_BULK_MATCH_DATAm, &match_data, MAC_ADDRf, mac_mask); BCM_IF_ERROR_RETURN (WRITE_L2_BULK_MATCH_MASKm(unit, MEM_BLOCK_ALL, 0, &match_mask)); BCM_IF_ERROR_RETURN (WRITE_L2_BULK_MATCH_DATAm(unit, MEM_BLOCK_ALL, 0, &match_data)); if (!SAL_BOOT_BCMSIM) { BCM_IF_ERROR_RETURN (soc_l2x_port_age(unit, L2_BULK_CONTROLr, INVALIDr)); } } } else #endif /* BCM_TRIDENT_SUPPORT */ { #ifdef BCM_TRIUMPH3_SUPPORT if (soc_feature(unit, soc_feature_ism_memory)) { if (!SAL_BOOT_PLISIM) { BCM_IF_ERROR_RETURN (bcm_tr3_l2_addr_delete_mcast(unit, FALSE)); } } else #endif /* BCM_TRIUMPH3_SUPPORT */ { if (!SAL_BOOT_BCMSIM) { BCM_IF_ERROR_RETURN (_bcm_xgs3_l2_addr_delete_mcast(unit, BCM_L2_DELETE_STATIC)); } } } } return L2MC_SIZE(unit); }
/* * Function * _shr_resource_alloc * Purpose * Allocate "count" number of resources. * Parameters * unit - (IN) unit number of the device * type - (IN) resource type * (one of _shr_usr_res_types_t) * count - (IN) Number of resources required * elements- (OUT) Resource Index return by the underlying allocator * flags - (IN) _SHR_RES_FLAGS_CONTIGOUS * if the resources need to be contigous * Returns * BCM_E_NONE if element allocated successfully * BCM_E_RESOURCE if resource is in reserved range and compliant, not * neccessarily an error. * BCM_E_* as appropriate otherwise */ int _shr_resource_alloc(int unit, _shr_usr_res_types_t type, uint32 count, uint32 *elements, uint32 flags) { _shr_res_handle_t handle; _shr_hw_res_attrs_t *res_attrs; int status, res; uint32 i, size; uint32 *done; shr_aidxres_element_t tmp_elem, first, last; if ((count <= 0) || (elements == NULL)) { return BCM_E_PARAM; } BCM_IF_ERROR_RETURN(_SHR_RESOURCE_LOCK(unit)); status = _shr_get_resource_handle(unit, type, &handle); if (status != BCM_E_NONE) { _SHR_RESOURCE_UNLOCK(unit); return status; } res_attrs = &_g_shr_res_attrs[unit][_g_mapped_hw_res[unit][type]]; /* * if the reserve flag is set, make sure that the elements are * available */ if (flags & _SHR_RES_FLAGS_RESERVE) { int checkVal = BCM_E_NOT_FOUND; int inRange = 0; if (res_attrs->reservedHigh && res_attrs->reservedLow) { for (i = 0; i < count; i++) { if (elements[i] >= res_attrs->reservedLow && elements[i] <= res_attrs->reservedHigh) { inRange++; } } ALCR_VERB((_SHR_D(unit, "Found a reserved range on resource %d: " "0x%08x-0x%08x count=%d inRange=%d\n"), type, res_attrs->reservedLow, res_attrs->reservedHigh, count, inRange)); if (inRange && inRange != count) { /* part some elements are in reserved range, but not all */ _SHR_RESOURCE_UNLOCK(unit); return BCM_E_PARAM; } /* If these elements are in the reserved range, * verify they exist */ if (inRange) { checkVal = BCM_E_EXISTS; } } switch (handle.alloc_style) { case SHR_ALLOC_STYLE_SINGLE: case SHR_ALLOC_STYLE_SCALED: for (i = 0; i < count; i++) { /* check and apply translator */ tmp_elem = elements[i]; if (res_attrs->e2i) { tmp_elem = res_attrs->e2i(unit, elements[i]); } res = shr_idxres_list_elem_state(handle.idx_handle, tmp_elem); if (res != checkVal) { status = BCM_E_BUSY; break; } } break; case SHR_ALLOC_STYLE_VERSATILE: for (i = 0; i < count; i++) { if (flags & _SHR_RES_FLAGS_CONTIGOUS) { tmp_elem = (shr_aidxres_element_t) (elements[0] + i); } else { tmp_elem = (shr_aidxres_element_t)elements[i]; } /* check and apply translator */ if (res_attrs->e2i) { tmp_elem = res_attrs->e2i(unit, elements[i]); } res = shr_aidxres_list_elem_state(handle.aidx_handle, tmp_elem); if (res != checkVal) { status = BCM_E_BUSY; break; } } break; } /* may not be a real error; informing the caller that the resource * is in the reserved range, and checks out as OK. */ if (inRange && BCM_SUCCESS(status)) { status = BCM_E_RESOURCE; } } if (status != BCM_E_NONE) { _SHR_RESOURCE_UNLOCK(unit); return status; } done = NULL; if ( (count > 1) && (!(flags & ((_SHR_RES_FLAGS_CONTIGOUS) | (_SHR_RES_FLAGS_RESERVE))))) { size = (sizeof(uint32) * count); done = (uint32 *)sal_alloc(size, "RES-LIB"); if (done == NULL) { _SHR_RESOURCE_UNLOCK(unit); return BCM_E_MEMORY; } sal_memset(done, 0, size); } if ((flags & _SHR_RES_FLAGS_RESERVE) && (res_attrs->e2i)) { for (i = 0; i < count; i++) { elements[i] = res_attrs->e2i(unit, elements[i]); } } switch (handle.alloc_style) { case SHR_ALLOC_STYLE_SINGLE: if (count > 1) { status = BCM_E_PARAM; } else { if (flags & _SHR_RES_FLAGS_RESERVE) { first = (shr_aidxres_element_t)elements[0]; last = (shr_aidxres_element_t)elements[0]; status = shr_idxres_list_reserve(handle.idx_handle, first, last); } else { status = shr_idxres_list_alloc(handle.idx_handle, (shr_aidxres_element_t *)elements); } } break; case SHR_ALLOC_STYLE_SCALED: if (flags & _SHR_RES_FLAGS_CONTIGOUS) { status = BCM_E_PARAM; } else { if (flags & _SHR_RES_FLAGS_RESERVE) { for (i = 0; i < count; i++) { first = (shr_aidxres_element_t)elements[i]; last = (shr_aidxres_element_t)elements[i]; shr_idxres_list_reserve(handle.idx_handle, first, last); } } else { if (count == 1) { status = shr_idxres_list_alloc(handle.idx_handle, (shr_aidxres_element_t *)elements); } else { status = shr_idxres_list_alloc_set(handle.idx_handle, (shr_idxres_element_t) count, (shr_idxres_element_t *) elements, (shr_idxres_element_t *) done); } } } break; case SHR_ALLOC_STYLE_VERSATILE: if (flags & _SHR_RES_FLAGS_RESERVE) { if ((count == 1) || ((flags & _SHR_RES_FLAGS_CONTIGOUS))) { first = (shr_aidxres_element_t)elements[0]; last = (shr_aidxres_element_t)elements[0] + count - 1; status = shr_aidxres_list_reserve(handle.aidx_handle, first, last); } else { for (i = 0; i < count; i++) { first = (shr_aidxres_element_t)elements[i]; last = (shr_aidxres_element_t)elements[i]; status = shr_aidxres_list_reserve(handle.aidx_handle, first, last); } } } else { if (count == 1) { status = shr_aidxres_list_alloc(handle.aidx_handle, (shr_aidxres_element_t *) elements); } else { if (!(flags & _SHR_RES_FLAGS_CONTIGOUS)) { status = shr_aidxres_list_alloc_set(handle.aidx_handle, (shr_aidxres_element_t) count, (shr_aidxres_element_t *) elements, (shr_aidxres_element_t *) done); } else { shr_aidxres_list_alloc_block(handle.aidx_handle, (shr_aidxres_element_t) count, (shr_aidxres_element_t *)elements); } } } break; } if (done != NULL) { if (status != BCM_E_NONE) { for (i = 0; i < count; i++) { if (done[i]) { if (handle.alloc_style == SHR_ALLOC_STYLE_VERSATILE) { shr_aidxres_list_free(handle.aidx_handle, done[i]); } else { shr_idxres_list_free(handle.idx_handle, done[i]); } } } } sal_free(done); } if (status != BCM_E_NONE) { _SHR_RESOURCE_UNLOCK(unit); return status; } /* check and apply translators */ if (res_attrs->i2e) { for (i = 0; i < count; i++) { elements[i] = res_attrs->i2e(unit, elements[i]); } } _SHR_RESOURCE_UNLOCK(unit); return BCM_E_NONE; }
static cmd_result_t _bcm_diag_trunk_show_range(int unit, args_t *a, int fp, int first, int last, int *found) { bcm_trunk_t tid; bcm_trunk_info_t t_add_info; pbmp_t pbmp; char const *s; int i; int rv; bcm_trunk_member_t *member_array = NULL; bcm_module_t tm[BCM_TRUNK_MAX_PORTCNT]; bcm_port_t tp[BCM_TRUNK_MAX_PORTCNT]; int member_count; member_array = sal_alloc(sizeof(bcm_trunk_member_t) * BCM_TRUNK_MAX_PORTCNT, "member array"); if (NULL == member_array) { cli_out("%s: failed: %s\n", ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY)); return CMD_FAIL; } sal_memset(tm, BCM_MODID_INVALID, sizeof(bcm_module_t)*BCM_TRUNK_MAX_PORTCNT); sal_memset(tp, -1, sizeof(bcm_port_t)*BCM_TRUNK_MAX_PORTCNT); for (tid = first; tid <= last; tid++) { rv = bcm_trunk_get(unit, tid, &t_add_info, BCM_TRUNK_MAX_PORTCNT, member_array, &member_count); if (rv == BCM_E_NOT_FOUND) { /* Only show existing trunk groups */ continue; } if (rv < 0) { cli_out("%s: trunk %d get failed: %s\n", ARG_CMD(a), tid, bcm_errmsg(rv)); sal_free(member_array); return CMD_FAIL; } if (fp) { /* Front panel trunk */ rv = bcm_trunk_egress_get(unit, tid, &pbmp); if (rv == BCM_E_UNAVAIL) { /* * Certain devices don't have a egress port per trunk * Instead it provides support to set this up on * a per port basis for each trunk member port * Ignore this on these devices. */ rv = BCM_E_NONE; SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); } if (rv < 0) { cli_out("%s: trunk %d egress get failed: %s\n", ARG_CMD(a), tid, bcm_errmsg(rv)); sal_free(member_array); return CMD_FAIL; } } else { /* Fabric trunk */ SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); } (*found) += 1; cli_out("trunk %d: (%s, %d ports)", tid, fp ? "front panel" : "fabric", member_count); if (member_count > 0) { #ifdef BCM_XGS_SUPPORT if (SOC_IS_XGS(unit)) { for (i = 0; i < member_count; i++) { int tgid, id; rv = _bcm_esw_gport_resolve(unit, member_array[i].gport, &tm[i], &tp[i], &tgid, &id); if ((rv < 0) || (tgid != -1) || (id != -1)) { sal_free(member_array); return CMD_FAIL; } rv = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_SET, tm[i], tp[i], &tm[i], &tp[i]); if (rv < 0) { sal_free(member_array); return CMD_FAIL; } } } #endif for (i = 0; i < member_count; i++) { cli_out("%s%s", i == 0 ? "=" : ",", mod_port_name(unit, tm[i], tp[i])); } s = t_add_info.dlf_index < 0 ? "any" : mod_port_name(unit, tm[t_add_info.dlf_index], tp[t_add_info.dlf_index]); cli_out(" dlf=%s", s); s = t_add_info.mc_index < 0 ? "any" : mod_port_name(unit, tm[t_add_info.mc_index], tp[t_add_info.mc_index]); cli_out(" mc=%s", s); s = t_add_info.ipmc_index < 0 ? "any" : mod_port_name(unit, tm[t_add_info.ipmc_index], tp[t_add_info.ipmc_index]); cli_out(" ipmc=%s", s); if ((t_add_info.psc & 0xf) <= 0 || (t_add_info.psc & 0xf) >= COUNTOF(_pscnames)) { s= "unknown"; } else { s = _pscnames[t_add_info.psc&0xf]; } cli_out(" psc=%s", s); #ifdef BCM_HERCULES15_SUPPORT if (SOC_IS_HERCULES15(unit)) { cli_out("%s%s%s%s%s%s%s%s%s%s%s%s", (t_add_info.psc & BCM_TRUNK_PSC_IPMACSA) ? "+ipmacsa" : "", (t_add_info.psc & BCM_TRUNK_PSC_IPMACDA) ? "+ipmacda" : "", (t_add_info.psc & BCM_TRUNK_PSC_IPTYPE) ? "+iptype" : "", (t_add_info.psc & BCM_TRUNK_PSC_IPVID) ? "+ipvid" : "", (t_add_info.psc & BCM_TRUNK_PSC_IPSA) ? "+ipsa" : "", (t_add_info.psc & BCM_TRUNK_PSC_IPDA) ? "+ipda" : "", (t_add_info.psc & BCM_TRUNK_PSC_L4SS) ? "+l4ss" : "", (t_add_info.psc & BCM_TRUNK_PSC_L4DS) ? "+l4ds" : "", (t_add_info.psc & BCM_TRUNK_PSC_MACSA) ? "+macsa" : "", (t_add_info.psc & BCM_TRUNK_PSC_MACDA) ? "+macda" : "", (t_add_info.psc & BCM_TRUNK_PSC_TYPE) ? "+type" : "", (t_add_info.psc & BCM_TRUNK_PSC_VID) ? "+vid" : ""); } #endif /* BCM_HERCULES15_SUPPORT */ cli_out(" (0x%x)", t_add_info.psc); } cli_out("\n"); if (SOC_PBMP_NEQ(pbmp, PBMP_ALL(unit))) { char buf[FORMAT_PBMP_MAX]; format_pbmp(unit, buf, sizeof (buf), pbmp); cli_out("trunk %d: egress ports=%s\n", tid, buf); } } sal_free(member_array); return CMD_OK; }
/* * Function: * _bcm_trx_multicast_reinit * Purpose: * Recover Multicast module state for Warm Boot * Parameters: * unit - StrataSwitch unit number. * Returns: * BCM_E_XXX */ STATIC int _bcm_trx_multicast_reinit(int unit) { int mem_size=0, mc_index, is_set, rv = BCM_E_NONE; int alloc_size; soc_scache_handle_t scache_handle; bcm_multicast_t group, scache_group; SHR_BITDCL *ipmc_groups_bits = NULL; uint8 *multicast_scache; _bcm_multicast_cb_info_t mc_cb_info; int num_ipmc_groups; /* L3 IPMC info may use scache info */ mem_size = soc_mem_index_count(unit, L3_IPMCm); alloc_size = mem_size * sizeof(uint8); SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_MULTICAST, 0); rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 0, &multicast_scache, BCM_WB_DEFAULT_VERSION, NULL); if (BCM_E_NOT_FOUND == rv) { multicast_scache = NULL; } else if (BCM_FAILURE(rv)) { return rv; } else { sal_memcpy(_multicast_ipmc_group_types[unit], multicast_scache, alloc_size); } /* Traversing multiple next hop types, set up IPMC repl logging */ alloc_size = SHR_BITALLOCSIZE(mem_size); ipmc_groups_bits = sal_alloc(alloc_size, "IPMC groups referenced"); if (ipmc_groups_bits == NULL) { bcm_fb_ipmc_repl_detach(unit); return BCM_E_MEMORY; } sal_memset(ipmc_groups_bits, 0, alloc_size); /* Store info for callback functions */ mc_cb_info.ipmc_groups_bits = ipmc_groups_bits; mc_cb_info.stale_scache = FALSE; mc_cb_info.flags = BCM_MULTICAST_TYPE_L3; if (soc_feature(unit, soc_feature_mpls)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_VPLS; } if (soc_feature(unit, soc_feature_subport)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_SUBPORT; } if (soc_feature(unit, soc_feature_mim)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_MIM; } if (soc_feature(unit, soc_feature_wlan)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_WLAN; } if (soc_feature(unit, soc_feature_vlan_vp)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_VLAN; } if (soc_feature(unit, soc_feature_trill)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_TRILL; } if (soc_feature(unit, soc_feature_niv)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_NIV; } if (soc_feature(unit, soc_feature_mpls)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_EGRESS_OBJECT; } if (soc_feature(unit, soc_feature_port_extension)) { mc_cb_info.flags |= BCM_MULTICAST_TYPE_EXTENDER; } /* Traverse L2 table for multicast groups */ rv = bcm_esw_l2_traverse(unit, &_bcm_trx_multicast_l2_traverse, &mc_cb_info); #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) /* Traverse VLAN MC groups */ if (BCM_SUCCESS(rv) && (soc_feature(unit, soc_feature_wlan) || soc_feature(unit, soc_feature_vlan_vp) || soc_feature(unit, soc_feature_trill) || soc_feature(unit, soc_feature_niv) || soc_feature(unit, soc_feature_port_extension))) { rv = _bcm_trx_multicast_vlan_traverse(unit, &mc_cb_info); } #endif /* Traverse VFI groups */ if (BCM_SUCCESS(rv)) { if (soc_feature(unit, soc_feature_virtual_switching)) { rv = _bcm_trx_multicast_vfi_traverse(unit, &mc_cb_info); } } if (BCM_SUCCESS(rv)) { num_ipmc_groups = mem_size; #if defined(BCM_TRIUMPH3_SUPPORT) if (soc_feature(unit, soc_feature_static_repl_head_alloc)) { soc_info_t *si; int member_count; int port, phy_port, mmu_port; /* Each replication group is statically allocated a region * in REPL_HEAD table. The size of the region depends on the * maximum number of valid ports. Thus, the max number of * replication groups is limited to number of REPL_HEAD entries * divided by the max number of valid ports. */ si = &SOC_INFO(unit); member_count = 0; PBMP_ITER(SOC_CONTROL(unit)->repl_eligible_pbmp, port) { phy_port = si->port_l2p_mapping[port]; mmu_port = si->port_p2m_mapping[phy_port]; if ((mmu_port == 57) || (mmu_port == 59) || (mmu_port == 62)) { /* No replication on MMU ports 57, 59, and 62 */ continue; } member_count++; } if (member_count > 0) { num_ipmc_groups = soc_mem_index_count(unit, MMU_REPL_HEAD_TBLm) / member_count; if (num_ipmc_groups > mem_size) { num_ipmc_groups = mem_size; } } } #endif /* BCM_TRIUMPH3_SUPPORT */ for (mc_index = 0; mc_index < num_ipmc_groups; mc_index++) { if (SHR_BITGET(ipmc_groups_bits, mc_index)) { /* Already did this group index, skip */ continue; } rv = bcm_xgs3_ipmc_id_is_set(unit, mc_index, &is_set); if (BCM_E_INIT == rv) { rv = BCM_E_NONE; break; } else if (BCM_FAILURE(rv)) { break; } else if (is_set) { if (NULL != multicast_scache) { /* If scache was used, check for staleness */ rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_index, &scache_group); if (BCM_E_NOT_FOUND == rv) { #ifdef BCM_KATANA_SUPPORT if (SOC_IS_KATANA(unit) && ((mc_index == 0) || (mc_index == 1))) { continue; } #endif /* BCM_KATANA_SUPPORT */ /* We expect a group from the HW state, but * it isn't in the scache info */ if (FALSE == mc_cb_info.stale_scache) { /* We have yet to complain about stale scache */ rv = soc_event_generate(unit, BCM_SWITCH_EVENT_STABLE_ERROR, SOC_STABLE_STALE, SOC_STABLE_MULTICAST, 0); if (BCM_FAILURE(rv)) { break; } mc_cb_info.stale_scache = TRUE; } } else if (BCM_FAILURE(rv)) { return rv; } /* Keep the cached group info and continue */ } else { /* Best guess is that this is an L3 group */ _BCM_MULTICAST_GROUP_SET(group, _BCM_MULTICAST_TYPE_L3, mc_index); rv = _bcm_trx_multicast_reinit_group(unit, group, &mc_cb_info); if (BCM_FAILURE(rv)) { break; } } } else if (NULL != multicast_scache) { /* If scache was used, check for staleness */ rv = _bcm_tr_multicast_ipmc_group_type_get(unit, mc_index, &scache_group); if (BCM_E_NOT_FOUND == rv) { /* In sync */ rv = BCM_E_NONE; } else if (BCM_FAILURE(rv)) { return rv; } else if (0 != scache_group) { if (!_BCM_MULTICAST_IS_L3(scache_group)) { /* We expect a group from the scache info, but * it wasn't recovered from HW. */ if (FALSE == mc_cb_info.stale_scache) { /* We have yet to complain about stale scache */ rv = soc_event_generate(unit, BCM_SWITCH_EVENT_STABLE_ERROR, SOC_STABLE_STALE, SOC_STABLE_MULTICAST, 0); if (BCM_FAILURE(rv)) { break; } mc_cb_info.stale_scache = TRUE; } } else { /* This is an L3 group that was created but * not installed, so there is no HW sign of it. * We need to mark it recovered in the IPMC area. */ rv = bcm_xgs3_ipmc_id_alloc(unit, mc_index); if (BCM_FAILURE(rv)) { break; } } } } } }