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


      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/drv.h>
      9 #include <bcm_int/esw/port.h>
     10 #include <bcm/error.h>
     11 #include <bcm/types.h>
     12 #include <soc/profile_mem.h>
     13 #include <soc/bondoptions.h>
     14 #include <shared/bsl.h>
     15 #include <bcm/port.h>
     16 #include <bcm_int/esw_dispatch.h>
     17 
     18 #if defined(BCM_GREYHOUND2_SUPPORT)
     19 int bcmi_gh2_port_mac_type_get(int unit, soc_port_t port,
     20                                bcmi_port_mac_type_t *port_type)
     21 
     22 {
     23     if (NULL == port_type) {
     24         return SOC_E_PARAM;
     25     }
     26     if (IS_XL_PORT(unit, port)) {
     27         *port_type = bcmiPortMacTypeXLmac;
     28         return SOC_E_NONE;
     29     } else if (IS_GE_PORT(unit, port)) {
     30         *port_type = bcmiPortMacTypeUnimac;
     31         return SOC_E_NONE;
     32     } else if (IS_CL_PORT(unit, port)) {
     33         *port_type = bcmiPortMacTypeCLmac;
     34         return SOC_E_NONE;
     35     } else {
     36         return SOC_E_PARAM;
     37     }
     38 }
     39 
     40 #define E2EFC_REMOTE_MODE_VALID(_m_)                                        \
     41     do {                                                                    \
     42         if ((_m_) != bcmPortE2efcModeTx && (_m_) != bcmPortE2efcModeRx) {   \
     43             return BCM_E_UNAVAIL;                                           \
     44         }                                                                   \
     45     } while (0)
     46 #define GH2_BYTE2CELL(_a_) ((_a_) / 144)
     47 
     48 #define GH2_CELL2BYTE(_a_) ((_a_) * 144)
     49 
     50 #define GH2_E2EFC_PBM2BINDEX(_a_)   \
     51     do {                            \
     52         switch (_a_)                \
     53         {                           \
     54             case 1:                 \
     55                 (_a_) = 1;          \
     56                 break;              \
     57             case 2:                 \
     58                 (_a_) = 2;          \
     59                 break;              \
     60             case 4:                 \
     61                 (_a_) = 3;          \
     62                 break;              \
     63             case 8:                 \
     64                 (_a_) = 4;          \
     65                 break;              \
     66             default:                \
     67                 return BCM_E_PARAM; \
     68         }                           \
     69     } while (0)
     70 
     71 #define GH2_E2EFC_REMOTE_PORT_NUM 48
     72 #define GH2_E2EFC_RMOD_NUM 4
     73 #define GH2_E2EFC_MODULE_HDR_LEN 2
     74 #define GH2_PORT_BLOCK_ENT_NUM 4
     75 #define GH2_PORT_BLOCK_INIT_NUM 57
     76 
     77 STATIC const soc_field_t e2efc_rmod_id_f[GH2_E2EFC_RMOD_NUM] = {
     78         RMOD_ID0f, RMOD_ID1f, RMOD_ID2f, RMOD_ID3f};
     79 STATIC const soc_reg_t
     80 e2efc_rmod_id_r[bcmPortE2efcModeCount][GH2_E2EFC_RMOD_NUM] = {
     81         {E2EFC_TX_RMODID_0r, E2EFC_TX_RMODID_0r,
     82         E2EFC_TX_RMODID_1r, E2EFC_TX_RMODID_1r},
     83         {E2EFC_RX_RMODID_0r, E2EFC_RX_RMODID_0r,
     84         E2EFC_RX_RMODID_1r, E2EFC_RX_RMODID_1r}};
     85 STATIC const soc_field_t e2efc_rmod_enable[GH2_E2EFC_RMOD_NUM] = {
     86         V0f, V1f, V2f, V3f};
     87 
     88 typedef enum port_e2efc_mac_type_c {
     89     E2efcModuleHdrXlmac = 0,
     90     E2efcModuleHdrClmac = 1,
     91     E2efcModuleHdrMacCount = 2
     92 } port_e2efc_mac_type_t;
     93 
     94 /* XLMAC : 0, CLMAC:1 */
     95 STATIC const soc_reg_t
     96 e2efc_module_hdr_r[E2efcModuleHdrMacCount][GH2_E2EFC_MODULE_HDR_LEN] = {
     97         {XLMAC_E2EFC_MODULE_HDR_0r, XLMAC_E2EFC_MODULE_HDR_1r},
     98         {CLMAC_E2EFC_MODULE_HDR_0r, CLMAC_E2EFC_MODULE_HDR_1r}};
     99 
    100 /*
    101  * Description:
    102  *      Enable and configure the remote module to apply E2EFC mechanism.
    103  *      Or disable it.
    104  * Parameter:
    105  *      unit           - (IN) unit number
    106  *      remote_module  - (IN) remote module id
    107  *      mode           - (IN) selected mode
    108  *      enable         - (IN) enable or disable selection
    109  *      e2efc_rmod_cfg - (IN) structure containing the configuration.
    110  *                       Ignored when enable = 0.
    111  */
    112 int
    113 bcmi_gh2_port_e2efc_remote_module_enable_set(
    114     int unit,
    115     bcm_module_t remote_module,
    116     bcm_port_e2efc_mode_t mode,
    117     int enable,
    118     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
    119 {
    120     bcm_port_t local_port;
    121     uint32 val;
    122     bcm_module_t remote_module_clear = 0;
    123     int modid, i, blk, bindex, blk_num, port_mode;
    124     /* XLMAC Related Parameters */
    125     uint32 hdr_0_lo, hdr_0_hi, hdr_1_lo, hdr_1_hi;
    126     uint32 src_mod, dest_mod, src_port;
    127     uint64 val_64;
    128     int time_unit_sel, time_units, value_a, value_b;
    129     uint32 val_min, val_max, new_pbm = 0;
    130     port_e2efc_mac_type_t mac_type;
    131     int hdr_0 = 0, hdr_1 = 1;
    132 
    133     E2EFC_REMOTE_MODE_VALID(mode);
    134     /* Check the remote module id is in the valid range or not */
    135     if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) {
    136         LOG_ERROR(BSL_LS_BCM_PORT,
    137                   (BSL_META_U(unit,
    138                   "Invalid remote module ID.\n")));
    139         return BCM_E_BADID;
    140     }
    141 
    142     if (e2efc_rmod_cfg == NULL) {
    143         LOG_ERROR(BSL_LS_BCM_PORT,
    144                   (BSL_META_U(unit,
    145                   "Null Remote Module Configuration.\n")));
    146         return BCM_E_PARAM;
    147     }
    148 
    149     /* Check the logical port is in the right range  */
    150     if (mode == bcmPortE2efcModeTx &&
    151         (!SOC_PORT_VALID(unit, e2efc_rmod_cfg->local_port))) {
    152         LOG_ERROR(BSL_LS_BCM_PORT,
    153                   (BSL_META_U(unit,
    154                   "Invalid port range.\n")));
    155         return BCM_E_PARAM;
    156     }
    157     /* Checking whether remote port is HG port */
    158     if (mode == bcmPortE2efcModeTx) {
    159         BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(
    160                                 unit, e2efc_rmod_cfg->local_port,
    161                                 &local_port));
    162         if (!IS_HG_PORT(unit, local_port)) {
    163             LOG_ERROR(
    164                 BSL_LS_BCM_PORT,
    165                 (BSL_META_U(unit,
    166                             "Error: unit %d port %d is not a Higig port. "
    167                             "E2EFC messages can only be transmitted to "
    168                             "or received from Higig ports.\n"),
    169                  unit, local_port));
    170             return BCM_E_PARAM;
    171         }
    172 
    173         if (e2efc_rmod_cfg->pkt_per_second < 0) {
    174             LOG_ERROR(
    175                 BSL_LS_BCM_PORT,
    176                 (BSL_META_U(unit,
    177                             "Frequency of sending an E2EFC message "
    178                             "cannot be less than zero. \n")));
    179             return BCM_E_PARAM;
    180         }
    181     }
    182 
    183     if (enable == 1) {
    184         /* Search whether the existing remote module ID exist */
    185         for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
    186             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
    187                                               REG_PORT_ANY, 0, &val));
    188             if ((remote_module == (soc_reg_field_get(
    189                                     unit, e2efc_rmod_id_r[mode][i], val,
    190                                     e2efc_rmod_id_f[i]))) &&
    191                 (soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], val,
    192                                    e2efc_rmod_enable[i]) == 1)) {
    193                 LOG_ERROR(BSL_LS_BCM_PORT,
    194                          (BSL_META_U(unit,
    195                           "Remote Module ID already exists.\n")));
    196                 return BCM_E_EXISTS;
    197             }
    198         }
    199         /* Traverse 4 remote module id and setup the one that is not enabled */
    200         modid = -1;
    201         for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
    202             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
    203                                               REG_PORT_ANY, 0, &val));
    204             if (!(soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i], val,
    205                                     e2efc_rmod_enable[i]))) {
    206                 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val,
    207                                   e2efc_rmod_id_f[i], remote_module);
    208                 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val,
    209                                   e2efc_rmod_enable[i], enable);
    210                 BCM_IF_ERROR_RETURN(soc_reg32_set(unit,
    211                                                   e2efc_rmod_id_r[mode][i],
    212                                                   REG_PORT_ANY, 0, val));
    213                 modid = i;
    214                 break;
    215             }
    216         }
    217         if (modid == -1 ) {
    218             LOG_ERROR(BSL_LS_BCM_PORT,
    219                      (BSL_META_U(unit,
    220                       "E2EFC No Available Remote.Module to Setup"
    221                       "Maximun 4 Remote Module only.\n")));
    222             return BCM_E_FULL;
    223         }
    224         /* Set up Higig Port and Port Speed Information */
    225         if (mode == bcmPortE2efcModeTx) {
    226             /* Register E2EFC_RMOD_CFG fill in */
    227             if (soc_feature(unit, soc_feature_logical_port_num)) {
    228                 blk = SOC_PORT_BLOCK(
    229                         unit, SOC_INFO(unit).port_l2p_mapping[local_port]);
    230                 bindex = SOC_PORT_BINDEX(
    231                             unit, SOC_INFO(unit).port_l2p_mapping[local_port]);
    232             } else {
    233                 blk = SOC_PORT_BLOCK(unit, local_port);
    234                 bindex = SOC_PORT_BINDEX(unit, local_port);
    235             }
    236             blk_num = SOC_BLOCK_INFO(unit, blk).number;
    237             if (IS_CL_PORT(unit, local_port)) {
    238                 /*
    239                  * the SOC_BLOCK_INFO will assign block 0 to CL_PORT,
    240                  * which should be 7 as it follow after XL_PORT block 6
    241                  */
    242                 blk_num += 7;
    243             }
    244             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr,
    245                                               REG_PORT_ANY, modid, &val));
    246             soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val,
    247                               PORT_GRP_IDf, blk_num);
    248             new_pbm |= (1 << bindex);
    249             soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val,
    250                               TX_ENABLE_BMPf, new_pbm);
    251             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_RMOD_CFGr,
    252                                               REG_PORT_ANY, modid, val));
    253             /* XLMAC Module Header Set up */
    254             bcm_esw_port_encap_get(unit, local_port, &port_mode);
    255             /* Higig2 Mode */
    256             bcm_esw_stk_my_modid_get(unit, (int *)&src_mod);
    257             if (port_mode == BCM_PORT_ENCAP_HIGIG2) {
    258                 /* default setting K.SOP = 0xfb, MCST = 0(unicast)*/
    259                 hdr_0_hi = 0xfb000000;
    260                 dest_mod = (remote_module & 0xff) << 8;
    261                 hdr_0_hi = hdr_0_hi | dest_mod;
    262                 hdr_0_lo = 0x00000000;
    263                 src_mod = (src_mod & 0xff) << 24;
    264                 src_port = (local_port & 0xff) << 16;
    265                 hdr_0_lo = hdr_0_lo | src_mod | src_port;
    266             } else {
    267                 /* Higig Mode */
    268                 /* default setting K.SOP = 0xfb, HGI = 8, VID = 1 */
    269                 hdr_0_hi = 0xfb800001;
    270                 src_mod = (src_mod & 0x1f) << 27;
    271                 dest_mod = remote_module & 0xff;
    272                 /* default setting OPCODE = 1, COS = 7 */
    273                 hdr_0_lo = 0x01000700 | src_mod | dest_mod;
    274             }
    275 
    276             if (IS_XL_PORT(unit, local_port)) {
    277                 mac_type = E2efcModuleHdrXlmac;
    278             } else if (IS_CL_PORT(unit, local_port)) {
    279                 mac_type = E2efcModuleHdrClmac;
    280             } else {
    281                 LOG_ERROR(BSL_LS_BCM_PORT,
    282                           (BSL_META_U(unit,
    283                           "Invalid Mac Type.\n")));
    284                 return BCM_E_PARAM;
    285             }
    286 
    287             BCM_IF_ERROR_RETURN(
    288                 soc_reg64_get(unit, e2efc_module_hdr_r[mac_type][hdr_0],
    289                               local_port, 0, &val_64));
    290             soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_0],
    291                                   &val_64, E2EFC_MODULE_HDR_0_LOf, hdr_0_lo);
    292             soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_0],
    293                                   &val_64, E2EFC_MODULE_HDR_0_HIf, hdr_0_hi);
    294             BCM_IF_ERROR_RETURN(
    295                 soc_reg64_set(unit, e2efc_module_hdr_r[mac_type][hdr_0],
    296                               local_port, 0, val_64));
    297 
    298             if (port_mode == BCM_PORT_ENCAP_HIGIG2) {
    299                 /* default setting vlan = 1, opcode = 1 */
    300                 hdr_1_lo = 0x00010100;
    301                 hdr_1_hi = 0x00000000;
    302             } else {
    303                 hdr_1_lo = 0x00000000;
    304                 hdr_1_hi = 0x00000000;
    305             }
    306             BCM_IF_ERROR_RETURN(
    307                 soc_reg64_get(unit, e2efc_module_hdr_r[mac_type][hdr_1],
    308                               local_port, 0, &val_64));
    309             soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_1],
    310                                   &val_64, E2EFC_MODULE_HDR_1_LOf, hdr_1_lo);
    311             soc_reg64_field32_set(unit, e2efc_module_hdr_r[mac_type][hdr_1],
    312                                   &val_64, E2EFC_MODULE_HDR_1_HIf,
    313                                   hdr_1_hi);
    314             BCM_IF_ERROR_RETURN(
    315                 soc_reg64_set(unit, e2efc_module_hdr_r[mac_type][hdr_1],
    316                               local_port, 0, val_64));
    317             /* In the absence of congestion, an E2EFC message is still
    318             * generated to refresh congestion status when the E2EFC max
    319             * timer expires. This timer is specified in units of 250ns or
    320             * 25us, and up to 1023 time units can be specified.
    321             * The selection of time unit and the number of time units
    322             * is computed as follows:
    323              *
    324              * Let E2EFC message refresh rate = N messages/sec, and N != 0,
    325              * A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N,
    326              * B = # of 25us time units = 1 sec / N / 25us =
    327              * 40000 / N = A / 100.
    328              *
    329              * If A < 1, configure the minimum allowed timer value:
    330              * time unit = 250ns, # of time units = 1.
    331              *
    332              * If A is between 1 and 1023, configure the timer as:
    333              * time unit = 250ns, # of time units = A.
    334              *
    335              * If A > 1023 and B <= 1023, configure the timer as:
    336              * time unit = 25us, # of time units = B.
    337              *
    338              * If B > 1023, configure the maximum allowed timer value:
    339              * time unit = 25us, # of time units = 1023.
    340              *
    341              * Note: If N = 0, # of time units will be set to 0, and E2EFC
    342              * message refresh is effectively disabled. E2ECC message
    343              * will be generated only when there is a change in congestion
    344              * status.
    345              */
    346 
    347             if (e2efc_rmod_cfg->pkt_per_second == 0) {
    348                 time_unit_sel = 0;
    349                 time_units = 0;
    350             } else {
    351                 value_a = 4000000 / e2efc_rmod_cfg->pkt_per_second;
    352                 value_b = value_a / 100;
    353                 if (value_a < 1) {
    354                     time_unit_sel = 0;
    355                     time_units = 1;
    356                 } else if (value_a <= 1023) {
    357                     time_unit_sel = 0;
    358                     time_units = value_a;
    359                 } else if ((value_a > 1023) && (value_b <= 1023)) {
    360                     time_unit_sel = 1;
    361                     time_units = value_b;
    362                 } else { /* value_b > 1023 */
    363                     time_unit_sel = 1;
    364                     time_units = 1023;
    365                 }
    366             }
    367             /* E2EFC meesage trasmit period setup */
    368             /* For Min TX Timer */
    369             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MIN_TX_TIMERr,
    370                                               REG_PORT_ANY, modid, &val_min));
    371             soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val_min,
    372                               LGf, time_unit_sel);
    373             soc_reg_field_set(unit, E2EFC_HG_MIN_TX_TIMERr, &val_min,
    374                               TIMERf, time_units);
    375             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_HG_MIN_TX_TIMERr,
    376                                               REG_PORT_ANY, modid, val_min));
    377             /* For Max TX Timer */
    378             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MAX_TX_TIMERr,
    379                                               REG_PORT_ANY, modid, &val_max));
    380             soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val_max,
    381                               LGf, time_unit_sel);
    382             soc_reg_field_set(unit, E2EFC_HG_MAX_TX_TIMERr, &val_max,
    383                               TIMERf, time_units);
    384             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_HG_MAX_TX_TIMERr,
    385                                               REG_PORT_ANY, modid, val_max));
    386         } else {
    387             LOG_VERBOSE(BSL_LS_BCM_PORT,
    388                         (BSL_META_U(unit,
    389                         "E2EFC RX mode not allowed to configure timer"
    390                         " and XLMAC and HG port setup.\n")));
    391         }
    392     } else {
    393         /* Traverse 4 rmod id and clear the one that match rmod id */
    394         modid = -1;
    395         for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
    396             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
    397                                               REG_PORT_ANY, 0, &val));
    398             if (remote_module == (soc_reg_field_get(
    399                                   unit, e2efc_rmod_id_r[mode][i], val,
    400                                   e2efc_rmod_id_f[i]))) {
    401                 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val,
    402                                   e2efc_rmod_id_f[i], remote_module_clear);
    403                 soc_reg_field_set(unit, e2efc_rmod_id_r[mode][i], &val,
    404                                   e2efc_rmod_enable[i], 0);
    405                 BCM_IF_ERROR_RETURN(soc_reg32_set(unit,
    406                                                   e2efc_rmod_id_r[mode][i],
    407                                                   REG_PORT_ANY, 0, val));
    408                 modid = i;
    409                 break;
    410             }
    411         }
    412         if (modid == -1 ) {
    413             LOG_ERROR(BSL_LS_BCM_PORT,
    414                      (BSL_META_U(unit,
    415                       "E2EFC No Existing Remote.Module to Clear"
    416                       "Maximun 4 Remote Module only.\n")));
    417             return BCM_E_NOT_FOUND;
    418         }
    419     }
    420 
    421     return BCM_E_NONE;
    422 }
    423 
    424 
    425 /*
    426  * Description:
    427  *      Get the enable mode and configuration of the remote module that
    428  *      applies E2EFC mechanism.
    429  * Parameter:
    430  *      unit           - (IN) unit number
    431  *      remote_module  - (IN) remote module id
    432  *      mode           - (IN) selected mode
    433  *      enable         - (OUT) enable or disable selection
    434  *      e2efc_rmod_cfg - (OUT) structure containing the configuration.
    435  *                       Only valid if the remote module is enabled.
    436  */
    437 int
    438 bcmi_gh2_port_e2efc_remote_module_enable_get(
    439     int unit,
    440     bcm_module_t remote_module,
    441     bcm_port_e2efc_mode_t mode,
    442     int *enable,
    443     bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg)
    444 {
    445     uint32 val, val_p, val_t;
    446     int i, time_unit_sel, time_units;
    447     int blk_num, pbm, phy_port = 0, log_port = 0;
    448 
    449     E2EFC_REMOTE_MODE_VALID(mode);
    450 
    451     /* Check the remote module id is in the valid range or not */
    452     if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) {
    453         LOG_ERROR(BSL_LS_BCM_PORT,
    454                   (BSL_META_U(unit,
    455                   "Invalid remote module ID.\n")));
    456         return BCM_E_BADID;
    457     }
    458 
    459     if (enable == NULL || e2efc_rmod_cfg == NULL) {
    460         return BCM_E_PARAM;
    461     }
    462 
    463     /* Check the logical port is in the right range  */
    464     if (!SOC_PORT_VALID(unit, e2efc_rmod_cfg->local_port)) {
    465         LOG_ERROR(BSL_LS_BCM_PORT,
    466                   (BSL_META_U(unit,
    467                   "Invalid port range.\n")));
    468         return BCM_E_PARAM;
    469     }
    470 
    471     /* if the matched rmod id is not found then the "enable" is zero */
    472     *enable = 0;
    473     /*
    474      * Only Mode TX has the bcm_port_e2efc_remote_module_config_t
    475      * configuration, so if mode == RX, the get API will check whether the
    476      * remote_module exists and return enable value.
    477      */
    478     /* Traverse 4 rmod id and search the one that match rmod id */
    479     for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
    480         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
    481                                           REG_PORT_ANY, 0, &val));
    482         if (remote_module == (soc_reg_field_get(unit,
    483                               e2efc_rmod_id_r[mode][i], val,
    484                               e2efc_rmod_id_f[i]))) {
    485             if (mode == bcmPortE2efcModeTx) {
    486                 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr,
    487                                                   REG_PORT_ANY, i, &val_p));
    488                 blk_num = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p,
    489                                             PORT_GRP_IDf);
    490                 pbm = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p,
    491                                         TX_ENABLE_BMPf);
    492                 GH2_E2EFC_PBM2BINDEX(pbm);
    493                 phy_port = (blk_num * GH2_PORT_BLOCK_ENT_NUM) + pbm
    494                             + GH2_PORT_BLOCK_INIT_NUM;
    495                 log_port = SOC_INFO(unit).port_p2l_mapping[phy_port];
    496                 e2efc_rmod_cfg->local_port = log_port;
    497                 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_HG_MIN_TX_TIMERr,
    498                                                   REG_PORT_ANY, i, &val_t));
    499                 time_unit_sel =
    500                     soc_reg_field_get(unit, E2EFC_HG_MIN_TX_TIMERr,
    501                                       val_t, LGf);
    502                 time_units =
    503                     soc_reg_field_get(unit, E2EFC_HG_MIN_TX_TIMERr,
    504                                       val_t, TIMERf);
    505                 if (time_units == 0) {
    506                     e2efc_rmod_cfg->pkt_per_second = 0;
    507                 } else if (time_unit_sel == 1) {
    508                     /* pkt_per_second = 1 / 25us / time_units */
    509                     e2efc_rmod_cfg->pkt_per_second = 40000 / time_units;
    510                 } else {
    511                     /* pkt_per_second = 1 / 250ns / time_units */
    512                     e2efc_rmod_cfg->pkt_per_second = 4000000 / time_units;
    513                 }
    514             }
    515             *enable = 1;
    516             break;
    517         }
    518     }
    519     return BCM_E_NONE;
    520 }
    521 
    522 /* helper function to search the remote module pointer */
    523 int
    524 bcmi_gh2_e2efc_remote_module_ptr_get(
    525     int unit,
    526     bcm_module_t remote_module,
    527     int *module_ptr)
    528 {
    529     int i, ptr;
    530     uint32 val;
    531     bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx;
    532 
    533     if (module_ptr == NULL) {
    534         return BCM_E_PARAM;
    535     }
    536     /* Check the remote module id is in the valid range or not */
    537     if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) {
    538         LOG_ERROR(BSL_LS_BCM_PORT,
    539                   (BSL_META_U(unit,
    540                   "Invalid remote module ID.\n")));
    541         return BCM_E_BADID;
    542     }
    543 
    544     ptr = -1;
    545     for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
    546         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
    547                                           REG_PORT_ANY, 0, &val));
    548         if (remote_module == (soc_reg_field_get(
    549                               unit, e2efc_rmod_id_r[mode][i], val,
    550                               e2efc_rmod_id_f[i]))) {
    551             ptr = i;
    552             break;
    553         }
    554     }
    555     if (ptr == -1) {
    556         LOG_ERROR(BSL_LS_BCM_PORT,
    557                   (BSL_META_U(unit,
    558                   "Remote module ID not found.\n")));
    559         return BCM_E_NOT_FOUND;
    560     } else {
    561         *module_ptr = ptr;
    562     }
    563     return BCM_E_NONE;
    564 }
    565 
    566 /* helper function to search the remote module id */
    567 int
    568 bcmi_gh2_e2efc_remote_module_id_get(
    569     int unit,
    570     int module_ptr,
    571     bcm_module_t *remote_module)
    572 {
    573     uint32 val;
    574     bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx;
    575 
    576     if (remote_module == NULL) {
    577         return BCM_E_PARAM;
    578     }
    579 
    580     if (module_ptr < 0 || module_ptr >= GH2_E2EFC_RMOD_NUM) {
    581         LOG_ERROR(BSL_LS_BCM_PORT,
    582                   (BSL_META_U(unit,
    583                   "Invalid remote module pointer. Should be 0~3.\n")));
    584         return BCM_E_PARAM;
    585     }
    586 
    587     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_r[mode][module_ptr],
    588                                       REG_PORT_ANY, 0, &val));
    589     /* the remote moduel is enabled */
    590     if (soc_reg_field_get(unit,
    591                           e2efc_rmod_id_r[mode][module_ptr], val,
    592                           e2efc_rmod_enable[module_ptr])) {
    593         *remote_module = (soc_reg_field_get(
    594                             unit, e2efc_rmod_id_r[mode][module_ptr], val,
    595                             e2efc_rmod_id_f[module_ptr]));
    596     } else {
    597         return BCM_E_FAIL;
    598     }
    599 
    600     return BCM_E_NONE;
    601 }
    602 
    603 /* helper function to init E2EFC remote port */
    604 int
    605 bcmi_gh2_port_e2efc_remote_port_init(int unit)
    606 {
    607     int i;
    608     uint32 val;
    609 
    610     for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) {
    611         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr,
    612                                           REG_PORT_ANY, i, &val));
    613         soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val, Vf, 0);
    614         BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr,
    615                                           REG_PORT_ANY, i, val));
    616     }
    617 
    618     return BCM_E_NONE;
    619 }
    620 
    621 /*
    622  * Description:
    623  *      Add remote module-port and set configuration.
    624  *      Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs.
    625  *      The API of remote module-port configuration is only for E2EFC
    626  *      transmission.
    627  * Parameter:
    628  *      unit            - (IN) unit number
    629  *      e2efc_rport_cfg - (IN) structure containing the configuration
    630  *      rport_handle_id - (OUT) remote port handle id, to be used for the rest
    631  *                        of bcm_port_e2efc_remote_port_xxx APIs
    632  */
    633 int
    634 bcmi_gh2_port_e2efc_remote_port_add(
    635     int unit,
    636     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg,
    637     int *rport_handle_id)
    638 {
    639     uint32 val_p, val_off, val_on, val_drop;
    640     int i, enable, rmod_ptr;
    641 
    642     if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) {
    643         return BCM_E_PARAM;
    644     }
    645 
    646     /* Check the logical port is in the right range  */
    647     if (!SOC_PORT_VALID(unit, e2efc_rport_cfg->remote_port)) {
    648         LOG_ERROR(BSL_LS_BCM_PORT,
    649                   (BSL_META_U(unit,
    650                   "Invalid port range.\n")));
    651         return BCM_E_PARAM;
    652     }
    653 
    654     if ((e2efc_rport_cfg->xoff_threshold_packets < 0) ||
    655         (e2efc_rport_cfg->xoff_threshold_bytes < 0) ||
    656         (e2efc_rport_cfg->xon_threshold_packets < 0) ||
    657         (e2efc_rport_cfg->xon_threshold_bytes < 0) ||
    658         (e2efc_rport_cfg->drop_threshold_packets < 0) ||
    659         (e2efc_rport_cfg->drop_threshold_bytes < 0)) {
    660         LOG_ERROR(BSL_LS_BCM_PORT,
    661                   (BSL_META_U(unit,
    662                   "Invalid threshhold value set, should not less than 0.\n")));
    663         return BCM_E_PARAM;
    664     }
    665 
    666     /* Checking if the duplicated Counter is being set */
    667     for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) {
    668         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr,
    669                                           REG_PORT_ANY, i, &val_p));
    670         if ((soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) {
    671             BCM_IF_ERROR_RETURN(
    672                 bcmi_gh2_e2efc_remote_module_ptr_get(
    673                     unit, e2efc_rport_cfg->remote_module, &rmod_ptr));
    674             if (e2efc_rport_cfg->remote_port ==
    675                     (soc_reg_field_get(unit, E2EFC_CNT_ATTRr,
    676                                        val_p, RMT_SRC_PORT_IDf))&&
    677                     rmod_ptr == (soc_reg_field_get(
    678                                 unit, E2EFC_CNT_ATTRr, val_p,
    679                                 RMOD_PTRf))) {
    680                 LOG_ERROR(BSL_LS_BCM_PORT,
    681                           (BSL_META_U(unit,
    682                           "Each remote source port should be"
    683                           "mapped to only one counter.\n")));
    684                 return BCM_E_FULL;
    685             }
    686         }
    687     }
    688 
    689     enable = 0;
    690     for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) {
    691         /* check whether the E2EFC_CNT_ATTRr Vf is enabled */
    692         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr,
    693                                           REG_PORT_ANY, i, &val_p));
    694         if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) {
    695             /* Setting remote port, module id and enable counter */
    696             enable = 1;
    697             soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, Vf, enable);
    698             BCM_IF_ERROR_RETURN(
    699             bcmi_gh2_e2efc_remote_module_ptr_get(
    700                 unit, e2efc_rport_cfg->remote_module, &rmod_ptr));
    701             soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    702                               RMOD_PTRf, rmod_ptr);
    703 
    704             soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    705                               RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port);
    706             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr,
    707                                               REG_PORT_ANY, i, val_p));
    708             /* Setting xoff theshhold */
    709             BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr,
    710                                               REG_PORT_ANY, i, &val_off));
    711             soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off,
    712                               PKT_SET_LIMITf,
    713                               e2efc_rport_cfg->xoff_threshold_packets);
    714             soc_reg_field_set(
    715                 unit, E2EFC_CNT_SET_LIMITr, &val_off, CELL_SET_LIMITf,
    716                 GH2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes));
    717             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr,
    718                                               REG_PORT_ANY, i, val_off));
    719             /* Setting xon theshhold */
    720             BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    721                                               E2EFC_CNT_RESET_LIMITr,
    722                                               REG_PORT_ANY, i, &val_on));
    723             soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr, &val_on,
    724                               PKT_RESET_LIMITf,
    725                               e2efc_rport_cfg->xon_threshold_packets);
    726             soc_reg_field_set(
    727                 unit, E2EFC_CNT_RESET_LIMITr, &val_on, CELL_RESET_LIMITf,
    728                 GH2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes));
    729             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr,
    730                                               REG_PORT_ANY, i, val_on));
    731             /* Setting drop theshhold */
    732             BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    733                                               E2EFC_CNT_DISC_LIMITr,
    734                                               REG_PORT_ANY, i, &val_drop));
    735             soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr, &val_drop,
    736                               PKT_DISC_LIMITf,
    737                               e2efc_rport_cfg->drop_threshold_packets);
    738             soc_reg_field_set(
    739                 unit, E2EFC_CNT_DISC_LIMITr, &val_drop, CELL_DISC_LIMITf,
    740                 GH2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes));
    741             BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr,
    742                                               REG_PORT_ANY, i, val_drop));
    743             break;
    744         }
    745     }
    746     if (enable == 0) {
    747         LOG_ERROR(BSL_LS_BCM_PORT,
    748                  (BSL_META_U(unit,
    749                   "Can't Port Config Because the 48 entries is all full")));
    750         return BCM_E_FULL;
    751     }
    752     *rport_handle_id = i;
    753 
    754     return BCM_E_NONE;
    755 }
    756 
    757 /*
    758  * Description:
    759  *      Set (modify) configuration of the remote port.
    760  * Parameter:
    761  *      unit            - (IN) unit number
    762  *      rport_handle_id - (IN) remote port handle id
    763  *      e2efc_rport_cfg - (IN) structure containing the configuration
    764  */
    765 int
    766 bcmi_gh2_port_e2efc_remote_port_set(
    767     int unit,
    768     int rport_handle_id,
    769     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
    770 {
    771     uint32 val_p, val_off, val_on, val_drop;
    772     int rmod_ptr;
    773 
    774     /* check whehter the handle id is valid */
    775     if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) {
    776         LOG_ERROR(BSL_LS_BCM_PORT,
    777                   (BSL_META_U(unit,
    778                   "Invalid Hadle ID.\n")));
    779         return BCM_E_PARAM;
    780     }
    781 
    782     if (e2efc_rport_cfg == NULL) {
    783         return BCM_E_PARAM;
    784     }
    785 
    786     /* Check the logical port is in the right range  */
    787     if (!SOC_PORT_VALID(unit, e2efc_rport_cfg->remote_port)) {
    788         LOG_ERROR(BSL_LS_BCM_PORT,
    789                   (BSL_META_U(unit,
    790                   "Invalid port range.\n")));
    791         return BCM_E_PARAM;
    792     }
    793 
    794     if ((e2efc_rport_cfg->xoff_threshold_packets < 0) ||
    795         (e2efc_rport_cfg->xoff_threshold_bytes < 0) ||
    796         (e2efc_rport_cfg->xon_threshold_packets < 0) ||
    797         (e2efc_rport_cfg->xon_threshold_bytes < 0) ||
    798         (e2efc_rport_cfg->drop_threshold_packets < 0) ||
    799         (e2efc_rport_cfg->drop_threshold_bytes < 0)) {
    800         LOG_ERROR(BSL_LS_BCM_PORT,
    801                   (BSL_META_U(unit,
    802                   "Invalid threshhold value set, should not less than 0.\n")));
    803         return BCM_E_PARAM;
    804     }
    805     /* check whether the parameter is added or not */
    806     BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    807                                       E2EFC_CNT_ATTRr,
    808                                       REG_PORT_ANY, rport_handle_id, &val_p));
    809     if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr,
    810                             val_p, Vf))) {
    811         LOG_ERROR(BSL_LS_BCM_PORT,
    812                   (BSL_META_U(unit,
    813                   "The port config is not added, thus can't set")));
    814         return BCM_E_PARAM;
    815     }
    816 
    817     /* Setting remote port and module id */
    818     BCM_IF_ERROR_RETURN(
    819     bcmi_gh2_e2efc_remote_module_ptr_get(
    820         unit, e2efc_rport_cfg->remote_module, &rmod_ptr));
    821     soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, RMOD_PTRf, rmod_ptr);
    822     soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    823                       RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port);
    824     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, REG_PORT_ANY,
    825                                       rport_handle_id, val_p));
    826     /* Setting xoff theshhold */
    827     BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    828                                       E2EFC_CNT_SET_LIMITr, REG_PORT_ANY,
    829                                       rport_handle_id, &val_off));
    830     soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off,
    831                       PKT_SET_LIMITf,
    832                       e2efc_rport_cfg->xoff_threshold_packets);
    833     soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off,
    834                       CELL_SET_LIMITf,
    835                       GH2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes));
    836     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr,
    837                                       REG_PORT_ANY, rport_handle_id, val_off));
    838     /* Setting xon theshhold */
    839     BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    840                                       E2EFC_CNT_RESET_LIMITr,
    841                                       REG_PORT_ANY, rport_handle_id, &val_on));
    842     soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr,
    843                       &val_on, PKT_RESET_LIMITf,
    844                       e2efc_rport_cfg->xon_threshold_packets);
    845     soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr,
    846                       &val_on, CELL_RESET_LIMITf,
    847                       GH2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes));
    848     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr,
    849                                       REG_PORT_ANY, rport_handle_id, val_on));
    850     /* Setting drop theshhold */
    851     BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    852                                       E2EFC_CNT_DISC_LIMITr, REG_PORT_ANY,
    853                                       rport_handle_id, &val_drop));
    854     soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr,
    855                       &val_drop, PKT_DISC_LIMITf,
    856                       e2efc_rport_cfg->drop_threshold_packets);
    857     soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr,
    858                       &val_drop, CELL_DISC_LIMITf,
    859                       GH2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes));
    860     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr,
    861                                       REG_PORT_ANY, rport_handle_id, val_drop));
    862 
    863     return BCM_E_NONE;
    864 }
    865 
    866 
    867 /*
    868  * Description:
    869  *      Get configuration of the remote port.
    870  *      Return the remote module, remote port and configuration of the
    871  *      handle id.
    872  * Parameter:
    873  *      unit            - (IN) unit number
    874  *      rport_handle_id - (IN) remote port handle id
    875  *      e2efc_rport_cfg - (OUT) structure containing the configuration
    876  */
    877 int
    878 bcmi_gh2_port_e2efc_remote_port_get(
    879     int unit,
    880     int rport_handle_id,
    881     bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg)
    882 {
    883     uint32 val_p, val_off, val_on, val_drop;
    884     int rmod_ptr, rmod_id;
    885     int xoff_threshold_cell, xon_threshold_cell, drop_threshold_cell;
    886 
    887     if (e2efc_rport_cfg == NULL) {
    888         return BCM_E_PARAM;
    889     }
    890 
    891     /* check whehter the handle id is valid */
    892     if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) {
    893         LOG_ERROR(BSL_LS_BCM_PORT,
    894                   (BSL_META_U(unit,
    895                   "Invalid Hadle ID.\n")));
    896         return BCM_E_PARAM;
    897     }
    898     /* check whether the parameter is added or not */
    899     BCM_IF_ERROR_RETURN(soc_reg32_get(unit,
    900                                       E2EFC_CNT_ATTRr,
    901                                       REG_PORT_ANY, rport_handle_id, &val_p));
    902     if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr,
    903                             val_p, Vf))) {
    904         LOG_ERROR(BSL_LS_BCM_PORT,
    905                  (BSL_META_U(unit,
    906                   "The port config is not added, thus can't get")));
    907         return BCM_E_NOT_FOUND;
    908     }
    909 
    910     /* Getting remote port and module id */
    911     rmod_ptr = soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, RMOD_PTRf);
    912     BCM_IF_ERROR_RETURN(
    913         bcmi_gh2_e2efc_remote_module_id_get(unit, rmod_ptr, &rmod_id));
    914     e2efc_rport_cfg->remote_module = rmod_id;
    915     e2efc_rport_cfg->remote_port =
    916     soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p,
    917                       RMT_SRC_PORT_IDf);
    918     /* Getting xoff theshhold */
    919     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr,
    920                                  REG_PORT_ANY, rport_handle_id, &val_off));
    921     e2efc_rport_cfg->xoff_threshold_packets =
    922         soc_reg_field_get(unit, E2EFC_CNT_SET_LIMITr, val_off,
    923                           PKT_SET_LIMITf);
    924     xoff_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_SET_LIMITr,
    925                                             val_off, CELL_SET_LIMITf);
    926     e2efc_rport_cfg->xoff_threshold_bytes = GH2_CELL2BYTE(xoff_threshold_cell);
    927     /* Getting xon theshhold */
    928     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_RESET_LIMITr,
    929                                       REG_PORT_ANY, rport_handle_id, &val_on));
    930     e2efc_rport_cfg->xon_threshold_packets =
    931         soc_reg_field_get(unit, E2EFC_CNT_RESET_LIMITr,
    932                           val_on, PKT_RESET_LIMITf);
    933     xon_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_RESET_LIMITr,
    934                                            val_on, CELL_RESET_LIMITf);
    935     e2efc_rport_cfg->xon_threshold_bytes = GH2_CELL2BYTE(xon_threshold_cell);
    936     /* Getting drop theshhold */
    937     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_DISC_LIMITr,
    938                                       REG_PORT_ANY,
    939                                       rport_handle_id, &val_drop));
    940     e2efc_rport_cfg->drop_threshold_packets =
    941         soc_reg_field_get(unit, E2EFC_CNT_DISC_LIMITr,
    942                           val_drop, PKT_DISC_LIMITf);
    943     drop_threshold_cell = soc_reg_field_get(unit, E2EFC_CNT_DISC_LIMITr,
    944                                             val_drop, CELL_DISC_LIMITf);
    945     e2efc_rport_cfg->drop_threshold_bytes = GH2_CELL2BYTE(drop_threshold_cell);
    946 
    947     return BCM_E_NONE;
    948 }
    949 
    950 
    951 /*
    952  * Description:
    953  *      Delete remote port.
    954  * Parameter:
    955  *      unit            - (IN) unit number
    956  *      rport_handle_id - (IN) remote port handle id
    957  */
    958 int
    959 bcmi_gh2_port_e2efc_remote_port_delete(
    960     int unit,
    961     int rport_handle_id)
    962 {
    963     uint32 val_p, val_off, val_on, val_drop;
    964     uint32 clear = 0x00000000;
    965 
    966     /* check whehter the handle id is valid */
    967     if ( rport_handle_id < 0 || rport_handle_id >= GH2_E2EFC_REMOTE_PORT_NUM) {
    968         LOG_ERROR(BSL_LS_BCM_PORT,
    969                   (BSL_META_U(unit,
    970                   "Invalid Hadle ID.\n")));
    971         return BCM_E_PARAM;
    972     }
    973     /* check whether the parameter is added or not */
    974     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr,
    975                                  REG_PORT_ANY, rport_handle_id, &val_p));
    976     if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr,
    977                             val_p, Vf))) {
    978         LOG_ERROR(BSL_LS_BCM_PORT,
    979                  (BSL_META_U(unit,
    980                   "The port config is not added, thus can't delete")));
    981         return BCM_E_NOT_FOUND;
    982     }
    983 
    984     /* Set to zero remote port and module id */
    985     soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    986                       Vf, clear);
    987     soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    988                       RMOD_PTRf, clear);
    989     soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p,
    990                       RMT_SRC_PORT_IDf, clear);
    991     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr,
    992                                       REG_PORT_ANY, rport_handle_id, val_p));
    993     /* Set to zero xoff theshhold */
    994     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_SET_LIMITr,
    995                                  REG_PORT_ANY, rport_handle_id, &val_off));
    996     soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off,
    997                       PKT_SET_LIMITf, clear);
    998     soc_reg_field_set(unit, E2EFC_CNT_SET_LIMITr, &val_off,
    999                       CELL_SET_LIMITf, clear);
   1000     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_SET_LIMITr,
   1001                                   REG_PORT_ANY, rport_handle_id, val_off));
   1002     /* Set to zero xon theshhold */
   1003     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_RESET_LIMITr,
   1004                                  REG_PORT_ANY, rport_handle_id, &val_on));
   1005     soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr,
   1006                       &val_on, PKT_RESET_LIMITf, clear);
   1007     soc_reg_field_set(unit, E2EFC_CNT_RESET_LIMITr,
   1008                       &val_on, CELL_RESET_LIMITf, clear);
   1009     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_RESET_LIMITr,
   1010                                       REG_PORT_ANY, rport_handle_id, val_on));
   1011     /* Set to zero drop theshhold */
   1012     BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_DISC_LIMITr,
   1013                                       REG_PORT_ANY, rport_handle_id,
   1014                                       &val_drop));
   1015     soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr,
   1016                       &val_drop, PKT_DISC_LIMITf, clear);
   1017     soc_reg_field_set(unit, E2EFC_CNT_DISC_LIMITr,
   1018                       &val_drop, CELL_DISC_LIMITf, clear);
   1019     BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_DISC_LIMITr,
   1020                                       REG_PORT_ANY, rport_handle_id,
   1021                                       val_drop));
   1022 
   1023     return BCM_E_NONE;
   1024 }
   1025 /*
   1026  * Description:
   1027  *      Traverse enabled remote modules that apply E2EFC mechanism.
   1028  * Parameter:
   1029  *      unit      - (IN) unit number
   1030  *      cb        - (IN) call back function to execute
   1031  *      user_data - (IN) pointer to user data
   1032 */
   1033 int
   1034 bcmi_gh2_port_e2efc_remote_module_traverse(
   1035     int unit,
   1036     bcm_port_e2efc_remote_module_traverse_cb cb,
   1037     void *user_data)
   1038 {
   1039     int i, rv, rmod_id;
   1040     bcm_port_e2efc_mode_t mode;
   1041     uint32 val;
   1042 
   1043     if (user_data == NULL) {
   1044         return BCM_E_PARAM;
   1045     }
   1046 
   1047     for (i = 0; i < GH2_E2EFC_RMOD_NUM; i++) {
   1048         for (mode = bcmPortE2efcModeTx; mode < bcmPortE2efcModeCount; mode++) {
   1049             soc_reg32_get(unit, e2efc_rmod_id_r[mode][i],
   1050                           REG_PORT_ANY, 0, &val);
   1051             if (soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i],
   1052                                   val, e2efc_rmod_enable[i])) {
   1053                 rmod_id = soc_reg_field_get(unit, e2efc_rmod_id_r[mode][i],
   1054                                             val, e2efc_rmod_id_f[i]);
   1055                 rv = cb(unit, rmod_id, mode, user_data);
   1056                 if (rv != BCM_E_NONE) {
   1057                     return rv;
   1058                 }
   1059             }
   1060         }
   1061     }
   1062     return BCM_E_NONE;
   1063 }
   1064 
   1065 /*
   1066  * Description:
   1067  *      Traverse remote ports.
   1068  * Parameter:
   1069  *      unit      - (IN) unit number
   1070  *      cb        - (IN) call back function to execute
   1071  *      user_data - (IN) pointer to user data
   1072  */
   1073 int
   1074 bcmi_gh2_port_e2efc_remote_port_traverse(
   1075     int unit,
   1076     bcm_port_e2efc_remote_port_traverse_cb cb,
   1077     void *user_data)
   1078 {
   1079     int i, rv;
   1080     uint32 val;
   1081 
   1082     if (user_data == NULL) {
   1083         return BCM_E_PARAM;
   1084     }
   1085 
   1086     for (i = 0; i < GH2_E2EFC_REMOTE_PORT_NUM; i++) {
   1087         /* check whether the E2EFC_CNT_ATTRr Vf is enabled */
   1088         BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr,
   1089                                           REG_PORT_ANY, i, &val));
   1090         if (soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val, Vf)) {
   1091             rv = cb(unit, i, user_data);
   1092             if (rv != BCM_E_NONE) {
   1093                 return rv;
   1094             }
   1095         }
   1096     }
   1097 
   1098     return BCM_E_NONE;
   1099 }
   1100 
   1101 #define BCMI_GH2_MAX_PHY_PORTS  (90)
   1102 /*
   1103  * Description:
   1104  *      Force MAC loopback for Riot loopback port.
   1105  * Parameter:
   1106  *      unit      - (IN) unit number
   1107  */
   1108 int
   1109 bcmi_gh2_port_force_lb_set(int unit)
   1110 {
   1111     soc_bond_info_t *bond_info = SOC_BOND_INFO(unit);
   1112     soc_info_t *si = &SOC_INFO(unit);
   1113     int pport, port, loopback;
   1114 
   1115     if (SOC_WARM_BOOT(unit)) {
   1116         return BCM_E_NONE;
   1117     }
   1118 
   1119     if (!soc_feature(unit, soc_feature_untethered_otp)) {
   1120         return SOC_E_NONE;
   1121     }
   1122 
   1123     /* Check Riot lb port */
   1124     for (pport = 0; pport < BCMI_GH2_MAX_PHY_PORTS; pport++) {
   1125         if (SHR_BITGET(bond_info->tsc_in_loop, pport)) {
   1126             port = si->port_p2l_mapping[pport];
   1127             if (port == -1) {
   1128                 continue;
   1129             }
   1130             BCM_IF_ERROR_RETURN(
   1131                 bcm_esw_port_loopback_get(unit, port, &loopback));
   1132             if (loopback == BCM_PORT_LOOPBACK_NONE) {
   1133                 BCM_IF_ERROR_RETURN(
   1134                     bcm_esw_port_loopback_set(
   1135                         unit, port, BCM_PORT_LOOPBACK_MAC));
   1136                 /* Enable MAC credit generation from TSC */
   1137                 BCM_IF_ERROR_RETURN(
   1138                     soc_phyctrl_control_set(
   1139                         unit, port, SOC_PHY_CONTROL_BOND_IN_PWRDN_OVERRIDE, 1));
   1140                 LOG_DEBUG(BSL_LS_BCM_PORT,
   1141                           (BSL_META_UP(unit, port,
   1142                                        "Set port as RIOT LB port\n")));
   1143             } else if (loopback != BCM_PORT_LOOPBACK_MAC) {
   1144                 LOG_WARN(BSL_LS_BCM_PORT,
   1145                          (BSL_META_UP(unit, port,
   1146                                      "port should be in LB NONE/MAC.\n")));
   1147                 return BCM_E_INTERNAL;
   1148             }
   1149         }
   1150     }
   1151     return BCM_E_NONE;
   1152 }
   1153 
   1154 #endif /* BCM_GREYHOUND2_SUPPORT */