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

subport.c (39190B)


      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:    subport.c
      8  * Purpose: Manages SUBPORT functions
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <sal/core/libc.h>
     14 
     15 #include <soc/defs.h>
     16 #include <soc/drv.h>
     17 #include <soc/scache.h>
     18 #include <soc/util.h>
     19 
     20 #include <bcm/l2.h>
     21 #include <bcm/port.h>
     22 #include <bcm/error.h>
     23 #include <bcm/subport.h>
     24 #include <bcm/types.h>
     25 #include <bcm_int/esw/subport.h>
     26 #include <bcm_int/esw/mbcm.h>
     27 #include <bcm_int/esw/xgs5.h>
     28 
     29 #if defined(BCM_FIREBOLT_SUPPORT)
     30 #include <bcm_int/esw/firebolt.h>
     31 #endif /* BCM_FIREBOLT_SUPPORT */
     32 #if defined(BCM_TRX_SUPPORT)
     33 #include <bcm_int/esw/triumph.h>
     34 #endif /* BCM_TRX_SUPPORT */
     35 #if defined(BCM_TRIUMPH2_SUPPORT)
     36 #include <bcm_int/esw/triumph2.h>
     37 #endif /* BCM_TRIUMPH2_SUPPORT */
     38 #include <bcm_int/esw_dispatch.h>
     39 #include <bcm_int/esw/xgs3.h>
     40 #if defined(BCM_KATANA2_SUPPORT)
     41 #include <soc/katana2.h>
     42 #include <bcm_int/esw/katana2.h>
     43 #endif /* BCM_KATANA2_SUPPORT */
     44 #if defined(BCM_TRIDENT2PLUS_SUPPORT)
     45 #include <bcm_int/esw/trident2plus.h>
     46 #endif /* BCM_TRIDENT2PLUS_SUPPORT */
     47 #if defined(BCM_APACHE_SUPPORT)
     48 #include <bcm_int/esw/apache.h>
     49 #endif /* BCM_APACHE_SUPPORT */
     50 #if defined(BCM_TRIDENT3_SUPPORT)
     51 #include <bcm_int/esw/trident3.h>
     52 #endif /* BCM_TRIDENT3_SUPPORT */
     53 
     54 
     55 
     56 /*
     57  * Subport Function Vector Driver
     58  */
     59 bcm_esw_subport_drv_t    *bcm_esw_subport_drv[BCM_MAX_NUM_UNITS] = {0};
     60 
     61 /*****************************************
     62 * Subport common section - start
     63  */
     64 
     65 
     66 /* The common data structures between KT2 and TD2+ Subport-CoE implementation */
     67 
     68 /*
     69 * Bitmap of subport group id
     70 * Each Subport group created has unique group id
     71 * across all ports in the device irrespective of
     72 * group type LinkPHY/SubTag
     73 */
     74 
     75 SHR_BITDCL *_bcm_subport_group_bitmap[BCM_MAX_NUM_UNITS] = { 0 };
     76 
     77 /* Count of all subport groups created */
     78 int _bcm_subport_group_count[BCM_MAX_NUM_UNITS] = { 0 };
     79 
     80 /* Count subport port per subport group*/
     81 int *(_bcm_subport_group_subport_port_count[BCM_MAX_NUM_UNITS]) = { 0 };
     82 
     83 sal_mutex_t _bcm_subport_mutex[BCM_MAX_NUM_UNITS] = {NULL};
     84 
     85 /* SubTag subport port array */
     86 _bcm_subtag_subport_port_info_t
     87            *(_bcm_subtag_subport_port_info[BCM_MAX_NUM_UNITS]) = { 0 };
     88 
     89 /*********************************
     90 * Subport common  section - end
     91  */
     92 
     93 /*********************************
     94 * General subport section - start
     95  */
     96 
     97 /* General subport port array */
     98 _bcm_general_subport_port_info_t
     99            *(_bcm_general_subport_port_info[BCM_MAX_NUM_UNITS]) = { 0 };
    100 
    101 /* Bitmap of general subport group id */
    102 SHR_BITDCL *_bcm_general_subport_group_bitmap[BCM_MAX_NUM_UNITS] = { 0 };
    103 
    104 /* Count of all general subport groups created */
    105 int _bcm_general_subport_group_count[BCM_MAX_NUM_UNITS] = { 0 };
    106 
    107 /*********************************
    108 * General subport section - end
    109  */
    110 
    111 /*********************************
    112 * SubTag subport section - start
    113  */
    114 
    115 /* Bitmap of SubTag subport group id */
    116 SHR_BITDCL *_bcm_subtag_group_bitmap[BCM_MAX_NUM_UNITS] = { 0 };
    117 
    118 /* Count of all SubTag subport groups created */
    119 int _bcm_subtag_subport_group_count[BCM_MAX_NUM_UNITS] = { 0 };
    120 
    121 SHR_BITDCL *_bcm_subtag_vlan_id_bitmap
    122                    [BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS] = {{ 0 }};
    123 
    124 /*********************************
    125 * SubTag subport section - end
    126  */
    127 
    128 #ifdef BCM_WARM_BOOT_SUPPORT
    129 #include <bcm_int/esw/switch.h>
    130 
    131 /*
    132  * Function:
    133  *      _bcm_esw_subport_wb_scache_alloc
    134  * Purpose:
    135  *      Allocates scache space for Level 2 Warm Boot
    136  * Parameters:
    137  *      unit - StrataSwitch unit number.
    138  * Returns:
    139  *      BCM_E_XXX
    140  */
    141 STATIC int
    142 _bcm_esw_subport_wb_scache_alloc(int unit)
    143 {
    144     int rv = BCM_E_NONE;
    145     uint8 *scache_ptr;
    146     int stable_size = 0;
    147     int alloc_sz = 0;
    148     soc_scache_handle_t scache_handle;
    149 
    150     BCM_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size));
    151     if ((stable_size == 0) || (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    152         return BCM_E_NONE;
    153     }
    154 
    155 #ifdef BCM_HGPROXY_COE_SUPPORT
    156     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
    157         rv = bcmi_xgs5_subport_wb_scache_alloc(unit,
    158                   BCM_SUBPORT_WB_DEFAULT_VERSION, &alloc_sz);
    159         BCM_IF_ERROR_RETURN(rv);
    160     }
    161 #endif /* BCM_HGPROXY_COE_SUPPORT */
    162 
    163 #ifdef BCM_KATANA2_SUPPORT
    164     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    165         soc_feature(unit, soc_feature_subtag_coe)) {
    166         rv = bcm_kt2_subport_wb_scache_alloc(unit,
    167                  BCM_SUBPORT_WB_DEFAULT_VERSION, &alloc_sz);
    168         BCM_IF_ERROR_RETURN(rv);
    169     }
    170 #endif /* BCM_KATANA2_SUPPORT */
    171 
    172     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUBPORT, 0);
    173     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE,
    174                                  alloc_sz, &scache_ptr,
    175                                  BCM_SUBPORT_WB_DEFAULT_VERSION, NULL);
    176 
    177     return rv;
    178 }
    179 
    180 /*
    181  * Function:
    182  *      _bcm_esw_subport_wb_recover
    183  * Purpose:
    184  *      Recover Subport info
    185  * Parameters:
    186  *      unit - Unit reference
    187  * Returns:
    188  *      BCM_E_XXX
    189  */
    190 STATIC int
    191 _bcm_esw_subport_wb_recover(int unit)
    192 {
    193     int rv;
    194     uint16 ver;
    195     uint8 *scache_ptr = NULL;
    196     soc_scache_handle_t scache_handle;
    197 
    198     /* Level 2 WB support is enabled only for linkphy/subtag-coe/
    199        hgproxy_subtag_coe */
    200     if (!(soc_feature(unit, soc_feature_linkphy_coe) ||
    201           soc_feature(unit, soc_feature_subtag_coe)  ||
    202           soc_feature(unit, soc_feature_hgproxy_subtag_coe))) {
    203         return BCM_E_UNAVAIL;
    204     }
    205 
    206     if ((SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    207         return BCM_E_NONE;
    208     }
    209     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUBPORT, 0);
    210     rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
    211                                 0, &scache_ptr,
    212                                 BCM_SUBPORT_WB_DEFAULT_VERSION, &ver);
    213 
    214     if (rv == BCM_E_NONE) { /* Use Level 2 cache */
    215 
    216 #ifdef BCM_HGPROXY_COE_SUPPORT
    217         if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
    218             return bcmi_xgs5_subport_wb_recover(unit,
    219                       BCM_SUBPORT_WB_DEFAULT_VERSION, &scache_ptr);
    220 		}
    221 #endif /* BCM_HGPROXY_COE_SUPPORT */
    222 #ifdef BCM_KATANA2_SUPPORT
    223         if (soc_feature(unit, soc_feature_linkphy_coe) ||
    224             soc_feature(unit, soc_feature_subtag_coe)) {
    225             rv = bcm_kt2_subport_wb_recover(unit, ver, &scache_ptr);
    226             BCM_IF_ERROR_RETURN(rv);
    227         }
    228 #endif /* BCM_KATANA2_SUPPORT */
    229     } else if (rv == SOC_E_NOT_FOUND) {
    230         /* Use non-Level 2 case for recovery */
    231         /* and Allocate scache space for further syncs */
    232         rv = _bcm_esw_subport_wb_scache_alloc(unit);
    233         BCM_IF_ERROR_RETURN(rv);
    234     } else if (SOC_FAILURE(rv)) {
    235         return rv;
    236     }
    237 
    238     return BCM_E_NONE;
    239 }
    240 
    241 /*
    242  * Function:
    243  *      _bcm_esw_subport_sync
    244  * Purpose:
    245  *      Record rx module persisitent info for Level 2 Warm Boot
    246  * Parameters:
    247  *      unit - StrataSwitch unit number.
    248  * Returns:
    249  *      BCM_E_XXX
    250  */
    251 
    252 int
    253 _bcm_esw_subport_sync(int unit)
    254 {
    255     uint8 *scache_ptr;
    256     soc_scache_handle_t scache_handle;
    257 
    258 	/* Level 2 WB support is enabled only for linkphy/subtag-coe/
    259 	   hgproxy_subtag_coe */
    260     if (!(soc_feature(unit, soc_feature_linkphy_coe) ||
    261           soc_feature(unit, soc_feature_subtag_coe)  ||
    262 	  soc_feature(unit, soc_feature_hgproxy_subtag_coe))) {
    263         return BCM_E_UNAVAIL;
    264     }
    265 
    266     if ((SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit))) {
    267         return BCM_E_NONE;
    268     }
    269     SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_SUBPORT, 0);
    270     BCM_IF_ERROR_RETURN
    271         (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE,
    272                                  0, &scache_ptr,
    273                                  BCM_SUBPORT_WB_DEFAULT_VERSION, NULL));
    274 
    275 #ifdef BCM_HGPROXY_COE_SUPPORT
    276     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) {
    277         return bcmi_xgs5_subport_wb_sync(unit,
    278                   BCM_SUBPORT_WB_DEFAULT_VERSION, &scache_ptr);
    279     }
    280 #endif /* BCM_HGPROXY_COE_SUPPORT */
    281 
    282 #ifdef BCM_KATANA2_SUPPORT
    283     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    284         soc_feature(unit, soc_feature_subtag_coe)) {
    285         return bcm_kt2_subport_wb_sync(unit,
    286                   BCM_SUBPORT_WB_DEFAULT_VERSION, &scache_ptr);
    287     }
    288 #endif /* BCM_KATANA2_SUPPORT */
    289 
    290     return BCM_E_NONE;
    291 }
    292 #endif /* BCM_WARM_BOOT_SUPPORT */
    293 
    294 
    295 /*
    296  * Function:
    297  *      bcm_subport_init
    298  * Purpose:
    299  *      Initialize the SUBPORT software module
    300  * Parameters:
    301  *      unit - Device Number
    302  * Returns:
    303  *      BCM_E_XXX
    304  */
    305 int
    306 bcm_esw_subport_init(int unit)
    307 {
    308 
    309     int rv = BCM_E_NONE, l3_enable = 1, subport_init = 0;
    310 #if defined(BCM_WARM_BOOT_SUPPORT)
    311     int wb_support = 0;
    312 #endif
    313 /* 1. subport is enabled for devices having linkphy_coe/subtag_coe/
    314  *    hgproxy_subtag_coe/subport_enhanced/subport features
    315  * 2. WB is enabled for devices having linkphy_coe/subtag_coe/hgproxy_subtag_coe
    316  *    features
    317  * 3. L3 is needed for subport initialization in devices having
    318  *    hgproxy_subtag_coe/subport_enhanced/subport features
    319  */
    320 #if defined(BCM_KATANA2_SUPPORT)
    321     if (soc_feature(unit, soc_feature_linkphy_coe) ||
    322         soc_feature(unit, soc_feature_subtag_coe)) {
    323         /* Linkphy/Subtag_Coe doesn't need L3 support */
    324         rv = bcm_kt2_subport_init(unit);
    325         subport_init = 1;
    326 #if defined(BCM_WARM_BOOT_SUPPORT)
    327         wb_support = 1;
    328 #endif
    329         if (SOC_FAILURE(rv)) {
    330             return rv;
    331         }
    332     }
    333 #endif /* BCM_KATANA2_SUPPORT */
    334     /* l3_enable is set to FALSE if,
    335      * 1. device won't support L3
    336      * 2. config variable "l3_enable" is set to FALSE
    337      * 3. L3 flag is not included in compilation
    338      */
    339 #if defined(INCLUDE_L3)
    340     if (!soc_feature(unit, soc_feature_l3) ||
    341         !soc_property_get(unit, spn_L3_ENABLE, 1)) {
    342         l3_enable = 0;
    343     }
    344 #else
    345         l3_enable = 0;
    346 #endif
    347 #if defined(BCM_HGPROXY_COE_SUPPORT)
    348     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    349         l3_enable) {
    350 #if defined(BCM_APACHE_SUPPORT)
    351         if (SOC_IS_APACHE(unit)) {
    352             SOC_IF_ERROR_RETURN(bcm_apache_subport_coe_init(unit));
    353         } else
    354 #endif
    355         if (SOC_IS_TRIDENT2PLUS(unit)) {
    356             SOC_IF_ERROR_RETURN(bcm_td2plus_subport_coe_init(unit));
    357         }
    358 #if defined(BCM_TRIDENT3_SUPPORT)
    359         if (SOC_IS_TRIDENT3X(unit)) {
    360             SOC_IF_ERROR_RETURN(bcm_td3_subport_coe_init(unit));
    361         }
    362 #endif
    363         subport_init = 1;
    364 #if defined(BCM_WARM_BOOT_SUPPORT)
    365         wb_support = 1;
    366 #endif
    367     }
    368 #endif /* BCM_HGPROXY_COE_SUPPORT */
    369 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
    370     if (soc_feature(unit, soc_feature_subport_enhanced) &&
    371         l3_enable) {
    372          rv = bcm_tr2_subport_init(unit);
    373          subport_init = 1;
    374     } else
    375 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
    376 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
    377     if (soc_feature(unit, soc_feature_subport) &&
    378         l3_enable) {
    379         rv = bcm_tr_subport_init(unit);
    380         subport_init = 1;
    381     } else
    382 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
    383     {
    384         if (l3_enable && !subport_init) {
    385             rv = BCM_E_UNAVAIL;
    386         }
    387     }
    388 
    389     BCM_IF_ERROR_RETURN(rv);
    390 
    391 #ifdef BCM_WARM_BOOT_SUPPORT
    392     /* Level 2 WB support is enabled only for linkphy/subtag-coe/
    393        hgproxy_subtag_coe */
    394     if (wb_support) {
    395         if (SOC_WARM_BOOT(unit)) {
    396             return (_bcm_esw_subport_wb_recover(unit));
    397         } else {
    398             return (_bcm_esw_subport_wb_scache_alloc(unit));
    399         }
    400     }
    401 #endif /* BCM_WARM_BOOT_SUPPORT */
    402 
    403     return rv;
    404 }
    405 
    406 /*
    407  * Function:
    408  *      bcm_subport_cleanup
    409  * Purpose:
    410  *      Cleanup the SUBPORT software module
    411  * Parameters:
    412  *      unit - Device Number
    413  * Returns:
    414  *      BCM_E_XXX
    415  */
    416 int
    417 bcm_esw_subport_cleanup(int unit)
    418 {
    419     if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    420         if (BCM_ESW_SUBPORT_DRV(unit)->coe_cleanup != NULL) {
    421             BCM_ESW_SUBPORT_DRV(unit)->coe_cleanup(unit);
    422         }
    423 
    424         if (BCM_ESW_SUBPORT_DRV(unit)->subport_cleanup != NULL) {
    425             return BCM_ESW_SUBPORT_DRV(unit)->subport_cleanup(unit);
    426         }
    427     }
    428 
    429     return BCM_E_NONE;
    430 }
    431 
    432 /*
    433  * Function:
    434  *      bcm_subport_group_create
    435  * Purpose:
    436  *      Create a subport group
    437  * Parameters:
    438  *      unit   - (IN) Device Number
    439  *      config - (IN) Subport group config information
    440  *      group  - (OUT) GPORT (generic port) identifier
    441  * Returns:
    442  *      BCM_E_XXX
    443  */
    444 int
    445 bcm_esw_subport_group_create(int unit,
    446                              bcm_subport_group_config_t *config,
    447                              bcm_gport_t *group)
    448 {
    449     if (config == NULL) {
    450         return (BCM_E_PARAM);
    451     }
    452     if (config->flags & BCM_SUBPORT_GROUP_WITH_ID) {
    453         if (group == NULL) {
    454             return (BCM_E_PORT);
    455         }
    456         if (!BCM_GPORT_IS_SUBPORT_GROUP(*group)) {
    457             return (BCM_E_PORT);
    458         }
    459     }
    460 
    461     if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    462         if(config->flags & BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG) {
    463             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_create != NULL) {
    464                 return BCM_ESW_SUBPORT_DRV(unit)->
    465                         coe_group_create(unit, config, group);
    466             }
    467         } else if ((config->flags & BCM_SUBPORT_GROUP_TYPE_LINKPHY) &&
    468                    (soc_feature(unit, soc_feature_linkphy_coe))) {
    469                        if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_create != NULL) {
    470                            return BCM_ESW_SUBPORT_DRV(unit)->
    471                                    coe_group_create(unit, config, group);
    472                        }
    473         } else if ((config->flags & BCM_SUBPORT_GROUP_TYPE_GENERAL) &&
    474                    (soc_feature(unit, soc_feature_general_cascade))) {
    475                 if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_create != NULL) {
    476                     return BCM_ESW_SUBPORT_DRV(unit)->
    477                             coe_group_create(unit, config, group);
    478             }
    479         } else {
    480             if (BCM_ESW_SUBPORT_DRV(unit)->subport_group_create != NULL) {
    481                 return BCM_ESW_SUBPORT_DRV(unit)->
    482                             subport_group_create(unit, config, group);
    483             }
    484         }
    485     }
    486 
    487     return BCM_E_UNAVAIL;
    488 }
    489 
    490 #define _TMP_UINT_BUF_COUNT  16
    491 
    492 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
    493 
    494 STATIC int 
    495 _bcm_esw_subport_port_traverse_cb(int unit, 
    496                                   bcm_gport_t port, 
    497                                   bcm_subport_config_t *config,  
    498                                   void *user_data)
    499 {   
    500 	uint32 *data = (uint32 *)user_data; 
    501     
    502     if (config->group == data[0]) {
    503 	    if (data[1] >= (_TMP_UINT_BUF_COUNT - 2)) {
    504 	    	return BCM_E_NONE;
    505 	    }
    506 	    data[1]++;
    507 	    data[data[1]+1] = port;
    508 	}
    509     
    510     return BCM_E_NONE;
    511 }
    512 
    513 #endif
    514 /*
    515  * Function:
    516  *      bcm_subport_group_destroy
    517  * Purpose:
    518  *      Destroy a subport group
    519  * Parameters:
    520  *      unit  - (IN) Device Number
    521  *      group - (IN) GPORT (generic port) identifier
    522  * Returns:
    523  *      BCM_E_XXX
    524  */
    525 int
    526 bcm_esw_subport_group_destroy(int unit, bcm_gport_t group)
    527 {
    528 #if ((defined(BCM_KATANA2_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) || \
    529      defined BCM_TRX_SUPPORT || defined (BCM_HGPROXY_COE_SUPPORT)) && \
    530          defined(INCLUDE_L3))
    531     uint32 sub_ports[_TMP_UINT_BUF_COUNT];
    532     uint32 i;
    533 #endif
    534     
    535     if (!BCM_GPORT_IS_SUBPORT_GROUP(group)) {
    536         return (BCM_E_PORT);
    537     }
    538     
    539 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3)
    540     if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    541             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group))) {
    542 
    543         while (TRUE) {
    544         	sub_ports[0] = (uint32)group;
    545         	sub_ports[1] = 0;
    546 	        bcmi_xgs5_subport_coe_port_traverse(unit, 
    547 	            _bcm_esw_subport_port_traverse_cb, sub_ports); 
    548 
    549 	        for (i = 0; i < sub_ports[1]; i++) {
    550 	        	bcmi_xgs5_subport_coe_port_delete(unit, 
    551 	        	        (bcm_gport_t)sub_ports[i+2]);
    552 	        }
    553 	        	
    554 	        if (sub_ports[1] != (_TMP_UINT_BUF_COUNT - 2)) {
    555 	        	break;
    556 	        } 	
    557         } 
    558         if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    559             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_destroy != NULL) {
    560                 return BCM_ESW_SUBPORT_DRV(unit)->
    561                             coe_group_destroy(unit, group);
    562             }
    563         }
    564     }
    565 #endif /* #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3) */
    566 
    567 #if defined(BCM_KATANA2_SUPPORT) && defined(INCLUDE_L3)
    568     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
    569             _BCM_COE_GPORT_IS_LINKPHY_SUBPORT_GROUP(group)) ||
    570         (soc_feature(unit, soc_feature_subtag_coe) &&
    571             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) ||
    572         (soc_feature(unit, soc_feature_general_cascade) &&
    573             _BCM_COE_GPORT_IS_GENERAL_SUBPORT_GROUP(group))) {
    574 
    575         while (TRUE) {
    576         	sub_ports[0] = (uint32)group;
    577         	sub_ports[1] = 0;
    578 	        bcm_kt2_subport_port_traverse(unit, 
    579 	            _bcm_esw_subport_port_traverse_cb, sub_ports); 
    580 
    581 	        for (i = 0; i < sub_ports[1]; i++) {
    582 	        	bcm_kt2_subport_port_delete(unit, 
    583 	        	        (bcm_gport_t)sub_ports[i+2]);
    584 	        }
    585 	        	
    586 	        if (sub_ports[1] != (_TMP_UINT_BUF_COUNT - 2)) {
    587 	        	break;
    588 	        } 	
    589         } 
    590         if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    591             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_destroy != NULL) {
    592                 return BCM_ESW_SUBPORT_DRV(unit)->
    593                             coe_group_destroy(unit, group);
    594             }
    595         }
    596     }
    597 #endif /* BCM_KATANA2_SUPPORT */
    598 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3)
    599     if (soc_feature(unit, soc_feature_subport_enhanced)) {
    600     	while (TRUE) {
    601         	sub_ports[0] = (uint32)group;
    602         	sub_ports[1] = 0;
    603 	        bcm_tr2_subport_port_traverse(unit, 
    604 	            _bcm_esw_subport_port_traverse_cb, sub_ports); 
    605 
    606 	        for (i = 0; i < sub_ports[1]; i++) {
    607 	        	bcm_tr2_subport_port_delete(unit, 
    608 	        	        (bcm_gport_t)sub_ports[i+2]);
    609 	        }
    610 	        	
    611 	        if (sub_ports[1] != (_TMP_UINT_BUF_COUNT - 2)) {
    612 	        	break;
    613 	        } 	
    614         }
    615            
    616         if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    617             if (BCM_ESW_SUBPORT_DRV(unit)->subport_group_destroy != NULL) {
    618                 return BCM_ESW_SUBPORT_DRV(unit)->
    619                             subport_group_destroy(unit, group);
    620             }
    621         }
    622     }
    623 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */
    624 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3)
    625     if (soc_feature(unit, soc_feature_subport)) {
    626     	while (TRUE) {
    627         	sub_ports[0] = (uint32)group;
    628         	sub_ports[1] = 0;
    629 	        bcm_tr_subport_port_traverse(unit, 
    630 	            _bcm_esw_subport_port_traverse_cb, sub_ports); 
    631 
    632 	        for (i = 0; i < sub_ports[1]; i++) {
    633 	        	bcm_tr_subport_port_delete(unit, 
    634 	        	        (bcm_gport_t)sub_ports[i+2]);
    635 	        }
    636 	        	
    637 	        if (sub_ports[1] != (_TMP_UINT_BUF_COUNT - 2)) {
    638 	        	break;
    639 	        } 	
    640         }
    641          
    642         if (BCM_ESW_SUBPORT_DRV(unit) != NULL ) {
    643             if (BCM_ESW_SUBPORT_DRV(unit)->subport_group_destroy != NULL) {
    644                 return BCM_ESW_SUBPORT_DRV(unit)->
    645                             subport_group_destroy(unit, group);
    646             }
    647         }
    648     }
    649 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */
    650     return BCM_E_UNAVAIL;
    651 }
    652 
    653 /*
    654  * Function:
    655  *      bcm_subport_group_get
    656  * Purpose:
    657  *      Get a subport group
    658  * Parameters:
    659  *      unit   - (IN) Device Number
    660  *      group  - (IN) GPORT (generic port) identifier
    661  *      config - (OUT) Subport group config information
    662  * Returns:
    663  *      BCM_E_XXX
    664  */
    665 int
    666 bcm_esw_subport_group_get(int unit, bcm_gport_t group,
    667                           bcm_subport_group_config_t *config)
    668 {
    669     if (!BCM_GPORT_IS_SUBPORT_GROUP(group)) {
    670         return (BCM_E_PORT);
    671     }
    672 
    673     if((soc_feature(unit, soc_feature_subtag_coe) ||
    674          soc_feature(unit, soc_feature_hgproxy_subtag_coe)) &&
    675             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) {
    676         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    677             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_get != NULL) {
    678                 return BCM_ESW_SUBPORT_DRV(unit)->
    679                         coe_group_get(unit, group, config);
    680             }
    681         }
    682     } else if ((soc_feature_linkphy_coe) && 
    683                _BCM_COE_GPORT_IS_LINKPHY_SUBPORT_GROUP(group)){
    684         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    685             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_get != NULL) {
    686                 return BCM_ESW_SUBPORT_DRV(unit)->
    687                         coe_group_get(unit, group, config);
    688             }
    689         }
    690     } else if (soc_feature(unit, soc_feature_general_cascade) &&
    691             _BCM_COE_GPORT_IS_GENERAL_SUBPORT_GROUP(group)) {
    692         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    693             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_get != NULL) {
    694                 return BCM_ESW_SUBPORT_DRV(unit)->
    695                     coe_group_get(unit, group, config);
    696             }
    697         }
    698     } else {
    699         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    700             if (BCM_ESW_SUBPORT_DRV(unit)->subport_group_get != NULL) {
    701                 return BCM_ESW_SUBPORT_DRV(unit)->
    702                             subport_group_get(unit, group, config);
    703             }
    704         }
    705     }
    706 
    707     return BCM_E_UNAVAIL;
    708 }
    709 
    710 /*
    711  * Function:
    712  *      bcm_subport_port_add
    713  * Purpose:
    714  *      Add a subport to a subport group
    715  * Parameters:
    716  *      unit   - (IN) Device Number
    717  *      config - (IN) Subport config information
    718  *      port   - (OUT) GPORT (generic port) identifier
    719  * Returns:
    720  *      BCM_E_XXX
    721  */
    722 int
    723 bcm_esw_subport_port_add(int unit, bcm_subport_config_t *config,
    724                          bcm_gport_t *port)
    725 {
    726     if(_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(config->group)) {
    727         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    728             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_add != NULL) {
    729                 return BCM_ESW_SUBPORT_DRV(unit)->
    730                         coe_port_add(unit, config, port);
    731             }
    732         }
    733     } else if ((_BCM_COE_GPORT_IS_LINKPHY_SUBPORT_GROUP(config->group)) &&
    734                (soc_feature(unit, soc_feature_linkphy_coe))){
    735         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    736             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_add != NULL) {
    737                 return BCM_ESW_SUBPORT_DRV(unit)->
    738                         coe_port_add(unit, config, port);
    739             }
    740         }
    741     } else if ((_BCM_COE_GPORT_IS_GENERAL_SUBPORT_GROUP(config->group)) &&
    742               soc_feature(unit, soc_feature_general_cascade)) {
    743         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    744             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_add != NULL) {
    745                 return BCM_ESW_SUBPORT_DRV(unit)->
    746                         coe_port_add(unit, config, port);
    747             }
    748         }
    749     } else {
    750         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    751             if (BCM_ESW_SUBPORT_DRV(unit)->subport_port_add != NULL) {
    752                 return BCM_ESW_SUBPORT_DRV(unit)->
    753                             subport_port_add(unit, config, port);
    754             }
    755         }
    756     }
    757 
    758     return BCM_E_UNAVAIL;
    759 }
    760 
    761 /*
    762  * Function:
    763  *      bcm_subport_port_delete
    764  * Purpose:
    765  *      Delete a subport 
    766  * Parameters:
    767  *      unit   - (IN) Device Number
    768  *      port   - (IN) GPORT (generic port) identifier
    769  * Returns:
    770  *      BCM_E_XXX
    771  */
    772 int
    773 bcm_esw_subport_port_delete(int unit, bcm_gport_t port)
    774 {
    775     if (!BCM_GPORT_IS_SUBPORT_PORT(port)) {
    776         return (BCM_E_PORT);
    777     }
    778 
    779 #if defined(BCM_HGPROXY_COE_SUPPORT)
    780     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    781         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
    782         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    783             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_delete != NULL) {
    784                 return BCM_ESW_SUBPORT_DRV(unit)->
    785                             coe_port_delete(unit, port);
    786             }
    787         }
    788     }
    789 #endif /* BCM_HGPROXY_COE_SUPPORT */
    790 
    791 #if defined(BCM_KATANA2_SUPPORT)
    792     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
    793             _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) ||
    794         (soc_feature(unit, soc_feature_subtag_coe) &&
    795             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
    796         (soc_feature(unit, soc_feature_general_cascade) &&
    797             _BCM_KT2_GPORT_IS_GENERAL_SUBPORT_PORT(unit, port))) {
    798         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    799             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_delete != NULL) {
    800                 return BCM_ESW_SUBPORT_DRV(unit)->
    801                             coe_port_delete(unit, port);
    802             }
    803         }
    804     }
    805 #endif /* BCM_KATANA2_SUPPORT */
    806 
    807     if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    808         if (BCM_ESW_SUBPORT_DRV(unit)->subport_port_delete != NULL) {
    809             return BCM_ESW_SUBPORT_DRV(unit)->
    810                         subport_port_delete(unit, port);
    811         }
    812     }
    813 
    814     return BCM_E_UNAVAIL;
    815 }
    816 
    817 /*
    818  * Function:
    819  *      bcm_subport_port_get
    820  * Purpose:
    821  *      Get a subport
    822  * Parameters:
    823  *      unit   - (IN) Device Number
    824  *      port   - (IN) GPORT (generic port) identifier
    825  *      config - (OUT) Subport config information
    826  * Returns:
    827  *      BCM_E_XXX
    828  */
    829 int
    830 bcm_esw_subport_port_get(int unit, bcm_gport_t port,
    831                          bcm_subport_config_t *config)
    832 {
    833 
    834 #if defined(BCM_HGPROXY_COE_SUPPORT)
    835     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    836         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) {
    837         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    838             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_get != NULL) {
    839                 return BCM_ESW_SUBPORT_DRV(unit)->
    840                             coe_port_get(unit, port, config);
    841             }
    842         }
    843     }
    844 #endif /* BCM_HGPROXY_COE_SUPPORT */
    845 
    846 #if defined(BCM_KATANA2_SUPPORT)
    847     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
    848             _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) ||
    849         (soc_feature(unit, soc_feature_subtag_coe) &&
    850             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) ||
    851         (soc_feature(unit, soc_feature_general_cascade) &&
    852             _BCM_KT2_GPORT_IS_GENERAL_SUBPORT_PORT(unit, port))) {
    853         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    854             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_get != NULL) {
    855                 return BCM_ESW_SUBPORT_DRV(unit)->
    856                             coe_port_get(unit, port, config);
    857             }
    858         }
    859     }
    860 #endif /* BCM_KATANA2_SUPPORT */
    861 
    862     if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    863         if (BCM_ESW_SUBPORT_DRV(unit)->subport_port_get != NULL) {
    864             return BCM_ESW_SUBPORT_DRV(unit)->
    865                         subport_port_get(unit, port, config);
    866         }
    867     }
    868 
    869     return BCM_E_UNAVAIL;
    870 }
    871 
    872 
    873 /*
    874  * Function:
    875  *      bcm_esw_subport_gport_modport_get
    876  * Purpose:
    877  *      Given a subport-gport, return teh corresponding mod-port 
    878  * Parameters:
    879  *      unit   - (IN) Device Number
    880  *      subport_gport  - (IN) GPORT (generic port) identifier
    881  *      module  - (OUT) Module associated with the subport
    882  *      port  - (OUT) Port associated with the subport  
    883  * Returns:
    884  *      BCM_E_XXX
    885  */
    886 int
    887 bcm_esw_subport_gport_modport_get(int unit, bcm_gport_t subport_gport,
    888                                   bcm_module_t *module, bcm_port_t *port)
    889 {
    890     if (!BCM_GPORT_IS_SUBPORT_PORT(subport_gport)) {
    891         return (BCM_E_PORT);
    892     }
    893 
    894 #if defined(BCM_HGPROXY_COE_SUPPORT)
    895     if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    896         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_gport)) {
    897         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    898             if (BCM_ESW_SUBPORT_DRV(unit)->subport_gport_modport_get != NULL) {
    899                 return BCM_ESW_SUBPORT_DRV(unit)->
    900                             subport_gport_modport_get(unit, subport_gport,
    901                                                       module, port);
    902             }
    903         }
    904     }
    905 #endif /* BCM_HGPROXY_COE_SUPPORT */
    906 
    907 #if defined(BCM_KATANA2_SUPPORT)
    908     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
    909             _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, subport_gport)) ||
    910         (soc_feature(unit, soc_feature_subtag_coe) &&
    911             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_gport)) ||
    912         (soc_feature(unit, soc_feature_general_cascade) &&
    913           _BCM_KT2_GPORT_IS_GENERAL_SUBPORT_PORT(unit, subport_gport))) {
    914         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    915             if (BCM_ESW_SUBPORT_DRV(unit)->subport_gport_modport_get != NULL) {
    916                 return BCM_ESW_SUBPORT_DRV(unit)->
    917                             subport_gport_modport_get(unit, subport_gport,
    918                                                       module, port);
    919             }
    920         }
    921     }
    922 #endif /* BCM_KATANA2_SUPPORT */
    923 
    924     return BCM_E_UNAVAIL;
    925 }
    926 
    927 /*
    928  * Function:
    929  *      bcm_subport_port_traverse
    930  * Purpose:
    931  *      Traverse all valid subports and call the
    932  *      supplied callback routine.
    933  * Parameters:
    934  *      unit      - Device Number
    935  *      cb        - User callback function, called once per subport.
    936  *      user_data - cookie
    937  * Returns:
    938  *      BCM_E_XXX
    939  */
    940 int
    941 bcm_esw_subport_port_traverse(int unit,
    942                               bcm_subport_port_traverse_cb cb,
    943                               void *user_data)
    944 {
    945     int rv = BCM_E_UNAVAIL;
    946 
    947     if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    948         if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_traverse != NULL) {
    949             rv = BCM_ESW_SUBPORT_DRV(unit)->
    950                     coe_port_traverse(unit, cb, user_data);
    951 
    952             if (!(soc_feature(unit, soc_feature_l3))) {
    953                    return rv;
    954             }
    955         }
    956 
    957         if (BCM_ESW_SUBPORT_DRV(unit)->subport_port_traverse != NULL) {
    958             rv = BCM_ESW_SUBPORT_DRV(unit)->
    959                         subport_port_traverse(unit, cb, user_data);
    960         }
    961     }
    962 
    963     return rv;
    964 }
    965 
    966 #if defined(BCM_XGS_SUPPORT)
    967 /*
    968  * Function:
    969  *      bcm_esw_subport_group_traverse
    970  * Purpose:
    971  *      Traverse all valid subports under given subport group and call the
    972  *      supplied callback routine.
    973  * Parameters:
    974  *      unit          (IN)Device Number
    975  *      subport_group (IN) Subport group GPORT (generic port identifier)
    976  *      cb             User callback function, called once per subport.
    977  *      user_data      cookie
    978  * Returns:
    979  *      BCM_E_XXX
    980  */
    981 int
    982 bcm_esw_subport_group_traverse(int unit,
    983                               bcm_gport_t subport_group,
    984                               bcm_subport_port_traverse_cb cb,
    985                               void *user_data)
    986 {
    987 
    988 #if defined(BCM_HGPROXY_COE_SUPPORT)
    989     if(soc_feature(unit, soc_feature_hgproxy_subtag_coe) &&
    990         _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(subport_group)) {
    991         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
    992             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_traverse != NULL) {
    993                 return BCM_ESW_SUBPORT_DRV(unit)->
    994                             coe_group_traverse(unit, subport_group, cb, user_data);
    995             }
    996         }
    997     }
    998 #endif
    999 
   1000 #if defined(BCM_KATANA2_SUPPORT)
   1001     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
   1002             _BCM_COE_GPORT_IS_LINKPHY_SUBPORT_GROUP(subport_group)) ||
   1003         (soc_feature(unit, soc_feature_subtag_coe) &&
   1004             _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(subport_group)) ||
   1005         (soc_feature(unit, soc_feature_general_cascade) &&
   1006            _BCM_COE_GPORT_IS_GENERAL_SUBPORT_GROUP(subport_group))) {
   1007             if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1008                 if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_traverse != NULL) {
   1009                     return BCM_ESW_SUBPORT_DRV(unit)->
   1010                                 coe_group_traverse(unit, subport_group, cb, user_data);
   1011                 }
   1012             }
   1013     }
   1014 #endif /* BCM_KATANA2_SUPPORT */
   1015     return BCM_E_UNAVAIL;
   1016 }
   1017 
   1018 /**
   1019  * Function:
   1020  *      bcm_esw_subport_group_linkphy_config_get
   1021  * Purpose:
   1022  *      Get ALL or selective LinkPHY configuration attributes 
   1023  *      on a given port GPORT.
   1024  * Parameters:
   1025  * Parameters:
   1026  *      uint (IN) BCM device number
   1027  *      port (IN) port GPORT
   1028  *      linkphy_cfg (OUT) LinkPHY configuration 
   1029  * Returns:
   1030  *      BCM_E_xxx
   1031  */
   1032 
   1033 int 
   1034 bcm_esw_subport_group_linkphy_config_get(
   1035     int unit, 
   1036     bcm_gport_t port, 
   1037     bcm_subport_group_linkphy_config_t *linkphy_config)
   1038 {
   1039 #if defined(BCM_KATANA2_SUPPORT)
   1040     int rv, port_out;
   1041     soc_info_t *si = &SOC_INFO(unit);
   1042 
   1043     if (soc_feature(unit, soc_feature_linkphy_coe)) {
   1044         rv = _bcm_esw_port_gport_validate(unit, port, &port_out);
   1045         if (SOC_FAILURE(rv)) {
   1046             LOG_ERROR(BSL_LS_BCM_SUBPORT,
   1047                       (BSL_META_U(unit,
   1048                                   "ERROR: Invalid port gport 0x%x for LinkPHY config\n"),
   1049                        port));
   1050             return rv;
   1051         }
   1052 
   1053         if (!BCM_PBMP_MEMBER(si->linkphy_pbm, port_out)) {
   1054             LOG_ERROR(BSL_LS_BCM_SUBPORT,
   1055                       (BSL_META_U(unit,
   1056                                   "ERROR: port %d is not member of pbmp_linkphy\n"),
   1057                        port_out));
   1058             return BCM_E_PORT;
   1059         }
   1060 
   1061         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1062             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_linkphy_config_get != NULL) {
   1063                 return BCM_ESW_SUBPORT_DRV(unit)->
   1064                             coe_group_linkphy_config_get(unit, port_out, linkphy_config);
   1065             }
   1066         }
   1067     }
   1068 #endif /* BCM_KATANA2_SUPPORT */
   1069     return BCM_E_UNAVAIL;
   1070 }
   1071 
   1072 /**
   1073  * Function:
   1074  *      bcm_esw_subport_group_linkphy_config_set
   1075  * Purpose:
   1076  *      Set ALL or selective LinkPHY configuration attributes 
   1077  *      on a given port GPORT.
   1078  * Parameters:
   1079  *      uint (IN) BCM device number
   1080  *      port (IN) port GPORT
   1081  *      linkphy_cfg (IN) LinkPHY configuration 
   1082  * Returns:
   1083  *      BCM_E_xxx
   1084  */
   1085 
   1086 int
   1087 bcm_esw_subport_group_linkphy_config_set(
   1088     int unit,
   1089     bcm_gport_t port,
   1090     bcm_subport_group_linkphy_config_t *linkphy_config)
   1091 {
   1092 #if defined(BCM_KATANA2_SUPPORT)
   1093     int rv, port_out;
   1094     soc_info_t *si = &SOC_INFO(unit);
   1095 
   1096     if (soc_feature(unit, soc_feature_linkphy_coe)) {
   1097         rv = _bcm_esw_port_gport_validate(unit, port, &port_out);
   1098         if (SOC_FAILURE(rv)) {
   1099             LOG_ERROR(BSL_LS_BCM_SUBPORT,
   1100                       (BSL_META_U(unit,
   1101                                   "ERROR: Invalid port gport 0x%x for LinkPHY config\n"),
   1102                        port));
   1103             return rv;
   1104         }
   1105 
   1106         if (!BCM_PBMP_MEMBER(si->linkphy_pbm, port_out)) {
   1107             LOG_ERROR(BSL_LS_BCM_SUBPORT,
   1108                       (BSL_META_U(unit,
   1109                                   "ERROR: port %d is not member of pbmp_linkphy\n"),
   1110                        port_out));
   1111             return BCM_E_PORT;
   1112         }
   1113 
   1114         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1115             if (BCM_ESW_SUBPORT_DRV(unit)->coe_group_linkphy_config_set != NULL) {
   1116                 return BCM_ESW_SUBPORT_DRV(unit)->
   1117                             coe_group_linkphy_config_set(unit,
   1118                                                          port_out,
   1119                                                          linkphy_config);
   1120             }
   1121         }
   1122     }
   1123 #endif /* BCM_KATANA2_SUPPORT */
   1124     return BCM_E_UNAVAIL;
   1125 }
   1126 
   1127 /*
   1128  * Function:
   1129  *      bcm_kt2_subport_port_stat_set
   1130  * Purpose:
   1131  *      Set the statistics value for a given subport port and statistics type
   1132  * Parameters:
   1133  *      unit      - (IN) Device Number
   1134  *      port      - (IN) subport port
   1135  *      stream_id - (IN) stream ID array index (if LinkPHY subport)
   1136  *      stat_type - (IN) statistics type
   1137  *      val       - (IN) value
   1138  * Returns:
   1139  *      BCM_E_XXX
   1140  */
   1141 int
   1142 bcm_esw_subport_port_stat_set(
   1143     int unit, 
   1144     bcm_gport_t port, 
   1145     int stream_id, 
   1146     bcm_subport_stat_t stat_type, 
   1147     uint64 val)
   1148 {
   1149 #if defined(BCM_KATANA2_SUPPORT)
   1150     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
   1151             _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) ||
   1152         (soc_feature(unit, soc_feature_subtag_coe) &&
   1153             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
   1154         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1155             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_stat_set != NULL) {
   1156                 return BCM_ESW_SUBPORT_DRV(unit)->
   1157                             coe_port_stat_set(unit, port,stream_id, 
   1158                                               stat_type, val);
   1159             }
   1160         }
   1161     }
   1162 #endif /* BCM_KATANA2_SUPPORT */
   1163     return BCM_E_UNAVAIL;
   1164 }
   1165 
   1166 /*
   1167  * Function:
   1168  *      bcm_kt2_subport_port_stat_get
   1169  * Purpose:
   1170  *      Get the statistics value for a given subport port and statistics type
   1171  * Parameters:
   1172  *      unit      - (IN) Device Number
   1173  *      port      - (IN) subport port
   1174  *      stream_id - (IN) stream ID array index (if LinkPHY subport)
   1175  *      stat_type - (IN) statistics type
   1176  *      val       - (OUT) value
   1177  * Returns:
   1178  *      BCM_E_XXX
   1179  */
   1180 int
   1181 bcm_esw_subport_port_stat_get(
   1182     int unit, 
   1183     bcm_gport_t port, 
   1184     int stream_id, 
   1185     bcm_subport_stat_t stat_type, 
   1186     uint64 *val)
   1187 {
   1188 #if defined(BCM_KATANA2_SUPPORT)
   1189     if ((soc_feature(unit, soc_feature_linkphy_coe) &&
   1190             _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) ||
   1191         (soc_feature(unit, soc_feature_subtag_coe) &&
   1192             _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) {
   1193         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1194             if (BCM_ESW_SUBPORT_DRV(unit)->coe_port_stat_get != NULL) {
   1195                 return BCM_ESW_SUBPORT_DRV(unit)->
   1196                             coe_port_stat_get(unit, port, stream_id, 
   1197                                               stat_type, val);
   1198             }
   1199         }
   1200     }
   1201 #endif /* BCM_KATANA2_SUPPORT */
   1202     return BCM_E_UNAVAIL;
   1203 }
   1204 
   1205 int bcmi_subport_common_init(int unit, bcm_esw_subport_drv_t *drv)
   1206 {
   1207     /* Initialize common SUBPORT module */
   1208     /* Install Tables */
   1209     /* If a driver is not assigned already, assign the driver */
   1210     if(BCM_ESW_SUBPORT_DRV(unit) == NULL) {
   1211         BCM_ESW_SUBPORT_DRV(unit) = drv;
   1212     }
   1213 
   1214     return BCM_E_NONE;
   1215 }
   1216 
   1217 int bcm_esw_subport_linkphy_rx_error_register(
   1218         int unit,
   1219         bcm_subport_linkphy_rx_errors_t errors,
   1220         bcm_subport_linkphy_rx_error_reg_info_t *reg_info,
   1221         void *user_data)
   1222 {
   1223 
   1224 #if defined(BCM_KATANA2_SUPPORT)
   1225     if (soc_feature(unit, soc_feature_linkphy_coe)) {
   1226         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1227             if (BCM_ESW_SUBPORT_DRV(unit)->subport_linkphy_rx_error_register != NULL) {
   1228                 return BCM_ESW_SUBPORT_DRV(unit)->
   1229                             subport_linkphy_rx_error_register(unit, errors, reg_info, 
   1230                                               user_data);
   1231             }
   1232         }
   1233     }
   1234 #endif /* BCM_KATANA2_SUPPORT */
   1235 
   1236     return BCM_E_UNAVAIL;
   1237 }
   1238 
   1239 int bcm_esw_subport_linkphy_rx_error_unregister(
   1240         int unit,
   1241         bcm_subport_linkphy_rx_errors_t errors)
   1242 {
   1243 
   1244 #if defined(BCM_KATANA2_SUPPORT)
   1245     if (soc_feature(unit, soc_feature_linkphy_coe)) {
   1246         if (BCM_ESW_SUBPORT_DRV(unit) != NULL) {
   1247             if (BCM_ESW_SUBPORT_DRV(unit)->subport_linkphy_rx_error_unregister != NULL) {
   1248                 return BCM_ESW_SUBPORT_DRV(unit)->
   1249                             subport_linkphy_rx_error_unregister(unit, errors);
   1250             }
   1251         }
   1252     }
   1253 #endif /* BCM_KATANA2_SUPPORT */
   1254 
   1255     return BCM_E_UNAVAIL;
   1256 }
   1257 
   1258 #endif /* BCM_XGS_SUPPORT */