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 }