openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

topo_create.c (6693B)


      1 /* 
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        topo_create.c
      8  * Purpose:     Local topology calculator
      9  */
     10 
     11 #include <assert.h>
     12 #include <bcm/error.h>
     13 #include <bcm/types.h>
     14 #include <appl/cpudb/cpudb.h>
     15 #include <appl/stktask/topology.h>
     16 #include <appl/stktask/topology.h>
     17 #include "topo_int.h"
     18 
     19 /*
     20  * Function:
     21  *     _cpudb_entry_modid_get(cpudb_entry_t *entry,
     22  *                            uint8 *modp, int max, int *lenp)
     23  * Purpose:
     24  *     Fill an array of modids assigned to a CPU entry
     25  * Parameters:
     26  *     entry - (IN) CPUDB entry
     27  *     modp  - (OUT) array of modids to fill
     28  *     max   - (IN) maximum length of array
     29  *     lenp  - (OUT) actual length of array
     30  * Returns:
     31  *     BCM_E_NONE     - no errors
     32  *     BCM_E_FULL     - too many modids for CPUDB
     33  *     BCM_E_PARAM    - db_ref NULL, db_ref not fully constructed
     34  *     BCM_E_MEMORY   - not enough memory or system resources
     35  *     BCM_E_FAIL     - topology calculation failed (CPUDB incomplete)
     36  *     BCM_E_RESOURCE - not enough modids available for topology
     37  * Notes:
     38  *     Modids must already be assigned.
     39  *
     40  *     Doesn't bother with the stackport flags, as it's only used
     41  *     internally to set the cpudb sp_info flags.
     42  */
     43 
     44 STATIC int
     45 _cpudb_entry_modid_get(cpudb_entry_t *entry, uint8 *modp, int max, int *lenp)
     46 {
     47     int i;
     48     int count;
     49     int mod, nmod;
     50 
     51     count = 0;
     52     for (i = 0; i < entry->base.num_units; i++) {
     53         mod = entry->mod_ids[i];
     54         for (nmod = 0; nmod < entry->base.mod_ids_req[i]; nmod++) {
     55             if (count < max) {
     56                 *modp++ = mod + nmod;
     57                 count++;
     58             } else {
     59                 return BCM_E_FULL;
     60             }
     61         }
     62     }
     63     *lenp = count;
     64 
     65     return BCM_E_NONE;
     66 }
     67 
     68 /*
     69  * Function:
     70  *     _bcm_stack_topo_cpu(cpudb_ref_t db_ref, topo_cpu_t *tp_cpu)
     71  * Purpose:
     72  *     Calculate local topology from db_ref, returning topo_cpu
     73  *     and updating db_ref.
     74  * Parameters:
     75  *     db_ref - (IN/OUT) CPU database
     76  *     tp_cpu - (OUT) Calculated topology
     77  * Returns:
     78  *     BCM_E_NONE     - no errors
     79  *     BCM_E_FULL     - too many modids for CPUDB
     80  *     BCM_E_PARAM    - db_ref NULL, db_ref not fully constructed
     81  *     BCM_E_MEMORY   - not enough memory or system resources
     82  *     BCM_E_FAIL     - topology calculation failed (CPUDB incomplete)
     83  *     BCM_E_RESOURCE - not enough modids available for topology
     84  * Notes:
     85  *     Modids must already be assigned.
     86  *
     87  *     Doesn't bother with the stackport flags, as it's only used
     88  *     internally to set the cpudb sp_info flags.
     89  */
     90 
     91 STATIC int
     92 _bcm_stack_topo_cpu(cpudb_ref_t db_ref, topo_cpu_t *tp_cpu)
     93 {
     94     cpudb_entry_t *local, *entry;
     95     int sp, dst, mcount, mleft, mtotal;
     96     uint8 *mptr;
     97     int rv = BCM_E_FAIL;
     98 
     99     if (!cpudb_valid(db_ref)) {
    100         return BCM_E_PARAM;
    101     }
    102 
    103     if (tp_cpu == NULL) {
    104         return BCM_E_PARAM;
    105     }
    106 
    107     if ((db_ref->topo_cookie == NULL) ||
    108         (db_ref->master_entry == NULL)) {
    109         return BCM_E_PARAM;
    110     }
    111 
    112     local = db_ref->local_entry;
    113     sal_memset(tp_cpu, 0, sizeof(*tp_cpu));
    114     tp_cpu->local_entry = *local;
    115     tp_cpu->master_seq_num = db_ref->master_entry->base.dseq_num;
    116     tp_cpu->num_cpus = db_ref->num_cpus;
    117 
    118     dst=0;
    119     
    120     CPUDB_FOREACH_ENTRY(db_ref, entry) {
    121         if (dst != local->topo_idx) {
    122 
    123             /* Get the TX stack port on this CPU that points to dst */
    124             sp = TP_TX_CXN(db_ref, local->topo_idx, dst);
    125 
    126             /* Append the modids associated with this stack port */
    127             mtotal = tp_cpu->tp_stk_port[sp].tx_mod_num;
    128             mleft = COUNTOF(tp_cpu->tp_stk_port[sp].tx_mods) - mtotal;
    129             if (mleft <= 0) {
    130                 rv = BCM_E_FULL;
    131                 break;
    132             }
    133             mptr = tp_cpu->tp_stk_port[sp].tx_mods + mtotal;
    134             rv = _cpudb_entry_modid_get(entry, mptr, mleft, &mcount);
    135             if (BCM_FAILURE(rv)) {
    136                 break;
    137             }
    138             tp_cpu->tp_stk_port[sp].tx_mod_num += mcount;
    139 
    140             
    141             entry->dest_mod = entry->mod_ids[entry->base.dest_unit];
    142             entry->dest_port = entry->base.dest_port;
    143             entry->tx_unit = local->base.stk_ports[sp].unit;
    144             entry->tx_port = local->base.stk_ports[sp].port;
    145             entry->flags |= (CPUDB_F_TX_KNOWN|CPUDB_F_DEST_KNOWN);
    146 
    147             /* Get the RX stack port on this CPU that points to dst */
    148             sp = TP_RX_CXN(db_ref, local->topo_idx, dst);
    149 
    150             /* Append the modids associated with this stack port */
    151             mtotal = tp_cpu->tp_stk_port[sp].rx_mod_num;
    152             mleft = COUNTOF(tp_cpu->tp_stk_port[sp].rx_mods) - mtotal;
    153             if (mleft <= 0) {
    154                 rv = BCM_E_FULL;
    155                 break;
    156             }
    157             mptr = tp_cpu->tp_stk_port[sp].rx_mods + mtotal;
    158             rv = _cpudb_entry_modid_get(entry, mptr, mleft, &mcount);
    159             if (BCM_FAILURE(rv)) {
    160                 break;
    161             }
    162             tp_cpu->tp_stk_port[sp].rx_mod_num += mcount;
    163 
    164         } else {
    165             /* local entry */
    166             local->dest_mod = local->mod_ids[local->base.dest_unit];
    167             local->dest_port = local->base.dest_port;
    168             local->tx_unit = local->base.dest_unit;
    169             local->tx_port = local->base.dest_port;
    170             local->flags |= (CPUDB_F_TX_KNOWN|CPUDB_F_DEST_KNOWN);
    171 
    172             if (db_ref->num_cpus == 1) {
    173                 /* Nothing more to do */
    174                 rv = BCM_E_NONE;
    175             }
    176         }
    177         dst++; /* Next dst id */
    178     }
    179 
    180     return rv;
    181 }
    182 
    183 /*
    184  * Function:
    185  *     bcm_stack_topo_create(cpudb_ref_t db_ref, topo_cpu_t *tp_cpu)
    186  * Purpose:
    187  *     Calculate local topology from db_ref, returning topo_cpu
    188  *     and updating db_ref.
    189  * Parameters:
    190  *     db_ref - (IN/OUT) CPU database
    191  *     tp_cpu - (OUT) Calculated topology
    192  * Returns:
    193  *     BCM_E_NONE     - no errors
    194  *     BCM_E_FULL     - too many modids for CPUDB
    195  *     BCM_E_PARAM    - db_ref NULL, db_ref not fully constructed
    196  *     BCM_E_MEMORY   - not enough memory or system resources
    197  *     BCM_E_FAIL     - topology calculation failed (CPUDB incomplete)
    198  *     BCM_E_RESOURCE - not enough modids available for topology
    199  * Notes:
    200  *     Does not perform any device programming.
    201  */
    202 
    203 int
    204 bcm_stack_topo_create(cpudb_ref_t db_ref, topo_cpu_t *tp_cpu)
    205 {
    206     BCM_IF_ERROR_RETURN(topology_mod_ids_assign(db_ref));
    207     BCM_IF_ERROR_RETURN(topology_create(db_ref));
    208     BCM_IF_ERROR_RETURN(_bcm_stack_topo_cpu(db_ref,tp_cpu));
    209 
    210     return BCM_E_NONE;
    211 }