port.c (190496B)
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: port.c 8 * Purpose: Functions to support CLI port commands 9 * Requires: 10 */ 11 12 #include <sal/core/libc.h> 13 #include <sal/types.h> 14 #include <sal/appl/sal.h> 15 #include <sal/appl/io.h> 16 #include <sal/core/libc.h> 17 #include <shared/bsl.h> 18 19 #include <soc/drv.h> 20 #include <soc/debug.h> 21 22 #include <appl/diag/shell.h> 23 #include <appl/diag/system.h> 24 #include <appl/diag/parse.h> 25 #include <appl/diag/diag.h> 26 #include <appl/diag/dport.h> 27 28 #include <bcm/init.h> 29 #include <bcm/port.h> 30 #include <bcm/stg.h> 31 #include <bcm/error.h> 32 33 #ifdef SW_AUTONEG_SUPPORT 34 #include <bcm_int/common/sw_an.h> 35 #endif 36 37 #if defined(BCM_ESW_SUPPORT) 38 #include <bcm_int/esw/portctrl.h> 39 #include <bcm_int/esw/port.h> 40 #endif 41 #ifdef BCM_DFE_SUPPORT 42 #include <bcm_int/dfe/port.h> 43 #endif 44 #ifdef BCM_PETRA_SUPPORT 45 #include <bcm_int/dpp/port.h> 46 #endif 47 #ifdef BCM_CMICX_SUPPORT 48 #include <shared/cmicfw/iproc_m0ssq.h> 49 #endif 50 #if defined(PORTMOD_SUPPORT) 51 #include <soc/portmod/portmod.h> 52 #endif 53 54 static int prev_linkscan_interval[BCM_MAX_NUM_UNITS]; 55 /* 56 * Function: 57 * if_fmt_speed 58 * Purpose: 59 * Format a speed as returned from bcm_xxx for display. 60 * Parameters: 61 * b - buffer to format into. 62 * speed - speed as returned from bcm_port_speed_get 63 * Returns: 64 * Pointer to buffer (b). 65 */ 66 67 char * 68 if_fmt_speed(char *b, int speed) 69 { 70 if (speed >= 1000) { /* Use Gb */ 71 if (speed % 1000) { /* Use Decimal */ 72 sal_sprintf(b, "%d.%dG", speed / 1000, (speed % 1000) / 100); 73 } else { 74 sal_sprintf(b, "%dG", speed / 1000); 75 } 76 } else if (speed == 0) { 77 sal_sprintf(b, "-"); 78 } else { /* Use Mb */ 79 sal_sprintf(b, "%dM", speed); 80 } 81 return (b); 82 } 83 84 /* 85 * These are ordered according the corresponding enumerated types. 86 * See soc/portmode.h, bcm/port.h and bcm/link.h for more information 87 */ 88 89 /* Note: See port.h, bcm_port_discard_e */ 90 char *discard_mode[] = { 91 "None", "All", "Untag", "Tag", NULL, NULL 92 }; 93 94 /* Note: See link.h, bcm_linkscan_mode_e */ 95 char *linkscan_mode[] = { 96 "None", "SW", "HW", "OFF", "ON", NULL 97 }; 98 99 /* Note: See portmode.h, soc_port_if_e */ 100 char *interface_mode[] = SOC_PORT_IF_NAMES_INITIALIZER; 101 102 /* Note: See portmode.h, soc_port_ms_e */ 103 char *phymaster_mode[] = { 104 "Slave", "Master", "Auto", "None", NULL 105 }; 106 107 /* Note: See port.h, bcm_port_loopback_e */ 108 char *loopback_mode[] = { 109 "NONE", "MAC", "PHY", "RMT", "MAC_RMT", NULL 110 }; 111 112 /* Note: See port.h, bcm_port_stp_e */ 113 char *forward_mode[] = { 114 "Disable", "Block", "LIsten", "LEarn", "Forward", NULL 115 }; 116 117 /* Note: See port.h, bcm_port_encap_e */ 118 char *encap_mode[] = { 119 "IEEE", "HIGIG", "B5632", "HIGIG2", "HGOE", NULL 120 }; 121 122 /* Note: See port.h, bcm_port_mdix_e */ 123 char *mdix_mode[] = { 124 "Auto", "ForcedAuto", "ForcedNormal", "ForcedXover", NULL 125 }; 126 127 /* Note: See port.h, bcm_port_mdix_status_e */ 128 char *mdix_status[] = { 129 "Normal", "Xover", NULL 130 }; 131 132 /* Note: See port.h, bcm_port_medium_t */ 133 char *medium_status[] = { 134 "None", "Copper", "Fiber", "Backplane", "All", NULL 135 }; 136 137 /* Note: See port.h, bcm_port_mcast_flood_t */ 138 char *mcast_flood[] = { 139 "FloodAll", "FloodUnknown", "FloodNone", NULL 140 }; 141 142 143 void 144 brief_port_info_header(int unit) 145 { 146 char *fc = " "; 147 #ifdef BCM_TOMAHAWK_SUPPORT 148 char *ln = ""; 149 char *asf[2] = {"", ""}; 150 #endif 151 char *disp_str = 152 "%15s " /* port number */ 153 "%5s " /* enable/link state */ 154 "%9s " /* speed/duplex */ 155 "%4s " /* link scan mode */ 156 "%4s " /* auto negotiate? */ 157 "%7s " /* spantree state */ 158 "%5s " /* pause tx/rx */ 159 "%6s " /* discard mode */ 160 "%3s " /* learn to CPU, ARL, FWD or discard */ 161 "%6s " /* interface */ 162 "%5s " /* max frame */ 163 "%5s\n"; /* loopback */ 164 165 #ifdef BCM_TOMAHAWK_SUPPORT 166 /* coverity [Out-of-bounds] */ 167 if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 168 ln = "Lns"; 169 asf[0] = "cut "; asf[1] = "thru?"; 170 #ifdef BCM_TOMAHAWK3_SUPPORT 171 if (SOC_IS_TOMAHAWK3(unit)){ 172 disp_str = 173 "%15s " /* port number */ 174 "%5s " /* enable/link state */ 175 "%3s" /* lanes */ 176 "%9s " /* speed/duplex */ 177 "%4s " /* link scan mode */ 178 "%4s " /* auto negotiate? */ 179 "%7s " /* spantree state */ 180 "%5s " /* pause tx/rx */ 181 "%6s " /* discard mode */ 182 "%3s " /* learn to CPU, ARL, FWD or discard */ 183 "%6s " /* interface */ 184 "%5s " /* max frame */ 185 "%6s " /* cutthrough */ 186 "%6s " /* FEC */ 187 "%8s\n"; /* loopback */ 188 } else 189 #endif 190 { 191 disp_str = 192 "%15s " /* port number */ 193 "%5s " /* enable/link state */ 194 "%3s" /* lanes */ 195 "%9s " /* speed/duplex */ 196 "%4s " /* link scan mode */ 197 "%4s " /* auto negotiate? */ 198 "%7s " /* spantree state */ 199 "%5s " /* pause tx/rx */ 200 "%6s " /* discard mode */ 201 "%3s " /* learn to CPU, ARL, FWD or discard */ 202 "%6s " /* interface */ 203 "%5s " /* max frame */ 204 "%6s " /* cutthrough */ 205 "%5s\n"; /* loopback */ 206 } 207 } 208 #endif 209 210 #ifdef BCM_TOMAHAWK_SUPPORT 211 if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 212 #ifdef BCM_TOMAHAWK3_SUPPORT 213 if (SOC_IS_TOMAHAWK3(unit)){ 214 cli_out(disp_str, 215 " ", /* port number */ 216 "ena/", /* enable/link state */ 217 " ", /* number of lanes */ 218 "speed/", /* speed/duplex */ 219 "link", /* link scan mode */ 220 "auto", /* auto negotiate? */ 221 " STP ", /* spantree state */ 222 fc, /* pause tx/rx or ilkn FC status */ 223 " ", /* discard mode */ 224 "lrn", /* learn to CPU, ARL, FWD or discard */ 225 "inter", /* interface */ 226 "max", /* max frame */ 227 asf[0], /* cutthrough */ 228 " ", /* FEC */ 229 "loop"); /* loopback */ 230 cli_out(disp_str, 231 "port", /* port number */ 232 "link", /* enable/link state */ 233 ln, /* number of lanes */ 234 "duplex", /* speed/duplex */ 235 "scan", /* link scan mode */ 236 "neg?", /* auto negotiate? */ 237 "state", /* spantree state */ 238 "pause", /* pause tx/rx */ 239 "discrd", /* discard mode */ 240 "ops", /* learn to CPU, ARL, FWD or discard */ 241 "face", /* interface */ 242 "frame", /* max frame */ 243 asf[1], /* cutthrough */ 244 "FEC", /* FEC */ 245 "back"); /* loopback */ 246 247 } else 248 #endif 249 { 250 cli_out(disp_str, 251 " ", /* port number */ 252 "ena/", /* enable/link state */ 253 " ", /* number of lanes */ 254 "speed/", /* speed/duplex */ 255 "link", /* link scan mode */ 256 "auto", /* auto negotiate? */ 257 " STP ", /* spantree state */ 258 fc, /* pause tx/rx or ilkn FC status */ 259 " ", /* discard mode */ 260 "lrn", /* learn to CPU, ARL, FWD or discard */ 261 "inter", /* interface */ 262 "max", /* max frame */ 263 asf[0], /* cutthrough */ 264 "loop"); /* loopback */ 265 cli_out(disp_str, 266 "port", /* port number */ 267 "link", /* enable/link state */ 268 ln, /* number of lanes */ 269 "duplex", /* speed/duplex */ 270 "scan", /* link scan mode */ 271 "neg?", /* auto negotiate? */ 272 "state", /* spantree state */ 273 "pause", /* pause tx/rx */ 274 "discrd", /* discard mode */ 275 "ops", /* learn to CPU, ARL, FWD or discard */ 276 "face", /* interface */ 277 "frame", /* max frame */ 278 asf[1], /* cutthrough */ 279 "back"); /* loopback */ 280 } 281 } else 282 #endif 283 { 284 cli_out(disp_str, 285 " ", /* port number */ 286 "ena/", /* enable/link state */ 287 "speed/", /* speed/duplex */ 288 "link", /* link scan mode */ 289 "auto", /* auto negotiate? */ 290 " STP ", /* spantree state */ 291 fc, /* pause tx/rx or ilkn FC status */ 292 " ", /* discard mode */ 293 "lrn", /* learn to CPU, ARL, FWD or discard */ 294 "inter", /* interface */ 295 "max", /* max frame */ 296 "loop"); /* loopback */ 297 cli_out(disp_str, 298 "port", /* port number */ 299 "link", /* enable/link state */ 300 "duplex", /* speed/duplex */ 301 "scan", /* link scan mode */ 302 "neg?", /* auto negotiate? */ 303 "state", /* spantree state */ 304 "pause", /* pause tx/rx */ 305 "discrd", /* discard mode */ 306 "ops", /* learn to CPU, ARL, FWD or discard */ 307 "face", /* interface */ 308 "frame", /* max frame */ 309 "back"); /* loopback */ 310 } 311 } 312 313 #define _CHECK_PRINT(unit, flags, mask, str, val) do { \ 314 if ((flags) & (mask)) { \ 315 cli_out(str, val); \ 316 } else { \ 317 cli_out(str, ""); \ 318 } \ 319 } while (0) 320 321 int 322 brief_port_info(int unit, int port, bcm_port_info_t *info, uint32 flags) 323 { 324 char *spt_str, *discrd_str; 325 char sbuf[6]; 326 int lrn_ptr; 327 char lrn_str[4]; 328 char remark[40]; 329 int p = 0; 330 331 #if defined(BCM_KATANA2_SUPPORT) 332 333 uint32 wc_xfi_mode_sel_val[2] = { 0 }; 334 uint32 top_misc_control_1_val = 0; 335 soc_field_t wc_xfi_mode_sel_fld[] = 336 { WC0_8_XFI_MODE_SELf, WC1_8_XFI_MODE_SELf }; 337 338 #endif 339 340 remark[0] = '\0'; 341 p = port; 342 spt_str = FORWARD_MODE(info->stp_state); 343 discrd_str = DISCARD_MODE(info->discard); 344 345 #if defined(BCM_KATANA2_SUPPORT) 346 347 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 348 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r 349 (unit, &top_misc_control_1_val)); 350 wc_xfi_mode_sel_val[0] = 351 soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, 352 top_misc_control_1_val, 353 wc_xfi_mode_sel_fld[0]); 354 wc_xfi_mode_sel_val[1] = 355 soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, 356 top_misc_control_1_val, 357 wc_xfi_mode_sel_fld[1]); 358 } 359 360 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 361 switch (port) { 362 case 25: 363 case 36: 364 if (wc_xfi_mode_sel_val[0]) { 365 p = (port == 25) ? 32 : 34; 366 sal_sprintf(remark, "XFI#Int:%d:==>Ext:%d:", port, p); 367 } 368 break; 369 case 26: 370 case 39: 371 if (wc_xfi_mode_sel_val[1]) { 372 p = (port == 26) ? 29 : 31; 373 sal_sprintf(remark, "XFI#Int:%d:==>Ext:%d:", port, p); 374 } 375 break; 376 default: 377 remark[0] = '\0'; 378 break; 379 } 380 } 381 #endif 382 383 384 /* port number (7) 385 * enable/link state (4) 386 * speed/duplex (6) 387 * link scan mode (4) 388 * auto negotiate? (4) 389 * spantree state (7) 390 * pause tx/rx (5) 391 * discard mode (6) 392 * learn to CPU, ARL, FWD or discard (3) 393 */ 394 cli_out("%10s(%3d) %4s ", BCM_PORT_NAME(unit, port), p, 395 !info->enable ? "!ena" : 396 (info->linkstatus == BCM_PORT_LINK_STATUS_FAILED) ? "fail" : 397 (info->linkstatus == BCM_PORT_LINK_STATUS_UP ? "up " : "down")); 398 #ifdef BCM_TOMAHAWK_SUPPORT 399 if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 400 if (flags & BCM_PORT_ATTR_ALL_MASK) { 401 cli_out(" %2d ", info->phy_master); 402 } else { 403 cli_out(" %2s ", ""); 404 } 405 } 406 #endif 407 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_SPEED_MASK, 408 "%5s ", if_fmt_speed(sbuf, info->speed)); 409 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_DUPLEX_MASK, 410 "%3s ", info->speed == 0 ? "" : info->duplex ? "FD" : "HD"); 411 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LINKSCAN_MASK, 412 "%4s ", LINKSCAN_MODE(info->linkscan)); 413 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_AUTONEG_MASK, 414 "%4s ", info->autoneg ? " Yes" : " No "); 415 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_STP_STATE_MASK, 416 " %7s ", spt_str); 417 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_PAUSE_TX_MASK, 418 "%2s ", info->pause_tx ? "TX" : ""); 419 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_PAUSE_RX_MASK, 420 "%2s ", info->pause_rx ? "RX" : ""); 421 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_DISCARD_MASK, 422 "%6s ", discrd_str); 423 424 lrn_ptr = 0; 425 sal_memset(lrn_str, 0, sizeof(lrn_str)); 426 lrn_str[0] = 'D'; 427 if (info->learn & BCM_PORT_LEARN_FWD) { 428 lrn_str[lrn_ptr++] = 'F'; 429 } 430 if (info->learn & BCM_PORT_LEARN_ARL) { 431 lrn_str[lrn_ptr++] = 'A'; 432 } 433 if (info->learn & BCM_PORT_LEARN_CPU) { 434 lrn_str[lrn_ptr++] = 'C'; 435 } 436 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LEARN_MASK, 437 "%3s ", lrn_str); 438 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_INTERFACE_MASK, 439 "%6s ", INTERFACE_MODE(info->interface)); 440 if (flags & BCM_PORT_ATTR_FRAME_MAX_MASK) { 441 cli_out("%5d ", info->frame_max); 442 } else { 443 cli_out("%5s ", ""); 444 } 445 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LOOPBACK_MASK, 446 " %s", 447 info->loopback != BCM_PORT_LOOPBACK_NONE ? 448 LOOPBACK_MODE(info->loopback) : ""); 449 cli_out(" %s\n",remark); 450 return 0; 451 } 452 453 #if defined(BCM_TOMAHAWK_SUPPORT) 454 int 455 esw_brief_port_info(int unit, int port, bcm_port_info_t *info, uint32 flags) 456 { 457 char *spt_str, *discrd_str; 458 char sbuf[6]; 459 int lrn_ptr; 460 char lrn_str[4]; 461 int ret = 0; 462 #if 1 463 char asf_str[4][4] = {"No", "Yes", "Yes", "Yes"}; 464 #endif 465 int asf_mode = 0; 466 int p = 0; 467 #ifdef BCM_TOMAHAWK3_SUPPORT 468 char lane_num[2]; 469 char itf_list[3][3]= {"KR", "CR", "SR"}; 470 char if_name[4]; 471 pm_info_t pm_info; 472 char fec_list[11][10] = {"NONE", "BASE-R", "RS528", "RS544-1xN", "RS272-1xN", "", "", "", "", "RS544-2xN", "RS272-2xN"}; 473 portmod_port_diag_info_t diag_info; 474 phymod_autoneg_status_t an_status; 475 portmod_speed_config_t speed_config_status; 476 int medium_type = 0; 477 #endif 478 p = port; 479 spt_str = FORWARD_MODE(info->stp_state); 480 discrd_str = DISCARD_MODE(info->discard); 481 482 /* port number (7) 483 * enable/link state (4) 484 * speed/duplex (6) 485 * link scan mode (4) 486 * auto negotiate? (4) 487 * spantree state (7) 488 * pause tx/rx (5) 489 * discard mode (6) 490 * learn to CPU, ARL, FWD or discard (3) 491 */ 492 cli_out("%10s(%3d) %4s ", BCM_PORT_NAME(unit, port), p, 493 !info->enable ? "!ena" : 494 (info->linkstatus == BCM_PORT_LINK_STATUS_FAILED) ? "fail" : 495 (info->linkstatus == BCM_PORT_LINK_STATUS_UP ? "up " : "down")); 496 497 if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 498 if (flags & BCM_PORT_ATTR_ALL_MASK) { 499 #ifdef BCM_TOMAHAWK3_SUPPORT 500 /* if TH3 and pm8x50, need to check an resolved num lane */ 501 if (SOC_IS_TOMAHAWK3(unit)) { 502 ret = portmod_pm_info_get(unit, port, &pm_info); 503 if (ret) return ret; 504 /* check is needed PM8x50 only */ 505 if (pm_info->type == portmodDispatchTypePm8x50) { 506 ret = portmod_port_autoneg_status_get(unit, port, &an_status); 507 if (ret) return ret; 508 if (an_status.enabled && an_status.locked) { 509 cli_out(" %2d ", an_status.resolved_num_lane); 510 } else { 511 ret = portmod_port_speed_config_get(unit, port, &speed_config_status); 512 if (ret) return ret; 513 cli_out(" %2d ", speed_config_status.num_lane); 514 } 515 } else { 516 cli_out(" %2d ", info->phy_master); 517 } 518 /*non TH3 device */ 519 } else 520 #endif 521 { 522 cli_out(" %2d ", info->phy_master); 523 } 524 } else { 525 cli_out(" %2s ", ""); 526 } 527 } 528 529 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_SPEED_MASK, 530 "%5s ", if_fmt_speed(sbuf, info->speed)); 531 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_DUPLEX_MASK, 532 "%3s ", info->speed == 0 ? "" : info->duplex ? "FD" : "HD"); 533 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LINKSCAN_MASK, 534 "%4s ", LINKSCAN_MODE(info->linkscan)); 535 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_AUTONEG_MASK, 536 "%4s ", info->autoneg ? " Yes" : " No "); 537 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_STP_STATE_MASK, 538 " %7s ", spt_str); 539 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_PAUSE_TX_MASK, 540 "%2s ", info->pause_tx ? "TX" : ""); 541 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_PAUSE_RX_MASK, 542 "%2s ", info->pause_rx ? "RX" : ""); 543 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_DISCARD_MASK, 544 "%6s ", discrd_str); 545 546 lrn_ptr = 0; 547 sal_memset(lrn_str, 0, sizeof(lrn_str)); 548 lrn_str[0] = 'D'; 549 if (info->learn & BCM_PORT_LEARN_FWD) { 550 lrn_str[lrn_ptr++] = 'F'; 551 } 552 if (info->learn & BCM_PORT_LEARN_ARL) { 553 lrn_str[lrn_ptr++] = 'A'; 554 } 555 if (info->learn & BCM_PORT_LEARN_CPU) { 556 lrn_str[lrn_ptr++] = 'C'; 557 } 558 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LEARN_MASK, 559 "%3s ", lrn_str); 560 561 #ifdef BCM_TOMAHAWK3_SUPPORT 562 if (SOC_IS_TOMAHAWK3(unit)){ 563 ret = portmod_pm_info_get(unit, port, &pm_info); 564 if (ret) return ret; 565 if (pm_info->type == portmodDispatchTypePm8x50) { 566 ret = portmod_port_speed_config_get(unit, port, &speed_config_status); 567 if (ret) { 568 return ret; 569 } 570 medium_type = BCM_PORT_RESOURCE_PHY_LANE_CONFIG_MEDIUM_GET(speed_config_status.lane_config); 571 sal_snprintf(lane_num, 2, "%d", info->phy_master); 572 /* Medium type is backplane */ 573 if (medium_type == 0) { 574 sal_strcpy(if_name, itf_list[0]); 575 /* Medium type is copper */ 576 } else if (medium_type == 1) { 577 sal_strcpy(if_name, itf_list[1]); 578 /* Medium type is optics */ 579 } else if (medium_type == 2) { 580 sal_strcpy(if_name, itf_list[2]); 581 } else { 582 sal_strcpy(if_name, itf_list[0]); 583 } 584 sal_strcat(if_name, lane_num); 585 cli_out("%6s ", if_name); 586 } else { 587 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_INTERFACE_MASK, 588 "%6s ", INTERFACE_MODE(info->interface)); 589 } 590 } else 591 #endif 592 { 593 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_INTERFACE_MASK, 594 "%6s ", INTERFACE_MODE(info->interface)); 595 } 596 if (flags & BCM_PORT_ATTR_FRAME_MAX_MASK) { 597 cli_out("%5d ", info->frame_max); 598 } else { 599 cli_out("%5s ", ""); 600 } 601 if (soc_feature(unit, soc_feature_asf_multimode)) { 602 ret = bcm_switch_control_port_get(unit, port, 603 bcmSwitchAlternateStoreForward, 604 &asf_mode); 605 if (BCM_E_UNAVAIL == ret) { 606 asf_mode = 0; 607 } 608 609 if ((asf_mode >= 0) && (asf_mode <= 3)) { 610 cli_out("%5s ", asf_str[asf_mode]); 611 } else { 612 cli_out("%5s ", " "); 613 } 614 } else { 615 cli_out("%5s ", " "); 616 } 617 #ifdef BCM_TOMAHAWK3_SUPPORT 618 if (SOC_IS_TOMAHAWK3(unit)){ 619 ret = portmod_port_diag_info_get(unit, port, &diag_info); 620 if (ret) return ret; 621 /* _SHR_PORT_PHY_FEC_INVALID is 0 in enum _shr_port_phy_fec_e */ 622 cli_out("%10s ", fec_list[diag_info.fec - 1]); 623 } 624 #endif 625 _CHECK_PRINT(BSL_UNIT_UNKNOWN, flags, BCM_PORT_ATTR_LOOPBACK_MASK, 626 "%5s", 627 info->loopback != BCM_PORT_LOOPBACK_NONE ? 628 LOOPBACK_MODE(info->loopback) : " "); 629 630 cli_out("\n"); 631 return ret; 632 } 633 #endif 634 635 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 636 /* 637 * Function: 638 * if_port_policer 639 * Purpose: 640 * Table display of port information 641 * Parameters: 642 * unit - SOC unit # 643 * a - pointer to args 644 * Returns: 645 * CMD_OK/CMD_FAIL 646 */ 647 cmd_result_t 648 if_esw_port_policer(int unit, args_t *a) 649 { 650 pbmp_t pbm; 651 char *subcmd, *argpbm, *argpid; 652 bcm_policer_t pid = 0; 653 bcm_port_config_t pcfg; 654 soc_port_t port, dport; 655 int rv; 656 657 if (!sh_check_attached(ARG_CMD(a), unit)) { 658 return CMD_FAIL; 659 } 660 661 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 662 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 663 return CMD_FAIL; 664 } 665 666 if ((subcmd = ARG_GET(a)) == NULL) { 667 subcmd = "Get"; 668 } 669 670 if ((argpbm = ARG_GET(a)) == NULL) { 671 pbm = pcfg.port; 672 } else { 673 if (parse_bcm_pbmp(unit, argpbm, &pbm) < 0) { 674 cli_out("%s: ERROR: unrecognized port bitmap: %s\n", 675 ARG_CMD(a), argpbm); 676 return CMD_FAIL; 677 } 678 679 BCM_PBMP_AND(pbm, pcfg.port); 680 } 681 682 if (sal_strcasecmp(subcmd, "Get") == 0) { 683 rv = BCM_E_NONE; 684 /* coverity[overrun-local] */ 685 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 686 if ((rv = bcm_port_policer_get(unit, port, &pid)) < 0) { 687 cli_out("Error retrieving info for port %s: %s\n", 688 BCM_PORT_NAME(unit, port), bcm_errmsg(rv)); 689 break; 690 } 691 692 cli_out("Port %s policer id is %d\n", 693 BCM_PORT_NAME(unit, port), pid); 694 } 695 return (rv < 0) ? CMD_FAIL : CMD_OK; 696 } else if (sal_strcasecmp(subcmd, "Set") == 0) { 697 if ((argpid = ARG_GET(a)) == NULL) { 698 cli_out("Missing PID for set.\n"); 699 return CMD_USAGE; 700 } 701 pid = sal_ctoi(argpid, 0); 702 } else { 703 return CMD_USAGE; 704 } 705 706 /* Set Policer id as indicated */ 707 708 rv = BCM_E_NONE; 709 710 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 711 if ((rv = bcm_port_policer_set(unit, port, pid)) < 0) { 712 cli_out("Error setting port %s default PID to %d: %s\n", 713 BCM_PORT_NAME(unit, port), pid, bcm_errmsg(rv)); 714 715 if ((rv == BCM_E_NOT_FOUND) || (rv == BCM_E_CONFIG)) { 716 cli_out("Error in setting PID %x to port \n", pid); 717 } 718 break; 719 } 720 } 721 return CMD_OK; 722 } 723 #endif /* BCM_KATANA_SUPPORT or BCM_TRIUMPH3_SUPPORT */ 724 /* 725 * Function: 726 * if_port_stat 727 * Purpose: 728 * Table display of port information 729 * Parameters: 730 * unit - SOC unit # 731 * a - pointer to args 732 * Returns: 733 * CMD_OK/CMD_FAIL 734 */ 735 cmd_result_t 736 if_esw_port_stat(int unit, args_t *a) 737 { 738 pbmp_t pbm, tmp_pbm; 739 bcm_port_info_t *info_all; 740 bcm_port_config_t pcfg; 741 soc_port_t p, dport; 742 int r = CMD_OK; 743 char *c; 744 uint32 mask; 745 746 if (!sh_check_attached(ARG_CMD(a), unit)) { 747 return CMD_FAIL; 748 } 749 750 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 751 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 752 return CMD_FAIL; 753 } 754 755 if ((c = ARG_GET(a)) == NULL) { 756 BCM_PBMP_ASSIGN(pbm, pcfg.port); 757 } else if (parse_bcm_pbmp(unit, c, &pbm) < 0) { 758 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(a), c); 759 return CMD_FAIL; 760 } 761 BCM_PBMP_AND(pbm, pcfg.port); 762 if (BCM_PBMP_IS_NULL(pbm)) { 763 cli_out("No ports specified.\n"); 764 return CMD_OK; 765 } 766 767 mask = BCM_PORT_ATTR_ALL_MASK; 768 769 info_all = sal_alloc(SOC_MAX_NUM_PORTS * sizeof(bcm_port_info_t), 770 "if_port_stat"); 771 if (info_all == NULL) { 772 cli_out("Insufficient memory.\n"); 773 return CMD_FAIL; 774 } 775 776 /* coverity[overrun-local] */ 777 DPORT_BCM_PBMP_ITER(unit, pbm, dport, p) { 778 port_info_init(unit, p, &info_all[p], mask); 779 if ((r |= bcm_port_selective_get(unit, p, &info_all[p])) < 0) { 780 cli_out("%s: Error: Could not get port %s information: %s\n", 781 ARG_CMD(a), BCM_PORT_NAME(unit, p), bcm_errmsg(r)); 782 continue; 783 } 784 #ifdef BCM_TOMAHAWK_SUPPORT 785 if (soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 786 /* reusing phy_master to display num of lanes */ 787 /* coverity[overrun-local] */ 788 info_all[p].phy_master = SOC_INFO(unit).port_num_lanes[p]; 789 } 790 #endif 791 } 792 793 brief_port_info_header(unit); 794 795 #if defined(BCM_TOMAHAWK_SUPPORT) 796 #define _call_bpi(pbm, pbm_mask) \ 797 tmp_pbm = pbm_mask; \ 798 BCM_PBMP_AND(tmp_pbm, pbm); \ 799 DPORT_BCM_PBMP_ITER(unit, tmp_pbm, dport, p) { \ 800 esw_brief_port_info(unit, p, &info_all[p], mask); \ 801 } 802 #else 803 #define _call_bpi(pbm, pbm_mask) \ 804 tmp_pbm = pbm_mask; \ 805 BCM_PBMP_AND(tmp_pbm, pbm); \ 806 DPORT_BCM_PBMP_ITER(unit, tmp_pbm, dport, p) { \ 807 brief_port_info(unit, p, &info_all[p], mask); \ 808 } 809 #endif 810 811 if (soc_property_get(unit, spn_DPORT_MAP_ENABLE, TRUE)) { 812 /* If port mapping is enabled, then use port order */ 813 _call_bpi(pbm, pcfg.port); 814 } else { 815 /* If no port mapping, ensure that ports are grouped by type */ 816 _call_bpi(pbm, pcfg.fe); 817 _call_bpi(pbm, pcfg.ge); 818 _call_bpi(pbm, pcfg.xe); 819 _call_bpi(pbm, pcfg.ce); 820 _call_bpi(pbm, pcfg.hg); 821 } 822 823 sal_free(info_all); 824 825 return r; 826 } 827 828 /* 829 * Function: 830 * if_port_rate 831 * Purpose: 832 * Set/display of port rate metering characteristics 833 * Parameters: 834 * unit - SOC unit # 835 * a - pointer to args 836 * Returns: 837 * CMD_OK/CMD_FAIL 838 */ 839 cmd_result_t 840 if_esw_port_rate(int unit, args_t *a) 841 { 842 pbmp_t pbm,tmp_pbm; 843 bcm_port_config_t pcfg; 844 soc_port_t p, dport; 845 int operation = 0; 846 int rv; 847 int header; 848 uint32 rate = 0xFFFFFFFF; 849 uint32 burst = 0xFFFFFFFF; 850 char *c; 851 852 #define SHOW 1 853 #define INGRESS 2 854 #define EGRESS 4 855 #define PAUSE 8 856 857 if (!sh_check_attached(ARG_CMD(a), unit)) { 858 return CMD_FAIL; 859 } 860 861 /* Check for metering capabilities */ 862 if (!soc_feature(unit, soc_feature_ingress_metering) && 863 !soc_feature(unit, soc_feature_egress_metering)) { 864 cli_out("%s: Error: metering unavailable for this device\n", ARG_CMD(a)); 865 return CMD_OK; 866 } 867 868 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 869 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 870 return CMD_FAIL; 871 } 872 873 874 if ((c = ARG_GET(a)) == NULL) { 875 /* Default with only Ethernet ports */ 876 BCM_PBMP_ASSIGN(pbm, pcfg.e); 877 } else if (parse_bcm_pbmp(unit, c, &pbm) < 0) { 878 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(a), c); 879 return CMD_FAIL; 880 } 881 882 883 /* Check if there is HG ports and show warning message */ 884 BCM_PBMP_ASSIGN(tmp_pbm, pbm); 885 BCM_PBMP_AND(tmp_pbm, pcfg.hg); 886 if (BCM_PBMP_NOT_NULL(tmp_pbm)) { 887 cli_out("Warning: Not suggested to control rate on HG ports\n"); 888 } 889 890 /* Apply PortRate only to those ports which support it */ 891 BCM_PBMP_AND(pbm, pcfg.port); 892 if (BCM_PBMP_IS_NULL(pbm)) { 893 cli_out("Warning: No valid ports specified.\n"); 894 return CMD_OK; 895 } 896 897 898 /* Ingress, egress or show both */ 899 if ((c = ARG_GET(a)) == NULL) { 900 operation = SHOW; 901 902 /* Show Ethernet ports and other ports (i.e. HG ...) */ 903 BCM_PBMP_ASSIGN(pbm, pcfg.port); 904 if (soc_feature(unit, soc_feature_ingress_metering)) { 905 operation |= INGRESS; 906 } 907 if (soc_feature(unit, soc_feature_egress_metering)) { 908 operation |= EGRESS; 909 } 910 } else if (!sal_strncasecmp(c, "ingress", sal_strlen(c))) { 911 if (soc_feature(unit, soc_feature_ingress_metering)) { 912 operation = INGRESS; 913 } else { 914 cli_out("%s: Error: ingress metering unavailable for " 915 "this device\n", ARG_CMD(a)); 916 return CMD_OK; 917 } 918 } else if (!sal_strncasecmp(c, "egress", sal_strlen(c))) { 919 if (soc_feature(unit, soc_feature_egress_metering)) { 920 operation = EGRESS; 921 } else { 922 cli_out("%s: Error: egress metering unavailable for " 923 "this device\n", ARG_CMD(a)); 924 return CMD_OK; 925 } 926 } else if (SOC_IS_TUCANA(unit) && 927 !sal_strncasecmp(c, "pause", sal_strlen(c))) { 928 operation = PAUSE; 929 } else { 930 cli_out("%s: Error: unrecognized port rate type: %s\n", ARG_CMD(a), c); 931 return CMD_FAIL; 932 } 933 934 /* Set or get */ 935 if ((c = ARG_GET(a)) != NULL) { 936 rate = parse_integer(c); 937 if ((c = ARG_GET(a)) != NULL) { 938 burst = parse_integer(c); 939 } else { 940 cli_out("%s: Error: missing port burst size\n", ARG_CMD(a)); 941 return CMD_FAIL; 942 } 943 } else { 944 operation |= SHOW; 945 } 946 947 /* coverity[overrun-local] */ 948 DPORT_BCM_PBMP_ITER(unit, pbm, dport, p) { 949 if (operation & SHOW) { 950 /* Display current setting */ 951 header = 0; 952 if (operation & (INGRESS | PAUSE)) { 953 rv = bcm_port_rate_ingress_get(unit, p, &rate, &burst); 954 if (rv < 0) { 955 cli_out("%s port %s: ERROR: bcm_port_rate_ingress_get: " 956 "%s\n", 957 ARG_CMD(a), BCM_PORT_NAME(unit, p), bcm_errmsg(rv)); 958 return CMD_FAIL; 959 } 960 if (rate) { 961 cli_out("%4s:", BCM_PORT_NAME(unit, p)); 962 header = 1; 963 if (rate < 64) { 964 cli_out("\tIngress meter: ? kbps ? kbits max burst.\n"); 965 } else { 966 cli_out("\tIngress meter: " 967 "%8d kbps %8d kbits max burst.\n", rate, burst); 968 } 969 if (SOC_IS_TUCANA(unit)) { 970 rv = bcm_port_rate_pause_get(unit, p, &rate, &burst); 971 if (rv < 0) { 972 cli_out("%s port %s: ERROR: " 973 "bcm_port_rate_pause_get: %s\n", 974 ARG_CMD(a), BCM_PORT_NAME(unit, p), 975 bcm_errmsg(rv)); 976 return CMD_FAIL; 977 } 978 if (rate) { 979 cli_out("\tPause frames: Pause = %8d kbits, " 980 "Resume = %8d kbits.\n", rate, burst); 981 } 982 } 983 } 984 } 985 if (operation & EGRESS) { 986 rv = bcm_port_rate_egress_get(unit, p, &rate, &burst); 987 if (rv < 0) { 988 cli_out("%s port %s: ERROR: bcm_port_rate_egress_get: %s\n", 989 ARG_CMD(a), BCM_PORT_NAME(unit, p), bcm_errmsg(rv)); 990 return CMD_FAIL; 991 } 992 if (rate) { 993 if (!header) 994 cli_out("%4s:", BCM_PORT_NAME(unit, p)); 995 cli_out("\tEgress meter: %8d kbps %8d kbits max burst.\n", 996 rate, burst); 997 } 998 } 999 } else { 1000 /* New setting */ 1001 if (!rate || !burst) 1002 rate = burst = 0; /* Disable port metering */ 1003 if (operation & INGRESS) { 1004 rv = bcm_port_rate_ingress_set(unit, p, rate, burst); 1005 if (rv < 0) { 1006 cli_out("%s: ERROR: bcm_port_rate_ingress_set: %s\n", 1007 ARG_CMD(a), bcm_errmsg(rv)); 1008 return CMD_FAIL; 1009 } 1010 } else if (operation & PAUSE) { 1011 rv = bcm_port_rate_pause_set(unit, p, rate, burst); 1012 if (rv < 0) { 1013 cli_out("%s: ERROR: bcm_port_rate_pause_set: %s\n", 1014 ARG_CMD(a), bcm_errmsg(rv)); 1015 return CMD_FAIL; 1016 } 1017 } else if (operation & EGRESS) { 1018 rv = bcm_port_rate_egress_set(unit, p, rate, burst); 1019 if (rv < 0) { 1020 cli_out("%s: ERROR: bcm_port_rate_egress_set: %s\n", 1021 ARG_CMD(a), bcm_errmsg(rv)); 1022 return CMD_FAIL; 1023 } 1024 } 1025 } 1026 } 1027 #undef SHOW 1028 #undef INGRESS 1029 #undef EGRESS 1030 #undef PAUSE 1031 1032 return CMD_OK; 1033 } 1034 1035 /* 1036 * Function: 1037 * if_port_samp_rate 1038 * Purpose: 1039 * Set/display of sflow port sampling rates. 1040 * Parameters: 1041 * unit - SOC unit # 1042 * args - pointer to comand line arguments 1043 * Returns: 1044 * CMD_OK/CMD_FAIL 1045 */ 1046 char if_port_samp_rate_usage[] = 1047 "Set/Display port sampling rate characteristics.\n" 1048 "Parameters: <pbm> [ingress_rate] [egress_rate]\n" 1049 "\tOn average, every 1/ingress_rate packets will be sampled.\n" 1050 "\tA rate of 0 indicates no sampling.\n" 1051 "\tA rate of 1 indicates all packets sampled.\n"; 1052 1053 cmd_result_t 1054 if_port_samp_rate(int unit, args_t *args) 1055 { 1056 #define SHOW 0x01 1057 #define SET 0x02 1058 pbmp_t pbm; 1059 bcm_port_config_t pcfg; 1060 char *ch; 1061 int operation = SET; /* Set or Show */ 1062 int ingress_rate = -1; 1063 int egress_rate = -1; 1064 soc_port_t soc_port, dport; 1065 int retval; 1066 1067 if (!sh_check_attached(ARG_CMD(args), unit)) { 1068 return CMD_FAIL; 1069 } 1070 1071 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 1072 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(args)); 1073 return CMD_FAIL; 1074 } 1075 1076 /* get port bitmap */ 1077 if ((ch = ARG_GET(args)) == NULL) { 1078 BCM_PBMP_ASSIGN(pbm, pcfg.port); 1079 } else if (parse_bcm_pbmp(unit, ch, &pbm) < 0) { 1080 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(args), ch); 1081 return CMD_FAIL; 1082 } 1083 1084 /* read in ingress_rate and egress_rate if given */ 1085 if ((ch = ARG_GET(args)) != NULL) { 1086 ingress_rate = parse_integer(ch); 1087 if ((ch = ARG_GET(args)) != NULL) { 1088 egress_rate = parse_integer(ch); 1089 } else { 1090 cli_out("%s: Error: missing egress rate \n", ARG_CMD(args)); 1091 return CMD_FAIL; 1092 } 1093 } else { 1094 operation = SHOW; 1095 } 1096 1097 /* Iterate through port bitmap and perform 'operation' on them. */ 1098 /* coverity[overrun-local] */ 1099 DPORT_BCM_PBMP_ITER(unit, pbm, dport, soc_port) { 1100 if (operation == SHOW) { 1101 /* Show port sflow sample rate(s) */ 1102 retval = bcm_port_sample_rate_get(unit, soc_port, &ingress_rate, 1103 &egress_rate); 1104 if (retval != BCM_E_NONE) { 1105 cli_out("%s port %s: ERROR: bcm_port_sample_rate_get: " 1106 "%s\n", ARG_CMD(args), 1107 BCM_PORT_NAME(unit, soc_port), bcm_errmsg(retval)); 1108 return CMD_FAIL; 1109 } 1110 1111 cli_out("%4s:", BCM_PORT_NAME(unit, soc_port)); 1112 1113 if (ingress_rate == 0) { 1114 cli_out("\tingress: not sampling,"); 1115 } else { 1116 cli_out("\tingress: 1 out of %d packets,", ingress_rate); 1117 } 1118 if (egress_rate == 0) { 1119 cli_out("\tegress: not sampling,"); 1120 } else { 1121 cli_out("\tegress: 1 out of %d packets,", egress_rate); 1122 } 1123 cli_out("\n"); 1124 } else { 1125 /* Set port sflow sample rate(s) */ 1126 retval = bcm_port_sample_rate_set(unit, soc_port, ingress_rate, 1127 egress_rate); 1128 if (retval != BCM_E_NONE) { 1129 cli_out("%s port %s: ERROR: bcm_port_sample_rate_set: " 1130 "%s\n", ARG_CMD(args), 1131 BCM_PORT_NAME(unit, soc_port), bcm_errmsg(retval)); 1132 return CMD_FAIL; 1133 } 1134 } 1135 } 1136 1137 #undef SHOW 1138 #undef SET 1139 return CMD_OK; 1140 } 1141 1142 /* 1143 * Function: 1144 * disp_port_info 1145 * Purpose: 1146 * Display selected port information 1147 * Parameters: 1148 * info - pointer to structure with info to display 1149 * port_ref - Port reference to print 1150 * st_port - Is the port a hi-gig port? 1151 * Returns: 1152 * Nothing 1153 * Notes: 1154 * Assumes link status info always valid 1155 */ 1156 1157 void 1158 disp_port_info(int unit, char *port_ref, bcm_port_t port, bcm_port_info_t *info, 1159 int st_port, uint32 flags) 1160 { 1161 int r; 1162 int no_an_props = 0; /* Do not show AN props */ 1163 bcm_port_ability_t *local = &info->port_ability; 1164 bcm_port_ability_t *remote = &info->remote_ability; 1165 bcm_port_ability_t *advert = &info->local_ability; 1166 #if defined(BCM_ESW_SUPPORT) 1167 _bcm_port_info_t *port_info; 1168 #endif 1169 1170 /* Assume link status always available. */ 1171 cli_out(" %c%-7s ", info->linkstatus ? '*' : ' ', port_ref); 1172 1173 if (info->linkstatus == BCM_PORT_LINK_STATUS_FAILED) { 1174 cli_out("%s", "FAILED "); 1175 } 1176 1177 if (flags & BCM_PORT_ATTR_ENABLE_MASK) { 1178 cli_out("%s", info->enable ? "(Enabled" : "(Disabled "); 1179 } 1180 1181 if (flags & BCM_PORT_ATTR_LINKSCAN_MASK) { 1182 if (info->linkscan) { 1183 cli_out("LS(%s ", LINKSCAN_MODE(info->linkscan)); 1184 } 1185 } 1186 if (st_port) { 1187 /* 1188 * Coverity 1189 * coverity[result_independent_of_operands] 1190 */ 1191 cli_out("%s(", ENCAP_MODE(info->encap_mode)); 1192 } else if (flags & BCM_PORT_ATTR_AUTONEG_MASK) { 1193 if (info->autoneg) { 1194 if (info->linkstatus != BCM_PORT_LINK_STATUS_UP) { 1195 cli_out("Auto(no link) "); 1196 no_an_props = 1; 1197 } else { 1198 cli_out("Auto("); 1199 } 1200 } else { 1201 cli_out("Forced("); 1202 } 1203 } 1204 1205 /* If AN is enabled, but not complete, don't show port settings */ 1206 if (!no_an_props) { 1207 if (flags & BCM_PORT_ATTR_SPEED_MASK) { 1208 char buf[32]; 1209 cli_out("(%s", if_fmt_speed(buf, info->speed)); 1210 } 1211 if (flags & BCM_PORT_ATTR_DUPLEX_MASK) { 1212 cli_out("%s", info->speed == 0 ? "" : info->duplex ? "FD" : "HD"); 1213 } 1214 if (flags & BCM_PORT_ATTR_PAUSE_MASK) { 1215 if (info->pause_tx && info->pause_rx) { 1216 cli_out(",pause"); 1217 } else if (info->pause_tx) { 1218 cli_out(",pause_tx"); 1219 } else if (info->pause_rx) { 1220 cli_out(",pause_rx"); 1221 } 1222 } 1223 cli_out(") "); 1224 } 1225 1226 if (flags & BCM_PORT_ATTR_AUTONEG_MASK) { 1227 if (info->autoneg) { 1228 char buf[80]; 1229 1230 if (flags & BCM_PORT_ATTR_ABILITY_MASK) { 1231 format_port_speed_ability(buf, sizeof(buf), 1232 local->speed_full_duplex); 1233 cli_out("Ability (fd = %s ", buf); 1234 format_port_speed_ability(buf, sizeof(buf), 1235 local->speed_half_duplex); 1236 cli_out("hd = %s ", buf); 1237 format_port_intf_ability(buf, sizeof(buf), local->interface); 1238 cli_out("intf = %s ", buf); 1239 format_port_medium_ability(buf, sizeof(buf), local->medium); 1240 cli_out("medium = %s ", buf); 1241 format_port_pause_ability(buf, sizeof(buf), local->pause); 1242 cli_out("pause = %s ", buf); 1243 format_port_lb_ability(buf, sizeof(buf), local->loopback); 1244 cli_out("lb = %s ", buf); 1245 format_port_flags_ability(buf, sizeof(buf), local->flags); 1246 cli_out("flags = %s )", buf); 1247 } 1248 1249 if (flags & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) { 1250 format_port_speed_ability(buf, sizeof(buf), 1251 advert->speed_full_duplex); 1252 cli_out("Local (fd = %s ", buf); 1253 format_port_speed_ability(buf, sizeof(buf), 1254 advert->speed_half_duplex); 1255 cli_out("hd = %s ", buf); 1256 format_port_intf_ability(buf, sizeof(buf), advert->interface); 1257 cli_out("intf = %s", buf); 1258 format_port_medium_ability(buf, sizeof(buf), advert->medium); 1259 cli_out("medium = %s ", buf); 1260 format_port_pause_ability(buf, sizeof(buf), advert->pause); 1261 cli_out("pause = %s ", buf); 1262 format_port_lb_ability(buf, sizeof(buf), advert->loopback); 1263 cli_out("lb = %s ", buf); 1264 format_port_flags_ability(buf, sizeof(buf), advert->flags); 1265 cli_out("flags = %s )", buf); 1266 } 1267 1268 if ((flags & BCM_PORT_ATTR_REMOTE_ADVERT_MASK) && 1269 info->remote_advert_valid && 1270 (info->linkstatus == BCM_PORT_LINK_STATUS_UP)) { 1271 format_port_speed_ability(buf, sizeof(buf), 1272 remote->speed_full_duplex); 1273 cli_out("Remote (fd = %s ", buf); 1274 format_port_speed_ability(buf, sizeof(buf), 1275 remote->speed_half_duplex); 1276 cli_out("hd = %s ", buf); 1277 format_port_intf_ability(buf, sizeof(buf), remote->interface); 1278 cli_out("intf = %s ", buf); 1279 format_port_medium_ability(buf, sizeof(buf), remote->medium); 1280 cli_out("medium = %s ", buf); 1281 format_port_pause_ability(buf, sizeof(buf), remote->pause); 1282 cli_out("pause = %s ", buf); 1283 format_port_lb_ability(buf, sizeof(buf), remote->loopback); 1284 cli_out("lb = %s ", buf); 1285 format_port_flags_ability(buf, sizeof(buf), remote->flags); 1286 cli_out("flags = %s )", buf); 1287 } 1288 } 1289 } 1290 1291 if (flags & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 1292 if ((info->pause_mac[0] | info->pause_mac[1] | 1293 info->pause_mac[2] | info->pause_mac[3] | 1294 info->pause_mac[4] | info->pause_mac[5]) != 0) { 1295 cli_out("Stad(%02x:%02x:%02x:%02x:%02x:%02x) ", 1296 info->pause_mac[0], info->pause_mac[1], 1297 info->pause_mac[2], info->pause_mac[3], 1298 info->pause_mac[4], info->pause_mac[5]); 1299 } 1300 } 1301 1302 if (flags & BCM_PORT_ATTR_STP_STATE_MASK) { 1303 cli_out("STP(%s) ", FORWARD_MODE(info->stp_state)); 1304 } 1305 1306 if (!st_port) { 1307 if (flags & BCM_PORT_ATTR_DISCARD_MASK) { 1308 switch (info->discard) { 1309 case BCM_PORT_DISCARD_NONE: 1310 break; 1311 case BCM_PORT_DISCARD_ALL: 1312 cli_out("Disc(all) "); 1313 break; 1314 case BCM_PORT_DISCARD_UNTAG: 1315 cli_out("Disc(untagged) "); 1316 break; 1317 case BCM_PORT_DISCARD_TAG: 1318 cli_out("Disc(tagged) "); 1319 break; 1320 default: 1321 cli_out("Disc(?) "); 1322 break; 1323 } 1324 } 1325 1326 if (flags & BCM_PORT_ATTR_LEARN_MASK) { 1327 cli_out("Lrn("); 1328 1329 r = 0; 1330 1331 if (info->learn & BCM_PORT_LEARN_ARL) { 1332 cli_out("ARL"); 1333 r = 1; 1334 } 1335 1336 if (info->learn & BCM_PORT_LEARN_CPU) { 1337 cli_out("%sCPU", r ? "," : ""); 1338 r = 1; 1339 } 1340 1341 if (info->learn & BCM_PORT_LEARN_FWD) { 1342 cli_out("%sFWD", r ? "," : ""); 1343 r = 1; 1344 } 1345 1346 if (!r) { 1347 cli_out("disc"); 1348 } 1349 cli_out(") "); 1350 } 1351 1352 if (flags & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 1353 cli_out("UtPri("); 1354 1355 if (info->untagged_priority < 0) { 1356 cli_out("off"); 1357 } else { 1358 cli_out("%d", info->untagged_priority); 1359 } 1360 cli_out(") "); 1361 } 1362 1363 if (flags & BCM_PORT_ATTR_PFM_MASK) { 1364 cli_out("Pfm(%s) ", MCAST_FLOOD(info->pfm)); 1365 } 1366 } /* !st_port */ 1367 if (flags & BCM_PORT_ATTR_INTERFACE_MASK) { 1368 if (info->interface >= 0 && info->interface < SOC_PORT_IF_COUNT) { 1369 cli_out("IF(%s) ", INTERFACE_MODE(info->interface)); 1370 } 1371 } 1372 1373 if (flags & BCM_PORT_ATTR_PHY_MASTER_MASK) { 1374 if (info->phy_master >= 0 && 1375 info->phy_master < SOC_PORT_MS_COUNT && 1376 info->phy_master != SOC_PORT_MS_NONE) { 1377 cli_out("PH(%s) ", PHYMASTER_MODE(info->phy_master)); 1378 } 1379 } 1380 1381 if (flags & BCM_PORT_ATTR_LOOPBACK_MASK) { 1382 if (info->loopback == BCM_PORT_LOOPBACK_PHY) { 1383 cli_out("LB(PHY) "); 1384 } else if (info->loopback == BCM_PORT_LOOPBACK_MAC) { 1385 cli_out("LB(MAC) "); 1386 } 1387 } 1388 1389 if (flags & BCM_PORT_ATTR_FRAME_MAX_MASK) { 1390 cli_out("Max_frame(%d) ", info->frame_max); 1391 } 1392 1393 if ((flags & BCM_PORT_ATTR_MDIX_MASK) && 1394 (0 <= info->mdix) && (info->mdix < BCM_PORT_MDIX_COUNT)) { 1395 cli_out("MDIX(%s", MDIX_MODE(info->mdix)); 1396 1397 if ((flags & BCM_PORT_ATTR_MDIX_STATUS_MASK) && 1398 (0 <= info->mdix_status) && 1399 (info->mdix_status < BCM_PORT_MDIX_STATUS_COUNT)) { 1400 cli_out(", %s", MDIX_STATUS(info->mdix_status)); 1401 } 1402 1403 cli_out(") "); 1404 } 1405 1406 if ((flags & BCM_PORT_ATTR_MEDIUM_MASK) && 1407 (0 <= info->medium) && (info->medium < BCM_PORT_MEDIUM_COUNT)) { 1408 cli_out("Medium(%s) ", MEDIUM_STATUS(info->medium)); 1409 } 1410 1411 if ((flags & BCM_PORT_ATTR_FAULT_MASK) && (info->fault)) { 1412 cli_out("Fault(%s%s) ", 1413 (info->fault & BCM_PORT_FAULT_LOCAL) ? "Local" : "", 1414 (info->fault & BCM_PORT_FAULT_REMOTE) ? "Remote" : ""); 1415 } 1416 1417 if ((flags & BCM_PORT_ATTR_VLANFILTER_MASK) && (info->vlanfilter > 0)) { 1418 cli_out("VLANFILTER(%d) ", info->vlanfilter); 1419 } 1420 1421 #if defined(BCM_ESW_SUPPORT) 1422 if (!SOC_USE_PORTCTRL(unit)) { 1423 _bcm_port_info_access(unit, port, &port_info); 1424 if (port_info != NULL) { 1425 cli_out("Mac driver(%s)", port_info->p_mac->drv_name); 1426 } else { 1427 cli_out("Mac driver(%s)", "NULL"); 1428 } 1429 } 1430 #endif 1431 1432 cli_out("\n"); 1433 } 1434 1435 /* This maps the above list to the masks for the proper attributes 1436 * Note that the order of this attribute map should match that of 1437 * the parse-table entry/creation below. 1438 */ 1439 static int port_attr_map[] = { 1440 BCM_PORT_ATTR_ENABLE_MASK, /* Enable */ 1441 BCM_PORT_ATTR_AUTONEG_MASK, /* AutoNeg */ 1442 BCM_PORT_ATTR_LOCAL_ADVERT_MASK, /* ADVert */ 1443 BCM_PORT_ATTR_SPEED_MASK, /* SPeed */ 1444 BCM_PORT_ATTR_DUPLEX_MASK, /* FullDuplex */ 1445 BCM_PORT_ATTR_LINKSCAN_MASK, /* LinkScan */ 1446 BCM_PORT_ATTR_LEARN_MASK, /* LeaRN */ 1447 BCM_PORT_ATTR_DISCARD_MASK, /* DISCard */ 1448 BCM_PORT_ATTR_VLANFILTER_MASK, /* VlanFilter */ 1449 BCM_PORT_ATTR_UNTAG_PRI_MASK, /* PRIOrity */ 1450 BCM_PORT_ATTR_PFM_MASK, /* PortFilterMode */ 1451 BCM_PORT_ATTR_PHY_MASTER_MASK, /* PHymaster */ 1452 BCM_PORT_ATTR_INTERFACE_MASK, /* InterFace */ 1453 BCM_PORT_ATTR_LOOPBACK_MASK, /* LoopBack */ 1454 BCM_PORT_ATTR_STP_STATE_MASK, /* SpanningTreeProtocol */ 1455 BCM_PORT_ATTR_PAUSE_MAC_MASK, /* STationADdress */ 1456 BCM_PORT_ATTR_PAUSE_TX_MASK, /* TxPAUse */ 1457 BCM_PORT_ATTR_PAUSE_RX_MASK, /* RxPAUse */ 1458 BCM_PORT_ATTR_ENCAP_MASK, /* Port encapsulation mode */ 1459 BCM_PORT_ATTR_FRAME_MAX_MASK, /* Max receive frame size */ 1460 BCM_PORT_ATTR_MDIX_MASK, /* MDIX mode */ 1461 BCM_PORT_ATTR_MEDIUM_MASK, /* port MEDIUM */ 1462 }; 1463 1464 /* 1465 * Function: 1466 * port_parse_setup 1467 * Purpose: 1468 * Setup the parse table for a port command 1469 * Parameters: 1470 * pt - the table 1471 * info - port info structure to hold parse results 1472 * Returns: 1473 * Nothing 1474 */ 1475 1476 void 1477 port_parse_setup(int unit, parse_table_t *pt, bcm_port_info_t *info) 1478 { 1479 int i; 1480 1481 /* 1482 * NOTE: ENTRIES IN THIS TABLE ARE POSITION-DEPENDENT! 1483 * See references to PQ_PARSED below. 1484 */ 1485 parse_table_init(unit, pt); 1486 parse_table_add(pt, "Enable", PQ_BOOL | PQ_DFL | PQ_NO_EQ_OPT, 1487 0, &info->enable, 0); 1488 parse_table_add(pt, "AutoNeg", PQ_BOOL | PQ_DFL | PQ_NO_EQ_OPT, 1489 0, &info->autoneg, 0); 1490 if (info->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) { 1491 parse_table_add(pt, "ADVert", PQ_PORTABIL | PQ_DFL | PQ_NO_EQ_OPT, 1492 0, &info->local_ability, 0); 1493 } else { 1494 parse_table_add(pt, "ADVert", PQ_PORTMODE | PQ_DFL | PQ_NO_EQ_OPT, 1495 0, &info->local_advert, 0); 1496 } 1497 parse_table_add(pt, "SPeed", PQ_INT | PQ_DFL | PQ_NO_EQ_OPT, 1498 0, &info->speed, 0); 1499 parse_table_add(pt, "FullDuplex", PQ_BOOL | PQ_DFL | PQ_NO_EQ_OPT, 1500 0, &info->duplex, 0); 1501 parse_table_add(pt, "LinkScan", PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1502 0, &info->linkscan, linkscan_mode); 1503 parse_table_add(pt, "LeaRN", PQ_INT | PQ_DFL | PQ_NO_EQ_OPT, 1504 0, &info->learn, 0); 1505 parse_table_add(pt, "DISCard", PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1506 0, &info->discard, discard_mode); 1507 parse_table_add(pt, "VlanFilter", PQ_INT | PQ_DFL | PQ_NO_EQ_OPT, 1508 0, &info->vlanfilter, 0); 1509 parse_table_add(pt, "PRIOrity", PQ_INT | PQ_DFL | PQ_NO_EQ_OPT, 1510 0, &info->untagged_priority, 0); 1511 parse_table_add(pt, "PortFilterMode", PQ_INT | PQ_DFL | PQ_NO_EQ_OPT, 1512 0, &info->pfm, 0); 1513 parse_table_add(pt, "PHymaster", PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1514 0, &info->phy_master, phymaster_mode); 1515 parse_table_add(pt, "InterFace", PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1516 0, &info->interface, interface_mode); 1517 parse_table_add(pt, "LoopBack", PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1518 0, &info->loopback, loopback_mode); 1519 parse_table_add(pt, "SpanningTreeProtocol", 1520 PQ_MULTI | PQ_DFL | PQ_NO_EQ_OPT, 1521 0, &info->stp_state, forward_mode); 1522 parse_table_add(pt, "STationADdress", PQ_MAC | PQ_DFL | PQ_NO_EQ_OPT, 1523 0, &info->pause_mac, 0); 1524 parse_table_add(pt, "TxPAUse", PQ_BOOL | PQ_DFL | PQ_NO_EQ_OPT, 1525 0, &info->pause_tx, 0); 1526 parse_table_add(pt, "RxPAUse", PQ_BOOL | PQ_DFL | PQ_NO_EQ_OPT, 1527 0, &info->pause_rx, 0); 1528 parse_table_add(pt, "ENCapsulation", PQ_MULTI | PQ_DFL, 1529 0, &info->encap_mode, encap_mode); 1530 parse_table_add(pt, "FrameMax", PQ_INT | PQ_DFL, 0, &info->frame_max, 0); 1531 parse_table_add(pt, "MDIX", PQ_MULTI | PQ_DFL, 0, &info->mdix, mdix_mode); 1532 parse_table_add(pt, "Medium", PQ_MULTI | PQ_DFL, 1533 0, &info->medium, medium_status); 1534 1535 if (SOC_IS_ARAD(unit)) { 1536 #ifdef BCM_PETRA_SUPPORT 1537 for (i = 0; i < pt->pt_cnt; i++) { 1538 if (~_BCM_DPP_PORT_ATTRS & port_attr_map[i]) { 1539 pt->pt_entries[i].pq_type |= PQ_IGNORE; 1540 } 1541 } 1542 #endif 1543 } else if (SOC_IS_DFE(unit)) { 1544 #ifdef BCM_DFE_SUPPORT 1545 for (i = 0; i < pt->pt_cnt; i++) { 1546 if (~_BCM_DFE_PORT_ATTRS & port_attr_map[i]) { 1547 pt->pt_entries[i].pq_type |= PQ_IGNORE; 1548 } 1549 } 1550 #endif 1551 } else if (SOC_IS_XGS12_FABRIC(unit)) { 1552 /* For Hercules, ignore some StrataSwitch attributes */ 1553 for (i = 0; i < pt->pt_cnt; i++) { 1554 if (~BCM_PORT_HERC_ATTRS & port_attr_map[i]) { 1555 pt->pt_entries[i].pq_type |= PQ_IGNORE; 1556 } 1557 } 1558 } else if (!SOC_IS_XGS(unit)) { 1559 /* For all non-XGS chips, ignore special XGS attributes */ 1560 for (i = 0; i < pt->pt_cnt; i++) { 1561 if (BCM_PORT_XGS_ATTRS & port_attr_map[i]) { 1562 pt->pt_entries[i].pq_type |= PQ_IGNORE; 1563 } 1564 } 1565 } 1566 } 1567 1568 /* 1569 * Function: 1570 * port_parse_mask_get 1571 * Purpose: 1572 * Given PT has been parsed, set seen and parsed flags 1573 * Parameters: 1574 * pt - the table 1575 * seen - which parameters occurred w/o = 1576 * parsed- which parameters occurred w = 1577 * Returns: 1578 * Nothing 1579 */ 1580 1581 void 1582 port_parse_mask_get(parse_table_t *pt, uint32 *seen, uint32 *parsed) 1583 { 1584 uint32 were_parsed = 0; 1585 uint32 were_seen = 0; 1586 int i; 1587 1588 /* Check that either all parameters are parsed or are seen (no =) */ 1589 1590 for (i = 0; i < pt->pt_cnt; i++) { 1591 if (pt->pt_entries[i].pq_type & PQ_SEEN) { 1592 were_seen |= port_attr_map[i]; 1593 } 1594 1595 if (pt->pt_entries[i].pq_type & PQ_PARSED) { 1596 were_parsed |= port_attr_map[i]; 1597 } 1598 } 1599 1600 *seen = were_seen; 1601 *parsed = were_parsed; 1602 } 1603 1604 /* Invalid unit number ( < 0) is permitted */ 1605 void 1606 port_info_init(int unit, int port, bcm_port_info_t *info, uint32 actions) 1607 { 1608 bcm_port_info_t_init(info); 1609 1610 info->action_mask = actions; 1611 1612 /* We generally need to get link state */ 1613 info->action_mask |= BCM_PORT_ATTR_LINKSTAT_MASK; 1614 1615 /* Add the autoneg and advert masks if any of actions is possibly 1616 * related to the autoneg. 1617 */ 1618 if (actions & (BCM_PORT_AN_ATTRS | 1619 BCM_PORT_ATTR_AUTONEG_MASK | 1620 BCM_PORT_ATTR_LOCAL_ADVERT_MASK)) { 1621 info->action_mask |= BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 1622 info->action_mask |= BCM_PORT_ATTR_REMOTE_ADVERT_MASK; 1623 info->action_mask |= BCM_PORT_ATTR_AUTONEG_MASK; 1624 } 1625 1626 /* if forced speed mode, speed_set should be called */ 1627 if ((info->action_mask & BCM_PORT_ATTR_AUTONEG_MASK) && 1628 (info->autoneg == 0)) { 1629 info->action_mask |= BCM_PORT_ATTR_SPEED_MASK; 1630 } 1631 1632 if (unit >= 0) { 1633 1634 if (unit >= 0 && SOC_IS_XGS12_FABRIC(unit)) { 1635 info->action_mask |= BCM_PORT_ATTR_ENCAP_MASK; 1636 } 1637 1638 /* Clear rate for HG/HL ports */ 1639 if (IS_ST_PORT(unit, port)) { 1640 info->action_mask &= ~(BCM_PORT_ATTR_RATE_MCAST_MASK | 1641 BCM_PORT_ATTR_RATE_BCAST_MASK | 1642 BCM_PORT_ATTR_RATE_DLFBC_MASK); 1643 } 1644 1645 if (SOC_IS_SC_CQ(unit) || SOC_IS_TRIUMPH2(unit) || 1646 SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit) || 1647 SOC_IS_TD_TT(unit) || SOC_IS_HAWKEYE(unit) || 1648 SOC_IS_GREYHOUND(unit) || SOC_IS_TRIUMPH3(unit) || 1649 SOC_IS_HURRICANE3(unit) || SOC_IS_JERICHO(unit) || 1650 SOC_IS_KATANA2(unit) || SOC_IS_GREYHOUND2(unit)) { 1651 info->action_mask2 |= BCM_PORT_ATTR2_PORT_ABILITY; 1652 } 1653 } 1654 } 1655 1656 /* Given a maximum speed, return the mask of bcm_port_ability_t speeds 1657 * while are less than or equal to the given speed. */ 1658 bcm_port_abil_t 1659 port_speed_max_mask(bcm_port_abil_t max_speed) 1660 { 1661 bcm_port_abil_t speed_mask = 0; 1662 /* This is a giant fall through switch */ 1663 switch (max_speed) { 1664 case 127000: 1665 speed_mask |= BCM_PORT_ABILITY_127GB; 1666 case 120000: 1667 speed_mask |= BCM_PORT_ABILITY_120GB; 1668 case 106000: 1669 speed_mask |= BCM_PORT_ABILITY_106GB; 1670 case 100000: 1671 speed_mask |= BCM_PORT_ABILITY_100GB; 1672 case 53000: 1673 speed_mask |= BCM_PORT_ABILITY_53GB; 1674 case 50000: 1675 speed_mask |= BCM_PORT_ABILITY_50GB; 1676 case 48000: 1677 speed_mask |= BCM_PORT_ABILITY_48GB; 1678 case 42000: 1679 speed_mask |= BCM_PORT_ABILITY_42GB; 1680 case 40000: 1681 speed_mask |= BCM_PORT_ABILITY_40GB; 1682 case 32000: 1683 speed_mask |= BCM_PORT_ABILITY_32GB; 1684 case 30000: 1685 speed_mask |= BCM_PORT_ABILITY_30GB; 1686 case 25000: 1687 speed_mask |= BCM_PORT_ABILITY_25GB; 1688 case 24000: 1689 speed_mask |= BCM_PORT_ABILITY_24GB; 1690 case 21000: 1691 speed_mask |= BCM_PORT_ABILITY_21GB; 1692 case 20000: 1693 speed_mask |= BCM_PORT_ABILITY_20GB; 1694 case 16000: 1695 speed_mask |= BCM_PORT_ABILITY_16GB; 1696 case 15000: 1697 speed_mask |= BCM_PORT_ABILITY_15GB; 1698 case 13000: 1699 speed_mask |= BCM_PORT_ABILITY_13GB; 1700 case 12500: 1701 speed_mask |= BCM_PORT_ABILITY_12P5GB; 1702 case 12000: 1703 speed_mask |= BCM_PORT_ABILITY_12GB; 1704 case 10000: 1705 speed_mask |= BCM_PORT_ABILITY_10GB; 1706 case 6000: 1707 speed_mask |= BCM_PORT_ABILITY_6000MB; 1708 case 5000: 1709 speed_mask |= BCM_PORT_ABILITY_5000MB; 1710 case 3000: 1711 speed_mask |= BCM_PORT_ABILITY_3000MB; 1712 case 2500: 1713 speed_mask |= BCM_PORT_ABILITY_2500MB; 1714 case 1000: 1715 speed_mask |= BCM_PORT_ABILITY_1000MB; 1716 case 100: 1717 speed_mask |= BCM_PORT_ABILITY_100MB; 1718 case 10: 1719 speed_mask |= BCM_PORT_ABILITY_10MB; 1720 default: 1721 break; 1722 } 1723 return speed_mask; 1724 } 1725 1726 /* 1727 * Function: 1728 * port_parse_port_info_set 1729 * Purpose: 1730 * Set/change values in a destination according to parsing 1731 * Parameters: 1732 * flags - What values to change 1733 * src - Where to get info from 1734 * dest - Where to put info 1735 * Returns: 1736 * -1 on error. 0 on success 1737 * Notes: 1738 * The speed_max and abilities values must be 1739 * set in the src port info structure before this is called. 1740 * 1741 * Assumes linkstat and autoneg are valid in the dest structure 1742 * If autoneg is specified in flags, assumes local advert 1743 * is valid in the dest structure. 1744 */ 1745 1746 int 1747 port_parse_port_info_set(uint32 flags, 1748 bcm_port_info_t *src, bcm_port_info_t *dest) 1749 { 1750 int info_speed_adj; 1751 1752 if (flags & BCM_PORT_ATTR_AUTONEG_MASK) { 1753 dest->autoneg = src->autoneg; 1754 } 1755 1756 if (flags & BCM_PORT_ATTR_ENABLE_MASK) { 1757 dest->enable = src->enable; 1758 } 1759 1760 if (flags & BCM_PORT_ATTR_STP_STATE_MASK) { 1761 dest->stp_state = src->stp_state; 1762 } 1763 1764 /* 1765 * info_speed_adj is the same as src->speed except a speed of 0 1766 * is replaced by the maximum speed supported by the port. 1767 */ 1768 1769 info_speed_adj = src->speed; 1770 1771 if ((flags & BCM_PORT_ATTR_SPEED_MASK) && (info_speed_adj == 0)) { 1772 info_speed_adj = src->speed_max; 1773 } 1774 1775 /* 1776 * If local_advert was parsed, use it. Otherwise, calculate a 1777 * reasonable local advertisement from the given values and current 1778 * values of speed/duplex. 1779 */ 1780 1781 if ((flags & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) != 0) { 1782 if (dest->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) { 1783 /* Copy source advert info to destination, converting the 1784 * format in the process */ 1785 BCM_IF_ERROR_RETURN 1786 (soc_port_mode_to_ability(src->local_advert, 1787 &(dest->local_ability))); 1788 1789 /* in case the PQ_PORTABIL is used for parsing */ 1790 if (!src->local_advert) { 1791 dest->local_ability = src->local_ability; 1792 } 1793 } else { 1794 dest->local_advert = src->local_advert; 1795 } 1796 } else if (dest->autoneg) { 1797 int cur_speed, cur_duplex; 1798 int cur_pause_tx, cur_pause_rx; 1799 int new_speed, new_duplex; 1800 int new_pause_tx, new_pause_rx; 1801 bcm_port_abil_t mode; 1802 1803 /* 1804 * Update link advertisements for speed/duplex/pause. All 1805 * speeds less than or equal to the requested speed are 1806 * advertised. 1807 */ 1808 1809 if (dest->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) { 1810 bcm_port_ability_t *dab, *sab; 1811 1812 dab = &(dest->local_ability); 1813 sab = &(src->port_ability); 1814 1815 cur_speed = 1816 BCM_PORT_ABILITY_SPEED_MAX(dab->speed_full_duplex | 1817 dab->speed_half_duplex); 1818 cur_duplex = (dab->speed_full_duplex ? 1819 SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF); 1820 cur_pause_tx = (dab->pause & BCM_PORT_ABILITY_PAUSE_TX) != 0; 1821 cur_pause_rx = (dab->pause & BCM_PORT_ABILITY_PAUSE_RX) != 0; 1822 1823 new_speed = (flags & BCM_PORT_ATTR_SPEED_MASK ? 1824 info_speed_adj : cur_speed); 1825 new_duplex = (flags & BCM_PORT_ATTR_DUPLEX_MASK ? 1826 src->duplex : cur_duplex); 1827 new_pause_tx = (flags & BCM_PORT_ATTR_PAUSE_TX_MASK ? 1828 src->pause_tx : cur_pause_tx); 1829 new_pause_rx = (flags & BCM_PORT_ATTR_PAUSE_RX_MASK ? 1830 src->pause_rx : cur_pause_rx); 1831 1832 if (new_duplex != SOC_PORT_DUPLEX_HALF) { 1833 mode = sab->speed_full_duplex; 1834 mode &= port_speed_max_mask(new_speed); 1835 dab->speed_full_duplex = mode; 1836 } else { 1837 dab->speed_full_duplex = 0; 1838 } 1839 1840 mode = sab->speed_half_duplex; 1841 mode &= port_speed_max_mask(new_speed); 1842 dab->speed_half_duplex = mode; 1843 1844 if (!(sab->pause & 1845 BCM_PORT_ABILITY_PAUSE_ASYMM) && 1846 (new_pause_tx != new_pause_rx)) { 1847 cli_out("port parse: Error: Asymmetrical pause not available\n"); 1848 return -1; 1849 } 1850 1851 if (!new_pause_tx) { 1852 dab->pause &= ~BCM_PORT_ABILITY_PAUSE_TX; 1853 } else { 1854 dab->pause |= BCM_PORT_ABILITY_PAUSE_TX; 1855 } 1856 1857 if (!new_pause_rx) { 1858 dab->pause &= ~BCM_PORT_ABILITY_PAUSE_RX; 1859 } else { 1860 dab->pause |= BCM_PORT_ABILITY_PAUSE_RX; 1861 } 1862 dab->eee = sab->eee; 1863 } else { 1864 mode = dest->local_advert; 1865 1866 cur_speed = BCM_PORT_ABIL_SPD_MAX(mode); 1867 cur_duplex = ((mode & BCM_PORT_ABIL_FD) ? 1868 SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF); 1869 cur_pause_tx = (mode & BCM_PORT_ABIL_PAUSE_TX) != 0; 1870 cur_pause_rx = (mode & BCM_PORT_ABIL_PAUSE_RX) != 0; 1871 1872 new_speed = (flags & BCM_PORT_ATTR_SPEED_MASK ? 1873 info_speed_adj : cur_speed); 1874 new_duplex = (flags & BCM_PORT_ATTR_DUPLEX_MASK ? 1875 src->duplex : cur_duplex); 1876 new_pause_tx = (flags & BCM_PORT_ATTR_PAUSE_TX_MASK ? 1877 src->pause_tx : cur_pause_tx); 1878 new_pause_rx = (flags & BCM_PORT_ATTR_PAUSE_RX_MASK ? 1879 src->pause_rx : cur_pause_rx); 1880 1881 /* Start with maximum ability and cut down */ 1882 1883 mode = src->ability; 1884 1885 if (new_duplex == SOC_PORT_DUPLEX_HALF) { 1886 mode &= ~BCM_PORT_ABIL_FD; 1887 } 1888 1889 if (new_speed < 13000) { 1890 mode &= ~BCM_PORT_ABIL_13GB; 1891 } 1892 1893 if (new_speed < 12000) { 1894 mode &= ~BCM_PORT_ABIL_12GB; 1895 } 1896 1897 if (new_speed < 10000) { 1898 mode &= ~BCM_PORT_ABIL_10GB; 1899 } 1900 1901 if (new_speed < 2500) { 1902 mode &= ~BCM_PORT_ABIL_2500MB; 1903 } 1904 1905 if (new_speed < 1000) { 1906 mode &= ~BCM_PORT_ABIL_1000MB; 1907 } 1908 1909 if (new_speed < 100) { 1910 mode &= ~BCM_PORT_ABIL_100MB; 1911 } 1912 1913 if (!(mode & BCM_PORT_ABIL_PAUSE_ASYMM) && 1914 (new_pause_tx != new_pause_rx)) { 1915 cli_out("port parse: Error: Asymmetrical pause not available\n"); 1916 return -1; 1917 } 1918 1919 if (!new_pause_tx) { 1920 mode &= ~BCM_PORT_ABIL_PAUSE_TX; 1921 } 1922 1923 if (!new_pause_rx) { 1924 mode &= ~BCM_PORT_ABIL_PAUSE_RX; 1925 } 1926 1927 dest->local_advert = mode; 1928 } 1929 } else { 1930 /* Update forced values for speed/duplex/pause */ 1931 1932 if (flags & BCM_PORT_ATTR_SPEED_MASK) { 1933 dest->speed = info_speed_adj; 1934 } 1935 1936 if (flags & BCM_PORT_ATTR_DUPLEX_MASK) { 1937 dest->duplex = src->duplex; 1938 } 1939 1940 if (flags & BCM_PORT_ATTR_PAUSE_TX_MASK) { 1941 dest->pause_tx = src->pause_tx; 1942 } 1943 1944 if (flags & BCM_PORT_ATTR_PAUSE_RX_MASK) { 1945 dest->pause_rx = src->pause_rx; 1946 } 1947 } 1948 1949 if (flags & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 1950 sal_memcpy(dest->pause_mac, src->pause_mac, sizeof(sal_mac_addr_t)); 1951 } 1952 1953 if (flags & BCM_PORT_ATTR_LINKSCAN_MASK) { 1954 dest->linkscan = src->linkscan; 1955 } 1956 1957 if (flags & BCM_PORT_ATTR_LEARN_MASK) { 1958 dest->learn = src->learn; 1959 } 1960 1961 if (flags & BCM_PORT_ATTR_DISCARD_MASK) { 1962 dest->discard = src->discard; 1963 } 1964 1965 if (flags & BCM_PORT_ATTR_VLANFILTER_MASK) { 1966 dest->vlanfilter = src->vlanfilter; 1967 } 1968 1969 if (flags & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 1970 dest->untagged_priority = src->untagged_priority; 1971 } 1972 1973 if (flags & BCM_PORT_ATTR_PFM_MASK) { 1974 dest->pfm = src->pfm; 1975 } 1976 1977 if (flags & BCM_PORT_ATTR_PHY_MASTER_MASK) { 1978 dest->phy_master = src->phy_master; 1979 } 1980 1981 if (flags & BCM_PORT_ATTR_INTERFACE_MASK) { 1982 dest->interface = src->interface; 1983 } 1984 1985 if (flags & BCM_PORT_ATTR_LOOPBACK_MASK) { 1986 dest->loopback = src->loopback; 1987 } 1988 1989 if (flags & BCM_PORT_ATTR_ENCAP_MASK) { 1990 dest->encap_mode = src->encap_mode; 1991 } 1992 1993 if (flags & BCM_PORT_ATTR_FRAME_MAX_MASK) { 1994 dest->frame_max = src->frame_max; 1995 } 1996 1997 if (flags & BCM_PORT_ATTR_MDIX_MASK) { 1998 dest->mdix = src->mdix; 1999 } 2000 2001 if (flags & BCM_PORT_ATTR_MEDIUM_MASK) { 2002 dest->medium = src->medium; 2003 } 2004 2005 return 0; 2006 } 2007 2008 /* Iterate thru a port bitmap with the given mask; display info */ 2009 STATIC int 2010 _port_disp_iter(int unit, pbmp_t pbm, pbmp_t pbm_mask, uint32 seen) 2011 { 2012 bcm_port_info_t info; 2013 soc_port_t port, dport; 2014 int r = CMD_OK; 2015 2016 BCM_PBMP_AND(pbm, pbm_mask); 2017 /* coverity[overrun-local] */ 2018 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 2019 2020 sal_memset(&info, 0, sizeof(bcm_port_info_t)); 2021 port_info_init(unit, port, &info, seen); 2022 2023 if ((r |= bcm_port_selective_get(unit, port, &info)) < 0) { 2024 cli_out("Error: Could not get port %s information: %s\n", 2025 BCM_PORT_NAME(unit, port), bcm_errmsg(r)); 2026 } 2027 2028 /* coverity[overrun-local] */ 2029 disp_port_info(unit, BCM_PORT_NAME(unit, port), port, &info, 2030 IS_ST_PORT(unit, port), seen); 2031 } 2032 2033 return r; 2034 } 2035 2036 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 2037 static int 2038 _asf_mode_in_range(int unit, int asf_mode) 2039 { 2040 int in_range = 0; 2041 2042 if (soc_feature(unit, soc_feature_asf)) { 2043 if (((asf_mode >= 0) && (asf_mode <= 1))) { 2044 in_range = 1; 2045 } 2046 } else if (soc_feature(unit, soc_feature_asf_multimode)) { 2047 if (((asf_mode >= 0) && (asf_mode < 4))) { 2048 in_range = 1; 2049 } 2050 #ifdef BCM_TOMAHAWK3_SUPPORT 2051 if ((SOC_IS_TOMAHAWK3(unit)) && (asf_mode >= 2)) { 2052 in_range = 0; 2053 } 2054 #endif 2055 } 2056 return in_range; 2057 } 2058 #endif 2059 2060 /* 2061 * Function: 2062 * if_port 2063 * Purpose: 2064 * Configure port specific parameters. 2065 * Parameters: 2066 * u - SOC unit # 2067 * a - pointer to args 2068 * Returns: 2069 * CMD_OK/CMD_FAIL 2070 */ 2071 cmd_result_t 2072 if_esw_port(int u, args_t *a) 2073 { 2074 pbmp_t pbm; 2075 bcm_port_config_t pcfg; 2076 bcm_port_info_t *info_all; 2077 bcm_port_info_t info_given; 2078 bcm_port_ability_t *ability_all; /* Abilities for all ports */ 2079 bcm_port_ability_t ability_port; /* Ability for current port */ 2080 bcm_port_ability_t ability_given; 2081 char *c; 2082 int r, rv = 0, cmd_rv = CMD_OK; 2083 soc_port_t p, dport; 2084 parse_table_t pt; 2085 uint32 seen = 0; 2086 uint32 parsed = 0, parsed_adj, pa_speed; 2087 char pfmt[SOC_PBMP_FMT_LEN]; 2088 int eee_tx_idle_time = 0, eee_tx_wake_time = 0, eee_state, i; 2089 int eee_tx_ev_cnt, eee_tx_dur, eee_rx_ev_cnt, eee_rx_dur; 2090 char *eee_enable = NULL, *stats = NULL, *str = NULL; 2091 uint32 flags; 2092 bcm_phy_config_t config; 2093 2094 if (!sh_check_attached(ARG_CMD(a), u)) { 2095 return CMD_FAIL; 2096 } 2097 2098 if (bcm_port_config_get(u, &pcfg) != BCM_E_NONE) { 2099 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 2100 return CMD_FAIL; 2101 } 2102 2103 if ((c = ARG_GET(a)) == NULL) { 2104 return (CMD_USAGE); 2105 } 2106 2107 info_all = sal_alloc(SOC_MAX_NUM_PORTS * sizeof(bcm_port_info_t), 2108 "if_port"); 2109 2110 if (info_all == NULL) { 2111 cli_out("Insufficient memory.\n"); 2112 return CMD_FAIL; 2113 } 2114 2115 ability_all = sal_alloc(SOC_MAX_NUM_PORTS * sizeof(bcm_port_ability_t), 2116 "if_port"); 2117 2118 if (ability_all == NULL) { 2119 cli_out("Insufficient memory.\n"); 2120 sal_free(info_all); 2121 return CMD_FAIL; 2122 } 2123 2124 sal_memset(&info_given, 0, sizeof(bcm_port_info_t)); 2125 sal_memset(info_all, 0, SOC_MAX_NUM_PORTS * sizeof(bcm_port_info_t)); 2126 sal_memset(&ability_given, 0, sizeof(bcm_port_ability_t)); 2127 sal_memset(&ability_port, 0, sizeof(bcm_port_ability_t)); 2128 sal_memset(ability_all, 0, SOC_MAX_NUM_PORTS * sizeof(bcm_port_ability_t)); 2129 sal_memset(&config, 0x0, sizeof(bcm_phy_config_t)); 2130 2131 if (parse_bcm_pbmp(u, c, &pbm) < 0) { 2132 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(a), c); 2133 sal_free(info_all); 2134 sal_free(ability_all); 2135 return CMD_FAIL; 2136 } 2137 2138 BCM_PBMP_AND(pbm, pcfg.port); 2139 2140 if (BCM_PBMP_IS_NULL(pbm)) { 2141 ARG_DISCARD(a); 2142 sal_free(info_all); 2143 sal_free(ability_all); 2144 return CMD_OK; 2145 } 2146 2147 if (ARG_CNT(a) == 0) { 2148 seen = BCM_PORT_ATTR_ALL_MASK; 2149 } else { 2150 /* 2151 * Otherwise, arguments are given. Use them to determine which 2152 * properties need to be gotten/set. 2153 * 2154 * Probe and detach, hidden commands. 2155 */ 2156 if (!sal_strcasecmp(_ARG_CUR(a), "detach")) { 2157 pbmp_t detached; 2158 bcm_port_detach(u, pbm, &detached); 2159 cli_out("Detached port bitmap %s\n", SOC_PBMP_FMT(detached, pfmt)); 2160 ARG_GET(a); 2161 sal_free(info_all); 2162 sal_free(ability_all); 2163 return CMD_OK; 2164 } else if ((!sal_strcasecmp(_ARG_CUR(a), "probe")) || 2165 (!sal_strcasecmp(_ARG_CUR(a), "attach"))) { 2166 pbmp_t probed; 2167 bcm_port_probe(u, pbm, &probed); 2168 cli_out("Probed port bitmap %s\n", SOC_PBMP_FMT(probed, pfmt)); 2169 ARG_GET(a); 2170 sal_free(info_all); 2171 sal_free(ability_all); 2172 return CMD_OK; 2173 } else if (!sal_strcasecmp(_ARG_CUR(a), "lanes")) { 2174 int lanes; 2175 ARG_GET(a); 2176 if ((c = ARG_GET(a)) == NULL) { 2177 sal_free(info_all); 2178 sal_free(ability_all); 2179 return CMD_USAGE; 2180 } 2181 lanes = sal_ctoi(c, 0); 2182 /* coverity[overrun-local] */ 2183 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2184 rv = bcm_port_control_set(u, p, bcmPortControlLanes, lanes); 2185 if (rv < 0) { 2186 cli_out("Unit:%d Port:%d :Port control lanes set failed" 2187 " with %d\n",u, p, rv); 2188 break; 2189 } 2190 } 2191 ARG_GET(a); 2192 sal_free(info_all); 2193 sal_free(ability_all); 2194 if (rv < 0) { 2195 return CMD_FAIL; 2196 } else { 2197 return CMD_OK; 2198 } 2199 } else if (!sal_strcasecmp(_ARG_CUR(a), "Bridge")) { 2200 int pbridge = 0; 2201 ARG_GET(a); 2202 if ((c = ARG_GET(a)) != NULL) { 2203 pbridge = sal_ctoi(c, 0); 2204 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2205 rv = bcm_port_control_set(u, p, bcmPortControlBridge, pbridge); 2206 if (rv < 0) { 2207 cli_out("Unit %d Port %d :Port Bridge set %d failed" 2208 " rv %d\n",u, p, pbridge, rv); 2209 break; 2210 } 2211 } 2212 } else { 2213 /* Port Bridge show */ 2214 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2215 rv = bcm_port_control_get(u, p, bcmPortControlBridge, &pbridge); 2216 if (rv >= 0) { 2217 cli_out("Unit %d Port %4s :Port Bridge = %d\n", 2218 u, SOC_PORT_NAME(u, p), pbridge); 2219 } else { 2220 cli_out("Unit %d Port %4s :Port Bridge get failed" 2221 " rv %d\n",u, SOC_PORT_NAME(u, p), rv); 2222 } 2223 } 2224 } 2225 sal_free(info_all); 2226 sal_free(ability_all); 2227 if (rv < 0) { 2228 return CMD_FAIL; 2229 } else { 2230 return CMD_OK; 2231 } 2232 } else if (!sal_strcasecmp(_ARG_CUR(a), "EEE")) { 2233 sal_free(info_all); 2234 sal_free(ability_all); 2235 c = ARG_GET(a); 2236 if ((c = ARG_CUR(a)) != NULL) { 2237 2238 parse_table_init(u, &pt); 2239 parse_table_add(&pt, "ENable", PQ_DFL | PQ_STRING, 2240 0, &eee_enable, 0); 2241 parse_table_add(&pt, "TxIDleTime", PQ_DFL | PQ_INT, 2242 0, &eee_tx_idle_time, 0); 2243 parse_table_add(&pt, "TxWakeTime", PQ_DFL | PQ_INT, 2244 0, &eee_tx_wake_time, 0); 2245 parse_table_add(&pt, "STats", PQ_DFL | PQ_STRING, 0, &stats, 0); 2246 2247 if (parse_arg_eq(a, &pt) < 0) { 2248 parse_arg_eq_done(&pt); 2249 return CMD_USAGE; 2250 } 2251 if (ARG_CNT(a) > 0) { 2252 cli_out("%s: Unknown argument %s\n", ARG_CMD(a), ARG_CUR(a)); 2253 parse_arg_eq_done(&pt); 2254 return CMD_USAGE; 2255 } 2256 2257 flags = 0; 2258 2259 for (i = 0; i < pt.pt_cnt; i++) { 2260 if (pt.pt_entries[i].pq_type & PQ_PARSED) { 2261 flags |= (1 << i); 2262 } 2263 } 2264 2265 DPORT_SOC_PBMP_ITER(u, pbm, dport, p) { 2266 cli_out("Port = %5s(%3d)\n", SOC_PORT_NAME(u, p), p); 2267 if (flags & 0x1) { 2268 if (sal_strcasecmp(eee_enable, "enable") == 0) { 2269 rv = bcm_port_control_set(u, p, 2270 bcmPortControlEEEEnable, 2271 1); 2272 } 2273 if (sal_strcasecmp(eee_enable, "disable") == 0) { 2274 rv = bcm_port_control_set(u, p, 2275 bcmPortControlEEEEnable, 2276 0); 2277 } 2278 2279 if (rv == BCM_E_NONE) { 2280 cli_out("EEE state set to %s\n", eee_enable); 2281 } else { 2282 if (rv == BCM_E_UNAVAIL) { 2283 cli_out("EEE %s is not available\n", eee_enable); 2284 } else { 2285 cli_out("EEE %s is unsuccessful\n", eee_enable); 2286 } 2287 } 2288 rv = bcm_port_control_get(u, p, 2289 bcmPortControlEEEEnable, 2290 &eee_state); 2291 if (rv == BCM_E_NONE) { 2292 if (eee_state == 1) { 2293 str = "Enable"; 2294 } else { 2295 str = "Disable"; 2296 } 2297 } else { 2298 str = "NA"; 2299 } 2300 cli_out("EEE State = %s\n", str); 2301 } 2302 2303 if (flags & 0x2) { 2304 rv = bcm_port_control_set(u, p, 2305 bcmPortControlEEETransmitIdleTime, 2306 eee_tx_idle_time); 2307 if (BCM_FAILURE(rv)) { 2308 cli_out("Port control set: " 2309 "bcmPortControlEEETransmitIdleTime " 2310 "failed with %d\n", rv); 2311 return CMD_FAIL; 2312 } 2313 rv = bcm_port_control_get(u, p, 2314 bcmPortControlEEETransmitIdleTime, 2315 &eee_tx_idle_time); 2316 if (BCM_FAILURE(rv)) { 2317 cli_out("Port control get: " 2318 "bcmPortControlEEETransmitIdleTime " 2319 "failed with %d\n", rv); 2320 return CMD_FAIL; 2321 } 2322 cli_out("EEE Transmit Idle Time is = %d(us)\n", 2323 eee_tx_idle_time); 2324 } 2325 2326 if (flags & 0x4) { 2327 rv = bcm_port_control_set(u, p, 2328 bcmPortControlEEETransmitWakeTime, 2329 eee_tx_wake_time); 2330 if (BCM_FAILURE(rv)) { 2331 cli_out("Port control set: " 2332 "bcmPortControlEEETransmitWakeTime " 2333 "failed with %d\n", rv); 2334 return CMD_FAIL; 2335 } 2336 rv = bcm_port_control_get(u, p, 2337 bcmPortControlEEETransmitWakeTime, 2338 &eee_tx_wake_time); 2339 if (BCM_FAILURE(rv)) { 2340 cli_out("Port control get: " 2341 "bcmPortControlEEETransmitWakeTime " 2342 "failed with %d\n", rv); 2343 return CMD_FAIL; 2344 } 2345 cli_out("EEE Transmit Wake Time is = %d(us)\n", 2346 eee_tx_wake_time); 2347 } 2348 2349 if (flags & 0x8) { 2350 if (sal_strcasecmp(stats, "get") == 0) { 2351 rv = bcm_port_control_get(u, p, 2352 bcmPortControlEEETransmitEventCount, 2353 &eee_tx_ev_cnt); 2354 if (BCM_FAILURE(rv)) { 2355 cli_out("Port control get: " 2356 "bcmPortControlEEETransmitEventCount " 2357 "failed with %d\n", rv); 2358 return CMD_FAIL; 2359 } 2360 rv = bcm_port_control_get(u, p, 2361 bcmPortControlEEETransmitDuration, 2362 &eee_tx_dur); 2363 if (BCM_FAILURE(rv)) { 2364 cli_out("Port control get: " 2365 "bcmPortControlEEETransmitDuration " 2366 "failed with %d\n", rv); 2367 return CMD_FAIL; 2368 } 2369 rv = bcm_port_control_get(u, p, 2370 bcmPortControlEEEReceiveEventCount, 2371 &eee_rx_ev_cnt); 2372 if (BCM_FAILURE(rv)) { 2373 cli_out("Port control get: " 2374 "bcmPortControlEEEReceiveEventCount " 2375 "failed with %d\n", rv); 2376 return CMD_FAIL; 2377 } 2378 rv = bcm_port_control_get(u, p, 2379 bcmPortControlEEEReceiveDuration, 2380 &eee_rx_dur); 2381 if (BCM_FAILURE(rv)) { 2382 cli_out("Port control get: " 2383 "bcmPortControlEEEReceiveDuration " 2384 "failed with %d\n", rv); 2385 return CMD_FAIL; 2386 } 2387 cli_out("Tx events = %d TX Duration = %d(us) " 2388 "RX events = %d RX Duration = %d(us)\n", 2389 eee_tx_ev_cnt, eee_tx_dur, eee_rx_ev_cnt, 2390 eee_rx_dur); 2391 } 2392 } 2393 } 2394 /* free allocated memory from arg parsing */ 2395 parse_arg_eq_done(&pt); 2396 } else { 2397 cli_out("EEE Details:\n"); 2398 cli_out("%10s %9s %14s %14s %12s %14s %12s %14s\n", 2399 "port", "EEE-State", "TxIdleTime(us)", "TxWakeTime(us)", 2400 "TxEventCount", "TxDuration(us)", "RxEventCount", 2401 "RxDuration(us)"); 2402 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2403 2404 rv = bcm_port_control_get(u, p, bcmPortControlEEEEnable, 2405 &eee_state); 2406 if (BCM_FAILURE(rv)) { 2407 cli_out("Port control get:bcmPortControlEEEEnable " 2408 "failed with %d\n", rv); 2409 return CMD_FAIL; 2410 } 2411 rv = bcm_port_control_get(u, p, 2412 bcmPortControlEEETransmitIdleTime, 2413 &eee_tx_idle_time); 2414 if (BCM_FAILURE(rv)) { 2415 cli_out("Port control get: " 2416 "bcmPortControlEEETransmitIdleTime " 2417 "failed with %d\n", rv); 2418 return CMD_FAIL; 2419 } 2420 rv = bcm_port_control_get(u, p, 2421 bcmPortControlEEETransmitWakeTime, 2422 &eee_tx_wake_time); 2423 if (BCM_FAILURE(rv)) { 2424 cli_out("Port control get: " 2425 "bcmPortControlEEETransmitWakeTime " 2426 "failed with %d\n", rv); 2427 return CMD_FAIL; 2428 } 2429 if (eee_state) { 2430 rv = bcm_port_control_get(u, p, 2431 bcmPortControlEEETransmitEventCount, 2432 &eee_tx_ev_cnt); 2433 if (BCM_FAILURE(rv)) { 2434 cli_out("Port control get: " 2435 "bcmPortControlEEETransmitEventCount " 2436 "failed with %d\n", rv); 2437 return CMD_FAIL; 2438 } 2439 rv = bcm_port_control_get(u, p, 2440 bcmPortControlEEETransmitDuration, 2441 &eee_tx_dur); 2442 if (BCM_FAILURE(rv)) { 2443 cli_out("Port control get: " 2444 "bcmPortControlEEETransmitDuration " 2445 "failed with %d\n", rv); 2446 return CMD_FAIL; 2447 } 2448 rv = bcm_port_control_get(u, p, 2449 bcmPortControlEEEReceiveEventCount, 2450 &eee_rx_ev_cnt); 2451 if (BCM_FAILURE(rv)) { 2452 cli_out("Port control get: " 2453 "bcmPortControlEEEReceiveEventCount " 2454 "failed with %d\n", rv); 2455 return CMD_FAIL; 2456 } 2457 rv = bcm_port_control_get(u, p, 2458 bcmPortControlEEEReceiveDuration, 2459 &eee_rx_dur); 2460 if (BCM_FAILURE(rv)) { 2461 cli_out("Port control get: " 2462 "bcmPortControlEEEReceiveDuration " 2463 "failed with %d\n", rv); 2464 return CMD_FAIL; 2465 } 2466 } else { 2467 eee_tx_ev_cnt = -1; 2468 eee_tx_dur = -1; 2469 eee_rx_ev_cnt = -1; 2470 eee_rx_dur = -1; 2471 } 2472 2473 cli_out("%5s(%3d) %9s %14u %14u %12u %14u %12u %14u\n", 2474 SOC_PORT_NAME(u, p), p, 2475 eee_state ? "Enable" : "Disable", eee_tx_idle_time, 2476 eee_tx_wake_time, eee_tx_ev_cnt, eee_tx_dur, 2477 eee_rx_ev_cnt, eee_rx_dur); 2478 } 2479 } 2480 return CMD_OK; 2481 } 2482 #if defined(BCM_ESW_SUPPORT) 2483 2484 else if (!sal_strcasecmp(_ARG_CUR(a), "detail")) { 2485 DPORT_SOC_PBMP_ITER(u, pbm, dport,p) { 2486 cli_out("******************************************** \n"); 2487 cli_out("\t %s PORT = %d INFORMATION \n",soc_dev_name(u),p); 2488 cli_out("********************************************\n\n"); 2489 /* coverity[overrun-call:FALSE] */ 2490 rv = _bcm_esw_port_sw_info_display(u, p); 2491 if (BCM_FAILURE(rv)) { 2492 cli_out("Port software information display failed with %d\n", rv); 2493 sal_free(info_all); 2494 sal_free(ability_all); 2495 return CMD_FAIL; 2496 } 2497 2498 rv = _bcm_esw_port_hw_info_display(u, p); 2499 if (BCM_FAILURE(rv)) { 2500 cli_out("Port hardware infomation display failed with %d\n", rv); 2501 sal_free(info_all); 2502 sal_free(ability_all); 2503 return CMD_FAIL; 2504 } else { 2505 seen = BCM_PORT_ATTR_ALL_MASK; 2506 } 2507 } 2508 } 2509 #endif 2510 2511 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 2512 else if (!sal_strcasecmp(_ARG_CUR(a), "asf")) { 2513 int asf_mode; 2514 int in_range = 0; 2515 2516 if (!soc_feature(u, soc_feature_asf) && 2517 !soc_feature(u, soc_feature_asf_multimode)) { 2518 sal_free(info_all); 2519 sal_free(ability_all); 2520 return CMD_NOTIMPL; 2521 } 2522 2523 ARG_GET(a); 2524 if ((c = ARG_GET(a)) == NULL) { 2525 sal_free(info_all); 2526 sal_free(ability_all); 2527 return CMD_USAGE; 2528 } 2529 asf_mode = sal_ctoi(c, 0); 2530 in_range = _asf_mode_in_range(u, asf_mode); 2531 if (!in_range) { 2532 cli_out("%d: invalid mode\n", asf_mode); 2533 sal_free(info_all); 2534 sal_free(ability_all); 2535 return CMD_OK; 2536 } 2537 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2538 rv = bcm_switch_control_port_set(u, p, 2539 bcmSwitchAlternateStoreForward, asf_mode); 2540 if (BCM_FAILURE(rv)) { 2541 if (BCM_E_UNAVAIL == rv) { 2542 cli_out("%s: unsupported\n", BCM_PORT_NAME(u, p)); 2543 } 2544 if (BCM_E_PARAM == rv) { 2545 cli_out("%s: invalid arg(s)\n", BCM_PORT_NAME(u, p)); 2546 } 2547 } 2548 continue; 2549 } 2550 sal_free(info_all); 2551 sal_free(ability_all); 2552 return CMD_OK; 2553 } 2554 #endif 2555 if (seen == 0) { 2556 if (!sal_strcmp(_ARG_CUR(a), "=")) { 2557 /* 2558 * For "=" where the user is prompted to enter all the parameters, 2559 * use the parameters from the first selected port as the defaults. 2560 */ 2561 if (ARG_CNT(a) != 1) { 2562 sal_free(info_all); 2563 sal_free(ability_all); 2564 return CMD_USAGE; 2565 } 2566 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2567 break; /* Find first port in bitmap */ 2568 } 2569 port_info_init(u, p, &info_given, 0); 2570 if ((rv = bcm_port_info_get(u, p, &info_given)) < 0) { 2571 cli_out("%s: Error: Failed to get port info\n", ARG_CMD(a)); 2572 sal_free(info_all); 2573 sal_free(ability_all); 2574 return CMD_FAIL; 2575 } 2576 } else { 2577 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2578 break; /* Find first port in bitmap */ 2579 } 2580 port_info_init(u, p, &info_given, 0); 2581 } 2582 2583 /* 2584 * Parse the arguments. Determine which ones were actually given. 2585 */ 2586 port_parse_setup(u, &pt, &info_given); 2587 2588 if (parse_arg_eq(a, &pt) < 0) { 2589 parse_arg_eq_done(&pt); 2590 sal_free(info_all); 2591 sal_free(ability_all); 2592 return (CMD_FAIL); 2593 } 2594 2595 if (info_given.encap_mode >= 0 2596 && info_given.encap_mode < (sizeof(encap_mode) / sizeof(encap_mode[0])) 2597 &&!sal_strcmp(encap_mode[info_given.encap_mode], "HGOE")) { 2598 info_given.encap_mode = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET; 2599 } 2600 2601 /* Translate port_info into port abilities. */ 2602 2603 if ((seen == 0) && (ARG_CNT(a) > 0)) { 2604 cli_out("%s: Unknown argument %s\n", ARG_CMD(a), ARG_CUR(a)); 2605 parse_arg_eq_done(&pt); 2606 sal_free(info_all); 2607 sal_free(ability_all); 2608 return (CMD_FAIL); 2609 } 2610 2611 /* 2612 * Find out what parameters specified. Record values specified. 2613 */ 2614 port_parse_mask_get(&pt, &seen, &parsed); 2615 parse_arg_eq_done(&pt); 2616 } 2617 } 2618 if (seen && parsed) { 2619 cli_out("%s: Cannot get and set " 2620 "port properties in one command\n", ARG_CMD(a)); 2621 sal_free(info_all); 2622 sal_free(ability_all); 2623 return CMD_FAIL; 2624 } else if (seen) { /* Show selected information */ 2625 cli_out("%s: Status (* indicates PHY link up)\n", ARG_CMD(a)); 2626 /* Display the information by port type */ 2627 #define _call_pdi(u, p, mp, s) \ 2628 if (_port_disp_iter(u, p, mp, s) != CMD_OK) { \ 2629 sal_free(info_all); \ 2630 sal_free(ability_all); \ 2631 return CMD_FAIL; \ 2632 } 2633 _call_pdi(u, pbm, pcfg.fe, seen); 2634 _call_pdi(u, pbm, pcfg.ge, seen); 2635 _call_pdi(u, pbm, pcfg.xe, seen); 2636 _call_pdi(u, pbm, pcfg.ce, seen); 2637 _call_pdi(u, pbm, pcfg.hg, seen); 2638 _call_pdi(u, pbm, pcfg.cd, seen); 2639 sal_free(info_all); 2640 sal_free(ability_all); 2641 ARG_GET(a); 2642 return (CMD_OK); 2643 } 2644 2645 /* Some set information was given */ 2646 2647 if (parsed & BCM_PORT_ATTR_LINKSCAN_MASK) { 2648 /* Map ON --> S/W, OFF--> None */ 2649 if (info_given.linkscan > 2) { 2650 info_given.linkscan -= 3; 2651 } 2652 } 2653 2654 parsed_adj = parsed; 2655 if (parsed & (BCM_PORT_ATTR_SPEED_MASK | BCM_PORT_ATTR_DUPLEX_MASK)) { 2656 parsed_adj |= BCM_PORT_ATTR_SPEED_MASK | BCM_PORT_ATTR_DUPLEX_MASK; 2657 } 2658 2659 /* 2660 * Retrieve all requested port information first, then later write 2661 * back all port information. That prevents a problem with loopback 2662 * cables where setting one port's info throws another into autoneg 2663 * causing it to return info in flux (e.g. suddenly go half duplex). 2664 */ 2665 2666 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2667 port_info_init(u, p, &info_all[p], parsed_adj); 2668 if ((r = bcm_port_selective_get(u, p, &info_all[p])) < 0) { 2669 cli_out("%s: Error: Could not get port %s information: %s\n", 2670 ARG_CMD(a), BCM_PORT_NAME(u, p), bcm_errmsg(r)); 2671 continue; 2672 } 2673 } 2674 2675 /* 2676 * Loop through all the specified ports, changing whatever field 2677 * values were actually given. This avoids copying unaffected 2678 * information from one port to another and prevents having to 2679 * re-parse the arguments once per port. 2680 */ 2681 2682 DPORT_BCM_PBMP_ITER(u, pbm, dport, p) { 2683 if (parsed & BCM_PORT_ATTR_MEDIUM_MASK) { 2684 rv = bcm_port_medium_config_set(u, p, info_given.medium, &config); 2685 if (rv < 0) { 2686 cli_out("port parse: Error: Could not set port %s medium: %s\n", 2687 BCM_PORT_NAME(u, p), bcm_errmsg(rv)); 2688 continue; 2689 } 2690 } 2691 2692 if ((rv = bcm_port_speed_max(u, p, &info_given.speed_max)) < 0) { 2693 cli_out("port parse: Error: Could not get port %s max speed: %s\n", 2694 BCM_PORT_NAME(u, p), bcm_errmsg(rv)); 2695 continue; 2696 } 2697 2698 if (!IS_CD_PORT(u, p)) { 2699 if ((rv = 2700 bcm_port_ability_local_get(u, p, &info_given.port_ability)) < 0) { 2701 cli_out("port parse: Error: Could not get port %s ability: %s\n", 2702 BCM_PORT_NAME(u, p), bcm_errmsg(rv)); 2703 continue; 2704 } 2705 if ((rv = soc_port_ability_to_mode(&info_given.port_ability, 2706 &info_given.ability)) < 0) { 2707 cli_out("port parse: Error: Could not " 2708 "transform port %s ability to mode: %s\n", 2709 BCM_PORT_NAME(u, p), bcm_errmsg(rv)); 2710 continue; 2711 } 2712 } 2713 2714 if ((r = port_parse_port_info_set(parsed, 2715 &info_given, &info_all[p])) < 0) { 2716 cli_out("%s: Error: Could not parse port %s info: %s\n", 2717 ARG_CMD(a), BCM_PORT_NAME(u, p), bcm_errmsg(r)); 2718 cmd_rv = CMD_FAIL; 2719 continue; 2720 } 2721 2722 /* If AN is on, do not set speed, duplex, pause */ 2723 if (info_all[p].autoneg) { 2724 info_all[p].action_mask &= ~BCM_PORT_AN_ATTRS; 2725 } else if (parsed & 2726 (BCM_PORT_ATTR_SPEED_MASK | BCM_PORT_ATTR_DUPLEX_MASK)) { 2727 int full_duplex_speed; 2728 int half_duplex_speed; 2729 2730 pa_speed = SOC_PA_SPEED(info_all[p].speed); 2731 2732 full_duplex_speed = info_given.port_ability.speed_full_duplex 2733 & pa_speed; 2734 half_duplex_speed = info_given.port_ability.speed_half_duplex 2735 & pa_speed; 2736 2737 if (!soc_feature(u, soc_feature_flexport_based_speed_set) 2738 && (info_all[p].speed != 0)) { 2739 2740 if (info_all[p].duplex) { 2741 if (!full_duplex_speed) { 2742 cli_out("%s: port %s does not support " 2743 "%d mbps full duplex\n", 2744 ARG_CMD(a), BCM_PORT_NAME(u, p), 2745 info_all[p].speed); 2746 continue; 2747 } 2748 } else { 2749 if (!half_duplex_speed) { 2750 cli_out("%s: port %s does not support " 2751 "%d mbps half duplex\n", 2752 ARG_CMD(a), BCM_PORT_NAME(u, p), 2753 info_all[p].speed); 2754 continue; 2755 } 2756 } 2757 } 2758 } else if (IS_CD_PORT(u, p) && (parsed & BCM_PORT_ATTR_AUTONEG_MASK)) { 2759 /* if pm8x50 and autoneg is being turned off, don't set speed */ 2760 info_all[p].action_mask &= ~BCM_PORT_ATTR_SPEED_MASK; 2761 } 2762 if ((r = bcm_port_selective_set(u, p, &info_all[p])) < 0) { 2763 cli_out("%s: Error: Could not set port %s information: %s\n", 2764 ARG_CMD(a), BCM_PORT_NAME(u, p), bcm_errmsg(r)); 2765 cmd_rv = CMD_FAIL; 2766 continue; 2767 } 2768 } 2769 2770 sal_free(info_all); 2771 sal_free(ability_all); 2772 return (cmd_rv); 2773 } 2774 2775 cmd_result_t 2776 if_esw_gport(int u, args_t *a) 2777 { 2778 char *c; 2779 soc_port_t arg_port = 0; 2780 parse_table_t pt; 2781 cmd_result_t retCode; 2782 char gpfmt[FORMAT_GPORT_MAX]; 2783 2784 if (!sh_check_attached(ARG_CMD(a), u)) { 2785 return CMD_FAIL; 2786 } 2787 2788 if ((c = ARG_CUR(a)) == NULL) { 2789 return (CMD_USAGE); 2790 } 2791 parse_table_init(u, &pt); 2792 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &arg_port, NULL); 2793 if (!parseEndOk(a, &pt, &retCode)) { 2794 cli_out(" Unable to Parse GPORT !!! \n"); 2795 return retCode; 2796 } 2797 2798 cli_out(" gport is = %s\n", format_gport(gpfmt, arg_port)); 2799 return CMD_OK; 2800 } 2801 2802 char if_egress_usage[] = 2803 "Usages:\n\t" 2804 " egress set [<Port=port#>] [<Modid=modid>] <PBmp=val>\n\t" 2805 " - Set allowed egress bitmap for (modid,port) or all\n\t" 2806 " egress show [<Port=port#>] [<Module=modid>]\n\t" 2807 " - Show allowed egress bitmap for (modid,port)\n"; 2808 2809 /* 2810 * Note: 2811 * 2812 * Since these port numbers are likely on different modules, we cannot 2813 * use PBMP qualifiers by this unit. 2814 */ 2815 2816 cmd_result_t 2817 if_egress(int unit, args_t *a) 2818 { 2819 char *subcmd, *c; 2820 soc_info_t *si = &SOC_INFO(unit); 2821 int port, arg_port = -1, min_port = 0, max_port = si->modport_max; 2822 int modid, arg_modid = -1, mod_min = 0, mod_max = SOC_MODID_MAX(unit); 2823 bcm_pbmp_t pbmp; 2824 int r; 2825 bcm_pbmp_t arg_pbmp; 2826 parse_table_t pt; 2827 cmd_result_t retCode; 2828 2829 if (!sh_check_attached(ARG_CMD(a), unit)) { 2830 return CMD_FAIL; 2831 } 2832 2833 if ((subcmd = ARG_GET(a)) == NULL) { 2834 return CMD_USAGE; 2835 } 2836 2837 BCM_PBMP_CLEAR(pbmp); 2838 BCM_PBMP_CLEAR(arg_pbmp); 2839 2840 /* Egress show command */ 2841 if (sal_strcasecmp(subcmd, "show") == 0) { 2842 2843 if ((c = ARG_CUR(a)) != NULL) { 2844 parse_table_init(unit, &pt); 2845 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &arg_port, NULL); 2846 parse_table_add(&pt, "Modid", PQ_DFL | PQ_INT, 0, &arg_modid, NULL); 2847 if (!parseEndOk(a, &pt, &retCode)) { 2848 return retCode; 2849 } 2850 2851 if (BCM_GPORT_IS_SET(arg_port)) { 2852 #if defined(BCM_ESW_SUPPORT) 2853 int tgid, id; 2854 2855 if (SOC_IS_ESW(unit)) { 2856 r = _bcm_esw_gport_resolve(unit, arg_port, &arg_modid, 2857 &arg_port, &tgid, &id); 2858 if ((tgid != BCM_TRUNK_INVALID) || (id != -1)||(r != BCM_E_NONE)) { 2859 return CMD_FAIL; 2860 } 2861 } else { 2862 return CMD_FAIL; 2863 } 2864 #else 2865 return CMD_FAIL; 2866 #endif 2867 } 2868 if (arg_modid >= 0) { 2869 mod_min = mod_max = arg_modid; 2870 } 2871 if (arg_port >= 0) { 2872 min_port = max_port = arg_port; 2873 } 2874 } 2875 2876 for (modid = mod_min; modid <= mod_max; modid++) { 2877 for (port = min_port; port <= max_port; port++) { 2878 r = bcm_port_egress_get(unit, port, modid, &pbmp); 2879 if (r < 0) { 2880 cli_out("%s: egress (modid=%d, port=%d) get failed: %s\n", 2881 ARG_CMD(a), modid, port, bcm_errmsg(r)); 2882 return CMD_FAIL; 2883 } 2884 2885 if (BCM_PBMP_NEQ(pbmp, PBMP_ALL(unit))) { 2886 char buf[FORMAT_PBMP_MAX]; 2887 format_bcm_pbmp(unit, buf, sizeof(buf), pbmp); 2888 cli_out("Module %d, port %d: Enabled egress ports %s\n", 2889 modid, port, buf); 2890 } 2891 } 2892 } 2893 2894 return CMD_OK; 2895 } 2896 2897 if (sal_strcasecmp(subcmd, "set") == 0) { 2898 parse_table_init(unit, &pt); 2899 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &arg_port, NULL); 2900 parse_table_add(&pt, "Modid", PQ_DFL | PQ_INT, 0, &arg_modid, NULL); 2901 parse_table_add(&pt, "Pbmp", PQ_DFL | PQ_PBMP | PQ_BCM, 0, &arg_pbmp, 2902 NULL); 2903 if (!parseEndOk(a, &pt, &retCode)) { 2904 return retCode; 2905 } 2906 2907 SOC_PBMP_ASSIGN(pbmp, arg_pbmp); 2908 2909 r = bcm_port_egress_set(unit, arg_port, arg_modid, pbmp); 2910 2911 } else { 2912 return CMD_USAGE; 2913 } 2914 2915 if (r < 0) { 2916 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 2917 return CMD_FAIL; 2918 } 2919 2920 return CMD_OK; 2921 } 2922 2923 cmd_result_t 2924 if_esw_dscp(int unit, args_t *a) 2925 { 2926 int rv, port, dport, srccp, mapcp, prio, cng, mode, count, i; 2927 bcm_port_config_t pcfg; 2928 bcm_pbmp_t pbm; 2929 bcm_pbmp_t tpbm; 2930 int use_global = 0; 2931 char *s; 2932 parse_table_t pt; 2933 2934 if (!sh_check_attached(ARG_CMD(a), unit)) { 2935 return CMD_FAIL; 2936 } 2937 2938 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 2939 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 2940 return CMD_FAIL; 2941 } 2942 2943 if ((s = ARG_GET(a)) == NULL) { 2944 cli_out("%s: ERROR: missing port bitmap\n", ARG_CMD(a)); 2945 return CMD_FAIL; 2946 } 2947 if (parse_bcm_pbmp(unit, s, &pbm) < 0) { 2948 cli_out("%s: ERROR: unrecognized port bitmap: %s\n", ARG_CMD(a), s); 2949 return CMD_FAIL; 2950 } 2951 2952 BCM_PBMP_ASSIGN(tpbm, pbm); 2953 BCM_PBMP_XOR(tpbm, pcfg.e); 2954 if (BCM_PBMP_IS_NULL(tpbm)) { 2955 /* global table */ 2956 use_global = 1; 2957 } 2958 2959 parse_table_init(unit, &pt); 2960 parse_table_add(&pt, "Mode", PQ_INT, (void *)-1, &mode, NULL); 2961 rv = parse_arg_eq(a, &pt); 2962 parse_arg_eq_done(&pt); 2963 if (BCM_FAILURE(rv)) { 2964 return CMD_FAIL; 2965 } 2966 2967 srccp = -1; 2968 s = ARG_GET(a); 2969 if (s) { 2970 srccp = parse_integer(s); 2971 } 2972 2973 if ((s = ARG_GET(a)) == NULL) { 2974 if (mode != -1) { 2975 cli_out("%s: WARNING: ignore mode argument\n", ARG_CMD(a)); 2976 } 2977 if (srccp < 0) { 2978 srccp = 0; 2979 count = 64; 2980 } else { 2981 count = 1; 2982 } 2983 if (BCM_PBMP_IS_NULL(pbm) && 2984 !soc_feature(unit, soc_feature_dscp_map_per_port)) { 2985 port = -1; 2986 rv = bcm_port_dscp_map_get(unit, port, 0, &mapcp, &prio); 2987 if (rv == BCM_E_PORT) { 2988 port = -1; 2989 cli_out("%d: dscp map:\n", unit); 2990 } 2991 for (i = 0; i < count; i++) { 2992 rv = bcm_port_dscp_map_get(unit, port, srccp + i, &mapcp, 2993 &prio); 2994 if (rv < 0) { 2995 cli_out("ERROR: dscp map get %d failed: %s\n", 2996 srccp + i, bcm_errmsg(rv)); 2997 return CMD_FAIL; 2998 } 2999 if (srccp + i != mapcp || count == 1) { 3000 cli_out(" %d->%d prio=%d cng=%d\n", 3001 srccp + i, mapcp, 3002 prio & BCM_PRIO_MASK, 3003 (prio & BCM_PRIO_DROP_FIRST) ? 1 : 0); 3004 3005 } 3006 } 3007 cli_out("\n"); 3008 } else { 3009 /* coverity[overrun-local] */ 3010 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 3011 if (use_global) { 3012 rv = bcm_port_dscp_map_get(unit, port, 0, &mapcp, &prio); 3013 if (rv == BCM_E_PORT) { 3014 port = -1; 3015 cli_out("%d: dscp map:\n", unit); 3016 } 3017 } else { 3018 cli_out("%d:%s dscp map:\n", unit, 3019 BCM_PORT_NAME(unit, port)); 3020 } 3021 for (i = 0; i < count; i++) { 3022 rv = bcm_port_dscp_map_get(unit, port, srccp + i, &mapcp, 3023 &prio); 3024 if (rv < 0) { 3025 cli_out("ERROR: dscp map get %d failed: %s\n", 3026 srccp + i, bcm_errmsg(rv)); 3027 return CMD_FAIL; 3028 } 3029 if (srccp + i != mapcp || count == 1) { 3030 cli_out(" %d->%d prio=%d cng=%d\n", 3031 srccp + i, mapcp, 3032 prio & BCM_PRIO_MASK, 3033 (prio & BCM_PRIO_DROP_FIRST) ? 1 : 0); 3034 3035 } 3036 } 3037 cli_out("\n"); 3038 if (port == -1) { 3039 break; 3040 } 3041 } 3042 } 3043 return CMD_OK; 3044 } 3045 3046 mapcp = parse_integer(s); 3047 prio = -1; 3048 cng = 0; 3049 3050 if ((s = ARG_GET(a)) != NULL) { 3051 prio = parse_integer(s); 3052 if ((s = ARG_GET(a)) != NULL) { 3053 cng = parse_integer(s); 3054 } 3055 } 3056 if (cng) 3057 prio |= BCM_PRIO_DROP_FIRST; 3058 3059 /* Allow empty pbmp to configure devices that don't support per port */ 3060 /* dscp mapping */ 3061 if (BCM_PBMP_IS_NULL(pbm) && 3062 !soc_feature(unit, soc_feature_dscp_map_per_port)) { 3063 port = -1; 3064 3065 if (mode != -1) { 3066 rv = bcm_port_dscp_map_mode_set(unit, port, mode); 3067 if (rv < 0) { 3068 cli_out("%d:%s ERROR: dscp mode set mode=%d: %s\n", 3069 unit, (port == -1) ? "" : BCM_PORT_NAME(unit, port), 3070 mode, bcm_errmsg(rv)); 3071 return CMD_FAIL; 3072 } 3073 } 3074 3075 rv = bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 3076 if (rv < 0) { 3077 cli_out("%d:%s ERROR: " 3078 "dscp map set %d->%d prio=%d cng=%d failed: %s\n", 3079 unit, (port == -1) ? "" : BCM_PORT_NAME(unit, port), 3080 srccp, mapcp, prio, cng, bcm_errmsg(rv)); 3081 return CMD_FAIL; 3082 } 3083 } else { 3084 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 3085 if (use_global) { 3086 port = -1; 3087 } 3088 3089 if (mode != -1) { 3090 rv = bcm_port_dscp_map_mode_set(unit, port, mode); 3091 if (rv < 0) { 3092 cli_out("%d:%s ERROR: dscp mode set mode=%d: %s\n", 3093 unit, (port == -1) ? "" : BCM_PORT_NAME(unit, port), 3094 mode, bcm_errmsg(rv)); 3095 return CMD_FAIL; 3096 } 3097 } 3098 3099 rv = bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 3100 if (rv < 0) { 3101 cli_out("%d:%s ERROR: " 3102 "dscp map set %d->%d prio=%d cng=%d failed: %s\n", 3103 unit, (port == -1) ? "" : BCM_PORT_NAME(unit, port), 3104 srccp, mapcp, prio, cng, bcm_errmsg(rv)); 3105 return CMD_FAIL; 3106 } 3107 if (port == -1) { 3108 break; 3109 } 3110 } 3111 } 3112 return CMD_OK; 3113 } 3114 3115 cmd_result_t 3116 if_esw_ipg(int unit, args_t *a) 3117 /* 3118 * Function: if_ipg 3119 * Purpose: Configure default IPG values. 3120 * Parameters: unit - SOC unit # 3121 * a - arguments 3122 * Returns: CMD_OK/CMD_FAIL 3123 */ 3124 { 3125 parse_table_t pt; 3126 pbmp_t arg_pbmp; 3127 int arg_speed, speed; 3128 bcm_port_duplex_t arg_duplex, duplex; 3129 int arg_gap; 3130 int arg_stretch; 3131 int stretch; 3132 cmd_result_t retCode; 3133 int real_ifg; 3134 int rv; 3135 int i; 3136 bcm_port_config_t pcfg; 3137 bcm_port_t port, dport; 3138 3139 const char *header = 3140 " " 3141 " 10M_HD" 3142 " 10M_FD" 3143 " 100M_HD" 3144 " 100M_FD" 3145 " 1G_HD" 3146 " 1G_FD" 3147 " 2.5G_HD" 3148 " 2.5G_FD" 3149 " 10G_FD" 3150 " 25G_FD" 3151 " 40G_FD" 3152 " 100G_FD" 3153 " 106G_FD" 3154 " STRETCH"; 3155 3156 const int speeds[] = { 10, 100, 1000, 2500, 10000, 25000, 40000, 100000, 106000 }; 3157 const int num_speeds = sizeof(speeds) / sizeof(int); 3158 3159 if (!sh_check_attached(ARG_CMD(a), unit)) { 3160 return CMD_FAIL; 3161 } 3162 3163 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 3164 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 3165 return CMD_FAIL; 3166 } 3167 3168 /* 3169 * Assign the defaults 3170 */ 3171 BCM_PBMP_ASSIGN(arg_pbmp, pcfg.port); 3172 arg_speed = 0; 3173 arg_duplex = BCM_PORT_DUPLEX_COUNT; 3174 arg_gap = 0; 3175 arg_stretch = -1; 3176 3177 /* 3178 * Parse the arguments 3179 */ 3180 if (ARG_CNT(a)) { 3181 parse_table_init(unit, &pt); 3182 parse_table_add(&pt, "PortBitMap", PQ_DFL | PQ_PBMP | PQ_BCM, 3183 0, &arg_pbmp, NULL); 3184 parse_table_add(&pt, "SPeed", PQ_DFL | PQ_INT, 0, &arg_speed, NULL); 3185 parse_table_add(&pt, "FullDuplex", PQ_DFL | PQ_BOOL, 3186 0, &arg_duplex, NULL); 3187 parse_table_add(&pt, "Gap", PQ_DFL | PQ_INT, 0, &arg_gap, NULL); 3188 parse_table_add(&pt, "STretch", PQ_DFL | PQ_INT, 0, &arg_stretch, NULL); 3189 3190 if (!parseEndOk(a, &pt, &retCode)) { 3191 return retCode; 3192 } 3193 } 3194 3195 cli_out("%s\n", header); 3196 /* 3197 * Display IPG settings for all the specified ports 3198 */ 3199 /* coverity[overrun-local] */ 3200 DPORT_BCM_PBMP_ITER(unit, arg_pbmp, dport, port) { 3201 cli_out("%-8.8s", BCM_PORT_NAME(unit, port)); 3202 for (i = 0; i < num_speeds; i++) { 3203 speed = speeds[i]; 3204 3205 for (duplex = BCM_PORT_DUPLEX_HALF; 3206 duplex < BCM_PORT_DUPLEX_COUNT; duplex++) { 3207 /* 3208 * Skip the illegal 10000HD combination 3209 */ 3210 if (speed >= 10000 && duplex == BCM_PORT_DUPLEX_HALF) { 3211 continue; 3212 } 3213 3214 /* 3215 * Skip an entry if the speed has been explicitly specified 3216 */ 3217 if (arg_speed != 0 && speed != arg_speed) { 3218 cli_out("%8.8s", " "); 3219 continue; 3220 } 3221 3222 /* 3223 * Skip an entry if duplex has been explicitly specified 3224 * and the entry doesn't match 3225 */ 3226 if (arg_duplex != BCM_PORT_DUPLEX_COUNT && arg_duplex != duplex) { 3227 cli_out("%8.8s", " "); 3228 continue; 3229 } 3230 3231 if (arg_gap != 0) { 3232 rv = bcm_port_ifg_set(unit, port, speed, duplex, arg_gap); 3233 if (rv != BCM_E_NONE) { 3234 return CMD_FAIL; 3235 } 3236 } 3237 3238 rv = bcm_port_ifg_get(unit, port, speed, duplex, &real_ifg); 3239 3240 if (rv == BCM_E_NONE) { 3241 cli_out("%8d", real_ifg); 3242 } else { 3243 cli_out("%8.8s", "n/a"); 3244 } 3245 } 3246 } 3247 if (arg_stretch >= 0) { 3248 rv = bcm_port_control_set(unit, port, 3249 bcmPortControlFrameSpacingStretch, 3250 arg_stretch); 3251 if (rv != BCM_E_NONE) { 3252 return CMD_FAIL; 3253 } 3254 } 3255 rv = bcm_port_control_get(unit, port, bcmPortControlFrameSpacingStretch, 3256 &stretch); 3257 3258 if (rv == BCM_E_NONE) { 3259 cli_out("%8d", stretch); 3260 } else { 3261 cli_out("%8.8s", "n/a"); 3262 } 3263 cli_out("\n"); 3264 } 3265 3266 return (CMD_OK); 3267 } 3268 3269 cmd_result_t 3270 if_esw_dtag(int unit, args_t *a) 3271 { 3272 char *subcmd, *c; 3273 bcm_port_config_t pcfg; 3274 bcm_pbmp_t pbmp; 3275 bcm_port_t port, dport; 3276 int mode, r; 3277 uint16 tpid; 3278 int dt_mode_mask; 3279 3280 if (!sh_check_attached(ARG_CMD(a), unit)) { 3281 return CMD_FAIL; 3282 } 3283 3284 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 3285 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 3286 return CMD_FAIL; 3287 } 3288 3289 dt_mode_mask = BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL; 3290 3291 if ((subcmd = ARG_GET(a)) == NULL) { 3292 subcmd = "show"; 3293 } 3294 3295 c = ARG_GET(a); 3296 if (c == NULL) { 3297 BCM_PBMP_ASSIGN(pbmp, pcfg.e); 3298 } else { 3299 if (parse_bcm_pbmp(unit, c, &pbmp) < 0) { 3300 cli_out("%s: ERROR: unrecognized port bitmap: %s\n", ARG_CMD(a), c); 3301 return CMD_FAIL; 3302 } 3303 } 3304 3305 r = 0; 3306 if (sal_strcasecmp(subcmd, "show") == 0) { 3307 char *mode_flag; 3308 3309 /* coverity[overrun-local] */ 3310 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3311 r = bcm_port_dtag_mode_get(unit, port, &mode); 3312 if (r < 0) { 3313 goto bcm_err; 3314 } 3315 r = bcm_port_tpid_get(unit, port, &tpid); 3316 if (r < 0) { 3317 goto bcm_err; 3318 } 3319 switch (mode & dt_mode_mask) { 3320 case BCM_PORT_DTAG_MODE_NONE: 3321 c = "none (disabled)"; 3322 break; 3323 case BCM_PORT_DTAG_MODE_INTERNAL: 3324 c = "internal (service provider)"; 3325 break; 3326 case BCM_PORT_DTAG_MODE_EXTERNAL: 3327 c = "external (customer)"; 3328 break; 3329 default: 3330 c = "unknown"; 3331 break; 3332 } 3333 3334 mode_flag = ""; 3335 if (mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) { 3336 mode_flag = " remove customer tag"; 3337 } else if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG) { 3338 mode_flag = " add customer tag"; 3339 } 3340 3341 cli_out("port %d:%s\tdouble tag mode %s%s, tpid 0x%x\n", 3342 unit, BCM_PORT_NAME(unit, port), c, mode_flag, tpid); 3343 } 3344 return CMD_OK; 3345 } 3346 3347 if (sal_strcasecmp(subcmd, "mode") == 0) { 3348 c = ARG_GET(a); 3349 if (c == NULL) { 3350 char *mode_flag; 3351 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3352 3353 r = bcm_port_dtag_mode_get(unit, port, &mode); 3354 if (r < 0) { 3355 goto bcm_err; 3356 } 3357 switch (mode & dt_mode_mask) { 3358 case BCM_PORT_DTAG_MODE_NONE: 3359 c = "none (disabled)"; 3360 break; 3361 case BCM_PORT_DTAG_MODE_INTERNAL: 3362 c = "internal (service provider)"; 3363 break; 3364 case BCM_PORT_DTAG_MODE_EXTERNAL: 3365 c = "external (customer)"; 3366 break; 3367 default: 3368 c = "unknown"; 3369 break; 3370 } 3371 3372 mode_flag = ""; 3373 if (mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) { 3374 mode_flag = " remove customer tag"; 3375 } else if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG) { 3376 mode_flag = " add customer tag"; 3377 } 3378 3379 cli_out("port %d:%s\tdouble tag mode %s%s\n", 3380 unit, BCM_PORT_NAME(unit, port), c, mode_flag); 3381 } 3382 return CMD_OK; 3383 } 3384 if (sal_strcasecmp(c, "none") == 0) { 3385 mode = BCM_PORT_DTAG_MODE_NONE; 3386 } else if (sal_strcasecmp(c, "internal") == 0) { 3387 mode = BCM_PORT_DTAG_MODE_INTERNAL; 3388 } else if (sal_strcasecmp(c, "external") == 0) { 3389 mode = BCM_PORT_DTAG_MODE_EXTERNAL; 3390 } else { 3391 return CMD_USAGE; 3392 } 3393 c = ARG_GET(a); 3394 if (c != NULL) { 3395 if (sal_strcasecmp(c, "addInnerTag") == 0) { 3396 mode |= BCM_PORT_DTAG_ADD_EXTERNAL_TAG; 3397 } else if (sal_strcasecmp(c, "removeInnerTag") == 0) { 3398 mode |= BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG; 3399 } else { 3400 return CMD_OK; 3401 } 3402 } 3403 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3404 r = bcm_port_dtag_mode_set(unit, port, mode); 3405 if (r < 0) { 3406 goto bcm_err; 3407 } 3408 } 3409 return CMD_OK; 3410 } 3411 3412 if (sal_strcasecmp(subcmd, "tpid") == 0) { 3413 c = ARG_GET(a); 3414 if (c == NULL) { 3415 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3416 r = bcm_port_tpid_get(unit, port, &tpid); 3417 if (r < 0) { 3418 goto bcm_err; 3419 } 3420 cli_out("port %d:%s\ttpid 0x%x\n", 3421 unit, BCM_PORT_NAME(unit, port), tpid); 3422 } 3423 } else { 3424 tpid = parse_integer(c); 3425 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3426 r = bcm_port_tpid_set(unit, port, tpid); 3427 if (r < 0) { 3428 goto bcm_err; 3429 } 3430 } 3431 } 3432 return CMD_OK; 3433 } 3434 3435 if (sal_strcasecmp(subcmd, "addTpid") == 0) { 3436 c = ARG_GET(a); 3437 if (c == NULL) { 3438 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3439 r = bcm_port_tpid_get(unit, port, &tpid); 3440 if (r < 0) { 3441 goto bcm_err; 3442 } 3443 cli_out("port %d:%s\ttpid 0x%x\n", 3444 unit, BCM_PORT_NAME(unit, port), tpid); 3445 } 3446 } else { 3447 tpid = parse_integer(c); 3448 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3449 r = bcm_port_tpid_add(unit, port, tpid, BCM_COLOR_PRIORITY); 3450 if (r < 0) { 3451 goto bcm_err; 3452 } 3453 } 3454 } 3455 return CMD_OK; 3456 } 3457 3458 if (sal_strcasecmp(subcmd, "deleteTpid") == 0) { 3459 c = ARG_GET(a); 3460 if (c == NULL) { 3461 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3462 r = bcm_port_tpid_get(unit, port, &tpid); 3463 if (r < 0) { 3464 goto bcm_err; 3465 } 3466 cli_out("port %d:%s\ttpid 0x%x\n", 3467 unit, BCM_PORT_NAME(unit, port), tpid); 3468 } 3469 } else { 3470 if (sal_strcasecmp(c, "all") == 0) { 3471 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3472 r = bcm_port_tpid_delete_all(unit, port); 3473 if (r < 0) { 3474 goto bcm_err; 3475 } 3476 } 3477 } else { 3478 tpid = parse_integer(c); 3479 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 3480 r = bcm_port_tpid_delete(unit, port, tpid); 3481 if (r < 0) { 3482 goto bcm_err; 3483 } 3484 } 3485 } 3486 } 3487 return CMD_OK; 3488 } 3489 3490 return CMD_USAGE; 3491 3492 bcm_err: 3493 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 3494 return CMD_FAIL; 3495 } 3496 3497 #ifdef SW_AUTONEG_SUPPORT 3498 cmd_result_t 3499 if_esw_swAutoneg(int unit, args_t *a) 3500 { 3501 int rv = 0; 3502 char *c; 3503 int enabled = 0; 3504 bcm_port_config_t pcfg; 3505 3506 3507 rv = bcm_init_check(unit); 3508 if (rv == BCM_E_UNIT) { 3509 cli_out("unit %d: is not initialized\n", unit); 3510 return CMD_FAIL; 3511 } 3512 3513 3514 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 3515 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 3516 return CMD_FAIL; 3517 } 3518 3519 if (!soc_feature(unit, soc_feature_sw_autoneg)) { 3520 cli_out("%s: Error: SW Autoneg is not supported on this platform\n", ARG_CMD(a)); 3521 return CMD_FAIL; 3522 } 3523 3524 if (ARG_CNT(a) == 0) { 3525 /* display status of SW AN thread enabled/disabled */ 3526 rv = bcm_sw_an_enable_get(unit, &enabled); 3527 if (rv != BCM_E_NONE) { 3528 cli_out("unit %d: %s failed\n", unit, __FUNCTION__); 3529 return CMD_FAIL; 3530 } 3531 if (enabled) { 3532 cli_out("SW AN is enabled on unit %d\n", unit); 3533 } else { 3534 cli_out("SW AN is disabled on unit %d\n", unit); 3535 } 3536 return CMD_OK; 3537 } 3538 3539 if (ARG_CUR(a) != NULL) { 3540 c = ARG_GET(a); 3541 3542 if (!sal_strcasecmp(c, "off") || 3543 !sal_strcasecmp(c, "disable") || 3544 !sal_strcasecmp(c, "no")) { 3545 rv = bcm_sw_an_enable_set(unit, 0); 3546 if (rv != BCM_E_NONE) { 3547 cli_out("unit %d: %s failed\n", unit, __FUNCTION__); 3548 return CMD_FAIL; 3549 } 3550 } else if (!sal_strcasecmp(c, "on") || 3551 !sal_strcasecmp(c, "enable") || 3552 !sal_strcasecmp(c, "yes")) { 3553 rv = bcm_sw_an_enable_set(unit, 1); 3554 if (rv != BCM_E_NONE) { 3555 cli_out("unit %d: %s failed\n", unit, __FUNCTION__); 3556 return CMD_FAIL; 3557 } 3558 } else { 3559 cli_out("unit: %d SW_AN Invalid argument\n", unit); 3560 return CMD_FAIL; 3561 } 3562 } 3563 3564 return CMD_OK; 3565 } 3566 #endif 3567 3568 cmd_result_t 3569 if_esw_linkscan(int unit, args_t *a) 3570 { 3571 parse_table_t pt; 3572 char *c; 3573 int us, rv; 3574 pbmp_t pbm_sw, pbm_hw, pbm_none, pbm_force; 3575 pbmp_t pbm_temp; 3576 pbmp_t pbm_sw_pre, pbm_hw_pre, pbm_none_pre; 3577 bcm_port_config_t pcfg; 3578 soc_port_t port, dport; 3579 char pfmt[SOC_PBMP_FMT_LEN]; 3580 int linkscan_interval_default; 3581 3582 linkscan_interval_default = soc_property_get(unit, 3583 spn_BCM_LINKSCAN_INTERVAL, BCM_LINKSCAN_INTERVAL_DEFAULT); 3584 3585 3586 /* 3587 * Workaround that allows "linkscan off" at the beginning of rc.soc 3588 */ 3589 3590 if (ARG_CNT(a) == 1 && sal_strcasecmp(_ARG_CUR(a), "off") == 0) { 3591 #ifdef BCM_CMICX_SUPPORT 3592 if (soc_feature(unit, soc_feature_cmicx) && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) { 3593 #if defined(BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) 3594 soc_iproc_m0ssq_exit(unit); 3595 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */ 3596 } 3597 #endif /* BCM_CMICX_SUPPORT */ 3598 rv = bcm_init_check(unit); 3599 if (rv == BCM_E_UNIT) { 3600 (void)ARG_GET(a); 3601 return (CMD_OK); 3602 } 3603 } 3604 3605 if (bcm_port_config_get(unit, &pcfg) != BCM_E_NONE) { 3606 cli_out("%s: Error: bcm ports not initialized\n", ARG_CMD(a)); 3607 return CMD_FAIL; 3608 } 3609 3610 /* 3611 * First get current linkscan state. (us == 0 if disabled). 3612 */ 3613 3614 if ((rv = bcm_linkscan_enable_get(unit, &us)) < 0) { 3615 cli_out("%s: Error: Failed to recover enable status: %s\n", 3616 ARG_CMD(a), bcm_errmsg(rv)); 3617 return (CMD_FAIL); 3618 } 3619 3620 BCM_PBMP_CLEAR(pbm_sw); 3621 BCM_PBMP_CLEAR(pbm_hw); 3622 BCM_PBMP_CLEAR(pbm_force); 3623 3624 DPORT_BCM_PBMP_ITER(unit, pcfg.port, dport, port) { 3625 int mode; 3626 3627 if ((rv = bcm_linkscan_mode_get(unit, port, &mode)) < 0) { 3628 /* Ignore requeue ports for linkscan */ 3629 if (!IS_REQ_PORT(unit, port)) { 3630 cli_out("%s: Error: Could not get linkscan state for port %s\n", 3631 ARG_CMD(a), BCM_PORT_NAME(unit, port)); 3632 } 3633 } else { 3634 switch (mode) { 3635 case BCM_LINKSCAN_MODE_SW: 3636 BCM_PBMP_PORT_ADD(pbm_sw, port); 3637 break; 3638 case BCM_LINKSCAN_MODE_HW: 3639 BCM_PBMP_PORT_ADD(pbm_hw, port); 3640 break; 3641 default: 3642 break; 3643 } 3644 } 3645 } 3646 BCM_PBMP_ASSIGN(pbm_sw_pre, pbm_sw); 3647 BCM_PBMP_ASSIGN(pbm_hw_pre, pbm_hw); 3648 BCM_PBMP_REMOVE(pbm_sw_pre, PBMP_HG_SUBPORT_ALL(unit)); 3649 BCM_PBMP_REMOVE(pbm_hw_pre, PBMP_HG_SUBPORT_ALL(unit)); 3650 3651 /* 3652 * If there are no arguments, just display the status. 3653 */ 3654 3655 if (ARG_CNT(a) == 0) { 3656 char buf[FORMAT_PBMP_MAX]; 3657 pbmp_t pbm; 3658 3659 if (us) { 3660 cli_out("%s: Linkscan enabled\n", ARG_CMD(a)); 3661 cli_out("%s: Software polling interval: %d usec\n", 3662 ARG_CMD(a), us); 3663 format_bcm_pbmp(unit, buf, sizeof(buf), pbm_sw); 3664 cli_out("%s: Software Port BitMap %s: %s\n", 3665 ARG_CMD(a), SOC_PBMP_FMT(pbm_sw, pfmt), buf); 3666 format_bcm_pbmp(unit, buf, sizeof(buf), pbm_hw); 3667 cli_out("%s: Hardware Port BitMap %s: %s\n", 3668 ARG_CMD(a), SOC_PBMP_FMT(pbm_hw, pfmt), buf); 3669 BCM_PBMP_ASSIGN(pbm_temp, pbm_sw); 3670 BCM_PBMP_OR(pbm_temp, pbm_hw); 3671 BCM_PBMP_REMOVE(pbm_temp, PBMP_HG_SUBPORT_ALL(unit)); 3672 BCM_PBMP_ASSIGN(pbm, pcfg.port); 3673 BCM_PBMP_XOR(pbm, pbm_temp); 3674 format_bcm_pbmp(unit, buf, sizeof(buf), pbm); 3675 cli_out("%s: Disabled Port BitMap %s: %s\n", 3676 ARG_CMD(a), SOC_PBMP_FMT(pbm, pfmt), buf); 3677 } else { 3678 cli_out("%s: Linkscan disabled\n", ARG_CMD(a)); 3679 } 3680 3681 return (CMD_OK); 3682 } 3683 3684 us = us ? us : linkscan_interval_default; 3685 3686 parse_table_init(unit, &pt); 3687 parse_table_add(&pt, "SwPortBitMap", PQ_PBMP | PQ_DFL | PQ_BCM, 0, &pbm_sw, 3688 0); 3689 parse_table_add(&pt, "HwPortBitMap", PQ_PBMP | PQ_DFL | PQ_BCM, 0, &pbm_hw, 3690 0); 3691 parse_table_add(&pt, "Force", PQ_PBMP | PQ_DFL | PQ_BCM, 0, &pbm_force, 0); 3692 parse_table_add(&pt, "Interval", PQ_INT | PQ_DFL, 0, &us, 0); 3693 3694 if (parse_arg_eq(a, &pt) < 0) { 3695 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 3696 parse_arg_eq_done(&pt); 3697 return (CMD_FAIL); 3698 } 3699 parse_arg_eq_done(&pt); 3700 3701 /* 3702 * Handle backward compatibility, allowing a raw interval to be 3703 * specified directly on the command line, as well as "on" or "off". 3704 */ 3705 3706 if (ARG_CUR(a) != NULL) { 3707 c = ARG_GET(a); 3708 3709 if (!sal_strcasecmp(c, "off") || 3710 !sal_strcasecmp(c, "disable") || 3711 !sal_strcasecmp(c, "no")) { 3712 us = 0; 3713 } else if (!sal_strcasecmp(c, "on") || 3714 !sal_strcasecmp(c, "enable") || 3715 !sal_strcasecmp(c, "yes")) { 3716 us = prev_linkscan_interval[unit] ? 3717 prev_linkscan_interval[unit] : linkscan_interval_default; 3718 if (us == 0) { 3719 cli_out("WARNING: Cannot enable Linkscan if the polling interval is zero\n"); 3720 } 3721 #ifdef BCM_CMICX_SUPPORT 3722 if (soc_feature(unit, soc_feature_cmicx) && us && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) { 3723 #if defined(BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) 3724 soc_iproc_m0ssq_init(unit); 3725 #endif /* BCM_ESW_SUPPORT || BCM_DNXF_SUPPORT */ 3726 } 3727 #endif /* BCM_CMICX_SUPPORT */ 3728 } else if (isint(c)) { 3729 us = parse_integer(c); 3730 } else { 3731 return (CMD_USAGE); 3732 } 3733 } 3734 3735 if (us == 0) { 3736 int prev_interval; 3737 3738 rv = bcm_linkscan_enable_get(unit, &prev_interval); 3739 if (rv < 0 || prev_interval <= 0) { 3740 prev_interval = linkscan_interval_default; 3741 } 3742 prev_linkscan_interval[unit] = prev_interval; 3743 /* Turn off linkscan */ 3744 if ((rv = bcm_linkscan_enable_set(unit, 0)) < 0) { 3745 cli_out("%s: Error: Failed to disable linkscan: %s\n", 3746 ARG_CMD(a), bcm_errmsg(rv)); 3747 return (CMD_FAIL); 3748 } 3749 3750 return (CMD_OK); 3751 } 3752 3753 BCM_PBMP_AND(pbm_sw, pcfg.port); 3754 BCM_PBMP_AND(pbm_hw, pcfg.port); 3755 BCM_PBMP_ASSIGN(pbm_none, pcfg.port); 3756 BCM_PBMP_REMOVE(pbm_sw, PBMP_HG_SUBPORT_ALL(unit)); 3757 BCM_PBMP_REMOVE(pbm_hw, PBMP_HG_SUBPORT_ALL(unit)); 3758 BCM_PBMP_REMOVE(pbm_none, PBMP_HG_SUBPORT_ALL(unit)); 3759 3760 BCM_PBMP_ASSIGN(pbm_temp, pbm_sw); 3761 BCM_PBMP_OR(pbm_temp, pbm_hw); 3762 BCM_PBMP_XOR(pbm_none, pbm_temp); 3763 BCM_PBMP_AND(pbm_force, pcfg.port); 3764 3765 BCM_PBMP_ASSIGN(pbm_temp, pbm_sw); 3766 BCM_PBMP_AND(pbm_temp, pbm_hw); 3767 if (BCM_PBMP_NOT_NULL(pbm_temp)) { 3768 cli_out("%s: Error: Same port can't use both " 3769 "software and hardware linkscan\n", ARG_CMD(a)); 3770 return (CMD_FAIL); 3771 } 3772 3773 if ((rv = bcm_linkscan_mode_set_pbm(unit, pbm_sw, 3774 BCM_LINKSCAN_MODE_SW)) < 0) { 3775 cli_out("%s: Failed to set software link scanning: PBM=%s: %s\n", 3776 ARG_CMD(a), SOC_PBMP_FMT(pbm_sw, pfmt), bcm_errmsg(rv)); 3777 return (CMD_FAIL); 3778 } 3779 3780 if ((rv = bcm_linkscan_mode_set_pbm(unit, pbm_hw, 3781 BCM_LINKSCAN_MODE_HW)) < 0) { 3782 cli_out("%s: Failed to set hardware link scanning: PBM=%s: %s\n", 3783 ARG_CMD(a), SOC_PBMP_FMT(pbm_hw, pfmt), bcm_errmsg(rv)); 3784 return (CMD_FAIL); 3785 } 3786 3787 /* Only set the port to mode_none state if it is not previously in this mode */ 3788 BCM_PBMP_ASSIGN(pbm_none_pre, pcfg.port); 3789 BCM_PBMP_ASSIGN(pbm_temp, pbm_sw_pre); 3790 BCM_PBMP_OR(pbm_temp, pbm_hw_pre); 3791 BCM_PBMP_XOR(pbm_none_pre, pbm_temp); 3792 BCM_PBMP_XOR(pbm_none_pre, pbm_none); 3793 BCM_PBMP_AND(pbm_none, pbm_none_pre); /* the one changed from 0 to 1 */ 3794 3795 if ((rv = bcm_linkscan_mode_set_pbm(unit, pbm_none, 3796 BCM_LINKSCAN_MODE_NONE)) < 0) { 3797 cli_out("%s: Failed to disable link scanning: PBM=%s: %s\n", 3798 ARG_CMD(a), SOC_PBMP_FMT(pbm_none, pfmt), bcm_errmsg(rv)); 3799 return (CMD_FAIL); 3800 } 3801 3802 if ((rv = bcm_linkscan_enable_set(unit, us)) < 0) { 3803 cli_out("%s: Error: Failed to enable linkscan: %s\n", 3804 ARG_CMD(a), bcm_errmsg(rv)); 3805 return (CMD_FAIL); 3806 } 3807 3808 if ((rv = bcm_link_change(unit, pbm_force)) < 0) { 3809 cli_out("%s: Failed to force link scan: PBM=%s: %s\n", 3810 ARG_CMD(a), SOC_PBMP_FMT(pbm_force, pfmt), bcm_errmsg(rv)); 3811 return (CMD_FAIL); 3812 } 3813 3814 return (CMD_OK); 3815 } 3816 3817 #if defined(BCM_TOMAHAWK_SUPPORT) 3818 cmd_result_t 3819 if_esw_asf(int unit, args_t *a) 3820 { 3821 int p, rv = BCM_E_NONE; 3822 char *arg; 3823 pbmp_t pbm; 3824 3825 if (!sh_check_attached(ARG_CMD(a), unit)) { 3826 return CMD_FAIL; 3827 } 3828 if (!soc_feature(unit, soc_feature_asf_multimode)) { 3829 return CMD_NOTIMPL; 3830 } 3831 3832 if ((arg = ARG_GET(a)) == NULL) { 3833 return (CMD_USAGE); 3834 } 3835 3836 if (arg && !sal_strcasecmp(arg, "show")) { 3837 if ((arg = ARG_GET(a)) == NULL) { 3838 return (CMD_USAGE); 3839 } 3840 if (parse_bcm_pbmp(unit, arg, &pbm) < 0) { 3841 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(a), arg); 3842 return CMD_FAIL; 3843 } 3844 if (BCM_PBMP_IS_NULL(pbm)) { 3845 return CMD_OK; 3846 } 3847 cli_out(" cut-through cut-through speed \n"); 3848 cli_out("port mode range (from/to)\n"); 3849 PBMP_ITER(pbm, p) { 3850 rv = bcm_esw_port_asf_show(unit, p); 3851 } 3852 } else if (arg && !sal_strcasecmp(arg, "diag")) { 3853 if ((arg = ARG_GET(a)) == NULL) { 3854 return (CMD_USAGE); 3855 } 3856 if (parse_bcm_pbmp(unit, arg, &pbm) < 0) { 3857 cli_out("%s: Error: unrecognized port bitmap: %s\n", ARG_CMD(a), arg); 3858 return CMD_FAIL; 3859 } 3860 if (BCM_PBMP_IS_NULL(pbm)) { 3861 return CMD_OK; 3862 } 3863 3864 rv = bcm_esw_asf_diag(unit); 3865 #ifdef BCM_TOMAHAWK3_SUPPORT 3866 if(SOC_IS_TOMAHAWK3(unit)) { 3867 cli_out("%-5s %-3s %-3s %-6s %-6s %-3s %-32s ", "port", "asf", 3868 "ctc", "min_sp", "max_sp", "thr", 3869 " xmit_start_count"); 3870 cli_out("%-3s, %-3s \n", "emc", "rxp"); 3871 cli_out("%-33s %-3s %-3s %-3s %-3s %-3s %-3s %-3s %-3s\n", " ", 3872 "sc0", "sc1", "sc2", "sc3", "sc4", "sc5", "sc6", "sc7"); 3873 3874 PBMP_ITER(pbm, p) { 3875 rv = bcm_esw_port_asf_diag(unit, p); 3876 } 3877 3878 cli_out("Legends:\n"); 3879 cli_out("asf: CT Mode, ctc: CT Class, min: Min. Src Port Speed, "\ 3880 "max: Max. Src Port Speed, thr: FIFO Threshold\n"); 3881 cli_out("xmit_start_count: Transmit Start Count, " 3882 "sc$: Source Class \n"); 3883 cli_out("emc: EGR MMU Credits, rxp: RX Pause\n"); 3884 } else 3885 3886 #endif 3887 { 3888 cli_out("port asf ctc min_sp max_sp thr dep "\ 3889 "xmit_start_count mpb mec emc rxp\n"); 3890 cli_out(" "\ 3891 "sc0 sc1 sc2 sc3 sc4 sc5 sc6 sc7 sc8 sc9 s10 s11 s12\n"); 3892 PBMP_ITER(pbm, p) { 3893 rv = bcm_esw_port_asf_diag(unit, p); 3894 } 3895 3896 cli_out("Legends:\n"); 3897 cli_out("asf: CT Mode, ctc: CT Class, min: Min. Src Port Speed, "\ 3898 "max: Max. Src Port Speed, thr: FIFO Threshold\n"); 3899 cli_out("dep: FIFO Depth, xmit_start_count: Transmit Start Count, " 3900 "sc$: Source Class, mpb: MMU Prebuffer\n"); 3901 cli_out("mec: MMU EP Credits, emc: EGR MMU Credits, rxp: RX Pause\n"); 3902 } 3903 } else { 3904 cli_out("error: incorrect argument\n"); 3905 } 3906 3907 if (BCM_FAILURE(rv)) { 3908 return CMD_FAIL; 3909 } else { 3910 return CMD_OK; 3911 } 3912 } 3913 #endif 3914 3915 3916 /* Must stay in sync with bcm_color_t enum (bcm/types.h) */ 3917 const char *diag_parse_color[] = { 3918 "Green", 3919 "Yellow", 3920 "Red", 3921 NULL 3922 }; 3923 3924 char cmd_color_usage[] = 3925 "Usages:\n\t" 3926 " color set Port=<port> Prio=<prio> CFI=<cfi>\n\t" 3927 " Color=<Green|Yellow|Red>\n\t" 3928 " color show Port=<port>\n\t" 3929 " color map Port=<port> PktPrio=<prio> CFI=<cfi>\n\t" 3930 " IntPrio=<prio> Color=<Green|Yellow|Red>\n\t" 3931 " color unmap Port=<port> IntPrio=<prio> Color=<Green|Yellow|Red>\n\t" 3932 " PktPrio=<prio> CFI=<cfi>\n"; 3933 3934 cmd_result_t 3935 cmd_color(int unit, args_t *a) 3936 { 3937 int port = 0, prio = -1, cfi = -1, color_parse = bcmColorRed; 3938 bcm_color_t color; 3939 char *subcmd; 3940 int r; 3941 parse_table_t pt; 3942 cmd_result_t retCode; 3943 3944 if (!sh_check_attached(ARG_CMD(a), unit)) { 3945 return CMD_FAIL; 3946 } 3947 3948 if ((subcmd = ARG_GET(a)) == NULL) { 3949 return CMD_USAGE; 3950 } 3951 3952 if (sal_strcasecmp(subcmd, "set") == 0) { 3953 3954 parse_table_init(unit, &pt); 3955 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &port, NULL); 3956 parse_table_add(&pt, "PRio", PQ_INT | PQ_DFL, 0, &prio, NULL); 3957 parse_table_add(&pt, "CFI", PQ_INT | PQ_DFL, 0, &cfi, NULL); 3958 parse_table_add(&pt, "Color", PQ_MULTI | PQ_DFL, 0, 3959 &color_parse, diag_parse_color); 3960 3961 if (!parseEndOk(a, &pt, &retCode)) { 3962 return retCode; 3963 } 3964 if (!SOC_PORT_VALID(unit, port)) { 3965 cli_out("%s: ERROR: Invalid port selection %d\n", ARG_CMD(a), port); 3966 return CMD_FAIL; 3967 } 3968 3969 color = (bcm_color_t) color_parse; 3970 3971 if (prio < 0) { 3972 if (cfi < 0) { 3973 /* No selection to assign color */ 3974 cli_out("%s: ERROR: No parameter to assign color\n", ARG_CMD(a)); 3975 return CMD_FAIL; 3976 } else { 3977 if ((r = bcm_port_cfi_color_set(unit, port, cfi, color)) < 0) { 3978 goto bcm_err; 3979 } 3980 } 3981 } else { 3982 if (cfi < 0) { 3983 if (prio > BCM_PRIO_MAX) { 3984 cli_out("%s: ERROR: Priority %d exceeds maximum\n", 3985 ARG_CMD(a), prio); 3986 return CMD_FAIL; 3987 } else { 3988 if ((r = bcm_port_priority_color_set(unit, port, prio, 3989 color)) < 0) { 3990 goto bcm_err; 3991 } 3992 } 3993 } 3994 3995 } 3996 return CMD_OK; 3997 } 3998 3999 if (sal_strcasecmp(subcmd, "show") == 0) { 4000 parse_table_init(unit, &pt); 4001 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &port, NULL); 4002 if (!parseEndOk(a, &pt, &retCode)) { 4003 return retCode; 4004 } 4005 if (!SOC_PORT_VALID(unit, port)) { 4006 cli_out("%s: ERROR: Invalid port selection %d\n", ARG_CMD(a), port); 4007 return CMD_FAIL; 4008 } 4009 4010 cli_out("Color settings for port %s\n", BCM_PORT_NAME(unit, port)); 4011 for (prio = BCM_PRIO_MIN; prio <= BCM_PRIO_MAX; prio++) { 4012 if ((r = bcm_port_priority_color_get(unit, port, prio, &color)) < 0) { 4013 goto bcm_err; 4014 } 4015 cli_out("Priority %d\t%s\n", prio, diag_parse_color[color]); 4016 } 4017 4018 if ((r = bcm_port_cfi_color_get(unit, port, FALSE, &color)) < 0) { 4019 goto bcm_err; 4020 } 4021 cli_out("No CFI \t%s\n", diag_parse_color[color]); 4022 4023 if ((r = bcm_port_cfi_color_get(unit, port, TRUE, &color)) < 0) { 4024 goto bcm_err; 4025 } 4026 cli_out("CFI \t%s\n", diag_parse_color[color]); 4027 return CMD_OK; 4028 } 4029 4030 if (sal_strcasecmp(subcmd, "map") == 0) { 4031 int pkt_prio, int_prio; 4032 4033 pkt_prio = int_prio = -1; 4034 4035 parse_table_init(unit, &pt); 4036 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &port, NULL); 4037 parse_table_add(&pt, "PktPrio", PQ_INT | PQ_DFL, 0, &pkt_prio, NULL); 4038 parse_table_add(&pt, "CFI", PQ_INT | PQ_DFL, 0, &cfi, NULL); 4039 parse_table_add(&pt, "IntPrio", PQ_INT | PQ_DFL, 0, &int_prio, NULL); 4040 parse_table_add(&pt, "Color", PQ_MULTI | PQ_DFL, 0, 4041 &color_parse, diag_parse_color); 4042 4043 if (!parseEndOk(a, &pt, &retCode)) { 4044 return retCode; 4045 } 4046 4047 if (!SOC_PORT_VALID(unit, port)) { 4048 cli_out("%s: ERROR: Invalid port selection %d\n", ARG_CMD(a), port); 4049 return CMD_FAIL; 4050 } 4051 4052 if (pkt_prio < 0 || cfi < 0 || int_prio < 0) { 4053 cli_out("Color map settings for port %s\n", 4054 BCM_PORT_NAME(unit, port)); 4055 4056 for (prio = BCM_PRIO_MIN; prio <= BCM_PRIO_MAX; prio++) { 4057 for (cfi = 0; cfi <= 1; cfi++) { 4058 if ((r = bcm_port_vlan_priority_map_get(unit, port, 4059 prio, cfi, 4060 &int_prio, 4061 &color)) < 0) { 4062 goto bcm_err; 4063 } 4064 cli_out("Packet Prio=%d, CFI=%d, Internal Prio=%d, " 4065 "Color=%s\n", 4066 prio, cfi, int_prio, diag_parse_color[color]); 4067 } 4068 } 4069 } else { 4070 color = (bcm_color_t) color_parse; 4071 if ((r = bcm_port_vlan_priority_map_set(unit, port, pkt_prio, cfi, 4072 int_prio, color)) < 0) { 4073 goto bcm_err; 4074 } 4075 } 4076 4077 return CMD_OK; 4078 } 4079 4080 if (sal_strcasecmp(subcmd, "unmap") == 0) { 4081 int pkt_prio, int_prio; 4082 4083 pkt_prio = int_prio = -1; 4084 4085 parse_table_init(unit, &pt); 4086 parse_table_add(&pt, "Port", PQ_DFL | PQ_PORT, 0, &port, NULL); 4087 parse_table_add(&pt, "PktPrio", PQ_INT | PQ_DFL, 0, &pkt_prio, NULL); 4088 parse_table_add(&pt, "CFI", PQ_INT | PQ_DFL, 0, &cfi, NULL); 4089 parse_table_add(&pt, "IntPrio", PQ_INT | PQ_DFL, 0, &int_prio, NULL); 4090 parse_table_add(&pt, "Color", PQ_MULTI | PQ_DFL, 0, 4091 &color_parse, diag_parse_color); 4092 4093 if (!parseEndOk(a, &pt, &retCode)) { 4094 return retCode; 4095 } 4096 4097 if (!SOC_PORT_VALID(unit, port)) { 4098 cli_out("%s: ERROR: Invalid port selection %d\n", ARG_CMD(a), port); 4099 return CMD_FAIL; 4100 } 4101 4102 if (pkt_prio < 0 || cfi < 0 || int_prio < 0) { 4103 cli_out("Color unmap settings for port %s\n", 4104 BCM_PORT_NAME(unit, port)); 4105 4106 for (prio = BCM_PRIO_MIN; prio <= BCM_PRIO_MAX; prio++) { 4107 for (color = bcmColorGreen; color <= bcmColorRed; color++) { 4108 if ((r = bcm_port_vlan_priority_unmap_get(unit, port, 4109 prio, color, 4110 &pkt_prio, 4111 &cfi)) < 0) { 4112 goto bcm_err; 4113 } 4114 cli_out("Internal Prio=%d, Color=%s, Packet Prio=%d, " 4115 "CFI=%d\n", 4116 prio, diag_parse_color[color], pkt_prio, cfi); 4117 } 4118 } 4119 } else { 4120 color = (bcm_color_t) color_parse; 4121 if ((r = bcm_port_vlan_priority_unmap_set(unit, port, int_prio, 4122 color, pkt_prio, 4123 cfi)) < 0) { 4124 goto bcm_err; 4125 } 4126 } 4127 4128 return CMD_OK; 4129 4130 } 4131 4132 cli_out("%s: ERROR: Unknown color subcommand: %s\n", ARG_CMD(a), subcmd); 4133 4134 return CMD_USAGE; 4135 4136 bcm_err: 4137 4138 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 4139 4140 return CMD_FAIL; 4141 } 4142 4143 #ifdef BCM_TRIUMPH3_SUPPORT 4144 char ibod_sync_usage[] = 4145 "Parameters: [on] [off] [Interval=<interval>] [tmmu]\n\t" 4146 "Starts the IBOD recovery thread running every <interval>\n\t" 4147 "microseconds. If <interval> is 0, stops the task.\n\t" 4148 "If <interval> is omitted, prints current setting.\n\t" 4149 "<tmmu> is used to trigger mmu recovery.\n"; 4150 4151 cmd_result_t 4152 cmd_ibod_sync(int unit, args_t *a) 4153 { 4154 parse_table_t pt; 4155 int r=BCM_E_NONE, ibod_running_flag; 4156 sal_usecs_t usec, port_avg_time, txerr_avg_time, mmu_avg_time; 4157 uint32 event_count, txerr_count, mmu_war_count; 4158 uint32 drain_timeout_count, egress_drain_timeout_count, port_recovery_failed_count; 4159 _port_ibod_ctrl_t *ibod_ctrl; 4160 4161 if (!sh_check_attached(ARG_CMD(a), unit)) { 4162 return CMD_FAIL; 4163 } 4164 4165 if (!SOC_IS_TRIUMPH3(unit)) { 4166 cli_out("%s: IBOD sync is not needed\n", ARG_CMD(a)); 4167 return CMD_OK; 4168 } 4169 4170 ibod_ctrl = sal_alloc(sizeof(_port_ibod_ctrl_t), "_port_ibod_ctrl_t"); 4171 if (ibod_ctrl == NULL) { 4172 return CMD_FAIL; 4173 } 4174 sal_memset(ibod_ctrl, 0, sizeof(_port_ibod_ctrl_t)); 4175 4176 if (_bcm_esw_ibod_sync_recovery_running(unit, ibod_ctrl) < 0) { 4177 ibod_running_flag = 0; 4178 usec = 0; 4179 port_avg_time = 0; 4180 txerr_avg_time = 0; 4181 mmu_avg_time = 0; 4182 event_count = 0; 4183 txerr_count = 0; 4184 mmu_war_count = 0; 4185 drain_timeout_count = 0; 4186 egress_drain_timeout_count = 0; 4187 port_recovery_failed_count = 0; 4188 } 4189 else { 4190 ibod_running_flag = 1; 4191 usec = ibod_ctrl->interval; 4192 port_avg_time = ibod_ctrl->port_avg_time; 4193 txerr_avg_time = ibod_ctrl->txerr_avg_time; 4194 mmu_avg_time = ibod_ctrl->mmu_avg_time; 4195 event_count = ibod_ctrl->event_count; 4196 txerr_count = ibod_ctrl->txerr_count; 4197 mmu_war_count = ibod_ctrl->mmu_war_count; 4198 drain_timeout_count = ibod_ctrl->drain_timeout_count; 4199 egress_drain_timeout_count = ibod_ctrl->egress_drain_timeout_count; 4200 port_recovery_failed_count = ibod_ctrl->port_recovery_failed_count; 4201 } 4202 4203 sal_free(ibod_ctrl); 4204 ibod_ctrl = NULL; 4205 4206 parse_table_init(unit, &pt); 4207 parse_table_add(&pt, "Interval", PQ_DFL | PQ_INT, (void *)0, &usec, NULL); 4208 4209 if (!ARG_CNT(a)) { /* Display settings */ 4210 cli_out("Current settings (unit %d):\n", unit); 4211 parse_eq_format(&pt); 4212 cli_out(" IBOD sync event count: %d\n", event_count); 4213 cli_out(" IBOD sync average time: %d us\n", port_avg_time); 4214 cli_out(" Txerr count: %d\n", txerr_count); 4215 cli_out(" Txerr average time: %d us\n", txerr_avg_time); 4216 cli_out(" MMU count: %d\n", mmu_war_count); 4217 cli_out(" MMU average time: %d us\n", mmu_avg_time); 4218 cli_out(" Drain timeout count: %d\n", drain_timeout_count); 4219 cli_out(" Egress drain timeout count: %d\n", egress_drain_timeout_count); 4220 cli_out(" Port recovery failed count: %d\n", port_recovery_failed_count); 4221 parse_arg_eq_done(&pt); 4222 return CMD_OK; 4223 } 4224 4225 if (parse_arg_eq(a, &pt) < 0) { 4226 cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a)); 4227 parse_arg_eq_done(&pt); 4228 return CMD_FAIL; 4229 } 4230 parse_arg_eq_done(&pt); 4231 4232 if (ARG_CNT(a) > 0 && !sal_strcasecmp(_ARG_CUR(a), "tmmu")) { 4233 ARG_NEXT(a); 4234 _bcm_esw_ibod_debug_flag_set(unit, _PORT_IBOD_FLAG_MMU_TRIGGER); 4235 return CMD_OK; 4236 } 4237 4238 if (ARG_CNT(a) > 0 && !sal_strcasecmp(_ARG_CUR(a), "on")) { 4239 ARG_NEXT(a); 4240 if (ibod_running_flag) { 4241 return CMD_OK; 4242 } 4243 if (usec == 0) { 4244 usec = soc_property_get(unit, spn_PORTMON_INTERVAL, IBOD_SYNC_INTERVAL_MIN); 4245 } 4246 } 4247 else if (ARG_CNT(a) > 0 && !sal_strcasecmp(_ARG_CUR(a), "off")) { 4248 usec = 0; 4249 ARG_NEXT(a); 4250 } 4251 else if (ARG_CNT(a) > 0) { 4252 return CMD_USAGE; 4253 } 4254 4255 if (usec > 0) { 4256 r = _bcm_esw_ibod_sync_recovery_start(unit, usec); 4257 } else { 4258 r = _bcm_esw_ibod_sync_recovery_stop(unit); 4259 } 4260 4261 if (r < 0) { 4262 cli_out("%s: Error: Could not set IBOD SYNCe: %s\n", 4263 ARG_CMD(a), soc_errmsg(r)); 4264 return CMD_FAIL; 4265 } 4266 4267 return CMD_OK; 4268 } 4269 #endif /* BCM_TRIUMPH3_SUPPORT */ 4270 4271 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 4272 4273 #define MAX_PM_NUM 64 4274 4275 /* Max number of PMs per device */ 4276 #define PM_NUM(unit) (SOC_IS_APACHE(unit) ? 18 : \ 4277 SOC_IS_TOMAHAWK2(unit) ? 64 : \ 4278 SOC_IS_TRIDENT3(unit) ? 32 : \ 4279 SOC_IS_TOMAHAWK3(unit) ? 32 : \ 4280 SOC_IS_HELIX5(unit) ? 19 : \ 4281 SOC_IS_MAVERICK2(unit) ? 20 : \ 4282 0) 4283 4284 #define FOUR_PORTS_PER_PBLK 4 4285 #define EIGHT_PORTS_PER_PBLK 8 4286 #define MAX_PORTS_PER_PBLK EIGHT_PORTS_PER_PBLK 4287 4288 typedef struct flexport_pm_info_s { 4289 /* Info get from cli input*/ 4290 char *pm_str; 4291 int ports[MAX_PORTS_PER_PBLK]; 4292 int port_cnt; 4293 4294 /* Parsed info */ 4295 bcm_port_resource_t pr[MAX_PORTS_PER_PBLK]; 4296 uint32 flags; 4297 #define FLXP_F_SEEN 0x1 /* PM seen without mode/port config */ 4298 #define FLXP_F_PARSED 0x2 /* PM with config is parsed */ 4299 #define FLXP_F_PORT_ASSIGNED 0x4 /* Logical ports have been assigned */ 4300 } flexport_pm_info_t; 4301 4302 typedef struct flexport_info_s { 4303 flexport_pm_info_t pm[MAX_PM_NUM]; 4304 int add_cnt; 4305 int del_cnt; 4306 } flexport_info_t; 4307 4308 /* 4309 * Function: 4310 * flexport_max_ports_per_pblk_get 4311 * Purpose: 4312 * Get max number of physical ports per port macro 4313 * Parameters: 4314 * unit(IN) - Strata switch unit number 4315 * max_ports(OUT) - Buffer to return value in to 4316 * Returns: 4317 * None 4318 */ 4319 static void 4320 flexport_max_ports_per_pblk_get(int unit, int *max_ports) 4321 { 4322 #ifdef BCM_TOMAHAWK3_SUPPORT 4323 if (SOC_IS_TOMAHAWK3(unit)) { 4324 *max_ports = EIGHT_PORTS_PER_PBLK; 4325 } else 4326 #endif 4327 { 4328 *max_ports = FOUR_PORTS_PER_PBLK; 4329 } 4330 } 4331 4332 static cmd_result_t 4333 flexport_show(int unit, flexport_info_t *f) 4334 { 4335 int pm, port, phy_port, phy_base, i; 4336 bcm_port_resource_t pr; 4337 char buf[6]; 4338 int max_ports = 0; 4339 4340 flexport_max_ports_per_pblk_get(unit, &max_ports); 4341 4342 for (pm = 0; pm < PM_NUM(unit) ; pm++) { 4343 if (!(f->pm[pm].flags & FLXP_F_SEEN)) { 4344 continue; 4345 } 4346 cli_out("PM%d:\n", pm); 4347 phy_base = (pm * max_ports) + 1; 4348 for(i = 0; i < max_ports; i++) { 4349 phy_port = phy_base + i; 4350 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 4351 if (port != -1) { 4352 bcm_port_resource_t_init(&pr); 4353 if (bcm_port_resource_get(unit, port, &pr) < 0) { 4354 cli_out("Flexport: Failed to get port resource of %s.\n", 4355 BCM_PORT_NAME(unit, port)); 4356 return CMD_FAIL; 4357 } 4358 cli_out("\t%s Port(%d) PhysicalPort(%d) Speed(%s) " 4359 "Lanes(%d) Encap(%s)\n", 4360 BCM_PORT_NAME(unit, port), port, pr.physical_port, 4361 if_fmt_speed(buf, pr.speed), pr.lanes, 4362 encap_mode[pr.encap]); 4363 } 4364 } 4365 } 4366 4367 return CMD_OK; 4368 } 4369 4370 static cmd_result_t 4371 flexport_parse_portlist(int unit, flexport_pm_info_t *pi) 4372 { 4373 int pm, p, pfirst, plast, i; 4374 char *s, *sn, *pl; 4375 int max_ports = 0; 4376 4377 /* no logical ports info for new ports from cmdline, so no parsing */ 4378 if (SOC_IS_TRIDENT3(unit)) { 4379 return CMD_OK; 4380 } 4381 4382 flexport_max_ports_per_pblk_get(unit, &max_ports); 4383 4384 for (pm = 0; pm < PM_NUM(unit); pm++) { 4385 if (pi[pm].pm_str == NULL) { 4386 continue; 4387 } 4388 pl = sal_strchr(pi[pm].pm_str, ':'); 4389 if (pl) { 4390 s = pl+1; 4391 pfirst = -1; 4392 i = 0; 4393 while (*s) { 4394 sn = s; 4395 if (isdigit((unsigned)*sn)) { 4396 p = 0; 4397 do { 4398 p = p * 10 + (*sn - '0'); 4399 sn++; 4400 } while (isdigit((unsigned)*sn)); 4401 } else { 4402 p = -1; 4403 } 4404 plast = p; 4405 4406 if (*sn == '-') { 4407 if (plast < 0) { 4408 return CMD_FAIL; 4409 } else if(pfirst < 0) { 4410 pfirst = plast; 4411 } else { 4412 return CMD_FAIL; 4413 } 4414 } else if (*sn == ',' || *sn == '\0') { 4415 if (pfirst < 0) { 4416 pfirst = plast; 4417 } 4418 for (p = pfirst; p <= plast; p++) { /* a range */ 4419 if (i >= max_ports) { 4420 return CMD_FAIL; 4421 } 4422 pi[pm].ports[i] = p; 4423 i++; 4424 } 4425 if (*sn == '\0') { 4426 break; 4427 } 4428 pfirst = -1; 4429 } else { 4430 return CMD_FAIL; 4431 } 4432 s = sn + 1; 4433 } 4434 if (i !=0 ) { 4435 pi[pm].port_cnt = i; 4436 pi[pm].flags |= FLXP_F_PORT_ASSIGNED; 4437 } 4438 *pl = '\0'; 4439 } 4440 } 4441 return CMD_OK; 4442 } 4443 4444 #ifndef MAX 4445 #define MAX(a, b) (((a)>(b))?(a):(b)) 4446 #endif 4447 4448 #ifdef BCM_TOMAHAWK3_SUPPORT 4449 static cmd_result_t 4450 th3_flexport_parse_pm_mode(int unit, flexport_info_t *f, int *auto_assign) 4451 { 4452 flexport_pm_info_t *pi = f->pm; 4453 bcm_port_resource_t *pr; 4454 int pm, phy_base, phy_port, port, i; 4455 int req_cnt; 4456 char *s; 4457 bcm_port_encap_t encap; 4458 int max_ports = 0; 4459 4460 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 4461 portmod_dispatch_type_t pm_type; 4462 int rv = BCM_E_NONE; 4463 #else 4464 /* For non-8x50 pm's, this command is not supported, return error */ 4465 return CMD_NOTIMPL; 4466 #endif 4467 4468 flexport_max_ports_per_pblk_get(unit, &max_ports); 4469 4470 f->del_cnt = 0; 4471 for (pm = 0; pm < PM_NUM(unit); pm++) { 4472 if (pi[pm].pm_str == NULL) { 4473 continue; 4474 } 4475 s = pi[pm].pm_str; 4476 pr = pi[pm].pr; 4477 phy_base = pm * max_ports + 1; 4478 4479 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT) 4480 /* 4481 * Check for pm type. If its not 8x50, return error 4482 */ 4483 rv = portmod_phy_pm_type_get(unit, phy_base, &pm_type); 4484 4485 if (rv != BCM_E_NONE) { 4486 cli_out("Error: portmod_phy_pm_type_get returned error %d" 4487 " for pm%d (%d:%d).\n", rv, pm, phy_base, 4488 SOC_INFO(unit).port_p2l_mapping[phy_base]); 4489 return CMD_FAIL; 4490 } 4491 4492 if (pm_type != portmodDispatchTypePm8x50) { 4493 cli_out("Error: Unsupported pm type %d, pm%d.\n", pm_type, pm); 4494 return CMD_FAIL; 4495 } 4496 #endif 4497 for(i = 0; i < max_ports; i++) { 4498 phy_port = phy_base + i; 4499 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 4500 if (port != -1) { 4501 f->del_cnt ++; 4502 } 4503 } 4504 4505 encap = BCM_PORT_ENCAP_IEEE; 4506 4507 if (!sal_strncasecmp(s, "1x400G", MAX(strlen(s), 6))) { 4508 req_cnt = 1; 4509 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4510 pr[0].port = pi[pm].ports[0]; 4511 } 4512 pr[0].physical_port = phy_base; 4513 pr[0].speed = 400000; 4514 pr[0].lanes = 8; 4515 pr[0].encap = encap; 4516 pr[0].fec_type = bcmPortPhyFecRs544_2xN; 4517 pr[0].phy_lane_config = -1; 4518 pr[0].link_training = 0; 4519 } else if(!sal_strncasecmp(s, "2x200G", MAX(strlen(s), 6))) { 4520 req_cnt = 2; 4521 for (i = 0; i < req_cnt; i++) { 4522 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4523 pr[i].port = pi[pm].ports[i]; 4524 } 4525 pr[i].physical_port = phy_base; 4526 pr[i].speed = 200000; 4527 pr[i].lanes = 4; 4528 pr[i].encap = encap; 4529 pr[i].fec_type = bcmPortPhyFecRs544_2xN; 4530 pr[i].phy_lane_config = -1; 4531 pr[i].link_training = 0; 4532 phy_base += pr[i].lanes; 4533 } 4534 } else if (!sal_strncasecmp(s, "2x100G", MAX(strlen(s), 6))) { 4535 req_cnt = 2; 4536 for (i = 0; i < req_cnt; i++) { 4537 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4538 pr[i].port = pi[pm].ports[i]; 4539 } 4540 pr[i].physical_port = phy_base; 4541 pr[i].speed = 100000; 4542 pr[i].lanes = 4; 4543 pr[i].encap = encap; 4544 pr[i].fec_type = bcmPortPhyFecNone; 4545 pr[i].phy_lane_config = -1; 4546 pr[i].link_training = 0; 4547 phy_base += pr[i].lanes; 4548 } 4549 } else if (!sal_strncasecmp(s, "2x40G", MAX(strlen(s), 5))) { 4550 req_cnt = 2; 4551 for (i = 0; i < req_cnt; i++) { 4552 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4553 pr[i].port = pi[pm].ports[i]; 4554 } 4555 pr[i].physical_port = phy_base; 4556 pr[i].speed = 40000; 4557 pr[i].lanes = 4; 4558 pr[i].encap = encap; 4559 pr[i].fec_type = bcmPortPhyFecNone; 4560 pr[i].phy_lane_config = -1; 4561 pr[i].link_training = 0; 4562 phy_base += pr[i].lanes; 4563 } 4564 } else if(!sal_strncasecmp(s, "4x100G", MAX(strlen(s), 6))) { 4565 req_cnt = 4; 4566 for (i = 0; i < req_cnt; i++) { 4567 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4568 pr[i].port = pi[pm].ports[i]; 4569 } 4570 pr[i].physical_port = phy_base; 4571 pr[i].speed = 100000; 4572 pr[i].lanes = 2; 4573 pr[i].encap = encap; 4574 pr[i].fec_type = bcmPortPhyFecRs544; 4575 pr[i].phy_lane_config = -1; 4576 pr[i].link_training = 0; 4577 phy_base += pr[i].lanes; 4578 } 4579 } else if(!sal_strncasecmp(s, "4x50G", MAX(strlen(s), 5))) { 4580 req_cnt = 4; 4581 for (i = 0; i < req_cnt; i++) { 4582 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4583 pr[i].port = pi[pm].ports[i]; 4584 } 4585 pr[i].physical_port = phy_base; 4586 pr[i].speed = 50000; 4587 pr[i].lanes = 2; 4588 pr[i].encap = encap; 4589 pr[i].fec_type = bcmPortPhyFecRs544; 4590 pr[i].phy_lane_config = -1; 4591 pr[i].link_training = 0; 4592 phy_base += pr[i].lanes; 4593 } 4594 } else if(!sal_strncasecmp(s, "4x40G", MAX(strlen(s), 5))) { 4595 req_cnt = 4; 4596 for (i = 0; i < req_cnt; i++) { 4597 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4598 pr[i].port = pi[pm].ports[i]; 4599 } 4600 pr[i].physical_port = phy_base; 4601 pr[i].speed = 40000; 4602 pr[i].lanes = 2; 4603 pr[i].encap = encap; 4604 pr[i].fec_type = bcmPortPhyFecNone; 4605 pr[i].phy_lane_config = -1; 4606 pr[i].link_training = 0; 4607 phy_base += pr[i].lanes; 4608 } 4609 } else if(!sal_strncasecmp(s, "8x50G", MAX(strlen(s), 5))) { 4610 req_cnt = 8; 4611 for (i = 0; i < req_cnt; i++) { 4612 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4613 pr[i].port = pi[pm].ports[i]; 4614 } 4615 pr[i].physical_port = phy_base; 4616 pr[i].speed = 50000; 4617 pr[i].lanes = 1; 4618 pr[i].encap = encap; 4619 pr[i].fec_type = bcmPortPhyFecRs544; 4620 pr[i].phy_lane_config = -1; 4621 pr[i].link_training = 0; 4622 phy_base += pr[i].lanes; 4623 } 4624 } else if(!sal_strncasecmp(s, "8x25G", MAX(strlen(s), 5))) { 4625 req_cnt = 8; 4626 for (i = 0; i < req_cnt; i++) { 4627 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4628 pr[i].port = pi[pm].ports[i]; 4629 } 4630 pr[i].physical_port = phy_base; 4631 pr[i].speed = 25000; 4632 pr[i].lanes = 1; 4633 pr[i].encap = encap; 4634 pr[i].fec_type = bcmPortPhyFecNone; 4635 pr[i].phy_lane_config = -1; 4636 pr[i].link_training = 0; 4637 phy_base += pr[i].lanes; 4638 } 4639 } else if(!sal_strncasecmp(s, "8x10G", MAX(strlen(s), 5))) { 4640 req_cnt = 8; 4641 for (i = 0; i < req_cnt; i++) { 4642 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4643 pr[i].port = pi[pm].ports[i]; 4644 } 4645 pr[i].physical_port = phy_base; 4646 pr[i].speed = 10000; 4647 pr[i].lanes = 1; 4648 pr[i].encap = encap; 4649 pr[i].fec_type = bcmPortPhyFecNone; 4650 pr[i].phy_lane_config = -1; 4651 pr[i].link_training = 0; 4652 phy_base += pr[i].lanes; 4653 } 4654 } else if (!sal_strncasecmp(s, "None", MAX(strlen(s), 4))) { 4655 /* Clear ports on a Port Macro, No add entries */ 4656 req_cnt = 0; 4657 } else { 4658 cli_out("Flexport: Error: Unsupported mode %s on pm%d.\n", 4659 s, pm); 4660 return CMD_FAIL; 4661 } 4662 4663 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4664 if (pi[pm].port_cnt != req_cnt) { 4665 cli_out("Flexport: Error: pm%d %s requires %d ports.\n", 4666 pm, s, req_cnt); 4667 return CMD_FAIL; 4668 } 4669 } else { 4670 pi[pm].port_cnt = req_cnt; 4671 if (req_cnt != 0) { 4672 *auto_assign |= 1; 4673 } 4674 } 4675 f->add_cnt += req_cnt; 4676 } 4677 4678 return CMD_OK; 4679 } 4680 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4681 4682 static cmd_result_t 4683 flexport_parse_pm_mode(int unit, flexport_info_t *f, int *auto_assign) 4684 { 4685 flexport_pm_info_t *pi = f->pm; 4686 bcm_port_resource_t *pr; 4687 int pm, phy_base, phy_port, port, i, hg_speed; 4688 int req_cnt; 4689 char *s; 4690 bcm_port_encap_t encap; 4691 int max_ports = 0; 4692 4693 #ifdef BCM_TOMAHAWK3_SUPPORT 4694 if (SOC_IS_TOMAHAWK3(unit)) { 4695 return th3_flexport_parse_pm_mode(unit, f, auto_assign); 4696 } 4697 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4698 4699 flexport_max_ports_per_pblk_get(unit, &max_ports); 4700 4701 f->del_cnt = 0; 4702 for (pm = 0; pm < PM_NUM(unit); pm++) { 4703 if (pi[pm].pm_str == NULL) { 4704 continue; 4705 } 4706 s = pi[pm].pm_str; 4707 pr = pi[pm].pr; 4708 phy_base = pm * max_ports + 1; 4709 for(i = 0; i < max_ports; i++) { 4710 phy_port = phy_base + i; 4711 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 4712 if (port != -1) { 4713 f->del_cnt ++; 4714 } 4715 } 4716 4717 /* Add entries info */ 4718 if (sal_strstr(s, "HG") || sal_strstr(s, "hg")) { 4719 encap = BCM_PORT_ENCAP_HIGIG2; 4720 } else { 4721 encap = BCM_PORT_ENCAP_IEEE; 4722 } 4723 4724 if (sal_strstr(s, "106") || sal_strstr(s, "53") || 4725 sal_strstr(s, "42") || sal_strstr(s, "27") || 4726 sal_strstr(s, "21") || sal_strstr(s, "11")) { 4727 hg_speed = 1; 4728 } else { 4729 hg_speed = 0; 4730 } 4731 4732 if (!sal_strncasecmp(s, "1x100G", MAX(strlen(s), 6)) || 4733 !sal_strncasecmp(s, "1xHG[106]", MAX(strlen(s), 9)) || 4734 !sal_strncasecmp(s, "1xHG[100]", MAX(strlen(s), 9))) { 4735 req_cnt = 1; 4736 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4737 pr[0].port = pi[pm].ports[0]; 4738 } 4739 pr[0].physical_port = phy_base; 4740 pr[0].speed = hg_speed ? 106000 : 100000; 4741 pr[0].lanes = 4; 4742 pr[0].encap = encap; 4743 } else if(!sal_strncasecmp(s, "1x40G", MAX(strlen(s), 5)) || 4744 !sal_strncasecmp(s, "1xHG[42]", MAX(strlen(s), 8)) || 4745 !sal_strncasecmp(s, "1xHG[40]", MAX(strlen(s), 8))) { 4746 req_cnt = 1; 4747 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4748 pr[0].port = pi[pm].ports[0]; 4749 } 4750 pr[0].physical_port = phy_base; 4751 pr[0].speed = hg_speed ? 42000 : 40000; 4752 pr[0].lanes = 4; 4753 pr[0].encap = encap; 4754 } else if(!sal_strncasecmp(s, "2x50G", MAX(strlen(s), 5)) || 4755 !sal_strncasecmp(s, "2xHG[53]", MAX(strlen(s), 8)) || 4756 !sal_strncasecmp(s, "2xHG[50]", MAX(strlen(s), 8))) { 4757 req_cnt = 2; 4758 for (i = 0; i < req_cnt; i++) { 4759 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4760 pr[i].port = pi[pm].ports[i]; 4761 } 4762 pr[i].physical_port = phy_base; 4763 pr[i].speed = hg_speed ? 53000 : 50000; 4764 pr[i].lanes = 2; 4765 pr[i].encap = encap; 4766 phy_base += pr[i].lanes; 4767 } 4768 } else if(!sal_strncasecmp(s, "2x40G", MAX(strlen(s), 5)) || 4769 !sal_strncasecmp(s, "2xHG[42]", MAX(strlen(s), 8)) || 4770 !sal_strncasecmp(s, "2xHG[40]", MAX(strlen(s), 8))) { 4771 req_cnt = 2; 4772 for (i = 0; i < req_cnt; i++) { 4773 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4774 pr[i].port = pi[pm].ports[i]; 4775 } 4776 pr[i].physical_port = phy_base; 4777 pr[i].speed = hg_speed ? 42000 : 40000; 4778 pr[i].lanes = 2; 4779 pr[i].encap = encap; 4780 phy_base += pr[i].lanes; 4781 } 4782 } else if(!sal_strncasecmp(s, "2x20G", MAX(strlen(s), 5)) || 4783 !sal_strncasecmp(s, "2xHG[21]", MAX(strlen(s), 8)) || 4784 !sal_strncasecmp(s, "2xHG[20]", MAX(strlen(s), 8))) { 4785 req_cnt = 2; 4786 for (i = 0; i < req_cnt; i++) { 4787 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4788 pr[i].port = pi[pm].ports[i]; 4789 } 4790 pr[i].physical_port = phy_base; 4791 pr[i].speed = hg_speed ? 21000 : 20000; 4792 pr[i].lanes = 2; 4793 pr[i].encap = encap; 4794 phy_base += pr[i].lanes; 4795 } 4796 } else if(!sal_strncasecmp(s, "1x40G+1x20G", MAX(strlen(s), 11)) || 4797 !sal_strncasecmp(s, "1xHG[42]+1xHG[21]", MAX(strlen(s), 17)) || 4798 !sal_strncasecmp(s, "1xHG[40]+1xHG[20]", MAX(strlen(s), 17))) { 4799 req_cnt = 2; 4800 for (i = 0; i < req_cnt; i++) { 4801 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4802 pr[i].port = pi[pm].ports[i]; 4803 } 4804 pr[i].physical_port = phy_base; 4805 if (i == 0) { 4806 pr[i].speed = hg_speed ? 42000 : 40000; 4807 } else { 4808 pr[i].speed = hg_speed ? 21000 : 20000; 4809 } 4810 pr[i].lanes = 2; 4811 pr[i].encap = encap; 4812 phy_base += pr[i].lanes; 4813 } 4814 } else if(!sal_strncasecmp(s, "1x20G+1x40G", MAX(strlen(s), 11)) || 4815 !sal_strncasecmp(s, "1xHG[21]+1xHG[42]", MAX(strlen(s), 17)) || 4816 !sal_strncasecmp(s, "1xHG[20]+1xHG[40]", MAX(strlen(s), 17))) { 4817 req_cnt = 2; 4818 for (i = 0; i < req_cnt; i++) { 4819 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4820 pr[i].port = pi[pm].ports[i]; 4821 } 4822 pr[i].physical_port = phy_base; 4823 if (i == 0) { 4824 pr[i].speed = hg_speed ? 21000 : 20000; 4825 } else { 4826 pr[i].speed = hg_speed ? 42000 : 40000; 4827 } 4828 pr[i].lanes = 2; 4829 pr[i].encap = encap; 4830 phy_base += pr[i].lanes; 4831 } 4832 } else if(!sal_strncasecmp(s, "1x25G+1x50G", MAX(strlen(s), 11)) || 4833 !sal_strncasecmp(s, "1xHG[27]+1xHG[53]", MAX(strlen(s), 17)) || 4834 !sal_strncasecmp(s, "1xHG[25]+1xHG[50]", MAX(strlen(s), 17))) { 4835 req_cnt = 2; 4836 for (i = 0; i < req_cnt; i++) { 4837 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4838 pr[i].port = pi[pm].ports[i]; 4839 } 4840 pr[i].physical_port = phy_base; 4841 if (i == 0) { 4842 pr[i].speed = hg_speed ? 27000 : 25000; 4843 pr[i].lanes = 1; 4844 pr[i].flags |= BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR; 4845 phy_base += 2; 4846 } else { 4847 pr[i].speed = hg_speed ? 53000 : 50000; 4848 pr[i].lanes = 2; 4849 phy_base += pr[i].lanes; 4850 } 4851 pr[i].encap = encap; 4852 } 4853 } else if(!sal_strncasecmp(s, "1x50G+1x25G", MAX(strlen(s), 11)) || 4854 !sal_strncasecmp(s, "1xHG[53]+1xHG[27]", MAX(strlen(s), 17)) || 4855 !sal_strncasecmp(s, "1xHG[50]+1xHG[25]", MAX(strlen(s), 17))) { 4856 req_cnt = 2; 4857 for (i = 0; i < req_cnt; i++) { 4858 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4859 pr[i].port = pi[pm].ports[i]; 4860 } 4861 pr[i].physical_port = phy_base; 4862 if (i == 0) { 4863 pr[i].speed = hg_speed ? 53000 : 50000; 4864 pr[i].lanes = 2; 4865 phy_base += pr[i].lanes; 4866 } else { 4867 pr[i].speed = hg_speed ? 27000 : 25000; 4868 pr[i].lanes = 1; 4869 pr[i].flags |= BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR; 4870 phy_base += 2; 4871 } 4872 pr[i].encap = encap; 4873 } 4874 }else if(!sal_strncasecmp(s, "2x25G", MAX(strlen(s), 5)) || 4875 !sal_strncasecmp(s, "2xHG[27]", MAX(strlen(s), 8)) || 4876 !sal_strncasecmp(s, "2xHG[25]", MAX(strlen(s), 8))) { 4877 req_cnt = 2; 4878 for (i = 0; i < req_cnt; i++) { 4879 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4880 pr[i].port = pi[pm].ports[i]; 4881 } 4882 pr[i].physical_port = phy_base; 4883 pr[i].speed = hg_speed ? 27000 : 25000; 4884 pr[i].lanes = 1; 4885 pr[i].flags |= BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR; 4886 phy_base += 2; 4887 pr[i].encap = encap; 4888 } 4889 }else if(!sal_strncasecmp(s, "1x50G+2x25G", MAX(strlen(s), 11)) || 4890 !sal_strncasecmp(s, "1xHG[53]+2xHG[27]", MAX(strlen(s), 17)) || 4891 !sal_strncasecmp(s, "1xHG[50]+2xHG[25]", MAX(strlen(s), 17))) { 4892 req_cnt = 3; 4893 for (i = 0; i < req_cnt; i++) { 4894 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4895 pr[i].port = pi[pm].ports[i]; 4896 } 4897 pr[i].physical_port = phy_base; 4898 if (i == 0) { 4899 pr[i].speed = hg_speed ? 53000 : 50000; 4900 pr[i].lanes = 2; 4901 } else { 4902 pr[i].speed = hg_speed ? 27000 : 25000; 4903 pr[i].lanes = 1; 4904 } 4905 pr[i].encap = encap; 4906 phy_base += pr[i].lanes; 4907 } 4908 } else if(!sal_strncasecmp(s, "2x25G+1x50G", MAX(strlen(s), 11)) || 4909 !sal_strncasecmp(s, "2xHG[27]+1xHG[53]", MAX(strlen(s), 17)) || 4910 !sal_strncasecmp(s, "2xHG[25]+1xHG[50]", MAX(strlen(s), 17))) { 4911 req_cnt = 3; 4912 for (i = 0; i < req_cnt; i++) { 4913 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4914 pr[i].port = pi[pm].ports[i]; 4915 } 4916 pr[i].physical_port = phy_base; 4917 if (i == 2) { 4918 pr[i].speed = hg_speed ? 53000 : 50000; 4919 pr[i].lanes = 2; 4920 } else { 4921 pr[i].speed = hg_speed ? 27000 : 25000; 4922 pr[i].lanes = 1; 4923 } 4924 pr[i].encap = encap; 4925 phy_base += pr[i].lanes; 4926 } 4927 } else if(!sal_strncasecmp(s, "1x40G+2x10G", MAX(strlen(s), 11)) || 4928 !sal_strncasecmp(s, "1xHG[42]+2xHG[11]", MAX(strlen(s), 17)) || 4929 !sal_strncasecmp(s, "1xHG[40]+2xHG[10]", MAX(strlen(s), 17))) { 4930 req_cnt = 3; 4931 for (i = 0; i < req_cnt; i++) { 4932 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4933 pr[i].port = pi[pm].ports[i]; 4934 } 4935 pr[i].physical_port = phy_base; 4936 if (i == 0) { 4937 pr[i].speed = hg_speed ? 42000 : 40000; 4938 pr[i].lanes = 2; 4939 } else { 4940 pr[i].speed = hg_speed ? 11000 : 10000; 4941 pr[i].lanes = 1; 4942 } 4943 pr[i].encap = encap; 4944 phy_base += pr[i].lanes; 4945 } 4946 } else if(!sal_strncasecmp(s, "2x10G+1x40G", MAX(strlen(s), 11)) || 4947 !sal_strncasecmp(s, "2xHG[11]+1xHG[42]", MAX(strlen(s), 17)) || 4948 !sal_strncasecmp(s, "2xHG[10]+1xHG[40]", MAX(strlen(s), 17))) { 4949 req_cnt = 3; 4950 for (i = 0; i < req_cnt; i++) { 4951 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4952 pr[i].port = pi[pm].ports[i]; 4953 } 4954 pr[i].physical_port = phy_base; 4955 if (i == 2) { 4956 pr[i].speed = hg_speed ? 42000 : 40000; 4957 pr[i].lanes = 2; 4958 } else { 4959 pr[i].speed = hg_speed ? 11000 : 10000; 4960 pr[i].lanes = 1; 4961 } 4962 pr[i].encap = encap; 4963 phy_base += pr[i].lanes; 4964 } 4965 } else if(!sal_strncasecmp(s, "1x20G+2x10G", MAX(strlen(s), 11)) || 4966 !sal_strncasecmp(s, "1xHG[21]+2xHG[11]", MAX(strlen(s), 17)) || 4967 !sal_strncasecmp(s, "1xHG[20]+2xHG[10]", MAX(strlen(s), 17))) { 4968 req_cnt = 3; 4969 for (i = 0; i < req_cnt; i++) { 4970 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4971 pr[i].port = pi[pm].ports[i]; 4972 } 4973 pr[i].physical_port = phy_base; 4974 if (i == 0) { 4975 pr[i].speed = hg_speed ? 21000 : 20000; 4976 pr[i].lanes = 2; 4977 } else { 4978 pr[i].speed = hg_speed ? 11000 : 10000; 4979 pr[i].lanes = 1; 4980 } 4981 pr[i].encap = encap; 4982 phy_base += pr[i].lanes; 4983 } 4984 } else if(!sal_strncasecmp(s, "2x10G+1x20G", MAX(strlen(s), 11)) || 4985 !sal_strncasecmp(s, "2xHG[11]+1xHG[21]", MAX(strlen(s), 17)) || 4986 !sal_strncasecmp(s, "2xHG[10]+1xHG[20]", MAX(strlen(s), 17))) { 4987 req_cnt = 3; 4988 for (i = 0; i < req_cnt; i++) { 4989 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 4990 pr[i].port = pi[pm].ports[i]; 4991 } 4992 pr[i].physical_port = phy_base; 4993 if (i == 2) { 4994 pr[i].speed = hg_speed ? 21000 : 20000; 4995 pr[i].lanes = 2; 4996 } else { 4997 pr[i].speed = hg_speed ? 11000 : 10000; 4998 pr[i].lanes = 1; 4999 } 5000 pr[i].encap = encap; 5001 phy_base += pr[i].lanes; 5002 } 5003 } else if(!sal_strncasecmp(s, "4x25G", MAX(strlen(s), 5)) || 5004 !sal_strncasecmp(s, "4xHG[27]", MAX(strlen(s), 8)) || 5005 !sal_strncasecmp(s, "4xHG[25]", MAX(strlen(s), 8))) { 5006 req_cnt = 4; 5007 for (i = 0; i < req_cnt; i++) { 5008 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5009 pr[i].port = pi[pm].ports[i]; 5010 } 5011 pr[i].physical_port = phy_base; 5012 pr[i].speed = hg_speed ? 27000 : 25000; 5013 pr[i].lanes = 1; 5014 pr[i].encap = encap; 5015 phy_base += pr[i].lanes; 5016 } 5017 } else if(!sal_strncasecmp(s, "4x10G", MAX(strlen(s), 5)) || 5018 !sal_strncasecmp(s, "4xHG[11]", MAX(strlen(s), 8)) || 5019 !sal_strncasecmp(s, "4xHG[10]", MAX(strlen(s), 8))) { 5020 req_cnt = 4; 5021 for (i = 0; i < req_cnt; i++) { 5022 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5023 pr[i].port = pi[pm].ports[i]; 5024 } 5025 pr[i].physical_port = phy_base; 5026 pr[i].speed = hg_speed ? 11000 : 10000; 5027 pr[i].lanes = 1; 5028 pr[i].encap = encap; 5029 phy_base += pr[i].lanes; 5030 } 5031 } else if(!sal_strncasecmp(s, "4x1G", MAX(strlen(s), 4))) { 5032 req_cnt = 4; 5033 for (i = 0; i < req_cnt; i++) { 5034 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5035 pr[i].port = pi[pm].ports[i]; 5036 } 5037 pr[i].physical_port = phy_base; 5038 pr[i].speed = 1000; 5039 pr[i].lanes = 1; 5040 pr[i].encap = encap; 5041 phy_base += pr[i].lanes; 5042 } 5043 } else if(!sal_strncasecmp(s, "4x5G", MAX(strlen(s), 4))) { 5044 req_cnt = 4; 5045 for (i = 0; i < req_cnt; i++) { 5046 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5047 pr[i].port = pi[pm].ports[i]; 5048 } 5049 pr[i].physical_port = phy_base; 5050 pr[i].speed = 5000; 5051 pr[i].lanes = 1; 5052 pr[i].encap = encap; 5053 phy_base += pr[i].lanes; 5054 } 5055 } else if(!sal_strncasecmp(s, "4x2.5G", MAX(strlen(s), 6))) { 5056 req_cnt = 4; 5057 for (i = 0; i < req_cnt; i++) { 5058 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5059 pr[i].port = pi[pm].ports[i]; 5060 } 5061 pr[i].physical_port = phy_base; 5062 pr[i].speed = 2500; 5063 pr[i].lanes = 1; 5064 pr[i].encap = encap; 5065 phy_base += pr[i].lanes; 5066 } 5067 } else if(!sal_strncasecmp(s, "None", MAX(strlen(s), 4))) { 5068 /* Clear ports on a Port Macro, No add entries */ 5069 req_cnt = 0; 5070 } else { 5071 cli_out("Flexport: Error: Unsupported mode %s on pm%d.\n", 5072 s, pm); 5073 return CMD_FAIL; 5074 } 5075 /* TD3 */ 5076 if (SOC_IS_TRIDENT3(unit)) { 5077 for (i = 0; i < req_cnt; i++) { 5078 pr[i].port = pr[i].physical_port > 64 ? (2 + pr[i].physical_port) : pr[i].physical_port; 5079 } 5080 pi[pm].flags |= FLXP_F_PORT_ASSIGNED; 5081 pi[pm].port_cnt = req_cnt; 5082 } 5083 5084 if (pi[pm].flags & FLXP_F_PORT_ASSIGNED) { 5085 if (pi[pm].port_cnt != req_cnt) { 5086 cli_out("Flexport: Error: pm%d %s requires %d ports.\n", 5087 pm, s, req_cnt); 5088 return CMD_FAIL; 5089 } 5090 } else { 5091 pi[pm].port_cnt = req_cnt; 5092 if (req_cnt != 0) { 5093 *auto_assign |= 1; 5094 } 5095 } 5096 f->add_cnt += req_cnt; 5097 } 5098 5099 return CMD_OK; 5100 } 5101 5102 static cmd_result_t 5103 flexport_port_assign(int unit, flexport_info_t *f) 5104 { 5105 bcm_pbmp_t pipe_pbmp[SOC_MAX_NUM_PIPES]; /* Free-port pool for each pipe */ 5106 int i, pm, port, phy_base, phy_port, pipe, cnt, pms_per_pipe; 5107 int ffport[SOC_MAX_NUM_PIPES]; /* First free port in each pipe */ 5108 int max_ports = 0; 5109 typedef struct pbs_s { 5110 int start_port; 5111 int end_port; 5112 } pbs_t; 5113 5114 /* General port boundary for each pipe */ 5115 STATIC pbs_t pbs_tomahawk2[] = { 5116 { 1, 32 }, 5117 { 34, 65 }, 5118 { 68, 99 }, 5119 { 102, 133 } 5120 }; 5121 STATIC pbs_t pbs_apache[] = { 5122 { 1, 72 } 5123 }; 5124 STATIC pbs_t pbs_helix5[] = { 5125 { 1, 69 } 5126 }; 5127 STATIC pbs_t pbs_maverick2[] = { 5128 { 1, 64 } 5129 }; 5130 STATIC pbs_t pbs_tomahawk3[] = { 5131 { 1, 18 }, 5132 { 20, 37 }, 5133 { 40, 57 }, 5134 { 60, 77 }, 5135 { 80, 97 }, 5136 { 100, 117 }, 5137 { 120, 137 }, 5138 { 140, 157 } 5139 }; 5140 STATIC pbs_t *pbs; 5141 if (SOC_IS_APACHE(unit)) { 5142 pbs = pbs_apache; 5143 } else if (SOC_IS_TOMAHAWK2(unit)) { 5144 pbs = pbs_tomahawk2; 5145 } else if (SOC_IS_HELIX5(unit)) { 5146 pbs = pbs_helix5; 5147 } else if (SOC_IS_MAVERICK2(unit)) { 5148 pbs = pbs_maverick2; 5149 } else if (SOC_IS_TOMAHAWK3(unit)) { 5150 pbs = pbs_tomahawk3; 5151 } else { 5152 return CMD_NOTIMPL; 5153 } 5154 pms_per_pipe = PM_NUM(unit)/NUM_PIPE(unit); 5155 5156 flexport_max_ports_per_pblk_get(unit, &max_ports); 5157 5158 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 5159 SOC_PBMP_CLEAR(pipe_pbmp[pipe]); 5160 if (SOC_IS_APACHE(unit)) { 5161 SOC_PBMP_PORTS_RANGE_ADD(pipe_pbmp[pipe], pbs[pipe].start_port, 72); 5162 } else if (SOC_IS_HELIX5(unit)) { 5163 SOC_PBMP_PORTS_RANGE_ADD(pipe_pbmp[pipe], pbs[pipe].start_port, 69); 5164 } else if (SOC_IS_MAVERICK2(unit)) { 5165 SOC_PBMP_PORTS_RANGE_ADD(pipe_pbmp[pipe], pbs[pipe].start_port, 64); 5166 } else { 5167 SOC_PBMP_PORTS_RANGE_ADD(pipe_pbmp[pipe], pbs[pipe].start_port, 32); 5168 } 5169 ffport[pipe] = pbs[pipe].start_port; 5170 } 5171 5172 for (i = 0; i < NUM_PIPE(unit); i++) { 5173 SOC_PBMP_REMOVE(pipe_pbmp[i], SOC_INFO(unit).pipe_pbm[i]); 5174 } 5175 5176 /* Existing ports need to be removed first during flexport, 5177 * thus, add these removed ports to free-port pool */ 5178 for (pm = 0; pm < PM_NUM(unit); pm++) { 5179 if (f->pm[pm].pm_str == NULL) { 5180 continue; 5181 } 5182 phy_base = pm * max_ports + 1; 5183 pipe = pm/pms_per_pipe; 5184 for(i = 0; i < max_ports; i++) { 5185 phy_port = phy_base + i; 5186 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 5187 if (port != -1) { 5188 SOC_PBMP_PORT_ADD(pipe_pbmp[pipe], port); 5189 } 5190 } 5191 } 5192 5193 /* Remove ports that specified by CLI from free-port pool */ 5194 for (pm = 0; pm < PM_NUM(unit); pm++) { 5195 if (f->pm[pm].pm_str == NULL || 5196 !(f->pm[pm].flags & FLXP_F_PORT_ASSIGNED)) { 5197 continue; 5198 } 5199 pipe = pm/pms_per_pipe; 5200 for (i = 0; i < f->pm[pm].port_cnt; i++) { 5201 SOC_PBMP_PORT_REMOVE(pipe_pbmp[pipe], f->pm[pm].ports[i]); 5202 } 5203 } 5204 5205 /* Keep the same logical port if possible */ 5206 for (pm = 0; pm < PM_NUM(unit); pm++) { 5207 if ((f->pm[pm].pm_str == NULL) || 5208 (f->pm[pm].port_cnt == 0) || /* mode is "None" */ 5209 (f->pm[pm].flags & FLXP_F_PORT_ASSIGNED)) { 5210 continue; 5211 } 5212 pipe = pm/pms_per_pipe; 5213 cnt = 0; 5214 for (i = 0; i < f->pm[pm].port_cnt; i++ ) { 5215 phy_port = f->pm[pm].pr[i].physical_port; 5216 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 5217 if (port != -1 && 5218 SOC_PBMP_MEMBER(pipe_pbmp[pipe], port) && 5219 SOC_INFO(unit).port_num_lanes[port] == f->pm[pm].pr[i].lanes) { 5220 f->pm[pm].pr[i].port = port; 5221 SOC_PBMP_PORT_REMOVE(pipe_pbmp[pipe], port); 5222 cnt++; 5223 } else { 5224 f->pm[pm].pr[i].port = -1; 5225 } 5226 } 5227 /* Set FLXP_F_PORT_ASSIGNED if all ports in the port macro keep using 5228 * previous port number. */ 5229 if (cnt == f->pm[pm].port_cnt) { 5230 f->pm[pm].flags |= FLXP_F_PORT_ASSIGNED; 5231 } 5232 } 5233 5234 /* Assign port from free-port pool */ 5235 for (pm = 0; pm < PM_NUM(unit); pm++) { 5236 if ((f->pm[pm].pm_str == NULL) || 5237 (f->pm[pm].port_cnt == 0) || /* mode is "None" */ 5238 (f->pm[pm].flags & FLXP_F_PORT_ASSIGNED)) { 5239 continue; 5240 } 5241 pipe = pm/pms_per_pipe; 5242 for (i = 0; i < f->pm[pm].port_cnt; i++ ) { 5243 if ( f->pm[pm].pr[i].port != -1) { 5244 continue; 5245 } 5246 for (port = ffport[pipe]; port <= pbs[pipe].end_port; 5247 port++) { 5248 if (SOC_PBMP_MEMBER(pipe_pbmp[pipe], port)) { 5249 f->pm[pm].pr[i].port = port; 5250 SOC_PBMP_PORT_REMOVE(pipe_pbmp[pm/pms_per_pipe], port); 5251 break; 5252 } 5253 } 5254 if (port > pbs[pipe].end_port) { 5255 cli_out("No free port."); 5256 return CMD_FAIL; 5257 } else { 5258 ffport[pipe] = port + 1;; 5259 } 5260 f->pm[pm].flags |= FLXP_F_PORT_ASSIGNED; 5261 } 5262 } 5263 return CMD_OK; 5264 } 5265 5266 static cmd_result_t 5267 flexport_diag(int unit, flexport_info_t *f) 5268 { 5269 bcm_port_resource_t *pr; 5270 int phy_port, phy_base, pm, port ; 5271 int nports, pr_idx, len, i; 5272 cmd_result_t retCode = CMD_OK; 5273 int rv = BCM_E_NONE; 5274 int max_ports = 0; 5275 5276 nports = f->del_cnt + f->add_cnt; 5277 if (nports > MAX_NUM_FLEXPORTS) { 5278 cli_out("Flexport: Entry num exceeds the Maxium(256).\n"); 5279 return CMD_FAIL; 5280 } 5281 5282 pr = sal_alloc(MAX_NUM_FLEXPORTS * sizeof(bcm_port_resource_t), 5283 "PortResource"); 5284 if (pr == NULL) { 5285 cli_out("Insufficient memory.\n"); 5286 return CMD_FAIL; 5287 } 5288 sal_memset(pr, 0, MAX_NUM_FLEXPORTS * sizeof(bcm_port_resource_t)); 5289 5290 flexport_max_ports_per_pblk_get(unit, &max_ports); 5291 5292 pr_idx = 0; 5293 5294 /* Del entries */ 5295 for (pm = 0; pm < PM_NUM(unit); pm++) { 5296 if (f->pm[pm].pm_str == NULL) { 5297 continue; 5298 } 5299 phy_base = (pm * max_ports) + 1; 5300 for(i = 0; i < max_ports; i++) { 5301 phy_port = phy_base + i; 5302 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 5303 if (port != -1) { 5304 if (SOC_IS_TRIDENT3(unit)) { 5305 if ((phy_port == 128) && SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), 130)) { 5306 nports--; 5307 continue; 5308 } 5309 } 5310 pr[pr_idx].port = port; 5311 pr[pr_idx].physical_port = -1; 5312 pr_idx++; 5313 } 5314 } 5315 } 5316 5317 /* Add entries */ 5318 for (pm = 0; pm < PM_NUM(unit); pm++) { 5319 if (f->pm[pm].pm_str == NULL || 5320 !(f->pm[pm].flags & FLXP_F_PORT_ASSIGNED)) { 5321 continue; 5322 } 5323 len = sizeof(bcm_port_resource_t) * f->pm[pm].port_cnt; 5324 sal_memcpy(&pr[pr_idx], f->pm[pm].pr, len); 5325 pr_idx += f->pm[pm].port_cnt; 5326 } 5327 5328 if (pr_idx != nports){ 5329 cli_out("Flexport: Unmatched entry num and nports.\n"); 5330 sal_free(pr); 5331 return CMD_FAIL; 5332 } 5333 5334 LOG_INFO(BSL_LS_APPL_TESTS, 5335 (BSL_META_U(unit, "\nCalling bcm_port_resource_multi:"))); 5336 for (i = 0; i < nports; i ++) { 5337 LOG_INFO(BSL_LS_APPL_TESTS, 5338 (BSL_META_U(unit, "\nresource[%0d]: physical_port = %0d"), 5339 i, pr[i].physical_port)); 5340 LOG_INFO(BSL_LS_APPL_TESTS, 5341 (BSL_META_U(unit, "\nresource[%0d]: port = %0d"), 5342 i, pr[i].port)); 5343 LOG_INFO(BSL_LS_APPL_TESTS, 5344 (BSL_META_U(unit, "\nresource[%0d]: speed = %0d"), 5345 i, pr[i].speed)); 5346 LOG_INFO(BSL_LS_APPL_TESTS, 5347 (BSL_META_U(unit, "\nresource[%0d]: lanes = %0d"), 5348 i, pr[i].lanes)); 5349 LOG_INFO(BSL_LS_APPL_TESTS, 5350 (BSL_META_U(unit, "\nresource[%0d]: encap = %0d"), 5351 i, pr[i].encap)); 5352 } 5353 5354 rv = bcm_port_resource_multi_set(unit, nports, pr); 5355 if (BCM_FAILURE(rv)) { 5356 retCode = CMD_FAIL; 5357 } else { 5358 retCode = CMD_OK; 5359 } 5360 5361 sal_free(pr); 5362 5363 return retCode; 5364 } 5365 5366 cmd_result_t 5367 cmd_if_flexport(int unit, args_t *a) 5368 { 5369 flexport_info_t *flexinfo; 5370 char *arg; 5371 parse_table_t pt; 5372 cmd_result_t retCode = CMD_OK; 5373 int i, auto_assign; 5374 uint32 seen, parsed; 5375 char *pm_str[] = { 5376 "PM0", "PM1", "PM2", "PM3", "PM4", "PM5", "PM6", "PM7", 5377 "PM8", "PM9", "PM10", "PM11", "PM12", "PM13", "PM14", "PM15", 5378 "PM16", "PM17", "PM18", "PM19", "PM20", "PM21", "PM22", "PM23", 5379 "PM24", "PM25", "PM26", "PM27", "PM28", "PM29", "PM30", "PM31", 5380 "PM32", "PM33", "PM34", "PM35", "PM36", "PM37", "PM38", "PM39", 5381 "PM40", "PM41", "PM42", "PM43", "PM44", "PM45", "PM46", "PM47", 5382 "PM48", "PM49", "PM50", "PM51", "PM52", "PM53", "PM54", "PM55", 5383 "PM56", "PM57", "PM58", "PM59", "PM60", "PM61", "PM62", "PM63" 5384 }; 5385 5386 if (!sh_check_attached(ARG_CMD(a), unit)) { 5387 return CMD_FAIL; 5388 } 5389 5390 if ((arg = ARG_CUR(a)) == NULL) { 5391 return (CMD_USAGE); 5392 } 5393 5394 flexinfo = sal_alloc(sizeof(flexport_info_t), "if_flexport"); 5395 if (flexinfo == NULL) { 5396 cli_out("Insufficient memory.\n"); 5397 return CMD_FAIL; 5398 } 5399 sal_memset(flexinfo, 0, sizeof(flexport_info_t)); 5400 5401 parse_table_init(unit, &pt); 5402 for (i = 0; i < PM_NUM(unit); i++) { 5403 parse_table_add(&pt, pm_str[i], PQ_STRING|PQ_DFL|PQ_NO_EQ_OPT, 0, 5404 &flexinfo->pm[i].pm_str, NULL); 5405 } 5406 5407 if (parse_arg_eq(a, &pt) < 0) { 5408 parse_arg_eq_done(&pt); 5409 sal_free(flexinfo); 5410 return CMD_FAIL; 5411 } 5412 5413 seen = 0; 5414 parsed = 0; 5415 for (i = 0; i < pt.pt_cnt; i++) { 5416 if (pt.pt_entries[i].pq_type & PQ_SEEN) { 5417 flexinfo->pm[i].flags |= FLXP_F_SEEN; 5418 seen = 1; 5419 } 5420 5421 if (pt.pt_entries[i].pq_type & PQ_PARSED) { 5422 flexinfo->pm[i].flags |= FLXP_F_PARSED; 5423 parsed = 1; 5424 } 5425 } 5426 5427 if (seen && parsed) { 5428 cli_out("%s: Cannot get and set port resources in one command\n", 5429 ARG_CMD(a)); 5430 retCode = CMD_FAIL; 5431 } else if (seen) { /* Show the port resource info for specified pm */ 5432 retCode = flexport_show(unit, flexinfo); 5433 } else if (parsed) { 5434 auto_assign = 0; 5435 retCode = flexport_parse_portlist(unit, flexinfo->pm); 5436 if (retCode == CMD_OK) { 5437 retCode = flexport_parse_pm_mode(unit, flexinfo, &auto_assign); 5438 } 5439 if (retCode == CMD_OK && auto_assign) { 5440 retCode = flexport_port_assign(unit, flexinfo); 5441 } 5442 if (retCode == CMD_OK) { 5443 retCode = flexport_diag(unit, flexinfo); 5444 } 5445 } 5446 parse_arg_eq_done(&pt); 5447 sal_free(flexinfo); 5448 return retCode; 5449 } 5450 5451 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */