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 (292474B)


      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:     XGS5 Port common driver.
      9  *
     10  * Notes:
     11  *      More than likely only new Port APIs are found in
     12  *      this function driver due to a huge amount of legacy code
     13  *      that were implemented before this model.
     14  */
     15 
     16 #include <shared/bsl.h>
     17 #include <soc/defs.h>
     18 #include <soc/drv.h>
     19 
     20 #include <bcm/error.h>
     21 #include <bcm/switch.h>
     22 
     23 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT
     24 #include <bcm_int/esw/xgs5.h>
     25 #include <bcm_int/esw/port.h>
     26 #include <bcm_int/esw/portctrl.h>
     27 #include <bcm_int/esw_dispatch.h>
     28 #include <bcm_int/common/multicast.h>
     29 #include <bcm_int/esw/trunk.h>
     30 #include <bcm_int/esw/stack.h>
     31 #include <bcm_int/esw/mirror.h>
     32 #include <bcm_int/esw/firebolt.h>
     33 #include <bcm_int/esw/triumph.h>
     34 #include <bcm_int/esw/triumph2.h>
     35 #include <bcm_int/esw/trident.h>
     36 #include <bcm_int/esw/trx.h>
     37 #include <bcm_int/esw/xgs3.h>
     38 #include <bcm_int/esw/stat.h>
     39 #include <bcm_int/esw/link.h>
     40 #include <bcm/port.h>
     41 
     42 #include <soc/counter.h>
     43 #include <soc/esw/portctrl.h>
     44 #if defined(BCM_TRIDENT3_SUPPORT)
     45 #include <soc/trident3.h>
     46 #endif /* BCM_TRIDENT3_SUPPORT */
     47 #if defined(BCM_HELIX5_SUPPORT)
     48 #include <soc/helix5.h>
     49 #endif /* BCM_HELIX5_SUPPORT */
     50 #if defined(BCM_TOMAHAWK2_SUPPORT)
     51 #include <soc/tomahawk2.h>
     52 #endif /* BCM_TOMAHAWK2_SUPPORT */
     53 
     54 #if defined(BCM_TOMAHAWK3_SUPPORT)
     55 #include <soc/tomahawk3.h>
     56 #endif /* BCM_TOMAHAWK3_SUPPORT */
     57 
     58 
     59 #undef DSCP_CODE_POINT_CNT
     60 #define DSCP_CODE_POINT_CNT 64
     61 
     62 /* Checks for 'null' argument */
     63 #define PARAM_NULL_CHECK(_arg)  \
     64     if ((_arg) == NULL) {       \
     65         return BCM_E_PARAM;     \
     66     }
     67 
     68 typedef struct bcmi_xgs5_port_resource_bmp_s {
     69 
     70     pbmp_t inact_pbm_log; /* Logical ports to be inactive via legacy API */
     71     pbmp_t act_pbm_log; /* Logical ports to be active via legacy API */
     72 
     73     pbmp_t del_pbm_log; /* Logical ports to be deleted in Flexport */
     74     pbmp_t add_pbm_log; /* Logical ports to be added in Flexport */
     75 
     76     /* Bitmap of local physical ports in each pipe that to be inactived/actived
     77      * during Flexport.
     78      * Global physical ports should be local_phy_port + pipe_offset
     79      */
     80     pbmp_t del_pbm_phy[SOC_MAX_NUM_PIPES];
     81     pbmp_t add_pbm_phy[SOC_MAX_NUM_PIPES];
     82 
     83     /* Port Macros to be inactived in Flexport */
     84     SHR_BITDCL  del_bmp_pm[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)];
     85     /* Port Macros to be actived in Flexport */
     86     SHR_BITDCL  add_bmp_pm[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)];
     87 } bcmi_xgs5_port_resource_bmp_t;
     88 
     89 /*
     90  * BCMI Port Driver
     91  */
     92 static bcmi_xgs5_port_drv_t  *bcmi_xgs5_port_drv[BCM_MAX_NUM_UNITS] = {0};
     93 
     94 #define BCMI_PORT_DRV(u_)             (bcmi_xgs5_port_drv[(u_)])
     95 #define BCMI_PORT_DRV_CALL(u_)        (bcmi_xgs5_port_drv[(u_)]->port_calls)
     96 #define BCMI_PORT_DRV_DEV_INFO(u_)    (bcmi_xgs5_port_drv[(u_)]->dev_info[(u_)])
     97 #define BCMI_PORT_DRV_PHY_INFO(u_, _p)    \
     98     (BCMI_PORT_DRV_DEV_INFO(u_)->phy_port_info[(_p)])
     99 
    100 #define BCMI_PORT_SCHEDULE_STATE_INIT_OP_ASF(_op)      \
    101     (_op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD |           \
    102             BCMI_XGS5_PORT_RESOURCE_OP_DEL |           \
    103             BCMI_XGS5_PORT_RESOURCE_OP_REMAP |         \
    104             BCMI_XGS5_PORT_RESOURCE_OP_LANES |         \
    105             BCMI_XGS5_PORT_RESOURCE_OP_SPEED |         \
    106             BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE |         \
    107             BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX |    \
    108             BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR))
    109 
    110 #define BCMI_PORT_SCHEDULE_STATE_INIT_OP_TDM(_op)      \
    111     (_op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD |           \
    112             BCMI_XGS5_PORT_RESOURCE_OP_DEL |           \
    113             BCMI_XGS5_PORT_RESOURCE_OP_REMAP |         \
    114             BCMI_XGS5_PORT_RESOURCE_OP_LANES |         \
    115             BCMI_XGS5_PORT_RESOURCE_OP_SPEED |         \
    116             BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE |         \
    117             BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX |    \
    118             BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR))
    119 
    120 /* Hardware definitions */
    121 static bcmi_xgs5_port_hw_defs_t  *bcmi_xgs5_port_hw_defs[BCM_MAX_NUM_UNITS] = {0};
    122 
    123 #define PORT_HW(u_)    (bcmi_xgs5_port_hw_defs[(u_)])
    124 
    125 #define PORT_REDIRECTION_HW_DEFS_EGR_PORT(u_)  \
    126     (bcmi_xgs5_port_hw_defs[(u_)]->egr_port)
    127 
    128 
    129 #define BCMI_MAX_STRENGTH_VALUE (0x3E)
    130 
    131 static char *bcmi_xgs5_port_attach_str[] = BCMI_XGS5_PORT_ATTACH_PHASES_MSG;
    132 static char *bcmi_xgs5_port_detach_str[] = BCMI_XGS5_PORT_DETACH_PHASES_MSG;
    133 
    134 /*
    135  * Function:
    136  *      bcmi_xgs5_port_addressable_local_get
    137  * Description:
    138  *      Validate that given port/gport parameter is an addressable
    139  *      local logical port and return local logical port in
    140  *      BCM port format (non-Gport).
    141  *      Logical port does not need to be defined (does not
    142  *      need to be a VALID port, only addressable).
    143  * Parameters:
    144  *      unit       - (IN) BCM device number
    145  *      port       - (IN) Port / Gport to validate
    146  *      local_port - (OUT) Port number if valid.
    147  * Return Value:
    148  *      BCM_E_NONE - Port OK
    149  *      BCM_E_INIT - Not initialized
    150  *      BCM_E_PORT - Port Invalid
    151  *
    152  * NOTE:
    153  *      This function only accepts those GPORT types that
    154  *      deal with logical BCM ports (i.e. MODPORT, LOCAL, etc.).
    155  *
    156  *      Also, unlike bcm_esw_port_local_get(), this routine only checks
    157  *      that the port number is within the valid port range.
    158  *      It does NOT check whether the port
    159  *      is a BCM valid port (i.e. a defined/configured port).
    160  *      This allows functions that requires port validation with
    161  *      a new logical port that has not been declared/configured
    162  *      in the system.
    163  */
    164 int
    165 bcmi_xgs5_port_addressable_local_get(int unit,
    166                                      bcm_port_t port, bcm_port_t *local_port)
    167 {
    168     bcm_module_t mod;
    169     bcm_trunk_t trunk_id;
    170     int id;
    171     int is_local;
    172 
    173     /*
    174      * A logical port can be:
    175      *   - Defined and active.
    176      *   - Defined and inactive (SOC property portmap with ':i' option).
    177      *   - Not defined.
    178      *
    179      * The following port definitions/words (i.e. functions, macro names)
    180      * are used in the SDK as follows:
    181      *   - VALID       :  The logical port is defined, it may be active or
    182      *                    inactive.
    183      *                    There IS a logical-to-physical port mapping.
    184      *
    185      *   - ADDRESSABLE :  The logical port number is within the valid
    186      *                    range.
    187      *                    The port may or may have not been defined
    188      *                    (i.e. there is NO logical-to-physical port mapping.)
    189      */
    190     if (BCM_GPORT_IS_SET(port)) {
    191         BCM_IF_ERROR_RETURN
    192             (_bcm_esw_gport_resolve(unit, port, &mod, local_port,
    193                                     &trunk_id, &id));
    194         if ((trunk_id != -1) || (id != -1)) {
    195             return BCM_E_PORT;
    196         }
    197 
    198         /* Check that port is local */
    199         BCM_IF_ERROR_RETURN
    200             (_bcm_esw_modid_is_local(unit, mod, &is_local));
    201 
    202         if (!is_local) {
    203             return BCM_E_PORT;
    204         }
    205     } else {
    206         *local_port = port;
    207     }
    208 
    209     /* Check that port is within valid logical port range */
    210     if (!SOC_PORT_ADDRESSABLE(unit, *local_port)) {
    211         return BCM_E_PORT;
    212     }
    213 
    214     return BCM_E_NONE;
    215 }
    216 
    217 /*
    218  * Function:
    219  *      _bcmi_xgs5_port_soc_info_ptype_update
    220  * Purpose:
    221  *      Update the SOC_INFO port type bitmaps and block information.
    222  * Parameters:
    223  *      unit                    - (IN) Unit number.
    224  *      port_schedule_state     - (IN) port_schedule_state
    225  *
    226  *
    227  * Returns:
    228  *      SOC_E_XXX
    229  * Notes:
    230  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
    231  *      locks are taken.
    232  */
    233 STATIC int
    234 _bcmi_xgs5_port_soc_info_ptype_update(int unit)
    235 {
    236     soc_info_t *si = &SOC_INFO(unit);
    237     int logic_port, phy_port, port_idx, max_port;
    238     int blk, bindex;
    239 
    240     /*
    241      * Update ptype information
    242      */
    243 #define RECONFIGURE_PORT_TYPE_INFO(ptype)                   \
    244     si->ptype.num = 0;                                      \
    245     si->ptype.min = si->ptype.max = -1;                     \
    246     PBMP_ITER(si->ptype.bitmap, logic_port) {               \
    247         si->port_offset[logic_port] = si->ptype.num;        \
    248         si->ptype.port[si->ptype.num++] = logic_port;       \
    249         if (si->ptype.min < 0) {                            \
    250             si->ptype.min = logic_port;                     \
    251         }                                                   \
    252         if (logic_port > si->ptype.max) {                   \
    253             si->ptype.max = logic_port;                     \
    254         }                                                   \
    255     }
    256 
    257     RECONFIGURE_PORT_TYPE_INFO(ge);
    258     RECONFIGURE_PORT_TYPE_INFO(xe);
    259     RECONFIGURE_PORT_TYPE_INFO(c);
    260     RECONFIGURE_PORT_TYPE_INFO(ce);
    261     RECONFIGURE_PORT_TYPE_INFO(cde);
    262     RECONFIGURE_PORT_TYPE_INFO(xl);
    263     RECONFIGURE_PORT_TYPE_INFO(cl);
    264     RECONFIGURE_PORT_TYPE_INFO(gx);
    265     RECONFIGURE_PORT_TYPE_INFO(ether);
    266     RECONFIGURE_PORT_TYPE_INFO(hg);
    267     RECONFIGURE_PORT_TYPE_INFO(st);
    268     RECONFIGURE_PORT_TYPE_INFO(port);
    269     RECONFIGURE_PORT_TYPE_INFO(all);
    270 
    271 #undef  RECONFIGURE_PORT_TYPE_INFO
    272 
    273 
    274     /*
    275      * Update block port
    276      * Use first logical port on block (logic follows ESW driver
    277      * soc_info_config().
    278      */
    279     for (phy_port = 0; ; phy_port++) {
    280 
    281         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
    282         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
    283         if (blk < 0 && bindex < 0) { /* End of port list */
    284             break;
    285         }
    286 
    287         logic_port = si->port_p2l_mapping[phy_port];
    288         if (logic_port < 0) {
    289             continue;
    290         }
    291 
    292         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
    293              port_idx++) {
    294             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
    295             if (blk < 0) { /* End of block list of each port */
    296                 break;
    297             }
    298 
    299             if (si->block_port[blk] < 0) {
    300                 si->block_port[blk] = logic_port;
    301             }
    302         }
    303     }
    304 
    305     /* Update MAX_PORT(unit) */
    306     max_port = -1;
    307     for (phy_port = 0; phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max;
    308          phy_port++) {
    309         logic_port = si->port_p2l_mapping[phy_port];
    310         if (logic_port < 0) {
    311             continue;
    312         }
    313         if (max_port < logic_port) {
    314             max_port = logic_port;
    315         }
    316     }
    317     si->port_num = max_port + 1;
    318 
    319     /* Update user port mappings (includes port names update) */
    320     soc_esw_dport_init(unit);
    321 
    322     return SOC_E_NONE;
    323 }
    324 
    325 /*
    326  * Function:
    327  *      _bcmi_xgs5_management_port_soc_info_ptype_update
    328  * Purpose:
    329  *      Update the SOC_INFO port type bitmaps for management port.
    330  * Parameters:
    331  *      unit           - (IN) Unit number.
    332  *      port           - (IN) Logical port.
    333  *      speed        - (IN) speed for given port.
    334  * Returns:
    335  *      BCM_E_XXX
    336  * Notes:
    337  */
    338 STATIC int
    339 _bcmi_xgs5_management_port_soc_info_ptype_update(int unit,
    340                                                 bcm_port_t port, int speed)
    341 {
    342     soc_info_t *si = &SOC_INFO(unit);
    343     int rv = BCM_E_NONE;
    344 
    345     if (!SOC_PBMP_MEMBER(si->st.bitmap, port) 
    346         && (!SOC_PBMP_MEMBER(si->hg.bitmap, port))) {
    347         SOC_CONTROL_LOCK(unit);
    348         SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
    349         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
    350 
    351         /* Current devices only support XE/GE/HG type management port */
    352         if (speed < 10000) {    /* GE */
    353             SOC_PBMP_PORT_ADD(si->ge.bitmap, port);
    354         } else {  /* XE */
    355             SOC_PBMP_PORT_ADD(si->xe.bitmap, port);
    356         }
    357 
    358         rv = _bcmi_xgs5_port_soc_info_ptype_update(unit);
    359         SOC_CONTROL_UNLOCK(unit);
    360     }
    361 
    362     return rv;
    363 
    364 }
    365 
    366 
    367 /*
    368  * Function:
    369  *      bcmi_xgs5_port_fn_drv_init
    370  * Purpose:
    371  *      Initialize the Port function driver.
    372  * Parameters:
    373  *      unit - (IN) Unit number.
    374  *      drv  - (IN) Pointer to the Port function driver.
    375  *      bcmi_drv - (IN) Pointer to the BCMI Port function driver.
    376  *      hw_defs - (IN) Pointer to the h/w definition struct.
    377  * Returns:
    378  *      BCM_E_xxx
    379  * Notes:
    380  *      This routine only intializes the function driver.
    381  *      The main port routine is still in the esw/port.c file.
    382  */
    383 int
    384 bcmi_xgs5_port_fn_drv_init(int unit, bcm_esw_port_drv_t *drv,
    385                            bcmi_xgs5_port_drv_t *bcmi_drv,
    386                            bcmi_xgs5_port_hw_defs_t *hw_defs)
    387 {
    388     PARAM_NULL_CHECK(drv);
    389 
    390     /* Assign the driver */
    391     BCM_ESW_PORT_DRV(unit) = drv;
    392 
    393     /* Assign the bcmi port driver */
    394     if (bcmi_drv) {
    395         BCMI_PORT_DRV(unit) = bcmi_drv;
    396     }
    397 
    398     /* Assign the hardware definitions */
    399     if(hw_defs) {
    400         PORT_HW(unit) = hw_defs;
    401     }
    402 
    403     return BCM_E_NONE;
    404 }
    405 
    406 /*
    407  * Function:
    408  *      bcmi_xgs5_port_resource_set
    409  * Purpose:
    410  *      Modify the following port resources:
    411  *      - Logical to physical port mapping
    412  *      - Speed
    413  *      - Number of PHY lanes
    414  *      - Encapsulation mode
    415  * Parameters:
    416  *      unit     - (IN) Unit number.
    417  *      port     - (IN) Logical port.
    418  *      resource - (IN) Port resource configuration.
    419  * Returns:
    420  *      BCM_E_XXX
    421  * Note:
    422  *      Assumes caller has lock.
    423  */
    424 int
    425 bcmi_xgs5_port_resource_set(int unit,
    426                             bcm_gport_t port, bcm_port_resource_t *resource)
    427 {
    428     bcm_port_t  lport1, lport2;
    429 
    430     PARAM_NULL_CHECK(resource);
    431 
    432     /* Check that given port matches logical port field in structure */
    433     BCM_IF_ERROR_RETURN
    434         (bcmi_xgs5_port_addressable_local_get(unit,
    435                                               port, &lport1));
    436     BCM_IF_ERROR_RETURN
    437         (bcmi_xgs5_port_addressable_local_get(unit,
    438                                               resource->port, &lport2));
    439     if (lport1 != lport2) {
    440         return BCM_E_PARAM;
    441     }
    442 
    443     return BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, 1, resource);
    444 }
    445 
    446 
    447 /*
    448  * Function:
    449  *      bcmi_xgs5_port_resource_get
    450  * Purpose:
    451  *      Get the port resource configuration for the specified logical port.
    452  * Parameters:
    453  *      unit      - (IN) Unit number.
    454  *      port      - (IN) Logical port.
    455  *      resource  - (OUT) Returns port resource information.
    456  * Returns:
    457  *      BCM_E_XXX
    458  * Note:
    459  *      Assumes caller has lock.
    460  */
    461 int
    462 bcmi_xgs5_port_resource_get(int unit,
    463                             bcm_gport_t port, bcm_port_resource_t *resource)
    464 {
    465     bcm_port_t lport;
    466     soc_info_t *si = &SOC_INFO(unit);
    467     int encap = 0;
    468 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
    469     portmod_speed_config_t speed_config;
    470     int rv;
    471 #endif
    472 
    473     PARAM_NULL_CHECK(resource);
    474 
    475     BCM_IF_ERROR_RETURN
    476         (bcmi_xgs5_port_addressable_local_get(unit,
    477                                               port, &lport));
    478     bcm_port_resource_t_init(resource);
    479     resource->flags = 0x0;
    480     resource->port = lport;
    481     resource->physical_port = si->port_l2p_mapping[lport];
    482     resource->lanes = si->port_num_lanes[lport];
    483     BCM_IF_ERROR_RETURN
    484         (bcm_esw_port_speed_get(unit, lport, &resource->speed));
    485     BCM_IF_ERROR_RETURN
    486         (bcm_esw_port_encap_get(unit, lport, &encap));
    487     resource->encap = encap;
    488 
    489 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
    490     rv = bcmi_esw_portctrl_speed_config_get(unit, port, &speed_config);
    491 
    492     if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) {
    493         /* PM8x50's autoneg can change the number of lanes used,
    494          * so if the user is in autoneg and does a bcm_port_resource_get
    495          * they need to get the # of lanes being used in hardware
    496          */
    497         resource->lanes = speed_config.num_lane;
    498 
    499         resource->fec_type = speed_config.fec;
    500         resource->phy_lane_config = speed_config.lane_config;
    501         resource->link_training = speed_config.link_training;
    502     } else
    503 #endif
    504     {
    505         /* Upon error fetching from hardware, or if running BCMSIM,
    506          * return the database values */
    507         resource->fec_type = SOC_INFO(unit).port_fec_type[lport];
    508         resource->phy_lane_config = SOC_INFO(unit).port_phy_lane_config[lport];
    509         resource->link_training = SOC_INFO(unit).port_link_training[lport];
    510     }
    511 
    512     /* Flag BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR indicates 25G port use 50G TDM.
    513      */
    514     if (SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport)) {
    515         resource->flags |= BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR;
    516     }
    517 
    518     return BCM_E_NONE;
    519 }
    520 
    521 /*
    522  * Function:
    523  *      _bcmi_xgs5_port_resource_resolve
    524  * Purpose:
    525  *      Convert logical port number GPORT to BCM local port format.
    526  * Parameters:
    527  *      unit     - (IN) Unit number.
    528  *      nport    - (IN) Number of elements in array resource.
    529  *      resource - (IN/OUT) Port resource configuration array.
    530  * Returns:
    531  *      BCM_E_XXX
    532  * Note:
    533  *      - Assumes caller has lock.
    534  *      - Resource is not NULL.
    535  */
    536 STATIC int
    537 _bcmi_xgs5_port_resource_resolve(int unit, 
    538                                 int nport,
    539                                 bcm_port_resource_t *resource)
    540 {
    541     int i;
    542     bcm_port_resource_t *pr;
    543     bcmi_xgs5_dev_info_t *dev_info = BCMI_PORT_DRV_DEV_INFO(unit);
    544 
    545     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    546 
    547         /* Check that logical port number is addressable and convert */
    548         BCM_IF_ERROR_RETURN
    549             (bcmi_xgs5_port_addressable_local_get(unit,
    550                                                   pr->port,
    551                                                   &pr->port));
    552 
    553         /* Check that physical port is within the valid range */
    554         if (pr->physical_port != -1 &&
    555             pr->physical_port >= dev_info->phy_ports_max) {
    556             LOG_ERROR(BSL_LS_BCM_PORT,
    557                       (BSL_META_U(unit,
    558                                   "Invalid physical port %d\n"),
    559                        pr->physical_port));
    560             return BCM_E_PORT;
    561         }
    562     }
    563 
    564     return BCM_E_NONE;
    565 }
    566 
    567 /*
    568  * Function:
    569  *      bcmi_xgs5_port_resource_speed_multi_set
    570  * Purpose:
    571  *      Modify the following port resources:
    572  *      - Speed
    573  *      - fec_type
    574  *      - phy_lane_config
    575  *      - link_training
    576  * Parameters:
    577  *      unit     - (IN) Unit number.
    578  *      nport    - (IN) Number of elements in array resource.
    579  *      resource - (IN) Port resource configuration array.
    580  * Returns:
    581  *      BCM_E_XXX
    582  * Note:
    583  *      Assumes caller has lock.
    584  */
    585 int
    586 bcmi_xgs5_port_resource_speed_multi_set(int unit, 
    587                                   int nport, bcm_port_resource_t *resource)
    588 {
    589 
    590     soc_info_t *si = &SOC_INFO(unit);
    591     int encap, i, soc_num, rindex, rv;
    592     bcm_port_resource_t *local_resource = NULL;
    593     int man_count = 0;
    594 
    595     /* double the number of passed entries because we need to delete the ports,
    596      * then add them. */
    597     soc_num = nport * 2;
    598 
    599     local_resource = sal_alloc(soc_num * sizeof(bcm_port_resource_t),
    600                                 "resource array");
    601     if (NULL == local_resource) {
    602         return BCM_E_MEMORY;
    603     }
    604 
    605     for (i = 0; i < soc_num; i++) {
    606         bcm_port_resource_t_init(&local_resource[i]);
    607     }
    608 
    609     /* Build port resource for delete */
    610     for (i = 0, rindex = 0; rindex < nport; i++, rindex++) {
    611         /* Don't include Management Ports in this */
    612         if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) &&
    613             IS_MANAGEMENT_PORT(unit,resource[rindex].port)) {
    614             /* back off one for this management port */
    615             i--;
    616             continue;
    617         }
    618 
    619         local_resource[i].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED;
    620         local_resource[i].port = resource[rindex].port;
    621         local_resource[i].physical_port = -1;
    622     }
    623 
    624 
    625     /* Build resource for add */
    626     for(i = nport, rindex = 0; rindex < nport; i++, rindex++) {
    627 
    628         /* Do nothing except update port type in case auxiliary ports don't
    629          * support flexport */
    630         /* Don't flex Management Ports; just update ptype */
    631         if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) &&
    632             IS_MANAGEMENT_PORT(unit,resource[rindex].port)) {
    633             BCM_IF_ERROR_RETURN
    634                 (_bcmi_xgs5_management_port_soc_info_ptype_update(unit, 
    635                                     resource[rindex].port, resource[rindex].speed));
    636             /* back off one for this management port */
    637             i--;
    638             man_count++;
    639             continue;
    640         }
    641 
    642 
    643         /* Keep encap, lanes, phy_port the same */
    644         local_resource[i].flags = SOC_PORT_RESOURCE_I_MAP | SOC_PORT_RESOURCE_SPEED;
    645         local_resource[i].port = resource[rindex].port;
    646         local_resource[i].physical_port = si->port_l2p_mapping[resource[rindex].port];
    647         local_resource[i].speed = resource[rindex].speed;
    648         local_resource[i].lanes = si->port_num_lanes[resource[rindex].port];
    649 
    650         /* Get current port encap */
    651         rv = bcm_esw_port_encap_get(unit, resource[rindex].port,
    652                             &encap);
    653         if (!BCM_SUCCESS(rv)) {
    654             goto cleanup;
    655         }
    656         local_resource[i].encap = encap;
    657 
    658         /* Required Fields for new speed set */
    659         local_resource[i].fec_type = resource[rindex].fec_type;
    660         local_resource[i].phy_lane_config = resource[rindex].phy_lane_config;
    661         local_resource[i].link_training = resource[rindex].link_training;
    662 
    663     }
    664 
    665     rv = bcmi_xgs5_port_resource_multi_set(unit, soc_num - (man_count * 2), local_resource);
    666 
    667 cleanup:
    668     if (NULL != local_resource) {
    669         sal_free(local_resource);
    670     }
    671 
    672     return rv;
    673 }
    674 
    675 /*
    676  * Function:
    677  *      _bcmi_xgs5_port_flexible_validate
    678  * Purpose:
    679  *      Check that FlexPort operation is valid on given physical port.
    680  * Parameters:
    681  *      unit      - (IN) Unit number.
    682  *      phy_port  - (IN) Physical port number
    683  * Returns:
    684  *      TRUE or FALSE.
    685  */
    686 STATIC int
    687 _bcmi_xgs5_port_flexible_validate(int unit, int phy_port)
    688 {
    689     if (phy_port != -1 && !BCMI_PORT_DRV_PHY_INFO(unit, phy_port).flex) {
    690         LOG_ERROR(BSL_LS_BCM_PORT,
    691                   (BSL_META_U(unit,
    692                               "FlexPort operation is not enabled on "
    693                               "physical port %d\n"),
    694                    phy_port));
    695         return BCM_E_PARAM;
    696     }
    697 
    698     return BCM_E_NONE;
    699 }
    700 
    701 /*
    702  * Function:
    703  *      _soc_td2p_phy_port_lanes_valid
    704  * Purpose:
    705  *      Check that given lane setting is valid for physical port.
    706  * Parameters:
    707  *      unit     - (IN) Unit number.
    708  *      port     - (IN) Base physical port.
    709  *      lanes    - (IN) Number of PHY lanes.
    710  * Returns:
    711  *      SOC_E_XXX
    712  */
    713 STATIC int
    714 _bcmi_xgs5_port_lanes_validate(int unit, int phy_port, int lanes)
    715 {
    716     uint32 lane_mask;
    717 
    718     switch (lanes) {
    719     case 1:
    720         lane_mask = BCMI_XGS5_PORT_LANES_1;
    721         break;
    722     case 2:
    723         lane_mask = BCMI_XGS5_PORT_LANES_2;
    724         break;
    725     case 4:
    726         lane_mask = BCMI_XGS5_PORT_LANES_4;
    727         break;
    728     case 8:
    729         lane_mask = BCMI_XGS5_PORT_LANES_8;
    730         break;
    731     case 10:
    732         lane_mask = BCMI_XGS5_PORT_LANES_10;
    733         break;
    734     case 12:
    735         lane_mask = BCMI_XGS5_PORT_LANES_12;
    736         break;
    737     default:
    738         LOG_ERROR(BSL_LS_BCM_PORT,
    739                     (BSL_META_U(unit,
    740                                 "Invalid number of lanes for "
    741                                 "physical_port=%d, lanes=%d\n"),
    742                     phy_port, lanes));
    743         return BCM_E_PARAM;
    744     }
    745 
    746     if (!(BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid & lane_mask)) {
    747         LOG_ERROR(BSL_LS_BCM_PORT,
    748                   (BSL_META_U(unit,
    749                               "Invalid lane configuration for "
    750                               "physical_port=%d, lane=%d, "
    751                               "valid_lanes=%s %s %s %s %s %s\n"),
    752                    phy_port, lanes,
    753                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    754                     BCMI_XGS5_PORT_LANES_1) ? "1" : "",
    755                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    756                     BCMI_XGS5_PORT_LANES_2) ? "2" : "",
    757                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    758                     BCMI_XGS5_PORT_LANES_4) ? "4" : "",
    759                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    760                     BCMI_XGS5_PORT_LANES_8) ? "8" : "",
    761                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    762                     BCMI_XGS5_PORT_LANES_10) ? "10" : "",
    763                    (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).lanes_valid &
    764                     BCMI_XGS5_PORT_LANES_12) ? "12" : ""));
    765 
    766         return BCM_E_PARAM;
    767     }
    768 
    769     return BCM_E_NONE;
    770 }
    771 
    772 /*
    773  * Function:
    774  *      _bcmi_xgs5_port_speed_validate
    775  * Purpose:
    776  *      Check that given speed is valid for the number of serdes lanes.
    777  * Parameters:
    778  *      unit     - (IN) Unit number.
    779  *      port     - (IN) Logical port number.
    780  *      phy_port - (IN) Physical port number.
    781  *      lanes    - (IN) Number of PHY lanes.
    782  *      encap    - (IN) Encap mode.
    783  *      speed    - (IN) Port rate to check.
    784  * Returns:
    785  *      SOC_E_XXX
    786  */
    787 STATIC int
    788 _bcmi_xgs5_port_speed_validate(int unit, int port, int phy_port, int lanes,
    789                                int encap, int speed)
    790 {
    791     uint32 speed_mask;
    792     char speed_valid[256], *pos;
    793     int i, string_len, len, is_hg_speed;
    794     char *port_ability_speed_string[] = SOC_PA_SPEED_STRING;
    795 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
    796     portmod_dispatch_type_t pm_type;
    797     int rv, existing_physical_port, autoneg = 0;
    798 #endif
    799 
    800     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) ||
    801         IS_MANAGEMENT_PORT(unit, port)) {
    802         return BCM_E_NONE;
    803     }
    804 
    805     if (speed == 1000 && encap != BCM_PORT_ENCAP_IEEE) {
    806         LOG_ERROR(BSL_LS_BCM_PORT,
    807                   (BSL_META_U(unit,
    808                               "Speed and encapsulation configuration unmatch "
    809                               "for port=%d: 1G ports don't support HG mode.\n"),
    810                    port));
    811         return BCM_E_PARAM;
    812     }
    813 
    814     if (speed > lanes * BCMI_PORT_DRV_PHY_INFO(unit, phy_port).max_lane_speed) {
    815         LOG_ERROR(BSL_LS_BCM_PORT,
    816                   (BSL_META_U(unit,
    817                               "Invalid speed port=%d: Max lane speed is %d.\n"),
    818                    port,
    819                    BCMI_PORT_DRV_PHY_INFO(unit, phy_port).max_lane_speed));
    820         return BCM_E_PARAM;
    821     }
    822 
    823 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
    824     /* PM8x50 don't support bcm_port_ability. Speeds will be verified
    825      * in portmod, but check to make sure the device supports the speed too */
    826     BCM_IF_ERROR_RETURN(portmod_phy_pm_type_get(unit, phy_port, &pm_type));
    827     if (pm_type == portmodDispatchTypePm8x50) {
    828 
    829         /* Autoneg in the PM8x50 allows scenarios like 50G with 4 lanes:
    830          * Starting with a 200G port (4 lanes), autoneg can scale down to 1 lane
    831          * with 50G.  So we don't want to do device speed/lane validations
    832          * if the port is in autoneg
    833          */
    834         existing_physical_port = SOC_INFO(unit).port_l2p_mapping[port];
    835         if (existing_physical_port != -1) {
    836             BCM_IF_ERROR_RETURN(bcm_esw_port_autoneg_get(unit,
    837                                     port, &autoneg));
    838             rv = BCM_E_NONE;
    839         }
    840 
    841         if (autoneg == 0) {
    842             rv = BCM_E_CONFIG;
    843 
    844             if (BCM_ESW_PORT_DRV(unit) != NULL) {
    845                 if (BCM_ESW_PORT_DRV(unit)->device_speed_check != NULL) {
    846                     rv = (BCM_ESW_PORT_DRV(unit)->device_speed_check(unit,
    847                                         speed, lanes));
    848                 }
    849             }
    850             /* speed and lane configuration wasn't found */
    851             if (BCM_FAILURE(rv)) {
    852                 LOG_ERROR(BSL_LS_BCM_PORT,
    853                       (BSL_META_U(unit,
    854                                   "Invalid speed configuration for "
    855                                   "port=%d, speed=%d, lanes=%d\n"),
    856                        port, speed, lanes));
    857                 return rv;
    858             }
    859         }
    860 
    861         return rv;
    862     }
    863 #endif
    864 
    865     speed_mask = SOC_PA_SPEED(speed);
    866     is_hg_speed = SOC_PA_IS_HG_SPEED(speed_mask);
    867 
    868     /* Expect non-higig speed for IEEE encapsulation mode. */
    869     if (is_hg_speed && encap == BCM_PORT_ENCAP_IEEE) {
    870         LOG_ERROR(BSL_LS_BCM_PORT,
    871                   (BSL_META_U(unit,
    872                               "Speed and encapsulation configuration unmatch "
    873                               "for port=%d, speed=%d, encap=%d\n"),
    874                    port, speed, encap));
    875         return BCM_E_PARAM;
    876     }
    877 
    878     if (!(BCMI_PORT_DRV_DEV_INFO(unit)->speed_valid[lanes] & speed_mask)) {
    879         LOG_ERROR(BSL_LS_BCM_PORT,
    880                   (BSL_META_U(unit,
    881                               "Invalid speed configuration for "
    882                               "port=%d, speed=%d\n"),
    883                    port, speed));
    884 
    885         sal_memset(speed_valid, 0, sizeof(speed_valid));
    886         string_len = sizeof(port_ability_speed_string)/sizeof(char *);
    887         pos = speed_valid;
    888         for (i = 0;i < string_len;i++){
    889             if (BCMI_PORT_DRV_DEV_INFO(unit)->speed_valid[lanes] & (1<<i)){
    890                 len = sal_sprintf(pos, "%s ", port_ability_speed_string[i]);
    891                 if (len < 0) {
    892                     LOG_ERROR(BSL_LS_BCM_COMMON,
    893                               (BSL_META_U(unit,
    894                                           "len = %d\n"),
    895                                len));
    896                     return BCM_E_RESOURCE;
    897                 }
    898                 pos += len;
    899             }
    900         }
    901 
    902         LOG_ERROR(BSL_LS_BCM_PORT,
    903                   (BSL_META_U(unit, "valid speeds: %s\n"), speed_valid));
    904         return BCM_E_PARAM;
    905     }
    906 
    907     return BCM_E_NONE;
    908 }
    909 
    910 /*
    911  * Function:
    912  *      _bcmi_xgs5_port_encap_validate
    913  * Purpose:
    914  *      Check that given encap is valid for unit.
    915  * Parameters:
    916  *      unit     - (IN) Unit number.
    917  *      port     - (IN) Logical port number.
    918  *      phy_port - (IN) Physical port number.
    919  *      encap    - (IN) Encap mode.
    920  * Returns:
    921  *      SOC_E_XXX
    922  */
    923 STATIC int
    924 _bcmi_xgs5_port_encap_validate(int unit, int port, int phy_port,
    925                                        int encap)
    926 {
    927     uint32 encap_mask;
    928 
    929     switch (encap) {
    930     case BCM_PORT_ENCAP_IEEE:
    931         encap_mask = BCM_PA_ENCAP_IEEE;
    932         break;
    933     case BCM_PORT_ENCAP_HIGIG:
    934         encap_mask = BCM_PA_ENCAP_HIGIG;
    935         break;
    936     case BCM_PORT_ENCAP_B5632:
    937         encap_mask = BCM_PA_ENCAP_B5632;
    938         break;
    939     case BCM_PORT_ENCAP_HIGIG2:
    940         encap_mask = BCM_PA_ENCAP_HIGIG2;
    941         break;
    942     case BCM_PORT_ENCAP_HIGIG2_LITE:
    943         encap_mask = BCM_PA_ENCAP_HIGIG2_LITE;
    944         break;
    945     case BCM_PORT_ENCAP_HIGIG2_L2:
    946         encap_mask = BCM_PA_ENCAP_HIGIG2_L2;
    947         break;
    948     case BCM_PORT_ENCAP_HIGIG2_IP_GRE:
    949         encap_mask = BCM_PA_ENCAP_HIGIG2_IP_GRE;
    950         break;
    951     case BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET:
    952         encap_mask = BCM_PA_ENCAP_HIGIG_OVER_ETHERNET;
    953         break;
    954     default:
    955         LOG_ERROR(BSL_LS_BCM_PORT,
    956                   (BSL_META_U(unit,
    957                               "Invalid encapsulation for "
    958                               "unit=%d, encap=%d\n"),
    959                    unit, encap));
    960         return BCM_E_PARAM;
    961     }
    962 
    963     if (!(BCMI_PORT_DRV_DEV_INFO(unit)->encap_mask & encap_mask)) {
    964         LOG_ERROR(BSL_LS_BCM_PORT,
    965                   (BSL_META_U(unit,
    966                               "Invalid encapsulation configuration for "
    967                               "unit=%d, encap=%d\n"),
    968                    unit, encap));
    969         return BCM_E_PARAM;
    970     }
    971 
    972     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) ||
    973         IS_MANAGEMENT_PORT(unit, port)) {
    974         return BCM_E_NONE;
    975     }
    976 
    977     if (BCMI_PORT_DRV_DEV_INFO(unit)->phy_port_info[phy_port].force_hg &&
    978         !(BCMI_PORT_DRV_DEV_INFO(unit)->hg_encap_mask & encap_mask)) {
    979         LOG_ERROR(BSL_LS_BCM_PORT,
    980                   (BSL_META_U(unit,
    981                               "Encapsulation configuration %d is invalid on "
    982                               "hg-only port %d of unit %d\n"),
    983                    encap, port, unit));
    984         return BCM_E_PARAM;
    985     }
    986 
    987     return BCM_E_NONE;
    988 }
    989 
    990 /*
    991  * Function:
    992  *      _bcmi_xgs5_port_flex_max_validate
    993  * Purpose:
    994  *      Check that the port num in a port macro shall not exceed the max num
    995  *      that it could flex to.
    996  * Parameters:
    997  *      unit     - (IN) Unit number.
    998  *      nport    - (IN) Number of elements in array resource.
    999  *      resource - (IN/OUT) Port resource configuration array.
   1000  * Returns:
   1001  *      BCM_E_XXX
   1002  * Note:
   1003  *      - Assumes caller has lock.
   1004  *      - Resource is not NULL.
   1005  */
   1006 STATIC int
   1007 _bcmi_xgs5_port_flex_max_validate(int unit,
   1008                                   int nport,
   1009                                   bcm_port_resource_t *resource)
   1010 {
   1011     soc_info_t *si = &SOC_INFO(unit);
   1012     bcm_port_resource_t *pr;
   1013     int logic_port, phy_port, port_idx, blk;
   1014     pbmp_t *blk_bitmap;
   1015     int port_count;
   1016     int i;
   1017 
   1018     blk_bitmap = sal_alloc(SOC_MAX_NUM_BLKS * sizeof(pbmp_t), "blk_bitmap");
   1019     sal_memcpy(blk_bitmap, si->block_bitmap, SOC_MAX_NUM_BLKS * sizeof(pbmp_t));
   1020 
   1021     /* Entries to delete ports */
   1022     for (i = 0, pr = &resource[0]; (i < nport) && pr->physical_port == -1;
   1023          i++, pr++) {
   1024         logic_port = pr->port;
   1025         phy_port = si->port_l2p_mapping[logic_port];
   1026         if (phy_port == -1) {
   1027             continue;
   1028         }
   1029 
   1030         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   1031              port_idx++) {
   1032             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   1033             if (blk < 0) { /* End of block list of each port */
   1034                 break;
   1035             }
   1036             SOC_PBMP_COUNT(blk_bitmap[blk], port_count);
   1037             if (port_count == 0) {
   1038                 LOG_ERROR(BSL_LS_BCM_PORT,
   1039                           (BSL_META_U(unit,
   1040                                       "Port Macro %d doesn't have valid port "
   1041                                       "to delete.\n"),
   1042                            SOC_BLOCK_NUMBER(unit,blk)));
   1043                 sal_free(blk_bitmap);
   1044                 return BCM_E_INTERNAL;
   1045             }
   1046             if (SOC_PBMP_MEMBER(blk_bitmap[blk], logic_port)) {
   1047                 SOC_PBMP_PORT_REMOVE(blk_bitmap[blk], logic_port);
   1048             }
   1049         } /* For each block in the given port */
   1050     }
   1051 
   1052     /* Entries to add ports */
   1053     for (;i < nport; i++) {
   1054         pr = &resource[i];
   1055         logic_port = pr->port;
   1056         phy_port = pr->physical_port;
   1057         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   1058              port_idx++) {
   1059             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   1060             if (blk < 0) { /* End of block list of each port */
   1061                 break;
   1062             }
   1063             if (!SOC_PBMP_MEMBER(blk_bitmap[blk], logic_port)) {
   1064                 SOC_PBMP_PORT_ADD(blk_bitmap[blk], logic_port);
   1065                 SOC_PBMP_COUNT(blk_bitmap[blk], port_count);
   1066                 if (port_count > si->pm_max_ports[blk]) {
   1067                     LOG_ERROR(BSL_LS_BCM_PORT,
   1068                               (BSL_META_U(unit,
   1069                                       "Port num on Port Macro %d would "
   1070                                       "exceed the Max num %d that it could "
   1071                                       "flex to.\n"),
   1072                                SOC_BLOCK_NUMBER(unit,blk),
   1073                                si->pm_max_ports[blk]));
   1074                     sal_free(blk_bitmap);
   1075                     return BCM_E_PARAM;
   1076                 }
   1077             }
   1078         } /* For each block in the given port */
   1079     }
   1080 
   1081     sal_free(blk_bitmap);
   1082     return BCM_E_NONE;
   1083 }
   1084 
   1085 /*
   1086  * Function:
   1087  *      _bcmi_xgs5_port_resource_input_validate
   1088  * Purpose:
   1089  *      Validate function input requirements.
   1090  *
   1091  *      This routine checks for function semantics and guidelines
   1092  *      from the API perspective:
   1093  *      - Check that logical port number is valid and convert GPORT port
   1094  *        format to BCM local port format.
   1095  *      - Logical and physical port number must be within valid range.
   1096  *      - Check the order of elements in array, 'delete' operations must
   1097  *        be placed first in array.
   1098  *      - Check that physical port is flexible.
   1099  *      - Check that lanes, speed and encap are valid.
   1100  * Parameters:
   1101  *      unit     - (IN) Unit number.
   1102  *      nport    - (IN) Number of elements in array resource.
   1103  *      resource - (IN/OUT) Port resource configuration array.
   1104  * Returns:
   1105  *      BCM_E_XXX
   1106  * Note:
   1107  *      - Assumes caller has lock.
   1108  *      - Resource is not NULL.
   1109  */
   1110 STATIC int
   1111 _bcmi_xgs5_port_resource_input_validate(int unit, 
   1112                                         int nport,
   1113                                         bcm_port_resource_t *resource)
   1114 {
   1115     int i;
   1116     bcm_port_resource_t *pr;
   1117     int enable;
   1118     int delete = 1;
   1119     soc_info_t *si = &SOC_INFO(unit);
   1120     int old_phy_port;
   1121     pbmp_t del_pbmp;
   1122 
   1123 
   1124     LOG_VERBOSE(BSL_LS_BCM_PORT,
   1125                 (BSL_META_U(unit,
   1126                             "==== PORT RESOURCE INPUT VALIDATE ====\n")));
   1127 
   1128     /* Convert port format and validate logical and physical port numbers */
   1129     BCM_IF_ERROR_RETURN
   1130         (_bcmi_xgs5_port_resource_resolve(unit, 
   1131                                          nport, resource));
   1132 
   1133     SOC_PBMP_CLEAR(del_pbmp);
   1134 
   1135     /* Check array order and port state disable */
   1136     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   1137 
   1138         /* Check that delete operations are first */
   1139         if (pr->physical_port != -1) {  /* First non-delete found */
   1140             delete = 0;
   1141         } else if (pr->physical_port == -1) {
   1142             if (!delete) {
   1143                 LOG_ERROR(BSL_LS_BCM_PORT,
   1144                           (BSL_META_U(unit,
   1145                                       "Delete operations must be "
   1146                                       "first in array\n")));
   1147                 return BCM_E_PARAM;
   1148             }
   1149             SOC_PBMP_PORT_ADD(del_pbmp, pr->port);
   1150         }
   1151 
   1152         old_phy_port = si->port_l2p_mapping[pr->port];
   1153 
   1154         /* Check if flex is enabled on port */
   1155         if (!(pr->flags & SOC_PORT_RESOURCE_I_MAP)) {
   1156             BCM_IF_ERROR_RETURN
   1157                 (_bcmi_xgs5_port_flexible_validate(unit, pr->physical_port));
   1158 
   1159             BCM_IF_ERROR_RETURN
   1160                 (_bcmi_xgs5_port_flexible_validate(unit, old_phy_port));
   1161         }
   1162 
   1163         if (si->port_l2p_mapping[pr->port] != -1 &&
   1164             !(pr->flags & SOC_PORT_RESOURCE_SPEED)) {
   1165             /* Check that ports are disabled */
   1166             BCM_IF_ERROR_RETURN
   1167                 (bcm_esw_port_enable_get(unit, pr->port, &enable));
   1168             if (enable) {
   1169                 LOG_ERROR(BSL_LS_BCM_PORT,
   1170                           (BSL_META_U(unit,
   1171                                       "Port %d needs to be disabled\n"),
   1172                            pr->port));
   1173                 return BCM_E_BUSY;
   1174             }
   1175         }
   1176 
   1177         if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) &&
   1178             SOC_PBMP_MEMBER(BCMI_PORT_DRV_DEV_INFO(unit)->aux_pbm, pr->port)) {
   1179             LOG_ERROR(BSL_LS_BCM_PORT,
   1180                       (BSL_META_U(unit,
   1181                                   "FlexPort is not supported for auxiliary "
   1182                                   "port %d.\n"),
   1183                        pr->port));
   1184             return BCM_E_PARAM;
   1185         }
   1186 
   1187         if (pr->physical_port != -1) {
   1188 
   1189             /* Delete existing ports which are part of the FlexPort operation */
   1190             if (old_phy_port != -1 && !SOC_PBMP_MEMBER(del_pbmp, pr->port)) {
   1191                 LOG_ERROR(BSL_LS_BCM_PORT,
   1192                           (BSL_META_U(unit,
   1193                                       "Delete entry is required for Port %d\n"),
   1194                            pr->port));
   1195                 return BCM_E_PARAM;
   1196             }
   1197 
   1198             /* Check Lanes assignment */
   1199             BCM_IF_ERROR_RETURN
   1200                 (_bcmi_xgs5_port_lanes_validate(unit, pr->physical_port,
   1201                                                 pr->lanes));
   1202 
   1203             /* Check speeds */
   1204             BCM_IF_ERROR_RETURN
   1205                 (_bcmi_xgs5_port_speed_validate(unit, pr->port,
   1206                                                 pr->physical_port,
   1207                                                 pr->lanes, pr->encap,
   1208                                                 pr->speed));
   1209 
   1210             /* Check Encapsulation */
   1211             BCM_IF_ERROR_RETURN
   1212                 (_bcmi_xgs5_port_encap_validate(unit, pr->port,
   1213                                                 pr->physical_port,
   1214                                                 pr->encap));
   1215         }
   1216     }
   1217 
   1218     /* Check that the port num in a port macro shall not exceed the max num
   1219      * that it could flex to. */
   1220     BCM_IF_ERROR_RETURN
   1221         (_bcmi_xgs5_port_flex_max_validate(unit, nport, resource));
   1222 
   1223     return BCM_E_NONE;
   1224 }
   1225 
   1226 /*
   1227  * Function:
   1228  *      _bcmi_xgs5_port_resource_op_set
   1229  * Purpose:
   1230  *      Get the type of FlexPort operations/changes:
   1231  *          none, add, delete remap, lanes, speed, encap.
   1232  *
   1233  * Parameters:
   1234  *      unit         - (IN) Unit number.
   1235  *      nport        - (IN) Number of elements in array resource.
   1236  *      resource     - (IN) BCM port resource configuration array.
   1237  *      soc_resource - (IN) SOC Port resource configuration array.
   1238  *                   - (OUT) resource[i].op is set with FlexPort operation
   1239  *      op           - (OUT) FlexPort operation BCMI_XGS5_PORT_RESOURCE_OP_...
   1240  * Returns:
   1241  *      BCM_E_XXX
   1242  * Note:
   1243  *      Assumes caller has lock.
   1244  *      Resource is not NULL.
   1245  *      Logical port in 'resource' is in BCM port format (non GPORT).
   1246  * Example:
   1247  *      L1 --> -1 (current mapped to P1 with 1 lane), op is LANES 
   1248  *      L2 --> -1 (current mapped to P2 with 1 lane), op is REMAP 
   1249  *      L3 --> -1 (current mapped to P3 with 1 lane), op is DELETE
   1250  *      L1 --> P1 (with 4 lane)                     , op is SAME 
   1251  *      L2 --> P5 (with 1 lane)                     , op is REMAP 
   1252  *      L9 --> P9 (with 4 lane)                     , op is NEW
   1253  *      L6 --> P6 (speed/encap update)              , op is SPEED/ENCAP
   1254  */
   1255 STATIC int
   1256 _bcmi_xgs5_port_resource_op_set(int unit, int nport,
   1257                                 bcm_port_resource_t *resource,
   1258                                 soc_port_resource_t *soc_resource,
   1259                                 int *op)
   1260 {
   1261     int i;
   1262     bcm_port_resource_t *r, cr;
   1263     soc_port_resource_t *pr;
   1264     soc_info_t *si = &SOC_INFO(unit);
   1265     int lport, pport, pre_pport, iport, pre_iport;
   1266     pbmp_t att_pbm, remap_pbm, lane_pbm, speed_pbm, encap_pbm;
   1267 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
   1268     portmod_dispatch_type_t pm_type;
   1269     int autoneg = 0;
   1270 #endif
   1271 
   1272     *op = BCMI_XGS5_PORT_RESOURCE_OP_NONE;
   1273     SOC_PBMP_CLEAR(att_pbm);
   1274     SOC_PBMP_CLEAR(remap_pbm);
   1275     SOC_PBMP_CLEAR(lane_pbm);
   1276     SOC_PBMP_CLEAR(speed_pbm);
   1277     SOC_PBMP_CLEAR(encap_pbm);
   1278 
   1279     for (i = nport-1, pr = &soc_resource[nport-1], r = &resource[nport-1];
   1280          i >= 0; i--, pr--, r--) {
   1281         lport = pr->logical_port;
   1282         pport = pr->physical_port;
   1283         pre_pport = si->port_l2p_mapping[lport];
   1284         iport = pr->idb_port;
   1285         pre_iport = si->port_l2i_mapping[lport];
   1286 
   1287         if (pport != -1) {
   1288 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
   1289             /* If it's PM8x50, need to check if fec_type, link training
   1290              * or phy lane config changed */
   1291             BCM_IF_ERROR_RETURN(portmod_phy_pm_type_get(unit, pport, &pm_type));
   1292 #endif
   1293 
   1294             /* Entries for port-attach */
   1295             SOC_PBMP_PORT_ADD(att_pbm, lport);
   1296 
   1297             /* Set op to ADD if port is non-existing */
   1298             if (pre_pport == -1) {
   1299                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_ADD;
   1300             } else {
   1301                 if ((pport != pre_pport) || (iport != pre_iport)) {
   1302                     pr->op = BCMI_XGS5_PORT_RESOURCE_OP_REMAP;
   1303                     SOC_PBMP_PORT_ADD(remap_pbm, lport);
   1304                 } else {
   1305                     bcm_port_resource_t_init(&cr);
   1306                     BCM_IF_ERROR_RETURN
   1307                         (bcm_esw_port_resource_get(unit, lport, &cr));
   1308 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
   1309                     if (pm_type == portmodDispatchTypePm8x50) {
   1310                         /* On PM8x50, number of lanes can be changed during AN.
   1311                          * However, BCMI_XGS5_PORT_RESOURCE_OP_LANES should not
   1312                          * be set for AN ports.
   1313                          */
   1314                         BCM_IF_ERROR_RETURN
   1315                             (bcm_esw_port_autoneg_get(unit, lport, &autoneg));
   1316                     }
   1317                     if (!autoneg)
   1318 #endif
   1319                     {
   1320                         if (r->lanes != cr.lanes) {
   1321                             pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_LANES;
   1322                             SOC_PBMP_PORT_ADD(lane_pbm, lport);
   1323                         }
   1324                     }
   1325                     if (r->speed != si->port_init_speed[lport] ||
   1326                         r->speed != cr.speed) {
   1327                         pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_SPEED;
   1328                         SOC_PBMP_PORT_ADD(speed_pbm, lport);
   1329                     }
   1330 #if defined(PORTMOD_SUPPORT) && defined(PORTMOD_PM8X50_SUPPORT)
   1331                     if (pm_type == portmodDispatchTypePm8x50) {
   1332                         /* Always set the Speed Op for PM8x50 if there's a port
   1333                          * passed in. There may have been a portmod VCO change
   1334                          * operation that requires the port to be reconfigured
   1335                          */
   1336                         pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_SPEED;
   1337                         SOC_PBMP_PORT_ADD(speed_pbm, lport);
   1338                     }
   1339 #endif
   1340                     if (r->encap != cr.encap) {
   1341                         if (BCMI_PORT_DRV_DEV_INFO(unit)->encap_change_flex) {
   1342                             pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX;
   1343                             SOC_PBMP_PORT_ADD(encap_pbm, lport);
   1344                         } else {
   1345                             pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ENCAP;
   1346                         }
   1347                     }
   1348                     if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, lport)) {
   1349                         pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE;
   1350                     }
   1351 
   1352                     /* Only TDM calendar change. Currently only between 25G port use 25G
   1353                                    * TDM calendar and 25G port use 50G TDM.
   1354                                    */
   1355                     if ((SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport) &&
   1356                         !(pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR)
   1357                         && (r->speed == 25000))
   1358                         ||
   1359                         (!SOC_PBMP_MEMBER(si->pbm_25g_use_50g_tdm, lport) &&
   1360                         (cr.speed == 25000) &&
   1361                         (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR)))
   1362                         {
   1363                         pr->op |= BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR;
   1364                     }
   1365                 }
   1366             }
   1367         } else {
   1368             /* Entries for port-detach */
   1369             /* Lane_num/speed/encap update don't require delete-port */
   1370             if (!SOC_PBMP_MEMBER(att_pbm, lport)) {
   1371                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_DEL;
   1372             } else if (SOC_PBMP_MEMBER(remap_pbm, lport)) {
   1373                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_REMAP;
   1374             } else if (SOC_PBMP_MEMBER(lane_pbm, lport)) {
   1375                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_LANES;
   1376             } else if (SOC_PBMP_MEMBER(speed_pbm, lport)) {
   1377                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_SPEED;
   1378             } else if (SOC_PBMP_MEMBER(encap_pbm, lport)) {
   1379                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX;
   1380             } else {
   1381                 pr->op = BCMI_XGS5_PORT_RESOURCE_OP_NONE;
   1382             }
   1383         }
   1384         *op |= pr->op;
   1385     }
   1386 
   1387     return BCM_E_NONE;
   1388 }
   1389 
   1390 /*
   1391  * Function:
   1392  *      _bcmi_xgs5_port_soc_schedule_state_init
   1393  * Purpose:
   1394  *      Construct soc_port_schedule_state_t structure which will pass to
   1395  *      FlexPort Tier1 API as input.
   1396  *
   1397  * Parameters:
   1398  *      unit                - (IN) Unit number.
   1399  *      nport               - (IN) Number of elements in array resource.
   1400  *      soc_resource        - (IN) SOC Port resource configuration array.
   1401  *      op                  - (IN) Operation code
   1402  *      port_schedule_state - (OUT) soc_port_schedule_state_t.
   1403  * Returns:
   1404  *      BCM_E_XXX
   1405  * Note:
   1406  *      Assumes caller has lock.
   1407  *      Resource is not NULL.
   1408  *      Logical port in 'resource' is in BCM port format (non GPORT).
   1409  */
   1410 STATIC int
   1411 _bcmi_xgs5_port_soc_schedule_state_init(int unit, int nport, int op,
   1412                                  soc_port_resource_t *soc_resource,
   1413                                  soc_port_schedule_state_t *port_schedule_state)
   1414 {
   1415     soc_info_t *si = &SOC_INFO(unit);
   1416     soc_port_map_type_t *in_port_map;
   1417     soc_asf_prop_t *asf;
   1418     int lossless, port, asf_mode, asf_prof;
   1419     int speed, lanes, encap;
   1420     int rv;
   1421 #ifdef BCM_TOMAHAWK3_SUPPORT
   1422     int dpr_freq;
   1423 #endif
   1424 
   1425     lossless = soc_property_get(unit, spn_MMU_LOSSLESS,
   1426                                     BCMI_PORT_DRV_DEV_INFO(unit)->mmu_lossless);
   1427 
   1428     /* port_schedule_state structure initialization */
   1429     sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t));
   1430 
   1431     /* Check the size, because port_schedule_state->resource is statically
   1432      * allocated and we don't want to overflow the buffer */
   1433     if (nport > MAX_NUM_FLEXPORTS) {
   1434         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1435                  (BSL_META_U(unit,
   1436                              "Number of flexports (%d) exceeds maximum for "
   1437                              "structure soc_port_schedule_state_t (%d)\n"),
   1438                               nport, MAX_NUM_FLEXPORTS));
   1439         return BCM_E_INTERNAL;
   1440     }
   1441 
   1442     port_schedule_state->nport = nport;
   1443     sal_memcpy(port_schedule_state->resource, soc_resource,
   1444                nport * sizeof(soc_port_resource_t));
   1445 
   1446     port_schedule_state->frequency = si->frequency;
   1447     port_schedule_state->bandwidth = si->bandwidth;
   1448     port_schedule_state->io_bandwidth = si->io_bandwidth;
   1449     port_schedule_state->lossless = lossless;
   1450     port_schedule_state->is_flexport = TRUE;
   1451 
   1452     /* ASF Setting */
   1453     if (soc_feature(unit, soc_feature_asf_multimode))  {
   1454 
   1455         if (BCMI_PORT_SCHEDULE_STATE_INIT_OP_ASF(op)) {
   1456             asf = &port_schedule_state->cutthru_prop;
   1457 
   1458             asf->switch_bypass_mode = SOC_SWITCH_BYPASS_MODE(unit);
   1459 
   1460             PBMP_PORT_ITER(unit, port) {
   1461                 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) ||
   1462                     IS_MANAGEMENT_PORT(unit, port)) {
   1463                     continue;
   1464                 }
   1465                 BCM_IF_ERROR_RETURN
   1466                     (bcm_esw_switch_control_port_get(unit, port,
   1467                                                      bcmSwitchAlternateStoreForward,
   1468                                                      &asf_mode));
   1469                 asf->asf_modes[port] = asf_mode;
   1470             }
   1471 
   1472             asf_prof = BCMI_PORT_DRV_DEV_INFO(unit)->asf_prof_default;
   1473             asf_prof = soc_property_get(unit, spn_ASF_MEM_PROFILE, asf_prof);
   1474 
   1475             if (!((asf_prof >= _SOC_ASF_MEM_PROFILE_NONE) &&
   1476                   (asf_prof < _SOC_ASF_MEM_PROFILE_END))) {
   1477                 asf_prof = BCMI_PORT_DRV_DEV_INFO(unit)->asf_prof_default;
   1478             }
   1479             asf->asf_mem_prof = asf_prof;
   1480         }
   1481     }
   1482 
   1483     /* Input port mapping */
   1484     in_port_map = &port_schedule_state->in_port_map;
   1485     PBMP_PORT_ITER(unit, port) {
   1486         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   1487             continue;
   1488         }
   1489 
   1490         speed = si->port_init_speed[port];
   1491         lanes = si->port_num_lanes[port];
   1492         if (LOG_CHECK(BSL_LS_BCM_PORT|BSL_VERBOSE)) {
   1493             if (IS_HG_PORT(unit, port)) {
   1494                 if (soc_feature(unit, soc_feature_no_higig_plus)) {
   1495                     encap = SOC_ENCAP_HIGIG2;
   1496                 } else {
   1497                     encap = soc_property_port_get(unit, port,
   1498                                                   spn_HIGIG2_HDR_MODE, 0) ?
   1499                             SOC_ENCAP_HIGIG2 : SOC_ENCAP_HIGIG;
   1500                 }
   1501             } else {
   1502                 encap = SOC_ENCAP_IEEE;
   1503             }
   1504 
   1505             rv = _bcmi_xgs5_port_speed_validate(unit, port,
   1506                                                 si->port_l2p_mapping[port],
   1507                                                 lanes, encap, speed);
   1508             if (BCM_FAILURE(rv)) {
   1509                 LOG_VERBOSE(BSL_LS_BCM_PORT,
   1510                          (BSL_META_U(unit,
   1511                                      "Invalid configuration for existing "
   1512                                      "port %d: physical_port=%d, speed=%d, "
   1513                                      "lanes=%d, encap=%d\n"),
   1514                           port, si->port_l2p_mapping[port], speed,
   1515                           lanes, encap));
   1516             }
   1517         }
   1518         if (speed < BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min) {
   1519             speed = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min;
   1520         }
   1521         in_port_map->log_port_speed[port] = speed;
   1522         in_port_map->port_num_lanes[port] = lanes;
   1523 #ifdef BCM_MAVERICK2_SUPPORT
   1524         if (SOC_IS_MAVERICK2(unit) && IS_MANAGEMENT_PORT(unit, port)) {
   1525             in_port_map->port_num_lanes[port] = 1;
   1526         }
   1527 #endif
   1528     }
   1529 
   1530 #ifdef BCM_TOMAHAWK3_SUPPORT
   1531     /* DPR Frequency is stored in this unused field so that MMU can have
   1532        PFC Optimized settings */
   1533     if (SOC_IS_TOMAHAWK3(unit)) {
   1534         dpr_freq = soc_property_get(unit, spn_DPR_CLOCK_FREQUENCY, -1);
   1535         in_port_map->port_p2PBLK_inst_mapping[0] = dpr_freq;
   1536     }
   1537 #endif
   1538 
   1539     sal_memcpy(in_port_map->port_p2l_mapping, si->port_p2l_mapping,
   1540                 sizeof(int)*SOC_MAX_NUM_PORTS);
   1541     sal_memcpy(in_port_map->port_l2p_mapping, si->port_l2p_mapping,
   1542                 sizeof(int)*SOC_MAX_NUM_PORTS);
   1543     sal_memcpy(in_port_map->port_p2m_mapping, si->port_p2m_mapping,
   1544                 sizeof(int)*SOC_MAX_NUM_PORTS);
   1545     sal_memcpy(in_port_map->port_m2p_mapping, si->port_m2p_mapping,
   1546                 sizeof(int)*SOC_MAX_NUM_MMU_PORTS);
   1547     sal_memcpy(in_port_map->port_l2i_mapping, si->port_l2i_mapping,
   1548                 sizeof(int)*SOC_MAX_NUM_PORTS);
   1549     sal_memcpy(&in_port_map->physical_pbm, &si->physical_pbm, sizeof(pbmp_t));
   1550     sal_memcpy(&in_port_map->hg2_pbm, &si->hg2_pbm, sizeof(pbmp_t));
   1551     sal_memcpy(&in_port_map->management_pbm, &si->management_pbm,
   1552                 sizeof(pbmp_t));
   1553     sal_memcpy(&in_port_map->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t));
   1554 
   1555     /* TDM info */
   1556     if (BCMI_PORT_SCHEDULE_STATE_INIT_OP_TDM(op)) {
   1557         if (BCMI_PORT_DRV_CALL(unit)->pre_flexport_tdm) {
   1558             BCM_IF_ERROR_RETURN
   1559                 (BCMI_PORT_DRV_CALL(unit)->pre_flexport_tdm(unit,
   1560                                                             port_schedule_state));
   1561         }
   1562     }
   1563 
   1564     return BCM_E_NONE;
   1565 }
   1566 
   1567 /*
   1568  * Function:
   1569  *      _bcmi_xgs5_port_info_post_flex
   1570  * Purpose:
   1571  *      Populate Post Flexport soc info.
   1572  *
   1573  *      Certain validations need the post FlexPort information for all
   1574  *      the ports at the same time (mostly contained in SOC_INFO).
   1575  *      The global SOC_INFO is updated after the validation phase so
   1576  *      the information is not available yet.
   1577  * Parameters:
   1578  *      unit           - (IN) Unit number.
   1579  *      port_schedule_state  - (IN/OUT) soc_port_schedule_state_t.
   1580  * Returns:
   1581  *      SOC_E_XXX
   1582  * Note:
   1583  *      This function does NOT modify the global SOC_INFO SW database,
   1584  *      the post information is returned in the local argument.
   1585  *
   1586  *      Assumes values in resource are valid (logical port, etc.)
   1587  */
   1588 STATIC int
   1589 _bcmi_xgs5_port_info_post_flex(int unit,
   1590                             soc_port_schedule_state_t *port_schedule_state)
   1591 {
   1592     soc_info_t *si = &SOC_INFO(unit);
   1593     soc_port_resource_t *pr;
   1594     int nport = port_schedule_state->nport;
   1595     soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map;
   1596     int i;
   1597     int logic_port, phy_port, mmu_port;
   1598 
   1599     /* Get current information */
   1600     sal_memcpy(post_pi, &port_schedule_state->in_port_map,
   1601                 sizeof(soc_port_map_type_t));
   1602 
   1603     /* First process 'delete' mappings */
   1604     for (i = 0, pr = port_schedule_state->resource;
   1605          (i < nport) && (pr->physical_port == -1);
   1606          i++, pr++) {
   1607         logic_port = pr->logical_port;
   1608 
   1609         post_pi->log_port_speed[logic_port] = 0;
   1610         post_pi->port_num_lanes[logic_port] = 0;
   1611         SOC_PBMP_PORT_REMOVE(post_pi->oversub_pbm, logic_port);
   1612         SOC_PBMP_PORT_REMOVE(post_pi->hg2_pbm, logic_port);
   1613         SOC_PBMP_PORT_REMOVE(post_pi->physical_pbm, logic_port);
   1614 
   1615         phy_port = si->port_l2p_mapping[logic_port];
   1616         if (phy_port == -1) {
   1617             continue;
   1618         }
   1619 
   1620         mmu_port = si->port_p2m_mapping[phy_port];
   1621 
   1622         post_pi->port_l2p_mapping[logic_port] = -1;
   1623         post_pi->port_p2l_mapping[phy_port] = -1;
   1624         post_pi->port_p2m_mapping[phy_port] = -1;
   1625         post_pi->port_m2p_mapping[mmu_port] = -1;
   1626         post_pi->port_l2i_mapping[logic_port] = -1;
   1627     }
   1628 
   1629     /* Continue with 'add' mappings in rest of array */
   1630     for (; i < nport; i++, pr++) {
   1631         logic_port = pr->logical_port;
   1632         phy_port = pr->physical_port;
   1633         mmu_port = pr->mmu_port;
   1634 
   1635         post_pi->log_port_speed[logic_port] = pr->speed;
   1636         post_pi->port_num_lanes[logic_port] = pr->num_lanes;
   1637         post_pi->port_l2p_mapping[logic_port] = phy_port;
   1638         post_pi->port_p2l_mapping[phy_port] = logic_port;
   1639         post_pi->port_p2m_mapping[phy_port] = mmu_port;
   1640         post_pi->port_m2p_mapping[mmu_port] = phy_port;
   1641         post_pi->port_l2i_mapping[logic_port] = pr->idb_port;
   1642 
   1643         if (pr->oversub) {
   1644             SOC_PBMP_PORT_ADD(post_pi->oversub_pbm, logic_port);
   1645         } else {
   1646             SOC_PBMP_PORT_REMOVE(post_pi->oversub_pbm, logic_port);
   1647         }
   1648         if (pr->encap == _SHR_PORT_ENCAP_HIGIG2) {
   1649             SOC_PBMP_PORT_ADD(post_pi->hg2_pbm, logic_port);
   1650         } else {
   1651             SOC_PBMP_PORT_REMOVE(post_pi->hg2_pbm, logic_port);
   1652         }
   1653 
   1654         /* physical_pbm used to store the port bitmap of 25G ports using 50G
   1655                * TDM calendar.
   1656                */
   1657         if (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR) {
   1658             SOC_PBMP_PORT_ADD(post_pi->physical_pbm, logic_port);
   1659         }
   1660     }
   1661 
   1662     LOG_VERBOSE(BSL_LS_BCM_PORT,
   1663                 (BSL_META_U(unit,
   1664                             "\n--- SOC INFO Post FlexPort Data ---\n")));
   1665     LOG_VERBOSE(BSL_LS_BCM_PORT,
   1666                 (BSL_META_U(unit,
   1667                             "Index L2P   Speed  Encap Ovs\n")));
   1668     for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   1669         if (post_pi->port_l2p_mapping[i] == -1) {
   1670             continue;
   1671         }
   1672         /* coverity[overrun-local] */
   1673         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1674                     (BSL_META_U(unit,
   1675                                 " %3d  %3d   %6d   %3s   %1d\n"),
   1676                      i,
   1677                      post_pi->port_l2p_mapping[i],
   1678                      post_pi->log_port_speed[i],
   1679                      SOC_PBMP_MEMBER(post_pi->hg2_pbm, i) ? "HG" : "!HG",
   1680                      SOC_PBMP_MEMBER(post_pi->oversub_pbm, i) ? 1 : 0));
   1681     }
   1682     LOG_VERBOSE(BSL_LS_BCM_PORT,
   1683                 (BSL_META_U(unit,
   1684                             "\n")));
   1685 
   1686     return SOC_E_NONE;
   1687 }
   1688 
   1689 /*
   1690  * Function:
   1691  *      _bcmi_xgs5_port_info_post_flex_clear
   1692  * Purpose:
   1693  *      Clear Post Flexport soc info in port_schedule_state.
   1694  * Parameters:
   1695  *      unit           - (IN) Unit number.
   1696  *      port_schedule_state  - (IN/OUT) soc_port_schedule_state_t.
   1697  * Returns:
   1698  *
   1699  * Note:
   1700  */
   1701 STATIC void
   1702 _bcmi_xgs5_port_info_post_flex_clear(int unit,
   1703                             soc_port_schedule_state_t *port_schedule_state)
   1704 {
   1705     sal_memset(&port_schedule_state->out_port_map, 0,
   1706                 sizeof(soc_port_map_type_t));
   1707 }
   1708 /*
   1709  * Function:
   1710  *      _bcmi_xgs5_port_linkscan_mode_validate
   1711  * Purpose:
   1712  *      Check logical ports to be 'detached' do not have linkscan mode set.
   1713  * Parameters:
   1714  *      unit     - (IN) Unit number.
   1715  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   1716  * Returns:
   1717  *      SOC_E_XXX
   1718  * Note:
   1719  */
   1720 STATIC int
   1721 _bcmi_xgs5_port_linkscan_mode_validate(int unit,
   1722                                 soc_port_schedule_state_t *port_schedule_state)
   1723 {
   1724     soc_port_resource_t *pr;
   1725     int nport = port_schedule_state->nport;
   1726     int i, rv;
   1727 
   1728     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   1729         if (pr->physical_port != -1) {
   1730             continue;
   1731         }
   1732 
   1733         if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL |
   1734                       BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   1735             rv = bcm_esw_linkscan_enable_port_get(unit, pr->logical_port);
   1736             if (rv == BCM_E_PORT) {
   1737                 return rv;
   1738             }
   1739             if (rv != BCM_E_DISABLED) {
   1740                 LOG_ERROR(BSL_LS_BCM_PORT,
   1741                           (BSL_META_U(unit,
   1742                                       "Linkscan mode needs to be "
   1743                                       "disabled on ports to be detached, "
   1744                                       "port=%d\n"),
   1745                            pr->logical_port));
   1746                 return BCM_E_BUSY;
   1747             }
   1748         }
   1749     }
   1750     return BCM_E_NONE;
   1751 }
   1752 
   1753 /*
   1754  * Function:
   1755  *      _bcmi_xgs5_port_range_validate
   1756  * Purpose:
   1757  *      Check logical port and physical port are in same pipe
   1758  * Parameters:
   1759  *      unit     - (IN) Unit number.
   1760  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   1761  * Returns:
   1762  *      SOC_E_XXX
   1763  * Note:
   1764  */
   1765 STATIC int
   1766 _bcmi_xgs5_port_range_validate(int unit,
   1767                                 soc_port_schedule_state_t *port_schedule_state)
   1768 {
   1769     soc_port_resource_t *pr;
   1770     int nport = port_schedule_state->nport;
   1771     bcmi_xgs5_dev_info_t *dev_info = BCMI_PORT_DRV_DEV_INFO(unit);
   1772     bcmi_xgs5_phy_port_t *phy_info;
   1773     int i;
   1774 
   1775     if (!dev_info->pipe_bound) {
   1776         return BCM_E_NONE;
   1777     }
   1778 
   1779     /* Check logical port and physical port are in same pipe */
   1780     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   1781         if (pr->physical_port == -1) {
   1782             continue;
   1783         }
   1784 
   1785         phy_info = &BCMI_PORT_DRV_PHY_INFO(unit, pr->physical_port);
   1786         if (pr->pipe != phy_info->pipe) {
   1787             LOG_ERROR(BSL_LS_BCM_PORT,
   1788                       (BSL_META_U(unit,
   1789                                   "Physical port %d and Logical port %d "
   1790                                   "are not in same pipe\n"),
   1791                        pr->physical_port, pr->logical_port));
   1792             return BCM_E_PORT;
   1793         }
   1794     }
   1795 
   1796     return BCM_E_NONE;
   1797 }
   1798 
   1799 /*
   1800  * Function:
   1801  *      _bcmi_xgs5_logic_ports_max_validate
   1802  * Purpose:
   1803  *      Check that number of logical ports do not exceed maximum allowed
   1804  * Parameters:
   1805  *      unit     - (IN) Unit number.
   1806  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   1807  * Returns:
   1808  *      SOC_E_XXX
   1809  * Note:
   1810  */
   1811 STATIC int
   1812 _bcmi_xgs5_logic_ports_max_validate(int unit,
   1813                                 soc_port_schedule_state_t *port_schedule_state)
   1814 {
   1815     soc_info_t *si = &SOC_INFO(unit);
   1816     soc_port_resource_t *pr;
   1817     int nport = port_schedule_state->nport;
   1818     int num_ports[SOC_MAX_NUM_PIPES];
   1819     int i;
   1820 
   1821     /* Get current num of logical ports per each pipe */
   1822     for (i = 0; i < SOC_MAX_NUM_PIPES; i++) {
   1823         SOC_PBMP_COUNT(si->pipe_pbm[i], num_ports[i]);
   1824     }
   1825 
   1826     /* Calculate num of logical ports after flexport */
   1827     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   1828         if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) {
   1829             num_ports[pr->pipe]--;
   1830         } else if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) {
   1831             num_ports[pr->pipe]--;
   1832         }
   1833     }
   1834 
   1835     for (i = 0; i < SOC_MAX_NUM_PIPES; i++) {
   1836         if (num_ports[i] > BCMI_PORT_DRV_DEV_INFO(unit)->ports_pipe_max[i]) {
   1837             LOG_ERROR(BSL_LS_BCM_PORT,
   1838                       (BSL_META_U(unit,
   1839                                   "Number of logical ports exceeds max "
   1840                                   "allowed: pipe=%d count=%d max_count=%d\n"),
   1841                        i, num_ports[i],
   1842                        BCMI_PORT_DRV_DEV_INFO(unit)->ports_pipe_max[i]));
   1843             return BCM_E_PARAM;
   1844         }
   1845     }
   1846 
   1847     return BCM_E_NONE;
   1848 }
   1849 
   1850 /*
   1851  * Function:
   1852  *      _bcmi_xgs5_port_mapping_validate
   1853  * Purpose:
   1854  *      Validate:
   1855  *      - Port numbers are available and mappings are not replicated.
   1856  * Parameters:
   1857  *      unit     - (IN) Unit number.
   1858  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   1859  * Returns:
   1860  *      SOC_E_XXX
   1861  * Note:
   1862  *      - Resource is not NULL.
   1863  *      - Assumes array order is correct
   1864  *        ('delete' operations are first in array).
   1865  */
   1866 STATIC int
   1867 _bcmi_xgs5_port_mapping_validate(int unit,
   1868                                 soc_port_schedule_state_t *port_schedule_state)
   1869 {
   1870     soc_info_t *si = &SOC_INFO(unit);
   1871     soc_port_resource_t *pr;
   1872     int nport = port_schedule_state->nport;
   1873     pbmp_t logic_pbmp;
   1874     uint8 lane_taken[SOC_MAX_NUM_PORTS];
   1875     int phy_port, logic_port, lane, i;
   1876 
   1877     SOC_PBMP_CLEAR(logic_pbmp);
   1878     sal_memset(lane_taken, 0, sizeof(lane_taken));
   1879 
   1880     /* Get current port assignment */
   1881     for (phy_port = 0; phy_port < SOC_MAX_NUM_PORTS; phy_port++) {
   1882         if (si->port_p2l_mapping[phy_port] == -1) {
   1883             continue;
   1884         }
   1885 
   1886 #ifdef BCM_TRIDENT3_SUPPORT
   1887         if (SOC_IS_TRIDENT3(unit)) {
   1888             if ((phy_port == 128) && SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), 130)) {
   1889                 continue;
   1890             }
   1891         }
   1892 #endif
   1893 
   1894         lane_taken[phy_port] = 1;
   1895         logic_port = si->port_p2l_mapping[phy_port];
   1896         SOC_PBMP_PORT_ADD(logic_pbmp, logic_port);
   1897 
   1898         for (lane = 1; lane < si->port_num_lanes[logic_port]; lane++) {
   1899             phy_port++;
   1900             if (phy_port >= SOC_MAX_NUM_PORTS) {
   1901                 break;
   1902             }
   1903             lane_taken[phy_port] = 1;
   1904         }
   1905     }
   1906 
   1907     /* First 'delete' mappings */
   1908     for (i = 0, pr = port_schedule_state->resource;
   1909          (i < nport) && (pr->physical_port == -1);
   1910          i++, pr++) {
   1911         phy_port = si->port_l2p_mapping[pr->logical_port];
   1912         if (phy_port == -1) {
   1913             LOG_ERROR(BSL_LS_BCM_PORT,
   1914                       (BSL_META_U(unit,
   1915                                   "Logical port %d is not currently mapped\n"),
   1916                        pr->logical_port));
   1917             return SOC_E_PARAM;
   1918         }
   1919 
   1920         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   1921             continue;
   1922         }
   1923 
   1924         lane_taken[phy_port] = 0;
   1925         SOC_PBMP_PORT_REMOVE(logic_pbmp, pr->logical_port);
   1926 
   1927         for (lane = 1; lane < si->port_num_lanes[pr->logical_port];
   1928              lane++) {
   1929             phy_port++;
   1930             lane_taken[phy_port] = 0;
   1931         }
   1932     }
   1933 
   1934     /* Continue with 'add' mappings in rest of array */
   1935     for (; i < nport; i++, pr++) {
   1936         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   1937             continue;
   1938         }
   1939         if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD |
   1940                         BCMI_XGS5_PORT_RESOURCE_OP_LANES |
   1941                         BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   1942             /* Check that port number is 'available' */
   1943             if (SOC_PBMP_MEMBER(logic_pbmp, pr->logical_port)) {
   1944                 LOG_ERROR(BSL_LS_BCM_PORT,
   1945                           (BSL_META_U(unit,
   1946                                       "Logical port %d is already mapped\n"),
   1947                            pr->logical_port));
   1948                 return BCM_E_BUSY;
   1949             }
   1950 
   1951             for (lane = 0; lane < pr->num_lanes; lane++) {
   1952                 phy_port = pr->physical_port + lane;
   1953                 if (lane_taken[phy_port]) {
   1954                     LOG_ERROR(BSL_LS_BCM_PORT,
   1955                               (BSL_META_U(unit,
   1956                                           "Physical port %d is already "
   1957                                           "taken by other port\n"),
   1958                                phy_port));
   1959                     return BCM_E_BUSY;
   1960                 }
   1961             }
   1962 
   1963             SOC_PBMP_PORT_ADD(logic_pbmp, pr->logical_port);
   1964             for (lane = 0; lane < pr->num_lanes; lane++) {
   1965                 phy_port = pr->physical_port + lane;
   1966                 lane_taken[phy_port] = 1;
   1967             }
   1968         }
   1969     }
   1970 
   1971     return BCM_E_NONE;
   1972 }
   1973 
   1974 /*
   1975  * Function:
   1976  *      _bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev
   1977  * Purpose:
   1978  *       Port configurations with a mixture of line-rate and oversub regular
   1979  *       ports are not supported.
   1980  *
   1981  * Parameters:
   1982  *      unit     - (IN) Unit number.
   1983  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   1984  * Returns:
   1985  *      BCM_E_XXX
   1986  */
   1987 STATIC int
   1988 _bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev(int unit,
   1989                                  soc_port_schedule_state_t *port_schedule_state)
   1990 {
   1991     soc_info_t *si = &SOC_INFO(unit);
   1992     soc_port_resource_t *pr;
   1993     int nport = port_schedule_state->nport;
   1994     int oversub_mode;
   1995     int i;
   1996 
   1997     oversub_mode = si->oversub_mode;
   1998 
   1999     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   2000         if (pr->physical_port == -1) {
   2001             continue;
   2002         }
   2003         if (oversub_mode ^ pr->oversub) {
   2004             LOG_ERROR(BSL_LS_BCM_PORT,
   2005                       (BSL_META_U(unit,
   2006                                   "-- Restriction: Port configurations "
   2007                                   "with a mixture of line-rate and oversub "
   2008                                   "ports are not supported\n")));
   2009             return BCM_E_PARAM;
   2010         }
   2011     }
   2012 
   2013     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2014                 (BSL_META_U(unit,
   2015                             "-- Flexport Restriction mix_lr_ovs_dev: PASS\n")));
   2016     return BCM_E_NONE;
   2017 }
   2018 
   2019 #if defined(BCM_TRIDENT3_SUPPORT)
   2020 /*
   2021  * Function:
   2022  *      _bcmi_xgs5_port_flex_restriction_pipe_lr_slot
   2023  * Purpose:
   2024  *       FlexPort cannot change the total calender length available per pipeline to
   2025  *       linerate ports.
   2026  *
   2027  * Parameters:
   2028  *      unit     - (IN) Unit number.
   2029  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2030  * Returns:
   2031  *      BCM_E_XXX
   2032  */
   2033 STATIC int
   2034 _bcmi_xgs5_port_flex_restriction_pipe_lr_slot(int unit,
   2035                                  soc_port_schedule_state_t *port_schedule_state)
   2036 {
   2037     soc_info_t *si = &SOC_INFO(unit);
   2038     soc_port_resource_t *pr;
   2039     int nport = port_schedule_state->nport;
   2040     int callen[SOC_MAX_NUM_PIPES] = {0};
   2041     int i, pipe, logic_port, speed, tdm_speed_min;
   2042     int eth = 1;
   2043     soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map;
   2044     uint32 cal = 0;
   2045 
   2046     tdm_speed_min = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_pipe_lr_bw_limit_checker_speed_min;
   2047 
   2048     if (SOC_PBMP_NOT_NULL(post_pi->hg2_pbm)) {
   2049         eth = 0;
   2050     }
   2051     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2052         callen[pipe] = 0;
   2053 
   2054         SOC_PBMP_ITER(si->pipe_pbm[pipe], logic_port) {
   2055             if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, logic_port) ||
   2056                 SOC_PBMP_MEMBER(si->oversub_pbm, logic_port)) {
   2057                 continue;
   2058             }
   2059             if (IS_CPU_PORT(unit, logic_port) ||
   2060                 IS_MANAGEMENT_PORT(unit, logic_port) ||
   2061                 IS_LB_PORT(unit, logic_port)) {
   2062                 continue;
   2063             }
   2064 
   2065             speed = si->port_init_speed[logic_port];
   2066             if (speed < tdm_speed_min) {
   2067                 speed = tdm_speed_min;
   2068             }
   2069             callen[pipe] += tdm_td3_cmn_get_speed_slots(speed);
   2070         }
   2071     }
   2072 
   2073     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   2074         if (pr->oversub == 1) {
   2075             continue;
   2076         }
   2077         if (pr->physical_port == -1 &&
   2078             pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL |
   2079                       BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   2080             pipe = si->port_pipe[pr->logical_port];
   2081             speed = si->port_init_speed[pr->logical_port];
   2082             if (speed < tdm_speed_min) {
   2083                 speed = tdm_speed_min;
   2084             }
   2085             callen[pipe] -= tdm_td3_cmn_get_speed_slots(speed);
   2086         } else if (pr->physical_port != -1 &&
   2087                    pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD|
   2088                              BCMI_XGS5_PORT_RESOURCE_OP_REMAP |
   2089                              BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)) {
   2090             speed = pr->speed;
   2091             if (speed < tdm_speed_min) {
   2092                 speed = tdm_speed_min;
   2093             }
   2094             callen[pr->pipe] += tdm_td3_cmn_get_speed_slots(speed);
   2095         } else if (pr->physical_port != -1 &&
   2096                    pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_LANES|
   2097                              BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX|
   2098                              BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) {
   2099             pipe = si->port_pipe[pr->logical_port];
   2100             speed = si->port_init_speed[pr->logical_port];
   2101             if (speed < tdm_speed_min) {
   2102                 speed = tdm_speed_min;
   2103             }
   2104             callen[pipe] -= tdm_td3_cmn_get_speed_slots(speed);
   2105             speed = pr->speed;
   2106             if (speed < tdm_speed_min) {
   2107                 speed = tdm_speed_min;
   2108             }
   2109             callen[pr->pipe] += tdm_td3_cmn_get_speed_slots(speed);
   2110         }
   2111     }
   2112     if (SOC_IS_TRIDENT3(unit)) {
   2113         soc_td3_max_lr_cal_len(unit, &cal, eth);
   2114     }
   2115     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2116         if (callen[pipe] > cal) {
   2117             LOG_ERROR(BSL_LS_BCM_PORT,
   2118                       (BSL_META_U(unit,
   2119                                   "-- Restriction: FlexPort requesting more calender slots"
   2120                                   "per pipeline than the available slots per pipe."
   2121                                   "pipe=%d slots req=%d max_slots=%d\n"),
   2122                        pipe, callen[pipe],cal));
   2123             return BCM_E_PARAM;
   2124         }
   2125     }
   2126 
   2127     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2128                 (BSL_META_U(unit,
   2129                          "-- Flexport restriction pipe_lr max calender length: PASS\n")));
   2130 
   2131     return BCM_E_NONE;
   2132 
   2133 }
   2134 #endif
   2135 
   2136 /*
   2137  * Function:
   2138  *      _bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth
   2139  * Purpose:
   2140  *       FlexPort cannot change the total throughput available per pipeline to
   2141  *       linerate ports.
   2142  *
   2143  * Parameters:
   2144  *      unit     - (IN) Unit number.
   2145  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2146  * Returns:
   2147  *      BCM_E_XXX
   2148  */
   2149 STATIC int
   2150 _bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth(int unit,
   2151                                  soc_port_schedule_state_t *port_schedule_state)
   2152 {
   2153     soc_info_t *si = &SOC_INFO(unit);
   2154     soc_port_resource_t *pr;
   2155     int nport = port_schedule_state->nport;
   2156     int bandwidth[SOC_MAX_NUM_PIPES] = {0};
   2157     int i, pipe, logic_port, speed, tdm_speed_min;
   2158 
   2159     tdm_speed_min = BCMI_PORT_DRV_DEV_INFO(unit)->tdm_pipe_lr_bw_limit_checker_speed_min;
   2160 
   2161     /* Get current bandwidth of line rate ports per pipe */
   2162     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2163         bandwidth[pipe] = 0;
   2164 
   2165         SOC_PBMP_ITER(si->pipe_pbm[pipe], logic_port) {
   2166             if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, logic_port) ||
   2167                 SOC_PBMP_MEMBER(si->oversub_pbm, logic_port)) {
   2168                 continue;
   2169             }
   2170             if (IS_CPU_PORT(unit, logic_port) ||
   2171                 IS_MANAGEMENT_PORT(unit, logic_port) ||
   2172                 IS_LB_PORT(unit, logic_port)) {
   2173                 continue;
   2174             }
   2175 
   2176             speed = si->port_init_speed[logic_port];
   2177             if (speed < tdm_speed_min) {
   2178                 speed = tdm_speed_min;
   2179             }
   2180             bandwidth[pipe] += speed;
   2181         }
   2182     }
   2183 
   2184     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   2185         if (pr->oversub == 1) {
   2186             continue;
   2187         }
   2188         if (pr->physical_port == -1 &&
   2189             pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL |
   2190                       BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   2191             pipe = si->port_pipe[pr->logical_port];
   2192             speed = si->port_init_speed[pr->logical_port];
   2193             if (speed < tdm_speed_min) {
   2194                 speed = tdm_speed_min;
   2195             }
   2196             bandwidth[pipe] -= speed;
   2197         } else if (pr->physical_port != -1 &&
   2198                    pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD|
   2199                              BCMI_XGS5_PORT_RESOURCE_OP_REMAP |
   2200                              BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)) {
   2201 
   2202             speed = pr->speed;
   2203             if (speed < tdm_speed_min) {
   2204                 speed = tdm_speed_min;
   2205             }
   2206             bandwidth[pr->pipe] += speed;
   2207         } else if (pr->physical_port != -1 &&
   2208                    pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_LANES|
   2209                              BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX|
   2210                              BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) {
   2211             pipe = si->port_pipe[pr->logical_port];
   2212             speed = si->port_init_speed[pr->logical_port];
   2213             if (speed < tdm_speed_min) {
   2214                 speed = tdm_speed_min;
   2215             }
   2216             bandwidth[pipe] -= speed;
   2217             speed = pr->speed;
   2218             if (speed < tdm_speed_min) {
   2219                 speed = tdm_speed_min;
   2220             }
   2221             bandwidth[pr->pipe] += speed;
   2222         }
   2223     }
   2224 
   2225     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   2226         if (bandwidth[pipe] > BCMI_PORT_DRV_DEV_INFO(unit)->pipe_lr_bw) {
   2227             LOG_ERROR(BSL_LS_BCM_PORT,
   2228                       (BSL_META_U(unit,
   2229                                   "-- Restriction: FlexPort cannot change "
   2230                                   "the total throughput available per "
   2231                                   "pipeline to linerate ports. "
   2232                                   "pipe=%d bandwidth=%d max_bandwidth=%d\n"),
   2233                        pipe, bandwidth[pipe],
   2234                        BCMI_PORT_DRV_DEV_INFO(unit)->pipe_lr_bw));
   2235             return BCM_E_PARAM;
   2236         }
   2237     }
   2238 
   2239     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2240                 (BSL_META_U(unit,
   2241                          "-- Flexport Restriction pipe_lr_bandwidth: PASS\n")));
   2242 
   2243 #if defined(BCM_TRIDENT3_SUPPORT)
   2244     if (SOC_IS_TRIDENT3(unit)) {
   2245         BCM_IF_ERROR_RETURN
   2246              (_bcmi_xgs5_port_flex_restriction_pipe_lr_slot(unit,
   2247                                                 port_schedule_state));
   2248     }
   2249 #endif
   2250     return BCM_E_NONE;
   2251 }
   2252 
   2253 /*
   2254  * Function:
   2255  *      _bcmi_xgs5_port_flex_restriction_speed_class
   2256  * Purpose:
   2257  *       No port configuration with more than Maximum port speed classes are
   2258  *       supported.
   2259  *
   2260  * Parameters:
   2261  *      unit     - (IN) Unit number.
   2262  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2263  * Returns:
   2264  *      BCM_E_XXX
   2265  */
   2266 STATIC int
   2267 _bcmi_xgs5_port_flex_restriction_speed_class(int unit,
   2268                                  soc_port_schedule_state_t *port_schedule_state)
   2269 {
   2270     uint32 speed_mask, mask, speed_class_num;
   2271     int i, speed;
   2272     soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map;
   2273     bcmi_xgs5_speed_class_t *speed_class;
   2274 #ifdef PORTMOD_PM8X50_SUPPORT
   2275     int speed_200 = 0, speed_400 = 0;
   2276 #endif
   2277 
   2278     mask = 0;
   2279     speed_mask = 0;
   2280     speed_class_num = 0;
   2281 
   2282     for (i = 0; i < SOC_MAX_NUM_PORTS; i++) {
   2283         /* coverity[overrun-local] */
   2284         if (post_pi->log_port_speed[i] <= 0 || IS_MANAGEMENT_PORT(unit,i)) {
   2285             continue;
   2286         }
   2287         speed = soc_port_speed_higig2eth(post_pi->log_port_speed[i]);
   2288         /* <=10G speeds in one speed class */
   2289         speed = speed < 10000 ? 10000 : speed;
   2290 #ifdef PORTMOD_PM8X50_SUPPORT
   2291         if (speed == 400000) {
   2292             speed_400 = 1;
   2293         } else if (speed == 200000) {
   2294             speed_200 = 1;
   2295         } else
   2296 #endif
   2297         {
   2298         mask = SOC_PA_SPEED(speed);
   2299 
   2300         if (!(speed_mask & mask)) {
   2301             speed_mask |= mask;
   2302             speed_class_num++;
   2303         }
   2304     }
   2305     }
   2306 
   2307 #ifdef PORTMOD_PM8X50_SUPPORT
   2308     speed_class_num += speed_200;
   2309     speed_class_num += speed_400;
   2310 #endif
   2311 
   2312     speed_class = &BCMI_PORT_DRV_DEV_INFO(unit)->speed_class;
   2313 
   2314     if (speed_class_num > speed_class->speed_class_num) {
   2315         LOG_ERROR(BSL_LS_BCM_PORT,
   2316                   (BSL_META_U(unit,
   2317                               "-- Restriction: No port configuration with more "
   2318                               "than %d port speed classes are supported. "
   2319                               "Speed class after flexport is %d\n"),
   2320                    speed_class->speed_class_num,
   2321                    speed_class_num));
   2322         return BCM_E_PARAM;
   2323     }
   2324 
   2325     if (speed_class->no_mix_speed_mask &&
   2326         ((speed_mask & speed_class->no_mix_speed_mask) ==
   2327          speed_class->no_mix_speed_mask)){
   2328         LOG_ERROR(BSL_LS_BCM_PORT,
   2329                   (BSL_META_U(unit,
   2330                               "-- Restriction: Not supported combination of "
   2331                               "speed classes. \n")));
   2332         return BCM_E_PARAM;
   2333     }
   2334 
   2335     if (BCMI_PORT_DRV_CALL(unit)->speed_mix_validate) {
   2336         BCM_IF_ERROR_RETURN
   2337             (BCMI_PORT_DRV_CALL(unit)->speed_mix_validate(unit, speed_mask));
   2338     }
   2339 
   2340     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2341                 (BSL_META_U(unit,
   2342                          "-- Flexport Restriction speed class: PASS\n")));
   2343     return BCM_E_NONE;
   2344 }
   2345 /*
   2346  * Function:
   2347  *      _bcmi_xgs5_port_flex_restriction_vco_validation
   2348  * Purpose:
   2349  *       Validate the following:
   2350  *       1. FEC, Link Training, Phy Lane Config in flex situations
   2351  *       2. VCO configuration is valid for Port macros
   2352  *
   2353  * Parameters:
   2354  *      unit     - (IN) Unit number.
   2355  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2356  * Returns:
   2357  *      BCM_E_XXX
   2358  */
   2359 STATIC int
   2360 _bcmi_xgs5_port_flex_restriction_vco_validation(int unit,
   2361                                  soc_port_schedule_state_t *port_schedule_state)
   2362 {
   2363     int i;
   2364     int autoneg;
   2365     int logical_port;
   2366     int existing_physical_port;
   2367     int all_autoneg = 1;
   2368     soc_port_resource_t *resource;
   2369     
   2370     for (i = 0; i < port_schedule_state->nport; i++) {
   2371         resource = &port_schedule_state->resource[i];
   2372 
   2373         /* Skip ports being deleted */
   2374         if (resource->physical_port == -1) {
   2375             continue;
   2376         }
   2377 
   2378         logical_port = resource->logical_port;
   2379         existing_physical_port = SOC_INFO(unit).port_l2p_mapping[logical_port];
   2380 
   2381         /* If the passed port already exists, and the lanes aren't changing,
   2382          * check it for autoneg.  We don't need to validate VCO if autoneg.
   2383          * resource_speed_set disables autoneg, so this code should only
   2384          * execute and skip VCO validation on a port update
   2385          */
   2386         if (existing_physical_port != -1 &&
   2387             resource->op == BCMI_XGS5_PORT_RESOURCE_OP_SPEED) {
   2388 
   2389             BCM_IF_ERROR_RETURN(bcm_esw_port_autoneg_get(unit,
   2390                                     resource->logical_port,
   2391                                     &autoneg));
   2392 
   2393             /* We don't need to do validation if the port is in autoneg */
   2394             if (autoneg == 1) {
   2395                 continue;
   2396             }
   2397         }
   2398 
   2399         /* Not all of the ports in port_schedule_state are autoneg, so
   2400          * port_schedule_state will need to be validated
   2401          */
   2402         all_autoneg = 0;
   2403 
   2404         /* Validate FEC */
   2405         if ((resource->fec_type >= socPortPhyFecCount) ||
   2406                 (resource->fec_type < socPortPhyFecNone)) {
   2407             LOG_ERROR(BSL_LS_BCM_PORT,
   2408                       (BSL_META_U(unit,
   2409                                   "-- Restriction: All ports must have a valid "
   2410                                   "FEC.\n")));
   2411 
   2412             return BCM_E_PARAM;
   2413         }
   2414 
   2415         /* Validate Link Training */
   2416         if ((resource->link_training > 1) ||
   2417                 (resource->link_training < 0)) {
   2418             LOG_ERROR(BSL_LS_BCM_PORT,
   2419                       (BSL_META_U(unit,
   2420                                   "-- Restriction: All ports must have "
   2421                                   "Link Training enabled or disabled.\n")));
   2422 
   2423             return BCM_E_PARAM;
   2424         }
   2425 
   2426         /* Phy Lane Config is validated inside Portmod since it's a bitmap
   2427          * and there isn't a clear range to check at this layer*/
   2428     }
   2429 
   2430     /* This info is filled in later, since it needs to be calculated. We'll use
   2431      * it later in PM VCO calculation
   2432      */
   2433     soc_esw_portctrl_pm_vco_store_clear(unit);
   2434 
   2435     /* all the ports in port_schedule_state are autoneg, so we don't want to
   2436      * do any validation
   2437      */
   2438     if (all_autoneg == 1) {
   2439         return BCM_E_NONE;
   2440     } else {
   2441         return soc_esw_portctrl_flex_vco_validation(unit, port_schedule_state);
   2442     }
   2443 }
   2444 
   2445 /*
   2446  * Function:
   2447  *      _bcmi_xgs5_port_flex_restriction_pm_sister_ports
   2448  * Purpose:
   2449  *       Validate sister ports:
   2450  *       1. All active ports in an oversub Port Macro must be the same speed
   2451  *       2. All ports in a port macro must be derived from a common VCO freq
   2452  *       3. Oversub and Line rate ports cannot coexist in one port macro
   2453  *       4. Ethernet and HiGig ports cannot coexist in one port macro
   2454  *
   2455  * Parameters:
   2456  *      unit     - (IN) Unit number.
   2457  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2458  *      mask     - (IN) Restriction mask
   2459  * Returns:
   2460  *      BCM_E_XXX
   2461  */
   2462 STATIC int
   2463 _bcmi_xgs5_port_flex_restriction_pm_sister_ports(int unit,
   2464                                  soc_port_schedule_state_t *port_schedule_state,
   2465                                  uint32 mask)
   2466 {
   2467     soc_port_resource_t *pr;
   2468     soc_port_map_type_t *post_pi = &port_schedule_state->out_port_map;
   2469     int nport, check_ovs_lr, check_ovs_mix_speed, check_pll, check_mix_encap, check_hg_mix;
   2470     int *sister_ports, len;
   2471     int logic_port, phy_port, blk, bindex, btype_idx, first_p, blktype;
   2472     int speed, first_speed, num_lanes, encap, first_encap, ovs, first_ovs, check_lr_mix_speed;
   2473     int mixed_sister_25_50_en, mixed_sister_25_10_en;
   2474     SHR_BITDCL blk_bmp[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)];
   2475     uint32 pll_div, first_pll_div;
   2476     int i, offset, rv;
   2477     uint32 speed_mask, mix_speed_mask, pm_mixed_pbm, pm_used_pbm;
   2478     uint32 mix_10G_1000MB_speed_mask, mix_25G_10G_1000MB_speed_mask;
   2479     soc_info_t *si = &SOC_INFO(unit);
   2480 
   2481     check_ovs_lr =
   2482         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_PM ? 1: 0;
   2483 
   2484     check_ovs_mix_speed =
   2485         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_OVS_MIX_SISTER ? 1 : 0;
   2486 
   2487     check_pll =
   2488         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_SINGLE_PLL ? 1 : 0;
   2489 
   2490     check_mix_encap =
   2491         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_MIX_ETH_HIGIG ? 1 : 0;
   2492 
   2493     check_hg_mix =
   2494         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_HG_MIX_SPEED ? 1 : 0;
   2495 
   2496     check_lr_mix_speed =
   2497         mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_LR_MIX_SISTER ? 1 : 0;
   2498 
   2499     mix_speed_mask = SOC_PA_SPEED_50GB | SOC_PA_SPEED_25GB | SOC_PA_SPEED_1000MB;
   2500     mix_10G_1000MB_speed_mask = SOC_PA_SPEED_10GB| SOC_PA_SPEED_1000MB | SOC_PA_SPEED_2500MB | SOC_PA_SPEED_5000MB;
   2501     mix_25G_10G_1000MB_speed_mask = SOC_PA_SPEED_25GB | SOC_PA_SPEED_10GB| SOC_PA_SPEED_1000MB;
   2502 
   2503     if (!check_ovs_lr && !check_ovs_mix_speed && !check_pll &&
   2504         !check_hg_mix && !check_lr_mix_speed &&
   2505         !check_mix_encap) {
   2506         return BCM_E_NONE;
   2507     }
   2508 
   2509     /* Alloc sister_ports[SOC_MAX_NUM_BLKS][BCMI_XGS5_PORTS_PER_PBLK] */
   2510     len = SOC_MAX_NUM_BLKS * BCMI_XGS5_PORTS_PER_PBLK * sizeof(int);
   2511     sister_ports = sal_alloc(len, "sister_ports");
   2512     if (sister_ports == NULL) {
   2513         return BCM_E_MEMORY;
   2514     }
   2515     sal_memset(sister_ports, -1, len);
   2516 
   2517     /* Get bitmap for block_id that have port flexing */
   2518     nport = port_schedule_state->nport;
   2519     SHR_BITCLR_RANGE(blk_bmp, 0, SOC_MAX_NUM_BLKS);
   2520     for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) {
   2521         if (pr->physical_port == -1) {
   2522             continue;
   2523         }
   2524         phy_port = pr->physical_port;
   2525         for (btype_idx = 0; btype_idx < SOC_DRIVER(unit)->port_num_blktype;
   2526              btype_idx++) {
   2527             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, btype_idx);
   2528             bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, btype_idx);
   2529             if ((blk < 0) || (bindex < 0)) {
   2530                 continue;
   2531             }
   2532             SHR_BITSET(blk_bmp, blk);
   2533         }
   2534     }
   2535 
   2536     /* Get sister ports for each block */
   2537     for (phy_port = 0;
   2538          phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max;
   2539          phy_port++) {
   2540 
   2541         if (SOC_PORT_BLOCK(unit, phy_port) < 0 &&
   2542             SOC_PORT_BINDEX(unit, phy_port) < 0) {
   2543             break;
   2544         }
   2545         for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype;
   2546              i++) {
   2547             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i);
   2548             bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i);
   2549             if ((blk < 0) || (bindex < 0)) {
   2550                 continue;
   2551             }
   2552             blktype = SOC_BLOCK_INFO(unit, blk).type;
   2553             if ((blktype == SOC_BLK_XLPORT) || (blktype == SOC_BLK_CLPORT)) {
   2554                 if (bindex > BCMI_XGS5_PORTS_PER_PBLK) {
   2555                     LOG_WARN(BSL_LS_BCM_PORT,
   2556                              (BSL_META_U(unit,
   2557                                          "Index of port within block(bindex) "
   2558                                          "exceeds the maximum.\n")));
   2559                     continue;
   2560                 }
   2561                 offset = blk * BCMI_XGS5_PORTS_PER_PBLK + bindex;
   2562                 sister_ports[offset] = phy_port;
   2563             }
   2564         }
   2565     }
   2566 
   2567     mixed_sister_25_50_en = si->os_mixed_sister_25_50_enable;
   2568 
   2569     /* For HX5 25g/10g mixed support is limited to LR ports only */
   2570     mixed_sister_25_10_en = SOC_IS_MAVERICK2(unit) ? 1 : 0;
   2571 
   2572     /* Check that sister ports (ports within a Port Macro) have the same VCO */
   2573     SHR_BIT_ITER(blk_bmp, SOC_MAX_NUM_BLKS, blk) {
   2574         first_p = 1;
   2575         speed = 0;
   2576         first_speed = 0;
   2577         pll_div = 0;
   2578         first_pll_div = 0;
   2579         encap = -1;
   2580         first_encap = -1;
   2581         ovs = -1;
   2582         first_ovs = -1;
   2583         speed_mask = 0;
   2584         pm_mixed_pbm = 0;
   2585         pm_used_pbm = 0;
   2586 
   2587         blktype = SOC_BLOCK_INFO(unit, blk).type;
   2588         if (!((blktype == SOC_BLK_XLPORT) || (blktype == SOC_BLK_CLPORT))) {
   2589             continue;
   2590         }
   2591 
   2592         for (i = 0; i < BCMI_XGS5_PORTS_PER_PBLK; i++) {
   2593             offset = blk * BCMI_XGS5_PORTS_PER_PBLK + i;
   2594 #ifdef BCM_TRIDENT3_SUPPORT
   2595             if (SOC_IS_TRIDENT3(unit)) {
   2596                 if ((offset == 135) && SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), 130)) {
   2597                     continue;
   2598                 }
   2599             }
   2600 #endif
   2601             phy_port = sister_ports[offset];
   2602             if (phy_port == -1) {
   2603                 LOG_ERROR(BSL_LS_BCM_PORT,
   2604                           (BSL_META_U(unit, "No sister ports.\n")));
   2605                 sal_free(sister_ports);
   2606                 return BCM_E_INTERNAL;
   2607             }
   2608             logic_port = post_pi->port_p2l_mapping[phy_port];
   2609             if (logic_port == -1) {
   2610                 continue;
   2611             }
   2612             /* Skip inactive ports */
   2613             if (post_pi->log_port_speed[logic_port] <= 0) {
   2614                 continue;
   2615             }
   2616 
   2617             speed = post_pi->log_port_speed[logic_port];
   2618             num_lanes = post_pi->port_num_lanes[logic_port];
   2619             encap = SOC_PBMP_MEMBER(post_pi->hg2_pbm, logic_port) ?
   2620                     SOC_ENCAP_HIGIG2 : SOC_ENCAP_IEEE;
   2621             ovs = SOC_PBMP_MEMBER(post_pi->oversub_pbm, logic_port) ? 1 : 0;
   2622             rv = soc_esw_portctrl_pll_div_get(unit, logic_port, phy_port, speed, num_lanes,
   2623                                               encap, &pll_div);
   2624             speed_mask |=  SOC_PA_SPEED(soc_port_speed_higig2eth(speed));
   2625             if (BCM_FAILURE(rv)) {
   2626                 LOG_VERBOSE(BSL_LS_BCM_PORT,
   2627                             (BSL_META_U(unit, "Failed to get PLL\n")));
   2628                 sal_free(sister_ports);
   2629                 return rv;
   2630             }
   2631             if (first_p) {
   2632                 first_pll_div = pll_div;
   2633                 first_encap = encap;
   2634                 first_speed = speed;
   2635                 first_ovs = ovs;
   2636                 first_p = 0;
   2637             }
   2638             if (ovs && mixed_sister_25_50_en) {
   2639                 speed_mask |= SOC_PA_SPEED(soc_port_speed_higig2eth(speed));
   2640                 pm_used_pbm |= 1 << ((phy_port - 1) % BCMI_XGS5_PORTS_PER_PBLK);
   2641                 if (SOC_PBMP_MEMBER(post_pi->physical_pbm, logic_port)) {
   2642                     if (SOC_PA_SPEED(soc_port_speed_higig2eth(speed))
   2643                         & SOC_PA_SPEED_25GB){
   2644                         pm_mixed_pbm |=
   2645                             1 << ((phy_port - 1) % BCMI_XGS5_PORTS_PER_PBLK);
   2646                     } else {
   2647                         LOG_ERROR(BSL_LS_SOC_PORT,
   2648                           (BSL_META_U(unit,
   2649                               "Only 25G port can with flag "
   2650                               "BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR, "
   2651                               "port %d with speed %d can't "
   2652                               "have flag "
   2653                               "BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR!\n"),
   2654                               logic_port, speed));
   2655                         sal_free(sister_ports);
   2656                         return SOC_E_CONFIG;
   2657                     }
   2658                 }
   2659             }
   2660             if (check_pll && (first_pll_div != pll_div)) {
   2661                 LOG_ERROR(BSL_LS_BCM_PORT,
   2662                           (BSL_META_U(unit,
   2663                                       "-- Restriction: All ports in a port "
   2664                                       "macro must be derived from a common VCO "
   2665                                       "frequency\n")));
   2666                 sal_free(sister_ports);
   2667                 return BCM_E_PARAM;
   2668             }
   2669             if (check_mix_encap && (first_encap != encap)) {
   2670                 LOG_ERROR(BSL_LS_BCM_PORT,
   2671                           (BSL_META_U(unit,
   2672                                       "-- Restriction: Ethernet and HiGig "
   2673                                       "ports cannot coexist in one port macro"
   2674                                       "\n")));
   2675                 sal_free(sister_ports);
   2676                 return BCM_E_PARAM;
   2677             }
   2678             if (check_ovs_lr && (first_ovs != ovs)) {
   2679                 LOG_ERROR(BSL_LS_BCM_PORT,
   2680                           (BSL_META_U(unit,
   2681                                       "-- Restriction: Oversub and Line-rate "
   2682                                       "ports cannot coexist in one port macro"
   2683                                       "\n")));
   2684                 sal_free(sister_ports);
   2685                 return BCM_E_PARAM;
   2686             }
   2687             if (ovs && check_ovs_mix_speed && (soc_port_speed_higig2eth(first_speed) !=
   2688                                                soc_port_speed_higig2eth(speed))) {
   2689                 /* Support 25G/50G mix sister speeds in a PM.
   2690                  * Only include 25G and 50G speeds.
   2691                  */
   2692                 if (mixed_sister_25_50_en &&
   2693                     (!(speed_mask & (~mix_speed_mask)))) {
   2694                     continue;
   2695                 } else if (!(speed_mask & (~mix_10G_1000MB_speed_mask))) {
   2696                     /* 10G and <10G is considered same speed from TDM perspective although
   2697                      * speed mask is for mixed speed 
   2698                      */
   2699                     continue;
   2700                 } else if (mixed_sister_25_10_en &&
   2701                            (!(speed_mask & (~mix_25G_10G_1000MB_speed_mask)))) {
   2702                     /* 25G/10G/1G mix supported */
   2703                     continue;
   2704                 } else {
   2705                     LOG_ERROR(BSL_LS_BCM_PORT,
   2706                               (BSL_META_U(unit,
   2707                                           "-- Restriction: Mixed-sister oversub "
   2708                                           "ports are not supported.\n")));
   2709                     sal_free(sister_ports);
   2710                     return BCM_E_PARAM;
   2711                 }
   2712             }
   2713             if ((encap == SOC_ENCAP_HIGIG2)  && (check_hg_mix) && (soc_port_speed_higig2eth(first_speed) !=
   2714                                                soc_port_speed_higig2eth(speed))) {
   2715                  LOG_ERROR(BSL_LS_BCM_PORT,
   2716                             (BSL_META_U(unit,
   2717                                        "-- Restriction:  different speed sub ports in HG2 "
   2718                                        "are not supported.\n")));
   2719                  sal_free(sister_ports);
   2720                  return BCM_E_PARAM;
   2721             }
   2722         }
   2723         if ((!ovs) && check_lr_mix_speed) {
   2724             if (((speed_mask & SOC_PA_SPEED_25GB) && (speed_mask & SOC_PA_SPEED_10GB)) ||
   2725                 ((speed_mask & SOC_PA_SPEED_25GB) && (speed_mask & SOC_PA_SPEED_1000MB)))  {
   2726                 LOG_ERROR(BSL_LS_BCMAPI_PORT,
   2727                           (BSL_META_U(unit,
   2728                                        "-- Restriction: Mixed-sister Linerate "
   2729                                        "10G/1G and 25G ports are not supported.\n")));
   2730                 sal_free(sister_ports);
   2731                 return BCM_E_PARAM;
   2732             }
   2733         }
   2734         if (ovs && mixed_sister_25_50_en) {
   2735             if (pm_mixed_pbm && (pm_used_pbm & 0xa)){
   2736                 LOG_ERROR(BSL_LS_BCMAPI_PORT,
   2737                           (BSL_META_U(unit,
   2738                                       "Mixed port speed configuration is wrong "
   2739                                       "on port macro %d!\n Either more than 2 "
   2740                                       "ports in this port macro or single lane "
   2741                                       "ports on 2/4th lane!\n"),
   2742                           SOC_BLOCK_NUMBER(unit, blk)));
   2743                 sal_free(sister_ports);
   2744                 return BCM_E_PARAM;
   2745             } else if (!pm_mixed_pbm && (speed_mask == mix_speed_mask)){
   2746                 LOG_ERROR(BSL_LS_BCMAPI_PORT,
   2747                           (BSL_META_U(unit,
   2748                                       "Mixed port speed bitmap not set on "
   2749                                       "25G ports of port macro %d!\n"),
   2750                           SOC_BLOCK_NUMBER(unit, blk)));
   2751                 sal_free(sister_ports);
   2752                 return BCM_E_PARAM;
   2753             }
   2754         }
   2755     }
   2756 
   2757     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2758                 (BSL_META_U(unit,
   2759                             "-- Flexport Restriction for sister ports: "
   2760                             "PASS\n")));
   2761     sal_free(sister_ports);
   2762     return BCM_E_NONE;
   2763 }
   2764 
   2765 /*
   2766  * Function:
   2767  *      _bcmi_xgs5_port_flex_restriction
   2768  * Purpose:
   2769  *      Validate that the given FlexPort operation is valid.
   2770  *
   2771  * Parameters:
   2772  *      unit     - (IN) Unit number.
   2773  *      port_schedule_state - (IN) soc_port_schedule_state_t.
   2774  * Returns:
   2775  *      BCM_E_XXX
   2776  */
   2777 STATIC int
   2778 _bcmi_xgs5_port_flex_restriction(int unit,
   2779                                  soc_port_schedule_state_t *port_schedule_state)
   2780 {
   2781     uint32 restrict_mask;
   2782 
   2783     restrict_mask = BCMI_PORT_DRV_DEV_INFO(unit)->restriction_mask;
   2784 
   2785     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2786                 (BSL_META_U(unit,
   2787                             "---- FLEXPORT RESTRICTION VALIDATE ----\n")));
   2788 
   2789     /*
   2790      * Restriction:
   2791      *   Port configurations with a mixture of line-rate and oversub regular
   2792      *   ports are not supported.
   2793      */
   2794     if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_DEV) {
   2795         BCM_IF_ERROR_RETURN
   2796             (_bcmi_xgs5_port_flex_restriction_mix_lr_ovs_dev(unit,
   2797                                                         port_schedule_state));
   2798     }
   2799 
   2800     /*
   2801      * Restriction:
   2802      *   FlexPort cannot change the total throughput available per pipeline to
   2803      *   linerate ports.
   2804      */
   2805     if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PIPE_BANDWIDTH) {
   2806         BCM_IF_ERROR_RETURN
   2807             (_bcmi_xgs5_port_flex_restriction_pipe_lr_bandwidth(unit,
   2808                                                         port_schedule_state));
   2809     }
   2810 
   2811     /*
   2812      * Restriction:
   2813      *   No port configuration with more than Maximum port speed classes are
   2814      *   supported.
   2815      */
   2816     if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_SPEED_CLASS) {
   2817         BCM_IF_ERROR_RETURN
   2818             (_bcmi_xgs5_port_flex_restriction_speed_class(unit,
   2819                                                         port_schedule_state));
   2820     }
   2821 
   2822     if (restrict_mask & BCMI_XGS5_FLEXPORT_RESTRICTION_PM_DOUBLE_PLL) {
   2823         BCM_IF_ERROR_RETURN
   2824             (_bcmi_xgs5_port_flex_restriction_vco_validation(unit,
   2825                                                        port_schedule_state));
   2826     } else {
   2827     /*
   2828      * Restriction:
   2829      *   Validate sister ports:
   2830      *     1. All active ports in an oversub Port Macro must be the same speed
   2831      *     2. All ports in a port macro must be derived from a common VCO freq
   2832      *     3. Oversub and Line rate ports cannot coexist in one port macro
   2833      *     4. Ethernet and HiGig ports cannot coexist in one port macro
   2834      */
   2835     BCM_IF_ERROR_RETURN
   2836         (_bcmi_xgs5_port_flex_restriction_pm_sister_ports(unit,
   2837                                                         port_schedule_state,
   2838                                                         restrict_mask));
   2839     }
   2840 
   2841     return BCM_E_NONE;
   2842 }
   2843 
   2844 /*
   2845  * Function:
   2846  *      _bcmi_xgs5_port_resource_validate
   2847  * Purpose:
   2848  *      - Check the port mapping is available.
   2849  *      - Validate that the given FlexPort configuration is valid.
   2850  *
   2851  * Parameters:
   2852  *      unit     - (IN) Unit number.
   2853  *      resource - (IN) bcm_port_resource_t
   2854  *      port_schedule_state - (OUT) soc_port_schedule_state_t.
   2855  * Returns:
   2856  *      BCM_E_XXX
   2857  */
   2858 STATIC int
   2859 _bcmi_xgs5_port_resource_validate(int unit,
   2860                                  soc_port_schedule_state_t *port_schedule_state)
   2861 {
   2862     int rv;
   2863 
   2864     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2865                 (BSL_META_U(unit,
   2866                             "==== PORT RESOURCE VALIDATE ====\n")));
   2867 
   2868     /* Check that ports to be 'detached' do not have linkscan mode set. */
   2869     BCM_IF_ERROR_RETURN
   2870         (_bcmi_xgs5_port_linkscan_mode_validate(unit, port_schedule_state));
   2871 
   2872     /* Check logical port and physical port are in same pipe */
   2873     BCM_IF_ERROR_RETURN
   2874         (_bcmi_xgs5_port_range_validate(unit, port_schedule_state));
   2875 
   2876     /* Check that number of logical ports do not exceed maximum allowed */
   2877     BCM_IF_ERROR_RETURN
   2878         (_bcmi_xgs5_logic_ports_max_validate(unit, port_schedule_state));
   2879 
   2880     /* Check port mapping */
   2881     BCM_IF_ERROR_RETURN
   2882         (_bcmi_xgs5_port_mapping_validate(unit, port_schedule_state));
   2883 
   2884     /* Flexport restrictions */
   2885 
   2886     /* Populate Post Flexport soc info in port_schedule_state->out_port_map,
   2887      * which will be used in the following validation. */
   2888     BCM_IF_ERROR_RETURN
   2889         (_bcmi_xgs5_port_info_post_flex(unit, port_schedule_state));
   2890 
   2891     if (BCMI_PORT_DRV_CALL(unit)->port_resource_validate) {
   2892         BCM_IF_ERROR_RETURN
   2893             (BCMI_PORT_DRV_CALL(unit)->port_resource_validate(unit,
   2894                                                          port_schedule_state));
   2895     }
   2896 
   2897     rv = _bcmi_xgs5_port_flex_restriction(unit, port_schedule_state);
   2898 
   2899     /* Clear the port_schedule_state->out_port_map */
   2900     _bcmi_xgs5_port_info_post_flex_clear(unit, port_schedule_state);
   2901 
   2902     BCM_IF_ERROR_RETURN(rv);
   2903 
   2904     return BCM_E_NONE;
   2905 }
   2906 
   2907 /*
   2908  * Function:
   2909  *      _bcmi_xgs5_port_pm_reset
   2910  * Purpose:
   2911  *      Reset newly bring up Port Macro
   2912  *
   2913  * Parameters:
   2914  *      unit        - (IN) Unit number.
   2915  *      add_bmp_pm  - (IN) Bitmap of Port Macros actived by Flexport.
   2916  *      add_pbm_phy - (IN) Bitmap of Physical ports actived by Flexport.
   2917  * Returns:
   2918  *      BCM_E_XXX
   2919  */
   2920 STATIC int
   2921 _bcmi_xgs5_port_pm_reset(int unit, SHR_BITDCL *add_bmp_pm, pbmp_t *add_pbm_phy)
   2922 {
   2923     soc_info_t *si = &SOC_INFO(unit);
   2924     int blk, bindex, phy_port, local_phy_port, tmp, block, is_clport, port_idx;
   2925     int pipe;
   2926     soc_reg_t reg;
   2927     uint64 rval64, val64_zero;
   2928     uint32 addr;
   2929     uint8 at;
   2930     int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   2931     static soc_field_t port_fields[4] = {
   2932         PORT0f, PORT1f, PORT2f, PORT3f
   2933     };
   2934 
   2935     LOG_VERBOSE(BSL_LS_BCM_PORT,
   2936                 (BSL_META_U(unit,
   2937                             "--- Port Macro Reset ---\n")));
   2938     COMPILER_64_ZERO(val64_zero);
   2939     SHR_BIT_ITER(add_bmp_pm, SOC_MAX_NUM_BLKS, blk) {
   2940         block = SOC_BLOCK_INFO(unit, blk).cmic;
   2941         is_clport = SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT ? 1 : 0;
   2942 
   2943         /*******************************
   2944          * Configure MAC Control
   2945          */
   2946         reg = is_clport ? CLPORT_MAC_CONTROLr : XLPORT_MAC_CONTROLr;
   2947         COMPILER_64_ZERO(rval64);
   2948         addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   2949                                 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   2950         SOC_REG_RST_VAL_GET(unit, reg, rval64);
   2951         soc_reg64_field32_set(unit, reg, &rval64, XMAC0_RESETf, 1);
   2952         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2953         sal_udelay(10);
   2954         soc_reg64_field32_set(unit, reg, &rval64, XMAC0_RESETf, 0);
   2955         if (is_clport &&
   2956             soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) {
   2957             /* Set PM interface to 16B */
   2958             soc_reg64_field32_set(unit, reg, &rval64, SYS_16B_INTF_MODEf, 1);
   2959         }
   2960         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2961 
   2962         /*******************************
   2963          * Reset TSC
   2964          */
   2965         if (soc_feature(unit, soc_feature_pm_refclk_master)) {
   2966             /* Port Macros act as refclk master are initialized in system
   2967              * init stage, no action during Flexport
   2968              */
   2969             if (SHR_BITGET(si->pm_ref_master_bitmap, blk)) {
   2970                 continue;
   2971             }
   2972         }
   2973 
   2974         reg = is_clport ? CLPORT_XGXS0_CTRL_REGr : XLPORT_XGXS0_CTRL_REGr;
   2975         COMPILER_64_ZERO(rval64);
   2976         addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   2977                                 SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   2978 
   2979         /* Set TSC in master mode */
   2980         SOC_REG_RST_VAL_GET(unit, reg, rval64);
   2981         soc_reg64_field32_set(unit, reg, &rval64, REFIN_ENf,
   2982                               SAL_BOOT_QUICKTURN ? 0 : 1);
   2983         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2984 
   2985         /* Deassert power down */
   2986         soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   2987         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2988         sal_usleep(sleep_usec);
   2989 
   2990         /* Reset XGXS */
   2991         soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   2992         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2993 
   2994         sal_usleep(sleep_usec + 10000);
   2995 
   2996         /* Bring XGXS out of reset */
   2997         soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1);
   2998         BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, rval64));
   2999         sal_usleep(sleep_usec);
   3000     }
   3001 
   3002     for (pipe = 0; pipe < si->num_pipe; pipe++) {
   3003         SOC_PBMP_ITER(add_pbm_phy[pipe], local_phy_port) {
   3004             phy_port = local_phy_port +
   3005                         BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe];
   3006 
   3007             for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   3008                  port_idx++) {
   3009 
   3010                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   3011                 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, port_idx);
   3012                 if (blk < 0) { /* End of block list of each port */
   3013                     break;
   3014                 }
   3015                 block = SOC_BLOCK_INFO(unit, blk).cmic;
   3016                 is_clport =
   3017                     SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT ? 1 : 0;
   3018 
   3019                 /* Initialize PORT MIB counter */
   3020                 reg = is_clport ? CLPORT_MIB_RESETr : XLPORT_MIB_RESETr;
   3021                 COMPILER_64_ZERO(rval64);
   3022                 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3023                                         SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   3024                 soc_reg64_field32_set(unit, reg, &rval64, CLR_CNTf, (1 < bindex));
   3025                 BCM_IF_ERROR_RETURN
   3026                     (_soc_reg64_set(unit, block, at, addr, rval64));
   3027                 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, val64_zero));
   3028 
   3029                 /* CLPORT_MODE_REG is programmed in Flexport Tier1 API */
   3030 
   3031                 reg = is_clport ? CLPORT_SOFT_RESETr : XLPORT_SOFT_RESETr;
   3032                 COMPILER_64_ZERO(rval64);
   3033                 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3034                                         SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   3035                 /* Assert CLPORT/XLPORT soft reset */
   3036                 soc_reg64_field32_set(unit, reg, &rval64, port_fields[bindex], 1);
   3037                 BCM_IF_ERROR_RETURN
   3038                     (_soc_reg64_set(unit, block, at, addr, rval64));
   3039                 /* De-assert CLPORT/XLPORT soft reset */
   3040                 BCM_IF_ERROR_RETURN(_soc_reg64_set(unit, block, at, addr, val64_zero));
   3041 
   3042                 reg = is_clport ? CLPORT_ENABLE_REGr : XLPORT_ENABLE_REGr;
   3043                 COMPILER_64_ZERO(rval64);
   3044                 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3045                                         SOC_REG_ADDR_OPTION_NONE, &tmp, &at);
   3046                 BCM_IF_ERROR_RETURN
   3047                     (_soc_reg64_get(unit, block, at, addr, &rval64));
   3048                 soc_reg64_field32_set(unit, reg, &rval64, port_fields[bindex], 1);
   3049                 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3050                                         SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   3051                 BCM_IF_ERROR_RETURN
   3052                     (_soc_reg64_set(unit, block, at, addr, rval64));
   3053 
   3054                 reg = is_clport ? CLPORT_POWER_SAVEr : XLPORT_POWER_SAVEr;
   3055                 COMPILER_64_ZERO(rval64);
   3056                 addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0,
   3057                                         SOC_REG_ADDR_OPTION_WRITE, &tmp, &at);
   3058                 soc_reg64_field32_set(unit, reg, &rval64, XPORT_CORE0f, 0);
   3059                 BCM_IF_ERROR_RETURN
   3060                     (_soc_reg64_set(unit, block, at, addr, rval64));
   3061             }
   3062         }
   3063     }
   3064     return BCM_E_NONE;
   3065 }
   3066 
   3067 /*
   3068  * Function:
   3069  *      _bcmi_xgs5_port_ipep_reconfigure
   3070  * Purpose:
   3071  *      Update the port related reg/mem in IP/EP after flexport
   3072  *
   3073  * Parameters:
   3074  *      unit        - (IN) Unit number.
   3075  *      add_pbm_log - (IN) Bitmap of newly added logical ports.
   3076  *      del_pbm_log - (IN) Bitmap of deleted logical ports.
   3077  * Returns:
   3078  *      BCM_E_XXX
   3079  */
   3080 STATIC int
   3081 _bcmi_xgs5_port_ipep_reconfigure(int unit,
   3082                                  pbmp_t add_pbm_log,
   3083                                  pbmp_t del_pbm_log)
   3084 {
   3085     int logic_port, is_clport, is_cdport;
   3086     soc_reg_t reg;
   3087     uint32 rval;
   3088     uint32 entry[SOC_MAX_MEM_WORDS];
   3089     pbmp_t pbmp;
   3090     int cntmaxsize;
   3091 
   3092     LOG_VERBOSE(BSL_LS_BCM_PORT,
   3093                 (BSL_META_U(unit,
   3094                             "--- Port IP/EP Reconfigure ---\n")));
   3095 
   3096     SOC_PBMP_ITER(add_pbm_log, logic_port) {
   3097         is_clport = IS_CL_PORT(unit, logic_port);
   3098         is_cdport = IS_CD_PORT(unit, logic_port);
   3099 
   3100         reg = INVALIDr;
   3101         if (is_cdport) {
   3102             reg = INVALIDr;
   3103         } else if (is_clport) {
   3104             reg = CLPORT_CNTMAXSIZEr;
   3105         } else if (IS_QSGMII_PORT(unit, logic_port)) {
   3106             reg = GPORT_CNTMAXSIZEr;
   3107         } else {
   3108             reg = XLPORT_CNTMAXSIZEr;
   3109         }
   3110 
   3111         if (reg != INVALIDr) {
   3112         rval = 0;
   3113         cntmaxsize = is_clport ? BCMI_PORT_DRV_DEV_INFO(unit)->cntmaxsize_cl :
   3114                                  BCMI_PORT_DRV_DEV_INFO(unit)->cntmaxsize_xl;
   3115         soc_reg_field_set(unit, reg, &rval, CNTMAXSIZEf, cntmaxsize);
   3116         BCM_IF_ERROR_RETURN
   3117             (soc_reg32_set(unit, reg, logic_port, 0, rval));
   3118         }
   3119 
   3120         reg = INVALIDr;
   3121         if (is_cdport) {
   3122             reg = CDPORT_FLOW_CONTROL_CONFIGr;
   3123         } else if (is_clport) {
   3124             reg = CLPORT_FLOW_CONTROL_CONFIGr;
   3125         } else {
   3126             reg = XLPORT_FLOW_CONTROL_CONFIGr;
   3127         }
   3128 
   3129         rval = 0;
   3130         soc_reg_field_set(unit, reg, &rval, MERGE_MODE_ENf, 1);
   3131         BCM_IF_ERROR_RETURN
   3132             (soc_reg32_set(unit, reg, logic_port, 0, rval));
   3133         sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
   3134         if (IS_HG_PORT(unit, logic_port)) {
   3135             soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
   3136         }
   3137         BCM_IF_ERROR_RETURN
   3138             (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, logic_port,
   3139                            entry));
   3140 #ifdef BCM_TRIDENT2PLUS_SUPPORT
   3141         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   3142             if (soc_feature(unit, soc_feature_egr_all_profile)) {
   3143                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit,
   3144                         logic_port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 1));
   3145 
   3146                 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit,
   3147                         logic_port, EGR_VLAN_CONTROL_1m, VT_MISS_UNTAGf, 0));
   3148 
   3149             } else {
   3150                 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
   3151                         EGR_VLAN_CONTROL_1m, logic_port, REMARK_OUTER_DOT1Pf, 1));
   3152 
   3153                 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit,
   3154                         EGR_VLAN_CONTROL_1m, logic_port, VT_MISS_UNTAGf, 0));
   3155            }
   3156         } else
   3157 #endif
   3158         {
   3159             reg = EGR_VLAN_CONTROL_1r;
   3160             rval = 0;
   3161             if (SOC_REG_FIELD_VALID(unit, reg, VT_MISS_UNTAGf)) {
   3162             soc_reg_field_set(unit, reg, &rval, VT_MISS_UNTAGf, 0);
   3163             }
   3164             if (SOC_REG_FIELD_VALID(unit, reg, REMARK_OUTER_DOT1Pf)) {
   3165             soc_reg_field_set(unit, reg, &rval, REMARK_OUTER_DOT1Pf, 1);
   3166             }
   3167             BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, logic_port, rval));
   3168         }
   3169     }
   3170 
   3171     BCM_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
   3172                                      MEM_BLOCK_ANY, 0, &entry));
   3173     soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, &entry,
   3174                            BITMAPf, &pbmp);
   3175     SOC_PBMP_REMOVE(pbmp, del_pbm_log);
   3176     SOC_PBMP_OR(pbmp, add_pbm_log);
   3177     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry,
   3178                            BITMAPf, &pbmp);
   3179     BCM_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
   3180                                       MEM_BLOCK_ANY, 0, &entry));
   3181 
   3182     return BCM_E_NONE;
   3183 }
   3184 
   3185 #if 0
   3186 /*
   3187  * Function:
   3188  *      _bcmi_xgs5_port_soc_info_ptype_update
   3189  * Purpose:
   3190  *      Update the SOC_INFO port type bitmaps and block information.
   3191  * Parameters:
   3192  *      unit                    - (IN) Unit number.
   3193  *      port_schedule_state     - (IN) port_schedule_state
   3194  *
   3195  *
   3196  * Returns:
   3197  *      SOC_E_XXX
   3198  * Notes:
   3199  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
   3200  *      locks are taken.
   3201  */
   3202 STATIC int
   3203 _bcmi_xgs5_port_soc_info_ptype_update(int unit)
   3204 {
   3205     soc_info_t *si = &SOC_INFO(unit);
   3206     int logic_port, phy_port, port_idx, max_port;
   3207     int blk, bindex;
   3208 
   3209     /*
   3210      * Update ptype information
   3211      */
   3212 #define RECONFIGURE_PORT_TYPE_INFO(ptype)                   \
   3213     si->ptype.num = 0;                                      \
   3214     si->ptype.min = si->ptype.max = -1;                     \
   3215     PBMP_ITER(si->ptype.bitmap, logic_port) {               \
   3216         si->port_offset[logic_port] = si->ptype.num;        \
   3217         si->ptype.port[si->ptype.num++] = logic_port;       \
   3218         if (si->ptype.min < 0) {                            \
   3219             si->ptype.min = logic_port;                     \
   3220         }                                                   \
   3221         if (logic_port > si->ptype.max) {                   \
   3222             si->ptype.max = logic_port;                     \
   3223         }                                                   \
   3224     }
   3225 
   3226     RECONFIGURE_PORT_TYPE_INFO(ge);
   3227     RECONFIGURE_PORT_TYPE_INFO(xe);
   3228     RECONFIGURE_PORT_TYPE_INFO(c);
   3229     RECONFIGURE_PORT_TYPE_INFO(ce);
   3230     RECONFIGURE_PORT_TYPE_INFO(xl);
   3231     RECONFIGURE_PORT_TYPE_INFO(cl);
   3232     RECONFIGURE_PORT_TYPE_INFO(gx);
   3233     RECONFIGURE_PORT_TYPE_INFO(ether);
   3234     RECONFIGURE_PORT_TYPE_INFO(hg);
   3235     RECONFIGURE_PORT_TYPE_INFO(st);
   3236     RECONFIGURE_PORT_TYPE_INFO(port);
   3237     RECONFIGURE_PORT_TYPE_INFO(all);
   3238 
   3239 #undef  RECONFIGURE_PORT_TYPE_INFO
   3240 
   3241 
   3242     /*
   3243      * Update block port
   3244      * Use first logical port on block (logic follows ESW driver
   3245      * soc_info_config().
   3246      */
   3247     for (phy_port = 0; ; phy_port++) {
   3248 
   3249         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
   3250         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
   3251         if (blk < 0 && bindex < 0) { /* End of port list */
   3252             break;
   3253         }
   3254 
   3255         logic_port = si->port_p2l_mapping[phy_port];
   3256         if (logic_port < 0) {
   3257             continue;
   3258         }
   3259 
   3260         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   3261              port_idx++) {
   3262             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   3263             if (blk < 0) { /* End of block list of each port */
   3264                 break;
   3265             }
   3266 
   3267             if (si->block_port[blk] < 0) {
   3268                 si->block_port[blk] = logic_port;
   3269             }
   3270         }
   3271     }
   3272 
   3273     /* Update MAX_PORT(unit) */
   3274     max_port = -1;
   3275     for (phy_port = 0; phy_port < BCMI_PORT_DRV_DEV_INFO(unit)->phy_ports_max;
   3276          phy_port++) {
   3277         logic_port = si->port_p2l_mapping[phy_port];
   3278         if (logic_port < 0) {
   3279             continue;
   3280         }
   3281         if (max_port < logic_port) {
   3282             max_port = logic_port;
   3283         }
   3284     }
   3285     si->port_num = max_port + 1;
   3286 
   3287     /* Update user port mappings (includes port names update) */
   3288     soc_esw_dport_init(unit);
   3289 
   3290     return SOC_E_NONE;
   3291 }
   3292 #endif
   3293 
   3294 /*
   3295  * Function:
   3296  *      _soc_xgs5_port_soc_info_ptype_block_add
   3297  * Purpose:
   3298  *      Set the port type bitmaps and block information in SOC_INFO
   3299  *      for ports to be configured during the FlexPort operation.
   3300  * Parameters:
   3301  *      unit           - (IN) Unit number.
   3302  *      post_count     - (IN) Array size for post-FlexPort array.
   3303  *      post_resource  - (IN) Pre-FlexPort configuration array.
   3304  * Returns:
   3305  *      SOC_E_XXX
   3306  * Notes:
   3307  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
   3308  *      locks are taken.
   3309  */
   3310 STATIC int
   3311 _bcmi_xgs5_port_soc_info_ptype_block_add(int unit,
   3312                                 soc_port_schedule_state_t *port_schedule_state)
   3313 {
   3314     soc_info_t *si = &SOC_INFO(unit);
   3315     soc_port_resource_t *resource, *pr;
   3316     int logic_port, phy_port, port_idx;
   3317     int blk, bindex, blktype, old_blktype;
   3318     int nport, i;
   3319 
   3320     nport = port_schedule_state->nport;
   3321     resource = port_schedule_state->resource;
   3322 
   3323     /*
   3324      * Add to port type bitmaps and block information
   3325      */
   3326     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   3327         if (pr->physical_port == -1) {
   3328             continue;
   3329         }
   3330 
   3331         logic_port = pr->logical_port;
   3332         phy_port = pr->physical_port;
   3333 
   3334         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
   3335         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
   3336         if (blk < 0 && bindex < 0) { /* End of regsfile port list */
   3337             continue;
   3338         }
   3339 
   3340         blktype = -1;
   3341         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   3342              port_idx++) {
   3343 
   3344             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   3345             if (blk < 0) { /* End of block list of each port */
   3346                 break;
   3347             }
   3348 
   3349             old_blktype = blktype;
   3350             blktype = SOC_BLOCK_INFO(unit, blk).type;
   3351 
   3352             switch (blktype) {
   3353             case SOC_BLK_CDPORT:
   3354                 SOC_PBMP_PORT_ADD(si->cd.bitmap, logic_port);
   3355                 if ((pr->encap == SOC_ENCAP_IEEE) &&
   3356                     ((si->port_init_speed[logic_port] == 200000) ||
   3357                     (si->port_init_speed[logic_port] == 400000))) { /* CDE */
   3358                     SOC_PBMP_PORT_ADD(si->cde.bitmap, logic_port);
   3359                     SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port);
   3360                     SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port);
   3361                     SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port);
   3362                     break;
   3363                 }
   3364                 /* fall through to case for SOC_BLK_CLPORT */
   3365 
   3366             case SOC_BLK_CLPORT:
   3367                 if (blktype == SOC_BLK_CLPORT) {
   3368                 SOC_PBMP_PORT_ADD(si->cl.bitmap, logic_port);
   3369                 }
   3370                 if (si->port_init_speed[logic_port] >= 100000) {
   3371                     /* Catch both CE and HG ports */
   3372                     SOC_PBMP_PORT_ADD(si->c.bitmap, logic_port);
   3373                 }
   3374                 if ((pr->encap == SOC_ENCAP_IEEE) &&
   3375                     ((si->port_init_speed[logic_port] == 100000) ||
   3376                     (si->port_init_speed[logic_port] == 120000))) { /* CE */
   3377                     SOC_PBMP_PORT_ADD(si->ce.bitmap, logic_port);
   3378                     SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port);
   3379                     SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port);
   3380                     SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port);
   3381                     break;
   3382                 }
   3383                 /* fall through to case for SOC_BLK_XLPORT */
   3384                 /* coverity[fallthrough: FALSE] */
   3385 
   3386             case SOC_BLK_XLPORT:
   3387                 if (!si->port_init_speed[logic_port]) {
   3388                     return SOC_E_INTERNAL;
   3389                 }
   3390 
   3391                 /* For 100G or more, use CLPORT block type */
   3392                 if ((SOC_BLK_XLPORT == blktype) &&
   3393                     (si->port_init_speed[logic_port] >= 100000)) {
   3394                     blktype = old_blktype;
   3395                     break;
   3396                 }
   3397 
   3398                 if (si->port_init_speed[logic_port] < 10000) {    /* GE */
   3399                     SOC_PBMP_PORT_ADD(si->ge.bitmap, logic_port);
   3400                     if (pr->encap == SOC_ENCAP_HIGIG2_LITE) {
   3401                         /* GE in Higig Lite Mode. Higig Like stack capable
   3402                          * port */
   3403                         SOC_PBMP_PORT_ADD(si->st.bitmap, logic_port);
   3404                         SOC_PBMP_PORT_ADD(si->hl.bitmap, logic_port);
   3405                     } else {
   3406                         SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port);
   3407                     }
   3408                 } else if (pr->encap == SOC_ENCAP_IEEE) {  /* XE */
   3409                     SOC_PBMP_PORT_ADD(si->xe.bitmap, logic_port);
   3410                     SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port);
   3411                 } else {                                   /* HG */
   3412                     SOC_PBMP_PORT_ADD(si->hg.bitmap, logic_port);
   3413                     SOC_PBMP_PORT_ADD(si->st.bitmap, logic_port);
   3414                     /* Name is default to hg by lookup above */
   3415                 }
   3416 
   3417                 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port);
   3418                 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port);
   3419 
   3420                 /*
   3421                  * Part of legacy code to add to these extra bitmaps
   3422                  */
   3423                 if (!IS_CL_PORT(unit, logic_port) &&
   3424                     !IS_CD_PORT(unit, logic_port)) {
   3425                     SOC_PBMP_PORT_ADD(si->xl.bitmap, logic_port);
   3426                 }
   3427                 if (!SOC_IS_HELIX5(unit)) {
   3428                     SOC_PBMP_PORT_ADD(si->gx.bitmap, logic_port);
   3429                 }
   3430                 break;
   3431             case SOC_BLK_GXPORT:
   3432                 SOC_PBMP_PORT_ADD(si->ether.bitmap, logic_port);
   3433                 if (si->port_init_speed[logic_port] < 10000) {
   3434                     SOC_PBMP_PORT_ADD(si->ge.bitmap, logic_port);
   3435                 }
   3436                 SOC_PBMP_PORT_ADD(si->port.bitmap, logic_port);
   3437                 SOC_PBMP_PORT_ADD(si->all.bitmap, logic_port);
   3438                 SOC_PBMP_PORT_ADD(si->gx.bitmap, logic_port);
   3439             default:
   3440                 break;
   3441             }
   3442 
   3443             /* Update block information */
   3444             si->block_valid[blk] += 1;
   3445 
   3446             if (si->block_port[blk] < 0) {
   3447                 si->block_port[blk] = logic_port;
   3448             }
   3449             SOC_PBMP_PORT_ADD(si->block_bitmap[blk], logic_port);
   3450 
   3451         } /* For each block in the given port */
   3452 
   3453         si->port_type[logic_port] = blktype;
   3454 
   3455     } /* For each port */
   3456 
   3457     BCM_IF_ERROR_RETURN
   3458         (_bcmi_xgs5_port_soc_info_ptype_update(unit));
   3459 
   3460     return SOC_E_NONE;
   3461 }
   3462 
   3463 /*
   3464  * Function:
   3465  *      _soc_xgs5_port_soc_info_ptype_block_delete
   3466  * Purpose:
   3467  *      Clear the port type bitmaps and block information in SOC_INFO
   3468  *      for ports to be removed during the FlexPort operation.
   3469  * Parameters:
   3470  *      unit           - (IN) Unit number.
   3471  * Returns:
   3472  *      SOC_E_XXX
   3473  * Notes:
   3474  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
   3475  *      locks are taken.
   3476  */
   3477 STATIC int
   3478 _bcmi_xgs5_port_soc_info_ptype_block_delete(int unit,
   3479                                 soc_port_schedule_state_t *port_schedule_state)
   3480 {
   3481     soc_info_t *si = &SOC_INFO(unit);
   3482     soc_port_resource_t *resource, *pr;
   3483     soc_port_map_type_t *pre_port_map;
   3484     int logic_port, phy_port, port_idx;
   3485     int blk, bindex;
   3486     int nport, i;
   3487 
   3488     nport = port_schedule_state->nport;
   3489     resource = port_schedule_state->resource;
   3490     pre_port_map = &port_schedule_state->in_port_map;
   3491 
   3492     /*
   3493      * Clear port bitmaps and block information
   3494      */
   3495     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   3496         /*
   3497          * If not a delete entry, don't do anything
   3498          * If 'inactive' flag, don't do anything
   3499          */
   3500         if (pr->physical_port != -1 ||
   3501             ((pr->flags & SOC_PORT_RESOURCE_I_MAP) &&
   3502              (pr->op == BCMI_XGS5_PORT_RESOURCE_OP_DEL))) {
   3503             continue;
   3504         }
   3505 
   3506         logic_port = pr->logical_port;
   3507         phy_port = pre_port_map->port_l2p_mapping[logic_port];
   3508 
   3509         /*
   3510          * Clear port from all possible port bitmaps where a flexed port
   3511          * can be a member of.
   3512          */
   3513         SOC_PBMP_PORT_REMOVE(si->cde.bitmap, logic_port);
   3514         SOC_PBMP_PORT_REMOVE(si->ge.bitmap, logic_port);
   3515         SOC_PBMP_PORT_REMOVE(si->xe.bitmap, logic_port);
   3516         SOC_PBMP_PORT_REMOVE(si->c.bitmap, logic_port);
   3517         SOC_PBMP_PORT_REMOVE(si->ce.bitmap, logic_port);
   3518         SOC_PBMP_PORT_REMOVE(si->xl.bitmap, logic_port);
   3519         SOC_PBMP_PORT_REMOVE(si->cl.bitmap, logic_port);
   3520         SOC_PBMP_PORT_REMOVE(si->gx.bitmap, logic_port);
   3521         SOC_PBMP_PORT_REMOVE(si->ether.bitmap, logic_port);
   3522         SOC_PBMP_PORT_REMOVE(si->hg.bitmap, logic_port);
   3523         SOC_PBMP_PORT_REMOVE(si->st.bitmap, logic_port);
   3524         SOC_PBMP_PORT_REMOVE(si->port.bitmap, logic_port);
   3525         SOC_PBMP_PORT_REMOVE(si->all.bitmap, logic_port);
   3526 
   3527         if (phy_port == -1) {
   3528             continue;
   3529         }
   3530 
   3531         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
   3532         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
   3533         if (blk < 0 && bindex < 0) { /* End of regsfile port list */
   3534             continue;
   3535         }
   3536 
   3537         /* Clear block information */
   3538         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   3539              port_idx++) {
   3540 
   3541             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   3542             if (blk < 0) { /* End of block list of each port */
   3543                 break;
   3544             }
   3545 
   3546             /* Update block information */
   3547             if (si->block_valid[blk] > 0) {
   3548                 si->block_valid[blk] -= 1;
   3549             }
   3550             if (si->block_port[blk] == logic_port) {
   3551                 si->block_port[blk] = REG_PORT_ANY;
   3552             }
   3553             SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk], logic_port);
   3554 
   3555         } /* For each block in the given port */
   3556 
   3557         si->port_type[logic_port] = 0;
   3558         si->port_offset[logic_port] = 0;
   3559 
   3560     } /* For each port */
   3561 
   3562     return SOC_E_NONE;
   3563 }
   3564 
   3565 
   3566 
   3567 /*
   3568  * Function:
   3569  *      _soc_xgs5_port_soc_counter_add
   3570  * Purpose:
   3571  *      Add ports to SOC counter map.
   3572  * Parameters:
   3573  *      unit           - (IN) Unit number.
   3574  *      post_count     - (IN) Array size.
   3575  *      post_resource  - (IN) Array of ports to add. * Returns:
   3576  *      SOC_E_XXX * Notes:
   3577  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
   3578  *      locks are taken.
   3579  */
   3580 STATIC int
   3581 _bcmi_xgs5_port_soc_counter_add(int unit,
   3582                            soc_port_schedule_state_t *port_schedule_state)
   3583 {
   3584     soc_control_t *soc = SOC_CONTROL(unit);
   3585     soc_port_resource_t *resource, *pr;
   3586     soc_counter_non_dma_t *non_dma;
   3587     int i, nport, dma_id;
   3588     int phy_port;
   3589     int logic_port;
   3590     int blk;
   3591     int bindex;
   3592     int blktype;
   3593     int port_idx;
   3594     soc_ctr_type_t ctype;
   3595     int rv = BCM_E_NONE;
   3596     
   3597     nport = port_schedule_state->nport;
   3598     resource = port_schedule_state->resource;
   3599 
   3600     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   3601 
   3602         /* Skip 'delete' ports */
   3603         if (pr->physical_port == -1) {
   3604             continue;
   3605         }
   3606 
   3607         logic_port = pr->logical_port;
   3608         phy_port = pr->physical_port;
   3609         blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0);
   3610         bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0);
   3611         if (blk < 0 && bindex < 0) { /* End of regsfile port list */
   3612             continue;
   3613         }
   3614         for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   3615              port_idx++) {
   3616             blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   3617             if (blk < 0) { /* End of block list of each port */
   3618                 break;
   3619             }
   3620             blktype = SOC_BLOCK_INFO(unit, blk).type;
   3621             switch (blktype) {
   3622             case SOC_BLK_CDPORT:
   3623                 ctype = SOC_CTR_TYPE_CD;
   3624                 break;
   3625             case SOC_BLK_CLPORT:
   3626                 ctype = SOC_CTR_TYPE_CE;
   3627                 break;
   3628             case SOC_BLK_XLPORT:
   3629             case SOC_BLK_GXPORT:
   3630                 if(IS_QSGMII_PORT(unit, logic_port)) {
   3631                     ctype = SOC_CTR_TYPE_GE;
   3632                 } else {
   3633                     ctype = SOC_CTR_TYPE_XE;
   3634                 }
   3635                 break;
   3636             default:
   3637                 ctype = -1;
   3638                 break;
   3639             }
   3640             if (ctype != -1) {
   3641                 /* Adding of dma counter descriptors is only necessary when the
   3642                  * counter thread is running
   3643                  * this check is necessary to avoid reallocating the dma
   3644                  * descriptos when the conter thread is stopped running before
   3645                  * the flex operation
   3646                  */
   3647                 if (soc->counter_interval) {
   3648                     rv = soc_counter_port_sbusdma_desc_alloc(unit, logic_port);
   3649                     if (BCM_FAILURE(rv)) {
   3650                         LOG_ERROR(BSL_LS_BCM_PORT,
   3651                                   (BSL_META_U(unit,
   3652                                               "Error! Unable to allocate SBUS "
   3653                                               "DMA descriptors per logical "
   3654                                               "port %d  \n"),
   3655                                    logic_port));
   3656                         return rv;
   3657                     }
   3658                 }
   3659                 BCM_IF_ERROR_RETURN
   3660                     (soc_port_cmap_set(unit, logic_port, ctype));
   3661                 SOC_PBMP_PORT_ADD(soc->counter_pbmp, logic_port);
   3662 
   3663                 for (dma_id = 0;
   3664                      dma_id < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START;
   3665                      dma_id++) {
   3666                     non_dma = &soc->counter_non_dma[dma_id];
   3667                     if (non_dma->entries_per_port > 0) {
   3668                         SOC_PBMP_PORT_ADD(non_dma->pbmp, logic_port);
   3669                     }
   3670                 }
   3671                 break;
   3672             }
   3673         } /* For each block in the given port */
   3674     } /* For each port */
   3675 
   3676     return SOC_E_NONE;
   3677 }
   3678 
   3679 /*
   3680  * Function:
   3681  *      _soc_xgs5_port_soc_counter_delete
   3682  * Purpose:
   3683  *      Delete ports from SOC counter map.
   3684  * Parameters:
   3685  *      unit           - (IN) Unit number.
   3686  *      pre_count      - (IN) Array size.
   3687  *      pre_resource   - (IN) Array of ports to delete.
   3688  * Returns:
   3689  *      SOC_E_XXX * Notes:
   3690  *      Assumes linkscan is paused, COUNTER_LOCK and SOC_CONTROL_LOCK
   3691  *      locks are taken.
   3692  */
   3693 STATIC int
   3694 _bcmi_xgs5_port_soc_counter_delete(int unit,
   3695                            soc_port_schedule_state_t *port_schedule_state)
   3696 {
   3697     soc_control_t *soc = SOC_CONTROL(unit);
   3698     soc_port_resource_t *resource, *pr;
   3699     int i, nport;
   3700     int phy_port;
   3701     int logic_port;
   3702     int rv = BCM_E_NONE;
   3703 
   3704     nport = port_schedule_state->nport;
   3705     resource = port_schedule_state->resource;
   3706 
   3707     /* Clear counter */
   3708     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   3709 
   3710         logic_port = pr->logical_port;
   3711         phy_port = port_schedule_state->in_port_map.port_l2p_mapping[logic_port];
   3712 
   3713         if (phy_port == -1) {
   3714             continue;
   3715         }
   3716 
   3717         /* Delete the counter dma descriptors */
   3718         rv = soc_counter_port_sbusdma_desc_free(unit, logic_port);
   3719         if (BCM_FAILURE(rv)) {
   3720             LOG_ERROR(BSL_LS_BCM_PORT,
   3721                       (BSL_META_U(unit,
   3722                                   "Error! Unable to delete SBUS DMA "
   3723                                   "descriptors per logical port %d  \n"),
   3724                        logic_port));
   3725             return rv;
   3726         }
   3727 
   3728         /*
   3729          * If 'inactive' flag, don't do anything
   3730          */
   3731         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   3732             continue;
   3733         }
   3734 
   3735         soc->counter_map[logic_port] = 0;
   3736         SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, logic_port);
   3737     }
   3738 
   3739     return SOC_E_NONE;
   3740 }
   3741 
   3742 /*
   3743  * Function:
   3744  *      _bcmi_xgs5_port_software_free
   3745  * Purpose:
   3746  *      Deallocates memory for a given port from the BCM PORT module
   3747  *      data structure.
   3748  * Parameters:
   3749  *      unit   - (IN) Unit number.
   3750  *      port   - (IN) Logical port, BCM format.
   3751  * Returns:
   3752  *      BCM_E_XXX
   3753  * Notes:
   3754  *      - Assumes main BCM PORT module initialization has been executed.
   3755  *      - Assumes port is valid.
   3756  */
   3757 STATIC int
   3758 _bcmi_xgs5_port_software_free(int unit, bcm_port_t port)
   3759 {
   3760     _bcm_port_info_t *pinfo;
   3761 
   3762     /* Get PORT info structure pointer */
   3763     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   3764     if  (pinfo == NULL) {
   3765         return BCM_E_INTERNAL;
   3766     }
   3767 
   3768     /* Proto-based VLAN_DATA state */
   3769     if (pinfo->p_vd_pbvl != NULL) {
   3770         sal_free(pinfo->p_vd_pbvl);
   3771         pinfo->p_vd_pbvl = NULL;
   3772     }
   3773 
   3774     /* End-to-end congestion control configuration */
   3775     if (pinfo->e2ecc_config != NULL) {
   3776         sal_free(pinfo->e2ecc_config);
   3777         pinfo->e2ecc_config = NULL;
   3778     }
   3779 
   3780     /* Reset all fields */
   3781     sal_memset(pinfo, 0, sizeof(_bcm_port_info_t));
   3782 
   3783     return BCM_E_NONE;
   3784 }
   3785 
   3786 /*
   3787  * Function:
   3788  *      _bcmi_xgs5_port_skip_attach_phase
   3789  * Purpose:
   3790  *      Check if the phase in attach should be skipped.
   3791  * Parameters:
   3792  *      unit    - (IN) Unit number.
   3793  *      phase   - (IN) Phase number in attach/detach.
   3794  * Returns:
   3795  *      1: skip the phase
   3796  *      0: Don't skip the phase
   3797  * Notes:
   3798  */
   3799 STATIC int
   3800 _bcmi_xgs5_port_skip_attach_phase(int unit, int phase)
   3801 {
   3802     int skip;
   3803     switch (phase)
   3804     {
   3805         case PORT_ATTACH_EXEC__STG:
   3806             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3807                               SHR_BPROF_BCM_STG);
   3808             break;
   3809         case PORT_ATTACH_EXEC__VLAN:
   3810             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3811                               SHR_BPROF_BCM_VLAN);
   3812             break;
   3813         case PORT_ATTACH_EXEC__TRUNK:
   3814             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3815                               SHR_BPROF_BCM_TRUNK);
   3816             break;
   3817         case PORT_ATTACH_EXEC__COSQ:
   3818             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3819                               SHR_BPROF_BCM_COSQ);
   3820             break;
   3821         case PORT_ATTACH_EXEC__LINKSCAN:
   3822             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3823                               SHR_BPROF_BCM_LINKSCAN);
   3824             break;
   3825         case PORT_ATTACH_EXEC__STATISTIC:
   3826             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3827                               SHR_BPROF_BCM_STAT);
   3828             break;
   3829         case PORT_ATTACH_EXEC__STACK:
   3830             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3831                               SHR_BPROF_BCM_STK);
   3832             break;
   3833         case PORT_ATTACH_EXEC__RATE:
   3834             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3835                               SHR_BPROF_BCM_RATE);
   3836             break;
   3837         case PORT_ATTACH_EXEC__FIELD:
   3838             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3839                               SHR_BPROF_BCM_FIELD);
   3840             break;
   3841         case PORT_ATTACH_EXEC__MIRROR:
   3842             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3843                               SHR_BPROF_BCM_MIRROR);
   3844             break;
   3845         case PORT_ATTACH_EXEC__L3:
   3846             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3847                               SHR_BPROF_BCM_L3);
   3848             break;
   3849         case PORT_ATTACH_EXEC__IPMC:
   3850             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3851                               SHR_BPROF_BCM_IPMC);
   3852             break;
   3853         case PORT_ATTACH_EXEC__IPMC_REPL:
   3854             if (SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3855                            SHR_BPROF_BCM_IPMC) &&
   3856                 soc_feature(unit, soc_feature_ip_mcast_repl)) {
   3857                 skip = 0;
   3858             } else {
   3859                 skip = 1;
   3860             }
   3861             break;
   3862         case PORT_ATTACH_EXEC__MPLS:
   3863             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3864                               SHR_BPROF_BCM_MPLS);
   3865             break;
   3866         case PORT_ATTACH_EXEC__MIM:
   3867             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   3868                               SHR_BPROF_BCM_MIM);
   3869             break;
   3870         default:
   3871             skip = 0;
   3872             break;
   3873     }
   3874     return skip;
   3875 }
   3876 
   3877 /*
   3878  * Function:
   3879  *      _bcm_xgs5_port_resource_attach
   3880  * Purpose:
   3881  *      Attach ports to the BCM layer and initialize them
   3882  *      to the default state.
   3883  *
   3884  *      Attach only those ports that are flagged as 'new' or 'remapped'.
   3885  *      If a port currently exists and the mapping is not changed, this
   3886  *      does not need to be attached.
   3887  *      - New:       Logical port did not exist before FlexPort.
   3888  *      - Remapped:  Logical port will continue to exist after FlexPort
   3889  *                   but is mapped to a different physical port.
   3890  *                   The port needs to be 'detached' and 'attached'.
   3891  * Parameters:
   3892  *      unit           - (IN) Unit number.
   3893  *      nport          - (IN) Number of elements in array resource.
   3894  *      resource       - (IN) Port Resource FlexPort configuration.
   3895  * Returns:
   3896  *      BCM_E_XXX
   3897  * Notes:
   3898  *      - Assumes caller have detached any ports that will be attached
   3899  *        in this routine (this is for the REMAP case).
   3900  *      - Assumes this is NOT called during Warmboot.
   3901  */
   3902 STATIC int
   3903 _bcmi_xgs5_port_resource_attach(int unit,
   3904                                 soc_port_schedule_state_t *port_schedule_state)
   3905 {
   3906     int rv = BCM_E_NONE;
   3907     soc_port_resource_t *pr, *resource;
   3908     int i, j, nport, my_modid;
   3909 
   3910     LOG_VERBOSE(BSL_LS_BCM_PORT,
   3911                 (BSL_META_U(unit,
   3912                             "--- BCM Attach ---\n")));
   3913 
   3914     nport = port_schedule_state->nport;
   3915     resource = port_schedule_state->resource;
   3916 
   3917     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
   3918 
   3919     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   3920         /*
   3921          * If 'inactive' flag, don't do anything
   3922          */
   3923         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   3924             continue;
   3925         }
   3926 
   3927         /* Skip 'delete' ports */
   3928         if (pr->physical_port == -1) {
   3929             continue;
   3930         }
   3931 
   3932         if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) ||
   3933             (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   3934             for(j = 0; j < PORT_ATTACH_EXEC__MAX; j++) {
   3935                 if(BCMI_PORT_DRV_CALL(unit)->port_attach_exec[j] != NULL) {
   3936 
   3937                     if (_bcmi_xgs5_port_skip_attach_phase(unit, j)) {
   3938                         LOG_VERBOSE(BSL_LS_BCM_PORT,
   3939                                     (BSL_META_U(unit,
   3940                                         "Skip Attach Phase %s\n"),
   3941                                         bcmi_xgs5_port_attach_str[j]));
   3942                         continue;
   3943                     }
   3944 
   3945                     LOG_VERBOSE(BSL_LS_BCM_PORT,
   3946                                 (BSL_META_U(unit,
   3947                                     "BCM PORT %d (%s) Attach Phase %s\n"),
   3948                                     pr->logical_port,
   3949                                     SOC_PORT_NAME(unit, pr->logical_port),
   3950                                     bcmi_xgs5_port_attach_str[j]));
   3951 
   3952                     rv = BCMI_PORT_DRV_CALL(unit)->port_attach_exec[j](unit,
   3953                                                             pr->logical_port);
   3954                     if (BCM_FAILURE(rv)) {
   3955                         _bcmi_xgs5_port_software_free(unit, pr->logical_port);
   3956                         LOG_ERROR(BSL_LS_BCM_PORT,
   3957                                   (BSL_META_U(unit,
   3958                                       "Error: Unable to attach BCM port. "
   3959                                       "Failed at phase %d - %s. "
   3960                                       "unit=%d port=%d rv=%d(%s)\n"),
   3961                                       j, bcmi_xgs5_port_attach_str[j], unit,
   3962                                       pr->logical_port, rv, bcm_errmsg(rv)));
   3963                         return rv;
   3964                     }
   3965 
   3966                 }
   3967             }
   3968         }
   3969     }
   3970 
   3971     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_set(unit, my_modid));
   3972 
   3973     return BCM_E_NONE;
   3974 }
   3975 
   3976 /*
   3977  * Function:
   3978  *      _bcmi_xgs5_port_soc_info_add
   3979  * Purpose:
   3980  *      Add port information in SOC_INFO SW
   3981  *
   3982  * Parameters:
   3983  *      unit                - (IN) Unit number.
   3984  *      port_schedule_state - (IN) Port schedule state.
   3985  * Returns:
   3986  *      SOC_E_XXX
   3987  */
   3988 STATIC int
   3989 _bcmi_xgs5_port_soc_info_add(int unit,
   3990                              bcm_port_resource_t *resource,
   3991                              soc_port_schedule_state_t *port_schedule_state)
   3992 {
   3993     soc_info_t *si = &SOC_INFO(unit);
   3994     soc_persist_t *sop = SOC_PERSIST(unit);
   3995     soc_port_resource_t *spr, *pr;
   3996     soc_pmvco_info_t pm_vco_info;
   3997     int i;
   3998     int port, phy_port, mmu_port, idb_port;
   3999     int nport;
   4000     int rv = BCM_E_NONE;
   4001 
   4002     nport = port_schedule_state->nport;
   4003     spr = port_schedule_state->resource;
   4004 
   4005     SOC_CONTROL_LOCK(unit);
   4006     /* Update mapping */
   4007     for (i = 0, pr = spr; i < nport; i++, pr++) {
   4008         port = pr->logical_port;
   4009         phy_port = pr->physical_port;
   4010         idb_port = pr->idb_port;
   4011         mmu_port = pr->mmu_port;
   4012 
   4013         if (phy_port == -1) {
   4014            /* Remove port from physical_pbm, which is used to store the port bitmap of 25G
   4015             *  ports using 50G TDM calendar.
   4016             */
   4017             if (SOC_PBMP_MEMBER(
   4018                     port_schedule_state->in_port_map.physical_pbm, port)){
   4019                 SOC_PBMP_PORT_REMOVE(
   4020                     port_schedule_state->in_port_map.physical_pbm, port);
   4021             }
   4022             continue;
   4023         }
   4024 
   4025         if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD |
   4026 		      BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   4027 
   4028             /* IPG Configuration per port */
   4029             sop->ipg[port].hd_10    = 96;
   4030             sop->ipg[port].hd_100   = 96;
   4031             sop->ipg[port].hd_1000  = 96;
   4032             sop->ipg[port].hd_2500  = 96;
   4033             sop->ipg[port].fd_10    = 96;
   4034             sop->ipg[port].fd_100   = 96;
   4035             sop->ipg[port].fd_1000  = 96;
   4036             sop->ipg[port].fd_2500  = 96;
   4037             sop->ipg[port].fd_10000 = 96;
   4038             sop->ipg[port].fd_xe    = 96;
   4039             sop->ipg[port].fd_hg    = 64;
   4040             sop->ipg[port].fd_hg2   = 96;
   4041 
   4042             SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port);
   4043 
   4044             /* Port Mapping related information */
   4045             si->port_l2p_mapping[port] = phy_port;
   4046             si->port_p2l_mapping[phy_port] = port;
   4047             si->port_l2i_mapping[port] = idb_port;
   4048             si->port_p2m_mapping[phy_port] = mmu_port;
   4049             if (mmu_port != -1) {
   4050                 si->port_m2p_mapping[mmu_port] = phy_port;
   4051             }
   4052 
   4053             /* Pipe */
   4054             si->port_pipe[port] = pr->pipe;
   4055             SOC_PBMP_PORT_ADD(si->pipe_pbm[pr->pipe], port);
   4056 
   4057             si->port_speed_max[port] = resource[i].speed;
   4058             si->port_init_speed[port] = resource[i].speed;
   4059             si->port_num_lanes[port] = pr->num_lanes;
   4060 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4061             if (SOC_IS_TOMAHAWK3(unit)) {
   4062                 si->port_serdes[port] =
   4063                     (phy_port - 1) / BCMI_XGS5_PORTS_PER_PM8X50_PBLK;
   4064             } else
   4065 #endif
   4066             {
   4067             si->port_serdes[port] = (phy_port - 1) / BCMI_XGS5_PORTS_PER_PBLK;
   4068             }
   4069 
   4070             si->port_fec_type[port] = resource[i].fec_type;
   4071             si->port_phy_lane_config[port] = resource[i].phy_lane_config;
   4072             si->port_link_training[port] = resource[i].link_training;
   4073 
   4074 #ifdef BCM_HELIX5_SUPPORT
   4075             if (SOC_IS_HELIX5(unit)) {
   4076                 if (phy_port <= 48) {
   4077                     si->port_serdes[port] = (phy_port - 1) / _HX5_PORTS_PER_PMQ_PBLK;
   4078                 } else {
   4079                     si->port_serdes[port] = ((phy_port - 1) / _HX5_PORTS_PER_PBLK) - 9;
   4080                 }
   4081             }
   4082 #endif
   4083 
   4084             /* Oversub */
   4085             if (pr->oversub) {
   4086                 SOC_PBMP_PORT_ADD(si->oversub_pbm, port);
   4087             } else {
   4088                 SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port);
   4089             }
   4090 
   4091             /* ENCAP */
   4092             if ((pr->encap == SOC_ENCAP_HIGIG2) ||
   4093                 (pr->encap == SOC_ENCAP_HIGIG2_LITE) ||
   4094                 (pr->encap == SOC_ENCAP_HIGIG2_L2) ||
   4095                 (pr->encap == SOC_ENCAP_HIGIG2_IP_GRE)) {
   4096                 SOC_PBMP_PORT_ADD(si->hg2_pbm, port);
   4097             } else {
   4098                 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port);
   4099             }
   4100 
   4101             /* High Speed Port */
   4102             if (pr->hsp) {
   4103                 SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   4104             } else {
   4105                 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port);
   4106             }
   4107         } else {
   4108             if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_SPEED |
   4109                              BCMI_XGS5_PORT_RESOURCE_OP_LANES)) {
   4110                 if ((si->port_speed_max[pr->logical_port] == 0) ||
   4111                     (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_LANES)){
   4112                     si->port_speed_max[pr->logical_port] = resource[i].speed;
   4113                 }
   4114 
   4115                 si->port_init_speed[pr->logical_port] = resource[i].speed;
   4116                 si->port_num_lanes[port] = pr->num_lanes;
   4117 
   4118                 si->port_fec_type[port] = resource[i].fec_type;
   4119                 si->port_phy_lane_config[port] = resource[i].phy_lane_config;
   4120                 si->port_link_training[port] = resource[i].link_training;
   4121 
   4122 
   4123                 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port);
   4124                 if (pr->hsp) {
   4125                     SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   4126                 }
   4127 
   4128                 /*
   4129                  * Update bitmaps and port names when switching b/w CE <=> XE ports.
   4130                  *  - Remove port from bitmap first
   4131                  */
   4132                 SOC_PBMP_PORT_REMOVE(si->cde.bitmap, port);
   4133                 SOC_PBMP_PORT_REMOVE(si->ce.bitmap, port);
   4134                 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port);
   4135                 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port);
   4136             }
   4137             /* ENCAP */
   4138             if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) ||
   4139                 (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) {
   4140                 if ((pr->encap == SOC_ENCAP_HIGIG2) ||
   4141                     (pr->encap == SOC_ENCAP_HIGIG2_LITE) ||
   4142                     (pr->encap == SOC_ENCAP_HIGIG2_L2) ||
   4143                     (pr->encap == SOC_ENCAP_HIGIG2_IP_GRE)) {
   4144                     SOC_PBMP_PORT_ADD(si->hg2_pbm, port);
   4145                 } else {
   4146                     SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port);
   4147                 }
   4148             }
   4149             if (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE) {
   4150                 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port);
   4151             }
   4152         }
   4153 
   4154         /* Update physical_pbm, which is used to store the port bitmap of 25G ports using
   4155          * 50G TDM calendar.
   4156          */
   4157         if (pr->flags & BCM_PORT_RESOURCE_25G_USE_50G_CALENDAR) {
   4158             SOC_PBMP_PORT_ADD(port_schedule_state->in_port_map.physical_pbm,
   4159                               port);
   4160         } else if (SOC_PBMP_MEMBER(
   4161                    port_schedule_state->in_port_map.physical_pbm, port)){
   4162             SOC_PBMP_PORT_REMOVE(port_schedule_state->in_port_map.physical_pbm,
   4163                                  port);
   4164         }
   4165 #ifdef BCM_TOMAHAWK3_SUPPORT
   4166         if (SOC_IS_TOMAHAWK3(unit)) {
   4167             soc_tomahawk3_num_cosq_init(unit, port);
   4168         }
   4169 #endif /* BCM_TOMAHAWK3_SUPPORT */
   4170     }
   4171 
   4172     /* Add port ptype bitmap and block information */
   4173     rv = _bcmi_xgs5_port_soc_info_ptype_block_add(unit, port_schedule_state);
   4174     if (BCM_FAILURE(rv)) {
   4175         goto cleanup;
   4176     }
   4177 
   4178     /* Add counter map */
   4179     rv = _bcmi_xgs5_port_soc_counter_add(unit, port_schedule_state);
   4180     if (BCM_FAILURE(rv)) {
   4181         goto cleanup;
   4182     }
   4183 
   4184     /* Update VCO information for devices that need it */
   4185     for (i = 0; i < SOC_MAX_NUM_BLKS; i++) {
   4186         rv = soc_esw_portctrl_pm_vco_fetch(unit, i, &pm_vco_info);
   4187         if (BCM_SUCCESS(rv)) {
   4188             if (pm_vco_info.is_tvco_new == 1 ||
   4189                 pm_vco_info.is_ovco_new == 1) {
   4190                 sal_memcpy(&si->pm_vco_info[i],
   4191                            &pm_vco_info,
   4192                            sizeof(soc_pmvco_info_t));
   4193             }
   4194         } else {
   4195             rv = BCM_E_NONE;
   4196         }
   4197     }
   4198 
   4199 cleanup:
   4200     SOC_CONTROL_UNLOCK(unit);
   4201 
   4202     return rv;
   4203 }
   4204 
   4205 /*
   4206  * Function:
   4207  *      _bcmi_xgs5_port_skip_detach_phase
   4208  * Purpose:
   4209  *      Check if the phase in detach should be skipped.
   4210  * Parameters:
   4211  *      unit    - (IN) Unit number.
   4212  *      phase   - (IN) Phase number in attach/detach.
   4213  * Returns:
   4214  *      1: skip the phase
   4215  *      0: Don't skip the phase
   4216  * Notes:
   4217  */
   4218 STATIC int
   4219 _bcmi_xgs5_port_skip_detach_phase(int unit, int phase)
   4220 {
   4221     int skip;
   4222     switch (phase)
   4223     {
   4224         case PORT_DETACH_EXEC__STG:
   4225             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4226                                SHR_BPROF_BCM_STG);
   4227             break;
   4228         case PORT_DETACH_EXEC__VLAN:
   4229             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4230                                SHR_BPROF_BCM_VLAN);
   4231             break;
   4232         case PORT_DETACH_EXEC__TRUNK:
   4233             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4234                                SHR_BPROF_BCM_TRUNK);
   4235             break;
   4236         case PORT_DETACH_EXEC__COSQ:
   4237             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4238                                SHR_BPROF_BCM_COSQ);
   4239             break;
   4240         case PORT_DETACH_EXEC__STACK:
   4241             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4242                                SHR_BPROF_BCM_STK);
   4243             break;
   4244         case PORT_DETACH_EXEC__RATE:
   4245             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4246                                SHR_BPROF_BCM_RATE);
   4247             break;
   4248         case PORT_DETACH_EXEC__FIELD:
   4249             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4250                                SHR_BPROF_BCM_FIELD);
   4251             break;
   4252         case PORT_DETACH_EXEC__MIRROR:
   4253             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4254                                SHR_BPROF_BCM_MIRROR);
   4255             break;
   4256         case PORT_DETACH_EXEC__L3:
   4257             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4258                                SHR_BPROF_BCM_L3);
   4259             break;
   4260         case PORT_DETACH_EXEC__IPMC:
   4261             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4262                                SHR_BPROF_BCM_IPMC);
   4263             break;
   4264         case PORT_DETACH_EXEC__IPMC_REPL:
   4265             if (SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4266                            SHR_BPROF_BCM_IPMC) &&
   4267                 soc_feature(unit, soc_feature_ip_mcast_repl)) {
   4268                 skip = 0;
   4269             } else {
   4270                 skip = 1;
   4271             }
   4272             break;
   4273         case PORT_DETACH_EXEC__MPLS:
   4274             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4275                                SHR_BPROF_BCM_MPLS);
   4276             break;
   4277         case PORT_DETACH_EXEC__MIM:
   4278             skip = !SHR_BITGET(BCMI_PORT_DRV_DEV_INFO(unit)->init_cond,
   4279                                SHR_BPROF_BCM_MIM);
   4280             break;
   4281         default:
   4282             skip = 0;
   4283             break;
   4284     }
   4285     return skip;
   4286 }
   4287 
   4288 /*
   4289  * Function:
   4290  *      _bcmi_xgs5_port_resource_detach
   4291  * Purpose:
   4292  *      Detach ports from the BCM layer.
   4293  *
   4294  * Parameters:
   4295  *      unit                - (IN) Unit number.
   4296  *      port_schedule_state - (IN) Port schedule state.
   4297  * Returns:
   4298  *      SOC_E_XXX
   4299  */
   4300 STATIC int
   4301 _bcmi_xgs5_port_resource_detach(int unit,
   4302                             soc_port_schedule_state_t *port_schedule_state)
   4303 {
   4304     int rv = BCM_E_NONE;
   4305     soc_port_resource_t *pr, *resource;
   4306     int i, j, nport;
   4307     pbmp_t      pbmp;
   4308 
   4309     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4310                 (BSL_META_U(unit,
   4311                             "--- BCM Detach ---\n")));
   4312 
   4313     SOC_PBMP_CLEAR(pbmp);
   4314 
   4315     nport = port_schedule_state->nport;
   4316     resource = port_schedule_state->resource;
   4317 
   4318     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   4319         /* Skip 'add' ports */
   4320         if (pr->physical_port != -1) {
   4321             continue;
   4322         }
   4323 
   4324         SOC_PBMP_PORT_ADD(pbmp, pr->logical_port);
   4325 
   4326         /*
   4327          * If 'inactive' flag, don't do anything
   4328          */
   4329         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   4330             continue;
   4331         }
   4332 
   4333         if ((pr->op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) ||
   4334             (pr->op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP)) {
   4335             for(j = 0; j < PORT_DETACH_EXEC__MAX; j++) {
   4336                 if(BCMI_PORT_DRV_CALL(unit)->port_detach_exec[j] != NULL) {
   4337                     if (_bcmi_xgs5_port_skip_detach_phase(unit, j)) {
   4338                         LOG_VERBOSE(BSL_LS_BCM_PORT,
   4339                                     (BSL_META_U(unit,
   4340                                         "Skip Detach Phase %s\n"),
   4341                                         bcmi_xgs5_port_detach_str[j]));
   4342                         continue;
   4343                     }
   4344 
   4345                     LOG_VERBOSE(BSL_LS_BCM_PORT,
   4346                                 (BSL_META_U(unit,
   4347                                     "BCM PORT %d (%s) Detach Phase %s\n"),
   4348                                     pr->logical_port,
   4349                                     SOC_PORT_NAME(unit, pr->logical_port),
   4350                                     bcmi_xgs5_port_detach_str[j]));
   4351 
   4352                     rv = BCMI_PORT_DRV_CALL(unit)->port_detach_exec[j](unit,
   4353                                                             pr->logical_port);
   4354                     if (BCM_FAILURE(rv)) {
   4355                         LOG_ERROR(BSL_LS_BCM_PORT,
   4356                                   (BSL_META_U(unit,
   4357                                       "Error: Unable to detach BCM port. "
   4358                                       "Failed at phase %d - %s. "
   4359                                       "unit=%d port=%d rv=%d(%s)\n"),
   4360                                       j, bcmi_xgs5_port_detach_str[j], unit,
   4361                                       pr->logical_port, rv, bcm_errmsg(rv)));
   4362                         return rv;
   4363                     }
   4364                 }
   4365             }
   4366         }
   4367     }
   4368 
   4369     /* Clear counters for ports in 'delete' entries */
   4370     BCM_IF_ERROR_RETURN(soc_counter_set32_by_port(unit, pbmp, 0));
   4371 
   4372     return BCM_E_NONE;
   4373 }
   4374 
   4375 /*
   4376  * Function:
   4377  *      _bcmi_xgs5_port_pm_delete
   4378  * Purpose:
   4379  *      Remove port from Port Macro if Portmod enabled.
   4380  *      Detach PHY if portmod disabled.
   4381  *
   4382  * Parameters:
   4383  *      unit   - (IN) Unit number.
   4384  *      pr_bmp - (IN) Bitmaps of port to be added/deleted during flexing.
   4385  * Returns:
   4386  *      SOC_E_XXX
   4387  * Notes:
   4388  */
   4389 STATIC int
   4390 _bcmi_xgs5_port_pm_delete(int unit,
   4391                           bcmi_xgs5_port_resource_bmp_t *pr_bmp)
   4392 {
   4393     int delete_count, inact_count, nport, i, rv = BCM_E_NONE;
   4394     soc_port_resource_t *del_res;
   4395     bcm_port_t port;
   4396     int loopback = BCM_PORT_LOOPBACK_NONE;
   4397 
   4398     SOC_PBMP_COUNT(pr_bmp->del_pbm_log, delete_count);
   4399     SOC_PBMP_COUNT(pr_bmp->inact_pbm_log, inact_count);
   4400 
   4401     if ((delete_count <= 0) && (inact_count <= 0)) {
   4402         return BCM_E_NONE;
   4403     }
   4404 
   4405     nport = delete_count + inact_count;
   4406     del_res = sal_alloc(sizeof(soc_port_resource_t) * nport,
   4407                         "Delete_port_resources");
   4408     if (del_res == NULL) {
   4409         LOG_ERROR(BSL_LS_SOC_PORT,
   4410                   (BSL_META_U(unit,
   4411                               "Unable to allocate memory for delete "
   4412                               "resource array in FlexPort operation\n")));
   4413         return SOC_E_MEMORY;
   4414     }
   4415     sal_memset(del_res, 0, sizeof(soc_port_resource_t) * nport);
   4416     i = 0;
   4417 
   4418     SOC_PBMP_ITER(pr_bmp->del_pbm_log, port) {
   4419         del_res[i].logical_port = port;
   4420         i++;
   4421     }
   4422     SOC_PBMP_ITER(pr_bmp->inact_pbm_log, port) {
   4423         del_res[i].logical_port = port;
   4424         i++;
   4425     }
   4426 
   4427     if (SOC_USE_PORTCTRL(unit)) {
   4428         /* Clear loopback */
   4429         for (i = 0; i < nport; i++) {
   4430             port = del_res[i].logical_port;
   4431             rv = bcm_esw_port_loopback_get(unit, port, &loopback);
   4432             if (SOC_SUCCESS(rv) && loopback != BCM_PORT_LOOPBACK_NONE) {
   4433                 rv = bcmi_esw_portctrl_loopback_set(unit, port,
   4434                                                     BCM_PORT_LOOPBACK_NONE);
   4435                 if (SOC_SUCCESS(rv)) {
   4436                    rv = bcmi_xgs5_port_enable_set(unit, port, 0);
   4437                 }
   4438             }
   4439             if (BCM_FAILURE(rv)) {
   4440                 sal_free(del_res);
   4441                 LOG_ERROR(BSL_LS_SOC_PORT,
   4442                           (BSL_META_U(unit,
   4443                                       "Unable to clear loopback in "
   4444                                       "FlexPort operation\n")));
   4445                 return rv;
   4446             }
   4447         }
   4448         rv = soc_esw_portctrl_pm_ports_delete(unit, nport, del_res);
   4449     } else {
   4450         for (i = 0; i < nport; i++) {
   4451             port = del_res[i].logical_port;
   4452             rv = soc_phyctrl_detach(unit, port);
   4453             if (BCM_FAILURE(rv)) {
   4454                 break;
   4455             }
   4456         }
   4457     }
   4458 
   4459     sal_free(del_res);
   4460 
   4461     if (BCM_FAILURE(rv)) {
   4462         LOG_ERROR(BSL_LS_SOC_PORT,
   4463                   (BSL_META_U(unit,
   4464                               "Unable to detach MAC/PHY in "
   4465                               "FlexPort operation\n")));
   4466     }
   4467     return rv;
   4468 }
   4469 
   4470 /*
   4471  * Function:
   4472  *      _bcmi_xgs5_port_pm_vco_reconfigure
   4473  * Purpose:
   4474  *      Reconfigure the VCOs of the Port Macros if the device supports
   4475  *      this and the PMs require reconfiguring.
   4476  *
   4477  *      For now, this calls down to a device specific portctrl
   4478  *            VCO reconfigure
   4479  *
   4480  * Parameters:
   4481  *      unit   - (IN) Unit number.
   4482  * Returns:
   4483  *      SOC_E_XXX
   4484  * Notes:
   4485  *      For now, this calls down to a device specific portctrl
   4486  *      VCO reconfigure
   4487  */
   4488 STATIC int
   4489 _bcmi_xgs5_port_pm_vco_reconfigure(int unit)
   4490 {
   4491     
   4492 #if defined(BCM_TOMAHAWK3_SUPPORT)
   4493     if (SOC_IS_TOMAHAWK3(unit)) {
   4494         return soc_esw_portctrl_pm_vco_reconfigure(unit);
   4495     } else
   4496 #endif
   4497     {
   4498         return BCM_E_NONE;
   4499     }
   4500 }
   4501 
   4502 /*
   4503  * Function:
   4504  *      _bcmi_xgs5_port_pm_add
   4505  * Purpose:
   4506  *      Add port to Port Macro if portmod enabled.
   4507  *      Probe MAC/PHY for port if portmod disabled. 
   4508  *
   4509  * Parameters:
   4510  *      unit   - (IN) Unit number.
   4511  *      pr_bmp - (IN) Bitmaps of port to be added/deleted during flexing.
   4512  * Returns:
   4513  *      SOC_E_XXX
   4514  * Notes:
   4515  */
   4516 STATIC int
   4517 _bcmi_xgs5_port_pm_add(int unit,
   4518                           bcmi_xgs5_port_resource_bmp_t *pr_bmp)
   4519 {
   4520     int add_count, act_count, inact_count, nport, i, rv = BCM_E_NONE;
   4521     soc_port_resource_t *add_res;
   4522     bcm_port_t port, phy_port;
   4523     uint32 rval;
   4524     int blk, blk_type, is_clport;
   4525     pbmp_t inact_pbm;
   4526 
   4527     SOC_PBMP_COUNT(pr_bmp->add_pbm_log, add_count);
   4528     SOC_PBMP_COUNT(pr_bmp->act_pbm_log, act_count);
   4529 
   4530     SOC_PBMP_ASSIGN(inact_pbm,pr_bmp->inact_pbm_log);
   4531     SOC_PBMP_REMOVE(inact_pbm,pr_bmp->act_pbm_log);
   4532     SOC_PBMP_COUNT(inact_pbm, inact_count);
   4533 
   4534     nport = add_count + act_count + inact_count;
   4535 
   4536     if (nport <= 0) {
   4537         return BCM_E_NONE;
   4538     }
   4539 
   4540     add_res = sal_alloc(sizeof(soc_port_resource_t) * nport,
   4541                         "Add_port_resources");
   4542     if (add_res == NULL) {
   4543         LOG_ERROR(BSL_LS_SOC_PORT,
   4544                   (BSL_META_U(unit,
   4545                               "Unable to allocate memory for add "
   4546                               "resource array in FlexPort operation\n")));
   4547         return SOC_E_MEMORY;
   4548     }
   4549     sal_memset(add_res, 0, sizeof(soc_port_resource_t) * nport);
   4550     i = 0;
   4551 
   4552     SOC_PBMP_ITER(inact_pbm, port) {
   4553         add_res[i].logical_port = port;
   4554         add_res[i].physical_port = -1;
   4555         i++;
   4556     }
   4557     SOC_PBMP_ITER(pr_bmp->add_pbm_log, port) {
   4558         add_res[i].logical_port = port;
   4559         add_res[i].physical_port = SOC_INFO(unit).port_l2p_mapping[port];
   4560         i++;
   4561     }
   4562     SOC_PBMP_ITER(pr_bmp->act_pbm_log, port) {
   4563         add_res[i].logical_port = port;
   4564         add_res[i].physical_port = SOC_INFO(unit).port_l2p_mapping[port];
   4565         i++;
   4566     }
   4567 
   4568     if (SOC_USE_PORTCTRL(unit)) {
   4569         rv = soc_esw_portctrl_pm_ports_add(unit, nport, add_res);
   4570     } else {
   4571         int okay;
   4572         for (i = 0; i < nport; i++) {
   4573             rv = _bcm_port_probe(unit, add_res[i].logical_port, &okay);
   4574             if (BCM_FAILURE(rv) || !okay) {
   4575                 break;
   4576             }
   4577             rv = _bcm_port_mode_setup(unit, add_res[i].logical_port, FALSE);
   4578             if (BCM_FAILURE(rv)) {
   4579                 break;
   4580             }
   4581         }
   4582     }
   4583 
   4584     if (BCM_FAILURE(rv)) {
   4585         LOG_ERROR(BSL_LS_SOC_PORT,
   4586                   (BSL_META_U(unit,
   4587                               "Unable to attach MAC/PHY in "
   4588                               "FlexPort operation\n")));
   4589         sal_free(add_res);
   4590         return rv;
   4591     }
   4592 
   4593     /* Set port configured with force_lb to PHY loopback */
   4594     for (i = 0; i < nport; i++) {
   4595         if (add_res[i].physical_port == -1) {
   4596             continue;
   4597         }
   4598         port = add_res[i].logical_port;
   4599         phy_port = add_res[i].physical_port;
   4600         if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb) {
   4601             rv = bcm_esw_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY);
   4602             if (BCM_FAILURE(rv)) {
   4603                 LOG_ERROR(BSL_LS_SOC_PORT,
   4604                           (BSL_META_U(unit,
   4605                                       "Fail to set port %d to PHY loopback\n"),
   4606                            port));
   4607                 sal_free(add_res);
   4608                 return rv;
   4609             }
   4610         }
   4611     }
   4612 
   4613     sal_free(add_res);
   4614 
   4615     /* Set PM interface to 16B, currently this is not covered by PortMod */
   4616     if (soc_feature(unit, soc_feature_clmac_16byte_interface_mode)) {
   4617         SHR_BIT_ITER(pr_bmp->add_bmp_pm, SOC_MAX_NUM_BLKS, blk) {
   4618             port = SOC_BLOCK_PORT(unit, blk);
   4619             blk_type = SOC_BLOCK_INFO(unit, blk).type;
   4620             is_clport = blk_type == SOC_BLK_CLPORT ? 1 : 0;
   4621 
   4622             if (is_clport) {
   4623                 BCM_IF_ERROR_RETURN
   4624                     (READ_CLPORT_MAC_CONTROLr(unit, port, &rval));
   4625                 soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval,
   4626                                     SYS_16B_INTF_MODEf, 1);
   4627                 BCM_IF_ERROR_RETURN
   4628                     (WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   4629             }
   4630         }
   4631     }
   4632 
   4633     return BCM_E_NONE;
   4634 }
   4635 
   4636 /*
   4637  * Function:
   4638  *      _bcmi_xgs5_port_pm_setup
   4639  * Purpose:
   4640  *      Setup port(s) in Port Macro if portmod enabled.
   4641  *
   4642  * Parameters:
   4643  *      unit   - (IN) Unit number.
   4644  *      port_schedule_state - (IN) Port schedule state.
   4645  * Returns:
   4646  *      SOC_E_XXX
   4647  * Notes:
   4648  */
   4649 STATIC int
   4650 _bcmi_xgs5_port_pm_setup(int unit, soc_port_schedule_state_t *port_schedule_state)
   4651 {
   4652     int nport, i;
   4653     soc_port_resource_t *resource, *pr;
   4654     bcm_port_t port;
   4655     soc_info_t *si = &SOC_INFO(unit);
   4656     soc_asf_mode_e asf_mode;
   4657     int pause;
   4658 
   4659     nport    = port_schedule_state->nport;
   4660     resource = port_schedule_state->resource;
   4661     if (SOC_USE_PORTCTRL(unit)) {
   4662         for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   4663             /*
   4664              * Check if 'delete' port needs to be added (NULL driver).
   4665              */
   4666             port = pr->logical_port;
   4667             if ((pr->physical_port == -1) &&
   4668                 !SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   4669                 /* Port is deleted and is not inactive, nothing to add */
   4670                 continue;
   4671             }
   4672             if (IS_HG_PORT(unit, port)) {
   4673                 pause = 0;
   4674             } else {
   4675                 pause = 1;
   4676             }
   4677             asf_mode = port_schedule_state->cutthru_prop.asf_modes[port];
   4678             BCM_IF_ERROR_RETURN
   4679                 (soc_esw_portctrl_pause_set(unit, port, pause, 
   4680                                             asf_mode != _SOC_ASF_MODE_SAF ? 0 : 
   4681                                             pause));
   4682         }
   4683     }
   4684 
   4685     return BCM_E_NONE;
   4686 }
   4687 
   4688 /*
   4689  * Function:
   4690  *      _bcmi_xgs5_pm_enable
   4691  * Purpose:
   4692  *      Power down or power up the port macro by programming
   4693  *      TOP_TSC_ENABLEr, TOP_TSC_ENABLE_1r
   4694  * Parameters:
   4695  *      unit   - (IN) Unit number.
   4696  *      pr_bmp - (IN) Bitmaps of port/PM to be added/deleted during flexing.
   4697  *      enable - (IN) 1: enable; 0: disable
   4698  * Returns:
   4699  *      SOC_E_XXX
   4700  * Notes:
   4701  */
   4702 STATIC int
   4703 _bcmi_xgs5_pm_enable(int unit, bcmi_xgs5_port_resource_bmp_t *pr_bmp,
   4704                      int enable)
   4705 {
   4706     SHR_BITDCL *pm_bmp;
   4707     int blk, pm, i, offset, count[2], pm_max = 64;
   4708     soc_reg_t reg[2] = {TOP_TSC_ENABLEr, TOP_TSC_ENABLE_1r};
   4709     uint32 rval[2];
   4710 
   4711     /* TOP_TSC_ENABLEr cover PM 0-31, TOP_TSC_ENABLE_1r cover PM 32-63 */
   4712 #define PM_NUM_PER_REG 32
   4713 
   4714     if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWK3(unit)) {
   4715         pm_max = 32;
   4716 #ifdef BCM_HELIX5_SUPPORT
   4717         
   4718         if (SOC_IS_HELIX5(unit)) {
   4719             return BCM_E_NONE;
   4720         }
   4721 #endif
   4722     }
   4723     for (i = 0; i < 2; i++) {
   4724         count[i] = 0;
   4725         rval[i] = 0;
   4726         if (SOC_REG_IS_VALID(unit, reg[i])){
   4727             BCM_IF_ERROR_RETURN
   4728                 (soc_reg32_get(unit, reg[i], REG_PORT_ANY, 0, &rval[i]));
   4729         }
   4730     }
   4731 
   4732     pm_bmp = enable ? pr_bmp->add_bmp_pm : pr_bmp->del_bmp_pm;
   4733 
   4734     SHR_BIT_ITER(pm_bmp, SOC_MAX_NUM_BLKS, blk) {
   4735         if (SHR_BITGET(SOC_INFO(unit).pm_ref_master_bitmap, blk)) {
   4736             continue;
   4737         }
   4738         if (SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_CLPORT &&
   4739             SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_CDPORT) {
   4740             continue;
   4741         }
   4742         pm = SOC_BLOCK_NUMBER(unit, blk);
   4743         if (pm >= pm_max) {
   4744             continue;
   4745         }
   4746 
   4747 #if defined(BCM_TRIDENT3_SUPPORT)
   4748         /* PM31 is the last PM in the LED scan chain in TD3.  Since the LED
   4749            firmware will always program LAST_PORT=124, we need to ensure that this
   4750            PM is always functional and will respond to the LED accumulation logic */
   4751         if (SOC_IS_TRIDENT3(unit) && (pm == 31) && (!enable)) {
   4752             continue;
   4753         }
   4754 #endif /* BCM_TRIDENT3_SUPPORT */
   4755 
   4756         i = pm / PM_NUM_PER_REG;
   4757         offset = pm % PM_NUM_PER_REG;
   4758         if (enable) {
   4759             rval[i] |= (1 << offset);
   4760         } else {
   4761             /* Disabling of TOP_TSC_ENABLE for TH3 causes link flapping in
   4762              * PMs not being modified, so do not allow TOP_TSC_ENABLE
   4763              * to be disabled during TH3 flex
   4764              */
   4765             if (!SOC_IS_TOMAHAWK3(unit)) {
   4766                 rval[i] &= ~(1 << offset);
   4767             }
   4768         }
   4769         count[i]++;
   4770         /* If shut down or power up many port blocks at the same time, PCI
   4771          * bus would become abnormal and BUS error happened. So update
   4772          * TOP_TSC_ENABLEx for 10 blocks change each time. */
   4773         if (count[i] > 10 && SOC_REG_IS_VALID(unit, reg[i])) {
   4774             BCM_IF_ERROR_RETURN(
   4775                 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, rval[i]));
   4776             count[i] = 0;
   4777             sal_usleep(100000);
   4778         }
   4779     }
   4780     for (i = 0; i < 2; i++) {
   4781         if (count[i] > 0 && SOC_REG_IS_VALID(unit, reg[i])) {
   4782             BCM_IF_ERROR_RETURN(
   4783                 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, rval[i]));
   4784             sal_usleep(100000);
   4785         }
   4786     }
   4787 
   4788     return BCM_E_NONE;
   4789 }
   4790 
   4791 /*
   4792  * Function:
   4793  *      _bcmi_xgs5_port_soc_info_delete
   4794  * Purpose:
   4795  *      Clear port information in SOC_INFO SW
   4796  *
   4797  * Parameters:
   4798  *      unit                - (IN) Unit number.
   4799  *      port_schedule_state - (IN) Port schedule state.
   4800  * Returns:
   4801  *      SOC_E_XXX
   4802  */
   4803 STATIC int
   4804 _bcmi_xgs5_port_soc_info_delete(int unit,
   4805                             soc_port_schedule_state_t *port_schedule_state)
   4806 {
   4807     soc_info_t *si = &SOC_INFO(unit);
   4808     soc_persist_t *sop = SOC_PERSIST(unit);
   4809     soc_port_resource_t *resource, *pr;
   4810     soc_pmvco_info_t pm_vco_info;
   4811     int i, pipe;
   4812     int port, phy_port, mmu_port;
   4813     int nport;
   4814     int rv = BCM_E_NONE;
   4815 
   4816     SOC_CONTROL_LOCK(unit);
   4817     /* Clear counter map */
   4818     rv = _bcmi_xgs5_port_soc_counter_delete(unit, port_schedule_state);
   4819     if (BCM_FAILURE(rv)) {
   4820         goto cleanup;
   4821     }
   4822 
   4823     nport = port_schedule_state->nport;
   4824     resource = port_schedule_state->resource;
   4825 
   4826     for (i = 0, pr = resource; i < nport; i++, pr++) {
   4827         port = pr->logical_port;
   4828         phy_port = si->port_l2p_mapping[port];
   4829         mmu_port = si->port_p2m_mapping[phy_port];
   4830 
   4831         if (pr->physical_port == -1) {
   4832             if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_DEL |
   4833 		        BCMI_XGS5_PORT_RESOURCE_OP_REMAP )) {
   4834 
   4835                 /*
   4836                  * If 'inactive' flag, just add port to disabled bitmap.
   4837                  * This is part of the legacy API behavior.
   4838                  */
   4839                 if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   4840                     SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
   4841                     continue;
   4842                 }
   4843 
   4844                 /* Clear IPG configuration */
   4845                 sal_memset(&sop->ipg[port], 0, sizeof(soc_ipg_t));
   4846 
   4847                 /* Port Mapping related information */
   4848                 si->port_l2p_mapping[port] = -1;
   4849                 si->port_l2i_mapping[port] = -1;
   4850                 if (phy_port != -1) {
   4851                     si->port_p2l_mapping[phy_port] = -1;
   4852                     si->port_p2m_mapping[phy_port] = -1;
   4853 #ifdef BCM_HELIX5_SUPPORT
   4854                     if (SOC_IS_HELIX5(unit) &&
   4855                         !((phy_port <= 60) && !pr->oversub)) {
   4856                         si->port_p2m_mapping[phy_port] = mmu_port;
   4857                     }
   4858 #endif
   4859                 }
   4860                 if (mmu_port != -1) {
   4861                     si->port_m2p_mapping[mmu_port] = -1;
   4862 #ifdef BCM_HELIX5_SUPPORT
   4863                     if (SOC_IS_HELIX5(unit) &&
   4864                         !((phy_port <= 60) && !pr->oversub))
   4865                         si->port_m2p_mapping[mmu_port] = phy_port;
   4866 #endif
   4867                 }
   4868 
   4869                 /* Pipeline */
   4870                 if (phy_port != -1) {
   4871                     pipe = si->port_pipe[port];
   4872                     SOC_PBMP_PORT_REMOVE(si->pipe_pbm[pipe], port);
   4873                     si->port_pipe[port] = -1;
   4874                 }
   4875 
   4876                 /* Logical port related information */
   4877                 si->port_speed_max[port] = 0;
   4878                 si->port_init_speed[port] = 0;
   4879                 si->port_num_lanes[port] = 0;
   4880                 si->port_group[port] = -1;
   4881                 si->port_serdes[port] = -1;
   4882 
   4883                 si->port_fec_type[port] = _SHR_PORT_PHY_FEC_NONE;
   4884                 si->port_phy_lane_config[port] = -1;
   4885                 si->port_link_training[port] = 0;
   4886 
   4887                 SOC_PBMP_PORT_REMOVE(si->oversub_pbm, port);
   4888                 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port);
   4889                 SOC_PBMP_PORT_REMOVE(si->eq_pbm, port);
   4890 
   4891                 continue;
   4892             } else if ((pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_SPEED |
   4893                                   BCMI_XGS5_PORT_RESOURCE_OP_LANES)) &&
   4894                        (!(pr->flags & SOC_PORT_RESOURCE_SPEED))) {
   4895                 si->port_speed_max[pr->logical_port] = 0;
   4896             }
   4897         }
   4898     }
   4899 
   4900     /* Clear out soc info's pm vco info if it's going to change */
   4901     for (i = 0; i < SOC_MAX_NUM_BLKS; i++) {
   4902         rv = soc_esw_portctrl_pm_vco_fetch(unit, i, &pm_vco_info);
   4903 
   4904         if (BCM_SUCCESS(rv)) {
   4905             if (pm_vco_info.is_tvco_new != 0 ||
   4906                 pm_vco_info.is_ovco_new != 0) {
   4907 
   4908                 si->pm_vco_info[i].tvco = -1;
   4909                 si->pm_vco_info[i].ovco = -1;
   4910                 si->pm_vco_info[i].is_tvco_new = 0;
   4911                 si->pm_vco_info[i].is_ovco_new = 0;
   4912             }
   4913         }
   4914     }
   4915 
   4916     /* Clear port ptype bitmap and block information */
   4917     rv = _bcmi_xgs5_port_soc_info_ptype_block_delete(unit, port_schedule_state);
   4918     if (BCM_FAILURE(rv)) {
   4919         goto cleanup;
   4920     }
   4921 
   4922 cleanup:
   4923     SOC_CONTROL_UNLOCK(unit);
   4924 
   4925     return rv;
   4926 }
   4927 
   4928 /*
   4929  * Function:
   4930  *      _bcmi_xgs5_port_reconfigure_bmp_get
   4931  * Purpose:
   4932  *      Get bitmaps of newly added logical ports, physical ports, port macros
   4933  *      and deleted logical port, physical port, port macro during Flexport.
   4934  * Parameters:
   4935  *      unit                - (IN) Unit number.
   4936  *      port_schedule_state - (IN) Port schedule state.
   4937  *      pr_bmp              - (OUT) Bitmaps of port, port macro that to be
   4938  *                                  added and deleted.
   4939  * Returns:
   4940  *      SOC_E_XXX
   4941  * Note:
   4942  *      Assumes:
   4943  *      - Basic checks are already performed by caller:
   4944  *          . Array is in order (deletes are first)
   4945  *          . Logical and physical ports are addressable
   4946  *      - Caller has lock.
   4947  */
   4948 STATIC int
   4949 _bcmi_xgs5_port_reconfigure_bmp_get(int unit,
   4950                             soc_port_schedule_state_t *port_schedule_state,
   4951                             bcmi_xgs5_port_resource_bmp_t *pr_bmp)
   4952 {
   4953     soc_info_t *si = &SOC_INFO(unit);
   4954     int nport = port_schedule_state->nport;
   4955     soc_port_resource_t *resource = port_schedule_state->resource, *pr;
   4956     int blk, logic_port, phy_port, old_phy_port, port_idx, local_phy_port;
   4957     int i, pipe;
   4958     pbmp_t pbm_and;
   4959     char block_valid[SOC_MAX_NUM_BLKS];
   4960 
   4961     sal_memset(pr_bmp, 0, sizeof(bcmi_xgs5_port_resource_bmp_t));
   4962 
   4963     for (i = 0, pr = resource; i < nport; i++, pr++) {
   4964         /* Legacy speed update API doesn't require port add/del */
   4965         if (pr->flags & SOC_PORT_RESOURCE_SPEED) {
   4966             continue;
   4967         }
   4968 
   4969         logic_port = pr->logical_port;
   4970         phy_port = pr->physical_port;
   4971         old_phy_port = si->port_l2p_mapping[logic_port];
   4972         pipe = pr->pipe;
   4973 
   4974         /* If 'inactive' flag, update the inact_pbm_log/act_pbm_log */
   4975         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
   4976             if (pr->physical_port == -1) {
   4977                 SOC_PBMP_PORT_ADD(pr_bmp->inact_pbm_log, logic_port);
   4978             } else {
   4979                 SOC_PBMP_PORT_ADD(pr_bmp->act_pbm_log, logic_port);
   4980             }
   4981             continue;
   4982         }
   4983 
   4984         if (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_REMAP |
   4985                       BCMI_XGS5_PORT_RESOURCE_OP_ADD |
   4986                       BCMI_XGS5_PORT_RESOURCE_OP_DEL |
   4987                       BCMI_XGS5_PORT_RESOURCE_OP_LANES |
   4988                       BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX |
   4989                       BCMI_XGS5_PORT_RESOURCE_OP_SPEED)) {
   4990             if (pr->physical_port == -1) {
   4991                 local_phy_port = old_phy_port -
   4992                         BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe];
   4993 
   4994                 SOC_PBMP_PORT_ADD(pr_bmp->del_pbm_log, logic_port);
   4995                 SOC_PBMP_PORT_ADD(pr_bmp->del_pbm_phy[pipe], local_phy_port);
   4996             } else {
   4997                 local_phy_port = phy_port -
   4998                         BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe];
   4999 
   5000                 if ((pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_REMAP |
   5001                                BCMI_XGS5_PORT_RESOURCE_OP_ADD |
   5002                                BCMI_XGS5_PORT_RESOURCE_OP_LANES)) ||
   5003                     SOC_PBMP_MEMBER(pr_bmp->del_pbm_log, logic_port)) {
   5004                     SOC_PBMP_PORT_ADD(pr_bmp->add_pbm_phy[pipe],
   5005                                       local_phy_port);
   5006                     SOC_PBMP_PORT_ADD(pr_bmp->add_pbm_log, logic_port);
   5007                 }
   5008             }
   5009         }
   5010     }
   5011 
   5012     sal_memcpy(block_valid, si->block_valid, SOC_MAX_NUM_BLKS);
   5013     for (pipe = 0; pipe < si->num_pipe; pipe++) {
   5014         SOC_PBMP_ASSIGN(pbm_and, pr_bmp->add_pbm_phy[pipe]);
   5015         SOC_PBMP_AND(pbm_and, pr_bmp->del_pbm_phy[pipe]);
   5016         SOC_PBMP_REMOVE(pr_bmp->add_pbm_phy[pipe], pbm_and);
   5017         SOC_PBMP_REMOVE(pr_bmp->del_pbm_phy[pipe], pbm_and);
   5018 
   5019         SOC_PBMP_ITER(pr_bmp->add_pbm_phy[pipe], local_phy_port) {
   5020             phy_port = local_phy_port +
   5021                         BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe];
   5022 
   5023             for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   5024                  port_idx++) {
   5025 
   5026                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   5027                 if (blk < 0) { /* End of block list of each port */
   5028                     break;
   5029                 }
   5030                 block_valid[blk] ++;
   5031             }
   5032         }
   5033 
   5034         SOC_PBMP_ITER(pr_bmp->del_pbm_phy[pipe], local_phy_port) {
   5035             phy_port = local_phy_port +
   5036                         BCMI_PORT_DRV_DEV_INFO(unit)->pipe_phy_port_base[pipe];
   5037 
   5038             for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype;
   5039                  port_idx++) {
   5040 
   5041                 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx);
   5042                 if (blk < 0) { /* End of block list of each port */
   5043                     break;
   5044                 }
   5045                 if (!block_valid[blk]) {
   5046                     return BCM_E_INTERNAL;
   5047                 }
   5048                 block_valid[blk]--;
   5049             }
   5050         }
   5051     }
   5052 
   5053     for (blk = 0; blk < SOC_MAX_NUM_BLKS; blk ++) {
   5054         if (block_valid[blk] && (!(si->block_valid[blk]))) {
   5055             SHR_BITSET(pr_bmp->add_bmp_pm, blk);
   5056         }
   5057         if ((!block_valid[blk]) && (si->block_valid[blk])) {
   5058             SHR_BITSET(pr_bmp->del_bmp_pm, blk);
   5059         }
   5060     }
   5061 
   5062     return BCM_E_NONE;
   5063 }
   5064 
   5065 /*
   5066  * Function:
   5067  *      _bcmi_xgs5_port_speed_update
   5068  * Purpose:
   5069  *      Update port for the case only speed or lanes change.
   5070  *
   5071  * Parameters:
   5072  *      unit                - (IN) Unit number.
   5073  *      port_schedule_state - (IN) Port schedule state.
   5074  * Returns:
   5075  *      SOC_E_XXX
   5076  * Note:
   5077  *      Assumes:
   5078  *      - Basic checks are already performed by caller:
   5079  *          . Array is in order (deletes are first)
   5080  *          . Logical and physical ports are addressable
   5081  *      - Caller has lock.
   5082  */
   5083 STATIC int
   5084 _bcmi_xgs5_port_speed_update(int unit,
   5085                             soc_port_schedule_state_t *port_schedule_state)
   5086 {
   5087     soc_port_resource_t *resource, *pr;
   5088     int i;
   5089     int port, phy_port;
   5090     int nport;
   5091     int count_width;
   5092     uint32 regval = 0;
   5093 
   5094     nport = port_schedule_state->nport;
   5095     resource = port_schedule_state->resource;
   5096 
   5097     for (i = 0, pr = resource; i < nport; i++, pr++) {
   5098         port = pr->logical_port;
   5099         phy_port = pr->physical_port;
   5100 
   5101         if (phy_port == -1 ||
   5102             !(pr->op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) ||
   5103             (pr->op & (BCMI_XGS5_PORT_RESOURCE_OP_ADD |
   5104                       BCMI_XGS5_PORT_RESOURCE_OP_REMAP))) {
   5105             continue;
   5106         }
   5107 
   5108         if (SOC_REG_IS_VALID(unit, PORT_INITIAL_COPY_COUNT_WIDTHr)) {
   5109         count_width = pr->hsp ? 1 : 0;
   5110 
   5111             if (!soc_feature(unit, soc_feature_skip_port_initial_copy_count)) {
   5112                 soc_reg_field_set(unit, PORT_INITIAL_COPY_COUNT_WIDTHr, &regval,
   5113                         BIT_WIDTHf, count_width);
   5114                 BCM_IF_ERROR_RETURN(WRITE_PORT_INITIAL_COPY_COUNT_WIDTHr
   5115                         (unit, port, regval));
   5116             }
   5117         }
   5118     }
   5119 
   5120     return BCM_E_NONE;
   5121 }
   5122 
   5123 /*
   5124  * Function:
   5125  *      _bcmi_xgs5_port_resource_configure
   5126  * Purpose:
   5127  *      Configure device ports based on given FlexPort information.
   5128  *
   5129  *      This routine executes the FlexPort operation.
   5130  * Parameters:
   5131  *      unit                - (IN) Unit number.
   5132  *      port_schedule_state - (IN) Port schedule state.
   5133  * Returns:
   5134  *      SOC_E_XXX
   5135  * Note:
   5136  *      Assumes:
   5137  *      - Basic checks are already performed by caller:
   5138  *          . Array is in order (deletes are first)
   5139  *          . Logical and physical ports are addressable
   5140  *      - Caller has lock.
   5141  */
   5142 STATIC int
   5143 _bcmi_xgs5_port_reconfigure(int unit,
   5144                             bcm_port_resource_t *resource,
   5145                             soc_port_schedule_state_t *port_schedule_state)
   5146 {
   5147     soc_info_t *si = &SOC_INFO(unit);
   5148     int blk, logic_port;
   5149     bcmi_xgs5_port_resource_bmp_t pr_bmp;
   5150     int rv = BCM_E_NONE;
   5151 
   5152     _bcmi_xgs5_port_reconfigure_bmp_get(unit, port_schedule_state, &pr_bmp);
   5153 
   5154     /* Enable Port Macro in TOP_TSC_ENABLE */
   5155     BCM_IF_ERROR_RETURN
   5156         (_bcmi_xgs5_pm_enable(unit, &pr_bmp, 1));
   5157 
   5158     if (!SOC_USE_PORTCTRL(unit)) {
   5159         /* Port Macro reset */
   5160         BCM_IF_ERROR_RETURN
   5161             (_bcmi_xgs5_port_pm_reset(unit, pr_bmp.add_bmp_pm,
   5162                                       pr_bmp.add_pbm_phy));
   5163     }
   5164     /***********************************************
   5165      * Because SOC reg/mem read/write functions use l2p_mapping or
   5166      * p2m_mapping in SOC_INFO to figuire out the access address of
   5167      * registers/memories of ports, SDK MUST follow below guideline
   5168      * to handle ADD/DEL/REMAP operations
   5169      *
   5170      * - HW programming on 'older' ports MUST to be done BEFORE
   5171      *   the SOC_INFO is updated.
   5172      * - HW programming on 'new' ports MUST to be done AFTER
   5173      *   the SOC_INFO is updated.
   5174      */
   5175 
   5176 
   5177     /***********************************************
   5178      * DETACH
   5179      *
   5180      * - Clearing any port references in HW
   5181      * - Removing port from Port Macro
   5182      * - Clear port information in SOC_INFO SW
   5183      */
   5184     COUNTER_UNLOCK(unit);
   5185     rv = _bcmi_xgs5_port_resource_detach(unit, port_schedule_state);
   5186     COUNTER_LOCK(unit);
   5187     if (BCM_FAILURE(rv)) {
   5188         return rv;
   5189     }
   5190 
   5191     BCM_IF_ERROR_RETURN
   5192         (_bcmi_xgs5_port_pm_delete(unit, &pr_bmp));
   5193     if (!SOC_USE_PORTCTRL(unit)) {
   5194         /* Power down the tsc that no longer used */
   5195         SHR_BIT_ITER(pr_bmp.del_bmp_pm, SOC_MAX_NUM_BLKS, blk) {
   5196             logic_port = si->block_port[blk];
   5197             BCM_IF_ERROR_RETURN
   5198                 (soc_pm_power_mode_set(unit, logic_port, 0, 1));
   5199         }
   5200     }
   5201 
   5202     BCM_IF_ERROR_RETURN
   5203         (_bcmi_xgs5_port_soc_info_delete(unit, port_schedule_state));
   5204 
   5205     /***********************************************
   5206      * Execute FlexPort operation by calling Flexport Tier1 API
   5207      *
   5208      * Changes are done to the HW.
   5209      * If any error occurs the operation, changes cannot be undone.
   5210      */
   5211     if (BCMI_PORT_DRV_CALL(unit)->reconfigure_ports) {
   5212         BCM_IF_ERROR_RETURN
   5213             (BCMI_PORT_DRV_CALL(unit)->reconfigure_ports(unit,
   5214                                                          port_schedule_state));
   5215     }
   5216 
   5217     /***********************************************
   5218      * ATTACH
   5219      *
   5220      * - Add port information in SOC_INFO SW
   5221      * - Configure new port in HW
   5222      * - Add port to Port Macro
   5223      */
   5224     BCM_IF_ERROR_RETURN
   5225         (_bcmi_xgs5_port_soc_info_add(unit, resource, port_schedule_state));
   5226 
   5227     BCM_IF_ERROR_RETURN
   5228         (_bcmi_xgs5_port_pm_vco_reconfigure(unit));
   5229 
   5230     BCM_IF_ERROR_RETURN
   5231         (_bcmi_xgs5_port_pm_add(unit, &pr_bmp));
   5232 
   5233     BCM_IF_ERROR_RETURN
   5234         (_bcmi_xgs5_port_pm_setup(unit, port_schedule_state));
   5235 
   5236     COUNTER_UNLOCK(unit);
   5237     rv = _bcmi_xgs5_port_resource_attach(unit, port_schedule_state);
   5238     COUNTER_LOCK(unit);
   5239     if (BCM_FAILURE(rv)) {
   5240         return rv;
   5241     }
   5242 
   5243     /* Update for the case that only SPEED or LANES change */
   5244     BCM_IF_ERROR_RETURN
   5245         (_bcmi_xgs5_port_speed_update(unit, port_schedule_state));
   5246 
   5247     /* Update TDM info */
   5248     if (BCMI_PORT_DRV_CALL(unit)->post_flexport_tdm) {
   5249         BCM_IF_ERROR_RETURN
   5250             (BCMI_PORT_DRV_CALL(unit)->post_flexport_tdm(unit,
   5251                                                         port_schedule_state));
   5252     }
   5253 
   5254     /* Update Port Macro */
   5255     if (BCMI_PORT_DRV_CALL(unit)->port_macro_update) {
   5256         BCM_IF_ERROR_RETURN
   5257             (BCMI_PORT_DRV_CALL(unit)->port_macro_update(unit,
   5258                                                          port_schedule_state));
   5259     }
   5260 
   5261     /* Disable Port Macro in TOP_TSC_ENABLE */
   5262     BCM_IF_ERROR_RETURN
   5263         (_bcmi_xgs5_pm_enable(unit, &pr_bmp, 0));
   5264 
   5265     /* Update the port related reg/mem in IP/EP after flexport */
   5266     BCM_IF_ERROR_RETURN
   5267         (_bcmi_xgs5_port_ipep_reconfigure(unit, pr_bmp.add_pbm_log,
   5268                                           pr_bmp.del_pbm_log));
   5269 
   5270     /* Update cos_map info */
   5271     if (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update) {
   5272         BCM_IF_ERROR_RETURN
   5273             (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update(unit, pr_bmp.del_pbm_log, 0));
   5274     }
   5275 
   5276     /* Update cos_map info */
   5277     if (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update) {
   5278         BCM_IF_ERROR_RETURN
   5279             (BCMI_PORT_DRV_CALL(unit)->port_cosmap_update(unit, pr_bmp.add_pbm_log, 1));
   5280     }
   5281 
   5282     return BCM_E_NONE;
   5283 }
   5284 
   5285 /*
   5286  * Function:
   5287  *      _bcmi_xgs5_port_resource_execute
   5288  * Purpose:
   5289  *      Perform a FlexPort operation.
   5290  *      This includes changes that involve:
   5291  *      - Logical to physical port mapping
   5292  *      - Speed
   5293  *      - Number of PHY lanes
   5294  * Parameters:
   5295  *      unit     - (IN) Unit number.
   5296  *      nport    - (IN) Number of elements in array resource.
   5297  *      resource - (IN) Port resource configuration array.
   5298  *      soc_resource - (IN) SOC Port Resource
   5299  *      port_schedule_state - (IN) SOC port schedule state
   5300  * Returns:
   5301  *      BCM_E_XXX
   5302  * Note:
   5303  *      Assumes caller has lock.
   5304  *      Assumes BCM data has been validated.
   5305  */
   5306 STATIC int
   5307 _bcmi_xgs5_port_resource_execute(int unit, int nport,
   5308                                  bcm_port_resource_t *resource,
   5309                                  soc_port_resource_t *soc_resource,
   5310                                  soc_port_schedule_state_t *port_schedule_state)
   5311 {
   5312     int rv;
   5313     int op, i;
   5314 
   5315 
   5316     /* SOC Port Structure initialization */
   5317     BCM_IF_ERROR_RETURN
   5318         (BCMI_PORT_DRV_CALL(unit)->soc_resource_init(unit, nport, resource,
   5319                                                  soc_resource));
   5320     /* Check type of FlexPort operations */
   5321     BCM_IF_ERROR_RETURN
   5322         (_bcmi_xgs5_port_resource_op_set(unit, nport, resource, soc_resource,
   5323                                          &op));
   5324 
   5325     LOG_VERBOSE(BSL_LS_BCM_PORT,
   5326                      (BSL_META_U(unit,
   5327                              "FlexPort operations 0x%x: %s %s %s %s %s %s %s %s %s\n"),
   5328                       op,
   5329                       (op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP) ? "remap" : "",
   5330                       (op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) ? "speed" : "",
   5331                       (op & BCMI_XGS5_PORT_RESOURCE_OP_LANES) ? "lanes" : "",
   5332                       (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) ? "encap" : "",
   5333                       (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) ? "encap_flex" : "",
   5334                       (op & BCMI_XGS5_PORT_RESOURCE_OP_ADD)   ? "add"   : "",
   5335                       (op & BCMI_XGS5_PORT_RESOURCE_OP_DEL)   ? "delete": "",
   5336                       (op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE)? "active": "",
   5337                       (op & BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)? "calendar": ""));
   5338 
   5339     if (((op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) ||
   5340          (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) &&
   5341         (!soc_feature(unit, soc_feature_xport_convertible))) {
   5342         LOG_ERROR(BSL_LS_BCM_PORT,
   5343                   (BSL_META_U(unit,
   5344                               "Encapsulation converting between HIGIG and IEEE "
   5345                               "is not allowed.\n")));
   5346         return BCM_E_UNAVAIL;
   5347     }
   5348 
   5349     /*
   5350     * Operations:
   5351     *     NONE                             => Nothing to do
   5352     *     ADD/DEL/REMAP/SPEED/LANES        => FlexPort sequence
   5353     *     ENCAP                            => Encap set
   5354     */
   5355     if (op == BCMI_XGS5_PORT_RESOURCE_OP_NONE) {
   5356         return BCM_E_NONE;     /* No changes, just return */
   5357     }
   5358 
   5359     if ((op & BCMI_XGS5_PORT_RESOURCE_OP_ADD) ||
   5360         (op & BCMI_XGS5_PORT_RESOURCE_OP_DEL) ||
   5361         (op & BCMI_XGS5_PORT_RESOURCE_OP_REMAP) ||
   5362         (op & BCMI_XGS5_PORT_RESOURCE_OP_LANES) ||
   5363         (op & BCMI_XGS5_PORT_RESOURCE_OP_SPEED) ||
   5364         (op & BCMI_XGS5_PORT_RESOURCE_OP_ACTIVE) ||
   5365         (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) ||
   5366         (op & BCMI_XGS5_PORT_RESOURCE_OP_CALENDAR)) {
   5367 
   5368         LOG_VERBOSE(BSL_LS_BCM_PORT,
   5369                  (BSL_META_U(unit,
   5370                              "Execute FlexPort sequence\n")));
   5371 
   5372         /* port_schedule_state structure initialization */
   5373         BCM_IF_ERROR_RETURN
   5374             (_bcmi_xgs5_port_soc_schedule_state_init(unit, nport, op,
   5375                                                      soc_resource,
   5376                                                      port_schedule_state));
   5377 
   5378         /* Validate SOC Port Resource data */
   5379         BCM_IF_ERROR_RETURN
   5380             (_bcmi_xgs5_port_resource_validate(unit, port_schedule_state));
   5381 
   5382         /* Pause linkscan */
   5383         soc_linkscan_pause(unit);
   5384 
   5385         /* Pause counter collection */
   5386         COUNTER_LOCK(unit);
   5387 
   5388         /* Flexport operations */
   5389         rv = _bcmi_xgs5_port_reconfigure(unit, resource, port_schedule_state);
   5390 
   5391         /* Resume counter collection */
   5392         COUNTER_UNLOCK(unit);
   5393 
   5394         /* Resume linkscan */
   5395         soc_linkscan_continue(unit);
   5396 
   5397         if (rv != BCM_E_NONE) {
   5398             LOG_ERROR(BSL_LS_BCM_PORT,
   5399                      (BSL_META_U(unit,
   5400                                  "Flexport operations failed: %d (%s)\n"),
   5401                                  rv, bcm_errmsg(rv)));
   5402             LOG_ERROR(BSL_LS_BCM_PORT,
   5403                       (BSL_META_U(unit,
   5404                                   "Changes to device may have been partially "
   5405                                   "executed.  System may be unstable.\n")));
   5406             return rv;
   5407         }
   5408 
   5409     }
   5410 
   5411     if ((op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) ||
   5412         (op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) {
   5413         LOG_VERBOSE(BSL_LS_BCM_PORT,
   5414                     (BSL_META_U(unit,
   5415                                 "Execute Encap change\n")));
   5416         for (i = 0; i < nport; i++) {
   5417             if (!(soc_resource[i].op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP) &&
   5418                 !(soc_resource[i].op & BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX)) {
   5419                 continue;
   5420             }
   5421             BCM_IF_ERROR_RETURN
   5422                 (bcmi_xgs5_port_encap_speed_check(unit, resource[i].port,
   5423                                                   resource[i].encap,
   5424                                                   resource[i].speed));
   5425             if (SOC_USE_PORTCTRL(unit)) {
   5426                 BCM_IF_ERROR_RETURN
   5427                     (bcmi_esw_portctrl_encap_set(unit, resource[i].port,
   5428                                                  resource[i].encap, TRUE));
   5429             } else {
   5430                 BCM_IF_ERROR_RETURN
   5431                     (bcmi_esw_port_encap_set(unit, resource[i].port,
   5432                                             resource[i].encap));
   5433             }
   5434         }
   5435     }
   5436 
   5437     /* Update speed */
   5438     for (i = 0; i < nport; i++) {
   5439         if (resource[i].physical_port == -1 ||
   5440             soc_resource[i].op == BCMI_XGS5_PORT_RESOURCE_OP_ENCAP ||
   5441             soc_resource[i].op == BCMI_XGS5_PORT_RESOURCE_OP_ENCAP_FLEX) {
   5442             continue;
   5443         }
   5444         if (((resource[i].speed < BCMI_PORT_DRV_DEV_INFO(unit)->tdm_speed_min) 
   5445 #if defined(BCM_TRIDENT3_SUPPORT)
   5446             || SOC_IS_TRIDENT3X(unit)
   5447 #endif
   5448             )
   5449                 &&
   5450             BCMI_PORT_DRV_CALL(unit)->no_tdm_speed_update) {
   5451             BCM_IF_ERROR_RETURN
   5452                 (BCMI_PORT_DRV_CALL(unit)->no_tdm_speed_update(unit,
   5453                                                             resource[i].port,
   5454                                                             resource[i].speed));
   5455         }
   5456     }
   5457 
   5458     /*
   5459      * Bring new ports down to ensure port state is proper
   5460      */
   5461     for (i = 0; i < nport; i++) {
   5462         if ((resource[i].physical_port == -1) ||
   5463             (resource[i].flags & SOC_PORT_RESOURCE_SPEED)) {
   5464             continue;
   5465         }
   5466         LOG_VERBOSE(BSL_LS_BCM_PORT,
   5467                     (BSL_META_U(unit,
   5468                                 "Disable port %d\n"), resource[i].port));
   5469 
   5470         BCM_IF_ERROR_RETURN
   5471             (bcm_esw_port_enable_set(unit, resource[i].port, 0));
   5472     }
   5473 
   5474     return BCM_E_NONE;
   5475 }
   5476 
   5477 /*
   5478  * Function:
   5479  *      bcmi_xgs5_port_resource_multi_set
   5480  * Purpose:
   5481  *      Modify the following port resources:
   5482  *      - Logical to physical port mapping
   5483  *      - Speed
   5484  *      - Number of PHY lanes
   5485  *      - Encapsulation mode
   5486  * Parameters:
   5487  *      unit     - (IN) Unit number.
   5488  *      nport    - (IN) Number of elements in array resource.
   5489  *      resource - (IN) Port resource configuration array.
   5490  * Returns:
   5491  *      BCM_E_XXX
   5492  * Note:
   5493  *      Assumes caller has lock.
   5494  */
   5495 int
   5496 bcmi_xgs5_port_resource_multi_set(int unit, 
   5497                                   int nport, bcm_port_resource_t *resource)
   5498 {
   5499     soc_port_resource_t *soc_resource;
   5500     soc_port_schedule_state_t *port_schedule_state;
   5501     int rv;
   5502 
   5503     if (resource == NULL) {
   5504         return BCM_E_PARAM;
   5505     }
   5506 
   5507     if ((BCMI_PORT_DRV_CALL(unit)->reconfigure_ports == NULL) ||
   5508         (BCMI_PORT_DRV_CALL(unit)->soc_resource_init == NULL)) {
   5509         return BCM_E_UNAVAIL;
   5510     }
   5511 
   5512     /*
   5513      * Validate function input requirements
   5514      *
   5515      * This steps checks for function semantics and guidelines
   5516      * from the API perspective.
   5517      */
   5518     BCM_IF_ERROR_RETURN
   5519         (_bcmi_xgs5_port_resource_input_validate(unit, nport, resource));
   5520 
   5521     /* Allocate memory for SOC Port Resource array data structure */
   5522     soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport,
   5523                              "port_resource");
   5524     if (soc_resource == NULL) {
   5525         return BCM_E_MEMORY;
   5526     }
   5527 
   5528     /* Allocate memory for soc_port_schedule_state_t structure */
   5529     port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t),
   5530                                     "port schedule state");
   5531     if (port_schedule_state == NULL) {
   5532         sal_free(soc_resource);
   5533         return BCM_E_MEMORY;
   5534     }
   5535 
   5536     rv = _bcmi_xgs5_port_resource_execute(unit, nport, resource, soc_resource,
   5537                                           port_schedule_state);
   5538 
   5539     if (rv != BCM_E_NONE) {
   5540         LOG_ERROR(BSL_LS_BCM_PORT,
   5541                  (BSL_META_U(unit,
   5542                              "Port resource execute failed: %d (%s)\n"),
   5543                              rv, bcm_errmsg(rv)));
   5544     }
   5545     sal_free(soc_resource);
   5546     sal_free(port_schedule_state);
   5547 
   5548     return rv;
   5549 }
   5550 
   5551 /*
   5552  * Function:
   5553  *      bcmi_xgs5_port_resource_traverse
   5554  * Purpose:
   5555  *      Iterates over the port resource configurations on a given
   5556  *      unit and calls user-provided callback for every entry.
   5557  * Parameters:
   5558  *      unit       - (IN) Unit number.
   5559  *      trav_fn    - (IN) Callback function to execute.
   5560  *      user_data  - (IN) Pointer to any user data.
   5561  * Returns:
   5562  *      BCM_E_XXX
   5563  */
   5564 int
   5565 bcmi_xgs5_port_resource_traverse(int unit, 
   5566                                  bcm_port_resource_traverse_cb trav_fn, 
   5567                                  void *user_data)
   5568 {
   5569     bcm_port_t port;
   5570     bcm_port_resource_t resource;
   5571     soc_info_t *si = &SOC_INFO(unit);
   5572 
   5573     PARAM_NULL_CHECK(trav_fn);
   5574 
   5575     for (port = 0; port < SOC_MAX_NUM_PORTS ; port++) {
   5576         /* Skip logical ports with no assignment and management ports */
   5577         /* coverity[overrun-local] */
   5578         if ((si->port_l2p_mapping[port] == -1) ||
   5579             IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   5580                 continue;
   5581         }
   5582 
   5583         /* Get port information */
   5584         if (BCM_FAILURE(bcmi_xgs5_port_resource_get(unit, port, &resource))) {
   5585             continue;
   5586         }
   5587 
   5588         /* Call user-provided callback routine */
   5589         BCM_IF_ERROR_RETURN(trav_fn(unit, &resource, user_data));
   5590     }
   5591 
   5592     return BCM_E_NONE;
   5593 }
   5594 
   5595 /***************************Legacy API *******************************/
   5596 /*
   5597  * Function:
   5598  *      bcmi_xgs5_port_lanes_set
   5599  * Purpose:
   5600  *      Set the number of PHY lanes for the given port.
   5601  *
   5602  *      This function should only be used to support the legacy
   5603  *      FlexPort API bcm_port_control_set(... , bcmPortControlLanes).
   5604  *
   5605  *      The legacy API does not delete the port mappings when flexing
   5606  *      to fewer lanes.  Ports which lanes are used by the base
   5607  *      physical port becomes inactive.
   5608  *
   5609  * Parameters:
   5610  *      unit     - (IN) Unit number.
   5611  *      port     - (IN) Logical port.
   5612  *      lanes    - (IN) Number of lanes to set on given port.
   5613  * Returns:
   5614  *      BCM_E_XXX
   5615  * Notes:
   5616  *      - Only to be used by legacy API to support flexport behavior
   5617  *        bcm_port_control_set(... , bcmPortControlLanes).
   5618  *      - Supports only up to 4 lanes (TSC-4).
   5619  *      - 'port' must be in BCM port format (non-GPORT) and mapped to
   5620  *        the base physical port.
   5621  *      - Several calls to legacy API may be required to
   5622  *        achieve desired configuration.
   5623  */
   5624 
   5625 int
   5626 bcmi_xgs5_port_lanes_set(int unit, bcm_port_t port, int lanes)
   5627 {
   5628     soc_info_t *si = &SOC_INFO(unit);
   5629     bcm_port_resource_t cur_resource, resource[8];  /* Max size to support up to 4 lanes */
   5630     int max_array_cnt;
   5631     int i;
   5632     int phy_port;
   5633     int speed;
   5634     int num_ports_clear;
   5635     int num_ports_new;
   5636 
   5637     bcm_port_resource_t_init(&cur_resource);
   5638     BCM_IF_ERROR_RETURN(bcm_esw_port_resource_get(unit, port, &cur_resource));
   5639 
   5640     /*
   5641      * Select speed based on number of lanes and the encap
   5642      */
   5643     switch(lanes) {
   5644     case 1:
   5645         speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 25000 : 27000;
   5646         break;
   5647     case 2:
   5648         speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 50000 : 53000;
   5649         break;
   5650     case 4:
   5651         speed = (cur_resource.encap == BCM_PORT_ENCAP_IEEE) ? 100000 : 106000;
   5652         break;
   5653     default:
   5654         /* Support legacy API up to 4 lanes */
   5655         return BCM_E_PARAM;
   5656     }
   5657 
   5658     /* Check current number of lanes */
   5659     if (cur_resource.lanes == lanes) {
   5660         return BCM_E_NONE;
   5661     }
   5662 
   5663     max_array_cnt = COUNTOF(resource);
   5664     sal_memset(resource, 0, sizeof(resource));
   5665 
   5666     /*
   5667      * Build port resource array
   5668      * Certain information is derived from 'best' guess,
   5669      * similar to the legacy behaviour.
   5670      */
   5671     switch (cur_resource.lanes) {
   5672     case 1:
   5673         if (lanes == 2) {
   5674             num_ports_clear = 2;
   5675             num_ports_new = 1;
   5676         } else {
   5677             num_ports_clear = 4;
   5678             num_ports_new = 1;
   5679         }
   5680         break;
   5681     case 2:
   5682         if (lanes == 1) {
   5683             num_ports_clear = 2;
   5684             num_ports_new = 2;
   5685         } else {
   5686             num_ports_clear = 4;
   5687             num_ports_new = 1;
   5688         }
   5689         break;
   5690     case 4:
   5691         if (lanes == 1) {
   5692             num_ports_clear = 4;
   5693             num_ports_new = 4;
   5694         } else {
   5695             num_ports_clear = 4;
   5696             num_ports_new = 2;
   5697         }
   5698         break;
   5699     default:
   5700         return BCM_E_PARAM;
   5701     }
   5702 
   5703     if ((num_ports_clear + num_ports_new) > max_array_cnt) {
   5704         return BCM_E_INTERNAL;
   5705     }
   5706 
   5707     /*
   5708      * Clear mapping for physical ports involved in FlexPort operation.
   5709      * Assume physical ports are numbered consecutively in device.
   5710      */
   5711     phy_port = si->port_l2p_mapping[port];
   5712     for (i = 0; i < num_ports_clear; i++) {
   5713         resource[i].flags = SOC_PORT_RESOURCE_I_MAP;
   5714         resource[i].port = si->port_p2l_mapping[phy_port++];
   5715         resource[i].physical_port = -1;
   5716     }
   5717 
   5718     /*
   5719      * Map new ports
   5720      *
   5721      * Legacy API requires that logical-physical port mapping
   5722      * is valid in the SOC_INFO SW data.
   5723      */
   5724     phy_port = si->port_l2p_mapping[port];
   5725     for (; i < (num_ports_clear + num_ports_new); i++) {
   5726         /* Check valid physical port */
   5727         if (phy_port == -1) {
   5728             return BCM_E_INTERNAL;
   5729         }
   5730 
   5731         resource[i].flags = SOC_PORT_RESOURCE_I_MAP;
   5732         resource[i].port = si->port_p2l_mapping[phy_port];
   5733         resource[i].physical_port = phy_port;
   5734         resource[i].lanes = lanes;
   5735         resource[i].speed = speed;
   5736         resource[i].encap = cur_resource.encap; /* Keep encap the same */
   5737         phy_port += lanes;
   5738     }
   5739 
   5740     BCM_IF_ERROR_RETURN
   5741         (bcmi_xgs5_port_resource_multi_set(unit,
   5742                                          (num_ports_clear + num_ports_new),
   5743                                          resource));
   5744 
   5745     return BCM_E_NONE;
   5746 }
   5747 
   5748 /*
   5749  * Function:
   5750  *      bcmi_xgs5_port_lanes_get
   5751  * Purpose:
   5752  *      Get the number of PHY lanes for the given port.
   5753  * Parameters:
   5754  *      unit     - (IN) Unit number.
   5755  *      port     - (IN) Logical port.
   5756  *      lanes    - (OUT) Returns number of lanes for port.
   5757  * Returns:
   5758  *      BCM_E_XXX
   5759  */
   5760 int
   5761 bcmi_xgs5_port_lanes_get(int unit, bcm_port_t port, int *lanes)
   5762 {
   5763     bcm_port_resource_t resource;
   5764 
   5765     BCM_IF_ERROR_RETURN(bcm_esw_port_resource_get(unit, port, &resource));
   5766 
   5767     *lanes = resource.lanes;
   5768 
   5769     return BCM_E_NONE;
   5770 }
   5771 
   5772 /*
   5773  * Function:
   5774  *      bcmi_xgs5_port_speed_set
   5775  * Purpose:
   5776  *      Set the speed for the given port.
   5777  *
   5778  *      This function should only be used to support the legacy
   5779  *      FlexPort API bcm_port_speed_set().
   5780  *
   5781  *
   5782  * Parameters:
   5783  *      unit     - (IN) Unit number.
   5784  *      port     - (IN) Logical port.
   5785  *      speed    - (IN) speed for given port.
   5786  * Returns:
   5787  *      BCM_E_XXX
   5788  * Notes:
   5789  *      - Only to be used by legacy API to support flexport behavior
   5790  *        bcm_port_speed_set().
   5791  *      - 'port' must be in BCM port format (non-GPORT) and mapped to
   5792  *        the base physical port.
   5793  *      - Several calls to legacy API may be required to
   5794  *        achieve desired configuration.
   5795  */
   5796 
   5797 int
   5798 bcmi_xgs5_port_speed_set(int unit, bcm_port_t port, int speed)
   5799 {
   5800     soc_info_t *si = &SOC_INFO(unit);
   5801     bcm_port_resource_t resource[2];
   5802     int encap, i;
   5803 
   5804     if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   5805         LOG_VERBOSE(BSL_LS_BCM_PORT,
   5806                     (BSL_META_U(unit,
   5807                                 "bcmi_xgs5_port_speed_set: "
   5808                                 "Set speed on disabled port, do nothing\n")));
   5809         return BCM_E_NONE;
   5810     }
   5811 
   5812     /* Do nothing except update port type in case auxiliary ports don't
   5813      * support flexport */
   5814     if ((!BCMI_PORT_DRV_DEV_INFO(unit)->aux_port_flexible) &&
   5815         IS_MANAGEMENT_PORT(unit,port)) {
   5816         BCM_IF_ERROR_RETURN
   5817             (_bcmi_xgs5_management_port_soc_info_ptype_update(unit, 
   5818                                                               port, speed));
   5819         return BCM_E_NONE;
   5820     }
   5821 
   5822     /*
   5823      * No reconfiguration is needed if new speed matches current speed
   5824      */
   5825     if (speed == si->port_init_speed[port]) {
   5826         LOG_VERBOSE(BSL_LS_BCM_PORT,
   5827                     (BSL_META_U(unit,
   5828                                 "Speed is already configured as %d\n"),
   5829                      speed));
   5830         return BCM_E_NONE;
   5831     }
   5832 
   5833     for (i = 0; i < 2; i++) {
   5834         bcm_port_resource_t_init(&resource[i]);
   5835     }
   5836     /*
   5837      * Build port resource
   5838      */
   5839 
   5840     /* Get current port encap */
   5841     BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap));
   5842 
   5843     /* Keep encap, lanes, phy_port the same */
   5844     resource[0].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED;
   5845     resource[0].port = port;
   5846     resource[0].physical_port = -1;
   5847 
   5848     resource[1].flags = SOC_PORT_RESOURCE_I_MAP| SOC_PORT_RESOURCE_SPEED;
   5849     resource[1].port = port;
   5850     resource[1].physical_port = si->port_l2p_mapping[port];
   5851     resource[1].speed = speed;
   5852     resource[1].lanes = si->port_num_lanes[port];
   5853     resource[1].encap = encap;
   5854 
   5855     BCM_IF_ERROR_RETURN
   5856         (bcmi_xgs5_port_resource_multi_set(unit, 2, resource));
   5857 
   5858     return BCM_E_NONE;
   5859 }
   5860 
   5861 /*
   5862  * Function:
   5863  *      bcmi_xgs5_port_attach_dscp
   5864  * Purpose:
   5865  *      Set default DSCP profile index to port table
   5866  *      Increase reference count of default DSCP profile
   5867  * Parameters:
   5868  *      unit    - (IN) Unit number.
   5869  *      port    - (IN) Logical port.
   5870  * Returns:
   5871  *      SOC_E_XXX
   5872  */
   5873 int
   5874 bcmi_xgs5_port_attach_dscp(int unit, bcm_port_t port)
   5875 {
   5876     BCM_IF_ERROR_RETURN
   5877         (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
   5878                                TRUST_DSCP_PTRf,
   5879                                0));
   5880     SOC_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, 0,
   5881                                                         64));
   5882 
   5883     return BCM_E_NONE;
   5884 }
   5885 
   5886 /*
   5887  * Function:
   5888  *      bcmi_xgs5_port_attach_software
   5889  * Purpose:
   5890  *      Initialize BCM PORT info structure (bcm_port_info[unit][port])
   5891  * Parameters:
   5892  *      unit    - (IN) Unit number.
   5893  *      port    - (IN) Logical port.
   5894  * Returns:
   5895  *      SOC_E_XXX
   5896  * Note:
   5897  *      Same port related initialization covered in _bcm_port_software_init()
   5898  */
   5899 int
   5900 bcmi_xgs5_port_attach_software(int unit, bcm_port_t port)
   5901 {
   5902     _bcm_port_info_t *pinfo;
   5903     int index, idxmax;
   5904     int inds_bytes;
   5905     int enabled;
   5906     uint32 value;
   5907 
   5908     /* Free memory in case this is already allocated */
   5909     BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_software_free(unit, port));
   5910 
   5911     /* Get PORT info structure pointer */
   5912     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   5913 
   5914     /*
   5915      * Initialization of vd_pbvl bitmap in port
   5916      */
   5917     idxmax = 0;
   5918     if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) {
   5919     idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm);
   5920 
   5921     inds_bytes = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE -  1)) / \
   5922                 _BCM_PORT_VD_PBVL_ESIZE; /* Round to the next entry */
   5923 
   5924     pinfo->p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info");
   5925     if (NULL == pinfo->p_vd_pbvl) {
   5926         return BCM_E_MEMORY;
   5927     }
   5928 
   5929     sal_memset(pinfo->p_vd_pbvl, 0, inds_bytes);
   5930     } else {
   5931         pinfo->p_vd_pbvl = NULL;
   5932     }
   5933 
   5934     /*
   5935      * Update TPID reference count
   5936      */
   5937     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   5938         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   5939             if (soc_feature(unit, soc_feature_egr_all_profile)) {
   5940                 BCM_IF_ERROR_RETURN(
   5941                     bcm_esw_port_egr_lport_field_get(
   5942                     unit, port, EGR_VLAN_CONTROL_1m,
   5943                     OUTER_TPID_INDEXf, (uint32 *)&index));
   5944             } else {
   5945                 BCM_IF_ERROR_RETURN(
   5946                     READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value));
   5947                 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m,
   5948                                                         &value, OUTER_TPID_INDEXf);
   5949             }
   5950         } else {
   5951             BCM_IF_ERROR_RETURN
   5952                 (READ_EGR_VLAN_CONTROL_1r(unit, port, &value));
   5953             index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 
   5954                                   value, OUTER_TPID_INDEXf);
   5955         }
   5956 
   5957         BCM_IF_ERROR_RETURN
   5958             (_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1));
   5959 
   5960         enabled = 0;
   5961         BCM_IF_ERROR_RETURN
   5962             (_bcm_esw_port_config_get(unit, port,
   5963                                       _bcmPortOuterTpidEnables, &enabled));
   5964         index = 0;
   5965         while (enabled) {
   5966             if (enabled & 1) {
   5967                     BCM_IF_ERROR_RETURN
   5968                         (_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1));
   5969             }
   5970             enabled = enabled >> 1;
   5971             index++;
   5972         }
   5973     }
   5974 
   5975 #if defined(BCM_TRIDENT3_SUPPORT)
   5976       if (SOC_IS_TRIDENT3X(unit)) {
   5977             BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_set(unit, port,
   5978                               EGR_QOS_PROFILE_INDEXf,0));
   5979       } else
   5980 #endif
   5981     /*
   5982      * Initialize priority map
   5983      */
   5984     if (soc_feature(unit, soc_feature_color_prio_map)) {
   5985         bcm_color_t color;
   5986         bcm_color_t color_array[] = {bcmColorGreen, bcmColorYellow, bcmColorRed};
   5987         int priority;
   5988         int cfi;
   5989 
   5990         for (index = 0; index < 3; index++) {
   5991             color = color_array[index];
   5992             for (priority = 0; priority <= 7; priority++) {
   5993                 cfi = (color == bcmColorRed) ? 1 : 0;
   5994                 BCM_IF_ERROR_RETURN
   5995                     (bcm_esw_port_vlan_priority_unmap_set(unit, port, priority,
   5996                                                           color, priority, cfi));
   5997             }
   5998         }
   5999     }
   6000 
   6001     pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE;
   6002 
   6003     return BCM_E_NONE;
   6004 }
   6005 
   6006 /*
   6007  * Function:
   6008  *      bcmi_xgs5_port_attach_egr_vlan_action
   6009  * Purpose:
   6010  *      Set the egress port's default vlan tag actions
   6011  * Parameters:
   6012  *      unit    - (IN) Unit number.
   6013  *      port    - (IN) Logical port.
   6014  * Returns:
   6015  *      SOC_E_XXX
   6016  */
   6017 int
   6018 bcmi_xgs5_port_attach_egr_vlan_action(int unit, bcm_port_t port)
   6019 {
   6020     bcm_vlan_action_set_t action;
   6021 
   6022     if (soc_feature(unit, soc_feature_vlan_action) &&
   6023         (!SOC_IS_TRIDENT3X(unit))) {
   6024 
   6025         /* Update Egress VLAN profile table count */
   6026         _bcm_trx_egr_vlan_action_profile_entry_increment(unit,
   6027                                     BCM_TRX_EGR_VLAN_ACTION_PROFILE_DEFAULT);
   6028 
   6029         if (IS_HG_PORT(unit, port)) {
   6030 
   6031             BCM_IF_ERROR_RETURN
   6032                 (_bcm_trx_vlan_port_egress_default_action_get(unit,
   6033                                                              port, &action));
   6034             /* Backward compatible defaults */
   6035             action.ot_outer = bcmVlanActionDelete;
   6036             action.dt_outer = bcmVlanActionDelete;
   6037             BCM_IF_ERROR_RETURN
   6038                 (_bcm_trx_vlan_port_egress_default_action_set(unit,
   6039                                                              port, &action));
   6040         }
   6041     }
   6042     return BCM_E_NONE;
   6043 }
   6044 
   6045 /*
   6046  * Function:
   6047  *      _bcmi_xgs5_port_bridge_port_init
   6048  * Purpose:
   6049  *      This function initializes PORT_BRIDGE_BMAP memory (for a normal port),
   6050  *      and/or PORT_BRIDGE_MIRROR_BMAP (for a Higig port). The initialization is
   6051  *      required for ensuring that port bit in one of the above memories
   6052  *      (depending on port type), and PORT_TAB.PORT_BRIDGE bit have the same
   6053  *      value. See notes.
   6054  * Parameters:
   6055  *      unit   - (IN) Unit number.
   6056  *      port   - (IN) Logical port, BCM format.
   6057  *      value  - 1 Set bit in PORT_BRIDGE_BMAP and/or PORT_BRIDGE_MIRROR_BMAP
   6058  *                 memory.
   6059  *               0 Reset bit in PORT_BRIDGE_BMAP and/or PORT_BRIDGE_MIRROR_BMAP
   6060  *                 memory.
   6061  *                 See Notes.
   6062  * Returns:
   6063  *      BCM_E_XXX
   6064  * Notes:
   6065  *      - PORT_TAB.PORT_BRIDGE is reset in function
   6066  *        mbcm_driver[unit]->mbcm_port_cfg_init()
   6067  *      - If this function is called outside of port attach and detach
   6068  *        functions then the caller must make sure that PORT_TAB.PORT_BRIDGE is
   6069  *        programmed to the same value as in these memories, for a given port
   6070  *        Refer to memory description of these two memories for more information
   6071  *      - Assumes port is valid.
   6072  *      - Assumes this is NOT called during Warmboot.
   6073  */
   6074 STATIC int
   6075 _bcmi_xgs5_port_bridge_port_init(int unit, bcm_port_t port, int value)
   6076 {
   6077     int rv = BCM_E_NONE;
   6078     bcm_pbmp_t  pbmp;
   6079 
   6080     if ((IS_E_PORT(unit, port) ||
   6081          IS_CPU_PORT(unit, port) ||
   6082          IS_HG_PORT(unit, port)) &&
   6083         SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) {
   6084         port_bridge_bmap_entry_t entry;
   6085 
   6086         SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm,
   6087                             MEM_BLOCK_ANY, 0, &entry));
   6088         soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry,
   6089                                BITMAPf, &pbmp);
   6090 
   6091         if (value) {
   6092             SOC_PBMP_PORT_ADD(pbmp, port);
   6093         } else {
   6094             SOC_PBMP_PORT_REMOVE(pbmp, port);
   6095         }
   6096 
   6097         soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry,
   6098                                BITMAPf, &pbmp);
   6099 
   6100         SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm,
   6101                             MEM_BLOCK_ANY, 0, &entry));
   6102     }
   6103 
   6104     if (IS_HG_PORT(unit, port) &&
   6105         SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) {
   6106         port_bridge_mirror_bmap_entry_t entry;
   6107 
   6108         SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm,
   6109                             MEM_BLOCK_ANY, 0, &entry));
   6110         soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
   6111                                BITMAPf, &pbmp);
   6112         if (value) {
   6113             SOC_PBMP_PORT_ADD(pbmp, port);
   6114         } else {
   6115             SOC_PBMP_PORT_REMOVE(pbmp, port);
   6116         }
   6117         soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry,
   6118                                BITMAPf, &pbmp);
   6119         SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm,
   6120                             MEM_BLOCK_ANY, 0, &entry));
   6121     }
   6122 
   6123     return rv;
   6124 }
   6125 
   6126 /*
   6127  * Function:
   6128  *      bcmi_xgs5_port_cfg_init
   6129  * Purpose:
   6130  *      Initialize the port configuration according to Initial System
   6131  *      Configuration (see init.c)
   6132  * Parameters:
   6133  *      unit    - (IN) Unit number.
   6134  *      port    - (IN) Logical port.
   6135  * Returns:
   6136  *      SOC_E_XXX
   6137  */
   6138 int
   6139 bcmi_xgs5_port_cfg_init(int unit, bcm_port_t port)
   6140 {
   6141     bcm_pbmp_t port_pbmp;
   6142     bcm_vlan_data_t vd;
   6143 
   6144     SOC_PBMP_CLEAR(port_pbmp);
   6145     BCM_PBMP_ASSIGN(port_pbmp, PBMP_ALL(unit));
   6146     SOC_PBMP_REMOVE(port_pbmp, PBMP_TDM(unit));
   6147 
   6148     vd.vlan_tag = BCM_VLAN_DEFAULT;
   6149     BCM_PBMP_ASSIGN(vd.port_bitmap, port_pbmp);
   6150     BCM_PBMP_ASSIGN(vd.ut_port_bitmap, port_pbmp);
   6151     BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit));
   6152 
   6153     BCM_IF_ERROR_RETURN
   6154         (mbcm_driver[unit]->mbcm_port_cfg_init(unit, port, &vd));
   6155 
   6156     BCM_IF_ERROR_RETURN
   6157         (_bcmi_xgs5_port_bridge_port_init(unit, port, 0));
   6158 
   6159     return BCM_E_NONE;
   6160 }
   6161 
   6162 /*
   6163  * Function:
   6164  *      bcmi_xgs5_port_attach_port_probe
   6165  * Purpose:
   6166  *      Probe the PHY and set up the PHY and MAC for the specified ports.
   6167  *      This is purely a discovery routine and does no configuration.
   6168  * Parameters:
   6169  *      unit    - (IN) Unit number.
   6170  *      port    - (IN) Logical port.
   6171  * Returns:
   6172  *      SOC_E_XXX
   6173  * Notes:
   6174  *      Only for Non PortMod unit.
   6175  *      Unit with PortMod enabled probe PHY and MAC via
   6176  *      _bcmi_xgs5_port_pm_delete/add().
   6177  */
   6178 int
   6179 bcmi_xgs5_port_attach_port_probe(int unit, bcm_port_t port)
   6180 {
   6181     int okay;
   6182 
   6183     if (!SOC_USE_PORTCTRL(unit)) {
   6184 
   6185         BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay));
   6186         if (!okay) {
   6187             return BCM_E_INTERNAL;
   6188         }
   6189         BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE));
   6190     }
   6191     return BCM_E_NONE;
   6192 }
   6193 
   6194 /*
   6195  * Function:
   6196  *      bcmi_xgs5_port_attach_frame_length_check
   6197  * Purpose:
   6198  *      Control 802.3 frame length field check in MAC
   6199  * Parameters:
   6200  *      unit    - (IN) Unit number.
   6201  *      port    - (IN) Logical port.
   6202  * Returns:
   6203  *      SOC_E_XXX
   6204  */
   6205 int
   6206 bcmi_xgs5_port_attach_frame_length_check(int unit, bcm_port_t port)
   6207 {
   6208     int length_check;
   6209     soc_reg_t reg = INVALIDr;
   6210     uint32 rval;
   6211 
   6212     
   6213     length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0);
   6214     if (IS_CL_PORT(unit, port) &&
   6215         SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) {
   6216         reg = CLPORT_MAC_RSV_MASKr;
   6217     } else if (IS_QSGMII_PORT(unit, port)) {
   6218         reg = GPORT_RSV_MASKr;
   6219     } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) {
   6220         reg = XLPORT_MAC_RSV_MASKr;
   6221     }
   6222 
   6223     if (reg != INVALIDr) {
   6224         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   6225         if (length_check) {
   6226             rval |= 0x20;  /* set bit 5 to enable frame length check */
   6227         } else {
   6228             rval &= ~0x20; /* clear bit 5 to disable frame length check */
   6229         }
   6230         if (!IS_QSGMII_PORT(unit, port)) {
   6231             /* set PFC frame detected indicator
   6232              * No RSV[34] bit in GPORT_RSV_MASK
   6233              */
   6234             rval |= 1 << 18;
   6235         }
   6236         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   6237     }
   6238 
   6239     return BCM_E_NONE;
   6240 }
   6241 
   6242 /*
   6243  * Function:
   6244  *      bcmi_xgs5_port_attach_rcpu_mtu
   6245  * Purpose:
   6246  *      Set the maximum receive frame size to JUMBO size for RCPU port
   6247  * Parameters:
   6248  *      unit    - (IN) Unit number.
   6249  *      port    - (IN) Logical port.
   6250  * Returns:
   6251  *      SOC_E_XXX
   6252  */
   6253 int
   6254 bcmi_xgs5_port_attach_rcpu_mtu(int unit, bcm_port_t port)
   6255 {
   6256 #ifdef BCM_RCPU_SUPPORT
   6257     if ((uint32)port == soc_property_get(unit, spn_RCPU_PORT, -1)) {
   6258         BCM_IF_ERROR_RETURN
   6259             (bcm_esw_port_frame_max_set(unit, port, BCM_PORT_JUMBO_MAXSZ));
   6260     }
   6261 #endif /* BCM_RCPU_SUPPORT */
   6262 
   6263     return BCM_E_NONE;
   6264 }
   6265 
   6266 /*
   6267  * Function:
   6268  *      bcmi_xgs5_port_attach_outer_tpid
   6269  * Purpose:
   6270  *      Enable the default Outer TPID
   6271  * Parameters:
   6272  *      unit    - (IN) Unit number.
   6273  *      port    - (IN) Logical port.
   6274  * Returns:
   6275  *      SOC_E_XXX
   6276  */
   6277 int
   6278 bcmi_xgs5_port_attach_outer_tpid(int unit, bcm_port_t port)
   6279 {
   6280     if (soc_feature(unit, soc_feature_egr_all_profile)) {
   6281         soc_field_t flds[3] = {
   6282             VT_MISS_UNTAGf,
   6283             REMARK_OUTER_DOT1Pf,
   6284             OUTER_TPID_VALIDf
   6285         };
   6286         uint32 vals[3] = {0, 1, 1};
   6287 
   6288         BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit,
   6289             port, EGR_VLAN_CONTROL_1m, 3, flds, vals));
   6290     }
   6291 
   6292     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   6293         BCM_IF_ERROR_RETURN
   6294             (bcm_esw_port_tpid_set(unit, port,
   6295                                _bcm_fb2_outer_tpid_default_get(unit)));
   6296     }
   6297     return BCM_E_NONE;
   6298 }
   6299 
   6300 /*
   6301  * Function:
   6302  *      bcmi_xgs5_port_egr_block_profile_init
   6303  * Purpose:
   6304  *      Initialize egress block profile pointer to invalid value
   6305  * Parameters:
   6306  *      unit    - (IN) Unit number.
   6307  *      port    - (IN) Logical port.
   6308  * Returns:
   6309  *      SOC_E_XXX
   6310  */
   6311 int
   6312 bcmi_xgs5_port_egr_block_profile_init(int unit, bcm_port_t port)
   6313 {
   6314     /* Initialize egress block profile pointer to invalid value */
   6315     BCM_IF_ERROR_RETURN
   6316         (bcmi_esw_port_egr_prof_ptr_set(unit, port, -1));
   6317 
   6318     return BCM_E_NONE;
   6319 }
   6320 
   6321 /*
   6322  * Function:
   6323  *      bcmi_xgs5_port_attach_vlan_protocol
   6324  * Purpose:
   6325  *      Program the VLAN_PROTOCOL_DATA_INDEX, FP_PORT_FIELD_SEL_INDEX,
   6326  *      PROTOCOL_PKT_INDEX pointers
   6327  * Parameters:
   6328  *      unit    - (IN) Unit number.
   6329  *      port    - (IN) Logical port.
   6330  * Returns:
   6331  *      SOC_E_XXX
   6332  */
   6333 int
   6334 bcmi_xgs5_port_attach_vlan_protocol(int unit, bcm_port_t port)
   6335 {
   6336     _bcm_port_info_t *pinfo;
   6337     uint32 profile_index;
   6338     vlan_protocol_data_entry_t vlan_protocol_data_entries[16];
   6339     uint32 vlan_protocol_data_index =0;
   6340     void *entries_buf[1];
   6341 
   6342     /* Get PORT info structure pointer */
   6343     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   6344     if  (pinfo == NULL) {
   6345         return BCM_E_INTERNAL;
   6346     }
   6347 
   6348     if (!IS_LB_PORT(unit, port) && !IS_TDM_PORT(unit, port)) {
   6349         if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) {
   6350             sal_memset(vlan_protocol_data_entries, 0,
   6351                        sizeof(vlan_protocol_data_entries));
   6352 
   6353             entries_buf[0] = &vlan_protocol_data_entries;
   6354 #if defined(BCM_TRIDENT3_SUPPORT)
   6355             if (SOC_IS_TRIDENT3X(unit)) {
   6356                 /* Trident3 default profile 0 */
   6357                 BCM_IF_ERROR_RETURN(
   6358                  _bcm_port_vlan_protocol_data_entry_get(unit, 0, 16, entries_buf));
   6359             }
   6360 #endif
   6361             BCM_IF_ERROR_RETURN(
   6362                  _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf,
   6363                                  16, (uint32 *)&vlan_protocol_data_index));
   6364         }
   6365 
   6366         if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_NONE) {
   6367             if (soc_mem_field_valid(unit, PORT_TABm,
   6368                         VLAN_PROTOCOL_DATA_INDEXf)) {
   6369             BCM_IF_ERROR_RETURN(
   6370                 _bcm_esw_port_tab_set(unit, port,
   6371                                _BCM_CPU_TABS_ETHER,
   6372                                VLAN_PROTOCOL_DATA_INDEXf,
   6373                                vlan_protocol_data_index/16));
   6374             }
   6375             pinfo->vlan_prot_ptr = vlan_protocol_data_index;
   6376         }
   6377 
   6378         if (soc_mem_field_valid(unit, PORT_TABm,
   6379             FP_PORT_FIELD_SEL_INDEXf)) {
   6380             BCM_IF_ERROR_RETURN(
   6381                 _bcm_esw_port_tab_set(unit, port,
   6382                            _BCM_CPU_TABS_ETHER,
   6383                             FP_PORT_FIELD_SEL_INDEXf, port));
   6384         }
   6385         if (soc_mem_field_valid(unit, PORT_TABm,
   6386                                 PROTOCOL_PKT_INDEXf)) {
   6387             if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
   6388                 soc_portreg) {
   6389                     BCM_IF_ERROR_RETURN(
   6390                         _bcm_esw_port_tab_set(unit, port,
   6391                                            _BCM_CPU_TABS_ETHER,
   6392                                            PROTOCOL_PKT_INDEXf,
   6393                                            port));
   6394             } else {
   6395                 BCM_IF_ERROR_RETURN
   6396                     (_bcm_prot_pkt_ctrl_add(unit, 0, 0,
   6397                                             &profile_index));
   6398                 BCM_IF_ERROR_RETURN
   6399                     (_bcm_esw_port_tab_set(unit, port,
   6400                                            _BCM_CPU_TABS_ETHER,
   6401                                            PROTOCOL_PKT_INDEXf,
   6402                                            profile_index));
   6403             }
   6404         }
   6405     }
   6406     return BCM_E_NONE;
   6407 }
   6408 /*
   6409  * Function:
   6410  *      bcmi_xgs5_port_attach_eee
   6411  * Purpose:
   6412  *      EEE config
   6413  * Parameters:
   6414  *      unit    - (IN) Unit number.
   6415  *      port    - (IN) Logical port.
   6416  * Returns:
   6417  *      SOC_E_XXX
   6418  */
   6419 int
   6420 bcmi_xgs5_port_attach_eee(int unit, bcm_port_t port)
   6421 {
   6422     int value = 0, rv;
   6423     _bcm_port_info_t *port_info;
   6424 
   6425     if (soc_feature (unit, soc_feature_eee)) {
   6426         if (!IS_LB_PORT(unit, port) && !IS_CPU_PORT (unit, port) &&
   6427             !IS_TDM_PORT(unit, port) && !IS_RDB_PORT(unit,port)) {
   6428             /* EEE standard compliance Work Around:
   6429              * Initialize the software state of native eee in MAC
   6430              */
   6431             BCM_IF_ERROR_RETURN
   6432                 (bcmi_esw_port_eee_cfg_set(unit, port, 0));
   6433             /* Check if MAC supports Native EEE and set the value of
   6434              * eee_cfg by reading the EEE status from MAC*/
   6435             if (SOC_USE_PORTCTRL(unit)) {
   6436                 rv = bcmi_esw_portctrl_eee_enable_get(unit, port, &value);
   6437             } else {
   6438                 _bcm_port_info_access(unit, port, &port_info);
   6439                 rv = MAC_CONTROL_GET(port_info->p_mac, unit, port,
   6440                                      SOC_MAC_CONTROL_EEE_ENABLE,
   6441                                      &value);
   6442             }
   6443             if (rv != BCM_E_UNAVAIL) {
   6444                 BCM_IF_ERROR_RETURN
   6445                     (bcmi_esw_port_eee_cfg_set(unit, port, value));
   6446             }
   6447         }
   6448     }
   6449     return BCM_E_NONE;
   6450 }
   6451 
   6452 /*
   6453  * Function:
   6454  *      bcmi_xgs5_port_attach_higig
   6455  * Purpose:
   6456  *      Set Higig/Higig2 mode
   6457  * Parameters:
   6458  *      unit    - (IN) Unit number.
   6459  *      port    - (IN) Logical port.
   6460  * Returns:
   6461  *      SOC_E_XXX
   6462  */
   6463 int
   6464 bcmi_xgs5_port_attach_higig(int unit, bcm_port_t port)
   6465 {
   6466     /**********
   6467      * HIGIG
   6468      */
   6469     if (IS_HG_PORT(unit, port)) {
   6470         if (SOC_USE_PORTCTRL(unit)) {
   6471             BCM_IF_ERROR_RETURN
   6472                 (bcmi_esw_portctrl_higig_mode_set(unit, port, TRUE));
   6473         }
   6474 #ifdef BCM_HIGIG2_SUPPORT
   6475         /* soc_feature_higig2 */
   6476         if (soc_feature(unit, soc_feature_higig2)) {
   6477             if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE,
   6478                     soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) ||
   6479                 SOC_USE_PORTCTRL(unit)) {
   6480                 BCM_IF_ERROR_RETURN
   6481                     (_bcm_esw_port_higig2_mode_set(unit, port, TRUE));
   6482                 SOC_HG2_ENABLED_PORT_ADD(unit, port);
   6483             }
   6484         }
   6485 #endif /* BCM_HIGIG2_SUPPORT */
   6486     }
   6487 
   6488     return BCM_E_NONE;
   6489 }
   6490 
   6491 /*
   6492  * Function:
   6493  *      bcmi_xgs5_port_attach_port_info_cfg
   6494  * Purpose:
   6495  *      Set SW PORT info
   6496  * Parameters:
   6497  *      unit    - (IN) Unit number.
   6498  *      port    - (IN) Logical port.
   6499  * Returns:
   6500  *      SOC_E_XXX
   6501  */
   6502 int
   6503 bcmi_xgs5_port_attach_port_info_cfg(int unit, bcm_port_t port)
   6504 {
   6505     _bcm_port_info_t *pinfo;
   6506     uint32 rx_los;
   6507     int enable;
   6508     int rv;
   6509 
   6510     /* Get PORT info structure pointer */
   6511     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   6512     if  (pinfo == NULL) {
   6513         return BCM_E_INTERNAL;
   6514     }
   6515 
   6516     /***********
   6517      * SW RX LOS configuration from PHY driver
   6518      */
   6519     if (IS_E_PORT(unit, port)) {
   6520         rv = bcm_esw_port_phy_control_get(unit, port,
   6521                                           BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS,
   6522                                           &rx_los);
   6523         if (BCM_SUCCESS(rv)) {
   6524             pinfo->rx_los = rx_los;
   6525         }
   6526     }
   6527 
   6528     /***********
   6529      * SW port enable status from HW
   6530      */
   6531     rv = bcm_esw_port_enable_get(unit, port, &enable);
   6532     if (BCM_SUCCESS(rv)) {
   6533         pinfo->enable = enable;
   6534     }
   6535 
   6536     return rv;
   6537 }
   6538 
   6539 /*
   6540  * Function:
   6541  *      bcmi_xgs5_port_attach_egr_link_delay
   6542  * Purpose:
   6543  *      Set port link delay
   6544  * Parameters:
   6545  *      unit    - (IN) Unit number.
   6546  *      port    - (IN) Logical port.
   6547  * Returns:
   6548  *      SOC_E_XXX
   6549  */
   6550 int
   6551 bcmi_xgs5_port_attach_egr_link_delay(int unit, bcm_port_t port)
   6552 {
   6553     int rv;
   6554     int speed;
   6555     uint64 rval64;
   6556     uint32 rval32;
   6557 
   6558     /**********
   6559      * Egress Link Delay
   6560      */
   6561     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   6562         rval32 = 0;
   6563         SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAYr(unit, port, rval32));
   6564     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   6565         COMPILER_64_ZERO(rval64);
   6566         SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64));
   6567     } else {
   6568         return BCM_E_NONE;
   6569     }
   6570 
   6571     rv = bcm_esw_port_speed_get(unit, port, &speed);
   6572     if (BCM_SUCCESS(rv)) {
   6573         rv = _bcm_esw_port_link_delay_update(unit, port, speed);
   6574     }
   6575 
   6576     return rv;
   6577 }
   6578 
   6579 /*
   6580  * Function:
   6581  *      bcmi_xgs5_port_attach_stg
   6582  * Purpose:
   6583  *      Set STP state of port to FORWARDING
   6584  * Parameters:
   6585  *      unit    - (IN) Unit number.
   6586  *      port    - (IN) Logical port.
   6587  * Returns:
   6588  *      SOC_E_XXX
   6589  */
   6590 int
   6591 bcmi_xgs5_port_attach_stg(int unit, bcm_port_t port)
   6592 {
   6593     /* STG */
   6594     BCM_IF_ERROR_RETURN
   6595         (bcm_esw_vlan_stp_set(unit, BCM_VLAN_DEFAULT, port, BCM_STG_STP_FORWARD));
   6596     return BCM_E_NONE;
   6597 }
   6598 
   6599 /*
   6600  * Function:
   6601  *      bcmi_xgs5_port_attach_vlan
   6602  * Purpose:
   6603  *      Add port into default vlan 1
   6604  * Parameters:
   6605  *      unit    - (IN) Unit number.
   6606  *      port    - (IN) Logical port.
   6607  * Returns:
   6608  *      SOC_E_XXX
   6609  */
   6610 int
   6611 bcmi_xgs5_port_attach_vlan(int unit, bcm_port_t port)
   6612 {
   6613 #ifndef BCM_VLAN_NO_DEFAULT_ETHER
   6614     /* Add ports to default VLAN only if vlan policy allows it */
   6615     bcm_pbmp_t pbmp;
   6616 
   6617     /* VLAN */
   6618     BCM_PBMP_CLEAR(pbmp);
   6619     BCM_PBMP_PORT_ADD(pbmp, port);
   6620     BCM_IF_ERROR_RETURN
   6621         (bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbmp, pbmp));
   6622 #endif
   6623     return BCM_E_NONE;
   6624 }
   6625 
   6626 /*
   6627  * Function:
   6628  *      bcmi_xgs5_port_attach_trunk
   6629  * Purpose:
   6630  *      Initializes trunk tables for newly added port
   6631  * Parameters:
   6632  *      unit    - (IN) Unit number.
   6633  *      port    - (IN) Logical port.
   6634  * Returns:
   6635  *      SOC_E_XXX
   6636  */
   6637 int
   6638 bcmi_xgs5_port_attach_trunk(int unit, bcm_port_t port)
   6639 {
   6640     bcm_pbmp_t pbmp;
   6641     higig_trunk_control_entry_t entry;
   6642     int rv = BCM_E_NONE;
   6643 
   6644     /* TRUNK */
   6645     if (soc_feature(unit, soc_feature_hg_trunking)) {
   6646         
   6647         soc_mem_lock(unit, HIGIG_TRUNK_CONTROLm);
   6648 
   6649         rv = soc_mem_read(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ANY, 0, &entry);
   6650         if (BCM_FAILURE(rv)) {
   6651             soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm);
   6652             return rv;
   6653         }
   6654 
   6655         BCM_PBMP_CLEAR(pbmp);
   6656 
   6657         /* Read port bmap from hardware, and add new port to the bitmap */
   6658         soc_mem_pbmp_field_get(unit, HIGIG_TRUNK_CONTROLm, &entry,
   6659                                ACTIVE_PORT_BITMAPf, &pbmp);
   6660 
   6661         BCM_PBMP_PORT_ADD(pbmp, port);
   6662 
   6663         soc_mem_pbmp_field_set(unit, HIGIG_TRUNK_CONTROLm, &entry,
   6664                            ACTIVE_PORT_BITMAPf, &pbmp);
   6665 
   6666         rv = soc_mem_write(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ALL, 0,
   6667                        &entry);
   6668 
   6669         soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm);
   6670     }
   6671     return rv;
   6672 }
   6673 
   6674 /*
   6675  * Function:
   6676  *      bcmi_xgs5_port_attach_linkscan
   6677  * Purpose:
   6678  *      Initializes linkscan on port
   6679  * Parameters:
   6680  *      unit    - (IN) Unit number.
   6681  *      port    - (IN) Logical port.
   6682  * Returns:
   6683  *      SOC_E_XXX
   6684  */
   6685 int
   6686 bcmi_xgs5_port_attach_linkscan(int unit, bcm_port_t port)
   6687 {
   6688 
   6689     /* Skip linkscan if module hasn't init */
   6690     if (_bcm_esw_lc_check_init(unit) != BCM_E_NONE) {
   6691         return BCM_E_NONE;
   6692     }
   6693 
   6694     /* LINKSCAN */
   6695     BCM_IF_ERROR_RETURN
   6696         (_soc_linkscan_hw_port_init(unit, port));
   6697 
   6698     /* Initialze to SW linkscan mode */
   6699     BCM_IF_ERROR_RETURN(bcm_esw_linkscan_port_attach(unit, port));
   6700 
   6701     return BCM_E_NONE;
   6702 }
   6703 
   6704 /*
   6705  * Function:
   6706  *      bcmi_xgs5_port_attach_stack
   6707  * Purpose:
   6708  *      Initializes statistic on port
   6709  * Parameters:
   6710  *      unit    - (IN) Unit number.
   6711  *      port    - (IN) Logical port.
   6712  * Returns:
   6713  *      SOC_E_XXX
   6714  */
   6715 int
   6716 bcmi_xgs5_port_attach_stat(int unit, bcm_port_t port)
   6717 {
   6718     pbmp_t      pbmp;
   6719     int         config_threshold;
   6720 
   6721     config_threshold = soc_property_get(unit, spn_BCM_STAT_JUMBO, 1518);
   6722     if ((config_threshold < 1518) ||
   6723         (config_threshold > 0x3fff) ) {
   6724         config_threshold = 1518;
   6725     }
   6726 
   6727     BCM_IF_ERROR_RETURN
   6728         (_bcm_esw_stat_ovr_threshold_set(unit, port, config_threshold));
   6729 
   6730     /* Clear counters */
   6731     SOC_PBMP_CLEAR(pbmp);
   6732     SOC_PBMP_PORT_ADD(pbmp, port);
   6733     BCM_IF_ERROR_RETURN(soc_counter_set32_by_port(unit, pbmp, 0));
   6734 
   6735     /* Note: Assuming soc_counter_start would be called later after
   6736              all the modules for the new port are initialised */
   6737 
   6738     return BCM_E_NONE;
   6739 }
   6740 
   6741 /*
   6742  * Function:
   6743  *      bcmi_xgs5_port_attach_stack
   6744  * Purpose:
   6745  *      Initializes stack on port
   6746  * Parameters:
   6747  *      unit    - (IN) Unit number.
   6748  *      port    - (IN) Logical port.
   6749  * Returns:
   6750  *      SOC_E_XXX
   6751  */
   6752 int
   6753 bcmi_xgs5_port_attach_stack(int unit, bcm_port_t port)
   6754 {
   6755 
   6756     /* Set HG ingress CPU Opcode map to the CPU */
   6757     if (IS_ST_PORT(unit, port)) {
   6758         pbmp_t      pbmp;
   6759         icontrol_opcode_bitmap_entry_t entry;
   6760 
   6761         SOC_PBMP_CLEAR(pbmp);
   6762         SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit));
   6763 
   6764         BCM_IF_ERROR_RETURN
   6765             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port,
   6766                                           &entry));
   6767         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
   6768                                BITMAPf, &pbmp);
   6769         BCM_IF_ERROR_RETURN
   6770             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port,
   6771                                            &entry));
   6772     }
   6773 
   6774     /* Initialize modport map profiles ptr on port.*/
   6775     if (soc_feature(unit, soc_feature_modport_map_dest_is_port_or_trunk)) {
   6776         BCM_IF_ERROR_RETURN
   6777             (bcm_td_stk_modport_map_port_attach(unit, port));
   6778     }
   6779 
   6780     return BCM_E_NONE;
   6781 }
   6782 
   6783 /*
   6784  * Function:
   6785  *      bcmi_xgs5_port_attach_rate
   6786  * Purpose:
   6787  *      Initialize port related information in the Rate module.
   6788  * Parameters:
   6789  *      unit    - (IN) Unit number.
   6790  *      port    - (IN) Logical port.
   6791  * Returns:
   6792  *      SOC_E_XXX
   6793  */
   6794 int
   6795 bcmi_xgs5_port_attach_rate(int unit, bcm_port_t port)
   6796 {
   6797     soc_field_t fields[] = {PACKET_QUANTUMf, BYTE_MODEf};
   6798     uint32 values[] = {0x100, 1};
   6799 
   6800     BCM_IF_ERROR_RETURN
   6801         (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0));
   6802 
   6803     BCM_IF_ERROR_RETURN
   6804         (soc_reg_fields32_modify(unit,
   6805                                  STORM_CONTROL_METER_CONFIGr,
   6806                                  port, COUNTOF(fields),
   6807                                  fields, values));
   6808 
   6809     return BCM_E_NONE;
   6810 }
   6811 
   6812 /*
   6813  * Function:
   6814  *      bcmi_xgs5_port_attach_field
   6815  * Purpose:
   6816  *      Enable filter lookup, ingress filter, egress filter on port
   6817  * Parameters:
   6818  *      unit    - (IN) Unit number.
   6819  *      port    - (IN) Logical port.
   6820  * Returns:
   6821  *      SOC_E_XXX
   6822  */
   6823 int
   6824 bcmi_xgs5_port_attach_field(int unit, bcm_port_t port)
   6825 {
   6826 #ifdef BCM_FIELD_SUPPORT
   6827     /* FIELD */
   6828     if (soc_feature(unit, soc_feature_field)) {
   6829         BCM_IF_ERROR_RETURN
   6830             (bcm_esw_port_control_set(unit, port,
   6831                                       bcmPortControlFilterLookup, 1));
   6832         BCM_IF_ERROR_RETURN
   6833             (bcm_esw_port_control_set(unit, port,
   6834                                       bcmPortControlFilterIngress, 1));
   6835         BCM_IF_ERROR_RETURN
   6836             (bcm_esw_port_control_set(unit, port,
   6837                                       bcmPortControlFilterEgress, 1));
   6838     }
   6839     BCM_IF_ERROR_RETURN
   6840         (_bcm_field_flex_port_attach(unit, port));
   6841 #endif /* BCM_FIELD_SUPPORT */
   6842 
   6843     return BCM_E_NONE;
   6844 }
   6845 
   6846 /*
   6847  * Function:
   6848  *      bcmi_xgs5_port_attach_mirror
   6849  * Purpose:
   6850  *      Initialize the mirror per-port configuration in the runtime
   6851  * Parameters:
   6852  *      unit    - (IN) Unit number.
   6853  *      port    - (IN) Logical port.
   6854  * Returns:
   6855  *      SOC_E_XXX
   6856  */
   6857 int
   6858 bcmi_xgs5_port_attach_mirror(int unit, bcm_port_t port)
   6859 {
   6860     /* MIRROR */
   6861     BCM_IF_ERROR_RETURN
   6862         (bcmi_esw_mirror_port_attach(unit, port));
   6863 
   6864     return BCM_E_NONE;
   6865 }
   6866 
   6867 /*
   6868  * Function:
   6869  *      bcmi_xgs5_port_attach_l3
   6870  * Purpose:
   6871  *      Enable IPv4, IPv6 on port
   6872  * Parameters:
   6873  *      unit    - (IN) Unit number.
   6874  *      port    - (IN) Logical port.
   6875  * Returns:
   6876  *      SOC_E_XXX
   6877  */
   6878 int
   6879 bcmi_xgs5_port_attach_l3(int unit, bcm_port_t port)
   6880 {
   6881 #ifdef INCLUDE_L3
   6882     /* L3 */
   6883     if (soc_feature(unit, soc_feature_l3) &&
   6884         soc_property_get(unit, spn_L3_ENABLE, 1) &&
   6885         !IS_ST_PORT(unit, port)) {
   6886 
   6887         BCM_IF_ERROR_RETURN
   6888             (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 1));
   6889         BCM_IF_ERROR_RETURN
   6890             (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 1));
   6891     }
   6892 #endif /* INCLUDE_L3 */
   6893     return BCM_E_NONE;
   6894 }
   6895 
   6896 /*
   6897  * Function:
   6898  *      bcmi_xgs5_port_attach_ipmc
   6899  * Purpose:
   6900  *      Initialize IPMC per-port configuration
   6901  * Parameters:
   6902  *      unit    - (IN) Unit number.
   6903  *      port    - (IN) Logical port.
   6904  * Returns:
   6905  *      SOC_E_XXX
   6906  */
   6907 int
   6908 bcmi_xgs5_port_attach_ipmc(int unit, bcm_port_t port)
   6909 {
   6910 #ifdef INCLUDE_L3
   6911     soc_field_t fields_lport[3] = {V4IPMC_ENABLEf, V6IPMC_ENABLEf, IPMC_DO_VLANf};
   6912     uint32      field_values[3] = {1, 1, 1};
   6913     /* IPMC */
   6914     if (soc_feature(unit, soc_feature_ip_mcast)) {
   6915 
   6916         int do_vlan = soc_property_get(unit, spn_IPMC_DO_VLAN, 1);
   6917 
   6918         field_values[2] = (do_vlan) ? 1 : 0;
   6919 
   6920         BCM_IF_ERROR_RETURN
   6921             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV4Enable, 1));
   6922         BCM_IF_ERROR_RETURN
   6923             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV6Enable, 1));
   6924         BCM_IF_ERROR_RETURN
   6925             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcVlanKey,
   6926                                       do_vlan ? 1 : 0));
   6927         BCM_IF_ERROR_RETURN(
   6928             bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB, 3, 
   6929                                           fields_lport, field_values)); 
   6930 
   6931         if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
   6932             return BCM_E_NONE;
   6933         }
   6934         if (IS_E_PORT(unit,port)) {
   6935             BCM_IF_ERROR_RETURN
   6936                 (bcm_esw_ipmc_egress_port_set(unit, port, _soc_mac_all_zeroes,
   6937                                               0, 0, 0));
   6938         }
   6939     }
   6940 #endif /* INCLUDE_L3 */
   6941     return BCM_E_NONE;
   6942 }
   6943 
   6944 /*
   6945  * Function:
   6946  *      bcmi_xgs5_port_attach_mpls
   6947  * Purpose:
   6948  *      Enable MPLS on port.
   6949  * Parameters:
   6950  *      unit    - (IN) Unit number.
   6951  *      port    - (IN) Logical port.
   6952  * Returns:
   6953  *      SOC_E_XXX
   6954  */
   6955 int
   6956 bcmi_xgs5_port_attach_mpls(int unit, bcm_port_t port)
   6957 {
   6958     int rv = BCM_E_NONE;
   6959 
   6960 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   6961     /* MPLS */
   6962     if (soc_feature(unit, soc_feature_mpls) &&
   6963         !IS_ST_PORT(unit, port)) {
   6964         BCM_IF_ERROR_RETURN
   6965             (bcm_esw_port_control_set(unit, port, bcmPortControlMpls, 1));
   6966     }
   6967 #endif /* L3 && BCM_MPLS_SUPPORT */
   6968     return rv;
   6969 }
   6970 
   6971 /*
   6972  * Function:
   6973  *      bcmi_xgs5_port_attach_mim
   6974  * Purpose:
   6975  *      Enable MAC-in-MAC frame processing on port.
   6976  * Parameters:
   6977  *      unit    - (IN) Unit number.
   6978  *      port    - (IN) Logical port.
   6979  * Returns:
   6980  *      SOC_E_XXX
   6981  */
   6982 int
   6983 bcmi_xgs5_port_attach_mim(int unit, bcm_port_t port)
   6984 {
   6985 #ifdef INCLUDE_L3
   6986     /* MIM */
   6987     if (soc_feature(unit, soc_feature_mim) &&
   6988         !IS_ST_PORT(unit, port)) {
   6989         BCM_IF_ERROR_RETURN
   6990             (bcm_esw_port_control_set(unit, port, bcmPortControlMacInMac, 1));
   6991     }
   6992 #endif /* INCLUDE_L3 */
   6993     return BCM_E_NONE;
   6994 }
   6995 
   6996 /*
   6997  * Function:
   6998  *      bcmi_xgs5_port_detach_dscp
   6999  * Purpose:
   7000  *      Detach port from default DSCP profile
   7001  * Parameters:
   7002  *      unit    - (IN) Unit number.
   7003  *      port    - (IN) Logical port.
   7004  * Returns:
   7005  *      SOC_E_XXX
   7006  */
   7007 int
   7008 bcmi_xgs5_port_detach_dscp(int unit, bcm_port_t port)
   7009 {
   7010     int value;
   7011     uint32 dscp_index;
   7012 
   7013     BCM_IF_ERROR_RETURN
   7014         (_bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &value));
   7015     dscp_index = value * 64;
   7016     if (0 == dscp_index) {
   7017         BCM_IF_ERROR_RETURN
   7018             (_bcm_dscp_table_entry_delete(unit, dscp_index));
   7019     }
   7020 
   7021     return BCM_E_NONE;
   7022 }
   7023 
   7024 /*
   7025  * Function:
   7026  *      bcmi_xgs5_port_detach_port_info_init
   7027  * Purpose:
   7028  *      Initialize BCM PORT info structure (bcm_port_info[unit][port])
   7029  * Parameters:
   7030  *      unit    - (IN) Unit number.
   7031  *      port    - (IN) Logical port.
   7032  * Returns:
   7033  *      SOC_E_XXX
   7034  */
   7035 int
   7036 bcmi_xgs5_port_detach_software(int unit, bcm_port_t port)
   7037 {
   7038     _bcm_port_info_t *pinfo;
   7039     int index;
   7040     int enabled;
   7041     uint32 value;
   7042 
   7043     /*
   7044      * Update TPID reference count
   7045      */
   7046     if (soc_feature(unit, soc_feature_vlan_ctrl)) {
   7047         if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) {
   7048             if (soc_feature(unit, soc_feature_egr_all_profile)) {
   7049                 BCM_IF_ERROR_RETURN(
   7050                     bcm_esw_port_egr_lport_field_get(
   7051                     unit, port, EGR_VLAN_CONTROL_1m,
   7052                     OUTER_TPID_INDEXf, (uint32 *)&index));
   7053             } else {
   7054                 BCM_IF_ERROR_RETURN(
   7055                     READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &value));
   7056                 index = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_1m,
   7057                                             &value, OUTER_TPID_INDEXf);
   7058             }
   7059         } else {
   7060             BCM_IF_ERROR_RETURN
   7061                 (READ_EGR_VLAN_CONTROL_1r(unit, port, &value));
   7062             index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r,
   7063                                   value, OUTER_TPID_INDEXf);
   7064         }
   7065 
   7066         /* Ignore error when deleting */
   7067         (void)_bcm_fb2_outer_tpid_entry_delete(unit, index);
   7068 
   7069         enabled = 0;
   7070         BCM_IF_ERROR_RETURN
   7071             (_bcm_esw_port_config_get(unit, port,
   7072                                       _bcmPortOuterTpidEnables, &enabled));
   7073         index = 0;
   7074         while (enabled) {
   7075             if (enabled & 1) {
   7076                 /* Ignore error when deleting */
   7077                 (void)_bcm_fb2_outer_tpid_entry_delete(unit, index);
   7078             }
   7079             enabled = enabled >> 1;
   7080             index++;
   7081         }
   7082     }
   7083 
   7084     /* Clear the Port INFO */
   7085     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   7086     if  (pinfo == NULL) {
   7087         return BCM_E_INIT;
   7088     }
   7089 
   7090     if (pinfo->p_vd_pbvl != NULL) {
   7091         sal_free(pinfo->p_vd_pbvl);
   7092         pinfo->p_vd_pbvl = NULL;
   7093     }
   7094     if (pinfo->e2ecc_config != NULL) {
   7095         sal_free(pinfo->e2ecc_config);
   7096         pinfo->e2ecc_config = NULL;
   7097     }
   7098 
   7099     sal_memset(pinfo, 0, sizeof(_bcm_port_info_t));
   7100 
   7101 
   7102     return BCM_E_NONE;
   7103 }
   7104 
   7105 /*
   7106  * Function:
   7107  *      bcmi_xgs5_port_detach_egr_vlan_action
   7108  * Purpose:
   7109  *      Set the egress port's default vlan tag actions
   7110  * Parameters:
   7111  *      unit    - (IN) Unit number.
   7112  *      port    - (IN) Logical port.
   7113  * Returns:
   7114  *      SOC_E_XXX
   7115  */
   7116 int
   7117 bcmi_xgs5_port_detach_egr_vlan_action(int unit, bcm_port_t port)
   7118 {
   7119     if (soc_feature(unit, soc_feature_vlan_action)) {
   7120         BCM_IF_ERROR_RETURN
   7121             (_bcm_trx_vlan_port_egress_default_action_delete(unit, port));
   7122     }
   7123     return BCM_E_NONE;
   7124 }
   7125 
   7126 /*
   7127  * Function:
   7128  *      bcmi_xgs5_port_detach_phy
   7129  * Purpose:
   7130  *      Probe the PHY and set up the PHY and MAC for the specified ports.
   7131  *      This is purely a discovery routine and does no configuration.
   7132  * Parameters:
   7133  *      unit    - (IN) Unit number.
   7134  *      port    - (IN) Logical port.
   7135  * Returns:
   7136  *      SOC_E_XXX
   7137  */
   7138 int
   7139 bcmi_xgs5_port_detach_phy(int unit, bcm_port_t port)
   7140 {
   7141     int rv;
   7142     soc_persist_t *sop = SOC_PERSIST(unit);
   7143 
   7144     /* If PortMod enable, detach phy is handled in _bcmi_xgs5_port_pm_delete */
   7145     if (SOC_USE_PORTCTRL(unit)) {
   7146         return BCM_E_NONE;
   7147     }
   7148 
   7149     BCM_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port));
   7150 
   7151     PORT_LOCK(unit);
   7152     rv = _bcm_port_mode_setup(unit, port, FALSE);
   7153     PORT_UNLOCK(unit);
   7154     BCM_IF_ERROR_RETURN(rv);
   7155 
   7156     if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) {
   7157         /* Bring down the internal PHY */
   7158         BCM_IF_ERROR_RETURN(bcm_esw_port_update(unit, port, FALSE));
   7159         SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port);
   7160     }
   7161     return BCM_E_NONE;
   7162 }
   7163 
   7164 /*
   7165  * Function:
   7166  *      bcmi_xgs5_port_detach_vlan_protocol
   7167  * Purpose:
   7168  *      Clear the VLAN_PROTOCOL_DATA_INDEX, FP_PORT_FIELD_SEL_INDEX,
   7169  *      PROTOCOL_PKT_INDEX pointers
   7170  * Parameters:
   7171  *      unit    - (IN) Unit number.
   7172  *      port    - (IN) Logical port.
   7173  * Returns:
   7174  *      SOC_E_XXX
   7175  */
   7176 int
   7177 bcmi_xgs5_port_detach_vlan_protocol(int unit, bcm_port_t port)
   7178 {
   7179     _bcm_port_info_t *pinfo;
   7180     int value = 0;
   7181 
   7182     /* Get PORT info structure pointer */
   7183     BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo));
   7184     if  (pinfo == NULL) {
   7185         return BCM_E_INTERNAL;
   7186     }
   7187 
   7188     if (!IS_LB_PORT(unit, port) && !IS_TDM_PORT(unit, port)) {
   7189 
   7190         if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_NONE) {
   7191             if (soc_mem_field_valid(unit, PORT_TABm,
   7192                         VLAN_PROTOCOL_DATA_INDEXf)) {
   7193             BCM_IF_ERROR_RETURN(
   7194                 _bcm_esw_port_tab_set(unit, port,
   7195                                _BCM_CPU_TABS_ETHER,
   7196                                VLAN_PROTOCOL_DATA_INDEXf,
   7197                                0));
   7198         }
   7199         }
   7200 
   7201         if (soc_mem_field_valid(unit, PORT_TABm,
   7202             FP_PORT_FIELD_SEL_INDEXf)) {
   7203             BCM_IF_ERROR_RETURN(
   7204                 _bcm_esw_port_tab_set(unit, port,
   7205                            _BCM_CPU_TABS_ETHER,
   7206                             FP_PORT_FIELD_SEL_INDEXf, 0));
   7207         }
   7208         if (soc_mem_field_valid(unit, PORT_TABm,
   7209                                 PROTOCOL_PKT_INDEXf)) {
   7210             if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype ==
   7211                 soc_portreg) {
   7212                     BCM_IF_ERROR_RETURN(
   7213                         _bcm_esw_port_tab_set(unit, port,
   7214                                            _BCM_CPU_TABS_ETHER,
   7215                                            PROTOCOL_PKT_INDEXf,
   7216                                            0));
   7217             } else {
   7218                 BCM_IF_ERROR_RETURN
   7219                     (_bcm_esw_port_tab_get(unit, port,
   7220                                            PROTOCOL_PKT_INDEXf,
   7221                                            &value));
   7222                 BCM_IF_ERROR_RETURN
   7223                     (_bcm_prot_pkt_ctrl_delete(unit, value));
   7224                 BCM_IF_ERROR_RETURN
   7225                     (_bcm_esw_port_tab_set(unit, port,
   7226                                            _BCM_CPU_TABS_ETHER,
   7227                                            PROTOCOL_PKT_INDEXf,
   7228                                            0));
   7229             }
   7230         }
   7231     }
   7232     BCM_IF_ERROR_RETURN(
   7233         _bcm_port_vlan_protocol_data_entry_delete(unit, pinfo->vlan_prot_ptr));
   7234     return BCM_E_NONE;
   7235 }
   7236 
   7237 /*
   7238  * Function:
   7239  *      bcmi_xgs5_port_detach_eee
   7240  * Purpose:
   7241  *      EEE config
   7242  * Parameters:
   7243  *      unit    - (IN) Unit number.
   7244  *      port    - (IN) Logical port.
   7245  * Returns:
   7246  *      SOC_E_XXX
   7247  */
   7248 int
   7249 bcmi_xgs5_port_detach_eee(int unit, bcm_port_t port)
   7250 {
   7251     if (!IS_LB_PORT(unit, port) && !IS_CPU_PORT (unit, port) &&
   7252         !IS_TDM_PORT(unit, port)) {
   7253         BCM_IF_ERROR_RETURN
   7254             (bcmi_esw_port_eee_cfg_set(unit, port, 0));
   7255     }
   7256 
   7257     return BCM_E_NONE;
   7258 }
   7259 
   7260 /*
   7261  * Function:
   7262  *      bcmi_xgs5_port_detach_higig
   7263  * Purpose:
   7264  *      Remove port from hg2_pbm
   7265  * Parameters:
   7266  *      unit    - (IN) Unit number.
   7267  *      port    - (IN) Logical port.
   7268  * Returns:
   7269  *      SOC_E_XXX
   7270  */
   7271 int
   7272 bcmi_xgs5_port_detach_higig(int unit, bcm_port_t port)
   7273 {
   7274     /**********
   7275      * HIGIG
   7276      */
   7277     if (IS_HG_PORT(unit, port)) {
   7278         if (SOC_USE_PORTCTRL(unit)) {
   7279             BCM_IF_ERROR_RETURN
   7280                 (bcmi_esw_portctrl_higig_mode_set(unit, port, FALSE));
   7281         }
   7282 #ifdef BCM_HIGIG2_SUPPORT
   7283         /* soc_feature_higig2 */
   7284         if (soc_feature(unit, soc_feature_higig2)) {
   7285             if (soc_property_port_get(unit, port, spn_HIGIG2_HDR_MODE,
   7286                     soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) ||
   7287                 SOC_USE_PORTCTRL(unit)) {
   7288                 BCM_IF_ERROR_RETURN
   7289                     (_bcm_esw_port_higig2_mode_set(unit, port, FALSE));
   7290                 SOC_HG2_ENABLED_PORT_REMOVE(unit, port);
   7291             }
   7292         }
   7293 #endif /* BCM_HIGIG2_SUPPORT */
   7294     }
   7295 
   7296     return BCM_E_NONE;
   7297 }
   7298 
   7299 /*
   7300  * Function:
   7301  *      bcmi_xgs5_port_detach_egr_link_delay
   7302  * Purpose:
   7303  *      Clear port link delay
   7304  * Parameters:
   7305  *      unit    - (IN) Unit number.
   7306  *      port    - (IN) Logical port.
   7307  * Returns:
   7308  *      SOC_E_XXX
   7309  */
   7310 int
   7311 bcmi_xgs5_port_detach_egr_link_delay(int unit, bcm_port_t port)
   7312 {
   7313     if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) {
   7314         BCM_IF_ERROR_RETURN
   7315             (soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr, port,
   7316                                     LINK_DELAYf, 0));
   7317     } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) {
   7318         BCM_IF_ERROR_RETURN
   7319             (soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r,
   7320                                              port, 0, LINK_DELAYf, 0));
   7321     }
   7322 
   7323     return BCM_E_NONE;
   7324 }
   7325 
   7326 /*
   7327  * Function:
   7328  *      bcmi_xgs5_port_detach_stg
   7329  * Purpose:
   7330  *      Set STP state of port to DISABLE
   7331  * Parameters:
   7332  *      unit    - (IN) Unit number.
   7333  *      port    - (IN) Logical port.
   7334  * Returns:
   7335  *      SOC_E_XXX
   7336  */
   7337 int
   7338 bcmi_xgs5_port_detach_stg(int unit, bcm_port_t port)
   7339 {
   7340     /* STG */
   7341     BCM_IF_ERROR_RETURN
   7342         (bcm_esw_vlan_stp_set(unit, BCM_VLAN_DEFAULT, port, BCM_STG_STP_DISABLE));
   7343     return BCM_E_NONE;
   7344 }
   7345 
   7346 /*
   7347  * Function:
   7348  *      bcmi_xgs5_port_detach_vlan
   7349  * Purpose:
   7350  *      Remove port from default vlan 1
   7351  * Parameters:
   7352  *      unit    - (IN) Unit number.
   7353  *      port    - (IN) Logical port.
   7354  * Returns:
   7355  *      SOC_E_XXX
   7356  */
   7357 int
   7358 bcmi_xgs5_port_detach_vlan(int unit, bcm_port_t port)
   7359 {
   7360     bcm_pbmp_t pbmp;
   7361 
   7362     /* VLAN */
   7363     BCM_PBMP_CLEAR(pbmp);
   7364     BCM_PBMP_PORT_ADD(pbmp, port);
   7365     BCM_IF_ERROR_RETURN
   7366         (bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbmp));
   7367 
   7368     return BCM_E_NONE;
   7369 }
   7370 
   7371 /*
   7372  * Function:
   7373  *      bcmi_xgs5_port_detach_trunk
   7374  * Purpose:
   7375  *      Update the trunk tables for a deleted port
   7376  * Parameters:
   7377  *      unit    - (IN) Unit number.
   7378  *      port    - (IN) Logical port.
   7379  * Returns:
   7380  *      SOC_E_XXX
   7381  */
   7382 int
   7383 bcmi_xgs5_port_detach_trunk(int unit, bcm_port_t port)
   7384 {
   7385     bcm_pbmp_t pbmp;
   7386     higig_trunk_control_entry_t entry;
   7387     int rv = BCM_E_NONE;
   7388 
   7389     /* TRUNK */
   7390     if (soc_feature(unit, soc_feature_hg_trunking)) {
   7391         
   7392         soc_mem_lock(unit, HIGIG_TRUNK_CONTROLm);
   7393 
   7394         rv = soc_mem_read(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ANY, 0, &entry);
   7395         if (BCM_FAILURE(rv)) {
   7396             soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm);
   7397             return rv;
   7398         }
   7399 
   7400         BCM_PBMP_CLEAR(pbmp);
   7401 
   7402         /* Read port bmap from hardware, and remove new port to the bitmap */
   7403         soc_mem_pbmp_field_get(unit, HIGIG_TRUNK_CONTROLm, &entry,
   7404                                ACTIVE_PORT_BITMAPf, &pbmp);
   7405 
   7406         BCM_PBMP_PORT_REMOVE(pbmp, port);
   7407 
   7408         soc_mem_pbmp_field_set(unit, HIGIG_TRUNK_CONTROLm, &entry,
   7409                            ACTIVE_PORT_BITMAPf, &pbmp);
   7410 
   7411         rv = soc_mem_write(unit, HIGIG_TRUNK_CONTROLm, MEM_BLOCK_ALL, 0,
   7412                        &entry);
   7413 
   7414         soc_mem_unlock(unit, HIGIG_TRUNK_CONTROLm);
   7415     }
   7416     return rv;
   7417 }
   7418 
   7419 /*
   7420  * Function:
   7421  *      bcmi_xgs5_port_detach_stack
   7422  * Purpose:
   7423  *      Clear port related information in the Stack module.
   7424  * Parameters:
   7425  *      unit    - (IN) Unit number.
   7426  *      port    - (IN) Logical port.
   7427  * Returns:
   7428  *      SOC_E_XXX
   7429  */
   7430 int
   7431 bcmi_xgs5_port_detach_stack(int unit, bcm_port_t port)
   7432 {
   7433 
   7434     /* Clear HG ingress CPU Opcode bitmap */
   7435     if (IS_ST_PORT(unit, port)) {
   7436         pbmp_t      pbmp;
   7437         icontrol_opcode_bitmap_entry_t entry;
   7438 
   7439         SOC_PBMP_CLEAR(pbmp);
   7440 
   7441         BCM_IF_ERROR_RETURN
   7442             (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port,
   7443                                           &entry));
   7444         soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry,
   7445                                BITMAPf, &pbmp);
   7446         BCM_IF_ERROR_RETURN
   7447             (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port,
   7448                                            &entry));
   7449     }
   7450 
   7451     /* detach port from modport map profiles */
   7452     if (soc_feature(unit, soc_feature_modport_map_dest_is_port_or_trunk)) {
   7453         BCM_IF_ERROR_RETURN
   7454             (bcm_td_stk_modport_map_port_detach(unit, port));
   7455     }
   7456 
   7457     return BCM_E_NONE;
   7458 }
   7459 
   7460 /*
   7461  * Function:
   7462  *      bcmi_xgs5_port_detach_rate
   7463  * Purpose:
   7464  *      Clear port related information in the Rate module.
   7465  * Parameters:
   7466  *      unit    - (IN) Unit number.
   7467  *      port    - (IN) Logical port.
   7468  * Returns:
   7469  *      SOC_E_XXX
   7470  */
   7471 int
   7472 bcmi_xgs5_port_detach_rate(int unit, bcm_port_t port)
   7473 {
   7474     BCM_IF_ERROR_RETURN
   7475         (WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0));
   7476 
   7477     return BCM_E_NONE;
   7478 }
   7479 
   7480 /*
   7481  * Function:
   7482  *      bcmi_xgs5_port_detach_field
   7483  * Purpose:
   7484  *      Disaable filter lookup, ingress filter, egress filter on port
   7485  * Parameters:
   7486  *      unit    - (IN) Unit number.
   7487  *      port    - (IN) Logical port.
   7488  * Returns:
   7489  *      SOC_E_XXX
   7490  */
   7491 int
   7492 bcmi_xgs5_port_detach_field(int unit, bcm_port_t port)
   7493 {
   7494 #ifdef BCM_FIELD_SUPPORT
   7495     /* FIELD */
   7496     if (soc_feature(unit, soc_feature_field)) {
   7497         BCM_IF_ERROR_RETURN
   7498             (bcm_esw_port_control_set(unit, port,
   7499                                       bcmPortControlFilterLookup, 0));
   7500         BCM_IF_ERROR_RETURN
   7501             (bcm_esw_port_control_set(unit, port,
   7502                                       bcmPortControlFilterIngress, 0));
   7503         BCM_IF_ERROR_RETURN
   7504             (bcm_esw_port_control_set(unit, port,
   7505                                       bcmPortControlFilterEgress, 0));
   7506     }
   7507     BCM_IF_ERROR_RETURN
   7508         (_bcm_field_flex_port_detach(unit, port));
   7509 #endif /* BCM_FIELD_SUPPORT */
   7510 
   7511     return BCM_E_NONE;
   7512 }
   7513 
   7514 /*
   7515  * Function:
   7516  *      bcmi_xgs5_port_detach_mirror
   7517  * Purpose:
   7518  *      Clear the mirror per-port configuration in the runtime
   7519  * Parameters:
   7520  *      unit    - (IN) Unit number.
   7521  *      port    - (IN) Logical port.
   7522  * Returns:
   7523  *      SOC_E_XXX
   7524  */
   7525 int
   7526 bcmi_xgs5_port_detach_mirror(int unit, bcm_port_t port)
   7527 {
   7528     /* MIRROR */
   7529     BCM_IF_ERROR_RETURN
   7530         (bcmi_esw_mirror_port_detach(unit, port));
   7531 
   7532     return BCM_E_NONE;
   7533 }
   7534 
   7535 /*
   7536  * Function:
   7537  *      bcmi_xgs5_port_detach_l3
   7538  * Purpose:
   7539  *      Disable IPv4, IPv6 on port
   7540  * Parameters:
   7541  *      unit    - (IN) Unit number.
   7542  *      port    - (IN) Logical port.
   7543  * Returns:
   7544  *      SOC_E_XXX
   7545  */
   7546 int
   7547 bcmi_xgs5_port_detach_l3(int unit, bcm_port_t port)
   7548 {
   7549 #ifdef INCLUDE_L3
   7550     /* L3 */
   7551     if (soc_feature(unit, soc_feature_l3) &&
   7552         soc_property_get(unit, spn_L3_ENABLE, 1) &&
   7553         !IS_ST_PORT(unit, port)) {
   7554 
   7555         BCM_IF_ERROR_RETURN
   7556             (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 0));
   7557         BCM_IF_ERROR_RETURN
   7558             (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 0));
   7559     }
   7560 #endif /* INCLUDE_L3 */
   7561     return BCM_E_NONE;
   7562 }
   7563 
   7564 /*
   7565  * Function:
   7566  *      bcmi_xgs5_port_detach_ipmc
   7567  * Purpose:
   7568  *      Clear IPMC per-port configuration
   7569  * Parameters:
   7570  *      unit    - (IN) Unit number.
   7571  *      port    - (IN) Logical port.
   7572  * Returns:
   7573  *      SOC_E_XXX
   7574  */
   7575 int
   7576 bcmi_xgs5_port_detach_ipmc(int unit, bcm_port_t port)
   7577 {
   7578 #ifdef INCLUDE_L3
   7579     soc_field_t fields_lport[3] = {V4IPMC_ENABLEf, V6IPMC_ENABLEf, IPMC_DO_VLANf};
   7580     uint32      field_values[3] = {0, 0, 0};
   7581     /* IPMC */
   7582     if (soc_feature(unit, soc_feature_ip_mcast)) {
   7583 
   7584         BCM_IF_ERROR_RETURN
   7585             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV4Enable, 0));
   7586         BCM_IF_ERROR_RETURN
   7587             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcV6Enable, 0));
   7588         BCM_IF_ERROR_RETURN
   7589             (_bcm_esw_port_config_set(unit, port, _bcmPortIpmcVlanKey, 0));
   7590 
   7591         BCM_IF_ERROR_RETURN(
   7592             bcm_esw_port_lport_fields_set(unit, port, LPORT_PROFILE_LPORT_TAB, 3, 
   7593                                           fields_lport, field_values));
   7594         if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) {
   7595             return BCM_E_NONE;
   7596         }
   7597         if (IS_E_PORT(unit,port)) {
   7598             BCM_IF_ERROR_RETURN
   7599                 (bcm_esw_ipmc_egress_port_set(unit, port, _soc_mac_all_zeroes,
   7600                                               0, 0, 0));
   7601         }
   7602     }
   7603 #endif /* INCLUDE_L3 */
   7604     return BCM_E_NONE;
   7605 }
   7606 
   7607 /*
   7608  * Function:
   7609  *      bcmi_xgs5_port_detach_mpls
   7610  * Purpose:
   7611  *      Disable MPLS on port.
   7612  * Parameters:
   7613  *      unit    - (IN) Unit number.
   7614  *      port    - (IN) Logical port.
   7615  * Returns:
   7616  *      SOC_E_XXX
   7617  */
   7618 int
   7619 bcmi_xgs5_port_detach_mpls(int unit, bcm_port_t port)
   7620 {
   7621     int rv = BCM_E_NONE;
   7622 
   7623 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT)
   7624     /* MPLS */
   7625     if (soc_feature(unit, soc_feature_mpls) &&
   7626         !IS_ST_PORT(unit, port)) {
   7627         BCM_IF_ERROR_RETURN
   7628             (bcm_esw_port_control_set(unit, port, bcmPortControlMpls, 0));
   7629     }
   7630 #endif /* L3 && BCM_MPLS_SUPPORT */
   7631     return rv;
   7632 }
   7633 
   7634 /*
   7635  * Function:
   7636  *      bcmi_xgs5_port_detach_mim
   7637  * Purpose:
   7638  *      Disable MAC-in-MAC frame processing on port.
   7639  * Parameters:
   7640  *      unit    - (IN) Unit number.
   7641  *      port    - (IN) Logical port.
   7642  * Returns:
   7643  *      SOC_E_XXX
   7644  */
   7645 int
   7646 bcmi_xgs5_port_detach_mim(int unit, bcm_port_t port)
   7647 {
   7648 #ifdef INCLUDE_L3
   7649     /* MIM */
   7650     if (soc_feature(unit, soc_feature_mim) &&
   7651         !IS_ST_PORT(unit, port)) {
   7652         BCM_IF_ERROR_RETURN
   7653             (bcm_esw_port_control_set(unit, port, bcmPortControlMacInMac, 0));
   7654     }
   7655 #endif /* INCLUDE_L3 */
   7656     return BCM_E_NONE;
   7657 }
   7658 
   7659 /*
   7660  * Function:
   7661  *      bcmi_xgs5_port_sched_structure
   7662  * Purpose:
   7663  *      Populate port_schedule_state
   7664  * Parameters:
   7665  *      unit  - (IN) Unit number.
   7666  *      nport - (IN) Number of elements in array port
   7667  *      port  - (IN) Array of logical port.
   7668  *      post  - (IN) Indicate populate out_port_map or not
   7669  *                   1: set out_port_map with post flex info;
   7670  *                   0: NOT set out_port_map
   7671  *      port_schedule_state - (OUT) port_schedule_state
   7672  * Returns:
   7673  *      SOC_E_XXX
   7674  */
   7675 STATIC int
   7676 bcmi_xgs5_port_sched_structure(int unit, int nport, bcm_port_t *port, int post,
   7677                                soc_port_schedule_state_t *port_schedule_state)
   7678 {
   7679     soc_info_t *si = &SOC_INFO(unit);
   7680     soc_port_resource_t *soc_resource;
   7681     int logic_port, phy_port, encap;
   7682     int i, rv = BCM_E_NONE;
   7683 
   7684     soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport,
   7685                              "soc_port_resource");
   7686     if (soc_resource == NULL) {
   7687         return BCM_E_MEMORY;
   7688     }
   7689     sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport);
   7690 
   7691     for (i = 0; i< nport; i++) {
   7692         logic_port = port[i];
   7693         phy_port = si->port_l2p_mapping[logic_port];
   7694 
   7695         rv = bcm_esw_port_encap_get(unit, logic_port, &encap);
   7696         if (BCM_FAILURE(rv)) {
   7697             break;
   7698         }
   7699         soc_resource[i].logical_port = logic_port;
   7700         soc_resource[i].physical_port = phy_port;
   7701         soc_resource[i].mmu_port = si->port_p2m_mapping[phy_port];
   7702         soc_resource[i].idb_port = si->port_l2i_mapping[logic_port];
   7703         soc_resource[i].pipe = si->port_pipe[logic_port];
   7704         soc_resource[i].speed = si->port_init_speed[logic_port];
   7705         soc_resource[i].encap = encap;
   7706         soc_resource[i].num_lanes = si->port_num_lanes[logic_port];
   7707         soc_resource[i].oversub =
   7708                         SOC_PBMP_MEMBER(si->oversub_pbm, logic_port) ? 1 : 0;
   7709         soc_resource[i].hsp =
   7710                         SOC_PBMP_MEMBER(si->eq_pbm, logic_port) ? 1 : 0;
   7711     }
   7712 
   7713     if (BCM_SUCCESS(rv)) {
   7714         rv = _bcmi_xgs5_port_soc_schedule_state_init(unit, nport,
   7715                                             BCMI_XGS5_PORT_RESOURCE_OP_ENABLE,
   7716                                             soc_resource,
   7717                                             port_schedule_state);
   7718     }
   7719 
   7720     if (BCM_SUCCESS(rv) && post) {
   7721         rv = _bcmi_xgs5_port_info_post_flex(unit, port_schedule_state);
   7722     }
   7723 
   7724     sal_free(soc_resource);
   7725     return rv;
   7726 }
   7727 
   7728 /*
   7729  * Function:
   7730  *      bcmi_xgs5_port_enable_set
   7731  * Purpose:
   7732  *      Enable or disable a port.
   7733  *
   7734  *      To reuse the port up/down routines from DV for port enable/disable 
   7735  * Parameters:
   7736  *      unit    - (IN) Unit number.
   7737  *      port    - (IN) Logical BCM Port number (non-GPORT).
   7738  *      enable  - (IN) Indicates whether to enable or disable port.
   7739  * Returns:
   7740  *      BCM_E_XXX
   7741  * Notes:
   7742  *      Must be called with PORT_LOCK held.
   7743  *      Must be called with PORTMOD enabled.
   7744  */
   7745 int
   7746 bcmi_xgs5_port_enable_set(int unit, bcm_port_t port, int enable)
   7747 {
   7748     soc_port_schedule_state_t *port_schedule_state;
   7749     int rv;
   7750 
   7751     /* Allocate memory for soc_port_schedule_state_t structure */
   7752     port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t),
   7753                                     "port schedule state");
   7754     if (port_schedule_state == NULL) {
   7755         return BCM_E_MEMORY;
   7756     }
   7757     sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t));
   7758 
   7759     rv = bcmi_xgs5_port_sched_structure(unit, 1, &port, 1, port_schedule_state);
   7760     if (BCM_FAILURE(rv)) {
   7761         sal_free(port_schedule_state);
   7762         return rv;
   7763     }
   7764 
   7765     if (enable && BCMI_PORT_DRV_CALL(unit)->port_enable) {
   7766         /* Port UP */
   7767         rv = BCMI_PORT_DRV_CALL(unit)->port_enable(unit, port_schedule_state);
   7768     } else if ((!enable) && BCMI_PORT_DRV_CALL(unit)->port_disable) {
   7769         /* Physical_port = -1 indicates bringing down a port */
   7770         port_schedule_state->resource[0].physical_port = -1;
   7771         /* Port Down */
   7772         rv = BCMI_PORT_DRV_CALL(unit)->port_disable(unit, port_schedule_state);
   7773     } else {
   7774         rv = BCM_E_UNAVAIL;
   7775     }
   7776 
   7777     sal_free(port_schedule_state);
   7778     return rv;
   7779 }
   7780 
   7781 /*
   7782  * Function:
   7783  *      bcmi_xgs5_flexport_based_speed_ability_get
   7784  * Purpose:
   7785  *      Retrieve the local port abilities.
   7786  * Parameters:
   7787  *      unit - Unit.
   7788  *      port - Logical port number.
   7789  *      mask - (OUT) Mask of BCM_PORT_ABILITY_ values indicating the
   7790  *              supported speeds of the port.
   7791  * Returns:
   7792  *      BCM_E_NONE
   7793  *      BCM_E_XXX
   7794  */
   7795 int
   7796 bcmi_xgs5_flexport_based_speed_ability_get(int unit, bcm_port_t port,
   7797                                            bcm_port_abil_t *mask)
   7798 {
   7799     if (BCMI_PORT_DRV_CALL(unit)->speed_ability_get) {
   7800         BCMI_PORT_DRV_CALL(unit)->speed_ability_get(unit, port, mask);
   7801     } else {
   7802         *mask = SOC_PA_ABILITY_ALL;
   7803     }
   7804     return BCM_E_NONE;
   7805 }
   7806 
   7807 /*
   7808  * Function:
   7809  *      bcmi_xgs5_port_encap_speed_check
   7810  * Purpose:
   7811  *      Restriction: Higig speed with IEEE encap mode is not supported.
   7812  * Parameters:
   7813  *      unit     - (IN) Unit number
   7814  *      port     - (IN) Logical port number
   7815  *      encap    - (IN) encap mode
   7816  *      speed    - (IN) speed
   7817  * Returns:
   7818  *      BCM_E_XXX
   7819  */
   7820 int
   7821 bcmi_xgs5_port_encap_speed_check(int unit, bcm_port_t port, int encap,
   7822                                  int speed)
   7823 {
   7824     int is_hg_speed;
   7825     uint32 speed_mask;
   7826 
   7827     if (speed == 0) {
   7828         BCM_IF_ERROR_RETURN
   7829             (bcm_esw_port_speed_get(unit, port, &speed));
   7830     }
   7831 
   7832     speed_mask = SOC_PA_SPEED(speed);
   7833     is_hg_speed = SOC_PA_IS_HG_SPEED(speed_mask);
   7834 
   7835     /* Expect non-higig speed for IEEE encapsulation mode. */
   7836     if (is_hg_speed && encap == BCM_PORT_ENCAP_IEEE) {
   7837         LOG_ERROR(BSL_LS_BCM_PORT,
   7838                   (BSL_META_U(unit,
   7839                               "Speed and encapsulation configuration unmatch "
   7840                               "for port=%d, speed=%d, encap=%d\n"),
   7841                    port, speed, encap));
   7842         return BCM_E_PARAM;
   7843     }
   7844 
   7845     return BCM_E_NONE;
   7846 }
   7847 
   7848 /*
   7849  * Function:
   7850  *      _bcmi_xgs5_port_redirect_config_set
   7851  * Purpose:
   7852  *      Configure the redirection data
   7853  * Parameters:
   7854  *      unit             - (IN) device id.
   7855  *      port             - (IN) Port number.
   7856  *      redirect_config  - (IN) Pointer to the redirection config structure
   7857  * Returns:
   7858  *      None
   7859  */
   7860 int _bcmi_xgs5_port_redirect_config_set(int unit, bcm_port_t port,
   7861                           bcm_port_redirect_config_t *redirect_config)
   7862 {
   7863     bcm_trunk_t trunk_id = -1;
   7864     bcm_module_t mod_id = -1;
   7865     bcm_port_t port_id = -1;
   7866     int id = -1, redirect_set = 1, color = -1;
   7867     int curr_dest_type = 0;
   7868     int dest_type = _BCM_REDIRECT_DEST_TYPE_NONE, dest_value = -1;
   7869     int dest_type_flags = 0;
   7870     egr_port_entry_t egr_port_entry;
   7871 #if defined(BCM_EP_REDIRECT_VERSION_2)
   7872     int redirect_action_value = 0, redirect_source_value = 0;
   7873     int buffer_priority = 0;
   7874 #endif
   7875 
   7876     /* If the dest_type_field is invalid, this feature is not
   7877        supported on this device */
   7878     if(PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type == INVALIDf) {
   7879         return BCM_E_UNAVAIL;
   7880     }
   7881 
   7882     dest_type_flags = (redirect_config->flags &
   7883                            (BCM_PORT_REDIRECT_DESTINATION_PORT |
   7884                             BCM_PORT_REDIRECT_DESTINATION_TRUNK |
   7885                             BCM_PORT_REDIRECT_DESTINATION_MCAST));
   7886 
   7887     /* Make sure only one destination type is set */
   7888     if(dest_type_flags & (dest_type_flags - 1)) {
   7889         return BCM_E_PARAM;
   7890     }
   7891 
   7892     /* Switch based on the destination type */
   7893     switch(dest_type_flags) {
   7894 
   7895         case BCM_PORT_REDIRECT_DESTINATION_PORT:
   7896 
   7897             /* Make sure that the supplied destination is valid */
   7898             if(!BCM_GPORT_IS_MODPORT(redirect_config->destination)) {
   7899                 return BCM_E_PORT;
   7900             }
   7901 
   7902             BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit,
   7903                                          redirect_config->destination,
   7904                                          &mod_id, &port_id, &trunk_id, &id));
   7905 
   7906             /* Set the destination type as GPP(Port) */
   7907             dest_type = _BCM_REDIRECT_DEST_TYPE_PORT;
   7908 
   7909             /* Set the (Mod,Port) value as destination */
   7910             BCMI_MOD_PORT_SET(dest_value, mod_id, port_id);
   7911 
   7912             break;
   7913 
   7914         case BCM_PORT_REDIRECT_DESTINATION_TRUNK:
   7915 
   7916             /* Make sure that the supplied destination is valid */
   7917             if(!BCM_GPORT_IS_SET(redirect_config->destination) ||
   7918                !BCM_GPORT_IS_TRUNK(redirect_config->destination)) {
   7919                 return BCM_E_PARAM;
   7920             }
   7921 
   7922             /* Get the trunk id */
   7923             trunk_id = BCM_GPORT_TRUNK_GET(redirect_config->destination);
   7924 
   7925             /* Check that the trunk id is valid */
   7926             BCM_IF_ERROR_RETURN(_bcm_trunk_id_validate(unit, trunk_id));
   7927 
   7928             /* Set the destination type as GPP(Port) */
   7929             dest_type = _BCM_REDIRECT_DEST_TYPE_TRUNK;
   7930 
   7931             /* Set the trunk id as the destiantion */
   7932             dest_value = trunk_id;
   7933 
   7934             break;
   7935 
   7936         case BCM_PORT_REDIRECT_DESTINATION_MCAST:
   7937 
   7938             /* Check the destination and make suure it is a valid l2 MC */
   7939             if (_BCM_MULTICAST_IS_SET(redirect_config->destination)) {
   7940                 if (!_BCM_MULTICAST_IS_L2(redirect_config->destination)) {
   7941                     return (BCM_E_PARAM);
   7942                 }
   7943             }
   7944 
   7945             /* Set the destination type as GPP(Port) */
   7946             dest_type = _BCM_REDIRECT_DEST_TYPE_MCAST;
   7947 
   7948             /* Set the l2 mc index as the destiantion */
   7949             dest_value = _BCM_MULTICAST_ID_GET(redirect_config->destination);
   7950 
   7951             break;
   7952 
   7953         default:
   7954 
   7955             /* Reset the redirection flag */
   7956             redirect_set = 0;
   7957 
   7958             /* Reset the destination type */
   7959             dest_type = _BCM_REDIRECT_DEST_TYPE_NONE;
   7960 
   7961             /* Reset the destination */
   7962             dest_value = 0;
   7963 
   7964             break;
   7965 
   7966     } /* End switch */
   7967 
   7968     /* Resolve the gport we are setting the redirection properties on */
   7969     BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port,
   7970                                                &mod_id, &port_id,
   7971                                                &trunk_id, &id));
   7972 
   7973     /* Get the egr port entry */
   7974     BCM_IF_ERROR_RETURN(soc_mem_read(unit,
   7975              PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->mem, MEM_BLOCK_ANY,
   7976              port_id, &egr_port_entry));
   7977 
   7978     /* Get the current dest_type */
   7979     curr_dest_type = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   7980                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type);
   7981 
   7982     /* Change the dest-type and dest-value only for non-mtp destinations,
   7983        this is because this gets setup in the 'mirror' module */
   7984     if(curr_dest_type != _BCM_REDIRECT_DEST_TYPE_MTP) {
   7985         /* Setup the destination type and destination values */
   7986         soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   7987                          PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type,
   7988                          dest_type);
   7989 
   7990         soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   7991                          PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_value,
   7992                          dest_value);
   7993     }
   7994 
   7995     /* Based on the redirection being set/cleared, set the drop_original flag,
   7996       when rediretion is set, we will drop the original packet */
   7997     soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   7998             PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->drop_original,
   7999             (redirect_set ? 1 : 0));
   8000 
   8001     /* Set the redirected packet color */
   8002     if(soc_feature(unit, soc_feature_ep_redirect_v2)) {
   8003         /* If the redirection is being added, set the user provided
   8004            color value, if it being disabled force the color to 0,
   8005            which is a hardware default */
   8006         if (redirect_set) {
   8007             /* Map the external color values to internal ones */
   8008             switch(redirect_config->color) {
   8009                 case bcmPortRedirectColorGreen:
   8010                     color = 0;
   8011                     break;
   8012                 case bcmPortRedirectColorYellow:
   8013                     color = 1;
   8014                     break;
   8015                 case bcmPortRedirectColorRed:
   8016                     color = 2;
   8017                     break;
   8018                 default:
   8019                     break;
   8020             }
   8021 
   8022             /* Set the color, if a valid value is supplied */
   8023             if (color != -1) {
   8024                 soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8025                         PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color, color);
   8026                 soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8027                         PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color,
   8028                         1);
   8029             } else {
   8030                 soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8031                         PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color,
   8032                         0);
   8033             }
   8034         } else {
   8035             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8036                              PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color,
   8037                              0);
   8038             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8039                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_color,
   8040                     0);
   8041         }
   8042     } else {
   8043         /* For the older scheme, the color from enum maps directly */
   8044        if (redirect_set) {
   8045             if(redirect_config->color < bcmPortRedirectColorNone) {
   8046                     soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8047                              PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color,
   8048                              redirect_config->color);
   8049             }
   8050        } else {
   8051            soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8052                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color,
   8053                     0);
   8054        }
   8055     }
   8056 
   8057     /* Set the redirected packet priority, if redirection is being disabled, set
   8058        to hardware defaults */
   8059     if (redirect_set) {
   8060         if(redirect_config->priority >= 0 && redirect_config->priority <= 15) {
   8061             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8062                              PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority,
   8063                              redirect_config->priority);
   8064             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8065               PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 1);
   8066         } else if (redirect_config->priority == -1){
   8067             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8068               PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 0);
   8069         } else {
   8070             return BCM_E_PARAM;
   8071         }
   8072     } else {
   8073         soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8074                          PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority,
   8075                          0);
   8076         soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8077                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_change_priority, 0);
   8078     }
   8079 
   8080 #if defined(BCM_EP_REDIRECT_VERSION_2)
   8081     /* For the newer feature, set the additionally supported fields */
   8082     if(soc_feature(unit, soc_feature_ep_redirect_v2)) {
   8083 
   8084         /* Set the trigger strength, if disabling redirection set it to
   8085            default */
   8086         if (redirect_set) {
   8087             if((redirect_config->strength >= 0) &&
   8088                (redirect_config->strength < BCMI_MAX_STRENGTH_VALUE)) {
   8089                 soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8090                        PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength,
   8091                        redirect_config->strength);
   8092             } else {
   8093                 return BCM_E_NONE;
   8094             }
   8095         } else {
   8096             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8097                    PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength,
   8098                    0);
   8099         }
   8100 
   8101         /* Set the buffer priority, if disabling redirection set it to
   8102            default */
   8103         if (redirect_set) {
   8104             if(redirect_config->buffer_priority &
   8105                BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW) {
   8106                 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW;
   8107             } else if(redirect_config->buffer_priority &
   8108                BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM) {
   8109                 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM;
   8110             } else if(redirect_config->buffer_priority &
   8111                BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH) {
   8112                 buffer_priority = _BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH;
   8113             }
   8114 
   8115             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8116                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority,
   8117                 buffer_priority);
   8118         } else {
   8119             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8120                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority,
   8121                 0);
   8122         }
   8123 
   8124         /* Set the redirected packet action, based on the flag. If the
   8125            redirection is being disabled, set it to default */
   8126         if (redirect_set) {
   8127             if(redirect_config->flags &
   8128                BCM_PORT_REDIRECT_DROPPED_PACKET) {
   8129                 redirect_action_value = _BCM_REDIRECT_IF_DROPPED;
   8130             } else if(redirect_config->flags &
   8131                       BCM_PORT_REDIRECT_NOT_DROPPED_PACKET) {
   8132                 redirect_action_value = _BCM_REDIRECT_IF_NOT_DROPPED;
   8133             } else {
   8134                 /* Default to always redirect */
   8135                 redirect_action_value = _BCM_REDIRECT_ALWAYS;
   8136             }
   8137 
   8138             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8139                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action,
   8140                     redirect_action_value);
   8141         } else {
   8142             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8143                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action,
   8144                     0);
   8145         }
   8146 
   8147         /* Set the redirected packet source to use, based on the flags.
   8148            If the redirection is being disabled, set it to default */
   8149         if (redirect_set) {
   8150             if(redirect_config->flags &
   8151                BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION) {
   8152                 redirect_source_value =
   8153                     _BCM_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION;
   8154             } else if(redirect_config->flags &
   8155                       _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) {
   8156                 redirect_source_value =
   8157                     _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE;
   8158             } else {
   8159                 /* Default it to original source */
   8160                 redirect_source_value =
   8161                     _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE;
   8162             }
   8163 
   8164             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8165                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source,
   8166                 redirect_source_value);
   8167         } else {
   8168             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8169                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source,
   8170                 0);
   8171         }
   8172 
   8173         /* Set the truncate option, if user has chosen the same. If the
   8174            redirection is being disabled, set it to default */
   8175         if (redirect_set) {
   8176             if(redirect_config->flags & BCM_PORT_REDIRECT_TRUNCATE) {
   8177                 soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8178                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate,
   8179                     1);
   8180             }
   8181         } else {
   8182             soc_EGR_PORTm_field32_set(unit, &egr_port_entry,
   8183                 PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate,
   8184                 0);
   8185         }
   8186     } /* soc_feature_ep_redirect_v2 */
   8187 #endif /* BCM_EP_REDIRECT_VERSION_2 */
   8188 
   8189     /* Write the entry to hardware */
   8190     BCM_IF_ERROR_RETURN(soc_mem_write(unit, EGR_PORTm,
   8191                                       MEM_BLOCK_ALL, port_id,
   8192                                       &egr_port_entry));
   8193     return BCM_E_NONE;
   8194 }
   8195 
   8196 
   8197 /*
   8198  * Function:
   8199  *      bcmi_xgs5_port_redirect_config_set
   8200  * Purpose:
   8201  *      Initialize the redirection config structure
   8202  * Parameters:
   8203  *      unit             - (IN) device id.
   8204  *      port             - (IN) Port number.
   8205  *      redirect_config  - (IN) Pointer to the redirection config structure
   8206  * Returns:
   8207  *      None
   8208  */
   8209 int bcmi_xgs5_port_redirect_config_set(int unit, bcm_gport_t port,
   8210                                      bcm_port_redirect_config_t *redirect_config)
   8211 {
   8212     int local_port = -1, flags = 0;
   8213 
   8214     /* Sanity check */
   8215     if(redirect_config == NULL) {
   8216         return BCM_E_PARAM;
   8217     }
   8218 
   8219     /* Check the sanity of flags */
   8220     flags = redirect_config->flags;
   8221     if((flags & BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) &&
   8222        (flags & BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION)) {
   8223         return BCM_E_PARAM;
   8224     }
   8225 
   8226     if((flags & BCM_PORT_REDIRECT_DROPPED_PACKET) &&
   8227        (flags & BCM_PORT_REDIRECT_NOT_DROPPED_PACKET)) {
   8228         return BCM_E_PARAM;
   8229     }
   8230 
   8231     /* Check flags that are only applicable on the redirection
   8232        2.0 */
   8233     if(!soc_feature(unit, soc_feature_ep_redirect_v2)) {
   8234         if(flags & (BCM_PORT_REDIRECT_TRUNCATE |
   8235                     BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE |
   8236                     BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION |
   8237                     BCM_PORT_REDIRECT_DROPPED_PACKET |
   8238                     BCM_PORT_REDIRECT_NOT_DROPPED_PACKET |
   8239                     BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW |
   8240                     BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM |
   8241                     BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH)) {
   8242                 return BCM_E_PARAM;
   8243         }
   8244     }
   8245 
   8246     /* Validate the port and extract the local_port */
   8247     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
   8248 
   8249     /* Set the data */
   8250     BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_redirect_config_set(unit,
   8251                                             port, redirect_config));
   8252 
   8253     return BCM_E_NONE;
   8254 }
   8255 
   8256 /*
   8257  * Function:
   8258  *      _bcmi_xgs5_port_redirect_get
   8259  * Purpose:
   8260  *      Configure the redirection data
   8261  * Parameters:
   8262  *      unit             - (IN) device id.
   8263  *      port             - (IN) Port number.
   8264  *      redirect_config  - (OUT) Pointer to the redirection config structure
   8265  * Returns:
   8266  *      None
   8267  */
   8268 int _bcmi_xgs5_port_redirect_get(int unit, bcm_port_t port,
   8269                           bcm_port_redirect_config_t *redirect_config)
   8270 {
   8271     int color = 0, mod_id = -1, port_id = -1;
   8272     int dest_type, dest_value = -1;
   8273     egr_port_entry_t  egr_port_entry;
   8274 #if defined(BCM_EP_REDIRECT_VERSION_2)
   8275     int redirect_action_value = 0, redirect_source_value = 0;
   8276     int buffer_priority = 0, truncate_flag = 0;
   8277 #endif
   8278 
   8279     /* If the dest_type_field is invalid, this feature is not
   8280        supported on this device */
   8281     if (PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type == INVALIDf) {
   8282         return BCM_E_UNAVAIL;
   8283     }
   8284 
   8285     /* Read the given egress port entry */
   8286     BCM_IF_ERROR_RETURN(soc_mem_read(unit,
   8287             PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->mem, MEM_BLOCK_ANY,
   8288             port, &egr_port_entry));
   8289 
   8290     /* Zero out the outgoing struct */
   8291     sal_memset(redirect_config, 0, sizeof(bcm_port_redirect_config_t));
   8292 
   8293     /* Reset flags */
   8294     redirect_config->flags = 0;
   8295     redirect_config->buffer_priority = 0;
   8296 
   8297     /* Get the dest_type and dest values */
   8298     dest_type = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   8299                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_type);
   8300     dest_value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   8301                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->dest_value);
   8302 
   8303     /* Switch based on the destination type */
   8304     switch(dest_type) {
   8305 
   8306         case _BCM_REDIRECT_DEST_TYPE_PORT:
   8307 
   8308             /* Extract the (Mod,Port) value from destination */
   8309             BCMI_MOD_PORT_MODID_GET(dest_value, mod_id);
   8310             BCMI_MOD_PORT_PORTID_GET(dest_value, port_id);
   8311 
   8312             BCM_GPORT_MODPORT_SET(redirect_config->destination,
   8313                                   mod_id, port_id);
   8314             redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_PORT;
   8315 
   8316             break;
   8317 
   8318         case _BCM_REDIRECT_DEST_TYPE_TRUNK:
   8319 
   8320             /* Put together a trunk gport and set the type */
   8321             BCM_GPORT_TRUNK_SET(redirect_config->destination, dest_value);
   8322             redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_TRUNK;
   8323 
   8324             break;
   8325 
   8326         case _BCM_REDIRECT_DEST_TYPE_MCAST:
   8327 
   8328             /* Put together a trunk gport and set the type */
   8329             _BCM_MULTICAST_GROUP_SET(redirect_config->destination,
   8330                                      _BCM_MULTICAST_TYPE_L2,
   8331                                      redirect_config->destination);
   8332             redirect_config->flags |= BCM_PORT_REDIRECT_DESTINATION_MCAST;
   8333 
   8334             break;
   8335 
   8336         default:
   8337 
   8338             /* Reset the destination type */
   8339             dest_type = _BCM_REDIRECT_DEST_TYPE_NONE;
   8340 
   8341             /* Reset the destination */
   8342             dest_value = 0;
   8343 
   8344             break;
   8345 
   8346     } /* End switch */
   8347 
   8348     /* Get the redirected packet color */
   8349     color = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   8350                     PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_color);
   8351 
   8352 #if defined(BCM_EP_REDIRECT_VERSION_2)
   8353     /* Map the internal color values to external ones */
   8354     if(soc_feature(unit, soc_feature_ep_redirect_v2)) {
   8355         switch(color) {
   8356             case 0:
   8357                 redirect_config->color = bcmPortRedirectColorGreen;
   8358                 break;
   8359             case 1:
   8360                 redirect_config->color = bcmPortRedirectColorYellow;
   8361                 break;
   8362             case 2:
   8363                 redirect_config->color = bcmPortRedirectColorRed;
   8364                 break;
   8365             default:
   8366                 break;
   8367         }
   8368     } else {
   8369 #endif
   8370     switch(color) {
   8371         case 0:
   8372             redirect_config->color = bcmPortRedirectColorNone;
   8373             break;
   8374         case 1:
   8375             redirect_config->color = bcmPortRedirectColorGreen;
   8376             break;
   8377         case 2:
   8378             redirect_config->color = bcmPortRedirectColorYellow;
   8379             break;
   8380         case 3:
   8381             redirect_config->color = bcmPortRedirectColorRed;
   8382             break;
   8383 
   8384         default:
   8385             break;
   8386     }
   8387 #if defined(BCM_EP_REDIRECT_VERSION_2)
   8388     }
   8389 #endif
   8390 
   8391     /* Get the redirected packet priority */
   8392     redirect_config->priority = soc_EGR_PORTm_field32_get(unit,
   8393                &egr_port_entry,
   8394                PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->pkt_priority);
   8395 
   8396 #if defined(BCM_EP_REDIRECT_VERSION_2)
   8397     /* For the newer redirection, get the additionally supported fields */
   8398     if (soc_feature(unit, soc_feature_ep_redirect_v2)) {
   8399 
   8400         /* Get the redirected packet strength */
   8401         redirect_config->strength = soc_EGR_PORTm_field32_get(unit,
   8402                    &egr_port_entry,
   8403                    PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->strength);
   8404 
   8405         /* Get the redirected packet buffer priority */
   8406         buffer_priority = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   8407                    PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->buffer_priority);
   8408 
   8409         if (buffer_priority ==
   8410             _BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW) {
   8411             redirect_config->buffer_priority |=
   8412                 BCM_PORT_REDIRECT_BUFFER_PRIORITY_LOW;
   8413         } else if(buffer_priority ==
   8414                   _BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM) {
   8415             redirect_config->buffer_priority |=
   8416                 BCM_PORT_REDIRECT_BUFFER_PRIORITY_MEDIUM;
   8417         } else if(buffer_priority ==
   8418                   _BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH) {
   8419             redirect_config->buffer_priority |=
   8420                 BCM_PORT_REDIRECT_BUFFER_PRIORITY_HIGH;
   8421         }
   8422 
   8423         /* Get the redirection action value */
   8424         redirect_action_value = soc_EGR_PORTm_field32_get(unit,
   8425                &egr_port_entry,
   8426                PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->action);
   8427 
   8428         /* Set the redirected packet action, based on the flags */
   8429         if(redirect_action_value == _BCM_REDIRECT_IF_DROPPED) {
   8430             redirect_config->flags |= BCM_PORT_REDIRECT_DROPPED_PACKET;
   8431         } else if(redirect_action_value ==
   8432                   _BCM_REDIRECT_IF_NOT_DROPPED) {
   8433             redirect_config->flags |= BCM_PORT_REDIRECT_NOT_DROPPED_PACKET;
   8434         }
   8435 
   8436         /* Get the redirection source value */
   8437         redirect_source_value = soc_EGR_PORTm_field32_get(unit,
   8438                   &egr_port_entry,
   8439                   PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_source);
   8440 
   8441         /* Get the redirected packet source to use and update flags */
   8442         if(redirect_source_value ==
   8443            _BCM_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION) {
   8444             redirect_config->flags |=
   8445                 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_DESTINATION;
   8446         } else if(redirect_source_value ==
   8447                   _BCM_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE) {
   8448             redirect_config->flags |=
   8449                 BCM_PORT_REDIRECT_SOURCE_USE_ORIGINAL_SOURCE;
   8450         }
   8451 
   8452         /* Set the redirected packet truncate flag, if it is set */
   8453         truncate_flag = soc_EGR_PORTm_field32_get(unit, &egr_port_entry,
   8454                       PORT_REDIRECTION_HW_DEFS_EGR_PORT(unit)->redir_pkt_truncate);
   8455         if(truncate_flag) {
   8456             redirect_config->flags |= BCM_PORT_REDIRECT_TRUNCATE;
   8457         }
   8458     }
   8459 
   8460 #endif
   8461 
   8462     return BCM_E_NONE;
   8463 }
   8464 
   8465 /*
   8466  * Function:
   8467  *      bcmi_xgs5_port_redirect_config_get
   8468  * Purpose:
   8469  *      Get the redirection config data
   8470  * Parameters:
   8471  *      unit             - (IN) device id.
   8472  *      port             - (IN) Port number.
   8473  *      redirect_config  - (OUT) Pointer to the redirection config structure
   8474  * Returns:
   8475  *      None
   8476  */
   8477 int bcmi_xgs5_port_redirect_config_get(int unit, bcm_gport_t port,
   8478                                  bcm_port_redirect_config_t *redirect_config)
   8479 {
   8480     int local_port = -1;
   8481 
   8482     /* Sanity check */
   8483     if(redirect_config == NULL) {
   8484         return BCM_E_PARAM;
   8485     }
   8486 
   8487     /* Validate the port and extract the local_port */
   8488     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit,
   8489                                                      port,
   8490                                                      &local_port));
   8491 
   8492     /* Get the data */
   8493     BCM_IF_ERROR_RETURN(_bcmi_xgs5_port_redirect_get(unit,
   8494                                                      local_port,
   8495                                                      redirect_config));
   8496 
   8497     return BCM_E_NONE;
   8498 }
   8499 
   8500 /*
   8501  * Function:
   8502  *      bcmi_xgs5_port_force_lb_set
   8503  * Purpose:
   8504  *      Force port into internal loopback accroding to bond options.
   8505  * Parameters:
   8506  *      unit          - (IN) Unit number.
   8507  * Returns:
   8508  *      BCM_E_XXX
   8509  * Notes:
   8510  */
   8511 int
   8512 bcmi_xgs5_port_force_lb_set(int unit)
   8513 {
   8514     soc_info_t *si;
   8515     int port, phy_port;
   8516 
   8517     si = &SOC_INFO(unit);
   8518 
   8519     PBMP_PORT_ITER(unit, port) {
   8520         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) ||
   8521             IS_MANAGEMENT_PORT(unit,port)) {
   8522             continue;
   8523         }
   8524         phy_port = si->port_l2p_mapping[port];
   8525         if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb) {
   8526             BCM_IF_ERROR_RETURN
   8527                 (bcm_esw_port_loopback_set(unit, port, BCM_PORT_LOOPBACK_PHY));
   8528         }
   8529     }
   8530 
   8531     return BCM_E_NONE;
   8532 }
   8533 
   8534 /*
   8535  * Function:
   8536  *      bcmi_xgs5_port_force_lb_check
   8537  * Purpose:
   8538  *      Check if port should be forced into internal loopback.
   8539  * Parameters:
   8540  *      unit          - (IN) Unit number.
   8541  *      port          - (IN) Logical port, BCM format.
   8542  *      loopback      - (IN) one of:
   8543  *                           BCM_PORT_LOOPBACK_NONE
   8544  *                           BCM_PORT_LOOPBACK_MAC
   8545  *                           BCM_PORT_LOOPBACK_PHY
   8546  * Returns:
   8547  *      BCM_E_XXX
   8548  * Notes:
   8549  */
   8550 int
   8551 bcmi_xgs5_port_force_lb_check(int unit, int port, int loopback)
   8552 {
   8553     soc_info_t *si;
   8554     int phy_port, local_port, phy_lane, phyn, sys_side;
   8555 
   8556     si = &SOC_INFO(unit);
   8557     local_port = -1;
   8558 
   8559     BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port,
   8560                          &local_port, &phyn, &phy_lane, &sys_side));
   8561 
   8562     if (local_port == -1) {
   8563        BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port));
   8564     } else {
   8565         port = local_port;
   8566     }
   8567 
   8568     if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) ||
   8569         IS_MANAGEMENT_PORT(unit,port)) {
   8570         return BCM_E_NONE;
   8571     }
   8572 
   8573     phy_port = si->port_l2p_mapping[port];
   8574     if (BCMI_PORT_DRV_PHY_INFO(unit, phy_port).force_lb &&
   8575         loopback != BCM_PORT_LOOPBACK_PHY) {
   8576         return BCM_E_PARAM;
   8577     }
   8578 
   8579     return BCM_E_NONE;
   8580 }
   8581 
   8582 /*
   8583  * Function:
   8584  *      bcmi_xgs5_port_resource_status_update
   8585  * Purpose:
   8586  *      Update the port resource status to depedent modules after
   8587  *      flex operation.
   8588  * Parameters:
   8589  *      unit     - (IN) Unit number.
   8590  *      nport    - (IN) Number of elements in array resource.
   8591  *      resource - (IN) Port resource configuration array.
   8592  * Returns:
   8593  *      BCM_E_XXX
   8594  * Note:
   8595  *      - Assumes caller has lock.
   8596  *      - This is to be called by the API dispatch driver.
   8597  *      - Should be invoked from resource_multi_set() routine
   8598  *        after completion of flex operation.
   8599  */
   8600 int
   8601 bcmi_xgs5_port_resource_status_update(int unit,
   8602                                       int nport,
   8603                                       bcm_port_resource_t *resource)
   8604 {
   8605     int i;
   8606     bcm_pbmp_t detached_pbmp;
   8607     bcm_pbmp_t attached_pbmp;
   8608     bcm_port_t local_port;
   8609 
   8610     if (resource == NULL) {
   8611         return BCM_E_PARAM;
   8612     }
   8613 
   8614     BCM_PBMP_CLEAR(detached_pbmp);
   8615     BCM_PBMP_CLEAR(attached_pbmp);
   8616     for (i = 0; i < nport; i++) {
   8617         /* Check that logical port number is addressable and convert */
   8618         BCM_IF_ERROR_RETURN
   8619             (bcmi_xgs5_port_addressable_local_get(unit,
   8620                                                   resource[i].port,
   8621                                                   &local_port));
   8622         if (resource[i].physical_port == -1) {
   8623            BCM_PBMP_PORT_ADD(detached_pbmp, local_port);
   8624         } else {
   8625            BCM_PBMP_PORT_ADD(attached_pbmp, local_port);
   8626         }
   8627     }
   8628 
   8629     /* Update SDK field module about the detached and attached ports to the device. */
   8630     return _bcm_field_flex_port_update(unit, detached_pbmp, attached_pbmp);
   8631 }
   8632 
   8633 /* Debug functions for Flexport */
   8634 
   8635 /*
   8636  * Function:
   8637  *      bcmi_xgs5_num_tsc
   8638  * Purpose:
   8639  *      Get number of TSC in the device, not include management TSC
   8640  * Parameters:
   8641  *      unit    - (IN) Unit number.
   8642  *      num     - (OUT) NUmber of TSC
   8643  * Returns:
   8644  *      SOC_E_XXX
   8645  */
   8646 int
   8647 bcmi_xgs5_num_tsc(int unit, int *num)
   8648 {
   8649     if (BCMI_PORT_DRV(unit) == NULL) {
   8650         return BCM_E_UNAVAIL;
   8651     }
   8652 
   8653     if (num == NULL) {
   8654         return BCM_E_PARAM;
   8655     }
   8656 
   8657     *num = BCMI_PORT_DRV_DEV_INFO(unit)->num_tsc;
   8658 
   8659     return SOC_E_NONE;
   8660 }
   8661 
   8662 /*
   8663  * Function:
   8664  *      bcmi_xgs5_phy_to_pipe
   8665  * Purpose:
   8666  *      Get pipe from the physical port
   8667  * Parameters:
   8668  *      unit    - (IN) Unit number.
   8669  *      phy_port- (IN) Physical port
   8670  *      pipe    - (OUT) Pipe
   8671  * Returns:
   8672  *      SOC_E_XXX
   8673  */
   8674 int
   8675 bcmi_xgs5_phy_to_pipe(int unit, int phy_port, int *pipe)
   8676 {
   8677     if (BCMI_PORT_DRV(unit) == NULL) {
   8678         return BCM_E_UNAVAIL;
   8679     }
   8680 
   8681     if (pipe == NULL) {
   8682         return BCM_E_PARAM;
   8683     }
   8684 
   8685     *pipe = BCMI_PORT_DRV_PHY_INFO(unit, phy_port).pipe;
   8686 
   8687     return SOC_E_NONE;
   8688 }
   8689 
   8690 /*
   8691  * Function:
   8692  *      bcmi_xgs5_port_range
   8693  * Purpose:
   8694  *      Get logical port range in a pipe
   8695  * Parameters:
   8696  *      unit    - (IN) Unit number.
   8697  *      pipe    - (IN) Pipe
   8698  *      port_start - (OUT) First logical port of the pipe
   8699  *      port_end   - (OUT) Last logical port of the pipe
   8700  * Returns:
   8701  *      SOC_E_XXX
   8702  */
   8703 int
   8704 bcmi_xgs5_port_range(int unit, int pipe, int *port_start, int *port_end)
   8705 {
   8706     bcmi_xgs5_dev_info_t *dev_info;
   8707 
   8708     if (BCMI_PORT_DRV(unit) == NULL) {
   8709         return BCM_E_UNAVAIL;
   8710     }
   8711 
   8712     if ((port_start == NULL) || (port_end == NULL)) {
   8713         return BCM_E_PARAM;
   8714     }
   8715 
   8716     dev_info = BCMI_PORT_DRV_DEV_INFO(unit);
   8717     if (dev_info->pipe_bound) {
   8718         *port_start = dev_info->pipe_log_port_base[pipe];
   8719         *port_end   = *port_start + dev_info->ports_pipe_max[pipe] - 1;
   8720     } else {
   8721         *port_start = 0;
   8722         *port_end   = dev_info->ports_pipe_max[dev_info->num_pipe - 1] - 1;
   8723     }
   8724 
   8725     return SOC_E_NONE;
   8726 }
   8727 
   8728 /*
   8729  * Function:
   8730  *      bcmi_xgs5_speed_to_lanes
   8731  * Purpose:
   8732  *      Get number of lanes based on ports speed in a PM.
   8733  *      If a speed have multiple lane mode (eg, 2-lane 40G and 4-lane 40G),
   8734  *      select as much lanes as possible.
   8735  * Example:
   8736  *      PM need to be configured as 1x40G+2x10G
   8737  *      Input speed[] = {40000, 0, 10000, 10000}
   8738  *      Output lanes[] = {2, 0, 1, 1}
   8739  * Parameters:
   8740  *      unit        - (IN) Unit number.
   8741  *      lane_max    - (IN) Max lanes in the PM
   8742  *      speed       - (IN) Port speed array in the PM
   8743  *      lanes       - (OUT) Lanes array in the PM
   8744  * Returns:
   8745  *      SOC_E_XXX
   8746  */
   8747 int
   8748 bcmi_xgs5_speed_to_lanes(int unit, int lane_max, int *speed, int *lanes)
   8749 {
   8750     int i, j;
   8751     int speed_mask[SOC_PORT_RESOURCE_LANES_MAX];
   8752     int port_lanes[SOC_PORT_RESOURCE_LANES_MAX] = {0};
   8753     bcmi_xgs5_dev_info_t *dev_info;
   8754 
   8755     if (BCMI_PORT_DRV(unit) == NULL) {
   8756         return BCM_E_UNAVAIL;
   8757     }
   8758 
   8759     if ((speed == NULL) || (lanes == NULL)) {
   8760         return BCM_E_PARAM;
   8761     }
   8762 
   8763     dev_info = BCMI_PORT_DRV_DEV_INFO(unit);
   8764 
   8765     /* calculate max lanes of each port */
   8766     for (i = 0, j = 0; i < lane_max; i ++) {
   8767         speed_mask[i] = SOC_PA_SPEED(speed[i]);
   8768         if (speed_mask[i] != 0) {
   8769             j = i;
   8770         }
   8771         port_lanes[j] ++;
   8772     }
   8773 
   8774     /* select max lanes of a speed */
   8775     for (i = 0; i < lane_max; i ++) {
   8776         if (port_lanes[i] > 0) {
   8777             for (j = port_lanes[i]; j > 0; j --) {
   8778                 if (dev_info->speed_valid[j] & speed_mask[i]) {
   8779                     lanes[i] = j;
   8780                     break;
   8781                 }
   8782             }
   8783             if (j == 0) {
   8784                 return SOC_E_PARAM;
   8785             }
   8786         } else {
   8787             lanes[i] = 0;
   8788         }
   8789     }
   8790 
   8791     return SOC_E_NONE;
   8792 }
   8793 
   8794 /* End of debug functions for Flexport */
   8795 
   8796 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */