trunk.c (17083B)
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 * Trunk CLI commands 8 */ 9 10 #include <appl/diag/system.h> 11 #include <appl/diag/parse.h> 12 #include <appl/diag/dport.h> 13 #include <shared/bsl.h> 14 #include <bcm/error.h> 15 #include <bcm/trunk.h> 16 #include <bcm/port.h> 17 #include <bcm/stack.h> 18 #include <bcm/debug.h> 19 20 21 22 cmd_result_t 23 if_esw_trunk(int unit, args_t *a) 24 { 25 char *subcmd; 26 bcm_trunk_t tid = -1; 27 bcm_pbmp_t pbmp; 28 int r; 29 int psc; 30 bcm_pbmp_t arg_pbmp; 31 uint32 arg_rtag=0; 32 uint32 arg_vlan=VLAN_ID_DEFAULT, arg_tid=0; 33 #ifdef BCM_FIREBOLT_SUPPORT 34 int arg_hash=0; 35 #endif /* BCM_FIREBOLT_SUPPORT */ 36 parse_table_t pt; 37 cmd_result_t retCode; 38 bcm_trunk_info_t t_add_info; 39 int i, j, dport; 40 sal_mac_addr_t mac; 41 vlan_id_t vid; 42 bcm_module_t modid; 43 44 45 if (!sh_check_attached(ARG_CMD(a), unit)) { 46 return CMD_FAIL; 47 } 48 49 if ((subcmd = ARG_GET(a)) == NULL) { 50 return CMD_USAGE; 51 } 52 53 BCM_PBMP_CLEAR(pbmp); 54 BCM_PBMP_CLEAR(arg_pbmp); 55 56 if (sal_strcasecmp(subcmd, "init") == 0) { 57 r = bcm_trunk_init(unit); 58 if (r < 0) { 59 cli_out("%s: trunk init failed: %s\n", ARG_CMD(a), bcm_errmsg(r)); 60 return CMD_FAIL; 61 } 62 63 return CMD_OK; 64 } 65 66 if (sal_strcasecmp(subcmd, "deinit") == 0) { 67 r = bcm_trunk_detach(unit); 68 if (r < 0) { 69 cli_out("%s: trunk deinit failed: %s\n", ARG_CMD(a), bcm_errmsg(r)); 70 return CMD_FAIL; 71 } 72 73 return CMD_OK; 74 } 75 76 /* trunk show command */ 77 if (sal_strcasecmp(subcmd, "show") == 0) { 78 return _bcm_diag_trunk_show(unit, a); 79 } 80 81 r = bcm_stk_my_modid_get(unit, &modid); 82 if ((r < 0) && (r != BCM_E_UNAVAIL)) { 83 cli_out("BCMX: Could not get mod id %d: %s\n", r, bcm_errmsg(r)); 84 return r; 85 } 86 87 88 if (r < 0) { /* If unavailable, indicate unknown */ 89 modid = -1; 90 } 91 92 if (sal_strcasecmp(subcmd, "add") == 0) { 93 bcm_trunk_chip_info_t ti; 94 bcm_module_t tm, _tm; 95 bcm_port_t tp, _tp; 96 bcm_trunk_member_t *member_array = NULL; 97 98 if ((r = bcm_trunk_chip_info_get(unit, &ti)) < 0) { 99 cli_out("%s: %s\n", ARG_CMD(a), bcm_errmsg(r)); 100 return CMD_FAIL; 101 } 102 103 parse_table_init(unit, &pt); 104 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL); 105 parse_table_add(&pt, "Rtag", PQ_DFL|PQ_INT, 0, &arg_rtag, NULL); 106 parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, 0, &arg_pbmp, NULL); 107 108 if (!parseEndOk(a, &pt, &retCode)) { 109 return retCode; 110 } 111 112 tid = arg_tid; 113 psc = arg_rtag; 114 pbmp = arg_pbmp; 115 116 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * 117 BCM_TRUNK_MAX_PORTCNT, "member array"); 118 if (NULL == member_array) { 119 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY)); 120 return CMD_FAIL; 121 } 122 j = 0; 123 /* coverity[overrun-local] */ 124 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, i) { 125 tm = (soc_feature(unit, soc_feature_mod1) && i > 31) ? modid + 1 : modid; 126 tp = i; 127 _tm = tm; 128 _tp = tp; 129 r = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_GET, tm, tp, 130 &tm, &tp); 131 if (r == BCM_E_UNAVAIL) { 132 tm = _tm; 133 tp = _tp; 134 } else if (r < 0) { 135 sal_free(member_array); 136 return CMD_FAIL; 137 } 138 if (j >= BCM_TRUNK_MAX_PORTCNT) { 139 sal_free(member_array); 140 return CMD_FAIL; 141 } 142 bcm_trunk_member_t_init(&member_array[j]); 143 if (BCM_GPORT_IS_SET(tp)) { 144 member_array[j].gport = tp; 145 } else { 146 BCM_GPORT_MODPORT_SET(member_array[j].gport, tm, tp); 147 } 148 j += 1; 149 }; 150 bcm_trunk_info_t_init(&t_add_info); 151 t_add_info.dlf_index = BCM_TRUNK_UNSPEC_INDEX; 152 t_add_info.mc_index = BCM_TRUNK_UNSPEC_INDEX; 153 t_add_info.ipmc_index = BCM_TRUNK_UNSPEC_INDEX; 154 t_add_info.psc = psc; 155 156 bcm_trunk_create(unit, BCM_TRUNK_FLAG_WITH_ID, &tid); 157 r = bcm_trunk_set(unit, tid, &t_add_info, j, member_array); 158 159 if (r < 0) { 160 bcm_trunk_destroy(unit, tid); 161 } 162 sal_free(member_array); 163 } else if (sal_strcasecmp(subcmd, "remove") == 0) { 164 bcm_module_t tm, _tm; 165 bcm_port_t tp, _tp; 166 bcm_trunk_member_t *member_array = NULL; 167 int member_count; 168 169 parse_table_init(unit, &pt); 170 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, 171 &arg_tid, NULL); 172 parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0), 173 &arg_pbmp, NULL); 174 if (!parseEndOk(a, &pt, &retCode)) { 175 return retCode; 176 } 177 178 pbmp = arg_pbmp; 179 tid = arg_tid; 180 181 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * 182 BCM_TRUNK_MAX_PORTCNT, "member array"); 183 if (NULL == member_array) { 184 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(BCM_E_MEMORY)); 185 return CMD_FAIL; 186 } 187 r = bcm_trunk_get(unit, tid, &t_add_info, BCM_TRUNK_MAX_PORTCNT, 188 member_array, &member_count); 189 190 if (r >= 0) { 191 BCM_PBMP_CLEAR(pbmp); 192 r = bcm_stk_my_modid_get(unit, &modid); 193 if (r < 0) { 194 sal_free(member_array); 195 return CMD_FAIL; 196 } 197 for (i = 0; i < member_count; i++) { 198 if (BCM_GPORT_IS_DEVPORT(member_array[i].gport)) { 199 tm = modid; 200 tp = BCM_GPORT_DEVPORT_PORT_GET(member_array[i].gport); 201 } else if (BCM_GPORT_IS_MODPORT(member_array[i].gport)) { 202 tm = BCM_GPORT_MODPORT_MODID_GET(member_array[i].gport); 203 tp = BCM_GPORT_MODPORT_PORT_GET(member_array[i].gport); 204 } else { 205 sal_free(member_array); 206 return CMD_FAIL; 207 } 208 if ((tm != modid) && 209 !soc_feature(unit, soc_feature_mod1)) { 210 tp +=32; 211 } 212 BCM_PBMP_PORT_ADD(pbmp, tp); 213 } 214 BCM_PBMP_REMOVE(pbmp, arg_pbmp); 215 216 j = 0; 217 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, i) { 218 tm = (soc_feature(unit, soc_feature_mod1) && i > 31) ? modid + 1: modid; 219 tp = i; 220 _tm = tm; 221 _tp = tp; 222 r = bcm_stk_modmap_map(unit, BCM_STK_MODMAP_GET, tm, tp, 223 &tm, &tp); 224 if (r == BCM_E_UNAVAIL) { 225 tm = _tm; 226 tp = _tp; 227 } else if (r < 0) { 228 sal_free(member_array); 229 return CMD_FAIL; 230 } 231 bcm_trunk_member_t_init(&member_array[j]); 232 if (BCM_GPORT_IS_SET(tp)) { 233 member_array[j].gport = tp; 234 } else { 235 BCM_GPORT_MODPORT_SET(member_array[j].gport, tm, tp); 236 } 237 j += 1; 238 } 239 240 if (j) { 241 r = bcm_trunk_set(unit, tid, &t_add_info, j, member_array); 242 } else { 243 r = bcm_trunk_destroy(unit, tid); 244 } 245 } 246 247 sal_free(member_array); 248 } else if (sal_strcasecmp(subcmd, "egress") == 0) { 249 parse_table_init(unit, &pt); 250 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL); 251 parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0), 252 &arg_pbmp, NULL); 253 if (!parseEndOk( a, &pt, &retCode)) return retCode; 254 tid = arg_tid; 255 BCM_PBMP_ASSIGN(pbmp, arg_pbmp); 256 r = bcm_trunk_egress_set(unit, tid, pbmp); 257 } else if (sal_strcasecmp(subcmd, "mcast") == 0) { 258 parse_table_init(unit, &pt); 259 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL); 260 parse_table_add(&pt, "Mac", PQ_DFL|PQ_MAC, 0, (void *)mac, NULL); 261 parse_table_add(&pt, "Vlanid", PQ_DFL|PQ_HEX, 0, &arg_vlan, NULL); 262 if (!parseEndOk( a, &pt, &retCode)) { 263 return retCode; 264 } 265 266 tid = arg_tid; 267 vid = arg_vlan; 268 r = bcm_trunk_mcast_join(unit, tid, vid, mac); 269 #ifdef BCM_FIREBOLT_SUPPORT 270 } else if (sal_strcasecmp(subcmd, "hash") == 0) { 271 char *subcmd_s; 272 bcm_port_t port, dport; 273 274 if ((subcmd_s = ARG_GET(a)) == NULL) { 275 return CMD_USAGE; 276 } 277 278 if (sal_strcasecmp(subcmd_s, "set") == 0) { 279 parse_table_init(unit, &pt); 280 parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0), 281 &arg_pbmp, NULL); 282 parse_table_add(&pt, "HashValue", PQ_DFL|PQ_INT, 0, &arg_hash, NULL); 283 if (!parseEndOk( a, &pt, &retCode)) { 284 return retCode; 285 } 286 287 /* coverity[overrun-local] */ 288 DPORT_BCM_PBMP_ITER(unit, arg_pbmp, dport, port) { 289 r = bcm_port_trunk_index_set(unit, port, arg_hash); 290 } 291 } else if (sal_strcasecmp(subcmd_s, "get") == 0) { 292 int hash; 293 294 parse_table_init(unit, &pt); 295 parse_table_add(&pt, "Pbmp", PQ_DFL|PQ_PBMP|PQ_BCM, (void *)(0), 296 &arg_pbmp, NULL); 297 if (!parseEndOk( a, &pt, &retCode)) { 298 return retCode; 299 } 300 DPORT_BCM_PBMP_ITER(unit, arg_pbmp, dport, port) { 301 r = bcm_port_trunk_index_get(unit, port, &hash); 302 if (r >= 0) { 303 cli_out("port %s programmable hash set to %d\n", 304 BCM_PORT_NAME(unit, port), hash); 305 } 306 } 307 } else { 308 return CMD_USAGE; 309 } 310 #endif /* BCM_FIREBOLT_SUPPORT */ 311 } else if (sal_strcasecmp(subcmd, "psc") == 0) { 312 parse_table_init(unit, &pt); 313 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 0, &arg_tid, NULL); 314 parse_table_add(&pt, "Rtag", PQ_DFL|PQ_INT, 0, &arg_rtag, NULL); 315 if (!parseEndOk(a, &pt, &retCode)) { 316 return retCode; 317 } 318 319 tid = arg_tid; 320 psc = arg_rtag; 321 322 r = bcm_trunk_psc_set(unit, tid, psc); 323 } else { 324 return CMD_USAGE; 325 } 326 327 if (r < 0) { 328 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 329 return CMD_FAIL; 330 } 331 332 return CMD_OK; 333 } 334 335 #ifdef BCM_HERCULES15_SUPPORT 336 char trunkpool_cmd_usage[] = 337 "\n\t" 338 "trunkpool set [Id=<val>] [PortBitMap=<pbmp>] [Size=<val>]\n\t" 339 " [W0=<val>] [W1=<val>] ... [W7=<val>]\n\t" 340 " - Set trunk pool information\n\t" 341 "trunkpool get [Id=<val>] [PortBitMap=<pbmp>]\n\t" 342 " - Get trunk pool information\n\t" 343 "Note: Need to configure trunk before setting pool table.\n"; 344 345 cmd_result_t 346 cmd_trunkpool(int unit, args_t *a) 347 { 348 char *subcmd; 349 parse_table_t pt; 350 cmd_result_t retCode; 351 bcm_pbmp_t pbmp; 352 bcm_port_config_t pcfg; 353 int arg_psize=-1, arg_tid=0; 354 int weights[BCM_TRUNK_MAX_PORTCNT]; 355 bcm_trunk_info_t add_info; 356 int count[BCM_TRUNK_MAX_PORTCNT]; 357 int i, port, dport, r, size; 358 bcm_trunk_member_t *member_array = NULL; 359 int member_count; 360 bcm_port_t local_port; 361 362 if (!sh_check_attached(ARG_CMD(a), unit)) { 363 return CMD_FAIL; 364 } 365 366 if ((subcmd = ARG_GET(a)) == NULL) { 367 return CMD_USAGE; 368 } 369 370 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 371 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 372 return CMD_FAIL; 373 } 374 375 BCM_PBMP_CLEAR(pbmp); 376 sal_memset(weights, 0, BCM_TRUNK_MAX_PORTCNT * sizeof(int)); 377 378 if (sal_strcasecmp(subcmd, "set") == 0) { 379 parse_table_init(unit, &pt); 380 parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 381 (void *)( 0), &pbmp, NULL); 382 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 383 (void *)( 0), &arg_tid, NULL); 384 parse_table_add(&pt, "Size", PQ_DFL|PQ_INT, 385 (void *)( 0), &arg_psize, NULL); 386 parse_table_add(&pt, "W0", PQ_DFL|PQ_INT, 387 (void *)( 0), &weights[0], NULL); 388 parse_table_add(&pt, "W1", PQ_DFL|PQ_INT, 389 (void *)( 0), &weights[1], NULL); 390 parse_table_add(&pt, "W2", PQ_DFL|PQ_INT, 391 (void *)( 0), &weights[2], NULL); 392 parse_table_add(&pt, "W3", PQ_DFL|PQ_INT, 393 (void *)( 0), &weights[3], NULL); 394 parse_table_add(&pt, "W4", PQ_DFL|PQ_INT, 395 (void *)( 0), &weights[4], NULL); 396 parse_table_add(&pt, "W5", PQ_DFL|PQ_INT, 397 (void *)( 0), &weights[5], NULL); 398 parse_table_add(&pt, "W6", PQ_DFL|PQ_INT, 399 (void *)( 0), &weights[6], NULL); 400 parse_table_add(&pt, "W7", PQ_DFL|PQ_INT, 401 (void *)( 0), &weights[7], NULL); 402 403 if (!parseEndOk(a, &pt, &retCode)) 404 return retCode; 405 406 if (arg_psize < 0) { 407 r = bcm_trunk_get(unit, arg_tid, &add_info, 408 0, NULL, &member_count); 409 if (r >= 0) { 410 arg_psize = member_count; 411 } 412 } 413 414 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * 415 BCM_TRUNK_MAX_PORTCNT, "member array"); 416 if (NULL == member_array) { 417 cli_out("ERROR: %s %s failed: %s\n", 418 ARG_CMD(a), subcmd, bcm_errmsg(BCM_E_MEMORY)); 419 return CMD_FAIL; 420 } 421 BCM_PBMP_AND(pbmp, pcfg.stack_ext); 422 /* coverity[overrun-local] */ 423 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 424 r = bcm_trunk_pool_set(unit, port, arg_tid, arg_psize, weights); 425 if (r < 0) { 426 cli_out("ERROR: %s %s port %s failed: %s\n", 427 ARG_CMD(a), subcmd, BCM_PORT_NAME(unit, port), 428 bcm_errmsg(r)); 429 sal_free(member_array); 430 return CMD_FAIL; 431 } 432 cli_out("port %s trunk pool set:\n", BCM_PORT_NAME(unit, port)); 433 cli_out(" tid=%d size=%d\n",arg_tid, arg_psize); 434 r = bcm_trunk_get(unit, arg_tid, &add_info, 435 BCM_TRUNK_MAX_PORTCNT, member_array, &member_count); 436 if (r >= 0) { 437 cli_out(" "); 438 for (i = 0; i < member_count; i++) { 439 r = bcm_port_local_get(unit, member_array[i].gport, 440 &local_port); 441 if (r >= 0) { 442 if (weights[local_port-1]) 443 cli_out("W[%d]=%d ", local_port - 1, 444 weights[local_port - 1]); 445 } 446 } 447 cli_out("\n"); 448 } 449 } 450 sal_free(member_array); 451 return CMD_OK; 452 } 453 454 if (sal_strcasecmp(subcmd, "get") == 0) { 455 parse_table_init(unit, &pt); 456 parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 457 (void *)( 0), &pbmp, NULL); 458 parse_table_add(&pt, "Id", PQ_DFL|PQ_INT, 459 (void *)( 0), &arg_tid, NULL); 460 if (!parseEndOk(a, &pt, &retCode)) 461 return retCode; 462 463 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * 464 BCM_TRUNK_MAX_PORTCNT, "member array"); 465 if (NULL == member_array) { 466 cli_out("ERROR: %s %s failed: %s\n", 467 ARG_CMD(a), subcmd, bcm_errmsg(BCM_E_MEMORY)); 468 return CMD_FAIL; 469 } 470 471 BCM_PBMP_AND(pbmp, pcfg.stack_ext); 472 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 473 r = bcm_trunk_pool_get(unit, port, arg_tid, &size, count); 474 if (r < 0) { 475 cli_out("ERROR: %s %s port %s failed: %s\n", 476 ARG_CMD(a), subcmd, BCM_PORT_NAME(unit, port), 477 bcm_errmsg(r)); 478 sal_free(member_array); 479 return CMD_FAIL; 480 } 481 cli_out("port %s trunk pool get:\n", BCM_PORT_NAME(unit, port)); 482 cli_out(" tid=%d size=%d\n",arg_tid, size); 483 r = bcm_trunk_get(unit, arg_tid, &add_info, 484 BCM_TRUNK_MAX_PORTCNT, member_array, &member_count); 485 if (r >= 0) { 486 cli_out(" "); 487 for (i = 0; i < member_count; i++) { 488 r = bcm_port_local_get(unit, member_array[i].gport, 489 &local_port); 490 if (r >= 0) { 491 if (count[local_port-1]) 492 cli_out("TotalCount[%d]=%d ", local_port - 1, 493 count[local_port - 1]); 494 } 495 } 496 cli_out("\n"); 497 } 498 } 499 sal_free(member_array); 500 return CMD_OK; 501 } 502 503 return CMD_USAGE; 504 } 505 #endif /* BCM_HERCULES15_SUPPORT */