brd_xgs3.c (15849B)
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: brd_xgs3.c 8 * Purpose: XGS3 Based SDK and Reference Design board programming 9 */ 10 11 #include <shared/bsl.h> 12 13 #include <soc/property.h> /* for Raptor support */ 14 #include <bcm/error.h> 15 #include <bcm/stack.h> 16 #include <bcm/trunk.h> 17 #include <bcm/topo.h> 18 #include <bcm/init.h> /* bcm_info_get */ 19 20 #include <appl/stktask/topo_brd.h> 21 #include <sal/appl/config.h> 22 23 #include "topo_int.h" 24 25 /* Set up a Firebolt device. */ 26 STATIC int 27 _bcm_board_xgs3_fb(int unit, topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 28 { 29 int i, m; 30 topo_stk_port_t *tsp; 31 int port; 32 cpudb_entry_t *l_entry; 33 bcm_module_t mod; 34 bcm_port_config_t config; 35 36 /* 37 * Generate the bitmap of egress ports for each mod id; 38 * Do not exclude the higig port from the bitmap b/c the 39 * FB ucbitmap set applies to the chip, not the ingress port. 40 */ 41 42 l_entry = &tp_cpu->local_entry; 43 for (i = 0; i < l_entry->base.num_stk_ports; i++) { 44 if (unit != l_entry->base.stk_ports[i].unit) { 45 /* Only looking at this device for now */ 46 continue; 47 } 48 49 /* For each mod-id reached by this port, set in device */ 50 tsp = &tp_cpu->tp_stk_port[i]; 51 port = l_entry->base.stk_ports[i].port; 52 53 for (m = 0; m < tsp->tx_mod_num; m++) { 54 mod = tsp->tx_mods[m]; 55 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port)); 56 } 57 } 58 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config)); 59 BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref, 60 &config)); 61 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(l_entry, db_ref, 62 BCM_BOARD_TRUNK_NORMAL)); 63 64 return BCM_E_NONE; 65 } 66 67 STATIC int 68 _bcm_board_banner(int unit, char *prefix) 69 { 70 bcm_info_t info; 71 uint32 dev; 72 73 BCM_IF_ERROR_RETURN(bcm_info_get(unit, &info)); 74 75 /* Make the device ID correspond to the actual part number */ 76 77 dev = info.device; 78 79 if (dev > 0x5699) { 80 dev += 0x4b000; 81 } 82 83 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 84 (BSL_META("TOPO: %sBCM%x SDK\n"), 85 prefix, dev)); 86 87 return BCM_E_NONE; 88 } 89 90 /* Single Fireolt or Firebolt-like device on a board, unit number is 0 */ 91 92 #define FB_UNIT 0 93 int 94 bcm_board_topo_sdk_xgs3_24g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 95 { 96 int modid; 97 98 _bcm_board_banner(FB_UNIT, ""); 99 100 /* Use the default stackable mod ID mapping since only one unit on brd */ 101 bcm_topo_map_set(bcm_board_topomap_stk); 102 103 modid = tp_cpu->local_entry.mod_ids[FB_UNIT]; 104 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(FB_UNIT, modid)); 105 106 return _bcm_board_xgs3_fb(FB_UNIT, tp_cpu, db_ref); 107 } 108 #undef FB_UNIT 109 110 /* Support functions for dual XGS3 SDK and Reference designs */ 111 112 /* Internal trunk setup */ 113 114 #define NUMXGS3DEV 2 115 116 STATIC int 117 _bcm_board_setup_trunk_dual_xgs3(xgs3devinfo_t dev[NUMXGS3DEV]) 118 { 119 int i; 120 bcm_trunk_info_t trunk; 121 bcm_trunk_chip_info_t ti; 122 int member_count; 123 bcm_trunk_member_t member_array[2]; 124 125 sal_memset(&trunk, 0, sizeof(trunk)); 126 trunk.psc = -1; 127 trunk.dlf_index = -1; 128 trunk.mc_index = -1; 129 trunk.ipmc_index = -1; 130 131 member_count = 2; 132 133 for ( i = 0; i < NUMXGS3DEV; i++ ) { 134 135 bcm_trunk_member_t_init(&member_array[0]); 136 member_array[0].gport = BCM_GPORT_DEVPORT(dev[i].unit, 137 dev[i].intport[0]); 138 bcm_trunk_member_t_init(&member_array[1]); 139 member_array[1].gport = BCM_GPORT_DEVPORT(dev[i].unit, 140 dev[i].intport[1]); 141 142 BCM_IF_ERROR_RETURN(bcm_trunk_chip_info_get(dev[i].unit, &ti)); 143 bcm_trunk_destroy(dev[i].unit, ti.trunk_fabric_id_max); 144 BCM_IF_ERROR_RETURN(bcm_trunk_create(dev[i].unit, 145 BCM_TRUNK_FLAG_WITH_ID, 146 &ti.trunk_fabric_id_max)); 147 BCM_IF_ERROR_RETURN(bcm_trunk_set(dev[i].unit, 148 ti.trunk_fabric_id_max, &trunk, 149 member_count, 150 member_array)); 151 } 152 153 return BCM_E_NONE; 154 } 155 156 157 /* Generic board programming for dual XGS3 designs */ 158 159 STATIC int 160 _bcm_board_dual_xgs3(xgs3devinfo_t dev[NUMXGS3DEV], topo_cpu_t *tp_cpu, 161 cpudb_ref_t db_ref) 162 { 163 int i, m; 164 topo_stk_port_t *tsp; 165 int port; 166 cpudb_entry_t *l_entry; 167 bcm_module_t mod; 168 bcm_port_config_t config; 169 int sp, np; 170 int auto_trunk; 171 172 /* Set devinfo device modids */ 173 for ( i = 0; i < NUMXGS3DEV; i++ ) { 174 dev[i].modid = tp_cpu->local_entry.mod_ids[i]; 175 } 176 177 l_entry = &tp_cpu->local_entry; 178 179 /* Set module mapping based on modids reachable by the stack ports */ 180 181 for ( i = 0; i < l_entry->base.num_stk_ports; i++) { 182 if (!(l_entry->sp_info[i].flags & CPUDB_SPF_TX_RESOLVED)) { 183 /* Skip unresolved ports */ 184 continue; 185 } 186 187 /* Set sp (stack-port-dev) and np (non-stack-port-dev) */ 188 if (dev[0].unit == l_entry->base.stk_ports[i].unit) { 189 /* sp is the dev in devinfo that this stack port is connected to */ 190 /* np is the other (non stack port) dev */ 191 sp = 0; 192 np = 1; 193 } else { 194 sp = 1; 195 np = 0; 196 } 197 198 /* For each modid reached by this port, set both devices (s 199 and np). For sp (the device this stack port is on), set the 200 modmap to the stack port. For np (the device this stack 201 port is *not* on), set the modmap to the internal port. */ 202 203 tsp = &tp_cpu->tp_stk_port[i]; 204 port = l_entry->base.stk_ports[i].port; 205 206 for (m = 0; m < tsp->tx_mod_num; m++) { 207 mod = tsp->tx_mods[m]; 208 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(dev[sp].unit, mod, port)); 209 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(dev[np].unit, mod, 210 dev[np].intport[0])); 211 } 212 } 213 214 /* Set the module mapping, internal stack ports and module 215 filtering for the two devices themselves. */ 216 217 BCM_IF_ERROR_RETURN(bcm_board_auto_trunk_get(&auto_trunk)); 218 for ( i = 0; i < NUMXGS3DEV; i++ ) { 219 int j = i^1; /* The other device */ 220 221 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(dev[i].unit, 222 dev[j].modid, 223 dev[i].intport[0])); 224 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(dev[i].unit, 225 dev[i].intport[0])); 226 if (dev[i].intport[1] >= 0 && auto_trunk) { 227 BCM_IF_ERROR_RETURN(bcm_board_internal_stk_port_add(dev[i].unit, 228 dev[i].intport[1])); 229 } 230 BCM_IF_ERROR_RETURN(bcm_port_config_get(dev[i].unit, &config)); 231 BCM_IF_ERROR_RETURN(bcm_board_module_filter(dev[i].unit, 232 tp_cpu, db_ref, &config)); 233 234 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(dev[i].unit, 235 dev[i].modid)); 236 } 237 238 /* Set up internal trunking */ 239 240 if (dev[0].intport[1] >= 0 && dev[1].intport[1] >= 0) { 241 _bcm_board_setup_trunk_dual_xgs3(dev); 242 } 243 244 /* Set up external trunking */ 245 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(l_entry, db_ref, 246 BCM_BOARD_TRUNK_NORMAL)); 247 248 #ifdef BCM_BOARD_AUTO_E2E 249 /* intra-board end to end flow control, if available */ 250 BCM_IF_ERROR_RETURN(_bcm_board_dual_xgs3_e2e_set(dev[0].unit, dev[0].modid, 251 dev[1].unit, 252 dev[1].modid)); 253 #endif /* BCM_BOARD_AUTO_E2E */ 254 255 return BCM_E_NONE; 256 } 257 258 /* sdk_xgs3_48f */ 259 260 xgs3devinfo_t xgs3_48f_devinfo[NUMXGS3DEV] = { 261 { 262 0, /* unit */ 263 -1, /* modid (dynamic) */ 264 { 26, -1 } /* internal stack port (not trunked) */ 265 }, 266 { 267 1, /* unit */ 268 -1, /* modid (dynamic) */ 269 { 26, -1 } /* internal stack port (not trunked) */ 270 } 271 }; 272 273 274 int 275 bcm_board_topo_xgs3_48f(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 276 { 277 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 278 (BSL_META("TOPO: XGS3 (2)56102 48FE+2GE+2XHG\n"))); 279 280 BCM_IF_ERROR_RETURN 281 (_bcm_board_dual_xgs3(xgs3_48f_devinfo, tp_cpu, db_ref)); 282 283 return BCM_E_NONE; 284 } 285 286 /* sdk_xgs3_48g */ 287 288 xgs3devinfo_t xgs3_48g_devinfo[NUMXGS3DEV] = { 289 { 290 0, /* unit */ 291 -1, /* modid (dynamic) */ 292 { 26, 27 } /* internal stack ports (trunked) */ 293 }, 294 { 295 1, /* unit */ 296 -1, /* modid (dynamic) */ 297 { 26, 27 } /* internal stack ports (trunked) */ 298 } 299 }; 300 301 int 302 bcm_board_topo_xgs3_48g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 303 { 304 _bcm_board_banner(0, "(2)"); 305 306 BCM_IF_ERROR_RETURN 307 (_bcm_board_dual_xgs3(xgs3_48g_devinfo, tp_cpu, db_ref)); 308 309 return BCM_E_NONE; 310 } 311 312 int 313 bcm_board_topo_xgs3_20x(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 314 { 315 int unit; 316 bcm_module_t mod; 317 bcm_port_t port; 318 bcm_port_config_t config; 319 320 unit = 0; /* board fabric unit */ 321 322 _bcm_board_banner(unit, ""); 323 324 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config)); 325 BCM_PBMP_ITER(config.cpu, port) { 326 break; /* Get CPU port */ 327 } 328 mod = db_ref->local_entry->mod_ids[0]; 329 BCM_IF_ERROR_RETURN(bcm_stk_modport_set(unit, mod, port)); 330 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(0, mod)); 331 BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit, 332 tp_cpu, 333 db_ref->local_entry)); 334 BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref, 335 &config)); 336 BCM_IF_ERROR_RETURN(bcm_board_trunk_system(&tp_cpu->local_entry, 337 db_ref, 338 BCM_BOARD_TRUNK_NORMAL)); 339 340 return BCM_E_NONE; 341 } 342 343 int 344 bcm_board_topo_xgs3_48g5g(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 345 { 346 int modid; 347 bcm_port_config_t config; 348 int unit = 0; 349 350 _bcm_board_banner(unit, ""); 351 352 BCM_IF_ERROR_RETURN(bcm_board_num_modid_set(16)); 353 354 /* Use the default stackable mod ID mapping since only one unit on brd */ 355 bcm_topo_map_set(bcm_board_topomap_stk); 356 357 modid = tp_cpu->local_entry.mod_ids[0]; 358 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_set(unit, modid)); 359 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &config)); 360 BCM_IF_ERROR_RETURN(bcm_board_fab_mod_map(unit, 361 tp_cpu, 362 db_ref->local_entry)); 363 BCM_IF_ERROR_RETURN(bcm_board_module_filter(unit, tp_cpu, db_ref, 364 &config)); 365 366 /* If there are only two CPUs, deal with any possible untrunkable 367 stack ports */ 368 if (db_ref->num_cpus == 2) { 369 BCM_IF_ERROR_RETURN(bcm_board_untrunkable_stack_ports(unit, tp_cpu)); 370 } 371 372 return BCM_E_NONE; 373 374 } 375 376 /* sdk_xgs3_48g2 */ 377 378 xgs3devinfo_t xgs3_48g2_devinfo[NUMXGS3DEV] = { 379 { 380 0, /* unit */ 381 -1, /* modid (dynamic) */ 382 { 1, -1 } /* internal stack port (not trunked) */ 383 }, 384 { 385 1, /* unit */ 386 -1, /* modid (dynamic) */ 387 { 1, -1 } /* internal stack port (not trunked) */ 388 } 389 }; 390 391 392 #if defined(INCLUDE_RCPU) && defined(BCM_ESW_SUPPORT) && !defined(NO_SAL_APPL) 393 int 394 bcm_board_topo_xgs3_48g2(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 395 { 396 extern int _bcm_esw_rcpu_init(int); 397 char modstr[16]; 398 int rv; 399 int mode, uidx, pidx; 400 char *rcpu_port_str; 401 int rcpu_port, rcpu_higig; 402 403 _bcm_board_banner(0, "(2)"); 404 405 rcpu_port_str = sal_config_get(spn_RCPU_PORT); 406 if (rcpu_port_str == NULL) { 407 return BCM_E_CONFIG; 408 } 409 rcpu_port = sal_ctoi(rcpu_port_str, NULL); 410 rcpu_higig = FALSE; 411 412 /* See if any internal 2.5G port is trunkable */ 413 xgs3_48g2_devinfo[0].intport[0] = 1; 414 xgs3_48g2_devinfo[1].intport[0] = 1; 415 xgs3_48g2_devinfo[0].intport[1] = 4; 416 xgs3_48g2_devinfo[1].intport[1] = 4; 417 418 for (uidx=0; uidx < 2; uidx++) { 419 for (pidx=0; pidx < 2; pidx++) { 420 if (xgs3_48g2_devinfo[uidx].intport[pidx] < 0) { 421 continue; 422 } 423 BCM_IF_ERROR_RETURN 424 (bcm_port_encap_get(xgs3_48g2_devinfo[uidx].unit, 425 xgs3_48g2_devinfo[uidx].intport[pidx], 426 &mode)); 427 if (mode == BCM_PORT_ENCAP_IEEE) { 428 /* If either port is not higig, neither port is trunkable */ 429 xgs3_48g2_devinfo[0].intport[pidx] = -1; 430 xgs3_48g2_devinfo[1].intport[pidx] = -1; 431 } else if (xgs3_48g2_devinfo[uidx].intport[pidx] == rcpu_port) { 432 rcpu_higig = TRUE; 433 } 434 } 435 } 436 437 BCM_IF_ERROR_RETURN 438 (_bcm_board_dual_xgs3(xgs3_48g2_devinfo, tp_cpu, db_ref)); 439 440 /* Disable ge2 */ 441 BCM_IF_ERROR_RETURN(bcm_port_enable_set(0, 3, 0)); 442 BCM_IF_ERROR_RETURN(bcm_port_enable_set(1, 3, 0)); 443 444 /* Manage RCPU higig properties */ 445 if (sal_config_set(spn_RCPU_HIGIG_PORT, rcpu_higig ? "1" : "0") != 0) { 446 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 447 (BSL_META("TOPO: " spn_RCPU_HIGIG_PORT " set error\n"))); 448 } 449 450 if (sal_config_set(spn_RCPU_RX_PBMP ".1", 451 rcpu_higig ? "0x12" : 452 ((rcpu_port == 4) ? "0x10" : "0x02")) != 0) { 453 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 454 (BSL_META("TOPO: " spn_RCPU_RX_PBMP ".1 set error\n"))); 455 } 456 457 /* reinit RCPU subsystem with new modids */ 458 sal_sprintf(modstr, "%d", db_ref->local_entry->mod_ids[0]); 459 if (sal_config_set(spn_RCPU_MASTER_MODID, modstr) != 0) { 460 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 461 (BSL_META("TOPO: " spn_RCPU_MASTER_MODID " set error\n"))); 462 } 463 rv = _bcm_esw_rcpu_init(0); 464 if (BCM_FAILURE(rv)) { 465 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 466 (BSL_META("TOPO: rcpu master init error %d (%s)\n"), 467 rv, bcm_errmsg(rv))); 468 } 469 470 sal_sprintf(modstr, "%d", db_ref->local_entry->mod_ids[1]); 471 if (sal_config_set(spn_RCPU_SLAVE_MODID, modstr) != 0) { 472 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 473 (BSL_META("TOPO: " spn_RCPU_SLAVE_MODID " set error\n"))); 474 } 475 rv=_bcm_esw_rcpu_init(1); 476 if (BCM_FAILURE(rv)) { 477 LOG_VERBOSE(BSL_LS_TKS_TOPOLOGY, 478 (BSL_META("TOPO: rcpu slave init error %d (%s)\n"), 479 rv, bcm_errmsg(rv))); 480 } 481 482 return BCM_E_NONE; 483 } 484 485 #else 486 487 int 488 bcm_board_topo_xgs3_48g2(topo_cpu_t *tp_cpu, cpudb_ref_t db_ref) 489 { 490 COMPILER_REFERENCE(tp_cpu); 491 COMPILER_REFERENCE(db_ref); 492 493 return BCM_E_UNAVAIL; 494 } 495 496 #endif /* defined(INCLUDE_RCPU) && defined(BCM_ESW_SUPPORT) 497 && !defined(NO_SAL_APPL) */