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

oob.c (63178B)


      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  * OOB Flow Control
      7  * Purpose: API to set different OOB Flow Control and OOB Stats registers.
      8  */
      9 #include <sal/core/libc.h>
     10 
     11 #include <shared/bsl.h>
     12 #include <soc/defs.h>
     13 #include <soc/drv.h>
     14 #include <soc/mem.h>
     15 
     16 #if defined(BCM_KATANA2_SUPPORT)
     17 #include <soc/profile_mem.h>
     18 #include <soc/debug.h>
     19 #include <soc/katana2.h>
     20 
     21 #include <bcm/error.h>
     22 #include <bcm/oob.h>
     23 
     24 #include <bcm_int/esw/mbcm.h>
     25 #include <bcm_int/esw/katana2.h>
     26 
     27 #include <bcm_int/esw_dispatch.h>
     28 #include <bcm_int/esw/stat.h>
     29 
     30 #ifdef BCM_WARM_BOOT_SUPPORT
     31 #include <bcm_int/esw/switch.h>
     32 #endif /* BCM_WARM_BOOT_SUPPORT */
     33 
     34 #if defined(BCM_METROLITE_SUPPORT)
     35 #include <soc/metrolite.h>
     36 #endif
     37 
     38 #define BCM_KT2_MMU_NUM_POOL  1
     39 /* Number of Traffic Class */
     40 #define BCM_KT2_NUM_TC  8
     41 /* Number of OOB FC Rx Interface */
     42 #define BCM_KT2_NUM_OOB_FC_RX_INTF   1 
     43 /* Maximum Value of Channel Base Value */
     44 #define BCM_KT2_MAX_CHANNEL_BASE    63
     45 
     46 /* Total number of Indexes in OOBFC RX memory */
     47 #define BCM_KT2_MAX_RX_MEM_ENTRY   41 
     48 #define BCM_SB2_MAX_RX_MEM_ENTRY   29 
     49 #define BCM_ML_MAX_RX_MEM_ENTRY    13
     50 
     51 typedef struct _bcm_kt2_oob_fc_rx_intf_info_s {
     52     uint32 channel_base; /* HCFC channel base */
     53     int enable;          /* Interface enable */
     54     uint8 num_ports;     /* Number of ports monitored */
     55     uint8 lookup_base;   /* Look up base in the OOB FC Rx Memory */
     56 } _bcm_kt2_oob_fc_rx_intf_info_t;
     57     
     58 /*
     59  * Function:
     60  *      _bcm_kt2_oob_fc_tx_config_flags_set
     61  * Purpose:
     62  *      Set OOB FC Tx enable flags
     63  * Parameters:
     64  *      unit - (IN) StrataSwitch unit number.
     65  *      flags - (IN) OOB FC Tx flags
     66  * Returns:
     67  *      BCM_E_XXX
     68  */
     69 STATIC int
     70 _bcm_kt2_oob_fc_tx_config_flags_set(int unit, uint32 flags)
     71 {
     72     uint32 rval = 0;
     73     uint64 rval64;
     74     uint64 field64;
     75 
     76     COMPILER_64_ZERO(rval64);
     77     COMPILER_64_ZERO(field64);
     78 
     79     if (flags & BCM_OOB_FC_TX_FCN_EN) {
     80         BCM_IF_ERROR_RETURN
     81             (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval));
     82         soc_reg_field_set(unit, INTFO_FCN_ENr, &rval, ENf, 0x1);
     83         BCM_IF_ERROR_RETURN
     84             (soc_reg32_set(unit, INTFO_FCN_ENr, 0, 0, rval));
     85     } else {
     86         BCM_IF_ERROR_RETURN
     87             (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval));
     88         soc_reg_field_set(unit, INTFO_FCN_ENr, &rval, ENf, 0x0);
     89         BCM_IF_ERROR_RETURN
     90             (soc_reg32_set(unit, INTFO_FCN_ENr, 0, 0, rval));
     91     }
     92 
     93     BCM_IF_ERROR_RETURN
     94         (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r,
     95                        0, 0, &rval64));
     96     if (flags & BCM_OOB_FC_TX_ING_EN) {
     97         COMPILER_64_SET(field64, 0, 1);
     98     }
     99     soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64,
    100                         ING_ENf, field64);
    101 
    102     COMPILER_64_ZERO(field64);
    103     if (flags & BCM_OOB_FC_TX_EGR_EN) {
    104         COMPILER_64_SET(field64, 0, 1);
    105     }
    106     soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64,
    107                         ENG_ENf, field64);
    108 
    109     /* pool enable not present */
    110     if (flags & BCM_OOB_FC_TX_POOL_EN) {
    111         return BCM_E_PARAM;
    112     }
    113     BCM_IF_ERROR_RETURN
    114         (soc_reg64_set(unit, OOBFC_CHANNEL_BASE_64r, 0, 0, rval64));
    115     return BCM_E_NONE;
    116 }
    117 
    118 /*
    119  * Function:
    120  *      _bcm_kt2_oob_fc_tx_config_ipg_set
    121  * Purpose:
    122  *      Set OOB FC Tx inter packet gap
    123  * Parameters:
    124  *      unit - (IN) StrataSwitch unit number.
    125  *      ipg - (IN) OOB FC Tx inter packet gap
    126  * Returns:
    127  *      BCM_E_XXX
    128  */
    129 STATIC int
    130 _bcm_kt2_oob_fc_tx_config_ipg_set(int unit, uint8 ipg)
    131 {
    132     uint32 rval;
    133 
    134     BCM_IF_ERROR_RETURN
    135         (soc_reg32_get(unit, OOBFC_TX_IDLEr, 0, 0, &rval));
    136     soc_reg_field_set(unit, OOBFC_TX_IDLEr, &rval,
    137                       IDLE_GAPf, ipg);
    138     BCM_IF_ERROR_RETURN
    139         (soc_reg32_set(unit, OOBFC_TX_IDLEr, 0, 0, rval));
    140     return BCM_E_NONE;
    141 }
    142 
    143 /*
    144  * Function:
    145  *      _bcm_kt2_oob_fc_tx_config_gcs_id_set
    146  * Purpose:
    147  *      Set OOB FC Tx global congestion reporting
    148  *      service pool id
    149  * Parameters:
    150  *      unit - (IN) StrataSwitch unit number.
    151  *      id - (IN) OOB FC Tx global congestion service pool id
    152  * Returns:
    153  *      BCM_E_XXX
    154  */
    155 STATIC int
    156 _bcm_kt2_oob_fc_tx_config_gcs_id_set(int unit,
    157                              bcm_service_pool_id_t id)
    158 {
    159     uint32 rval;
    160 
    161     BCM_IF_ERROR_RETURN
    162         (soc_reg32_get(unit, OOBFC_GCSr, 0, 0, &rval));
    163     soc_reg_field_set(unit, OOBFC_GCSr, &rval,
    164                       GCS_IDf, id);
    165     BCM_IF_ERROR_RETURN
    166         (soc_reg32_set(unit, OOBFC_GCSr, 0, 0, rval));
    167 
    168     return BCM_E_NONE;
    169 }
    170 
    171 /*
    172  * Function:
    173  *      _bcm_kt2_oob_fc_tx_config_egr_mode_set
    174  * Purpose:
    175  *      Set OOB FC Tx egress congestion reporting mode
    176  * Parameters:
    177  *      unit - (IN) StrataSwitch unit number.
    178  *      mode - (IN) OOB FC Tx egress congestion reporting mode
    179  * Returns:
    180  *      BCM_E_XXX
    181  */
    182 STATIC int
    183 _bcm_kt2_oob_fc_tx_config_egr_mode_set(int unit,
    184                              bcm_oob_egress_mode_t mode)
    185 {
    186     uint64 rval64;
    187     uint64 field64;
    188 
    189     COMPILER_64_ZERO(field64);
    190     COMPILER_64_ZERO(rval64);
    191     BCM_IF_ERROR_RETURN
    192         (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r,
    193                        0, 0, &rval64));
    194     COMPILER_64_SET(field64, 0, mode);
    195     soc_reg64_field_set(unit, OOBFC_CHANNEL_BASE_64r, &rval64,
    196                         ENG_MODEf, field64);
    197     BCM_IF_ERROR_RETURN
    198         (soc_reg64_set(unit, OOBFC_CHANNEL_BASE_64r,
    199                        0, 0, rval64));
    200 
    201     return BCM_E_NONE;
    202 }
    203 
    204 /*
    205  * Function:
    206  *      _bcm_kt2_oob_fc_tx_config_flags_get
    207  * Purpose:
    208  *      Get OOB FC Tx enable status
    209  * Parameters:
    210  *      unit - (IN) StrataSwitch unit number.
    211  *      config - (OUT) OOB FC Tx configuration
    212  * Returns:
    213  *      BCM_E_XXX
    214  */
    215 STATIC int
    216 _bcm_kt2_oob_fc_tx_config_flags_get(int unit,
    217                               bcm_oob_fc_tx_config_t *config)
    218 {
    219     uint32 rval = 0;
    220     uint64 rval64;
    221     uint64 regval64;
    222 
    223     COMPILER_64_ZERO(rval64);
    224     COMPILER_64_ZERO(regval64);
    225 
    226     config->flags = 0x0;
    227 
    228     BCM_IF_ERROR_RETURN
    229         (soc_reg32_get(unit, INTFO_FCN_ENr, 0, 0, &rval));
    230 
    231     if (soc_reg_field_get(unit, INTFO_FCN_ENr, rval, ENf)) {
    232         config->flags |= BCM_OOB_FC_TX_FCN_EN;
    233     }
    234 
    235     BCM_IF_ERROR_RETURN
    236         (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r,
    237                        0, 0, &rval64));
    238 
    239     regval64 = soc_reg64_field_get(unit, OOBFC_CHANNEL_BASE_64r,
    240                             rval64, ING_ENf);
    241     if (!COMPILER_64_IS_ZERO(regval64)) {
    242         config->flags |= BCM_OOB_FC_TX_ING_EN;
    243     }
    244 
    245     regval64 = soc_reg64_field_get(unit, OOBFC_CHANNEL_BASE_64r,
    246                             rval64, ENG_ENf);
    247     if (!COMPILER_64_IS_ZERO(regval64)) {
    248         config->flags |= BCM_OOB_FC_TX_EGR_EN;
    249     }
    250     return BCM_E_NONE;
    251 }
    252 
    253 /*
    254  * Function:
    255  *      _bcm_kt2_oob_fc_tx_config_ipg_get
    256  * Purpose:
    257  *      Get OOB FC Tx inter packet gap
    258  * Parameters:
    259  *      unit - (IN) StrataSwitch unit number.
    260  *      config - (OUT) OOB FC Tx configuration
    261  * Returns:
    262  *      BCM_E_XXX
    263  */
    264 STATIC int
    265 _bcm_kt2_oob_fc_tx_config_ipg_get(int unit,
    266                             bcm_oob_fc_tx_config_t *config)
    267 {
    268     uint32 rval;
    269 
    270     BCM_IF_ERROR_RETURN
    271         (soc_reg32_get(unit, OOBFC_TX_IDLEr, 0, 0, &rval));
    272 
    273     config->inter_pkt_gap = soc_reg_field_get(unit, OOBFC_TX_IDLEr,
    274                                               rval, IDLE_GAPf);
    275 
    276     return BCM_E_NONE;
    277 }
    278 
    279 /*
    280  * Function:
    281  *      _bcm_kt2_oob_fc_tx_config_gcs_id_get
    282  * Purpose:
    283  *      Get OOB FC Tx global congestion reporting
    284  *      service pool id
    285  * Parameters:
    286  *      unit - (IN) StrataSwitch unit number.
    287  *      config - (OUT) OOB FC Tx configuration
    288  * Returns:
    289  *      BCM_E_XXX
    290  */
    291 STATIC int
    292 _bcm_kt2_oob_fc_tx_config_gcs_id_get(int unit,
    293                               bcm_oob_fc_tx_config_t *config)
    294 {
    295     uint32 rval;
    296 
    297     BCM_IF_ERROR_RETURN
    298         (soc_reg32_get(unit, OOBFC_GCSr, 0, 0, &rval));
    299 
    300     config->gcs_id = soc_reg_field_get(unit, OOBFC_GCSr, rval,
    301                                        GCS_IDf);
    302 
    303     return BCM_E_NONE;
    304 }
    305 
    306 /*
    307  * Function:
    308  *      _bcm_kt2_oob_fc_tx_config_egr_mode_get
    309  * Purpose:
    310  *      Get OOB FC Tx egress congestion reporting mode
    311  * Parameters:
    312  *      unit - (IN) StrataSwitch unit number.
    313  *      config - (OUT) OOB FC Tx configuration
    314  * Returns:
    315  *      BCM_E_XXX
    316  */
    317 STATIC int
    318 _bcm_kt2_oob_fc_tx_config_egr_mode_get(int unit,
    319                                   bcm_oob_fc_tx_config_t *config)
    320 {
    321     uint64 rval64;
    322 
    323     BCM_IF_ERROR_RETURN
    324         (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r,
    325                        0, 0, &rval64));
    326 
    327     config->egr_mode = soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r,
    328                                              rval64, ENG_MODEf);
    329 
    330     return BCM_E_NONE;
    331 }
    332 
    333 /*
    334  * Function:
    335  *      _bcm_kt2_oob_localport_resolve
    336  * Purpose:
    337  *      Get the logical port from modport gport
    338  * Parameters:
    339  *      unit - (IN) StrataSwitch unit number.
    340  *      gport - (IN) Modport gport.
    341  *      local_port - (OUT) Logical port number.
    342  * Returns:
    343  *      BCM_E_XXX
    344  */
    345 STATIC int
    346 _bcm_kt2_oob_localport_resolve(int unit, bcm_gport_t gport,
    347                         bcm_port_t *local_port)
    348 {
    349     bcm_module_t module;
    350     bcm_port_t port;
    351     bcm_trunk_t trunk;
    352     int id, result;
    353 
    354     if (!BCM_GPORT_IS_SET(gport)) {
    355         if (!SOC_PORT_VALID(unit, gport)) {
    356             return BCM_E_PORT;
    357         }
    358         *local_port = gport;
    359         return BCM_E_NONE;
    360     }
    361 
    362     BCM_IF_ERROR_RETURN
    363         (_bcm_esw_gport_resolve(unit, gport, &module, &port, &trunk, &id));
    364 
    365     BCM_IF_ERROR_RETURN(_bcm_esw_modid_is_local(unit, module, &result));
    366     if (result == FALSE) {
    367         return BCM_E_PARAM;
    368     }
    369 
    370     *local_port = port;
    371 
    372     return BCM_E_NONE;
    373 }
    374 
    375 /*
    376  * Function:
    377  *      _bcm_kt2_oob_fc_rx_get_intf_info
    378  * Purpose:
    379  *      Get the per OOBFC Rx interface info structure
    380  * Parameters:
    381  *      unit - (IN) StrataSwitch unit number.
    382  *      info - (OUT) Per OOBFC RX interface info structure.
    383  *      intf_id - (IN) OOBFC Rx Interface ID.
    384  * Returns:
    385  *      BCM_E_XXX
    386  */
    387 STATIC int
    388 _bcm_kt2_oob_fc_rx_get_intf_info(int unit, _bcm_kt2_oob_fc_rx_intf_info_t *info,
    389                             bcm_oob_fc_rx_intf_id_t intf_id)
    390 {
    391     uint32 rval = 0x0;
    392     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
    393    
    394     BCM_IF_ERROR_RETURN
    395         (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval));
    396         
    397     info->enable = soc_reg_field_get(unit, cfg_reg[intf_id], rval,
    398                                      OOBFC_CH_ENf);
    399     if (info->enable == 1) {
    400         info->num_ports = soc_reg_field_get(unit, cfg_reg[intf_id], rval,
    401                                             CH_PORT_NUMf);
    402         info->lookup_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval,
    403                                               LOOKUP_BASEf);
    404         info->channel_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval,
    405                                                OOBFC_CH_BASEf);
    406     }
    407     return BCM_E_NONE;
    408 }
    409 
    410 /*
    411  * Function:
    412  *      _bcm_kt2_oob_fc_rx_disable_intf
    413  * Purpose:
    414  *      Disable OOBFC Rx interface.
    415  * Parameters:
    416  *      unit - (IN) StrataSwitch unit number.
    417  *      intf_id - (IN) OOBFC Rx Interface ID.
    418  * Returns:
    419  *      BCM_E_XXX
    420  */
    421 STATIC int
    422 _bcm_kt2_oob_fc_rx_disable_intf(int unit,
    423                            bcm_oob_fc_rx_intf_id_t intf_id)
    424 {
    425     uint32 rval = 0x0;
    426     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
    427 
    428     BCM_IF_ERROR_RETURN
    429         (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval));
    430     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    431                       OOBFC_CH_ENf, 0);
    432     BCM_IF_ERROR_RETURN
    433         (soc_reg32_set(unit, cfg_reg[intf_id], 0, 0, rval));
    434 
    435     return BCM_E_NONE;
    436 }
    437 
    438 /*
    439  * Function:
    440  *      _bcm_kt2_oob_fc_rx_enable_intf
    441  * Purpose:
    442  *      Enable OOBFC Rx interface.
    443  * Parameters:
    444  *      unit - (IN) StrataSwitch unit number.
    445  *      intf_id - (IN) OOBFC Rx Interface ID.
    446  * Returns:
    447  *      BCM_E_XXX
    448  */
    449 STATIC int
    450 _bcm_kt2_oob_fc_rx_enable_intf(int unit,
    451                           bcm_oob_fc_rx_intf_id_t intf_id)
    452 {
    453     uint32 rval = 0x0;
    454     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
    455 
    456     BCM_IF_ERROR_RETURN
    457         (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval));
    458 
    459     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    460                       OOBFC_CH_ENf, 1);
    461     BCM_IF_ERROR_RETURN
    462         (soc_reg32_set(unit, cfg_reg[intf_id], 0, 0, rval));
    463 
    464     return BCM_E_NONE;
    465 }
    466 
    467 /*
    468  * Function:
    469  *      _bcm_kt2_oob_fc_rx_intf_get_lookup_base
    470  * Purpose:
    471  *      Get the look base in OOBFC Rx Memory for
    472  *      given OOBFC Rx interface.
    473  * Parameters:
    474  *      unit - (IN) StrataSwitch unit number.
    475  *      intf_id - (IN) OOBFC Rx Interface ID.
    476  *      look_base - (OUT) Lookup base in OOBFC Rx Memory
    477  * Returns:
    478  *      BCM_E_XXX
    479  */
    480 STATIC int
    481 _bcm_kt2_oob_fc_rx_intf_get_lookup_base(int unit,
    482                                 bcm_oob_fc_rx_intf_id_t intf_id,
    483                                 uint32 *lookup_base)
    484 {
    485     uint32 rval = 0x0;
    486     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
    487 
    488     BCM_IF_ERROR_RETURN
    489         (soc_reg32_get(unit, cfg_reg[intf_id], 0, 0, &rval));
    490 
    491     *lookup_base = soc_reg_field_get(unit, cfg_reg[intf_id], rval,
    492                                      LOOKUP_BASEf);
    493 
    494     return BCM_E_NONE;
    495 }
    496 
    497 
    498 /*
    499  * Function:
    500  *      bcm_kt2_oob_fc_tx_config_set
    501  * Purpose:
    502  *      Set OOB FC Tx global configuration.
    503  * Parameters:
    504  *      unit - (IN) StrataSwitch unit number.
    505  *      config - (IN) OOB FC Tx global configuration
    506  * Returns:
    507  *      BCM_E_XXX
    508  */
    509 int
    510 bcm_kt2_oob_fc_tx_config_set(int unit,
    511                             bcm_oob_fc_tx_config_t *config)
    512 {
    513     if (config == NULL) {
    514         return BCM_E_PARAM;
    515     }
    516 
    517     if ((config->gcs_id < 0) || (config->gcs_id >= BCM_KT2_MMU_NUM_POOL)) {
    518         return BCM_E_PARAM;
    519     }
    520 
    521     if ((config->egr_mode < 0) || (config->egr_mode >= bcmOOBFCTxReportCount)) {
    522         return BCM_E_PARAM;
    523     }
    524 
    525     /* Enabling/Disabling FCN, OOBFC Tx Ingress, Egress and Service Pool */ 
    526     BCM_IF_ERROR_RETURN
    527         (_bcm_kt2_oob_fc_tx_config_flags_set(unit, config->flags));
    528 
    529     /* Setting Inter packet Gap between two HCFC message */
    530     BCM_IF_ERROR_RETURN
    531         (_bcm_kt2_oob_fc_tx_config_ipg_set(unit, config->inter_pkt_gap));
    532 
    533     /* Setting service pool id whose congestion state will be
    534        reported in every HCFC message */
    535     BCM_IF_ERROR_RETURN
    536         (_bcm_kt2_oob_fc_tx_config_gcs_id_set(unit, config->gcs_id));
    537 
    538     /* Setting Egress mode for reporting OOBFC message. */
    539     BCM_IF_ERROR_RETURN
    540         (_bcm_kt2_oob_fc_tx_config_egr_mode_set(unit, config->egr_mode));
    541 
    542     return BCM_E_NONE;
    543 }
    544 
    545 /*
    546  * Function:
    547  *      bcm_kt2_oob_fc_tx_config_get
    548  * Purpose:
    549  *      Get OOB FC Tx global configuration.
    550  * Parameters:
    551  *      unit - (IN) StrataSwitch unit number.
    552  *      config - (OUT) OOB FC Tx global configuration
    553  * Returns:
    554  *      BCM_E_XXX
    555  */
    556 int
    557 bcm_kt2_oob_fc_tx_config_get(int unit,
    558                             bcm_oob_fc_tx_config_t *config)
    559 {
    560     if (config == NULL) {
    561         return BCM_E_PARAM;
    562     }
    563 
    564     /* Get the congestion state reporting status of FCN,
    565        OOBFC Tx Ingress, Egress and Service Pool */
    566     BCM_IF_ERROR_RETURN
    567         (_bcm_kt2_oob_fc_tx_config_flags_get(unit, config));
    568 
    569     /* Get the configured Inter Packet Gap between OOBFC Tx message.*/
    570     BCM_IF_ERROR_RETURN
    571         (_bcm_kt2_oob_fc_tx_config_ipg_get(unit, config));
    572 
    573     /* Setting service pool id whose congestion state will be
    574        reported in every HCFC message */
    575     BCM_IF_ERROR_RETURN
    576         (_bcm_kt2_oob_fc_tx_config_gcs_id_get(unit, config));
    577 
    578     /* Get the configured Egress mode of OOBFC Tx side */
    579     BCM_IF_ERROR_RETURN
    580         (_bcm_kt2_oob_fc_tx_config_egr_mode_get(unit, config));
    581 
    582     return BCM_E_NONE;
    583 }
    584 
    585 /*
    586  * Function:
    587  *      _bcm_kt2_oob_fc_tx_port_control_set
    588  * Purpose:
    589  *      Set OOB FC Tx Port configuration.
    590  * Parameters:
    591  *      unit - (IN) StrataSwitch unit number.
    592  *      gport - (IN) Modport Gport
    593  *      status - (IN) Status of Congestion State reporting 
    594  *      dir - (IN) Direction 0 = Ingreess, 1 = Egress
    595  * Returns:
    596  *      BCM_E_XXX
    597  */
    598 int
    599 _bcm_kt2_oob_fc_tx_port_control_set(int unit, bcm_port_t localport,
    600                               int status, int dir)
    601 {
    602     uint64 rval64;
    603     static const soc_field_t field[2] = {ING_PORT_ENf, ENG_PORT_ENf};
    604     static const soc_reg_t reg_kt2[2][1] = {
    605         {OOBFC_ING_PORT_EN_41r},
    606         {OOBFC_ENG_PORT_EN_41r}};
    607     static const soc_reg_t reg_sb2[2][1] = {
    608         {OOBFC_ING_PORT_EN_29r},
    609         {OOBFC_ENG_PORT_EN_29r}}; 
    610     int  max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
    611 
    612     if ((status != 1) && (status != 0)) {
    613         return BCM_E_PARAM;
    614     }
    615 
    616     if (dir > 1) {
    617         return BCM_E_PARAM;
    618     }
    619 
    620     COMPILER_64_ZERO(rval64);
    621 
    622     if (SOC_IS_SABER2(unit)) {
    623 #ifdef BCM_METROLITE_SUPPORT
    624         if (SOC_IS_METROLITE(unit))  {
    625             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;  
    626         } else 
    627 #endif
    628         {
    629             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
    630         }  
    631         if ((0 <= localport) && (localport < max_rx_mem_entry)) {
    632             BCM_IF_ERROR_RETURN
    633                   (soc_reg64_get(unit, reg_sb2[dir][0], 0, 0, &rval64));
    634             if (((status == 1) && (!COMPILER_64_BITTEST(rval64, localport))) ||
    635                ((status == 0) && (COMPILER_64_BITTEST(rval64, localport)))) {
    636                  if (status == 1) {
    637                      COMPILER_64_BITSET(rval64, localport);
    638                  } else {
    639                      COMPILER_64_BITCLR(rval64, localport);
    640                  }
    641                  soc_reg64_field_set(unit, reg_sb2[dir][0], &rval64,
    642                                 field[dir], rval64);
    643                  BCM_IF_ERROR_RETURN
    644                         (soc_reg64_set(unit, reg_sb2[dir][0], 0, 0, rval64));
    645             }
    646         } else {
    647             return BCM_E_PARAM;
    648         }
    649     } else if (SOC_IS_KATANA2(unit)) {
    650         if ((0 <= localport) && (localport < max_rx_mem_entry)) { 
    651             BCM_IF_ERROR_RETURN
    652                   (soc_reg64_get(unit, reg_kt2[dir][0], 0, 0, &rval64));
    653             if (((status == 1) && (!COMPILER_64_BITTEST(rval64, localport))) ||
    654                ((status == 0) && (COMPILER_64_BITTEST(rval64, localport)))) {
    655                  if (status == 1) {
    656                       COMPILER_64_BITSET(rval64, localport);
    657                  } else {
    658                      COMPILER_64_BITCLR(rval64, localport);
    659                  }
    660                  soc_reg64_field_set(unit, reg_kt2[dir][0], &rval64,
    661                         field[dir], rval64);
    662                  BCM_IF_ERROR_RETURN 
    663                        (soc_reg64_set(unit, reg_kt2[dir][0], 0, 0, rval64)); 
    664             }  
    665         } else {
    666             return BCM_E_PARAM;
    667         }
    668     } 
    669     return BCM_E_NONE;
    670 }
    671 
    672 /*
    673  * Function:
    674  *      _bcm_kt2_oob_fc_tx_port_control_get
    675  * Purpose:
    676  *      Get OOB FC Tx side Port configuration.
    677  * Parameters:
    678  *      unit - (IN) StrataSwitch unit number.
    679  *      gport - (IN) Modport Gport
    680  *      status - (OUT) Status of Congestion State reporting 
    681  *      dir - (IN) Direction 0 = Ingreess, 1 = Egress
    682  * Returns:
    683  *      BCM_E_XXX
    684  */
    685 int
    686 _bcm_kt2_oob_fc_tx_port_control_get(int unit, bcm_port_t localport,
    687                                  int *status, int dir)
    688 {
    689     uint64 rval64;
    690     static const soc_reg_t reg_kt2[2][1] = {
    691         {OOBFC_ING_PORT_EN_41r},
    692         {OOBFC_ENG_PORT_EN_41r}};
    693     static const soc_reg_t reg_sb2[2][1] = {
    694         {OOBFC_ING_PORT_EN_29r},
    695         {OOBFC_ENG_PORT_EN_29r}};
    696     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY; 
    697     if (dir > 1) {
    698         return BCM_E_PARAM;
    699     }
    700 
    701     COMPILER_64_ZERO(rval64);
    702 
    703     if (SOC_IS_SABER2(unit)) {
    704 #ifdef BCM_METROLITE_SUPPORT
    705         if (SOC_IS_METROLITE(unit))  {
    706             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
    707         } else 
    708 #endif
    709         {
    710             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
    711         } 
    712         if ((0 <= localport) && (localport < max_rx_mem_entry)) {
    713             BCM_IF_ERROR_RETURN
    714                (soc_reg64_get(unit, reg_sb2[dir][0], 0, 0, &rval64));
    715         } else {
    716             return BCM_E_PARAM;
    717         }
    718     } else if (SOC_IS_KATANA2(unit)) {
    719         if ((0 <= localport) && (localport < max_rx_mem_entry)) {
    720             BCM_IF_ERROR_RETURN   
    721                (soc_reg64_get(unit, reg_kt2[dir][0], 0, 0, &rval64));
    722         } else {
    723             return BCM_E_PARAM;
    724         }
    725     }
    726 
    727     if (COMPILER_64_BITTEST(rval64, localport)) {
    728         *status = 0x1;
    729     } else {
    730         *status = 0x0;
    731     }
    732     return BCM_E_NONE;
    733 }
    734 
    735 /*
    736 * Function:
    737 *      bcm_kt2_oob_fc_tx_info_get
    738 * Purpose:
    739 *      Get OOB FC Tx global information.
    740 * Parameters:
    741 *      unit - (IN) StrataSwitch unit number.
    742 *      info - (OUT) OOB FC Tx global information
    743 * Returns:
    744 *      BCM_E_XXX
    745 */
    746 int
    747 bcm_kt2_oob_fc_tx_info_get(int unit, bcm_oob_fc_tx_info_t *info)
    748 {
    749     uint64 rval64;
    750 
    751     if (info == NULL) {
    752         return BCM_E_PARAM;
    753     }
    754 
    755     BCM_IF_ERROR_RETURN
    756         (soc_reg64_get(unit, OOBFC_CHANNEL_BASE_64r,
    757                        0, 0, &rval64));
    758 
    759     /* Get the Channel base value for HCFC messages containing
    760        congestion state of different resources */
    761     /* Ingress Ports */
    762     info->ing_base =  (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r,
    763                                                    rval64, ING_BASEf);
    764 
    765     /* Egress Unicast Queue */
    766     info->ucast_base =  (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r,
    767                                                      rval64, ENGU_BASEf);
    768 
    769     /* Egress Multicast Queue */
    770     info->mcast_base =  (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r,
    771                                                      rval64, ENGM_BASEf);
    772 
    773     /* Egress Cos Queue */
    774     info->cos_base =  (uint8)soc_reg64_field32_get(unit, OOBFC_CHANNEL_BASE_64r,
    775                                                    rval64, ENGG_BASEf);
    776 
    777     return BCM_E_NONE;
    778 }
    779 
    780 /*
    781  * Function:
    782  *      _bcm_kt2_oob_fc_rx_config_enable_set
    783  * Purpose:
    784  *      Enable and configure the given OOB FC Rx Interface
    785  * Parameters:
    786  *      unit - (IN) StrataSwitch unit number
    787  *      intf_id - (IN) OOB FC Rx Interface Number
    788  *      channel_base - (IN) HCFC channel base
    789  *      array_count - (IN) Number of gports in the gport array
    790  *      gport_array - (IN) Array of modport type gport
    791  * Returns:
    792  *      BCM_E_XXX
    793  */
    794 STATIC int
    795 _bcm_kt2_oob_fc_rx_config_enable_set(int unit,
    796                             bcm_oob_fc_rx_intf_id_t intf_id,
    797                             uint8 channel_base,
    798                             int array_count,
    799                             bcm_gport_t *gport_array)
    800 {
    801     _bcm_kt2_oob_fc_rx_intf_info_t info[BCM_KT2_NUM_OOB_FC_RX_INTF];
    802     char *sysport_buf, *tc2pri_buf;
    803     uint32 sysport_list[BCM_KT2_MAX_RX_MEM_ENTRY];
    804     int rv = BCM_E_INTERNAL;
    805     void *pentry1, *pentry2;
    806     uint32 rval = 0x0;
    807     int mem_wsz = 0;
    808     int i = 0, total_num_ports = 0;
    809     int  max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
    810     bcm_port_t localport = 0;
    811     uint64 tc_to_pri_mapping;
    812     uint32 tc_to_pri_mapping_low = 0x0;
    813     uint32 tc_to_pri_mapping_high = 0x0;
    814     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
    815    
    816     if (SOC_IS_SABER2(unit)) {
    817 #ifdef BCM_METROLITE_SUPPORT
    818         if (SOC_IS_METROLITE(unit))  {
    819             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
    820         } else 
    821 #endif
    822         {
    823             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
    824         } 
    825     } 
    826     COMPILER_64_ZERO(tc_to_pri_mapping);
    827    
    828     sal_memset(info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) *
    829                BCM_KT2_NUM_OOB_FC_RX_INTF);
    830     sal_memset(sysport_list, 0, sizeof(uint32) *
    831                BCM_KT2_MAX_RX_MEM_ENTRY);
    832 
    833     /* Backup the per OOBFC Rx interface configuration */
    834     for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) {
    835         BCM_IF_ERROR_RETURN
    836             (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &info[i], i));
    837         /* Compute the total number of ports which is
    838            already configured */
    839         if (info[i].enable == 1) {
    840             total_num_ports += info[i].num_ports;
    841         }
    842     }
    843 
    844     /* Return error if trying to enable already enabled
    845        OOBFC Rx Interface */
    846     if (info[intf_id].enable == 1) {
    847         return BCM_E_PARAM;
    848     }
    849 
    850     /* Return error if there is no room in memory to accomodate
    851        the list of ports which need to programmed in memory */
    852     if ((total_num_ports + array_count) > max_rx_mem_entry) {
    853         return BCM_E_PARAM;
    854     }
    855 
    856     /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */
    857     mem_wsz = sizeof(uint32) *
    858                 soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm);
    859     sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
    860                                 "oob sysport_buf");
    861     if (sysport_buf == NULL) {
    862         return BCM_E_MEMORY;
    863     }
    864 
    865     if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL,
    866                            0, max_rx_mem_entry - 1, sysport_buf)) {
    867         rv = BCM_E_INTERNAL;
    868         soc_cm_sfree(unit, sysport_buf);
    869         return rv;
    870     }
    871 
    872     /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */
    873     mem_wsz = sizeof(uint32) *
    874                 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm);
    875     tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
    876                                "oob tc2pri_buf");
    877     if (tc2pri_buf == NULL) {
    878         rv = BCM_E_MEMORY;
    879         soc_cm_sfree(unit, sysport_buf);
    880         return rv;
    881     }
    882 
    883     if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
    884                            0, max_rx_mem_entry - 1, tc2pri_buf)) {
    885         rv = BCM_E_INTERNAL;
    886         soc_cm_sfree(unit, tc2pri_buf);
    887         soc_cm_sfree(unit, sysport_buf);
    888         return rv;
    889     }
    890 
    891     /* Creating a list of logical port number from a list of
    892        modport gport */
    893     for (i = 0; i < array_count; i++) {
    894         rv = _bcm_kt2_oob_localport_resolve(unit, gport_array[i],
    895                                            &localport);
    896         if (rv != BCM_E_NONE) {
    897             soc_cm_sfree(unit, tc2pri_buf);
    898             soc_cm_sfree(unit, sysport_buf);
    899             return rv;
    900         }
    901         sysport_list[i] = localport;
    902     }
    903 
    904     /* Fill the info structure for the given interface */
    905     info[intf_id].enable = 1;
    906     info[intf_id].channel_base = channel_base;
    907     info[intf_id].lookup_base = total_num_ports;
    908     info[intf_id].num_ports = array_count;
    909 
    910     /* Program sysport_list in MMU_CHFC_SYSPORT_MAPPING */
    911     /* Program default value into MMU_INTFO_TC2PRI_MAPPING */
    912     for (i = 0; i < array_count; i++) {
    913         pentry1 = soc_mem_table_idx_to_pointer(unit,
    914                                                MMU_CHFC_SYSPORT_MAPPINGm,
    915                                                void*, sysport_buf,
    916                                                (total_num_ports + i));
    917         pentry2 = soc_mem_table_idx_to_pointer(unit,
    918                                                MMU_INTFO_TC2PRI_MAPPINGm,
    919                                                void*, tc2pri_buf,
    920                                                (total_num_ports + i));
    921         soc_mem_field32_set(unit, MMU_CHFC_SYSPORT_MAPPINGm, pentry1,
    922                             SYS_PORTf, sysport_list[i]);
    923         /* TC to PRI Mapping Default Value is unity mapped
    924            TC=7 mapped PRI=7 0x80 (bits 63-56)
    925            TC=6 mapped PRI=6 0x40 (bits 55-48)
    926            TC=5 mapped PRI=5 0x20 (bits 47-40) 
    927            TC=4 mapped PRI=4 0x10 (bits 39-32)
    928            TC=3 mapped PRI=3 0x08 (bits 31-24)
    929            TC=2 mapped PRI=2 0x04 (bits 23-16)
    930            TC=1 mapped PRI=1 0x02 (bits 15-8)
    931            TC=0 mapped PRI=0 0x01 (bits 7-0)
    932          */
    933         tc_to_pri_mapping_high |= 0x80 << 24;
    934         tc_to_pri_mapping_high |= 0x40 << 16;
    935         tc_to_pri_mapping_high |= 0x20 << 8;
    936         tc_to_pri_mapping_high |= 0x10;
    937         tc_to_pri_mapping_low |= 0x08 << 24;
    938         tc_to_pri_mapping_low |= 0x04 << 16;
    939         tc_to_pri_mapping_low |= 0x02 << 8;
    940         tc_to_pri_mapping_low |= 0x01;
    941 
    942         COMPILER_64_SET(tc_to_pri_mapping, tc_to_pri_mapping_high,
    943                         tc_to_pri_mapping_low);
    944 
    945         soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm,
    946                             pentry2, PRI_BMPf, tc_to_pri_mapping);
    947     }
    948 
    949     if (soc_mem_write_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL,
    950                             0, max_rx_mem_entry - 1, sysport_buf)) {
    951         rv = BCM_E_INTERNAL;
    952         soc_cm_sfree(unit, tc2pri_buf);
    953         soc_cm_sfree(unit, sysport_buf);
    954         return rv;
    955     }
    956 
    957     if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
    958                             0, max_rx_mem_entry - 1, tc2pri_buf)) {
    959         rv = BCM_E_INTERNAL;
    960         soc_cm_sfree(unit, tc2pri_buf);
    961         soc_cm_sfree(unit, sysport_buf);
    962         return rv;
    963     }
    964 
    965     /* Program the given interface configuration register.*/
    966     rv = soc_reg32_get(unit, cfg_reg[intf_id],
    967                        0, 0, &rval);
    968     if (rv != BCM_E_NONE) {
    969         soc_cm_sfree(unit, tc2pri_buf);
    970         soc_cm_sfree(unit, sysport_buf);
    971         return rv;
    972     }
    973     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    974                       OOBFC_CH_ENf, info[intf_id].enable);
    975     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    976                       OOBFC_CH_BASEf, info[intf_id].channel_base);
    977     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    978                       LOOKUP_BASEf, info[intf_id].lookup_base);
    979     soc_reg_field_set(unit, cfg_reg[intf_id], &rval,
    980                       CH_PORT_NUMf, info[intf_id].num_ports);
    981     rv = soc_reg32_set(unit, cfg_reg[intf_id],
    982                        0, 0, rval);
    983     if (rv != BCM_E_NONE) {
    984         soc_cm_sfree(unit, tc2pri_buf);
    985         soc_cm_sfree(unit, sysport_buf);
    986         return rv;
    987     }
    988 
    989     rv = BCM_E_NONE;
    990     soc_cm_sfree(unit, tc2pri_buf);
    991     soc_cm_sfree(unit, sysport_buf);
    992     return rv;
    993 }
    994 
    995 /*
    996  * Function:
    997  *      _bcm_kt2_oob_fc_rx_port_offset_get
    998  * Purpose:
    999  *      Get the channel offset value for a given port
   1000  *      in the HCFC message received on a given OOB FC
   1001  *      Rx Interface
   1002  * Parameters:
   1003  *      unit - (IN) StrataSwitch unit number
   1004  *      intf_id - (IN) OOB FC Rx Interface Number
   1005  *      gport - (IN) Modport gport
   1006  *      offset - (OUT) Channel offset value
   1007  * Returns:
   1008  *      BCM_E_XXX
   1009  */
   1010 STATIC int
   1011 _bcm_kt2_oob_fc_rx_port_offset_get(int unit,
   1012                          bcm_oob_fc_rx_intf_id_t intf_id,
   1013                          bcm_gport_t gport,
   1014                          uint32 *offset)
   1015 {
   1016     bcm_oob_fc_rx_config_t config;
   1017     bcm_gport_t gport_array[BCM_KT2_MAX_RX_MEM_ENTRY] = {0x0};
   1018     int array_count = 0, i = 0;
   1019     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
   1020 
   1021     if (SOC_IS_SABER2(unit)) {
   1022 #ifdef BCM_METROLITE_SUPPORT
   1023         if (SOC_IS_METROLITE(unit))  {
   1024             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
   1025         } else 
   1026 #endif
   1027         {
   1028             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
   1029         } 
   1030     } 
   1031 
   1032     /* Get the configured list of gport array
   1033        and array count*/
   1034     BCM_IF_ERROR_RETURN
   1035         (bcm_kt2_oob_fc_rx_config_get(unit, intf_id, &config,
   1036                                       max_rx_mem_entry, gport_array,
   1037                                      &array_count));
   1038 
   1039     if (config.enable == 0) {
   1040         return BCM_E_PARAM;
   1041     }
   1042 
   1043     /* Get the Channel offset of the port in HCFC message */
   1044     for (i = 0; i < array_count; i++) {
   1045         if (gport == gport_array[i]) {
   1046             break;
   1047         }
   1048     }
   1049 
   1050     /* Return error if gport is not there in the list */
   1051     if (i == array_count) {
   1052         return BCM_E_NOT_FOUND;
   1053     }
   1054 
   1055     *offset = i;
   1056     
   1057     return BCM_E_NONE;
   1058 }
   1059 
   1060 /*
   1061  * Function:
   1062  *      _bcm_kt2_oob_fc_rx_tc_mapping_get
   1063  * Purpose:
   1064  *      Get the traffic class to priority
   1065  *      mapping for given OOB FC Rx Interface at
   1066  *      given idx in the memory.
   1067  * Parameters:
   1068  *      unit - (IN) StrataSwitch unit number
   1069  *      intf_id - (IN) OOB FC Rx Interface Number
   1070  *      tc - (IN) Traffic Class array[0-7]
   1071  *      pri_bmp - (OUT) Priority Bitmap[0-7]
   1072  *      idx - (IN) Index in TC to PRI mapping memory
   1073  * Returns:
   1074  *      BCM_E_XXX
   1075  */
   1076 STATIC int
   1077 _bcm_kt2_oob_fc_rx_tc_mapping_get(int unit,
   1078                         bcm_oob_fc_rx_intf_id_t intf_id,
   1079                         uint32 tc, uint32 *pri_bmp,
   1080                         uint32 idx)
   1081 {
   1082     char *tc2pri_buf;
   1083     uint64 tc2pri;
   1084     void *pentry;
   1085     int mem_wsz = 0;
   1086     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
   1087 
   1088     if (SOC_IS_SABER2(unit)) {
   1089 #ifdef BCM_METROLITE_SUPPORT
   1090         if (SOC_IS_METROLITE(unit))  {
   1091             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
   1092         } else 
   1093 #endif
   1094         {
   1095             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
   1096         } 
   1097     }
   1098     COMPILER_64_ZERO(tc2pri);
   1099 
   1100     /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */
   1101     mem_wsz = sizeof(uint32) *
   1102                 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm);
   1103     tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
   1104                                          "oob tc2pri_buf");
   1105     if (tc2pri_buf == NULL) {
   1106         return BCM_E_MEMORY;
   1107     }
   1108 
   1109     if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
   1110                            0, max_rx_mem_entry - 1, tc2pri_buf)) {
   1111         soc_cm_sfree(unit, tc2pri_buf);
   1112         return BCM_E_INTERNAL;
   1113     }
   1114 
   1115     /* Get the pointer to the given index. */
   1116     pentry = soc_mem_table_idx_to_pointer(unit,
   1117                                           MMU_INTFO_TC2PRI_MAPPINGm,
   1118                                           void*, tc2pri_buf, idx);
   1119 
   1120     soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm,
   1121                         pentry, PRI_BMPf, &tc2pri);
   1122 
   1123     /* Get tc2pri value */
   1124     COMPILER_64_SHR(tc2pri, (8 * tc));
   1125     *pri_bmp = COMPILER_64_LO(tc2pri) & 0xFF;
   1126 
   1127     soc_cm_sfree(unit, tc2pri_buf);
   1128     return BCM_E_NONE;
   1129 }
   1130 
   1131 /*
   1132  * Function:
   1133  *      _bcm_kt2_oob_fc_rx_tc_mapping_set
   1134  * Purpose:
   1135  *      Set the traffic class to priority
   1136  *      mapping for given OOB FC Rx Interface at
   1137  *      given idx in the memory.
   1138  * Parameters:
   1139  *      unit - (IN) StrataSwitch unit number
   1140  *      intf_id - (IN) OOB FC Rx Interface Number
   1141  *      tc - (IN) Traffic Class array[0-7]
   1142  *      pri_bmp - (IN) Priority Bitmap[0-7]
   1143  *      idx - (IN) Index in TC to PRI mapping memory
   1144  * Returns:
   1145  *      BCM_E_XXX
   1146  */
   1147 STATIC int
   1148 _bcm_kt2_oob_fc_rx_tc_mapping_set(int unit,
   1149                           bcm_oob_fc_rx_intf_id_t intf_id, uint32 tc,
   1150                           uint32 pri_bmp, uint32 idx)
   1151 {
   1152     char *tc2pri_buf;
   1153     uint64 tc2pri;
   1154     uint64 mask64;
   1155     uint64 pri_bmp64;
   1156     int rv = BCM_E_INTERNAL;
   1157     void *pentry;
   1158     int mem_wsz = 0;
   1159     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
   1160 
   1161     if (SOC_IS_SABER2(unit)) {
   1162 #ifdef BCM_METROLITE_SUPPORT
   1163         if (SOC_IS_METROLITE(unit))  {
   1164             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
   1165         } else 
   1166 #endif
   1167         {
   1168             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
   1169         } 
   1170     }
   1171     COMPILER_64_ZERO(tc2pri);
   1172     COMPILER_64_ZERO(mask64);
   1173     COMPILER_64_ZERO(pri_bmp64);
   1174 
   1175     /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_buf */
   1176     mem_wsz = sizeof(uint32) *
   1177                 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm);
   1178     tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
   1179                                          "oob tc2pri_buf");
   1180     if (tc2pri_buf == NULL) {
   1181         return BCM_E_MEMORY;
   1182     }
   1183 
   1184     if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
   1185                            0, max_rx_mem_entry - 1, tc2pri_buf)) {
   1186         rv = BCM_E_INTERNAL;
   1187         soc_cm_sfree(unit, tc2pri_buf);
   1188         return rv;
   1189     }
   1190 
   1191     /* Get the pointer to the given index. */
   1192     pentry = soc_mem_table_idx_to_pointer(unit,
   1193                                           MMU_INTFO_TC2PRI_MAPPINGm,
   1194                                           void*, tc2pri_buf, idx);
   1195 
   1196     soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm,
   1197                         pentry, PRI_BMPf, &tc2pri);
   1198 
   1199 
   1200     /* Disable the given OOBFC Rx interface */
   1201     rv = _bcm_kt2_oob_fc_rx_disable_intf(unit, intf_id);
   1202     if (rv != BCM_E_NONE) {
   1203         soc_cm_sfree(unit, tc2pri_buf);
   1204         return rv;
   1205     }
   1206 
   1207     /* Update tc2pri value */
   1208     COMPILER_64_SET(pri_bmp64, 0, pri_bmp);
   1209     COMPILER_64_SHL(pri_bmp64, (tc * 8));
   1210     COMPILER_64_MASK_CREATE(mask64, 8, (tc * 8));
   1211     COMPILER_64_NOT(mask64);
   1212     COMPILER_64_AND(tc2pri, mask64);
   1213     COMPILER_64_OR(tc2pri, pri_bmp64);
   1214 
   1215     /* Program tc2pri MMU_INTFO_TC2PRI_MAPPING */
   1216     soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm,
   1217                         pentry, PRI_BMPf, tc2pri);
   1218 
   1219     if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
   1220                             0, max_rx_mem_entry - 1, tc2pri_buf)) {
   1221         rv = BCM_E_INTERNAL;
   1222         soc_cm_sfree(unit, tc2pri_buf);
   1223         return rv;
   1224     }
   1225 
   1226     /* Enable the given OOBFC Rx interface back */
   1227     rv = _bcm_kt2_oob_fc_rx_enable_intf(unit, intf_id);
   1228     if (rv != BCM_E_NONE) {
   1229         soc_cm_sfree(unit, tc2pri_buf);
   1230         return rv;
   1231     }
   1232 
   1233     rv = BCM_E_NONE;
   1234     soc_cm_sfree(unit, tc2pri_buf);
   1235     return rv;
   1236 }
   1237 
   1238 /*
   1239  * Function:
   1240  *      _bcm_kt2_oob_fc_rx_config_disable_set
   1241  * Purpose:
   1242  *      Disable and reset the configuration of the
   1243  *      given OOB FC Rx Interface
   1244  * Parameters:
   1245  *      unit - (IN) StrataSwitch unit number
   1246  *      intf_id - (IN) OOB FC Rx Interface Number
   1247  * Returns:
   1248  *      BCM_E_XXX
   1249  */
   1250 STATIC int
   1251 _bcm_kt2_oob_fc_rx_config_disable_set(int unit,
   1252                             bcm_oob_fc_rx_intf_id_t intf_id)
   1253 {
   1254     _bcm_kt2_oob_fc_rx_intf_info_t old_info[BCM_KT2_NUM_OOB_FC_RX_INTF];
   1255     _bcm_kt2_oob_fc_rx_intf_info_t new_info[BCM_KT2_NUM_OOB_FC_RX_INTF];
   1256     char *sysport_buf, *tc2pri_buf;
   1257     uint32 *old_sysport_list = NULL;
   1258     uint64 *old_tc2pri_list = NULL;
   1259     uint32 *new_sysport_list = NULL;
   1260     uint64 *new_tc2pri_list = NULL;
   1261     int rv = BCM_E_INTERNAL;
   1262     int mem_wsz = 0;
   1263     int i = 0, j = 0, k = 0;
   1264     void *pentry;
   1265     uint32 rval = 0x0;
   1266     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
   1267     soc_reg_t cfg_reg[BCM_KT2_NUM_OOB_FC_RX_INTF] = {OOBFC_CHIF_CFGr};
   1268 
   1269 
   1270     old_sysport_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint32),
   1271                                          "oob old_sysport_list");
   1272     if (old_sysport_list == NULL) {
   1273         return BCM_E_MEMORY;
   1274     }
   1275     old_tc2pri_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint64),
   1276                                          "oob old_tc2pri_list");
   1277     if (old_tc2pri_list == NULL) {
   1278         soc_cm_sfree(unit, old_sysport_list);
   1279         return BCM_E_MEMORY;
   1280     }
   1281     
   1282     new_sysport_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint32),
   1283                                          "oob new_sysport_list");
   1284     if (new_sysport_list == NULL) {
   1285         soc_cm_sfree(unit, old_sysport_list);
   1286         soc_cm_sfree(unit, old_tc2pri_list);
   1287         return BCM_E_MEMORY;
   1288     }
   1289 
   1290     new_tc2pri_list = soc_cm_salloc(unit, BCM_KT2_MAX_RX_MEM_ENTRY * sizeof(uint64),
   1291                                          "oob new_tc2pri_list");
   1292     if (new_tc2pri_list == NULL) {
   1293         soc_cm_sfree(unit, old_sysport_list);
   1294         soc_cm_sfree(unit, old_tc2pri_list);
   1295         soc_cm_sfree(unit, new_sysport_list);
   1296         return BCM_E_MEMORY;
   1297     }
   1298     if (SOC_IS_SABER2(unit)) {
   1299 #ifdef BCM_METROLITE_SUPPORT
   1300         if (SOC_IS_METROLITE(unit))  {
   1301             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
   1302         } else 
   1303 #endif
   1304         {
   1305             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
   1306         } 
   1307     } 
   1308 
   1309     sal_memset(old_info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) *
   1310                BCM_KT2_NUM_OOB_FC_RX_INTF);
   1311     sal_memset(new_info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t) *
   1312                BCM_KT2_NUM_OOB_FC_RX_INTF);
   1313     sal_memset(old_sysport_list, 0, sizeof(uint32) *
   1314                BCM_KT2_MAX_RX_MEM_ENTRY);
   1315     sal_memset(new_sysport_list, 0, sizeof(uint32) *
   1316                BCM_KT2_MAX_RX_MEM_ENTRY);
   1317     sal_memset(old_tc2pri_list, 0, sizeof(uint64) *
   1318                BCM_KT2_MAX_RX_MEM_ENTRY);
   1319     sal_memset(new_tc2pri_list, 0, sizeof(uint64) *
   1320                BCM_KT2_MAX_RX_MEM_ENTRY);
   1321 
   1322     /* Store all the OOBFC Rx interface configuration */
   1323     for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) {
   1324         BCM_IF_ERROR_RETURN
   1325             (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &old_info[i], i));
   1326     }
   1327 
   1328     /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */
   1329     mem_wsz = sizeof(uint32) *
   1330                 soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm);
   1331     sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
   1332                                          "oob sysport_buf");
   1333     if (sysport_buf == NULL) {
   1334         soc_cm_sfree(unit, old_sysport_list);
   1335         soc_cm_sfree(unit, old_tc2pri_list);
   1336         soc_cm_sfree(unit, new_sysport_list);
   1337         soc_cm_sfree(unit, new_tc2pri_list);
   1338         return BCM_E_MEMORY;
   1339     }
   1340 
   1341     if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL,
   1342                            0, max_rx_mem_entry - 1, sysport_buf)) {
   1343         rv = BCM_E_INTERNAL;
   1344         soc_cm_sfree(unit, old_sysport_list);
   1345         soc_cm_sfree(unit, old_tc2pri_list);
   1346         soc_cm_sfree(unit, new_sysport_list);
   1347         soc_cm_sfree(unit, new_tc2pri_list);
   1348         soc_cm_sfree(unit, sysport_buf);
   1349         return rv;
   1350     }
   1351 
   1352     /* Store the sysport_buf in old_sysport_list */
   1353     for (i = 0; i < max_rx_mem_entry; i++) {
   1354         pentry = soc_mem_table_idx_to_pointer(unit,
   1355                                               MMU_CHFC_SYSPORT_MAPPINGm,
   1356                                               void*, sysport_buf, i);
   1357         old_sysport_list[i] = soc_mem_field32_get(unit,
   1358                                                   MMU_CHFC_SYSPORT_MAPPINGm,
   1359                                                   pentry, SYS_PORTf);
   1360     }
   1361 
   1362     /* Read the MMU_INTFO_TC2PRI_MAPPING memory into tc2pri_list */
   1363     mem_wsz = sizeof(uint32) *
   1364                 soc_mem_entry_words(unit, MMU_INTFO_TC2PRI_MAPPINGm);
   1365     tc2pri_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
   1366                                          "oob tc2pri_buf");
   1367     if (tc2pri_buf == NULL) {
   1368         rv = BCM_E_MEMORY;
   1369         soc_cm_sfree(unit, old_sysport_list);
   1370         soc_cm_sfree(unit, old_tc2pri_list);
   1371         soc_cm_sfree(unit, new_sysport_list);
   1372         soc_cm_sfree(unit, new_tc2pri_list);
   1373         soc_cm_sfree(unit, sysport_buf);
   1374         return rv;
   1375     }
   1376 
   1377     if (soc_mem_read_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
   1378                            0, max_rx_mem_entry - 1, tc2pri_buf)) {
   1379         rv = BCM_E_INTERNAL;
   1380         soc_cm_sfree(unit, old_sysport_list);
   1381         soc_cm_sfree(unit, old_tc2pri_list);
   1382         soc_cm_sfree(unit, new_sysport_list);
   1383         soc_cm_sfree(unit, new_tc2pri_list);
   1384         soc_cm_sfree(unit, tc2pri_buf);
   1385         soc_cm_sfree(unit, sysport_buf);
   1386         return rv;
   1387     }
   1388 
   1389     /* Store the tc2pri_buf in old_tc2pri_list */
   1390     for (i = 0; i < max_rx_mem_entry; i++) {
   1391         pentry = soc_mem_table_idx_to_pointer(unit,
   1392                                               MMU_INTFO_TC2PRI_MAPPINGm,
   1393                                               void*, tc2pri_buf, i);
   1394         soc_mem_field64_get(unit, MMU_INTFO_TC2PRI_MAPPINGm,
   1395                             pentry, PRI_BMPf, &old_tc2pri_list[i]);
   1396     }
   1397 
   1398     /* Disable all the OOBFC Rx interface */
   1399     for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) {
   1400         if (old_info[i].enable == 1) {
   1401             rv = _bcm_kt2_oob_fc_rx_disable_intf(unit, i);
   1402             if (rv != BCM_E_NONE) {
   1403                 soc_cm_sfree(unit, tc2pri_buf);
   1404                 soc_cm_sfree(unit, sysport_buf);
   1405                 soc_cm_sfree(unit, old_sysport_list);
   1406                 soc_cm_sfree(unit, old_tc2pri_list);
   1407                 soc_cm_sfree(unit, new_sysport_list);
   1408                 soc_cm_sfree(unit, new_tc2pri_list);
   1409                 return rv;
   1410             }
   1411         }
   1412     }
   1413 
   1414     /* Generate new_info */
   1415     /* Genrate new_sysport_list */
   1416     /* Genrate new_tc2pri_list */
   1417     j = 0;
   1418     k = 0;
   1419     for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) {
   1420         if (i != intf_id) {
   1421             new_info[i].enable = old_info[i].enable;
   1422             new_info[i].channel_base = old_info[i].channel_base;
   1423             new_info[i].num_ports = old_info[i].num_ports;
   1424             if (new_info[i].enable) {
   1425                 new_info[i].lookup_base = j;
   1426             } else {
   1427                 new_info[i].lookup_base = 0x0;
   1428             }
   1429             for (k = 0; k < new_info[i].num_ports; k++) {
   1430                 new_sysport_list[j] = old_sysport_list[old_info[i].lookup_base + k];
   1431                 new_tc2pri_list[j] = old_tc2pri_list[old_info[i].lookup_base + k];
   1432                 j++;
   1433             }
   1434         } else {
   1435             new_info[i].enable = 0;
   1436             new_info[i].channel_base = 0;
   1437             new_info[i].lookup_base = 0;
   1438             new_info[i].num_ports = 0;
   1439         }
   1440     }
   1441 
   1442     /* Program new_tc2pri_list in MMU_INTFO_TC2PRI_MAPPING */
   1443     for (i = 0; i < max_rx_mem_entry; i++) {
   1444         pentry = soc_mem_table_idx_to_pointer(unit,
   1445                                               MMU_INTFO_TC2PRI_MAPPINGm,
   1446                                               void*, tc2pri_buf, i);
   1447         soc_mem_field64_set(unit, MMU_INTFO_TC2PRI_MAPPINGm,
   1448                             pentry, PRI_BMPf, new_tc2pri_list[i]);
   1449     }
   1450 
   1451     if (soc_mem_write_range(unit, MMU_INTFO_TC2PRI_MAPPINGm, MEM_BLOCK_ALL,
   1452                             0, max_rx_mem_entry - 1, tc2pri_buf)) {
   1453         rv = BCM_E_INTERNAL;
   1454         soc_cm_sfree(unit, tc2pri_buf);
   1455         soc_cm_sfree(unit, sysport_buf);
   1456         soc_cm_sfree(unit, old_sysport_list);
   1457         soc_cm_sfree(unit, old_tc2pri_list);
   1458         soc_cm_sfree(unit, new_sysport_list);
   1459         soc_cm_sfree(unit, new_tc2pri_list);
   1460         return rv;
   1461     }
   1462 
   1463     /* Program new_sysport_list MMU_CHFC_SYSPORT_MAPPING */
   1464     for (i = 0; i < max_rx_mem_entry; i++) {
   1465         pentry = soc_mem_table_idx_to_pointer(unit,
   1466                                               MMU_CHFC_SYSPORT_MAPPINGm,
   1467                                               void*, sysport_buf, i);
   1468         soc_mem_field32_set(unit, MMU_CHFC_SYSPORT_MAPPINGm, pentry,
   1469                             SYS_PORTf, new_sysport_list[i]);
   1470     }
   1471 
   1472     if (soc_mem_write_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL,
   1473                             0, max_rx_mem_entry - 1, sysport_buf)) {
   1474         rv = BCM_E_INTERNAL;
   1475         soc_cm_sfree(unit, old_sysport_list);
   1476         soc_cm_sfree(unit, old_tc2pri_list);
   1477         soc_cm_sfree(unit, new_sysport_list);
   1478         soc_cm_sfree(unit, new_tc2pri_list);
   1479         soc_cm_sfree(unit, tc2pri_buf);
   1480         soc_cm_sfree(unit, sysport_buf);
   1481         return rv;
   1482     }
   1483 
   1484     /* Program all the OOBFC Rx interface configuration register */
   1485     for (i = 0; i < BCM_KT2_NUM_OOB_FC_RX_INTF; i++) {
   1486         rv = soc_reg32_get(unit, cfg_reg[i],
   1487                            0, 0, &rval);
   1488         if (rv != BCM_E_NONE) {
   1489             soc_cm_sfree(unit, old_sysport_list);
   1490             soc_cm_sfree(unit, old_tc2pri_list);
   1491             soc_cm_sfree(unit, new_sysport_list);
   1492             soc_cm_sfree(unit, new_tc2pri_list);
   1493             soc_cm_sfree(unit, tc2pri_buf);
   1494             soc_cm_sfree(unit, sysport_buf);
   1495             return rv;
   1496         }
   1497         soc_reg_field_set(unit, cfg_reg[i], &rval,
   1498                           OOBFC_CH_ENf, new_info[i].enable);
   1499         soc_reg_field_set(unit, cfg_reg[i], &rval,
   1500                           OOBFC_CH_BASEf, new_info[i].channel_base);
   1501         soc_reg_field_set(unit, cfg_reg[i], &rval,
   1502                           LOOKUP_BASEf, new_info[i].lookup_base);
   1503         soc_reg_field_set(unit, cfg_reg[i], &rval,
   1504                           CH_PORT_NUMf, new_info[i].num_ports);
   1505         rv = soc_reg32_set(unit, cfg_reg[i],
   1506                            0, 0, rval);
   1507         if (rv != BCM_E_NONE) {
   1508             soc_cm_sfree(unit, old_sysport_list);
   1509             soc_cm_sfree(unit, old_tc2pri_list);
   1510             soc_cm_sfree(unit, new_sysport_list);
   1511             soc_cm_sfree(unit, new_tc2pri_list);
   1512             soc_cm_sfree(unit, tc2pri_buf);
   1513             soc_cm_sfree(unit, sysport_buf);
   1514             return rv;
   1515         }
   1516     }
   1517 
   1518     rv = BCM_E_NONE;
   1519     soc_cm_sfree(unit, old_sysport_list);
   1520     soc_cm_sfree(unit, old_tc2pri_list);
   1521     soc_cm_sfree(unit, new_sysport_list);
   1522     soc_cm_sfree(unit, new_tc2pri_list);
   1523     soc_cm_sfree(unit, tc2pri_buf);
   1524     soc_cm_sfree(unit, sysport_buf);
   1525     return rv;
   1526 }
   1527 
   1528 /*
   1529  * Function:
   1530  *      _bcm_kt2_oob_fc_rx_config_get
   1531  * Purpose:
   1532  *      Get the configuration and status
   1533  *      each OOB FC Rx Interface.
   1534  * Parameters:
   1535  *      unit - (IN) StrataSwitch unit number
   1536  *      intf_id - (IN) OOB FC Rx Interface Number
   1537  *      config - (OUT) OOB FC Rx Interface Config
   1538  *      array_max - (IN) Maximum Lenght of Gport array passed
   1539  *      gport_array - (OUT) Array of modport type gport
   1540  *      array_count - (OUT) Number of gports returned in the gport array
   1541  * Returns:
   1542  *      BCM_E_XXX
   1543  */
   1544 STATIC int
   1545 _bcm_kt2_oob_fc_rx_config_get(int unit,
   1546                  bcm_oob_fc_rx_intf_id_t intf_id,
   1547                  bcm_oob_fc_rx_config_t *config,
   1548                  int array_max,
   1549                  bcm_gport_t *gport_array,
   1550                  int *array_count)
   1551 {
   1552     _bcm_kt2_oob_fc_rx_intf_info_t info;
   1553     int rv = BCM_E_INTERNAL;
   1554     char *sysport_buf;
   1555     void *pentry;
   1556     int mem_wsz = 0;
   1557     int i = 0 , j = 0;
   1558     bcm_gport_t gport;
   1559     uint32 new_sysport_list[BCM_KT2_MAX_RX_MEM_ENTRY];
   1560     int max_rx_mem_entry = BCM_KT2_MAX_RX_MEM_ENTRY;
   1561 
   1562     if (SOC_IS_SABER2(unit)) {
   1563 #ifdef BCM_METROLITE_SUPPORT
   1564         if (SOC_IS_METROLITE(unit))  {
   1565             max_rx_mem_entry = BCM_ML_MAX_RX_MEM_ENTRY;
   1566         } else 
   1567 #endif
   1568         {
   1569             max_rx_mem_entry = BCM_SB2_MAX_RX_MEM_ENTRY;
   1570         } 
   1571     }
   1572 
   1573     sal_memset(&info, 0, sizeof(_bcm_kt2_oob_fc_rx_intf_info_t));
   1574     sal_memset(new_sysport_list, 0, sizeof(uint32) *
   1575                BCM_KT2_MAX_RX_MEM_ENTRY);
   1576     
   1577     /* Store all the OOBFC Rx interface configuration */
   1578     BCM_IF_ERROR_RETURN
   1579             (_bcm_kt2_oob_fc_rx_get_intf_info(unit, &info, intf_id));
   1580 
   1581     /* If given OOBFC Rx Interface is not enabled then
   1582        return empty gport array */
   1583     if (info.enable == 0) {
   1584         sal_memset(config, 0, sizeof(bcm_oob_fc_rx_config_t));
   1585         sal_memset(gport_array, 0, sizeof(bcm_gport_t) * array_max);
   1586         *array_count = 0;
   1587         return BCM_E_NONE;
   1588     } else {
   1589         config->enable = info.enable;
   1590         config->channel_base = info.channel_base;
   1591         /* Read the MMU_CHFC_SYSPORT_MAPPING memory into sysport_buf */
   1592         mem_wsz = sizeof(uint32) *
   1593                     soc_mem_entry_words(unit, MMU_CHFC_SYSPORT_MAPPINGm);
   1594         sysport_buf = soc_cm_salloc(unit, max_rx_mem_entry * mem_wsz,
   1595                                              "oob sysport_buf");
   1596         if (sysport_buf == NULL) {
   1597             return BCM_E_MEMORY;
   1598         }
   1599 
   1600         if (soc_mem_read_range(unit, MMU_CHFC_SYSPORT_MAPPINGm, MEM_BLOCK_ALL,
   1601                                0, max_rx_mem_entry - 1, sysport_buf)) {
   1602             rv = BCM_E_INTERNAL;
   1603             soc_cm_sfree(unit, sysport_buf);
   1604             return rv;
   1605         }
   1606 
   1607         if (array_max >= info.num_ports) {
   1608             *array_count = info.num_ports;
   1609         } else {
   1610             *array_count = array_max;
   1611         }
   1612 
   1613         /* Store the required number of indexes into a sysport_list */
   1614         for (i = info.lookup_base, j = 0;
   1615              i < (info.lookup_base + *array_count); i++, j++) {
   1616             pentry = soc_mem_table_idx_to_pointer(unit,
   1617                                                   MMU_CHFC_SYSPORT_MAPPINGm,
   1618                                                   void*, sysport_buf, i);
   1619             new_sysport_list[j] = soc_mem_field32_get(unit,
   1620                                                       MMU_CHFC_SYSPORT_MAPPINGm,
   1621                                                       pentry, SYS_PORTf);
   1622         }
   1623 
   1624         /* Convert the sysport list into a modport gport list */
   1625         for (i = 0; i < *array_count; i++) {
   1626             rv = bcm_esw_port_gport_get(unit, new_sysport_list[i],
   1627                                         &gport);
   1628             if (rv != BCM_E_NONE) {
   1629                 soc_cm_sfree(unit, sysport_buf);
   1630                 return rv;
   1631             }
   1632             gport_array[i] = gport;
   1633         }
   1634 
   1635     }
   1636 
   1637     rv = BCM_E_NONE;
   1638     soc_cm_sfree(unit, sysport_buf);
   1639     return rv;
   1640 }
   1641 
   1642 /*
   1643  * Function:
   1644  *      bcm_kt2_oob_fc_rx_config_set
   1645  * Purpose:
   1646  *      Set the configuration and enable 
   1647  *      each OOB FC Rx Interface.
   1648  * Parameters:
   1649  *      unit - (IN) StrataSwitch unit number
   1650  *      intf_id - (IN) OOB FC Rx Interface Number
   1651  *      config - (IN) OOB FC Rx Interface Config
   1652  *      array_count - (IN) Number of gports in the gport array
   1653  *      gport_array - (IN) Array of modport type gport
   1654  * Returns:
   1655  *      BCM_E_XXX
   1656  */
   1657 int
   1658 bcm_kt2_oob_fc_rx_config_set(int unit,
   1659                      bcm_oob_fc_rx_intf_id_t intf_id,
   1660                      bcm_oob_fc_rx_config_t *config,
   1661                      int array_count,
   1662                      bcm_gport_t *gport_array)
   1663 {
   1664     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1665         return BCM_E_PARAM;
   1666     }
   1667 
   1668     if (config == NULL) {
   1669         return BCM_E_PARAM;
   1670     }
   1671 
   1672     if ((config->enable != 0) && (config->enable != 1)) {
   1673         return BCM_E_PARAM;
   1674     }
   1675 
   1676     if ((config->enable == 1) &&
   1677         ((array_count <= 0) || (gport_array == NULL) ||
   1678         (array_count > BCM_KT2_MAX_RX_MEM_ENTRY))) {
   1679         return BCM_E_PARAM;
   1680     }
   1681 
   1682     if ((config->enable == 1) &&
   1683         ((config->channel_base >= BCM_KT2_MAX_CHANNEL_BASE))) {
   1684         return BCM_E_PARAM;
   1685     }
   1686 
   1687     if (config->enable == 1) {
   1688         /* Add entries into MMU_CHFC_SYSPORT_MAPPING memory */
   1689         BCM_IF_ERROR_RETURN
   1690             (_bcm_kt2_oob_fc_rx_config_enable_set(unit, intf_id,
   1691                                                  config->channel_base,
   1692                                                  array_count, gport_array));
   1693     } else {
   1694         /* Remove entries from MMU_CHFC_SYSPORT_MAPPING memory */
   1695         BCM_IF_ERROR_RETURN
   1696             (_bcm_kt2_oob_fc_rx_config_disable_set(unit, intf_id));
   1697     }
   1698 
   1699     return BCM_E_NONE;
   1700 }
   1701 
   1702 /*
   1703  * Function:
   1704  *      bcm_kt2_oob_fc_rx_config_get
   1705  * Purpose:
   1706  *      Get the configuration and status
   1707  *      each OOB FC Rx Interface.
   1708  * Parameters:
   1709  *      unit - (IN) StrataSwitch unit number
   1710  *      intf_id - (IN) OOB FC Rx Interface Number
   1711  *      config - (OUT) OOB FC Rx Interface Config
   1712  *      array_max - (IN) Maximum Lenght of Gport array passed
   1713  *      gport_array - (OUT) Array of modport type gport
   1714  *      array_count - (OUT) Number of gports returned in the gport array
   1715  * Returns:
   1716  *      BCM_E_XXX
   1717  */
   1718 int
   1719 bcm_kt2_oob_fc_rx_config_get(int unit,
   1720                      bcm_oob_fc_rx_intf_id_t intf_id,
   1721                      bcm_oob_fc_rx_config_t *config,
   1722                      int array_max,
   1723                      bcm_gport_t *gport_array,
   1724                      int *array_count)
   1725 {
   1726     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1727         return BCM_E_PARAM;
   1728     }
   1729 
   1730     if ((gport_array == NULL) ||
   1731         (config == NULL) ||
   1732         (array_count == NULL) ||
   1733         (array_max <= 0)) {
   1734         return BCM_E_PARAM;
   1735     }
   1736 
   1737     BCM_IF_ERROR_RETURN
   1738         (_bcm_kt2_oob_fc_rx_config_get(unit, intf_id,
   1739                                       config, array_max,
   1740                                       gport_array,
   1741                                       array_count));
   1742 
   1743     return BCM_E_NONE;
   1744 }
   1745 
   1746 /*
   1747  * Function:
   1748  *      bcm_kt2_oob_fc_rx_port_tc_mapping_multi_set
   1749  * Purpose:
   1750  *      Set the per port traffic class to priority
   1751  *      mapping for each OOB FC Rx Interface.
   1752  * Parameters:
   1753  *      unit - (IN) StrataSwitch unit number
   1754  *      intf_id - (IN) OOB FC Rx Interface Number
   1755  *      gport - (IN) Modport type gport
   1756  *      array_count - (IN) Number of elements in Traffic Class array
   1757  *      tc - (IN) Traffic Class array[0-7]
   1758  *      pri_bmp - (IN) Priority Bitmap Array[0-7]
   1759  * Returns:
   1760  *      BCM_E_XXX
   1761  */
   1762 int
   1763 bcm_kt2_oob_fc_rx_port_tc_mapping_multi_set(int unit,
   1764                                  bcm_oob_fc_rx_intf_id_t intf_id,
   1765                                  bcm_gport_t gport,
   1766                                  int array_count,
   1767                                  uint32 *tc,
   1768                                  uint32 *pri_bmp)
   1769 {
   1770     int i = 0;
   1771 
   1772     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1773         return BCM_E_PARAM;
   1774     }
   1775 
   1776     if ((array_count < 1) || (array_count > BCM_KT2_NUM_TC)) {
   1777         return BCM_E_PARAM;
   1778     }
   1779 
   1780     if ((tc == NULL) || (pri_bmp == NULL)) {
   1781         return BCM_E_PARAM;
   1782     }
   1783 
   1784     for (i = 0; i < array_count; i++) {
   1785         if ((tc[i] > (BCM_KT2_NUM_TC - 1)) || (pri_bmp[i] > 0xFF)) {
   1786             return BCM_E_PARAM;
   1787         }
   1788     }
   1789 
   1790     for (i = 0; i < array_count; i++) {
   1791         BCM_IF_ERROR_RETURN
   1792             (bcm_kt2_oob_fc_rx_port_tc_mapping_set(unit, intf_id,
   1793                                                   gport, tc[i],
   1794                                                   pri_bmp[i]));
   1795     }
   1796 
   1797     return BCM_E_NONE;
   1798 }
   1799 
   1800 /*
   1801  * Function:
   1802  *      bcm_kt2_oob_fc_rx_port_tc_mapping_multi_get
   1803  * Purpose:
   1804  *      Get the per port traffic class to priority
   1805  *      mapping for each OOB FC Rx Interface.
   1806  * Parameters:
   1807  *      unit - (IN) StrataSwitch unit number
   1808  *      intf_id - (IN) OOB FC Rx Interface Number
   1809  *      gport - (IN) Modport type gport
   1810  *      array_max - (IN) Maximum Length tc and pri_bmp array
   1811  *      tc - (OUT) Traffic Class array[0-7]
   1812  *      pri_bmp - (OUT) Priority Bitmap Array[0-7]
   1813  *      array_count - (OUT) Number of elements in Traffic Class array
   1814  * Returns:
   1815  *      BCM_E_XXX
   1816  */
   1817 int
   1818 bcm_kt2_oob_fc_rx_port_tc_mapping_multi_get(int unit,
   1819                                      bcm_oob_fc_rx_intf_id_t intf_id,
   1820                                      bcm_gport_t gport,
   1821                                      int array_max,
   1822                                      uint32 *tc,
   1823                                      uint32 *pri_bmp,
   1824                                      int *array_count)
   1825 {
   1826     int i = 0;
   1827 
   1828     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1829         return BCM_E_PARAM;
   1830     }
   1831 
   1832     if (array_max < 1) {
   1833         return BCM_E_PARAM;
   1834     }
   1835 
   1836     if ((array_count == NULL) ||
   1837         (tc == NULL) ||
   1838         (pri_bmp == NULL)) {
   1839         return BCM_E_PARAM;
   1840     }
   1841 
   1842     if (array_max > BCM_KT2_NUM_TC) {
   1843         *array_count = BCM_KT2_NUM_TC;
   1844     } else {
   1845         *array_count = array_max;
   1846     }
   1847 
   1848     for (i = 0; i < *array_count; i++) {
   1849         if (tc[i] > (BCM_KT2_NUM_TC - 1)) {
   1850             return BCM_E_PARAM;
   1851         }
   1852     }
   1853 
   1854     for (i = 0; i < *array_count; i++) {
   1855         BCM_IF_ERROR_RETURN
   1856             (bcm_kt2_oob_fc_rx_port_tc_mapping_get(unit, intf_id,
   1857                                                   gport, tc[i],
   1858                                                   &pri_bmp[i]));
   1859     }
   1860     return BCM_E_NONE;
   1861 }
   1862 
   1863 
   1864 /*
   1865  * Function:
   1866  *      bcm_kt2_oob_fc_rx_port_tc_mapping_set
   1867  * Purpose:
   1868  *      Set the per port traffic class to priority
   1869  *      mapping for each OOB FC Rx Interface.
   1870  * Parameters:
   1871  *      unit - (IN) StrataSwitch unit number
   1872  *      intf_id - (IN) OOB FC Rx Interface Number
   1873  *      gport - (IN) Modport type gport
   1874  *      tc - (IN) Traffic Class array[0-7]
   1875  *      pri_bmp - (IN) Priority Bitmap[0-7]
   1876  * Returns:
   1877  *      BCM_E_XXX
   1878  */
   1879 int
   1880 bcm_kt2_oob_fc_rx_port_tc_mapping_set(int unit,
   1881                                  bcm_oob_fc_rx_intf_id_t intf_id,
   1882                                  bcm_gport_t gport,
   1883                                  uint32 tc,
   1884                                  uint32 pri_bmp)
   1885 {
   1886     uint32 idx = 0;
   1887     uint32 offset = 0;
   1888     uint32 lookup_base = 0;
   1889 
   1890     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1891         return BCM_E_PARAM;
   1892     }
   1893 
   1894     if ((tc > (BCM_KT2_NUM_TC - 1)) || (pri_bmp > 0xFF)) {
   1895         return BCM_E_PARAM;
   1896     }
   1897 
   1898     BCM_IF_ERROR_RETURN
   1899         (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id,
   1900                                            gport, &offset));
   1901 
   1902     /* Get lookup base */
   1903     BCM_IF_ERROR_RETURN
   1904         (_bcm_kt2_oob_fc_rx_intf_get_lookup_base(unit, intf_id,
   1905                                                 &lookup_base));
   1906 
   1907     idx = offset + lookup_base;
   1908 
   1909     BCM_IF_ERROR_RETURN
   1910         (_bcm_kt2_oob_fc_rx_tc_mapping_set(unit, intf_id, tc,
   1911                                           pri_bmp, idx));
   1912 
   1913     return BCM_E_NONE;
   1914 }
   1915 
   1916 /*
   1917  * Function:
   1918  *      bcm_kt2_oob_fc_rx_port_tc_mapping_get
   1919  * Purpose:
   1920  *      Set the per port traffic class to priority
   1921  *      mapping for each OOB FC Rx Interface.
   1922  * Parameters:
   1923  *      unit - (IN) StrataSwitch unit number
   1924  *      intf_id - (IN) OOB FC Rx Interface Number
   1925  *      gport - (IN) Modport type gport
   1926  *      tc - (IN) Traffic Class array[0-7]
   1927  *      pri_bmp - (OUT) Priority Bitmap[0-7]
   1928  * Returns:
   1929  *      BCM_E_XXX
   1930  */
   1931 int
   1932 bcm_kt2_oob_fc_rx_port_tc_mapping_get(int unit,
   1933                                  bcm_oob_fc_rx_intf_id_t intf_id,
   1934                                  bcm_gport_t gport,
   1935                                  uint32 tc,
   1936                                  uint32 *pri_bmp)
   1937 {
   1938     uint32 idx = 0;
   1939     uint32 offset = 0;
   1940     uint32 lookup_base = 0;
   1941 
   1942     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1943         return BCM_E_PARAM;
   1944     }
   1945 
   1946     if (tc > (BCM_KT2_NUM_TC - 1)) {
   1947         return BCM_E_PARAM;
   1948     }
   1949 
   1950     BCM_IF_ERROR_RETURN
   1951         (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id,
   1952                                            gport, &offset));
   1953 
   1954     /* Get lookup base */
   1955     BCM_IF_ERROR_RETURN
   1956         (_bcm_kt2_oob_fc_rx_intf_get_lookup_base(unit, intf_id,
   1957                                                 &lookup_base));
   1958 
   1959     idx = offset + lookup_base;
   1960 
   1961     BCM_IF_ERROR_RETURN
   1962         (_bcm_kt2_oob_fc_rx_tc_mapping_get(unit, intf_id, tc,
   1963                                           pri_bmp, idx));
   1964 
   1965     return BCM_E_NONE;
   1966 }
   1967 
   1968 /*
   1969  * Function:
   1970  *      bcm_kt2_oob_fc_rx_port_offset_get
   1971  * Purpose:
   1972  *      Get the Channel offset value for a given port
   1973  *      on given OOB FC Rx Interface.
   1974  * Parameters:
   1975  *      unit - (IN) StrataSwitch unit number
   1976  *      intf_id - (IN) OOB FC Rx Interface Number
   1977  *      gport - (IN) Modport type gport
   1978  *      offset - (OUT) Channel offset value in HCFC message
   1979  * Returns:
   1980  *      BCM_E_XXX
   1981  */
   1982 int
   1983 bcm_kt2_oob_fc_rx_port_offset_get(int unit,
   1984                              bcm_oob_fc_rx_intf_id_t intf_id,
   1985                              bcm_gport_t gport,
   1986                              uint32 *offset)
   1987 {
   1988     if ((intf_id < 0) || (intf_id >= BCM_KT2_NUM_OOB_FC_RX_INTF)) {
   1989         return BCM_E_PARAM;
   1990     }
   1991 
   1992     BCM_IF_ERROR_RETURN
   1993         (_bcm_kt2_oob_fc_rx_port_offset_get(unit, intf_id,
   1994                                            gport, offset));
   1995 
   1996     return BCM_E_NONE;
   1997 }
   1998 
   1999 #endif /* BCM_KATANA2_SUPPORT */