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


      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:     Port driver.
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <soc/defs.h>
     14 
     15 #if defined(BCM_APACHE_SUPPORT)
     16 #include <soc/drv.h>
     17 #include <soc/types.h>
     18 #include <soc/apache.h>
     19 #include <bcm_int/esw_dispatch.h>
     20 #include <bcm_int/esw/port.h>
     21 #include <bcm_int/esw/stack.h>
     22 #include <bcm_int/esw/portctrl.h>
     23 #include <bcm_int/esw/xgs5.h>
     24 #include <bcm_int/esw/trident2.h>
     25 #include <bcm_int/esw/trident2plus.h>
     26 #include <bcm_int/esw/apache.h>
     27 #include <bcm/error.h>
     28 #include <bcm/port.h>
     29 
     30 #define AP_FLEX_MAX_NUM_PORTS        76
     31 
     32 #define IS_AP_HSP_PORT(u,p)   \
     33     ((_soc_apache_port_sched_type_get((u),(p)) == SOC_APACHE_SCHED_HSP) ? 1 : 0)
     34 
     35 /*
     36  * Function:
     37  *      _bcm_apache_port_mac_get
     38  * Description:
     39  *      Get EGR_PORT/LPORT table mac address
     40  * Parameters:
     41  *      unit    - (IN)  BCM device number
     42  *      port    - (IN)  Port number if valid.
     43  *      oui     - (IN)  Indicates mac field is OUI/Non-OUI
     44  *      mac     - (OUT) OUI/Non-OUI part of MAC-ADDRESS
     45  * Return Value:
     46  *      BCM_E_XXX
     47  */
     48 int
     49 _bcm_apache_port_mac_get(int unit, bcm_port_t port, int oui, uint32* mac)
     50 {
     51     egr_port_entry_t   egr_port_entry;
     52     bcm_module_t       modid;
     53     bcm_port_t         local_port;
     54     bcm_trunk_t        tgid;
     55     int                id;
     56     int                is_local = FALSE;
     57     soc_field_t        field;
     58 
     59     if (oui) {
     60         field = MAC_ADDRESS_UPPERf;
     61     } else {
     62         field = MAC_ADDRESS_LOWERf;
     63     }
     64 
     65     if (BCM_GPORT_IS_SET(port)) {
     66 
     67         /* GPORT Validations */
     68         BCM_IF_ERROR_RETURN(
     69            _bcm_esw_gport_resolve(
     70                           unit, port, &modid, &local_port, &tgid, &id));
     71 
     72         if (-1 == local_port) {
     73             return BCM_E_PARAM;
     74         }
     75 
     76         BCM_IF_ERROR_RETURN(
     77                            _bcm_esw_modid_is_local(unit, modid, &is_local));
     78         if (!is_local) {
     79             return BCM_E_PARAM;
     80         }
     81 
     82         /* For subports get from EGR_LPORT_PROFILE table */
     83         if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
     84             return bcm_esw_port_egr_lport_field_get(unit,
     85                                                     port,
     86                                                     EGR_LPORT_PROFILEm,
     87                                                     field,
     88                                                     mac);
     89         }
     90 
     91 
     92     } else {
     93         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
     94     }
     95 
     96     SOC_IF_ERROR_RETURN(
     97             READ_EGR_PORTm(unit, MEM_BLOCK_ANY, local_port, &egr_port_entry));
     98 
     99     *mac = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, field);
    100 
    101     return BCM_E_NONE;
    102 }
    103 
    104 /*
    105  * Function:
    106  *      _bcm_apache_port_mac_set
    107  * Description:
    108  *      Configure EGR_PORT/LPORT table mac address
    109  * Parameters:
    110  *      unit  - (IN) BCM device number
    111  *      port  - (IN) Port number if valid.
    112  *      oui   - (IN) Indicates mac field is OUI/Non-OUI
    113  *      mac   - (IN) OUI/Non-OUI part of MAC-ADDRESS
    114  * Return Value:
    115  *      BCM_E_XXX
    116  */
    117 int
    118 _bcm_apache_port_mac_set(int unit, bcm_port_t port, int oui, uint32 mac)
    119 {
    120     egr_port_entry_t   egr_port_entry;
    121     bcm_module_t       modid;
    122     bcm_port_t         local_port;
    123     bcm_trunk_t        tgid;
    124     int                id;
    125     int                is_local = FALSE;
    126     soc_field_t        field;
    127 
    128     if (oui) {
    129         field = MAC_ADDRESS_UPPERf;
    130     } else {
    131         field = MAC_ADDRESS_LOWERf;
    132     }
    133 
    134     if (BCM_GPORT_IS_SET(port)) {
    135 
    136         /* GPORT Validations */
    137         BCM_IF_ERROR_RETURN(
    138             _bcm_esw_gport_resolve(
    139                                    unit, port, &modid, &local_port, &tgid, &id));
    140 
    141         if (-1 == local_port) {
    142             return BCM_E_PARAM;
    143         }
    144 
    145         BCM_IF_ERROR_RETURN(
    146                            _bcm_esw_modid_is_local(unit, modid, &is_local));
    147         if (!is_local) {
    148             return BCM_E_PARAM;
    149         }
    150 
    151         /* For subports set the EGR_LPORT_PROFILE table */
    152         if (BCM_GPORT_IS_SUBPORT_PORT(port)) {
    153             return bcm_esw_port_egr_lport_field_set(unit,
    154                                                     port,
    155                                                     EGR_LPORT_PROFILEm,
    156                                                     field,
    157                                                     mac);
    158         }
    159 
    160     } else {
    161         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port));
    162     }
    163 
    164 
    165     SOC_IF_ERROR_RETURN(
    166                  READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port_entry));
    167 
    168     soc_EGR_PORTm_field_set(unit, &egr_port_entry, field, &mac);
    169 
    170     SOC_IF_ERROR_RETURN(
    171             WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port_entry));
    172 
    173     return BCM_E_NONE;
    174 }
    175 
    176 
    177 
    178 /*
    179  * FlexPort Operations Changes
    180  *
    181  * Flags to be used to determine the type of operations required
    182  * when the FlexPort API multi_set() is called.
    183  *
    184  * OP_NONE  - No changes.
    185  * OP_PMAP  - Change in port mapping.  It requires FlexPort sequence.
    186  * OP_LANES - Change in lanes.  It requires FlexPort sequence.
    187  * OP_SPEED - Change in speed.  This is covered in a FlexPort sequence.
    188  *            A change in speed may require a FlexPort sequence.
    189  *            If it is not required, then calling the 'speed' set
    190  *            function is sufficient.
    191  * OP_ENCAP - Change in encap mode.  It is NOT covered in a FlexPort
    192  *            sequence, so an explicit call must be made to change
    193  *            the encap mode.
    194  * OP_ALL   - All the above.  It requires FlexPort sequence.  
    195  */
    196 #define BCM_AP_PORT_RESOURCE_OP_NONE     0
    197 #define BCM_AP_PORT_RESOURCE_OP_PMAP    (1 << 0)
    198 #define BCM_AP_PORT_RESOURCE_OP_LANES   (1 << 1)
    199 #define BCM_AP_PORT_RESOURCE_OP_SPEED   (1 << 2)
    200 #define BCM_AP_PORT_RESOURCE_OP_ENCAP   (1 << 3)
    201 #define BCM_AP_PORT_RESOURCE_OP_ALL           \
    202     (BCM_AP_PORT_RESOURCE_OP_PMAP  |          \
    203      BCM_AP_PORT_RESOURCE_OP_LANES |          \
    204      BCM_AP_PORT_RESOURCE_OP_SPEED |          \
    205      BCM_AP_PORT_RESOURCE_OP_ENCAP) 
    206 
    207 /*
    208  * Internal BCM Port Resource Configuration
    209  */
    210 typedef struct bcm_apache_port_resource_s {
    211     uint32 flags;              /* SOC_PORT_RESOURCE_XXX */
    212     bcm_gport_t port;          /* Local logical port number to connect to
    213                                   the given physical port */
    214     int physical_port;         /* Local physical port, -1 if the logical to
    215                                   physical mapping is to be deleted */
    216     int speed;                 /* Initial speed after FlexPort operation */
    217     int lanes;                 /* Number of PHY lanes for this physical port */
    218     bcm_port_encap_t encap;    /* Encapsulation mode for port */
    219 } bcm_apache_port_resource_t;
    220 
    221 
    222 
    223 /*
    224  * Forward static function declaration
    225  */
    226 STATIC int
    227 _bcm_apache_port_resource_multi_set(int unit, 
    228                                     int nport, bcm_port_resource_t *resource);
    229 STATIC int
    230 _bcm_apache_port_resource_speed_set(int unit, bcm_port_t port, int speed);
    231 
    232 
    233 /*
    234  * Device Specific HW Tables
    235  */
    236 
    237 /* Egr port table */
    238 static bcmi_xgs5_port_redirection_egr_port_table_t
    239             bcmi_apache_port_redirection_egr_port_table = {
    240     /* mem */ 	              EGR_PORTm,
    241     /* dest_type */           ER_REDIR_DEST_TYPEf,
    242     /* dest_value */          ER_REDIR_DESTINATIONf,
    243     /* drop_original */       ER_REDIR_DROP_ORIGINALf,
    244     /* pkt_priority */        ER_REDIR_NEW_PRIf,
    245     /* pkt_change_priority */ ER_REDIR_CHANGE_PRIf,
    246     /* pkt_color */           ER_REDIR_NEW_COLORf,
    247     /* pkt_change_color */    ER_REDIR_CHANGE_COLORf,
    248     /* strength */            ER_REDIR_STRENGTHf,
    249     /* buffer_priority */     ER_REDIR_RDB_PRIORITYf,
    250     /* action */              ER_REDIR_ACTIONf,
    251     /* redir_pkt_source */    ER_REDIR_SOURCEf,
    252     /* redir_pkt_truncate */  ER_REDIR_FIRST_CELL_ONLYf
    253 };
    254 
    255 /* HW Definitions */
    256 static bcmi_xgs5_port_hw_defs_t  bcmi_apache_port_hw_defs;
    257 
    258 
    259 /*
    260  * Function Vector
    261  */
    262 static bcm_esw_port_drv_t bcm_apache_port_drv = {
    263     /* fn_drv_init                */ bcmi_apache_port_fn_drv_init,
    264     /* resource_set               */ bcmi_xgs5_port_resource_set,
    265     /* resource_get               */ bcmi_xgs5_port_resource_get,
    266     /* resource_multi_set         */ _bcm_apache_port_resource_multi_set,
    267     /* resource_speed_set         */ _bcm_apache_port_resource_speed_set,
    268     /* resource_traverse          */ bcmi_xgs5_port_resource_traverse,
    269     /* port_redirect_set          */ bcmi_xgs5_port_redirect_config_set,
    270     /* port_redirect_get          */ bcmi_xgs5_port_redirect_config_get,
    271     /* port_enable_set            */ NULL,
    272     /* encap_speed_check          */ bcmi_xgs5_port_encap_speed_check,
    273     /* force_lb_set               */ NULL,
    274     /* force_lb_check             */ NULL,
    275     /* resource_status_update     */ bcmi_xgs5_port_resource_status_update
    276 };
    277 
    278 
    279 /*
    280  * Function:
    281  *      bcmi_apache_port_fn_drv_init
    282  * Purpose:
    283  *      Initialize the Port function driver.
    284  * Parameters:
    285  *      unit - (IN) Unit number.
    286  * Returns:
    287  *      BCM_E_xxx
    288  * Notes:
    289  */
    290 int
    291 bcmi_apache_port_fn_drv_init(int unit)
    292 {
    293     /* HW Definition Tables */
    294     sal_memset(&bcmi_apache_port_hw_defs, 0,
    295                sizeof(bcmi_apache_port_hw_defs));
    296     bcmi_apache_port_hw_defs.egr_port =
    297         &bcmi_apache_port_redirection_egr_port_table;
    298 
    299     /* Initialize Common XGS5 Port module */
    300     BCM_IF_ERROR_RETURN
    301         (bcmi_xgs5_port_fn_drv_init(unit, &bcm_apache_port_drv, NULL,
    302                             &bcmi_apache_port_hw_defs));
    303 
    304     return BCM_E_NONE;
    305 }
    306 
    307 
    308 /*
    309  * Function:
    310  *      _bcm_apache_port_attach
    311  * Purpose:
    312  *      Attach given port to the BCM layer and initialize it
    313  *      to its default state.
    314  * Parameters:
    315  *      unit     - (IN) Unit number.
    316  *      port     - (IN) Logical port, BCM format.
    317  * Returns:
    318  *      BCM_E_XXX
    319  * Note:
    320  *      - Assumes port is a valid BCM logical port.
    321  *      - Assumes function is called when a new port is added into the system,
    322  *        so it is not called during WarmBoot.
    323  *      - Assumes BCM PORT module initialization routine has
    324  *        been called.
    325  *      - Assumes this is NOT called during Warmboot.
    326  */
    327 STATIC int
    328 _bcm_apache_port_attach(int unit, bcm_port_t port)
    329 {
    330     int rv = BCM_E_NONE;
    331 
    332     BCM_IF_ERROR_RETURN(bcm_esw_td2p_flexport_port_attach(unit, port));
    333 
    334     rv = bcm_ap_cosq_default_llfc_profile_attach(unit, port);
    335     if (BCM_FAILURE(rv)) {
    336         LOG_ERROR(BSL_LS_BCM_PORT,
    337                   (BSL_META_U(unit,
    338                               "Unable to add default entries for PRIO2COS_PROFILE"
    339                               "register profile unit=%d port=%d rv=%d\n"),
    340                    unit, port, rv));
    341         return rv;
    342     }
    343 
    344     BCM_IF_ERROR_RETURN(bcm_ap_cosq_flex_port_update( unit , port , TRUE));
    345 
    346     /* Setup CosQ hierarchy  */
    347     if (!IS_AP_HSP_PORT(unit, port)) {
    348         rv = _bcm_ap_port_lls_config_set(unit, port);
    349         if (BCM_FAILURE(rv)) {
    350             LOG_ERROR(BSL_LS_BCM_PORT,
    351                       (BSL_META_U(unit,
    352                                   "Error: Unable to setup LLS sched tree "
    353                                   "unit=%d port=%d rv=%d\n"),
    354                        unit, port, rv));
    355             return rv;
    356         }
    357         if (soc_ap_is_skip_default_lls_creation(unit)) {
    358                 SOC_IF_ERROR_RETURN(
    359                     soc_apache_port_mmu_tx_enable_set(unit, port, 0));
    360         }
    361         
    362 
    363     } else {
    364         rv = soc_apache_cosq_enable_hsp_sched(unit,port);
    365         if (BCM_FAILURE(rv)) {
    366             LOG_ERROR(BSL_LS_BCM_PORT,
    367                       (BSL_META_U(unit,
    368                                   "Error: Unable to setup HSP sched tree "
    369                                   "unit=%d port=%d rv=%d\n"),
    370                        unit, port, rv));
    371             return rv;
    372         }
    373 
    374         rv = _bcm_ap_port_hsp_config_set(unit, port);
    375         if (BCM_FAILURE(rv)) {
    376             LOG_ERROR(BSL_LS_BCM_PORT,
    377                       (BSL_META_U(unit,
    378                                   "Error: Unable config HSP node "
    379                                   "unit=%d port=%d rv=%d\n"),
    380                        unit, port, rv));
    381             return rv;
    382         }
    383         if (soc_ap_is_skip_default_lls_creation(unit)) {
    384                 SOC_IF_ERROR_RETURN(
    385                     soc_apache_port_mmu_tx_enable_set(unit, port, 1));
    386         }
    387  
    388     }
    389 
    390     rv = soc_apache_mmu_config_init(unit, 0, port);
    391     BCM_IF_ERROR_RETURN(rv);
    392 
    393 
    394     return BCM_E_NONE;
    395 }
    396 
    397 
    398 /*
    399  * Function:
    400  *      _bcm_apache_port_detach
    401  * Purpose:
    402  *      Detach given port from the BCM layer and clear any data
    403  *      that is normally configured when a port is initialized.
    404  * Parameters:
    405  *      unit     - (IN) Unit number.
    406  *      port     - (IN) Logical port, BCM format.
    407  * Returns:
    408  *      BCM_E_XXX
    409  * Note:
    410  *      - Assumes port is a valid BCM logical port.
    411  *      - Assumes this is NOT called during Warmboot.
    412  */
    413 STATIC int
    414 _bcm_apache_port_detach(int unit, bcm_port_t port)
    415 {
    416     bcm_gport_t gport;
    417     int rv = BCM_E_NONE;
    418 
    419     rv = bcm_esw_td2p_flexport_port_detach(unit, port);
    420     if (BCM_FAILURE(rv)) {
    421         LOG_ERROR(BSL_LS_BCM_PORT,
    422                   (BSL_META_U(unit,
    423                               "Error: Unable to detach BCM port "
    424                               "unit=%d port=%d rv=%d\n"),
    425                    unit, port, rv));
    426         return rv;
    427     }
    428 
    429     rv = bcm_ap_cosq_llfc_profile_detach(unit, port);
    430     if (BCM_FAILURE(rv)) {
    431         LOG_ERROR(BSL_LS_BCM_PORT,
    432                   (BSL_META_U(unit,
    433                               "Unable to delete default entries for PRIO2COS_PROFILE"
    434                               "register profile unit=%d port=%d rv=%d\n"),
    435                    unit, port, rv));
    436         return rv;
    437     }
    438 
    439     if (IS_AP_HSP_PORT(unit, port)) {
    440         /* Clear HSP port bitmap */
    441         SOC_IF_ERROR_RETURN(soc_apache_cosq_disable_hsp_sched(unit, port));
    442     }
    443     /* Delete CoS queue tree */
    444     rv = bcm_esw_port_gport_get(unit, port, &gport);
    445     if (BCM_FAILURE(rv)) {
    446         LOG_ERROR(BSL_LS_BCM_PORT,
    447                   (BSL_META_U(unit,
    448                               "Error: Unable to retrieve gport "
    449                               "unit=%d port=%d rv=%d\n"),
    450                    unit, port, rv));
    451         return rv;
    452     }
    453 
    454     rv = bcm_ap_cosq_gport_delete(unit, gport);
    455     if (BCM_FAILURE(rv)) {
    456         LOG_ERROR(BSL_LS_BCM_PORT,
    457                   (BSL_META_U(unit,
    458                               "Error: Unable to destroy LLS tree "
    459                               "unit=%d port=%d rv=%d\n"),
    460                    unit, port, rv));
    461         return rv;
    462     }
    463     BCM_IF_ERROR_RETURN(
    464     bcm_ap_cosq_flex_port_update( unit , port , FALSE));
    465 
    466     return BCM_E_NONE;
    467 }
    468 
    469 
    470 /*
    471  * Function:
    472  *      bcm_apache_flexport_pbmp_update
    473  * Description:
    474  *      Returns bitmap of max valid ports
    475  * Parameters:
    476  *      unit    - (IN) BCM device number
    477  *      pbmp    - (IN/OUT) port bit map
    478  */
    479 
    480 int
    481 bcm_apache_flexport_pbmp_update(int unit, bcm_pbmp_t *pbmp)
    482 {
    483     bcm_port_t port;
    484 
    485     if (NULL == pbmp) {
    486         return BCM_E_PARAM;
    487     }
    488     for (port = 0; port < AP_FLEX_MAX_NUM_PORTS; port++) {
    489         BCM_PBMP_PORT_ADD(*pbmp, port);
    490     }
    491     return BCM_E_NONE;
    492 }
    493 
    494 
    495 
    496 /*
    497  * Function:
    498  *      _bcm_apache_port_resource_attach
    499  * Purpose:
    500  *      Attach ports to the BCM layer and initialize them
    501  *      to the default state.
    502  *
    503  * Parameters:
    504  *      unit           - (IN) Unit number.
    505  *      nport          - (IN) Number of elements in array resource.
    506  *      resource       - (IN) Port Resource FlexPort configuration.
    507  * Returns:
    508  *      BCM_E_XXX
    509  * Notes:
    510  *      - Assumes caller have detached any ports that will be attached
    511  *        in this routine.
    512  *      - Assumes this is NOT called during Warmboot.
    513  *      - Set current MY_MODID for all newly attached ports.
    514  */
    515 STATIC int
    516 _bcm_apache_port_resource_attach(int unit,
    517                                int nport,
    518                                bcm_apache_port_resource_t *resource)
    519 {
    520     int rv = BCM_E_NONE;
    521     bcm_apache_port_resource_t *pr;
    522     int i;
    523     int my_modid;
    524 
    525     LOG_VERBOSE(BSL_LS_BCM_PORT,
    526                 (BSL_META_U(unit,
    527                             "--- BCM Attach ---\n")));
    528     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
    529 
    530 
    531     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    532         if (pr->flags & SOC_PORT_RESOURCE_ATTACH) {
    533             rv = _bcm_apache_port_attach(unit, pr->port);
    534             if (BCM_FAILURE(rv)) {
    535                 LOG_ERROR(BSL_LS_BCM_PORT,
    536                           (BSL_META_U(unit,
    537                                       "Error: Unable to attach BCM port "
    538                                       "unit=%d port=%d rv=%d\n"),
    539                            unit, pr->port, rv));
    540                 return rv;
    541             }
    542         }
    543     }
    544 
    545     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_set(unit, my_modid));
    546 
    547     return BCM_E_NONE;
    548 }
    549 
    550 
    551 /*
    552  * Function:
    553  *      _bcm_apache_port_resource_detach
    554  * Purpose:
    555  *      Detach ports from the BCM layer.
    556  *
    557  *      It clears any HW or SW state that was programmed
    558  *      by the SDK initialization routines.  It does NOT clear
    559  *      references to logical ports that have been programmed by the
    560  *      application.  Applications are responsible for doing that.
    561  *
    562  * Parameters:
    563  *      unit           - (IN) Unit number.
    564  *      nport          - (IN) Number of elements in array resource.
    565  *      resource       - (IN) Port Resource FlexPort configuration.
    566  * Returns:
    567  *      BCM_E_XXX
    568  * Notes:
    569  *      - Assumes this is NOT called during Warmboot.
    570  */
    571 STATIC int
    572 _bcm_apache_port_resource_detach(int unit,
    573                                int nport,
    574                                bcm_apache_port_resource_t *resource)
    575 {
    576     int rv = BCM_E_NONE;
    577     bcm_apache_port_resource_t *pr;
    578     int i;
    579 
    580     LOG_VERBOSE(BSL_LS_BCM_PORT,
    581                 (BSL_META_U(unit,
    582                             "--- BCM Detach ---\n")));
    583 
    584     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    585         if (pr->flags & SOC_PORT_RESOURCE_DETACH) {
    586             rv = _bcm_apache_port_detach(unit, pr->port);
    587             if (BCM_FAILURE(rv)) {
    588                 LOG_ERROR(BSL_LS_BCM_PORT,
    589                           (BSL_META_U(unit,
    590                                       "Error: Unable to detach BCM port "
    591                                       "unit=%d port=%d rv=%d\n"),
    592                            unit, pr->port, rv));
    593                 return rv;
    594             }
    595         }
    596     }
    597 
    598     return BCM_E_NONE;
    599 }
    600 
    601 
    602 /*
    603  * Function:
    604  *      _bcm_apache_port_resource_resolve
    605  * Purpose:
    606  *      Convert logical port number GPORT to BCM local port format and
    607  *      validate port numbers:
    608  *      - Logical and physical port numbers are within the valid range.
    609  *      - Ports must not be CPU or Loopback ports.
    610  * Parameters:
    611  *      unit     - (IN) Unit number.
    612  *      nport    - (IN) Number of elements in array resource.
    613  *      resource - (IN/OUT) Port resource configuration array.
    614  * Returns:
    615  *      BCM_E_XXX
    616  * Note:
    617  *      - Assumes caller has lock.
    618  *      - Resource is not NULL.
    619  */
    620 STATIC int
    621 _bcm_apache_port_resource_resolve(int unit, 
    622                                   int nport,
    623                                   bcm_apache_port_resource_t *resource)
    624 {
    625     int i;
    626     bcm_apache_port_resource_t *pr;
    627     soc_info_t *si = &SOC_INFO(unit);
    628 
    629     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    630 
    631         /* Check that logical port number is addressable and convert */
    632         BCM_IF_ERROR_RETURN
    633             (bcmi_xgs5_port_addressable_local_get(unit,
    634                                                   pr->port,
    635                                                   &pr->port));
    636 
    637         /*
    638          * Check that logical port number is valid for Apache
    639          * (above check is generic)
    640          */
    641         SOC_IF_ERROR_RETURN
    642             (soc_ap_port_addressable(unit, pr->port));
    643 
    644         /* Check that physical port is within the valid range */
    645         if (pr->physical_port != -1) {
    646             SOC_IF_ERROR_RETURN
    647                 (soc_ap_phy_port_addressable(unit, pr->physical_port));
    648         }
    649 
    650         /* Check that ports, logical and physical, are not a management port */
    651         if ((si->port_l2p_mapping[pr->port] == AP_PHY_PORT_CPU) ||
    652             (si->port_l2p_mapping[pr->port] == AP_PHY_PORT_LB) ||
    653             (pr->physical_port == AP_PHY_PORT_CPU) ||
    654             (pr->physical_port == AP_PHY_PORT_LB)) {
    655             LOG_ERROR(BSL_LS_BCM_PORT,
    656                       (BSL_META_U(unit,
    657                                   "Port cannot be CPU, LB, or RDB port "
    658                                   "unit=%d port=%d\n"),
    659                        unit, pr->port));
    660             return BCM_E_PORT;
    661         }
    662     }
    663 
    664     return BCM_E_NONE;
    665 }
    666 
    667 
    668 /*
    669  * Function:
    670  *      _bcm_apache_port_resource_input_validate
    671  * Purpose:
    672  *      Validate function input requirements.
    673  *
    674  *      This routine checks for function semantics and guidelines
    675  *      from the API perspective:
    676  *      - Check the order of elements in array, 'delete' operations must
    677  *        be placed first in array.
    678  *      - Ports must not be CPU or Loopback ports.
    679  *      - Ports must be disabled.
    680  *      - Ports linkscan mode must be NONE.
    681  * Parameters:
    682  *      unit     - (IN) Unit number.
    683  *      nport    - (IN) Number of elements in array resource.
    684  *      resource - (IN/OUT) Port resource configuration array.
    685  * Returns:
    686  *      BCM_E_XXX
    687  * Note:
    688  *      - Assumes caller has lock.
    689  *      - Resource is not NULL.
    690  *      - Assumes port values has been validated.
    691  */
    692 STATIC int
    693 _bcm_apache_port_resource_input_validate(int unit, 
    694                                          int nport,
    695                                          bcm_apache_port_resource_t *resource)
    696 {
    697     int i;
    698     bcm_apache_port_resource_t *pr;
    699     int delete = 1;
    700     int enable;
    701     soc_info_t *si = &SOC_INFO(unit);
    702 
    703     /* Check array order and port state disable */
    704     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    705 
    706         /* Skip check for speed change */
    707         if (pr->flags & SOC_PORT_RESOURCE_SPEED) {
    708             continue;
    709         }
    710 
    711         /* Check that delete operations are first */
    712         if (pr->physical_port != -1) {  /* First non-delete found */
    713             delete = 0;
    714         } else if ((pr->physical_port == -1) && !delete) {
    715             LOG_ERROR(BSL_LS_BCM_PORT,
    716                       (BSL_META_U(unit,
    717                                   "Delete operations must be "
    718                                   "first in array\n")));
    719             return BCM_E_CONFIG;
    720         }
    721 
    722         if ((pr->encap != BCM_PORT_ENCAP_IEEE) &&
    723             (pr->encap != BCM_PORT_ENCAP_HIGIG2)) {
    724             LOG_ERROR(BSL_LS_BCM_PORT,
    725                       (BSL_META_U(unit,
    726                                   "Encap modes can only be IEEE or HIGIG2 "
    727                                   "unit=%d port=%d\n"),
    728                        unit, pr->port));
    729             return BCM_E_CONFIG;
    730         }
    731 
    732         /* Skip ports that are not currently defined */
    733         if (si->port_l2p_mapping[pr->port] == -1) {
    734             continue;
    735         }
    736 
    737         /* Check that ports are disabled */
    738         BCM_IF_ERROR_RETURN
    739             (bcm_esw_port_enable_get(unit, pr->port, &enable));
    740         if (enable) {
    741             LOG_ERROR(BSL_LS_BCM_PORT,
    742                       (BSL_META_U(unit,
    743                                   "Port %d needs to be disabled\n"),
    744                        pr->port));
    745             return BCM_E_BUSY;
    746         }
    747 
    748         /*
    749          * Check that ports to be 'detached' do not
    750          * have linkscan mode set.  See _bcm_apache_port_resource_pmap_get().
    751          */
    752         if (pr->flags & SOC_PORT_RESOURCE_DETACH) {
    753             if (bcm_esw_linkscan_enable_port_get(unit, pr->port) !=
    754                 BCM_E_DISABLED) {
    755                 LOG_ERROR(BSL_LS_BCM_PORT,
    756                           (BSL_META_U(unit,
    757                                       "Linkscan mode needs to be "
    758                                       "disabled on ports to be detached, "
    759                                       "port=%d\n"),
    760                            pr->port));
    761                 return BCM_E_BUSY;
    762             }
    763         }
    764     }
    765 
    766     return BCM_E_NONE;
    767 }
    768 
    769 
    770 
    771 /*
    772  * Function:
    773  *      _bcm_apache_port_resource_pmap_get
    774  * Purpose:
    775  *      Determine the type of port mapping changes, if any,
    776  *      as a result of the FlexPort operation.  In addition, it
    777  *      determines whether the port needs to go through the attach
    778  *      and/or detach process.
    779  *
    780  *      All ports that are being flexed will be detached except for those
    781  *      that will become inactive (this is only for legacy mode).
    782  *      All ports that are active after flexed are always attached (this is
    783  *      for new and legacy mode).
    784  *
    785  *      When a port is 'marked' as 'delete' (physical port is -1),
    786  *      this does not mean the logical port will be destroyed.  Depending
    787  *      on the rest of the information in the array, the port mapping
    788  *      may be the same, remapped, or it may no longer exist after FlexPort.
    789  *
    790  *      Likewise, when a valid port mapping is given, the port may
    791  *      not be necessarily new.
    792  *
    793  *      Example:
    794  *
    795  *      Main FlexPort array ('resource') (application input)
    796  *               L1 --> -1 (current mapped to P1), mapping is SAME
    797  *               L2 --> -1 (current mapped to P2), mapping is REMAP
    798  *               L3 --> -1 (current mapped to P3), mapping is DESTROY
    799  *               L1 --> P1                       , mapping is SAME
    800  *               L2 --> P5                       , mapping is REMAP
    801  *               L9 --> P9                       , mapping is NEW
    802  *
    803  * Parameters:
    804  *      unit           - (IN) Unit number.
    805  *      nport          - (IN) Number of elements in array resource.
    806  *      resource       - (IN/OUT) Port Resource FlexPort configuration.
    807  * Returns:
    808  *      SOC_E_XXX
    809  * Notes:
    810  *      Assumes all 'delete' elements are first in array.
    811  */
    812 STATIC int
    813 _bcm_apache_port_resource_pmap_get(int unit, int nport,
    814                                    bcm_apache_port_resource_t *resource)
    815 {
    816     int i;
    817     int j;
    818     bcm_apache_port_resource_t *pr;
    819     soc_info_t *si = &SOC_INFO(unit);
    820 
    821     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    822 
    823         if (pr->physical_port == -1) {
    824             /*
    825              * Find if port is given in later elements.
    826              * If so, check if port is remapped.
    827              * If not found, port is marked to be destroyed
    828              * (port will no longer exist after FlexPort)
    829              *
    830              * Note that all the 'delete' ports must always first
    831              * in array.
    832              */
    833             for (j = i; j < nport; j++) {
    834                 if (resource[j].physical_port == -1) {
    835                     continue;
    836                 }
    837                 if (resource[j].port == pr->port) {  /* Found */
    838                     int cur_encap;
    839                     /* Get current port encap */
    840                     BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, pr->port,
    841                                                                &cur_encap));
    842                     /* Check if mapping is same */
    843                     if (resource[j].physical_port !=
    844                         si->port_l2p_mapping[pr->port]) {
    845                         pr->flags |= SOC_PORT_RESOURCE_REMAP;
    846                         if (resource[j].flags & SOC_PORT_RESOURCE_SPEED) {
    847                             LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U
    848                                 (unit, "Port Mapping doesn't match\n")));
    849                             return BCM_E_CONFIG;
    850                         }
    851                     }
    852 
    853                     /* Check if lanes and encap mode are same */
    854                     if ((si->port_num_lanes[pr->port] != resource[j].lanes) ||
    855                         (cur_encap != resource[j].encap)) {
    856                         if (resource[j].flags & SOC_PORT_RESOURCE_SPEED) {
    857                             LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U
    858                                 (unit, "Lanes or Encap mode doesn't match\n")));
    859                             return BCM_E_CONFIG;
    860                         }
    861                     }
    862                     break;
    863                 }
    864             }
    865 
    866             if (j >= nport) {  /* Not found */
    867                 pr->flags |= SOC_PORT_RESOURCE_DESTROY;
    868                 if (pr->flags & SOC_PORT_RESOURCE_SPEED) {
    869                     LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U
    870                         (unit, "Port Mapping doesn't match\n")));
    871                     return BCM_E_CONFIG;
    872                 }
    873             }
    874 
    875             /*
    876              * Detach only if the port is not becoming inactive (legacy).
    877              *
    878              * A port that is becoming inactive after flex is indicated
    879              * when both of the following flags are set:
    880              *     DESTROY
    881              *     I_MAP
    882              */
    883             if (!(pr->flags & SOC_PORT_RESOURCE_DESTROY) ||
    884                 !(pr->flags & SOC_PORT_RESOURCE_I_MAP)) {
    885                 pr->flags |= SOC_PORT_RESOURCE_DETACH;
    886             }
    887 
    888         } else {
    889 
    890             /*
    891              * Check if logical port is new (port does exist), or
    892              * port is being remapped.
    893              */
    894             if (si->port_l2p_mapping[pr->port] == -1) {
    895                 pr->flags |= SOC_PORT_RESOURCE_NEW;
    896                 pr->flags &= ~SOC_PORT_RESOURCE_SPEED;
    897             } else if (pr->physical_port != si->port_l2p_mapping[pr->port]) {
    898                 pr->flags |= SOC_PORT_RESOURCE_REMAP;
    899                 pr->flags &= ~SOC_PORT_RESOURCE_SPEED;
    900             }
    901 
    902             /* All active ports after flexed are always attached */
    903             pr->flags |= SOC_PORT_RESOURCE_ATTACH;
    904         }
    905 
    906     }
    907 
    908     return BCM_E_NONE;
    909 }
    910 
    911 /*
    912  * Function:
    913  *      _bcm_apache_port_resource_op_get
    914  * Purpose:
    915  *      Get the type of FlexPort operations/changes:
    916  *          none, port-mapping, lanes, speed, encap.
    917  *
    918  *      Some operations only need speed or encap changes.  In this
    919  *      case, the actual FlexPort operation is not necessary and
    920  *      only calls to set to speed and/or encap mode are made.
    921  *
    922  * Parameters:
    923  *      unit     - (IN) Unit number.
    924  *      nport    - (IN) Number of elements in array resource.
    925  *      resource - (IN) Port resource configuration array.
    926  *      op       - (OUT) FlexPort operation BCM_AP_PORT_RESOURCE_OP_...
    927  * Returns:
    928  *      BCM_E_XXX
    929  * Note:
    930  *      Assumes caller has lock.
    931  *      Resource is not NULL.
    932  *      Logical port in 'resource' is in BCM port format (non GPORT).
    933  */
    934 STATIC int
    935 _bcm_apache_port_resource_op_get(int unit, int nport,
    936                                 bcm_apache_port_resource_t *resource, int *op)
    937 {
    938     int i;
    939     bcm_apache_port_resource_t *pr;
    940     soc_info_t *si = &SOC_INFO(unit);
    941     int speed = 0;
    942     int encap = 0;
    943 
    944     *op = BCM_AP_PORT_RESOURCE_OP_NONE;
    945 
    946     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
    947 
    948         /* Check port speed */
    949         if (pr->flags & SOC_PORT_RESOURCE_SPEED) {
    950             /*
    951              * NOTE: speed_set sequence
    952              *
    953              * pr->flags & SOC_PORT_RESOURCE_SPEED is set by speed_set API.
    954              * No logical-physical port mapping changes.
    955              * OP_PMAP flag doesn't need to be set in this case.
    956              * _bcm_ap_port_resource_speed_execute will be called.
    957              */
    958             *op |= BCM_AP_PORT_RESOURCE_OP_SPEED;
    959             LOG_VERBOSE(BSL_LS_BCM_PORT,
    960                         (BSL_META_U(unit,
    961                                     "Speed change detected: "
    962                                     "logical=%d physical=%d\n"),
    963                          pr->port, pr->physical_port));
    964             continue;
    965         }
    966 
    967         /* Check port mapping change */
    968         if (pr->flags &
    969             (SOC_PORT_RESOURCE_NEW | SOC_PORT_RESOURCE_DESTROY |
    970              SOC_PORT_RESOURCE_REMAP)) {
    971             *op |= BCM_AP_PORT_RESOURCE_OP_PMAP;
    972 
    973             LOG_VERBOSE(BSL_LS_BCM_PORT,
    974                         (BSL_META_U(unit,
    975                                     "Port map change detected: "
    976                                     "%s %s %s l=%d p=%d\n"),
    977                          (pr->flags & SOC_PORT_RESOURCE_NEW) ? "new" : "",
    978                          (pr->flags & SOC_PORT_RESOURCE_DESTROY) ?
    979                          "destroy" : "",
    980                          (pr->flags & SOC_PORT_RESOURCE_REMAP) ? "remap" : "",
    981                          pr->port, pr->physical_port));
    982         }
    983 
    984         /* Skip ports that are being deleted or not defined */
    985         if ((pr->physical_port == -1) ||
    986             (si->port_l2p_mapping[pr->port] == -1)) {
    987             continue;
    988         }
    989 
    990         /*
    991          * NOTE: Execute full flex operation if speed is different
    992          */
    993         if (!(*op & BCM_AP_PORT_RESOURCE_OP_SPEED)) {
    994             BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, pr->port, &speed));
    995             if (pr->speed != speed) {
    996                 *op |= BCM_AP_PORT_RESOURCE_OP_PMAP;
    997             }
    998         }
    999 
   1000         /* Check port lanes */
   1001         if (!(*op & BCM_AP_PORT_RESOURCE_OP_LANES)) {
   1002             if (pr->lanes != si->port_num_lanes[pr->port]) {
   1003                 *op |= BCM_AP_PORT_RESOURCE_OP_LANES;
   1004             }
   1005         }
   1006 
   1007         /* Check port encap */
   1008         if (!(*op & BCM_AP_PORT_RESOURCE_OP_ENCAP)) {
   1009             BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, pr->port, &encap));
   1010             if (pr->encap != encap) {
   1011                 *op |= BCM_AP_PORT_RESOURCE_OP_ENCAP;
   1012             }
   1013         }
   1014 
   1015         /* If all are set, no more checking is necessary */
   1016         if (*op == BCM_AP_PORT_RESOURCE_OP_ALL) {
   1017             break;
   1018         }
   1019     }
   1020     
   1021     return BCM_E_NONE;
   1022 }
   1023 
   1024 
   1025 /*
   1026  * Function:
   1027  *      _bcm_apache_port_resource_loopback_clear
   1028  * Purpose:
   1029  *      Clear the loopback mode for the given set of ports.
   1030  *
   1031  * Parameters:
   1032  *      unit           - (IN) Unit number.
   1033  *      nport          - (IN) Number of elements in array resource.
   1034  *      resource       - (IN) Port Resource FlexPort configuration.
   1035  * Returns:
   1036  *      SOC_E_XXX
   1037  * Notes:
   1038  *      Assumes all 'delete' elements are first in array.
   1039  */
   1040 STATIC int
   1041 _bcm_apache_port_resource_loopback_clear(int unit,
   1042                                          int nport,
   1043                                          bcm_apache_port_resource_t *resource)
   1044 {
   1045     int i;
   1046     int loopback;
   1047     bcm_apache_port_resource_t *pr;
   1048 
   1049     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
   1050         if (pr->physical_port == -1) {
   1051             BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_loopback_get(unit,
   1052                                                 pr->port, &loopback));
   1053             if (loopback != BCM_PORT_LOOPBACK_NONE) {
   1054                 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_loopback_set(unit,
   1055                                                 pr->port,
   1056                                                 BCM_PORT_LOOPBACK_NONE));
   1057             }
   1058         }
   1059     }
   1060 
   1061     return BCM_E_NONE;
   1062 
   1063 }
   1064 
   1065 /*
   1066  * Function:
   1067  *      _bcm_apache_port_resource_speed_execute
   1068  * Purpose:
   1069  *      Perform a speed set operation.
   1070  *      This includes speed change only
   1071  *
   1072  * Parameters:
   1073  *      unit     - (IN) Unit number.
   1074  *      nport    - (IN) Number of elements in array resource.
   1075  *      resource - (IN) Port resource configuration array.
   1076  * Returns:
   1077  *      BCM_E_XXX
   1078  * Note:
   1079  *      Assumes caller has lock.
   1080  *      Assumes BCM data has been validated (basic API semantics)
   1081  *
   1082  * Details:
   1083  *     This function is pretty similar as _bcm_apache_port_resource_execute.
   1084  *     But speed set doesn't change logical-physical port mapping.
   1085  *     So this function should skip detach, attach function calls.
   1086  *       _bcm_apache_port_resource_detach
   1087  *       _bcm_apache_port_resource_attach
   1088  *     Also this calls soc_apache_port_resource_configure with
   1089  *     the flag:SOC_PORT_RESOURCE_CONFIGURE_SPEED_SET to make slightly
   1090  *     different sequence from full flex operation.
   1091  */
   1092 STATIC int
   1093 _bcm_apache_port_resource_speed_execute(int unit,
   1094                                   int nport, bcm_apache_port_resource_t *resource)
   1095 {
   1096     int rv;
   1097     int i;
   1098     soc_port_resource_t *soc_resource;
   1099 
   1100     soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport,
   1101                              "port_resource");
   1102     if (soc_resource == NULL) {
   1103         LOG_ERROR(BSL_LS_BCM_PORT,
   1104                   (BSL_META_U(unit,
   1105                               "Unable to allocate memory for SOC FlexPort "
   1106                               "array\n")));
   1107         return BCM_E_MEMORY;
   1108     }
   1109 
   1110     /* Clear data structure */
   1111     sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport);
   1112 
   1113     /* Copy initial information */
   1114     for (i = 0; i < nport; i++) {
   1115         soc_resource[i].flags = resource[i].flags;
   1116         soc_resource[i].logical_port = resource[i].port;
   1117         soc_resource[i].physical_port = resource[i].physical_port;
   1118         soc_resource[i].speed = resource[i].speed;
   1119         soc_resource[i].num_lanes = resource[i].lanes;
   1120         soc_resource[i].encap = resource[i].encap;
   1121         /* Use CL91 settings in case it is already enabled on the port */
   1122         rv = bcmi_esw_portctrl_phy_control_get(unit, resource[i].port,
   1123                                                BCM_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91,
   1124                                                &(soc_resource[i].cl91_enabled));
   1125         if (BCM_FAILURE(rv)) {
   1126             /* All PHYs don't support CL91 */
   1127             soc_resource[i].cl91_enabled = 0;
   1128         }
   1129     }
   1130 
   1131     rv = soc_ap_port_resource_validate(unit, nport, soc_resource);
   1132     if (SOC_FAILURE(rv)) {
   1133         sal_free(soc_resource);
   1134         return rv;
   1135     }
   1136 
   1137     /* SOC Port Resource Configure */
   1138     rv = soc_ap_port_resource_configure(unit, nport, soc_resource,
   1139                         SOC_PORT_RESOURCE_CONFIGURE_SPEED_ONLY);
   1140 
   1141     if (BCM_FAILURE(rv)) {
   1142         LOG_ERROR(BSL_LS_BCM_PORT,
   1143                   (BSL_META_U(unit,
   1144                               "Changes to device may have been partially "
   1145                               "executed.  System may be unstable.\n")));
   1146     }
   1147 
   1148     sal_free(soc_resource);
   1149 
   1150     return rv;
   1151 }
   1152 
   1153 /*
   1154  * Function:
   1155  *      _bcm_apache_port_resource_execute
   1156  * Purpose:
   1157  *      Perform a FlexPort operation.
   1158  *      This includes changes that involve:
   1159  *      - Logical to physical port mapping
   1160  *      - Speed
   1161  *      - Number of PHY lanes
   1162  *
   1163  * Parameters:
   1164  *      unit     - (IN) Unit number.
   1165  *      nport    - (IN) Number of elements in array resource.
   1166  *      resource - (IN) Port resource configuration array.
   1167  * Returns:
   1168  *      BCM_E_XXX
   1169  * Note:
   1170  *      Assumes caller has lock.
   1171  *      Assumes BCM data has been validated (basic API semantics)
   1172  *
   1173  * Details:
   1174  *
   1175  * Port Mapping
   1176  * ------------
   1177  * A logical to physical port mapping is given as part of the port resource
   1178  * array.  This can lead to the following operations:
   1179  * - Port Mapping Delete (or clear)
   1180  *   This is indicated when the physical port is set to (-1) and
   1181  *   the port to be flexed is considered an 'old' port.
   1182  *   The logical port in the array entry must always be valid.
   1183  *   A 'delete' may result in the following actions for a port mapping:
   1184  *      (1) Destroyed
   1185  *      (2) Same
   1186  *      (3) Remapped
   1187  *
   1188  * - Port Mapping Add (or set)
   1189  *   This is indicated when the physical port is set to a valid
   1190  *   physical port number (>=0).
   1191  *   The logical port in the array entry must always be valid.
   1192  *   An 'add' may result in the following actions for a port mapping:
   1193  *      (1) New
   1194  *      (2) Same
   1195  *      (3) Remapped
   1196  *
   1197  * Destroyed: Logical port no longer exist after FlexPort.
   1198  * Remapped:  Logical port will continue to exist after FlexPort
   1199  *            but is mapped to a different physical port.
   1200  * New:       Logical port did not exist before FlexPort.
   1201  * Same:      Logical to physical port mapping remains the same.
   1202  */
   1203 STATIC int
   1204 _bcm_apache_port_resource_execute(int unit, 
   1205                                   int nport, bcm_apache_port_resource_t *resource)
   1206 {
   1207     int rv;
   1208     int i;
   1209     soc_port_resource_t *soc_resource;
   1210 
   1211     /*
   1212      * Main FlexPort Sequence
   1213      *
   1214      * - SOC Validation:
   1215      *     + More validation takes place in the SOC layer.
   1216      *     + These check for abilities and configurations based on
   1217      *       the physical aspects of the device.
   1218      *
   1219      * NOTE: Up to this point, no changes has taken place in SW
   1220      *       data structures or HW.
   1221      *       From this point forward, HW and SW data will be modified,
   1222      *       any errors will leave the system unstabled.
   1223      *
   1224      * - Clear any port related settings in BCM layer as needed.
   1225      *
   1226      * - Detach 'old' ports from BCM layer:
   1227      *     + These are all ports to be cleared/deleted (indicated by physical
   1228      *       port -1), EXCEPT those that will become inactive after the
   1229      *       FlexPort operation (this is only true with legacy API).
   1230      *     + The port state should be the same as the state of a
   1231      *       port that was never configured during SDK initialization.
   1232      *     + This involves SW and HW changes.
   1233      *
   1234      * - SOC Port Resource Configure:
   1235      *     Takes place in the SOC layer.
   1236      *     It consists primarliy of these steps:
   1237      *       + Delete ports in SOC layer (SOC_INFO SW, HW update).
   1238      *       + Add ports in SOC layer (SOC_INFO SW, HW update).
   1239      *       + Execute FlexPort operation as defined by HW specs.
   1240      *
   1241      * - Attach 'new' ports to BCM layer:
   1242      *     + These are all ports that are active after the FlexPort operation.
   1243      *     + Ports are initialized to a default state
   1244      *       (same state when a port is brought up after SDK is initialized).
   1245      *     + This involves SW and HW changes.
   1246      *
   1247      * - Set BCM properties on flexed ports as needed.
   1248      */
   1249 
   1250     /*
   1251      * SOC Port Structure initialization
   1252      */
   1253     /* Allocate memory for SOC Port Resource array data structure */
   1254     soc_resource = sal_alloc(sizeof(soc_port_resource_t) * nport,
   1255                              "port_resource");
   1256     if (soc_resource == NULL) {
   1257         LOG_ERROR(BSL_LS_BCM_PORT,
   1258                   (BSL_META_U(unit,
   1259                               "Unable to allocate memory for SOC FlexPort "
   1260                               "array\n")));
   1261         return BCM_E_MEMORY;
   1262     }
   1263 
   1264     /* Clear data structure */
   1265     sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport);
   1266 
   1267     /* Copy initial information */
   1268     for (i = 0; i < nport; i++) {
   1269         soc_resource[i].flags = resource[i].flags;
   1270         soc_resource[i].logical_port = resource[i].port;
   1271         soc_resource[i].physical_port = resource[i].physical_port;
   1272         soc_resource[i].speed = resource[i].speed;
   1273         soc_resource[i].num_lanes = resource[i].lanes;
   1274         soc_resource[i].encap = resource[i].encap;
   1275         /* In case full flexport sequence is required assume cl91 is disabled.
   1276          * If user wants to enable CL91 on new ports, it is expected that call to
   1277          * bcmi_esw_portctrl_phy_control_set() will be followed by a speed_set()
   1278          */
   1279         soc_resource[i].cl91_enabled = 0;
   1280     }
   1281 
   1282     /* SOC Validation */
   1283     rv = soc_ap_port_resource_validate(unit, nport, soc_resource);
   1284     if (SOC_FAILURE(rv)) {
   1285         sal_free(soc_resource);
   1286         return rv;
   1287     }
   1288 
   1289     /* Detach ports from BCM layer */
   1290     rv = _bcm_apache_port_resource_detach(unit, nport, resource);
   1291 
   1292     /* SOC Port Resource Configure */
   1293     if (BCM_SUCCESS(rv)) {
   1294         rv = soc_ap_port_resource_configure(unit, nport, soc_resource,
   1295                        SOC_PORT_RESOURCE_CONFIGURE_FLEX);
   1296     }
   1297 
   1298     /* Attach ports to BCM layer */
   1299     if (BCM_SUCCESS(rv)) {
   1300         rv = _bcm_apache_port_resource_attach(unit, nport, resource);
   1301     }
   1302 
   1303     if (BCM_FAILURE(rv)) {
   1304         LOG_ERROR(BSL_LS_BCM_PORT,
   1305                   (BSL_META_U(unit,
   1306                               "Changes to device may have been partially "
   1307                               "executed.  System may be unstable.\n")));
   1308     }
   1309 
   1310     sal_free(soc_resource);
   1311 
   1312     return rv;
   1313 }
   1314 
   1315 
   1316 /*
   1317  * Function:
   1318  *      _bcm_apache_port_resource_configure
   1319  * Purpose:
   1320  *      Modify the following port resources:
   1321  *      - Logical to physical port mapping
   1322  *      - Speed
   1323  *      - Number of PHY lanes
   1324  *      - Encapsulation mode
   1325  * Parameters:
   1326  *      unit     - (IN) Unit number.
   1327  *      nport    - (IN) Number of elements in array resource.
   1328  *      resource - (IN/OUT) Port resource configuration array.
   1329  * Returns:
   1330  *      BCM_E_XXX
   1331  * Note:
   1332  *      - Assumes caller has lock.
   1333  *      - The data is modified by the function.
   1334  *      - It takes the internal bcm_apache_port_resource_t data type.
   1335  */
   1336 STATIC int
   1337 _bcm_apache_port_resource_configure(int unit, 
   1338                                     int nport,
   1339                                     bcm_apache_port_resource_t *resource)
   1340 {
   1341     int op;
   1342     int i;
   1343 
   1344     /* Convert port format and validate logical and physical port numbers */
   1345     BCM_IF_ERROR_RETURN
   1346         (_bcm_apache_port_resource_resolve(unit,
   1347                                          nport, resource));
   1348 
   1349     /* Get port mapping change */
   1350     BCM_IF_ERROR_RETURN
   1351         (_bcm_apache_port_resource_pmap_get(unit, nport, resource));
   1352 
   1353     /* clear loopback */
   1354     BCM_IF_ERROR_RETURN
   1355         (_bcm_apache_port_resource_loopback_clear(unit, nport, resource));
   1356 
   1357     /*
   1358      * Validate function input requirements
   1359      *
   1360      * This steps checks for function semantics and guidelines
   1361      * from the API perspective.
   1362      */
   1363     BCM_IF_ERROR_RETURN
   1364         (_bcm_apache_port_resource_input_validate(unit, nport, resource));
   1365 
   1366     /*
   1367      * FlexPort operations types:
   1368      *     NONE                             => Nothing to do
   1369      *     PMAP or LANES                    => FlexPort sequence
   1370      *     ENCAP                            => Encap set
   1371      *     SPEED, but not PMAP or LANES     => Speed set
   1372      */
   1373     BCM_IF_ERROR_RETURN
   1374         (_bcm_apache_port_resource_op_get(unit, nport, resource, &op));
   1375 
   1376 
   1377     LOG_VERBOSE(BSL_LS_BCM_PORT,
   1378                 (BSL_META_U(unit,
   1379                             "FlexPort operations 0x%x: %s %s %s %s\n"),
   1380                  op,
   1381                  (op & BCM_AP_PORT_RESOURCE_OP_PMAP) ? "pmap" : "",
   1382                  (op & BCM_AP_PORT_RESOURCE_OP_SPEED) ? "speed" : "",
   1383                  (op & BCM_AP_PORT_RESOURCE_OP_LANES) ? "lanes" : "",
   1384                  (op & BCM_AP_PORT_RESOURCE_OP_ENCAP) ? "encap" : ""));
   1385 
   1386     if (op == BCM_AP_PORT_RESOURCE_OP_NONE) {
   1387         return BCM_E_NONE;     /* No changes, just return */
   1388     }
   1389 
   1390     /*
   1391      * Port Mapping / Lane
   1392      *
   1393      * These changes always require a FlexPort operation.
   1394      */
   1395     if ((op & BCM_AP_PORT_RESOURCE_OP_PMAP) ||
   1396         (op & BCM_AP_PORT_RESOURCE_OP_LANES)) {
   1397         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1398                     (BSL_META_U(unit,
   1399                                 "--- Execute FlexPort sequence ---\n")));
   1400         BCM_IF_ERROR_RETURN
   1401             (_bcm_apache_port_resource_execute(unit,
   1402                                            nport, resource));
   1403         for (i = 0; i < nport; i++) {
   1404             if (resource[i].physical_port == -1) {
   1405                 continue;
   1406             }
   1407 
   1408             /* Bring new ports down to ensure port state is proper */
   1409             BCM_IF_ERROR_RETURN
   1410                 (bcmi_esw_portctrl_enable_set(unit, resource[i].port, 0));
   1411         }
   1412 
   1413     } else if (op & BCM_AP_PORT_RESOURCE_OP_SPEED) {
   1414         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1415                     (BSL_META_U(unit,
   1416                                 "--- Execute Speed Set sequence ---\n")));
   1417         BCM_IF_ERROR_RETURN
   1418             (_bcm_apache_port_resource_speed_execute(unit,
   1419                                                      nport, resource));
   1420     }
   1421 
   1422     /*
   1423      * Encap
   1424      */
   1425     if (op & BCM_AP_PORT_RESOURCE_OP_ENCAP) {
   1426         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1427                     (BSL_META_U(unit,
   1428                                 "Execute Encap change\n")));
   1429         for (i = 0; i < nport; i++) {
   1430             if (resource[i].physical_port == -1) {
   1431                 continue;
   1432             }
   1433 
   1434             BCM_IF_ERROR_RETURN
   1435                 (bcmi_esw_portctrl_encap_set(unit, resource[i].port,
   1436                                              resource[i].encap, TRUE));
   1437         }
   1438     }
   1439 
   1440     return BCM_E_NONE;
   1441 }
   1442 
   1443 
   1444 /*
   1445  * Function:
   1446  *      _bcm_apache_port_resource_multi_set
   1447  * Purpose:
   1448  *      Modify the following port resources:
   1449  *      - Logical to physical port mapping
   1450  *      - Speed
   1451  *      - Number of PHY lanes
   1452  *      - Encapsulation mode
   1453  * Parameters:
   1454  *      unit     - (IN) Unit number.
   1455  *      nport    - (IN) Number of elements in array resource.
   1456  *      resource - (IN) Port resource configuration array.
   1457  * Returns:
   1458  *      BCM_E_XXX
   1459  * Note:
   1460  *      - Assumes caller has lock.
   1461  *      - This is to be called by the API dispatch driver.
   1462  *      - It takes the public bcm_apache_port_resource_t data type.
   1463  */
   1464 STATIC int
   1465 _bcm_apache_port_resource_multi_set(int unit, 
   1466                                     int nport,
   1467                                     bcm_port_resource_t *resource)
   1468 {
   1469     int rv;
   1470     int i;
   1471     bcm_apache_port_resource_t *port_resource;
   1472 
   1473     if (resource == NULL) {
   1474         return BCM_E_PARAM;
   1475     }
   1476 
   1477     /*
   1478      * Use internal port resource structure type.
   1479      * Called routines will be modifying the data, so
   1480      * having a copy avoids modifying user's data.
   1481      */
   1482     port_resource = sal_alloc(sizeof(bcm_apache_port_resource_t) * nport,
   1483                               "port_resource");
   1484     if (port_resource == NULL) {
   1485         LOG_ERROR(BSL_LS_BCM_PORT,
   1486                   (BSL_META_U(unit,
   1487                               "Unable to allocate memory for internal "
   1488                               "FlexPort array\n")));
   1489         return BCM_E_MEMORY;
   1490     }
   1491 
   1492     /* Clear data structure */
   1493     sal_memset(port_resource, 0, sizeof(bcm_apache_port_resource_t) * nport);
   1494 
   1495     /* Copy initial information */
   1496     for (i = 0; i < nport; i++) {
   1497         /*
   1498          * Translate from public to internal flags.
   1499          */
   1500         if (resource[i].flags & BCM_PORT_RESOURCE_SPEED_ONLY) {
   1501             port_resource[i].flags = SOC_PORT_RESOURCE_SPEED;
   1502         }
   1503         port_resource[i].port = resource[i].port;
   1504         port_resource[i].physical_port = resource[i].physical_port;
   1505         port_resource[i].speed = resource[i].speed;
   1506         port_resource[i].lanes = resource[i].lanes;
   1507         port_resource[i].encap = resource[i].encap;
   1508     }
   1509 
   1510     rv = _bcm_apache_port_resource_configure(unit, nport, port_resource);
   1511     if (BCM_FAILURE(rv)) {
   1512         sal_free(port_resource);
   1513         return rv;
   1514     }
   1515 
   1516     for (i = 0; i < nport; i++) {
   1517         if ((port_resource[i].physical_port == -1) ||
   1518             !(port_resource[i].flags & SOC_PORT_RESOURCE_SPEED)) {
   1519             continue;
   1520         }
   1521 
   1522         /* Need to follow remaining speed_set() sequence.
   1523          * Will not lead to another flexport operation since
   1524          * speed change is already done and soc structures have been updated above
   1525          */
   1526         rv = bcmi_esw_portctrl_speed_set(unit, resource[i].port, resource[i].speed);
   1527         if (BCM_FAILURE(rv)) {
   1528             sal_free(port_resource);
   1529             return rv;
   1530         }
   1531     }
   1532 
   1533     sal_free(port_resource);
   1534 
   1535     return rv;
   1536 }
   1537 
   1538 /*
   1539  * Function:
   1540  *      _bcm_apache_port_resource_speed_set
   1541  * Purpose:
   1542  *      Changes the speed but keeps the same number of lanes
   1543  * Parameters:
   1544  *      unit     - (IN) Unit number
   1545  *      port     - (IN) Logical port number(bcm_port_t, not bcm_gport_t)
   1546  *      speed    - (IN) Port speed
   1547  * Returns:
   1548  *      BCM_E_XXX
   1549  * Note:
   1550  *      - Assumes caller has lock.
   1551  *      - This is to be called by the bcmi_esw_portctrl_speed_set().
   1552  */
   1553 STATIC int
   1554 _bcm_apache_port_resource_speed_set(int unit, bcm_port_t port, int speed)
   1555 {
   1556     soc_info_t *si = &SOC_INFO(unit);
   1557     bcm_apache_port_resource_t resource[2]; /* resource for pre and post */
   1558     int cur_encap;
   1559     int phy_port;
   1560 
   1561     /* si->port_speed_max is the current speed at which MMU/TDM is configured */
   1562     if ((si->port_speed_max[port] == speed) || (speed == 0)) {
   1563         LOG_VERBOSE(BSL_LS_BCM_PORT,
   1564                     (BSL_META_U(unit,
   1565                     "Speed is already configured as %d\n"), si->port_speed_max[port]));
   1566         return BCM_E_NONE;
   1567     }
   1568 
   1569     /* Get current port encap */
   1570     BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &cur_encap));
   1571 
   1572     /*
   1573      * Clear mapping for physical ports involved in FlexPort operation.
   1574      */
   1575     phy_port = si->port_l2p_mapping[port];
   1576     /* Check valid physical port */
   1577     if (phy_port == -1) {
   1578         LOG_ERROR(BSL_LS_BCM_PORT,
   1579                   (BSL_META_U(unit,
   1580                               "Invalid physical port "
   1581                               "for logical port %d\n"),
   1582                    port));
   1583         return BCM_E_INTERNAL;
   1584     }
   1585 
   1586     resource[0].flags = SOC_PORT_RESOURCE_SPEED;
   1587     resource[0].port = port;
   1588     resource[0].physical_port = -1;
   1589 
   1590     resource[1].flags = SOC_PORT_RESOURCE_SPEED;
   1591     resource[1].port = port;
   1592     resource[1].physical_port = phy_port;
   1593     resource[1].speed = speed;
   1594     resource[1].lanes = si->port_num_lanes[port];
   1595     resource[1].encap = cur_encap;
   1596 
   1597     BCM_IF_ERROR_RETURN(_bcm_apache_port_resource_configure(unit, 2, resource));
   1598 
   1599     return BCM_E_NONE;
   1600 }
   1601 
   1602 /*
   1603  * Function:
   1604  *      bcmi_apache_port_lanes_get
   1605  * Purpose:
   1606  *      Get the number of PHY lanes for the given port.
   1607  * Parameters:
   1608  *      unit     - (IN) Unit number.
   1609  *      port     - (IN) Logical port.
   1610  *      lanes    - (OUT) Returns number of lanes for port.
   1611  * Returns:
   1612  *      BCM_E_XXX
   1613  */
   1614 int
   1615 bcmi_apache_port_lanes_get(int unit, bcm_port_t port, int *lanes)
   1616 {
   1617     bcm_port_resource_t resource;
   1618 
   1619     BCM_IF_ERROR_RETURN(bcm_esw_port_resource_get(unit, port, &resource));
   1620 
   1621     *lanes = resource.lanes;
   1622 
   1623     return BCM_E_NONE;
   1624 }
   1625 
   1626 /*
   1627  * Function:
   1628  *      bcmi_apache_port_lanes_set
   1629  * Purpose:
   1630  *      Set the number of PHY lanes for the given port.
   1631  *
   1632  *      This function should only be used to support the legacy
   1633  *      FlexPort API bcm_port_control_set(... , bcmPortControlLanes).
   1634  *
   1635  *      The legacy API does not delete the port mappings when flexing
   1636  *      to fewer lanes.  Ports which lanes are used by the base
   1637  *      physical port becomes inactive.
   1638  *
   1639  * Parameters:
   1640  *      unit     - (IN) Unit number.
   1641  *      port     - (IN) Logical port.
   1642  *      lanes    - (IN) Number of lanes to set on given port.
   1643  * Returns:
   1644  *      BCM_E_XXX
   1645  * Notes:
   1646  *      - Only to be used by legacy API to support TD2 behavior
   1647  *        bcm_port_control_set(... , bcmPortControlLanes).
   1648  *      - Supports only up to 4 lanes (TSC-4).
   1649  *      - 'port' must be in BCM port format (non-GPORT) and mapped to
   1650  *        the base physical port.
   1651  *      - Several calls to legacy API may be required to
   1652  *        achieve desired configuration.
   1653  */
   1654 int
   1655 bcmi_apache_port_lanes_set(int unit, bcm_port_t port, int lanes)
   1656 {
   1657     soc_info_t *si = &SOC_INFO(unit);
   1658     bcm_apache_port_resource_t resource[8];  /* Max size to support up to 4 lanes */
   1659     int max_array_cnt;
   1660     int i;
   1661     int cur_lanes;
   1662     int cur_speed;
   1663     int cur_encap = 0;
   1664     int phy_port;
   1665     int speed;
   1666     int num_ports_clear;
   1667     int num_ports_new;
   1668 
   1669     /* Support legacy API up to 4 lanes */
   1670     if ((lanes != 1) && (lanes != 2) && (lanes != 4)) {
   1671         return BCM_E_PARAM;
   1672     }
   1673 
   1674     /* Check current number of lanes */
   1675     cur_lanes = si->port_num_lanes[port];
   1676     if (cur_lanes == lanes) {
   1677         return BCM_E_NONE;
   1678     }
   1679 
   1680     /* Check that port can support number of lanes specified */
   1681     SOC_IF_ERROR_RETURN(soc_ap_port_lanes_valid(unit, port, lanes));
   1682 
   1683     /* Get current port speed */
   1684     BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &cur_speed));
   1685 
   1686     /* Get current port encap */
   1687     BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &cur_encap));
   1688 
   1689     /* Clear array */
   1690     max_array_cnt = COUNTOF(resource);
   1691     sal_memset(resource, 0, sizeof(resource));
   1692 
   1693     /*
   1694      * Build port resource array
   1695      * Certain information is derived from 'best' guess,
   1696      * similar to the legacy behaviour.
   1697      */
   1698 
   1699     /*
   1700      * Select speed based on number of lanes
   1701      *
   1702      * For HG, if the current HG speed is the higher speed
   1703      * (i.e. 42 vs 40) select the higher HG speed for the number of lanes.
   1704      * Example
   1705      *    1xHG[42] --> 4xHG[11]
   1706      *    1xHG[40] --> 4xHG[10]
   1707      *
   1708      * Notes:  Assumes encap is HIGIG2 if it is not IEEE
   1709      */
   1710     switch(lanes) {
   1711     case 1:
   1712         if (cur_encap == BCM_PORT_ENCAP_IEEE) {    /* IEEE */
   1713             speed = PORT_IS_PM4x25_PORT(unit, port) ? 25000: 10000;
   1714         } else {                                   /* HG2  */
   1715             speed = PORT_IS_PM4x25_PORT(unit, port) ? 27000: 11000;
   1716         }
   1717         break;
   1718     case 2:
   1719         if (cur_encap == BCM_PORT_ENCAP_IEEE) {    /* IEEE */
   1720             speed = PORT_IS_PM4x25_PORT(unit, port) ? 50000: 20000;
   1721         } else {                                   /* HG2  */
   1722             speed = PORT_IS_PM4x25_PORT(unit, port) ? 53000: 21000;
   1723         }
   1724 
   1725         break;
   1726     case 4:
   1727         if (cur_encap == BCM_PORT_ENCAP_IEEE) {    /* IEEE */
   1728             speed = PORT_IS_PM4x25_PORT(unit, port) ? 100000: 40000;
   1729         } else {                                   /* HG2  */
   1730             speed = PORT_IS_PM4x25_PORT(unit, port) ? 106000: 42000;
   1731         }
   1732         break;
   1733     /*
   1734      * COVERITY
   1735      *
   1736      * Case for default is intentional as a defensive check.
   1737      */
   1738     /* coverity[dead_error_begin] */
   1739 
   1740     default:
   1741         return BCM_E_PARAM;
   1742         break;
   1743     }
   1744 
   1745     switch (cur_lanes) {
   1746     case 1:
   1747         /*
   1748          * 2x10 flex to: 2 lanes -> 1x20
   1749          * 4x10 flex to: 4 lanes -> 1x40
   1750          */
   1751         if (lanes == 2) {
   1752             num_ports_clear = 2;
   1753             num_ports_new = 1;
   1754         } else {
   1755             num_ports_clear = 4;
   1756             num_ports_new = 1;
   1757         }
   1758         break;
   1759     case 2:
   1760         /*
   1761          * 1x20 flex to: 1 lane  -> 2x10
   1762          * 2x20 flex to: 4 lanes -> 1x40
   1763          */
   1764         if (lanes == 1) {
   1765             num_ports_clear = 2;
   1766             num_ports_new = 2;
   1767         } else {
   1768             num_ports_clear = 4;
   1769             num_ports_new = 1;
   1770         }
   1771         break;
   1772     case 4:
   1773         /*
   1774          * 1x40 flex to: 1 lane  -> 4x10
   1775          *               2 lanes -> 2x20
   1776          */
   1777         if (lanes == 1) {
   1778             num_ports_clear = 4;
   1779             num_ports_new = 4;
   1780         } else {
   1781             num_ports_clear = 4;
   1782             num_ports_new = 2;
   1783         }
   1784         break;
   1785     default:
   1786         return BCM_E_CONFIG;
   1787         break;
   1788     }
   1789 
   1790     if ((num_ports_clear + num_ports_new) > max_array_cnt) {
   1791         LOG_ERROR(BSL_LS_BCM_PORT,
   1792                   (BSL_META_U(unit,
   1793                               "Invalid array FlexPort calculation "
   1794                               "num_ports_clear=%d num_ports_new=%d "
   1795                               "max_array=%d\n"),
   1796                    num_ports_clear, num_ports_new, max_array_cnt));
   1797         return BCM_E_INTERNAL;
   1798     }
   1799 
   1800     /*
   1801      * Clear mapping for physical ports involved in FlexPort operation.
   1802      * Assume physical ports are numbered consecutively in device.
   1803      */
   1804     phy_port = si->port_l2p_mapping[port];
   1805     for (i = 0; i < num_ports_clear; i++) {
   1806         resource[i].flags = SOC_PORT_RESOURCE_I_MAP;
   1807         resource[i].port = si->port_p2l_mapping[phy_port++];
   1808         resource[i].physical_port = -1;
   1809     }
   1810 
   1811 
   1812     /*
   1813      * Map new ports
   1814      *
   1815      * Legacy API requires that logical-physical port mapping
   1816      * is valid in the SOC_INFO SW data.
   1817      */
   1818     phy_port = si->port_l2p_mapping[port];
   1819     for (; i < (num_ports_clear + num_ports_new); i++) {
   1820         /* Check valid physical port */
   1821         if (phy_port == -1) {
   1822             LOG_ERROR(BSL_LS_BCM_PORT,
   1823                       (BSL_META_U(unit,
   1824                                   "Invalid physical port "
   1825                                   "for logical port %d\n"),
   1826                        port));
   1827             return BCM_E_INTERNAL;
   1828         }
   1829 
   1830         resource[i].flags = SOC_PORT_RESOURCE_I_MAP;
   1831         resource[i].port = si->port_p2l_mapping[phy_port];
   1832         resource[i].physical_port = phy_port;
   1833         resource[i].lanes = lanes;
   1834         resource[i].speed = speed;
   1835         resource[i].encap = cur_encap;
   1836         phy_port += lanes;
   1837     }
   1838 
   1839 
   1840     BCM_IF_ERROR_RETURN
   1841         (_bcm_apache_port_resource_configure(unit,
   1842                                              (num_ports_clear + num_ports_new),
   1843                                              resource));
   1844 
   1845     return BCM_E_NONE;
   1846 }
   1847 
   1848 /*
   1849  * Function:
   1850  *     _bcm_apache_port_drain_cells
   1851  * Purpose:
   1852  *     To drain cells associated to the port.
   1853  * Parameters:
   1854  *     unit       - (IN) unit number
   1855  *     port       - (IN) Port
   1856  * Returns:
   1857  *     BCM_E_XXX
   1858  */
   1859 STATIC int
   1860 _bcm_apache_port_drain_cells(int unit, int port)
   1861 {
   1862     return bcmi_esw_portctrl_egress_queue_drain(unit, port);
   1863 }
   1864 
   1865 int
   1866 bcm_apache_port_drain_cells(int unit, int port)
   1867 {
   1868     return (_bcm_apache_port_drain_cells(unit, port));
   1869 }
   1870 
   1871 #else /* BCM_APACHE_SUPPORT */
   1872 int bcm_esw_ap_port_not_empty;
   1873 #endif /* BCM_APACHE_SUPPORT */