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


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