openbcm

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

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 */