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

apache.c (650242B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        apache.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 #include <shared/bsl.h>
     13 
     14 #include <sal/core/boot.h>
     15 #include <soc/bradley.h>
     16 #include <soc/drv.h>
     17 #include <soc/error.h>
     18 #include <soc/debug.h>
     19 #include <soc/mem.h>
     20 #include <soc/apache.h>
     21 #include <soc/i2c.h>
     22 #include <soc/mspi.h>
     23 #include <soc/l2x.h>
     24 #include <soc/soc_ser_log.h>
     25 #include <soc/trident2.h>
     26 #include <soc/tdm/core/tdm_top.h>
     27 #include <soc/mcm/memregs.h>
     28 #ifdef BCM_APACHE_SUPPORT
     29 #include <soc/iproc.h>
     30 
     31 #ifdef ALPM_ENABLE
     32 #include <soc/lpm.h>
     33 #include <soc/alpm.h>
     34 #include <soc/esw/alpm_int.h>
     35 #endif /* ALPM_ENABLE */
     36 
     37 #include <soc/mmu_config.h>
     38 #include <soc/post.h>
     39 
     40 #include <soc/esw/portctrl.h>
     41 #include <soc/bondoptions.h>
     42 
     43 #ifdef PORTMOD_SUPPORT
     44 #include <soc/portmod/portmod.h>
     45 #endif /*  PORTMOD_SUPPORT */
     46 
     47 
     48 #define APACHE_PORTS_PER_TSC         4
     49 #define APACHE_TSCS_PER_PGW          9
     50 #define APACHE_NUM_XLP_PER_PGW       7
     51 #define APACHE_NUM_CLP_PER_PGW       2
     52 #define APACHE_PGWS_PER_DEV          2
     53 #define APACHE_PGW0                  0
     54 #define APACHE_PGW1                  1
     55 
     56 #define APACHE_PORTS_PER_PGW         (APACHE_PORTS_PER_TSC * APACHE_TSCS_PER_PGW)
     57 #define APACHE_PORTS_PER_PIPE        (APACHE_PORTS_PER_PGW * APACHE_PGWS_PER_DEV)
     58 
     59 #define _APACHE_BYTES_PER_OBM_CELL    16
     60 #define _APACHE_CELLS_PER_OBM         1020
     61 
     62 #define _APACHE_LOG_PORTS_PER_PIPE    75
     63 #define _APACHE_MMU_PORTS_PER_PIPE    75
     64 #define _SOC_APACHE_MAX_PORT          (_APACHE_LOG_PORTS_PER_PIPE)
     65 
     66 #define _APACHE_MMU_PACKET_HEADER_BYTES 64    /* bytes */
     67 #define _APACHE_MMU_JUMBO_FRAME_BYTES   9216  /* bytes */
     68 #define _APACHE_MMU_DEFAULT_MTU_BYTES   1536  /* bytes */
     69 
     70 #define _APACHE_MMU_BYTES_PER_CELL      208   /* bytes (1664 bits) */
     71 #define _APACHE_MMU_NUM_PG              8
     72 #define _APACHE_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE 50
     73 #define _APACHE_MMU_PG_MIN              8
     74 
     75 #define SOC_APACHE_MMU_CFG_QGROUP_MAX   128
     76 
     77 #define SOC_APACHE_MMU_MCQ_ENTRY        31540 
     78 #define SOC_APACHE_MMU_RQE_ENTRY        3936 
     79 
     80 #define _APACHE_MMU_TOTAL_MCQ_ENTRY(unit)  SOC_APACHE_MMU_MCQ_ENTRY
     81 
     82 #define _APACHE_MMU_TOTAL_RQE_ENTRY(unit)  SOC_APACHE_MMU_RQE_ENTRY
     83 
     84 #define _SOC_APACHE_DEFIP_MAX_TCAMS   8
     85 #define _SOC_APACHE_DEFIP_TCAM_DEPTH 1024
     86 
     87 #define IS_OVERSUB_PORT(unit,port)           \
     88         (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))
     89 
     90 /*
     91  * TDM algo does not support all speeds. SDK needs to adjust
     92  * the speeds to  what is supported in the algorithm.
     93  *
     94  * For FB5 LR ports:
     95  * Anything < 1G will be passed as 1G.
     96  * 5G needs to be passed as 10G.
     97  * 2.5G is supported in the TDM. We can pass as is.
     98  *
     99  * For OS and MV LR ports:
    100  * Anything < 10G will be passed as 10G
    101  */
    102 #define APACHE_TDM_SPEED_ADJUST(unit, port, speed)          \
    103     do {                                                    \
    104         speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);     \
    105         if ((speed > 0) && (speed < 10000)) {               \
    106             if (SOC_INFO(unit).oversub_mode != 2) {         \
    107                 speed = 10000;                              \
    108             } else if (IS_OVERSUB_PORT(unit, port)) {       \
    109                 speed = 10000;                              \
    110             } else if (speed < 1000) {                      \
    111                 speed = 1000;                               \
    112             } else if (speed == 5000) {                     \
    113                 speed = 10000;                              \
    114             }                                               \
    115         }                                                   \
    116     } while (0)
    117 
    118 #define INVALID_PORT  -1
    119 
    120 /* defines for Reserved Buffer for Flex Port Macro when new Flex Port is
    121    enabled */
    122 /* lossless defines */
    123 #define _AP_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 185 
    124 #define _AP_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS  214  
    125 
    126 #define _AP_RSVD_BUF_FLEX_QGRP 16
    127 #define _AP_RSVD_BUF_10G_FLEX_ASF 4
    128 #define _AP_RSVD_BUF_25G_FLEX_ASF 16
    129 
    130 /* defines for Reserved Buffer for Ports when Flex Port for the macro is NOT
    131    enabled*/
    132 #define _AP_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS 687 
    133 #define _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS  558 
    134 #define _AP_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS  352  
    135 #define _AP_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS   298 
    136 #define _AP_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS  338  
    137 #define _AP_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS  284  
    138 #define _AP_RSVD_BUF_NON_FLEX_OB_25G_HDRM_LOSSLESS  214 
    139 #define _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS  191 
    140 #define _AP_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS  206 
    141 #define _AP_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS  183 
    142 #define _AP_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS  185  
    143 #define _AP_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS  162 
    144 #define _AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 8
    145 #define _AP_RSVD_BUF_NON_FLEX_PGMIN 8
    146 #define _AP_RSVD_BUF_NON_FLEX_QGRP 16
    147 #define _AP_RSVD_BUF_NON_FLEX_ASF 16
    148 #define _AP_RSVD_BUF_NON_FLEX_10G_ASF 4
    149 /* mmu_mc_egr_qentry_min in Settings sheet */
    150 #define _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD 4 
    151 #define _AP_RSVD_BUF_10G_FLEX_QGRP 16 
    152 #define _AP_MMU_NUM_MCQ_PORT_MACRO 10
    153 #define _AP_MMU_RDB_PORT_MIN 90 
    154 
    155 
    156 int soc_apache_is_any_port_flex_enable(int unit);
    157 int soc_ap_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled);
    158 
    159 typedef enum {
    160     _SOC_PARITY_TYPE_NONE,
    161     _SOC_PARITY_TYPE_GENERIC,
    162     _SOC_PARITY_TYPE_PARITY,
    163     _SOC_PARITY_TYPE_ECC,
    164     _SOC_PARITY_TYPE_CXXPORT,
    165     _SOC_PARITY_TYPE_MMU_SER,
    166     _SOC_PARITY_TYPE_START_ERR,
    167     _SOC_PARITY_TYPE_SER,
    168     _SOC_PARITY_TYPE_BST,
    169     _SOC_PARITY_TYPE_MAC_RX_CDC,
    170     _SOC_PARITY_TYPE_MAC_TX_CDC,
    171     _SOC_PARITY_TYPE_MAC_RX_TS,
    172     _SOC_PARITY_TYPE_MIB
    173 } _soc_apache_ser_info_type_t;
    174 
    175 typedef struct _soc_apache_fifo_ser_info_s {
    176     soc_reg_t   enable_reg;
    177     soc_field_t enable_field;
    178     uint8       type; /* 0: mem, 1: reg, 2: bus */
    179     soc_mem_t   mem;
    180     soc_reg_t   reg;
    181     char        *name_str; /* Used when mem == INVALIDm or reg == INVALIDr or type == bus
    182                               (either not accessible or multiple) */
    183 } _soc_apache_fifo_ser_info_t;
    184 
    185 typedef struct _soc_apache_ser_block_info_s {
    186     int         type;
    187     soc_block_t blocktype;
    188     char        name[16];
    189     soc_reg_t   fifo_reset_reg;
    190     void        *info;
    191 } _soc_apache_ser_block_info_t;
    192 
    193 typedef struct _soc_apache_ser_reg_s {
    194     soc_reg_t reg;
    195     char      *mem_str;
    196 } _soc_apache_ser_reg_t;
    197 
    198 typedef struct _soc_apache_ser_info_s {
    199     _soc_apache_ser_info_type_t   type;
    200     struct _soc_apache_ser_info_s *info;
    201     int                        id;
    202     soc_field_t                group_reg_enable_field;
    203     soc_field_t                group_reg_status_field;
    204     soc_mem_t                  mem;
    205     char                      *mem_str;
    206     soc_reg_t                  enable_reg;
    207     soc_field_t                enable_field;
    208     soc_reg_t                  intr_status_reg;
    209     _soc_apache_ser_reg_t     *intr_status_reg_list;
    210     soc_reg_t                  intr_clr_reg;
    211     soc_field_t                intr_clr_field;
    212     soc_field_t               *intr_clr_field_list;
    213 } _soc_apache_ser_info_t;
    214 
    215 typedef struct _soc_apache_ser_route_block_s {
    216     uint32              cmic_bit;
    217     soc_block_t         blocktype;
    218     soc_reg_t           enable_reg;
    219     soc_reg_t           status_reg;
    220     soc_field_t         enable_field;
    221     _soc_apache_ser_info_t *info;
    222     uint8               id;
    223 } _soc_apache_ser_route_block_t;
    224 
    225 typedef struct _soc_apache_mmu_traffic_ctrl_s {
    226     uint8   thdo_drop_bmp[_SOC_APACHE_MAX_PORT];
    227 } _soc_apache_mmu_traffic_ctrl_t;
    228 
    229 typedef struct _soc_ap_mmu_buffer_config_s {
    230     int total_physical_memory;
    231     int cfapfullsetpoint;
    232     int total_cell_memory;
    233     int num_mem_banks;
    234     int num_10g_ports;
    235     int num_20g_ports;
    236     int num_25g_ports;
    237     int num_40g_ports;
    238     int num_100g_ports;
    239     int num_ovsb_10g_ports;
    240     int num_ovsb_20g_ports;
    241     int num_ovsb_25g_ports;
    242     int num_ovsb_40g_ports;
    243     int num_ovsb_100g_ports;
    244 } _soc_ap_mmu_buffer_config_t;
    245 
    246 #define _AP_NUM_SKEWS 3
    247 STATIC _soc_ap_mmu_buffer_config_t soc_ap_buffer_config[_AP_NUM_SKEWS] = {
    248     { 65536, 61376, 60495, 16, 50, 0, 4, 0,  0, 50, 0, 0,  4, 0 },
    249     { 53248, 46016, 45372, 13, 72, 0, 0, 0,  0, 72, 0, 0,  0, 0 },
    250     { 36864, 30656, 30248,  9,  0, 0, 4, 11, 0,  0, 0, 4, 11, 0 }
    251 };
    252 STATIC int _soc_ap_skew_index;
    253 
    254 #define _APACHE_MMU_PHYSICAL_CELLS                                     \
    255         soc_ap_buffer_config[_soc_ap_skew_index].total_physical_memory
    256 
    257 #define _APACHE_CFAPFULLSETPOINT                                    \
    258         soc_ap_buffer_config[_soc_ap_skew_index].cfapfullsetpoint
    259 #define _APACHE_MMU_RSVD_CELLS_CFAP                                 \
    260         soc_ap_buffer_config[_soc_ap_skew_index].num_mem_banks *    \
    261                             (23 + 2 + 10)
    262 
    263 #define _APACHE_MMU_TOTAL_CELLS                                     \
    264         soc_ap_buffer_config[_soc_ap_skew_index].total_cell_memory
    265 
    266 #define   MAC_ENABLE_SET_CTRL          (1 << 0)
    267 #define   MMU_TRAFFIC_EN_CTRL          (1 << 1)
    268 #define   COSQ_SCHED_SET_CTRL          (1 << 2) 
    269 static    _soc_apache_mmu_traffic_ctrl_t
    270               *_soc_apache_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES];
    271 static    sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES];
    272 #define   FWD_CTRL_LOCK(unit) \
    273           sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER)
    274 #define   FWD_CTRL_UNLOCK(unit) \
    275           sal_mutex_give(_fwd_ctrl_lock[unit])
    276 
    277 /* Forward declarations */
    278 STATIC int
    279 _soc_apache_mdio_reg_read(int unit, uint32 phy_addr,
    280                             uint32 phy_reg, uint32 *phy_data);
    281 STATIC int
    282 _soc_apache_mdio_reg_write(int unit, uint32 phy_addr,
    283                              uint32 phy_reg, uint32 phy_data);
    284 
    285 #define _SOC_APACHE_SER_TYPE_REG 0
    286 #define _SOC_APACHE_SER_TYPE_MEM 1
    287 #define _SOC_APACHE_SER_TYPE_BUS 2
    288 #define _SOC_APACHE_SER_TYPE_BUF 3
    289 
    290 /* These are now generated from the regsfile processing into bcm56560_a0.c 
    291    structures are defined in chip.h */
    292 #if defined(BCM_56560_A0)
    293 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_ip_mem_ser_info[];
    294 extern _soc_reg_ser_en_info_t _soc_bcm56560_a0_ip_reg_ser_info[];
    295 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_ep_mem_ser_info[];
    296 extern _soc_reg_ser_en_info_t _soc_bcm56560_a0_ep_reg_ser_info[];
    297 extern _soc_mem_ser_en_info_t _soc_bcm56560_a0_mmu_mem_ser_info[];
    298 
    299 /* These can be re-used from TD2P. As naming is SOC independent
    300  * and information is same we'll reuse them here
    301  */
    302 extern _soc_bus_ser_en_info_t     _soc_ip_bus_ser_info[];
    303 extern _soc_buffer_ser_en_info_t  _soc_ip_buffer_ser_info[];
    304 extern _soc_buffer_ser_en_info_t  _soc_mmu_buffer_ser_info[];
    305 
    306 static _soc_bus_ser_en_info_t _soc_ep_bus_ser_info [] = {
    307     { "EFP",     EFP_PARITY_CONTROLr,      EFP_BUS_PARITY_ENf     },
    308     { "EFPPARS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf },
    309     { "EHCPM",   EGR_EHCPM_SER_CONTROLr,   EHCPM_BUS_PARITY_ENf },
    310     { "EPMOD",   EGR_EPMOD_SER_CONTROLr,   EPMOD_BUS_PARITY_ENf },
    311     { "EVLAN",   EGR_VLAN_SER_CONTROLr,    EVLAN_BUS_PARITY_ENf },
    312     { "", INVALIDr } /* end */ 
    313 };
    314 
    315 static _soc_buffer_ser_en_info_t _soc_ep_buffer_ser_info[] = {
    316     { "INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf },
    317     { "EGR MPB",  EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf },
    318     { "EDB_CM_MEM", EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf },
    319     { "XLP13_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP13_ECC_ENf },
    320     { "XLP12_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP12_ECC_ENf },
    321     { "XLP11_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP11_ECC_ENf },
    322     { "XLP10_CELL_BUF", EGR_EDATABUF_PARITY_CONTROLr, XLP10_ECC_ENf },
    323     { "XLP9_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP9_ECC_ENf  },
    324     { "XLP8_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf  },
    325     { "XLP7_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf  },
    326     { "XLP6_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf  },
    327     { "XLP5_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf  },
    328     { "XLP4_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf  },
    329     { "XLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf  },
    330     { "XLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf  },
    331     { "XLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf  },
    332     { "XLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf  },
    333     { "CLP5_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP5_ECC_ENf  },
    334     { "CLP4_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP4_ECC_ENf  },
    335     { "CLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf  },
    336     { "CLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf  },
    337     { "CLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf  },
    338     { "CLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf  },
    339     { "EP_XLP13_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP13_ECC_ENf },
    340     { "EP_XLP12_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP12_ECC_ENf },
    341     { "EP_XLP11_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP11_ECC_ENf },
    342     { "EP_XLP10_DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP10_ECC_ENf },
    343     { "EP_XLP9__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP9_ECC_ENf  },
    344     { "EP_XLP8__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP8_ECC_ENf  },
    345     { "EP_XLP7__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP7_ECC_ENf  },
    346     { "EP_XLP6__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP6_ECC_ENf  },
    347     { "EP_XLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf  },
    348     { "EP_XLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf  },
    349     { "EP_XLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf  },
    350     { "EP_XLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf  },
    351     { "EP_XLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf  },
    352     { "EP_XLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf  },
    353     { "EP_CLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP5_ECC_ENf  },
    354     { "EP_CLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP4_ECC_ENf  },
    355     { "EP_CLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf  },
    356     { "EP_CLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf  },
    357     { "EP_CLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf  },
    358     { "EP_CLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf  },
    359 
    360 
    361     { "", INVALIDr }
    362 };
    363 
    364 static const _soc_apache_ser_block_info_t _soc_apache_ser_block_info[] = {
    365     { _SOC_APACHE_SER_TYPE_REG, SOC_BLK_IPIPE, "IPIPE regs", INVALIDr, _soc_bcm56560_a0_ip_reg_ser_info },
    366     { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_IPIPE, "IPIPE mems", ING_SER_FIFO_CTRLr, _soc_bcm56560_a0_ip_mem_ser_info },
    367     { _SOC_APACHE_SER_TYPE_BUS, SOC_BLK_EPIPE, "IPIPE buses",INVALIDr, _soc_ip_bus_ser_info },
    368     { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_EPIPE, "IPIPE buff" ,INVALIDr, _soc_ip_buffer_ser_info },
    369     { _SOC_APACHE_SER_TYPE_REG, SOC_BLK_EPIPE, "EPIPE regs", INVALIDr, _soc_bcm56560_a0_ep_reg_ser_info },
    370     { _SOC_APACHE_SER_TYPE_BUS, SOC_BLK_EPIPE, "EPIPE buses",INVALIDr, _soc_ep_bus_ser_info },
    371     { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_EPIPE, "EPIPE buff" ,INVALIDr, _soc_ep_buffer_ser_info },
    372     { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_EPIPE, "EPIPE mems", EGR_SER_FIFO_CTRLr, _soc_bcm56560_a0_ep_mem_ser_info },
    373     { _SOC_APACHE_SER_TYPE_MEM, SOC_BLK_MMU,   "MMU mems", INVALIDr, _soc_bcm56560_a0_mmu_mem_ser_info },
    374     { _SOC_APACHE_SER_TYPE_BUF, SOC_BLK_MMU,   "MMU buff", INVALIDr, _soc_mmu_buffer_ser_info },
    375     { -1, 0 }
    376 };
    377 
    378 
    379 STATIC _soc_apache_ser_info_t _soc_apache_mmu_ser_info[] = {
    380     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    381         DEQ_NOT_IP_ERR_ENf,
    382         DEQ_NOT_IP_ERRf,
    383         INVALIDm, "MMU DEQ NOT IP",
    384         INVALIDr, INVALIDf,
    385         INVALIDr, NULL,
    386         INVALIDr, INVALIDf, NULL },
    387     { _SOC_PARITY_TYPE_START_ERR, NULL, 0,
    388         START_BY_START_ERR_ENf,
    389         START_BY_START_ERRf,
    390         INVALIDm, "MMU START BY START",
    391         INVALIDr, INVALIDf,
    392         INVALIDr, NULL,
    393         INVALIDr, INVALIDf, NULL },
    394     { _SOC_PARITY_TYPE_MMU_SER, NULL, 0,
    395         MEM_PAR_ERR_ENf,
    396         MEM_PAR_ERRf,
    397         INVALIDm, "MMU MEM PAR",
    398         INVALIDr, INVALIDf,
    399         MEM_FAIL_INT_STATr, NULL,
    400         MEM_FAIL_INT_CLEARr, MEM_PAR_ERR_CLRf, NULL },
    401     { _SOC_PARITY_TYPE_BST, NULL, 0,
    402         INVALIDf,
    403         BST_THDI_INTf,
    404         INVALIDm, NULL, 
    405         INVALIDr, INVALIDf,
    406         INVALIDr, NULL,
    407         INVALIDr, INVALIDf, NULL },
    408     { _SOC_PARITY_TYPE_BST, NULL, 0,
    409         INVALIDf,
    410         BST_THDO_INTf,
    411         INVALIDm, NULL, 
    412         INVALIDr, INVALIDf,
    413         INVALIDr, NULL,
    414         INVALIDr, INVALIDf, NULL },
    415     { _SOC_PARITY_TYPE_BST, NULL, 0,
    416         INVALIDf,
    417         BST_CFAP_INTf,
    418         INVALIDm, NULL, 
    419         INVALIDr, INVALIDf,
    420         INVALIDr, NULL,
    421         INVALIDr, INVALIDf, NULL },
    422     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    423 };
    424 
    425 STATIC _soc_apache_ser_reg_t _soc_apache_pg_bod_status_reg[] = {
    426     { PGW_BOD_XLP0_ECC_STATUSr, "PGW BOD XLP0 ECC" },
    427     { PGW_BOD_XLP1_ECC_STATUSr, "PGW BOD XLP1 ECC" },
    428     { PGW_BOD_XLP2_ECC_STATUSr, "PGW BOD XLP2 ECC" },
    429     { PGW_BOD_XLP3_ECC_STATUSr, "PGW BOD XLP3 ECC" },
    430     { PGW_BOD_XLP4_ECC_STATUSr, "PGW BOD XLP4 ECC" },
    431     { PGW_BOD_XLP5_ECC_STATUSr, "PGW BOD XLP5 ECC" },
    432     { PGW_BOD_XLP6_ECC_STATUSr, "PGW BOD XLP6 ECC" },
    433     { PGW_BOD_CLP0_ECC_STATUSr, "PGW BOD CLP0 ECC" },
    434     { PGW_BOD_CLP1_ECC_STATUSr, "PGW BOD CLP1 ECC" },
    435     { INVALIDr }
    436 };
    437 
    438 STATIC _soc_apache_ser_info_t _soc_apache_pg_ser_info[] = {
    439     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    440         PGW_OBM_PERR_INTRf,
    441         PGW_OBM_PERR_INTRf,
    442         INVALIDm, "PGW OBM0",
    443         IDB_OBM0_SER_CONTROLr, DATA_ECC_ENABLEf,
    444         IDB_OBM0_DATA_ECC_STATUSr, NULL,
    445         INVALIDr, INVALIDf, NULL },
    446     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    447         PGW_OBM_PERR_INTRf,
    448         PGW_OBM_PERR_INTRf,
    449         INVALIDm, "PGW OBM1",
    450         IDB_OBM1_SER_CONTROLr, DATA_ECC_ENABLEf,
    451         IDB_OBM1_DATA_ECC_STATUSr, NULL,
    452         INVALIDr, INVALIDf, NULL },
    453     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    454         PGW_OBM_PERR_INTRf,
    455         PGW_OBM_PERR_INTRf,
    456         INVALIDm, "PGW OBM2",
    457         IDB_OBM2_SER_CONTROLr, DATA_ECC_ENABLEf,
    458         IDB_OBM2_DATA_ECC_STATUSr, NULL,
    459         INVALIDr, INVALIDf, NULL },
    460     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    461         PGW_OBM_PERR_INTRf,
    462         PGW_OBM_PERR_INTRf,
    463         INVALIDm, "PGW OBM3",
    464         IDB_OBM3_SER_CONTROLr, DATA_ECC_ENABLEf,
    465         IDB_OBM3_DATA_ECC_STATUSr, NULL,
    466         INVALIDr, INVALIDf, NULL },
    467     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    468         PGW_OBM_PERR_INTRf,
    469         PGW_OBM_PERR_INTRf,
    470         INVALIDm, "PGW OBM4",
    471         IDB_OBM4_SER_CONTROLr, DATA_ECC_ENABLEf,
    472         IDB_OBM4_DATA_ECC_STATUSr, NULL,
    473         INVALIDr, INVALIDf, NULL },
    474     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    475         PGW_OBM_PERR_INTRf,
    476         PGW_OBM_PERR_INTRf,
    477         INVALIDm, "PGW OBM5",
    478         IDB_OBM5_SER_CONTROLr, DATA_ECC_ENABLEf,
    479         IDB_OBM5_DATA_ECC_STATUSr, NULL,
    480         INVALIDr, INVALIDf, NULL },
    481     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    482         PGW_OBM_PERR_INTRf,
    483         PGW_OBM_PERR_INTRf,
    484         INVALIDm, "PGW OBM6",
    485         IDB_OBM6_SER_CONTROLr, DATA_ECC_ENABLEf,
    486         IDB_OBM6_DATA_ECC_STATUSr, NULL,
    487         INVALIDr, INVALIDf, NULL },
    488     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    489         PGW_OBM_PERR_INTRf,
    490         PGW_OBM_PERR_INTRf,
    491         INVALIDm, "PGW OBM7",
    492         IDB_OBM7_SER_CONTROLr, DATA_ECC_ENABLEf,
    493         IDB_OBM7_DATA_ECC_STATUSr, NULL,
    494         INVALIDr, INVALIDf, NULL },
    495     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    496         PGW_OBM_PERR_INTRf,
    497         PGW_OBM_PERR_INTRf,
    498         INVALIDm, "PGW OBM8",
    499         IDB_OBM8_SER_CONTROLr, DATA_ECC_ENABLEf,
    500         IDB_OBM8_DATA_ECC_STATUSr, NULL,
    501         INVALIDr, INVALIDf, NULL },
    502     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    503         PGW_BOD_PERR_INTRf,
    504         PGW_BOD_PERR_INTRf,
    505         INVALIDm, "PGW BOD",
    506         PGW_BOD_ECC_ENABLEr, BOD_ECC_ENABLEf,
    507         INVALIDr, _soc_apache_pg_bod_status_reg,
    508         INVALIDr, INVALIDf, NULL },
    509     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    510 };
    511 
    512 static const
    513 _soc_apache_ser_route_block_t  _soc_apache_ser_route_blocks_irq3[] = {
    514     { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */
    515       SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, INVALIDf, 
    516       _soc_apache_mmu_ser_info, 0 },
    517     { 0x00000002, /* EP1_TO_CMIC_PERR_INTR */
    518       SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, SER_FIFO_NON_EMPTYf, NULL, 0 },
    519     { 0x00000004, /* EP2_TO_CMIC_PERR_INTR */
    520       SOC_BLK_EPIPE, EGR_INTR_ENABLEr, EGR_INTR_STATUSr, SER_FIFO_NON_EMPTYf, NULL, 0 },
    521     { 0x00000008, /* IP0_TO_CMIC_PERR_INTR */
    522       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    523     { 0x00000010, /* IP1_TO_CMIC_PERR_INTR */
    524       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    525     { 0x00000020, /* IP2_TO_CMIC_PERR_INTR */
    526       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    527     { 0x00000040, /* IP3_TO_CMIC_PERR_INTR */
    528       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    529     { 0x00000080, /* IP4_TO_CMIC_PERR_INTR */
    530       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    531     { 0x00000100, /* IP5_TO_CMIC_PERR_INTR */
    532       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    533     { 0x00000200, /* PGW_0_TO_CMIC_PERR_INTR */
    534       SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    535       _soc_apache_pg_ser_info, 0 },
    536     { 0x00000400, /* PGW_1_TO_CMIC_PERR_INTR */
    537       SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    538       _soc_apache_pg_ser_info, 1 },
    539     { 0 } /* table terminator */
    540 };
    541 
    542 static soc_field_t _soc_apache_pm_rx_cdc_clear_field[] = {
    543     CLEAR_RX_CDC_SINGLE_BIT_ERRf, CLEAR_RX_CDC_DOUBLE_BIT_ERRf
    544 };
    545 static soc_field_t _soc_apache_pm_tx_cdc_clear_field[] = {
    546     CLEAR_TX_CDC_SINGLE_BIT_ERRf, CLEAR_TX_CDC_DOUBLE_BIT_ERRf
    547 };
    548 static soc_field_t _soc_apache_pm_rx_ts_clear_field[] = {
    549     CLEAR_RX_TS_MEM_SINGLE_BIT_ERRf, CLEAR_RX_TS_MEM_DOUBLE_BIT_ERRf
    550 };
    551 static _soc_apache_ser_reg_t _soc_apache_pm_xlp_rx_status_reg[] = {
    552     { XLPORT_MIB_RSC0_ECC_STATUSr, "XLP MIB RSC0 ECC" },
    553     { XLPORT_MIB_RSC1_ECC_STATUSr, "XLP MIB RSC1 ECC" },
    554     { INVALIDr }
    555 };
    556 static _soc_apache_ser_reg_t _soc_apache_pm_xlp_tx_status_reg[] = {
    557     { XLPORT_MIB_TSC0_ECC_STATUSr, "XLP MIB TSC0 ECC" },
    558     { XLPORT_MIB_TSC1_ECC_STATUSr, "XLP MIB TSC1 ECC" },
    559     { INVALIDr }
    560 };
    561 
    562 static  _soc_apache_ser_info_t _soc_apache_xlport_ser_info[] = {
    563     /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL
    564      * interrupts in XLPORT. Currently not being handled.
    565      */
    566     { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0,
    567       MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf,
    568       INVALIDm, "MAC RX CDC memory",
    569       XLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf,
    570       XLMAC_RX_CDC_ECC_STATUSr, NULL,
    571       XLMAC_CLEAR_ECC_STATUSr, INVALIDf,
    572       _soc_apache_pm_rx_cdc_clear_field
    573     },
    574     { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0,
    575       MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf,
    576       INVALIDm, "MAC TX CDC memory",
    577       XLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf,
    578       XLMAC_TX_CDC_ECC_STATUSr, NULL,
    579       XLMAC_CLEAR_ECC_STATUSr, INVALIDf,
    580       _soc_apache_pm_tx_cdc_clear_field
    581     },
    582     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    583       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    584       INVALIDm, "MIB RX Statistic Counter memory",
    585       XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    586       INVALIDr, _soc_apache_pm_xlp_rx_status_reg,
    587       XLPORT_MIB_RESETr, INVALIDf, NULL
    588     },
    589     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    590       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    591       INVALIDm, "MIB TX Statistic Counter memory",
    592       XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    593       INVALIDr, _soc_apache_pm_xlp_tx_status_reg,
    594       XLPORT_MIB_RESETr, INVALIDf, NULL
    595     },
    596     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    597 };
    598 
    599 static  _soc_apache_ser_info_t _soc_apache_xlb0port_ser_info[] = {
    600     /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL
    601      * interrupts in XLPORT. Currently not being handled
    602      */
    603     { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0,
    604       MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf,
    605       INVALIDm, "MAC RX CDC memory",
    606       XLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf,
    607       XLMAC_B0_RX_CDC_ECC_STATUSr, NULL,
    608       XLMAC_B0_CLEAR_ECC_STATUSr, INVALIDf,
    609       _soc_apache_pm_rx_cdc_clear_field
    610     },
    611     { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0,
    612       MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf,
    613       INVALIDm, "MAC TX CDC memory",
    614       XLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf,
    615       XLMAC_B0_TX_CDC_ECC_STATUSr, NULL,
    616       XLMAC_B0_CLEAR_ECC_STATUSr, INVALIDf,
    617       _soc_apache_pm_tx_cdc_clear_field
    618     },
    619     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    620       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    621       INVALIDm, "MIB RX Statistic Counter memory",
    622       XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    623       INVALIDr, _soc_apache_pm_xlp_rx_status_reg,
    624       XLPORT_MIB_RESETr, INVALIDf, NULL
    625     },
    626     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    627       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    628       INVALIDm, "MIB TX Statistic Counter memory",
    629       XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    630       INVALIDr, _soc_apache_pm_xlp_tx_status_reg,
    631       XLPORT_MIB_RESETr, INVALIDf, NULL
    632     },
    633     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    634 };
    635 
    636 static _soc_apache_ser_reg_t _soc_apache_pm_clp_rx_status_reg[] = {
    637     { CLPORT_MIB_RSC0_ECC_STATUSr, "CLP MIB RSC0 ECC" },
    638     { CLPORT_MIB_RSC1_ECC_STATUSr, "CLP MIB RSC1 ECC" },
    639     { INVALIDr }
    640 };
    641 
    642 static _soc_apache_ser_reg_t _soc_apache_pm_clp_tx_status_reg[] = {
    643     { CLPORT_MIB_TSC0_ECC_STATUSr, "CLP MIB TSC0 ECC" },
    644     { CLPORT_MIB_TSC1_ECC_STATUSr, "CLP MIB TSC1 ECC" },
    645     { INVALIDr }
    646 };
    647 static  _soc_apache_ser_info_t _soc_apache_clport_ser_info[] = {
    648     /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL
    649      * interrupts in CLPORT. Currently not being handled
    650      */
    651     { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0,
    652       MAC_RX_TS_CDC_MEM_ERRf, MAC_RX_TS_CDC_MEM_ERRf,
    653       INVALIDm, "MAC RX TimeStamp CDC memory",
    654       CLPORT_INTR_ENABLEr, MAC_RX_TS_CDC_MEM_ERRf,
    655       CLMAC_RX_TS_MEM_ECC_STATUSr, NULL,
    656       CLMAC_CLEAR_ECC_STATUSr, INVALIDf,
    657       _soc_apache_pm_rx_ts_clear_field
    658     },
    659     { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0,
    660       MAC_RX_CDC_MEM_ERRf, MAC_RX_CDC_MEM_ERRf,
    661       INVALIDm, "MAC RX CDC memory",
    662       CLPORT_INTR_ENABLEr, MAC_RX_CDC_MEM_ERRf,
    663       CLMAC_RX_CDC_ECC_STATUSr, NULL,
    664       CLMAC_CLEAR_ECC_STATUSr, INVALIDf,
    665       _soc_apache_pm_rx_cdc_clear_field
    666     },
    667     { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0,
    668       MAC_TX_CDC_MEM_ERRf, MAC_TX_CDC_MEM_ERRf,
    669       INVALIDm, "MAC TX CDC memory",
    670       CLPORT_INTR_ENABLEr, MAC_TX_CDC_MEM_ERRf,
    671       CLMAC_TX_CDC_ECC_STATUSr, NULL,
    672       CLMAC_CLEAR_ECC_STATUSr, INVALIDf,
    673       _soc_apache_pm_tx_cdc_clear_field
    674     },
    675     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    676       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    677       INVALIDm, "MIB RX Statistic Counter memory",
    678       CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    679       INVALIDr, _soc_apache_pm_clp_rx_status_reg,
    680       CLPORT_MIB_RESETr, INVALIDf, NULL
    681     },
    682     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    683       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    684       INVALIDm, "MIB TX Statistic Counter memory",
    685       CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    686       INVALIDr, _soc_apache_pm_clp_tx_status_reg,
    687       CLPORT_MIB_RESETr, INVALIDf, NULL
    688     },
    689     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    690 };
    691 static  _soc_apache_ser_info_t _soc_apache_clg2port_ser_info[] = {
    692     /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL
    693      * MAC_ERR and LINK_DOWN interrupts in CLG2PORT as well as many other interrupts
    694      * in CLG2MAC. Currently not being handled
    695     */
    696     { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0,
    697       INVALIDf, INVALIDf,
    698       INVALIDm, "MAC RX TimeStamp CDC memory",
    699       CLG2MAC_INTR_ENABLEr, EN_RX_TS_MEM_SINGLE_BIT_ERRf,
    700       CLG2MAC_RX_TS_MEM_ECC_STATUSr, NULL,
    701       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    702       _soc_apache_pm_rx_ts_clear_field
    703     },
    704     { _SOC_PARITY_TYPE_MAC_RX_TS, NULL, 0,
    705       INVALIDf, INVALIDf,
    706       INVALIDm, "MAC RX TimeStamp CDC memory",
    707       CLG2MAC_INTR_ENABLEr, EN_RX_TS_MEM_DOUBLE_BIT_ERRf,
    708       CLG2MAC_RX_TS_MEM_ECC_STATUSr, NULL,
    709       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    710       _soc_apache_pm_rx_ts_clear_field
    711     },
    712     { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0,
    713       INVALIDf, INVALIDf,
    714       INVALIDm, "MAC RX CDC memory",
    715       CLG2MAC_INTR_ENABLEr, EN_RX_CDC_SINGLE_BIT_ERRf,
    716       CLG2MAC_RX_CDC_ECC_STATUSr, NULL,
    717       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    718       _soc_apache_pm_rx_cdc_clear_field
    719     },
    720     { _SOC_PARITY_TYPE_MAC_RX_CDC, NULL, 0,
    721       INVALIDf, INVALIDf,
    722       INVALIDm, "MAC RX CDC memory",
    723       CLG2MAC_INTR_ENABLEr, EN_RX_CDC_DOUBLE_BIT_ERRf,
    724       CLG2MAC_RX_CDC_ECC_STATUSr, NULL,
    725       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    726       _soc_apache_pm_rx_cdc_clear_field
    727     },
    728     { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0,
    729       INVALIDf, INVALIDf,
    730       INVALIDm, "MAC TX CDC memory",
    731       CLG2MAC_INTR_ENABLEr, EN_TX_CDC_SINGLE_BIT_ERRf,
    732       CLG2MAC_TX_CDC_ECC_STATUSr, NULL,
    733       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    734       _soc_apache_pm_tx_cdc_clear_field
    735     },
    736     { _SOC_PARITY_TYPE_MAC_TX_CDC, NULL, 0,
    737       INVALIDf, INVALIDf,
    738       INVALIDm, "MAC TX CDC memory",
    739       CLG2MAC_INTR_ENABLEr, EN_TX_CDC_DOUBLE_BIT_ERRf,
    740       CLG2MAC_TX_CDC_ECC_STATUSr, NULL,
    741       CLG2MAC_CLEAR_ECC_STATUSr, INVALIDf,
    742       _soc_apache_pm_tx_cdc_clear_field
    743     },
    744     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    745       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    746       INVALIDm, "MIB RX Statistic Counter memory",
    747       CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    748       INVALIDr, _soc_apache_pm_clp_rx_status_reg,
    749       CLPORT_MIB_RESETr, INVALIDf, NULL
    750     },
    751     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    752       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    753       INVALIDm, "MIB TX Statistic Counter memory",
    754       CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    755       INVALIDr, _soc_apache_pm_clp_tx_status_reg,
    756       CLPORT_MIB_RESETr, INVALIDf, NULL
    757     },
    758     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    759 };
    760 
    761 static  _soc_apache_ser_info_t _soc_apache_pgw0_cxxport_ser_info[] = {
    762     /* There are six INTR fields in CXXPORT_INTR_STATUS reg.
    763      * 3 for TSC and 4 for CORE. Currently not being handled
    764      */
    765     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_clport_ser_info, 0,
    766       CORE3_INTf, CORE3_INTf,
    767       INVALIDm, "PM4x25_CORE interrupt",
    768       CLPORT_INTR_ENABLEr, INVALIDf,
    769       CLPORT_INTR_STATUSr, NULL,
    770       INVALIDr, INVALIDf, NULL
    771     },
    772     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 6,
    773       CORE2_INTf, CORE2_INTf,
    774       INVALIDm, "PM4x10_CORE_2 interrupt",
    775       XLPORT_INTR_ENABLEr, INVALIDf,
    776       XLPORT_INTR_STATUSr, NULL,
    777       INVALIDr, INVALIDf, NULL
    778     },
    779     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 5,
    780       CORE1_INTf, CORE1_INTf,
    781       INVALIDm, "PM4x10_CORE_1 interrupt",
    782       XLPORT_INTR_ENABLEr, INVALIDf,
    783       XLPORT_INTR_STATUSr, NULL,
    784       INVALIDr, INVALIDf, NULL
    785     },
    786     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 4,
    787       CORE0_INTf, CORE0_INTf,
    788       INVALIDm, "PM4x10_CORE_0 interrupt",
    789       XLPORT_INTR_ENABLEr, INVALIDf,
    790       XLPORT_INTR_STATUSr, NULL,
    791       INVALIDr, INVALIDf, NULL
    792     },
    793     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    794 };
    795 
    796 static  _soc_apache_ser_info_t _soc_apache_pgw1_cxxport_ser_info[] = {
    797     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_clport_ser_info, 3,
    798       CORE3_INTf, CORE3_INTf,
    799       INVALIDm, "PM4x25_CORE interrupt",
    800       CLPORT_INTR_ENABLEr, INVALIDf,
    801       CLPORT_INTR_STATUSr, NULL,
    802       INVALIDr, INVALIDf, NULL
    803     },
    804     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 13,
    805       CORE2_INTf, CORE2_INTf,
    806       INVALIDm, "PM4x10_CORE_2 interrupt",
    807       XLPORT_INTR_ENABLEr, INVALIDf,
    808       XLPORT_INTR_STATUSr, NULL,
    809       INVALIDr, INVALIDf, NULL
    810     },
    811     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 12,
    812       CORE1_INTf, CORE1_INTf,
    813       INVALIDm, "PM4x10_CORE_1 interrupt",
    814       XLPORT_INTR_ENABLEr, INVALIDf,
    815       XLPORT_INTR_STATUSr, NULL,
    816       INVALIDr, INVALIDf, NULL
    817     },
    818     { _SOC_PARITY_TYPE_CXXPORT, _soc_apache_xlport_ser_info, 11,
    819       CORE0_INTf, CORE0_INTf,
    820       INVALIDm, "PM4x10_CORE_0 interrupt",
    821       XLPORT_INTR_ENABLEr, INVALIDf,
    822       XLPORT_INTR_STATUSr, NULL,
    823       INVALIDr, INVALIDf, NULL
    824     },
    825     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    826 };
    827 
    828 static const
    829 _soc_apache_ser_route_block_t  _soc_apache_ser_route_blocks_irq4[] = {
    830     {0x00000001, /* Port Macro0 (PM0) interrupt */
    831      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    832      _soc_apache_xlb0port_ser_info, 0},
    833     {0x00000002, /* Port Macro1 (PM1) interrupt */
    834      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    835      _soc_apache_xlb0port_ser_info, 1},
    836     {0x00000004, /* Port Macro2 (PM2) interrupt */
    837      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    838      _soc_apache_xlb0port_ser_info, 2},
    839     {0x00000008, /* Port Macro3 (PM3) interrupt */
    840      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    841      _soc_apache_xlb0port_ser_info, 3},
    842     {0x00000010, /* Port Macro4 (PM4) interrupt */
    843      SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf,
    844      _soc_apache_pgw0_cxxport_ser_info, 0},
    845     {0x00000020, /* Port Macro5 (PM5) interrupt */
    846      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    847      _soc_apache_clport_ser_info, 1},
    848     {0x00000040, /* Port Macro6 (PM6) interrupt */
    849      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    850      _soc_apache_clport_ser_info, 2},
    851     {0x00000080, /* Port Macro7 (PM7) interrupt */
    852      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    853      _soc_apache_xlb0port_ser_info, 7},
    854     {0x00000100, /* Port Macro8 (PM8) interrupt */
    855      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    856      _soc_apache_xlb0port_ser_info, 8},
    857     {0x00000200, /* Port Macro9 (PM9) interrupt */
    858      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    859      _soc_apache_xlb0port_ser_info, 9},
    860     {0x00000400, /* Port Macro10 (PM10) interrupt */
    861      SOC_BLK_XLPORTB0, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    862      _soc_apache_xlb0port_ser_info, 10},
    863     {0x00000800, /* Port Macro11 (PM11) interrupt */
    864      SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf,
    865      _soc_apache_pgw1_cxxport_ser_info, 1},
    866     {0x00001000, /* Port Macro12 (PM12) interrupt */
    867      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    868      _soc_apache_clport_ser_info, 4},
    869     {0x00002000, /* Port Macro13 (PM13) interrupt */
    870      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    871      _soc_apache_clport_ser_info, 5},
    872     /* Bits 14-31 are reserved */
    873     {0} /* table terminator */
    874 };
    875 
    876 static const
    877 _soc_apache_ser_route_block_t  _soc_apache_ser_route_b0_blocks_irq4[] = {
    878     {0x00000001, /* Port Macro0 (PM0) interrupt */
    879      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    880      _soc_apache_xlport_ser_info, 0},
    881     {0x00000002, /* Port Macro1 (PM1) interrupt */
    882      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    883      _soc_apache_xlport_ser_info, 1},
    884     {0x00000004, /* Port Macro2 (PM2) interrupt */
    885      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    886      _soc_apache_xlport_ser_info, 2},
    887     {0x00000008, /* Port Macro3 (PM3) interrupt */
    888      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    889      _soc_apache_xlport_ser_info, 3},
    890     {0x00000010, /* Port Macro4 (PM4) interrupt */
    891      SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf,
    892      _soc_apache_pgw0_cxxport_ser_info, 0},
    893     {0x00000020, /* Port Macro5 (PM5) interrupt */
    894      SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    895      _soc_apache_clg2port_ser_info, 1},
    896     {0x00000040, /* Port Macro6 (PM6) interrupt */
    897      SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    898      _soc_apache_clg2port_ser_info, 2},
    899     {0x00000080, /* Port Macro7 (PM7) interrupt */
    900      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    901      _soc_apache_xlport_ser_info, 7},
    902     {0x00000100, /* Port Macro8 (PM8) interrupt */
    903      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    904      _soc_apache_xlport_ser_info, 8},
    905     {0x00000200, /* Port Macro9 (PM9) interrupt */
    906      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    907      _soc_apache_xlport_ser_info, 9},
    908     {0x00000400, /* Port Macro10 (PM10) interrupt */
    909      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    910      _soc_apache_xlport_ser_info, 10},
    911     {0x00000800, /* Port Macro11 (PM11) interrupt */
    912      SOC_BLK_CXXPORT, CXXPORT_INTR_ENABLEr, CXXPORT_INTR_STATUSr, INVALIDf,
    913      _soc_apache_pgw1_cxxport_ser_info, 1},
    914     {0x00001000, /* Port Macro12 (PM12) interrupt */
    915      SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    916      _soc_apache_clg2port_ser_info, 4},
    917     {0x00002000, /* Port Macro13 (PM13) interrupt */
    918      SOC_BLK_CLG2PORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    919      _soc_apache_clg2port_ser_info, 5},
    920     /* Bits 14-31 are reserved */
    921     {0} /* table terminator */
    922 };
    923 
    924 static soc_ser_functions_t _apache_ser_functions;
    925 
    926 extern uint8 _soc_alpm_mode[SOC_MAX_NUM_DEVICES];
    927 
    928 static uint32 _apache_ser_delay = 0;
    929 
    930 #endif
    931 
    932 /* Values map to HW encodings */
    933 enum soc_ap_port_ca_mode_e {
    934     SOC_AP_PORT_CA_MODE_SINGLE      = 0,
    935     SOC_AP_PORT_CA_MODE_DUAL        = 1,
    936     SOC_AP_PORT_CA_MODE_QUAD        = 2,
    937     SOC_AP_PORT_CA_MODE_TRI_211     = 3,
    938     SOC_AP_PORT_CA_MODE_TRI_112     = 4,
    939     SOC_AP_PORT_CA_MODE_TRI_411     = 5,
    940     SOC_AP_PORT_CA_MODE_TRI_114     = 6,
    941     SOC_AP_PORT_CA_MODE_COUNT       /* unused */
    942 };
    943 STATIC int
    944 _soc_apache_thdo_hw_set(int unit, soc_port_t port, int enable);
    945 /*
    946  * SINGLE   => {VALUE => 0, DESC => "Port 0 valid.  10G/20G/25G/40G/50G/100G."},
    947  * DUAL     => {VALUE => 1, DESC => "Port 0 and 2 valid.  10G/20G/25G/40G/50G."},
    948  * QUAD     => {VALUE => 2, DESC => "Port 0, 1, 2, and 3 valid.  10G/20G/25G."},
    949  * TRI211   => {VALUE => 3, DESC => "Port 0 is 20G, port 2 10G, and port 3 10G."},
    950  * TRI112   => {VALUE => 4, DESC => "Port 0 is 10G, port 1 10G, and port 2 20G."},
    951  * TRI411   => {VALUE => 5, DESC => "Port 0 is 40G, port 2 10G, and port 3 10G."},
    952  * TRI114   => {VALUE => 6, DESC => "Port 0 is 10G, port 1 10G, and port 2 40G."},
    953  */
    954 STATIC int
    955 soc_apache_port_ca_mode_get(int unit, int flexport, int xlp, int *mode)
    956 {
    957     soc_info_t *si;
    958     int port, phy_port_base, lane;
    959     int num_lanes[APACHE_PORTS_PER_TSC];
    960     int speed_max[APACHE_PORTS_PER_TSC];
    961 
    962     si = &SOC_INFO(unit);
    963     *mode = SOC_AP_PORT_CA_MODE_QUAD;
    964 
    965     phy_port_base = 1 + (xlp * APACHE_PORTS_PER_TSC);
    966     for (lane = 0; lane < APACHE_PORTS_PER_TSC; lane++) {
    967         port = si->port_p2l_mapping[phy_port_base + lane];
    968         if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
    969             num_lanes[lane] = -1;
    970             speed_max[lane] = -1;
    971         } else {
    972             num_lanes[lane] = si->port_num_lanes[port];
    973             speed_max[lane] = si->port_speed_max[port];
    974         }
    975     }
    976 
    977     if (num_lanes[0] >= 4) {
    978         *mode = SOC_AP_PORT_CA_MODE_SINGLE;
    979     } else if ((num_lanes[0] == 2) && (num_lanes[2] == 2)) {
    980         *mode = SOC_AP_PORT_CA_MODE_DUAL;
    981     } else if ((num_lanes[0] == 1) && (num_lanes[1] == 1) &&
    982                (num_lanes[2] == 1) && (num_lanes[3] == 1)) {
    983         *mode = SOC_AP_PORT_CA_MODE_QUAD;
    984     } else if (num_lanes[0] == 2) {
    985         *mode = (speed_max[0] >= 40000) ?
    986                 SOC_AP_PORT_CA_MODE_TRI_411 : SOC_AP_PORT_CA_MODE_TRI_211;
    987     } else if (num_lanes[2] == 2) {
    988         *mode = (speed_max[2] >= 40000) ?
    989                 SOC_AP_PORT_CA_MODE_TRI_114 : SOC_AP_PORT_CA_MODE_TRI_112;
    990     }
    991     return SOC_E_NONE;
    992 }
    993 
    994 
    995 int
    996 _soc_apache_idb_port_init(int unit, int reset, int lossless, soc_port_t port)
    997 {
    998     soc_info_t *si;
    999     soc_mem_t mem;
   1000     soc_reg_t reg;
   1001     int obm, pgw, pgw_inst, index;
   1002     int port_osub, phy_port, subport;
   1003     uint32 rval32;
   1004     uint64 rval64;
   1005     idb_obm0_pri_map_port0_entry_t entry;
   1006 
   1007     uint32 discard_limit = 0, lossy_discard = 0, lossy_low_pri = 0;
   1008     uint32 port_xon = 0, port_xoff = 0, lossless0_xon = 0 ,lossless0_xoff = 0;
   1009 
   1010     static const soc_reg_t obm_ctrl_regs[] = {
   1011         IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr,
   1012         IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr,
   1013         IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr,
   1014         IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr,
   1015         IDB_OBM8_CONTROLr
   1016     };
   1017     static const soc_reg_t obm_thresh_regs[] = {
   1018         IDB_OBM0_THRESHOLDr, IDB_OBM1_THRESHOLDr,
   1019         IDB_OBM2_THRESHOLDr, IDB_OBM3_THRESHOLDr,
   1020         IDB_OBM4_THRESHOLDr, IDB_OBM5_THRESHOLDr,
   1021         IDB_OBM6_THRESHOLDr, IDB_OBM7_THRESHOLDr,
   1022         IDB_OBM8_THRESHOLDr,
   1023     };
   1024     static const soc_reg_t obm_fc_thresh_regs[] = {
   1025         IDB_OBM0_FC_THRESHOLDr, IDB_OBM1_FC_THRESHOLDr,
   1026         IDB_OBM2_FC_THRESHOLDr, IDB_OBM3_FC_THRESHOLDr,
   1027         IDB_OBM4_FC_THRESHOLDr, IDB_OBM5_FC_THRESHOLDr,
   1028         IDB_OBM6_FC_THRESHOLDr, IDB_OBM7_FC_THRESHOLDr,
   1029         IDB_OBM8_FC_THRESHOLDr,
   1030     };
   1031     static const soc_reg_t obm_shared_regs[] = {
   1032         IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr,
   1033         IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr,
   1034         IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr,
   1035         IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr,
   1036         IDB_OBM8_SHARED_CONFIGr,
   1037     };
   1038     static const soc_reg_t obm_max_usage_regs[] = {
   1039         IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr,
   1040         IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr,
   1041         IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr,
   1042         IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr,
   1043         IDB_OBM8_MAX_USAGE_SELECTr
   1044     };
   1045 
   1046     static const soc_reg_t obm_port_config_regs[] = {
   1047         IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr,
   1048         IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr,
   1049         IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr,
   1050         IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr,
   1051         IDB_OBM8_PORT_CONFIGr
   1052     };
   1053     static const soc_reg_t obm_fc_config_regs[] = {
   1054         IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr,
   1055         IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr,
   1056         IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr,
   1057         IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr,
   1058         IDB_OBM8_FLOW_CONTROL_CONFIGr,
   1059     };
   1060 
   1061     static const soc_field_t obm_bypass_fields[] = {
   1062         PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf,
   1063         PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf
   1064     };
   1065     static const soc_field_t obm_oversub_fields[] = {
   1066         PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf,
   1067         PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf
   1068     };
   1069 
   1070     static const soc_mem_t obm_pri_map_port_mem[] = {
   1071         IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m,
   1072         IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m,
   1073         IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m,
   1074         IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m,
   1075         IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m,
   1076         IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m,
   1077         IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m,
   1078         IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m,
   1079         IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m,
   1080         IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m,
   1081         IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m,
   1082         IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m,
   1083         IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m,
   1084         IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m,
   1085         IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m,
   1086         IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m,
   1087         IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m,
   1088         IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m,
   1089     };
   1090 
   1091 
   1092     static const soc_field_t offset_ob_prio[] = {
   1093         OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf,
   1094         OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf,
   1095         OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf,
   1096         OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf,
   1097         OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf,
   1098         OFFSET15_OB_PRIORITYf,
   1099     };
   1100     static const soc_reg_t obm_ct_thresh_regs[] = {
   1101         IDB_OBM0_CT_THRESHOLDr, IDB_OBM1_CT_THRESHOLDr,
   1102         IDB_OBM2_CT_THRESHOLDr, IDB_OBM3_CT_THRESHOLDr,
   1103         IDB_OBM4_CT_THRESHOLDr, IDB_OBM5_CT_THRESHOLDr,
   1104         IDB_OBM6_CT_THRESHOLDr, IDB_OBM7_CT_THRESHOLDr,
   1105         IDB_OBM8_CT_THRESHOLDr,
   1106     };
   1107  
   1108     si = &SOC_INFO(unit);
   1109 
   1110     /* Calculation of obm and lanes(subport)
   1111        obm is 0 for phy_port 1 to 4 
   1112        1 for phy port 5 to 8 and so on till 8 for phy_port 33 to 36
   1113        Similarly obm 0 for phy_port 37 to 40 and so on 
   1114        lane(subport) is 0,1,2,3 for phy_port 1,2,3,4 resp       
   1115        lane(subport) is 0,1,2,3 for phy_port 5,6,7,8 resp and so on
   1116        Block index is PGW0 for ports 1 to 36
   1117        Block index is PGW1 for ports 37 to 72
   1118     */ 
   1119     phy_port = si->port_l2p_mapping[port];
   1120 
   1121     /*  Deleting a port  */
   1122     if (phy_port == -1) {
   1123         return SOC_E_PARAM;
   1124     }
   1125 
   1126     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
   1127         /*  nothing to do for non-idb ports */
   1128         return SOC_E_NONE;
   1129     }
   1130 
   1131     /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1  */
   1132     obm = si->port_serdes[port];
   1133     obm %= APACHE_TSCS_PER_PGW;
   1134 
   1135     pgw = si->port_group[port];
   1136     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   1137     subport = (phy_port - 1) % APACHE_PORTS_PER_TSC;
   1138 
   1139     if (si->port_speed_max[port] <= 11000) {
   1140             discard_limit = 253;
   1141             lossy_discard = lossless ? 196 : 249;
   1142             lossy_low_pri = lossless ? 100 : 173;
   1143             port_xon = lossless ? 116 : 1023;
   1144             port_xoff = lossless ? 126 : 1023;
   1145             lossless0_xon = lossless ? 36 : 1023;
   1146             lossless0_xoff = lossless ? 46 : 1023;
   1147     } else if (si->port_speed_max[port] <= 21000) {
   1148             discard_limit = 253;
   1149             lossy_discard = lossless ? 196 : 249;
   1150             lossy_low_pri = lossless ? 100 : 173;
   1151             port_xon = lossless ? 101 : 1023;
   1152             port_xoff = lossless ? 111 : 1023;
   1153             lossless0_xon = lossless ? 36 : 1023;
   1154             lossless0_xoff = lossless ? 46 : 1023;
   1155     } else if (si->port_speed_max[port] <= 27000) {
   1156             discard_limit = 253;
   1157             lossy_discard = lossless ? 176 : 249;
   1158             lossy_low_pri = lossless ? 80 : 173;
   1159             port_xon = lossless ? 94 : 1023;
   1160             port_xoff = lossless ? 104 : 1023;
   1161             lossless0_xon = lossless ? 36 : 1023;
   1162             lossless0_xoff = lossless ? 46 : 1023;
   1163     } else if (si->port_speed_max[port] <= 42000) {
   1164             discard_limit = 506;
   1165             lossy_discard = lossless ? 196 : 502;
   1166             lossy_low_pri = lossless ? 100 : 426;
   1167             port_xon = lossless ? 279 : 1023;
   1168             port_xoff = lossless ? 289 : 1023;
   1169             lossless0_xon = lossless ? 98 : 1023;
   1170             lossless0_xoff = lossless ? 108 : 1023;
   1171     } else if (si->port_speed_max[port] <= 53000) {
   1172             discard_limit = 506;
   1173             lossy_discard = lossless ? 196 : 502;
   1174             lossy_low_pri = lossless ? 100 : 426;
   1175             port_xon = lossless ? 259 : 1023;
   1176             port_xoff = lossless ? 269 : 1023;
   1177             lossless0_xon = lossless ? 98 : 1023;
   1178             lossless0_xoff = lossless ? 108 : 1023;
   1179     } else { /* greter than 53000 including 106000 */
   1180             discard_limit = 1012;
   1181             lossy_discard = lossless ? 196 : 1008;
   1182             lossy_low_pri = lossless ? 100 : 932;
   1183             port_xon = lossless ? 609 : 1023;
   1184             port_xoff = lossless ? 619 : 1023;
   1185             lossless0_xon = lossless ? 248 : 1023;
   1186             lossless0_xoff = lossless ? 258 : 1023;
   1187     }
   1188 
   1189     if (reset) {
   1190        discard_limit = 0;
   1191        lossy_discard = 0;
   1192        lossy_low_pri = 0;
   1193        port_xon = 0;
   1194        port_xoff = 0;
   1195        lossless0_xon = 0;
   1196        lossless0_xoff = 0;
   1197     }
   1198 
   1199 
   1200     rval32 = 0;
   1201     reg = obm_port_config_regs[obm];
   1202 
   1203     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32));
   1204     soc_reg_field_set(unit, reg, &rval32, PORT_PRIf, 2);
   1205     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32));
   1206 
   1207     rval32 = 0;
   1208     reg = obm_max_usage_regs[obm];
   1209 
   1210     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32));
   1211     soc_reg_field_set(unit, reg, &rval32, PRIORITY_SELECTf, 2);
   1212     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32));
   1213 
   1214     COMPILER_64_ZERO(rval64);
   1215     reg = obm_thresh_regs[obm];
   1216 
   1217     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1218     soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, discard_limit);
   1219     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1023);
   1220     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1023);
   1221     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, lossy_discard);
   1222     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, lossy_low_pri);
   1223     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_MINf, 0);
   1224     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1225 
   1226     rval32 = 0;
   1227     reg = obm_shared_regs[obm];
   1228 
   1229     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32));
   1230     soc_reg_field_set(unit, reg, &rval32, SOP_DISCARD_MODEf,  1);
   1231     soc_reg_field_set(unit, reg, &rval32, SOP_THRESHOLDf,  1023);
   1232     soc_reg_field_set(unit, reg, &rval32, DISCARD_THRESHOLDf, 1023);
   1233     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32));
   1234 
   1235     COMPILER_64_ZERO(rval64);
   1236     reg = obm_fc_thresh_regs[obm];
   1237 
   1238     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1239     soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, port_xon);
   1240     soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, port_xoff);
   1241     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 1023);
   1242     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 1023);
   1243     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, lossless0_xon);
   1244     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, lossless0_xoff);
   1245     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1246 
   1247     if (!IS_OVERSUB_PORT(unit, port) ||
   1248         ((IS_OVERSUB_PORT(unit, port)) &&
   1249             ((si->port_speed_max[port] == 40000) ||
   1250             (si->port_speed_max[port] == 42000)))) {
   1251         COMPILER_64_ZERO(rval64);
   1252         reg = obm_ct_thresh_regs[obm];
   1253 
   1254         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1255         soc_reg64_field32_set(unit, reg, &rval64, CUT_THROUGH_OKf, 2);
   1256         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1257     }
   1258 
   1259     COMPILER_64_ZERO(rval64);
   1260     reg = obm_fc_config_regs[obm];
   1261 
   1262     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1263     soc_reg64_field32_set(unit, reg, &rval64, XOFF_REFRESH_TIMERf, 256);
   1264     soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, lossless ? 1 : 0);
   1265     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, lossless ? 1 : 0);
   1266     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, 
   1267             lossless ? 65535 : 0);
   1268     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1269 
   1270     rval32 = 0;
   1271     reg =  obm_ctrl_regs[obm];
   1272     port_osub = SOC_PBMP_MEMBER(si->oversub_pbm, port);
   1273 
   1274     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32));
   1275     soc_reg_field_set(unit, reg, &rval32, obm_bypass_fields[subport], 1);
   1276     soc_reg_field_set(unit, reg, &rval32, obm_oversub_fields[subport], port_osub);
   1277     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32));
   1278 
   1279     if (lossless) {
   1280         mem = obm_pri_map_port_mem[(phy_port - 1) % APACHE_PORTS_PER_PGW];
   1281         sal_memset(&entry, 0, sizeof(entry));
   1282         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry));
   1283         for (index = 0; index < COUNTOF(offset_ob_prio); index++) {
   1284             soc_mem_field32_set(unit, mem, &entry, offset_ob_prio[index], 2);
   1285         }
   1286         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry));
   1287     }
   1288 
   1289     return SOC_E_NONE;
   1290 }
   1291 
   1292 STATIC int
   1293 _soc_apache_port_blk_ca_mode_set(int unit, int flexport, int xlp)
   1294 {
   1295     int rv;
   1296     soc_reg_t reg;
   1297     int ca_port_mode = 0;
   1298     int pgw_inst;
   1299     uint32 r32val0, r32val1;
   1300 
   1301     static const soc_reg_t obm_ca_ctrl_regs[] = {
   1302         IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr,
   1303         IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr,
   1304         IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr
   1305     };
   1306 
   1307     /* Calculate the mode of the Cell Assembly for the port block */
   1308     rv = soc_apache_port_ca_mode_get(unit, flexport, xlp, &ca_port_mode);
   1309     SOC_IF_ERROR_RETURN(rv);
   1310 
   1311     r32val0 = 0;
   1312     reg = obm_ca_ctrl_regs[xlp % APACHE_TSCS_PER_PGW];
   1313     pgw_inst = ((xlp / APACHE_TSCS_PER_PGW) | SOC_REG_ADDR_INSTANCE_MASK);
   1314     /* Debug output */
   1315     LOG_VERBOSE(BSL_LS_SOC_PORT,
   1316                 (BSL_META_U(unit,
   1317                             "Port Block CellAssembly Mode: "
   1318                             "xlp=%d  pgw=%d reg=%s ca_mode=%d \n"),
   1319                  xlp, (xlp / APACHE_TSCS_PER_PGW), SOC_REG_NAME(unit, reg), ca_port_mode));
   1320 
   1321 
   1322     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &r32val0));
   1323     soc_reg_field_set(unit, reg, &r32val0, PORT_MODEf, ca_port_mode);
   1324     r32val1 = r32val0;
   1325     if (!flexport) {
   1326         soc_reg_field_set(unit, reg, &r32val0, PORT0_RESETf, 1);
   1327         soc_reg_field_set(unit, reg, &r32val0, PORT1_RESETf, 1);
   1328         soc_reg_field_set(unit, reg, &r32val0, PORT2_RESETf, 1);
   1329         soc_reg_field_set(unit, reg, &r32val0, PORT3_RESETf, 1);
   1330 
   1331         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val0));
   1332     }
   1333     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val1));
   1334 
   1335     return SOC_E_NONE;
   1336 }
   1337 
   1338 int
   1339 soc_apache_idb_init(int unit)
   1340 {
   1341     int rv;
   1342     int lossless;
   1343     soc_port_t port;
   1344     int xlp, blk_index;
   1345     soc_block_t port_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0,
   1346                                  SOC_BLK_CLPORT, SOC_BLK_CLG2PORT,
   1347                                  SOC_BLOCK_TYPE_INVALID};
   1348 
   1349     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
   1350     /* Per-port settings */
   1351     PBMP_ALL_ITER(unit, port) {
   1352         SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, FALSE, lossless, port));
   1353     }
   1354 
   1355     SOC_BLOCKS_ITER(unit, blk_index, port_blocks) {
   1356         port = SOC_BLOCK_PORT(unit, blk_index);
   1357         xlp = SOC_INFO(unit).port_serdes[port];
   1358         rv = _soc_apache_port_blk_ca_mode_set(unit, FALSE, xlp);
   1359         SOC_IF_ERROR_RETURN(rv);
   1360     }
   1361 
   1362     return SOC_E_NONE;
   1363 }
   1364 
   1365 
   1366 STATIC int
   1367 soc_ap_mmu_delay_insertion_set (int unit, int port)
   1368 {
   1369     int phy_port, mmu_port;    
   1370     int val = 0;
   1371     uint32 rval;
   1372     soc_info_t *si;
   1373 
   1374     si = &SOC_INFO(unit);      
   1375 
   1376     phy_port = si->port_l2p_mapping[port];
   1377     mmu_port = si->port_p2m_mapping[phy_port];
   1378 
   1379 
   1380     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, 
   1381                 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, &rval));
   1382 
   1383     if (IS_OVERSUB_PORT(unit, port ) && si->port_speed_max[port] >= 20000) {
   1384         val = 120 + (sal_rand() % 20);
   1385     } else {
   1386         /* linerate port or OS with < 20G */
   1387     }
   1388     soc_reg_field_set(unit, ES_PIPE0_MMU_3DBG_Cr, &rval, FIELD_Af, val);
   1389 
   1390     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, 
   1391                 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, rval));
   1392 
   1393     return SOC_E_NONE;
   1394 }
   1395 
   1396 
   1397 STATIC int
   1398 _soc_apache_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1399                             soc_reg_t group_reg, uint64 *group_rval,
   1400                             const _soc_apache_ser_info_t *info_list,
   1401                             soc_mem_t mem, int enable);
   1402 STATIC int
   1403 _soc_apache_ser_enable_cxxport(int unit, int inst, 
   1404                                const _soc_apache_ser_info_t *info,
   1405                                soc_mem_t mem, int enable)
   1406 {
   1407     uint64      rval;
   1408     int         block_info_idx, port, blk_idx;
   1409 
   1410     port = INVALID_PORT;
   1411     
   1412     if ((inst == 0) || (inst == 3)) {
   1413         blk_idx    = SOC_BLK_CLPORT;
   1414     } else {
   1415         blk_idx    = SOC_BLK_XLPORT;
   1416     }
   1417 
   1418     SOC_BLOCK_ITER(unit, block_info_idx, blk_idx) {
   1419         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) {
   1420             port = SOC_BLOCK_PORT(unit, block_info_idx);
   1421             break;
   1422         }
   1423     }
   1424 
   1425     if (port == INVALID_PORT) {
   1426         return SOC_E_NONE;
   1427     }
   1428 
   1429     /* Read reg val here */
   1430     SOC_IF_ERROR_RETURN
   1431         (soc_reg_get(unit, info->enable_reg, port, 0, &rval));
   1432     SOC_IF_ERROR_RETURN
   1433         (_soc_apache_ser_enable_info(unit, block_info_idx, inst, port,
   1434                                      info->enable_reg, &rval,
   1435                                      info, mem, enable));
   1436     /* Write back reg val here */
   1437     SOC_IF_ERROR_RETURN
   1438         (soc_reg_set(unit, info->enable_reg, port, 0, rval));
   1439 
   1440     return SOC_E_NONE;
   1441 }
   1442 
   1443 STATIC int
   1444 _soc_apache_ser_enable_mmu_1bit_ecc (int unit, int enable)
   1445 {
   1446     int i, f;
   1447     uint64 rval64;
   1448     uint32 rval;
   1449     soc_field_info_t *fieldp;
   1450     soc_reg_info_t   *regp;
   1451     soc_reg_t reg;
   1452     
   1453     soc_reg_t _1b_reg_list[] = {
   1454         CFAP_EN_COR_ERR_RPTr,
   1455         MMU_DEQ_EN_COR_ERR_RPTr,
   1456         MMU_ENQ_EN_COR_ERR_RPTr,
   1457         MMU_EPRG_EN_COR_ERR_RPTr,
   1458         INTFI_EN_COR_ERR_RPTr,
   1459         LLS_EN_COR_ERR_RPT_PORTr,
   1460         LLS_EN_COR_ERR_RPT_L0r,
   1461         LLS_EN_COR_ERR_RPT_L1r,
   1462         LLS_EN_COR_ERR_RPT_L2r,
   1463         MMU_PQE_EN_COR_ERR_RPTr,
   1464         MMU_QCN_EN_COR_ERR_RPTr,
   1465         RQE_EN_COR_ERR_RPTr,
   1466         MMU_TDM_EN_COR_ERR_RPTr,
   1467         THDI_EN_COR_ERR_RPTr,
   1468         MMU_THDM_DB_EN_COR_ERR_RPTr,
   1469         MMU_THDM_MCQE_EN_COR_ERR_RPTr,
   1470         MMU_THDU_EN_COR_ERR_RPTr,
   1471         MMU_TOQ_EN_COR_ERR_RPTr,
   1472         HSP_EN_COR_ERR_RPTr
   1473     };
   1474     for (i = 0; i < COUNTOF(_1b_reg_list); i++) {
   1475         reg = _1b_reg_list[i];
   1476         regp = &(SOC_REG_INFO(unit, reg));
   1477         if (SOC_REG_IS_64(unit, reg)) {
   1478             SOC_IF_ERROR_RETURN
   1479                 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   1480             for (f = 0; f < regp->nFields; f++) {
   1481                 fieldp = &(regp->fields[f]);
   1482                 soc_reg64_field32_set(unit, reg, &rval64, fieldp->field,
   1483                                       enable ? 1 : 0);
   1484             }
   1485             SOC_IF_ERROR_RETURN
   1486                 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
   1487         } else {
   1488             SOC_IF_ERROR_RETURN
   1489                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1490             for (f = 0; f < regp->nFields; f++) {
   1491                 fieldp = &(regp->fields[f]);
   1492                 soc_reg_field_set(unit, reg, &rval, fieldp->field,
   1493                                   enable ? 1 : 0);
   1494             }
   1495             SOC_IF_ERROR_RETURN
   1496                 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1497         }
   1498     }
   1499 
   1500     return SOC_E_NONE;
   1501 }
   1502 
   1503 
   1504 STATIC int
   1505 _soc_apache_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1506                             soc_reg_t group_reg, uint64 *group_rval,
   1507                             const _soc_apache_ser_info_t *info_list,
   1508                             soc_mem_t mem, int enable)
   1509 {
   1510     const _soc_apache_ser_info_t *info;
   1511     int info_index, rv, rv1;
   1512     soc_reg_t reg;
   1513     uint32 rval;
   1514     uint64 rval64, mac_err_mask;
   1515 
   1516     rv = SOC_E_NOT_FOUND;
   1517 
   1518     /* Loop through each info entry in the list */
   1519     for (info_index = 0; ; info_index++) {
   1520         info = &info_list[info_index];
   1521         if (info->type == _SOC_PARITY_TYPE_NONE) {
   1522             /* End of table */
   1523             break;
   1524         }
   1525 
   1526         if (mem != INVALIDm && info->mem != mem) {
   1527             continue;
   1528         }
   1529 
   1530         rv = SOC_E_NONE;
   1531 
   1532         /* Enable the info entry in the group register */
   1533         if (info->group_reg_enable_field != INVALIDf) {
   1534             soc_reg64_field32_set(unit, group_reg, group_rval,
   1535                                   info->group_reg_enable_field, enable ? 1 : 0);
   1536         }
   1537 
   1538         /* Handle different parity error reporting style */
   1539         switch (info->type) {
   1540         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   1541         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   1542         case _SOC_PARITY_TYPE_MAC_RX_TS:
   1543             COMPILER_64_SET(mac_err_mask, 0, 0x7800);
   1544             if (info->group_reg_enable_field == INVALIDf) {
   1545                 COMPILER_64_OR(*group_rval, mac_err_mask);
   1546             }
   1547             /* fall through */
   1548         case _SOC_PARITY_TYPE_MIB:
   1549         case _SOC_PARITY_TYPE_PARITY:
   1550         case _SOC_PARITY_TYPE_ECC:
   1551             reg = info->enable_reg;
   1552             if (!SOC_REG_IS_VALID(unit, reg)) {
   1553                 break;
   1554             }
   1555             if (SOC_REG_IS_64(unit, reg)) {
   1556                 SOC_IF_ERROR_RETURN
   1557                     (soc_reg_get(unit, reg, port, 0, &rval64));
   1558                 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field,
   1559                                       enable ? 1 : 0);
   1560                 SOC_IF_ERROR_RETURN
   1561                     (soc_reg_set(unit, reg, port, 0, rval64));
   1562             } else {
   1563                 SOC_IF_ERROR_RETURN
   1564                     (soc_reg32_get(unit, reg, port, 0, &rval));
   1565                 soc_reg_field_set(unit, reg, &rval, info->enable_field,
   1566                                   enable ? 1 : 0);
   1567                 SOC_IF_ERROR_RETURN
   1568                     (soc_reg32_set(unit, reg, port, 0, rval));
   1569             }
   1570             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1571                         "SER enable for: %s\n"),
   1572                         (info->mem == INVALIDm) ? info->mem_str : 
   1573                         SOC_MEM_NAME(unit, info->mem)));
   1574             break;
   1575         case _SOC_PARITY_TYPE_CXXPORT:
   1576             /* One more level of enable tree structure */
   1577             rv1 = _soc_apache_ser_enable_cxxport(unit, info->id, info->info,
   1578                                                  mem, enable);
   1579             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1580                 return rv;
   1581             }
   1582             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1583                         "SER enable for: %s\n"),
   1584                         (info->mem == INVALIDm) ? info->mem_str : 
   1585                         SOC_MEM_NAME(unit, info->mem)));
   1586             break;
   1587         case _SOC_PARITY_TYPE_MMU_SER:
   1588             rv1 = _soc_apache_ser_enable_mmu_1bit_ecc(unit, enable);
   1589             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1590                 return rv;
   1591             }
   1592             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1593                         "SER enable for: %s\n"), 
   1594                         (info->mem == INVALIDm) ? info->mem_str : 
   1595                         SOC_MEM_NAME(unit, info->mem)));
   1596             break;
   1597         case _SOC_PARITY_TYPE_GENERIC:
   1598         case _SOC_PARITY_TYPE_START_ERR:
   1599         case _SOC_PARITY_TYPE_BST:
   1600             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1601                         "SER enable for: %s\n"),
   1602                         (info->mem == INVALIDm) ? info->mem_str : 
   1603                         SOC_MEM_NAME(unit, info->mem)));
   1604         default:
   1605             break;
   1606         } /* Handle different parity error reporting style */
   1607         if (mem != INVALIDm) {
   1608             break;
   1609         }
   1610 
   1611     } /* Loop through each info entry in the route block */
   1612 
   1613     return rv;
   1614 }
   1615 
   1616 STATIC int
   1617 _soc_apache_ser_enable_pm (int unit, int enable)
   1618 {
   1619 #if defined(BCM_56560_A0)
   1620     uint32    cmic_rval = 0, cmic_bit = 0;
   1621     uint64    rval64;
   1622     int       rbi, block_info_idx, port, rv = SOC_E_NONE;
   1623     const _soc_apache_ser_route_block_t   *rb;
   1624     
   1625     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval));
   1626 
   1627     for (rbi = 0; ; rbi++) {
   1628         if (soc_feature(unit, soc_feature_clport_gen2)) {
   1629             rb = &_soc_apache_ser_route_b0_blocks_irq4[rbi];
   1630         } else {
   1631             rb = &_soc_apache_ser_route_blocks_irq4[rbi];
   1632         }
   1633         cmic_bit = rb->cmic_bit;
   1634         if (cmic_bit == 0) {
   1635             /* End of table */
   1636             break;
   1637         }
   1638         if (rb->info == NULL) {
   1639             continue;
   1640         }
   1641         if (enable) {
   1642             cmic_rval |= cmic_bit;
   1643         }
   1644         port = INVALID_PORT;
   1645         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   1646             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   1647                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   1648                 break;
   1649             }
   1650         }
   1651 
   1652         if (port == INVALID_PORT) {
   1653             continue;
   1654         }
   1655 
   1656         if (rb->enable_reg != INVALIDr) {
   1657             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   1658                                   SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   1659                     /* This port block is not configured */
   1660                     continue;
   1661             }
   1662             SOC_IF_ERROR_RETURN
   1663                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64));
   1664 
   1665             rv = _soc_apache_ser_enable_info(unit, block_info_idx, rb->id, port,
   1666                                              rb->enable_reg, &rval64,
   1667                                              rb->info, INVALIDm, enable);
   1668         }
   1669 
   1670         if (rv == SOC_E_NOT_FOUND) {
   1671             continue;
   1672         } else if (SOC_FAILURE(rv)) {
   1673             return rv;
   1674         }
   1675 
   1676         if (rb->enable_reg != INVALIDr) {
   1677             /* Write per route block parity enable register */
   1678             SOC_IF_ERROR_RETURN
   1679                 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64));
   1680         }
   1681     } /* end of rbi for */
   1682 
   1683     if (enable) {
   1684         /* Write CMIC enable register */
   1685         (void)soc_cmicm_intr4_enable(unit, cmic_rval);
   1686     } else {
   1687         /* Write CMIC disable register */
   1688         (void)soc_cmicm_intr4_disable(unit, cmic_rval);
   1689     }
   1690 
   1691     return SOC_E_NONE;
   1692 #else 
   1693     return SOC_E_NONE;
   1694 #endif 
   1695 }
   1696 
   1697 STATIC int
   1698 _soc_apache_ser_enable_all (int unit, int enable)
   1699 {
   1700 #if defined(BCM_56560_A0)
   1701     uint8                                 rbi, bcount, type;
   1702     uint16                                pcount;
   1703     uint32                                cmic_rval;
   1704     uint32                                rval, cmic_bit;
   1705     int                                   port = REG_PORT_ANY;
   1706     int                                   rv, block_info_idx;
   1707     uint64                                rval64;
   1708     soc_reg_t                             reg, ecc1b_reg;
   1709     soc_field_t                           field, ecc1b_field;
   1710     _soc_reg_ser_en_info_t                *reg_info;
   1711     _soc_mem_ser_en_info_t                *mem_info;
   1712     _soc_bus_ser_en_info_t                *bus_info;
   1713     _soc_buffer_ser_en_info_t             *buf_info;
   1714     char                                  *str_type;
   1715     char                                  *str_name;
   1716     const _soc_apache_ser_route_block_t   *rb;
   1717     const _soc_apache_ser_block_info_t    *ser_block_info;
   1718     static char *parity_module_str[4]     = {"REG", "MEM", "BUS", "BUF"};
   1719 
   1720     /* coverity[result_independent_of_operands] */
   1721     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK3r(unit, &cmic_rval));
   1722 
   1723     /* Enable new fifo mechanism based SER stuff */
   1724     ser_block_info = _soc_apache_ser_block_info;
   1725     for (bcount = 0; ser_block_info[bcount].blocktype; bcount++) {
   1726         int done = 0;
   1727 
   1728         LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1729                    (BSL_META_U(unit,
   1730                                "Unit %d SER enable for: %s\n"),
   1731                                     unit, ser_block_info[bcount].name));
   1732 
   1733         type = ser_block_info[bcount].type;
   1734         reg_info = (_soc_reg_ser_en_info_t*)ser_block_info[bcount].info;
   1735         mem_info = (_soc_mem_ser_en_info_t*)ser_block_info[bcount].info;
   1736         bus_info = (_soc_bus_ser_en_info_t*)ser_block_info[bcount].info;
   1737         buf_info = (_soc_buffer_ser_en_info_t*)ser_block_info[bcount].info;
   1738         for (pcount = 0; ; pcount++) {
   1739             ecc1b_reg = INVALIDr;    
   1740             ecc1b_field = INVALIDf;
   1741             switch (type) {
   1742             case _SOC_APACHE_SER_TYPE_REG: 
   1743                 if (reg_info[pcount].reg == INVALIDr) { 
   1744                     done = 1;
   1745                 } else {
   1746                     reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg;
   1747                     field = reg_info[pcount].en_ctrl.en_fld;
   1748                     str_name = SOC_REG_NAME(unit, reg_info[pcount].reg);
   1749                 }
   1750                 break;
   1751             case _SOC_APACHE_SER_TYPE_MEM:
   1752                 if (mem_info[pcount].mem == INVALIDm) { 
   1753                     done = 1;
   1754                 } else {
   1755                     if (soc_feature(unit, soc_feature_parity_injection_l2)) {
   1756                         if ((mem_info[pcount].mem == L2_USER_ENTRYm) ||
   1757                             (mem_info[pcount].mem == L2_USER_ENTRY_DATA_ONLYm)){ 
   1758                             continue;
   1759                         }
   1760                     }
   1761                     if (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags & 
   1762                         SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP) {
   1763                         continue;
   1764                     }
   1765                     reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg;
   1766                     field = mem_info[pcount].en_ctrl.en_fld;
   1767                     ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg;
   1768                     ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld;
   1769                     str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem);
   1770                 }
   1771                 break;
   1772             case _SOC_APACHE_SER_TYPE_BUS:
   1773                 if (bus_info[pcount].en_reg == INVALIDr) { 
   1774                     done = 1;
   1775                 } else {
   1776                     reg = bus_info[pcount].en_reg;
   1777                     field = bus_info[pcount].en_fld;
   1778                     str_name = bus_info[pcount].bus_name;
   1779                 }
   1780                 break;
   1781             case _SOC_APACHE_SER_TYPE_BUF:
   1782                 if (buf_info[pcount].en_reg == INVALIDr) {
   1783                     done = 1;
   1784                 } else {
   1785                     reg = buf_info[pcount].en_reg;
   1786                     field = buf_info[pcount].en_fld;
   1787                     str_name = buf_info[pcount].buffer_name;
   1788                 }
   1789                 break;
   1790             default:
   1791                 LOG_ERROR(BSL_LS_SOC_MEM,
   1792                           (BSL_META_U(unit,
   1793                                       "Unknown parity module [bcount: %d][pcount: %d].\n"),
   1794                                        bcount, pcount));
   1795                 return SOC_E_INTERNAL;
   1796             }
   1797             if (done) { 
   1798                 break;
   1799             } else {
   1800                 str_type = parity_module_str[type];
   1801             }
   1802             /* NOTE: Do not use the field modify routine in the following as
   1803                      some regs do not return the correct value due to which the
   1804                      modify routine skips the write */
   1805             if (SOC_REG_IS_64(unit, reg)) {
   1806                 SOC_IF_ERROR_RETURN
   1807                     (soc_reg_get(unit, reg, port, 0, &rval64));
   1808                 soc_reg64_field32_set(unit, reg, &rval64, field, enable ? 1 : 0);
   1809                 SOC_IF_ERROR_RETURN
   1810                     (soc_reg_set(unit, reg, port, 0, rval64));
   1811             } else {
   1812                 SOC_IF_ERROR_RETURN
   1813                     (soc_reg32_get(unit, reg, port, 0, &rval));
   1814                 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   1815                 SOC_IF_ERROR_RETURN
   1816                     (soc_reg32_set(unit, reg, port, 0, rval));
   1817             }
   1818             if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf) {
   1819                 if (SOC_REG_IS_64(unit, ecc1b_reg)) {
   1820                     SOC_IF_ERROR_RETURN
   1821                         (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64));
   1822                     soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, enable ? 1 : 0);
   1823                     SOC_IF_ERROR_RETURN
   1824                         (soc_reg_set(unit, ecc1b_reg, port, 0, rval64));
   1825                 } else {
   1826                     SOC_IF_ERROR_RETURN
   1827                         (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval));
   1828                     soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, enable ? 1 : 0);
   1829                     if (20 == SOC_REG_ACC_TYPE(unit, ecc1b_reg)) {
   1830                         SOC_IF_ERROR_RETURN(
   1831                             soc_reg32_set(unit, ecc1b_reg, \
   1832                                           SOC_REG_ADDR_INSTANCE_MASK, 0, rval));
   1833                     } else {
   1834                         SOC_IF_ERROR_RETURN
   1835                             (soc_reg32_set(unit, ecc1b_reg, port, 0, rval));
   1836                     }
   1837                 }
   1838             }
   1839             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   1840                       (BSL_META_U(unit,
   1841                                   "SER enable for %s: %s\n"),
   1842                                    str_type, str_name));
   1843         }
   1844 
   1845         /* Loop through each place-and-route of block entry 
   1846          Handle entries with valid REG & FIELD values */
   1847         for (rbi = 0; ; rbi++) {
   1848             rb = &_soc_apache_ser_route_blocks_irq3[rbi];
   1849             cmic_bit = rb->cmic_bit;
   1850             if (cmic_bit == 0) {
   1851                 /* End of table */
   1852                 break;
   1853             }
   1854             if (rb->blocktype == ser_block_info[bcount].blocktype) {
   1855                 cmic_rval |= cmic_bit;
   1856                 if (rb->enable_reg != INVALIDr && rb->enable_field != INVALIDf) {
   1857                     SOC_IF_ERROR_RETURN
   1858                         (soc_reg_field32_modify(unit, rb->enable_reg,
   1859                             REG_PORT_ANY, rb->enable_field, enable ? 1 : 0));
   1860                 }
   1861             }
   1862         }
   1863 
   1864         /* reset (toggle) fifo if applicable */
   1865         if (ser_block_info[bcount].fifo_reset_reg != INVALIDr) {
   1866             SOC_IF_ERROR_RETURN
   1867                  (soc_reg_field32_modify(unit,
   1868                      ser_block_info[bcount].fifo_reset_reg,
   1869                                          REG_PORT_ANY, FIFO_RESETf, 1));
   1870             SOC_IF_ERROR_RETURN
   1871                  (soc_reg_field32_modify(unit,
   1872                      ser_block_info[bcount].fifo_reset_reg,
   1873                                          REG_PORT_ANY, FIFO_RESETf, 0));
   1874         }
   1875     }
   1876 
   1877     /* Enable 1B error reporting for some special items */
   1878 
   1879     /* Description of IARB_EN_COR_ERR_RPT says, supress these errors
   1880      * by setting bits. So basically we are supressing error reporting
   1881      * by setting bits.
   1882      * Then again, following TD2P code...
   1883      */
   1884     SOC_IF_ERROR_RETURN
   1885          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 
   1886                                  REG_PORT_ANY, 
   1887                                  CMIC_BUFFER_1BIT_ERROR_REPORTf,enable?1:0));
   1888     SOC_IF_ERROR_RETURN
   1889          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 
   1890                                  REG_PORT_ANY, 
   1891                                  LEARN_FIFO_1BIT_ERROR_REPORTf, enable?1:0));
   1892 
   1893     /* Loop through each place-and-route block 
   1894        Handle entries with non-null INFO */
   1895     for (rbi = 0; ; rbi++) {
   1896         rb = &_soc_apache_ser_route_blocks_irq3[rbi];
   1897         cmic_bit = rb->cmic_bit;
   1898         if (cmic_bit == 0) {
   1899             /* End of table */
   1900             break;
   1901         }
   1902         if (rb->info == NULL) {
   1903             continue;
   1904         }
   1905         if (enable) {
   1906             cmic_rval |= cmic_bit;
   1907         }
   1908 
   1909         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   1910             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   1911                     port = SOC_BLOCK_PORT(unit, block_info_idx);
   1912                     break;
   1913             }
   1914         }
   1915         if (rb->enable_reg != INVALIDr) {
   1916             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   1917                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   1918                     /* This port block is not configured */
   1919                     continue;
   1920             }
   1921             SOC_IF_ERROR_RETURN
   1922                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64));
   1923         }
   1924 
   1925         rv = _soc_apache_ser_enable_info(unit, block_info_idx, rb->id, port,
   1926                                          rb->enable_reg, &rval64,
   1927                                          rb->info, INVALIDm, enable);
   1928         if (rv == SOC_E_NOT_FOUND) {
   1929             continue;
   1930         } else if (SOC_FAILURE(rv)) {
   1931             return rv;
   1932         }
   1933 
   1934         if (rb->enable_reg != INVALIDr) {
   1935             /* Write per route block parity enable register */
   1936             SOC_IF_ERROR_RETURN
   1937                 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64));
   1938         }
   1939     }
   1940 
   1941     if (enable) {
   1942         uint32 rval1;
   1943         /* MMU enables */
   1944 
   1945         SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1));
   1946         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0);
   1947         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   1948 
   1949         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1950 
   1951         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0);
   1952         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1953 
   1954         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1);
   1955         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1956 
   1957         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */
   1958 
   1959         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1);
   1960         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   1961 
   1962         /* Write CMIC enable register */
   1963         (void)soc_cmicm_intr3_enable(unit, cmic_rval);
   1964     } else {
   1965         /* MMU disables */
   1966         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   1967         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0);
   1968         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   1969         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0));
   1970 
   1971         /* Write CMIC disable register */
   1972         (void)soc_cmicm_intr3_disable(unit, cmic_rval);
   1973     }
   1974 
   1975     SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_pm(unit,enable));
   1976 
   1977     return SOC_E_NONE;
   1978 #else 
   1979     return SOC_E_NONE;
   1980 #endif 
   1981 }
   1982 
   1983 STATIC int
   1984 _soc_apache_clear_mmu_memory(int unit, soc_mem_t mem)
   1985 {
   1986     int i, count;
   1987     static soc_mem_t mmu_mems[] = {
   1988         MMU_INTFI_XPIPE_FC_MAP_TBL0m,
   1989         MMU_INTFI_XPIPE_FC_MAP_TBL1m,
   1990         MMU_INTFI_XPIPE_FC_MAP_TBL2m
   1991     };
   1992 
   1993     count = COUNTOF(mmu_mems);
   1994     /* MMU mem clear to avoid SER issue */
   1995     for (i = 0; i < count; i++) {
   1996         if (mem != INVALIDm) {
   1997             if (mem == mmu_mems[i]) {
   1998                 SOC_IF_ERROR_RETURN
   1999                     (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2000                 break;
   2001             }
   2002         } else {
   2003             SOC_IF_ERROR_RETURN
   2004                 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2005         }
   2006     }
   2007     return SOC_E_NONE;
   2008 }
   2009 
   2010 static int _soc_ap_num_shared_alpm_banks[SOC_MAX_NUM_DEVICES] = {0};
   2011 static soc_mem_t *_soc_apache_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES];
   2012 #define _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks)    ((num_uft_banks == 4) ? 0xFFFF : 0x7FFF)
   2013 #define _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)   ((num_uft_banks == 4) ? 16 : 15)
   2014 
   2015 int
   2016 _soc_apache_mem_sram_info_get (int unit, soc_mem_t mem, int index,
   2017                                _soc_ser_sram_info_t *sram_info)
   2018 {
   2019     soc_mem_t view;
   2020     int i, j, base, base_index, offset, base_bucket, bkt_offset;
   2021     int entries_per_ram = 0, entries_per_bank, contiguous = 0;
   2022     int num_uft_banks = 0;
   2023 
   2024     switch (mem) {
   2025     case L2Xm:
   2026     case L2_ENTRY_ONLY_ECCm:
   2027         if (mem == L2Xm) {
   2028             sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr;
   2029             sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2030         }
   2031         /* Total number of dedicated L2 entries is 16k */
   2032         if (index < SOC_APACHE_NUM_ENTRIES_L2_BANK) {
   2033             /*
   2034              * Total number of L2 dedicated banks      : 2 (B0, B1)
   2035              * Number of buckets in one bank           : 2048
   2036              * Number of entries in one bucket         : 4
   2037              * Total number of entries in 1 bank       : 8192
   2038              */
   2039             /* Number of entries in a bucket */
   2040             sram_info->ram_count = SOC_APACHE_NUM_EL_L2;
   2041             /* Number of buckets in a bank */
   2042             entries_per_ram = SOC_APACHE_NUM_BKTS_PER_L2_BANK;
   2043             /* Total number of entries in one bank */
   2044             entries_per_bank = entries_per_ram * sram_info->ram_count;
   2045             /* 1st entry within L2 dedicated bank */
   2046             offset = index % entries_per_ram;
   2047             /* 1st index for correction */
   2048             base = offset;
   2049             if (index >= entries_per_bank) {
   2050                 base = offset + entries_per_bank;
   2051             }
   2052         } else {
   2053             /*
   2054              * Total number of shared banks      : 4 (B2, B3, B4, B5)
   2055              * Number of buckets in one bank     : 16384
   2056              * Number of entries in one bucket   : 4
   2057              * Total number of entries in 1 bank : 65536
   2058              */
   2059             /* Number of entries in a bucket */
   2060             sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED;
   2061             /* Number of buckets in a bank */
   2062             entries_per_ram = SOC_APACHE_NUM_BKTS_PER_SHARED_BANK;
   2063             /* Total number of entries in one bank */
   2064             entries_per_bank = entries_per_ram * sram_info->ram_count;
   2065             /* index in uft space */
   2066             base_index = index - SOC_APACHE_NUM_ENTRIES_L2_BANK;
   2067             /* base addr of uft bank */
   2068             base = (base_index/entries_per_bank) * entries_per_bank;
   2069             /* 1st entry within uft bank */
   2070             offset = base_index % entries_per_ram;
   2071             /* 1st index for correction */
   2072             base += SOC_APACHE_NUM_ENTRIES_L2_BANK + offset;
   2073         }
   2074         break;
   2075     case L3_ENTRY_ONLYm:
   2076     case L3_ENTRY_IPV4_UNICASTm:
   2077     case L3_ENTRY_IPV4_MULTICASTm:
   2078     case L3_ENTRY_IPV6_UNICASTm:
   2079     case L3_ENTRY_IPV6_MULTICASTm:
   2080     case L3_ENTRY_ONLY_ECCm:
   2081         /* Total number of dedicated L3 entries is 4k */
   2082         if (index < SOC_APACHE_NUM_ENTRIES_L3_BANK) {
   2083             sram_info->ram_count = 1;
   2084             base = index;
   2085         } else {
   2086             /*
   2087              * Total number of shared banks      : 4 (B2, B3, B4, B5)
   2088              * Number of buckets in one bank     : 16384
   2089              * Number of entries in one bucket   : 4
   2090              * Total number of entries in 1 bank : 65536
   2091              */
   2092             /* Number of entries in a bucket */
   2093             sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED;
   2094             /* Number of buckets in a bank */
   2095             entries_per_ram = SOC_APACHE_NUM_BKTS_PER_SHARED_BANK;
   2096             /* Total number of entries in one bank */
   2097             entries_per_bank = entries_per_ram * sram_info->ram_count;
   2098             /* index in uft space */
   2099             base_index = index - SOC_APACHE_NUM_ENTRIES_L3_BANK;
   2100             /* base addr of uft bank */
   2101             base = (base_index/entries_per_bank) * entries_per_bank;
   2102             /* 1st entry within uft bank */
   2103             offset = base_index % entries_per_ram;
   2104             /* 1st index for correction */
   2105             base += SOC_APACHE_NUM_ENTRIES_L3_BANK + offset;
   2106         }
   2107         break;
   2108     case L3_DEFIP_ALPM_IPV4m:
   2109     case L3_DEFIP_ALPM_IPV4_1m:
   2110     case L3_DEFIP_ALPM_IPV6_64m:
   2111     case L3_DEFIP_ALPM_IPV6_64_1m:
   2112     case L3_DEFIP_ALPM_IPV6_128m:
   2113     case L3_DEFIP_ALPM_RAWm:
   2114     case L3_DEFIP_ALPM_ECCm:
   2115         num_uft_banks = soc_apache_get_alpm_banks(unit);
   2116         sram_info->disable_reg = ILPM_SER_CONTROLr;
   2117         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2118         sram_info->force_reg = ISS_MEMORY_CONTROL_84r;
   2119         sram_info->force_field = FORCE_XOR_GENERATIONf;
   2120 
   2121         sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED;
   2122         base_bucket = ((index >> ((num_uft_banks + 1) / 2)) & SOC_APACHE_ALPM_BKT_MASK);
   2123         base = index & ((num_uft_banks == 4) ? 0x3 : 0x1);
   2124         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2125                     (BSL_META_U(unit,
   2126                                 "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base));
   2127         base_bucket = base_bucket % SOC_APACHE_ALPM_BKT_OFFFSET;
   2128         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2129                     (BSL_META_U(unit,
   2130                                 "base bucket: 0x%08x\n"), base_bucket));
   2131         sram_info->ram_count = SOC_APACHE_NUM_EL_SHARED;
   2132         base_bucket = ((index  >> ((num_uft_banks + 1) / 2)) & SOC_APACHE_ALPM_BKT_MASK);
   2133         base = index & ((num_uft_banks == 4) ? 0x3 : 0x1);
   2134         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2135                     (BSL_META_U(unit,
   2136                                 "reported bucket: 0x%08x, bank:%d\n"), base_bucket, base));
   2137         base_bucket = base_bucket % SOC_APACHE_ALPM_BKT_OFFFSET;
   2138         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2139                     (BSL_META_U(unit,
   2140                                 "base bucket: 0x%08x\n"), base_bucket));
   2141             
   2142         for (i = 0; i < SOC_APACHE_NUM_EL_SHARED; i++) {
   2143             /* Retreive views for all 8 buckets */
   2144             bkt_offset = base_bucket + SOC_APACHE_ALPM_BKT_OFFFSET * i;
   2145             view = _soc_apache_alpm_bkt_view_map[unit][bkt_offset];
   2146             if (INVALIDm != view) {
   2147                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2148                             (BSL_META_U(unit,
   2149                                         "\nbucket[%d]: 0x%08x view: %s\n"), i, bkt_offset,
   2150                              SOC_MEM_NAME(unit, view)));
   2151             }
   2152             /* Use RAW view to recovery those unused ALPM buckets and avoid
   2153              * false alarm */
   2154             if (INVALIDm == view) {
   2155                 view = L3_DEFIP_ALPM_RAWm;
   2156             }
   2157             sram_info->view[i] = view;
   2158             switch (view) {
   2159             case L3_DEFIP_ALPM_RAWm:
   2160                 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_PER_BKT_COUNT;
   2161                 sram_info->mem_indexes[i][0] = (bkt_offset <<
   2162                                                 ((num_uft_banks + 1) / 2)) | base;
   2163                 break;
   2164             case L3_DEFIP_ALPM_IPV6_128m:
   2165                 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_128_PER_BKT_COUNT;
   2166                 sram_info->mem_indexes[i][0] = (bkt_offset <<
   2167                                                 ((num_uft_banks + 1) / 2)) | base;
   2168                 sram_info->mem_indexes[i][1] = (1 <<
   2169                                                 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) |
   2170                                                 (bkt_offset << ((num_uft_banks + 1) / 2)) | base;
   2171                 break;
   2172             case L3_DEFIP_ALPM_IPV6_64_1m:
   2173                 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_1_PER_BKT_COUNT;
   2174                 sram_info->mem_indexes[i][0] = (bkt_offset <<
   2175                                                 ((num_uft_banks + 1) / 2)) | base;
   2176                 sram_info->mem_indexes[i][1] = (1 <<
   2177                                                 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) |
   2178                                                 (bkt_offset << ((num_uft_banks + 1) / 2)) | base;
   2179                 sram_info->mem_indexes[i][2] = (2 <<
   2180                                                 _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) |
   2181                                                 (bkt_offset << ((num_uft_banks + 1) / 2)) | base;
   2182                 break;
   2183             case L3_DEFIP_ALPM_IPV4m:
   2184                 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT;
   2185                 for (j = 0; j < SOC_APACHE_L3_DEFIP_ALPM_IPV4_PER_BKT_COUNT; j++) {
   2186                     sram_info->mem_indexes[i][j] = (j <<
   2187                                                     _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) |
   2188                                                     (bkt_offset << ((num_uft_banks + 1) / 2)) |
   2189                         base;                
   2190                 }
   2191                 break;
   2192             case L3_DEFIP_ALPM_IPV4_1m:
   2193             case L3_DEFIP_ALPM_IPV6_64m:
   2194                 sram_info->index_count[i] = SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT;
   2195                 for (j = 0; j < SOC_APACHE_L3_DEFIP_ALPM_IPV6_64_PER_BKT_COUNT; j++) {
   2196                     sram_info->mem_indexes[i][j] = (j <<
   2197                                                     _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) |
   2198                                                     (bkt_offset << ((num_uft_banks + 1) / 2)) |
   2199                         base;                
   2200                 }
   2201             default:
   2202                 break;
   2203             }
   2204             LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2205                         (BSL_META_U(unit,
   2206                                     "Entries per bkt: %d\n"), sram_info->index_count[i]));
   2207             for (j = 0; j < sram_info->index_count[i]; j++) {
   2208                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
   2209                             (BSL_META_U(unit,
   2210                                         "Index[%d]: [0x%08x]%d\n"), j, sram_info->mem_indexes[i][j],
   2211                              sram_info->mem_indexes[i][j]));
   2212             }
   2213         }
   2214         return SOC_E_NONE;
   2215     case VLAN_XLATEm:
   2216     case VLAN_MACm:
   2217     case VLAN_XLATE_ECCm:
   2218         contiguous = 1;
   2219         sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r;
   2220         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2221         sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r;
   2222         sram_info->force_field = FORCE_XOR_GENf;
   2223         sram_info->ram_count = SOC_APACHE_NUM_EL_VLAN_XLATE;
   2224         base = (index/4) * 4;
   2225         break;
   2226     case EGR_VLAN_XLATEm:
   2227     case EGR_VLAN_XLATE_ECCm:
   2228         contiguous = 1;
   2229         sram_info->disable_reg = EGR_VLAN_XLATE_CONTROLr;
   2230         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2231         sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr;
   2232         sram_info->force_field = FORCE_XOR_GENf;
   2233         sram_info->ram_count = SOC_APACHE_NUM_EL_EGR_VLAN_XLATE;
   2234         base = (index/4) * 4;
   2235         break;
   2236     case ING_L3_NEXT_HOPm:
   2237         sram_info->ram_count = SOC_APACHE_NUM_EL_ING_L3_NEXT_HOP(unit);
   2238         entries_per_ram = SOC_APACHE_RAM_OFFSET_ING_L3_NEXT_HOP;
   2239         base = index % entries_per_ram;
   2240         break;
   2241     case L3_IPMCm:
   2242         sram_info->ram_count = SOC_APACHE_NUM_EL_L3_IPMC(unit);
   2243         entries_per_ram = SOC_APACHE_RAM_OFFSET_L3_IPMC;
   2244         base = index % entries_per_ram;
   2245         break;
   2246     case L2MCm:
   2247         sram_info->ram_count = SOC_APACHE_NUM_EL_L2MC;
   2248         entries_per_ram = SOC_APACHE_RAM_OFFSET_L2MC;
   2249         base = index % entries_per_ram;
   2250         break;
   2251     default:
   2252         return SOC_E_UNAVAIL;
   2253     }
   2254     sram_info->mem_indexes[0][0] = base;
   2255     if (contiguous) {
   2256         for (i = 1; i < sram_info->ram_count; i++) {
   2257             sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1;
   2258         }
   2259     } else {
   2260         for (i = 1; i < sram_info->ram_count; i++) {
   2261             sram_info->mem_indexes[i][0] =  sram_info->mem_indexes[i-1][0] + entries_per_ram;
   2262         }
   2263     }
   2264     return SOC_E_NONE;
   2265 }
   2266 
   2267 STATIC int
   2268 _soc_apache_lls_hw_init(int unit)
   2269 {
   2270     uint32 rval;
   2271     int lls_init_timer;
   2272     soc_timeout_t to;
   2273 
   2274     /* Init LLS  */
   2275     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, LLS_INITr,
   2276                                                REG_PORT_ANY, INITf, 1));
   2277 
   2278     /*  Wait longer in QT; and not at all in BCMSIM */
   2279     if (SAL_BOOT_QUICKTURN) {
   2280         lls_init_timer = 5000000;
   2281     } else if (SAL_BOOT_SIMULATION) {
   2282         lls_init_timer = 50;
   2283     } else {
   2284         lls_init_timer = 50000;
   2285     }
   2286 
   2287     /* Check INIT_DONE in LLS block */
   2288     soc_timeout_init(&to, lls_init_timer, 1);
   2289     do {
   2290         SOC_IF_ERROR_RETURN(READ_LLS_INITr(unit, &rval));
   2291         if (soc_reg_field_get(unit, LLS_INITr, rval, INIT_DONEf)) {
   2292             break;
   2293         }
   2294         if (soc_timeout_check(&to)) {
   2295             LOG_WARN(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "LLS INIT timeout\n")));
   2296             break;
   2297         }
   2298     } while (TRUE);
   2299 
   2300     return SOC_E_NONE;
   2301 }
   2302 
   2303 
   2304 
   2305 /* Place holder for mmu init time defaults */
   2306 STATIC int
   2307 _soc_apache_mmu_init_default_val(int unit)
   2308 {
   2309 
   2310     /*  Initialize LLS tree to reset state */
   2311     SOC_IF_ERROR_RETURN(_soc_apache_lls_hw_init(unit));
   2312 
   2313     return SOC_E_NONE;
   2314 }
   2315 
   2316 int
   2317 _soc_apache_mem_ser_control(int unit, soc_mem_t mem, int copyno,
   2318                             int enable)
   2319 {
   2320     if (enable) {
   2321         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2322                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 0));
   2323         sal_usleep(1000);
   2324         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2325                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 1));
   2326         sal_usleep(1000);
   2327     }
   2328     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2329         SOC_IF_ERROR_RETURN(_soc_apache_clear_mmu_memory(unit, INVALIDm));
   2330         SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_all(unit, enable));
   2331     }
   2332     if (enable) {
   2333         SOC_IF_ERROR_RETURN
   2334             (_soc_apache_mmu_init_default_val(unit));
   2335     }
   2336     return SOC_E_NONE;
   2337 }
   2338 
   2339 STATIC void
   2340 _soc_apache_mem_parity_info(int unit, int block_info_idx, int pipe,
   2341                          soc_field_t field_enum, uint32 *minfo)
   2342 {
   2343     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
   2344         | ((pipe & 0xff) << SOC_ERROR_PIPE_BP)
   2345         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
   2346 }
   2347 
   2348 STATIC int
   2349 _soc_apache_mem_is_dyn(int unit, soc_mem_t mem)
   2350 {
   2351     if (SOC_MEM_FIELD_VALID(unit, mem, HITf) ||
   2352         SOC_MEM_FIELD_VALID(unit, mem, HIT0f) ||
   2353         SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) ||
   2354         SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) ||
   2355         SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) ||
   2356         SOC_MEM_FIELD_VALID(unit, mem, HITSAf) ||
   2357         SOC_MEM_FIELD_VALID(unit, mem, HITDAf) ||
   2358         SOC_MEM_FIELD_VALID(unit, mem, B0_HITf) ||
   2359         SOC_MEM_FIELD_VALID(unit, mem, B1_HITf)) {
   2360         return 1;
   2361     }
   2362     if (mem == L2_ENTRY_ONLY_ECCm ||
   2363         mem == L3_ENTRY_ONLY_ECCm ||
   2364         mem == L3_DEFIP_ALPM_ECCm) {
   2365         return 1;
   2366     }
   2367     return 0;
   2368 }
   2369 
   2370 STATIC int
   2371 _soc_apache_populate_ser_log(int unit, soc_reg_t parity_enable_reg,
   2372                           soc_field_t parity_enable_field,
   2373                           soc_mem_t mem,
   2374                           int mem_block,
   2375                           soc_acc_type_t acc_type,
   2376                           int index,
   2377                           sal_usecs_t detect_time,
   2378                           uint32 sblk,
   2379                           uint32 address)
   2380 {
   2381     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   2382     int log_entry_size, id, entry_dw;
   2383     uint32 *cache;
   2384     uint8 *vmap;
   2385     soc_ser_log_tlv_memory_t log_mem;
   2386     soc_ser_log_tlv_generic_t log_generic;
   2387 
   2388     sal_memset(&log_generic, 0, sizeof(log_generic));
   2389     sal_memset(&log_mem, 0, sizeof(log_mem));
   2390 
   2391     /*
   2392     must be large enough for at least generic and terminator, as well as the
   2393     memory type since we might decode it in soc_ser_correction.
   2394     */
   2395     log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 +
   2396                      sizeof(soc_ser_log_tlv_generic_t) +
   2397                      sizeof(soc_ser_log_tlv_memory_t);
   2398 
   2399     if (mem == INVALIDm) {
   2400         mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address);
   2401         if (mem != INVALIDm) {
   2402             if (sblk) {
   2403                 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) {
   2404                     if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) {
   2405                         break;
   2406                     }
   2407                 }
   2408             } else {
   2409                 mem_block = SOC_MEM_BLOCK_ANY(unit, mem);
   2410             }
   2411         }
   2412     }
   2413     /*
   2414     If we have decoded the memory we can record its contents/cache
   2415     */
   2416     if((mem != INVALIDm) &&
   2417        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) {
   2418         entry_dw = soc_mem_entry_words(unit, mem);
   2419 
   2420         /* Check to make sure this isn't a duplicate */
   2421         /* Search for a log entry with the same mem, and index with within the last 5 seconds */
   2422         if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) {
   2423             return 0;
   2424         }
   2425 
   2426         log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2427 
   2428         cache = SOC_MEM_STATE(unit, mem).cache[mem_block];
   2429         vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block];
   2430         if (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CACHABLE) {
   2431             log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2432         }
   2433 
   2434         /* create the entry based on determined size, save id */
   2435         id = soc_ser_log_create_entry(unit, log_entry_size);
   2436 
   2437         /* Add the memory information to the log now so we can detect duplicate errors */
   2438         log_generic.time = detect_time;
   2439         log_mem.memory = mem;
   2440         log_mem.index = index;
   2441         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY,
   2442             sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2443         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC,
   2444             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   2445 
   2446         if (!_soc_apache_mem_is_dyn(unit, mem) &&
   2447             (parity_enable_reg != INVALIDr) &&
   2448             (parity_enable_field != INVALIDf)) {
   2449 
   2450             /* Disable Parity */
   2451             if (soc_reg_field32_modify(unit, parity_enable_reg,
   2452                 REG_PORT_ANY, parity_enable_field, 0) < 0) {
   2453                 return 0;
   2454             }
   2455 
   2456             /*Enable NACK on read */
   2457             soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN,
   2458                                   mem, 0, mem_block,
   2459                                   index, tmp_entry);
   2460 
   2461             /* fill in the memory contents tlv */
   2462             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS,
   2463                 entry_dw*4, tmp_entry) < 0) {
   2464                 return 0;
   2465             }
   2466 
   2467             /* Enable Parity */
   2468             if (soc_reg_field32_modify(unit, parity_enable_reg,
   2469                 REG_PORT_ANY, parity_enable_field, 1) < 0) {
   2470                 return 0;
   2471             }
   2472         }
   2473 
   2474 
   2475         if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2476             /* fill in the memory cache tlv */
   2477             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE,
   2478                 entry_dw*4, (cache + index*entry_dw)) < 0) {
   2479                 return 0;
   2480             }
   2481         }
   2482     } else {
   2483         id = soc_ser_log_create_entry(unit, log_entry_size);
   2484     }
   2485 
   2486     return id;
   2487 }
   2488 
   2489 STATIC int
   2490 _soc_apache_ser_process_parity(int unit, int block_info_idx, int pipe, 
   2491                                int port, const _soc_apache_ser_info_t *info,
   2492                                int schan, char *prefix_str, char *mem_str)
   2493 {
   2494     int rv;
   2495     _soc_apache_ser_reg_t reg_entry[2], *reg_ptr;
   2496     soc_reg_t reg;
   2497     uint32 rval, minfo;
   2498     uint32 multiple, entry_idx, idx, has_error;
   2499     char *mem_str_ptr;
   2500     _soc_ser_correct_info_t spci;
   2501 
   2502     if (schan) {
   2503         /* Some table does not have NACK register */
   2504         return SOC_E_NONE;
   2505     } else {
   2506         if (info->intr_status_reg != INVALIDr) {
   2507             reg_entry[0].reg = info->intr_status_reg;
   2508             reg_entry[0].mem_str = NULL;
   2509             reg_entry[1].reg = INVALIDr;
   2510             reg_ptr = reg_entry;
   2511         } else if (info->intr_status_reg_list != NULL) {
   2512             reg_ptr = info->intr_status_reg_list;
   2513         } else {
   2514             return SOC_E_NONE;
   2515         }
   2516     }
   2517 
   2518     has_error = FALSE;
   2519     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2520         reg = reg_ptr[idx].reg;
   2521         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2522             reg_ptr[idx].mem_str : mem_str;
   2523         SOC_IF_ERROR_RETURN
   2524             (soc_reg32_get(unit, reg, port, 0, &rval));
   2525 
   2526         if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) {
   2527             has_error = TRUE;
   2528             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2529             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2530             _soc_apache_mem_parity_info(unit, block_info_idx, pipe,
   2531                                      info->group_reg_status_field, &minfo);
   2532             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2533                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   2534                                entry_idx, minfo);
   2535             LOG_WARN(BSL_LS_SOC_SER,
   2536                       (BSL_META_U(unit,
   2537                                   "%s %s entry %d parity error\n"),
   2538                        prefix_str, mem_str_ptr, entry_idx));
   2539             if (multiple) {
   2540                 LOG_WARN(BSL_LS_SOC_SER,
   2541                           (BSL_META_U(unit,
   2542                                       "%s %s has multiple parity errors\n"),
   2543                            prefix_str, mem_str_ptr));
   2544             }
   2545             if (idx == 0 && info->mem != INVALIDm) {
   2546                 sal_memset(&spci, 0, sizeof(spci));
   2547                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   2548                 if (multiple) {
   2549                     spci.flags |= SOC_SER_ERR_MULTI;
   2550                 }
   2551                 spci.reg = INVALIDr;
   2552                 spci.mem = info->mem;
   2553                 spci.blk_type = -1;
   2554                 spci.index = entry_idx;
   2555                 spci.parity_type = info->type;
   2556                 spci.detect_time = sal_time_usecs();
   2557                 spci.log_id = _soc_apache_populate_ser_log(unit,
   2558                                           info->enable_reg,
   2559                                           info->enable_field,
   2560                                           spci.mem,
   2561                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   2562                                           spci.acc_type,
   2563                                           spci.index,
   2564                                           spci.detect_time,
   2565                                           spci.sblk,
   2566                                           spci.addr);
   2567                 rv = soc_ser_correction(unit, &spci);
   2568                 if (spci.log_id != 0) {
   2569                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2570                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   2571                                        spci.log_id, 0);
   2572                 }
   2573                 if (SOC_FAILURE(rv)) {
   2574                     /* Add reporting failed to correct event flag to
   2575                      * application */
   2576                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2577                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   2578                             entry_idx, minfo);
   2579                     return rv;
   2580                 }
   2581             }
   2582         }
   2583 
   2584         /* Clear parity status */
   2585         SOC_IF_ERROR_RETURN
   2586             (soc_reg32_set(unit, reg, port, 0, 0));
   2587     }
   2588 
   2589     if (!has_error) {
   2590         LOG_ERROR(BSL_LS_SOC_SER,
   2591                   (BSL_META_U(unit,
   2592                               "%s %s parity hardware inconsistency\n"),
   2593                    prefix_str, mem_str));
   2594     }
   2595 
   2596     return SOC_E_NONE;
   2597 }
   2598 
   2599 STATIC int
   2600 _soc_apache_ser_process_ecc(int unit, int block_info_idx, int pipe, int port,
   2601                               const _soc_apache_ser_info_t *info,
   2602                               int schan, char *prefix_str, char *mem_str)
   2603 {
   2604     int rv;
   2605     _soc_apache_ser_reg_t reg_entry[2], *reg_ptr;
   2606     soc_reg_t reg;
   2607     uint32 rval, minfo;
   2608     uint64 rval64;
   2609     uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error;
   2610     char *mem_str_ptr;
   2611     _soc_ser_correct_info_t spci;
   2612 
   2613     if (schan) {
   2614         /* Some table does not have NACK register */
   2615         return SOC_E_NONE;
   2616     } else {
   2617         if (info->intr_status_reg != INVALIDr) {
   2618             reg_entry[0].reg = info->intr_status_reg;
   2619             reg_entry[0].mem_str = NULL;
   2620             reg_entry[1].reg = INVALIDr;
   2621             reg_ptr = reg_entry;
   2622         } else if (info->intr_status_reg_list != NULL) {
   2623             reg_ptr = info->intr_status_reg_list;
   2624         } else {
   2625             return SOC_E_NONE;
   2626         }
   2627     }
   2628 
   2629     has_error = FALSE;
   2630     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2631         reg = reg_ptr[idx].reg;
   2632         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2633             reg_ptr[idx].mem_str : mem_str;
   2634 
   2635         if (SOC_REG_IS_64(unit, reg)) {
   2636             SOC_IF_ERROR_RETURN
   2637                 (soc_reg64_get(unit, reg, port, 0, &rval64));
   2638             ecc_err = soc_reg64_field32_get(unit, reg, rval64, ECC_ERRf);
   2639             multiple = soc_reg64_field32_get(unit, reg, rval64, MULTIPLE_ERRf);
   2640             double_bit = soc_reg64_field32_get(unit, reg, rval64, DOUBLE_BIT_ERRf);
   2641             entry_idx = soc_reg64_field32_get(unit, reg, rval64, ENTRY_IDXf);
   2642         } else {
   2643             SOC_IF_ERROR_RETURN
   2644                 (soc_reg32_get(unit, reg, port, 0, &rval));
   2645             ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf);
   2646             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2647             double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf);
   2648             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2649         }
   2650 
   2651         if (ecc_err) {
   2652             has_error = TRUE;
   2653             _soc_apache_mem_parity_info(unit, block_info_idx, pipe,
   2654                                      info->group_reg_status_field, &minfo);
   2655             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2656                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   2657                                entry_idx, minfo);
   2658             sal_memset(&spci, 0, sizeof(spci));
   2659             if (double_bit) {
   2660                 spci.double_bit = 1;
   2661                 LOG_WARN(BSL_LS_SOC_SER,
   2662                           (BSL_META_U(unit,
   2663                                       "%s %s entry %d double-bit ECC error\n"),
   2664                            prefix_str, mem_str_ptr, entry_idx));
   2665             } else {
   2666                 LOG_WARN(BSL_LS_SOC_SER,
   2667                           (BSL_META_U(unit,
   2668                                       "%s %s entry %d ECC error\n"),
   2669                            prefix_str, mem_str_ptr, entry_idx));
   2670             }
   2671             if (multiple) {
   2672                 LOG_WARN(BSL_LS_SOC_SER,
   2673                           (BSL_META_U(unit,
   2674                                       "%s %s has multiple ECC errors\n"),
   2675                            prefix_str, mem_str_ptr));
   2676             }
   2677             if (idx == 0 && info->mem != INVALIDm) {
   2678                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   2679                 if (multiple) {
   2680                     spci.flags |= SOC_SER_ERR_MULTI;
   2681                 }
   2682                 spci.reg = INVALIDr;
   2683                 spci.mem = info->mem;
   2684                 spci.blk_type = -1;
   2685                 spci.index = entry_idx;
   2686                 spci.parity_type = info->type;
   2687                 spci.detect_time = sal_time_usecs();
   2688                 spci.log_id = _soc_apache_populate_ser_log(unit,
   2689                                           info->enable_reg,
   2690                                           info->enable_field,
   2691                                           spci.mem,
   2692                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   2693                                           spci.acc_type,
   2694                                           spci.index,
   2695                                           spci.detect_time,
   2696                                           spci.sblk,
   2697                                           spci.addr);
   2698                 rv = soc_ser_correction(unit, &spci);
   2699                 if (spci.log_id != 0) {
   2700                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2701                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   2702                                        spci.log_id, 0);
   2703                 }
   2704                 if (SOC_FAILURE(rv)) {
   2705                     /* Add reporting failed to correct event flag to
   2706                      * application */
   2707                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2708                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   2709                             entry_idx, minfo);
   2710                     return rv;
   2711                 }
   2712             }
   2713         }
   2714 
   2715         /* Clear parity status */
   2716         if (SOC_REG_IS_64(unit, reg)) {
   2717             COMPILER_64_ZERO(rval64);
   2718             SOC_IF_ERROR_RETURN
   2719                 (soc_reg64_set(unit, reg, port, 0, rval64));
   2720         } else {
   2721             SOC_IF_ERROR_RETURN
   2722                 (soc_reg32_set(unit, reg, port, 0, 0));
   2723         }
   2724     }
   2725 
   2726     if (!has_error) {
   2727         LOG_ERROR(BSL_LS_SOC_SER,
   2728                   (BSL_META_U(unit,
   2729                               "%s %s ECC hardware inconsistency\n"),
   2730                    prefix_str, mem_str));
   2731     }
   2732 
   2733     return SOC_E_NONE;
   2734 }
   2735 
   2736 STATIC int
   2737 _soc_apache_ser_process_mac(int unit, int block_info_idx, int pipe, int port,
   2738                             const _soc_apache_ser_info_t *info,
   2739                             int schan, char *prefix_str, char *mem_str)
   2740 {
   2741     _soc_apache_ser_reg_t reg_entry[2], *reg_ptr;
   2742     soc_reg_t reg;
   2743     soc_field_t single_bit_f, double_bit_f;
   2744     uint64 rval;
   2745     uint32 single_bit = 0, double_bit = 0, idx;
   2746     char *mem_str_ptr;
   2747 
   2748     if (schan) {
   2749         /* Some table does not have NACK register */
   2750         return SOC_E_NONE;
   2751     } else {
   2752         if (info->intr_status_reg != INVALIDr) {
   2753             reg_entry[0].reg = info->intr_status_reg;
   2754             reg_entry[0].mem_str = NULL;
   2755             reg_entry[1].reg = INVALIDr;
   2756             reg_ptr = reg_entry;
   2757         } else if (info->intr_status_reg_list != NULL) {
   2758             reg_ptr = info->intr_status_reg_list;
   2759         } else {
   2760             return SOC_E_NONE;
   2761         }
   2762     }
   2763 
   2764     switch (info->type) {
   2765         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   2766             single_bit_f = TX_CDC_SINGLE_BIT_ERRf;
   2767             double_bit_f = TX_CDC_DOUBLE_BIT_ERRf;
   2768             break;
   2769         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   2770             single_bit_f = RX_CDC_SINGLE_BIT_ERRf;
   2771             double_bit_f = RX_CDC_DOUBLE_BIT_ERRf;
   2772             break;
   2773         case _SOC_PARITY_TYPE_MAC_RX_TS:
   2774             single_bit_f = RX_TS_MEM_SINGLE_BIT_ERRf;
   2775             double_bit_f = RX_TS_MEM_DOUBLE_BIT_ERRf;
   2776             break;
   2777         default:
   2778             return SOC_E_PARAM;
   2779     }
   2780 
   2781     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2782         reg = reg_ptr[idx].reg;
   2783         mem_str_ptr = reg_ptr[idx].mem_str != NULL ? reg_ptr[idx].mem_str : mem_str;
   2784         SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, port, 0, &rval));
   2785 
   2786         single_bit = soc_reg64_field32_get(unit, reg, rval, single_bit_f);
   2787         double_bit = soc_reg64_field32_get(unit, reg, rval, double_bit_f);
   2788         if (single_bit || double_bit) {
   2789             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2790                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0);
   2791             if (double_bit) {
   2792                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2793                                    SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0);
   2794                 LOG_WARN(BSL_LS_SOC_SER,
   2795                           (BSL_META_U(unit,
   2796                                       "%s %s double-bit ECC error on port %d\n"),
   2797                            prefix_str, mem_str_ptr, port));
   2798             } else {
   2799                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2800                                    SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0);
   2801                 LOG_WARN(BSL_LS_SOC_SER,
   2802                           (BSL_META_U(unit,
   2803                                       "%s %s single-bit ECC error on port %d\n"),
   2804                            prefix_str, mem_str_ptr, port));
   2805             }
   2806         }
   2807 
   2808         /* Clear parity status by a rising edge on intr_clr_field in intr_clr_reg */
   2809         SOC_IF_ERROR_RETURN
   2810             (soc_reg64_get(unit, info->intr_clr_reg, port, 0, &rval));
   2811         if (single_bit) {
   2812             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 0);
   2813             SOC_IF_ERROR_RETURN
   2814                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   2815             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 1);
   2816             SOC_IF_ERROR_RETURN
   2817                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   2818         }
   2819         if (double_bit) {
   2820             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 0);
   2821             SOC_IF_ERROR_RETURN
   2822                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   2823             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 1);
   2824             SOC_IF_ERROR_RETURN
   2825                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   2826         }
   2827     }
   2828 
   2829     return SOC_E_NONE;
   2830 }
   2831 
   2832 STATIC int
   2833 _soc_apache_ser_process_mib(int unit, int block_info_idx, int pipe, int port,
   2834                             const _soc_apache_ser_info_t *info,
   2835                             int schan, char *prefix_str, char *mem_str)
   2836 {
   2837     _soc_apache_ser_reg_t reg_entry[2], *reg_ptr;
   2838     soc_reg_t reg;
   2839     uint32 rval;
   2840     uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error;
   2841     char *mem_str_ptr;
   2842 
   2843     if (schan) {
   2844         /* Some table does not have NACK register */
   2845         return SOC_E_NONE;
   2846     } else {
   2847         if (info->intr_status_reg != INVALIDr) {
   2848             reg_entry[0].reg = info->intr_status_reg;
   2849             reg_entry[0].mem_str = NULL;
   2850             reg_entry[1].reg = INVALIDr;
   2851             reg_ptr = reg_entry;
   2852         } else if (info->intr_status_reg_list != NULL) {
   2853             reg_ptr = info->intr_status_reg_list;
   2854         } else {
   2855             return SOC_E_NONE;
   2856         }
   2857     }
   2858 
   2859     has_error = FALSE;
   2860     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2861         reg = reg_ptr[idx].reg;
   2862         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2863                       reg_ptr[idx].mem_str : mem_str;
   2864 
   2865         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   2866         ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf);
   2867         multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2868         double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf);
   2869         entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2870 
   2871         if (ecc_err) {
   2872             has_error = TRUE;
   2873             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2874                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0);
   2875             if (double_bit) {
   2876                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2877                                    SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE,
   2878                                    entry_idx, 0);
   2879                 LOG_WARN(BSL_LS_SOC_SER,
   2880                           (BSL_META_U
   2881                            (unit, "%s %s double-bit ECC error on port %d\n"),
   2882                            prefix_str, mem_str_ptr, port));
   2883             } else {
   2884                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   2885                                    SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED,
   2886                                    entry_idx, 0);
   2887                 LOG_WARN(BSL_LS_SOC_SER,
   2888                           (BSL_META_U
   2889                            (unit, "%s %s single-bit ECC error on port %d\n"),
   2890                            prefix_str, mem_str_ptr, port));
   2891             }
   2892 
   2893             if (multiple) {
   2894                 LOG_WARN(BSL_LS_SOC_SER,
   2895                           (BSL_META_U(unit, "%s %s has multiple ECC errors\n"),
   2896                            prefix_str, mem_str_ptr));
   2897             }
   2898             if (double_bit) {
   2899                 /* Entry Idx:
   2900                  * 0-15  Port 0
   2901                  * 16-31 Port 1
   2902                  * 32-47 Port 2
   2903                  * 48-63 Port 3
   2904                  * In case of double-bit error we need to reset MIB counters
   2905                  * for that port to recover
   2906                  */
   2907                 rval = 0x1 << ((entry_idx & 63) / 16);
   2908                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, rval));
   2909                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, 0x0));
   2910             }
   2911         }
   2912 
   2913         /* Clear parity status */
   2914         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, 0));
   2915     }
   2916 
   2917     if (!has_error) {
   2918         LOG_ERROR(BSL_LS_SOC_SER,
   2919                   (BSL_META_U(unit, "%s %s ECC hardware inconsistency\n"),
   2920                    prefix_str, mem_str));
   2921     }
   2922 
   2923     return SOC_E_NONE;
   2924 }
   2925 
   2926 STATIC void
   2927 _soc_apache_ser_control_reg_get(int unit,
   2928                                 void *fifo_ser_list,
   2929                                 soc_mem_t   mem,
   2930                                 soc_reg_t   *ser_control_reg,
   2931                                 soc_field_t *ser_enable_field)
   2932 {
   2933     int i;
   2934     _soc_mem_ser_en_info_t *ser_en_info = NULL;
   2935 
   2936     if ((fifo_ser_list == NULL) || (ser_control_reg == NULL) || 
   2937         (ser_enable_field == NULL)) {
   2938         return;
   2939     }
   2940 
   2941     ser_en_info = (_soc_mem_ser_en_info_t*)fifo_ser_list;
   2942     for (i = 0; ser_en_info[i].mem != INVALIDm; i++) {
   2943         if (ser_en_info[i].mem == mem) {
   2944             *ser_control_reg = ser_en_info[i].en_ctrl.ctrl_type.en_reg;
   2945             *ser_enable_field = ser_en_info[i].en_ctrl.en_fld;
   2946             break;
   2947         }
   2948     }
   2949 }
   2950 
   2951 STATIC int
   2952 _soc_apache_ser_process_mmu_err (int unit, int block_info_idx,
   2953                                  const _soc_apache_ser_info_t *info,
   2954                                  char *prefix_str)
   2955 {
   2956 #if defined(BCM_56560_A0)
   2957     uint32 rval, err, addr, bidx;
   2958     uint64 rval64;
   2959     soc_reg_t reg = MMU_MEM_FAIL_ADDR_64r;
   2960     uint8 blk_idx;
   2961     uint32 sblk = 0;
   2962     int rv = SOC_E_NONE;
   2963     _soc_ser_correct_info_t spci;
   2964     soc_reg_t parity_enable_reg = INVALIDr;
   2965     soc_field_t parity_enable_field = INVALIDf;
   2966     
   2967     SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   2968     if (soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)) {
   2969         LOG_ERROR(BSL_LS_SOC_SER,
   2970                   (BSL_META_U(unit,
   2971                               "MMU SER interrupt with empty fifo !!\n")));
   2972         SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   2973         LOG_WARN(BSL_LS_SOC_SER,
   2974                   (BSL_META_U(unit,
   2975                               "MMU ERR status: 0x%08x\n"), rval));
   2976         SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0));
   2977         return rv;
   2978     }
   2979     SOC_BLOCK_ITER(unit, blk_idx, SOC_BLK_MMU) {
   2980         sblk = SOC_BLOCK2SCH(unit, blk_idx);
   2981         break;
   2982     }
   2983     do {
   2984         SOC_IF_ERROR_RETURN(READ_MMU_MEM_FAIL_ADDR_64r(unit, &rval64));
   2985         err = soc_reg64_field32_get(unit, reg, rval64, ERR_TYPEf);
   2986         addr = soc_reg64_field32_get(unit, reg, rval64, EADDRf);
   2987         bidx = soc_reg64_field32_get(unit, reg, rval64, BIDXf);
   2988 
   2989 
   2990         /* Address reported in MMU_MEM_FAIL_ADDR_64 is the entry offset within 
   2991          * MMU sub block. The complete Sbus address is composed of MMU sub block 
   2992          * base address and offset within MMU sub block address space.
   2993          */
   2994         addr = (bidx << 26) | addr;
   2995         sal_memset(&spci, 0, sizeof(spci));
   2996         spci.flags |= SOC_SER_SRC_MEM;
   2997         spci.reg = INVALIDr;
   2998         spci.mem = INVALIDm;
   2999         spci.acc_type = -1;
   3000         spci.blk_type = SOC_BLK_MMU;
   3001         spci.sblk = sblk;
   3002         spci.detect_time = sal_time_usecs();
   3003         
   3004         /* Try to decode memory */
   3005         spci.mem = soc_addr_to_mem_extended(unit, sblk, _SOC_ACC_TYPE_PIPE_ANY, addr);
   3006         if (spci.mem != INVALIDm) {
   3007             spci.index = addr - soc_mem_base(unit, spci.mem);
   3008             spci.flags |= SOC_SER_REG_MEM_KNOWN;
   3009             _soc_apache_ser_control_reg_get(unit,
   3010                                             _soc_bcm56560_a0_mmu_mem_ser_info,
   3011                                             spci.mem,
   3012                                             &parity_enable_reg,
   3013                                             &parity_enable_field);
   3014         } else {
   3015             spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   3016         }
   3017         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3018                            SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   3019                            sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3020         spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3021         spci.log_id = _soc_apache_populate_ser_log(unit, parity_enable_reg,
   3022                                                    parity_enable_field,
   3023                                                    spci.mem, blk_idx,
   3024                                                    _SOC_ACC_TYPE_PIPE_ANY,
   3025                                                    spci.index,
   3026                                                    spci.detect_time, spci.sblk,
   3027                                                    spci.addr);
   3028         if ((spci.mem == INVALIDm) ||
   3029             (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) {
   3030             LOG_WARN(BSL_LS_SOC_SER,
   3031                       (BSL_META_U(unit,
   3032                                   "MMU ERR Type: %s, Addr: 0x%08x, module: %d\n"),
   3033                                   (err == 1) ? "1B error" : "2B error", addr, bidx));
   3034             rv = soc_ser_correction(unit, &spci);
   3035             if (SOC_FAILURE(rv)) {
   3036                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3037                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3038                                    sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3039             }
   3040         } else {
   3041             rv = SOC_E_NONE;
   3042             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3043                                SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED,
   3044                                sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3045         }
   3046 
   3047         if (spci.log_id != 0) {
   3048             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3049                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3050                                spci.log_id, 0);
   3051         }
   3052         SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   3053     } while (!soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf));
   3054     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &rval));
   3055     LOG_WARN(BSL_LS_SOC_SER,
   3056               (BSL_META_U(unit,
   3057                           "MMU ERR ctr: %d\n"), rval));
   3058     SOC_IF_ERROR_RETURN
   3059         (soc_reg_field32_modify(unit, info->intr_status_reg, REG_PORT_ANY,
   3060                                 info->group_reg_status_field, 0));
   3061 
   3062     SOC_IF_ERROR_RETURN
   3063         (soc_reg_field32_modify(unit, info->intr_clr_reg, REG_PORT_ANY,
   3064                                 info->intr_clr_field, 1));
   3065     SOC_IF_ERROR_RETURN
   3066         (soc_reg_field32_modify(unit, info->intr_clr_reg, REG_PORT_ANY,
   3067                                 info->intr_clr_field, 0));
   3068     return rv;
   3069 #else 
   3070     return SOC_E_NONE;
   3071 #endif  
   3072 }
   3073 
   3074 STATIC int
   3075 _soc_apache_ser_process_start_err(int unit, int block_info_idx,
   3076                                     const _soc_apache_ser_info_t *info,
   3077                                     char *prefix_str)
   3078 {
   3079 #if defined(BCM_56560_A0)
   3080     soc_info_t *si;
   3081     uint64 rval64;
   3082     uint32 pbmp_31_0, pbmp_63_32, pbmp_74_64;
   3083     soc_pbmp_t pbmp;
   3084     uint32 rval32, minfo;
   3085     int port, mmu_port, phy_port;
   3086     soc_ser_log_tlv_generic_t log_generic;
   3087     int log_id;
   3088 
   3089     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3090 
   3091     si = &SOC_INFO(unit);
   3092 
   3093     /* mmu port 52-0 */
   3094     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_0r(unit, &rval64));
   3095     pbmp_31_0 = COMPILER_64_LO(rval64);
   3096     pbmp_63_32 = COMPILER_64_HI(rval64);
   3097     /* mmu port 74-64 */
   3098     SOC_IF_ERROR_RETURN
   3099         (soc_reg32_get(unit, START_BY_START_ERROR_1r, REG_PORT_ANY, 0, &rval32));
   3100     pbmp_74_64 = (rval32 & 0x3ff);
   3101     SOC_PBMP_CLEAR(pbmp);
   3102     SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0);
   3103     SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32);
   3104     SOC_PBMP_WORD_SET(pbmp, 2, pbmp_74_64);
   3105 
   3106     SOC_PBMP_ITER(pbmp, mmu_port) {
   3107         phy_port = si->port_m2p_mapping[mmu_port];
   3108         port = si->port_p2l_mapping[phy_port];
   3109         _soc_apache_mem_parity_info(unit, block_info_idx, 0,
   3110                                  info->group_reg_status_field, &minfo);
   3111         /* Report uncorrectable event flag to application */
   3112         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3113                            SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3114                            minfo);
   3115 
   3116         log_generic.time = sal_time_usecs();
   3117         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3118         log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3119         log_generic.parity_type = info->type;
   3120 
   3121         log_id = soc_ser_log_create_entry(unit,
   3122             sizeof(soc_ser_log_tlv_generic_t) +
   3123             sizeof(soc_ser_log_tlv_hdr_t) *2);
   3124 
   3125         soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3126             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3127         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3128                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3129 
   3130         LOG_WARN(BSL_LS_SOC_SER,
   3131                   (BSL_META_U(unit,
   3132                               "%s port %d start error detected\n"), prefix_str,
   3133                               port));
   3134     }
   3135 
   3136     /* Clear parity status */
   3137     COMPILER_64_ZERO(rval64);
   3138     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_0r(unit, rval64));
   3139     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_1r(unit, rval64));
   3140 
   3141     return SOC_E_NONE;
   3142 #else 
   3143     return SOC_E_NONE;
   3144 #endif  
   3145 }
   3146 
   3147 STATIC int
   3148 _soc_apache_process_ser (int unit, int block_info_idx, int inst, int pipe,
   3149                          int port, soc_reg_t group_reg, uint64 group_rval,
   3150                          const _soc_apache_ser_info_t *info_list,
   3151                          char *prefix_str);
   3152 STATIC int
   3153 _soc_apache_ser_process_cxxport(int unit, int inst, int pipe,
   3154                                 const _soc_apache_ser_info_t *info, char *prefix_str)
   3155 {
   3156     soc_reg_t port_reg;
   3157     uint64 port_rval;
   3158     int block_info_idx, port, blk_idx;
   3159 
   3160     if (info->intr_status_reg == INVALIDr) {
   3161         return SOC_E_NONE;
   3162     }
   3163 
   3164     if ((inst == 0) || (inst == 3)) {
   3165         blk_idx    = SOC_BLK_CLPORT;
   3166     } else {
   3167         blk_idx    = SOC_BLK_XLPORT;
   3168     }
   3169 
   3170     port = -1;
   3171     SOC_BLOCK_ITER(unit, block_info_idx, blk_idx) {
   3172         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst) {
   3173             port = SOC_BLOCK_PORT(unit, block_info_idx);
   3174             break;
   3175         }
   3176     }
   3177     if (port < 0) {
   3178         return SOC_E_NONE;
   3179     }
   3180 
   3181     port_reg = info->intr_status_reg;
   3182     SOC_IF_ERROR_RETURN
   3183         (soc_reg_get(unit, port_reg, port, 0, &port_rval));
   3184     if (COMPILER_64_IS_ZERO(port_rval)) {
   3185         return SOC_E_NONE;
   3186     }
   3187 
   3188     SOC_IF_ERROR_RETURN
   3189         (_soc_apache_process_ser(unit, block_info_idx, inst, pipe, port,
   3190                                  port_reg, port_rval, info->info, prefix_str));
   3191 
   3192     return SOC_E_NONE;
   3193 }
   3194 
   3195 STATIC _soc_apache_bst_hw_cb apache_bst_cb;
   3196 
   3197 STATIC int
   3198 _soc_apache_process_mmu_bst(int unit)
   3199 {
   3200     int rv = SOC_E_NONE;
   3201     if (apache_bst_cb) {
   3202         rv = apache_bst_cb(unit);
   3203     }
   3204     return rv;
   3205 }
   3206 
   3207 int soc_apache_set_bst_callback(int unit, _soc_apache_bst_hw_cb cb)
   3208 {
   3209     apache_bst_cb = cb;
   3210     return SOC_E_NONE;
   3211 }
   3212 
   3213 STATIC int
   3214 _soc_apache_process_ser (int unit, int block_info_idx, int inst, int pipe,
   3215                          int port, soc_reg_t group_reg, uint64 group_rval,
   3216                          const _soc_apache_ser_info_t *info_list,
   3217                          char *prefix_str)
   3218 {
   3219     const _soc_apache_ser_info_t *info;
   3220     int info_index;
   3221     char *mem_str = "INVALIDm";
   3222     uint32 minfo;
   3223     soc_ser_log_tlv_generic_t log_generic;
   3224     int log_id;
   3225 
   3226     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3227 
   3228     /* Loop through each info entry in the list */
   3229     for (info_index = 0; ; info_index++) {
   3230         info = &info_list[info_index];
   3231         if (info->type == _SOC_PARITY_TYPE_NONE) {
   3232             /* End of table */
   3233             break;
   3234         }
   3235 
   3236         /* Check status for the info entry in the group register */
   3237         if ((info->group_reg_status_field != INVALIDf) &&
   3238             (!soc_reg64_field32_get(unit, group_reg, group_rval,
   3239                                     info->group_reg_status_field))) {
   3240             continue;
   3241         }
   3242 
   3243         if (info->mem_str) {
   3244             mem_str = info->mem_str;
   3245         } else if (info->mem != INVALIDm) {
   3246             mem_str = SOC_MEM_NAME(unit, info->mem);
   3247         } else if (info->group_reg_status_field != INVALIDf) {
   3248             mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field);
   3249         }
   3250 
   3251         /* Handle different parity error reporting style */
   3252         switch (info->type) {
   3253         case _SOC_PARITY_TYPE_GENERIC:
   3254             _soc_apache_mem_parity_info(unit, block_info_idx, 0,
   3255                                      info->group_reg_status_field, &minfo);
   3256             /* Report uncorrectable event flag to application */
   3257             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3258                                SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3259                                minfo);
   3260 
   3261             log_generic.time = sal_time_usecs();
   3262             log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3263             log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3264             log_generic.parity_type = info->type;
   3265 
   3266             log_id = soc_ser_log_create_entry(unit,
   3267                 sizeof(soc_ser_log_tlv_generic_t) +
   3268                 sizeof(soc_ser_log_tlv_hdr_t) *2);
   3269 
   3270             soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3271                 sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3272             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3273                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3274 
   3275             LOG_WARN(BSL_LS_SOC_SER,
   3276                       (BSL_META_U(unit,
   3277                                   "%s %s asserted\n"), prefix_str, mem_str));
   3278             break;
   3279         case _SOC_PARITY_TYPE_PARITY:
   3280             /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */
   3281             SOC_IF_ERROR_RETURN
   3282                 (_soc_apache_ser_process_parity(unit, block_info_idx,
   3283                                                   pipe, port, info, FALSE,
   3284                                                   prefix_str, mem_str));
   3285             break;
   3286         case _SOC_PARITY_TYPE_ECC:
   3287             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   3288             SOC_IF_ERROR_RETURN
   3289                 (_soc_apache_ser_process_ecc(unit, block_info_idx, pipe,
   3290                                                port, info, FALSE,
   3291                                                prefix_str, mem_str));
   3292             break;
   3293         case _SOC_PARITY_TYPE_MIB:
   3294             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   3295             SOC_IF_ERROR_RETURN
   3296                 (_soc_apache_ser_process_mib(unit, block_info_idx, pipe,
   3297                                              port, info, FALSE,
   3298                                              prefix_str, mem_str));
   3299             /* MIB_RX_MEM_ERR and MIB_TX_MEM_ERR in PORT_INTR_STATUS are write 1 to clear
   3300              * So we write back the status we read.
   3301              */
   3302             SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval));
   3303             break;
   3304         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   3305         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   3306         case _SOC_PARITY_TYPE_MAC_RX_TS:
   3307             /* xxx_SINGLE_BIT_ERRf, xxx_DOUBLE_BIT_ERRf */
   3308             SOC_IF_ERROR_RETURN
   3309                 (_soc_apache_ser_process_mac(unit, block_info_idx, pipe,
   3310                                              port, info, FALSE,
   3311                                              prefix_str, mem_str));
   3312             /* MAC_RX_CDC_MEM_ERR, MAC_TX_CDC_MEM_ERR, MAC_RX_TS_CDC_MEM_ERR
   3313              * in PORT_INTR_STATUS are write 1 to clear
   3314              * So we write back the status we read.
   3315              */
   3316             SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval));
   3317             break;
   3318         case _SOC_PARITY_TYPE_CXXPORT:
   3319             /* One more level of report tree structure */
   3320             SOC_IF_ERROR_RETURN
   3321                 (_soc_apache_ser_process_cxxport(unit, info->id, pipe, info, prefix_str));
   3322             break;
   3323         case _SOC_PARITY_TYPE_START_ERR:
   3324             SOC_IF_ERROR_RETURN
   3325                 (_soc_apache_ser_process_start_err(unit, block_info_idx,
   3326                                                      info, prefix_str));
   3327             break;
   3328         case _SOC_PARITY_TYPE_MMU_SER:
   3329             SOC_IF_ERROR_RETURN
   3330                 (_soc_apache_ser_process_mmu_err(unit, block_info_idx,
   3331                                                    info, prefix_str));
   3332             break;
   3333         case _SOC_PARITY_TYPE_BST:
   3334             SOC_IF_ERROR_RETURN(_soc_apache_process_mmu_bst(unit));
   3335             break;
   3336         default:
   3337             break;
   3338         } /* Handle different parity error reporting style */
   3339     } /* Loop through each info entry in the list */
   3340 
   3341     return SOC_E_NONE;
   3342 }
   3343 
   3344 STATIC char *_soc_apache_ser_hwmem_base_info[] = {
   3345     "CMIC PKT BUFFER - In Iarb",
   3346     "CPU PKT BUFFER - In Iarb",
   3347     "Invalid value",
   3348     "EINITBUF_PACKET_BUFFER - In Iarb",
   3349     "INGRESS PACKET BUFFER - In Ipars",
   3350     "Invalid value",
   3351     "Invalid value",
   3352     "Invalid value",
   3353     "Invalid value",
   3354     "Invalid value",
   3355     "Invalid value",
   3356     "ISW2_EOP_BUFFER_A - In Iesmif",
   3357     "ISW2_EOP_BUFFER_B - In Iesmif",
   3358     "ISW2_EOP_BUFFER_C - In Iesmif",
   3359     "Invalid value",
   3360     "Invalid value",
   3361     "EP MPB DATA - In El3",
   3362     "EP INITBUF - In Ehcpm",
   3363     "CM DATA BUFFER - In Edatabuf",
   3364     "XLP0 DATA BUFFER - In Edatabuf",
   3365     "XLP1 DATA BUFFER - In Edatabuf",
   3366     "XLP2 DATA BUFFER - In Edatabuf",
   3367     "XLP3 DATA BUFFER - In Edatabuf",
   3368     "XLP4 DATA BUFFER - In Edatabuf",
   3369     "XLP5 DATA BUFFER - In Edatabuf",
   3370     "XLP6 DATA BUFFER - In Edatabuf",
   3371     "CLP1 DATA BUFFER - In Edatabuf",
   3372     "CLP2 DATA BUFFER - In Edatabuf",
   3373     "XLP7 DATA BUFFER - In Edatabuf",
   3374     "XLP8 DATA BUFFER - In Edatabuf",
   3375     "XLP9 DATA BUFFER - In Edatabuf",
   3376     "XLP10 DATA BUFFER - In Edatabuf",
   3377     "XLP11 DATA BUFFER - In Edatabuf",
   3378     "XLP12 DATA BUFFER - In Edatabuf",
   3379     "XLP13 DATA BUFFER - In Edatabuf",
   3380     "CLP4 DATA BUFFER - In Edatabuf",
   3381     "CLP5 DATA BUFFER - In Edatabuf",
   3382     "CLP0 DATA BUFFER - In Edatabuf",
   3383     "CLP3 DATA BUFFER - In Edatabuf",
   3384     "RESI0 DATA BUFFER - In Edatabuf",
   3385     "RESI1 DATA BUFFER - In Edatabuf",
   3386     "RESI2 DATA BUFFER - In Edatabuf",
   3387     "RESI3 DATA BUFFER - In Edatabuf",
   3388     "Invalid value",
   3389     "Invalid value",
   3390     "Invalid value",
   3391     "Invalid value",
   3392     "Invalid value",
   3393     "Invalid value",
   3394     "Invalid value",
   3395     "Invalid value",
   3396     "XLP0 EDB CTRL BUFFER - In Edatabuf",
   3397     "XLP1 EDB CTRL BUFFER - In Edatabuf",
   3398     "XLP2 EDB CTRL BUFFER - In Edatabuf",
   3399     "XLP3 EDB CTRL BUFFER - In Edatabuf",
   3400     "XLP4 EDB CTRL BUFFER - In Edatabuf",
   3401     "XLP5 EDB CTRL BUFFER - In Edatabuf",
   3402     "XLP6 EDB CTRL BUFFER - In Edatabuf",
   3403     "CLP1 EDB CTRL BUFFER - In Edatabuf",
   3404     "CLP2 EDB CTRL BUFFER - In Edatabuf",
   3405     "XLP7 EDB CTRL BUFFER - In Edatabuf",
   3406     "XLP8 EDB CTRL BUFFER - In Edatabuf",
   3407     "XLP9 EDB CTRL BUFFER - In Edatabuf",
   3408     "XLP10 EDB CTRL BUFFER - In Edatabuf",
   3409     "XLP11 EDB CTRL BUFFER - In Edatabuf",
   3410     "XLP12 EDB CTRL BUFFER - In Edatabuf",
   3411     "XLP13 EDB CTRL BUFFER - In Edatabuf",
   3412     "CLP4 EDB CTRL BUFFER - In Edatabuf",
   3413     "CLP5 EDB CTRL BUFFER - In Edatabuf",
   3414     "CLP0 EDB CTRL BUFFER - In Edatabuf",
   3415     "CLP3 EDB CTRL BUFFER - In Edatabuf",
   3416     "LEARN FIFO - In IARB",
   3417     "IFP_COUNTER_MUX_DATA_STAGING - In Ifp",
   3418     "Invalid value",
   3419     "Invalid value",
   3420     "Invalid value",
   3421     "Invalid value",
   3422     "Invalid value",
   3423     "Invalid value",
   3424     "Invalid value",
   3425     "IFP_METER_MUX_DATA_STAGING_0 - In Ifp",
   3426     "IFP_METER_MUX_DATA_STAGING_1 - In Ifp",
   3427     "IFP_METER_MUX_DATA_STAGING_2 - In Ifp",
   3428     "IFP_METER_MUX_DATA_STAGING_3 - In Ifp",
   3429     "IFP_METER_MUX_DATA_STAGING_4 - In Ifp",
   3430     "IFP_METER_MUX_DATA_STAGING_5 - In Ifp",
   3431     "IFP_METER_MUX_DATA_STAGING_6 - In Ifp",
   3432     "IFP_METER_MUX_DATA_STAGING_7 - In Ifp",
   3433     "EGR VLAN BUS",
   3434     "EGR HCPM BUS",
   3435     "EGR PMOD BUS",
   3436     "EGR FPPARS BUS",
   3437     "EFP BUS",
   3438     "IVP BUS",
   3439     "ICFG BUS",
   3440     "Invalid value",
   3441     "Invalid value",
   3442     "Invalid value",
   3443     "Invalid value",
   3444     "Invalid value",
   3445     "Invalid value",
   3446     "Invalid value",
   3447     "Invalid value",
   3448     "Invalid value",
   3449     "IPARS BUS",
   3450     "IVXLT BUS",
   3451     "IMPLS BUS",
   3452     "IL2L3 BUS",
   3453     "Invalid value",
   3454     "IFP BUS",
   3455     "IRSEL1 BUS",
   3456     "ISW1 BUS",
   3457     "IRSEL2 BUS"
   3458     "IFP_PASSTHRU_HIGHWAY_BUFFER"
   3459     "EFPMOD_EMOP_BUFFER"
   3460 };
   3461 
   3462 #define _SOC_APACHE_SER_REG 1
   3463 #define _SOC_APACHE_SER_MEM 0
   3464 
   3465 STATIC void
   3466 _soc_apache_print_ser_fifo_details (int unit, uint8 regmem, soc_block_t blk, 
   3467                                     uint32 sblk, int pipe, uint32 address, 
   3468                                     uint32 stage, uint32 base, uint32 index, 
   3469                                     uint32 hwmbase, uint32 type, uint32 drop,
   3470                                     uint32 non_sbus)
   3471 {
   3472     uint32   hwmbase_max;
   3473     
   3474     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) {
   3475         switch (type) {
   3476         case 0:
   3477             LOG_WARN(BSL_LS_SOC_SER,
   3478                       (BSL_META_U(unit,
   3479                                   "Error in: SOP cell.\n")));
   3480             break;
   3481         case 1:
   3482             LOG_WARN(BSL_LS_SOC_SER,
   3483                       (BSL_META_U(unit,
   3484                                   "Error in: MOP cell.\n")));
   3485             break;
   3486         case 2:
   3487             LOG_WARN(BSL_LS_SOC_SER,
   3488                       (BSL_META_U(unit,
   3489                                   "Error in: EOP cell.\n")));
   3490             break;
   3491         case 3:
   3492             LOG_WARN(BSL_LS_SOC_SER,
   3493                       (BSL_META_U(unit,
   3494                                   "Error in: SBUS transaction.\n")));
   3495             break;
   3496         case 4:
   3497             LOG_WARN(BSL_LS_SOC_SER,
   3498                       (BSL_META_U(unit,
   3499                                   "Error in: miscellaneous transaction.\n")));
   3500             break;
   3501         default:
   3502             LOG_WARN(BSL_LS_SOC_SER,
   3503                       (BSL_META_U(unit,
   3504                                   "Invalid error reported !!\n")));
   3505             break;
   3506         }
   3507         LOG_WARN(BSL_LS_SOC_SER,
   3508                   (BSL_META_U(unit,
   3509                               "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, stage: %d, index: %d\n"),
   3510                               sblk, pipe, address, base, stage, index));
   3511         if (regmem == _SOC_APACHE_SER_MEM) {
   3512             if (hwmbase >= 0x80) {
   3513                 hwmbase -= 0x28; /* handle the gap */
   3514             }
   3515             if (non_sbus) {
   3516                 hwmbase_max = sizeof(_soc_apache_ser_hwmem_base_info)/sizeof(_soc_apache_ser_hwmem_base_info[0]);
   3517                 LOG_WARN(BSL_LS_SOC_SER,
   3518                           (BSL_META_U(unit,
   3519                                       "Mem hwbase: 0x%x [%s]\n"), hwmbase,
   3520                                       (hwmbase < hwmbase_max) ? _soc_apache_ser_hwmem_base_info[hwmbase] : "--"));
   3521             }
   3522         }
   3523         if (drop) {
   3524             LOG_WARN(BSL_LS_SOC_SER,
   3525                       (BSL_META_U(unit,
   3526                                   "SER caused packet drop.\n")));
   3527         }
   3528     }
   3529 }
   3530 
   3531 #define IF_IPIPE_ARBITER_LOCK(_unit_, _blk_) \
   3532     if (_blk_ == SOC_BLK_IPIPE) {\
   3533         IP_ARBITER_LOCK(_unit_);\
   3534     }
   3535 
   3536 #define IF_IPIPE_ARBITER_UNLOCK(_unit_, _blk_) \
   3537     if (_blk_ == SOC_BLK_IPIPE) {\
   3538         IP_ARBITER_UNLOCK(_unit_);\
   3539     }
   3540 
   3541 #if defined(BCM_56560_A0)
   3542 static uint32 _apache_ser_status_bus_fmt_get (uint32 *entry, int fld)
   3543 {
   3544     switch(fld) {
   3545     case VALIDf: /* Bit 1*/
   3546         return (entry[0] & 0x00000001);
   3547     case INSTRUCTION_TYPEf: /* Bits 1-4 */
   3548         return ((entry[0] & 0x0000001E) >> 1);
   3549     case HWMEMBASEf: /* Bits 23-30 */
   3550     case MEMBASEf:
   3551         return ((entry[0] & 0x7F800000) >> 23);
   3552     case MEMINDEXf: /* Bits 5-22 */
   3553         return ((entry[0] & 0x007FFFE0) >> 5);
   3554     case REGINDEXf: /* Bits 5-12 */
   3555         return ((entry[0] & 0x00001FE0) >> 5);
   3556     case REGBASEf: /* Bits 13-29 */
   3557         return ((entry[0] & 0x3FFFE000) >> 13);
   3558     case PIPE_STAGEf: /* Bits 31-36 */
   3559         return (((entry[0] & 0x80000000) >> 31) |
   3560                 ((entry[1] & 0x0000001F) << 1));
   3561     case ADDRESSf: /* Bits 36-5 */
   3562         return ((entry[0] >> 5) | 
   3563                 ((entry[1] & 0x0000001F) << 27));
   3564     case DROPf: /* Bit 37 */
   3565         return (entry[1] & 0x00000020);
   3566     case ECC_PARITYf: /* Bits 38-39 */
   3567         return ((entry[1] & 0x000000C0) >> 6);
   3568     case MEM_TYPEf:/* Bit 40 */
   3569         return (entry[1] & 0x00000100);
   3570     case NON_SBUSf: /* Bit 41 */
   3571         return (entry[1] & 0x00000200);
   3572     case MULTIPLEf: /* Bit 42 */
   3573         return (entry[1] & 0x00000400);
   3574     default:
   3575         return -1;
   3576     }
   3577 }
   3578 
   3579 #endif 
   3580 int
   3581 soc_apache_mem_index_remap(int unit, int index, soc_mem_t *mem)
   3582 {
   3583     int logical_index = -1;
   3584     switch (*mem) {
   3585         case L3_DEFIPm:
   3586         case L3_DEFIP_PAIR_128m:
   3587         case L3_DEFIP_ONLYm:    
   3588         case L3_DEFIP_PAIR_128_ONLYm:
   3589         case L3_DEFIP_DATA_ONLYm:
   3590         case L3_DEFIP_PAIR_128_DATA_ONLYm:
   3591             logical_index =  soc_apache_l3_defip_index_remap(unit, *mem, index);
   3592             if (logical_index == -1) {
   3593                 /* This case arises when the passed index (physical) belongs
   3594                  * to wider view, but the passed mem is narrow view 
   3595                  * Note that below API rewrites mem to the correct (wide) view.
   3596                  */
   3597                 logical_index = soc_apache_l3_defip_mem_index_get(unit, index, mem);
   3598             }
   3599             return logical_index;
   3600         default:
   3601             return index;
   3602     }
   3603 }
   3604 
   3605 STATIC uint32
   3606 _soc_apache_flex_ctr_addr_check (int unit, uint32 address, soc_block_t blk,
   3607                                  uint32 stage, uint32 index)
   3608 {
   3609     uint32 index2 = index;
   3610 
   3611     if ((SOC_BLK_IPIPE == blk) && (21 == stage)) {
   3612         switch (address & 0xfffff000) {
   3613             /* ING_FLEX_CTR_OFFSET_TABLE_*m */
   3614         case 0x56800000:
   3615         case 0x56801000:
   3616         case 0x56802000:
   3617         case 0x56803000:
   3618         case 0x56840000:
   3619         case 0x56841000:
   3620         case 0x56842000:
   3621         case 0x56843000:
   3622             index2 = address & 0x3ff; break; /* 1K depth */
   3623             /* ING_FLEX_CTR_COUNTER_TABLE_*m */
   3624         case 0x56804000:
   3625         case 0x56808000:
   3626         case 0x5680c000:
   3627         case 0x56810000:
   3628         case 0x56844000:
   3629         case 0x56848000:
   3630         case 0x5684c000:
   3631         case 0x56850000:
   3632             index2 = address & 0xfff; break; /* 4K depth */
   3633         default:
   3634             break;
   3635         }
   3636     }
   3637 
   3638     if ((SOC_BLK_EPIPE == blk) && (10 == stage)) {
   3639         switch (address & 0XFFFFF000) {
   3640         case 0x2a800000:
   3641         case 0x2a801000:
   3642         case 0x2a802000:
   3643         case 0x2a803000:
   3644             index2 = address & 0x3ff; break; /* 1K depth */
   3645         case 0x2a804000:
   3646         case 0x2a808000:
   3647         case 0x2a80c000:
   3648         case 0x2a810000:
   3649             index2 = address & 0xfff; break; /* 4K depth */
   3650         default:
   3651             break;
   3652         }
   3653     }
   3654     return index2;
   3655 }
   3656 
   3657 STATIC int
   3658 _soc_apache_process_ser_fifo (int unit, soc_block_t blk, char *prefix_str)
   3659 {
   3660 #if defined(BCM_56560_A0)
   3661     int            rv;
   3662     uint8          bidx;
   3663     soc_mem_t      mem;
   3664     char           blk_str[10];
   3665     void          *ser_info_table = NULL;
   3666     uint32         entry[SOC_MAX_MEM_WORDS], address = 0;
   3667     uint32         reg_val = 0, mask = 0;
   3668     uint32         stage = 0, addrbase = 0, index = 0, hwmbase = 0, type = 0;
   3669     uint32         sblk = 0, regmem = 0, non_sbus = 0, drop = 0, ecc_parity = 0;
   3670     soc_reg_t      parity_enable_reg = INVALIDr;
   3671     soc_field_t    parity_enable_field = INVALIDf;
   3672     _soc_ser_correct_info_t spci;
   3673     soc_reg_t reg = INVALIDr;
   3674 
   3675     switch (blk) {
   3676     case SOC_BLK_IPIPE:
   3677         mem = ING_SER_FIFOm;
   3678         ser_info_table = _soc_bcm56560_a0_ip_mem_ser_info;
   3679         sal_sprintf(blk_str, "IPIPE");
   3680         break;
   3681     case SOC_BLK_EPIPE:
   3682         mem = EGR_SER_FIFOm;
   3683         ser_info_table = _soc_bcm56560_a0_ep_mem_ser_info;
   3684         mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */
   3685         reg = EGR_INTR_STATUSr;
   3686         sal_sprintf(blk_str, "EPIPE");
   3687         break;
   3688     default:
   3689         return SOC_E_PARAM;
   3690     }
   3691 
   3692     IF_IPIPE_ARBITER_LOCK(unit, blk);
   3693     do {
   3694         sal_memset(&spci, 0, sizeof(spci));
   3695         rv = soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry);
   3696         if (rv != SOC_E_NONE) {
   3697             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3698         }
   3699         SOC_IF_ERROR_RETURN(rv);
   3700         /* process entry */
   3701         if (_apache_ser_status_bus_fmt_get(entry,VALIDf)) {
   3702             ecc_parity = _apache_ser_status_bus_fmt_get(entry, ECC_PARITYf);
   3703             regmem = _apache_ser_status_bus_fmt_get(entry, MEM_TYPEf);
   3704             address = _apache_ser_status_bus_fmt_get(entry, ADDRESSf);
   3705             stage = _apache_ser_status_bus_fmt_get(entry, PIPE_STAGEf);
   3706             type = _apache_ser_status_bus_fmt_get(entry, INSTRUCTION_TYPEf);
   3707             drop = _apache_ser_status_bus_fmt_get(entry, DROPf);
   3708             SOC_BLOCK_ITER(unit, bidx, blk) {
   3709                 sblk = SOC_BLOCK2SCH(unit, bidx);
   3710                 break;
   3711             }
   3712             LOG_WARN(BSL_LS_SOC_SER,
   3713                       (BSL_META_U(unit,
   3714                                   "%s\n"), prefix_str));
   3715             if (_apache_ser_status_bus_fmt_get(entry, MULTIPLEf)) {
   3716                 LOG_WARN(BSL_LS_SOC_SER,
   3717                           (BSL_META_U(unit,
   3718                                       "Multiple: ")));
   3719             }
   3720             if (regmem == _SOC_APACHE_SER_REG ) {
   3721                 LOG_WARN(BSL_LS_SOC_SER,
   3722                           (BSL_META_U(unit,
   3723                                       "Reg: ")));
   3724             } else {
   3725                 LOG_WARN(BSL_LS_SOC_SER,
   3726                           (BSL_META_U(unit,
   3727                                       "Mem: ")));
   3728             }
   3729             spci.double_bit = 0;
   3730             switch (ecc_parity) {
   3731             case 0:
   3732                 LOG_WARN(BSL_LS_SOC_SER,
   3733                           (BSL_META_U(unit,
   3734                                       "Parity error..\n")));
   3735                 spci.parity_type = SOC_PARITY_TYPE_PARITY;
   3736                 break;
   3737             case 1:
   3738                 LOG_WARN(BSL_LS_SOC_SER,
   3739                           (BSL_META_U(unit,
   3740                                       "Corrected single bit ECC error..\n")));
   3741                 spci.parity_type = SOC_PARITY_TYPE_ECC;
   3742                 break;
   3743             case 2:
   3744                 LOG_WARN(BSL_LS_SOC_SER,
   3745                           (BSL_META_U(unit,
   3746                                       "Double or Multiple bit ECC error..\n")));
   3747                 spci.parity_type = SOC_PARITY_TYPE_ECC;
   3748                 spci.double_bit = 1;
   3749                 spci.flags |= SOC_SER_ERR_MULTI;
   3750                 break;
   3751             default:
   3752                 LOG_ERROR(BSL_LS_SOC_SER,
   3753                           (BSL_META_U(unit,
   3754                                       "Invalid SER issue !!\n")));
   3755 
   3756                 IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3757                 return SOC_E_INTERNAL;
   3758             }
   3759             if (regmem == _SOC_APACHE_SER_MEM) {
   3760                 /* process mem */
   3761                 non_sbus = _apache_ser_status_bus_fmt_get(entry, NON_SBUSf);
   3762                 addrbase = _apache_ser_status_bus_fmt_get(entry, MEMBASEf);
   3763                 index = _apache_ser_status_bus_fmt_get(entry, MEMINDEXf);
   3764                 hwmbase = _apache_ser_status_bus_fmt_get(entry, HWMEMBASEf);
   3765                 if (blk == SOC_BLK_IPIPE) {
   3766                     switch (stage) {
   3767                         case 7: /* IL2LU_2 */
   3768                         case 8: /* IL2LU_3 */
   3769                         case 9: /* IL2LU_4 */
   3770                         case 11: /* IL3LU_1 */
   3771                         case 12: /* IL3LU_2 */
   3772                         case 13: /* IL3LU_3 */
   3773                         case 15: /* ILPM_1 */
   3774                             /* Mems in these stages in IPIPE have more than 256k indexes */
   3775                             index |= hwmbase << 18;
   3776                             hwmbase = addrbase = 0;
   3777                         default: break;
   3778                     }
   3779                 }
   3780 
   3781                 index = _soc_apache_flex_ctr_addr_check(unit, address, blk,
   3782                                                         stage, index);
   3783                 if (non_sbus == 0) {
   3784                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3785                                        ecc_parity == 0 ?
   3786                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   3787                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   3788                                        sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET,
   3789                                        address);
   3790                     _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0,
   3791                                                        address, stage, addrbase,
   3792                                                        index, hwmbase, type,
   3793                                                        drop, non_sbus);
   3794                     spci.flags = SOC_SER_SRC_MEM;
   3795                     spci.reg = INVALIDr;
   3796                     spci.mem = INVALIDm;
   3797                     spci.blk_type = blk;
   3798                     spci.sblk = sblk;
   3799                     spci.addr = address - index;
   3800                     spci.index = index;
   3801                     spci.stage = stage;
   3802                     spci.detect_time = sal_time_usecs();
   3803                     spci.mem = soc_addr_to_mem_extended(unit,spci.sblk,
   3804                                                         -1,spci.addr);
   3805                     if (spci.mem != INVALIDm) {
   3806                         spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
   3807                         spci.flags |= SOC_SER_REG_MEM_KNOWN;
   3808                         spci.index = soc_apache_mem_index_remap(unit, index, &(spci.mem));
   3809                     }
   3810                     else {
   3811                         /* Invalid mem, use the first acc_type_ptr*/
   3812                         spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
   3813                         spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   3814                     }
   3815 
   3816                     if (spci.mem != INVALIDm) {
   3817                         _soc_apache_ser_control_reg_get(unit, ser_info_table, 
   3818                             spci.mem, 
   3819                             &parity_enable_reg, 
   3820                             &parity_enable_field);
   3821                     }
   3822                     spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3823                     spci.log_id = _soc_apache_populate_ser_log(unit,
   3824                                               parity_enable_reg,
   3825                                               parity_enable_field,
   3826                                               spci.mem,
   3827                                               bidx,
   3828                                               spci.acc_type,
   3829                                               spci.index,
   3830                                               spci.detect_time,
   3831                                               spci.sblk,
   3832                                               spci.addr);
   3833 
   3834                     rv = soc_ser_correction(unit, &spci);
   3835                     if (SOC_FAILURE(rv)) {
   3836                         if (rv != SOC_E_NOT_FOUND) {
   3837                             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3838                             /* Add reporting failed to correct event flag to
   3839                              * application */
   3840                             soc_event_generate(unit,
   3841                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   3842                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3843                                     sblk |
   3844                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   3845                             return rv;
   3846                         }
   3847                     }
   3848                     if (spci.log_id != 0) {
   3849                         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3850                                            SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3851                                            spci.log_id, 0);
   3852                     }
   3853 
   3854                 } else {
   3855                     LOG_WARN(BSL_LS_SOC_SER,
   3856                               (BSL_META_U(unit,
   3857                                           "%s SER mem address un-accessable !!\n"), blk_str));
   3858           _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0, address,
   3859                                              stage, addrbase, index, hwmbase,
   3860                                              type, drop, non_sbus);
   3861                 }
   3862             } else {
   3863                 /* process reg */
   3864                 non_sbus = _apache_ser_status_bus_fmt_get(entry, NON_SBUSf);
   3865                 addrbase = _apache_ser_status_bus_fmt_get(entry, REGBASEf);
   3866                 index = _apache_ser_status_bus_fmt_get(entry, REGINDEXf);
   3867 
   3868                 if (non_sbus == 0) {
   3869                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3870                                        ecc_parity == 0 ? 
   3871                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   3872                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   3873                                        sblk |
   3874                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   3875                     _soc_apache_print_ser_fifo_details(unit, 1, blk, sblk, 0,
   3876                                                        address, stage, addrbase,
   3877                                                        index, 0, type, drop,
   3878                                                        non_sbus);
   3879                     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN;
   3880                     spci.reg = INVALIDr;
   3881                     spci.mem = INVALIDm;
   3882                     spci.blk_type = blk;
   3883                     spci.sblk = sblk;
   3884                     spci.addr = address;
   3885                     spci.index = index;
   3886                     spci.stage = stage;
   3887                     spci.detect_time = sal_time_usecs();
   3888                     spci.log_id = soc_ser_log_create_entry(unit,
   3889                             sizeof(soc_ser_log_tlv_generic_t) +
   3890                             sizeof(soc_ser_log_tlv_register_t) +
   3891                             sizeof(soc_ser_log_tlv_hdr_t) *3);
   3892                     rv = soc_ser_correction(unit, &spci);
   3893                     if (SOC_FAILURE(rv)) {
   3894                         IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3895                         /* Add reporting failed to correct event flag to
   3896                          * application */
   3897                         soc_event_generate(unit,
   3898                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   3899                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3900                                     sblk |
   3901                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   3902                         return rv;
   3903                     }
   3904                     if (spci.log_id != 0) {
   3905                         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3906                                            SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3907                                            spci.log_id, 0);
   3908                     }
   3909                 } else {
   3910                     LOG_WARN(BSL_LS_SOC_SER,
   3911                               (BSL_META_U(unit,
   3912                                           "%s SER reg address un-accessable !!\n"), blk_str));
   3913                     _soc_apache_print_ser_fifo_details(unit, 0, blk, sblk, 0,
   3914                                                        address, stage, addrbase,
   3915                                                        index, hwmbase, type,
   3916                                                        drop, non_sbus);
   3917                 }
   3918             }
   3919         } else {
   3920             LOG_ERROR(BSL_LS_SOC_SER,
   3921                       (BSL_META_U(unit,
   3922                                   "unit %d Got invalid mem pop from %s !!\n"),
   3923                                   unit, SOC_MEM_NAME(unit, mem)));
   3924         }
   3925 
   3926         if (rv != SOC_E_NONE) {
   3927             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3928         }
   3929 
   3930         /* check if any more pending */
   3931         if (reg == INVALIDr) {
   3932             rv = READ_CMIC_CMC0_IRQ_STAT2r(unit, &reg_val);
   3933         } else {
   3934             rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &reg_val);
   3935         }
   3936         SOC_IF_ERROR_RETURN(rv);
   3937     } while (reg_val & mask);
   3938     IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3939 
   3940     return SOC_E_NONE;
   3941 #else 
   3942     return SOC_E_NONE;
   3943 #endif
   3944 }
   3945 
   3946 STATIC int
   3947 _soc_apache_ser_process_irq3 (int unit, int bit_pos)
   3948 {
   3949 #if defined(BCM_56560_A0)
   3950     uint8      rbi;
   3951     int        port = REG_PORT_ANY;
   3952     uint32     cmic_rval, cmic_bit;
   3953     uint64     rb_enable64, rb_rval64, tmp64;
   3954     const      _soc_apache_ser_route_block_t *rb;
   3955     char       prefix_str[10];
   3956     int        block_info_idx;
   3957     soc_stat_t *stat = SOC_STAT(unit);
   3958 
   3959     sal_sprintf(prefix_str, "Unit: %d \n", unit);
   3960 
   3961     /* Read CMIC parity status register */
   3962     SOC_IF_ERROR_RETURN
   3963         (READ_CMIC_CMC0_IRQ_STAT3r(unit, &cmic_rval));
   3964     if (cmic_rval == 0) {
   3965         return SOC_E_NONE;
   3966     }
   3967     /* Loop through each place-and-route block entry */
   3968     for (rbi = 0; ; rbi++) {
   3969         rb = &_soc_apache_ser_route_blocks_irq3[rbi];
   3970         cmic_bit = rb->cmic_bit;
   3971         if (cmic_bit == 0) {
   3972             /* End of table */
   3973             break;
   3974         }
   3975         if (cmic_bit != (1 << bit_pos)) {
   3976             continue;
   3977         }
   3978         if (!(cmic_rval & cmic_bit)) {
   3979             /* No interrupt bit asserted for the route block */
   3980             continue;
   3981         }
   3982         if (rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) {
   3983             /* New fifo style processing */
   3984             (void)_soc_apache_process_ser_fifo(unit, rb->blocktype, prefix_str);
   3985             stat->ser_err_fifo++;
   3986         } else {
   3987             /* Legacy processing */
   3988             SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   3989                 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   3990                     port = SOC_BLOCK_PORT(unit, block_info_idx);
   3991                     break;
   3992                 }
   3993             }
   3994             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 
   3995                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   3996                     /* This port block is not configured */
   3997                     LOG_ERROR(BSL_LS_SOC_SER,
   3998                               (BSL_META_U(unit,
   3999                                           "unit %d SER error on disabled port block %d !!\n"),
   4000                                           unit, block_info_idx));
   4001                     sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */
   4002                     continue;
   4003             }
   4004             /* Read per route block parity status register */
   4005             SOC_IF_ERROR_RETURN
   4006                 (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64));
   4007             if (COMPILER_64_IS_ZERO(rb_rval64)) {
   4008                 continue;
   4009             }
   4010             SOC_IF_ERROR_RETURN
   4011                 (_soc_apache_process_ser(unit, block_info_idx, rb->id, -1,
   4012                                          port, rb->status_reg, rb_rval64,
   4013                                          rb->info, prefix_str));
   4014             
   4015             SOC_IF_ERROR_RETURN
   4016                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64));
   4017             COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64));
   4018             COMPILER_64_NOT(tmp64);
   4019             COMPILER_64_AND(rb_enable64, tmp64);
   4020             SOC_IF_ERROR_RETURN
   4021                 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4022             COMPILER_64_OR(rb_enable64, rb_rval64);
   4023             SOC_IF_ERROR_RETURN
   4024                 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4025             
   4026             stat->ser_err_int++;
   4027         }
   4028     }
   4029     return SOC_E_NONE;
   4030 #else 
   4031     return SOC_E_NONE;
   4032 #endif
   4033 }
   4034 
   4035 STATIC int
   4036 _soc_apache_ser_process_irq4 (int unit, int bit_pos)
   4037 {
   4038 #if defined(BCM_56560_A0)
   4039     uint8      rbi;
   4040     int        port = REG_PORT_ANY;
   4041     uint32     cmic_rval, cmic_bit;
   4042     uint64     rb_enable64, rb_rval64, tmp64;
   4043     char       prefix_str[10];
   4044     int        block_info_idx;
   4045     soc_stat_t *stat = SOC_STAT(unit);
   4046 
   4047     const _soc_apache_ser_route_block_t *rb;
   4048 
   4049     sal_sprintf(prefix_str, "\nUnit: %d: ", unit);
   4050 
   4051     /* Read CMIC parity status register */
   4052     SOC_IF_ERROR_RETURN
   4053         (READ_CMIC_CMC0_IRQ_STAT4r(unit, &cmic_rval));
   4054     if (cmic_rval == 0) {
   4055         return SOC_E_NONE;
   4056     }
   4057 
   4058     /* Loop through each place-and-route block entry */
   4059     for (rbi = 0; ; rbi++) {
   4060         if (soc_feature(unit, soc_feature_clport_gen2)) {
   4061             rb = &_soc_apache_ser_route_b0_blocks_irq4[rbi];
   4062         } else {
   4063             rb = &_soc_apache_ser_route_blocks_irq4[rbi];
   4064         }
   4065         cmic_bit = rb->cmic_bit;
   4066         if (cmic_bit == 0) {
   4067             /* End of table */
   4068             break;
   4069         }
   4070         if (cmic_bit != (1 << bit_pos)) {
   4071             continue;
   4072         }
   4073         if (!(cmic_rval & cmic_bit)) {
   4074             /* No interrupt bit asserted for the route block */
   4075             continue;
   4076         }
   4077 
   4078         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   4079             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   4080                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   4081                 break;
   4082             }
   4083         }
   4084         
   4085         if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 
   4086                               SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   4087             /* This port block is not configured */
   4088             LOG_ERROR(BSL_LS_SOC_SER,
   4089                       (BSL_META_U(unit,
   4090                                   "unit %d SER error on disabled port block %d !!\n"),
   4091                        unit, block_info_idx));
   4092             sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */
   4093             continue;
   4094         }
   4095          
   4096         /* Read per route block parity status register */
   4097         SOC_IF_ERROR_RETURN
   4098             (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64));
   4099         if (COMPILER_64_IS_ZERO(rb_rval64)) {
   4100             continue;
   4101         }
   4102 
   4103         SOC_IF_ERROR_RETURN
   4104             (_soc_apache_process_ser(unit, block_info_idx, rb->id, -1,
   4105                                      port, rb->status_reg, rb_rval64,
   4106                                      rb->info, prefix_str));
   4107 
   4108         SOC_IF_ERROR_RETURN
   4109             (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64));
   4110         COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64));
   4111         COMPILER_64_NOT(tmp64);
   4112         COMPILER_64_AND(rb_enable64, tmp64);
   4113         SOC_IF_ERROR_RETURN
   4114             (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4115         COMPILER_64_OR(rb_enable64, rb_rval64);
   4116         SOC_IF_ERROR_RETURN
   4117             (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4118             
   4119         stat->ser_err_int++;
   4120     }
   4121 
   4122     return SOC_E_NONE;
   4123 #else 
   4124     return SOC_E_NONE;
   4125 #endif
   4126 }
   4127 
   4128 #define IRQ3_STATUS_REG 3
   4129 #define IRQ4_STATUS_REG 4
   4130 STATIC int
   4131 _soc_apache_ser_process_all (int unit, int top_irq, int bit_pos)
   4132 {
   4133 #if defined(BCM_56560_A0)
   4134     switch (top_irq) {
   4135     case IRQ3_STATUS_REG:
   4136         SOC_IF_ERROR_RETURN(_soc_apache_ser_process_irq3(unit,bit_pos));
   4137         break;
   4138     case IRQ4_STATUS_REG:
   4139         SOC_IF_ERROR_RETURN(_soc_apache_ser_process_irq4(unit,bit_pos));
   4140         break;
   4141     default:
   4142         return SOC_E_INTERNAL; /* Shouldn't come here */
   4143     }
   4144 
   4145     return SOC_E_NONE;
   4146 #else 
   4147     return SOC_E_NONE;
   4148 #endif
   4149 }
   4150 
   4151 void
   4152 soc_apache_ser_set_long_delay(int delay)
   4153 {
   4154 #if defined(BCM_56560_A0)
   4155     _apache_ser_delay = delay;
   4156     return;
   4157 #endif
   4158 }
   4159 
   4160 STATIC void
   4161 soc_apache_ser_error (void *unit_vp, void *d1,
   4162                       void *d2, void *d3, void *d4)
   4163 {
   4164 #if defined(BCM_56560_A0)
   4165     int unit     = PTR_TO_INT(unit_vp);
   4166     int irq_reg  = PTR_TO_INT(d3);
   4167     int old_mask = 0;
   4168 
   4169     (void)_soc_apache_ser_process_all(unit,irq_reg,PTR_TO_INT(d4));
   4170 
   4171     sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : (_apache_ser_delay != 0 ? 10000000 : 100000));
   4172 
   4173     if (d2 != NULL) {
   4174         old_mask = PTR_TO_INT(d2);
   4175         if (irq_reg == 3) {
   4176             (void)soc_cmicm_intr3_enable(unit, old_mask);
   4177         } else if (irq_reg == 4) {
   4178             (void)soc_cmicm_intr4_enable(unit, old_mask);
   4179         }
   4180     }
   4181     /* soc_intr_enable(unit, IRQ_MEM_FAIL); */
   4182 #endif
   4183 }
   4184 
   4185 /* SER processing for TCAMs */
   4186 static _soc_generic_ser_info_t _soc_apache_tcam_ser_info_template[] = {
   4187     /* HW SER engine protection */
   4188     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4189       _SOC_SER_PARITY_4BITS,
   4190       _SOC_SER_INTERLEAVE_MOD2,
   4191       { {0, 97}, {1, 97}, {98, 193}, {99, 193} }, 0, 0, 0, 0,
   4192       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA |
   4193       _SOC_SER_FLAG_REMAP_READ  | _SOC_SER_FLAG_SIZE_VERIFY},
   4194     { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4195       _SOC_SER_PARITY_8BITS,
   4196       _SOC_SER_INTERLEAVE_NONE,
   4197       { {0, 99}, {100, 195}, {196, 291}, {292, 387} }, 0, 0, 0, 0,
   4198       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA |
   4199       _SOC_SER_FLAG_REMAP_READ  | _SOC_SER_FLAG_SIZE_VERIFY},
   4200     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4201       _SOC_SER_PARITY_4BITS,
   4202       _SOC_SER_INTERLEAVE_MOD2,
   4203       { {0, 165}, {1, 165}, {166, 353}, {167, 353} }, 0, 0, 0, 0,
   4204       _SOC_SER_FLAG_XY_READ},
   4205     { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4206       _SOC_SER_PARITY_4BITS,
   4207       _SOC_SER_INTERLEAVE_MOD2,
   4208       { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0,
   4209       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA},
   4210     { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4211       _SOC_SER_PARITY_4BITS,
   4212       _SOC_SER_INTERLEAVE_MOD2, 
   4213       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0,
   4214       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA},
   4215     { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4216       _SOC_SER_PARITY_4BITS,
   4217       _SOC_SER_INTERLEAVE_MOD2,
   4218       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4219       _SOC_SER_FLAG_XY_READ},
   4220     { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4221       _SOC_SER_PARITY_4BITS,
   4222       _SOC_SER_INTERLEAVE_MOD2,
   4223       { {0, 145}, {2, 145}, {146, 289}, {148, 289} }, 0, 0, 0, 0,
   4224       _SOC_SER_FLAG_XY_READ},
   4225     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4226       _SOC_SER_PARITY_4BITS,
   4227       _SOC_SER_INTERLEAVE_MOD2,
   4228       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4229       _SOC_SER_FLAG_XY_READ},
   4230     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4231       _SOC_SER_PARITY_4BITS,
   4232       _SOC_SER_INTERLEAVE_MOD2,
   4233       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4234       _SOC_SER_FLAG_XY_READ},
   4235     { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4236       _SOC_SER_PARITY_4BITS,
   4237       _SOC_SER_INTERLEAVE_MOD2,
   4238       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4239       _SOC_SER_FLAG_XY_READ},
   4240     { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4241       _SOC_SER_PARITY_4BITS,
   4242       _SOC_SER_INTERLEAVE_MOD2,
   4243       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4244       _SOC_SER_FLAG_XY_READ},
   4245     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4246       _SOC_SER_PARITY_4BITS,
   4247       _SOC_SER_INTERLEAVE_MOD2,
   4248       { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0,
   4249       _SOC_SER_FLAG_XY_READ},
   4250     { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4251       _SOC_SER_PARITY_4BITS,
   4252       _SOC_SER_INTERLEAVE_MOD2,
   4253       { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0,
   4254       _SOC_SER_FLAG_XY_READ},
   4255     { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4256       _SOC_SER_PARITY_4BITS,
   4257       _SOC_SER_INTERLEAVE_MOD2,
   4258       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0,
   4259       _SOC_SER_FLAG_XY_READ},
   4260     { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4261       _SOC_SER_PARITY_4BITS,
   4262       _SOC_SER_INTERLEAVE_MOD2,
   4263       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4264       _SOC_SER_FLAG_XY_READ},
   4265     { SUBPORT_TAG_SGPP_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4266       _SOC_SER_PARITY_4BITS,
   4267       _SOC_SER_INTERLEAVE_MOD2,
   4268       { {0, 32}, {1, 32}, {33, 64}, {34, 64} }, 0, 0, 0, 0,
   4269       _SOC_SER_FLAG_XY_READ},
   4270 
   4271     /* Below memories have SW memscan SER engine protection */
   4272     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4273       -1, -1,
   4274       { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0,
   4275       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE |
   4276       _SOC_SER_FLAG_OVERLAY},
   4277     { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4278       -1, -1,
   4279       { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0,
   4280       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE |
   4281       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE},
   4282     { INVALIDm },
   4283 };
   4284 
   4285 static _soc_generic_ser_info_t *_soc_apache_tcam_ser_info[SOC_MAX_NUM_DEVICES];
   4286 
   4287 STATIC void
   4288 _soc_apache_ser_info_flag_update(_soc_generic_ser_info_t *ser_info,
   4289                               soc_mem_t mem, uint32 flag, int enable)
   4290 {
   4291     int ser_idx = 0;
   4292 
   4293     while (INVALIDm != ser_info[ser_idx].mem) {
   4294         if (ser_info[ser_idx].mem == mem) {
   4295             if (enable) {
   4296                 ser_info[ser_idx].ser_flags |= flag;
   4297             } else {
   4298                 ser_info[ser_idx].ser_flags &= ~flag;
   4299             }
   4300             break;
   4301         }
   4302         ser_idx++;
   4303     }
   4304 }
   4305 
   4306 STATIC int
   4307 _soc_apache_tcam_ser_init (int unit)
   4308 {
   4309     int alloc_size;
   4310 
   4311     /* First, make per-unit copy of the master TCAM list */
   4312     alloc_size = sizeof(_soc_apache_tcam_ser_info_template);
   4313     if (NULL == _soc_apache_tcam_ser_info[unit]) {
   4314         if ((_soc_apache_tcam_ser_info[unit] =
   4315              sal_alloc(alloc_size, "apache tcam list")) == NULL) {
   4316             return SOC_E_MEMORY;
   4317         }
   4318     }
   4319 
   4320     /* Make a fresh copy of the TCAM template info */
   4321     sal_memcpy(_soc_apache_tcam_ser_info[unit],
   4322                &(_soc_apache_tcam_ser_info_template),
   4323                alloc_size);
   4324 
   4325     if (soc_feature(unit, soc_feature_field_half_slice_single_tcam) &&
   4326             soc_feature(unit, soc_feature_field_ingress_two_slice_types)) {
   4327         _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_GLOBAL_MASK_TCAMm,
   4328                 _SOC_SER_FLAG_NO_DMA, TRUE);
   4329         _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_TCAMm,
   4330                 _SOC_SER_FLAG_NO_DMA, TRUE);
   4331         _soc_apache_ser_info_flag_update(_soc_apache_tcam_ser_info[unit], FP_GM_FIELDSm,
   4332                 _SOC_SER_FLAG_NO_DMA, TRUE);
   4333     }
   4334 
   4335 
   4336     return soc_generic_ser_init(unit, _soc_apache_tcam_ser_info[unit]);
   4337 }
   4338 
   4339 STATIC void
   4340 soc_apache_ser_fail (int unit)
   4341 {
   4342     soc_generic_ser_process_error(unit, _soc_apache_tcam_ser_info[unit],
   4343                                   _SOC_PARITY_TYPE_SER);
   4344 }
   4345 
   4346 int
   4347 soc_apache_mem_config(int unit)
   4348 {
   4349     soc_persist_t *sop;
   4350     int l2_entries, cfg_l2_entries, shared_l2_banks;
   4351     int l3_entries, cfg_l3_entries, shared_l3_banks;
   4352     int shared_bank_size = 64;
   4353     int min_l2_entries;
   4354     int min_l3_entries;
   4355     int max_l2_entries;
   4356     int max_l3_entries;
   4357     int alpm_enable;
   4358     int num_ecmp_rh_flowset_entries;
   4359     int num_ipv6_128b_entries = 0;
   4360     int config_v6_entries = 0;
   4361     int defip_config = 0;
   4362     int uft_size = 256;
   4363     int def_ipv6_128b_num = 2048;
   4364     int def_lpm_scaling = 0;
   4365     int def_lpm_ipv6_128b_reserved = 1;
   4366     uint16              dev_id;
   4367     uint8               rev_id;
   4368 
   4369     sop = SOC_PERSIST(unit);
   4370     soc_cm_get_id(unit, &dev_id, &rev_id);
   4371 
   4372     if (soc_feature(unit, soc_feature_untethered_otp)) {
   4373         if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureUft128k)) {
   4374             shared_bank_size = 32;
   4375         }
   4376     }
   4377 
   4378     uft_size = shared_bank_size * 4;
   4379     min_l2_entries = 16; /* 16K dedicated L2 entries */
   4380     min_l3_entries = 4; /* 4K dedicated L3 entries */
   4381     max_l2_entries =  min_l2_entries + uft_size; /* Dedicated (16K) + Shared (256K/128K)*/ 
   4382     max_l3_entries =  min_l3_entries + uft_size; /* Dedicated (16K) + Shared (256K/128K)*/; /* Dedicated (4K) + Shared (256K)*/
   4383 
   4384 
   4385     if (SAL_BOOT_SIMULATION) {
   4386         /*
   4387          * Smaller table lengths for BCMSIM environment.
   4388          */
   4389         max_l2_entries = min_l2_entries;
   4390         max_l3_entries = min_l3_entries;
   4391     }
   4392 
   4393     cfg_l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, -1);
   4394     l2_entries = cfg_l2_entries == -1 ? max_l2_entries * 1024 : cfg_l2_entries;
   4395 
   4396     if (l2_entries <= min_l2_entries * 1024) { /* Min table size */
   4397         l2_entries = min_l2_entries * 1024;
   4398         shared_l2_banks = 0;
   4399     } else if (l2_entries <= max_l2_entries * 1024) {
   4400         l2_entries -= min_l2_entries * 1024;
   4401         shared_l2_banks = (l2_entries + (shared_bank_size * 1024 - 1)) / (shared_bank_size * 1024);
   4402         l2_entries = min_l2_entries * 1024 + shared_l2_banks * shared_bank_size * 1024;
   4403     } else {
   4404         LOG_CLI((BSL_META_U(unit,
   4405                             "The specified l2_mem_entries (%d) exceeds 272K\n"),
   4406                             cfg_l2_entries));
   4407         return SOC_E_PARAM;
   4408     }
   4409 
   4410     cfg_l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, -1);
   4411     l3_entries = cfg_l3_entries == -1 ? (min_l3_entries * 1024 ) : cfg_l3_entries;
   4412     if (l3_entries <= min_l3_entries * 1024) { /* 4k dedicated L3 entries */
   4413         l3_entries = min_l3_entries * 1024;
   4414         shared_l3_banks = 0;
   4415     } else if (l3_entries <= max_l3_entries * 1024) {
   4416         l3_entries -= min_l3_entries * 1024;
   4417         shared_l3_banks = (l3_entries + (shared_bank_size * 1024 - 1)) / (shared_bank_size * 1024);
   4418         l3_entries = min_l3_entries * 1024 + shared_l3_banks * shared_bank_size * 1024;
   4419     } else {
   4420         LOG_CLI((BSL_META_U(unit,
   4421                             "The specified l3_mem_entries (%d) exceeds 260K\n"),
   4422                             cfg_l3_entries));
   4423         return SOC_E_PARAM;
   4424     }
   4425 
   4426     alpm_enable = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
   4427 
   4428     if (alpm_enable && soc_feature(unit, soc_feature_alpm)) {
   4429 
   4430         if (shared_l2_banks + shared_l3_banks > 2) {
   4431             LOG_CLI((BSL_META_U(unit,
   4432                        "A minimum of 2 shared banks is required for ALPM "
   4433                        "when it is enabled\n")));
   4434             return SOC_E_PARAM;
   4435         }
   4436     } else if (shared_l2_banks + shared_l3_banks > 4) {
   4437         if (cfg_l2_entries == -1) {
   4438             LOG_CLI((BSL_META_U(unit,
   4439                        "Default L2 size (294912) and the specified "
   4440                        "l3_mem_entries (%d) require more than 4 shared "
   4441                        "banks\n"),
   4442                        cfg_l3_entries));
   4443         } else {
   4444             LOG_CLI((BSL_META_U(unit,
   4445                        "The specified l2_mem_entries (%d) and "
   4446                        "l3_mem_entries (%d) require more than 4 shared "
   4447                        "banks\n"),
   4448                        cfg_l2_entries, cfg_l3_entries));
   4449         }
   4450         return SOC_E_PARAM;
   4451     }
   4452     _soc_alpm_mode[unit] = alpm_enable;
   4453 
   4454     /* Adjust L2 table size */
   4455     sop->memState[L2Xm].index_max = l2_entries - 1;
   4456     sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
   4457     sop->memState[L2_ENTRY_ONLY_ECCm].index_max = l2_entries - 1;
   4458     sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1;
   4459     sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1;
   4460     sop->memState[L2_ENTRY_LPm].index_max = min_l2_entries*1024 / 4 - 1;
   4461     sop->memState[L2_ENTRY_ISS_LPm].index_max =
   4462         (l2_entries - min_l2_entries*1024) / 4 - 1;
   4463 
   4464     /* Adjust L3 table size */
   4465     sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1;
   4466     sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1;
   4467     sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = l3_entries / 2 - 1;
   4468     sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = l3_entries/ 2 - 1;
   4469     sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = l3_entries / 4 - 1;
   4470     sop->memState[L3_ENTRY_ONLY_ECCm].index_max = l3_entries - 1;
   4471     sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1;
   4472     sop->memState[L3_ENTRY_LPm].index_max = min_l3_entries*1024 / 4 - 1;
   4473     sop->memState[L3_ENTRY_ISS_LPm].index_max =
   4474         (l3_entries - min_l3_entries*1024) / 4 - 1;
   4475 
   4476     /* Adjust ALPM table size */
   4477     if (alpm_enable) {
   4478         /* The check below is sufficient because if ALPM mode is enabled
   4479          * and number of shared banks used is > 2 we return SOC_E_PARAM
   4480          * in code at the top of this function.
   4481          */
   4482         if (shared_l2_banks + shared_l3_banks > 0) {
   4483             sop->memState[L3_DEFIP_ALPM_RAWm].index_max =
   4484                 sop->memState[L3_DEFIP_ALPM_RAWm].index_max/2;
   4485             sop->memState[L3_DEFIP_ALPM_IPV4m].index_max =
   4486                 sop->memState[L3_DEFIP_ALPM_IPV4m].index_max/2;
   4487             sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max =
   4488                 sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max/2;
   4489             sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max =
   4490                 sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max/2;
   4491             sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max =
   4492                 sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max/2;
   4493             sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max =
   4494                 sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max/2;
   4495             sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max =
   4496                 sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max/2;
   4497             sop->memState[L3_DEFIP_ALPM_ECCm].index_max =
   4498                 sop->memState[L3_DEFIP_ALPM_ECCm].index_max/2;
   4499         }
   4500     } else {
   4501         sop->memState[L3_DEFIP_ALPM_RAWm].index_max = -1;
   4502         sop->memState[L3_DEFIP_ALPM_IPV4m].index_max = -1;
   4503         sop->memState[L3_DEFIP_ALPM_IPV4_1m].index_max = -1;
   4504         sop->memState[L3_DEFIP_ALPM_IPV6_64m].index_max = -1;
   4505         sop->memState[L3_DEFIP_ALPM_IPV6_64_1m].index_max = -1;
   4506         sop->memState[L3_DEFIP_ALPM_IPV6_128m].index_max = -1;
   4507         sop->memState[L3_DEFIP_ALPM_HIT_ONLYm].index_max = -1;
   4508         sop->memState[L3_DEFIP_ALPM_ECCm].index_max = -1;
   4509     }
   4510 
   4511     /* LAG and ECMP resilient hashing features share the same flow set table.
   4512      * The table can be configured in one of 3 modes:
   4513      * - dedicated to LAG resilient hashing,
   4514      * - dedicated to ECMP resilient hashing,
   4515      * - split evenly between LAG and ECMP resilient hashing.
   4516      */
   4517     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   4518             spn_ECMP_RESILIENT_HASH_SIZE, 32768);
   4519     switch (num_ecmp_rh_flowset_entries) {
   4520         case 0:
   4521             sop->memState[RH_ECMP_FLOWSETm].index_max = -1;
   4522             break;
   4523         case 32768:
   4524             sop->memState[RH_LAG_FLOWSETm].index_max /= 2;
   4525             sop->memState[RH_ECMP_FLOWSETm].index_max /= 2;
   4526             break;
   4527         case 65536:
   4528             sop->memState[RH_LAG_FLOWSETm].index_max = -1;
   4529             break;
   4530         default:
   4531             return SOC_E_CONFIG;
   4532     }
   4533 
   4534     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   4535         SOC_CONTROL(unit)->l3_defip_max_tcams = 0;
   4536     } else if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   4537         SOC_CONTROL(unit)->l3_defip_max_tcams = 2;
   4538     } else if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf)) {
   4539         SOC_CONTROL(unit)->l3_defip_max_tcams = 2;
   4540         def_ipv6_128b_num = 1024;
   4541         def_lpm_scaling   = 1;
   4542         def_lpm_ipv6_128b_reserved = 0;
   4543     } else {
   4544         SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_APACHE_DEFIP_MAX_TCAMS;
   4545     }
   4546     SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_APACHE_DEFIP_TCAM_DEPTH;
   4547 
   4548     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   4549         /* LPM is disabled, disable all L3_DEFIP memories */
   4550         sop->memState[L3_DEFIPm].index_max = -1;
   4551         sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   4552         sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   4553         sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   4554         sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   4555         sop->memState[L3_DEFIP_ONLYm].index_max = -1;
   4556         sop->memState[L3_DEFIP_DATA_ONLYm].index_max = -1;
   4557         sop->memState[L3_DEFIP_HIT_ONLYm].index_max = -1;
   4558         SOC_CONTROL(unit)->l3_defip_index_remap = 0;
   4559     } else if (soc_property_get(unit, "l3_defip_sizing", TRUE)) {
   4560         if (!soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) {
   4561             defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1);
   4562 
   4563             num_ipv6_128b_entries = soc_property_get(unit,
   4564                                         spn_NUM_IPV6_LPM_128B_ENTRIES,
   4565                                         (defip_config ? def_ipv6_128b_num : 0));
   4566 
   4567             /*
   4568              * Config property num_ipv6_lpm_128b_entries is not valid
   4569              * on Ranger2+
   4570              */
   4571             if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf) &&
   4572                     soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES, 0)) {
   4573                 return SOC_E_CONFIG;
   4574             }
   4575 
   4576             num_ipv6_128b_entries = num_ipv6_128b_entries +
   4577                                     (num_ipv6_128b_entries % 2);
   4578 
   4579             config_v6_entries = num_ipv6_128b_entries;
   4580             if (soc_property_get(unit, spn_LPM_SCALING_ENABLE,
   4581                 def_lpm_scaling)) {
   4582 
   4583                 num_ipv6_128b_entries = 0;
   4584                 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED,
   4585                     def_lpm_ipv6_128b_reserved)) {
   4586 
   4587                     config_v6_entries = ((config_v6_entries /
   4588                                         SOC_CONTROL(unit)->l3_defip_tcam_size) +
   4589                                         ((config_v6_entries %
   4590                                          SOC_CONTROL(unit)->l3_defip_tcam_size)
   4591                                         ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size;
   4592                 } else {
   4593                     /*
   4594                      * Config property lpm_ipv6_128b_reserved is not valid
   4595                      * on Ranger2+
   4596                      */
   4597                     if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf)) {
   4598                         return SOC_E_CONFIG;
   4599                     }
   4600                 }
   4601             }
   4602             sop->memState[L3_DEFIP_PAIR_128m].index_max =
   4603                                               num_ipv6_128b_entries - 1;
   4604             sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
   4605                                               num_ipv6_128b_entries - 1;
   4606             sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
   4607                                               num_ipv6_128b_entries - 1;
   4608             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
   4609                                               num_ipv6_128b_entries - 1;
   4610             sop->memState[L3_DEFIPm].index_max =
   4611                                      (SOC_CONTROL(unit)->l3_defip_max_tcams *
   4612                                      SOC_CONTROL(unit)->l3_defip_tcam_size) -
   4613                                      (num_ipv6_128b_entries * 2) - 1;
   4614 
   4615             sop->memState[L3_DEFIP_ONLYm].index_max =
   4616                                           sop->memState[L3_DEFIPm].index_max;
   4617             sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
   4618                                           sop->memState[L3_DEFIPm].index_max;
   4619             sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
   4620                                           sop->memState[L3_DEFIPm].index_max;
   4621             SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries;
   4622         } else {
   4623             if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) {
   4624                 /* slightly different processing for v6-128 */
   4625                 num_ipv6_128b_entries = soc_property_get(unit, 
   4626                                             spn_NUM_IPV6_LPM_128B_ENTRIES,
   4627                                             def_ipv6_128b_num);
   4628                 /*
   4629                  * Config property num_ipv6_lpm_128b_entries is not valid
   4630                  * on Ranger2+
   4631                  */
   4632                 if (soc_feature(unit, soc_feature_defip_2_tcams_with_separate_rpf) &&
   4633                         soc_property_get(unit, spn_NUM_IPV6_LPM_128B_ENTRIES, 0)) {
   4634                     return SOC_E_CONFIG;
   4635                 }
   4636 
   4637                 num_ipv6_128b_entries = num_ipv6_128b_entries + 
   4638                                         (num_ipv6_128b_entries % 2);
   4639 
   4640                 if (soc_feature(unit, soc_feature_alpm)) {
   4641                     if ((alpm_enable == 1) || (alpm_enable == 3)) {
   4642                         num_ipv6_128b_entries = (num_ipv6_128b_entries + 3) / 4 * 4;
   4643                     }
   4644                 }
   4645 
   4646                 config_v6_entries = num_ipv6_128b_entries;
   4647                 sop->memState[L3_DEFIP_PAIR_128m].index_max = 
   4648                                                 num_ipv6_128b_entries - 1;
   4649                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 
   4650                                                 num_ipv6_128b_entries - 1;
   4651                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 
   4652                                                 num_ipv6_128b_entries - 1;
   4653                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 
   4654                                                 num_ipv6_128b_entries - 1;
   4655                 sop->memState[L3_DEFIPm].index_max = 
   4656                                   (SOC_CONTROL(unit)->l3_defip_max_tcams * 
   4657                                   SOC_CONTROL(unit)->l3_defip_tcam_size) - 
   4658                                   (num_ipv6_128b_entries * 2) - 1;
   4659     
   4660                 sop->memState[L3_DEFIP_ONLYm].index_max = 
   4661                                        sop->memState[L3_DEFIPm].index_max;
   4662                 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 
   4663                                        sop->memState[L3_DEFIPm].index_max;
   4664                 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 
   4665                                        sop->memState[L3_DEFIPm].index_max;
   4666 
   4667                 SOC_CONTROL(unit)->l3_defip_index_remap = 
   4668                                               (num_ipv6_128b_entries / 2) * 2; 
   4669             } else {
   4670                 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   4671                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   4672                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   4673                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   4674             }
   4675         }
   4676         soc_l3_defip_indexes_init(unit, config_v6_entries); 
   4677     }
   4678 
   4679     if (_soc_apache_alpm_bkt_view_map[unit] != NULL) {
   4680         sal_free(_soc_apache_alpm_bkt_view_map[unit]);
   4681         _soc_apache_alpm_bkt_view_map[unit] = NULL;
   4682     }
   4683 
   4684     if (NULL == _soc_apache_alpm_bkt_view_map[unit]) {
   4685         if ((_soc_apache_alpm_bkt_view_map[unit] = 
   4686              sal_alloc(sizeof(soc_mem_t) * SOC_APACHE_ALPM_MAX_BKTS, 
   4687                        "alpm_bkt_map")) == NULL) {
   4688             return SOC_E_MEMORY;
   4689         }
   4690     }
   4691 
   4692     memset(_soc_apache_alpm_bkt_view_map[unit], INVALIDm,
   4693            sizeof(soc_mem_t) * SOC_APACHE_ALPM_MAX_BKTS);
   4694 
   4695     if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) {
   4696         if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) {
   4697             /* IFP */
   4698             sop->memState[FP_RANGE_CHECKm].index_max = -1;
   4699             sop->memState[FP_GLOBAL_MASK_TCAMm].index_max = -1;
   4700             sop->memState[FP_GM_FIELDSm].index_max = -1;
   4701             sop->memState[FP_TCAMm].index_max = -1;
   4702             sop->memState[FP_SLICE_MAPm].index_max = -1;
   4703             sop->memState[FP_POLICY_TABLEm].index_max = -1;
   4704             sop->memState[FP_METER_TABLEm].index_max = -1;
   4705             sop->memState[FP_COUNTER_TABLEm].index_max = -1;
   4706             sop->memState[FP_STORM_CONTROL_METERSm].index_max = -1;
   4707             sop->memState[FP_SLICE_KEY_CONTROLm].index_max = -1;
   4708             sop->memState[FP_PORT_METER_MAPm].index_max = -1;
   4709             sop->memState[FP_I2E_CLASSID_SELECTm].index_max = -1;
   4710             sop->memState[FP_HG_CLASSID_SELECTm].index_max = -1;
   4711 
   4712             sop->memState[SVM_MACROFLOW_INDEX_TABLEm].index_max = -1;
   4713             sop->memState[SVM_METER_TABLEm].index_max = -1;
   4714             sop->memState[SVM_OFFSET_TABLEm].index_max = -1;
   4715             sop->memState[SVM_POLICY_TABLEm].index_max = -1;
   4716             sop->memState[SVM_DBG_01m].index_max = -1;
   4717             sop->memState[SVM_DBG_02m].index_max = -1;
   4718             sop->memState[SVM_DBG_03m].index_max = -1;
   4719 
   4720             /* EFP */
   4721             sop->memState[EFP_TCAMm].index_max = -1;
   4722             sop->memState[EFP_POLICY_TABLEm].index_max = -1;
   4723             sop->memState[EFP_METER_TABLEm].index_max = -1;
   4724             sop->memState[EGR_PW_INIT_COUNTERSm].index_max = -1;
   4725 
   4726             sop->memState[EGR_TRILL_PARSE_CONTROL_2m].index_max = -1;
   4727             sop->memState[EGR_1588_SAm].index_max = -1;
   4728             sop->memState[EGR_FC_HEADER_TYPEm].index_max = -1;
   4729             sop->memState[EGR_PORT_1m].index_max = -1;
   4730         }
   4731 
   4732         /* IVXLT */
   4733         sop->memState[VLAN_PROTOCOLm].index_max = -1;
   4734         sop->memState[VLAN_PROTOCOL_DATAm].index_max = -1;
   4735         sop->memState[VLAN_SUBNETm].index_max = -1;
   4736         sop->memState[VLAN_SUBNET_ONLYm].index_max = -1;
   4737         sop->memState[VLAN_SUBNET_DATA_ONLYm].index_max = -1;
   4738         sop->memState[VLAN_MACm].index_max = -1;
   4739         sop->memState[VLAN_XLATEm].index_max = -1;
   4740         sop->memState[VFP_TCAMm].index_max = -1;
   4741         sop->memState[VFP_POLICY_TABLEm].index_max = -1;
   4742         sop->memState[ING_VLAN_TAG_ACTION_PROFILEm].index_max = -1;
   4743         sop->memState[MPLS_ENTRYm].index_max = -1;
   4744         sop->memState[UDF_CONDITIONAL_CHECK_TABLE_CAMm].index_max = -1;
   4745         sop->memState[UDF_CONDITIONAL_CHECK_TABLE_RAMm].index_max = -1;
   4746         sop->memState[ING_ETAG_PCP_MAPPINGm].index_max = -1;
   4747         sop->memState[VLAN_XLATE_ECCm].index_max = -1;
   4748         sop->memState[MPLS_ENTROPY_LABEL_DATAm].index_max = -1;
   4749         sop->memState[VLAN_XLATE_LPm].index_max = -1;
   4750 
   4751     }
   4752 
   4753     return SOC_E_NONE;
   4754 }
   4755 
   4756 int soc_apache_get_alpm_banks(int unit)
   4757 {
   4758     int rv = SOC_E_NONE;
   4759     soc_reg_t reg = ISS_LOG_TO_PHY_BANK_MAP_2r;
   4760     uint32 bank_mode = 0;
   4761     uint32 map = 0;
   4762 
   4763     if (_soc_ap_num_shared_alpm_banks[unit] == 0) {
   4764         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &map);
   4765         if (rv >= 0) {
   4766             bank_mode = soc_reg_field_get(unit, reg, map, ALPM_BANK_MODEf);
   4767         }
   4768 
   4769         if (bank_mode == 1) {
   4770             _soc_ap_num_shared_alpm_banks[unit] = 2;
   4771         } else {
   4772             _soc_ap_num_shared_alpm_banks[unit] = 4;
   4773         }
   4774     }
   4775 
   4776     return _soc_ap_num_shared_alpm_banks[unit];
   4777 }
   4778 
   4779 int 
   4780 soc_apache_alpm_mode_get(int unit)
   4781 {
   4782     return _soc_alpm_mode[unit];
   4783 }
   4784 
   4785 #define _APACHE_INDEX_1K_ENTRIES  1024
   4786 #define _APACHE_INDEX_2K_ENTRIES  2048
   4787 #define _APACHE_INDEX_3K_ENTRIES  3072
   4788 #define _APACHE_INDEX_4K_ENTRIES  4096
   4789 #define _APACHE_INDEX_6K_ENTRIES  6144
   4790 
   4791 /* Map logical (always starts from 0 and contiguous) index to physical index 
   4792    which can have a starting offset and/or holes.
   4793    Input  : logical index
   4794    Returns: physical index */
   4795 int
   4796 soc_apache_l3_defip_index_map (int unit, soc_mem_t mem, int index)
   4797 {
   4798     int wide = 0;
   4799     int alpm_mode = _soc_alpm_mode[unit];
   4800     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   4801     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   4802 
   4803     /* don't remap for ALPM */
   4804     if (defip128_tbl_sz == 0) {
   4805         return index;
   4806     }
   4807 
   4808     if (mem == L3_DEFIP_PAIR_128m ||
   4809         mem == L3_DEFIP_PAIR_128_ONLYm ||
   4810         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   4811         mem == L3_DEFIP_PAIR_128_HIT_ONLYm) {
   4812         wide = 1;
   4813     }
   4814 
   4815     if (alpm_mode == 2) {
   4816         if (is_urpf_mode) { 
   4817             if (wide == 0) {
   4818                 if (index >= _APACHE_INDEX_2K_ENTRIES) {
   4819                     return index + (defip128_tbl_sz * 2);
   4820                 }
   4821                 return index + defip128_tbl_sz;
   4822             } else {
   4823                 if (index >= _APACHE_INDEX_1K_ENTRIES) {
   4824                     return index + defip128_tbl_sz / 2;
   4825                 }
   4826                 return index;
   4827             }
   4828         }
   4829 
   4830         /* not uRPF */
   4831         return (wide) ? index : index + (defip128_tbl_sz * 2);
   4832     } 
   4833     if (alpm_mode == 1) {
   4834         uint32 incr = soc_mem_index_count(unit, mem)/4;
   4835         uint32 entries_per_tcam = _APACHE_INDEX_1K_ENTRIES;
   4836         uint32 tcam_num, tcam_idx;
   4837         uint32 cnt_128;
   4838         uint32 tmp;
   4839         
   4840         if (is_urpf_mode) {
   4841             if (wide) {
   4842                 /* Coverity issue ignored:
   4843                  * Since mem index count cannot be 0
   4844                  * hence, the scenario does not arise */
   4845                 /* coverity[divide_by_zero : FALSE] */
   4846                 tcam_num = index/incr;
   4847                 tcam_idx = index % incr;
   4848                 return tcam_num * entries_per_tcam + tcam_idx;
   4849             }
   4850             incr = incr/2;
   4851             /* coverity[divide_by_zero : FALSE] */
   4852             tcam_num = index/incr;
   4853             tcam_idx = index % incr;
   4854             return tcam_num * entries_per_tcam + tcam_idx + 
   4855                                 defip128_tbl_sz/4;
   4856         }
   4857         if (wide > 0) {
   4858             if (index < (soc_mem_index_count(unit, mem) / 2)) {
   4859                 return index;
   4860             } 
   4861             /* make index relative to upper half */
   4862             index -= (soc_mem_index_count(unit, mem) / 2);
   4863             return index + _APACHE_INDEX_2K_ENTRIES;
   4864         }
   4865 
   4866         cnt_128 = defip128_tbl_sz;
   4867  
   4868         if (cnt_128/2 <= _APACHE_INDEX_1K_ENTRIES) {
   4869             if ((cnt_128/2 + index) < _APACHE_INDEX_1K_ENTRIES) {
   4870                 return index + cnt_128/2;
   4871             } else if ((cnt_128 + index) < _APACHE_INDEX_4K_ENTRIES) {
   4872                 return index + cnt_128;
   4873             } else if ((cnt_128 + index + cnt_128/2) < 
   4874                        (_APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_1K_ENTRIES)) {
   4875                 return index + cnt_128 + cnt_128/2;
   4876             } else {
   4877                 return index + 2 * cnt_128;
   4878             }
   4879         } else if (cnt_128/2 <= _APACHE_INDEX_2K_ENTRIES) {
   4880             tmp = cnt_128 - _APACHE_INDEX_2K_ENTRIES;
   4881             if ((tmp/2 + index + _APACHE_INDEX_2K_ENTRIES) < _APACHE_INDEX_3K_ENTRIES) {
   4882                 return index + _APACHE_INDEX_2K_ENTRIES + tmp/2;
   4883             } else if ((cnt_128 + index) < _APACHE_INDEX_4K_ENTRIES) {
   4884                 return index + cnt_128;
   4885             } else if ((cnt_128 + tmp/2 + index + _APACHE_INDEX_2K_ENTRIES) < 
   4886                        (_APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_3K_ENTRIES)) {
   4887                 return index + cnt_128 + tmp/2 + _APACHE_INDEX_2K_ENTRIES;
   4888             } else {
   4889                 return index + cnt_128 * 2;
   4890             }
   4891         }
   4892         
   4893         if (index < soc_mem_index_count(unit, mem)/2) {
   4894             return index + defip128_tbl_sz;
   4895         } else {
   4896             /* make index relative to upper half */
   4897             index -= (soc_mem_index_count(unit, mem)/2);
   4898             return index + 2 * _APACHE_INDEX_2K_ENTRIES + 
   4899                    defip128_tbl_sz;
   4900        }
   4901     }
   4902 
   4903     if (is_urpf_mode) { /* URPF mode */
   4904         return soc_l3_defip_urpf_index_map(unit, wide, index);
   4905     }
   4906 
   4907     return soc_l3_defip_index_map(unit, wide, index);
   4908 }
   4909 
   4910 /* Reverse map physical index to logical index.
   4911    Input  : physical index
   4912    Returns: logical index */
   4913 int
   4914 soc_apache_l3_defip_index_remap(int unit, soc_mem_t mem, int index)
   4915 {
   4916     int wide = 0;
   4917     int alpm_mode = _soc_alpm_mode[unit];
   4918     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   4919     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   4920 
   4921     /* don't remap for ALPM */
   4922     if (defip128_tbl_sz == 0) {
   4923         return index;
   4924     }
   4925 
   4926     if (mem == L3_DEFIP_PAIR_128m ||
   4927         mem == L3_DEFIP_PAIR_128_ONLYm ||
   4928         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   4929         mem == L3_DEFIP_PAIR_128_HIT_ONLYm) {
   4930         wide = 1;
   4931     }
   4932 
   4933     if (alpm_mode == 2) {
   4934         if (is_urpf_mode) { /* URPF mode */
   4935             if (wide == 0) {
   4936                 if (index >= _APACHE_INDEX_6K_ENTRIES) {
   4937                     return index - (defip128_tbl_sz * 2);
   4938                 }
   4939                 return index - defip128_tbl_sz;
   4940             } else {
   4941                 if (index >= _APACHE_INDEX_1K_ENTRIES) {
   4942                     return index - defip128_tbl_sz / 2;
   4943                 }
   4944                 return index;
   4945             }
   4946         }
   4947         return (wide) ? index : index - (defip128_tbl_sz * 2);
   4948     } 
   4949     if (alpm_mode == 1) {
   4950         int cnt_128;
   4951         
   4952         if (is_urpf_mode) {
   4953             uint32 num_chunks, chunk_offset;
   4954             if (wide) {
   4955                 num_chunks = index / _APACHE_INDEX_1K_ENTRIES;
   4956                 chunk_offset = index % _APACHE_INDEX_1K_ENTRIES;
   4957                 return num_chunks * soc_mem_index_count(unit, mem)/4 
   4958                        + chunk_offset;
   4959             }
   4960             num_chunks = index / _APACHE_INDEX_1K_ENTRIES;
   4961             chunk_offset = index % _APACHE_INDEX_1K_ENTRIES;
   4962             chunk_offset -= (defip128_tbl_sz/4);
   4963             return num_chunks*soc_mem_index_count(unit, mem)/8 + chunk_offset;
   4964             
   4965         }
   4966 
   4967         cnt_128 = defip128_tbl_sz;
   4968         
   4969         if (wide) {
   4970             if (index < cnt_128/2) {
   4971                 return index;
   4972             } else if ((index >= _APACHE_INDEX_2K_ENTRIES) && 
   4973                        (index < _APACHE_INDEX_2K_ENTRIES + cnt_128/2)){
   4974                 return index - _APACHE_INDEX_2K_ENTRIES + cnt_128/2;               
   4975             } else {
   4976                 return -1;
   4977             }
   4978         }
   4979 
   4980         if (cnt_128/2 <= _APACHE_INDEX_1K_ENTRIES) {
   4981             if ((index < _APACHE_INDEX_1K_ENTRIES) &&
   4982                 (index >= cnt_128/2)) {
   4983                 return index - cnt_128/2;
   4984             } else if ((index >= _APACHE_INDEX_1K_ENTRIES + cnt_128/2) && 
   4985                            (index < _APACHE_INDEX_4K_ENTRIES)) {
   4986                 return index - cnt_128;
   4987             } else if ((index < _APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_1K_ENTRIES) &&
   4988                            (index >= _APACHE_INDEX_4K_ENTRIES + cnt_128/2)) {
   4989                 return index - cnt_128 - cnt_128/2;
   4990             } else {
   4991                 return index - cnt_128 * 2;
   4992             }
   4993         } else if (cnt_128/2 <= _APACHE_INDEX_2K_ENTRIES) {
   4994             if (index < _APACHE_INDEX_3K_ENTRIES) {
   4995                 return index - _APACHE_INDEX_2K_ENTRIES - \
   4996                        (cnt_128 - _APACHE_INDEX_2K_ENTRIES)/2;
   4997             } else if (index < _APACHE_INDEX_4K_ENTRIES) {
   4998                 return index - cnt_128;
   4999             } else if (index < _APACHE_INDEX_4K_ENTRIES + _APACHE_INDEX_3K_ENTRIES) {
   5000                 return index - cnt_128 - _APACHE_INDEX_2K_ENTRIES - \
   5001                        (cnt_128 - _APACHE_INDEX_2K_ENTRIES)/2;
   5002             } else {
   5003                 return index - cnt_128 * 2;
   5004             }
   5005         }
   5006     }
   5007     if (is_urpf_mode) { /* URPF mode */
   5008         return soc_l3_defip_urpf_index_remap(unit, wide, index);
   5009     }
   5010 
   5011     return soc_l3_defip_index_remap(unit, wide, index);
   5012 }
   5013 
   5014 /* Given a physical index (always in terms of the narrow entry) 
   5015    return the logical index and memory type */
   5016 int
   5017 soc_apache_l3_defip_mem_index_get(int unit, int pindex, soc_mem_t *mem)
   5018 {
   5019     return soc_l3_defip_index_mem_map(unit, pindex, mem);
   5020 }
   5021 
   5022 void
   5023 _soc_apache_alpm_bkt_view_set(int unit, int index, soc_mem_t view)
   5024 {
   5025     int bkt = soc_apache_get_alpm_banks(unit) + 1;
   5026     bkt = (index >> (bkt / 2)) & SOC_APACHE_ALPM_BKT_MASK;
   5027 
   5028     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt set index:%d bkt:%d view:%s\n"),
   5029                  unit, index, bkt, SOC_MEM_NAME(unit, view)));
   5030     _soc_apache_alpm_bkt_view_map[unit][bkt] = view;
   5031 }
   5032 
   5033 soc_mem_t
   5034 _soc_apache_alpm_bkt_view_get(int unit, int index)
   5035 {
   5036     soc_mem_t view;
   5037     int bkt = soc_apache_get_alpm_banks(unit) + 1;
   5038     bkt = (index >> (bkt / 2)) & SOC_APACHE_ALPM_BKT_MASK;
   5039 
   5040     view = _soc_apache_alpm_bkt_view_map[unit][bkt];
   5041     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt get index:%d bkt:%d view:%s\n"),
   5042                  unit, index, bkt, SOC_MEM_NAME(unit, view)));
   5043     return view;
   5044 }
   5045  
   5046 int
   5047 _soc_apache_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno,
   5048                                     int enable, int *orig_enable)
   5049 {
   5050     soc_reg_t reg;
   5051     soc_field_t field;
   5052     int blk, port;
   5053     soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID};
   5054     uint32 rval, fval, orig_fval, enable_fval, disable_fval;
   5055 
   5056     enable_fval = 1;
   5057     disable_fval = 0;
   5058 
   5059     switch (mem) {
   5060     case XLPORT_WC_UCMEM_DATAm:
   5061         reg = XLPORT_WC_UCMEM_CTRLr;
   5062         field = ACCESS_MODEf;
   5063         SOC_BLOCKS_ITER(unit, blk, xlport_blocks) {
   5064             port = SOC_BLOCK_PORT(unit, blk);
   5065             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   5066             /* It will use the setting from the last block */
   5067             *orig_enable = soc_reg_field_get(unit, reg, rval, field);
   5068             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   5069             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   5070         }
   5071         return SOC_E_NONE;
   5072     case L3_DEFIP_ALPM_RAWm:
   5073     case L3_DEFIP_ALPM_IPV4m:
   5074     case L3_DEFIP_ALPM_IPV4_1m:
   5075     case L3_DEFIP_ALPM_IPV6_64m:
   5076     case L3_DEFIP_ALPM_IPV6_64_1m:
   5077     case L3_DEFIP_ALPM_IPV6_128m:
   5078         reg = ISS_MEMORY_CONTROL_84r;
   5079         field = BYPASS_ISS_MEMORY_LPf;
   5080         enable_fval = 0xf;
   5081         break;
   5082     case MMU_INTFI_PFC_ST_TBLm:
   5083         reg = INTFI_CFGr;
   5084         field = PFC_ST_TBL_DISABLEf;
   5085         break;
   5086     case LINK_STATUSm:
   5087         reg = SW2_HW_CONTROLr;
   5088         field = LINK_STATUS_UPDATE_ENABLEf;
   5089         break;
   5090     case MMU_INTFO_QCN_CNM_TIMER_TBLm:
   5091     case MMU_INTFI_XPIPE_FC_MAP_TBL2m:
   5092     case MMU_MTRI_BKPMETERINGBUCKET_MEM_0m:
   5093     case MMU_MTRO_BUCKET_L0_MEM_0m:
   5094     case MMU_MTRO_BUCKET_L1_MEM_0m:
   5095     case MMU_MTRO_BUCKET_L1_MEM_1m:
   5096     case MMU_MTRO_BUCKET_L2_MEM_0m:
   5097     case MMU_MTRO_BUCKET_L2_MEM_1m:
   5098     case MMU_MTRO_BUCKET_L2_MEM_2m:
   5099     case MMU_MTRO_BUCKET_L2_MEM_3m:
   5100     case MMU_MTRO_BUCKET_L2_MEM_4m:
   5101     case MMU_MTRO_BUCKET_L2_MEM_5m:
   5102     case MMU_MTRO_BUCKET_L2_MEM_6m:
   5103     case MMU_MTRO_BUCKET_L2_MEM_7m:
   5104     case MMU_WRED_AVG_QSIZE_X_PIPEm:
   5105     case MMU_WRED_CONFIG_X_PIPEm:
   5106     case MMU_WRED_PORT_SP_DROP_THD_X_PIPEm:
   5107     case MMU_WRED_QGROUP_DROP_THD_X_PIPEm:
   5108     case MMU_WRED_UC_QUEUE_DROP_THD_DEQ_X_PIPE_0m:
   5109     case MMU_WRED_UC_QUEUE_DROP_THD_ENQ_X_PIPE_0m:
   5110         reg = MISCCONFIGr;
   5111         field = REFRESH_ENf;
   5112         enable_fval = 0;
   5113         disable_fval = 1;
   5114         break;
   5115     default:
   5116         return SOC_E_NONE;
   5117     }
   5118 
   5119     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   5120     orig_fval = soc_reg_field_get(unit, reg, rval, field);
   5121     fval = enable ? enable_fval : disable_fval;
   5122 
   5123     *orig_enable = orig_fval == enable_fval;
   5124     if (fval != orig_fval) {
   5125         soc_reg_field_set(unit, reg, &rval, field, fval);
   5126         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   5127     }
   5128 
   5129     return SOC_E_NONE;
   5130 }
   5131 
   5132 
   5133 /*
   5134  * cpu port (mmu port 72): 48 queues (17114 -17161)
   5135  * loopback port (mmu port 73): 8 queues (17104- 17111)
   5136  */
   5137 #define _APACHE_CPU_QUEUE_BASE  17114
   5138 #define _APACHE_LB_QUEUE_BASE   17104
   5139 #define _APACHE_QCN_QUEUE_BASE   17112
   5140 #define _APACHE_HSP_PORTS       16
   5141 #define _APACHE_UC_QUEUE_BASE   0
   5142 #define _APACHE_MC_QUEUE_BASE   16384
   5143 #define _APACHE_NUMBER_OF_UC_QUEUE   16384
   5144 #define _APACHE_NUMBER_OF_MC_QUEUE   720 
   5145 #define IS_AP_HSP_PORT(u,p)   \
   5146     ((_soc_apache_port_sched_type_get((u),(p)) == SOC_APACHE_SCHED_HSP) ? 1 : 0)
   5147 
   5148 int
   5149 soc_apache_num_cosq_init(int unit)
   5150 {
   5151     soc_info_t *si;
   5152     int mmu_port, port, phy_port;
   5153     int lls_uc_cosq_base;
   5154     int count;
   5155     si = &SOC_INFO(unit);
   5156 
   5157     if (soc_feature(unit, soc_feature_cmic_reserved_queues)) {
   5158         si->port_num_cosq[CMIC_PORT(unit)] = 44;
   5159     } else {
   5160         si->port_num_cosq[CMIC_PORT(unit)] = 48;
   5161     }
   5162 
   5163     si->port_cosq_base[CMIC_PORT(unit)] = _APACHE_CPU_QUEUE_BASE - _APACHE_MC_QUEUE_BASE;
   5164     si->port_num_cosq[LB_PORT(unit)] = 9;
   5165     si->port_cosq_base[LB_PORT(unit)] = _APACHE_LB_QUEUE_BASE - _APACHE_MC_QUEUE_BASE ;
   5166     si->port_num_cosq[RDB_PORT(unit)] = 0;
   5167 #if defined(BCM_56560_A0)
   5168     si->port_cosq_base[74] = 0;
   5169 #endif
   5170 
   5171     SOC_PBMP_COUNT(si->eq_pbm, count);
   5172     /* Flexport op may lead to change of schedulars.
   5173      * Assign LLS uc queues from 16(max HSP ports)*10 onwards
   5174      * to prevent any possible overlap
   5175      */
   5176     lls_uc_cosq_base =
   5177         soc_reg_field_length(unit, HSP_SCHED_GLOBAL_CONFIGr, IS_HSP_PORT_IN_XPIPEf) * 10;
   5178 
   5179     for (mmu_port = 0; mmu_port < _APACHE_MMU_PORTS_PER_PIPE; mmu_port++) {
   5180         phy_port = si->port_m2p_mapping[mmu_port];
   5181         if (phy_port == -1) {
   5182             continue;
   5183         }
   5184 
   5185         port = si->port_p2l_mapping[phy_port];
   5186         if (port == -1) {
   5187             continue;
   5188         }
   5189 
   5190         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
   5191             continue;
   5192         }
   5193 
   5194         si->port_num_cosq[port] = 10;
   5195         si->port_cosq_base[port] = mmu_port * si->port_num_cosq[port];
   5196 
   5197         if (SOC_PBMP_MEMBER(si->eq_pbm, port)) { /* VBS (HSP) port */
   5198             /* Made port_uc_cosq_base a function of mmu_port number
   5199              * rather than a running number (as calculated by
   5200              * uc_cosq_base before). If it is a running number, &
   5201              * the port numbers come & go dynamically (as in flex port)
   5202              * uc_cosq_base overlap. With port_uc_cosq_base a function
   5203              * of mmu_port, each port has a fixed offset
   5204              */
   5205             si->port_num_uc_cosq[port] = 10;
   5206             si->port_uc_cosq_base[port] = mmu_port * si->port_num_uc_cosq[port];
   5207         } else {
   5208             si->port_num_uc_cosq[port] = 16;
   5209             /* uc_cosq_base for LLS port must be:
   5210              * divisible by 4 for PFC to work
   5211              * divisible by 8 for E2ECC to work
   5212              */
   5213 
   5214             lls_uc_cosq_base = (lls_uc_cosq_base + 7) & (~7);
   5215             si->port_uc_cosq_base[port] = lls_uc_cosq_base;
   5216             lls_uc_cosq_base += si->port_num_uc_cosq[port];
   5217         }
   5218 
   5219         if ((si->port_uc_cosq_base[port] > _APACHE_NUMBER_OF_UC_QUEUE) ||
   5220             (si->port_cosq_base[port] > _APACHE_NUMBER_OF_MC_QUEUE)) {
   5221             return SOC_E_INTERNAL;
   5222         }
   5223 
   5224         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
   5225             "port = %d phy_port = %d mmu = %d ucq = %d mcq = %d\n"),
   5226             port, phy_port, mmu_port, si->port_uc_cosq_base[port], si->port_cosq_base[port]));
   5227     }
   5228 
   5229     return SOC_E_NONE;
   5230 }
   5231 
   5232 STATIC int
   5233 soc_apache_frequency_get(int unit, int *max_freq, int *def_freq)
   5234 {
   5235     if (soc_feature(unit, soc_feature_untethered_otp)) {
   5236         *max_freq = SOC_BOND_INFO(unit)->max_core_freq;
   5237         *def_freq = SOC_BOND_INFO(unit)->default_core_freq;
   5238     } else {
   5239         *def_freq = 793;
   5240         *max_freq = 841;
   5241     }
   5242 
   5243     return SOC_E_NONE;
   5244 }
   5245 
   5246 int
   5247 soc_apache_tsc_map_get(int unit, uint32 *tsc_map, uint32 *force_hg)
   5248 {
   5249 
   5250     if (soc_feature(unit, soc_feature_untethered_otp)) {
   5251         *tsc_map = SOC_BOND_INFO(unit)->tsc_enable;
   5252         *force_hg = SOC_BOND_INFO(unit)->tsc_force_hg;
   5253     } else {
   5254         *tsc_map = 0xffffffff;
   5255         *force_hg = 0x0;
   5256     }
   5257 
   5258     return SOC_E_NONE;
   5259 }
   5260 
   5261 typedef struct soc_apache_valid_fallback_cores_s {
   5262     soc_100g_lane_config_t lane_config;
   5263     int                    valid_lanes[3];
   5264 }soc_apache_valid_fallback_cores_t;
   5265 
   5266 const soc_apache_valid_fallback_cores_t soc_apache_valid_an_cores[] = {
   5267     {SOC_LANE_CONFIG_100G_4_4_2, {TRUE, TRUE, TRUE} },
   5268     {SOC_LANE_CONFIG_100G_3_4_3, {TRUE, TRUE, TRUE} },
   5269     {SOC_LANE_CONFIG_100G_2_4_4, {TRUE, TRUE, TRUE} },
   5270     {SOC_INVALID_LANE_CONFIG}
   5271 };
   5272 
   5273 
   5274 STATIC int
   5275 soc_apache_port_is_falcon(int unit, int phy_port)
   5276 {
   5277 
   5278     if (((phy_port >= 29) && (phy_port <= 36)) ||
   5279         ((phy_port >= 65) && (phy_port <= 72))) {
   5280         return TRUE;
   5281     }
   5282 
   5283     return FALSE;
   5284 }
   5285 
   5286 STATIC int
   5287 soc_apache_port_is_2p5g_forced(int unit, int phy_port)
   5288 {
   5289     int tsc_id, bit_pos;
   5290     if (soc_apache_port_is_falcon(unit, phy_port) ||
   5291         !soc_feature(unit, soc_feature_untethered_otp)) {
   5292         return FALSE;
   5293     }
   5294 
   5295     tsc_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC);
   5296 
   5297     /* SOC_BOND_INFO(unit)->tsce_max_2p5g is 14bit wide representing 14 Eagle TSCs in AP
   5298      * In case TSC belongs in PGW 1, subtract 2 TSC falcons of PGW 0 to get correct bit pos
   5299      */
   5300     bit_pos = (tsc_id >= APACHE_TSCS_PER_PGW) ? (tsc_id - APACHE_NUM_CLP_PER_PGW) : tsc_id;
   5301 
   5302     if (!((SOC_BOND_INFO(unit)->tsce_max_2p5g) & (1 << bit_pos))) {
   5303         return FALSE;
   5304     }
   5305     return TRUE;
   5306 }
   5307 
   5308 #if 0
   5309 STATIC int
   5310 soc_apache_port_is_11g_forced(int unit, int phy_port)
   5311 {
   5312     int tsc_id, bit_pos;
   5313     if (!soc_apache_port_is_falcon(unit, phy_port) ||
   5314         !soc_feature(unit, soc_feature_untethered_otp)) {
   5315         return FALSE;
   5316     }
   5317 
   5318     tsc_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC);
   5319 
   5320     /* SOC_BOND_INFO(unit)->tscf_max_11g is 4bit wide representing 4 Falcon TSCs in AP
   5321      * In case TSC belongs in PGW 1, subtract 7 TSC eagles of PGW 1 to get correct bit pos
   5322      */
   5323     bit_pos = (tsc_id >= APACHE_TSCS_PER_PGW) ? (tsc_id - APACHE_NUM_XLP_PER_PGW) : tsc_id;
   5324 
   5325     /* Subtract 7 TSC eagles for PGW 0 */
   5326     bit_pos -= APACHE_NUM_XLP_PER_PGW;
   5327 
   5328     if (!((SOC_BOND_INFO(unit)->tscf_max_11g) & (1 << bit_pos))) {
   5329         return FALSE;
   5330     }
   5331     return TRUE;
   5332 }
   5333 #endif
   5334 
   5335 /* If CLPORT0/1/2/3/4/5 block is disabled
   5336  * CLPORT speeds like 1x100G, 2x50G, 4x25G are disabled
   5337  */
   5338 #define IS_100G_DISABLED(clp_block) \
   5339     (soc_feature(unit, soc_feature_untethered_otp) ? (!((SOC_BOND_INFO(unit)->clmac_map) & (1 << (clp_block)))) : (0))
   5340 
   5341 STATIC soc_error_t
   5342 _soc_apache_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth)
   5343 {
   5344     if (soc_apache_port_is_falcon(unit, phy_port)) {
   5345         *lanes =   (port_bandwidth > 53000) ?
   5346                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1
   5347                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1
   5348                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1
   5349                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1
   5350                      : 4
   5351                  : (port_bandwidth > 42000) ?
   5352                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1
   5353                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1
   5354                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1
   5355                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1
   5356                      : 2
   5357                  : (port_bandwidth > 27000) ?
   5358                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? 4
   5359                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? 4
   5360                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? 4
   5361                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? 4
   5362                      : 2
   5363                  : (port_bandwidth == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(21000)) ? 2
   5364                  : (port_bandwidth > 11000) ?
   5365                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1
   5366                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1
   5367                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1
   5368                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1
   5369                      : 1
   5370                  : 1;
   5371     } else {
   5372         *lanes =   (port_bandwidth >= 100000) ?
   5373                        (IS_100G_DISABLED(0) && (phy_port == 17)) ? -1
   5374                      : (IS_100G_DISABLED(3) && (phy_port == 53)) ? -1
   5375                      : 10
   5376                  : (port_bandwidth > 21000) ? 4
   5377                  : (port_bandwidth > 11000) ? 2
   5378                  : 1;
   5379     }
   5380     return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE);
   5381 }
   5382 
   5383 /* Function to check legal BW values per port 
   5384  */
   5385 STATIC int
   5386 _soc_apache_port_speed_supported(int unit, int port, int phy_port,
   5387                                  int port_lanes, int port_bandwidth)
   5388 {
   5389     soc_pbmp_t xe_pbmp;
   5390 
   5391     if (port_lanes == -1) {
   5392         if (SOC_FAILURE(_soc_apache_port_lanes_set(unit, phy_port, &port_lanes, port_bandwidth))) {
   5393             return FALSE;
   5394         }
   5395     }
   5396 
   5397     switch (port_bandwidth) {
   5398     case 1000:
   5399         /*  Eagles or Falcons - 1 x lanes */
   5400         return (port_lanes == 1);
   5401     case 2500:
   5402     case 5000:
   5403         /*  Eagles only - 1 x lanes */
   5404         return (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1));
   5405     case 10000:
   5406         /*  Falcons - 1 x lanes and Eagles - 1, 2 or 4 lanes */
   5407         return (!soc_apache_port_is_falcon(unit, phy_port) ||
   5408                 (soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1)));
   5409     case 20000:
   5410         /*  Eagles or Falcons - 2 x lanes */
   5411         return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || (port_lanes == 2));
   5412     case 25000:
   5413         /*  Falcons only - 1 x lanes */
   5414         return ((soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 1)) ||
   5415                 (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)));
   5416     case 30000:
   5417         /*  Eagles only - 4 x lanes */
   5418         return (!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4));
   5419     case 40000:
   5420         /*  Eagles - 4 x lanes; Falcons - 2, 4 lanes */
   5421         return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 4)) ||
   5422                 (soc_apache_port_is_falcon(unit, phy_port) && ((port_lanes == 2) || (port_lanes == 4))));
   5423     case 50000:
   5424         /*  Falcons only - 2 lanes */
   5425         return (soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 2));
   5426     case 100000:
   5427         /*  Eagles - 10 x lanes; Falcons - 4 lanes */
   5428         return ((!soc_apache_port_is_falcon(unit, phy_port) && (port_lanes == 10)) ||
   5429                 (soc_apache_port_is_falcon(unit, phy_port) &&  (port_lanes == 4)));
   5430 
   5431     case 11000:
   5432     case 21000:
   5433     case 27000:
   5434     case 42000:
   5435     case 53000:
   5436     case 106000:
   5437         SOC_PBMP_CLEAR(xe_pbmp);
   5438         xe_pbmp = soc_property_get_pbmp_default(unit,
   5439                                spn_PBMP_XPORT_XE, xe_pbmp);
   5440         if (!SOC_PBMP_MEMBER(xe_pbmp, port)) {
   5441             return _soc_apache_port_speed_supported(unit, port, phy_port, port_lanes, SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth));
   5442         } else {
   5443             LOG_CLI((BSL_META_U(unit,
   5444                                 "Port %d: Invalid HG2 bandwidth %d Gb\n"),
   5445                      port, port_bandwidth / 1000));
   5446             return FALSE;
   5447         }
   5448         break;
   5449 
   5450     default:
   5451         LOG_CLI((BSL_META_U(unit,
   5452                             "Port %d: Invalid bandwidth %d Gb\n"),
   5453                  port, port_bandwidth / 1000));
   5454         return FALSE;
   5455         break;
   5456     }
   5457 
   5458     return FALSE;
   5459 }
   5460 
   5461 int
   5462 soc_apache_port_config_bandwidth_check(int unit)
   5463 {
   5464     int rv = SOC_E_NONE;
   5465     int oversub_mode;
   5466     int port_bandwidth;
   5467     int *blk_port = NULL;
   5468     int *blk_port_bandwidth = NULL;
   5469     int index, port, phy_port, lane_count, blk, pgw;
   5470     int is_fb5_device = 0;
   5471     int speed_lanes_1 = 0, speed_lanes_2 = 0;
   5472     int blk_linerate_bandwidth, blk_oversub_bandwidth;
   5473     int pgw_port[APACHE_PORTS_PER_PGW];
   5474     int pgw_port_bandwidth[APACHE_PORTS_PER_PGW];
   5475     int pgw_linerate_bandwidth[APACHE_PGWS_PER_DEV], pgw_oversub_bandwidth[APACHE_PGWS_PER_DEV];
   5476     int max_pgw_core_bandwidth[APACHE_PGWS_PER_DEV];
   5477     int max_pgw_oversub_bandwidth[APACHE_PGWS_PER_DEV];
   5478     int os_ratio[APACHE_PGWS_PER_DEV];
   5479     /* MAX OS ratio for a few FB5 configs is > 1.5 but is limited only to a single PGW */
   5480     int max_os_ratio = 1750, def_os_ratio = 1500;
   5481     uint32 blk_configured_map, blk_inactive_map, blk_oversub_map;
   5482     int falcon_lr_bandwidth = 0, falcon_os_bandwidth = 0, *falcon_bw_ptr = 0;
   5483 
   5484     for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) {
   5485         max_pgw_core_bandwidth[pgw] = (SOC_INFO(unit).bandwidth) / APACHE_PGWS_PER_DEV;
   5486         max_pgw_oversub_bandwidth[pgw] = (SOC_INFO(unit).io_bandwidth) / APACHE_PGWS_PER_DEV;
   5487 
   5488         /* OVSB TDM per slot bandwidth granularity is 10G
   5489          * 56068 SKU has 2x1G ports which will be passed as 2x10g to algo-TDM
   5490          * We don't care even if io_bandwidth overshoots
   5491          * as long as TDM calendar allocates only 1g worth of slots.
   5492          */
   5493         max_pgw_oversub_bandwidth[pgw] += (SOC_INFO(unit).frequency == 841 ? 10000 : 0);
   5494     }
   5495 
   5496     oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
   5497 
   5498     /* Bandwidth check for ports in each XLPORT/CLPORT block */
   5499     for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) {
   5500         pgw_linerate_bandwidth[pgw] = 0;
   5501         pgw_oversub_bandwidth[pgw] = 0;
   5502 
   5503         /* Prepare per PGW local variables for ease of processing */
   5504         for (index = 0; index < APACHE_PORTS_PER_PGW; index++) {
   5505             phy_port = 1 + pgw * APACHE_PORTS_PER_PGW + index;
   5506             port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   5507             pgw_port[index] = port;
   5508             if (port == -1) {
   5509                 pgw_port_bandwidth[index] = 0;
   5510             } else {
   5511                 pgw_port_bandwidth[index] = SOC_INFO(unit).port_speed_max[port];
   5512                 APACHE_TDM_SPEED_ADJUST(unit, port, pgw_port_bandwidth[index]);
   5513             }
   5514         }
   5515 
   5516         for (blk = 0; blk < APACHE_TSCS_PER_PGW; blk++) {
   5517 
   5518             blk_port = &pgw_port[blk * APACHE_PORTS_PER_TSC];
   5519             blk_port_bandwidth = &pgw_port_bandwidth[blk * APACHE_PORTS_PER_TSC];
   5520 
   5521             blk_configured_map = 0;
   5522             for (index = 0; index < APACHE_PORTS_PER_TSC; index++) {
   5523                 if (blk_port[index] != -1) {
   5524                     blk_configured_map |= 1 << index;
   5525                 }
   5526             }
   5527             if (blk_configured_map == 0) {
   5528                 continue;
   5529             }
   5530 
   5531             /* Normal port block handling */
   5532             blk_inactive_map = 0;
   5533             blk_oversub_map = 0;
   5534             blk_linerate_bandwidth = 0;
   5535             blk_oversub_bandwidth = 0;
   5536             for (index = 0; index < APACHE_PORTS_PER_TSC; index++) {
   5537                 port = blk_port[index];
   5538                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   5539                 if (port == -1) {
   5540                     continue;
   5541                 }
   5542                 port_bandwidth = blk_port_bandwidth[index];
   5543                 if (IS_OVERSUB_PORT(unit, port)) {
   5544                     blk_oversub_map |= 1 << index;
   5545                 }
   5546                 if (SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5547                     blk_inactive_map |= 1 << index;
   5548                 } else {
   5549                     if (blk_oversub_map & (1 << index)) {
   5550                         falcon_bw_ptr = &falcon_os_bandwidth;
   5551                         blk_oversub_bandwidth += port_bandwidth;
   5552                     } else {
   5553                         falcon_bw_ptr = &falcon_lr_bandwidth;
   5554                         blk_linerate_bandwidth += port_bandwidth;
   5555                     }
   5556                 }
   5557 
   5558                 /* 0-3 Blocks are PM4x10 and 4-6 are PM12x10 */
   5559                 if (blk >= 0 && blk <= 6) {
   5560                     if ((port_bandwidth > 106000)  ||
   5561                         (port_bandwidth > 42000 && (blk != 4))  ||
   5562                         (port_bandwidth > 21000 && (index != 0)) ||
   5563                         (port_bandwidth > 11000 && (index & 1))) {
   5564 
   5565                         LOG_CLI((BSL_META_U(unit,
   5566                                             "Port %d: Physical port %d can not "
   5567                                             "be configured to %d Gb\n"),
   5568                                  port, phy_port, (port_bandwidth / 1000)));
   5569                         rv = SOC_E_FAIL;
   5570                     }
   5571 
   5572                     speed_lanes_1 = 11000;
   5573                     speed_lanes_2 = 21000;
   5574                }
   5575 
   5576                 /* 7-8 Blocks are PM4x25 */
   5577                 if (blk >= 7 && blk <= 8) {
   5578                     if ((port_bandwidth > 106000) ||
   5579                         (port_bandwidth > 53000 && (index != 0)) ||
   5580                         (port_bandwidth > 27000 && (index & 1))) {
   5581 
   5582                         LOG_CLI((BSL_META_U(unit,
   5583                                             "Port %d: Physical port %d can not "
   5584                                             "be configured to %d Gb\n"),
   5585                                  port, phy_port, (port_bandwidth / 1000)));
   5586                         rv = SOC_E_FAIL;
   5587                     }
   5588 
   5589                     speed_lanes_1 = 27000;
   5590                     speed_lanes_2 = 53000;
   5591 
   5592                     *falcon_bw_ptr += port_bandwidth;
   5593                 }
   5594             }
   5595 
   5596             /* Check if any of the lanes used by first port of block is
   5597              * not used by other port */
   5598             port_bandwidth = blk_port_bandwidth[0];
   5599             if (port_bandwidth > speed_lanes_2) {
   5600                 lane_count = 4;
   5601             } else if (port_bandwidth > speed_lanes_1) {
   5602                 lane_count = 2;
   5603             } else {
   5604                 lane_count = 1;
   5605             }
   5606 
   5607             for (index = 1; index < lane_count; index++) {
   5608                 port = blk_port[index];
   5609                 if (port == -1 || SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5610                     continue;
   5611                 }
   5612                 LOG_CLI((BSL_META_U(unit,
   5613                                     "Port %d bandwidth %d Gb and "
   5614                                     "port %d can not be both configured\n"),
   5615                          blk_port[0], port_bandwidth / 1000, port));
   5616                 rv = SOC_E_FAIL;
   5617             }
   5618 
   5619             /* Check if any of the lanes used by third port of block is
   5620              * not used by other port */
   5621             port_bandwidth = blk_port_bandwidth[2];
   5622             if (port_bandwidth > speed_lanes_1) {
   5623                 port = blk_port[3];
   5624                 if (port != -1 && !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5625                     LOG_CLI((BSL_META_U(unit,
   5626                                         "Port %d bandwidth %d Gb and port %d "
   5627                                         "can not be both configured\n"),
   5628                              blk_port[2], port_bandwidth / 1000, port));
   5629                     rv = SOC_E_FAIL;
   5630                 }
   5631                 if (blk_port[0] == -1) {
   5632                     LOG_CLI((BSL_META_U(unit,
   5633                                "Physical port %d needs to be "
   5634                                "configured in order to work with "
   5635                                "port %d\n"),
   5636                                1 + pgw * APACHE_PORTS_PER_PGW +
   5637                                blk * APACHE_PORTS_PER_TSC,
   5638                                blk_port[2]));
   5639                     rv = SOC_E_FAIL;
   5640                 }
   5641             }
   5642 
   5643             if (blk_inactive_map == blk_configured_map) {
   5644                 LOG_CLI((BSL_META_U(unit, "Flex port")));
   5645                 for (index = 0; index < APACHE_PORTS_PER_TSC; index++) {
   5646                     if (blk_port[index] != -1) {
   5647                         LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index]));
   5648                     }
   5649                 }
   5650                 LOG_CLI((BSL_META_U(unit, ": Can not be all inactive\n")));
   5651                 rv = SOC_E_FAIL;
   5652                 continue;
   5653             }
   5654 
   5655             if (blk_inactive_map != 0) {
   5656                 if (blk_oversub_map != 0 &&
   5657                     blk_oversub_map != blk_configured_map) {
   5658                     LOG_CLI((BSL_META_U(unit, "Flex port")));
   5659                     for (index = 0; index < APACHE_PORTS_PER_TSC;
   5660                          index++) {
   5661                         if (blk_port[index] != -1) {
   5662                             LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index]));
   5663                         }
   5664                     }
   5665                     LOG_CLI((BSL_META_U(unit,
   5666                                         ": Can not be configured to "
   5667                                         "different oversubscription "
   5668                                         "mode within a port block\n")));
   5669                     rv = SOC_E_FAIL;
   5670                     continue;
   5671                 }
   5672             }
   5673 
   5674             if (falcon_lr_bandwidth != 0 && falcon_os_bandwidth != 0) {
   5675                 LOG_CLI((BSL_META_U(unit,
   5676                                     "TDM algorith does not support mixed LR and OS ports "
   5677                                     "modes on PM4x25 ports. LR BW = %d Gbps & OS BW = %d Gbps\n"),
   5678                          falcon_lr_bandwidth / 1000, falcon_os_bandwidth / 1000));
   5679                 rv = SOC_E_FAIL;
   5680             }
   5681 
   5682 
   5683             if (blk_linerate_bandwidth != 0 && blk_oversub_map != 0) {
   5684                 LOG_CLI((BSL_META_U(unit,
   5685                                     "TSC %d cannot have mixed LR and OS ports "
   5686                                     "LR Bandwidth = %d Gbps & OS Bandwidth = %d Gbps\n"),
   5687                          blk, blk_linerate_bandwidth / 1000, blk_oversub_bandwidth / 1000));
   5688                 rv = SOC_E_FAIL;
   5689             }
   5690 
   5691             pgw_linerate_bandwidth[pgw] += blk_linerate_bandwidth;
   5692             pgw_oversub_bandwidth[pgw] += blk_oversub_bandwidth;
   5693         } /* for (blk = 0; blk < APACHE_TSCS_PER_PGW; blk++) */
   5694 
   5695         if ((oversub_mode == 1) && (pgw_linerate_bandwidth[pgw] != 0)) {
   5696             LOG_ERROR(BSL_LS_SOC_COMMON,
   5697                       (BSL_META_U(unit, "Oversub mode: Linerate BW for PGW %d is not 0.\n"), pgw));
   5698             rv = SOC_E_FAIL;
   5699         } else if ((oversub_mode == 0) && (pgw_oversub_bandwidth[pgw] != 0)) {
   5700             LOG_ERROR(BSL_LS_SOC_COMMON,
   5701                       (BSL_META_U(unit, "Linerate mode: Oversub BW for PGW %d is not 0.\n"), pgw));
   5702             rv = SOC_E_FAIL;
   5703         } else if (oversub_mode == 2) {
   5704             /*
   5705              * OS ratio = (IO BW - LR BW) / (MAX LR BW - IO LR BW)
   5706              */
   5707             os_ratio[pgw] = (((pgw_oversub_bandwidth[pgw]) * 1000) / (max_pgw_core_bandwidth[pgw] - pgw_linerate_bandwidth[pgw]));
   5708         }
   5709 
   5710         if (soc_feature(unit, soc_feature_untethered_otp)) {
   5711             if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureFamilyFirebolt5)) {
   5712                 is_fb5_device = 1;
   5713             }
   5714         }
   5715 
   5716         /*
   5717          * On some FB5 SKUs, there will be a few MGIG ports for which the estimated 
   5718          * effective bandwidth will be 10G for each port in theory. 
   5719          * This would make the bandwidth checks below to fail. 
   5720          * It is expected that the users do not run these ports beyond 1G or 
   5721          * whatever is constrained by the HW Datasheet. These checks are relaxed for FB5 configs.
   5722          */
   5723         if ((oversub_mode != 2) && !is_fb5_device){
   5724             /* Linerate Bandwidth check */
   5725             if (pgw_linerate_bandwidth[pgw] > max_pgw_core_bandwidth[pgw]) {
   5726                 LOG_CLI((BSL_META_U(unit,
   5727                                     "PGW_CL%d total line rate bandwidth "
   5728                                     "(%d Gb) exceeds %d Gb\n"),
   5729                         pgw, (pgw_linerate_bandwidth[pgw] / 1000),
   5730                         (max_pgw_core_bandwidth[pgw] / 1000)));
   5731                 rv = SOC_E_FAIL;
   5732             }
   5733 
   5734             /* Oversub Bandwidth check */
   5735             if ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) {
   5736                 LOG_CLI((BSL_META_U(unit,
   5737                                     "PGW_CL%d total oversub bandwidth "
   5738                                     "(%d Gb) exceeds %d Gb\n"),
   5739                         pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000),
   5740                         (max_pgw_oversub_bandwidth[pgw] / 1000)));
   5741                 rv = SOC_E_FAIL;
   5742             }
   5743         }
   5744     }
   5745 
   5746     if (oversub_mode == 2) {
   5747         /* For mixed-mode we can have asymmetrical bandwidth distribution
   5748          * Check the OS ratio in this case
   5749          */
   5750         if ((os_ratio[APACHE_PGW0] > def_os_ratio) && (os_ratio[APACHE_PGW0] < max_os_ratio)) {
   5751             if (os_ratio[APACHE_PGW1] > def_os_ratio) {
   5752                 LOG_CLI((BSL_META_U(unit,
   5753                                     "PGW_CL1 total oversub bandwidth "
   5754                                     "(%d Gb) exceeds limit\n"),
   5755                                     ((pgw_oversub_bandwidth[APACHE_PGW1]) / 1000)));
   5756                 rv = SOC_E_FAIL;
   5757             }
   5758         } else if ((os_ratio[APACHE_PGW1] > def_os_ratio) && (os_ratio[APACHE_PGW1] < max_os_ratio)) {
   5759             if (os_ratio[APACHE_PGW0] > def_os_ratio) {
   5760                 LOG_CLI((BSL_META_U(unit,
   5761                                     "PGW_CL0 total oversub bandwidth "
   5762                                     "(%d Gb) exceeds limit\n"),
   5763                                     ((pgw_oversub_bandwidth[APACHE_PGW0]) / 1000)));
   5764                 rv = SOC_E_FAIL;
   5765             }
   5766         }
   5767     }
   5768 
   5769     return rv;
   5770 }
   5771 
   5772 
   5773 int
   5774 soc_apache_mmu_hsp_port_reserve(int unit, int port, int speed_max)
   5775 {
   5776     int def_freq, max_freq;
   5777     int min_hsp_ovs_speed;
   5778 
   5779     SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_freq, &def_freq));
   5780     def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq);
   5781 
   5782     switch (def_freq) {
   5783         case 841:
   5784         case 793:
   5785             min_hsp_ovs_speed = 100000;
   5786             break;
   5787         default:
   5788             min_hsp_ovs_speed = 40000;
   5789             break;
   5790 
   5791     }
   5792 
   5793     if (IS_OVERSUB_PORT(unit, port) && speed_max >= min_hsp_ovs_speed) {
   5794         return TRUE;
   5795     }
   5796 
   5797     return FALSE;
   5798 }
   5799 
   5800 /* MMU port numbers must be in following range.
   5801  * HSP ports         : [0-15]
   5802  * CT ports (40G OS) : [0-17]
   5803  * 50G/53G LR        : [0-15]
   5804  */
   5805 STATIC int
   5806 soc_apache_mmu_ports_assign(int unit)
   5807 {
   5808     int port, phy_port, mmu_port;
   5809     int port_is_hsp;
   5810     int num_phy_port = APACHE_PORTS_PER_PIPE;
   5811     soc_info_t *si;
   5812     soc_pbmp_t pbmp;
   5813 
   5814     si = &SOC_INFO(unit);
   5815 
   5816     /* Setup vector-based scheduler (VBS)
   5817      * a.k.a high speed port scheduler (HSP) pbm */
   5818     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5819         port = si->port_p2l_mapping[phy_port];
   5820         if (port == -1) {
   5821             continue;
   5822         }
   5823 
   5824         /* Usage:
   5825          *  port_sched_hsp_<log_port> = 1 ;            Port is in HSP
   5826          *  port_sched_hsp_<log_port> = 0 ;            Port is in LLS
   5827          *  port_sched_hsp_<log_port> = -1 (default) ; SDK determines sched type
   5828  */
   5829         port_is_hsp = (soc_property_port_get(unit, port, spn_PORT_SCHED_HSP, -1));
   5830         if (port_is_hsp == -1) {
   5831             port_is_hsp = soc_apache_mmu_hsp_port_reserve(unit, port, si->port_speed_max[port]);
   5832         }
   5833 
   5834         if (port_is_hsp) {
   5835             SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   5836         } else {
   5837             SOC_PBMP_PORT_REMOVE(si->eq_pbm, port);
   5838         }
   5839 	
   5840     }
   5841 
   5842 #ifdef BCM_WARM_BOOT_SUPPORT
   5843     if (SOC_WARM_BOOT(unit)) {
   5844         /* For WB we recover port mappings from scache */
   5845         return SOC_E_NONE;
   5846     }
   5847 #endif
   5848 
   5849     mmu_port = 0;
   5850 
   5851     /* First assign the lowest MMU port number for VBS (HSP) ports */
   5852     pbmp = si->xpipe_pbm;
   5853     SOC_PBMP_AND(pbmp, si->eq_pbm);
   5854     SOC_PBMP_ITER(pbmp, port) {
   5855         if ( port < _APACHE_LOG_PORTS_PER_PIPE ) {
   5856            phy_port = si->port_l2p_mapping[port];
   5857            if ( phy_port <= num_phy_port) { 
   5858                si->port_p2m_mapping[phy_port] = mmu_port;
   5859                si->port_m2p_mapping[mmu_port] = phy_port;
   5860                mmu_port++;
   5861             }
   5862         }   
   5863     }
   5864 
   5865     /* Assign MMU port for all OS ports with speed >= 100G
   5866      * 100G OS ports are HSP by default
   5867      */
   5868     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5869         if (si->port_p2m_mapping[phy_port] != -1) {
   5870             continue;
   5871         }
   5872 
   5873         port = si->port_p2l_mapping[phy_port];
   5874         if (port == -1) {
   5875             continue;
   5876         }
   5877 
   5878         if ((IS_OVERSUB_PORT(unit, port)) &&
   5879             (si->port_speed_max[port] >= 100000)) {
   5880             si->port_p2m_mapping[phy_port] = mmu_port;
   5881             si->port_m2p_mapping[mmu_port] = phy_port;
   5882             mmu_port++;
   5883         }
   5884     }
   5885 
   5886     /* Assign MMU port for all OS ports with speed = 40G/42G
   5887      * 40G OS ports support CT
   5888      */
   5889     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5890         if (si->port_p2m_mapping[phy_port] != -1) {
   5891             continue;
   5892         }
   5893 
   5894         port = si->port_p2l_mapping[phy_port];
   5895         if (port == -1) {
   5896             continue;
   5897         }
   5898 
   5899         if ((IS_OVERSUB_PORT(unit, port)) &&
   5900             (SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(si->port_speed_max[port]) == 40000 )) {
   5901             si->port_p2m_mapping[phy_port] = mmu_port;
   5902             si->port_m2p_mapping[mmu_port] = phy_port;
   5903             mmu_port++;
   5904         }
   5905     }
   5906 
   5907     /* Assign MMU port for 1st OS phy port in PM4x25
   5908      * Can become 100G(HSP) or 40G(CT) after flex
   5909      */
   5910     for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   5911         if (si->port_p2m_mapping[phy_port] != -1) {
   5912             continue;
   5913         }
   5914 
   5915         port = si->port_p2l_mapping[phy_port];
   5916         if (port == -1) {
   5917             continue;
   5918         }
   5919 
   5920         if (IS_OVERSUB_PORT(unit, port) &&
   5921             soc_apache_port_is_falcon(unit, phy_port)) {
   5922             si->port_p2m_mapping[phy_port] = mmu_port;
   5923             si->port_m2p_mapping[mmu_port] = phy_port;
   5924             mmu_port++;
   5925         }
   5926     }
   5927 
   5928     /* Assign MMU port to 1st phy port in remaining(disabled) PM4x25
   5929      * Can become 100G(HSP) or 40G(CT) or 50G(LR) after flex
   5930      */
   5931     for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   5932         if (si->port_p2m_mapping[phy_port] != -1) {
   5933             continue;
   5934         }
   5935 
   5936         if (soc_apache_port_is_falcon(unit, phy_port)) {
   5937             si->port_p2m_mapping[phy_port] = mmu_port;
   5938             si->port_m2p_mapping[mmu_port] = phy_port;
   5939             mmu_port++;
   5940         }
   5941     }
   5942 
   5943     /* Assign MMU port to 3rd OS phy port in PM4x25
   5944      * Can become 40G(CT) after flex
   5945      */
   5946     for (phy_port = 3; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   5947         if (si->port_p2m_mapping[phy_port] != -1) {
   5948             continue;
   5949         }
   5950 
   5951         port = si->port_p2l_mapping[phy_port];
   5952         if (port == -1) {
   5953             continue;
   5954         }
   5955 
   5956         if (IS_OVERSUB_PORT(unit, port) &&
   5957             soc_apache_port_is_falcon(unit, phy_port)) {
   5958             si->port_p2m_mapping[phy_port] = mmu_port;
   5959             si->port_m2p_mapping[mmu_port] = phy_port;
   5960             mmu_port++;
   5961         }
   5962     }
   5963 
   5964     /* Assign MMU port to 1st OS phy port in PM4x10
   5965      * Can become 40G(CT) after flex
   5966      */
   5967     for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   5968         if (si->port_p2m_mapping[phy_port] != -1) {
   5969             continue;
   5970         }
   5971 
   5972         port = si->port_p2l_mapping[phy_port];
   5973         if (port == -1) {
   5974             continue;
   5975         }
   5976 
   5977         if (IS_OVERSUB_PORT(unit, port)) {
   5978             si->port_p2m_mapping[phy_port] = mmu_port;
   5979             si->port_m2p_mapping[mmu_port] = phy_port;
   5980             mmu_port++;
   5981         }
   5982     }
   5983 
   5984     /* Assign MMU port to 3rd phy port in remaining(disabled) PM4x25
   5985      * Can become 40G(CT) or 50g(LR) after flex
   5986      */
   5987     for (phy_port = 3; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   5988         if (si->port_p2m_mapping[phy_port] != -1) {
   5989             continue;
   5990         }
   5991 
   5992         if (soc_apache_port_is_falcon(unit, phy_port)) {
   5993             si->port_p2m_mapping[phy_port] = mmu_port;
   5994             si->port_m2p_mapping[mmu_port] = phy_port;
   5995             mmu_port++;
   5996         }
   5997     }
   5998 
   5999     /* Assign MMU port to 1st phy port in remaining(disabled) PM4x10
   6000      * Can become 40G(CT) after flex
   6001      */
   6002     for (phy_port = 1; phy_port <= num_phy_port; phy_port += APACHE_PORTS_PER_TSC) {
   6003         if (si->port_p2m_mapping[phy_port] != -1) {
   6004             continue;
   6005         }
   6006 
   6007         si->port_p2m_mapping[phy_port] = mmu_port;
   6008         si->port_m2p_mapping[mmu_port] = phy_port;
   6009         mmu_port++;
   6010     }
   6011 
   6012     /* Assign MMU port for all remaining valid ports */
   6013     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   6014         if (si->port_p2m_mapping[phy_port] != -1) {
   6015             continue;
   6016         }
   6017 
   6018         if (si->port_p2l_mapping[phy_port] == -1) {
   6019             continue;
   6020         }
   6021 
   6022         si->port_p2m_mapping[phy_port] = mmu_port;
   6023         si->port_m2p_mapping[mmu_port] = phy_port;
   6024         mmu_port++;
   6025     }
   6026 
   6027     /* Assign MMU port for all remaining(disabled) ports */
   6028     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   6029         if (si->port_p2m_mapping[phy_port] != -1) {
   6030             continue;
   6031         }
   6032 
   6033         si->port_p2m_mapping[phy_port] = mmu_port;
   6034         si->port_m2p_mapping[mmu_port] = phy_port;
   6035         mmu_port++;
   6036     }
   6037 
   6038     return SOC_E_NONE;
   6039 }
   6040 
   6041 STATIC int
   6042 _soc_ap_ports_speed_init_update(int unit)
   6043 {
   6044     int port;
   6045     soc_info_t *si = &SOC_INFO(unit);
   6046 
   6047     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   6048         /* Set init speed to max speed by default */
   6049         /* Used during port probe and portmod attach */
   6050         si->port_init_speed[port] = si->port_speed_max[port];
   6051     }
   6052 
   6053     return SOC_E_NONE;
   6054 }
   6055 
   6056 /*
   6057  * Apache port mapping
   6058  *     130 physical ports: port 0-64 in X pipe, port 65-129 in Y pipe
   6059  *     106 logical ports
   6060  *     108 mmu ports: port 0-53 in X pipe, port 64-117 in Y pipe
   6061  *     cpu port number is fixed: physical 0, logical 0, mmu 52
   6062  *     loopback port number is fixed: physical 129, logical 105, mmu 116
   6063  *     mmu port 53 and mmu port 117 are purge port
   6064  *     mmu port can only map to physical port ID in the same pipe
   6065  *     XLPORT3 (physical port 13-16) can be configured as management port(s)
   6066  *     management port can be:
   6067  *     - one 10G port
   6068  *     - one to four ports with speed up to 2.5G each
   6069  * Physical port number in eacc port group
   6070  *     PGW_CL0: XLPORTB0_0  TSC-E 0     port 1-4
   6071  *              XLPORTB0_1  TSC-E 1     port 5-8
   6072  *              XLPORTB0_2  TSC-E 2     port 9-12
   6073  *              XLPORTB0_3  TSC-E 3     port 13-16
   6074  *              CXXPORT0    TSC-E 4-6   port 17-28
   6075  *              CLPORT0     TSC-E 4-6   port 17
   6076  *              XLPORT4     TSC-E 4     port 17-20
   6077  *              XLPORT5     TSC-E 5     port 21-24
   6078  *              XLPORT6     TSC-E 6     port 25-28
   6079  *              CLPORT1     TSC-F 0     port 29-32
   6080  *              CLPORT2     TSC-F 1     port 33-36
   6081  *
   6082  *     PGW_CL1: XLPORTB0_7  TSC-E 7     port 37-40
   6083  *              XLPORTB0_8  TSC-E 8     port 41-44
   6084  *              XLPORTB0_9  TSC-E 9     port 45-48
   6085  *              XLPORTB0_10 TSC-E 10    port 49-52
   6086  *              CXXPORT1    TSC-E 11-13 port 53-64
   6087  *              CLPORT3     TSC-E 11-13 port 53
   6088  *              XLPORT11    TSC-E 11    port 53-56
   6089  *              XLPORT12    TSC-E 12    port 57-60
   6090  *              XLPORT13    TSC-E 13    port 61-64
   6091  *              CLPORT4     TSC-F 2     port 65-68
   6092  *              CLPORT5     TSC-F 3     port 69-72
   6093  * This routine will setup:
   6094  *     SOC_INFO(unit).port_p2l_mapping[]
   6095  *     SOC_INFO(unit).port_l2p_mapping[]
   6096  *     SOC_INFO(unit).port_p2m_mapping[]
   6097  *     SOC_INFO(unit).port_m2p_mapping[]
   6098  *     SOC_INFO(unit).port_speed_max[]
   6099  *     SOC_INFO(unit).port_group[]
   6100  *     SOC_INFO(unit).port_serdes[]
   6101  *     SOC_INFO(unit).port_num_lanes[]
   6102  *     SOC_INFO(unit).phy_port_base[]
   6103  *     SOC_INFO(unit).mmu_port_base[]
   6104  * 100+G port:
   6105  *     - can only be @ 760MHz
   6106  *     - needs to be HSP
   6107  *     - cannot be in oversubscribe mode
   6108  * 40/42G port:
   6109  *     - needs to be HSP except @ 760MHz
   6110  *     - oversubscribe mode can support both cut-through and store-and-forward
   6111  * sub-40G port:
   6112  *     - oversubscribe mode can only support store-and-forward
   6113  */
   6114 int
   6115 soc_apache_port_config_init(int unit, uint16 dev_id, uint8 rev_id)
   6116 {
   6117     char *config_str, *sub_str, *sub_str_end;
   6118     static const char str_2p5[] = "2.5";
   6119     char str_buf[8];
   6120     soc_info_t *si;
   6121     int i, rv;
   6122     int num_port, num_phy_port;
   6123     int port, phy_port;
   6124     int port_bandwidth, port_active_lanes;
   6125     int def_freq, max_freq;
   6126     soc_100g_lane_config_t lane_config = SOC_LANE_CONFIG_100G_DEFAULT;
   6127     int fallback_core = SOC_LANE_CONFIG_100G_DEFAULT;
   6128     int index, tsc_id;
   6129     char option_inactive, option_lanes;
   6130     int port_count;
   6131     int oversub_mode = 0;
   6132     soc_pbmp_t oversub_pbm;
   6133     soc_pbmp_t xe_pbmp;
   6134     uint32 tsc_map, force_hg;
   6135     int freq_list_len;
   6136     int const *freq_list;
   6137     static const int apache_freq_list[] = { 841, 793, 575, 510, 435 };
   6138     int int_ports[3][3] = {
   6139                          /* {log, phy, mmu} */
   6140                             {0,   0,   72}, /* CPU */
   6141                             {73,  73,  73}, /* LB */
   6142                             {74,  74,  74}, /* RDB */
   6143         };
   6144 
   6145     SOC_PBMP_CLEAR(xe_pbmp);
   6146     SOC_PBMP_CLEAR(oversub_pbm);
   6147     xe_pbmp = soc_property_get_pbmp_default(unit,
   6148                                             spn_PBMP_XPORT_XE, xe_pbmp);
   6149     si = &SOC_INFO(unit);
   6150 
   6151     {
   6152         num_port = 72;
   6153         num_phy_port = 72;
   6154     }
   6155 
   6156     SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_freq, &def_freq));
   6157     def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq);
   6158     if (def_freq <= max_freq) {
   6159         freq_list = apache_freq_list;
   6160         freq_list_len = sizeof(apache_freq_list) / sizeof(int);
   6161         for (index = 0; index < freq_list_len; index++) {
   6162             if (def_freq == freq_list[index]) {
   6163                 break;
   6164             }
   6165         }
   6166 
   6167         if (index < freq_list_len) {
   6168             si->frequency = def_freq;
   6169         } else {
   6170             LOG_CLI((BSL_META_U(unit,
   6171                        "*** Input core clock frequency %dMHz is not "
   6172                        "supported!\n"), def_freq));
   6173         }
   6174     }
   6175     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6176                     (BSL_META_U(unit, "Running core clock frequency %dMhz\n"), def_freq));
   6177 
   6178     /* Setup max I/O and core bandwidth */
   6179     switch (si->frequency) {
   6180     case 841:
   6181         si->io_bandwidth = 880000;
   6182         si->bandwidth = 567000;
   6183         break;
   6184     case 793:
   6185         si->io_bandwidth = 720000;
   6186         si->bandwidth = 480000;
   6187         break;
   6188     case 575:
   6189         /* LR Only */
   6190         si->io_bandwidth = 340000;
   6191         si->bandwidth = 340000;
   6192         break;
   6193     case 435:
   6194         /* LR Only */
   6195         si->io_bandwidth = 260000;
   6196         si->bandwidth = 260000;
   6197         break;
   6198     case 510:
   6199         /* si->bandwidth = 260000; */
   6200         LOG_CLI((BSL_META_U(unit,
   6201                        "*** Input core clock frequency %dMHz is not yet "
   6202                        "supported!\n"), si->frequency));
   6203         return SOC_E_INTERNAL; /* unknown frequency */
   6204     default:
   6205         si->io_bandwidth = 720000;
   6206         si->bandwidth = 480000;
   6207         break;
   6208     }
   6209 
   6210 
   6211     si->oversub_mode = oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
   6212     if (oversub_mode == 2) {
   6213         oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0);
   6214     }
   6215 
   6216     SOC_IF_ERROR_RETURN(soc_apache_tsc_map_get(unit, &tsc_map, &force_hg));
   6217 
   6218     /* Initialize the soc_info params */
   6219     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   6220         si->port_l2p_mapping[port] = -1;
   6221         si->port_speed_max[port] = -1;
   6222         si->port_group[port] = -1;
   6223         si->port_serdes[port] = -1;
   6224         si->port_num_lanes[port] = -1;
   6225 
   6226         /* Indexed by physical port */
   6227         si->port_p2l_mapping[port] = -1;
   6228         si->port_p2m_mapping[port] = -1;
   6229 
   6230         /* Indexed by mmu port */
   6231         si->port_m2p_mapping[port] = -1;
   6232     }
   6233 
   6234 
   6235 
   6236     for (index = 0; index < COUNTOF(int_ports); index++) {
   6237         /* int_ports is an array of log, phy & mmu ports in that order */
   6238         si->port_p2l_mapping[int_ports[index][1]] = int_ports[index][0];
   6239         si->port_p2m_mapping[int_ports[index][1]] = int_ports[index][2];
   6240 
   6241         SOC_PBMP_PORT_SET(si->xpipe_pbm, int_ports[index][0]);
   6242     }
   6243 
   6244 
   6245     SOC_PBMP_CLEAR(si->oversub_pbm);
   6246     SOC_PBMP_CLEAR(si->management_pbm);
   6247     SOC_PBMP_CLEAR(si->all.disabled_bitmap);
   6248 
   6249     si->phy_port_base[0] = 1;               /* First physical port */
   6250     si->mmu_port_base[0] = 0;               /* First mmu port */
   6251     port_count = 0;
   6252 
   6253     rv = SOC_E_NONE;
   6254     for (port = 0; port <= num_port; port++) {
   6255 
   6256         config_str = soc_property_port_get_str(unit, port, spn_PORTMAP);
   6257         if (config_str == NULL) {
   6258             continue;
   6259         }
   6260 
   6261 	/*
   6262 	 * portmap.<port>=<physical port number>:<bandwidth in Gb>:[<num_lanes>]:[i]
   6263 	 */
   6264         sub_str = config_str;
   6265 
   6266         /* Parse physical port number */
   6267         phy_port = sal_ctoi(sub_str, &sub_str_end);
   6268         if (sub_str == sub_str_end) {
   6269             LOG_CLI((BSL_META_U(unit,
   6270                        "Port %d: Missing physical port information \"%s\"\n"),
   6271                        port, config_str));
   6272             rv = SOC_E_FAIL;
   6273             continue;
   6274         }
   6275 
   6276         /* phy_port valid range [1..72] */
   6277         if (phy_port < 1 || phy_port > num_phy_port) {
   6278             LOG_CLI((BSL_META_U(unit,
   6279                        "Port %d: Invalid physical port number %d\n"),
   6280                        port, phy_port));
   6281             rv = SOC_E_FAIL;
   6282             continue;
   6283         }
   6284 
   6285         tsc_id = (phy_port - 1) / APACHE_PORTS_PER_TSC;
   6286         if (!(tsc_map & (1 << tsc_id))) {
   6287             LOG_CLI((BSL_META_U(unit,
   6288                        "Port %d: Physical port %d is in disabled TSC %d\n"),
   6289                        port, phy_port, tsc_id));
   6290             rv = SOC_E_FAIL;
   6291             continue;
   6292         }
   6293 
   6294         if ((force_hg & (1 << tsc_id)) &&
   6295             (SOC_PBMP_MEMBER(xe_pbmp, port))) {
   6296             LOG_CLI((BSL_META_U(unit,
   6297                        "Port %d: non-hg port in TSC(%d) which is hg-only\n"),
   6298                        port, tsc_id));
   6299             rv = SOC_E_FAIL;
   6300             continue;
   6301         }
   6302 
   6303         if (si->port_p2l_mapping[phy_port] != -1) {
   6304             LOG_CLI((BSL_META_U(unit,
   6305                        "Port %d: Physical port %d is used by port %d\n"),
   6306                        port, phy_port, si->port_p2l_mapping[phy_port]));
   6307             rv = SOC_E_FAIL;
   6308             continue;
   6309         }
   6310 
   6311         if (port_count > num_port) {
   6312             LOG_CLI((BSL_META_U(unit,
   6313                        "Can not configure more than %d port\n"), num_port));
   6314             rv = SOC_E_FAIL;
   6315             continue;
   6316         }
   6317 
   6318         /* Skip ':' between physical port number and bandwidth */
   6319         sub_str = sub_str_end;
   6320         if (*sub_str != '\0') {
   6321             if (*sub_str != ':') {
   6322                 LOG_CLI((BSL_META_U(unit,
   6323                                     "Port %d: Bad config string \"%s\"\n"),
   6324                          port, config_str));
   6325                 rv = SOC_E_FAIL;
   6326                 continue;
   6327             }
   6328             sub_str++;
   6329         }
   6330 
   6331         /* Parse bandwidth - special case 2.5G */
   6332         for (index = 0; index < sizeof(str_2p5) - 1; index++) {
   6333             if (sub_str[index] == '\0') {
   6334                 break;
   6335             }
   6336             str_buf[index] = sub_str[index];
   6337         }
   6338         str_buf[index] = '\0';
   6339 
   6340         if (!sal_strcmp(str_buf, str_2p5)) {
   6341             port_bandwidth = 2500;
   6342             sub_str_end = &sub_str[sizeof(str_2p5) - 1];
   6343         } else {
   6344             port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000;
   6345             if (sub_str == sub_str_end) {
   6346                 LOG_CLI((BSL_META_U(unit,
   6347                                     "Port %d: Missing bandwidth "
   6348                                     "information \"%s\"\n"),
   6349                          port, config_str));
   6350                 rv = SOC_E_FAIL;
   6351                 continue;
   6352             }
   6353         }
   6354 
   6355         /* Check if option presents */
   6356         option_inactive = option_lanes = 0;
   6357         sub_str = sub_str_end;
   6358         if (*sub_str != '\0') {
   6359             /* Skip ':' between bandwidth and options */
   6360             if (*sub_str != ':') {
   6361                 LOG_CLI((BSL_META_U(unit,
   6362                                     "Port %d: Bad config string \"%s\"\n"),
   6363                            port, config_str));
   6364                 rv = SOC_E_FAIL;
   6365                 continue;
   6366             }
   6367             sub_str++;
   6368 
   6369             /* Read 100G lane configuration if present.
   6370              * Skip if options are present */
   6371             if (*sub_str != '\0') {
   6372                 if (*sub_str == 'i') {
   6373                     option_inactive = *sub_str;
   6374                     sub_str++;
   6375                 } else if ((port_bandwidth >= 100000) &&
   6376                            ((phy_port == 17) || (phy_port == 53))) {
   6377 
   6378                     for (index = 0; index < 3; index++) {
   6379                         if (sub_str[index] == '\0') {
   6380                             break;
   6381                         }
   6382                         str_buf[index] = sub_str[index];
   6383                     }
   6384                     str_buf[index] = '\0';
   6385                     if (!sal_strcmp(str_buf, "442")) {
   6386                         lane_config = SOC_LANE_CONFIG_100G_4_4_2;
   6387                     } else if (!sal_strcmp(str_buf, "244")) {
   6388                         lane_config = SOC_LANE_CONFIG_100G_2_4_4;
   6389                     } else if (!sal_strcmp(str_buf, "343")) {
   6390                         lane_config = SOC_LANE_CONFIG_100G_3_4_3;
   6391                     } else {
   6392                         LOG_ERROR(BSL_LS_SOC_PORT,
   6393                                   (BSL_META_U(unit, "Port %d: "
   6394                                               "Bad config string \"%s\"\n"),
   6395                                               port, str_buf));
   6396                         rv = SOC_E_FAIL;
   6397                         continue;
   6398                     }
   6399                     sub_str_end = &sub_str[3]; /*Advance */
   6400 
   6401                     /* Skip ':' between 100G lane config and 100G fallback port */
   6402                     sub_str = sub_str_end;
   6403                     if (*sub_str != '\0') {
   6404                         if (*sub_str != ':') {
   6405                             LOG_ERROR(BSL_LS_SOC_PORT,
   6406                                       (BSL_META_U(unit, "Port %d: "
   6407                                                   "Bad config string \"%s\"\n"),
   6408                                                   port, config_str));
   6409                             rv = SOC_E_FAIL;
   6410                             continue;
   6411                         }
   6412                         sub_str_end++;
   6413                     }
   6414 
   6415                     sub_str = sub_str_end;
   6416                     /* Gather the desired fallback TSC for 100G auto-negotiation */
   6417                     fallback_core = SOC_LANE_CONFIG_100G_AN_CORE_DEFAULT;
   6418                     if (*sub_str != '\0') {
   6419                         fallback_core = sal_ctoi(sub_str, &sub_str_end);
   6420                         if (fallback_core > 2 || fallback_core < 0) {
   6421                             LOG_ERROR(BSL_LS_SOC_PORT,
   6422                                       (BSL_META_U(unit, "Port %d: "
   6423                                                   "Invalid default core \"%d\"\n"),
   6424                                                   port, fallback_core));
   6425                             rv = SOC_E_FAIL;
   6426                             continue;
   6427                         } else {
   6428                             /* Validate that for a given lane configuration
   6429                              * the selected fallback core is valid. */
   6430                             for (i = 0; soc_apache_valid_an_cores[i].lane_config != SOC_INVALID_LANE_CONFIG; i++) {
   6431                                 if (soc_apache_valid_an_cores[i].lane_config == lane_config) {
   6432                                     if (!soc_apache_valid_an_cores[i].valid_lanes[fallback_core]) {
   6433                                         fallback_core = -1;
   6434                                         break;
   6435                                     }
   6436                                 }
   6437                             }
   6438                         }
   6439 
   6440                         if (fallback_core < 0) {
   6441                             LOG_ERROR(BSL_LS_SOC_PORT,
   6442                                       (BSL_META_U(unit, "Port %d: "
   6443                                                   "Invalid default lane \"%d\"\n"),
   6444                                                   port, fallback_core));
   6445                             rv = SOC_E_FAIL;
   6446                             continue;
   6447                         }
   6448                     }
   6449                 } else if ((*sub_str == '1') ||
   6450                            (*sub_str == '2') ||
   6451                            (*sub_str == '4')) {
   6452                     option_lanes = *sub_str;
   6453                     sub_str++;
   6454 
   6455                     if (*sub_str != '\0') {
   6456                         if (*sub_str != 'i') {
   6457                             LOG_CLI((BSL_META_U(unit,
   6458                                        "Port %d: Bad config string \"%s\"\n"),
   6459                                        port, config_str));
   6460                             rv = SOC_E_FAIL;
   6461                             continue;
   6462                         }
   6463                         option_inactive = *sub_str;
   6464                         sub_str++;
   6465                     }
   6466                 } else {
   6467                     LOG_CLI((BSL_META_U(unit,
   6468                                "Port %d: Bad config string \"%s\"\n"),
   6469                                port, config_str));
   6470                     rv = SOC_E_FAIL;
   6471                     continue;
   6472                 }
   6473             }
   6474         }
   6475 
   6476         /* Check trailing string */
   6477         if (*sub_str != '\0') {
   6478             LOG_CLI((BSL_META_U(unit,
   6479                        "Port %d: Bad config string \"%s\"\n"),
   6480                        port, config_str));
   6481             rv = SOC_E_FAIL;
   6482             continue;
   6483         }
   6484 
   6485         /*
   6486          * Use new properties for 100GE mode lane and
   6487          * fallback autoneg core if these are specified.
   6488          */
   6489         if ((port_bandwidth >= 100000) && ((phy_port == 17) || (phy_port == 53))) {
   6490             int an_core, mode_lane, found = 0;
   6491 
   6492             if (SOC_SUCCESS(soc_apache_port_lane_config_get(unit,
   6493                                                             phy_port,
   6494                                                             &mode_lane,
   6495                                                             &found))) {
   6496                 if (found) {
   6497                     lane_config = mode_lane;
   6498                 }
   6499             }
   6500             if (SOC_SUCCESS(soc_apache_port_autoneg_core_get(unit,
   6501                                                              phy_port,
   6502                                                              &an_core,
   6503                                                              &found))) {
   6504                 if (found) {
   6505                     fallback_core = an_core;
   6506                 }
   6507             }
   6508 
   6509         }
   6510         switch (option_lanes) {
   6511             case '1': port_active_lanes = 1; break;
   6512             case '2': port_active_lanes = 2; break;
   6513             case '4': port_active_lanes = 4; break;
   6514             default :
   6515                 if (SOC_FAILURE(_soc_apache_port_lanes_set(unit, phy_port,
   6516                                                            &port_active_lanes,
   6517                                                            port_bandwidth))) {
   6518                     rv = SOC_E_FAIL;
   6519                 }
   6520                 break;
   6521         }
   6522         if (option_inactive == 'i') {
   6523             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
   6524             port_active_lanes = -1;
   6525         }
   6526 
   6527         /* PORT bandwidth checks  */
   6528         if ((soc_apache_port_is_2p5g_forced(unit, phy_port)) &&
   6529             (port_bandwidth > 2500)) {
   6530             rv = SOC_E_FAIL;
   6531             LOG_CLI((BSL_META_U(unit,
   6532                                 "Port %d: Invalid bandwidth %d Gb\n"
   6533                                 "Max bandwidth supported is 2.5G\n"),
   6534                      port, port_bandwidth / 1000));
   6535 
   6536             continue;
   6537         }
   6538 
   6539         if (!_soc_apache_port_speed_supported(unit, port, phy_port,
   6540                                               port_active_lanes, port_bandwidth)) {
   6541             rv = SOC_E_FAIL;
   6542             continue;
   6543         }
   6544 
   6545 
   6546         /* Update soc_info */
   6547         si->port_p2l_mapping[phy_port] = port;
   6548         si->port_l2p_mapping[port] = phy_port;
   6549         si->port_speed_max[port] = port_bandwidth;
   6550         si->port_100g_lane_config[port] = lane_config;
   6551         si->port_fallback_lane[port]    = fallback_core;
   6552         si->port_num_lanes[port] = port_active_lanes;
   6553 
   6554         if (SOC_PBMP_MEMBER(oversub_pbm,port) || (oversub_mode == 1)) {
   6555             SOC_PBMP_PORT_ADD(si->oversub_pbm, port);
   6556         }
   6557 
   6558         port_count++;
   6559     }
   6560 
   6561     /*
   6562      * Earlier SDK was restricting the mixed mode (LR + OS) to only FB5 SKUs and
   6563      * the Maverick/Ranger2+ are expected to run either LR-only or OS-only port configs. 
   6564      * With the new port configs supported by SDK, this is no longer true. 
   6565      * We have a few configs in FB5 which are all OS and a few configs on 
   6566      * Maverick which have a mix of LR and OS ports. These checks are hence removed.
   6567      */
   6568 
   6569     /* Legacy Flex config ":i" case detected, disabled ports in config */
   6570     if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all))) {
   6571         si->flex_eligible = TRUE;
   6572     }
   6573 
   6574     if (port_count == 0) {
   6575 #ifdef __KERNEL__
   6576         /* config.bcm is not parsed yet at the time 1st call of soc_attach
   6577            in Kernel mode SDK. Shouldn't return error code. */
   6578         return SOC_E_NONE;
   6579 #else
   6580         if (SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) { /* not for PCID */
   6581             rv = SOC_E_FAIL;
   6582         }
   6583 #endif
   6584     }
   6585     
   6586     /* Bandwidth check for ports in each XLPORT/CLPORT block */
   6587     if (SOC_SUCCESS(rv)) {
   6588         rv = soc_apache_port_config_bandwidth_check(unit);
   6589     }
   6590 
   6591     if (SOC_FAILURE(rv)) {
   6592         for (phy_port = 1; phy_port < 72; phy_port++) {
   6593             si->port_p2l_mapping[phy_port] = -1;
   6594         }
   6595         return rv;
   6596     }
   6597 
   6598     /* Setup port_group, num_lanes, xpipe_pbm */
   6599     for (port = 0; port <= num_port; port++) {
   6600         phy_port = si->port_l2p_mapping[port];
   6601         if (phy_port == -1) { /* unused port */
   6602             continue;
   6603         }
   6604         /* 26 ports per PGW_CL */
   6605         si->port_group[port] = (phy_port - 1) / APACHE_PORTS_PER_PGW;
   6606         si->port_serdes[port] = (phy_port - 1) / APACHE_PORTS_PER_TSC;
   6607 
   6608         SOC_PBMP_PORT_ADD(si->xpipe_pbm, port);
   6609     }
   6610     SOC_PBMP_ASSIGN(si->pipe_pbm[0], si->xpipe_pbm);
   6611 
   6612 #ifdef BCM_WARM_BOOT_SUPPORT
   6613     if (SOC_WARM_BOOT(unit)) {
   6614         rv = soc_apache_flexport_scache_recovery(unit);
   6615         if (SOC_FAILURE(rv)) {
   6616             if (rv == SOC_E_NOT_FOUND) {
   6617                 rv = SOC_E_NONE;
   6618             } else {
   6619                 return rv;
   6620             }
   6621         }
   6622     } else {
   6623         /* Cold boot create */
   6624         SOC_IF_ERROR_RETURN(soc_apache_flexport_scache_allocate(unit));
   6625     }
   6626 #endif /* BCM_WARM_BOOT_SUPPORT */
   6627 
   6628     /* Assign mmu ports for all active and inactive ports */
   6629     SOC_IF_ERROR_RETURN(soc_apache_mmu_ports_assign(unit));
   6630 
   6631     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   6632         LOG_CLI((BSL_META_U(unit, "physical to logical mapping:")));
   6633         for (index = 0; index < num_phy_port; index++) {
   6634             if (index % 16 == 0) {
   6635                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6636             }
   6637             LOG_CLI((BSL_META_U(unit, " %3d"),
   6638                        si->port_p2l_mapping[index]));
   6639         }
   6640         LOG_CLI((BSL_META_U(unit, "\n")));
   6641         LOG_CLI((BSL_META_U(unit, "physical port bandwidth:")));
   6642         for (index = 0; index < num_phy_port; index++) {
   6643             if (index % 16 == 0) {
   6644                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6645             }
   6646             port = si->port_p2l_mapping[index];
   6647             if (port == -1) {
   6648                 LOG_CLI((BSL_META_U(unit, "  -1")));
   6649             } else if (si->port_speed_max[port] == 2500) {
   6650                 LOG_CLI((BSL_META_U(unit, " 2.5")));
   6651             } else {
   6652                 LOG_CLI((BSL_META_U(unit, " %3d"),
   6653                            si->port_speed_max[port] / 1000));
   6654             }
   6655         }
   6656         LOG_CLI((BSL_META_U(unit, "\n")));
   6657         LOG_CLI((BSL_META_U(unit, "physical to mmu mapping:")));
   6658         for (index = 0; index < num_phy_port; index++) {
   6659             if (index % 16 == 0) {
   6660                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6661             }
   6662             LOG_CLI((BSL_META_U(unit, " %3d"),
   6663                        si->port_p2m_mapping[index]));
   6664         }
   6665         LOG_CLI((BSL_META_U(unit, "\n")));
   6666     }
   6667 
   6668     SOC_IF_ERROR_RETURN(soc_ap_phy_info_init(unit));
   6669     /*  update port_init_speed array for all ports */
   6670     SOC_IF_ERROR_RETURN(_soc_ap_ports_speed_init_update(unit));
   6671     SOC_IF_ERROR_RETURN(soc_ap_port_ovs_speed_group_validate(unit));
   6672     SOC_IF_ERROR_RETURN(soc_ap_port_mixed_sister_speed_validate(unit));
   6673 
   6674     return SOC_E_NONE;
   6675 }
   6676 
   6677 soc_error_t
   6678 soc_apache_port_reg_blk_index_get(int unit, int port, soc_block_type_t blktype, int *block)
   6679 {
   6680     uint16 dev_id;
   6681     uint8  rev_id;
   6682     int phy_port;
   6683 
   6684     soc_cm_get_id(unit, &dev_id, &rev_id);
   6685     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   6686 
   6687     switch (blktype) {
   6688         case SOC_BLK_CLG2PORT:
   6689         case SOC_BLK_CLPORT:
   6690             if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit, port)) {
   6691                 if (phy_port == 17) {
   6692                     *block = (rev_id == BCM56560_A0_REV_ID ? 11 : 7);
   6693                 } else if (phy_port == 53) {
   6694                     *block = (rev_id == BCM56560_A0_REV_ID ? 14 : 8);
   6695                 } else {
   6696                     return SOC_E_PARAM;
   6697                 }
   6698             }
   6699             break;
   6700         case SOC_BLK_CXXPORT:
   6701             if ((phy_port >= 17) && (phy_port <= 28)) {
   6702                 *block = (rev_id == BCM56560_A0_REV_ID ? 18 : 10);
   6703             } else if ((phy_port >= 53) && (phy_port <= 64)) {
   6704                 *block = (rev_id == BCM56560_A0_REV_ID ? 19 : 11);
   6705             } else {
   6706                 return SOC_E_PARAM;
   6707             }
   6708             break;
   6709         default:
   6710             break;
   6711     }
   6712     return SOC_E_NONE;
   6713 }
   6714 
   6715 int
   6716 soc_apache_lls_bmap_alloc(int unit)
   6717 {
   6718     soc_control_t *soc;
   6719     int port;
   6720     int alloc_size_s1, alloc_size_l0, alloc_size_l1, alloc_size_l2;
   6721 
   6722     soc = SOC_CONTROL(unit);
   6723 
   6724     alloc_size_s1 =
   6725         SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_S1_PARENTm));
   6726     alloc_size_l0 =
   6727         SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L0_PARENTm));
   6728     alloc_size_l1 =
   6729         SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L1_PARENTm));
   6730     alloc_size_l2 =
   6731         SHR_BITALLOCSIZE(soc_mem_index_count(unit, LLS_L2_PARENTm));
   6732 
   6733     for (port = 0; port < APACHE_PORTS_PER_PIPE + 2; port++) {
   6734         soc->port_lls_s1_bmap[port] = sal_alloc(alloc_size_s1, "LLS_S1_BMAP");
   6735         if (soc->port_lls_s1_bmap[port] == NULL) {
   6736             return SOC_E_MEMORY;
   6737         }
   6738         soc->port_lls_l0_bmap[port] = sal_alloc(alloc_size_l0, "LLS_L0_BMAP");
   6739         if (soc->port_lls_l0_bmap[port] == NULL) {
   6740             return SOC_E_MEMORY;
   6741         }
   6742 
   6743         soc->port_lls_l1_bmap[port] = sal_alloc(alloc_size_l1, "LLS_L1_BMAP");
   6744         if (soc->port_lls_l1_bmap[port] == NULL) {
   6745             return SOC_E_MEMORY;
   6746         }
   6747         soc->port_lls_l2_bmap[port] = sal_alloc(alloc_size_l2, "LLS_L2_BMAP");
   6748         if (soc->port_lls_l2_bmap[port] == NULL) {
   6749             return SOC_E_MEMORY;
   6750         }
   6751         sal_memset(soc->port_lls_s1_bmap[port], 0, alloc_size_s1);
   6752         sal_memset(soc->port_lls_l0_bmap[port], 0, alloc_size_l0);
   6753         sal_memset(soc->port_lls_l1_bmap[port], 0, alloc_size_l1);
   6754         sal_memset(soc->port_lls_l2_bmap[port], 0, alloc_size_l2);
   6755     }
   6756 
   6757     return SOC_E_NONE;
   6758 }
   6759 
   6760 #define _SOC_AP_DEF_TEMP_MAX   130
   6761 
   6762 static uint32 _soc_ap_temp_mon_mask[SOC_MAX_NUM_DEVICES];
   6763 
   6764 
   6765 /*
   6766  * Function: soc_apache_tsc_disable
   6767  *
   6768  * Purpose:
   6769  *     Function to enable/disable used/unused TSCs in the chip.
   6770  */
   6771 int
   6772 soc_apache_tsc_disable(int unit)
   6773 {
   6774     soc_info_t *si = &SOC_INFO(unit);
   6775     uint32 tsc_enable = 0;
   6776     int lane, phy_port, tsc, port;
   6777 
   6778     for (phy_port = 1;
   6779          phy_port <= APACHE_PORTS_PER_PIPE;
   6780          phy_port = (phy_port + APACHE_PORTS_PER_TSC)) {
   6781 
   6782         tsc = (phy_port - 1) / APACHE_PORTS_PER_TSC;
   6783         for (lane = 0; lane < APACHE_PORTS_PER_TSC; lane++) {
   6784             port = si->port_p2l_mapping[phy_port + lane];
   6785             if (port != -1) {
   6786                 tsc_enable |= (1 << tsc);
   6787                 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit,port)) {
   6788                     tsc_enable |= (1 << (tsc + 1));
   6789                     tsc_enable |= (1 << (tsc + 2));
   6790                 }
   6791                 break;
   6792             }
   6793         }
   6794     }
   6795 
   6796     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, TOP_TSC_ENABLEr,
   6797                                       REG_PORT_ANY, 0, tsc_enable));
   6798 
   6799     return SOC_E_NONE;
   6800 }
   6801 
   6802 
   6803 void
   6804 soc_apache_sbus_ring_map_config(int unit)
   6805 {
   6806     uint16              dev_id;
   6807     uint8               rev_id;
   6808 
   6809     /*
   6810      *  SBUS Ring # Start   Through Blocks                                                      End
   6811      *      0       CMIC    IP                                                                  CMIC
   6812      *      1       CMIC    EP                                                                  CMIC
   6813      *      2       CMIC    MMU                                                                 CMIC
   6814      *      3       CMIC    TSC0 - TSC1 - TSC2 - TSC3 - PGW0 - TSC4_5_6 - TSC7 - TSC8           CMIC
   6815      *      4       CMIC    TSC9 - TSC10 - TSC11 - TSC12 - PGW1 - TSC13_14_15 - TSC16 - TSC17   CMIC
   6816      *      5       CMIC    TOP REGISTERS - OTPC - AVS - SER                                    CMIC
   6817      *      6       CMIC    RDB                                                                 CMIC
   6818      *      7       CMIC    Not used                                                            CMIC
   6819      */
   6820 
   6821     WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x43052100);
   6822     WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x33333333);
   6823     WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x44444333);
   6824     WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x50444444);
   6825     WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x00060555);
   6826     WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x00000000);
   6827     WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0x00000000);
   6828     WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00000000);
   6829 
   6830 
   6831     soc_cm_get_id(unit, &dev_id, &rev_id);
   6832 
   6833     if (rev_id == BCM56560_A0_REV_ID) {
   6834         WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x1000);
   6835     } else {
   6836         WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x7d0);
   6837     }
   6838 
   6839     return;
   6840 }
   6841 
   6842 
   6843 /* OVST toggle data */
   6844 static uint32 ovst_write_data[] = {
   6845     0x3fffff40, 0xbffffbfe, 0x31fc9e80, 0xbffffbfe,
   6846     0x40000000, 0x44000000, 0x40000000, 0x40000000,
   6847     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6848     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6849     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6850     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6851     0x40000000, 0x40000000, 0x40000000, 0x80000300,
   6852     0x31fc9e80, 0xbffffbfe, 0x40000000, 0x44000000,
   6853     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6854     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6855     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6856     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6857     0x40000000, 0x42000000, 0x40000000, 0x40000000,
   6858     0x40000000, 0x80000300, 0x31fc9e80, 0xbffffbfe,
   6859     0x40000000, 0x44000000, 0x40000000, 0x40000000,
   6860     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6861     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6862     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6863     0x40000000, 0x40000000, 0x40000000, 0x40000000,
   6864     0x40000000, 0x40000000, 0x40000000, 0x80000300
   6865 };
   6866 
   6867 
   6868 /*
   6869  * Function:
   6870  *      apache_ovstb_toggle
   6871  * Purpose:
   6872  *      Execute the OVST sequence for Apache devces
   6873  * Parameters:
   6874  *      unit - StrataSwitch unit #
   6875 */
   6876 STATIC void
   6877 apache_ovstb_toggle(int unit)
   6878 {
   6879     int ix;
   6880     int array_length;
   6881     uint32 read_data = 0;
   6882 
   6883     /* OVST toggle sequence needs to be run only for Apache A0/B0 parts */
   6884     if (!soc_feature(unit, soc_feature_apache_ovst_toggle)) {
   6885         return;
   6886     }
   6887 
   6888     array_length = sizeof(ovst_write_data) / sizeof(uint32);
   6889 
   6890     /* Enable UC_TAP write */
   6891     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e);
   6892     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e);
   6893     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f);
   6894     READ_TOP_UC_TAP_CONTROLr(unit, &read_data);
   6895 
   6896     /* OVST toggle write data */
   6897     for (ix = 0; ix < array_length; ix++) {
   6898         WRITE_TOP_UC_TAP_WRITE_DATAr(unit, ovst_write_data[ix]);
   6899         WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f);
   6900 
   6901         READ_TOP_UC_TAP_READ_DATAr(unit, &read_data);
   6902         /*
   6903          * Hardware requires about 4us spacing between two SBUS writes.
   6904          * A single shift instruction requires a data write of 54 bits that is
   6905          * split into two sbus writes. Using uninterruptible sleep.
   6906          */
   6907         sal_udelay(4);
   6908     }
   6909 
   6910     /* Disable UC_TAP write */
   6911     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2f);
   6912     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2e);
   6913     WRITE_TOP_UC_TAP_CONTROLr(unit, 0x2c);
   6914 
   6915     return;
   6916 }
   6917 
   6918 
   6919 
   6920 
   6921 int
   6922 soc_apache_chip_reset(int unit)
   6923 {
   6924     soc_info_t *si;
   6925     uint16 dev_id;
   6926     uint8 rev_id;
   6927     int max_frequency, def_freq;
   6928     uint32 rval, to_usec;
   6929     soc_reg_t reg;
   6930     int index;
   6931     int shared_bank_offset = 0;
   6932     int num_shared_l2_banks, num_shared_l3_banks, num_banks;
   6933     int shared_bank;
   6934     uint32 config = 0, map = 0;
   6935     int num_ecmp_rh_flowset_entries;
   6936     int rh_table_config_encoding;
   6937 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   6938     int num_overlay_ecmp_rh_flowset_entries;
   6939     int rh_bank_sel = 0x0;
   6940     int ecmp_levels = 1;
   6941 #endif
   6942     static soc_field_t l2_fields[] = {
   6943         L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f,
   6944         L2_ENTRY_BANK_5f
   6945     };
   6946     static soc_field_t l3_fields[] = {
   6947         L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f,
   6948         L3_ENTRY_BANK_7f
   6949     };
   6950 
   6951     int temp_mask, temp_thr;
   6952     static const soc_reg_t temp_thr_reg[] = {
   6953         TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr,
   6954         TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr,
   6955         TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr,
   6956         TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr
   6957     };
   6958     static const char *temp_thr_prop[] = {
   6959         "temp0_threshold", "temp1_threshold", "temp2_threshold",
   6960         "temp3_threshold", "temp4_threshold", "temp5_threshold",
   6961         "temp6_threshold", "temp7_threshold"
   6962     };
   6963     int freq_list_len, sel;
   6964     int const *freq_list;
   6965     static const int apache_freq_list[] = { 841, 793, 575, 510, 435 };
   6966 
   6967 #if 0 
   6968     static const soc_reg_t lcpll_ctrl1_reg[] = {
   6969         TOP_XG_PLL0_CTRL_1r, TOP_XG_PLL1_CTRL_1r,
   6970         TOP_XG_PLL2_CTRL_1r, TOP_XG_PLL3_CTRL_1r,
   6971     };
   6972     static const soc_reg_t lcpll_ctrl3_reg[] = {
   6973         TOP_XG_PLL0_CTRL_3r, TOP_XG_PLL1_CTRL_3r,
   6974         TOP_XG_PLL2_CTRL_3r, TOP_XG_PLL3_CTRL_3r
   6975     };
   6976     static const soc_reg_t lcpll_ctrl4_reg[] = {
   6977         TOP_XG_PLL0_CTRL_4r, TOP_XG_PLL1_CTRL_4r,
   6978         TOP_XG_PLL2_CTRL_4r, TOP_XG_PLL3_CTRL_4r
   6979     };
   6980 #endif
   6981     static const soc_reg_t lcpll_status_reg[] = {
   6982         TOP_XG_PLL0_STATUSr, TOP_XG_PLL1_STATUSr,
   6983         TOP_XG_PLL2_STATUSr, TOP_XG_PLL3_STATUSr
   6984     };
   6985 
   6986     /* Settings for 500 MHz TSPLL output clock. */
   6987     unsigned ts_ref_freq = 0;
   6988     unsigned ts_idx = 0;
   6989 
   6990     static const soc_pll_param_t ts_pll[] = {
   6991     /*     Fref, Ndiv_int, Ndiv_frac,  Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */
   6992       {12800000,      273,   0x70000,     1,    7,  0,  2,  3,        1}, /* Ndiv = 273.4375 */
   6993       {20000000,      175,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 175.0 */
   6994       {25000000,      140,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 140.0 */
   6995       {32000000,      109,   0x60000,     1,    7,  0,  2,  3,        1}, /* Ndiv = 109.375 */
   6996       {50000000,       70,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 70.0 */
   6997       {       0,      140,         0,     1,    7,  0,  2,  3,        1} /* 25 MHz, from internal reference. */
   6998     };
   6999 
   7000     /* Settings for 20 MHz BSPLL output clock. */
   7001     unsigned bs_ref_freq = 0;
   7002     unsigned bs_idx = 0;
   7003     uint32 bs_ndiv_high, bs_ndiv_low;
   7004 
   7005     static const soc_pll_param_t bs_pll[] = {
   7006     /*     Fref, Ndiv_int,   Ndiv_frac,  Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */
   7007       {12800000,      273,  0x70000000,     1,  175,  0,  2,  3,        1},
   7008       {20000000,      175,           0,     1,  175,  0,  2,  3,        1},
   7009       {25000000,      140,           0,     1,  175,  0,  2,  3,        1},
   7010       {32000000,      109,  0x60000000,     1,  175,  0,  2,  3,        1},
   7011       {50000000,       70,           0,     1,  175,  0,  2,  3,        1},
   7012       {       0,      140,           0,     1,  175,  0,  2,  3,        1} /* 25 MHz, from internal reference. */
   7013     };
   7014 
   7015 
   7016     si = &SOC_INFO(unit);
   7017 
   7018     to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
   7019                                    (10 * MILLISECOND_USEC);
   7020 
   7021    /* Reset all mHost processors */
   7022    SOC_IF_ERROR_RETURN(WRITE_MHOST_0_CR5_RST_CTRLr(unit, 0));
   7023    SOC_IF_ERROR_RETURN(WRITE_MHOST_1_CR5_RST_CTRLr(unit, 0));
   7024 
   7025     soc_apache_sbus_ring_map_config(unit);
   7026 
   7027     /*Reset the common UARTs */
   7028     SOC_IF_ERROR_RETURN(WRITE_CHIPCOMMONG_UART0_UART_SRRr(unit, 1));
   7029     SOC_IF_ERROR_RETURN(WRITE_CHIPCOMMONG_UART1_UART_SRRr(unit, 1));
   7030 
   7031     /* Wait for AXI bus to clean up */
   7032     sal_usleep(50 * MILLISECOND_USEC);
   7033 
   7034     /* Bring the mHosts out of reset but leave the ARM cores in Halt, As
   7035      * some reg accesses could cause PCI bus error while mHost is in reset
   7036      */
   7037     SOC_IF_ERROR_RETURN(WRITE_MHOST_0_CR5_RST_CTRLr(unit, 0xf));
   7038     SOC_IF_ERROR_RETURN(WRITE_MHOST_1_CR5_RST_CTRLr(unit, 0xf));
   7039 
   7040     sal_usleep(to_usec);
   7041 
   7042     apache_ovstb_toggle(unit);
   7043 
   7044     soc_cm_get_id(unit, &dev_id, &rev_id);
   7045 
   7046     SOC_IF_ERROR_RETURN(soc_apache_frequency_get(unit, &max_frequency, &def_freq));
   7047     freq_list = apache_freq_list;
   7048     freq_list_len = sizeof(apache_freq_list) / sizeof(int);
   7049     if (si->frequency != def_freq) {
   7050         for (sel = 0; sel < freq_list_len; sel++) {
   7051             if (si->frequency == freq_list[sel]) {
   7052                 break;
   7053             }
   7054         }
   7055 
   7056         LOG_CLI((BSL_META_U(unit,
   7057                    "*** change CORE_CLK_FREQ_SEL to %d\n"), sel));
   7058         LOG_CLI((BSL_META_U(unit,
   7059                    "*** change core clock frequency to %dMHz\n"),
   7060                    si->frequency));
   7061 
   7062         SOC_IF_ERROR_RETURN(READ_TOP_CORE_CLK_FREQ_SELr(unit, &rval));
   7063         soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   7064                           SW_CORE_CLK_SEL_ENf, 1);
   7065         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   7066         soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   7067                           CORE_CLK_FREQ_SELf, sel);
   7068         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   7069 
   7070         sal_usleep(to_usec);
   7071     }
   7072 
   7073 
   7074 
   7075     /*
   7076      * For TD2+ and TD+ compatible packages where there is no 1.25V supply in the package,
   7077      * ams_pll_drv_hv_disable needs to be set to 1.
   7078      *
   7079      * ams_pll_drv_hv_disable: This is the main TX driver mode for Falcon, and is properly enabled
   7080      * when TVDD1P25 = 1.25V, and tx_drv_hv_disable is set to its default value, "0".
   7081      * To prevent damage to the output driver, this bit must always be "0" if TVDD1P25 = 1.25V
   7082      */
   7083     if (soc_feature(unit, soc_feature_untethered_otp)) {
   7084         int pkg_50mm;
   7085 
   7086         pkg_50mm = (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureApachePkg50mmTDpCompat) ||
   7087                     SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureApachePkg50mmTD2pCompat));
   7088 
   7089         pkg_50mm |= (SOC_BOND_INFO(unit)->dev_id == BCM56765_DEVICE_ID);
   7090 
   7091         if (pkg_50mm) {
   7092 
   7093             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_MISC_CONTROLr,
   7094                                     REG_PORT_ANY, FALCON_TX_DRV_HV_DISABLEf, 1));
   7095         }
   7096     }
   7097 
   7098     /* Put TS, BS PLLs to reset before changing PLL control registers */
   7099     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   7100     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7101                         TOP_TS_PLL_RST_Lf, 0);
   7102     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7103                         TOP_BS_PLL0_RST_Lf, 0);
   7104     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7105                         TOP_BS_PLL1_RST_Lf, 0);
   7106     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7107                         TOP_TS_PLL_POST_RST_Lf, 0);
   7108     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7109                         TOP_BS_PLL0_POST_RST_Lf, 0);
   7110     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7111                         TOP_BS_PLL1_POST_RST_Lf, 0);
   7112     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   7113 
   7114     rval = 0;
   7115 
   7116     /* Configure TS PLL */ 
   7117     ts_ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0);  /* 0->internal reference */
   7118 
   7119     for (ts_idx = 0; ts_idx < sizeof(ts_pll)/sizeof(ts_pll[0]); ++ts_idx) {
   7120         if (ts_pll[ts_idx].ref_freq == ts_ref_freq) {
   7121             break;
   7122         }
   7123     }
   7124     if (ts_idx == sizeof(ts_pll)/sizeof(ts_pll[0])) {
   7125         /* Valid configuration lookup failed. Use internal reference. */
   7126         ts_idx = 5;
   7127         ts_ref_freq = 0;
   7128     }
   7129 
   7130     /* Do not change PLL settings for internal reference */
   7131     if(ts_ref_freq) {
   7132         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit, &rval));
   7133         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, (ts_ref_freq != 0));
   7134         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_1r(unit, rval));
   7135 
   7136         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval));
   7137         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, PDIVf,
   7138                           soc_property_get(unit, spn_PTP_TS_PLL_PDIV, ts_pll[ts_idx].pdiv));
   7139         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, CH0_MDIVf,
   7140                           soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, ts_pll[ts_idx].mdiv));
   7141         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_3r(unit, rval));
   7142 
   7143         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval));
   7144         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_INTf,
   7145                           soc_property_get(unit, spn_PTP_TS_PLL_N, ts_pll[ts_idx].ndiv_int));
   7146         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_FRACf, ts_pll[ts_idx].ndiv_frac);
   7147         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_4r(unit, rval));
   7148 
   7149         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_5r(unit,&rval));
   7150         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KAf,
   7151                           soc_property_get(unit, spn_PTP_TS_KA, ts_pll[ts_idx].ka));
   7152         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KIf,
   7153                           soc_property_get(unit, spn_PTP_TS_KI, ts_pll[ts_idx].ki));
   7154         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KPf,
   7155                           soc_property_get(unit, spn_PTP_TS_KP, ts_pll[ts_idx].kp));
   7156         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_5r(unit, rval));
   7157     }
   7158 
   7159     /* Set 250Mhz (implies 4ns resolution) default timesync clock to 
   7160        calculate assymentric delays */
   7161     SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */
   7162      
   7163     /* Configure BroadSync PLLs. */
   7164     bs_ref_freq = soc_property_get(unit, spn_PTP_BS_FREF, 0);  /* 0->internal reference */
   7165 
   7166     for (bs_idx = 0; bs_idx < sizeof(bs_pll)/sizeof(bs_pll[0]); ++bs_idx) {
   7167         if (bs_pll[bs_idx].ref_freq == bs_ref_freq) {
   7168             break;
   7169         }
   7170     }
   7171     if (bs_idx == sizeof(bs_pll)/sizeof(bs_pll[0])) {
   7172         /* Valid configuration lookup failed. Use internal reference. */
   7173         bs_idx = 5;
   7174         bs_ref_freq = 0;
   7175     }
   7176 
   7177     if (bs_ref_freq) {
   7178         /* PLL settings for external reference */
   7179 
   7180         bs_ndiv_high = ((soc_property_get(unit, spn_PTP_BS_NDIV_INT,
   7181                             bs_pll[bs_idx].ndiv_int) << 6) |
   7182                        ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC,
   7183                             bs_pll[bs_idx].ndiv_frac) >> 26) & 0x3f));
   7184         bs_ndiv_low = ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC,
   7185                             bs_pll[bs_idx].ndiv_frac) << 6) & 0xffffc000);
   7186 
   7187         /* Configure BS PLL0 */
   7188         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_1r(unit, &rval));
   7189         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0));
   7190         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_1r(unit, rval));
   7191 
   7192         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval));
   7193         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, PDIVf,
   7194                           soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv));
   7195         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf,
   7196                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7197         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval));
   7198 
   7199         /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */
   7200         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_5r(unit,&rval));
   7201         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low);
   7202         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_5r(unit, rval));
   7203 
   7204         /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */
   7205         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_6r(unit,&rval));
   7206         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high);
   7207         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_6r(unit, rval));
   7208 
   7209         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_4r(unit, &rval));
   7210         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KAf,
   7211                           soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka));
   7212         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KIf,
   7213                           soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki));
   7214         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KPf,
   7215                           soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp));
   7216         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_4r(unit, rval));
   7217 
   7218         /* Configure BS PLL1 */
   7219         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_1r(unit, &rval));
   7220         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0));
   7221         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_1r(unit, rval));
   7222 
   7223         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval));
   7224         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, PDIVf,
   7225                           soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv));
   7226         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf,
   7227                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7228         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval));
   7229 
   7230         /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */
   7231         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_5r(unit,&rval));
   7232         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low);
   7233         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_5r(unit, rval));
   7234 
   7235         /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */
   7236         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_6r(unit,&rval));
   7237         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high);
   7238         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_6r(unit, rval));
   7239 
   7240         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_4r(unit, &rval));
   7241         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KAf,
   7242                           soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka));
   7243         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KIf,
   7244                           soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki));
   7245         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KPf,
   7246                           soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp));
   7247         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_4r(unit, rval));
   7248     } else {
   7249         /* PLL settings for internal reference are retained to default except for MDIV */
   7250 
   7251         /* BS PLLs Fout by default is 14MHz. Adjust MDIV to make it as 20MHz */
   7252         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval));
   7253         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf,
   7254                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7255         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval));
   7256 
   7257         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval));
   7258         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf,
   7259                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7260         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval));
   7261     }
   7262 
   7263     /* Bring LCPLL, time sync PLL, BroadSync PLL out of reset */
   7264     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   7265     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
   7266                       1);
   7267     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf,
   7268                       1);
   7269     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf,
   7270                       1);
   7271     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PMB_RST_Lf, 1);
   7272     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_RST_Lf, 1);
   7273     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1);
   7274     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   7275 
   7276     sal_usleep(to_usec);
   7277 
   7278     if (!SAL_BOOT_SIMULATION) {
   7279         /* Check LCPLL lock status */
   7280         for (index = 0; index < 4; index++) {
   7281             reg = lcpll_status_reg[index];
   7282             SOC_IF_ERROR_RETURN
   7283                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   7284             if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) {
   7285                 LOG_ERROR(BSL_LS_SOC_COMMON,
   7286                           (BSL_META_U(unit, "LCPLL %d not locked on unit %d "
   7287                                  "status = 0x%08x\n"), index, unit, rval));
   7288             }
   7289         }
   7290         /* Check time sync lock status */
   7291         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_STATUSr(unit, &rval));
   7292         if (!soc_reg_field_get(unit, TOP_TS_PLL_STATUSr, rval, PLL_LOCKf)) {
   7293             LOG_ERROR(BSL_LS_SOC_COMMON,
   7294                           (BSL_META_U(unit, "TS_PLL not locked on unit %d "
   7295                              "status = 0x%08x\n"), unit, rval));
   7296         }
   7297 
   7298         /* Check BroadSync lock status */
   7299         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_STATUSr(unit, &rval));
   7300         if (!soc_reg_field_get(unit, TOP_BS_PLL0_STATUSr, rval, PLL_LOCKf)) {
   7301             LOG_ERROR(BSL_LS_SOC_COMMON,
   7302                           (BSL_META_U(unit, "BS_PLL0 not locked on unit %d "
   7303                              "status = 0x%08x\n"), unit, rval));
   7304         }
   7305 
   7306         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_STATUSr(unit, &rval));
   7307         if (!soc_reg_field_get(unit, TOP_BS_PLL1_STATUSr, rval, PLL_LOCKf)) {
   7308             LOG_ERROR(BSL_LS_SOC_COMMON,
   7309                           (BSL_META_U(unit, "BS_PLL1 not locked on unit %d "
   7310                              "status = 0x%08x\n"), unit, rval));
   7311         }
   7312     }
   7313 
   7314     /* De-assert LCPLL's post reset */
   7315     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   7316     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7317                       TOP_TS_PLL_POST_RST_Lf, 1);
   7318     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7319                       TOP_BS_PLL0_POST_RST_Lf, 1);
   7320     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7321                       TOP_BS_PLL1_POST_RST_Lf, 1);
   7322 
   7323     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7324                       TOP_PVT_MON_MIN_RST_Lf, 1);
   7325 
   7326     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   7327 
   7328     sal_usleep(to_usec);
   7329 
   7330     /* Set correct value for BG_ADJ */
   7331     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval));
   7332     soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 0);
   7333     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval));
   7334 
   7335     /* Enable high temperature interrupt monitoring.
   7336      * Default on: pvtmon6 (close to core_plls at center of die).
   7337      */
   7338     temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6);
   7339     /* The above is a 9 bit mask to indicate which temp sensor to hook up to
   7340      * the interrupt.
   7341      */
   7342     rval = 0;
   7343     for (index = 0; index <COUNTOF(temp_thr_reg); index++) {
   7344         uint32 trval;
   7345 
   7346         /* data = 410.04-(temp/0.48705) = (410040-(temp*1000))/487
   7347          * Note: Since this is a high temp value we can safely assume it to
   7348          * always be a +ive number. This is in degrees celcius.
   7349          */
   7350         temp_thr = soc_property_get(unit, temp_thr_prop[index], _SOC_AP_DEF_TEMP_MAX);
   7351         if (temp_thr > 410) {
   7352             LOG_ERROR(BSL_LS_SOC_COMMON,
   7353                       (BSL_META_U(unit,
   7354                                   "Unsupported temp value %d !! Max 410. Using %d.\n"),
   7355                        temp_thr, _SOC_AP_DEF_TEMP_MAX));
   7356             temp_thr = _SOC_AP_DEF_TEMP_MAX;
   7357         }
   7358         /* Convert temperature to config data */
   7359         temp_thr = (410040-(temp_thr*1000))/487;
   7360         SOC_IF_ERROR_RETURN
   7361             (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval));
   7362         soc_reg_field_set(unit, temp_thr_reg[index], &trval, MAX_THRESHOLDf,
   7363                           temp_thr);
   7364         SOC_IF_ERROR_RETURN
   7365             (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval));
   7366         if (temp_mask & (1 << index)) {
   7367             rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */
   7368         }
   7369     }
   7370     _soc_ap_temp_mon_mask[unit] = temp_mask;
   7371 
   7372     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_MASKr(unit, rval));
   7373     /* Enable temp mon interrupt */
   7374     (void)soc_cmicm_intr3_enable(unit, 0x4); /* PVTMON_INTR bit 2 */
   7375 
   7376     /* Bring port blocks out of reset */
   7377     rval = 0;
   7378     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 1);
   7379     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 1);
   7380     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1);
   7381     WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   7382 
   7383     sal_usleep(to_usec);
   7384 
   7385     /* Bring IP, EP, and MMU blocks out of reset */
   7386     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval));
   7387     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 1);
   7388     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   7389 
   7390     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1);
   7391     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1);
   7392 
   7393     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval));
   7394 
   7395     sal_usleep(to_usec);
   7396 
   7397     /* Bring PMs out of reset */
   7398     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_3r(unit, &rval));
   7399     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM0_RST_Lf, 1);
   7400     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM1_RST_Lf, 1);
   7401     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM2_RST_Lf, 1);
   7402     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM3_RST_Lf, 1);
   7403     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM4_RST_Lf, 1);
   7404     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM5_RST_Lf, 1);
   7405     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM6_RST_Lf, 1);
   7406     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM7_RST_Lf, 1);
   7407     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM8_RST_Lf, 1);
   7408     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM9_RST_Lf, 1);
   7409     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM10_RST_Lf, 1);
   7410     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM11_RST_Lf, 1);
   7411     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM12_RST_Lf, 1);
   7412     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM13_RST_Lf, 1);
   7413     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, rval));
   7414 
   7415     sal_usleep(to_usec);
   7416 
   7417     SOC_IF_ERROR_RETURN
   7418         (soc_apache_hash_bank_count_get(unit, L2Xm, &num_banks));
   7419     num_shared_l2_banks = num_banks - 2; /* minus 2 dedicated L2 banks */
   7420     SOC_IF_ERROR_RETURN
   7421         (soc_apache_hash_bank_count_get(unit, L3_ENTRY_ONLYm, &num_banks));
   7422     num_shared_l3_banks = num_banks - 4; /* minus 4 dedicated L3 banks */
   7423 
   7424     if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) {
   7425         int non_alpm = num_shared_l3_banks + num_shared_l2_banks;
   7426         if ((non_alpm) && (non_alpm <= 2)) {
   7427             /* If Shared banks are used between ALPM and non-ALPM memories,
   7428              * then ALPM uses Shared Bank B2, B3 and non-ALPM uses B4, B5 banks
   7429              */
   7430             SOC_IF_ERROR_RETURN
   7431                 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r,
   7432                                         REG_PORT_ANY, ALPM_BANK_MODEf, 1));
   7433             SOC_IF_ERROR_RETURN
   7434                 (soc_reg_field32_modify(unit, LPM_LOG_TO_PHY_BANK_MAPr,
   7435                                         REG_PORT_ANY, ALPM_BANK_MODEf, 1));
   7436             SOC_IF_ERROR_RETURN
   7437                 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r,
   7438                                         REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0x3));
   7439             _soc_ap_num_shared_alpm_banks[unit] = 2;
   7440             shared_bank_offset = 2;
   7441         } else {
   7442             SOC_IF_ERROR_RETURN
   7443                 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r,
   7444                                         REG_PORT_ANY, ALPM_BANK_MODEf, 0));
   7445             SOC_IF_ERROR_RETURN
   7446                 (soc_reg_field32_modify(unit, LPM_LOG_TO_PHY_BANK_MAPr,
   7447                                         REG_PORT_ANY, ALPM_BANK_MODEf, 0));
   7448             SOC_IF_ERROR_RETURN
   7449                 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r,
   7450                                         REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0xf));
   7451             _soc_ap_num_shared_alpm_banks[unit] = 4;
   7452         }
   7453     }
   7454 
   7455     soc_reg_field_set(unit, L2_ISS_BANK_CONFIGr, &config, L2_ENTRY_BANK_CONFIGf,
   7456                       ((1 << num_shared_l2_banks) - 1) << shared_bank_offset);
   7457     for (index = 0; index < num_shared_l2_banks; index++) {
   7458         shared_bank = index + shared_bank_offset;
   7459         soc_reg_field_set(unit, L2_ISS_LOG_TO_PHY_BANK_MAPr, &map,
   7460                           l2_fields[index], shared_bank);
   7461     }
   7462     SOC_IF_ERROR_RETURN
   7463         (soc_reg32_set(unit, L2_ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config));
   7464     SOC_IF_ERROR_RETURN
   7465         (soc_reg32_set(unit, L2_ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map));
   7466 
   7467     config = map = 0;
   7468     shared_bank_offset += num_shared_l2_banks;
   7469 
   7470     soc_reg_field_set(unit, L3_ISS_BANK_CONFIGr, &config, L3_ENTRY_BANK_CONFIGf,
   7471                       ((1 << num_shared_l3_banks) - 1) << shared_bank_offset);
   7472     for (index = 0; index < num_shared_l3_banks; index++) {
   7473         shared_bank = index + shared_bank_offset;;
   7474         soc_reg_field_set(unit, L3_ISS_LOG_TO_PHY_BANK_MAPr, &map,
   7475                           l3_fields[index], shared_bank);
   7476     }
   7477     SOC_IF_ERROR_RETURN
   7478         (soc_reg32_set(unit, L3_ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config));
   7479     SOC_IF_ERROR_RETURN
   7480         (soc_reg32_set(unit, L3_ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map));
   7481 
   7482     /* SHARED_TABLE_HASH_CONTROLr.UFT_BANK_ENABLEf programming is redundant in
   7483      * Apache (as in TH). If the PHY banks are not enabled for any of the LOG Tables,
   7484      * the low power mode is implicit - i.e., no explicit bank_disable is reqd. */
   7485 
   7486     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   7487             spn_ECMP_RESILIENT_HASH_SIZE, 32768);
   7488     switch (num_ecmp_rh_flowset_entries) {
   7489         case 0:
   7490             rh_table_config_encoding = 2;
   7491             break;
   7492         case 32768:
   7493             rh_table_config_encoding = 0;
   7494             break;
   7495         case 65536:
   7496             rh_table_config_encoding = 1;
   7497             break;
   7498         default:
   7499             return SOC_E_CONFIG;
   7500     }
   7501 
   7502 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   7503     ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1);
   7504     if ((soc_feature(unit, soc_feature_riot) ||
   7505          soc_feature(unit, soc_feature_multi_level_ecmp)) &&
   7506         ecmp_levels > 1) {
   7507 
   7508         num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit,
   7509             spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0);
   7510 
   7511         if (SOC_FIELD_RANGE_CHECK(
   7512             num_overlay_ecmp_rh_flowset_entries, 0, 16384)) {
   7513 
   7514             num_overlay_ecmp_rh_flowset_entries = 16384;
   7515         } else if (SOC_FIELD_RANGE_CHECK(
   7516             num_overlay_ecmp_rh_flowset_entries, 16384, 32768)) {
   7517 
   7518             num_overlay_ecmp_rh_flowset_entries = 32768;
   7519         } else if (SOC_FIELD_RANGE_CHECK(
   7520             num_overlay_ecmp_rh_flowset_entries, 32768, 49152)) {
   7521 
   7522             num_overlay_ecmp_rh_flowset_entries = 49152;
   7523         } else if (SOC_FIELD_RANGE_CHECK(
   7524             num_overlay_ecmp_rh_flowset_entries, 49152, 65536)) {
   7525 
   7526             num_overlay_ecmp_rh_flowset_entries = 65536;
   7527         }
   7528 
   7529         switch (num_overlay_ecmp_rh_flowset_entries) {
   7530         case 0:
   7531             rh_bank_sel = 0x0;
   7532             break;
   7533         case 16384:
   7534             if (num_ecmp_rh_flowset_entries >= 16384) {
   7535                 rh_bank_sel = 0x1;
   7536             } else {
   7537                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7538                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7539                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7540                     num_overlay_ecmp_rh_flowset_entries));
   7541                 return SOC_E_CONFIG;
   7542             }
   7543             break;
   7544         case 32768:
   7545             if (num_ecmp_rh_flowset_entries >= 32768) {
   7546                 rh_bank_sel = 0x3;
   7547             } else {
   7548                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7549                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7550                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7551                     num_overlay_ecmp_rh_flowset_entries));
   7552                 return SOC_E_CONFIG;
   7553             }
   7554             break;
   7555         case 49152:
   7556             if (num_ecmp_rh_flowset_entries >= 49152) {
   7557                 rh_bank_sel = 0x7;
   7558             } else {
   7559                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7560                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7561                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7562                     num_overlay_ecmp_rh_flowset_entries));
   7563                 return SOC_E_CONFIG;
   7564             }
   7565             break;
   7566         case 65536:
   7567             if (num_ecmp_rh_flowset_entries >= 65536) {
   7568                 rh_bank_sel = 0xf;
   7569             } else {
   7570                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7571                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7572                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7573                     num_overlay_ecmp_rh_flowset_entries));
   7574                 return SOC_E_CONFIG;
   7575             }
   7576             break;
   7577         default:
   7578                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7579                     "%s: Value for overlay RH entries is not correct : %d \n"),
   7580                     FUNCTION_NAME(),  num_overlay_ecmp_rh_flowset_entries));
   7581             return SOC_E_CONFIG;
   7582     }
   7583     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, RH_ECMP_FLOWSET_BANK_SELr,
   7584                 REG_PORT_ANY, BANK_SELf,
   7585                 rh_bank_sel));
   7586   }
   7587 #endif
   7588 
   7589     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr,
   7590                 REG_PORT_ANY, RH_FLOWSET_TABLE_CONFIG_ENCODINGf,
   7591                 rh_table_config_encoding));
   7592 
   7593     READ_TOP_PVTMON_CTRL_1r(unit, &rval);
   7594     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   7595     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7596     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0);
   7597     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7598     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   7599     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7600 
   7601     /* Bypass unused Port Blocks */
   7602     if (soc_property_get(unit, "disable_unused_port_blocks", TRUE)) {
   7603         SOC_IF_ERROR_RETURN(soc_apache_tsc_disable(unit));
   7604     }
   7605 
   7606 
   7607     /* Do not use SBUS MDIO by default */
   7608     SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = NULL;
   7609     SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = NULL;
   7610 
   7611     /* Optionally allow SBUS MDIO for debug */
   7612     if (soc_property_get(unit, "apache_sbus_mdio", 1)) {
   7613         SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = _soc_apache_mdio_reg_read;
   7614         SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = _soc_apache_mdio_reg_write;
   7615     }
   7616 
   7617     if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED) &&
   7618             soc_feature(unit, soc_feature_turbo_boot)) {
   7619         SOC_HW_RESET_START(unit);
   7620     }
   7621 
   7622     return SOC_E_NONE;
   7623 }
   7624 
   7625 int
   7626 soc_apache_tsc_reset(int unit)
   7627 {
   7628     int blk, port;
   7629     uint32 rval;
   7630 
   7631     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CXXPORT) {
   7632         port = SOC_BLOCK_PORT(unit, blk);
   7633         
   7634         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7635         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 1));
   7636         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 2));
   7637     }
   7638 
   7639     /* Though TSC/MAC reset is controlled by PortMod internally,
   7640      * this is needed in case access to MAC registers is needed
   7641      * before PortMod attach for cases like:
   7642      * - To enable SER MAC interrupts
   7643      * - Various sanity register read/write tests
   7644      */
   7645     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLG2PORT) {
   7646         port = SOC_BLOCK_PORT(unit, blk);
   7647 
   7648         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7649         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval));
   7650         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7651         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   7652     }
   7653 
   7654     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
   7655         port = SOC_BLOCK_PORT(unit, blk);
   7656 
   7657         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7658         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval));
   7659         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7660         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   7661     }
   7662 
   7663     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   7664         port = SOC_BLOCK_PORT(unit, blk);
   7665 
   7666         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7667         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   7668         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7669         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   7670     }
   7671 
   7672     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORTB0) {
   7673         port = SOC_BLOCK_PORT(unit, blk);
   7674 
   7675         SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7676         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   7677         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7678         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   7679     }
   7680 
   7681     return SOC_E_NONE;
   7682 }
   7683 
   7684 STATIC int
   7685 _soc_apache_clear_enabled_port_data (int unit)
   7686 {
   7687     uint64 rval64;
   7688     int    port;
   7689     uint32 evc = 0;
   7690     egr_vlan_control_1_entry_t entry1;
   7691     egr_vlan_control_2_entry_t entry2;
   7692     egr_vlan_control_3_entry_t entry3;
   7693 
   7694     sal_memset(&entry1, 0, sizeof(entry1));
   7695     sal_memset(&entry2, 0, sizeof(entry2));
   7696     sal_memset(&entry3, 0, sizeof(entry3));
   7697 
   7698     /* Some registers are implemented in memory, need to clear them in order
   7699      * to have correct parity value */
   7700     COMPILER_64_ZERO(rval64);
   7701     PBMP_ALL_ITER(unit, port) {
   7702         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry1));
   7703         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry2));
   7704         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry3));
   7705 
   7706         SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, 0));
   7707         SOC_IF_ERROR_RETURN(WRITE_EGR_SF_SRC_MODID_CHECKr(unit, port, rval64));
   7708         SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64));
   7709         SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_INVALID_CRC_FRAMESr(unit, port, 0));
   7710         SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_DELIMITER_ERROR_FRAMESr(unit, port, 0));
   7711         SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ALL, port, &evc));
   7712         SOC_IF_ERROR_RETURN(WRITE_ING_TRILL_ADJACENCYr(unit, port, rval64));
   7713         SOC_IF_ERROR_RETURN(WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0));
   7714         SOC_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, 0));
   7715     }
   7716 
   7717     return SOC_E_NONE;
   7718 }
   7719 
   7720 STATIC int
   7721 _soc_apache_clear_all_port_data (int unit)
   7722 {
   7723     int    r, p;
   7724     uint32 addr;
   7725     
   7726     SOC_IF_ERROR_RETURN(_soc_apache_clear_enabled_port_data(unit));
   7727 
   7728     
   7729     
   7730     /* Clear TDBGCn regs for all indexes */
   7731     for (r = 0; r < 12; r++) {
   7732         addr = 0x28000000 + r*0x100;
   7733         for (p = 0; p < 106; p++) {
   7734             _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7735             _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7736         }
   7737     }
   7738 
   7739     /* Clear EGR_TRILL_TX_PKTS */
   7740     addr = 0x28000c00;
   7741     for (p = 0; p < 106; p++) {
   7742         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7743         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7744     }
   7745     /* Clear EGR_TRILL_TX_ACCESS_PORT_TRILL_PKTS_DISCARDED */
   7746     addr = 0x28000d00;
   7747     for (p = 0; p < 106; p++) {
   7748         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7749         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7750     }
   7751     /* Clear EGR_TRILL_TX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED */
   7752     addr = 0x28000e00;
   7753     for (p = 0; p < 106; p++) {
   7754         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7755         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7756     }
   7757     /* Clear TPCE */
   7758     addr = 0x28000f00;
   7759     for (p = 0; p < 106; p++) {
   7760         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7761         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7762     }
   7763     return SOC_E_NONE;
   7764 }
   7765 
   7766 STATIC int
   7767 _soc_apache_clear_all_memory(int unit, int mmu_init)
   7768 {
   7769     int                 blk;
   7770     int                 pgw, pgw_inst, num_pgw = 0;
   7771     uint32              rval, in_progress[1];
   7772     int                 hw_reset_to, index, count;
   7773     soc_reg_t           hw_reset_reg;
   7774     soc_timeout_t       to;
   7775     static const struct {
   7776         soc_mem_t mem;
   7777         uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */
   7778     } cam_list[] = {
   7779         { CPU_COS_MAPm,                     BOOT_F_PLISIM },
   7780         { EFP_TCAMm,                        BOOT_F_PLISIM },
   7781         { FP_GLOBAL_MASK_TCAMm,             BOOT_F_PLISIM },
   7782         { FP_TCAMm,                         BOOT_F_PLISIM },
   7783         { VFP_TCAMm,                        BOOT_F_PLISIM },
   7784         { FP_UDF_TCAMm,                     BOOT_F_PLISIM },
   7785         { ING_SNATm,                        BOOT_F_PLISIM },
   7786         { IP_MULTICAST_TCAMm,               BOOT_F_PLISIM },
   7787         { L2_USER_ENTRYm,                   BOOT_F_PLISIM },
   7788         { L3_DEFIPm,                        BOOT_F_PLISIM },
   7789         { L3_DEFIP_PAIR_128m,               BOOT_F_PLISIM },
   7790         { L3_TUNNELm,                       BOOT_F_PLISIM },
   7791         { MY_STATION_TCAMm,                 BOOT_F_PLISIM },
   7792         { UDF_CONDITIONAL_CHECK_TABLE_CAMm, BOOT_F_PLISIM },
   7793         { MY_STATION_TCAM_2m,               BOOT_F_PLISIM },
   7794         { SUBPORT_TAG_SGPP_MAPm,            BOOT_F_PLISIM },
   7795         { VLAN_SUBNETm,                     0 },/* VLAN API needs all 0 mask */
   7796         { MY_STATION_TCAM_2m,               BOOT_F_PLISIM },
   7797         { SUBPORT_TAG_SGPP_MAPm,            BOOT_F_PLISIM },
   7798 #ifdef PLISIM
   7799         /* In HW, these are the same as FP_GLOBAL_MASK_TCAM.
   7800          * In simulation, they are separate instances.
   7801          */
   7802         { FP_GM_FIELDSm,                    BOOT_F_PLISIM }
   7803 #endif
   7804     };
   7805 
   7806     if (mmu_init) {
   7807         uint32 rval1;
   7808         /* Start MMU memory initialization */
   7809         SOC_IF_ERROR_RETURN
   7810             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 0));
   7811 
   7812         SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1));
   7813         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0);
   7814         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   7815         SOC_IF_ERROR_RETURN
   7816             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 1));
   7817 
   7818         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */
   7819         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1);
   7820         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   7821     }
   7822 
   7823     SOC_IF_ERROR_RETURN
   7824         (_soc_apache_mmu_init_default_val(unit));
   7825 
   7826     /*
   7827      * Reset the PGW, IPIPE and EPIPE block
   7828      */
   7829     rval = 0;
   7830     hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r;
   7831     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7832     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7833 
   7834     SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) {
   7835         num_pgw += 1;
   7836         pgw = SOC_BLOCK_NUMBER(unit, blk);
   7837         pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   7838         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval));
   7839     }
   7840 
   7841     rval = 0;
   7842     hw_reset_reg = ING_HW_RESET_CONTROL_2r;
   7843     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   7844     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7845     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7846 
   7847     /* Set count to # entries of largest IPIPE table */
   7848     count = soc_mem_index_count(unit, RH_HGT_FLOWSETm);
   7849     if (count < soc_mem_index_count(unit, L2Xm)) {
   7850         count = soc_mem_index_count(unit, L2Xm);
   7851     }
   7852     if (count < soc_mem_index_count(unit, L3_ENTRY_ONLYm)) {
   7853         count = soc_mem_index_count(unit, L3_ENTRY_ONLYm);
   7854     }
   7855     if (count < soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) {
   7856         count = soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m);
   7857     }
   7858     soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count);
   7859     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval));
   7860 
   7861     rval = 0;
   7862     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   7863 
   7864     hw_reset_reg = EGR_HW_RESET_CONTROL_1r;
   7865     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7866     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7867     /* Set count to # entries of largest EPIPE table 32k */
   7868     count = soc_mem_index_count(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm);
   7869     soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count);
   7870     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval));
   7871 
   7872     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   7873     if (SAL_BOOT_QUICKTURN) {
   7874         hw_reset_to = 10000000;
   7875     } else {
   7876         hw_reset_to = 50000;
   7877     }
   7878     soc_timeout_init(&to, hw_reset_to, 0);
   7879 
   7880     /* Wait for PGW memory initialization done. */
   7881     hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r;
   7882     /*  in_progress = ((1 << num_pgw) - 1); */  /* 1b for each PGW */
   7883     in_progress[0] = 0;
   7884     SHR_BITSET_RANGE(in_progress, 0, num_pgw);  /* 1b for each PGW */
   7885 
   7886     do {
   7887         SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) {
   7888             pgw = SOC_BLOCK_NUMBER(unit, blk);
   7889             pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   7890             if (SHR_BITGET(in_progress, pgw)) { /* PGW RESET not done yet */
   7891                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg,
   7892                                                   pgw_inst, 0, &rval));
   7893 
   7894                 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7895                     SHR_BITCLR(in_progress, pgw); /* Clear bit corresponding to the PGW */
   7896                 }
   7897             }
   7898         }
   7899 
   7900         if (soc_timeout_check(&to)) {
   7901             if (!SAL_BOOT_BCMSIM) {
   7902                 LOG_WARN(BSL_LS_SOC_COMMON,
   7903                          (BSL_META_U(unit, "PGW_ING_HW_RESET timeout\n")));
   7904             }
   7905             break;
   7906         }
   7907     } while (in_progress[0] != 0);
   7908 
   7909     /* Wait for EPIPE memory initialization done. */
   7910     in_progress[0] = 1;
   7911     hw_reset_reg = EGR_HW_RESET_CONTROL_1r;
   7912     do {
   7913         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval));
   7914         if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7915             in_progress[0] = 0;
   7916         }
   7917         if (soc_timeout_check(&to)) {
   7918             if (!SAL_BOOT_BCMSIM) {
   7919                 LOG_WARN(BSL_LS_SOC_COMMON,
   7920                          (BSL_META_U(unit, "EGR_HW_RESET timeout\n")));
   7921             }
   7922             break;
   7923         }
   7924     } while (in_progress[0] != 0);
   7925 
   7926     rval = 0;
   7927     hw_reset_reg = EGR_HW_RESET_CONTROL_0r;
   7928     soc_reg_field_set(unit, hw_reset_reg, &rval, STAGE_NUMBERf, 1);
   7929     soc_reg_field_set(unit, hw_reset_reg, &rval, START_ADDRESSf, 0x80000);
   7930     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   7931 
   7932     rval = 0;
   7933     in_progress[0] = 1;
   7934     hw_reset_reg = EGR_HW_RESET_CONTROL_1r;
   7935     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7936     soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count);
   7937     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   7938 
   7939     do {
   7940         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval));
   7941         if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7942             in_progress[0] = 0;
   7943         }
   7944         if (soc_timeout_check(&to)) {
   7945             if (!SAL_BOOT_BCMSIM) {
   7946                 LOG_WARN(BSL_LS_SOC_COMMON,
   7947                          (BSL_META_U(unit, "EGR_HW_RESET timeout\n")));
   7948             }
   7949             break;
   7950         }
   7951     } while (in_progress[0] != 0);
   7952 
   7953     /* Wait for IPIPE memory initialization done. */
   7954     in_progress[0] = 1;
   7955     hw_reset_reg = ING_HW_RESET_CONTROL_2r;
   7956     do {
   7957         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval));
   7958         if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7959             in_progress[0] = 0;
   7960         }
   7961 
   7962         if (soc_timeout_check(&to)) {
   7963             if (!SAL_BOOT_BCMSIM) {
   7964                 LOG_WARN(BSL_LS_SOC_COMMON,
   7965                          (BSL_META_U(unit, "ING_HW_RESET timeout\n")));
   7966             }
   7967             break;
   7968         }
   7969     } while (in_progress[0] != 0);
   7970 
   7971     /* Clear HW reset control registers */
   7972     rval = 0;
   7973     hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r;
   7974     SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) {
   7975         pgw = SOC_BLOCK_NUMBER(unit, blk);
   7976         pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   7977         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval));
   7978     }
   7979 
   7980     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   7981     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   7982 
   7983     /* TCAM tables are not handled by hardware reset control */
   7984     if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM) {
   7985         for (index = 0; index < sizeof(cam_list) / sizeof(cam_list[0]);
   7986              index++) {
   7987             if (sal_boot_flags_get() & cam_list[index].skip_flags) {
   7988                 continue;
   7989             }
   7990             SOC_IF_ERROR_RETURN
   7991                 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE));
   7992         }
   7993     }
   7994 
   7995     return SOC_E_NONE;
   7996 }
   7997 
   7998 
   7999 STATIC int
   8000 _soc_apache_port_mapping_init(int unit)
   8001 {
   8002     soc_info_t *si;
   8003     soc_mem_t mem;
   8004     uint32 rval;
   8005     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
   8006     int port, phy_port, mmu_port;
   8007     int num_port, num_phy_port;
   8008 
   8009     si = &SOC_INFO(unit);
   8010 
   8011     /* Ingress physical to logical port mapping */
   8012     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
   8013     num_phy_port = soc_mem_index_count(unit, mem);
   8014     sal_memset(&entry, 0, sizeof(entry));
   8015     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
   8016         port = si->port_p2l_mapping[phy_port];
   8017         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
   8018                             port == -1 ? 0x7f : port);
   8019         SOC_IF_ERROR_RETURN
   8020             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
   8021     }
   8022 
   8023     /* Ingress logical to physical port mapping */
   8024     num_port = soc_mem_index_count(unit, PORT_TABm) - 1;
   8025 
   8026     for (port = 0; port < num_port; port++) {
   8027         phy_port = si->port_l2p_mapping[port];
   8028         rval = 0;
   8029         if (phy_port != -1) {
   8030             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   8031                               VALIDf, 1);
   8032 
   8033             /* IFP_GM_LOGICAL_TO_PHYSICAL_MAPP?ING.PHYSICAL_PORT_NUM is
   8034              * merely a unique stream ID, it's not physical port number */
   8035             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   8036                               PHYSICAL_PORT_NUMf,
   8037                               si->port_p2m_mapping[phy_port] & 0x7f);
   8038         }
   8039         SOC_IF_ERROR_RETURN
   8040             (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval));
   8041     }
   8042 
   8043     /* Egress logical to physical port mapping */
   8044     for (port = 0; port < num_port; port++) {
   8045         phy_port = si->port_l2p_mapping[port];
   8046         rval = 0;
   8047         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
   8048                           &rval, PHYSICAL_PORT_NUMBERf,
   8049                           phy_port == -1 ? 0x7f : phy_port);
   8050         SOC_IF_ERROR_RETURN
   8051             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
   8052                                                                 rval));
   8053     }
   8054 
   8055     /* MMU to physical port mapping and MMU to logical port mapping */
   8056     for (port = 0; port < num_port; port++) {
   8057         phy_port = si->port_l2p_mapping[port];
   8058         mmu_port = si->port_p2m_mapping[phy_port];
   8059         if ((phy_port == -1) || (mmu_port == -1)) {
   8060             continue;
   8061         }
   8062         rval = 0;
   8063         soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval,
   8064                           PHY_PORTf, phy_port);
   8065         SOC_IF_ERROR_RETURN
   8066             (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, port, 0,
   8067                            rval));
   8068 
   8069         rval = 0;
   8070         soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval,
   8071                           LOGIC_PORTf, port);
   8072         SOC_IF_ERROR_RETURN
   8073             (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, port, 0,
   8074                            rval));
   8075     }
   8076 
   8077     return SOC_E_NONE;
   8078 }
   8079 
   8080 #define APACHE_PGW_TDM_LENGTH                 AP_LR_LLS_LEN
   8081 #define APACHE_PGW_TDM_OVS_SIZE               AP_OS_LLS_GRP_LEN
   8082 #define APACHE_PGW_TDM_SLOTS_PER_REG          4
   8083 #define APACHE_MMU_TDM_LENGTH                 512
   8084 #define APACHE_MMU_OVS_GROUP_COUNT            AP_OS_VBS_GRP_NUM
   8085 #define APACHE_MMU_OVS_WT_GROUP_COUNT         4
   8086 #define APACHE_MMU_OVS_GROUP_TDM_LENGTH       AP_OS_VBS_GRP_LEN
   8087 #define APACHE_IARB_TDM_LENGTH                AP_LR_IARB_STATIC_LEN
   8088 
   8089 
   8090 #define OVS_TOKEN AP_OVSB_TOKEN
   8091 #define IDL1_TOKEN AP_IDL1_TOKEN
   8092 #define IDL2_TOKEN AP_IDL2_TOKEN
   8093 #define AUX_TOKEN  AP_AUX_TOKEN
   8094 #define SBUS_TOKEN AP_SBUS_TOKEN
   8095 
   8096 #define NUM_EXT_PORTS AP_NUM_EXT_PORTS
   8097 
   8098 #define PORT_STATE_UNUSED          0   /*  PORT_STATE__DISABLED */
   8099 #define PORT_STATE_LINERATE        1   /*  PORT_STATE__LINERATE */
   8100 #define PORT_STATE_OVERSUB         2   /*  PORT_STATE__OVERSUB  */
   8101 #define PORT_STATE_SUBPORT         3   /*  PORT_STATE__COMBINED */
   8102 
   8103 enum _ap_ovs_speed_classes {
   8104     ap_ovs_speed_None = 0,
   8105     ap_ovs_speed_5G   = 2,
   8106     ap_ovs_speed_10G  = 4,
   8107     ap_ovs_speed_20G  = 8,
   8108     ap_ovs_speed_25G  = 10,
   8109     ap_ovs_speed_40G  = 16,
   8110     ap_ovs_speed_50G  = 20,
   8111     ap_ovs_speed_100G = 40
   8112 };
   8113 
   8114 typedef struct soc_apache_tdm_s {
   8115     int tdm_bw;
   8116     int is_oversub;
   8117 
   8118     int speed[NUM_EXT_PORTS];
   8119     int port_state[NUM_EXT_PORTS];
   8120 
   8121     int pgw_tdm[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH];
   8122     int mmu_tdm[APACHE_MMU_TDM_LENGTH + 1];
   8123 
   8124     struct {
   8125         int pgw_ovs_tdm[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH];
   8126         int pgw_ovs_spacing[APACHE_PGWS_PER_DEV][APACHE_PGW_TDM_LENGTH];
   8127     } ingress_ovs_tdm;
   8128 
   8129     struct {
   8130         int mmu_ovs_group_tdm[APACHE_MMU_OVS_GROUP_COUNT][APACHE_MMU_OVS_GROUP_TDM_LENGTH];
   8131         int mmu_ovs_group_speed[APACHE_MMU_OVS_GROUP_COUNT]; /* Speed for each OVS grp */
   8132         int mmu_ovs_group_wt_group[APACHE_MMU_OVS_GROUP_COUNT]; /* Weighti group for each OVS grp */
   8133     } egress_ovs_tdm;
   8134 
   8135     int iarb_tdm_wrap_ptr;
   8136     int iarb_tdm[APACHE_IARB_TDM_LENGTH];
   8137 } soc_apache_tdm_t;
   8138 
   8139 
   8140 
   8141 struct soc_apache_misc_info_s {
   8142     int tdm_active_cal;
   8143     uint16 tdm_wtg_used[APACHE_MMU_OVS_WT_GROUP_COUNT];
   8144     soc_apache_tdm_t tdm0;
   8145     soc_apache_tdm_t tdm1;
   8146 } *soc_apache_misc_info[SOC_MAX_NUM_DEVICES] = {0};
   8147 
   8148 #define AP_MISC(unit) (soc_apache_misc_info[unit])
   8149 
   8150 static const soc_field_t ap_mmu_ovs_group_wt_select_fields[] = {
   8151     GRP0f, GRP1f, GRP2f, GRP3f, GRP4f, GRP5f, GRP6f, GRP7f
   8152 };
   8153 
   8154 
   8155 static const soc_reg_t ap_pgw_lr_tdm_regs[2][16] = {
   8156     {
   8157         PGW_LR_TDM_REG_0r,  PGW_LR_TDM_REG_1r,
   8158         PGW_LR_TDM_REG_2r,  PGW_LR_TDM_REG_3r,
   8159         PGW_LR_TDM_REG_4r,  PGW_LR_TDM_REG_5r,
   8160         PGW_LR_TDM_REG_6r,  PGW_LR_TDM_REG_7r,
   8161         PGW_LR_TDM_REG_8r,  PGW_LR_TDM_REG_9r,
   8162         PGW_LR_TDM_REG_10r, PGW_LR_TDM_REG_11r,
   8163         PGW_LR_TDM_REG_12r, PGW_LR_TDM_REG_13r,
   8164         PGW_LR_TDM_REG_14r, PGW_LR_TDM_REG_15r
   8165     },
   8166     {
   8167         PGW_LR_TDM2_REG_0r,  PGW_LR_TDM2_REG_1r,
   8168         PGW_LR_TDM2_REG_2r,  PGW_LR_TDM2_REG_3r,
   8169         PGW_LR_TDM2_REG_4r,  PGW_LR_TDM2_REG_5r,
   8170         PGW_LR_TDM2_REG_6r,  PGW_LR_TDM2_REG_7r,
   8171         PGW_LR_TDM2_REG_8r,  PGW_LR_TDM2_REG_9r,
   8172         PGW_LR_TDM2_REG_10r, PGW_LR_TDM2_REG_11r,
   8173         PGW_LR_TDM2_REG_12r, PGW_LR_TDM2_REG_13r,
   8174         PGW_LR_TDM2_REG_14r, PGW_LR_TDM2_REG_15r
   8175     }
   8176 };
   8177 
   8178 static const soc_field_t ap_pgw_tdm_fields[] = {
   8179     TDM_ENTRY0_PORT_IDf,  TDM_ENTRY1_PORT_IDf,
   8180     TDM_ENTRY2_PORT_IDf,  TDM_ENTRY3_PORT_IDf,
   8181     TDM_ENTRY4_PORT_IDf,  TDM_ENTRY5_PORT_IDf,
   8182     TDM_ENTRY6_PORT_IDf,  TDM_ENTRY7_PORT_IDf,
   8183     TDM_ENTRY8_PORT_IDf,  TDM_ENTRY9_PORT_IDf,
   8184     TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf,
   8185     TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf,
   8186     TDM_ENTRY14_PORT_IDf, TDM_ENTRY15_PORT_IDf,
   8187     TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf,
   8188     TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf,
   8189     TDM_ENTRY20_PORT_IDf, TDM_ENTRY21_PORT_IDf,
   8190     TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf,
   8191     TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf,
   8192     TDM_ENTRY26_PORT_IDf, TDM_ENTRY27_PORT_IDf,
   8193     TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf,
   8194     TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf,
   8195     TDM_ENTRY32_PORT_IDf, TDM_ENTRY33_PORT_IDf,
   8196     TDM_ENTRY34_PORT_IDf, TDM_ENTRY35_PORT_IDf,
   8197     TDM_ENTRY36_PORT_IDf, TDM_ENTRY37_PORT_IDf,
   8198     TDM_ENTRY38_PORT_IDf, TDM_ENTRY39_PORT_IDf,
   8199     TDM_ENTRY40_PORT_IDf, TDM_ENTRY41_PORT_IDf,
   8200     TDM_ENTRY42_PORT_IDf, TDM_ENTRY43_PORT_IDf,
   8201     TDM_ENTRY44_PORT_IDf, TDM_ENTRY45_PORT_IDf,
   8202     TDM_ENTRY46_PORT_IDf, TDM_ENTRY47_PORT_IDf,
   8203     TDM_ENTRY48_PORT_IDf, TDM_ENTRY49_PORT_IDf,
   8204     TDM_ENTRY50_PORT_IDf, TDM_ENTRY51_PORT_IDf,
   8205     TDM_ENTRY52_PORT_IDf, TDM_ENTRY53_PORT_IDf,
   8206     TDM_ENTRY54_PORT_IDf, TDM_ENTRY55_PORT_IDf,
   8207     TDM_ENTRY56_PORT_IDf, TDM_ENTRY57_PORT_IDf,
   8208     TDM_ENTRY58_PORT_IDf, TDM_ENTRY59_PORT_IDf,
   8209     TDM_ENTRY60_PORT_IDf, TDM_ENTRY61_PORT_IDf,
   8210     TDM_ENTRY62_PORT_IDf, TDM_ENTRY63_PORT_IDf
   8211 };
   8212 
   8213 static const soc_reg_t ap_pgw_ovs_tdm_regs[] = {
   8214     PGW_OS_TDM_REG_0r, PGW_OS_TDM_REG_1r,
   8215     PGW_OS_TDM_REG_2r, PGW_OS_TDM_REG_3r,
   8216     PGW_OS_TDM_REG_4r, PGW_OS_TDM_REG_5r,
   8217     PGW_OS_TDM_REG_6r, PGW_OS_TDM_REG_7r,
   8218     PGW_OS_TDM_REG_8r, PGW_OS_TDM_REG_9r
   8219 };
   8220 static const soc_reg_t ap_pgw_ovs_spacing_regs[] = {
   8221     PGW_OS_PORT_SPACING_REG_0r, PGW_OS_PORT_SPACING_REG_1r,
   8222     PGW_OS_PORT_SPACING_REG_2r, PGW_OS_PORT_SPACING_REG_3r,
   8223     PGW_OS_PORT_SPACING_REG_4r, PGW_OS_PORT_SPACING_REG_5r,
   8224     PGW_OS_PORT_SPACING_REG_6r, PGW_OS_PORT_SPACING_REG_7r,
   8225     PGW_OS_PORT_SPACING_REG_8r, PGW_OS_PORT_SPACING_REG_9r
   8226 };
   8227 static const soc_field_t ap_pgw_spacing_fields[] = {
   8228     SLOT0f, SLOT1f, SLOT2f, SLOT3f, SLOT4f, SLOT5f, SLOT6f, SLOT7f,
   8229     SLOT8f, SLOT9f, SLOT10f, SLOT11f, SLOT12f, SLOT13f, SLOT14f, SLOT15f,
   8230     SLOT16f, SLOT17f, SLOT18f, SLOT19f, SLOT20f, SLOT21f, SLOT22f, SLOT23f,
   8231     SLOT24f, SLOT25f, SLOT26f, SLOT27f, SLOT28f, SLOT29f, SLOT30f, SLOT31f,
   8232     SLOT32f, SLOT33f, SLOT34f, SLOT35f, SLOT36f, SLOT37f, SLOT38f, SLOT39f
   8233 };
   8234 
   8235 /* Registers are serviced in SPRI manner.
   8236  * e.g. PGW_HSP_CONFIG_0 is highest priority with PGW_HSP_CONFIG_8 the lowest.
   8237  * In order to minimise bunching of slots as much as possible, the order
   8238  * these should be programmed is like below
   8239  */
   8240 static const soc_reg_t pgw_hsp_config_regs[APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC] = {
   8241     PGW_HSP_CONFIG_1r, PGW_HSP_CONFIG_5r, PGW_HSP_CONFIG_3r, PGW_HSP_CONFIG_7r,
   8242     PGW_HSP_CONFIG_0r, PGW_HSP_CONFIG_4r, PGW_HSP_CONFIG_2r, PGW_HSP_CONFIG_6r
   8243 };
   8244 
   8245 static const soc_reg_t pgw_hsp_config_fields[APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC] = {
   8246     PHY_PORT_NO_1f, PHY_PORT_NO_5f, PHY_PORT_NO_3f, PHY_PORT_NO_7f,
   8247     PHY_PORT_NO_0f, PHY_PORT_NO_4f, PHY_PORT_NO_2f, PHY_PORT_NO_6f
   8248 };
   8249 
   8250 static const soc_reg_t ap_tdm_pgw_ctrl = PGW_TDM_CONTROLr;
   8251 static const soc_reg_t ap_tdm_mmu_ctrl = ES_PIPE0_TDM_CONFIGr;
   8252 static const soc_reg_t mmu_ovs_group_regs[APACHE_MMU_OVS_GROUP_COUNT] = {
   8253     ES_PIPE0_OVR_SUB_GRP0_TBLr, ES_PIPE0_OVR_SUB_GRP1_TBLr,
   8254     ES_PIPE0_OVR_SUB_GRP2_TBLr, ES_PIPE0_OVR_SUB_GRP3_TBLr,
   8255     ES_PIPE0_OVR_SUB_GRP4_TBLr, ES_PIPE0_OVR_SUB_GRP5_TBLr,
   8256     ES_PIPE0_OVR_SUB_GRP6_TBLr, ES_PIPE0_OVR_SUB_GRP7_TBLr
   8257 };
   8258 
   8259 static const soc_reg_t mmu_ovs_group_wt_regs[4] = {
   8260     ES_PIPE0_OVR_SUB_GRP_WT0r, ES_PIPE0_OVR_SUB_GRP_WT1r,
   8261     ES_PIPE0_OVR_SUB_GRP_WT2r, ES_PIPE0_OVR_SUB_GRP_WT3r
   8262 };
   8263 
   8264 /*
   8265  * MMU OVS TDM min. slot bandwidth is 5G.
   8266  * For FB5 family of devices:
   8267  * Anything less than 5G will be grouped together and will have provision for up to 5G.
   8268  *
   8269  * For MV,Rg2+, anything <=10G will be grouped together
   8270  */
   8271 #define APACHE_TDM_MMU_SPEED_GET(unit, speed)                                                               \
   8272     do {                                                                                                    \
   8273         speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);                                                     \
   8274         if ((speed <= 5000) && (speed > 0)) {                                                               \
   8275             speed = 10000;                                                                                 \
   8276             if (soc_feature(unit, soc_feature_untethered_otp)) {                                            \
   8277                 speed = (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureFamilyFirebolt5) ? 5000 : 10000);\
   8278             }                                                                                               \
   8279         }                                                                                                   \
   8280     } while (0)
   8281 
   8282 
   8283 #define AP_TDM_WT_GRP_SPG_GET(unit, _wtg)     ((AP_MISC(unit)->tdm_wtg_used[_wtg] & 0xff))
   8284 #define AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg)  ((AP_MISC(unit)->tdm_wtg_used[_wtg] >> 8) & 0xff)
   8285 
   8286 #define APACHE_TDM_WT_GRP_SPEED_GET(unit, _wtg)   ((AP_TDM_WT_GRP_SPG_GET(unit, _wtg) * 2500))
   8287 
   8288 
   8289 #define APACHE_TDM_WT_GRP_RESERVE(unit, _wtg, _spg)                    \
   8290     do {                                                               \
   8291         uint16 _tmp = (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) + 1);      \
   8292         AP_MISC(unit)->tdm_wtg_used[_wtg] = ((_spg) | (_tmp << 8));    \
   8293     } while (0)
   8294 
   8295 #define APACHE_TDM_WT_GRP_FREE(unit, _wtg)                             \
   8296     do {                                                               \
   8297         uint16 _tmp = (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) - 1);      \
   8298         if (AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) <= 1) {               \
   8299             soc_apache_misc_info[unit]->tdm_wtg_used[_wtg] = 0;        \
   8300         } else {                                                       \
   8301             soc_apache_misc_info[unit]->tdm_wtg_used[_wtg] =           \
   8302                 (AP_TDM_WT_GRP_SPG_GET(unit, _wtg) | (_tmp << 8));     \
   8303         }                                                              \
   8304     } while (0)
   8305 
   8306 #define APACHE_TDM_WT_GRP_LOG(unit)                                             \
   8307     do {                                                                        \
   8308         int _wtg;                                                               \
   8309         LOG_VERBOSE(BSL_LS_SOC_TDM,                                             \
   8310                     (BSL_META_U(unit,                                           \
   8311                                 "Weight groups and reference counts: \n\t")));  \
   8312         for (_wtg = 0; _wtg < 4; _wtg++)  {                                     \
   8313             LOG_VERBOSE(BSL_LS_SOC_TDM,                                         \
   8314                         (BSL_META_U(unit,                                       \
   8315                             "Grp = %d Refcnt = %d Speed Grp = %d Speed = %d;"), \
   8316                             _wtg, AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg),         \
   8317                             AP_TDM_WT_GRP_SPG_GET(unit, _wtg),                  \
   8318                             APACHE_TDM_WT_GRP_SPEED_GET(unit, _wtg)));          \
   8319         }                                                                       \
   8320         LOG_VERBOSE(BSL_LS_SOC_TDM, (BSL_META_U(unit, "\n")));                  \
   8321     } while (0)
   8322 
   8323 #define APACHE_TDM_WT_GRP_USABLE(unit, _wtg, _spg)   \
   8324     ((AP_TDM_WT_GRP_REFCNT_GET(unit, _wtg) == 0) || (AP_TDM_WT_GRP_SPG_GET(unit, _wtg) == _spg))
   8325 
   8326 #define APACHE_TDM_ACTIVE_CAL(unit) soc_apache_misc_info[unit]->tdm_active_cal
   8327 #define APACHE_TDM_STRUCT_ACTIVE(unit) (!APACHE_TDM_ACTIVE_CAL(unit)) ? \
   8328             &(soc_apache_misc_info[unit]->tdm0) : &(soc_apache_misc_info[unit]->tdm1)
   8329 #define APACHE_TDM_STRUCT_BACKUP(unit) (APACHE_TDM_ACTIVE_CAL(unit)) ? \
   8330             &(soc_apache_misc_info[unit]->tdm0) : &(soc_apache_misc_info[unit]->tdm1)
   8331 
   8332 #define APACHE_TDM_PGW_LR_REG(cur_cal, slot) ap_pgw_lr_tdm_regs[cur_cal][slot/4]
   8333 
   8334 #define APACHE_TDM_PGW_OS_REG(slot) ap_pgw_ovs_tdm_regs[slot/4]
   8335 
   8336 #define APACHE_TDM_PGW_OS_SPACING_REG(slot) ap_pgw_ovs_spacing_regs[slot/4]
   8337 
   8338 #define APACHE_TDM_PGW_SLOT(slot)  ap_pgw_tdm_fields[slot]
   8339 #define APACHE_TDM_PGW_OS_SPACING_FIELD(slot)  ap_pgw_spacing_fields[slot]
   8340 
   8341 #define APACHE_TDM_MMU_TBL(cur_cal) \
   8342             (!cur_cal) ? ES_PIPE0_TDM_TABLE_0m : ES_PIPE0_TDM_TABLE_1m
   8343 
   8344 #if !defined(SOC_NO_NAMES)
   8345 #define APACHE_TDM_PGW_LOG(_u, _desc, _r, _f, _v)            \
   8346             LOG_INFO(BSL_LS_SOC_COMMON,                      \
   8347                         (BSL_META_U(_u,                      \
   8348                                     _desc ": %s.%s = %d\n"), \
   8349                                     SOC_REG_NAME(_u, _r),    \
   8350                                     soc_fieldnames[_f], _v))
   8351 #else
   8352 #define APACHE_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \
   8353             LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(_u, _desc ": = %d\n"), _v))
   8354 #endif
   8355 
   8356 soc_error_t
   8357 _soc_apache_mmu_ovs_speed_class_map_get(int unit, int *speed, int *spg, uint32 *sp_spacing)
   8358 {
   8359     APACHE_TDM_MMU_SPEED_GET(unit, *speed);
   8360     switch (*speed) {
   8361         case 5000:
   8362             *sp_spacing = 0x14;
   8363             *spg = ap_ovs_speed_5G;
   8364             break;
   8365         case 10000:
   8366             *sp_spacing = 0x14;
   8367             *spg = ap_ovs_speed_10G;
   8368             break;
   8369         case 20000:
   8370             *sp_spacing = 0x0a;
   8371             *spg = ap_ovs_speed_20G;
   8372             break;
   8373         case 25000:
   8374             *sp_spacing = 0x0a;
   8375             *spg = ap_ovs_speed_25G;
   8376             break;
   8377         case 40000:
   8378             *sp_spacing = 0x0a;
   8379             *spg = ap_ovs_speed_40G;
   8380             break;
   8381         case 50000:
   8382             *sp_spacing = 0x0a;
   8383             *spg = ap_ovs_speed_50G;
   8384             break;
   8385         case 100000:
   8386             *sp_spacing = 0x04;
   8387             *spg = ap_ovs_speed_100G;
   8388             break;
   8389         default:
   8390             *sp_spacing = 0x0;
   8391             *spg = ap_ovs_speed_None;
   8392             return SOC_E_FAIL;
   8393     }
   8394 
   8395     return SOC_E_NONE;
   8396 }
   8397 
   8398 /*
   8399  * soc_apache_tdm_algo_freq_get
   8400  *
   8401  * TDM Algorithm differentiates between various static calendars used for 
   8402  * FB5 with the input core clock frequency.
   8403  * For all-OS, all-LR configs, TDM algo expects the actual core clock frequency 
   8404  * of the device and will calculate the calendars accordingly. 
   8405  * For mixed mode (LR + OS) ports, a unique core clock frequency is assigned for each SKU (FB5).
   8406  * This function maps the input core clock and SKU id to the clock frequency the tdm algo expects.
   8407  */
   8408 
   8409 STATIC int
   8410 soc_apache_tdm_algo_freq_get(int unit, int *core_clk_freq)
   8411 {
   8412     int oversub_mode;
   8413     uint16 dev_id;
   8414     uint8  rev_id;
   8415 #if defined(BCM_56560_A0) || defined(BCM_56560_B0)
   8416     soc_pbmp_t pbmp;
   8417     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
   8418 #endif
   8419 
   8420     oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
   8421     soc_cm_get_id(unit, &dev_id, &rev_id);
   8422 
   8423 
   8424     switch (oversub_mode) {
   8425         /* fall through */
   8426         case 0:          /* All Linerate */
   8427         case 1:          /* All Oversub  */
   8428             switch (dev_id) {
   8429                 case BCM56768_DEVICE_ID:
   8430                 case BCM56068_DEVICE_ID:
   8431                    *core_clk_freq = 840;
   8432                     break;
   8433                 default:
   8434                    *core_clk_freq = 793;
   8435                     break;
   8436             }
   8437             break;
   8438         case 2:         /* Mix of Linerate and Oversub */ 
   8439             switch (dev_id) {
   8440                 case BCM56565_DEVICE_ID:
   8441                     *core_clk_freq = 794;
   8442                     break;
   8443                 case BCM56567_DEVICE_ID:
   8444                     *core_clk_freq = 795;
   8445                     break;
   8446                 case BCM56568_DEVICE_ID:
   8447                     *core_clk_freq = 796;
   8448 
   8449 #if defined(BCM_56560_A0) || defined(BCM_56560_B0)
   8450                     if (SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 16) + 1]) &&
   8451                             !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 16) + 1]) &&
   8452                             SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 17) + 1]) &&
   8453                             !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 17) + 1])) {
   8454                         /* TSC16 and TSC 17 is in line rate */
   8455                         *core_clk_freq = 797;
   8456                     } else if ( SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 6) + 1]) &&
   8457                             !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 6) + 1]) &&
   8458                             SOC_PBMP_MEMBER(pbmp, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 9) + 1]) &&
   8459                             !IS_OVERSUB_PORT(unit, SOC_INFO(unit).port_p2l_mapping[(APACHE_PORTS_PER_TSC * 9) + 1])) {
   8460                         /*new config TSC 6 and TSC 9 are in line rate */
   8461                         *core_clk_freq = 798;
   8462                     }
   8463 #endif
   8464                     break;
   8465                 default:
   8466                     *core_clk_freq  = 793;
   8467                     break;
   8468             }
   8469             break;
   8470         default:
   8471             *core_clk_freq = 793;
   8472             break;
   8473     }
   8474    return SOC_E_NONE;
   8475 }
   8476 
   8477 STATIC int
   8478 soc_apache_tdm_calc(int unit, soc_apache_tdm_t *apache_tdm)
   8479 {
   8480     int rv, pgw, group, index;
   8481     tdm_soc_t apache_chip_pkg;
   8482     tdm_mod_t *apache_tdm_pkg;
   8483 
   8484     sal_memset(&apache_chip_pkg, 0, sizeof(tdm_soc_t));
   8485 
   8486     apache_chip_pkg.unit = unit;
   8487     apache_chip_pkg.num_ext_ports = AP_NUM_EXT_PORTS;
   8488     apache_chip_pkg.state = sal_alloc((apache_chip_pkg.num_ext_ports)*sizeof(int *), "port state list");
   8489     apache_chip_pkg.speed = sal_alloc((apache_chip_pkg.num_ext_ports)*sizeof(int *), "port speed list");
   8490 
   8491     for (index = 1; index < apache_chip_pkg.num_ext_ports; index++) {
   8492         apache_chip_pkg.state[index] = apache_tdm->port_state[index];
   8493     }
   8494     apache_chip_pkg.state[0] = 1;  /* enable cpu port */
   8495     apache_chip_pkg.state[73] = 1; /* enable loopback port */
   8496     apache_chip_pkg.state[74] = 1; /* enable RDB port */
   8497 
   8498     for (index = 0; index < apache_chip_pkg.num_ext_ports; index++) {
   8499         apache_chip_pkg.speed[index] = apache_tdm->speed[index];
   8500     }
   8501 
   8502 
   8503     if (soc_property_get(unit, "tdm_check_disable", 0)) {
   8504         apache_chip_pkg.soc_vars.ap.tdm_chk_en = 0;
   8505     } else {
   8506         apache_chip_pkg.soc_vars.ap.tdm_chk_en = 1;
   8507     }
   8508 
   8509 
   8510     SOC_IF_ERROR_RETURN(soc_apache_tdm_algo_freq_get(unit, &apache_chip_pkg.clk_freq));
   8511     apache_tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&apache_chip_pkg));
   8512 
   8513     if (!apache_tdm_pkg) {
   8514         LOG_CLI((BSL_META_U(unit,
   8515             "Unsupported config for TDM calendar generation\n")));
   8516         return SOC_E_FAIL;
   8517     }
   8518 
   8519     /*  PGW0 LR/OS Calendars */
   8520     sal_memcpy(apache_tdm->pgw_tdm[0],
   8521                apache_tdm_pkg->_chip_data.cal_0.cal_main,
   8522                sizeof(int)*APACHE_PGW_TDM_LENGTH);
   8523     sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[0],
   8524                apache_tdm_pkg->_chip_data.cal_0.cal_grp[0],
   8525                sizeof(int)*APACHE_PGW_TDM_OVS_SIZE);
   8526     sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[0],
   8527                apache_tdm_pkg->_chip_data.cal_0.cal_grp[1],
   8528                sizeof(int)*APACHE_PGW_TDM_OVS_SIZE);
   8529 
   8530     /*  PGW1 LR/OS Calendars */
   8531     sal_memcpy(apache_tdm->pgw_tdm[1],
   8532                apache_tdm_pkg->_chip_data.cal_1.cal_main,
   8533                sizeof(int)*APACHE_PGW_TDM_LENGTH);
   8534     sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[1],
   8535                apache_tdm_pkg->_chip_data.cal_1.cal_grp[0],
   8536                sizeof(int)*APACHE_PGW_TDM_OVS_SIZE);
   8537     sal_memcpy(apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[1],
   8538                apache_tdm_pkg->_chip_data.cal_1.cal_grp[1],
   8539                sizeof(int)*APACHE_PGW_TDM_OVS_SIZE);
   8540 
   8541     sal_memcpy(apache_tdm->mmu_tdm,
   8542                apache_tdm_pkg->_chip_data.cal_2.cal_main,
   8543                sizeof(int)*APACHE_MMU_TDM_LENGTH);
   8544 
   8545     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[0],
   8546                apache_tdm_pkg->_chip_data.cal_2.cal_grp[0],
   8547                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8548     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[1],
   8549                apache_tdm_pkg->_chip_data.cal_2.cal_grp[1],
   8550                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8551     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[2],
   8552                apache_tdm_pkg->_chip_data.cal_2.cal_grp[2],
   8553                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8554     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[3],
   8555                apache_tdm_pkg->_chip_data.cal_2.cal_grp[3],
   8556                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8557     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[4],
   8558                apache_tdm_pkg->_chip_data.cal_2.cal_grp[4],
   8559                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8560     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[5],
   8561                apache_tdm_pkg->_chip_data.cal_2.cal_grp[5],
   8562                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8563     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[6],
   8564                apache_tdm_pkg->_chip_data.cal_2.cal_grp[6],
   8565                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8566     sal_memcpy(apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[7],
   8567                apache_tdm_pkg->_chip_data.cal_2.cal_grp[7],
   8568                sizeof(int)*APACHE_MMU_OVS_GROUP_TDM_LENGTH);
   8569 
   8570     sal_free(apache_chip_pkg.state);
   8571     sal_free(apache_chip_pkg.speed);
   8572 
   8573     apache_tdm_pkg->_chip_exec[TDM_CHIP_EXEC__FREE](apache_tdm_pkg);
   8574     sal_free(apache_tdm_pkg);
   8575 
   8576     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   8577         for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) {
   8578             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_tdm:"), pgw));
   8579             for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) {
   8580                 if (index % 16 == 0) {
   8581                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8582                 }
   8583                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8584                            apache_tdm->pgw_tdm[pgw][index]));
   8585             }
   8586             LOG_CLI((BSL_META_U(unit, "\n")));
   8587             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_tdm:"), pgw));
   8588             for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) {
   8589                 if (index % 16 == 0) {
   8590                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8591                 }
   8592                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8593                            apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][index]));
   8594             }
   8595             LOG_CLI((BSL_META_U(unit, "\n")));
   8596             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_spacing:"), pgw));
   8597             for (index = 0; index < APACHE_PGW_TDM_LENGTH; index++) {
   8598                 if (index % 16 == 0) {
   8599                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8600                 }
   8601                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8602                              apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][index]));
   8603             }
   8604             LOG_CLI((BSL_META_U(unit, "\n")));
   8605         }
   8606         LOG_CLI((BSL_META_U(unit, "mmu_tdm:")));
   8607         for (index = 0; index < APACHE_MMU_TDM_LENGTH; index++) {
   8608             if (index % 16 == 0) {
   8609                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   8610             }
   8611             LOG_CLI((BSL_META_U(unit, " %3d"),
   8612                        apache_tdm->mmu_tdm[index]));
   8613         }
   8614         LOG_CLI((BSL_META_U(unit, "\n")));
   8615         for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
   8616             LOG_CLI((BSL_META_U(unit, "group %d ovs_group_tdm"), group));
   8617             for (index = 0; index < APACHE_MMU_OVS_GROUP_TDM_LENGTH;
   8618                  index++) {
   8619                 if (index % 16 == 0) {
   8620                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8621                 }
   8622                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8623                            apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][index]));
   8624             }
   8625             LOG_CLI((BSL_META_U(unit, "\n")));
   8626         }
   8627     }
   8628 
   8629     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   8630         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), apache_tdm->tdm_bw));
   8631         LOG_CLI((BSL_META_U(unit, "ovs state: %d\n"),
   8632                    apache_tdm->is_oversub));
   8633     }
   8634 
   8635 
   8636     rv = tdm_ap_set_iarb_tdm(apache_tdm->tdm_bw,
   8637                             apache_tdm->is_oversub,
   8638                             &apache_tdm->iarb_tdm_wrap_ptr,
   8639                             apache_tdm->iarb_tdm);
   8640 
   8641     if (rv == 0) {
   8642         LOG_CLI((BSL_META_U(unit,
   8643                    "Unsupported config for TDM calendar generation\n")));
   8644         return SOC_E_FAIL;
   8645     }
   8646 
   8647     if ((LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO))) {
   8648         LOG_CLI((BSL_META_U(unit,
   8649                    "iarb_tdm: (wrap_ptr %d)"),
   8650                    apache_tdm->iarb_tdm_wrap_ptr));
   8651         for (index = 0; index < APACHE_IARB_TDM_LENGTH; index++) {
   8652             if (index > apache_tdm->iarb_tdm_wrap_ptr) {
   8653                 break;
   8654             }
   8655             if (index % 16 == 0) {
   8656                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   8657             }
   8658             LOG_CLI((BSL_META_U(unit, " %3d"),
   8659                        apache_tdm->iarb_tdm[index]));
   8660         }
   8661         LOG_CLI((BSL_META_U(unit, "\n")));
   8662     }
   8663 
   8664     return SOC_E_NONE;
   8665 }
   8666 
   8667 
   8668 STATIC int
   8669 soc_apache_tdm_update(int unit, int init_time, int cur_cal,
   8670                       soc_apache_tdm_t *apache_tdm)
   8671 {
   8672     int rv;
   8673     int count, slot;
   8674     int pgw, pgw_inst, length;
   8675     int pgw_hsp_config_index[APACHE_PGWS_PER_DEV] = {0, 0};
   8676     int mmu_idle_port_ix = 0;
   8677     int mmu_idle_ports[] = {76, 78, 79, 80}; /* IDLE MMU ports in Apache */
   8678 
   8679     soc_port_t port, phy_port, mmu_port;
   8680     soc_port_t pgw_clp_ports[APACHE_PGWS_PER_DEV] = {29, 65};
   8681 
   8682     soc_mem_t mem;
   8683     soc_reg_t reg, hsp_reg;
   8684     soc_field_t field, cal_end_f, cal_end_single_f, lr_tdm_wrap_f, hsp_fields[2];
   8685     es_pipe0_tdm_table_0_entry_t entry;
   8686 
   8687     uint32 rval, hsp_values[2];
   8688     uint64 rval64, ctrl_rval64;
   8689 
   8690     soc_info_t *si;
   8691 
   8692     int index, group, weight, wt_group;
   8693     int speed_class, speed_group, speed;
   8694     uint32 wt_group_select = 0;
   8695     uint32 same_spacing = 0;
   8696     uint32 speed_spacing = 0;
   8697 
   8698 
   8699     si = &SOC_INFO(unit);
   8700 
   8701     /* Configure PGW TDM for APACHE */
   8702     for (pgw = 0; pgw < APACHE_PGWS_PER_DEV; pgw++) {
   8703 
   8704         /* coverity[negative_returns : FALSE] */
   8705         if (!SOC_INFO(unit).block_valid[PGW_CL_BLOCK(unit, pgw)]) {
   8706             continue;
   8707         }
   8708 
   8709         pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK;
   8710 
   8711         rv = soc_reg_get(unit, ap_tdm_pgw_ctrl, pgw_inst, 0, &ctrl_rval64);
   8712         SOC_IF_ERROR_RETURN(rv);
   8713 
   8714         /* Configure PGW line rate ports TDM */
   8715         count = 0;
   8716         COMPILER_64_ZERO(rval64);
   8717 
   8718         for (slot= 0; slot < APACHE_PGW_TDM_LENGTH; slot++) {
   8719 
   8720             reg = APACHE_TDM_PGW_LR_REG(cur_cal, slot);
   8721             field = APACHE_TDM_PGW_SLOT(slot);
   8722 
   8723             phy_port = apache_tdm->pgw_tdm[pgw][slot];
   8724 
   8725             if (phy_port == NUM_EXT_PORTS) {
   8726                 phy_port = 0xff;
   8727                 if (slot % APACHE_PGW_TDM_SLOTS_PER_REG) {
   8728                     break;
   8729                 }
   8730             } else {
   8731                 if (phy_port == OVS_TOKEN) {
   8732                     phy_port = 0x4b;
   8733                 }
   8734                 count++;
   8735             }
   8736 
   8737 
   8738             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8739 
   8740             APACHE_TDM_PGW_LOG(unit, "PGW LR TDM config", reg, field, phy_port);
   8741 
   8742             if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) {
   8743 
   8744                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8745                 COMPILER_64_ZERO(rval64);
   8746             }
   8747         }
   8748 
   8749         lr_tdm_wrap_f = (!cur_cal) ? LR_TDM_WRAP_PTRf : LR_TDM2_WRAP_PTRf;
   8750   
   8751         if (count > 0) {
   8752             soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8753                                   lr_tdm_wrap_f, count - 1);
   8754         }
   8755         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8756                               LR_TDM_SELf, cur_cal);
   8757         /* Always set both LR_TDM_ENABLE and LR_TDM2_ENABLE.
   8758          * Even when switching, we need to make sure the the current
   8759          * calendar is active so that it services the slots until the
   8760          * end of the calendar when it actually switches to the new one.
   8761  */
   8762         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8763                               LR_TDM_ENABLEf, 1);
   8764         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8765                               LR_TDM2_ENABLEf, 1);
   8766 
   8767         /* Configure PGW oversubscription ports TDM */
   8768         count = 0;
   8769         COMPILER_64_ZERO(rval64);
   8770 
   8771         for (slot= 0; slot < APACHE_PGW_TDM_OVS_SIZE; slot++) {
   8772 
   8773             reg = APACHE_TDM_PGW_OS_REG(slot);
   8774             field = APACHE_TDM_PGW_SLOT(slot);
   8775 
   8776             phy_port = apache_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][slot];;
   8777             APACHE_TDM_PGW_LOG(unit, "PGW OS TDM config", reg, field, phy_port);
   8778 
   8779             if (phy_port == NUM_EXT_PORTS) {
   8780                 phy_port = 0xff;
   8781             } else {
   8782                 count++;
   8783             }
   8784 
   8785             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8786 
   8787             if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) {
   8788 
   8789                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8790                 COMPILER_64_ZERO(rval64);
   8791             }
   8792         }
   8793 
   8794         /* Enable os_skip_cnt_arb_sel by default in Apache */
   8795         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8796                               OS_SKIP_CNT_ARB_SELf, TRUE);
   8797 
   8798         for (phy_port = pgw_clp_ports[pgw];
   8799              phy_port < pgw_clp_ports[pgw] + (APACHE_NUM_CLP_PER_PGW * APACHE_PORTS_PER_TSC);
   8800              phy_port++)
   8801         {
   8802             port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8803             hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]];
   8804             hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]];
   8805             hsp_fields[1] = ENTRIES_IN_CALf;
   8806 
   8807             if ((port == -1) || !IS_OVERSUB_PORT(unit, port)) {
   8808                 hsp_values[0] = 0x0;
   8809                 hsp_values[1] = 0x0;
   8810             } else {
   8811                 hsp_values[0] = phy_port;
   8812                 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(SOC_INFO(unit).port_speed_max[port]);
   8813                 hsp_values[1] = speed < 10000 ? 1 : ((speed + 5000) / 10000) ;
   8814             }
   8815             rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst,
   8816                                          2, hsp_fields, hsp_values);
   8817             SOC_IF_ERROR_RETURN(rv);
   8818             pgw_hsp_config_index[pgw] += 1;
   8819         }
   8820 
   8821         /* OS_TDM_WRAP_PTR and OS_TDM_ENABLE programming */
   8822         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8823                               OS_TDM_WRAP_PTRf, (count - 1));
   8824         soc_reg64_field32_set(unit, ap_tdm_pgw_ctrl, &ctrl_rval64,
   8825                               OS_TDM_ENABLEf, count ? 1 : 0);
   8826 
   8827         /* Configure PGW oversubscription port spacing */
   8828         COMPILER_64_ZERO(rval64);
   8829         for (slot= 0; slot < APACHE_PGW_TDM_OVS_SIZE; slot++) {
   8830 
   8831             reg = APACHE_TDM_PGW_OS_SPACING_REG(slot);
   8832             field = APACHE_TDM_PGW_OS_SPACING_FIELD(slot);
   8833 
   8834             phy_port = apache_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][slot];
   8835             APACHE_TDM_PGW_LOG(unit, "PGW OS Spacing config", reg, field, phy_port);
   8836 
   8837             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8838 
   8839             if (((slot + 1) % APACHE_PGW_TDM_SLOTS_PER_REG) == 0) {
   8840                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8841                 COMPILER_64_ZERO(rval64);
   8842             }
   8843         }
   8844 
   8845 
   8846         rv = soc_reg_set(unit, ap_tdm_pgw_ctrl, pgw_inst, 0, ctrl_rval64);
   8847         SOC_IF_ERROR_RETURN(rv);
   8848     }
   8849 
   8850 
   8851     /* Configure MMU TDM */
   8852     mem = APACHE_TDM_MMU_TBL(cur_cal);
   8853 
   8854     length = APACHE_MMU_TDM_LENGTH;
   8855     while ((apache_tdm->mmu_tdm[length] == NUM_EXT_PORTS)) {
   8856         length--;
   8857     }
   8858 
   8859     rv = soc_reg32_get(unit, ap_tdm_mmu_ctrl, REG_PORT_ANY, 0, &rval);
   8860     SOC_IF_ERROR_RETURN(rv);
   8861 
   8862     sal_memset(&entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
   8863 
   8864     for (slot = 0; slot <= length; slot++) {
   8865 
   8866         phy_port = apache_tdm->mmu_tdm[slot];
   8867 
   8868         /*
   8869          * TDM algo inserts CMIC, LB and ANC tokens for Auxillary
   8870          * bandwidth in each TDM. ANC token needs to be replaced with
   8871          * internal port 77 and CMIC & LB will be mapped to their mmu ports.
   8872          *
   8873          * Each TDM will also have a dedicated slot for guaranteed SBUS ops.
   8874          * While the ANC slots can be used for SBUS as well, there could be
   8875          * cases where the PRG (being of higher priority over SBUS) hogs SBUS
   8876          * operations from getting handled. MMU port 81 will be programmed for
   8877          * these tokens appearing in the algorithm.
   8878          *
   8879          * For unclaimed bandwidth (compared to max LR BW) from each config,
   8880          * TDM algo inserts IDLE tokens. The idle tokens needs to be replaced
   8881          * with internal mmu ports for Purge or SBUS operations. However, since
   8882          * Hardware flags 1in4 violation errors even with these internal mmu
   8883          * ports, we would iterate over all available internal ports (leaving out
   8884          * ANC port - 77, of course).
   8885  */
   8886 
   8887         if ((phy_port == SBUS_TOKEN)) {
   8888             mmu_port = 81; /* Dedicated token for guaranteed SBUS ops */
   8889         } else if (phy_port == AUX_TOKEN) {
   8890             mmu_port = 77; /* Dedicated ANC slot */ 
   8891         } else if(phy_port == IDL1_TOKEN) {
   8892             /* iter over all available internal ports to avoid 1:4 violation */
   8893             mmu_port = mmu_idle_ports[mmu_idle_port_ix];
   8894             mmu_idle_port_ix = (mmu_idle_port_ix + 1) % COUNTOF(mmu_idle_ports);
   8895         } else if (phy_port == OVS_TOKEN) {
   8896             mmu_port = 75; /* Oversub port */
   8897         } else if (phy_port >= NUM_EXT_PORTS) {
   8898             mmu_port = 0x7f; /* Invalid Port */
   8899         } else {
   8900             mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
   8901         }
   8902 
   8903         field = (slot % 2) ? PORT_NUM_ODDf : PORT_NUM_EVENf;
   8904         if (mmu_port == -1) {
   8905             return SOC_E_FAIL;
   8906         }
   8907         soc_mem_field32_set(unit, mem, &entry, field, mmu_port);
   8908 
   8909         /* two slots in each entry; length can be odd too */
   8910         if ((slot % 2) || (slot == length)) {
   8911             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   8912                                               (slot / 2), &entry));
   8913         }
   8914     }
   8915 
   8916     cal_end_f = (cur_cal) ? CAL1_ENDf : CAL0_ENDf;
   8917     cal_end_single_f = (cur_cal) ? CAL1_END_SINGLEf : CAL0_END_SINGLEf;
   8918 
   8919     /*
   8920      * Examples:
   8921      *   1) cal length = 401; cal_end = 401/2 - 0 = 200, cal_end_single = 1
   8922      *   2) cal length = 402; cal_end = 402/2 - 1 = 200, cal_end_single = 0
   8923  */
   8924     soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, cal_end_f,
   8925                       (slot % 2) ? (slot / 2): ((slot / 2) - 1));
   8926     if (slot % 2) {
   8927         soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, cal_end_single_f, 1);
   8928     }
   8929     
   8930     soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, OPP_CPULB_ENf, 1);
   8931     soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, ENABLEf, 1);
   8932     soc_reg_field_set(unit, ap_tdm_mmu_ctrl, &rval, CURR_CALf, cur_cal);
   8933     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ap_tdm_mmu_ctrl, REG_PORT_ANY, 0, rval));
   8934 
   8935 
   8936     rval = 0;
   8937     for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
   8938         speed_class = apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group];
   8939         reg = mmu_ovs_group_regs[group];
   8940         for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
   8941 
   8942             phy_port = apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot];
   8943             if (phy_port >= NUM_EXT_PORTS) {
   8944                 mmu_port = 0x7f;
   8945             } else {
   8946                 mmu_port = si->port_p2m_mapping[phy_port];
   8947                 if (speed_class == 0) {
   8948                     speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]];
   8949                 }
   8950             }
   8951             soc_reg_field_set(unit, reg, &rval, MMU_PORTf, (mmu_port & 0x7f));
   8952             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval));
   8953         }
   8954 
   8955         if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get(
   8956                         unit, &speed_class, &speed_group, &speed_spacing))) {
   8957             continue;
   8958         }
   8959 
   8960         if (init_time) {
   8961 
   8962             for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
   8963                 if (APACHE_TDM_WT_GRP_USABLE(unit, wt_group, speed_group)) {
   8964                     APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
   8965                     break;
   8966                 }
   8967             }
   8968 
   8969             APACHE_TDM_WT_GRP_LOG(unit);
   8970 
   8971             apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
   8972             apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
   8973 
   8974         } else {
   8975             wt_group = apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group];
   8976             speed_class = apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group];
   8977         }
   8978  
   8979         if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) {
   8980             return SOC_E_INTERNAL;
   8981         }
   8982 
   8983         /* Apache supports 4 oversub speeds only */
   8984         soc_reg_field_set(unit, ES_PIPE0_GRP_WT_SELECTr, &wt_group_select,
   8985                          ap_mmu_ovs_group_wt_select_fields[group], wt_group);
   8986         reg = ES_PIPE0_OVR_SUB_GRP_CFGr;
   8987         soc_reg_field_set(unit, reg, &same_spacing, SAME_SPACINGf, speed_spacing);
   8988         rv = soc_reg32_set(unit, reg, REG_PORT_ANY, group, same_spacing);
   8989         SOC_IF_ERROR_RETURN(rv);
   8990 
   8991 
   8992     }
   8993 
   8994     for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
   8995 
   8996         speed_class = APACHE_TDM_WT_GRP_SPEED_GET(unit, wt_group);
   8997         if (speed_class == 0) {
   8998             weight = 0x0;
   8999         } else {
   9000             /* use 2500M as weight unit */
   9001             weight = (speed_class > 2500 ? speed_class : 2500) / 2500;
   9002         }
   9003         reg = mmu_ovs_group_wt_regs[wt_group];
   9004         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval);
   9005         SOC_IF_ERROR_RETURN(rv);
   9006 
   9007         /* The proportional weights are already programmed  */
   9008         if (soc_reg_field_get(unit, reg, rval, WEIGHTf) == weight) {
   9009             continue;
   9010         }
   9011 
   9012         for (index = 0; index < APACHE_MMU_OVS_GROUP_TDM_LENGTH; index++) {
   9013             soc_reg_field_set(unit, reg, &rval, WEIGHTf, (weight * (index + 1)));
   9014             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, index, rval));
   9015         }
   9016     }
   9017 
   9018 
   9019     reg = ES_PIPE0_GRP_WT_SELECTr;
   9020     rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, wt_group_select);
   9021     SOC_IF_ERROR_RETURN(rv);
   9022 
   9023 
   9024     return SOC_E_NONE;
   9025 }
   9026 
   9027 STATIC int soc_ap_port_resource_tdm_calculate(int unit, soc_apache_tdm_t *tdm);
   9028 
   9029 
   9030 STATIC int
   9031 soc_apache_tdm_reinit(int unit)
   9032 {
   9033     soc_reg_t reg;
   9034     int phy_port, mmu_port;
   9035     int slot, group, wt_group, speed_group, speed_class;
   9036     uint32 rval, wt_group_select, speed_spacing;
   9037 
   9038     soc_apache_tdm_t *apache_tdm;
   9039     soc_info_t *si = &SOC_INFO(unit);
   9040 
   9041     reg = ES_PIPE0_TDM_CONFIGr;
   9042     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9043     APACHE_TDM_ACTIVE_CAL(unit) = soc_reg_field_get(unit, reg, rval, CURR_CALf);
   9044 
   9045     apache_tdm = APACHE_TDM_STRUCT_ACTIVE(unit);
   9046 
   9047     SOC_IF_ERROR_RETURN(soc_ap_port_resource_tdm_calculate(unit, apache_tdm));
   9048 
   9049     reg = ES_PIPE0_GRP_WT_SELECTr;
   9050     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &wt_group_select));
   9051 
   9052 
   9053     for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
   9054         speed_class = 0;
   9055         speed_group = 0;
   9056         reg = mmu_ovs_group_regs[group];
   9057 
   9058         wt_group = soc_reg_field_get(unit, ES_PIPE0_GRP_WT_SELECTr, wt_group_select,
   9059                                      ap_mmu_ovs_group_wt_select_fields[group]);
   9060 
   9061         for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
   9062 
   9063             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval));
   9064             mmu_port = soc_reg_field_get(unit, reg, rval, MMU_PORTf);
   9065 
   9066             if (mmu_port == 0x7f) {
   9067                 phy_port = NUM_EXT_PORTS;
   9068             } else {
   9069                 phy_port = SOC_INFO(unit).port_m2p_mapping[mmu_port];
   9070                 if (speed_class == 0) {
   9071                     speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]];
   9072 
   9073                     if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get(
   9074                                     unit, &speed_class, &speed_group, &speed_spacing))) {
   9075                         continue;
   9076                     }
   9077                     APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
   9078                 }
   9079             }
   9080             apache_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port;
   9081         }
   9082         APACHE_TDM_WT_GRP_LOG(unit);
   9083 
   9084         apache_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
   9085         apache_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
   9086     }
   9087 
   9088     return SOC_E_NONE;
   9089 }
   9090 
   9091 
   9092 STATIC int
   9093 soc_apache_tdm_init(int unit)
   9094 {
   9095     soc_info_t *si;
   9096     soc_pbmp_t pbmp;
   9097 
   9098     int rv, index, cur_cal;
   9099     int slot, port, phy_port, mmu_port;
   9100     soc_apache_tdm_t *apache_tdm;
   9101 
   9102     uint32 rval;
   9103     uint32 entry[SOC_MAX_MEM_WORDS];
   9104     uint32 values[4];
   9105     soc_field_t fields[4];
   9106 
   9107     soc_mem_t mem;
   9108     static const soc_mem_t iarb_tdm_mem = IARB_MAIN_TDMm;
   9109 
   9110     cur_cal = APACHE_TDM_ACTIVE_CAL(unit);
   9111     apache_tdm = APACHE_TDM_STRUCT_ACTIVE(unit);
   9112 
   9113     sal_memset(apache_tdm, 0, sizeof(soc_apache_tdm_t));
   9114 
   9115     si = &SOC_INFO(unit);
   9116 
   9117     PBMP_PORT_ITER(unit, port) {
   9118         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   9119             continue;
   9120         }
   9121         phy_port = si->port_l2p_mapping[port];
   9122 
   9123         apache_tdm->speed[phy_port] = si->port_speed_max[port];
   9124         APACHE_TDM_SPEED_ADJUST(unit, port, apache_tdm->speed[phy_port]);
   9125 
   9126         apache_tdm->port_state[phy_port] =
   9127             IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE;
   9128 
   9129         /*
   9130          * Primary port will be setup as line-rate or oversub.
   9131          * Subsequent physical ports (sister-ports) will be either
   9132          * DISABLED or SUBPORT/COMBINED mode.
   9133          *
   9134          * TDM Algo expects lanes info based on speed.
   9135          */
   9136         if (soc_apache_port_is_falcon(unit, phy_port)) { /*  Falcons  */
   9137             if (apache_tdm->speed[phy_port] > 25000) {
   9138                 apache_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
   9139             }
   9140             if (apache_tdm->speed[phy_port] > 50000) {
   9141                 apache_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
   9142                 apache_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
   9143             }
   9144         } else {                                         /*  Eagles  */
   9145             if (apache_tdm->speed[phy_port] > 10000) {
   9146                 apache_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
   9147             }
   9148             if (apache_tdm->speed[phy_port] > 20000) {
   9149                 apache_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
   9150                 apache_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
   9151             }
   9152             if (apache_tdm->speed[phy_port] > 40000) {
   9153                 apache_tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT;
   9154                 apache_tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT;
   9155                 apache_tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT;
   9156                 apache_tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT;
   9157                 apache_tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT;
   9158                 apache_tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT;
   9159             }
   9160         }
   9161 
   9162     }
   9163 
   9164     /* CPU, LB and RDB ports */
   9165     apache_tdm->speed[0] = 1000;
   9166     apache_tdm->speed[73] = 1000;
   9167     apache_tdm->speed[74] = 1000;
   9168 
   9169     apache_tdm->tdm_bw = si->bandwidth / 1000;
   9170 
   9171     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
   9172     SOC_PBMP_AND(pbmp, si->xpipe_pbm);
   9173 
   9174     /* tell tdm code the device is oversub if any ports is oversub */
   9175     apache_tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp);
   9176     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
   9177 
   9178     for (slot = 0; slot <= APACHE_MMU_TDM_LENGTH; slot++) {
   9179         apache_tdm->mmu_tdm[slot] = NUM_EXT_PORTS;
   9180     }
   9181 
   9182     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   9183         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), apache_tdm->tdm_bw));
   9184         LOG_CLI((BSL_META_U(unit, "port speed:")));
   9185         for (index = 0; index < NUM_EXT_PORTS; index++) {
   9186             if (index % 8 == 0) {
   9187                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   9188             }
   9189             LOG_CLI((BSL_META_U(unit, " %06d(%03d)"),
   9190                      apache_tdm->speed[index], index));
   9191         }
   9192         LOG_CLI((BSL_META_U(unit, "\n")));
   9193         LOG_CLI((BSL_META_U(unit, "port state map:")));
   9194         for (index = 0; index < NUM_EXT_PORTS; index++) {
   9195             if (index % 8 == 0) {
   9196                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   9197             }
   9198             if (index == 0 || index == (NUM_EXT_PORTS - 1)) {
   9199                 LOG_CLI((BSL_META_U(unit, " --------")));
   9200             } else {
   9201                 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"),
   9202                          apache_tdm->port_state[index], index));
   9203             }
   9204         }
   9205         LOG_CLI((BSL_META_U(unit, "\n")));
   9206     }
   9207 
   9208 
   9209     SOC_IF_ERROR_RETURN(soc_apache_tdm_calc(unit, apache_tdm));
   9210 
   9211     SOC_IF_ERROR_RETURN(soc_apache_tdm_update(unit, 1, cur_cal, apache_tdm));
   9212 
   9213 
   9214     /* Configure IARB TDM */
   9215     mem = iarb_tdm_mem;
   9216     sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
   9217     for (slot = 0; slot < APACHE_IARB_TDM_LENGTH; slot++) {
   9218         if (slot > apache_tdm->iarb_tdm_wrap_ptr) {
   9219             break;
   9220         }
   9221         if (apache_tdm->iarb_tdm[slot] > 0x7) {
   9222             LOG_ERROR(BSL_LS_SOC_COMMON,
   9223                       (BSL_META_U(unit,
   9224                                   "Invalid IARB TDM slot(%d) = %d !!\n"),
   9225                                   slot, apache_tdm->iarb_tdm[slot]));
   9226         }
   9227         soc_mem_field32_set(unit, mem, entry, TDM_SLOTf,
   9228                             apache_tdm->iarb_tdm[slot]);
   9229         SOC_IF_ERROR_RETURN
   9230             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry));
   9231     }
   9232 
   9233     /* IARB_TDM_CONTROL */
   9234     fields[0] = TDM_WRAP_PTRf;
   9235     values[0] = apache_tdm->iarb_tdm_wrap_ptr;
   9236     fields[1] = DISABLEf;
   9237     values[1] = 0;
   9238     SOC_IF_ERROR_RETURN
   9239         (soc_reg_fields32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY, 2,
   9240                                  fields, values));
   9241 
   9242     /* IARB_OPP_SCH_CONTROL */
   9243     fields[0] = RDB_OPP_ENf;
   9244     values[0] = 1;
   9245     fields[1] = LB_OPP_ENf;
   9246     values[1] = 1;
   9247     SOC_IF_ERROR_RETURN
   9248         (soc_reg_fields32_modify(unit, IARB_OPP_SCH_CONTROLr, REG_PORT_ANY, 2,
   9249                                  fields, values));
   9250     rval = 0;
   9251     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_CFAP_FULL_DROP_ENf, 1);
   9252     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_FIFO_THRESHOLDf, 3);
   9253     soc_reg_field_set(unit, ENQ_CONFIGr, &rval, ASF_HS_FIFO_THRESHOLDf, 13);
   9254     SOC_IF_ERROR_RETURN(WRITE_ENQ_CONFIGr(unit, rval));
   9255 
   9256 
   9257     fields[0] = FIELD_Af;
   9258     values[0] = 1023;
   9259     fields[1] = FIELD_Bf;
   9260     values[1] = 9215;
   9261     fields[2] = FIELD_Cf;
   9262     values[2] = 16;
   9263     rv = soc_reg_fields32_modify(unit, EGR_FORCE_SAF_CONFIGr, REG_PORT_ANY, 3, fields, values);
   9264     SOC_IF_ERROR_RETURN(rv);
   9265 
   9266     fields[0] = FIELD_Af;
   9267     values[0] = 1;
   9268     fields[1] = DI_ACT_THRf;
   9269     values[1] = 20;
   9270     rv = soc_reg_fields32_modify(unit, ES_PIPE0_MMU_1DBG_Cr, REG_PORT_ANY, 2, fields, values);
   9271     SOC_IF_ERROR_RETURN(rv);
   9272 
   9273     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_DI_THRr, REG_PORT_ANY, OS_SLT_LMTf, 1000);
   9274     SOC_IF_ERROR_RETURN(rv);
   9275 
   9276     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_1r, REG_PORT_ANY, FIELD_Bf, 0);
   9277     SOC_IF_ERROR_RETURN(rv);
   9278     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_0r, REG_PORT_ANY,
   9279                                 FIELD_Af, (si->frequency * 200));
   9280     SOC_IF_ERROR_RETURN(rv);
   9281 
   9282 
   9283     /* values array for filling mmu_1dbg_a regs  */
   9284     values[0] = values[1] = values[2] = 0;
   9285 
   9286     PBMP_PORT_ITER(unit, port) {
   9287 
   9288         phy_port = si->port_l2p_mapping[port];
   9289         if (phy_port == -1 ) {
   9290             continue;
   9291         }
   9292         mmu_port = si->port_p2m_mapping[phy_port];
   9293         if (mmu_port == -1) {
   9294             continue;
   9295         }
   9296 
   9297         SOC_IF_ERROR_RETURN(soc_ap_mmu_delay_insertion_set(unit, port));
   9298 
   9299 
   9300         if (IS_OVERSUB_PORT(unit, port)) {
   9301 
   9302             rval = ((si->port_speed_max[port] / 1000) *
   9303                     (12148125 / (si->frequency * 100)));
   9304             rv = soc_mem_field32_modify(unit, EDB_1DBG_Bm, phy_port, FIELD_Bf, rval);
   9305             SOC_IF_ERROR_RETURN(rv);
   9306 
   9307             if (mmu_port < 32) {          /* mmu_port in [0, 32)  */
   9308                 values[0] |= (1 << mmu_port);
   9309             } else if (mmu_port < 64) {   /* mmu_port in [32, 64) */ 
   9310                 values[1] |= (1 << (mmu_port - 32));
   9311             } else {                      /* mmu_port in [64, 74)  */
   9312                 values[2] |= (1 << (mmu_port - 64));
   9313             }
   9314         }
   9315     }
   9316 
   9317     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_LOr, REG_PORT_ANY, FIELD_Af, values[0]);
   9318     SOC_IF_ERROR_RETURN(rv);
   9319     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_MIDr, REG_PORT_ANY, FIELD_Af, values[1]);
   9320     SOC_IF_ERROR_RETURN(rv);
   9321     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_1DBG_A_HIr, REG_PORT_ANY, FIELD_Af, values[2]);
   9322     SOC_IF_ERROR_RETURN(rv);
   9323 
   9324     return SOC_E_NONE;
   9325 }
   9326 
   9327 STATIC int
   9328 _soc_apache_hash_init(int unit)
   9329 {
   9330     soc_field_t fields[4];
   9331     uint32 values[4];
   9332 
   9333     /* L2 dedicated banks */
   9334     fields[0] = BANK0_HASH_OFFSETf;
   9335     values[0] = 0;  /* CRC32_LOWER */
   9336     fields[1] = BANK1_HASH_OFFSETf;
   9337     values[1] = 16; /* CRC32_UPPER */
   9338     SOC_IF_ERROR_RETURN
   9339         (soc_reg_fields32_modify(unit, L2_TABLE_HASH_CONTROLr, REG_PORT_ANY, 2,
   9340                                  fields, values));
   9341 
   9342     /* L3 dedicated banks */
   9343     fields[0] = BANK6_HASH_OFFSETf;
   9344     values[0] = 0;  /* CRC32_LOWER */
   9345     fields[1] = BANK7_HASH_OFFSETf;
   9346     values[1] = 12;  /* CRC32 >> 12 */
   9347     fields[2] = BANK8_HASH_OFFSETf;
   9348     values[2] = 24; /* CRC16_LOWER << 8 | CRC32 >> 24 */
   9349     fields[3] = BANK9_HASH_OFFSETf;
   9350     values[3] = 36; /* CRC16 >> 4 */
   9351     SOC_IF_ERROR_RETURN
   9352         (soc_reg_fields32_modify(unit, L3_TABLE_HASH_CONTROLr, REG_PORT_ANY, 4,
   9353                                  fields, values));
   9354 
   9355     /* L2/L3/ALPM shared banks */
   9356     fields[0] = BANK2_HASH_OFFSETf;
   9357     values[0] = 4;  /* CRC32 >> 4 */
   9358     fields[1] = BANK3_HASH_OFFSETf;
   9359     values[1] = 12; /* CRC32 >> 12 */
   9360     fields[2] = BANK4_HASH_OFFSETf;
   9361     values[2] = 20; /* CRC32 >> 20 */
   9362     fields[3] = BANK5_HASH_OFFSETf;
   9363     values[3] = 24; /* CRC32 >> 24 */
   9364     SOC_IF_ERROR_RETURN
   9365         (soc_reg_fields32_modify(unit, SHARED_TABLE_HASH_CONTROLr,
   9366                                  REG_PORT_ANY, 4, fields, values));
   9367 
   9368 #ifdef SOC_ROBUST_HASH
   9369     /* Robust Hash initialization */
   9370     if (soc_feature(unit, soc_feature_robust_hash)) {
   9371         uint32 value, seed = 0;
   9372 
   9373         if (NULL == ROBUSTHASH(unit)) {
   9374             ROBUSTHASH(unit) = sal_alloc(sizeof(soc_robust_hash_db_t),
   9375                                          "soc_robust_hash");
   9376             if (ROBUSTHASH(unit) == NULL) {
   9377                 return SOC_E_MEMORY;
   9378             }
   9379             sal_memset(ROBUSTHASH(unit), 0, sizeof(soc_robust_hash_db_t));
   9380         }
   9381 
   9382         /* Enable Robust hashing for ING_VP_VLAN_MEMBERSHIP table and configure 
   9383          * corresponding remap and action tables.
   9384          */
   9385           
   9386         if ((soc_property_get(unit, "robust_hash_disable_ing_vp_vlan", 0)) == 1)
   9387         {
   9388             /* Disable robust hashing */
   9389             SOC_IF_ERROR_RETURN
   9390                 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
   9391             soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 
   9392                               &value, ROBUST_HASH_ENABLEf, 0x0);
   9393             SOC_IF_ERROR_RETURN
   9394                 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
   9395 
   9396             ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 0;
   9397         } else {
   9398             /* Enable robust hashing */
   9399             SOC_IF_ERROR_RETURN
   9400                 (READ_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
   9401             soc_reg_field_set(unit, ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
   9402                               &value, ROBUST_HASH_ENABLEf, 0x1);
   9403             SOC_IF_ERROR_RETURN
   9404                 (WRITE_ING_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
   9405             ROBUSTHASH(unit)->ing_vp_vlan_member.enable = 1;
   9406 
   9407             /* Fill action and remap tables with random data */
   9408             ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[0] = 
   9409                                               ING_VP_VLAN_MEMBERSHIP_REMAP_Am;
   9410             ROBUSTHASH(unit)->ing_vp_vlan_member.remap_tab[1] = 
   9411                                               ING_VP_VLAN_MEMBERSHIP_REMAP_Bm;
   9412             ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[0] = 
   9413                                               ING_VP_VLAN_MEMBERSHIP_ACTION_Am;
   9414             ROBUSTHASH(unit)->ing_vp_vlan_member.action_tab[1] = 
   9415                                               ING_VP_VLAN_MEMBERSHIP_ACTION_Bm;
   9416 
   9417             seed = soc_property_get(unit, 
   9418                                     spn_ROBUST_HASH_SEED_INGRESS_VP_VLAN, 
   9419                                     16777213);
   9420 
   9421             SOC_IF_ERROR_RETURN
   9422                 (soc_robust_hash_table_set(unit,
   9423                                         &(ROBUSTHASH(unit)->ing_vp_vlan_member),
   9424                                         seed));
   9425         }
   9426  
   9427         /* Enable Robust hashing for EGR_VP_VLAN_MEMBERSHIP table and configure 
   9428          * corresponding remap and action tables.
   9429          */
   9430           
   9431         if ((soc_property_get(unit, "robust_hash_disable_egr_vp_vlan", 0)) == 1)
   9432         {
   9433             /* Disable robust hashing */
   9434             SOC_IF_ERROR_RETURN
   9435                 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
   9436             soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr, 
   9437                               &value, ROBUST_HASH_ENABLEf, 0x0);
   9438             SOC_IF_ERROR_RETURN
   9439                 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
   9440 
   9441             ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 0;
   9442         } else {
   9443             /* Enable robust hashing */
   9444             SOC_IF_ERROR_RETURN
   9445                 (READ_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, &value));
   9446             soc_reg_field_set(unit, EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr,
   9447                               &value, ROBUST_HASH_ENABLEf, 0x1);
   9448             SOC_IF_ERROR_RETURN
   9449                 (WRITE_EGR_VP_VLAN_MEMBERSHIP_HASH_CONTROLr(unit, value));
   9450             ROBUSTHASH(unit)->egr_vp_vlan_member.enable = 1;
   9451 
   9452             /* Fill action and remap tables with random data */
   9453             ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[0] = 
   9454                                               EGR_VP_VLAN_MEMBERSHIP_REMAP_Am;
   9455             ROBUSTHASH(unit)->egr_vp_vlan_member.remap_tab[1] = 
   9456                                               EGR_VP_VLAN_MEMBERSHIP_REMAP_Bm;
   9457             ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[0] = 
   9458                                               EGR_VP_VLAN_MEMBERSHIP_ACTION_Am;
   9459             ROBUSTHASH(unit)->egr_vp_vlan_member.action_tab[1] = 
   9460                                               EGR_VP_VLAN_MEMBERSHIP_ACTION_Bm;
   9461 
   9462             seed = soc_property_get(unit, 
   9463                                     spn_ROBUST_HASH_SEED_EGRESS_VP_VLAN, 
   9464                                     16777213);
   9465 
   9466             SOC_IF_ERROR_RETURN
   9467                 (soc_robust_hash_table_set(unit,
   9468                                         &(ROBUSTHASH(unit)->egr_vp_vlan_member),
   9469                                         seed));
   9470         }
   9471     }
   9472 #endif /* SOC_ROBUST_HASH */
   9473 
   9474     return SOC_E_NONE;
   9475 }
   9476 
   9477 #define PORTS_PER_LED_CHAIN 36
   9478 STATIC int
   9479 soc_apache_ledup_init(int unit)
   9480 {
   9481 #if defined(BCM_56560_B0)
   9482     uint32 rval = 0, ix;
   9483     soc_info_t *si;
   9484     uint8 remap_value[SOC_MAX_NUM_PORTS];
   9485     int phy_port;
   9486 
   9487     si = &SOC_INFO(unit);
   9488     /* configure the LED scan delay cycles */
   9489     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval));
   9490     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xd);
   9491     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4);
   9492     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval));
   9493 
   9494     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP1_CTRLr(unit, &rval));
   9495     soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xb);
   9496     soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4);
   9497     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_CTRLr(unit, rval));
   9498 
   9499     for (ix = 0; ix < PORTS_PER_LED_CHAIN; ix++) {
   9500         /* Chain 0: Phy Ports 1-36
   9501          * LED HW Status arrives descending order to CMIC
   9502          * i.e Status for Port 36 comes first and for Port 1 last
   9503          */
   9504         phy_port = PORTS_PER_LED_CHAIN - ix;
   9505         if (si->port_p2l_mapping[phy_port] == -1) {
   9506             remap_value[ix] = 0;
   9507         } else {
   9508             remap_value[ix] = phy_port;
   9509         }
   9510 
   9511         /* Chain 1 Phy Ports 37-72
   9512          * LED HW Status arrives descending order to CMIC
   9513          * i.e Status for Port 72 comes first and for Port 37 last
   9514          */
   9515         if (si->port_p2l_mapping[phy_port + PORTS_PER_LED_CHAIN] == -1) {
   9516             remap_value[ix + PORTS_PER_LED_CHAIN] = 0;
   9517         } else {
   9518             remap_value[ix + PORTS_PER_LED_CHAIN] = phy_port;
   9519         }
   9520     }
   9521 
   9522     /* Configure LED Port remap registers */
   9523     ix = 0;
   9524     rval = 0;
   9525     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f, remap_value[ix++]);
   9526     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++]);
   9527     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]);
   9528     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]);
   9529     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval));
   9530 
   9531     rval = 0;
   9532     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]);
   9533     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]);
   9534     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]);
   9535     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]);
   9536     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval));
   9537 
   9538     rval = 0;
   9539     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f, remap_value[ix++]);
   9540     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f, remap_value[ix++]);
   9541     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]);
   9542     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]);
   9543     /* coverity[result_independent_of_operands] */
   9544     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval));
   9545 
   9546     rval = 0;
   9547     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]);
   9548     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]);
   9549     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]);
   9550     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]);
   9551     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval));
   9552 
   9553     rval = 0;
   9554     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_16f, remap_value[ix++]);
   9555     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]);
   9556     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]);
   9557     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]);
   9558     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval));
   9559 
   9560     rval = 0;
   9561     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]);
   9562     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]);
   9563     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]);
   9564     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]);
   9565     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval));
   9566 
   9567     rval = 0;
   9568     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]);
   9569     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]);
   9570     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]);
   9571     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]);
   9572     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval));
   9573 
   9574     rval = 0;
   9575     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]);
   9576     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_29f, remap_value[ix++]);
   9577     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]);
   9578     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]);
   9579     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval));
   9580 
   9581     rval = 0;
   9582     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]);
   9583     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]);
   9584     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]);
   9585     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]);
   9586     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval));
   9587 
   9588 
   9589     /* Configure LED Port remap registers - LED uP1*/
   9590     rval = 0;
   9591     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f, remap_value[ix++]);
   9592     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++]);
   9593     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]);
   9594     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]);
   9595     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r(unit, rval));
   9596 
   9597     rval = 0;
   9598     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]);
   9599     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]);
   9600     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]);
   9601     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]);
   9602     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r(unit, rval));
   9603 
   9604     rval = 0;
   9605     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f, remap_value[ix++]);
   9606     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f, remap_value[ix++]);
   9607     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]);
   9608     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]);
   9609     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r(unit, rval));
   9610 
   9611     rval = 0;
   9612     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]);
   9613     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]);
   9614     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]);
   9615     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]);
   9616     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r(unit, rval));
   9617 
   9618     rval = 0;
   9619     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_16f, remap_value[ix++]);
   9620     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]);
   9621     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]);
   9622     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]);
   9623     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r(unit, rval));
   9624 
   9625     rval = 0;
   9626     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]);
   9627     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]);
   9628     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]);
   9629     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]);
   9630     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r(unit, rval));
   9631 
   9632     rval = 0;
   9633     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]);
   9634     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]);
   9635     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]);
   9636     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]);
   9637     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r(unit, rval));
   9638 
   9639     rval = 0;
   9640     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]);
   9641     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_29f, remap_value[ix++]);
   9642     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]);
   9643     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]);
   9644     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r(unit, rval));
   9645 
   9646     rval = 0;
   9647     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]);
   9648     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]);
   9649     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]);
   9650     soc_reg_field_set(unit, CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]);
   9651     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r(unit, rval));
   9652 
   9653 
   9654     /* initialize the UP0, UP1 data ram */
   9655     rval = 0;
   9656     for (ix = 0; ix < 256; ix++) {
   9657         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval));
   9658         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_DATA_RAMr(unit,ix, rval));
   9659     }
   9660 
   9661 #endif
   9662     return SOC_E_NONE;
   9663 }
   9664 
   9665 #if defined(SER_TR_TEST_SUPPORT)
   9666 soc_ser_test_functions_t ser_apache_test_fun;
   9667 #endif
   9668 
   9669 STATIC int
   9670 _soc_apache_egr_buf_reset(int unit, int port, int reset)
   9671 {
   9672     uint32 entry[SOC_MAX_MEM_WORDS];
   9673 
   9674     SOC_IF_ERROR_RETURN(
   9675         READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
   9676                                             port, entry));
   9677     soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
   9678                         entry, ENABLEf, reset);
   9679     SOC_IF_ERROR_RETURN(
   9680         WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
   9681                                              port, entry));
   9682 
   9683     return SOC_E_NONE;
   9684 }
   9685 
   9686 STATIC int
   9687 _soc_portctrl_apache_port_init(int unit)
   9688 {
   9689     soc_info_t *si;
   9690     int port;
   9691     int blk;
   9692     int pgw_inst;
   9693 
   9694     si = &SOC_INFO(unit);
   9695 
   9696     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CXXPORT) {
   9697         port = SOC_BLOCK_PORT(unit, blk);
   9698         if (port == -1) {
   9699             continue;
   9700         }
   9701 
   9702         /*  If this is a 100G port, reset egress port buffer */
   9703         if (si->port_speed_max[port] >= 100000) {
   9704             SOC_IF_ERROR_RETURN(_soc_apache_egr_buf_reset(unit, port, 1));
   9705 
   9706             SOC_IF_ERROR_RETURN(soc_apache_port_speed_update(unit, port, si->port_speed_max[port]));
   9707 
   9708             SOC_IF_ERROR_RETURN(_soc_apache_egr_buf_reset(unit, port, 0));
   9709 
   9710             pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK;
   9711             SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PGW_ETM_MODEr, pgw_inst, ETM_PORT_EN_CONFIGf, 1));
   9712         }
   9713     }
   9714 
   9715     /* Cut through settings for all ports */
   9716     PBMP_ALL_ITER(unit, port) {
   9717         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
   9718             continue;
   9719         }
   9720 
   9721         SOC_IF_ERROR_RETURN(soc_apache_port_asf_set(unit, port, si->port_speed_max[port]));
   9722     }
   9723 
   9724     return SOC_E_NONE;
   9725 }
   9726 
   9727 
   9728 /*
   9729  * Function:
   9730  *      soc_apache_idb_buf_reset
   9731  * Purpose:
   9732  *      Poll until Cell Assembly and OBM buffers are empty.
   9733  * Parameters:
   9734  *      unit    - (IN) Unit number.
   9735  *      port    - (IN) Logical SOC port number.
   9736  *      reset   - (IN) Reset.
   9737  * Returns:
   9738  *      SOC_E_XXX
   9739  */
   9740 int
   9741 soc_apache_idb_buf_reset(int unit, soc_port_t port, int reset)
   9742 {
   9743     soc_info_t *si = &SOC_INFO(unit);
   9744     soc_reg_t reg;
   9745     soc_field_t field;
   9746     uint64 rval64;
   9747     int phy_port, port_index, xlp, pgw, obm, pgw_inst;
   9748     soc_timeout_t to;
   9749     int use_count, fifo_empty;
   9750     int wait_time = 250000;
   9751 
   9752     static const soc_reg_t pgw_obm_use_counter_regs[] = {
   9753         IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, IDB_OBM2_USAGEr,
   9754         IDB_OBM3_USAGEr, IDB_OBM4_USAGEr, IDB_OBM5_USAGEr,
   9755         IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, IDB_OBM8_USAGEr
   9756     };
   9757     static const soc_reg_t obm_ctrl_regs[] = {
   9758         IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, IDB_OBM2_CONTROLr,
   9759         IDB_OBM3_CONTROLr, IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr,
   9760         IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, IDB_OBM8_CONTROLr
   9761     };
   9762     static const soc_reg_t obm_ca_ctrl_regs[] = {
   9763         IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr,
   9764         IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr,
   9765         IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr
   9766     };
   9767     static const soc_field_t port_reset_fields[] = {
   9768         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf
   9769     };
   9770 
   9771 
   9772     if (SAL_BOOT_QUICKTURN) {
   9773         wait_time *= 20;
   9774         wait_time *= 3;
   9775     }
   9776 
   9777     /* Get physical port PGW information */
   9778     phy_port = si->port_l2p_mapping[port];
   9779     pgw = si->port_group[port];
   9780     xlp = si->port_serdes[port];
   9781     port_index = (phy_port - 1) % 4;
   9782 
   9783     obm = xlp % APACHE_TSCS_PER_PGW;
   9784     pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK;
   9785 
   9786     /* Assume values returned above are valid */
   9787     reg = pgw_obm_use_counter_regs[obm];
   9788     field = TOTAL_COUNTf;
   9789 
   9790     if (reset && (!SAL_BOOT_BCMSIM)) {
   9791         /* Poll until Cell Assembly and OBM buffers are empty */
   9792         soc_timeout_init(&to, wait_time, 0);
   9793         for (;;) {
   9794             /* Get PGW use counter */
   9795             SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, port_index, &rval64));
   9796             use_count = soc_reg64_field32_get(unit, reg, rval64, field);
   9797 
   9798             /* Get PGW fifo empty flag */
   9799             SOC_IF_ERROR_RETURN(READ_PGW_BOD_STATUS1r(unit, port, &rval64));
   9800             fifo_empty = soc_reg64_field32_get(unit, PGW_BOD_STATUS1r,
   9801                                                rval64, PGW_BOD_FIFO_EMPTYf);
   9802 
   9803             LOG_INFO(BSL_LS_SOC_PORT,
   9804                       (BSL_META_U(unit,
   9805                                   "PGW/OBM buffer reset : port %d, %s (log=%d phy=%d), "
   9806                                   "subport: %d tsc: %d obm:%d pgw: %d"
   9807                                   "(use_count: %d) "
   9808                                   "(pgw_bod_fifo_emty:%d)\n"),
   9809                        unit, SOC_PORT_NAME(unit, port), port, phy_port,
   9810                        port_index, xlp, obm, pgw,
   9811                        use_count, fifo_empty));
   9812 
   9813             if ((use_count == 0) && (fifo_empty == 1)) {
   9814                 break;
   9815             }
   9816 
   9817             if (soc_timeout_check(&to)) {
   9818                 LOG_ERROR(BSL_LS_SOC_PORT,
   9819                           (BSL_META_U(unit,
   9820                                       "PGW/OBM buffer reset timeout: port %d, %s, "
   9821                                       "timeout (use_count: %d) "
   9822                                       "(pgw_bod_fifo_emty:%d)\n"),
   9823                            unit, SOC_PORT_NAME(unit, port),
   9824                            use_count, fifo_empty));
   9825                 return SOC_E_INTERNAL;
   9826             }
   9827         }
   9828     }
   9829 
   9830     reg = obm_ctrl_regs[obm];
   9831     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst,
   9832                                                port_reset_fields[port_index], reset));
   9833 
   9834     reg = obm_ca_ctrl_regs[obm];
   9835     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst,
   9836                                                port_reset_fields[port_index], reset));
   9837 
   9838     return SOC_E_NONE;
   9839 }
   9840 
   9841 STATIC int
   9842 _soc_apache_port_credit_size_get(int unit, soc_port_t port, int *ep_credit_size)
   9843 {
   9844     int speed;
   9845     uint32 cl91_enabled;
   9846 
   9847     speed = SOC_INFO(unit).port_speed_max[port];
   9848 
   9849     SOC_IF_ERROR_RETURN(soc_apache_port_cl91_status_get(unit, port, &cl91_enabled));
   9850 
   9851     if (soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) {
   9852         if (speed <= 11000) {
   9853             *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11;
   9854         } else if (speed <= 27000) {
   9855             *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : (cl91_enabled ? 18 : 16);
   9856         } else if (speed <= 42000) {
   9857             *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 21 : 20;
   9858         } else if (speed <= 53000) {
   9859             *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : (cl91_enabled ? 25 : 23);
   9860         } else {
   9861             *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39;
   9862         }
   9863     }
   9864 
   9865     return SOC_E_NONE;
   9866 }
   9867 
   9868 /*
   9869  * Function:
   9870  *      _soc_apache_mmu_ep_credit_set
   9871  * Purpose:
   9872  *      Initalize EP credits in MMU so EP is in charge
   9873  *      of distributing the correct number of credits.
   9874  * Parameters:
   9875  *      unit    - (IN) Unit number.
   9876  *      port    - (IN) Logical SOC port number.
   9877  * Returns:
   9878  *      SOC_E_XXX
   9879  */
   9880 STATIC int
   9881 _soc_apache_mmu_ep_credit_set(int unit, soc_port_t port)
   9882 {
   9883     soc_info_t *si = &SOC_INFO(unit);
   9884     int phy_port;
   9885     int mmu_port;
   9886     int ep_credit_size = 0;
   9887     soc_reg_t reg;
   9888     uint32 rval;
   9889 
   9890     /* Get physical port */
   9891     phy_port = si->port_l2p_mapping[port];
   9892     if (phy_port == -1) {
   9893         return SOC_E_INTERNAL;
   9894     }
   9895 
   9896     /* Get MMU port */
   9897     mmu_port = si->port_p2m_mapping[phy_port];
   9898     if (mmu_port == -1) {
   9899         return SOC_E_INTERNAL;
   9900     }
   9901 
   9902     /* Wait until credits are initialised at non-optimum value
   9903      * EP passes MMU 1 credit per cycle, so worse case delay is 95 cycles after EGR_ENABLE is set.
   9904      * @793.75MHz, this is ~120ns.
   9905      */
   9906     sal_usleep(1);
   9907 
   9908     reg = ES_PIPE0_MMU_PORT_CREDITr;
   9909 
   9910     SOC_IF_ERROR_RETURN(_soc_apache_port_credit_size_get(unit, port, &ep_credit_size));
   9911     SOC_IF_ERROR_RETURN
   9912         (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval));
   9913     soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, ep_credit_size);
   9914     SOC_IF_ERROR_RETURN
   9915         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
   9916 
   9917     return SOC_E_NONE;
   9918 }
   9919 
   9920 /*
   9921  * Function:
   9922  *      _soc_apache_mmu_ep_credit_reset
   9923  * Purpose:
   9924  *      Reset EP credits in MMU
   9925  * Parameters:
   9926  *      unit    - (IN) Unit number.
   9927  *      port    - (IN) Logical SOC port number.
   9928  * Returns:
   9929  *      SOC_E_XXX
   9930  */
   9931 STATIC int
   9932 _soc_apache_mmu_ep_credit_reset(int unit, soc_port_t port)
   9933 {
   9934     soc_info_t *si = &SOC_INFO(unit);
   9935     int phy_port;
   9936     int mmu_port;
   9937     soc_reg_t reg;
   9938     uint32 rval;
   9939 
   9940     /* Get physical port */
   9941     phy_port = si->port_l2p_mapping[port];
   9942     if (phy_port == -1) {
   9943         return SOC_E_INTERNAL;
   9944     }
   9945 
   9946     /* Get MMU port */
   9947     mmu_port = si->port_p2m_mapping[phy_port];
   9948     if (mmu_port == -1) {
   9949         return SOC_E_INTERNAL;
   9950     }
   9951 
   9952     reg = ES_PIPE0_MMU_PORT_CREDITr;
   9953 
   9954     SOC_IF_ERROR_RETURN
   9955         (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval));
   9956     soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, 0);
   9957     SOC_IF_ERROR_RETURN
   9958         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
   9959 
   9960     return SOC_E_NONE;
   9961 }
   9962 
   9963 
   9964 /*
   9965  * Function:
   9966  *      soc_apache_edb_buf_reset
   9967  * Purpose:
   9968  *      Initialize EP credits in MMU, release EDB port buffer and
   9969  *      enable cell request in EP.
   9970  * Parameters:
   9971  *      unit    - (IN) Unit number.
   9972  *      port    - (IN) Logical SOC port number.
   9973  *      reset   - (IN) Reset.
   9974  * Returns:
   9975  *      SOC_E_XXX
   9976  */
   9977 int
   9978 soc_apache_edb_buf_reset(int unit, soc_port_t port, int reset)
   9979 {
   9980     soc_info_t *si = &SOC_INFO(unit);
   9981     uint32 entry[SOC_MAX_MEM_WORDS];
   9982     int phy_port;
   9983 
   9984     /* Get physical port */
   9985     phy_port = si->port_l2p_mapping[port];
   9986     if (phy_port == -1) {
   9987         return SOC_E_INTERNAL;
   9988     }
   9989 
   9990     if (reset) {
   9991         /*
   9992          * Hold EDB port buffer in reset state and disable cell
   9993          * request generation in EP.
   9994          */
   9995         SOC_IF_ERROR_RETURN
   9996             (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
   9997                                                  phy_port, entry));
   9998         soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
   9999                             entry, ENABLEf, 1);
  10000         SOC_IF_ERROR_RETURN
  10001             (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  10002                                                   phy_port, entry));
  10003         SOC_IF_ERROR_RETURN
  10004             (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
  10005         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 0);
  10006         SOC_IF_ERROR_RETURN
  10007             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
  10008 
  10009     } else {
  10010 
  10011         /* Initialize EP credits in MMU */
  10012         SOC_IF_ERROR_RETURN(_soc_apache_mmu_ep_credit_reset(unit, port));
  10013 
  10014         /*
  10015          * Release EDB port buffer reset and
  10016          * enable cell request generation in EP.
  10017          */
  10018         SOC_IF_ERROR_RETURN
  10019             (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  10020                                                  phy_port, entry));
  10021         soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
  10022                             entry, ENABLEf, 0);
  10023         SOC_IF_ERROR_RETURN
  10024             (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  10025                                                   phy_port, entry));
  10026 
  10027         SOC_IF_ERROR_RETURN
  10028             (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
  10029         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  10030         SOC_IF_ERROR_RETURN
  10031             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
  10032 
  10033         SOC_IF_ERROR_RETURN(_soc_apache_mmu_ep_credit_set(unit, port));
  10034     }
  10035 
  10036     return SOC_E_NONE;
  10037 }
  10038 
  10039 int
  10040 soc_apache_port_edb_config(int unit, int asf, soc_port_t port)
  10041 {
  10042     int rv;
  10043     uint32 osct_pbm;
  10044     uint64 tmp, lrct_pbm;
  10045     soc_info_t *si;
  10046     soc_port_t phy_port, mmu_port;
  10047     int pm_id, pgw_inst, linerate;
  10048     uint32 cl91_enabled;
  10049 
  10050     soc_mem_t edb_mem = EGR_EDB_XMIT_CTRLm;
  10051     soc_field_t edb_fields[3] = {START_CNTf, WAIT_FOR_MOPf, WAIT_FOR_2ND_MOPf};
  10052     uint32 edb_values[3] = {0};
  10053 
  10054     soc_reg_t asm_ct_thresh_reg = CELL_ASM_CUT_THRU_THRESHOLD0r;
  10055     soc_field_t asm_ct_fields[APACHE_NUM_XLP_PER_PGW + APACHE_NUM_CLP_PER_PGW] = {
  10056         XLP0_CELL_ASM_CUT_THRU_THRESHOLDf,
  10057         XLP1_CELL_ASM_CUT_THRU_THRESHOLDf,
  10058         XLP2_CELL_ASM_CUT_THRU_THRESHOLDf,
  10059         XLP3_CELL_ASM_CUT_THRU_THRESHOLDf,
  10060         XLP4_CELL_ASM_CUT_THRU_THRESHOLDf,
  10061         XLP5_CELL_ASM_CUT_THRU_THRESHOLDf,
  10062         XLP6_CELL_ASM_CUT_THRU_THRESHOLDf,
  10063         CLP0_CELL_ASM_CUT_THRU_THRESHOLDf,
  10064         CLP1_CELL_ASM_CUT_THRU_THRESHOLDf,
  10065     };
  10066     int asm_ct_thresh;
  10067 
  10068     si = &SOC_INFO(unit);
  10069 
  10070     /* Remove extraneous ports from the input list */
  10071     SOC_IF_ERROR_RETURN(READ_ENQ_ASF_HS_OVERSUB_ENr(unit, &osct_pbm));
  10072     SOC_IF_ERROR_RETURN(READ_ENQ_ASF_LRCT_OVERSUB_ENr(unit, &lrct_pbm));
  10073 
  10074     phy_port = si->port_l2p_mapping[port];
  10075     mmu_port = si->port_p2m_mapping[phy_port];
  10076     pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK;
  10077     linerate = (!SOC_PBMP_MEMBER(si->oversub_pbm, port));
  10078 
  10079     SOC_IF_ERROR_RETURN(soc_apache_port_cl91_status_get(unit, port, &cl91_enabled));
  10080 
  10081     pm_id = ((phy_port - 1) / APACHE_PORTS_PER_TSC) % APACHE_TSCS_PER_PGW;
  10082     if (pm_id < APACHE_NUM_XLP_PER_PGW) { /* Eagle Cores */
  10083         if (si->port_speed_max[port] <= 21000) {  /* 0-21G */
  10084             edb_values[0] = (linerate) ? (asf ? 9 : 0) : (asf ? 0 : 5);
  10085             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10086             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10087 
  10088             asm_ct_thresh = 6;
  10089         } else if (si->port_speed_max[port] <= 42000) {  /* 21G-42G */
  10090             edb_values[0] = (linerate) ? (asf ? 9 : 0) : (asf ? 18 : 9);
  10091             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10092             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10093 
  10094             asm_ct_thresh = 6;
  10095         } else { /* 42G or more (100G)  */
  10096             edb_values[0] = (linerate) ? (asf ? 14 : 0) : (asf ? 0 : 4);
  10097             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10098             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10099 
  10100             asm_ct_thresh = 6;
  10101         }
  10102     } else { /*  Falcon Cores  */
  10103         if (si->port_speed_max[port] <= 11000) {  /* 0-11G */
  10104             edb_values[0] = (linerate) ? (asf ? 4 : 0) : (asf ? 0 : 4);
  10105             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10106             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10107 
  10108             asm_ct_thresh = 6;
  10109         } else if (si->port_speed_max[port] <= 27000) {  /* 11G-27G */
  10110             edb_values[0] = (linerate) ? (asf ? (cl91_enabled ? 10 : 4) : 0) : (asf ? 0 : 4);
  10111             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10112             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10113 
  10114             asm_ct_thresh = 6;
  10115         } else if (si->port_speed_max[port] <= 42000) {  /* 27G-42G */
  10116             edb_values[0] = (linerate) ? (asf ? 5 : 0) : (asf ? 7 : 4);
  10117             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10118             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10119  
  10120             asm_ct_thresh = 6;
  10121         } else if (si->port_speed_max[port] <= 53000) { /* 42G-53G  */
  10122             edb_values[0] = (linerate) ? (asf ? (cl91_enabled ? 11 : 5) : 0) : (asf ? 0 : 4);
  10123             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10124             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10125 
  10126             asm_ct_thresh = 6;
  10127         } else { /* 53G-106G */
  10128             edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4);
  10129             edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10130             edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10131  
  10132             asm_ct_thresh = 6;
  10133         }
  10134     }
  10135   
  10136     rv = soc_mem_fields32_modify(unit, edb_mem, phy_port, 3, edb_fields, edb_values);
  10137     SOC_IF_ERROR_RETURN(rv);
  10138 
  10139     rv = soc_reg_field32_modify(unit, asm_ct_thresh_reg, pgw_inst,
  10140                                 asm_ct_fields[pm_id], asm_ct_thresh);
  10141     SOC_IF_ERROR_RETURN(rv);
  10142 
  10143     if (IS_OVERSUB_PORT(unit, port)) {
  10144         if ((si->port_speed_max[port] == 40000) ||
  10145             (si->port_speed_max[port] == 42000)) {
  10146             osct_pbm |= 1 << mmu_port;    /* mmu ports: [0, 17] */
  10147         }
  10148     } else {
  10149         COMPILER_64_SET(tmp, 0, 1);
  10150         COMPILER_64_SHL(tmp, (mmu_port - 18)); /* mmu ports: [18, 71] */
  10151         COMPILER_64_OR(lrct_pbm, tmp);
  10152     }
  10153 
  10154     SOC_IF_ERROR_RETURN(WRITE_ENQ_ASF_HS_OVERSUB_ENr(unit, osct_pbm));
  10155     SOC_IF_ERROR_RETURN(WRITE_ENQ_ASF_LRCT_OVERSUB_ENr(unit, lrct_pbm));
  10156 
  10157     return SOC_E_NONE;
  10158 }
  10159 
  10160 
  10161 STATIC int
  10162 soc_apache_edb_init(int unit)
  10163 {
  10164     soc_pbmp_t pbm;
  10165     soc_port_t port;
  10166 
  10167     SOC_PBMP_ASSIGN(pbm, PBMP_PORT_ALL(unit));
  10168     SOC_PBMP_ITER(pbm, port) {
  10169         SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, 0, port));
  10170     }
  10171 
  10172     return SOC_E_NONE;
  10173 }
  10174 
  10175 STATIC int
  10176 _soc_apache_misc_deinit (int unit)
  10177 {
  10178 
  10179     SOC_IF_ERROR_RETURN(soc_ap_phy_info_deinit(unit));
  10180 
  10181     if (soc_apache_misc_info[unit] != NULL) {
  10182         sal_free(soc_apache_misc_info[unit]);
  10183         soc_apache_misc_info[unit] = NULL;
  10184     }
  10185 
  10186     return SOC_E_NONE;
  10187 }
  10188 
  10189 STATIC int
  10190 soc_apc_mem_modify_range(int unit, soc_mem_t mem, int min_idx, int max_idx,
  10191                          int nfields, soc_field_t *fields, uint32 *values)
  10192 {
  10193     uint8 *mbuf;
  10194     void  *entry_ptr;
  10195     int    e_idx, f_idx, size, rv;
  10196 
  10197     size = SOC_MEM_TABLE_BYTES(unit, mem);
  10198     mbuf = soc_cm_salloc(unit, size, "soc_mem_name[mem]");
  10199 
  10200     if (NULL == mbuf) {
  10201         return SOC_E_MEMORY;
  10202     }
  10203 
  10204     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf);
  10205     if (SOC_FAILURE(rv)) {
  10206         soc_cm_sfree(unit, mbuf);
  10207         return rv;
  10208     }
  10209 
  10210     for (e_idx = min_idx; e_idx <= max_idx; e_idx++) {
  10211         entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, void *, mbuf, e_idx);
  10212         for (f_idx = 0; f_idx < nfields; f_idx++) {
  10213             /* If value is -1, program entry_idx */
  10214             soc_mem_field32_set(unit, mem, entry_ptr, fields[f_idx],
  10215                                 (values[f_idx] == -1 ? e_idx : values[f_idx]));
  10216         }
  10217     }
  10218 
  10219     rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf);
  10220     soc_cm_sfree(unit, mbuf);
  10221     SOC_IF_ERROR_RETURN(rv);
  10222 
  10223     return SOC_E_NONE;
  10224 }
  10225 
  10226 #ifdef ALPM_ENABLE
  10227 STATIC int
  10228 _soc_apache_alpm_mode_enable(int unit)
  10229 {
  10230     uint32 rval = 0;
  10231     uint32 mode;
  10232 
  10233     mode = soc_property_get(unit, spn_L3_ALPM_ENABLE, 0);
  10234     if (mode && soc_feature(unit, soc_feature_alpm)) {
  10235         /* Set DEFIP mode to ALPM */
  10236         SOC_IF_ERROR_RETURN(READ_L3_DEFIP_RPF_CONTROLr(unit, &rval));
  10237         soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LPM_MODEf, 1);
  10238         /* Parallel mode */
  10239         if (mode == SOC_ALPM_MODE_PARALLEL) {
  10240             soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 1);
  10241         } else {
  10242             /* combined search mode */
  10243             soc_reg_field_set(unit, L3_DEFIP_RPF_CONTROLr, &rval, LOOKUP_MODEf, 0);
  10244         }
  10245         SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_RPF_CONTROLr(unit, rval));
  10246     }
  10247     return SOC_E_NONE;
  10248 }
  10249 #endif /* ALPM_ENABLE */
  10250 
  10251 #define MIN(a,b) ((a < b) ? a : b)
  10252 STATIC int
  10253 _soc_apache_misc_init (int unit)
  10254 {
  10255     static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 };
  10256     soc_info_t *si;
  10257     uint32 rval = 0;
  10258     uint64 rval64;
  10259     uint32 entry[SOC_MAX_MEM_WORDS];
  10260     soc_pbmp_t pbmp;
  10261     int port, min_port, max_port;
  10262     int block_info_idx;
  10263     int index, count, sub_sel, offset, higig2;
  10264     int freq, target_freq, divisor, dividend, delay;
  10265     int parity_enable = 0, cache_fpgm;
  10266     soc_field_t fields[2];
  10267     uint32 values[2];
  10268     int l2mc_max_group_size = 16384, ipmc_max_group_size;
  10269 
  10270     si = &SOC_INFO(unit);
  10271 
  10272     if (soc_apache_misc_info[unit] == NULL) {
  10273         soc_apache_misc_info[unit] = sal_alloc(sizeof(*soc_apache_misc_info[unit]),
  10274                                                "apache misc info");
  10275         if (soc_apache_misc_info[unit] == NULL) {
  10276             return SOC_E_MEMORY;
  10277         }
  10278     }
  10279 
  10280     sal_memset(soc_apache_misc_info[unit], 0, (sizeof(*soc_apache_misc_info[unit])));
  10281 
  10282     /* Stop the mem scan task before all of the parity init takes place */
  10283     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
  10284 
  10285     if (!SOC_WARM_BOOT(unit)) {
  10286 
  10287         /*  Initialize PORT MIB counter */
  10288         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) {
  10289             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10290             soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10291             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval));
  10292             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0));
  10293         }
  10294         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLG2PORT) {
  10295             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10296             soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10297             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval));
  10298             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0));
  10299         }
  10300 
  10301         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) {
  10302             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10303             soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10304             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval));
  10305             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0));
  10306         }
  10307         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORTB0) {
  10308             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10309             soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10310             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval));
  10311             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0));
  10312         }
  10313 
  10314     }
  10315 
  10316     /* Stop the mem scan task before all of the parity init takes place */
  10317     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
  10318     SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit));
  10319 
  10320 
  10321     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
  10322     if (parity_enable) {
  10323         if ((!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) &&
  10324             !SOC_WARM_BOOT(unit)) {
  10325             /* Certain mems/regs need to be cleared before enabling SER */
  10326             SOC_IF_ERROR_RETURN(_soc_apache_clear_mmu_memory(unit, INVALIDm));
  10327             SOC_IF_ERROR_RETURN(_soc_apache_clear_all_port_data(unit));
  10328         }
  10329         SOC_IF_ERROR_RETURN(_soc_apache_tcam_ser_init(unit));
  10330         SOC_IF_ERROR_RETURN(_soc_apache_ser_enable_all(unit, TRUE));
  10331 #ifdef INCLUDE_MEM_SCAN
  10332         soc_mem_scan_ser_list_register(unit, TRUE,
  10333                                        _soc_apache_tcam_ser_info[unit]);
  10334 #endif
  10335 #if defined(BCM_56560_A0)
  10336         memset(&_apache_ser_functions, 0, sizeof(soc_ser_functions_t));
  10337         _apache_ser_functions._soc_ser_fail_f = &soc_apache_ser_fail;
  10338         _apache_ser_functions._soc_ser_parity_error_cmicm_intr_f = 
  10339             &soc_apache_ser_error;
  10340         soc_ser_function_register(unit, &_apache_ser_functions);
  10341         soc_apache_ser_set_long_delay(FALSE);
  10342 #endif
  10343 #if defined(SER_TR_TEST_SUPPORT)
  10344         /*Initialize chip-specific functions for SER testing*/
  10345         memset(&ser_apache_test_fun, 0, sizeof(soc_ser_test_functions_t));
  10346         ser_apache_test_fun.inject_error_f = &soc_apache_ser_inject_error;
  10347         ser_apache_test_fun.test_mem = &soc_apache_ser_test_mem;
  10348         ser_apache_test_fun.test = &soc_apache_ser_test;
  10349         ser_apache_test_fun.parity_control = &_ser_test_parity_control_reg_set;
  10350         ser_apache_test_fun.injection_support = &soc_apache_ser_error_injection_support;
  10351         soc_ser_test_functions_register(unit, &ser_apache_test_fun);
  10352 #endif /*defined(SER_TR_TEST_SUPPORT*/
  10353     }
  10354 
  10355     if (!SOC_WARM_BOOT(unit)) {
  10356         SOC_IF_ERROR_RETURN
  10357             (_soc_apache_clear_all_memory(unit, (parity_enable ? 0 : 1)));
  10358         if (!parity_enable) {
  10359             /* Clear enabled port's regs if not done above */
  10360             SOC_IF_ERROR_RETURN(_soc_apache_clear_enabled_port_data(unit));
  10361         }
  10362     }
  10363 
  10364     SOC_IF_ERROR_RETURN(_soc_apache_port_mapping_init(unit));
  10365 
  10366 
  10367     if (!SAL_BOOT_BCMSIM && !soc_property_get(unit, "skip_tdm_init", 0)) {
  10368         if (!SOC_WARM_BOOT(unit)) {
  10369             SOC_IF_ERROR_RETURN(soc_apache_tdm_init(unit));
  10370             SOC_IF_ERROR_RETURN(soc_apache_idb_init(unit));
  10371             SOC_IF_ERROR_RETURN(soc_apache_edb_init(unit));
  10372         } else {
  10373             SOC_IF_ERROR_RETURN(soc_apache_tdm_reinit(unit));
  10374         }
  10375     }
  10376 
  10377     sal_memset(entry, 0, sizeof(cpu_pbm_entry_t));
  10378     soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit));
  10379     SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry));
  10380 
  10381     sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t));
  10382     soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit));
  10383     SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry));
  10384 
  10385     sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t));
  10386     soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf,
  10387                            &PBMP_LB(unit));
  10388     SOC_IF_ERROR_RETURN(soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm,
  10389                                       MEM_BLOCK_ALL, 0, entry));
  10390 
  10391     sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
  10392     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
  10393     PBMP_HG_ITER(unit, port) {
  10394         SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm,
  10395                                           MEM_BLOCK_ALL, port, entry));
  10396     }
  10397     higig2 = soc_property_port_get(unit, CMIC_PORT(unit), spn_HIGIG2_HDR_MODE,
  10398                                    soc_feature(unit,
  10399                                    soc_feature_no_higig_plus) ? 1 : 0)
  10400                                    ? 1 : 0;
  10401     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2);
  10402 
  10403     SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL,
  10404                                       si->cpu_hg_index, entry));
  10405     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2);
  10406     SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL,
  10407                                       LB_PORT(unit), entry));
  10408 
  10409     /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to
  10410      * initialize the cache until now.  This is the time to check for
  10411      * the cache permission of this table.
  10412      */
  10413     cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 
  10414             soc_property_get(unit, spn_MEM_CACHE_ENABLE, 
  10415                              (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1);
  10416 
  10417     if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) {
  10418         char mem_name[100];
  10419         char *mptr;
  10420 
  10421         sal_memset(mem_name, 0, sizeof(mem_name));
  10422         sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_"));
  10423         mptr = &mem_name[sal_strlen(mem_name)];
  10424         sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm),
  10425                     sizeof(mem_name) - sal_strlen(mem_name) - 1);
  10426         if (soc_property_get(unit, mem_name, 0)) {
  10427             cache_fpgm = 0;
  10428         }
  10429     }
  10430 
  10431     if (cache_fpgm && (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) {
  10432         SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |= SOC_MEM_FLAG_CACHABLE;
  10433         SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm,
  10434                                               MEM_BLOCK_ALL, TRUE));
  10435 
  10436         SOC_MEM_INFO(unit, FP_GM_FIELDSm).flags |= SOC_MEM_FLAG_CACHABLE;
  10437         SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, FP_GM_FIELDSm,
  10438                                               MEM_BLOCK_ALL, TRUE));
  10439     }
  10440 
  10441     SOC_IF_ERROR_RETURN(_soc_portctrl_apache_port_init(unit));
  10442 
  10443     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
  10444     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
  10445     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
  10446 
  10447     /* Enable dual hash tables */
  10448     SOC_IF_ERROR_RETURN(_soc_apache_hash_init(unit));
  10449 
  10450 #ifdef ALPM_ENABLE
  10451     SOC_IF_ERROR_RETURN(_soc_apache_alpm_mode_enable(unit));
  10452 #endif
  10453 
  10454     rval = 0;
  10455     soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, AGE_COUNTf,
  10456                       soc_mem_index_max(unit, L2Xm));
  10457     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_DEBUGr(unit, rval));
  10458 
  10459     /*
  10460      * Egress Enable (for non-serdes ports).
  10461      * For PM ports, it is set during port enable/disable sequence.
  10462      */
  10463     sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  10464     soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  10465 
  10466     /* Only enable internal ports in EGR_ENABLE.
  10467      *  The packet processing ports are enabled via port enable sequence.
  10468      */
  10469     SOC_PBMP_CLEAR(pbmp);
  10470     SOC_PBMP_PORT_ADD(pbmp, CMIC_PORT(unit));
  10471     SOC_PBMP_PORT_ADD(pbmp, LB_PORT(unit));
  10472     SOC_PBMP_PORT_ADD(pbmp, RDB_PORT(unit));
  10473 
  10474     PBMP_ITER(pbmp, port) {
  10475         SOC_IF_ERROR_RETURN
  10476             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, port, entry));
  10477     }
  10478 
  10479     SOC_PBMP_CLEAR(pbmp);
  10480     SOC_PBMP_ASSIGN(pbmp, PBMP_CMIC(unit));
  10481     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, &pbmp);
  10482     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry));
  10483 
  10484         /* Bypass control settings */
  10485     if (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_NONE) {
  10486         rval = 0;
  10487 
  10488         /* AP does not support IRSEL1 and IVP bypass stage */
  10489         /*soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  10490                                IRSEL1_STAGE_BYPASS_ENABLEf, 1);
  10491         soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  10492                                IVP_STAGE_BYPASS_ENABLEf, 1);*/
  10493 
  10494         soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  10495                                IVXLT_STAGE_BYPASS_ENABLEf, 1);
  10496 
  10497         if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) {
  10498             soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval,
  10499                                   IFP_STAGE_BYPASS_ENABLEf, 1);
  10500         }
  10501 
  10502         SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval));
  10503 
  10504         soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval,
  10505                                EFP_STAGE_BYPASS_ENABLEf, 1);
  10506 
  10507         SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval));
  10508     }
  10509 
  10510     /*
  10511      * Enable all ports (except RDB port)
  10512      * RDB port is an ingress-only port that should not have any packets
  10513      * enqueued against it, even if the port is added to any vlan or other
  10514      * forwarding table by mistake.
  10515      */
  10516 #if __GNUC__ > 6
  10517 #pragma GCC diagnostic push
  10518 #pragma GCC diagnostic ignored "-Wmemset-elt-size"
  10519 #endif
  10520     /*
  10521      * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for
  10522      * performance reasons, because the actual soc_mem_field_set()
  10523      * will only write sizeof(ing_dest_port_enable_entry_t)=20
  10524      * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651
  10525      * depending on which devices are compiled in.
  10526      */
  10527     sal_memset(entry, 0, sizeof(ing_dest_port_enable_entry_t));
  10528 #if __GNUC__ > 6
  10529 #pragma GCC diagnostic pop
  10530 #endif
  10531     SOC_PBMP_CLEAR(pbmp);
  10532     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  10533     SOC_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit));
  10534     soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, entry, PORT_BITMAPf, &pbmp);
  10535     SOC_IF_ERROR_RETURN(WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, entry));
  10536 
  10537     min_port = SOC_PORT_MIN(unit, all);
  10538     max_port = SOC_PORT_MAX(unit, all);
  10539 
  10540     fields[0] = DESTf; values[0] = -1; /* -1 => port */
  10541     fields[1] = ENABLEf; values[1] = 1;
  10542     SOC_IF_ERROR_RETURN(soc_apc_mem_modify_range(unit, MODPORT_MAP_SUBPORTm,
  10543                                                  min_port, max_port,
  10544                                                  2, fields, values));
  10545 
  10546     /* setting up my_modid */
  10547     SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64));
  10548 
  10549     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  10550                           MODID_0_VALIDf, 1);
  10551     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  10552                           MODID_0f, SOC_BASE_MODID(unit));
  10553 
  10554     SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64));
  10555 
  10556 
  10557     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64));
  10558     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10559                           L3SRC_HIT_ENABLEf, 1);
  10560     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10561                           L2DST_HIT_ENABLEf, 1);
  10562     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10563                           APPLY_EGR_MASK_ON_L2f, 1);
  10564     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10565                           APPLY_EGR_MASK_ON_L3f, 1);
  10566     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10567                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
  10568     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10569                           ARP_VALIDATION_ENf, 1);
  10570 
  10571     /*
  10572      * If riot is enabled,
  10573      *     MY_STATION1 will be used for tunnels.
  10574      *     MY_STATION2 will be used for routing.
  10575      * Else,
  10576      *     MY_STATION1 should be used for both tunnels and routing.
  10577      *     For this, USE_MY_STATION1_FOR_NON_TUNNELS should be set to TRUE.
  10578      */
  10579     if (!soc_feature(unit, soc_feature_riot)) {
  10580         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10581                 USE_MY_STATION1_FOR_NON_TUNNELSf, 1);
  10582     }
  10583 
  10584     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64));
  10585 
  10586     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1r,
  10587                                                REG_PORT_ANY, RING_MODEf, 1));
  10588 
  10589 
  10590     /* T2OQ needs to be setup for all ports that require 1 in 9 spacing or less
  10591      *  In Apache, it is safe to program all mmu ports 0-15 in T2OQ (whether in 
  10592      *  high speed mode or not). In TD2+, part of the MCQDB memory was re-used
  10593      *  for T2OQ; Apache has separate 160 deep MCQDB memory */
  10594     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOQ_MC_CFG1r,
  10595                                                REG_PORT_ANY, IS_MC_T2OQ_PORT0f,
  10596                                                0xffff));
  10597 
  10598     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
  10599      * causes the outer tag to be removed from packets that don't have
  10600      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
  10601      */
  10602     fields[0] = VT_MISS_UNTAGf; values[0] = 0;
  10603     fields[1] = REMARK_OUTER_DOT1Pf; values[1] = 1;
  10604     SOC_IF_ERROR_RETURN(soc_apc_mem_modify_range(unit, EGR_VLAN_CONTROL_1m,
  10605                                                  min_port, max_port,
  10606                                                  2, fields, values));
  10607 
  10608     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  10609     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
  10610     SOC_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit));
  10611     SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  10612                                      MEM_BLOCK_ANY, 0, &entry));
  10613     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, &pbmp);
  10614     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  10615                                       MEM_BLOCK_ANY, 0, &entry));
  10616 
  10617     if (soc_feature(unit, soc_feature_untethered_otp)) {
  10618         if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureL2mc4k)) {
  10619             l2mc_max_group_size = 4096;
  10620         }
  10621     }
  10622 
  10623     ipmc_max_group_size = soc_mem_index_count(unit, L3_IPMCm);
  10624 
  10625     /* Multicast range initialization */
  10626     SOC_IF_ERROR_RETURN(soc_hbx_higig2_mcast_sizes_set(unit,
  10627         soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
  10628                          SOC_HBX_MULTICAST_RANGE_DEFAULT),
  10629         MIN(l2mc_max_group_size, soc_property_get(unit,
  10630                 spn_HIGIG2_MULTICAST_L2_RANGE, l2mc_max_group_size)),
  10631         MIN(ipmc_max_group_size, soc_property_get(unit,
  10632                 spn_HIGIG2_MULTICAST_L3_RANGE, ipmc_max_group_size))));
  10633 
  10634     SOC_IF_ERROR_RETURN(soc_hbx_mcast_size_set(unit,
  10635         MIN(l2mc_max_group_size, soc_property_get(unit,
  10636                 spn_MULTICAST_L2_RANGE, l2mc_max_group_size))));
  10637 
  10638     SOC_IF_ERROR_RETURN(soc_hbx_ipmc_size_set(unit,
  10639         MIN(ipmc_max_group_size, soc_property_get(unit,
  10640                 spn_MULTICAST_L3_RANGE, ipmc_max_group_size))));
  10641 
  10642     /* Setup SW2_FP_DST_ACTION_CONTROL */
  10643     fields[0] = HGTRUNK_RES_ENf;
  10644     values[0] = 1;
  10645     fields[1] = LAG_RES_ENf;
  10646     values[1] = 1;
  10647     SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr,
  10648                                                 REG_PORT_ANY, 2, fields, values));
  10649 
  10650     /* Populate and enable RTAG7 Macro flow offset table */
  10651     if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) {
  10652         count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm);
  10653         sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t));
  10654         for (index = 0; index < count; ) {
  10655             for (sub_sel = 0; (sub_sel < 8) && (index < count); sub_sel++) {
  10656                 for (offset = 0;
  10657                      offset < rtag7_field_width[sub_sel] && index < count;
  10658                      offset++) {
  10659                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10660                                         SUB_SEL_ECMPf, sub_sel);
  10661                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10662                                         OFFSET_ECMPf, offset);
  10663 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  10664                     if ((soc_feature(unit, soc_feature_riot) ||
  10665                         soc_feature(unit, soc_feature_multi_level_ecmp))) {
  10666 
  10667                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10668                                             SUB_SEL_ECMP_LEVEL1f, sub_sel);
  10669                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10670                                             OFFSET_ECMP_LEVEL1f, offset);
  10671                     }
  10672 #endif
  10673                     SOC_IF_ERROR_RETURN
  10674                         (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm,
  10675                                        MEM_BLOCK_ANY, index, &entry));
  10676                     index++;
  10677                 }
  10678             }
  10679         }
  10680 
  10681         rval = 0;
  10682         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, USE_FLOW_SEL_ECMPf, 1);
  10683 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  10684         if ((soc_feature(unit, soc_feature_riot) ||
  10685             soc_feature(unit, soc_feature_multi_level_ecmp))) {
  10686 
  10687             soc_reg_field_set(unit, RTAG7_HASH_SELr,
  10688                 &rval, USE_FLOW_SEL_ECMP1f, 1);
  10689         }
  10690 #endif
  10691         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, 
  10692                                                 USE_FLOW_SEL_TRILL_ECMPf, 1);
  10693         SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_SELr(unit, rval));
  10694     }
  10695 
  10696     freq = si->frequency;
  10697 
  10698     /*
  10699      * Set external MDIO freq to around 6MHz
  10700      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  10701      */
  10702     target_freq = 6;
  10703     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  10704     divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, divisor);
  10705     dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1);
  10706     rval = 0;
  10707     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
  10708     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
  10709     WRITE_CMIC_RATE_ADJUSTr(unit, rval);
  10710 
  10711     /*
  10712      * Set internal MDIO freq to around 12MHz
  10713      * Valid range is from 2.5MHz to 20MHz
  10714      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  10715      * or
  10716      * DIVISOR = core_clock_freq * DIVIDENT / (target_freq * 2)
  10717      */
  10718     target_freq = 12;
  10719     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  10720     divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, divisor);
  10721     dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1);
  10722     rval = 0;
  10723     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf,
  10724                        divisor);
  10725     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf,
  10726                        dividend);
  10727     WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval);
  10728 
  10729     delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1);
  10730     if (delay >= 1  && delay <= 15) {
  10731         /* coverity[result_independent_of_operands] */
  10732         SOC_IF_ERROR_RETURN(READ_CMIC_MIIM_CONFIGr(unit, &rval));
  10733         soc_reg_field_set(unit, CMIC_MIIM_CONFIGr, &rval, MDIO_OUT_DELAYf,
  10734                           delay);
  10735         /* coverity[result_independent_of_operands] */
  10736         SOC_IF_ERROR_RETURN(WRITE_CMIC_MIIM_CONFIGr(unit, rval));
  10737     }
  10738 
  10739     if (!SOC_WARM_BOOT(unit)) {
  10740         SOC_IF_ERROR_RETURN(soc_apache_ledup_init(unit));
  10741     }
  10742 
  10743     if (soc_mspi_init(unit) != SOC_E_NONE) {
  10744         LOG_WARN(BSL_LS_SOC_COMMON,
  10745                  (BSL_META_U(unit,
  10746                              "unit %d : MSPI Init Failed\n"), unit));
  10747     }
  10748 
  10749     if (parity_enable) {
  10750         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
  10751         SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit));
  10752     }
  10753 
  10754     soc_ser_log_init(unit, NULL, 0);
  10755 
  10756     /* Setup config needed for EP-Redirection */
  10757     /* Enable re-direction */
  10758     rval = 0;
  10759     soc_reg_field_set(unit, EP_REDIR_CONTROLr, &rval, ENABLEf, 1);
  10760     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, EP_REDIR_CONTROLr,
  10761                                       REG_PORT_ANY, 0, rval));
  10762 
  10763     /* Enable RX/TX */
  10764     rval = 0;
  10765     soc_reg_field_set(unit, RDB_ENABLEr, &rval, RX_ENABLEf, 1);
  10766     soc_reg_field_set(unit, RDB_ENABLEr, &rval, TX_ENABLEf, 1);
  10767     soc_reg_field_set(unit, RDB_ENABLEr, &rval, CTRL_INITf, 1);
  10768     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, RDB_ENABLEr,
  10769                                       REG_PORT_ANY, 0, rval));
  10770 
  10771     /* Enable Credit */
  10772     rval = 0;
  10773     soc_reg_field_set(unit, RDB_CREDIT_ENABLEr, &rval, ENABLEf, 1);
  10774     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, RDB_CREDIT_ENABLEr,
  10775                                       REG_PORT_ANY, 0, rval));
  10776 
  10777     return SOC_E_NONE;
  10778 }
  10779 
  10780 uint32 _soc_apache_mmu_port(int unit, int port)
  10781 {
  10782     soc_info_t *si = &SOC_INFO(unit);
  10783     return si->port_p2m_mapping[si->port_l2p_mapping[port]];
  10784 }
  10785 
  10786 uint32 _soc_apache_piped_mem_index(int unit, soc_port_t port,
  10787                                      soc_mem_t mem, int arr_off)
  10788 {
  10789     int     mmu_port;
  10790 
  10791     mmu_port = SOC_APACHE_MMU_PORT(unit, port);
  10792 
  10793     switch (mem) {
  10794     case MMU_THDM_DB_PORTSP_CONFIG_0m:
  10795     case MMU_THDM_DB_PORTSP_CONFIG_1m:
  10796     case MMU_THDM_MCQE_PORTSP_CONFIG_0m:
  10797     case MMU_THDM_MCQE_PORTSP_CONFIG_1m:
  10798         /* RDB port does not have any THDM data so doing a minus 1 */
  10799         return (mmu_port & 0x7f) + (_APACHE_MMU_PORTS_PER_PIPE - 1) * arr_off;
  10800     case THDI_PORT_SP_CONFIG_Xm:
  10801     case MMU_THDU_XPIPE_CONFIG_PORTm:
  10802     case MMU_THDU_XPIPE_RESUME_PORTm:
  10803         return (mmu_port & 0x7f) * _APACHE_MMU_NUM_POOL + arr_off;
  10804     case THDI_PORT_PG_CONFIG_Xm:
  10805         return (mmu_port & 0x7f) * _APACHE_MMU_NUM_PG + arr_off;
  10806    default:
  10807         return 0xffffffff;
  10808     }
  10809 }
  10810 
  10811 #define _APACHE_MMU_BYTES_TO_CELLS(_byte_)  \
  10812     (((_byte_) + _APACHE_MMU_BYTES_PER_CELL - 1) / _APACHE_MMU_BYTES_PER_CELL)
  10813 
  10814 STATIC void
  10815 _soc_apache_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg,
  10816                              int lossless)
  10817 {
  10818     soc_info_t *si;
  10819     int ct_fifo_rsvd_count;
  10820     int qcn_port_count = 0;
  10821     soc_pbmp_t pbmp;
  10822     int port;
  10823 
  10824     si = &SOC_INFO(unit);
  10825 
  10826     sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t));
  10827 
  10828     devcfg->max_pkt_byte = si->max_mtu;
  10829     devcfg->mmu_hdr_byte = _APACHE_MMU_PACKET_HEADER_BYTES;
  10830     devcfg->jumbo_pkt_size = _APACHE_MMU_JUMBO_FRAME_BYTES;
  10831     devcfg->default_mtu_size = _APACHE_MMU_DEFAULT_MTU_BYTES;
  10832     devcfg->mmu_cell_size = _APACHE_MMU_BYTES_PER_CELL;
  10833 
  10834     /*
  10835      * Reserve 1 cell for each cut-through fifo entry
  10836      * Assume each port use 1 QCN queue, reserve 1 cell for each QCN queue
  10837      * Reserve 10 cells for ingress pool overshoot for lossless setting
  10838      */
  10839     ct_fifo_rsvd_count = 0;
  10840     SOC_PBMP_ASSIGN(pbmp, si->port.bitmap);
  10841     SOC_PBMP_REMOVE(pbmp, si->all.disabled_bitmap);
  10842 
  10843     SOC_PBMP_ITER(pbmp, port) {
  10844         qcn_port_count++;
  10845 
  10846         if (soc_feature(unit, soc_feature_asf)) {
  10847             ct_fifo_rsvd_count += si->port_speed_max[port] <= 11000 ? 4 : 16;
  10848         }
  10849     }
  10850 
  10851     /*
  10852      * Reserve cells for CT FIFO when Flexport is not enabled
  10853      * For Flexport cases, soc_apache_mmu_additional_buffer_reserve() will cover
  10854  */
  10855     if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  10856          ct_fifo_rsvd_count = 0;
  10857     }
  10858 
  10859     devcfg->mmu_total_cell = _APACHE_MMU_TOTAL_CELLS  -
  10860                              ct_fifo_rsvd_count  -
  10861                              qcn_port_count  -
  10862                              (lossless ? 10 : 0);
  10863    
  10864 
  10865     devcfg->num_pg = _APACHE_MMU_NUM_PG;
  10866     devcfg->num_service_pool = _APACHE_MMU_NUM_POOL;
  10867     devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN |
  10868                     SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY;
  10869     devcfg->total_mcq_entry = _APACHE_MMU_TOTAL_MCQ_ENTRY(unit);
  10870     devcfg->rqe_queue_num = 11;
  10871 }
  10872 
  10873 STATIC int
  10874 _soc_apache_default_lossless_pg_headroom(int unit, soc_port_t port)
  10875 {
  10876     soc_info_t *si;
  10877 
  10878     if (IS_RDB_PORT(unit, port)) {
  10879         return 0;
  10880     }
  10881     if (IS_CPU_PORT(unit, port)) {
  10882         return 50;
  10883     }
  10884     if (IS_LB_PORT(unit, port)) {
  10885         return 162;
  10886     }
  10887 
  10888     si = &SOC_INFO(unit);
  10889     if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  10890         if (si->port_speed_max[port] >= 100000) {
  10891             return 687;
  10892         } else if (si->port_speed_max[port] >= 50000) {
  10893              return 352;    
  10894         } else if (si->port_speed_max[port] >= 40000) {
  10895             return 338;
  10896         } else if (si->port_speed_max[port] >= 25000) {
  10897             return 214;
  10898         } else if (si->port_speed_max[port] >= 20000) {
  10899             return 206;
  10900         } else {
  10901             return 185;
  10902         }
  10903     } else {
  10904         if (si->port_speed_max[port] >= 100000) {
  10905             return 558;
  10906         } else if (si->port_speed_max[port] >= 50000) {
  10907              return 298;    
  10908         } else if (si->port_speed_max[port] >= 40000) {
  10909             return 284;
  10910         } else if (si->port_speed_max[port] >= 25000) {
  10911             return 191;
  10912         } else if (si->port_speed_max[port] >= 20000) {
  10913             return 183;
  10914         } else {
  10915             return 162;
  10916         }
  10917     }
  10918 
  10919     return 0;
  10920 }
  10921 
  10922 STATIC int
  10923 _soc_apache_min_cell_rsvd_per_mcq(int unit, int port, int default_val)
  10924 {
  10925     int freq, speed, osub;
  10926     soc_info_t *si;
  10927     uint8 rev_id;
  10928 
  10929     soc_cm_get_id(unit, NULL, &rev_id);
  10930 
  10931     if (rev_id == BCM56850_A1_REV_ID) {
  10932         si = &SOC_INFO(unit);
  10933         speed = si->port_speed_max[port];
  10934         osub = (SOC_PBMP_MEMBER(si->oversub_pbm, port)) ? 1 : 0;
  10935 
  10936         if (speed <= 11000) {
  10937             return (osub) ? 10 : 5;
  10938         } else if (speed <= 42000) {
  10939             freq = si->frequency;
  10940             return ((freq >= 760) && !osub) ? 9 : 16;
  10941         }
  10942     }
  10943 
  10944     return default_val;
  10945 }
  10946 
  10947 
  10948 /*
  10949 * Function:
  10950 *     soc_apache_mcq_entries_rsvd_port
  10951 * Purpose:
  10952 *     For a given port, soc_ap_mcq_entries_rsvd_port calculates
  10953 *     the number of MC q entries (Reserved Egress Queue Entries).
  10954 *     This function only gives MC q entries for
  10955 *     for flex disabled ports.
  10956 *     For flex enabled port macros, this function is not used.
  10957 * Parameters:
  10958 *     unit    - (IN) Unit number.
  10959 *     port    - (IN) logical port num
  10960 * Returns:
  10961 *     Reserved Egress Queue Entries for a given port
  10962  */
  10963 int soc_ap_mcq_entries_rsvd_port(int unit, int port)
  10964 {
  10965     int port_num_cosq;
  10966     soc_info_t *si;
  10967     int mcq_entry = 0;
  10968 
  10969     si = &SOC_INFO(unit);
  10970     port_num_cosq = si->port_num_cosq[port];
  10971     if (IS_LB_PORT(unit, port)) {
  10972         /* Loopback port has 9 queues (including QCN)
  10973          * For calculation of Egress queue entries,
  10974          * loopback port is considered having 8 queues
  10975          * (Why? :- ask Architecture)
  10976  */
  10977         port_num_cosq = si->port_num_cosq[port] - 1;
  10978     }
  10979 
  10980     mcq_entry = port_num_cosq * _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD;
  10981     return mcq_entry;
  10982 }
  10983 
  10984 int
  10985 soc_apache_mmu_additional_buffer_reserve(int unit,  int flex,
  10986                                      _soc_mmu_rsvd_buffer_t *rsvd_buffer)
  10987 {
  10988     soc_info_t *si;
  10989     int pg_min_cells = 0, qgrp_min_cells = 0, hdrm_cells = 0, asf_cells = 0;
  10990     int total_reserve = 0;
  10991     int lossless = 0;
  10992     int mcq_entry = 0;
  10993     int num_lanes = 4 ; 
  10994     int mc_num_cos = 10;
  10995     int pm, j, start_port, logical_port, start_pm, end_pm;
  10996     int pm_flex_enabled = 0;
  10997     int cut_through;
  10998     COMPILER_REFERENCE(si);
  10999     si = &SOC_INFO(unit);
  11000 
  11001     if(!rsvd_buffer) {
  11002         return SOC_E_PARAM;
  11003     }
  11004 
  11005     if (flex) {
  11006         return SOC_E_NONE;
  11007     }   
  11008 
  11009     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  11010     cut_through = soc_feature(unit, soc_feature_asf);
  11011 
  11012     start_pm = 0;
  11013     end_pm = 18 ;
  11014 
  11015     /* Per pipe, calculate the memory required on a per port macro (TSC4) basis */    
  11016     for (pm = start_pm; pm < end_pm; pm++) {
  11017         SOC_IF_ERROR_RETURN(
  11018             soc_ap_port_macro_flex_enabled(unit, pm, &pm_flex_enabled));
  11019 
  11020         /* if this port macro is flex enabled, allocate memory for it accordingly */
  11021         if (pm_flex_enabled == 1) {
  11022             /* Reserved Buffer for Flex Port Macro when Flex Port is enabled in
  11023                device */
  11024             if (lossless) {
  11025                 /* eagle port macro*/
  11026                 if( pm < 6  || (pm > 8 && pm< 16) ) {
  11027                     hdrm_cells      = (_AP_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 
  11028                                       *  num_lanes);
  11029                     pg_min_cells    = (_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS
  11030                                    * num_lanes);
  11031                     qgrp_min_cells  = 0;
  11032                     if (cut_through) {  
  11033                         asf_cells       = (_AP_RSVD_BUF_25G_FLEX_ASF
  11034                                           * 2);
  11035                     }
  11036                }else {
  11037                     /* falcom port macro */
  11038                     hdrm_cells      = (_AP_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS 
  11039                                       *  num_lanes);
  11040                     pg_min_cells    = (_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS
  11041                                    * num_lanes);
  11042                     qgrp_min_cells  = 0;
  11043                     if (cut_through) {  
  11044                         asf_cells       = (_AP_RSVD_BUF_25G_FLEX_ASF
  11045                                           * num_lanes);
  11046                     }
  11047 
  11048                } 
  11049             } else {
  11050                 if( pm < 6  || (pm > 8 && pm< 16) ) {
  11051                    hdrm_cells      = 0;
  11052                    pg_min_cells    = 0;
  11053                    qgrp_min_cells  = (_AP_RSVD_BUF_10G_FLEX_QGRP 
  11054                                    * num_lanes);
  11055 
  11056                    if (cut_through) {  
  11057                        asf_cells       = (_AP_RSVD_BUF_25G_FLEX_ASF
  11058                                    * 2);
  11059                    } 
  11060                } else { 
  11061                    hdrm_cells      = 0;
  11062                    pg_min_cells    = 0;
  11063                    qgrp_min_cells  = (_AP_RSVD_BUF_10G_FLEX_QGRP 
  11064                                    * num_lanes);
  11065 
  11066                    if (cut_through) {  
  11067                        asf_cells       = (_AP_RSVD_BUF_25G_FLEX_ASF
  11068                                    * num_lanes);
  11069                    } 
  11070 
  11071                }
  11072             }
  11073             mcq_entry = mc_num_cos * 
  11074                 _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD *
  11075                 num_lanes;
  11076         } else {
  11077             /*For port modules that are in non-flex mode, buffer is reserved 
  11078               per port (not port macro).
  11079              
  11080               Here we are calculating the buffer requirements for this TSC4 on
  11081               a per port basis. */
  11082             hdrm_cells = 0;
  11083             pg_min_cells = 0;
  11084             qgrp_min_cells = 0;
  11085             asf_cells = 0;
  11086             mcq_entry = 0;
  11087             start_port = (APACHE_PORTS_PER_TSC * pm ) + 1 ;
  11088             for (j = start_port; j < start_port + APACHE_PORTS_PER_TSC; j++) {
  11089                 /* figure out from the logical port what the speed of this port is */
  11090                 logical_port = si->port_p2l_mapping[j];
  11091                 if (logical_port == -1) {
  11092                     continue;
  11093                 }
  11094 
  11095                 if (si->port_speed_max[logical_port] >= 100000) {
  11096                     if (lossless) {
  11097                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11098                             hdrm_cells += _AP_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS; 
  11099                         } else { 
  11100                             hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS;
  11101                         }
  11102                         hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS;
  11103                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11104                         qgrp_min_cells  += 0;
  11105                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11106                     } else {
  11107                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11108                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11109                     }
  11110                 } else if (si->port_speed_max[logical_port] >= 50000) {
  11111                     if (lossless) {
  11112                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11113                             hdrm_cells  +=_AP_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS; 
  11114                         } else { 
  11115                             hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS;
  11116                         }
  11117                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11118                         qgrp_min_cells  += 0;
  11119                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11120                     } else {
  11121                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11122                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11123                     } 
  11124                 } else if (si->port_speed_max[logical_port] >= 40000) {
  11125                     if (lossless) {
  11126                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11127                             hdrm_cells      += 
  11128                               _AP_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS;
  11129                         } else { 
  11130                             hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS;
  11131                         }
  11132                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11133                         qgrp_min_cells  += 0;
  11134                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11135                     } else {
  11136                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11137                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11138                     }
  11139                 } else if (si->port_speed_max[logical_port] >= 25000) {
  11140                     if (lossless) {
  11141                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11142                             hdrm_cells      += 
  11143                                 _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS;
  11144                         } else { 
  11145                             hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS;
  11146                         }
  11147                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11148                         qgrp_min_cells  += 0;
  11149                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11150                     } else {
  11151                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11152                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11153                     }  
  11154                 } else if (si->port_speed_max[logical_port] >= 20000) {
  11155                     if (lossless) {
  11156                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11157                             hdrm_cells      += 
  11158                                   _AP_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS;
  11159                         } else {  
  11160                            hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS;
  11161                         } 
  11162                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11163                         qgrp_min_cells  += 0;
  11164                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11165                     } else {
  11166                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11167                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_ASF;
  11168                     }
  11169                 } else {
  11170                     if (lossless) {
  11171                         if (SOC_PBMP_MEMBER(si->oversub_pbm, j)) { 
  11172                             hdrm_cells      += 
  11173                                      _AP_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS;
  11174                         } else { 
  11175                             hdrm_cells      += _AP_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS;
  11176                         } 
  11177                         pg_min_cells    += _AP_RSVD_BUF_NON_FLEX_PGMIN;
  11178                         qgrp_min_cells  += 0;
  11179                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_10G_ASF;
  11180                     } else {
  11181                         qgrp_min_cells  += _AP_RSVD_BUF_NON_FLEX_QGRP;
  11182                         asf_cells       += _AP_RSVD_BUF_NON_FLEX_10G_ASF;
  11183                     }
  11184                 }
  11185                 mcq_entry += soc_ap_mcq_entries_rsvd_port(unit, logical_port);
  11186             }
  11187         }
  11188 
  11189         /* Add what was calculated for the port macro to the total */
  11190         rsvd_buffer->ing_rsvd_cells += (hdrm_cells + pg_min_cells);
  11191         rsvd_buffer->egr_rsvd_cells += qgrp_min_cells;
  11192         rsvd_buffer->asf_rsvd_cells += asf_cells;
  11193         rsvd_buffer->mcq_entry_rsvd += mcq_entry;
  11194     }
  11195 
  11196     total_reserve = rsvd_buffer->ing_rsvd_cells;
  11197     total_reserve += rsvd_buffer->egr_rsvd_cells;
  11198     total_reserve += rsvd_buffer->asf_rsvd_cells;
  11199 
  11200     LOG_VERBOSE(BSL_LS_SOC_MMU,
  11201                 (BSL_META_U(unit,
  11202                             "MMU config: Cells rsvd for Pipe %d,"
  11203                             " Flex/ASF per pipe: %d, Ing: %d,"
  11204                             " Egr: %d, ASF: %d MCQ %d\n"),
  11205                             0, total_reserve, rsvd_buffer->ing_rsvd_cells,
  11206                             rsvd_buffer->egr_rsvd_cells,
  11207                             rsvd_buffer->asf_rsvd_cells,
  11208                             rsvd_buffer->mcq_entry_rsvd));
  11209 
  11210     return SOC_E_NONE;
  11211 }
  11212 /*
  11213 * Function:
  11214 *     soc_ap_egr_buf_rsvd_port
  11215 * Purpose:
  11216 *     For Cpu port or loopback port,
  11217 *     soc_td2p_egr_buf_rsvd_port calculates
  11218 *     the reserved queue min/guarantee.
  11219 *     This function only gives cumulative (for all queues)
  11220 *     queue guarantee for CPU port or Loopback port.
  11221 * Parameters:
  11222 *     unit    - (IN) Unit number.
  11223 *     port    - (IN) logical port num for CPU port or LB port
  11224 * Returns:
  11225 *     Reserved Cumulative (total for all queues) Queue Min/Guarantee value
  11226  */
  11227 int soc_ap_egr_buf_rsvd_port(int unit, int port, int default_mtu_cells)
  11228 {
  11229     int port_num_cosq;
  11230     soc_info_t *si;
  11231     int egr_rsvd = 0;
  11232     int min_cell_per_mcq;
  11233 
  11234     if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) {
  11235         return 0;
  11236     }
  11237 
  11238     si = &SOC_INFO(unit);
  11239 
  11240     port_num_cosq = si->port_num_cosq[port];
  11241     if (IS_LB_PORT(unit, port)) {
  11242         /* Loopback port has 9 queues (including QCN)
  11243          * For calculation of Egress queue entries,
  11244          * loopback port is considered having 8 queues
  11245          * (Why? :- ask Architecture)
  11246  */
  11247         port_num_cosq = si->port_num_cosq[port] - 1;
  11248     }
  11249  
  11250 
  11251     if (soc_feature(unit, soc_feature_min_cell_per_queue)) {
  11252         min_cell_per_mcq = _soc_apache_min_cell_rsvd_per_mcq
  11253                              (unit, port, default_mtu_cells);
  11254     } else {
  11255         min_cell_per_mcq = default_mtu_cells;
  11256     }
  11257 
  11258     egr_rsvd = port_num_cosq * min_cell_per_mcq;
  11259     return egr_rsvd;
  11260 }
  11261 
  11262 STATIC void
  11263 _soc_apache_mmu_config_buf_default(int unit, _soc_mmu_cfg_buf_t *buf,
  11264                                 _soc_mmu_device_info_t *devcfg, int lossless)
  11265 {
  11266     soc_info_t *si;
  11267     _soc_mmu_cfg_buf_pool_t *buf_pool;
  11268     _soc_mmu_cfg_buf_port_t *buf_port;
  11269     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  11270     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  11271     _soc_mmu_cfg_buf_queue_t *buf_queue;
  11272     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  11273     int max_packet_cells, pg_min, default_mtu_cells;
  11274     int port, idx, per_q_guarentee;
  11275     int total_pool_size = 0, egr_shared_total = 0;
  11276     int q_reserved = 0, in_reserved = 0;
  11277     int mcq_entry_reserved = 0;
  11278     int mcq_entry_shared_total;
  11279     int rqe_entry_shared_total, min_cell_per_mcq;
  11280     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  11281     int asf_rsvd = 0, ing_rsvd = 0, egr_rsvd = 0;
  11282     si = &SOC_INFO(unit);
  11283 
  11284     min_cell_per_mcq = soc_feature(unit, soc_feature_min_cell_per_queue) ? 1 : 0;
  11285     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  11286                 (BSL_META_U(unit,
  11287                             "Initializing default MMU config (u=%d)\n"), unit));
  11288     max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte +
  11289                                                    devcfg->mmu_hdr_byte,
  11290                                                    devcfg->mmu_cell_size);
  11291     pg_min = _APACHE_MMU_PG_MIN;
  11292     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  11293                                                    devcfg->mmu_hdr_byte,
  11294                                                    devcfg->mmu_cell_size);
  11295 
  11296     total_pool_size = devcfg->mmu_total_cell;
  11297 
  11298     buf->headroom = 2 * _APACHE_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE;
  11299 
  11300     in_reserved += (buf->headroom/2);
  11301 
  11302     per_q_guarentee = _AP_RSVD_BUF_FLEX_QGRP ;
  11303     if (FALSE == si->flex_eligible) {
  11304         /* This checks to see if the new flex port method has been specified
  11305          in the config file and is being used */
  11306          if(soc_apache_is_any_port_flex_enable(unit)) {
  11307              soc_apache_mmu_additional_buffer_reserve(unit, 0, 
  11308                             &buf->rsvd_buffers[0]);
  11309           }
  11310     }
  11311     if (asf_rsvd < buf->rsvd_buffers[0].asf_rsvd_cells) {
  11312             asf_rsvd = buf->rsvd_buffers[0].asf_rsvd_cells;
  11313     }
  11314     if (egr_rsvd < buf->rsvd_buffers[0].egr_rsvd_cells) {
  11315         egr_rsvd = buf->rsvd_buffers[0].egr_rsvd_cells;
  11316     }
  11317     if (ing_rsvd < buf->rsvd_buffers[0].ing_rsvd_cells) {
  11318         ing_rsvd = buf->rsvd_buffers[0].ing_rsvd_cells;
  11319     }
  11320     
  11321     PBMP_ALL_ITER(unit, port) {
  11322         if (!IS_LB_PORT(unit,port) && !IS_CPU_PORT(unit,port) 
  11323              && !IS_RDB_PORT(unit,port) & !lossless) {  
  11324              q_reserved += 
  11325                per_q_guarentee;
  11326         }
  11327     }
  11328     if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  11329         total_pool_size -= asf_rsvd;
  11330         /* Legacy flex port (:i) is not enabled
  11331         * Overwrite total_rsvd with flexport reservations made
  11332         * Add cpu & lb port egr rsvd entries */
  11333         if (lossless) {
  11334             q_reserved = egr_rsvd +  88;
  11335         } else {
  11336             q_reserved = egr_rsvd + 
  11337                 soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) +
  11338                 soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) +
  11339                 88;
  11340         }
  11341         egr_shared_total = total_pool_size - q_reserved;
  11342     } else {
  11343         egr_shared_total = total_pool_size - q_reserved - 88;
  11344     }
  11345 
  11346     mcq_entry_shared_total = _APACHE_MMU_TOTAL_MCQ_ENTRY(unit) - mcq_entry_reserved;
  11347 
  11348     rqe_entry_shared_total = _APACHE_MMU_TOTAL_RQE_ENTRY(unit) - 88;
  11349 
  11350     for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  11351         buf_pool = &buf->pools[idx];
  11352 
  11353         if (idx == 0) {  /* 100% scale up by 100 */
  11354             buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  11355             buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  11356             buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  11357             buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  11358             buf_pool->total_rqe_entry = rqe_entry_shared_total;
  11359         } else {
  11360             buf_pool->size = 0;
  11361             buf_pool->yellow_size = 0;
  11362             buf_pool->red_size = 0;
  11363             buf_pool->total_mcq_entry = 0;
  11364             buf_pool->total_rqe_entry = 0;
  11365         }
  11366     }
  11367 
  11368     for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) {
  11369         queue_grp = &buf->qgroups[idx];
  11370         queue_grp->pool_limit = egr_shared_total;
  11371         if (lossless) {
  11372             queue_grp->guarantee = 0;
  11373             queue_grp->pool_scale = -1;
  11374             queue_grp->discard_enable = 0;
  11375             queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11376             queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11377         } else {
  11378             queue_grp->guarantee = 16;
  11379             queue_grp->discard_enable = 1;
  11380             queue_grp->pool_scale = 8;
  11381         }
  11382         queue_grp->pool_resume = default_mtu_cells * 2;
  11383         queue_grp->yellow_resume = default_mtu_cells * 2;
  11384         queue_grp->red_resume = default_mtu_cells * 2;
  11385     }
  11386 
  11387     PBMP_ALL_ITER(unit, port) {
  11388         buf_port = &buf->ports[port];
  11389 
  11390         /* internal priority to priority group mapping */
  11391         for (idx = 0; idx < 16; idx++) {
  11392             buf_port->pri_to_prigroup[idx] = 7;
  11393             if (lossless && IS_RDB_PORT(unit, port)) {
  11394                 if (idx < 5) {
  11395                     buf_port->pri_to_prigroup[idx] = idx + 2;
  11396                 }
  11397             }
  11398         }
  11399 
  11400         /* priority group to pool mapping */
  11401         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  11402             buf_port->prigroups[idx].pool_idx = 0;
  11403         }
  11404 
  11405         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  11406             buf_port_pool = &buf_port->pools[idx];
  11407             buf_port_pool->guarantee = 0;
  11408             buf_port_pool->pool_limit = 0;
  11409             buf_port_pool->pool_resume = 0;
  11410             if (idx == 0) {
  11411                 if (lossless && IS_RDB_PORT(unit, port)) {
  11412                     buf_port_pool->guarantee += 90;
  11413                 }
  11414                 buf_port_pool->pool_limit = total_pool_size;
  11415                 buf_port_pool->pool_resume = 
  11416                             total_pool_size - (default_mtu_cells * 2);
  11417             }
  11418             in_reserved += buf_port_pool->guarantee;
  11419         }
  11420 
  11421         buf_port->pkt_size = max_packet_cells;
  11422         
  11423         /* priority group */
  11424         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  11425             buf_prigroup = &buf_port->prigroups[idx];
  11426             buf_prigroup->guarantee = 0;
  11427             buf_prigroup->user_delay = -1;
  11428             buf_prigroup->switch_delay = -1;
  11429             buf_prigroup->pkt_size = max_packet_cells;
  11430             buf_prigroup->device_headroom_enable = 0;
  11431             buf_prigroup->pool_limit = 0;
  11432             buf_prigroup->pool_floor = 0;
  11433             buf_prigroup->pool_scale = -1;
  11434             buf_prigroup->headroom = 0;
  11435             buf_prigroup->pool_resume = 0;
  11436             buf_prigroup->flow_control_enable = 0;
  11437             if (lossless && IS_RDB_PORT(unit, port) && (idx < 7)) {
  11438                 buf_prigroup->device_headroom_enable = 1;
  11439                 buf_prigroup->headroom = 
  11440                     _soc_apache_default_lossless_pg_headroom(unit, port);
  11441                 buf_prigroup->pool_scale = 8;
  11442                 buf_prigroup->pool_resume = default_mtu_cells * 2;
  11443             }
  11444             if (idx == 7) {
  11445                 buf_prigroup->device_headroom_enable = 1;
  11446                 if (!IS_RDB_PORT(unit, port)) {
  11447                     buf_prigroup->flow_control_enable = lossless;
  11448                 }
  11449                 if (lossless) {
  11450                     buf_prigroup->headroom = 
  11451                         _soc_apache_default_lossless_pg_headroom(unit, port);
  11452                     if (!IS_RDB_PORT(unit, port) && buf_prigroup->headroom) {
  11453                         buf_prigroup->guarantee = pg_min;
  11454                     }
  11455                     buf_prigroup->pool_scale = 8;
  11456                     buf_prigroup->pool_resume = default_mtu_cells * 2;
  11457                 }
  11458                 if (!lossless && IS_CPU_PORT(unit, port)) {
  11459                     buf_prigroup->headroom = 
  11460                         _soc_apache_default_lossless_pg_headroom(unit, port);
  11461                 }
  11462             }
  11463             in_reserved += buf_prigroup->guarantee + buf_prigroup->headroom;
  11464         }
  11465 
  11466         /* multicast queue */
  11467         for (idx = 0; idx < si->port_num_cosq[port]; idx++) {
  11468             buf_queue = &buf_port->queues[idx];
  11469             buf_queue->qgroup_id = -1;
  11470             buf_queue->mcq_entry_guarantee = _AP_MMU_PER_COSQ_EGRESS_QENTRY_RSVD;
  11471             if (IS_LB_PORT(unit, port) && (idx == 8)) {
  11472                 buf_queue->mcq_entry_guarantee = 0;
  11473             }
  11474             if (lossless) {
  11475                 buf_queue->guarantee = min_cell_per_mcq ?
  11476                     _soc_apache_min_cell_rsvd_per_mcq(unit, port, 0) : 0;
  11477                 buf_queue->discard_enable = 0;
  11478                 buf_queue->pool_scale = -1;
  11479                 buf_queue->pool_limit = egr_shared_total;
  11480                 buf_queue->mcqe_limit = mcq_entry_shared_total;
  11481                 buf_queue->yellow_limit = mcq_entry_shared_total;
  11482                 buf_queue->red_limit = mcq_entry_shared_total;
  11483                 buf_queue->color_discard_enable = 0;
  11484                 buf_queue->pool_resume = 16;
  11485             } else {
  11486                 if (IS_CPU_PORT(unit, port) ||
  11487                         (IS_LB_PORT(unit, port) && (idx != (si->port_num_cosq[port]-1)))) {
  11488                     buf_queue->guarantee = min_cell_per_mcq ?
  11489                         _soc_apache_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) :
  11490                         default_mtu_cells;
  11491                 } else {   
  11492                     buf_queue->guarantee = min_cell_per_mcq ?  
  11493                              _soc_apache_min_cell_rsvd_per_mcq(unit, port, default_mtu_cells) : 0;
  11494                 }
  11495                 buf_queue->discard_enable = 1;
  11496                 buf_queue->pool_scale = 8;
  11497                 buf_queue->pool_limit = 0;
  11498                 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11499                                             | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11500                 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11501                                          | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11502                 buf_queue->color_discard_enable = 0;
  11503                 buf_queue->pool_resume = 16;
  11504                 if (soc_feature(unit, soc_feature_untethered_otp)) {
  11505                     if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu6Mb)) {
  11506                         buf_queue->qgroup_id = 0;
  11507                         buf_queue->discard_enable = 0;
  11508                         buf_queue->qgroup_min_enable= 1;
  11509                     }
  11510                 }
  11511             }
  11512         }
  11513 
  11514         /* unicast queue */
  11515         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
  11516             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
  11517             if (lossless) {
  11518                 buf_queue->qgroup_id = -1;
  11519                 buf_queue->guarantee = 0;
  11520                 buf_queue->discard_enable = 0;
  11521                 buf_queue->pool_scale = -1;
  11522                 buf_queue->pool_limit = egr_shared_total;
  11523                 buf_queue->yellow_limit = egr_shared_total;
  11524                 buf_queue->red_limit = egr_shared_total;
  11525                 buf_queue->color_discard_enable = 0;
  11526                 buf_queue->pool_resume = default_mtu_cells * 2;
  11527                 buf_queue->yellow_resume = default_mtu_cells * 2;
  11528                 buf_queue->red_resume = default_mtu_cells * 2;
  11529             } else {
  11530                 buf_queue->qgroup_id = 0;
  11531                 buf_queue->guarantee = 0;
  11532                 buf_queue->discard_enable = 1;
  11533                 buf_queue->pool_scale = 8;
  11534                 buf_queue->pool_limit = 0;
  11535                 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11536                                             | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11537                 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11538                                          | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11539                 buf_queue->color_discard_enable = 0;
  11540                 buf_queue->pool_resume = default_mtu_cells * 2;
  11541                 buf_queue->yellow_resume = default_mtu_cells * 2;
  11542                 buf_queue->red_resume = default_mtu_cells * 2;
  11543                 if (soc_feature(unit, soc_feature_untethered_otp)) {
  11544                     if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu6Mb)) {
  11545                         buf_queue->qgroup_id = 0;
  11546                         buf_queue->discard_enable = 0;
  11547                         buf_queue->qgroup_min_enable= 1;
  11548                     }
  11549                 }
  11550             }
  11551         }
  11552 
  11553         /* queue to pool mapping */
  11554         for (idx = 0; 
  11555              idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) {
  11556             buf_port->queues[idx].pool_idx = 0;
  11557         }
  11558     }
  11559 
  11560     PBMP_ALL_ITER(unit, port) {
  11561         buf_port = &buf->ports[port];
  11562         buf_prigroup = &buf_port->prigroups[7];
  11563         if (!lossless) {
  11564             buf_prigroup->pool_limit = total_pool_size - in_reserved;
  11565         }
  11566     }
  11567 
  11568     /* RQE */
  11569     for (idx = 0; idx < 11; idx++) {
  11570         buf_rqe_queue = &buf->rqe_queues[idx];
  11571         buf_rqe_queue->pool_idx = 0;
  11572         buf_rqe_queue->yellow_limit = egr_shared_total;
  11573         buf_rqe_queue->red_limit = egr_shared_total;
  11574         if (lossless) {
  11575             buf_rqe_queue->guarantee = 8;
  11576             buf_rqe_queue->discard_enable = 0;
  11577             buf_rqe_queue->pool_scale = -1;
  11578             buf_rqe_queue->pool_limit = egr_shared_total;
  11579         } else {
  11580             buf_rqe_queue->guarantee = default_mtu_cells;
  11581             buf_rqe_queue->discard_enable = 1;
  11582             buf_rqe_queue->pool_scale = 8;
  11583             buf_rqe_queue->pool_limit = 0;
  11584             buf_rqe_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11585             buf_rqe_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11586         }
  11587     }
  11588 
  11589 }
  11590 
  11591 STATIC int
  11592 _soc_apache_pool_scale_to_limit(int size, int scale)
  11593 {
  11594     int factor = 1000;
  11595 
  11596     switch (scale) {
  11597         case 7: factor = 875; break;
  11598         case 6: factor = 750; break;
  11599         case 5: factor = 625; break;
  11600         case 4: factor = 500; break;
  11601         case 3: factor = 375; break;
  11602         case 2: factor = 250; break;
  11603         case 1: factor = 125; break;
  11604         case 0:
  11605         default:
  11606             factor = 1000; break;
  11607     }
  11608     return (size * factor)/1000;
  11609 }
  11610 
  11611 STATIC int
  11612 _soc_apache_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf,
  11613                                _soc_mmu_device_info_t *devcfg, int lossless,
  11614                                soc_port_t input_port)
  11615 {
  11616     soc_info_t *si;
  11617     _soc_mmu_cfg_buf_pool_t *buf_pool;
  11618     _soc_mmu_cfg_buf_port_t *buf_port;
  11619     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  11620     _soc_mmu_cfg_buf_queue_t *buf_queue;
  11621     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  11622     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  11623     soc_mem_t mem, mem1, mem2, mem3;
  11624     uint32 rval, fval, rval2, rval3;
  11625     uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS];
  11626     thdi_port_pg_config_entry_t pg_config_mem;
  11627     thdi_port_sp_config_entry_t thdi_sp_config;
  11628     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  11629     mmu_thdu_xpipe_offset_qgroup_entry_t offset_qgrp;
  11630     int default_mtu_cells, limit, midx, pri, rlimit, min_resume_limit;
  11631     int port, base, numq, idx;
  11632     int jumbo_frame_cells, pval, rqlen, qbase;
  11633     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  11634     int port_count = 0;
  11635     soc_reg_t reg = INVALIDr; 
  11636     static const soc_field_t prigroup_reg[] = {
  11637         THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r
  11638     };
  11639     static const soc_field_t prigroup_field[] = {
  11640         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
  11641         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf,
  11642         PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
  11643         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
  11644     };
  11645     static const soc_field_t prigroup_spid_field[] = {
  11646         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  11647         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  11648     };
  11649     int index1;
  11650     int pool_resume = 0;
  11651     uint16      dev_id;
  11652     uint8       rev_id;
  11653     int         ing_rsvd = 0, egr_rsvd = 0, asf_rsvd = 0;
  11654     int total_rsvd = 0 ; 
  11655     int rqe_rsvd = 0 ;
  11656     int lb_hdrm = 0, cpu_hdrm = 0, rdb_hdrm = 0; 
  11657     int rqe =0 ;
  11658     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe;
  11659     int mcq_entry_rsvd = 0;
  11660     int q_reserved = 0;
  11661     uint32 e2ecc_ds_config;
  11662     soc_cm_get_id(unit, &dev_id, &rev_id);
  11663     min_resume_limit = soc_feature(unit, soc_feature_min_resume_limit_1) ? 8 : 0;
  11664 
  11665     si = &SOC_INFO(unit);
  11666 
  11667     jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size +
  11668                                                    devcfg->mmu_hdr_byte,
  11669                                                    devcfg->mmu_cell_size);
  11670     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  11671                                                    devcfg->mmu_hdr_byte,
  11672                                                    devcfg->mmu_cell_size);
  11673 
  11674     PBMP_ALL_ITER(unit, port) {
  11675        if (!IS_LB_PORT(unit,port) && !IS_CPU_PORT(unit,port) &&  
  11676             !IS_RDB_PORT(unit,port) && !lossless) {  
  11677            q_reserved += _AP_RSVD_BUF_FLEX_QGRP;
  11678        }
  11679     }
  11680     idx = 0 ; 
  11681     rval = 0;
  11682     fval = _APACHE_CFAPFULLSETPOINT;
  11683     if (input_port == -1) {
  11684         soc_reg_field_set(unit, CFAPFULLSETPOINTr, &rval, CFAPFULLSETPOINTf,
  11685                 fval);
  11686         SOC_IF_ERROR_RETURN(WRITE_CFAPFULLSETPOINTr(unit, rval));
  11687         rval = 0;
  11688         soc_reg_field_set(unit, CFAPFULLRESETPOINTr, &rval,
  11689                 CFAPFULLRESETPOINTf, fval - 2 * jumbo_frame_cells);
  11690         SOC_IF_ERROR_RETURN(WRITE_CFAPFULLRESETPOINTr(unit, rval));
  11691     }
  11692     if (asf_rsvd < buf->rsvd_buffers[idx].asf_rsvd_cells) {
  11693             asf_rsvd = buf->rsvd_buffers[idx].asf_rsvd_cells;
  11694     }
  11695     if (egr_rsvd < buf->rsvd_buffers[idx].egr_rsvd_cells) {
  11696            egr_rsvd = buf->rsvd_buffers[idx].egr_rsvd_cells;
  11697     }
  11698     if (ing_rsvd < buf->rsvd_buffers[idx].ing_rsvd_cells) {
  11699             ing_rsvd = buf->rsvd_buffers[idx].ing_rsvd_cells;
  11700     }
  11701     mcq_entry_rsvd = buf->rsvd_buffers[idx].mcq_entry_rsvd;
  11702   
  11703     LOG_VERBOSE(BSL_LS_SOC_MMU,
  11704                 (BSL_META_U(unit,
  11705                             "MMU config set HW: Cells rsvd : %d\n"),
  11706                             (ing_rsvd + egr_rsvd + asf_rsvd)));
  11707 
  11708     /* internal priority to priority group mapping */
  11709     PBMP_ALL_ITER(unit, port) {
  11710         if ((input_port != port) &&
  11711                 (input_port != -1)) {
  11712             continue;
  11713         }
  11714         buf_port = &buf->ports[port];
  11715 
  11716         for (idx = 0; idx < 16; idx++) {
  11717             if (idx % 8 == 0) { /* 8 fields per register */
  11718                 reg = prigroup_reg[idx / 8];
  11719                 rval = 0;
  11720             }
  11721             soc_reg_field_set(unit, reg, &rval, prigroup_field[idx],
  11722                               buf_port->pri_to_prigroup[idx]);
  11723             if (idx % 8 == 7) { /* 8 fields per register */
  11724                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  11725             }
  11726         }
  11727     }
  11728     if (input_port == -1) {
  11729         /* Input thresholds */
  11730         rval = 0;
  11731         soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 
  11732                 &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2);
  11733         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr, 
  11734                     REG_PORT_ANY, 0, rval));
  11735 
  11736 
  11737         fval = 0;
  11738         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  11739             if ((buf->pools[idx].size & ~_MMU_CFG_BUF_PERCENT_FLAG) != 0) {
  11740                 fval |= 1 << idx;
  11741             }
  11742         }
  11743 
  11744         rval = 0;
  11745         soc_reg_field_set(unit, THDI_BYPASSr, &rval, INPUT_THRESHOLD_BYPASSf, 0);
  11746         SOC_IF_ERROR_RETURN(WRITE_THDI_BYPASSr(unit, rval));
  11747 
  11748 
  11749         rval = 0;
  11750         soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, COLOR_AWAREf, 0);
  11751         soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, PUBLIC_ENABLEf, 1);
  11752         SOC_IF_ERROR_RETURN(WRITE_THDI_POOL_CONFIGr(unit, rval));
  11753 
  11754         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  11755             buf_pool = &buf->pools[idx];
  11756             if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  11757                 continue;
  11758             }
  11759             if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  11760                 /* Legacy flex port (:i) is not enabled */
  11761                 /* additional per port macro buffers reserved */
  11762                 /* Add cpu & lb port pg headroom */
  11763                 if (lossless) {
  11764                     lb_hdrm = _soc_apache_default_lossless_pg_headroom(
  11765                             unit,
  11766                             LB_PORT(unit));
  11767          
  11768                     cpu_hdrm = _soc_apache_default_lossless_pg_headroom(
  11769                             unit,
  11770                             CMIC_PORT(unit));
  11771                     rdb_hdrm = _soc_apache_default_lossless_pg_headroom(
  11772                             unit,
  11773                             RDB_PORT(unit));
  11774                     /* Add PG min for CPU & Loopback port  and RDB port min */
  11775                 }
  11776                 ing_rsvd = ing_rsvd + cpu_hdrm + lb_hdrm +rdb_hdrm + 
  11777                         2 *_AP_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS + _AP_MMU_RDB_PORT_MIN;
  11778             } else {
  11779               ing_rsvd = buf_pool->prigroup_headroom + buf_pool->prigroup_guarantee;  
  11780 
  11781             }
  11782 
  11783             if (lossless) {
  11784                 limit = devcfg->mmu_total_cell - (ing_rsvd+
  11785                         (buf->headroom/2) + 
  11786                         buf_pool->queue_guarantee + asf_rsvd);
  11787             } else {
  11788                  
  11789                 cpu_hdrm = _soc_apache_default_lossless_pg_headroom(
  11790                             unit,
  11791                             CMIC_PORT(unit));
  11792                 limit = buf_pool->total - 
  11793                     (buf->headroom/2) -  cpu_hdrm - asf_rsvd ;
  11794             }
  11795 
  11796             PBMP_ALL_ITER(unit, port) {
  11797                 port_count++;
  11798             }
  11799             port_count -= 1;
  11800             pool_resume = (port_count / 2) *  default_mtu_cells;
  11801 
  11802             rval = 0;
  11803             soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit);
  11804             SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, rval));
  11805 
  11806             rval = 0;
  11807             soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 
  11808                     OFFSETf, pool_resume);
  11809             SOC_IF_ERROR_RETURN(WRITE_THDI_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval));
  11810         }
  11811 
  11812         rval = 0;
  11813         SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr(unit, rval));
  11814 
  11815         /* output thresholds */
  11816         SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval));
  11817         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_QUEUE_AND_GROUP_TICKETf, 1);
  11818         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_UPDATE_COLOR_RESUMEf, 1);
  11819         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  11820         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  11821         SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval));
  11822 
  11823         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  11824         soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, MOP_POLICYf, 1);
  11825         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  11826 
  11827         /* per service pool settings */
  11828         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  11829             buf_pool = &buf->pools[idx];
  11830             if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  11831                 continue;
  11832             }
  11833              if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  11834                 /* Legacy flex port (:i) is not enabled
  11835                 * Overwrite total_rsvd with flexport reservations made
  11836                 * Add cpu & lb port egr rsvd entries */
  11837                 if (devcfg->flags & SOC_MMU_CFG_F_RQE) {
  11838                     for (rqe = 0; rqe < 11; rqe++) {
  11839                         buf_rqe = &buf->rqe_queues[rqe];
  11840                         rqe_rsvd += buf_rqe->guarantee;
  11841                     }
  11842                 }
  11843                 if (lossless) {
  11844                     total_rsvd = egr_rsvd +  rqe_rsvd;
  11845                 } else {
  11846                     total_rsvd = egr_rsvd + 
  11847                         soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) +
  11848                         soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) +
  11849                         rqe_rsvd;
  11850                 }
  11851             } else { 
  11852     
  11853               total_rsvd = buf_pool->queue_guarantee + q_reserved;  
  11854 
  11855             }
  11856  
  11857             limit = buf_pool->total - ( total_rsvd + asf_rsvd);
  11858 
  11859             if (limit <= 0) {
  11860                 limit = 0;
  11861             }
  11862 
  11863             rval = 0;
  11864             soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 
  11865                     SHARED_LIMITf, limit);
  11866             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, idx, rval));
  11867 
  11868             rval = 0;
  11869             soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 
  11870                     &rval, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  11871             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, idx, rval));
  11872 
  11873             rval = 0;
  11874             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 
  11875                     &rval, RED_SHARED_LIMITf, (limit + 7)/8);
  11876             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, idx, rval));
  11877 
  11878             rval = 0;
  11879             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 
  11880                     &rval, RESUME_LIMITf, (limit + 7) /8);
  11881             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, idx, rval));
  11882 
  11883             rval = 0;
  11884             soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 
  11885                     &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8);
  11886             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, idx, rval));
  11887 
  11888             rval = 0;
  11889             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 
  11890                     &rval, RED_RESUME_LIMITf, (limit + 7)/8);
  11891             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, idx, rval));
  11892 
  11893             total_rsvd = 0 ; 
  11894             if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  11895                 /* Legacy flex port (:i) is not enabled */
  11896                 /* additional per port macro mcq entries reserved */
  11897                 /* Add cpu & lb port mcs entries */
  11898                 total_rsvd = mcq_entry_rsvd +
  11899                     soc_ap_mcq_entries_rsvd_port(unit, CMIC_PORT(unit)) +
  11900                     soc_ap_mcq_entries_rsvd_port(unit, LB_PORT(unit));
  11901             } else {
  11902                 /* cpu & lb port mcq reserved entries already included
  11903                  *  in buf_pool->mcq_entry_reserved
  11904                  */
  11905                 total_rsvd = buf_pool->mcq_entry_reserved;
  11906             }
  11907 
  11908             /* mcq entries */
  11909             limit = buf_pool->total_mcq_entry - total_rsvd; 
  11910             
  11911 
  11912             rval = 0;
  11913             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 
  11914                     &rval, SHARED_LIMITf, limit/4);
  11915             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 
  11916                         idx, rval));
  11917 
  11918             rval = 0;
  11919             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 
  11920                     &rval, YELLOW_SHARED_LIMITf, (limit + 7)/ 8);
  11921             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 
  11922                         idx, rval));
  11923 
  11924             rval = 0;
  11925             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 
  11926                     &rval, RED_SHARED_LIMITf, (limit + 7)/8);
  11927             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 
  11928                         idx, rval));
  11929 
  11930             rval = 0;
  11931             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 
  11932                     &rval, RESUME_LIMITf, (limit + 7)/8);
  11933             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 
  11934                         idx, rval));
  11935 
  11936             rval = 0;
  11937             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 
  11938                     &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8);
  11939             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 
  11940                         idx, rval));
  11941 
  11942             rval = 0;
  11943             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 
  11944                     &rval, RED_RESUME_LIMITf, (limit + 7)/8);
  11945             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 
  11946                         idx, rval));
  11947         }
  11948 
  11949         rval = 0;
  11950         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 
  11951                 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  11952         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  11953         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  11954         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval));
  11955 
  11956         rval = 0;
  11957         soc_reg_field_set(unit, MMU_THDR_QE_CONFIGr, &rval, 
  11958                 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  11959         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIGr(unit, rval));
  11960 
  11961         /* configure Q-groups */
  11962         for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) {
  11963             queue_grp = &buf->qgroups[idx];
  11964 
  11965             mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  11966             mem1 = MMU_THDU_XPIPE_OFFSET_QGROUPm;
  11967 
  11968             sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  11969             sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp));
  11970 
  11971             soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11972                     Q_MIN_LIMIT_CELLf, queue_grp->guarantee);
  11973 
  11974             if (queue_grp->pool_scale != -1) {
  11975                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11976                         Q_SHARED_ALPHA_CELLf, queue_grp->pool_scale);
  11977                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11978                         Q_LIMIT_DYNAMIC_CELLf, 1);
  11979             } else {
  11980                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11981                         Q_SHARED_LIMIT_CELLf, queue_grp->pool_limit);
  11982             }
  11983 
  11984             if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  11985                 pval = _soc_apache_pool_scale_to_limit(queue_grp->pool_limit,
  11986                         queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  11987                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11988                         LIMIT_RED_CELLf, (pval + 7)/8);
  11989 
  11990             } else {
  11991                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11992                         LIMIT_RED_CELLf, queue_grp->red_limit);
  11993                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  11994                         Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  11995             }
  11996 
  11997             if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  11998                 pval = _soc_apache_pool_scale_to_limit(queue_grp->pool_limit,
  11999                         queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  12000                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12001                         LIMIT_YELLOW_CELLf, (pval + 7)/8);
  12002 
  12003             } else {
  12004                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12005                         LIMIT_YELLOW_CELLf, queue_grp->yellow_limit);
  12006                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12007                         Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  12008             }
  12009             SOC_IF_ERROR_RETURN
  12010                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  12011 
  12012             soc_mem_field32_set(unit, mem1, 
  12013                     &offset_qgrp, RESET_OFFSET_CELLf, queue_grp->pool_resume / 8);
  12014             soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_YELLOW_CELLf,
  12015                     queue_grp->yellow_resume / 8);
  12016             soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_RED_CELLf,
  12017                     queue_grp->red_resume / 8);
  12018 
  12019             SOC_IF_ERROR_RETURN
  12020                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp));
  12021         }
  12022     }
  12023 
  12024     /* Input port per port settings */
  12025     PBMP_ALL_ITER(unit, port) {
  12026         if ((input_port != port) &&
  12027                 (input_port != -1)) {
  12028             continue;
  12029         }
  12030 
  12031         buf_port = &buf->ports[port];
  12032 
  12033         rval = 0;
  12034         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  12035             soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval,
  12036                               prigroup_spid_field[idx],
  12037                               buf_port->prigroups[idx].pool_idx);
  12038         }
  12039         SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval));
  12040 
  12041         mem = THDI_PORT_SP_CONFIG_Xm;
  12042         /* Per port per pool settings */
  12043         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  12044             buf_port_pool = &buf_port->pools[idx];
  12045             midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12046             sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config));
  12047             soc_mem_field32_set(unit, mem, &thdi_sp_config, 
  12048                                 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee);
  12049             soc_mem_field32_set(unit, mem, &thdi_sp_config, 
  12050                            PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume);
  12051             soc_mem_field32_set(unit, mem, &thdi_sp_config, 
  12052                                PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit);
  12053             SOC_IF_ERROR_RETURN
  12054                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, &thdi_sp_config));
  12055         }
  12056 
  12057         fval = 0;
  12058         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  12059             if (buf_port->prigroups[idx].flow_control_enable != 0) {
  12060                 for (pri=0; pri < 16; pri++) {
  12061                     if (buf_port->pri_to_prigroup[pri] == idx) {
  12062                         fval |= 1 << pri;
  12063                     }
  12064                 }
  12065             }
  12066         }
  12067 
  12068         rval = 0;
  12069         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  12070                                           INPUT_PORT_RX_ENABLEf, 1);
  12071         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  12072                           PORT_PRI_XON_ENABLEf, fval);
  12073         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  12074                           PORT_PAUSE_ENABLEf, fval ? 1 : 0);
  12075         SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval));
  12076 
  12077         rval = 0;
  12078         soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 
  12079                             PORT_MAX_PKT_SIZEf, buf_port->pkt_size);
  12080         SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval));
  12081 
  12082         /* Input port per port per priority group settings */
  12083         mem = THDI_PORT_PG_CONFIG_Xm;
  12084         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  12085             buf_prigroup = &buf->ports[port].prigroups[idx];
  12086 
  12087             midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12088             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  12089             soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12090                                 PG_MIN_LIMITf, buf_prigroup->guarantee);
  12091 
  12092             if (buf_prigroup->pool_scale != -1) {
  12093                 soc_mem_field32_set(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf, 1);
  12094                 soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12095                                     PG_SHARED_LIMITf, buf_prigroup->pool_scale);
  12096             } else {
  12097                 soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12098                                    PG_SHARED_LIMITf, buf_prigroup->pool_limit);
  12099             }
  12100 
  12101             soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12102                          PG_GBL_HDRM_ENf, buf_prigroup->device_headroom_enable);
  12103             soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12104                                        PG_HDRM_LIMITf, buf_prigroup->headroom);
  12105 
  12106             soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12107                                  PG_RESET_OFFSETf, buf_prigroup->pool_resume);
  12108 
  12109             soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12110                                   PG_RESET_FLOORf, buf_prigroup->pool_floor);
  12111                                         
  12112             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 
  12113                                            MEM_BLOCK_ALL, midx, &pg_config_mem));
  12114         }
  12115     }
  12116 
  12117     /***********************************
  12118      * THDO 
  12119  */
  12120     /* Output port per port per queue setting for regular multicast queue */
  12121     PBMP_ALL_ITER(unit, port) {
  12122         if ((input_port != port) &&
  12123                 (input_port != -1)) {
  12124             continue;
  12125         }
  12126 
  12127         if (IS_RDB_PORT(unit, port)) {
  12128             continue;
  12129         }
  12130 
  12131         numq = si->port_num_cosq[port];
  12132         qbase = si->port_cosq_base[port];
  12133         if (numq == 0) {
  12134             continue;
  12135         }
  12136 
  12137         mem = MMU_THDM_DB_QUEUE_CONFIG_0m;
  12138 
  12139         base = soc_apache_l2_hw_index(unit, qbase, 0) - _APACHE_MC_QUEUE_BASE;
  12140 
  12141         mem1 = MMU_THDM_DB_QUEUE_OFFSET_0m;
  12142         mem2 = MMU_THDM_MCQE_QUEUE_OFFSET_0m;
  12143 
  12144         for (idx = 0; idx < numq; idx++) {
  12145             buf_queue = &buf->ports[port].queues[idx];
  12146 
  12147             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  12148 
  12149             soc_mem_field32_set(unit, mem, entry0, 
  12150                                 Q_MIN_LIMITf, buf_queue->guarantee);
  12151             if (buf_queue->discard_enable) {
  12152                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  12153             }
  12154             if (buf_queue->color_discard_enable) {
  12155                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  12156             }
  12157             if (buf_queue->pool_scale != -1) {
  12158                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  12159                 soc_mem_field32_set(unit, mem, entry0,
  12160                            Q_SHARED_ALPHAf, buf_queue->pool_scale);
  12161             } else {
  12162                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  12163                 soc_mem_field32_set(unit, mem, entry0,
  12164                                Q_SHARED_LIMITf, buf_queue->pool_limit);
  12165             }
  12166             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  12167                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  12168                 soc_mem_field32_set(unit, mem, entry0,
  12169                                     Q_COLOR_LIMIT_DYNAMICf, 1);
  12170                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  12171                         buf_queue->yellow_limit
  12172                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12173                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12174                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  12175                         buf_queue->red_limit
  12176                                  & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12177                                  & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12178             } else {
  12179                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  12180                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  12181                      (buf_queue->pool_limit + 7) / 8);
  12182                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  12183                      (buf_queue->pool_limit + 7) / 8);
  12184             }
  12185 
  12186             soc_mem_field32_set(unit, mem, entry0, 
  12187                                 Q_SPIDf, buf_queue->pool_idx);
  12188 
  12189             SOC_IF_ERROR_RETURN
  12190                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  12191                                entry0));
  12192 
  12193             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t));
  12194 
  12195             soc_mem_field32_set(unit, mem1, entry0, 
  12196                                 RESUME_OFFSETf, (default_mtu_cells * 2)/8);
  12197             soc_mem_field32_set(unit, mem1, entry0, 
  12198                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  12199             soc_mem_field32_set(unit, mem1, entry0, 
  12200                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
  12201             SOC_IF_ERROR_RETURN
  12202                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  12203                                entry0));
  12204 
  12205             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_0_entry_t));
  12206             soc_mem_field32_set(unit, mem1, entry0, 
  12207                     RESUME_OFFSETf, 1);
  12208             SOC_IF_ERROR_RETURN
  12209                 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx,
  12210                                entry0));
  12211 
  12212             SOC_IF_ERROR_RETURN
  12213                 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0,
  12214                                         YELLOW_RESUME_OFFSETf, 
  12215                                         2));
  12216 
  12217             SOC_IF_ERROR_RETURN
  12218                 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0,
  12219                                         RED_RESUME_OFFSETf, 
  12220                                         2));
  12221         }
  12222 
  12223         mem = MMU_THDM_MCQE_QUEUE_CONFIG_0m;
  12224         for (idx = 0; idx < numq; idx++) {
  12225             buf_queue = &buf->ports[port].queues[idx];
  12226 
  12227             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_0_entry_t));
  12228 
  12229             soc_mem_field32_set(unit, mem, entry0, 
  12230                                 Q_MIN_LIMITf, buf_queue->mcq_entry_guarantee/4);
  12231             if (buf_queue->discard_enable) {
  12232                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  12233             }
  12234             if (buf_queue->color_discard_enable) {
  12235                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  12236             }
  12237             if (buf_queue->pool_scale != -1) {
  12238                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  12239                 soc_mem_field32_set(unit, mem, entry0,
  12240                            Q_SHARED_ALPHAf, buf_queue->pool_scale);
  12241             } else {
  12242                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  12243                 soc_mem_field32_set(unit, mem, entry0,
  12244                                Q_SHARED_LIMITf, buf_queue->mcqe_limit/4);
  12245             }
  12246             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  12247                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  12248                 soc_mem_field32_set(unit, mem, entry0,
  12249                                     Q_COLOR_LIMIT_DYNAMICf, 1);
  12250                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  12251                      buf_queue->yellow_limit
  12252                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12253                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12254                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  12255                      buf_queue->red_limit
  12256                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12257                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12258             } else {
  12259                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  12260                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  12261                      (buf_queue->yellow_limit + 7) / 8);
  12262                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  12263                      (buf_queue->red_limit + 7)/ 8);
  12264             }
  12265 
  12266             soc_mem_field32_set(unit, mem, entry0, 
  12267                                 Q_SPIDf, buf_queue->pool_idx);
  12268 
  12269             SOC_IF_ERROR_RETURN
  12270                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  12271                                entry0));
  12272 
  12273             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t));
  12274 
  12275             soc_mem_field32_set(unit, mem1, entry0, 
  12276                                 RESUME_OFFSETf, (default_mtu_cells * 2)/8);
  12277             soc_mem_field32_set(unit, mem1, entry0, 
  12278                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  12279             soc_mem_field32_set(unit, mem1, entry0, 
  12280                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
  12281             SOC_IF_ERROR_RETURN
  12282                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  12283                                entry0));
  12284 
  12285             SOC_IF_ERROR_RETURN
  12286                 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0,
  12287                                         YELLOW_RESUME_OFFSETf, 
  12288                                         1));
  12289 
  12290             SOC_IF_ERROR_RETURN
  12291                 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0,
  12292                                         RED_RESUME_OFFSETf, 
  12293                                         1));
  12294         }
  12295 
  12296         /* Per  port per pool */
  12297         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  12298             buf_pool = &buf->pools[idx];
  12299             if (buf_pool->total == 0) {
  12300                 continue;
  12301             }
  12302             total_rsvd =0;
  12303             buf_rqe = 0;
  12304             rqe_rsvd = 0;  
  12305             if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  12306                 /* Legacy flex port (:i) is not enabled
  12307                 * Overwrite total_rsvd with flexport reservations made
  12308                 * Add cpu & lb port egr rsvd entries */
  12309                 if (devcfg->flags & SOC_MMU_CFG_F_RQE) {
  12310                     for (rqe = 0; rqe < 11; rqe++) {
  12311                         buf_rqe = &buf->rqe_queues[rqe];
  12312                         rqe_rsvd += buf_rqe->guarantee;
  12313                     }
  12314                 }
  12315                 if (lossless) {
  12316                     total_rsvd = egr_rsvd +  rqe_rsvd;
  12317                 } else {
  12318                     total_rsvd = egr_rsvd + 
  12319                         soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) +
  12320                         soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) +
  12321                         rqe_rsvd;
  12322                 }
  12323             } else { 
  12324                 
  12325               total_rsvd = buf_pool->queue_guarantee + q_reserved;  
  12326             }
  12327             limit = buf_pool->total - total_rsvd;
  12328             if ((limit - 2 * default_mtu_cells) > 0) {
  12329                 rlimit = ((limit - 2 * default_mtu_cells) < min_resume_limit) ?
  12330                     min_resume_limit : limit - 2 * default_mtu_cells;
  12331             } else {
  12332                 rlimit = min_resume_limit;
  12333             }
  12334             mem2 = MMU_THDM_DB_PORTSP_CONFIG_0m;
  12335             index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  12336             sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  12337 
  12338             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  12339             soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8);
  12340             soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  12341 
  12342             soc_mem_field32_set(unit, mem2, entry0, 
  12343                                             SHARED_LIMIT_ENABLEf, !lossless);
  12344 
  12345             soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, (rlimit + 7)/8);
  12346             soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, (rlimit + 7)/8);
  12347             soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, (rlimit + 7)/8);
  12348             
  12349             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 
  12350                                 index1, entry0));
  12351 
  12352             mem2 = MMU_THDM_MCQE_PORTSP_CONFIG_0m;
  12353             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_0_entry_t));
  12354 
  12355             limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved;
  12356             rlimit = (limit < min_resume_limit) ? min_resume_limit : limit;
  12357 
  12358             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, (limit + 3)/4);
  12359             soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, 
  12360                     ((rlimit/8) - 1));
  12361             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMIT_ENABLEf, !lossless);
  12362             soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8);
  12363             soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, 
  12364                     ((rlimit + 7)/8 - 1));
  12365             soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  12366             soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, 
  12367                     ((rlimit + 7)/8 -1));
  12368 
  12369             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 
  12370                                 index1, entry0));
  12371         }
  12372     }
  12373 
  12374     /* Output port per port per queue setting for regular unicast queue */
  12375     PBMP_PORT_ITER(unit, port) {
  12376         if ((input_port != port) &&
  12377                 (input_port != -1)) {
  12378             continue;
  12379         }
  12380 
  12381         if(IS_RDB_PORT(unit, port)) {
  12382             continue;
  12383         }
  12384         /* per port regular unicast queue */
  12385         numq = si->port_num_uc_cosq[port];
  12386         qbase = si->port_uc_cosq_base[port];
  12387         if (numq == 0) {
  12388             continue;
  12389         }
  12390         base = soc_apache_l2_hw_index(unit, qbase, 1);
  12391         mem = MMU_THDU_XPIPE_CONFIG_QUEUEm;
  12392         mem1 = MMU_THDU_XPIPE_OFFSET_QUEUEm;
  12393         mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm;
  12394         for (idx = 0; idx < numq; idx++) {
  12395             buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx];
  12396 
  12397             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  12398             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_offset_queue_entry_t));
  12399 
  12400             soc_mem_field32_set(unit, mem, entry0, 
  12401                                 Q_MIN_LIMIT_CELLf, buf_queue->guarantee);
  12402             if (buf_queue->pool_scale != -1) {
  12403                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf, 1);
  12404                 soc_mem_field32_set(unit, mem, entry0,
  12405                            Q_SHARED_ALPHA_CELLf, buf_queue->pool_scale);
  12406             } else {
  12407                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  12408                 soc_mem_field32_set(unit, mem, entry0,
  12409                                Q_SHARED_LIMIT_CELLf, buf_queue->pool_limit);
  12410             }
  12411             soc_mem_field32_set(unit, mem1, 
  12412                 entry1, RESET_OFFSET_CELLf, buf_queue->pool_resume / 8);
  12413 
  12414             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  12415                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  12416                 soc_mem_field32_set(unit, mem, entry0,
  12417                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  12418                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  12419                      buf_queue->yellow_limit
  12420                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12421                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12422                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  12423                      buf_queue->red_limit
  12424                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  12425                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  12426             } else {
  12427                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  12428                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  12429                                          (buf_queue->yellow_limit + 7) / 8);
  12430                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  12431                                          (buf_queue->red_limit + 7) / 8);
  12432             }
  12433             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf,
  12434                                 buf_queue->yellow_resume / 8);
  12435             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf,
  12436                                 buf_queue->red_resume / 8);
  12437             SOC_IF_ERROR_RETURN
  12438                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  12439 
  12440             SOC_IF_ERROR_RETURN
  12441                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1));
  12442 
  12443             sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t));
  12444             soc_mem_field32_set(unit, mem2,
  12445                     entry0, Q_SPIDf, buf_queue->pool_idx);
  12446             if (buf_queue->discard_enable) {
  12447                 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1);
  12448             }
  12449             if (buf_queue->color_discard_enable) {
  12450                 soc_mem_field32_set(unit, mem2, entry0, QGROUP_COLOR_ENABLE_CELLf, 1);
  12451                 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_ENABLE_CELLf, 1);
  12452             }
  12453             if (buf_queue->qgroup_id >= 0) {
  12454                 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1);
  12455                 soc_mem_field32_set(unit, mem2, entry0, QGROUPf, buf_queue->qgroup_id);
  12456                 if (buf_queue->qgroup_min_enable) {
  12457                     soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1);
  12458                 }
  12459             }
  12460             if (soc_mem_field_length(unit, mem2, Q_E2ECC_DS_CONFIGf) > 2) {
  12461                 e2ecc_ds_config = IS_AP_HSP_PORT(unit,port) ? 4 : 1;
  12462             } else {
  12463                 if (IS_AP_HSP_PORT(unit,port)) {
  12464                     if ((idx < 8) && (buf_queue->qgroup_id < 0)) {
  12465                         /* If HSP port does not use qgroup for its lower 8 queues */
  12466                         soc_mem_field32_set(unit, mem2, entry0, QGROUPf, idx);
  12467                         e2ecc_ds_config = 2;
  12468                     } else {
  12469                         e2ecc_ds_config = 1;
  12470                     }
  12471                 } else {
  12472                     /* LLS port */
  12473                     e2ecc_ds_config = 1;
  12474                 }
  12475             }
  12476 
  12477             soc_mem_field32_set(unit, mem2, entry0, Q_E2ECC_DS_CONFIGf, e2ecc_ds_config);
  12478             
  12479             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 
  12480                                 base + idx, entry0));
  12481         }
  12482         
  12483         /* Per  port per pool unicast */
  12484         for (idx = 0; idx < _APACHE_MMU_NUM_POOL; idx++) {
  12485             buf_pool = &buf->pools[idx];
  12486 
  12487             if (buf_pool->total == 0) {
  12488                 continue;
  12489             }
  12490             total_rsvd = 0;
  12491             buf_rqe = 0;
  12492             rqe_rsvd = 0;  
  12493             if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  12494                 /* Legacy flex port (:i) is not enabled
  12495                 * Overwrite total_rsvd with flexport reservations made
  12496                 * Add cpu & lb port egr rsvd entries */
  12497                 if (devcfg->flags & SOC_MMU_CFG_F_RQE) {
  12498                     for (rqe = 0; rqe < 11; rqe++) {
  12499                         buf_rqe = &buf->rqe_queues[rqe];
  12500                         rqe_rsvd += buf_rqe->guarantee;
  12501                     }
  12502                 }
  12503                 if (lossless) {
  12504                     total_rsvd = egr_rsvd +  rqe_rsvd;
  12505                 } else {
  12506                     total_rsvd = egr_rsvd + 
  12507                         soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) +
  12508                         soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) +
  12509                         rqe_rsvd;
  12510                 }
  12511             } else { 
  12512                 
  12513                 total_rsvd = buf_pool->queue_guarantee + q_reserved;  
  12514             }
  12515             limit = buf_pool->total - total_rsvd ;
  12516             mem2 = MMU_THDU_XPIPE_CONFIG_PORTm;
  12517             index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  12518             mem3 = MMU_THDU_XPIPE_RESUME_PORTm;
  12519             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  12520             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_resume_port_entry_t));
  12521 
  12522             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  12523             soc_mem_field32_set(unit, mem3, entry1,
  12524                          SHARED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  12525 
  12526             soc_mem_field32_set(unit, mem2, entry0, YELLOW_LIMITf, (limit + 7)/8);
  12527             soc_mem_field32_set(unit, mem3, entry1,
  12528                             YELLOW_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  12529 
  12530             soc_mem_field32_set(unit, mem2, entry0, RED_LIMITf, (limit + 7)/8);
  12531             soc_mem_field32_set(unit, mem3, entry1,
  12532                               RED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  12533             
  12534             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 
  12535                                 index1, entry0));
  12536             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem3, MEM_BLOCK_ALL, 
  12537                                 index1, entry1));
  12538         }
  12539     }
  12540    
  12541     if (input_port == -1) {
  12542         /* RQE */
  12543         for (idx = 0; idx < 11; idx++) {
  12544             buf_rqe_queue = &buf->rqe_queues[idx];
  12545 
  12546             rval = 0;
  12547             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 
  12548                     &rval, MIN_LIMITf, buf_rqe_queue->guarantee);
  12549             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval));
  12550 
  12551             rval = 0;
  12552             rval2 = 0;
  12553             rval3 = 0;
  12554             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 
  12555                     &rval, SPIDf, buf_rqe_queue->pool_idx);
  12556 
  12557             if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  12558                     (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  12559                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 
  12560                         &rval, COLOR_LIMIT_DYNAMICf, 1);
  12561                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 
  12562                         SHARED_RED_LIMITf, buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  12563                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 
  12564                         SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  12565             } else {
  12566                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 
  12567                         SHARED_RED_LIMITf, (buf_rqe_queue->red_limit + 7)/ 8);
  12568 
  12569                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 
  12570                         SHARED_YELLOW_LIMITf, (buf_rqe_queue->yellow_limit + 7) / 8);
  12571             }
  12572 
  12573             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 
  12574                     (buf_rqe_queue->discard_enable ? 1 : 0));
  12575 
  12576             if (buf_rqe_queue->pool_scale != -1) {
  12577                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 
  12578                         &rval, DYNAMIC_ENABLEf, 1);
  12579                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 
  12580                         SHARED_ALPHAf, buf_rqe_queue->pool_scale);
  12581             } else {
  12582                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 
  12583                         SHARED_LIMITf, buf_rqe_queue->pool_limit);
  12584             }
  12585             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 2);
  12586 
  12587             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval));
  12588             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2));
  12589             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  12590 
  12591             rval = 0;
  12592             soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 
  12593                     &rval, RESET_OFFSET_REDf, (default_mtu_cells * 2)/8);
  12594             soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 
  12595                     &rval, RESET_OFFSET_YELLOWf, (default_mtu_cells * 2)/8);
  12596             SOC_IF_ERROR_RETURN(
  12597                     WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  12598 
  12599             /* queue entry */
  12600             buf_pool = &buf->pools[buf_rqe_queue->pool_idx];
  12601             fval = ((buf_pool->total_rqe_entry + 7) / 8);
  12602             rval = 0;
  12603             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 
  12604                     &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8);
  12605             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval));
  12606 
  12607             rval = 0;
  12608             rval2 = 0;
  12609             rval3 = 0;
  12610             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 
  12611                     &rval, SPIDf, buf_rqe_queue->pool_idx);
  12612 
  12613             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 
  12614                     &rval, COLOR_LIMIT_DYNAMICf, lossless ? 0 : 1);
  12615             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 
  12616                     &rval3, SHARED_RED_LIMITf, lossless ? fval : 0);
  12617             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 
  12618                     &rval3, SHARED_YELLOW_LIMITf, lossless ? fval : 0);
  12619             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, DYNAMIC_ENABLEf, 
  12620                     lossless ? 0 :1);
  12621             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 
  12622                     lossless ? 0 :1);
  12623             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 
  12624                     SHARED_LIMITf, lossless ? fval : 8);
  12625             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 1);
  12626             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval));
  12627             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2));
  12628             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  12629 
  12630             rval = 0;
  12631             soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 
  12632                     &rval, RESET_OFFSET_REDf, default_mtu_cells/8);
  12633             soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 
  12634                     &rval, RESET_OFFSET_YELLOWf, default_mtu_cells/8);
  12635             SOC_IF_ERROR_RETURN(
  12636                     WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  12637 
  12638         }
  12639 
  12640         /* per pool RQE settings */
  12641         rqe_rsvd = 0;
  12642         total_rsvd = 0;  
  12643         for (idx = 0; idx < 4; idx++) {
  12644             buf_pool = &buf->pools[idx];
  12645             if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) ||
  12646                     (buf_pool->total == 0)) {
  12647                 continue;
  12648             }
  12649 
  12650             if ((FALSE == si->flex_eligible) && soc_apache_is_any_port_flex_enable(unit)) {
  12651                 /* Legacy flex port (:i) is not enabled
  12652                 * Overwrite total_rsvd with flexport reservations made
  12653                 * Add cpu & lb port egr rsvd entries */
  12654                 if (devcfg->flags & SOC_MMU_CFG_F_RQE) {
  12655                     for (rqe = 0; rqe < 11; rqe++) {
  12656                         buf_rqe = &buf->rqe_queues[rqe];
  12657                         rqe_rsvd += buf_rqe->guarantee;
  12658                     }
  12659                 }
  12660                 if (lossless) {
  12661                     total_rsvd = egr_rsvd +  rqe_rsvd;
  12662                 } else {
  12663                     total_rsvd = egr_rsvd + 
  12664                         soc_ap_egr_buf_rsvd_port(unit, CMIC_PORT(unit), 8) +
  12665                         soc_ap_egr_buf_rsvd_port(unit, LB_PORT(unit), 8) +
  12666                         rqe_rsvd;
  12667                 }
  12668             } else { 
  12669               total_rsvd = buf_pool->queue_guarantee + q_reserved;  
  12670             } 
  12671             limit = buf_pool->total - total_rsvd - asf_rsvd;
  12672 
  12673 
  12674             rval = 0;
  12675             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, 
  12676                     &rval, SHARED_LIMITf, limit);
  12677             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf, 
  12678                     (limit - (default_mtu_cells * 2) + 7)/8);
  12679             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr_REG32(unit, idx, rval));
  12680 
  12681             rval = 0;
  12682             soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 
  12683                     SHARED_RED_LIMITf, (limit + 7)/8);
  12684             soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 
  12685                     SHARED_YELLOW_LIMITf, (limit + 7)/8);
  12686             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval));
  12687 
  12688             rval = 0;
  12689             soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 
  12690                     RESUME_RED_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8);
  12691             soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 
  12692                     RESUME_YELLOW_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8);
  12693             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 
  12694                         idx, rval));
  12695             if (lossless) {
  12696                 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) - 1 ;
  12697             } else {
  12698                 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) ;
  12699             }
  12700             if (rqlen == 0) {
  12701                 continue;
  12702             }
  12703 
  12704             rval = 0;
  12705             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, SHARED_LIMITf, rqlen);
  12706             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, RESUME_LIMITf, rqlen - 1);
  12707             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval));
  12708 
  12709             rval = 0;
  12710             soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 
  12711                     SHARED_RED_LIMITf, rqlen);
  12712             soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 
  12713                     SHARED_YELLOW_LIMITf, rqlen);
  12714             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, idx, rval));
  12715 
  12716             rval = 0;
  12717             soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 
  12718                     RESUME_RED_LIMITf, rqlen - 1);
  12719             soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 
  12720                     RESUME_YELLOW_LIMITf, rqlen - 1);
  12721             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 
  12722                         idx, rval));
  12723         }
  12724 
  12725         /* Device level config setting */
  12726         if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) {
  12727             SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  12728             soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval,
  12729                     UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1);
  12730             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  12731         }
  12732     }
  12733     return SOC_E_NONE;
  12734 }
  12735 
  12736 STATIC int
  12737 _soc_apache_mmu_config_shared_update_check(int unit, int val1, int val2, int flags)
  12738 {
  12739     int rv = 0;
  12740     if (flags == 1) {
  12741         if (val1 > val2) {
  12742             rv = 1;
  12743         }
  12744     } else {
  12745         if (val1 < val2) {
  12746             rv = 1;
  12747         }
  12748     }
  12749     return rv;
  12750 }
  12751 
  12752 int
  12753 soc_apache_mmu_config_shared_buf_recalc(int unit, uint32 spid, int shared_size, int flags)
  12754 {
  12755     soc_info_t *si;
  12756     soc_mem_t mem, mem2;
  12757     soc_reg_t reg = INVALIDr;
  12758     soc_field_t field = INVALIDf;
  12759     uint32 rval, rval2;
  12760     uint32 entry0[SOC_MAX_MEM_WORDS];
  12761     thdi_port_pg_config_entry_t pg_config_mem;
  12762     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  12763     int port, base, qbase, numq, idx;
  12764     int cur_limit, midx, index1;
  12765     int granularity;
  12766     uint16      dev_id;
  12767     uint8       rev_id;
  12768 
  12769     static const soc_field_t pg_spid_field[] = {
  12770         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  12771         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  12772     };
  12773 
  12774     if (spid >= _APACHE_MMU_NUM_POOL) {
  12775         return SOC_E_PARAM;
  12776     }
  12777     
  12778     soc_cm_get_id(unit, &dev_id, &rev_id);
  12779 
  12780     si = &SOC_INFO(unit);
  12781 
  12782     /* per service pool settings */
  12783     idx = spid;     
  12784     rval = 0;
  12785     reg = MMU_THDM_DB_POOL_SHARED_LIMITr;
  12786     field = SHARED_LIMITf;
  12787     granularity = 1;
  12788     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12789     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12790     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12791         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12792         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12793     }
  12794 
  12795     rval = 0;
  12796     reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr;
  12797     field = YELLOW_SHARED_LIMITf;
  12798     granularity = 8;
  12799     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12800     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12801     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12802         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12803         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12804     }
  12805 
  12806     rval = 0;
  12807     reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr;
  12808     field = RED_SHARED_LIMITf;
  12809     granularity = 8;
  12810     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12811     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12812     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12813         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12814         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12815     }
  12816 
  12817     /* configure Q-groups */
  12818     mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  12819     for (idx = 0; idx < SOC_APACHE_MMU_CFG_QGROUP_MAX; idx++) {
  12820         sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  12821 
  12822         SOC_IF_ERROR_RETURN
  12823                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  12824 
  12825         field = Q_SHARED_LIMIT_CELLf;
  12826         granularity = 1;
  12827         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) {
  12828             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12829             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12830                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12831                                     field, shared_size/granularity);
  12832             }
  12833         }
  12834         
  12835         granularity = 8;
  12836         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp,
  12837                                  Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  12838             field = LIMIT_RED_CELLf;
  12839             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12840             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12841                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12842                                     field, shared_size/granularity);
  12843             }
  12844 
  12845             field = LIMIT_YELLOW_CELLf;
  12846             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12847             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12848                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12849                                     field, shared_size/granularity);
  12850             }
  12851         }
  12852 
  12853         SOC_IF_ERROR_RETURN
  12854                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  12855 
  12856     }
  12857 
  12858     /* Input port per port settings */
  12859     PBMP_ALL_ITER(unit, port) {
  12860         rval = 0;
  12861         /* Input port per port per priority group settings */
  12862         mem = THDI_PORT_PG_CONFIG_Xm;
  12863         field = PG_SHARED_LIMITf;
  12864         granularity = 1;
  12865         for (idx = 0; idx < _APACHE_MMU_NUM_PG; idx++) {
  12866             SOC_IF_ERROR_RETURN(READ_THDI_PORT_PG_SPIDr(unit, port, &rval));
  12867             if (spid != soc_reg_field_get(unit, THDI_PORT_PG_SPIDr, rval, 
  12868                             pg_spid_field[idx])){
  12869                 continue;
  12870             }
  12871             midx = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12872             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  12873             SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  12874                                              MEM_BLOCK_ALL, midx, &pg_config_mem));
  12875             if (!soc_mem_field32_get(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf)) {
  12876                 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, field);
  12877                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12878                     soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12879                                         field, shared_size/granularity);
  12880                 }
  12881             }
  12882         
  12883             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 
  12884                                            MEM_BLOCK_ALL, midx, &pg_config_mem));
  12885         }
  12886     }
  12887 
  12888     /***********************************
  12889      * THDO 
  12890  */
  12891     /* Output port per port per queue setting for regular multicast queue */
  12892     PBMP_PORT_ITER(unit, port) {
  12893 
  12894         numq = si->port_num_cosq[port];
  12895         qbase = si->port_cosq_base[port];
  12896         if (numq == 0) {
  12897             continue;
  12898         }
  12899 
  12900         mem = MMU_THDM_DB_QUEUE_CONFIG_0m;
  12901         base = soc_apache_l2_hw_index(unit, qbase, 0) - _APACHE_MC_QUEUE_BASE;
  12902 
  12903         for (idx = 0; idx < numq; idx++) {
  12904             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  12905 
  12906             SOC_IF_ERROR_RETURN
  12907                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  12908 
  12909             if (spid != soc_mem_field32_get(unit, mem, entry0, Q_SPIDf)){
  12910                 continue;
  12911             }
  12912             field = Q_SHARED_LIMITf;
  12913             granularity = 1;
  12914             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) {
  12915                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12916                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12917                     soc_mem_field32_set(unit, mem, entry0, 
  12918                                         field, shared_size/granularity);
  12919                 }
  12920             }
  12921 
  12922             granularity = 8;
  12923             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) {
  12924                 field = YELLOW_SHARED_LIMITf;
  12925                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12926                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12927                     soc_mem_field32_set(unit, mem, entry0, 
  12928                                         field, shared_size/granularity);
  12929                 }
  12930                 field = RED_SHARED_LIMITf;
  12931                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12932                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12933                     soc_mem_field32_set(unit, mem, entry0, 
  12934                                         field, shared_size/granularity);
  12935                 }
  12936             }
  12937             SOC_IF_ERROR_RETURN
  12938                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  12939                                entry0));
  12940         }
  12941 
  12942         /* Per  port per pool */
  12943         idx = spid;    
  12944         mem = MMU_THDM_DB_PORTSP_CONFIG_0m;
  12945         index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12946         sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  12947 
  12948         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 
  12949                             index1, entry0));
  12950 
  12951         field = SHARED_LIMITf;
  12952         granularity = 1;
  12953         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12954         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12955             soc_mem_field32_set(unit, mem, entry0, 
  12956                                 field, shared_size/granularity);
  12957         }
  12958 
  12959         field = RED_SHARED_LIMITf;
  12960         granularity = 8;
  12961         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12962         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12963             soc_mem_field32_set(unit, mem, entry0, 
  12964                                 field, shared_size/granularity);
  12965         }
  12966 
  12967         field = YELLOW_SHARED_LIMITf;
  12968         granularity = 8;
  12969         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12970         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12971             soc_mem_field32_set(unit, mem, entry0, 
  12972                                 field, shared_size/granularity);
  12973         }
  12974         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 
  12975                             index1, entry0));
  12976     }
  12977 
  12978     /* Output port per port per queue setting for regular unicast queue */
  12979     PBMP_PORT_ITER(unit, port) {
  12980         /* per port regular unicast queue */
  12981         numq = si->port_num_uc_cosq[port];
  12982         qbase = si->port_uc_cosq_base[port];
  12983 
  12984         if (numq == 0) {
  12985             continue;
  12986         }
  12987         base = soc_apache_l2_hw_index(unit, qbase, 1);
  12988         mem = MMU_THDU_XPIPE_CONFIG_QUEUEm;
  12989         mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm;
  12990         for (idx = 0; idx < numq; idx++) {
  12991             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_q_to_qgrp_map_entry_t));
  12992             SOC_IF_ERROR_RETURN
  12993                 (soc_mem_read(unit, mem2, MEM_BLOCK_ALL, base+idx, entry0));
  12994             if (spid != soc_mem_field32_get(unit, mem2, entry0, Q_SPIDf)){
  12995                 continue;
  12996             }
  12997             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  12998 
  12999             SOC_IF_ERROR_RETURN
  13000                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  13001 
  13002             field = Q_SHARED_LIMIT_CELLf;
  13003             granularity = 1;
  13004             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) {
  13005                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13006                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13007                     soc_mem_field32_set(unit, mem, entry0, 
  13008                                         field, shared_size/granularity);
  13009                 }
  13010             }
  13011 
  13012             granularity = 8;
  13013             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  13014                 field = LIMIT_YELLOW_CELLf;
  13015                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13016                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13017                     soc_mem_field32_set(unit, mem, entry0, 
  13018                                         field, shared_size/granularity);
  13019                 }
  13020                 field = LIMIT_RED_CELLf;
  13021                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13022                 if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13023                     soc_mem_field32_set(unit, mem, entry0, 
  13024                                         field, shared_size/granularity);
  13025                 }
  13026             }
  13027             SOC_IF_ERROR_RETURN
  13028                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  13029         }
  13030         
  13031         /* Per  port per pool unicast */
  13032         idx = spid;
  13033         mem = MMU_THDU_XPIPE_CONFIG_PORTm;
  13034         index1 = SOC_APACHE_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  13035         sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  13036 
  13037         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 
  13038                             index1, entry0));
  13039 
  13040         field = SHARED_LIMITf;
  13041         granularity = 1;
  13042         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13043         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13044             soc_mem_field32_set(unit, mem, entry0, 
  13045                                 field, shared_size/granularity);
  13046         }
  13047 
  13048         granularity = 8;
  13049         field = YELLOW_LIMITf;
  13050         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13051         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13052             soc_mem_field32_set(unit, mem, entry0, 
  13053                                 field, shared_size/granularity);
  13054         }
  13055         field = RED_LIMITf;
  13056         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  13057         if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13058             soc_mem_field32_set(unit, mem, entry0, 
  13059                                 field, shared_size/granularity);
  13060         }
  13061         
  13062         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 
  13063                             index1, entry0));
  13064     }
  13065 
  13066     /* RQE */
  13067     for (idx = 0; idx < 11; idx++) {
  13068         rval = 0;
  13069         rval2 = 0;
  13070 
  13071         SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval));
  13072         if (spid != soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, SPIDf)){
  13073             continue;
  13074         }
  13075 
  13076         reg = MMU_THDR_DB_CONFIG_PRIQr;
  13077         field = SHARED_LIMITf;
  13078         granularity = 1;
  13079         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  13080         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  13081                                DYNAMIC_ENABLEf)) {
  13082             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  13083             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13084                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  13085                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  13086             }
  13087         }
  13088 
  13089         rval2 = 0;
  13090         reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr;
  13091         granularity = 8;
  13092         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  13093 
  13094         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  13095                                COLOR_LIMIT_DYNAMICf)) {
  13096             field = SHARED_RED_LIMITf;
  13097             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  13098             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13099                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  13100             }
  13101 
  13102             field = SHARED_YELLOW_LIMITf;
  13103             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  13104             if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13105                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  13106             }
  13107             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  13108         }
  13109 
  13110     }
  13111 
  13112     /* per pool RQE settings */
  13113     idx = spid;    
  13114     reg = MMU_THDR_DB_CONFIG_SPr;
  13115     field = SHARED_LIMITf;
  13116     granularity = 1;
  13117 
  13118     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  13119 
  13120     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  13121 
  13122     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  13123         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  13124         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  13125     }
  13126 
  13127     reg = MMU_THDR_DB_SP_SHARED_LIMITr;
  13128     granularity = 8;
  13129 
  13130     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  13131 
  13132     field =SHARED_YELLOW_LIMITf;
  13133     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  13134 
  13135     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){
  13136         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  13137     }
  13138 
  13139     field = SHARED_RED_LIMITf;
  13140     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  13141 
  13142     if (_soc_apache_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){
  13143         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  13144     }
  13145     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  13146     return SOC_E_NONE;
  13147 }
  13148 
  13149 int
  13150 soc_apache_mmu_config_init(int unit, int test_only, soc_port_t port)
  13151 {
  13152     int rv;
  13153     int lossless;
  13154     _soc_mmu_cfg_buf_t *buf;
  13155     _soc_mmu_device_info_t devcfg;
  13156 
  13157     buf = soc_mmu_cfg_alloc(unit);
  13158     if (!buf) {
  13159         return SOC_E_MEMORY;
  13160     }
  13161 
  13162     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  13163 
  13164     _soc_apache_mmu_init_dev_config(unit, &devcfg, lossless);
  13165     _soc_apache_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  13166     if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
  13167         _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
  13168     }
  13169     rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg);
  13170     if (!test_only) {
  13171         if (SOC_FAILURE(rv)) {
  13172             LOG_VERBOSE(BSL_LS_SOC_COMMON,
  13173                         (BSL_META_U(unit,
  13174                                     "MMU config: Use default setting\n")));
  13175             _soc_apache_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  13176             _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg);
  13177         }
  13178         rv = _soc_apache_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, port);
  13179     }
  13180 
  13181     soc_mmu_cfg_free(unit, buf);
  13182 
  13183     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  13184                 (BSL_META_U(unit,
  13185                             "MMU THDI/THDO init done\n")));
  13186     return rv;
  13187 }
  13188 
  13189 /*Clear MMU_CBPDATA for APACHE mmu_init*/
  13190 STATIC int
  13191 _soc_apache_mmu_cbpdata_clear(int unit)
  13192 {
  13193     soc_mem_t mem;
  13194     soc_mem_t cbpdata_start_m;
  13195     soc_mem_t cbpdata_end_m;
  13196 
  13197     cbpdata_start_m = MMU_CBPDATA0m;
  13198     cbpdata_end_m = MMU_CBPDATA3m;
  13199 
  13200     for (mem = cbpdata_start_m; mem <= cbpdata_end_m; mem++) {
  13201         SOC_IF_ERROR_RETURN(
  13202                 soc_mem_clear(unit, mem, MEM_BLOCK_ALL, TRUE));
  13203     }
  13204     return SOC_E_NONE;
  13205 }
  13206 
  13207 
  13208 STATIC int
  13209 _soc_apache_mmu_init(int unit)
  13210 {
  13211     uint32 rval;
  13212     uint64 rval64;
  13213     soc_info_t *si;
  13214     int total_entries, clock_period, refresh_time_val;
  13215     int cpu_slots;
  13216     int msbus_idle_enable;
  13217     int alloc_size;
  13218     int port = 0;
  13219     if (soc_feature(unit, soc_feature_untethered_otp)) {
  13220         if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu12Mb)) {
  13221             _soc_ap_skew_index = 0;
  13222         } else if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureMmu9Mb)) {
  13223             _soc_ap_skew_index = 1;
  13224         } else {
  13225             /*socBondInfoFeatureMmu6Mb*/
  13226             _soc_ap_skew_index = 2;
  13227         }
  13228     } else {
  13229         /*socBondInfoFeatureMmu12Mb*/
  13230         _soc_ap_skew_index = 0;
  13231     }
  13232 
  13233     /* MMU Settings Configuration */
  13234     SOC_IF_ERROR_RETURN(soc_apache_mmu_config_init(unit, SAL_BOOT_BCMSIM, -1));
  13235 
  13236     rval = 0;
  13237     soc_reg_field_set(unit, LLS_CONFIG0r, &rval, FC_ENABLEf, 1);
  13238     soc_reg_field_set(unit, LLS_CONFIG0r, &rval, ENQUEUE_ENABLEf, 1);
  13239     soc_reg_field_set(unit, LLS_CONFIG0r, &rval, DEQUEUE_ENABLEf, 1);
  13240     soc_reg_field_set(unit, LLS_CONFIG0r, &rval, PORT_SCHEDULER_ENABLEf, 1);
  13241     SOC_IF_ERROR_RETURN(WRITE_LLS_CONFIG0r(unit, rval));
  13242 
  13243     rval = 0;
  13244     soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_SC_FOR_MH_PRIf, 1);
  13245     soc_reg_field_set(unit, PRIORITY_CONTROLr, &rval, USE_QM_FOR_MH_PRIf, 1);
  13246     SOC_IF_ERROR_RETURN(WRITE_PRIORITY_CONTROLr(unit, rval));
  13247 
  13248     /* Enable IP to CMICM credit transfer */
  13249     rval = 0;
  13250     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  13251                       TRANSFER_ENABLEf, 1);
  13252     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  13253                       NUM_OF_CREDITSf, 32);
  13254     SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, rval));
  13255 
  13256     if (_fwd_ctrl_lock[unit] == NULL) {
  13257         _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock");
  13258     }
  13259     
  13260     if (_fwd_ctrl_lock[unit] == NULL) {
  13261         return SOC_E_MEMORY;
  13262     }
  13263 
  13264     /*mmu traffic control*/
  13265     alloc_size = sizeof(_soc_apache_mmu_traffic_ctrl_t);
  13266     if (_soc_apache_mmu_traffic_ctrl[unit] == NULL) {
  13267         _soc_apache_mmu_traffic_ctrl[unit] = 
  13268             sal_alloc(alloc_size,"_soc_apache_mmu_traffic_ctrl");
  13269         if (_soc_apache_mmu_traffic_ctrl[unit] == NULL) {
  13270             return SOC_E_MEMORY;
  13271         }
  13272     }
  13273     sal_memset(_soc_apache_mmu_traffic_ctrl[unit], 0, alloc_size);
  13274 
  13275 
  13276     /* Enable all ports */
  13277     COMPILER_64_ZERO(rval64);
  13278     if (!soc_ap_is_skip_default_lls_creation(unit)) {
  13279         COMPILER_64_SET(rval64, 0xffffffff, 0xffffffff);
  13280         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE0_64r(unit, rval64));
  13281         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE0_64r(unit, rval64));
  13282         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r(unit, rval64));
  13283         COMPILER_64_SET(rval64, 0x0, 0x3ff);
  13284         SOC_IF_ERROR_RETURN(WRITE_THDU_OUTPUT_PORT_RX_ENABLE1_64r(unit, rval64));
  13285         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_PORTSP_RX_ENABLE1_64r(unit, rval64));
  13286         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r(unit, rval64));
  13287     } else { 
  13288         PBMP_ALL_ITER(unit, port)
  13289         { 
  13290           if (IS_CPU_PORT(unit, port) ||   
  13291               IS_AP_HSP_PORT(unit,port) || 
  13292               IS_LB_PORT(unit, port))
  13293           { _soc_apache_thdo_hw_set(unit, port, 1);  
  13294         
  13295           }
  13296         }
  13297     }
  13298     si = &SOC_INFO(unit);
  13299 
  13300     /*
  13301      * Refresh Value = 
  13302      *  ((total no of entities to be refreshed) X Core clk period in ns)/Wred tick period 50 ns
  13303      */
  13304 
  13305     total_entries = 4096 + 1024;
  13306     cpu_slots = (total_entries * 2) / 16; /* 2 slots for every 16 entries refreshed */
  13307     clock_period = (1 * 1000 * 1000) / si->frequency; /*clock period in microseconds */
  13308 
  13309     SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval));    
  13310     msbus_idle_enable = soc_reg_field_get(unit, WRED_REFRESH_CONTROLr,
  13311             rval, MSBUS_IDLE_ENABLEf);
  13312 
  13313     if (msbus_idle_enable) {
  13314         refresh_time_val = ((total_entries + cpu_slots) * clock_period) / 50;
  13315     } else {
  13316         refresh_time_val = (total_entries * clock_period) / 50;
  13317     }
  13318     refresh_time_val = refresh_time_val / 1000;  /* micro to nano seconds */
  13319 
  13320     soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
  13321             REFRESH_TIME_VALf, refresh_time_val);
  13322     soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
  13323             REFRESH_DISABLEf, 0);
  13324     SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval));
  13325 
  13326     /* Clear MMU_CBPData */
  13327     SOC_IF_ERROR_RETURN(_soc_apache_mmu_cbpdata_clear(unit));
  13328 
  13329     SOC_IF_ERROR_RETURN(soc_apache_lls_init(unit));
  13330 
  13331    SOC_IF_ERROR_RETURN
  13332         (soc_reg_field32_modify(unit, OOBFC_CHANNEL_BASE_64r, REG_PORT_ANY,
  13333                                 ENG_ENf, 1));
  13334 
  13335     if (soc_feature(unit, soc_feature_post)) {
  13336         SOC_IF_ERROR_RETURN(soc_mmu_post_init(unit));
  13337     }
  13338 
  13339     PBMP_ALL_ITER(unit, port) {
  13340         if (IS_CPU_PORT(unit, port) ||   
  13341             IS_LB_PORT(unit, port) ||
  13342             IS_RDB_PORT(unit, port)) 
  13343         {
  13344               continue;
  13345         }
  13346         COMPILER_64_ZERO(rval64);
  13347         soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1);
  13348         SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64));
  13349         rval = 0;   
  13350         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13351                                                   COS0_E2E_DS_ENf , 1);
  13352         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13353                                                   COS1_E2E_DS_ENf , 1);
  13354         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13355                                                   COS2_E2E_DS_ENf , 1);
  13356         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13357                                                   COS3_E2E_DS_ENf , 1);
  13358         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13359                                                   COS4_E2E_DS_ENf , 1);
  13360         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13361                                                   COS5_E2E_DS_ENf , 1);
  13362         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13363                                                   COS6_E2E_DS_ENf , 1);
  13364         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  13365                                                   COS7_E2E_DS_ENf , 1);
  13366         WRITE_THDU_PORT_E2ECC_COS_SPIDr(unit , port , rval);
  13367     }
  13368 
  13369     return SOC_E_NONE;
  13370 }
  13371 
  13372 
  13373 STATIC int
  13374 _soc_apache_age_timer_get(int unit, int *age_seconds, int *enabled)
  13375 {
  13376     soc_control_t *soc = SOC_CONTROL(unit);
  13377     uint32 rval;
  13378 
  13379     if (!soc->l2x_sw_aging) {
  13380         SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval));
  13381         *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf);
  13382         *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf);
  13383     } else {
  13384         *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  13385                    soc->l2x_age_enable ?
  13386                    1 : 0;
  13387         *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  13388                        soc->l2x_age_enable ?
  13389                        soc->l2x_age_interval : 0;
  13390     }
  13391 
  13392     return SOC_E_NONE;
  13393 }
  13394 
  13395 STATIC int
  13396 _soc_apache_age_timer_max_get(int unit, int *max_seconds)
  13397 {
  13398     soc_control_t *soc = SOC_CONTROL(unit);
  13399 
  13400     if (!soc->l2x_sw_aging) {
  13401         *max_seconds =
  13402             soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
  13403     } else {
  13404         *max_seconds = 0x7fffffff;
  13405     }
  13406 
  13407     return SOC_E_NONE;
  13408 }
  13409 
  13410 STATIC int
  13411 _soc_apache_age_timer_set(int unit, int age_seconds, int enable)
  13412 {
  13413     soc_control_t *soc = SOC_CONTROL(unit);
  13414     sal_usecs_t interval = soc->l2x_age_interval;
  13415     uint32 rval = 0;
  13416 
  13417     if (!soc->l2x_sw_aging) {
  13418         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable);
  13419         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds);
  13420         SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval));
  13421     } else if (soc->l2x_age_interval) {
  13422         if (!enable) {
  13423             soc->l2x_age_enable = 0;
  13424         } else {
  13425             if (age_seconds) {
  13426                 SOC_CONTROL_LOCK(unit);
  13427                 soc->l2x_age_interval = age_seconds;
  13428                 SOC_CONTROL_UNLOCK(unit);
  13429             }
  13430             soc->l2x_age_enable = 1;
  13431             if (interval != age_seconds) {
  13432                 sal_sem_give(soc->l2x_age_notify);
  13433             }
  13434         }
  13435     } else {
  13436         if (enable) {
  13437             SOC_IF_ERROR_RETURN
  13438                 (soc_td2_l2_bulk_age_start(unit, age_seconds));
  13439         }
  13440     }
  13441 
  13442     return SOC_E_NONE;
  13443 }
  13444 
  13445 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \
  13446         ((_phy_reg) |= ((_phyad) & 0x1f) << 19)
  13447 
  13448 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \
  13449         ((_phy_reg) |= ((_phyad) & 0x1f) << 19)
  13450 
  13451 STATIC int
  13452 _soc_apache_mdio_addr_to_port(uint32 phy_addr)
  13453 {
  13454     int bus, offset = 0;
  13455 
  13456     /* Must be internal MDIO address */
  13457     if ((phy_addr & 0x80) == 0) {
  13458         return 0;
  13459     }
  13460 
  13461     /*
  13462      * Internal phy address:
  13463      * bus 0 phy 1 to 28 are mapped to Physical port 1 to 28
  13464      * bus 1 phy 1 to 20 are mapped to Physical port 29 to 48
  13465      * bus 2 phy 1 to 24 are mapped to Physical port 49 to 72
  13466      */
  13467     bus = PHY_ID_BUS_NUM(phy_addr);
  13468     if (bus > 2) {
  13469         return 0;
  13470     }
  13471 
  13472     switch (bus) {
  13473     case 0: offset = 0; break;
  13474     case 1: offset = 28; break;
  13475     case 2: offset = 48; break;
  13476     }
  13477 
  13478 
  13479     return (phy_addr & 0x1f) + offset;
  13480 }
  13481 
  13482 STATIC int
  13483 _soc_apache_mdio_reg_read(int unit, uint32 phy_addr,
  13484                             uint32 phy_reg, uint32 *phy_data)
  13485 {
  13486     int port, phy_port, blk;
  13487     soc_mem_t ucmem_data;
  13488     soc_reg_t ucmem_ctrl;
  13489 
  13490     /* Physical port based on MDIO address */
  13491     phy_port = _soc_apache_mdio_addr_to_port(phy_addr);
  13492     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
  13493     blk = SOC_PORT_BLOCK(unit, phy_port);
  13494 
  13495     if ((phy_port >= 17 && phy_port <= 28) ||
  13496         (phy_port >= 53 && phy_port <= 64)) {
  13497         ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13498         ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13499         SOC_IF_ERROR_RETURN(soc_apache_port_reg_blk_index_get(unit, port, SOC_BLK_CXXPORT, &blk));
  13500 
  13501     } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) {
  13502         ucmem_data = CLPORT_WC_UCMEM_DATAm;
  13503         ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  13504 
  13505     } else {
  13506         ucmem_data = XLPORT_WC_UCMEM_DATAm;
  13507         ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr;
  13508 
  13509     }
  13510 
  13511     if (phy_port >= 17 && phy_port <= 28) {
  13512         if (phy_port >= 17 && phy_port <= 20) {
  13513             ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13514             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13515         } else if (phy_port >= 21 && phy_port <= 24) {
  13516             ucmem_data = CXXPORT_WC_UCMEM_DATA1m;
  13517             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r;
  13518         } else {
  13519             ucmem_data = CXXPORT_WC_UCMEM_DATA2m;
  13520             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r;
  13521         }
  13522     } else if (phy_port >= 53 && phy_port <= 64) {
  13523         if (phy_port >= 53 && phy_port <= 56) {
  13524             ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13525             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13526         } else if (phy_port >= 57 && phy_port <= 60) {
  13527             ucmem_data = CXXPORT_WC_UCMEM_DATA1m;
  13528             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r;
  13529         } else {
  13530             ucmem_data = CXXPORT_WC_UCMEM_DATA2m;
  13531             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r;
  13532         }
  13533     }
  13534 
  13535     LOG_INFO(BSL_LS_SOC_MII,
  13536              (BSL_META_U(unit,
  13537                          "soc_apache_mdio_reg_read[%d]: %d/%d/%d\n"),
  13538               unit, phy_addr, phy_port, port));
  13539 
  13540     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
  13541 
  13542     /* Call common S-bus MDIO read function */
  13543     return soc_sbus_mdio_reg_read(unit, port, blk, 0,
  13544                                   phy_addr, phy_reg, phy_data,
  13545                                   ucmem_data, ucmem_ctrl);
  13546 
  13547 }
  13548 
  13549 STATIC int
  13550 _soc_apache_mdio_reg_write(int unit, uint32 phy_addr,
  13551                              uint32 phy_reg, uint32 phy_data)
  13552 {
  13553     int port, phy_port, blk;
  13554     soc_mem_t ucmem_data;
  13555     soc_reg_t ucmem_ctrl;
  13556 
  13557     /* Physical port based on MDIO address */
  13558     phy_port = _soc_apache_mdio_addr_to_port(phy_addr);
  13559     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
  13560     blk = SOC_PORT_BLOCK(unit, phy_port);
  13561 
  13562 
  13563     if ((phy_port >= 17 && phy_port <= 28) ||
  13564         (phy_port >= 53 && phy_port <= 64)) {
  13565         ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13566         ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13567         SOC_IF_ERROR_RETURN(soc_apache_port_reg_blk_index_get(unit, port, SOC_BLK_CXXPORT, &blk));
  13568 
  13569     } else if (IS_CL_PORT(unit, port) || IS_CLG2_PORT(unit, port)) {
  13570         ucmem_data = CLPORT_WC_UCMEM_DATAm;
  13571         ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  13572 
  13573     } else {
  13574         ucmem_data = XLPORT_WC_UCMEM_DATAm;
  13575         ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr;
  13576 
  13577     }
  13578 
  13579     if (phy_port >= 17 && phy_port <= 28) {
  13580         if (phy_port >= 17 && phy_port <= 20) {
  13581             ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13582             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13583         } else if (phy_port >= 21 && phy_port <= 24) {
  13584             ucmem_data = CXXPORT_WC_UCMEM_DATA1m;
  13585             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r;
  13586         } else {
  13587             ucmem_data = CXXPORT_WC_UCMEM_DATA2m;
  13588             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r;
  13589         }
  13590     } else if (phy_port >= 53 && phy_port <= 64) {
  13591         if (phy_port >= 53 && phy_port <= 56) {
  13592             ucmem_data = CXXPORT_WC_UCMEM_DATA0m;
  13593             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL0r;
  13594         } else if (phy_port >= 57 && phy_port <= 60) {
  13595             ucmem_data = CXXPORT_WC_UCMEM_DATA1m;
  13596             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL1r;
  13597         } else {
  13598             ucmem_data = CXXPORT_WC_UCMEM_DATA2m;
  13599             ucmem_ctrl = CXXPORT_WC_UCMEM_CTRL2r;
  13600         }
  13601     }
  13602 
  13603     LOG_INFO(BSL_LS_SOC_MII,
  13604              (BSL_META_U(unit,
  13605                          "soc_apache_mdio_reg_read[%d]: %d/%d/%d\n"),
  13606               unit, phy_addr, phy_port, port));
  13607 
  13608     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
  13609 
  13610 
  13611     /* Call common S-bus MDIO read function */
  13612     return soc_sbus_mdio_reg_write(unit, port, blk, 0,
  13613                                    phy_addr, phy_reg, phy_data,
  13614                                    ucmem_data, ucmem_ctrl);
  13615 }
  13616 
  13617 static const soc_reg_t pvtmon_result_reg[] = {
  13618     TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r,
  13619     TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r,
  13620     TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r,
  13621     TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r
  13622 };
  13623 
  13624 
  13625 STATIC void
  13626 soc_apache_temperature_intr(int unit)
  13627 {
  13628     uint32 rval, trval;
  13629     int i, rv;
  13630     soc_port_t port;
  13631     soc_block_t blk;
  13632     soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID};
  13633     soc_block_t clport_blocks[] = {SOC_BLK_CLPORT, SOC_BLK_CLG2PORT, SOC_BLOCK_TYPE_INVALID};
  13634 
  13635     /* Raise event to app for it to take further graceful actions */
  13636     for (i = 0; i < COUNTOF(pvtmon_result_reg); i++) {
  13637         if ((0x1 << i)  & _soc_ap_temp_mon_mask[unit]) {
  13638             if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0,
  13639                                     &trval)) != SOC_E_NONE) {
  13640                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13641                           (BSL_META_U(unit,
  13642                                       "AP Top Intr, Reg access error.\n")));
  13643             }
  13644             trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval,
  13645                                       PVT_DATAf);
  13646             /* Convert data to temperature.
  13647              * temp = 410.04-(data*0.48705) = (410040-(data*487))/1000
  13648              * Note: Since this is a high temp interrupt we can safely assume
  13649              * that this will end up being a +ive value.
  13650              */
  13651             trval = (410040-(trval*487))/1000;
  13652             LOG_ERROR(BSL_LS_SOC_COMMON,
  13653                       (BSL_META_U(unit,
  13654                                   "TempMon %d: %d deg C.\n"), i, trval));
  13655             (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM,
  13656                                      SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval);
  13657         }
  13658     }
  13659 
  13660     /* Optionally hold system in reset.
  13661      * Note: The main intention is to stop the chip from getting fried and halt
  13662      *       all schan accesses as the h/w will not respond anymore.
  13663      *       We are not implementing a gracefull recovery, the unit needs to be
  13664      *       rebooted after this.
  13665      */
  13666     if (soc_property_get(unit, "temp_monitor_shutdown", 1)) {
  13667         if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) {
  13668             LOG_ERROR(BSL_LS_SOC_COMMON,
  13669                       (BSL_META_U(unit,
  13670                                   "AP Temp Intr, Reg access error.\n")));
  13671         }
  13672 
  13673         /* Stop all schan transactions on this unit */
  13674 #ifdef  INCLUDE_I2C
  13675         if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) {
  13676             LOG_ERROR(BSL_LS_SOC_COMMON,
  13677                       (BSL_META_U(unit,
  13678                                   "AP Temp Intr, i2c detach error.\n")));
  13679         }
  13680 #endif
  13681         if (!SOC_IS_RCPU_ONLY(unit)) {
  13682             /* Free up DMA memory */
  13683             if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) {
  13684                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13685                           (BSL_META_U(unit,
  13686                                       "AP Temp Intr, dma detach error.\n")));
  13687             }
  13688         }
  13689 #ifdef INCLUDE_MEM_SCAN        
  13690         if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) {
  13691             LOG_ERROR(BSL_LS_SOC_COMMON,
  13692                       (BSL_META_U(unit,
  13693                                   "AP Temp Intr, mem scan stop error.\n")));
  13694         }
  13695 #endif /* INCLUDE_MEM_SCAN */      
  13696         /* Terminate counter module */
  13697         if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) {
  13698             LOG_ERROR(BSL_LS_SOC_COMMON,
  13699                       (BSL_META_U(unit,
  13700                                   "AP Temp Intr, counter stop error.\n")));
  13701         }
  13702         if (SOC_SBUSDMA_DM_INFO(unit)) {
  13703             if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) {
  13704                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13705                           (BSL_META_U(unit,
  13706                                       "AP Temp Intr, sbusdma stop error.\n")));
  13707             }
  13708         }
  13709         if (soc_feature(unit, soc_feature_arl_hashed)) {
  13710             /* Stop L2X thread */
  13711             if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) {
  13712                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13713                           (BSL_META_U(unit,
  13714                                       "AP Temp Intr, L2x stop error.\n")));
  13715             }
  13716 
  13717         }
  13718 
  13719         rv = READ_TOP_SOFT_RESET_REGr(unit, &rval);
  13720         if (SOC_E_NONE != rv) {
  13721             LOG_ERROR(BSL_LS_SOC_COMMON,
  13722                       (BSL_META_U(unit,
  13723                                   "AP Temp Intr, Reg access error.\n")));
  13724         }
  13725         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 0);
  13726         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0);
  13727         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 0);
  13728         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 0);
  13729         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 0);
  13730         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 0);
  13731         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 0);
  13732         rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
  13733         if (SOC_E_NONE != rv) {
  13734             LOG_ERROR(BSL_LS_SOC_COMMON,
  13735                       (BSL_META_U(unit,
  13736                                   "AP Temp Intr, Reg access error.\n")));
  13737         }
  13738 
  13739         if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) {
  13740             LOG_ERROR(BSL_LS_SOC_COMMON,
  13741                       (BSL_META_U(unit,
  13742                                   "AP Temp Intr, Reg access error.\n")));
  13743         }
  13744         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf,
  13745                           0);
  13746         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf,
  13747                           0);
  13748         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf,
  13749                           0);
  13750         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf,
  13751                           0);
  13752         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
  13753                           1);
  13754         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf,
  13755                           0);
  13756         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf,
  13757                           0);
  13758         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1);
  13759         if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) {
  13760             LOG_ERROR(BSL_LS_SOC_COMMON,
  13761                       (BSL_META_U(unit,
  13762                                   "AP Temp Intr, Reg access error.\n")));
  13763         }
  13764         /* Powerdown Falcon analog cores */
  13765         SOC_BLOCKS_ITER(unit, blk, clport_blocks) {
  13766             port = SOC_BLOCK_PORT(unit, blk);
  13767             rv = READ_CLPORT_XGXS0_CTRL_REGr(unit, port, &rval);
  13768             if (SOC_E_NONE != rv) {
  13769                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13770                           (BSL_META_U(unit,
  13771                                       "AP Temp Intr, Reg access error.\n")));
  13772             }
  13773             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1);
  13774             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1);
  13775             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0);
  13776             rv = WRITE_CLPORT_XGXS0_CTRL_REGr(unit, port, rval);
  13777             if (SOC_E_NONE != rv) {
  13778                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13779                           (BSL_META_U(unit,
  13780                                       "AP Temp Intr, Reg access error.\n")));
  13781             }
  13782         }
  13783         /* Powerdown Eagle analog cores */
  13784         SOC_BLOCKS_ITER(unit, blk, xlport_blocks) {
  13785             port = SOC_BLOCK_PORT(unit, blk);
  13786             rv = READ_XLPORT_XGXS0_CTRL_REGr(unit, port, &rval);
  13787             if (SOC_E_NONE != rv) {
  13788                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13789                           (BSL_META_U(unit,
  13790                                       "AP Temp Intr, Reg access error.\n")));
  13791             }
  13792             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1);
  13793             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1);
  13794             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0);
  13795             rv = WRITE_XLPORT_XGXS0_CTRL_REGr(unit, port, rval);
  13796             if (SOC_E_NONE != rv) {
  13797                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13798                           (BSL_META_U(unit,
  13799                                       "AP Temp Intr, Reg access error.\n")));
  13800             }
  13801         }
  13802 
  13803         /* Disable all interrupts */
  13804         soc_cmicm_intr0_disable(unit, ~0);
  13805         soc_cmicm_intr1_disable(unit, ~0);
  13806         soc_cmicm_intr2_disable(unit, ~0);
  13807         soc_cmicm_intr3_disable(unit, ~0);
  13808         soc_cmicm_intr4_disable(unit, ~0);
  13809         soc_cmicm_intr5_disable(unit, ~0);
  13810 
  13811         /* Power down core PLL, once this is done all SCHAN accesses
  13812          * will fail.
  13813          */
  13814         rv = READ_TOP_CORE_PLL_CTRL_1r(unit, &rval);
  13815         if (SOC_E_NONE != rv) {
  13816             LOG_ERROR(BSL_LS_SOC_COMMON,
  13817                       (BSL_META_U(unit,
  13818                                   "AP Temp Intr, Reg access error.\n")));
  13819         }
  13820         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, ISO_INf, 1);
  13821         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRONf, 0);
  13822         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRON_LDOf, 0);
  13823         WRITE_TOP_CORE_PLL_CTRL_1r(unit, rval);
  13824         SCHAN_LOCK(unit);
  13825 
  13826         /* Clear all outstanding DPCs owned by this unit */
  13827         sal_dpc_cancel(INT_TO_PTR(unit));
  13828         LOG_ERROR(BSL_LS_SOC_COMMON,
  13829                   (BSL_META_U(unit,
  13830                               "\nReboot the system..")));
  13831     }
  13832 }
  13833 
  13834 
  13835 void
  13836 soc_apache_top_intr(void *unit_vp, void *d1, void *d2,
  13837                                    void *d3, void *d4)
  13838 {
  13839     uint32 rval, pvtrval;
  13840     int rv, unit = PTR_TO_INT(unit_vp);
  13841 
  13842     if ((rv = READ_TOP_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) {
  13843         LOG_ERROR(BSL_LS_SOC_COMMON,
  13844                   (BSL_META_U(unit,
  13845                               "AP TOP Intr, Reg access error.\n")));
  13846     }
  13847 
  13848     /* Bits 0-17 for PVTMON and rest for AVS */
  13849     pvtrval = rval & ((1 << 18) - 1);
  13850     if (pvtrval) {
  13851         LOG_ERROR(BSL_LS_SOC_COMMON,
  13852                   (BSL_META_U(unit,
  13853                               "High temp interrupt: 0x%08x\n"), rval));
  13854 
  13855         soc_apache_temperature_intr(unit);
  13856         return;
  13857     }
  13858 
  13859     
  13860 
  13861     return;
  13862 }
  13863 
  13864 int
  13865 soc_apache_temperature_monitor_get(int unit, 
  13866             int temperature_max,
  13867             soc_switch_temperature_monitor_t *temperature_array,
  13868             int *temperature_count)
  13869 {
  13870     soc_reg_t reg;
  13871     int index;
  13872     uint32 rval;
  13873     int fval, cur, peak;
  13874     int num_entries_out;
  13875 
  13876     if (temperature_count) {
  13877         *temperature_count = 0;
  13878     }
  13879     if (COUNTOF(pvtmon_result_reg) > temperature_max) {
  13880         num_entries_out = temperature_max;
  13881     } else {
  13882         num_entries_out = COUNTOF(pvtmon_result_reg);
  13883     }
  13884     SOC_IF_ERROR_RETURN
  13885         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY, PVTMON_SELECTf, 0));
  13886 
  13887     SOC_IF_ERROR_RETURN
  13888         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13889             PVTMON_ADC_RESETBf, 1));
  13890     SOC_IF_ERROR_RETURN
  13891         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13892             PVTMON_ADC_RESETBf, 0));
  13893     SOC_IF_ERROR_RETURN
  13894         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13895             PVTMON_ADC_RESETBf, 1));
  13896 
  13897 
  13898     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  13899     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13900                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13901     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13902                       TOP_PVT_MON_MIN_RST_Lf, 1);
  13903     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13904 
  13905     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13906                       TOP_PVT_MON_MAX_RST_Lf, 0);
  13907     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13908                       TOP_PVT_MON_MIN_RST_Lf, 0);
  13909     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13910 
  13911     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13912                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13913     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13914                       TOP_PVT_MON_MIN_RST_Lf, 1);
  13915     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13916     sal_usleep(1000);
  13917 
  13918     for (index = 0; index < num_entries_out; index++) {
  13919         reg = pvtmon_result_reg[index];
  13920         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13921 
  13922         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13923         cur = (4100400 - (4870 * fval)) / 1000;
  13924         fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf);
  13925         peak = (4100400 - (4870 * fval)) / 1000;
  13926         (temperature_array + index)->curr = cur;
  13927         (temperature_array + index)->peak = peak;
  13928     }
  13929     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  13930     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13931                       TOP_PVT_MON_MAX_RST_Lf, 0);
  13932     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13933     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13934                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13935     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13936 
  13937     if (temperature_count) {
  13938         *temperature_count=num_entries_out;
  13939     }
  13940 
  13941     return SOC_E_NONE;
  13942 }
  13943 
  13944 int
  13945 soc_apache_show_material_process(int unit)
  13946 {
  13947     soc_reg_t reg;
  13948     int index;
  13949     uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg;
  13950 
  13951     READ_TOP_PVTMON_CTRL_1r(unit, &rval);
  13952     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 0);
  13953     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  13954     sal_usleep(1000);
  13955     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 1);
  13956     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  13957     sal_usleep(1000);
  13958 
  13959     SOC_IF_ERROR_RETURN
  13960         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13961                                 PVTMON_SELECTf, 1));
  13962     sal_usleep(1000);
  13963 
  13964     p_avg = 0;
  13965 
  13966     /* Read NMOS information */
  13967     SOC_IF_ERROR_RETURN
  13968         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  13969                                 MEASUREMENT_CALLIBRATIONf, 5));
  13970 
  13971     sal_usleep(1000);
  13972 
  13973     n_avg = 0;
  13974     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  13975         reg = pvtmon_result_reg[index];
  13976         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13977         nmos[index] = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13978         n_avg += nmos[index];
  13979     }
  13980 
  13981     /* Read PMOS information and print both NMOS and PMOS value */
  13982     SOC_IF_ERROR_RETURN
  13983         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  13984                                 MEASUREMENT_CALLIBRATIONf, 7));
  13985 
  13986     sal_usleep(1000);
  13987 
  13988     p_avg = 0;
  13989     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  13990         reg = pvtmon_result_reg[index];
  13991         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13992         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13993         p_avg += fval;
  13994 
  13995         LOG_CLI((BSL_META_U(unit,
  13996                    "Material process location %d: NMOS = %3d PMOS = %3d\n"),
  13997                    index, nmos[index], fval));
  13998     }
  13999 
  14000     LOG_CLI((BSL_META_U(unit,
  14001                "Average:                     NMOS = %3d PMOS = %3d\n"),
  14002                n_avg / COUNTOF(pvtmon_result_reg),
  14003                p_avg / COUNTOF(pvtmon_result_reg)));
  14004 
  14005     return SOC_E_NONE;
  14006 }
  14007 
  14008 int
  14009 soc_apache_show_ring_osc(int unit)
  14010 {
  14011     static const struct {
  14012         int osc_sel;
  14013         soc_field_t field0;
  14014         int value0;
  14015         soc_field_t field1;
  14016         int value1;
  14017         char *name;
  14018     } osc_tbl[] = {
  14019         { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" },
  14020         { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" },
  14021         { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" },
  14022         { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" },
  14023         { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" },
  14024         { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" },
  14025         { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" },
  14026         { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" },
  14027         { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" },
  14028         { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" },
  14029         { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" },
  14030         { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" }
  14031     };
  14032     soc_reg_t ctrl_reg, stat_reg;
  14033     uint32 rval, fval;
  14034     int index, core_clk, quo, rem, frac, retry;
  14035 
  14036     core_clk = SOC_INFO(unit).frequency * 1024;
  14037     ctrl_reg = TOP_RING_OSC_CTRLr;
  14038     stat_reg = TOP_OSC_COUNT_STATr;
  14039 
  14040     for (index = 0; index < COUNTOF(osc_tbl); index++) {
  14041         rval = 0;
  14042         /*
  14043          * set OSC_CNT_RSTBf to 0 to do softreset
  14044          * set OSC_CNT_START to 0 to hold the counter until it selects
  14045          * the input signal
  14046          */
  14047         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  14048         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1);
  14049         soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1);
  14050         soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0,
  14051                           osc_tbl[index].value0);
  14052         if (osc_tbl[index].field1 != INVALIDf) {
  14053             soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1,
  14054                               osc_tbl[index].value1);
  14055         }
  14056         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf,
  14057                           osc_tbl[index].osc_sel);
  14058         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  14059         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1);
  14060         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  14061         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1);
  14062         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  14063 
  14064         for (retry = 0; retry < 10; retry++) {
  14065             sal_usleep(1000);
  14066             SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval));
  14067             if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) {
  14068                 continue;
  14069             }
  14070 
  14071             fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf);
  14072             quo = core_clk / fval;
  14073             rem = core_clk - quo * fval;
  14074             frac = (rem * 10000) / fval;
  14075             LOG_CLI((BSL_META_U(unit, "%s: %d.%04d Mhz\n"),
  14076                        osc_tbl[index].name, quo, frac));
  14077             break;
  14078         }
  14079     }
  14080 
  14081     return SOC_E_NONE;
  14082 }
  14083 
  14084 int
  14085 soc_apache_show_voltage(int unit)
  14086 {
  14087     soc_reg_t reg;
  14088     int index;
  14089     uint32 rval, fval, avg;
  14090 
  14091     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval));
  14092     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0);
  14093     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval));
  14094     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
  14095     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 4);
  14096     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval));
  14097     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  14098     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 0);
  14099     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  14100     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1);
  14101     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  14102 
  14103     sal_sleep(1);
  14104     avg = 0;
  14105 
  14106     /* Read Voltages. Ignores result of PVTMON8 */
  14107     for (index = 0; index < COUNTOF(pvtmon_result_reg) - 1; index++) {
  14108         reg = pvtmon_result_reg[index];
  14109         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  14110         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  14111         /* (PVT_DATA * 880) / 1024 * 0.7 */
  14112         fval = (fval * 880 * 10) / (1024 * 7);
  14113         avg += fval;
  14114         LOG_CLI((BSL_META_U(unit,
  14115                             "Voltage monitor %d: voltage = %d.%03dV\n"),
  14116                  index, (fval/1000), (fval %1000)));
  14117     }
  14118 
  14119     avg /= (COUNTOF(pvtmon_result_reg) - 1);
  14120     LOG_CLI((BSL_META_U(unit,
  14121                         "Average voltage is = %d.%03dV\n"),
  14122              (avg/1000), (avg %1000)));
  14123 
  14124     return SOC_E_NONE;
  14125 }
  14126 
  14127 /*
  14128  * Function:
  14129  *      soc_apache_process_func_intr
  14130  * Description:
  14131  *      Chip specific DPC function to service interrupts
  14132  * Parameters:
  14133  *      unit_vp       - Device number
  14134  *      d1            - IRQ3 mask
  14135  *      d2            - IRQ3 number (to distinguish between
  14136  *                      different types of interrupts).
  14137  */
  14138 void
  14139 soc_apache_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4)
  14140 {
  14141     int unit = PTR_TO_INT(unit_vp);
  14142     int irq3_num = PTR_TO_INT(d2);
  14143     uint32 rval;
  14144 
  14145     if ((irq3_num == 13) /* L2LU INTR */ &&
  14146         soc_feature(unit, soc_feature_l2_overflow)) {
  14147         if (READ_IL2LU_INTR_STATUSr(unit, &rval)) {
  14148             LOG_ERROR(BSL_LS_SOC_COMMON,
  14149                       (BSL_META_U(unit,
  14150                                   "unit %d: Error reading %s reg !!\n"),
  14151                                   unit, SOC_REG_NAME(unit, IL2LU_INTR_STATUSr)));
  14152             return;
  14153         }
  14154         if (soc_reg_field_get(unit, IL2LU_INTR_STATUSr, rval,
  14155                               L2_LEARN_INSERT_FAILUREf)) {
  14156             soc_td2_l2_overflow_interrupt_handler(unit);
  14157         }
  14158     } else if ((irq3_num == 14) /* RDB INTR */) {
  14159         
  14160     }
  14161 
  14162     sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */
  14163     if (d1 != NULL) {
  14164         (void)soc_cmicm_intr3_enable(unit, 
  14165                                      PTR_TO_INT(d1));
  14166     }
  14167 
  14168     return;
  14169 }
  14170 
  14171 int
  14172 soc_apache_port_asf_speed_set(int unit, soc_port_t port, int speed)
  14173 {
  14174     soc_apache_port_ct_speed_t asf_speed_mode;
  14175     uint32 rval; 
  14176 
  14177     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  14178     
  14179     switch (speed) {
  14180         case 10:
  14181             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_10M_FULL;
  14182             break;
  14183         case 100:
  14184             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_100M_FULL;
  14185             break;
  14186         case 1000:
  14187             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_1000M_FULL;
  14188             break;
  14189         case 2500:
  14190             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_2500M_FULL;
  14191             break;
  14192         case 5000:
  14193             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_5000M_FULL;
  14194             break;
  14195         case 10000:
  14196             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_10000M_FULL;
  14197             break;
  14198         case 11000:
  14199             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_11000M_FULL;
  14200             break;
  14201         case 20000:
  14202             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_20000M_FULL;
  14203             break;
  14204         case 21000:
  14205             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_21000M_FULL;
  14206             break;
  14207         case 25000:
  14208             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_25000M_FULL;
  14209             break;
  14210         case 27000:
  14211             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_27000M_FULL;
  14212             break;
  14213         case 40000:
  14214             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_40000M_FULL;
  14215             break;
  14216         case 42000:
  14217             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_42000M_FULL;
  14218             break;
  14219         case 50000:
  14220             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_50000M_FULL;
  14221             break;
  14222         case 53000:
  14223             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_53000M_FULL;
  14224             break;
  14225         case 100000:
  14226             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_100000M_FULL;
  14227             break;
  14228         case 106000:
  14229             asf_speed_mode = SOC_APACHE_PORT_CT_SPEED_106000M_FULL;
  14230             break;
  14231         case 0:
  14232             return SOC_E_NONE;
  14233         default:
  14234             return SOC_E_PARAM;
  14235     }   
  14236     
  14237     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval,
  14238                       ASF_PORT_SPEEDf, asf_speed_mode);
  14239     
  14240     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));  
  14241     return SOC_E_NONE;
  14242 }
  14243 
  14244 int
  14245 soc_apache_port_asf_set(int unit, soc_port_t port, int speed)
  14246 {
  14247     uint32 rval;
  14248     soc_reg_t reg;
  14249     int mmu_port, phy_port;
  14250     int asf_credit_thresh_lo, asf_credit_thresh_hi;
  14251 
  14252     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  14253     mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  14254 
  14255 
  14256     
  14257     if (!soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) {
  14258         if (speed <= 11000) {
  14259             asf_credit_thresh_lo = 4;
  14260             asf_credit_thresh_hi = 9;
  14261         } else if (speed <= 21000) {
  14262             asf_credit_thresh_lo = 8;
  14263             asf_credit_thresh_hi = 18;
  14264         } else if (speed <= 42000) {
  14265             asf_credit_thresh_lo = 18;
  14266             asf_credit_thresh_hi = 36;
  14267         } else {
  14268             asf_credit_thresh_lo = 30;
  14269             asf_credit_thresh_hi = 72;
  14270         }
  14271     } else {
  14272         if (speed <= 11000) {
  14273             asf_credit_thresh_lo = 3;
  14274             asf_credit_thresh_hi = 3;
  14275         } else if (speed <= 27000) {
  14276             asf_credit_thresh_lo = 4;
  14277             asf_credit_thresh_hi = 4;
  14278         } else if (speed <= 42000) {
  14279             asf_credit_thresh_lo = IS_OVERSUB_PORT(unit,port) ? 6 : 5;
  14280             asf_credit_thresh_hi = IS_OVERSUB_PORT(unit,port) ? 6 : 5;
  14281         } else if (speed <= 53000) {
  14282             asf_credit_thresh_lo = 6;
  14283             asf_credit_thresh_hi = 6;
  14284         } else {
  14285             asf_credit_thresh_lo = 10;
  14286             asf_credit_thresh_hi = 10;
  14287         }
  14288     }
  14289 
  14290 
  14291     rval = 0;
  14292     reg = ES_PIPE0_ASF_CREDIT_THRESH_LOr;
  14293     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo);
  14294     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
  14295 
  14296     rval = 0;
  14297     reg = ES_PIPE0_ASF_CREDIT_THRESH_HIr;
  14298     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi);
  14299     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
  14300     SOC_IF_ERROR_RETURN(soc_apache_port_asf_speed_set(unit, port, speed));
  14301 
  14302     return SOC_E_NONE;
  14303 }
  14304 
  14305 int
  14306 soc_apache_port_speed_update(int unit, soc_port_t port, int speed)
  14307 {
  14308     int lossless;
  14309 
  14310     /* Update Edatabuf transmit start count */
  14311     SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, 0, port));
  14312 
  14313     SOC_IF_ERROR_RETURN(soc_apache_port_asf_set(unit, port, speed));
  14314 
  14315     /* Update oversubscription buffer manager (OBM) threshold */
  14316     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  14317     SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, FALSE, lossless, port));
  14318 
  14319     SOC_IF_ERROR_RETURN(soc_ap_mmu_delay_insertion_set(unit, port));
  14320 
  14321     return SOC_E_NONE;
  14322 }
  14323 
  14324 
  14325 
  14326 STATIC int
  14327 _soc_apache_thdo_hw_set(int unit, soc_port_t port, int enable)
  14328 {
  14329     uint64 rval64, rval64_tmp;
  14330     int mmu_port, phy_port, i,mmu_port_tmp;
  14331     soc_info_t *si;
  14332     soc_reg_t reg_tmp;
  14333     soc_reg_t reg[3][2] = {
  14334         {
  14335             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  14336             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  14337         },
  14338         {
  14339             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  14340             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  14341         },
  14342         {
  14343             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  14344             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  14345         }
  14346     };
  14347 
  14348     si = &SOC_INFO(unit);
  14349 
  14350     phy_port = si->port_l2p_mapping[port];
  14351     mmu_port = si->port_p2m_mapping[phy_port];
  14352     if (mmu_port > 73) {
  14353         return SOC_E_PARAM;
  14354     }
  14355 
  14356     for (i = 0; i < 3; i++) {
  14357         COMPILER_64_ZERO(rval64);
  14358         COMPILER_64_ZERO(rval64_tmp);
  14359         if (mmu_port < 64) {
  14360             reg_tmp = reg[i][0];
  14361             mmu_port_tmp = mmu_port; 
  14362         } else {
  14363             reg_tmp = reg[i][1];
  14364             mmu_port_tmp = mmu_port - 64;
  14365         }
  14366 
  14367         SOC_IF_ERROR_RETURN(
  14368             soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  14369 
  14370         if (mmu_port_tmp < 32) {
  14371             COMPILER_64_SET(rval64_tmp, 0, 1 << mmu_port_tmp);
  14372         } else {
  14373             COMPILER_64_SET(rval64_tmp, 1 << (mmu_port_tmp - 32), 0);
  14374         }
  14375 
  14376         if (enable) {
  14377             COMPILER_64_OR(rval64, rval64_tmp);
  14378         } else {
  14379             COMPILER_64_NOT(rval64_tmp);
  14380             COMPILER_64_AND(rval64, rval64_tmp);
  14381         }
  14382 
  14383         SOC_IF_ERROR_RETURN(
  14384             soc_reg_set(unit, reg_tmp, REG_PORT_ANY, 0, rval64));
  14385     }
  14386 
  14387     return SOC_E_NONE;
  14388 }
  14389 STATIC int
  14390 _soc_apache_thdo_hw_get(int unit, soc_port_t port, int *enable)
  14391 {
  14392     uint64 rval64;
  14393     int mmu_port, phy_port, i, reg_grp = 0;
  14394     int rv = SOC_E_NONE;
  14395     soc_info_t *si;
  14396     soc_reg_t reg_tmp;
  14397     soc_reg_t reg[3][2] = {
  14398         {
  14399             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  14400             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  14401         },
  14402         {
  14403             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  14404             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  14405         },
  14406         {
  14407             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  14408             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  14409         }
  14410     };
  14411     int max_reg = 3;
  14412 
  14413     si = &SOC_INFO(unit);
  14414 
  14415     phy_port = si->port_l2p_mapping[port];
  14416     mmu_port = si->port_p2m_mapping[phy_port];
  14417 
  14418     COMPILER_64_ZERO(rval64);
  14419     if (mmu_port  < 64 ) {
  14420         mmu_port &= 0x3f;
  14421     } else {
  14422         mmu_port &= 0xf;
  14423         reg_grp = 1;
  14424     }
  14425 
  14426     for (i = 0; i < max_reg; i++) {
  14427         reg_tmp = reg[i][reg_grp];
  14428 
  14429         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  14430 
  14431         if (COMPILER_64_BITTEST(rval64 , mmu_port)) {
  14432             *enable = TRUE;
  14433         } else {
  14434             *enable = FALSE;
  14435         }
  14436     }
  14437     return rv;
  14438 }
  14439 
  14440 /*
  14441  * Function:
  14442  *      _soc_apache_port_thdo_rx_enable_set
  14443  * Purpose:
  14444  *     enable/disable  the traffic to the port according to
  14445  *     different callers.
  14446  *  the traffic to the port can be enabled only if all of the callers
  14447  *  are to enable it.
  14448  * Parameters:
  14449  *     unit                - (IN) unit number
  14450  *     port                - (IN) local port
  14451  *     enable              - (IN) enable/disable the traffic to the port.
  14452  *     flag                - (IN) different callers.
  14453  * Returns:
  14454  *     BCM_E_XXX
  14455  */
  14456 STATIC int
  14457 _soc_apache_port_thdo_rx_enable_set(int unit, soc_port_t port, 
  14458                                  int enable, uint8 flag)
  14459 {
  14460     int   rv = SOC_E_NONE;
  14461     uint8 *thdo_drop_bmp;
  14462     _soc_apache_mmu_traffic_ctrl_t *mmu_traffic_ctrl;
  14463     int cur_enable =0 ;
  14464     FWD_CTRL_LOCK(unit);
  14465 
  14466     mmu_traffic_ctrl = _soc_apache_mmu_traffic_ctrl[unit];
  14467     if (mmu_traffic_ctrl ==  NULL) {
  14468         FWD_CTRL_UNLOCK(unit);
  14469         return SOC_E_INIT;
  14470     }
  14471     thdo_drop_bmp =
  14472         &(mmu_traffic_ctrl->thdo_drop_bmp[port]);
  14473 
  14474     if (!enable) {
  14475         if (*thdo_drop_bmp & flag) {
  14476             FWD_CTRL_UNLOCK(unit);
  14477             return rv;
  14478         }
  14479 
  14480         if (*thdo_drop_bmp == 0) {
  14481             rv = _soc_apache_thdo_hw_set(unit, port, enable);
  14482             if (SOC_FAILURE(rv)) {
  14483                 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Clearing the registers failed.\n")));
  14484                 FWD_CTRL_UNLOCK(unit);
  14485                 return rv;
  14486             }
  14487         }
  14488 
  14489         *thdo_drop_bmp |= flag;
  14490 
  14491         FWD_CTRL_UNLOCK(unit);
  14492         return rv;
  14493     } else {
  14494         if (0 == *thdo_drop_bmp) {
  14495             rv = _soc_apache_thdo_hw_get(unit, port, &cur_enable);
  14496             if (SOC_FAILURE(rv)) {
  14497                 LOG_ERROR(BSL_LS_SOC_COMMON,
  14498                           (BSL_META_U(unit,
  14499                                       "Get the registers fail.\n")));
  14500                 FWD_CTRL_UNLOCK(unit);
  14501                 return rv;
  14502             }
  14503             /* Warmboot: latest value of *thdo_drop_bmp is not sync to WB cache.
  14504             * We execute "sc controlsync=1" when one port is link up. But when we exit SDK,
  14505             * the port is link down, so the conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  14506             * of the port is zero.  After WarmBoot SDK,
  14507             * we can't set conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  14508             * for the port when it is link up, because, the value of thdo_drop_bmp is zero.
  14509             */
  14510             if(cur_enable == FALSE) {
  14511                 LOG_INFO(BSL_LS_SOC_COMMON,
  14512                           (BSL_META_U(unit,
  14513                                       "Latest thdo_drop_bmp was not updated to WB cache!!!\n")));
  14514                 *thdo_drop_bmp |= flag;
  14515             }
  14516         }
  14517 
  14518         if (*thdo_drop_bmp != flag) {
  14519             /*other callers are in thdo drop*/
  14520             *thdo_drop_bmp &= ~flag;
  14521             FWD_CTRL_UNLOCK(unit);
  14522             return rv;
  14523         }
  14524 
  14525         /*Ok, only self is in thdo drop, enbable it*/
  14526         rv = _soc_apache_thdo_hw_set(unit, port, enable);
  14527         if (SOC_FAILURE(rv)) {
  14528             LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Setting the registers failed.\n")));
  14529             FWD_CTRL_UNLOCK(unit);
  14530             return rv;
  14531         }
  14532 
  14533         *thdo_drop_bmp &= ~flag;
  14534 
  14535         FWD_CTRL_UNLOCK(unit);
  14536         return rv;
  14537     }
  14538 
  14539     FWD_CTRL_UNLOCK(unit);
  14540     return rv;
  14541 }
  14542 
  14543 
  14544 int
  14545 soc_apache_port_traffic_egr_enable_set(int unit, soc_port_t port,
  14546                                int enable)
  14547 {
  14548     return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 
  14549                                             COSQ_SCHED_SET_CTRL);
  14550 }
  14551 
  14552 int
  14553 soc_apache_port_mmu_tx_enable_set(int unit, soc_port_t port,
  14554                                int enable)
  14555 {
  14556     return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 
  14557                                            MMU_TRAFFIC_EN_CTRL); 
  14558 }
  14559 
  14560 
  14561 int
  14562 soc_apache_port_thdo_rx_enable_set(int unit, soc_port_t port, 
  14563                                      int enable)
  14564 {
  14565     return _soc_apache_port_thdo_rx_enable_set(unit, port, enable, 
  14566                                             MAC_ENABLE_SET_CTRL);
  14567 }
  14568 
  14569 
  14570 STATIC int
  14571 _soc_ap_resource_data_check(int unit, int num_res, soc_port_resource_t *res)
  14572 {
  14573     int i, j;
  14574     /* null check for all resource data before accessing register */
  14575     for (i = 0 ; i < num_res ; ++i) {
  14576         soc_port_resource_t *p = &res[i];
  14577         if (NULL == p) {
  14578             /* 
  14579             * COVERITY 
  14580             * It is kept intentionally as a defensive check. 
  14581             */
  14582             /* coverity[dead_error_line] */
  14583             return SOC_E_PARAM;
  14584         }
  14585         for (j = 0; j < p->num_lanes ; ++j) {
  14586             soc_port_lane_info_t *p_lane_info = p->lane_info[j];
  14587             if (NULL == p_lane_info) {
  14588                 return SOC_E_PARAM;
  14589             }
  14590         }
  14591     }
  14592     return SOC_E_NONE;
  14593 }
  14594 
  14595 /*
  14596  * Function:
  14597  *      soc_ap_pgw_obm_set
  14598  * Purpose:
  14599  *      Reconfigure PGW_OBM registers in flex port sequence
  14600  *      This function will do two things,
  14601  *      1. clear all registers for old ports which exists in pre-Flex status
  14602  *      2. initialize all registers for new ports which exists in post-Flex status
  14603  *
  14604  * Parameters:
  14605  *      unit         - (IN) Unit number.
  14606  *      pre_num_res  - (IN) Number of resource data which exist in pre-Flex status
  14607  *      post_num_res - (IN) Number of resource data which exist in post-Flex status
  14608  *      pre_res      - (IN) Resource data structure pointer in pre-Flex status
  14609  *      post_res     - (IN) Resource data structure pointer in post-Flex status
  14610  *
  14611  * Returns:
  14612  *      SOC_E_XXX
  14613  */
  14614 int
  14615 soc_ap_pgw_obm_set(int unit,
  14616                      int pre_num_res,  soc_port_resource_t *pre_res,
  14617                      int post_num_res, soc_port_resource_t *post_res)
  14618 {
  14619     int i;
  14620     int port, xlp;
  14621     int lossless;
  14622 
  14623     SOC_IF_ERROR_RETURN(
  14624         _soc_ap_resource_data_check(unit, pre_num_res, pre_res));
  14625     SOC_IF_ERROR_RETURN(
  14626         _soc_ap_resource_data_check(unit, post_num_res, post_res));
  14627 
  14628     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  14629     for (i = 0; i < pre_num_res; i++) {
  14630         if (pre_res[i].flags & SOC_PORT_RESOURCE_I_MAP) {
  14631             continue;
  14632         }
  14633         if (pre_res[i].physical_port == -1) {
  14634             continue;
  14635         }
  14636         port = pre_res[i].logical_port;
  14637         _soc_apache_idb_port_init(unit, TRUE, lossless, port);
  14638         xlp = (pre_res[i].physical_port % (APACHE_TSCS_PER_PGW * APACHE_PGWS_PER_DEV));
  14639         SOC_IF_ERROR_RETURN(_soc_apache_port_blk_ca_mode_set(unit, TRUE, xlp));
  14640     }
  14641 
  14642     for (i = 0; i < post_num_res; i++) {
  14643         port = post_res[i].logical_port;
  14644         _soc_apache_idb_port_init(unit, FALSE, lossless, port);
  14645         xlp = SOC_INFO(unit).port_serdes[port];
  14646         SOC_IF_ERROR_RETURN(_soc_apache_port_blk_ca_mode_set(unit, TRUE, xlp));
  14647     }
  14648 
  14649 
  14650     return SOC_E_NONE;
  14651 }
  14652 
  14653 
  14654 /*
  14655  * Function:
  14656  *      soc_ap_obm_threshold_default_set
  14657  * Purpose:
  14658  *      Reconfigure PGW Threshold in flex port sequence
  14659  *      In this function following registers will be initialized.
  14660  *          PGW_OBM[0-3]_THRESHOLD
  14661  *          PGW_OBM[0-3]_THRESHOLD2
  14662  *      If default_flag is PGW_OBM_INIT_HW_DEFAULT,
  14663  *      register will be intialized by HW reset value
  14664  *      If default_flag is PGW_OBM_INIT_SW_DEFAULT,
  14665  *      register will be intialized by SW reset value
  14666  *
  14667  * Parameters:
  14668  *      unit         - (IN) Unit number
  14669  *      num_res      - (IN) Number of resource
  14670  *      res          - (IN) Resource data structure
  14671  *      lossless     - (IN) Lossless configuration of device
  14672  *      default_flag - (IN) PGW_OBM_INIT_HW_DEFAULT
  14673  *                          Use HW reset value for register value
  14674  *                   - (IN) PGW_OBM_INIT_SW_DEFAULT
  14675  *                          Use SW default value
  14676  *
  14677  * Assumption:
  14678  *      This function cannot access SOC_INFO data structure.
  14679  *      So assume followings condition should be checked
  14680  *      before calling this function.
  14681  *
  14682  *      1. pgw block is valid
  14683  *             si->block_valid[PGW_CL_BLOCK(unit, pgw)] is true
  14684  *      2. port block is used
  14685  *             block = PGW_CL_BLOCK(unit, pgw);
  14686  *             SOC_BLOCK_PORT(unit, block) < 0
  14687  *      3. num_res should be correct number of resource data structure.
  14688  *         all resource data structure should be accessed by using
  14689  *         pointer offset by res_num. If the pointer of resource data is NULL,
  14690  *         returns SOC_E_PARAM.
  14691  *
  14692  * Returns:
  14693  *      SOC_E_XXX
  14694  */
  14695 STATIC
  14696 soc_error_t soc_ap_obm_threshold_default_set(int unit,
  14697                                                int num_res,
  14698                                                soc_port_resource_t *res,
  14699                                                int lossless,
  14700                                                int reset)
  14701 {
  14702     int i;
  14703 
  14704     for (i = 0 ; i < num_res ; ++i) {
  14705 
  14706         
  14707         SOC_IF_ERROR_RETURN(_soc_apache_idb_port_init(unit, reset, lossless, res->logical_port));
  14708 
  14709     }
  14710 
  14711     return SOC_E_NONE;
  14712 }
  14713 
  14714 STATIC int
  14715 soc_ap_obm_threshold_hw_default_set(int unit, int num_res,
  14716                                       soc_port_resource_t *res,
  14717                                       int lossless)
  14718 {
  14719 
  14720     SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_default_set(unit, num_res, res,
  14721                                                lossless,
  14722                                                TRUE));
  14723     return SOC_E_NONE;
  14724 }
  14725 
  14726 STATIC int
  14727 soc_ap_obm_threshold_sw_default_set(int unit, int num_res,
  14728                                       soc_port_resource_t *res,
  14729                                       int lossless)
  14730 {
  14731     SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_default_set(unit, num_res, res,
  14732                                                lossless,
  14733                                                FALSE));
  14734     return SOC_E_NONE;
  14735 }
  14736 
  14737 /*
  14738  * Function:
  14739  *      soc_ap_obm_threshold_set
  14740  * Purpose:
  14741  *  Reconfigure PGW registers in flex port sequence
  14742  *  In this function PGW OBM threshold registers will be initialized.
  14743  *  This function will do two things,
  14744  *  1. clear all registers for old ports which exists in pre-Flex status
  14745  *  2. initialize all registers for new ports which exists in post-Flex status
  14746  *
  14747  * Parameters:
  14748  *  unit         - (IN) Unit number.
  14749  *  pre_num_res  - (IN) Number of resource data which exist in pre-Flex status
  14750  *  post_num_res - (IN) Number of resource data which exist in post-Flex status
  14751  *  pre_res      - (IN) Resource data structure pointer in pre-Flex status
  14752  *  post_res     - (IN) Resource data structure pointer in post-Flex status
  14753  *  lossless     - (IN) mmu lossless information
  14754  *
  14755  * Returns:
  14756  *  SOC_E_XXX
  14757  *
  14758  * Note : For 100G port, this functions expects the ovsersub field to be
  14759  * disabled.
  14760  */
  14761 soc_error_t soc_ap_obm_threshold_set(int unit,
  14762                          int pre_num_res, soc_port_resource_t *pre_res,
  14763                          int post_num_res, soc_port_resource_t *post_res,
  14764                          int lossless)
  14765 {
  14766     
  14767     SOC_IF_ERROR_RETURN(_soc_ap_resource_data_check(unit, pre_num_res,
  14768                                                       pre_res));
  14769     SOC_IF_ERROR_RETURN(_soc_ap_resource_data_check(unit, post_num_res,
  14770                                                       post_res));
  14771     SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_hw_default_set(unit,
  14772                         pre_num_res, pre_res, lossless));
  14773 
  14774     SOC_IF_ERROR_RETURN(soc_ap_obm_threshold_sw_default_set(unit, 
  14775                         post_num_res, post_res, lossless));
  14776 
  14777     return SOC_E_NONE;
  14778 }
  14779 
  14780 
  14781 /*
  14782  * This function is used to enable or disable cut through when a port is 
  14783  * operating in store and forward mode. 
  14784  * Refer TD2_Cutthrough_programming_guideline.pdf
  14785  * Caller must pass the correct port_info pointer, corresponding to the port
  14786  * being configured (and sent by the BCM layer)
  14787  * To enable cut-through, pass enable = 1
  14788  * To disable cut-through, pass enable = 0
  14789  */
  14790 int
  14791 soc_ap_cut_thru_enable_disable(int unit, soc_port_t port, int enable)
  14792 {
  14793     uint32 rval;
  14794     uint32 speed;
  14795 
  14796     /* Cut-through not supported on non-packet-forwarding ports */
  14797     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  14798         return SOC_E_PORT;
  14799     }
  14800 
  14801     /* When in Oversub, only 40G speeds support CT  */
  14802     speed = SOC_INFO(unit).port_speed_max[port];
  14803     speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);
  14804     if (IS_OVERSUB_PORT(unit, port) && speed != 40000) {
  14805         LOG_ERROR(BSL_LS_SOC_COMMON,
  14806                   (BSL_META_U(unit,
  14807                               "ASF supported only on 40G/42G ports "
  14808                               "when in Oversub\n")));
  14809         return SOC_E_PORT;
  14810     }
  14811 
  14812     if (soc_feature(unit, soc_feature_untethered_otp)) {
  14813         if (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoOsubCT) && (IS_OVERSUB_PORT(unit, port))) {
  14814             LOG_ERROR(BSL_LS_SOC_COMMON,
  14815                       (BSL_META_U(unit,
  14816                                   "ASF not supported on Oversub ports\n")));
  14817             return SOC_E_CONFIG;
  14818         }
  14819     }
  14820 
  14821     /* Mask unnecessary bits */
  14822     enable &= 0x1;
  14823 
  14824     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  14825 
  14826     speed = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, ASF_PORT_SPEEDf);
  14827 
  14828     /* Set port speed to 0 */
  14829     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, 0);
  14830     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14831 
  14832     if (!enable) {
  14833         /* Wait 8ms for draining all cells */
  14834         sal_usleep(8000);
  14835     }
  14836 
  14837     SOC_IF_ERROR_RETURN(soc_apache_port_edb_config(unit, enable, port));
  14838 
  14839     /* Set UC_ASF_ENABLE, MC_ASF_ENABLE bits to 1 */
  14840     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, UC_ASF_ENABLEf, enable);
  14841     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, MC_ASF_ENABLEf, enable);
  14842     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14843 
  14844     if (enable) {
  14845         /* Wait 1 micro-sec */
  14846         sal_usleep(1);
  14847     }
  14848 
  14849     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, speed);
  14850     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14851 
  14852     return SOC_E_NONE;
  14853 }
  14854 
  14855 
  14856 int soc_ap_max_speed_port_find(int phy_port, 
  14857                                         soc_port_resource_t *port_info,
  14858                                         int port_info_arr_size) 
  14859 {
  14860     int idx, index, speed;
  14861   
  14862     index = 0;
  14863     speed = port_info[index].speed;
  14864 
  14865     for (idx = 1; idx < port_info_arr_size; idx++) {
  14866         /* If all speeds are equal, '>' will return the 1st index,
  14867          * '>=' will return the last index
  14868          */
  14869         if (port_info[idx].speed > speed) {
  14870             speed = port_info[idx].speed;
  14871             index = idx;
  14872         }
  14873     }
  14874 
  14875     return index;
  14876 }
  14877 
  14878 /*
  14879  * This function checks if cut-through is enabled for a given port.
  14880  * If either unicast or multicast cut-through is enabled, the function
  14881  * returns TRUE else FALSE is returned
  14882  */
  14883 int
  14884 soc_apache_is_cut_thru_enabled(int unit, soc_port_t port, int *enable)
  14885 {
  14886     uint32 rval;
  14887     uint32 uc_enable, mc_enable;
  14888 
  14889     /* Cut-through not supported on following ports */
  14890     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  14891         return SOC_E_PARAM;
  14892     }
  14893 
  14894     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  14895 
  14896     uc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, UC_ASF_ENABLEf);
  14897     mc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, MC_ASF_ENABLEf);
  14898 
  14899     if (uc_enable || mc_enable) {
  14900         *enable = TRUE;
  14901     } else {
  14902         *enable = FALSE;
  14903     }
  14904 
  14905     return SOC_E_NONE;
  14906 }
  14907 
  14908 /*
  14909  * This function is used to clear various counters in EP block. The 
  14910  * counters to clear are mentioned in 'Reconfigure EP' section of TD2+ Flexport
  14911  */
  14912 STATIC int soc_ap_ep_counters_clear(int unit, soc_port_resource_t *port_info)
  14913 {
  14914     uint64 val64;
  14915     uint32 val = 0;
  14916 
  14917     COMPILER_64_ZERO(val64);
  14918     SOC_IF_ERROR_RETURN(WRITE_EGR_TRILL_TX_PKTSr(unit, port_info->logical_port,
  14919                         val));
  14920     SOC_IF_ERROR_RETURN(WRITE_EGR_TRILL_TX_ACCESS_PORT_TRILL_PKTS_DISCARDEDr(unit, port_info->logical_port, val));
  14921     SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_DELIMITER_ERROR_FRAMESr(unit,
  14922                         port_info->logical_port, val));
  14923     SOC_IF_ERROR_RETURN(WRITE_EGR_FCOE_INVALID_CRC_FRAMESr(unit, 
  14924                         port_info->logical_port, val));
  14925 
  14926     SOC_IF_ERROR_RETURN(WRITE_TPCEr(unit, port_info->logical_port, val64));
  14927 
  14928     SOC_IF_ERROR_RETURN(WRITE_TDBGC0r(unit, port_info->logical_port, val64));
  14929     SOC_IF_ERROR_RETURN(WRITE_TDBGC1r(unit, port_info->logical_port, val64));
  14930     SOC_IF_ERROR_RETURN(WRITE_TDBGC2r(unit, port_info->logical_port, val64));
  14931     SOC_IF_ERROR_RETURN(WRITE_TDBGC3r(unit, port_info->logical_port, val64));
  14932     SOC_IF_ERROR_RETURN(WRITE_TDBGC4r(unit, port_info->logical_port, val64));
  14933     SOC_IF_ERROR_RETURN(WRITE_TDBGC5r(unit, port_info->logical_port, val64));
  14934     SOC_IF_ERROR_RETURN(WRITE_TDBGC6r(unit, port_info->logical_port, val64));
  14935     SOC_IF_ERROR_RETURN(WRITE_TDBGC7r(unit, port_info->logical_port, val64));
  14936     SOC_IF_ERROR_RETURN(WRITE_TDBGC8r(unit, port_info->logical_port, val64));
  14937     SOC_IF_ERROR_RETURN(WRITE_TDBGC9r(unit, port_info->logical_port, val64));
  14938     SOC_IF_ERROR_RETURN(WRITE_TDBGC10r(unit, port_info->logical_port, val64));
  14939     SOC_IF_ERROR_RETURN(WRITE_TDBGC11r(unit, port_info->logical_port, val64));
  14940 
  14941     return SOC_E_NONE;
  14942 }
  14943 
  14944 
  14945 STATIC int
  14946 soc_ap_port_resource_tdm_calculate(int unit, soc_apache_tdm_t *tdm)
  14947 {
  14948     int index;
  14949     soc_info_t *si;
  14950     soc_pbmp_t pbmp;
  14951     int port, slot, phy_port;
  14952 
  14953     /* soc info has new values */
  14954     si = &SOC_INFO(unit);
  14955 
  14956     sal_memset(tdm, 0, sizeof(soc_apache_tdm_t));
  14957 
  14958     PBMP_PORT_ITER(unit, port) {
  14959         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
  14960             continue;
  14961         }
  14962         phy_port = si->port_l2p_mapping[port];
  14963 
  14964         tdm->speed[phy_port] = si->port_speed_max[port];
  14965         APACHE_TDM_SPEED_ADJUST(unit, port, tdm->speed[phy_port]);
  14966 
  14967         tdm->port_state[phy_port] =
  14968             IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE;
  14969 
  14970         /*
  14971          * Primary port will be setup as line-rate or oversub.
  14972          * Subsequent physical ports (sister-ports) will be either
  14973          * DISABLED or SUBPORT/COMBINED mode.
  14974          *
  14975          * TDM Algo expects lanes info based on speed.
  14976          */
  14977         if (soc_apache_port_is_falcon(unit, phy_port)) { /*  Falcons  */
  14978             if (tdm->speed[phy_port] > 25000) {
  14979                 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
  14980             }
  14981             if (tdm->speed[phy_port] > 50000) {
  14982                 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
  14983                 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
  14984             }
  14985         } else {                                         /*  Eagles  */
  14986             if (tdm->speed[phy_port] > 10000) {
  14987                 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
  14988             }
  14989             if (tdm->speed[phy_port] > 20000) {
  14990                 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
  14991                 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
  14992             }
  14993             if (tdm->speed[phy_port] > 40000) {
  14994                 tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT;
  14995                 tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT;
  14996                 tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT;
  14997                 tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT;
  14998                 tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT;
  14999                 tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT;
  15000             }
  15001         }
  15002     }
  15003 
  15004     /* CPU, LB and RDB ports */
  15005     tdm->speed[0] = 1000;
  15006     tdm->speed[73] = 1000;
  15007     tdm->speed[74] = 1000;
  15008     tdm->tdm_bw = si->bandwidth / 1000;
  15009     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  15010     SOC_PBMP_AND(pbmp, si->xpipe_pbm);
  15011     /* tell tdm code the device is oversub if any ports is oversub */
  15012     tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp);
  15013     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  15014 
  15015     for (slot = 0; slot <= APACHE_MMU_TDM_LENGTH; slot++) {
  15016         tdm->mmu_tdm[slot] = NUM_EXT_PORTS;
  15017     }
  15018 
  15019     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  15020         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), tdm->tdm_bw));
  15021         LOG_CLI((BSL_META_U(unit, "port speed:")));
  15022         for (index = 0; index < NUM_EXT_PORTS; index++) {
  15023             if (index % 8 == 0) {
  15024                 LOG_CLI((BSL_META_U(unit, "\n    ")));
  15025             }
  15026             LOG_CLI((BSL_META_U(unit, " %06d(%03d)"),
  15027                      tdm->speed[index], index));
  15028         }
  15029         LOG_CLI((BSL_META_U(unit, "\n")));
  15030         LOG_CLI((BSL_META_U(unit, "port state map:")));
  15031         for (index = 0; index < NUM_EXT_PORTS; index++) {
  15032             if (index % 8 == 0) {
  15033                 LOG_CLI((BSL_META_U(unit, "\n    ")));
  15034             }
  15035             if (index == 0 || index == (NUM_EXT_PORTS - 1)) {
  15036                 LOG_CLI((BSL_META_U(unit, " --------")));
  15037             } else {
  15038                 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"),
  15039                          tdm->port_state[index], index));
  15040             }
  15041         }
  15042         LOG_CLI((BSL_META_U(unit, "\n")));
  15043     }
  15044 
  15045 
  15046     SOC_IF_ERROR_RETURN(soc_apache_tdm_calc(unit, tdm));
  15047 
  15048 
  15049     return SOC_E_NONE;
  15050 }
  15051 
  15052 
  15053 
  15054 STATIC int
  15055 soc_ap_ovr_sub_tdm_update(int unit,
  15056                           soc_apache_tdm_t *tdm,
  15057                           int pre_count,
  15058                           soc_port_resource_t *pre_res,
  15059                           int post_count,
  15060                           soc_port_resource_t *post_res)
  15061 {
  15062     int phy_port;
  15063     int group, wt_group, speed_group;
  15064     int res_count, speed_class;
  15065     int slot, empty_slot_cnt;
  15066     uint32 speed_spacing;
  15067     soc_apache_tdm_t *cur_tdm;
  15068 
  15069 
  15070     tdm = APACHE_TDM_STRUCT_BACKUP(unit);
  15071     cur_tdm = APACHE_TDM_STRUCT_ACTIVE(unit);
  15072 
  15073     /* Remove old ports from the existing egress overusb groups */
  15074     for (res_count = 0; res_count < pre_count; res_count++) {
  15075         soc_port_resource_t *p = &pre_res[res_count];
  15076 
  15077         /* If OBM is not enabled then continue */
  15078         if (!p->oversub) {
  15079             continue;
  15080         }
  15081 
  15082         if (p->flags & SOC_PORT_RESOURCE_INACTIVE) {
  15083             continue;
  15084         }
  15085 
  15086         phy_port = p->physical_port;
  15087 
  15088         for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
  15089             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) {
  15090                 continue;
  15091             }
  15092             empty_slot_cnt = 0;
  15093             for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
  15094                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] == phy_port) {
  15095                     cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = NUM_EXT_PORTS;
  15096 
  15097                 }
  15098                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) {
  15099                     empty_slot_cnt++;
  15100                 }
  15101             }
  15102 
  15103             /* Mark group that has no more valid mmu ports as free */
  15104             if (empty_slot_cnt == APACHE_MMU_OVS_GROUP_TDM_LENGTH) {
  15105                 APACHE_TDM_WT_GRP_FREE(unit, cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]);
  15106                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = 0;
  15107                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = APACHE_MMU_OVS_WT_GROUP_COUNT;
  15108                 break;
  15109             }
  15110          }
  15111     }
  15112 
  15113     /* Add 'new' ports to the egress schedulers */
  15114     for (res_count = 0; res_count < post_count; res_count++) {
  15115         soc_port_resource_t *p = &post_res[res_count];
  15116 
  15117         /* If OBM is not enabled then continue */
  15118         if (!p->oversub) {
  15119             continue;
  15120         }
  15121 
  15122         if (p->flags & SOC_PORT_RESOURCE_INACTIVE) {
  15123             continue;
  15124         }
  15125 
  15126         speed_class = p->speed;
  15127         phy_port = p->physical_port;
  15128 
  15129         if (SOC_FAILURE(_soc_apache_mmu_ovs_speed_class_map_get(
  15130                         unit, &speed_class, &speed_group, &speed_spacing))) {
  15131             LOG_ERROR(BSL_LS_SOC_PORT,
  15132                       (BSL_META_U(unit,
  15133                                   "Invalid Speed Class %d for port %d (physical = %d)"),
  15134                        speed_class, p->logical_port, phy_port));
  15135 
  15136             return SOC_E_INTERNAL;
  15137         }
  15138 
  15139         APACHE_TDM_WT_GRP_LOG(unit);
  15140 
  15141         /* Try to fit the new port in the group with same speed ports */
  15142         for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
  15143             /* Group with different speed ports; skip! */
  15144             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] != speed_class) {
  15145                 continue;
  15146             }
  15147 
  15148             for (slot = 0; slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
  15149                 /*  break when an empty slot is found */
  15150                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) {
  15151                     break;
  15152                 }
  15153             }
  15154             if (slot < APACHE_MMU_OVS_GROUP_TDM_LENGTH) {
  15155                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port;
  15156                 phy_port = NUM_EXT_PORTS;
  15157                 break;
  15158             }
  15159         }
  15160 
  15161         if (phy_port == NUM_EXT_PORTS) {
  15162             /* Found an empty slot and filled; continue to next */
  15163             continue;
  15164         }
  15165 
  15166         /* Could not get a group with same speed ports, try a free group  */
  15167         for (group = 0; group < APACHE_MMU_OVS_GROUP_COUNT; group++) {
  15168             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) {
  15169                 break;
  15170             }
  15171         }
  15172 
  15173         if (group < APACHE_MMU_OVS_GROUP_COUNT) {
  15174             cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][0] = phy_port;
  15175             cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
  15176 
  15177             for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
  15178                 if (AP_TDM_WT_GRP_SPG_GET(unit, wt_group) == speed_group) {
  15179                     APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
  15180                     break;
  15181                 }
  15182             }
  15183 
  15184             if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) {
  15185                 for (wt_group = 0; wt_group < APACHE_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
  15186                     if (AP_TDM_WT_GRP_REFCNT_GET(unit, wt_group) == 0) {
  15187                         APACHE_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
  15188                         break;
  15189                     }
  15190                 }
  15191             }
  15192 
  15193             if (wt_group >= APACHE_MMU_OVS_WT_GROUP_COUNT) {
  15194                 /* We could not find a weight group for this new port */
  15195                 LOG_ERROR(BSL_LS_SOC_PORT,
  15196                     (BSL_META_U(unit,
  15197                                 "Could not find a usable weight group for "
  15198                                 "port %d (physical = %d; speed_class = %d)"),
  15199                     p->logical_port, phy_port, speed_class));
  15200                 return SOC_E_INTERNAL;
  15201             }
  15202 
  15203             cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
  15204 
  15205             continue;
  15206         }
  15207 
  15208         /* We could not find a group that can fit this new port */
  15209         LOG_ERROR(BSL_LS_SOC_PORT,
  15210                   (BSL_META_U(unit,
  15211                               "Could not find a usable oversub group for "
  15212                               "port %d (physical = %d; speed_class = %d)"),
  15213                    p->logical_port, phy_port, speed_class));
  15214 
  15215         return SOC_E_INTERNAL;
  15216      }
  15217 
  15218     sal_memcpy(&(tdm->egress_ovs_tdm), &(cur_tdm->egress_ovs_tdm), sizeof(tdm->egress_ovs_tdm));
  15219 
  15220     return SOC_E_NONE;
  15221 }
  15222 
  15223 
  15224 /*
  15225  * Function:
  15226  *      soc_ap_port_resource_tdm_set
  15227  * Purpose:
  15228  *      Reconfigure the ingress and egress schedulers for
  15229  *      the new port configuration.
  15230  *
  15231  *      This includes reconfiguration of:
  15232  *      - OBM Thresholds
  15233  *      - EDB Prebuffer
  15234  *      - Ingress Oversub Scheduler
  15235  *      - Egress Oversub Scheduler
  15236  *      - Line-Rate Scheduler
  15237  * Parameters:
  15238  *      unit                 - (IN) Unit number.
  15239  *      curr_port_info_size  - (IN) Size of current port information array
  15240  *      curr_port_info       - (IN) Per-port array with current flexing info
  15241  *      new_port_info_size   - (IN) Size of new port information array
  15242  *      new_port_info        - (IN) Per-port array with new flexing info
  15243  *      si_info              - (IN) Contains subset of fields from
  15244  *                             soc_info_t structure
  15245  *                             prior to the flexing operation
  15246  *      lossless             - (IN) MMU lossless information
  15247  * Returns:
  15248  *      SOC_E_XXX
  15249  * Note:
  15250  *      Assumptions
  15251  *      - soc info structure members have been updated to reflect the latest
  15252  *        flexing operation
  15253  *      - There is no overlapping between logical or physical ports in the 
  15254  *        arrays passed, that is, operations like 4x10->1x40->4x10 on the same
  15255  *        set of ports have been rejected at bcm layer itself, and do not reach
  15256  *        this function
  15257  *      - Pre-FlexPort array
  15258  *        Contains current information on ports to be modified after
  15259  *        the FlexPort operation.  This should include ports whose
  15260  *        mappings are either deleted or remapped.
  15261  *      - Post-FlexPort array
  15262  *        Contains information on new configuration for
  15263  *        ports that are active (present) after the FlexPort operation.
  15264  *        This should include ports whose mappings that are remapped or new.
  15265  */
  15266 int soc_ap_port_resource_tdm_set(int unit, int curr_port_info_size,
  15267                                    soc_port_resource_t *curr_port_info,
  15268                                    int new_port_info_size,
  15269                                    soc_port_resource_t *new_port_info,
  15270                                    soc_ap_info_t *si_info,
  15271                                    int lossless)
  15272 {
  15273     int rv;
  15274     uint32 rval;
  15275     soc_apache_tdm_t *tdm;
  15276 
  15277     /* Reconfigure EDB prebuffer */
  15278 
  15279     SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval));
  15280     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15281                       CLPORT_CELL_COUNTSf, 0x1);
  15282     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15283                       XLPORT_CELL_COUNTSf, 0x3);
  15284     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15285                       ENABLEf, 0x1);
  15286     SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval));
  15287 
  15288     /* Reconfigure EDB prebuffer back up calendar, for line rate
  15289      * TDM calendar. Oversub related portion will be added later
  15290      */
  15291 
  15292     /* Configure ingress scheduler back up calendar */
  15293     tdm = APACHE_TDM_STRUCT_BACKUP(unit);
  15294     SOC_IF_ERROR_RETURN(soc_ap_port_resource_tdm_calculate(unit, tdm));
  15295 
  15296     /* Reconfigure oversub scheduler.
  15297      * Function internally determines if oversub is enabled/disabled
  15298      */
  15299     rv = soc_ap_ovr_sub_tdm_update(unit, tdm, 
  15300                                    curr_port_info_size, curr_port_info,
  15301                                    new_port_info_size, new_port_info);
  15302     SOC_IF_ERROR_RETURN(rv);
  15303 
  15304 
  15305     /* toggle the active calendar */
  15306     APACHE_TDM_ACTIVE_CAL(unit) ^= 1;
  15307 
  15308     /* update the tdm calendar config in the hardware */
  15309     SOC_IF_ERROR_RETURN(soc_apache_tdm_update(unit, 0, APACHE_TDM_ACTIVE_CAL(unit), tdm));
  15310 
  15311 
  15312     /* Reconfigure EDB prebuffer */
  15313 
  15314     sal_usleep(1);
  15315 
  15316     SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval));
  15317     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15318                       CLPORT_CELL_COUNTSf, 0x1);
  15319     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15320                       XLPORT_CELL_COUNTSf, 0x3);
  15321     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  15322                       ENABLEf, 0x0);
  15323     SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval));
  15324 
  15325 
  15326     return SOC_E_NONE;
  15327 }
  15328 
  15329 /*
  15330  * Function:
  15331  *      soc_ap_port_resource_pgw_set
  15332  * Purpose:
  15333  *      Reconfigure PGW registers in flex port sequence
  15334  *      In this function following registers will be initialized.
  15335  *      This function will do two things,
  15336  *      1. clear all registers for old ports which exists in pre-Flex status
  15337  *      2. initialize all registers for new ports which exists in post-Flex
  15338  *         status
  15339  *
  15340  * Parameters:
  15341  *      unit         - (IN) Unit number.
  15342  *      pre_num_res  - (IN) Number of resource data which exist in pre-Flex
  15343  *                          status
  15344  *      post_num_res - (IN) Number of resource data which exist in post-Flex
  15345  *                          status
  15346  *      pre_res      - (IN) Resource data structure pointer in pre-Flex status
  15347  *      post_res     - (IN) Resource data structure pointer in post-Flex status
  15348  *      lossless     - (IN) MMU lossless information
  15349  *
  15350  * Returns:
  15351  *      SOC_E_XXX
  15352  * Note: 
  15353  *      - Assumes FlexPort cases are valid.
  15354  *      - Pre-FlexPort array
  15355  *        Contains current information on ports to be modified after
  15356  *        the FlexPort operation.  This should include ports whose
  15357  *        mappings are either deleted or remapped.
  15358  *      - Post-FlexPort array
  15359  *        Contains information on new configuration for
  15360  *        ports that are active (present) after the FlexPort operation.
  15361  *        This should include ports whose mappings that are remapped or new.
  15362  */
  15363 int
  15364 soc_ap_port_resource_pgw_set(int unit,
  15365                       int pre_num_res,  soc_port_resource_t *pre_res,
  15366                       int post_num_res, soc_port_resource_t *post_res,
  15367                       int lossless)
  15368 {
  15369     int i;
  15370 
  15371     SOC_IF_ERROR_RETURN(
  15372         _soc_ap_resource_data_check(unit, pre_num_res, pre_res));
  15373     SOC_IF_ERROR_RETURN(
  15374         _soc_ap_resource_data_check(unit, post_num_res, post_res));
  15375 
  15376     for (i = 0; i < post_num_res; i++) {
  15377         /* Reconfigure the Port Mode for Port Macro */
  15378         SOC_IF_ERROR_RETURN(
  15379             soc_portctrl_port_mode_set(unit, post_res[i].logical_port, post_res[i].mode));
  15380     }
  15381 
  15382     SOC_IF_ERROR_RETURN(soc_ap_pgw_obm_set(unit,
  15383                                            pre_num_res, pre_res,
  15384                                            post_num_res, post_res));
  15385 
  15386     return SOC_E_NONE;
  15387 }
  15388 
  15389 /*
  15390  * Function:
  15391  *      soc_ap_port_resource_ip_set
  15392  * Purpose:
  15393  *      Reconfigure IP.
  15394  * Parameters:
  15395  *      unit     - (IN) Unit number.
  15396  *      curr_port_info_size - (IN) Size of current port information array
  15397  *      curr_port_info - (IN) Per-port array with current flexing info
  15398  *      new_port_info_size - (IN) Size of new port information array
  15399  *      new_port_info - (IN) Per-port array with new flexing info
  15400  *      si_info - (IN) Contains subset of fields from soc_info_t structure
  15401  *                     prior to the flexing operation
  15402  * Returns:
  15403  *      SOC_E_XXX
  15404  * Note:
  15405  *      Assumptions
  15406  *      - soc info structure members have been updated to reflect the latest
  15407  *        flexing operation
  15408  *      - There is no overlapping between logical or physical ports in the 
  15409  *        arrays passed, example, operations like 4x10->1x40->4x10 on the same
  15410  *        set of ports have been rejected at bcm layer itself, and do not reach
  15411  *        this function
  15412  *      - Pre-FlexPort array
  15413  *        Contains current information on ports to be modified after
  15414  *        the FlexPort operation.  This should include ports whose
  15415  *        mappings are either deleted or remapped.
  15416  *      - Post-FlexPort array
  15417  *        Contains information on new configuration for
  15418  *        ports that are active (present) after the FlexPort operation.
  15419  *        This should include ports whose mappings that are remapped or new.
  15420  */
  15421 int soc_ap_port_resource_ip_set(int unit, int curr_port_info_size,
  15422                                   soc_port_resource_t *curr_port_info,
  15423                                   int new_port_info_size,
  15424                                   soc_port_resource_t *new_port_info,
  15425                                   soc_ap_info_t *si_info)
  15426 {
  15427     soc_info_t *si;
  15428     soc_mem_t mem;
  15429     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
  15430     int port, phy_port;
  15431     int num_phy_port;
  15432 
  15433     si = &SOC_INFO(unit);
  15434 
  15435     /* Ingress physical to logical port mapping */
  15436     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
  15437     num_phy_port = soc_mem_index_count(unit, mem);
  15438 
  15439     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
  15440         sal_memset(&entry, 0, sizeof(entry));
  15441 
  15442         /* The p2l mapping has been updated before this function is called */
  15443         port = si->port_p2l_mapping[phy_port];
  15444 
  15445         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
  15446                             port == -1 ? 0x7F : port);
  15447         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port,
  15448                                           &entry));
  15449     }
  15450 
  15451     return SOC_E_NONE;
  15452 }
  15453 
  15454 /*
  15455  * Function:
  15456  *      soc_ap_port_resource_ep_set
  15457  * Purpose:
  15458  *      Reconfigure EP.
  15459  * Parameters:
  15460  *      unit     - (IN) Unit number.
  15461  *      curr_port_info_size - (IN) Size of current port information array
  15462  *      curr_port_info - (IN) Per-port array with current flexing info
  15463  *      new_port_info_size - (IN) Size of new port information array
  15464  *      new_port_info - (IN) Per-port array with new flexing info
  15465  *      si_info - (IN) Contains subset of fields from soc_info_t structure
  15466  *                     prior to the flexing operation
  15467  * Returns:
  15468  *      SOC_E_XXX
  15469  * Note:
  15470  *      Assumptions
  15471  *      - soc info structure members have been updated to reflect the latest
  15472  *        flexing operation
  15473  *      - There is no overlapping between logical or physical ports in the 
  15474  *        arrays passed, example, operations like 4x10->1x40->4x10 on the same
  15475  *        set of ports have been rejected at bcm layer itself, and do not reach
  15476  *        this function
  15477  *      - Pre-FlexPort array
  15478  *        Contains current information on ports to be modified after
  15479  *        the FlexPort operation.  This should include ports whose
  15480  *        mappings are either deleted or remapped.
  15481  *      - Post-FlexPort array
  15482  *        Contains information on new configuration for
  15483  *        ports that are active (present) after the FlexPort operation.
  15484  *        This should include ports whose mappings that are remapped or new.
  15485  */
  15486 int soc_ap_port_resource_ep_set(int unit, int curr_port_info_size,
  15487                                   soc_port_resource_t *curr_port_info,
  15488                                   int new_port_info_size,
  15489                                   soc_port_resource_t *new_port_info,
  15490                                   soc_ap_info_t *si_info)
  15491 {
  15492     soc_info_t *si;
  15493     uint32 rval;
  15494     int num_port, port, idx, phy_port;
  15495 
  15496     si = &SOC_INFO(unit);
  15497 
  15498     /* Ingress logical to physical port mapping */
  15499     num_port = soc_mem_index_count(unit, PORT_TABm) - 1;
  15500 
  15501     /* Egress logical to physical port mapping */
  15502     for (port = 0; port < num_port; port++) {
  15503         /*
  15504          * Use logical to physical number mapping from soc info structure
  15505          * since it has been updated before this function is called
  15506          */
  15507         phy_port = si->port_l2p_mapping[port];
  15508 
  15509         rval = 0;
  15510         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
  15511                           &rval, PHYSICAL_PORT_NUMBERf,
  15512                           phy_port == -1 ? 0x7F : phy_port);
  15513         SOC_IF_ERROR_RETURN
  15514             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
  15515                                                                 rval));
  15516     }
  15517 
  15518     /* Clear counters for the newly added ports */
  15519     for (idx = 0; idx < new_port_info_size; idx++) {
  15520         SOC_IF_ERROR_RETURN(soc_ap_ep_counters_clear(unit,
  15521                                                        &new_port_info[idx]));
  15522     }
  15523 
  15524     return SOC_E_NONE;
  15525 }
  15526 
  15527 /*
  15528  * Function: 
  15529  *      soc_ap_port_resource_mmu_mapping_set
  15530  * Purpose:
  15531  *      Set the HW MMU Port mappings.
  15532  * Parameters:
  15533  *      unit      - (IN) Unit number.
  15534  *      nport     - (IN) Number of elements in array resource.
  15535  *      resource  - (IN) Port Resource FlexPort configuration.
  15536  * Returns:
  15537  *      SOC_E_XXX
  15538  * Note:
  15539  *      Assumes FlexPort cases are valid.
  15540  *      Assumes SOC INFO data structure has been updated.
  15541  */
  15542 int
  15543 soc_ap_port_resource_mmu_mapping_set(int unit, int nport,
  15544                                        soc_port_resource_t *resource)
  15545 {
  15546     soc_info_t *si = &SOC_INFO(unit);
  15547     soc_port_resource_t *pr;
  15548     int i;
  15549     int logic_port;
  15550     int phy_port;
  15551     uint32 rval;
  15552 
  15553     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
  15554         /*
  15555          * Skip for legacy inactive configurations since
  15556          * MMU mappings are kept the same.
  15557          */
  15558         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
  15559             LOG_VERBOSE(BSL_LS_SOC_PORT,
  15560                         (BSL_META_U(unit,
  15561                                     "  Skip port with inactive configuration, "
  15562                                     "mappings are kept the same, "
  15563                                     "mmu=%d logical=%d physical=%d\n"),
  15564                          si->port_p2m_mapping
  15565                          [si->port_l2p_mapping[pr->logical_port]],
  15566                          pr->logical_port,
  15567                          si->port_l2p_mapping[pr->logical_port]));
  15568             continue;
  15569         }
  15570 
  15571         if (pr->physical_port == -1) {
  15572             /* Remove old MMU mappings. */
  15573             logic_port = 0x7F;
  15574             phy_port = 0x7F;
  15575 
  15576         } else {
  15577             logic_port = pr->logical_port;
  15578             phy_port = pr->physical_port;
  15579         }
  15580 
  15581         rval = 0;
  15582         soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval,
  15583                           PHY_PORTf, phy_port);
  15584         SOC_IF_ERROR_RETURN
  15585             (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, pr->logical_port,
  15586                            0, rval));
  15587 
  15588         rval = 0;
  15589         soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval,
  15590                           LOGIC_PORTf, logic_port);
  15591         SOC_IF_ERROR_RETURN
  15592             (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, pr->logical_port,
  15593                            0, rval));
  15594 
  15595         LOG_VERBOSE(BSL_LS_SOC_PORT,
  15596                     (BSL_META_U(unit,
  15597                                 "MMU port mappings: "
  15598                                 "mmu=%d logical=%d physical=%d\n"),
  15599                      si->port_p2m_mapping
  15600                      [si->port_l2p_mapping[pr->logical_port]],
  15601                      logic_port, phy_port));
  15602     }
  15603 
  15604     return SOC_E_NONE;
  15605 }
  15606 
  15607 
  15608 /*
  15609  * Function:
  15610  *      soc_ap_port_resource_mmu_set
  15611  * Purpose:
  15612  *      Called to reconfigure the MMU hardware.
  15613  * Parameters:
  15614  *      unit           - (IN) Device Number
  15615  *      nport          - (IN) The number of port modifications in flexport_data
  15616  *      flexport_data  - (IN) An array of port changes that are being done
  15617  * Returns:
  15618  *      SOC_E_NONE if parameters are valid, an error otherwise. 
  15619  * Note:
  15620  *      Assumes FlexPort cases are valid.
  15621  *      Assumes SOC INFO data structure has been updated.
  15622  */
  15623 int
  15624 soc_ap_port_resource_mmu_set(int unit, int nport,
  15625                                soc_port_resource_t *flexport_data)
  15626 {
  15627     int i;
  15628 
  15629     /* Update MMU Port Mappings */
  15630     SOC_IF_ERROR_RETURN
  15631         (soc_ap_port_resource_mmu_mapping_set(unit, nport, flexport_data));
  15632 
  15633     /* Configure all MMU registers for new ports */
  15634     for (i = 0; i < nport; i++) {
  15635         if (flexport_data[i].physical_port != -1) {
  15636             SOC_IF_ERROR_RETURN(
  15637             soc_apache_mmu_port_resource_set(unit, flexport_data[i].logical_port,
  15638                                              flexport_data[i].speed));
  15639         }
  15640     }
  15641 
  15642     return SOC_E_NONE;
  15643 }
  15644 
  15645 /*
  15646  * Function:
  15647  *     soc_ap_is_port_flex_enable
  15648  * Purpose:
  15649  *     Find out if port_flex_enable{physical port num} config
  15650  *     is present on the given physical port in config.bcm
  15651  * Parameters:
  15652  *     unit    - (IN) Unit number.
  15653  *     phy_port - (IN) physical port num
  15654  * Returns:
  15655  *     TRUE or FALSE
  15656  */
  15657 STATIC int
  15658 soc_ap_is_port_flex_enable(int unit, int phy_port)
  15659 {
  15660     int enable = 0;
  15661 
  15662     /* This property does not apply to cpu port &
  15663      * loopback port
  15664  */
  15665 
  15666     if (phy_port > 0 && phy_port < 129) {
  15667         enable = soc_property_phys_port_get(unit,
  15668                                             phy_port,
  15669                                             spn_PORT_FLEX_ENABLE, 0);
  15670     }
  15671 
  15672     return enable;
  15673 }
  15674 
  15675 
  15676 /* Tells if a port macro (indexed by TSC4, not TSC12) is flex port enabled.
  15677  *  
  15678  * Port macro flex on or off is determined by the first port in that macro. 
  15679  * For TSC12 it's the first port in the first TSC4. For a TSC4 that is NOT 
  15680  * part of a TSC12, it's also the first port of that port macro.  For a TSC4 
  15681  * that is a part of a TSC12, refer to the first port of the first port macro 
  15682  * for that TSC12. 
  15683  *  
  15684  * Parameters:
  15685  *      unit          - (IN) Unit number.
  15686  *      port_macro    - (IN) port macro desired
  15687  *      flex_enabled  - (OUT) whether the port macro is enabled or disabled
  15688  *  
  15689  *  Returns: 
  15690  *      SOC_E_xxx
  15691  */
  15692 int
  15693 soc_ap_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled)
  15694 {
  15695     int port_num = -1;
  15696 
  15697     if ((port_macro < 0) || (port_macro > 18)) {
  15698         return SOC_E_PARAM;
  15699     }
  15700 
  15701     port_num = (APACHE_PORTS_PER_TSC * port_macro) + 1;
  15702 
  15703     *flex_enabled = soc_ap_is_port_flex_enable(unit, port_num);
  15704 
  15705     return SOC_E_NONE;
  15706 }
  15707 
  15708 
  15709 /*
  15710 * Function:
  15711 *     soc_apache_port_icc_width_set
  15712 * Purpose:
  15713 *     Program PORT_INITIAL_COPY_COUNT_WIDTHr
  15714 * Parameters:
  15715 *     unit    - (IN) Unit number.
  15716 *     port    - (IN) Logical SOC port number.
  15717 * Returns:
  15718 *     SOC_E_XXX
  15719  */
  15720 STATIC int
  15721 soc_apache_port_icc_width_set(int unit, soc_port_t port)
  15722 {
  15723     int count_width = 0;
  15724 
  15725     if (SOC_INFO(unit).port_speed_max[port] < 25000) {
  15726         count_width = 1; /* 1 ICC bit  */
  15727     } else if (SOC_INFO(unit).port_speed_max[port] <= 53000) {
  15728         count_width = 2; /* 2 ICC bits  */
  15729     } else {
  15730         count_width = 3; /* 3 ICC bits  */
  15731     }
  15732 
  15733     SOC_IF_ERROR_RETURN(
  15734         soc_reg_field32_modify(unit, PORT_INITIAL_COPY_COUNT_WIDTHr,
  15735             port, BIT_WIDTHf, count_width ? (count_width - 1) : 0));
  15736 
  15737     return SOC_E_NONE;
  15738 }
  15739 
  15740 /*
  15741  * Function:
  15742  *     soc_apache_repl_port_agg_map_init
  15743  * Purpose:
  15744  *     Initialize L3MC Port Agg Map.
  15745  * Parameters:
  15746  *     unit    - (IN) Unit number.
  15747  *     port    - (IN) Logical SOC port number.
  15748  * Returns:
  15749  *     SOC_E_xxx
  15750  */
  15751 STATIC int
  15752 soc_apache_repl_port_agg_map_init(int unit, soc_port_t port)
  15753 {
  15754     soc_info_t *si;
  15755     int phy_port, mmu_port;
  15756     uint32 regval;
  15757 
  15758     si = &SOC_INFO(unit);
  15759     phy_port = si->port_l2p_mapping[port];
  15760     mmu_port = si->port_p2m_mapping[phy_port];
  15761 
  15762     /* configure mmu port to repl aggregateId map */
  15763     regval = 0;
  15764     soc_reg_field_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, &regval,
  15765                       L3MC_PORT_AGG_IDf, mmu_port % 74);
  15766     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr,
  15767                 port,0,regval));
  15768 
  15769     return SOC_E_NONE;
  15770 }
  15771 
  15772 /*
  15773 * Function:
  15774 *     soc_apache_ipmc_repl_init
  15775 * Purpose:
  15776 *     Initialize IPMC Replication settings
  15777 * Parameters:
  15778 *     unit    - (IN) Unit number.
  15779 *     port    - (IN) Logical SOC port number.
  15780 * Returns:
  15781 *     SOC_E_XXX
  15782  */
  15783 STATIC int
  15784 soc_apache_ipmc_repl_init(int unit, soc_port_t port)
  15785 {
  15786     /* Program MMU_TOQ_REPL_PORT_AGG_MAP
  15787  */
  15788     SOC_IF_ERROR_RETURN(soc_apache_repl_port_agg_map_init(unit, port));
  15789 
  15790     return SOC_E_NONE;
  15791 }
  15792 
  15793 /*
  15794 * Function:
  15795 * soc_apache_mmu_port_resource_set
  15796 * Purpose:
  15797 * Reconfigure MMU for flexport operation
  15798 * Parameters:
  15799 * unit    - (IN) Unit number.
  15800 * port    - (IN) Logical SOC port number.
  15801 * reset   - (IN) Reset.
  15802 * Returns:
  15803 * SOC_E_XXX
  15804  */
  15805 int soc_apache_mmu_port_resource_set(int unit, soc_port_t port, int speed)
  15806 {
  15807 
  15808     /* Flex port operation not allowed on CPU or loopback port
  15809  */
  15810      if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  15811          return SOC_E_PARAM;
  15812      }
  15813 
  15814     /* Configure all MMU registers for new ports whose setting is
  15815      * based on port speed.
  15816      */
  15817     SOC_IF_ERROR_RETURN(soc_apache_port_speed_update(unit, port, speed));
  15818 
  15819     /* Program PORT_INITIAL_COPY_COUNT_WIDTH
  15820  */
  15821     SOC_IF_ERROR_RETURN(soc_apache_port_icc_width_set(unit, port));
  15822 
  15823     /* Reconfigure IPMC replication
  15824  */
  15825     SOC_IF_ERROR_RETURN(soc_apache_ipmc_repl_init(unit, port));
  15826 
  15827     return SOC_E_NONE;
  15828 }
  15829 
  15830 /*
  15831 * Function:
  15832 *     soc_apache_is_any_port_flex_enable
  15833 * Purpose:
  15834 *     Find out if
  15835 *     port_flex_enable=1 OR
  15836 *     port_flex_enable{physical port num}=1
  15837 *     config is present in config.bcm
  15838 * Parameters:
  15839 *     unit    - (IN) Unit number.
  15840 * Returns:
  15841 *     TRUE or FALSE
  15842 *     If such a config is present, this function
  15843 *     returns 1 - implying that flex is enable on
  15844 *     at least 1 port (port macro) in the system
  15845 *     This function returns 0, if flex is not enabled
  15846 *     on any port (port macro) in the system
  15847  */
  15848 int soc_apache_is_any_port_flex_enable(int unit)
  15849 {
  15850     int phy_port, num_phy_port;
  15851 
  15852     num_phy_port = 72;
  15853 
  15854     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
  15855         if (soc_property_phys_port_get(unit,
  15856                                        phy_port,
  15857                                        spn_PORT_FLEX_ENABLE, 0)) {
  15858             return TRUE;
  15859         }
  15860     }
  15861 
  15862     return FALSE;
  15863 }
  15864 
  15865 #if defined(SER_TR_TEST_SUPPORT)
  15866 
  15867 #define MAX_HW_TCAMS 32
  15868 typedef struct ser_apache_skipped_mem_s {
  15869     soc_mem_t mem;
  15870     soc_acc_type_t acc_type;
  15871 } ser_apache_skipped_mem_t;
  15872 
  15873 const ser_apache_skipped_mem_t apache_skipped_mems[] = {
  15874     /* Below memories have only one entry */
  15875     {L2_BULK_MATCH_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15876     {L2_BULK_MATCH_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  15877     {L2_BULK_REPLACE_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15878     {L2_BULK_REPLACE_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  15879     {L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY},
  15880     {MPLS_ENTROPY_LABEL_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15881 
  15882     {OAM_LM_COUNTERSm, _SOC_ACC_TYPE_PIPE_ANY},
  15883     {LMEPm, _SOC_ACC_TYPE_PIPE_ANY},
  15884     {LMEP_DAm, _SOC_ACC_TYPE_PIPE_ANY},
  15885     {MAID_REDUCTIONm, _SOC_ACC_TYPE_PIPE_ANY},
  15886     {MA_INDEXm, _SOC_ACC_TYPE_PIPE_ANY},
  15887     {MA_STATEm, _SOC_ACC_TYPE_PIPE_ANY},
  15888     {RMEPm, _SOC_ACC_TYPE_PIPE_ANY},
  15889     {ING_SNAT_ONLYm, _SOC_ACC_TYPE_PIPE_ANY},
  15890 
  15891     /* FP_GLOBAL_MASK_TCAM and FP_GM_FILEDSm have special handling in memscan
  15892      * since H/W space is shared between these two mems.
  15893      * It is protected by SW memscan SER engine
  15894      */
  15895     {FP_GLOBAL_MASK_TCAMm, _SOC_ACC_TYPE_PIPE_ANY},
  15896     {INVALIDm}
  15897 };
  15898 
  15899 int
  15900 ser_test_apache_mem_index_remap(int unit, ser_test_data_t *test_data,
  15901                                   int *mem_has_ecc)
  15902 {
  15903     int uft_bkt_bank = 0;
  15904     int num_uft_banks = 0;
  15905     int uft_le_fv = 0;
  15906     int uft_le_ecc = 0;
  15907     int remap_status = 0;
  15908 
  15909     *mem_has_ecc = 0;
  15910     test_data->mem = test_data->mem_fv;
  15911     test_data->index = test_data->index_fv;
  15912 
  15913     num_uft_banks = soc_apache_get_alpm_banks(unit);
  15914     switch (test_data->mem_fv) {
  15915     case VLAN_XLATEm:
  15916     case VLAN_MACm:
  15917         test_data->mem = VLAN_XLATE_ECCm;
  15918         *mem_has_ecc = 1;
  15919         break;
  15920     case EGR_VLAN_XLATEm:
  15921         test_data->mem = EGR_VLAN_XLATE_ECCm;
  15922         *mem_has_ecc = 1;
  15923         break;
  15924     case L2Xm:
  15925     case L2_ENTRY_ONLYm:
  15926         test_data->mem = L2_ENTRY_ONLY_ECCm;
  15927         *mem_has_ecc = 1;
  15928         break;
  15929     case L3_ENTRY_ONLYm:
  15930     case L3_ENTRY_IPV4_UNICASTm:
  15931         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15932         test_data->index = test_data->index_fv;
  15933         *mem_has_ecc = 1;
  15934         break;
  15935     case L3_ENTRY_IPV4_MULTICASTm:
  15936     case L3_ENTRY_IPV6_UNICASTm:
  15937         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15938         test_data->index = test_data->index_fv*2;
  15939         *mem_has_ecc = 1;
  15940         break;
  15941     case L3_ENTRY_IPV6_MULTICASTm:
  15942         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15943         test_data->index = test_data->index_fv*4;
  15944         *mem_has_ecc = 1;
  15945         break;
  15946     case L3_DEFIP_ALPM_IPV4m: /* 6:4 */
  15947         *mem_has_ecc = 1;
  15948         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15949         uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks);
  15950         uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks);
  15951         switch (uft_le_fv) {
  15952         case 0: uft_le_ecc = 0; break;
  15953         case 1: uft_le_ecc = 0; break; /* or 1 */
  15954         case 2: uft_le_ecc = 1; break;
  15955         case 3: uft_le_ecc = 2; break;
  15956         case 4: uft_le_ecc = 2; break; /* or 3 */
  15957         case 5: uft_le_ecc = 3; break;
  15958         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15959         }
  15960         test_data->index = (uft_le_ecc <<
  15961             _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15962         break;
  15963     case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */
  15964     case L3_DEFIP_ALPM_IPV6_64m:
  15965         *mem_has_ecc = 1;
  15966         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15967         test_data->index = test_data->index_fv;
  15968         break;
  15969     case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */
  15970         *mem_has_ecc = 1;
  15971         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15972             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks);
  15973             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks);
  15974         switch (uft_le_fv) {
  15975         case 0: uft_le_ecc = 0; break; /* or 1 */
  15976         case 1: uft_le_ecc = 1; break; /* or 2 */
  15977         case 2: uft_le_ecc = 2; break; /* or 3 */
  15978         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15979         }
  15980         test_data->index = (uft_le_ecc <<
  15981             _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15982         break;
  15983     case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */
  15984         *mem_has_ecc = 1;
  15985         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15986             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks);
  15987             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks);
  15988         switch (uft_le_fv) {
  15989         case 0: uft_le_ecc = 0; break; /* or 1 */
  15990         case 1: uft_le_ecc = 2; break; /* or 3 */
  15991         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15992         }
  15993         test_data->index = (uft_le_ecc <<
  15994             _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15995         break;
  15996     case L3_DEFIP_ALPM_RAWm: /* 1:4 */
  15997         *mem_has_ecc = 1;
  15998         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15999             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_AP_ALPM_MASK(num_uft_banks);
  16000             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks);
  16001         switch (uft_le_fv) {
  16002         case 0: uft_le_ecc = 0; break; /* or 1,2,3 */
  16003         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  16004         }
  16005         test_data->index = (uft_le_ecc <<
  16006             _SER_TEST_MEM_AP_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  16007         break;
  16008     default:
  16009         test_data->mem = test_data->mem_fv;
  16010         test_data->index = test_data->index_fv;
  16011         break;
  16012     }
  16013     if ((test_data->mem != test_data->mem_fv) ||
  16014         (test_data->index != test_data->index_fv)) {
  16015         LOG_VERBOSE(BSL_LS_SOC_SER,
  16016             (BSL_META_U(unit,
  16017                         "unit %d, ser_test_mem_index_remap: "
  16018                         "mem_fv %s, index_fv %0d, mem %s, index %0d, "
  16019                         "uft_bkt_bank %0d, uft_le_fv %0d, "
  16020                         "uft_le_ecc %0d, remap_status %0d \n"),
  16021              unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv,
  16022              SOC_MEM_NAME(unit, test_data->mem), test_data->index,
  16023              uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status));
  16024     }
  16025     return remap_status;
  16026 }
  16027 
  16028 int
  16029 soc_apache_mem_is_eligible_for_scan(int unit, soc_mem_t mem)
  16030 {
  16031     switch (mem) {
  16032         case L3_DEFIP_ALPM_ECCm:
  16033         case L2_ENTRY_LPm:
  16034         case L3_ENTRY_LPm:
  16035         case VLAN_XLATE_LPm:
  16036         case EGR_VLAN_XLATE_LPm:
  16037         case L2_ENTRY_ISS_LPm:
  16038         case L3_ENTRY_ISS_LPm:
  16039         return 1;
  16040         
  16041         default:
  16042         break;
  16043     }
  16044     return 0;
  16045 }
  16046 
  16047 int
  16048 soc_apache_ser_test_skip_check (int unit, soc_mem_t mem)
  16049 {
  16050     int i;
  16051 
  16052     if (!SOC_MEM_IS_VALID(unit, mem) ||
  16053         ((mem != INVALIDm) &&
  16054          ((SOC_MEM_INFO(unit, mem).flags &
  16055            SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) {
  16056         return 1;
  16057     }
  16058 
  16059     if (soc_mem_index_count(unit, mem) <= 0) {
  16060         return 1;
  16061     }
  16062 
  16063     for (i = 0; apache_skipped_mems[i].mem != INVALIDm; i++) {
  16064         if (apache_skipped_mems[i].mem == mem) {
  16065             return 1;
  16066         }
  16067     }
  16068     if (!(SOC_MEM_INFO(unit, mem).flags & SOC_MEM_SER_FLAGS)) {
  16069         return 1;
  16070     }
  16071     /* Skip the memory if the relevant feature and memory is disabled. */
  16072     if (!soc_feature(unit, soc_feature_l3)
  16073         || !soc_feature(unit, soc_feature_lpm_tcam) ) {
  16074         /* Skip L3_DEFIP memorys */
  16075         if ((L3_DEFIPm == mem) || (L3_DEFIP_PAIR_128m == mem)) return 1;
  16076     }
  16077     if (!soc_feature(unit, soc_feature_l3) ||
  16078         soc_feature(unit, soc_feature_no_tunnel)) {
  16079         /* Skip ING L3 Tunnel memorys */
  16080         if ((L3_TUNNELm == mem) || (L3_TUNNEL_DATA_ONLYm == mem)) return 1;
  16081     }
  16082     if (!soc_feature(unit, soc_feature_nat)) {
  16083         /* Skip NAT  memorys */
  16084         if (ING_SNATm == mem) return 1;
  16085     }
  16086     
  16087     /* Skip MPLS memories */
  16088 
  16089     if (ING_MPLS_EXP_MAPPINGm == mem) {
  16090         return 1;
  16091     }
  16092 
  16093     return 0;
  16094 }
  16095 
  16096 STATIC 
  16097 soc_error_t
  16098 _soc_apache_tcam_ser_mem_info_get (int unit, soc_mem_t mem, int *index_p)
  16099 {
  16100     int i;
  16101     _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit];
  16102     
  16103     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  16104         if (tcams[i].mem == mem) {
  16105             *index_p = i;
  16106             return SOC_E_NONE;
  16107         }
  16108     }
  16109     return SOC_E_NOT_FOUND;
  16110 }
  16111 
  16112 STATIC soc_error_t
  16113 _soc_apache_ser_mem_info_get (int unit, soc_mem_t mem, _soc_mem_ser_en_info_t** ser_mem_info)
  16114 {
  16115 #if defined(BCM_56560_A0)
  16116     int i, j;
  16117     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  16118 
  16119     for (i = 0; _soc_apache_ser_block_info[i].blocktype != 0; i++) {
  16120         if ((_soc_apache_ser_block_info[i].type == _SOC_APACHE_SER_TYPE_MEM) &&
  16121             ((_soc_apache_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  16122              (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  16123              (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  16124             ser_en_info = _soc_apache_ser_block_info[i].info;
  16125             for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  16126                 if (ser_en_info[j].mem == mem) {
  16127                     *ser_mem_info = &ser_en_info[j];
  16128                     return SOC_E_NONE;
  16129                 }
  16130             }
  16131         }
  16132     }
  16133 #endif
  16134     return SOC_E_NOT_FOUND;
  16135 }
  16136 /*
  16137  * Function:
  16138  *      soc_apache_ser_error_injection_support
  16139  * Purpose:
  16140  *      Checks if a memory is supported by error injection interface
  16141  *
  16142  * Parameters:
  16143  *      unit        - (IN) Device Number
  16144  *      memory      - (IN) Test data required for SER test
  16145  *      pipe        - (IN) How many indices to test for each memory
  16146  *
  16147  * Returns:
  16148  *  SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported
  16149  */
  16150 soc_error_t
  16151 soc_apache_ser_error_injection_support (int unit, soc_mem_t mem,
  16152                                         int pipe)
  16153 {
  16154     int        rv = SOC_E_UNAVAIL;
  16155     _soc_mem_ser_en_info_t *ser_mem_info = NULL;
  16156     int        tcam_idx = 0;
  16157 
  16158     if (soc_apache_ser_test_skip_check (unit,mem)) {
  16159         return rv;
  16160     }
  16161 
  16162     rv = _soc_apache_ser_mem_info_get(unit, mem, &ser_mem_info);
  16163     if (rv == SOC_E_NONE) {
  16164         return rv;
  16165     }
  16166     
  16167     rv = _soc_apache_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  16168     if (rv == SOC_E_NONE) {
  16169         return rv;
  16170     }
  16171     
  16172     return rv;
  16173 }
  16174 
  16175 /*
  16176  * Function:
  16177  *      _soc_apache_perform_ser_test
  16178  * Purpose:
  16179  *      Performs test operations common to TCAM and FIFO memory tests before
  16180  *      invoking common SER test.
  16181  * Parameters:
  16182  *      unit        - (IN) Device Number
  16183  *      test_data   - (IN) Test data required for SER test
  16184  *      test_type   - (IN) How many indices to test for each memory
  16185  *      mem_failed  - (OUT) Incremented when memories fail the test.
  16186  * Returns:
  16187  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  16188  *      possible.)
  16189  */
  16190 soc_error_t
  16191 _soc_apache_perform_ser_test (int unit, ser_test_data_t *test_data,
  16192                               _soc_ser_test_t test_type,
  16193                               int *mem_skipped, int *mem_failed)
  16194 {
  16195     int skip_mem = FALSE;
  16196     soc_error_t rv = SOC_E_NONE;
  16197     uint32 flags = 0;
  16198 
  16199     if (soc_apache_ser_test_skip_check (unit,test_data->mem)) {
  16200         skip_mem = TRUE;
  16201     }
  16202 
  16203     if (!skip_mem) {
  16204          if (test_data->mem == ING_VLAN_VFI_MEMBERSHIPm ||
  16205              test_data->mem == MMU_MTRO_S1_MEM_0m ||
  16206              test_data->mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_0m ||
  16207              test_data->mem == MMU_MTRO_EGRMETERINGCONFIG_MEM_0m) {
  16208              flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16209         }
  16210         rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed);
  16211     } else {
  16212         LOG_VERBOSE(BSL_LS_SOC_COMMON,
  16213                     (BSL_META_U(unit,
  16214                                 "Memory %s skipped due to known issues.\n"),
  16215                      SOC_MEM_NAME(unit,test_data->mem)));
  16216         (*mem_skipped)++;
  16217     }
  16218 
  16219     return rv;
  16220 }
  16221 
  16222 /*
  16223  * Function:
  16224  *      soc_apache_ser_tcam_test
  16225  * Purpose:
  16226  *      Tests that SER is working for fifo and SRAM memories
  16227  * Parameters:
  16228  *      unit        - (IN) Device Number
  16229  *      test_type   - (IN) How many indices to test for each memory
  16230  * Returns:
  16231  *  the number of tests which are failed
  16232  */
  16233 int
  16234 soc_apache_ser_tcam_test (int unit, _soc_ser_test_t test_type) {
  16235     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  16236     ser_test_data_t test_data;
  16237     int mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  16238     _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit];
  16239     int i, rv;
  16240     soc_acc_type_t acc_type;
  16241     soc_field_t    test_field = VALIDf;
  16242 
  16243     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  16244         mem_tests++;
  16245         if ( i >= MAX_HW_TCAMS) {
  16246             mem_skipped++;
  16247             LOG_VERBOSE(BSL_LS_SOC_COMMON,
  16248                         (BSL_META_U(unit,
  16249                                     "Memory %s skipped due to lack of test mechanism \
  16250                                     for Software-protected TCAMS.\n"),
  16251                          SOC_MEM_NAME(unit,test_data.mem)));
  16252             continue;
  16253         }
  16254 
  16255         acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16256 
  16257         if (tcams[i].mem == L3_DEFIPm) {
  16258             test_field = VALID0f;
  16259         } else if (tcams[i].mem == L3_DEFIP_PAIR_128m) {
  16260             test_field = VALID0_LWRf;
  16261         } else {
  16262             test_field = VALIDf;
  16263         }
  16264 
  16265         soc_ser_create_test_data(unit, tmp_entry, fieldData, SER_RANGE_ENABLEr,
  16266                                  i, INVALIDf, tcams[i].mem, test_field,
  16267                                  MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0,
  16268                                  &test_data);
  16269 
  16270         rv = _soc_apache_perform_ser_test(unit, &test_data, test_type,
  16271                                           &mem_skipped, &mem_failed);
  16272         if (SOC_FAILURE(rv)) {
  16273             LOG_CLI((BSL_META_U(unit,
  16274                                 "TCAM SER test fail for mem: \t %s\n\n"),
  16275                                 SOC_MEM_NAME(unit,test_data.mem)));
  16276         }
  16277     }
  16278 
  16279     LOG_CLI((BSL_META_U(unit,
  16280                "\nTCAM memories tested on unit %d: %d\n"), unit, mem_tests));
  16281     LOG_CLI((BSL_META_U(unit,
  16282                "TCAM tests passed:\t%d\n"),
  16283                mem_tests - mem_failed - mem_skipped));
  16284     LOG_CLI((BSL_META_U(unit,
  16285                "TCAM tests skipped:\t%d (use verbose option to see "
  16286                "skipped memories)\n"),
  16287                mem_skipped));
  16288     LOG_CLI((BSL_META_U(unit,
  16289                "TCAM tests failed:\t%d\n\n"), mem_failed));
  16290 
  16291     return mem_failed;
  16292 }
  16293 
  16294 /*
  16295  * Function:
  16296  *      soc_apache_ser_hardware_test
  16297  * Purpose:
  16298  *      Tests that SER is working for fifo and SRAM memories
  16299  * Parameters:
  16300  *      unit        - (IN) Device Number
  16301  *      test_type   - (IN) How many indices to test for each memory
  16302  * Returns:
  16303  *  the number of tests which are failed
  16304  */
  16305 int
  16306 soc_apache_ser_hardware_test (int unit, _soc_ser_test_t test_type) {
  16307 #if defined(BCM_56560_A0)
  16308     ser_test_data_t      test_data;
  16309     int                  mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  16310     int                  i,j,rv;
  16311     soc_acc_type_t       acc_type;
  16312     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  16313     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  16314 
  16315     for (i = 0; _soc_apache_ser_block_info[i].blocktype != 0; i++) {
  16316         if ((_soc_apache_ser_block_info[i].type == _SOC_APACHE_SER_TYPE_MEM) &&
  16317             ((_soc_apache_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  16318              (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  16319              (_soc_apache_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  16320             ser_en_info = _soc_apache_ser_block_info[i].info;
  16321             for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  16322                 mem_tests += 1;
  16323                 test_data.test_field = EVEN_PARITYf;
  16324                 acc_type = -1;
  16325                 soc_ser_create_test_data(unit, tmp_entry, fieldData,
  16326                                          ser_en_info[j].en_ctrl.ctrl_type.en_reg,
  16327                                          SOC_INVALID_TCAM_PARITY_BIT,
  16328                                          ser_en_info[j].en_ctrl.en_fld,
  16329                                          ser_en_info[j].mem,
  16330                                          test_data.test_field, 
  16331                                          MEM_BLOCK_ANY,
  16332                                          REG_PORT_ANY, acc_type, 0, 
  16333                                          &test_data);
  16334                 if ((test_data.mem_info == NULL) || 
  16335                     (!(soc_mem_index_count(unit, ser_en_info[j].mem) > 0))) {
  16336                     mem_skipped++;
  16337                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  16338                                 (BSL_META_U(unit,
  16339                                  "Memory %s skipped due to lack of"
  16340                                  " mem_info structure or being disabled.\n"),
  16341                                  SOC_MEM_NAME(unit,test_data.mem)));
  16342                     continue;
  16343                 }
  16344                 rv = _soc_apache_perform_ser_test(unit, &test_data,
  16345                                                   test_type, &mem_skipped,
  16346                                                   &mem_failed);
  16347                 if (SOC_FAILURE(rv)) {
  16348                     LOG_CLI((BSL_META_U(unit,
  16349                                         "H/W SER test fail for mem: \t %s\n\n"),
  16350                              SOC_MEM_NAME(unit,test_data.mem)));
  16351                 }
  16352             }
  16353         }
  16354     }
  16355 
  16356     LOG_CLI((BSL_META_U(unit,
  16357                "\nH/W memories tested on unit %d: %d\n"), unit, mem_tests));
  16358     LOG_CLI((BSL_META_U(unit,
  16359                "H/W tests passed:\t%d\n"),
  16360                mem_tests - mem_failed - mem_skipped));
  16361     LOG_CLI((BSL_META_U(unit,
  16362                "H/W tests skipped:\t%d (use verbose option to see "
  16363                "skipped memories)\n"),
  16364                mem_skipped));
  16365     LOG_CLI((BSL_META_U(unit,
  16366                "H/W tests failed:\t%d\n\n"), mem_failed));
  16367     return mem_failed;
  16368 #else 
  16369     return SOC_E_NONE;
  16370 #endif  
  16371 
  16372 }
  16373 
  16374 
  16375 /*
  16376  * Function:
  16377  *      soc_apache_ser_test
  16378  * Purpose:
  16379  *      Tests that SER is working for all supported memories.
  16380  * Parameters:
  16381  *      unit        - (IN) Device Number
  16382  *      test_type   - (IN) How many indices to test for each memory
  16383  * Returns:
  16384  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  16385  *      possible.)
  16386  */
  16387 soc_error_t
  16388 soc_apache_ser_test (int unit, _soc_ser_test_t test_type) {
  16389     int errors = 0;
  16390 
  16391     /*Test TCAM memories*/
  16392     errors += soc_apache_ser_tcam_test(unit, test_type);
  16393 
  16394     /*Test for FIFO memories*/
  16395     errors += soc_apache_ser_hardware_test(unit, test_type);
  16396 
  16397     if (errors == 0) {
  16398         return SOC_E_NONE;
  16399     } else {
  16400         return SOC_E_FAIL;
  16401     }
  16402 }
  16403 
  16404 #define TR_MEM_NAME_SIZE_MAX    100
  16405 
  16406 #ifdef SOC_MEM_NAME
  16407 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do {                    \
  16408         const char *_mem_name = SOC_MEM_NAME(_unit_, _mem);             \
  16409         if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) {             \
  16410             sal_strcpy(_msg, _mem_name);                                \
  16411         }                                                               \
  16412     } while (0)
  16413 #else
  16414 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem)
  16415 #endif
  16416 
  16417 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do {                       \
  16418         sal_sprintf(_msg, "Mem ID: %d", _mem);                          \
  16419         TR_TEST_MEM_NAME_GET(_unit, _msg, _mem);                        \
  16420         LOG_CLI((BSL_META_U(_unit,                                      \
  16421                             "Memory %s is valid, but not currently testable.\n"), \
  16422                  _msg));                                                \
  16423     } while (0)
  16424 
  16425 /*
  16426  * Function:
  16427  *      soc_apache_ser_inject_or_test_mem
  16428  * Purpose:
  16429  *      Provide a common function for injecting errors and testing single
  16430  *      single memories
  16431  * Parameters:
  16432  *      unit        - (IN) Device Number
  16433  *      mem         - (IN) The memory into which an error will be injected
  16434  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  16435  *      index       - (IN) The index into which the error will be injected.
  16436  *      test_type   - (IN) How many indices to test in the passes memory
  16437  *      cmd         - (IN) TRUE if a command-line test is desired.
  16438  * Returns:
  16439  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  16440  *      are possible.)
  16441  */
  16442 soc_error_t
  16443 soc_apache_ser_inject_or_test_mem (int unit, soc_mem_t mem, int pipe_target,
  16444                                    int block, int index, 
  16445                                    _soc_ser_test_t test_type,
  16446                                    int inject_only, int cmd, uint32 flags)
  16447 {
  16448     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  16449     ser_test_data_t tcam_test_data, hw_test_data, *test_data;
  16450     int             tcam_idx = 0;
  16451         _soc_generic_ser_info_t *tcams = _soc_apache_tcam_ser_info[unit];
  16452     int error_count = 0, skip_count = 0, found_mem = FALSE;
  16453     char fail_message[400];
  16454     soc_error_t rv = SOC_E_NONE;
  16455     soc_field_t test_field = INVALIDf;
  16456     soc_acc_type_t soc_acc_type_target = _SOC_ACC_TYPE_PIPE_ANY;
  16457     _soc_mem_ser_en_info_t *ser_mem_info = NULL;
  16458     int mem_has_ecc = 0, is_tcam = 0, is_fifo_mem = 0;
  16459 
  16460     /* TCAM test */
  16461     rv = _soc_apache_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  16462     if (rv == SOC_E_NONE) {
  16463         if (tcams[tcam_idx].mem == L3_DEFIPm) {
  16464             test_field = VALID0f;
  16465         } else if (tcams[tcam_idx].mem == L3_DEFIP_PAIR_128m) {
  16466             test_field = VALID0_LWRf;
  16467         } else {
  16468             test_field = VALIDf;
  16469         }
  16470         soc_ser_create_test_data(unit, tmp_entry, fieldData,
  16471                                  SER_RANGE_ENABLEr, tcam_idx, INVALIDf, mem,
  16472                                  test_field, block, REG_PORT_ANY,
  16473                                  soc_acc_type_target, index, &tcam_test_data);
  16474         found_mem = TRUE;
  16475         is_tcam = 1;
  16476     }
  16477 
  16478     /* H/W test */
  16479     rv = _soc_apache_ser_mem_info_get (unit, mem, &ser_mem_info);
  16480     if (rv == SOC_E_NONE) {
  16481         if (mem == ING_L3_NEXT_HOPm) {
  16482             test_field= ECC_1f;
  16483         } else {
  16484             test_field = EVEN_PARITYf;
  16485         }
  16486         soc_ser_create_test_data(unit, tmp_entry, fieldData,
  16487                                  ser_mem_info->en_ctrl.ctrl_type.en_reg,
  16488                                  SOC_INVALID_TCAM_PARITY_BIT,
  16489                                  ser_mem_info->en_ctrl.en_fld,
  16490                                  mem, test_field, block,
  16491                                  REG_PORT_ANY, soc_acc_type_target,
  16492                                  index, &hw_test_data);
  16493         if (SOC_REG_IS_VALID(unit, ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg) &&
  16494                 (INVALIDf != ser_mem_info->ecc1b_ctrl.en_fld)) {
  16495                 flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16496         }
  16497         SOC_IF_ERROR_RETURN
  16498             (ser_test_mem_index_remap(unit, &hw_test_data, &mem_has_ecc));
  16499         if (mem_has_ecc) {
  16500             flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16501         }
  16502         /* ING_VLAN_VFI_MEMBERSHIP is ECC protected, however
  16503          * there is no 1bit error reporting control register for it.
  16504          */
  16505         if (mem == ING_VLAN_VFI_MEMBERSHIPm) {
  16506             flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16507         }
  16508         found_mem = TRUE;
  16509         is_fifo_mem = 1;
  16510     }
  16511 
  16512     if (found_mem) {
  16513         test_data = is_tcam ? &tcam_test_data : &hw_test_data;
  16514         test_data->acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16515         if (inject_only) {
  16516             /* Check if the memory is to be skipped */
  16517             if (soc_apache_ser_test_skip_check(unit,mem)) {
  16518                 TR_TEST_MEM_PRINT(unit, fail_message, mem);
  16519                 return SOC_E_UNAVAIL;
  16520             }
  16521 
  16522             /*Disable parity*/
  16523             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, test_data, 0));
  16524             /*Read the memory (required for successful injection)*/
  16525             SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, test_data));
  16526              /*Inject error*/
  16527             SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags,
  16528                                                          test_data));
  16529             /*Enable parity*/
  16530             rv = _ser_test_parity_control(unit, test_data, 1);
  16531         } else {
  16532             if (cmd) {
  16533                 tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16534                 ser_test_cmd_generate(unit, &tcam_test_data);
  16535                 hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16536                 ser_test_cmd_generate(unit, &hw_test_data);
  16537             } else {
  16538                 if (is_tcam) {
  16539                     tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16540                     rv = _soc_apache_perform_ser_test(unit, &tcam_test_data, test_type,
  16541                                                       &skip_count, &error_count);
  16542                     if (SOC_SUCCESS(rv)) {
  16543                         LOG_CLI((BSL_META_U(unit,
  16544                                 "TCAM SER test PASSED for memory %s\n\n"),
  16545                                 tcam_test_data.mem_name));
  16546                     } else {
  16547                         LOG_CLI((BSL_META_U(unit,
  16548                                 "TCAM SER test FAILED for memory %s\n\n"),
  16549                                 tcam_test_data.mem_name));
  16550                     }
  16551                 }
  16552 
  16553                 if (is_fifo_mem) {
  16554                     hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16555                     rv = _soc_apache_perform_ser_test(unit, &hw_test_data, test_type,
  16556                                                       &skip_count, &error_count);
  16557                     if (SOC_SUCCESS(rv)) {
  16558                         LOG_CLI((BSL_META_U(unit,
  16559                                 "H/W SER test PASSED for memory %s\n\n"),
  16560                                 hw_test_data.mem_name));
  16561                     } else {
  16562                         LOG_CLI((BSL_META_U(unit,
  16563                                 "H/W SER test FAILED for memory %s\n\n"),
  16564                                 hw_test_data.mem_name));
  16565                     }
  16566                 }
  16567 
  16568                 if (skip_count != 0 ) {
  16569                     LOG_CLI((BSL_META_U(unit,
  16570                                "Test skipped due to known issues with "
  16571                                "this memory.\n")));
  16572                 }
  16573             }
  16574         }
  16575     } else {
  16576         TR_TEST_MEM_PRINT(unit, fail_message, mem);
  16577         rv = SOC_E_UNAVAIL;
  16578     }
  16579     return rv;
  16580 }
  16581 #undef TR_TEST_MEM_PRINT
  16582 
  16583 /*
  16584  * Function:
  16585  *      soc_apache_ser_inject_error
  16586  * Purpose:
  16587  *      Injects an error into a single apache memory
  16588  * Parameters:
  16589  *      unit        - (IN) Device Number
  16590  *      mem         - (IN) The memory into which an error will be injected
  16591  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  16592  *      index       - (IN) The index into which the error will be injected.
  16593  */
  16594 soc_error_t
  16595 soc_apache_ser_inject_error (int unit, uint32 flags, soc_mem_t mem,
  16596                              int pipe_target, int block, int index)
  16597 {
  16598     /* Check if memory needs to be skipped */
  16599     if (ser_apache_test_fun.injection_support) {
  16600         SOC_IF_ERROR_RETURN(
  16601             soc_apache_ser_error_injection_support(unit, mem, pipe_target));
  16602     }
  16603 
  16604     return soc_apache_ser_inject_or_test_mem(unit, mem, pipe_target, block,
  16605                                              index, SER_SINGLE_INDEX, TRUE,
  16606                                              FALSE, flags);
  16607 }
  16608 
  16609 /*
  16610  * Function:
  16611  *      soc_apache_ser_test_mem
  16612  * Purpose:
  16613  *      Perform SER test on a single memory, or generate a test the user can
  16614  *      enter by the command line.
  16615  * Parameters:
  16616  *      unit        - (IN) Device Number
  16617  *      mem         - (IN) The memory into which an error will be injected
  16618  *      test_type   - (IN) How many indices to test in the passes memory
  16619  *      cmd         - (IN) TRUE if a command-line test is desired.
  16620  * Returns:
  16621  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  16622  *      are possible.)
  16623  */
  16624 soc_error_t
  16625 soc_apache_ser_test_mem (int unit, soc_mem_t mem, _soc_ser_test_t test_type,
  16626                         int cmd)
  16627 {
  16628     return soc_apache_ser_inject_or_test_mem (unit, mem, _SOC_ACC_TYPE_PIPE_ANY,
  16629                                               MEM_BLOCK_ANY, 0,
  16630                                               test_type, FALSE, cmd, FALSE);
  16631 }
  16632 #endif /*defined(SER_TR_TEST_SUPPORT)*/
  16633 
  16634 /*
  16635  * Apache chip driver functions.
  16636  */
  16637 soc_functions_t soc_apache_drv_funs = {
  16638     _soc_apache_misc_init,
  16639     _soc_apache_mmu_init,
  16640     _soc_apache_age_timer_get,
  16641     _soc_apache_age_timer_max_get,
  16642     _soc_apache_age_timer_set,
  16643     NULL,
  16644     _soc_apache_mdio_reg_read,
  16645     _soc_apache_mdio_reg_write,
  16646     soc_apache_bond_info_init,
  16647     _soc_apache_misc_deinit
  16648 };
  16649 
  16650 #endif /* BCM_APACHE_SUPPORT */
  16651