Beispiel #1
0
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));
        }
    }
Beispiel #2
0
Datei: pkt.c Projekt: ariavie/bcm
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;
}
Beispiel #3
0
/*
 *  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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
    /*
     * 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;
}
Beispiel #6
0
Datei: io.c Projekt: ariavie/bcm
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;
}
Beispiel #7
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;
}
Beispiel #8
0
/*
 * 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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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");
    }
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
0
Datei: pkt.c Projekt: ariavie/bcm
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;
}
Beispiel #16
0
/**
 * 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;
}
Beispiel #17
0
/**
 * 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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
Datei: io.c Projekt: ariavie/bcm
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;
}
Beispiel #20
0
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;
}
Beispiel #23
0
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;
}
Beispiel #25
0
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;
}
Beispiel #26
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;
}
Beispiel #27
0
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);
}
Beispiel #28
0
/*
 *   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;
}
Beispiel #29
0
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;
}
Beispiel #30
0
/*
 * 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;
                        }
                    }
                }
            }
        }
    }