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


      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 
      8 #include <soc/defs.h>
      9 
     10 #include <assert.h>
     11 
     12 #include <sal/core/libc.h>
     13 #if defined(BCM_GREYHOUND_SUPPORT)
     14 #include <shared/util.h>
     15 #include <soc/mem.h>
     16 #include <soc/cm.h>
     17 #include <soc/drv.h>
     18 #include <soc/register.h>
     19 #include <soc/memory.h>
     20 #include <soc/hash.h>
     21 #include <bcm_int/esw/port.h>
     22 #include <bcm_int/esw/stack.h>
     23 #include <bcm_int/esw/greyhound.h>
     24 #include <bcm_int/esw_dispatch.h>
     25 
     26 /*
     27  * Function:
     28  *      bcm_gh_port_niv_type_set
     29  * Description:
     30  *      Set NIV port type.
     31  * Parameters:
     32  *      unit - (IN) Device number
     33  *      port - (IN) Port number
     34  *      value - (IN) NIV port type 
     35  * Return Value:
     36  *      BCM_E_XXX
     37  */
     38 int
     39 bcm_gh_port_niv_type_set(int unit, bcm_port_t port, int value)
     40 {
     41     bcm_module_t my_modid;
     42     int mod_port_index;
     43     uint64 val64;
     44 
     45     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     46                 DISCARD_IF_VNTAG_NOT_PRESENTf, 0));
     47     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     48                 DISCARD_IF_VNTAG_PRESENTf, 0));
     49     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     50                 VNTAG_ACTIONS_IF_PRESENTf, VNTAG_NOOP));
     51     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     52                 VNTAG_ACTIONS_IF_NOT_PRESENTf, VNTAG_NOOP));
     53     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     54                 TX_DEST_PORT_ENABLEf, 0));
     55     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     56                 NIV_VIF_LOOKUP_ENABLEf, 0));
     57     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     58                 NIV_RPF_CHECK_ENABLEf, 0));
     59     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     60                 NIV_UPLINK_PORTf, 0));
     61     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
     62                 VT_ENABLEf, 0));
     63 
     64     BCM_IF_ERROR_RETURN(bcm_esw_port_control_set(unit, port,
     65                 bcmPortControlDoNotCheckVlan, 0));
     66 
     67     BCM_IF_ERROR_RETURN(READ_EGR_PORT_64r(unit, port, &val64));
     68     soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
     69                 VNTAG_ACTIONS_IF_PRESENTf, VNTAG_NOOP); 
     70     soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
     71                 NIV_PRUNE_ENABLEf, 0); 
     72     soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
     73                 NIV_UPLINK_PORTf, 0); 
     74     SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_64r(unit, port, val64));
     75 
     76 
     77     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
     78     BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit,
     79                 my_modid, port, &mod_port_index));
     80 
     81     switch (value) {
     82         case BCM_PORT_NIV_TYPE_NONE:
     83             break;
     84         case BCM_PORT_NIV_TYPE_SWITCH:
     85             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
     86                             _BCM_CPU_TABS_ETHER, VT_KEY_TYPE_USE_GLPf, 1));
     87             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
     88                         _BCM_CPU_TABS_ETHER, VT_ENABLEf, 1));
     89             break;
     90 
     91         case BCM_PORT_NIV_TYPE_UPLINK:
     92             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
     93                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_NOT_PRESENTf, 1));
     94             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
     95                         _BCM_CPU_TABS_ETHER, NIV_VIF_LOOKUP_ENABLEf, 1));
     96             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
     97                         _BCM_CPU_TABS_ETHER, NIV_UPLINK_PORTf, 1));
     98             BCM_IF_ERROR_RETURN(bcm_esw_port_control_set(unit, port,
     99                         bcmPortControlDoNotCheckVlan, 1));
    100 
    101             BCM_IF_ERROR_RETURN(READ_EGR_PORT_64r(unit, port, &val64));
    102             soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
    103                         NIV_UPLINK_PORTf, 1); 
    104             SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_64r(unit, port, val64));
    105 
    106             break;
    107 
    108         case BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS:
    109             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    110                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_PRESENTf, 1));
    111             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    112                         _BCM_CPU_TABS_ETHER, VNTAG_ACTIONS_IF_NOT_PRESENTf,
    113                         VNTAG_ADD));
    114             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    115                         _BCM_CPU_TABS_ETHER, TX_DEST_PORT_ENABLEf, 1));
    116             BCM_IF_ERROR_RETURN(bcm_esw_port_control_set(unit, port,
    117                         bcmPortControlDoNotCheckVlan, 1));
    118 
    119             BCM_IF_ERROR_RETURN(READ_EGR_PORT_64r(unit, port, &val64));
    120             soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
    121                         VNTAG_ACTIONS_IF_PRESENTf, VNTAG_DELETE); 
    122             soc_reg64_field32_set(unit, EGR_PORT_64r, &val64, \
    123                         NIV_PRUNE_ENABLEf, 1); 
    124             SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_64r(unit, port, val64));
    125 
    126             break;
    127 
    128         case BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT:
    129             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    130                         _BCM_CPU_TABS_ETHER, DISCARD_IF_VNTAG_NOT_PRESENTf, 1));
    131             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    132                         _BCM_CPU_TABS_ETHER, TX_DEST_PORT_ENABLEf, 1));
    133             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    134                         _BCM_CPU_TABS_ETHER, NIV_RPF_CHECK_ENABLEf, 1));
    135             BCM_IF_ERROR_RETURN(bcm_esw_port_control_set(unit, port,
    136                         bcmPortControlDoNotCheckVlan, 1));
    137             break;
    138 
    139         default:
    140             return BCM_E_PARAM;
    141     }
    142 
    143     return BCM_E_NONE;
    144 }
    145 
    146 /*
    147  * Function:
    148  *      bcm_gh_port_niv_type_get
    149  * Description:
    150  *      Get NIV port type.
    151  * Parameters:
    152  *      unit - (IN) Device number
    153  *      port - (IN) Port number
    154  *      value - (OUT) NIV port type 
    155  * Return Value:
    156  *      BCM_E_XXX
    157  */
    158 int
    159 bcm_gh_port_niv_type_get(int unit, bcm_port_t port, int *value)
    160 {
    161     int rv = BCM_E_NONE;
    162     int vt_enable, uplink, rpf_enable, prune_enable;
    163     uint64 val64;
    164 
    165     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
    166                 port, VT_ENABLEf, &vt_enable));
    167 
    168     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
    169                 port, NIV_UPLINK_PORTf, &uplink));
    170 
    171     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit,
    172                 port, NIV_RPF_CHECK_ENABLEf, &rpf_enable));
    173 
    174 	BCM_IF_ERROR_RETURN(READ_EGR_PORT_64r(unit, port, &val64));
    175     prune_enable = soc_reg64_field32_get(unit, EGR_PORT_64r, val64, 
    176                    NIV_PRUNE_ENABLEf);
    177 
    178     if (vt_enable) {
    179         *value = BCM_PORT_NIV_TYPE_SWITCH;
    180     } else if (uplink) {
    181         *value = BCM_PORT_NIV_TYPE_UPLINK;
    182     } else if (rpf_enable) {
    183         *value = BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT;
    184     } else if (prune_enable) {
    185         *value = BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS;
    186     } else {
    187         *value = BCM_PORT_NIV_TYPE_NONE;
    188     }
    189 
    190     return rv;
    191 }
    192 
    193 /*
    194  * Function:
    195  *      bcm_gh_port_extender_type_set
    196  * Description:
    197  *      Set Port Extender port type.
    198  * Parameters:
    199  *      unit - (IN) Device number
    200  *      port - (IN) Port number
    201  *      value - (IN) Port type 
    202  * Return Value:
    203  *      BCM_E_XXX
    204  */
    205 int
    206 bcm_gh_port_extender_type_set(int unit, bcm_port_t port, int value)
    207 {
    208     switch (value) {
    209         case BCM_PORT_EXTENDER_TYPE_NONE:
    210             BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_set(unit, port,
    211                         BCM_PORT_NIV_TYPE_NONE));
    212             break;
    213         case BCM_PORT_EXTENDER_TYPE_SWITCH:
    214             BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_set(unit, port,
    215                         BCM_PORT_NIV_TYPE_SWITCH));
    216             break;
    217         case BCM_PORT_EXTENDER_TYPE_UPLINK:
    218             BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_set(unit, port,
    219                         BCM_PORT_NIV_TYPE_UPLINK));
    220             break;
    221         case BCM_PORT_EXTENDER_TYPE_DOWNLINK_ACCESS:
    222             BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_set(unit, port,
    223                         BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS));
    224             BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port,
    225                         _BCM_CPU_TABS_ETHER, VNTAG_ACTIONS_IF_NOT_PRESENTf,
    226                         2));
    227             break;
    228         case BCM_PORT_EXTENDER_TYPE_DOWNLINK_TRANSIT:
    229             BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_set(unit, port,
    230                         BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT));
    231             break;
    232         default:
    233             return BCM_E_PARAM;
    234     }
    235 
    236     return BCM_E_NONE;
    237 }
    238 
    239 /*
    240  * Function:
    241  *      bcm_gh_port_extender_type_get
    242  * Description:
    243  *      Get Port Extender port type.
    244  * Parameters:
    245  *      unit - (IN) Device number
    246  *      port - (IN) Port number
    247  *      value - (IN) Port type 
    248  * Return Value:
    249  *      BCM_E_XXX
    250  */
    251 int
    252 bcm_gh_port_extender_type_get(int unit, bcm_port_t port, int *value)
    253 {
    254     int type;
    255 
    256     BCM_IF_ERROR_RETURN(bcm_gh_port_niv_type_get(unit, port, &type));
    257     switch (type) {
    258         case BCM_PORT_NIV_TYPE_NONE:
    259             *value = BCM_PORT_EXTENDER_TYPE_NONE;
    260             break;
    261         case BCM_PORT_NIV_TYPE_SWITCH:
    262             *value = BCM_PORT_EXTENDER_TYPE_SWITCH;
    263             break;
    264         case BCM_PORT_NIV_TYPE_UPLINK:
    265             *value = BCM_PORT_EXTENDER_TYPE_UPLINK;
    266             break;
    267         case BCM_PORT_NIV_TYPE_DOWNLINK_ACCESS:
    268             *value = BCM_PORT_EXTENDER_TYPE_DOWNLINK_ACCESS;
    269             break;
    270         case BCM_PORT_NIV_TYPE_DOWNLINK_TRANSIT:
    271             *value = BCM_PORT_EXTENDER_TYPE_DOWNLINK_TRANSIT;
    272             break;
    273         default:
    274             return BCM_E_INTERNAL;
    275     }
    276 
    277     return BCM_E_NONE;
    278 }
    279 
    280 #if defined(INCLUDE_L3) 
    281 /*
    282  * Function:
    283  *      bcm_gh_port_etag_pcp_de_source_set
    284  * Description:
    285  *      Set source of ETAG's PCP and DE fields.
    286  * Parameters:
    287  *      unit - (IN) Device number
    288  *      port - (IN) Port number
    289  *      value - (IN) PCP and DE source
    290  * Return Value:
    291  *      BCM_E_XXX
    292  */
    293 int
    294 bcm_gh_port_etag_pcp_de_source_set(int unit, bcm_port_t port, int value)
    295 {
    296     int source;
    297 
    298     switch (value) {
    299         case BCM_EXTENDER_PCP_DE_SELECT_OUTER_TAG:
    300             source = 0;
    301             break;
    302         case BCM_EXTENDER_PCP_DE_SELECT_INNER_TAG:
    303             source = 1;
    304             break;
    305         case BCM_EXTENDER_PCP_DE_SELECT_DEFAULT:
    306             source = 2;
    307             break;
    308         case BCM_EXTENDER_PCP_DE_SELECT_PHB:
    309             source = 3;
    310             break;
    311         default:
    312             return BCM_E_PARAM;
    313     }
    314 
    315     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER,
    316                 ETAG_PCP_DE_SOURCEf, source));
    317     return BCM_E_NONE;
    318 }
    319 
    320 /*
    321  * Function:
    322  *      bcm_gh_port_etag_pcp_de_source_get
    323  * Description:
    324  *      Get source of ETAG's PCP and DE fields.
    325  * Parameters:
    326  *      unit - (IN) Device number
    327  *      port - (IN) Port number
    328  *      value - (IN) PCP and DE source
    329  * Return Value:
    330  *      BCM_E_XXX
    331  */
    332 int
    333 bcm_gh_port_etag_pcp_de_source_get(int unit, bcm_port_t port, int *value)
    334 {
    335     int source;
    336 
    337     BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, ETAG_PCP_DE_SOURCEf,
    338                 &source));
    339 
    340     switch (source) {
    341         case 0:
    342             *value = BCM_EXTENDER_PCP_DE_SELECT_OUTER_TAG;
    343             break;
    344         case 1:
    345             *value = BCM_EXTENDER_PCP_DE_SELECT_INNER_TAG;
    346             break;
    347         case 2:
    348             *value = BCM_EXTENDER_PCP_DE_SELECT_DEFAULT;
    349             break;
    350         case 3:
    351             *value = BCM_EXTENDER_PCP_DE_SELECT_PHB;
    352             break;
    353         default:
    354             return BCM_E_INTERNAL;
    355     }
    356 
    357     return BCM_E_NONE;
    358 }
    359 #endif /* INCLUDE_L3 */
    360 
    361 /*
    362  * Function:
    363  *      _bcm_gh_port_pmq_swrst_release
    364  * Description:
    365  *      To release reset state of QSGMII PCS cores in PM4x10Q.
    366  * Parameters:
    367  *      unit - (IN) Device number
    368  * Return Value:
    369  *      BCM_E_XXX
    370  */
    371 STATIC int
    372 _bcm_gh_port_pmq_swrst_release(int unit)
    373 {
    374     uint32 rval;
    375     /*reset ILKN FIFO*/
    376     BCM_IF_ERROR_RETURN(READ_CHIP_SWRSTr(unit, REG_PORT_ANY, &rval));
    377     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, FLUSHf, 0x1);
    378     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, ILKN_BYPASS_RSTNf, 0);
    379     BCM_IF_ERROR_RETURN(WRITE_CHIP_SWRSTr(unit, REG_PORT_ANY, rval));
    380 
    381     
    382     BCM_IF_ERROR_RETURN(READ_CHIP_SWRSTr(unit, REG_PORT_ANY, &rval));
    383     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, ILKN_BYPASS_RSTNf, 0xf);
    384     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, FLUSHf, 0);
    385     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, SOFT_RESET_QSGMII_PCSf, 0);
    386     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, SOFT_RESET_GPORT1f, 0);
    387     soc_reg_field_set(unit, CHIP_SWRSTr, &rval, SOFT_RESET_GPORT0f, 0);
    388     BCM_IF_ERROR_RETURN(WRITE_CHIP_SWRSTr(unit, REG_PORT_ANY, rval));
    389 
    390     return BCM_E_NONE;
    391 }
    392 
    393 /*
    394  * Function:
    395  *      bcm_gh_port_init
    396  * Description:
    397  *      For GH specific port init process.
    398  * Parameters:
    399  *      unit - (IN) Device number
    400  * Return Value:
    401  *      BCM_E_XXX
    402  */
    403 int
    404 bcm_gh_port_init(int unit)
    405 {
    406     uint32 rval, pmq_disabled, qmode_en = 0;
    407 
    408     /* special init process for PMQ(PM4x10Q in QSGMII mode) 
    409      *  - to release PMQ's QSGMII reset state after QSGMII-PCS and UniMAC init.
    410      */
    411     BCM_IF_ERROR_RETURN(READ_PGW_CTRL_0r(unit, &rval));
    412     pmq_disabled = soc_reg_field_get(unit, 
    413             PGW_CTRL_0r, rval, SW_PM4X10Q_DISABLEf);
    414     /* ensure the pm4x10Q is enabled and QMODE enabled */
    415     if (!pmq_disabled) {
    416         BCM_IF_ERROR_RETURN(READ_CHIP_CONFIGr(unit, REG_PORT_ANY, &rval));
    417         qmode_en = soc_reg_field_get(unit, CHIP_CONFIGr, rval, QMODEf);
    418         if (qmode_en) {
    419             BCM_IF_ERROR_RETURN(_bcm_gh_port_pmq_swrst_release(unit));
    420         }
    421     }
    422 
    423     return BCM_E_NONE;
    424 }
    425 
    426 /*
    427  * Function:
    428  *      bcm_gh_port_priority_group_mapping_set
    429  * Purpose:
    430  *      Assign a Priority Group for the input priority.
    431  * Parameters:
    432  *      unit       - (IN) device id.
    433  *      gport     - (IN) generic port.
    434  *      prio       - (IN) input priority.
    435  *      priority_group  - (IN) priority group ID that the input priority mapped to.
    436  * Returns:
    437  *      BCM_E_XXX
    438  */
    439 int
    440 bcm_gh_port_priority_group_mapping_set(int unit, bcm_gport_t gport, int prio, int priority_group)
    441 {
    442     int rv = BCM_E_UNAVAIL;
    443     bcm_port_t port;
    444     uint32 value;
    445     int field_count;
    446     soc_field_t  fields_0[]={PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
    447                             PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf};
    448     soc_field_t  fields_1[]={PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
    449                             PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf};
    450 
    451     if (soc_feature(unit, soc_feature_priority_flow_control) &&
    452         soc_feature(unit, soc_feature_gh_style_pfc_config)) {
    453         /* PFC : 0-7, SAFC : 0-15. Taking the larger range for comparison */
    454         if ((prio < GH_SAFC_INPUT_PRIORITY_MIN) || 
    455             (prio > GH_SAFC_INPUT_PRIORITY_MAX)) {
    456             return BCM_E_PARAM;
    457         }
    458 
    459         if ((priority_group < GH_PRIOROTY_GROUP_ID_MIN) || 
    460             (priority_group > GH_PRIOROTY_GROUP_ID_MAX)) {
    461             return BCM_E_PARAM;
    462         }
    463 
    464         BCM_IF_ERROR_RETURN
    465             (bcm_esw_port_local_get(unit, gport, &port));
    466         if (!SOC_PORT_VALID(unit, port)) {
    467             return BCM_E_PORT;
    468         }
    469         field_count = COUNTOF(fields_0);
    470         if (prio < field_count) {
    471             /* input priority 0~7 */
    472             BCM_IF_ERROR_RETURN(READ_PG_CTRL0r(unit, port, &value));
    473             soc_reg_field_set(unit, PG_CTRL0r, &value, 
    474                                 fields_0[prio], priority_group);
    475             BCM_IF_ERROR_RETURN(WRITE_PG_CTRL0r(unit, port, value));
    476             return BCM_E_NONE;
    477         } else {
    478             /* input priority 8~15 */
    479             BCM_IF_ERROR_RETURN(READ_PG_CTRL1r(unit, port, &value));
    480             soc_reg_field_set(unit, PG_CTRL1r, &value, 
    481                                 fields_1[prio-field_count], priority_group);
    482             BCM_IF_ERROR_RETURN(WRITE_PG_CTRL1r(unit, port, value));
    483             return BCM_E_NONE;
    484         }
    485     }
    486 
    487     return rv;
    488 }
    489 
    490 /*
    491  * Function:
    492  *      bcm_gh_port_priority_group_mapping_get
    493  * Purpose:
    494  *      Get the assigned Priority Group ID of the input priority.
    495  * Parameters:
    496  *      unit       - (IN) device id.
    497  *      gport     - (IN) generic port.
    498  *      prio       - (IN) input priority.
    499  *      priority_group  - (OUT) priority group ID that the input priority mapped to.
    500  * Returns:
    501  *      BCM_E_XXX
    502  */
    503 int
    504 bcm_gh_port_priority_group_mapping_get(int unit, bcm_gport_t gport, int prio, int *priority_group)
    505 {
    506     int rv = BCM_E_UNAVAIL;
    507     bcm_port_t port;
    508     uint32 value;
    509     int field_count;
    510     soc_field_t  fields_0[]={PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
    511                             PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf};
    512     soc_field_t  fields_1[]={PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
    513                             PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf};
    514 
    515     if (soc_feature(unit, soc_feature_priority_flow_control) &&
    516         soc_feature(unit, soc_feature_gh_style_pfc_config)) {
    517         /* PFC : 0-7, SAFC : 0-15. Taking the larger range for comparison */
    518         if ((prio < GH_SAFC_INPUT_PRIORITY_MIN) || 
    519             (prio > GH_SAFC_INPUT_PRIORITY_MAX)) {
    520             return BCM_E_PARAM;
    521         }
    522 
    523         BCM_IF_ERROR_RETURN
    524             (bcm_esw_port_local_get(unit, gport, &port));
    525         if (!SOC_PORT_VALID(unit, port)) {
    526             return BCM_E_PORT;
    527         }
    528         field_count = COUNTOF(fields_0);
    529         if (prio < field_count) {
    530             /* input priority 0~7 */
    531             BCM_IF_ERROR_RETURN(READ_PG_CTRL0r(unit, port, &value));
    532             *priority_group = soc_reg_field_get(unit, PG_CTRL0r, value, 
    533                                                 fields_0[prio]);
    534             return BCM_E_NONE;
    535         } else {
    536             /* input priority 8~15 */
    537             BCM_IF_ERROR_RETURN(READ_PG_CTRL1r(unit, port, &value));
    538             *priority_group = soc_reg_field_get(unit, PG_CTRL1r, value, 
    539                                                 fields_1[prio-field_count]);
    540             return BCM_E_NONE;
    541         }
    542     }
    543 
    544     return rv;
    545 }
    546 
    547 /*
    548  * Function:
    549  *      bcm_gh_port_priority_group_config_set
    550  * Purpose:
    551  *      Set the port priority group configuration.
    552  * Parameters:
    553  *      unit       - (IN) device id.
    554  *      gport     - (IN) generic port.
    555  *      priority_group - (IN) priority group id.
    556  *      prigrp_config  - (IN) structure describes port priority group configuration.
    557  * Returns:
    558  *      BCM_E_XXX
    559  */
    560 int
    561 bcm_gh_port_priority_group_config_set(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
    562 {
    563     int rv = BCM_E_UNAVAIL;
    564     bcm_port_t port;
    565     uint32 rval;
    566     uint32 fval;
    567 
    568     if (soc_feature(unit, soc_feature_priority_flow_control) &&
    569         soc_feature(unit, soc_feature_gh_style_pfc_config)) {
    570         if ((priority_group < GH_PRIOROTY_GROUP_ID_MIN) || 
    571             (priority_group > GH_PRIOROTY_GROUP_ID_MAX)) {
    572             return BCM_E_PARAM;
    573         }
    574 
    575         BCM_IF_ERROR_RETURN
    576             (bcm_esw_port_local_get(unit, gport, &port));
    577         if (!SOC_PORT_VALID(unit, port)) {
    578             return BCM_E_PORT;
    579         }
    580 
    581         BCM_IF_ERROR_RETURN(READ_PG_CTRL0r(unit, port, &rval));
    582         fval = soc_reg_field_get(unit, PG_CTRL0r, rval, PPFC_PG_ENf);
    583         if (prigrp_config->pfc_transmit_enable) {
    584             fval |= (1 << priority_group);
    585         } else {
    586             fval &= ~(1 << priority_group);
    587         }
    588         soc_reg_field_set(unit, PG_CTRL0r, &rval, PPFC_PG_ENf, fval);
    589         BCM_IF_ERROR_RETURN(WRITE_PG_CTRL0r(unit, port, rval));
    590 
    591         BCM_IF_ERROR_RETURN(READ_SHARED_POOL_CTRLr(unit, port, &rval));
    592 
    593         fval = soc_reg_field_get(unit, SHARED_POOL_CTRLr, rval, SHARED_POOL_XOFF_ENf);
    594         if (prigrp_config->shared_pool_xoff_enable) {
    595             fval |= (1 << priority_group);
    596         } else {
    597             fval &= ~(1 << priority_group);
    598         }
    599         soc_reg_field_set(unit, SHARED_POOL_CTRLr, &rval, SHARED_POOL_XOFF_ENf, fval);
    600 
    601         fval = soc_reg_field_get(unit, SHARED_POOL_CTRLr, rval, SHARED_POOL_DISCARD_ENf);
    602         if (prigrp_config->shared_pool_discard_enable) {
    603             fval |= (1 << priority_group);
    604         } else {
    605             fval &= ~(1 << priority_group);
    606         }
    607         soc_reg_field_set(unit, SHARED_POOL_CTRLr, &rval, SHARED_POOL_DISCARD_ENf, fval);
    608 
    609         BCM_IF_ERROR_RETURN(WRITE_SHARED_POOL_CTRLr(unit, port, rval));
    610 
    611         BCM_IF_ERROR_RETURN(READ_PG2TCr(unit, port, priority_group, &rval));
    612         soc_reg_field_set(unit, PG2TCr, &rval, 
    613                   PG_BMPf, prigrp_config->priority_enable_vector_mask);
    614         BCM_IF_ERROR_RETURN(WRITE_PG2TCr(unit, port, priority_group, rval));
    615 
    616         return BCM_E_NONE;
    617     }
    618 
    619     return rv;
    620 }
    621 
    622 /*
    623  * Function:
    624  *      bcm_gh_port_priority_group_config_get
    625  * Purpose:
    626  *      Get the port priority group configuration.
    627  * Parameters:
    628  *      unit       - (IN) device id.
    629  *      gport     - (IN) generic port.
    630  *      priority_group - (IN) priority group id.
    631  *      prigrp_config  - (OUT) structure describes port priority group configuration.
    632  * Returns:
    633  *      BCM_E_XXX
    634  */
    635 int
    636 bcm_gh_port_priority_group_config_get(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config)
    637 {
    638     int rv = BCM_E_UNAVAIL;
    639     bcm_port_t port;
    640     uint32 rval;
    641     uint32 fval;
    642 
    643     if (soc_feature(unit, soc_feature_priority_flow_control) &&
    644         soc_feature(unit, soc_feature_gh_style_pfc_config)) {
    645         if ((priority_group < GH_PRIOROTY_GROUP_ID_MIN) || 
    646             (priority_group > GH_PRIOROTY_GROUP_ID_MAX)) {
    647             return BCM_E_PARAM;
    648         }
    649 
    650         BCM_IF_ERROR_RETURN
    651             (bcm_esw_port_local_get(unit, gport, &port));
    652         if (!SOC_PORT_VALID(unit, port)) {
    653             return BCM_E_PORT;
    654         }
    655 
    656         BCM_IF_ERROR_RETURN(READ_PG_CTRL0r(unit, port, &rval));
    657         fval = soc_reg_field_get(unit, PG_CTRL0r, rval, PPFC_PG_ENf);
    658         if (fval & (1 << priority_group)) {
    659             prigrp_config->pfc_transmit_enable = 1;
    660         } else {
    661             prigrp_config->pfc_transmit_enable = 0;
    662         }
    663 
    664         BCM_IF_ERROR_RETURN(READ_SHARED_POOL_CTRLr(unit, port, &rval));
    665 
    666         fval = soc_reg_field_get(unit, SHARED_POOL_CTRLr, rval, SHARED_POOL_XOFF_ENf);
    667         if (fval & (1 << priority_group)) {
    668             prigrp_config->shared_pool_xoff_enable = 1;
    669         } else {
    670             prigrp_config->shared_pool_xoff_enable = 0;
    671         }
    672 
    673         fval = soc_reg_field_get(unit, SHARED_POOL_CTRLr, rval, SHARED_POOL_DISCARD_ENf);
    674         if (fval & (1 << priority_group)) {
    675             prigrp_config->shared_pool_discard_enable = 1;
    676         } else {
    677             prigrp_config->shared_pool_discard_enable = 0;
    678         }
    679 
    680         BCM_IF_ERROR_RETURN(READ_PG2TCr(unit, port, priority_group, &rval));
    681         prigrp_config->priority_enable_vector_mask = 
    682                 soc_reg_field_get(unit, PG2TCr, rval, PG_BMPf);
    683 
    684         return BCM_E_NONE;
    685     }
    686 
    687     return rv;
    688 }
    689 
    690 #endif /* BCM_GREYHOUND_SUPPORT */