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

monterey.c (649746B)


      1 /*
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  *
      6  * File:        monterey.c
      7  * Purpose:
      8  * Requires:
      9  */
     10 
     11 #include <shared/bsl.h>
     12 
     13 #include <sal/core/boot.h>
     14 #include <soc/bradley.h>
     15 #include <soc/drv.h>
     16 #include <soc/error.h>
     17 #include <soc/debug.h>
     18 #include <soc/mem.h>
     19 #include <soc/monterey.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_MONTEREY_SUPPORT
     29 
     30 #ifdef ALPM_ENABLE
     31 #include <soc/lpm.h>
     32 #include <soc/alpm.h>
     33 #include <soc/esw/alpm_int.h>
     34 #endif /* ALPM_ENABLE */
     35 
     36 #include <soc/mmu_config.h>
     37 #include <soc/post.h>
     38 
     39 #include <soc/esw/portctrl.h>
     40 #include <soc/bondoptions.h>
     41 
     42 #ifdef PORTMOD_SUPPORT
     43 #include <soc/portmod/portmod.h>
     44 #endif /*  PORTMOD_SUPPORT */
     45 #ifdef CPRIMOD_SUPPORT
     46 #include <soc/cprimod/cprimod.h>
     47 #include <shared/cpri.h>
     48 #endif /* CPRIMOD_SUPPORT */
     49 #ifdef INCLUDE_XFLOW_MACSEC
     50 #include <bcm_int/common/xflow_macsec_cmn.h>
     51 #endif
     52 
     53 #include <soc/iproc.h>
     54 #include <bcm/pkt.h>
     55 #include <bcm/tx.h>
     56 
     57 #define _MONTEREY_BYTES_PER_OBM_CELL    16
     58 #define _MONTEREY_CELLS_PER_OBM         1020
     59 
     60 #define _MONTEREY_LOG_PORTS_PER_PIPE    67 
     61 #define _MONTEREY_MMU_PORTS_PER_PIPE    67 
     62 #define _SOC_MONTEREY_MAX_PORT          (_MONTEREY_LOG_PORTS_PER_PIPE)
     63 
     64 #define _MONTEREY_MMU_PACKET_HEADER_BYTES 64    /* bytes */
     65 #define _MONTEREY_MMU_JUMBO_FRAME_BYTES   9216  /* bytes */
     66 #define _MONTEREY_MMU_DEFAULT_MTU_BYTES   1536  /* bytes */
     67 
     68 #define _MONTEREY_MMU_BYTES_PER_CELL      208   /* bytes (1664 bits) */
     69 #define _MONTEREY_MMU_NUM_PG              8
     70 #define _MONTEREY_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE 50
     71 #define _MONTEREY_MMU_PG_MIN              8
     72 
     73 #define SOC_MONTEREY_MMU_CFG_QGROUP_MAX   128
     74 
     75 #define SOC_MONTEREY_MMU_MCQ_ENTRY        12288 
     76 #define SOC_MONTEREY_MMU_RQE_ENTRY        1024 
     77 
     78 #define _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit)  SOC_MONTEREY_MMU_MCQ_ENTRY
     79 
     80 #define _MONTEREY_MMU_TOTAL_RQE_ENTRY(unit)  SOC_MONTEREY_MMU_RQE_ENTRY
     81 
     82 #define _SOC_MONTEREY_DEFIP_MAX_TCAMS   8
     83 #define _SOC_MONTEREY_DEFIP_TCAM_DEPTH  64
     84 
     85 #define IS_OVERSUB_PORT(unit,port)           \
     86         (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))
     87 
     88 #define INVALID_PORT  -1
     89 
     90 /* defines for Reserved Buffer for Flex Port Macro when new Flex Port is
     91    enabled */
     92 /* lossless defines */
     93 #define _MN_RSVD_BUF_10G_FLEX_HDRM_LOSSLESS 185 
     94 #define _MN_RSVD_BUF_25G_FLEX_HDRM_LOSSLESS  214  
     95 
     96 #define _MN_RSVD_BUF_FLEX_QGRP 16
     97 #define _MN_RSVD_BUF_10G_FLEX_ASF 4
     98 #define _MN_RSVD_BUF_25G_FLEX_ASF 16
     99 
    100 /* defines for Reserved Buffer for Ports when Flex Port for the macro is NOT
    101    enabled*/
    102 #define _MN_RSVD_BUF_NON_FLEX_OB_100G_HDRM_LOSSLESS 687 
    103 #define _MN_RSVD_BUF_NON_FLEX_100G_HDRM_LOSSLESS  558 
    104 #define _MN_RSVD_BUF_NON_FLEX_OB_50G_HDRM_LOSSLESS  352  
    105 #define _MN_RSVD_BUF_NON_FLEX_50G_HDRM_LOSSLESS   298 
    106 #define _MN_RSVD_BUF_NON_FLEX_OB_40G_HDRM_LOSSLESS  338  
    107 #define _MN_RSVD_BUF_NON_FLEX_40G_HDRM_LOSSLESS  284  
    108 #define _MN_RSVD_BUF_NON_FLEX_OB_25G_HDRM_LOSSLESS  214 
    109 #define _MN_RSVD_BUF_NON_FLEX_25G_HDRM_LOSSLESS  191 
    110 #define _MN_RSVD_BUF_NON_FLEX_OB_20G_HDRM_LOSSLESS  206 
    111 #define _MN_RSVD_BUF_NON_FLEX_20G_HDRM_LOSSLESS  183 
    112 #define _MN_RSVD_BUF_NON_FLEX_OB_10G_HDRM_LOSSLESS  185  
    113 #define _MN_RSVD_BUF_NON_FLEX_10G_HDRM_LOSSLESS  162 
    114 #define _MN_MMU_RSVD_BUF_FLEX_PGMIN_LOSSLESS 8
    115 #define _MN_RSVD_BUF_NON_FLEX_PGMIN 8
    116 #define _MN_RSVD_BUF_NON_FLEX_QGRP 16
    117 #define _MN_RSVD_BUF_NON_FLEX_ASF 16
    118 #define _MN_RSVD_BUF_NON_FLEX_10G_ASF 4
    119 /* mmu_mc_egr_qentry_min in Settings sheet */
    120 #define _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD 6 
    121 #define _MN_RSVD_BUF_10G_FLEX_QGRP 16 
    122 #define _MN_MMU_NUM_MCQ_PORT_MACRO 10
    123 #define _MN_MMU_RDB_PORT_MIN 90 
    124 
    125 #define _MN_MMU_EXPRESS_BUFFER_TOTAL_1 11550 
    126 #define _MN_MMU_EXPRESS_BUFFER_TOTAL_2 12170 
    127 
    128 /*
    129  * TDM algo does not support all speeds. SDK needs to adjust
    130  * the speeds to  what is supported in the algorithm.
    131  *
    132  * Anything < 1G will be passed as 1G.
    133  * 5G needs to be passed as 10G.
    134  * 2.5G is supported in the TDM. We can pass as is.
    135  */
    136 #define MONTEREY_TDM_SPEED_ADJUST(unit, port, speed)          \
    137     do {                                                    \
    138         speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);     \
    139         if ((speed > 0) && (speed < 10000)) {               \
    140             if (IS_OVERSUB_PORT(unit, port)) {              \
    141                 speed = 10000;                              \
    142             } else if (speed < 1000) {                      \
    143                 speed = 1000;                               \
    144             } else if (speed == 5000) {                     \
    145                 speed = 10000;                              \
    146             }                                               \
    147         }                                                   \
    148     } while (0)
    149 int soc_monterey_is_any_port_flex_enable(int unit);
    150 int soc_mn_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled);
    151 int
    152 bcmi_mn_preemption_capability_get(int unit, bcm_port_t port,
    153                                     uint32* arg);
    154 
    155 typedef enum {
    156     _SOC_PARITY_TYPE_NONE,
    157     _SOC_PARITY_TYPE_GENERIC,
    158     _SOC_PARITY_TYPE_PARITY,
    159     _SOC_PARITY_TYPE_ECC,
    160     _SOC_PARITY_TYPE_MMU_SER,
    161     _SOC_PARITY_TYPE_START_ERR,
    162     _SOC_PARITY_TYPE_SER,
    163     _SOC_PARITY_TYPE_BST,
    164     _SOC_PARITY_TYPE_MAC_RX_CDC,
    165     _SOC_PARITY_TYPE_MAC_TX_CDC,
    166     _SOC_PARITY_TYPE_MAC_RX_TS,
    167     _SOC_PARITY_TYPE_MIB, 
    168     _SOC_PARITY_TYPE_OBM
    169 #ifdef INCLUDE_XFLOW_MACSEC
    170     ,_SOC_PARITY_TYPE_MACSEC_SER,
    171     _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL
    172 #endif
    173 } _soc_monterey_ser_info_type_t;
    174 
    175 typedef struct _soc_monterey_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_monterey_fifo_ser_info_t;
    184 
    185 typedef struct _soc_monterey_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_monterey_ser_block_info_t;
    192 
    193 typedef struct _soc_monterey_ser_reg_s {
    194     soc_reg_t reg;
    195     char      *mem_str;
    196 } _soc_monterey_ser_reg_t;
    197 
    198 typedef struct _soc_monterey_ser_info_s {
    199     _soc_monterey_ser_info_type_t   type;
    200     struct _soc_monterey_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_monterey_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_monterey_ser_info_t;
    214 
    215 typedef struct _soc_monterey_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_monterey_ser_info_t *info;
    222     uint8               id;
    223 } _soc_monterey_ser_route_block_t;
    224 
    225 typedef struct _soc_monterey_intr_info_s {
    226     _soc_monterey_ser_info_type_t   type;
    227     struct _soc_monterey_ser_info_s *info;
    228     int                        id;
    229     soc_field_t                group_reg_enable_field;
    230     soc_field_t                group_reg_status_field;
    231     soc_mem_t                  mem;
    232     char                      *mem_str;
    233     soc_reg_t                  enable_reg;
    234     soc_field_t                enable_field;
    235     soc_reg_t                  intr_status_reg;
    236     _soc_monterey_ser_reg_t     *intr_status_reg_list;
    237     soc_reg_t                  intr_clr_reg;
    238     soc_field_t                intr_clr_field;
    239     soc_field_t               *intr_clr_field_list;
    240 } _soc_monterey_intr_info_t;
    241                                                                                 
    242 typedef struct _soc_monterey_intr_route_block_s {
    243     uint32                    cmic_bit;
    244     soc_block_t               blocktype;
    245     soc_reg_t                 enable_reg;
    246     soc_reg_t                 status_reg;
    247     soc_field_t               enable_field;
    248     _soc_monterey_intr_info_t *info;
    249     uint8                     id;
    250 } _soc_monterey_pm_cpri_intr_info_t;
    251 
    252 typedef struct _soc_monterey_pm_ecc_info_s {
    253     _soc_monterey_ser_info_type_t   type;
    254     _shr_cpri_ecc_err_type_t ecc_err_type; /* 1-bit, 2-bit, multi-bit */
    255     int                      port;
    256     soc_mem_t                mem;
    257     uint32                   mem_index;
    258     char                     *mem_str;
    259 } _soc_monterey_pm_ecc_info_t;
    260 
    261 typedef struct _soc_monterey_mmu_traffic_ctrl_s {
    262     uint8   thdo_drop_bmp[_SOC_MONTEREY_MAX_PORT];
    263 } _soc_monterey_mmu_traffic_ctrl_t;
    264 
    265 typedef struct _soc_mn_mmu_buffer_config_s {
    266     int total_physical_memory;
    267     int cfapfullsetpoint;
    268     int total_cell_memory;
    269     int num_mem_banks;
    270     int num_10g_ports;
    271     int num_20g_ports;
    272     int num_40g_ports;
    273     int num_100g_ports;
    274     int num_ovsb_10g_ports;
    275     int num_ovsb_20g_ports;
    276     int num_ovsb_40g_ports;
    277     int num_ovsb_100g_ports;
    278 } _soc_mn_mmu_buffer_config_t;
    279 
    280 #define _MN_NUM_SKEWS   1 
    281 STATIC _soc_mn_mmu_buffer_config_t soc_mn_buffer_config[_MN_NUM_SKEWS] = {
    282     { 24576, 20416, 20416, 6, 64, 0, 0, 0, 64, 0, 0, 0 }
    283 };
    284 STATIC int _soc_mn_skew_index;
    285 
    286 #define _MONTEREY_MMU_PHYSICAL_CELLS                                     \
    287         soc_mn_buffer_config[_soc_mn_skew_index].total_physical_memory
    288 
    289 #define _MONTEREY_CFAPFULLSETPOINT                                    \
    290         soc_mn_buffer_config[_soc_mn_skew_index].cfapfullsetpoint
    291 #define _MONTEREY_MMU_RSVD_CELLS_CFAP                                 \
    292         soc_mn_buffer_config[_soc_mn_skew_index].num_mem_banks *    \
    293                             (23 + 2 + 10)
    294 
    295 #define _MONTEREY_MMU_TOTAL_CELLS                                     \
    296         soc_mn_buffer_config[_soc_mn_skew_index].total_cell_memory
    297 
    298 #define   MAC_ENABLE_SET_CTRL          (1 << 0)
    299 #define   MMU_TRAFFIC_EN_CTRL          (1 << 1)
    300 #define   COSQ_SCHED_SET_CTRL          (1 << 2) 
    301 static    _soc_monterey_mmu_traffic_ctrl_t
    302               *_soc_monterey_mmu_traffic_ctrl[SOC_MAX_NUM_DEVICES];
    303 static    sal_mutex_t _fwd_ctrl_lock[SOC_MAX_NUM_DEVICES];
    304 #define   FWD_CTRL_LOCK(unit) \
    305           sal_mutex_take(_fwd_ctrl_lock[unit], sal_mutex_FOREVER)
    306 #define   FWD_CTRL_UNLOCK(unit) \
    307           sal_mutex_give(_fwd_ctrl_lock[unit])
    308 
    309 typedef struct tsc_dpll_refclk_connect
    310 {
    311     int pll0_refclk_select;      /* 0: select PAD ref clock; 1: select internal LC ref clock, refer to pll0_lc_refclk_select*/
    312     int pll0_master_enable;      /* 0: disable; 1: enable ref clock output for other PLL */
    313     int pll0_lc_refclk_select;   /* 0: select pll0_lc_refclk; 1 select pll1_lc_refclk */
    314     int pll1_refclk_select;      /* 0: select PAD ref clock; 1: select internal LC ref clock, refer to pll1_lc_refclk_select*/
    315     int pll1_master_enable;      /* 0: disable; 1: enable ref clock output for other PLL */
    316     int pll1_lc_refclk_select;   /* 0: select pll0_lc_refclk; 1: select pll1_lc_refclk */
    317 }tsc_dpll_refclk_connect_t;
    318 
    319 #define PM_NUM  16
    320 
    321 /* CPM cores: TSC0 - TSC2, TSC13 - TSC15               */
    322 /*           select pll0_lc_refclk (122.88MHz) as CPRI */
    323 /*           select pll1_lc_refclk (156.25MHz) as ETH  */
    324 /* PM4X25 cores: TSC3 - TSC4, TSC11 - TSC12            */
    325 /*           TSC3/TSC12 are master PLL core            */
    326 /*           select pll0_lc_refclk                     */
    327 /* PM4X10 cores: TSC5 - TSC7, TSC8 - TSC10             */
    328 /*           TSC6/TSC9 are master PLL core             */
    329 /*           select pll0_lc_refclk                     */
    330 /* This table is for all CPM cores working in Ethernet */
    331 tsc_dpll_refclk_connect_t monterey_tsc_refclk_connect[PM_NUM] =
    332 {
    333     /* TSC0 CPM4X25 */
    334     /* PLL0/PLL1 select LC refclk;  disable refclk output; select pll1_lc_refclk */
    335     {1, 0, 1,  1, 0, 1},
    336     /* TSC1 CPM4X25 */
    337     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll1_lc_refclk */
    338     {1, 0, 1,  1, 0, 1},
    339     /* TSC2 CPM4X25 PLL1 master PLL*/
    340     /* PLL0 select LC refclk,  disable refclk output, select pll1_lc_refclk */
    341     /* PLL1 select LC refclk,  enable refclk output, select pll1_lc_refclk */
    342     {1, 0, 1,  1, 1, 1},
    343     /* TSC3 PM4X25 PLL0 master PLL*/
    344     /* PLL0 select LC refclk,  enable refclk output, select pll0_lc_refclk */
    345     /* PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    346     {1, 1, 0,  1, 0, 0},
    347     /* TSC4 PM4X25 */
    348     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    349     {1, 0, 0,  1, 0, 0},
    350     /* TSC5 PM4X10 */
    351     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    352     {1, 0, 0,  1, 0, 0},
    353     /* TSC6 PM4X10  PLL0/PLL1 master pll*/
    354     /* PLL0/PLL1 select LC refclk,  enable refclk output, select pll0_lc_refclk */
    355     {1, 1, 0,  1, 1, 0},
    356     /* TSC7 PM4X10 */
    357     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    358     {1, 0, 0,  1, 0, 0},
    359     /* TSC8 PM4X10 */
    360     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    361     {1, 0, 0,  1, 0, 0},
    362     /* TSC9 PM4X10  PLL0/PLL1 master pll*/
    363     /* PLL0/PLL1 select LC refclk,  enable refclk output, select pll0_lc_refclk */
    364     {1, 1, 0,  1, 1, 0},
    365     /* TSC10 PM4X10 */
    366     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    367     {1, 0, 0,  1, 0, 0},
    368     /* TSC11 PM4X25 */
    369     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    370     {1, 0, 0,  1, 0, 0},
    371     /* TSC12 PM4X25 PLL0 master PLL*/
    372     /* PLL0 select LC refclk,  enable refclk output, select pll0_lc_refclk */
    373     /* PLL1 select LC refclk,  disable refclk output, select pll0_lc_refclk */
    374     {1, 1, 0,  1, 0, 0},
    375     /* TSC13 CPM4X25 PLL1 master PLL*/
    376     /* PLL0 select LC refclk,  disable refclk output, select pll1_lc_refclk */
    377     /* PLL1 select LC refclk,  enable refclk output, select pll1_lc_refclk */
    378     {1, 0, 1,  1, 1, 1},
    379     /* TSC14 CPM4X25 */
    380     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll1_lc_refclk */
    381     {1, 0, 1,  1, 0, 1},
    382     /* TSC15 CPM4X25 */
    383     /* PLL0/PLL1 select LC refclk,  disable refclk output, select pll1_lc_refclk */
    384     {1, 0, 1,  1, 0, 1}
    385 };
    386 
    387 #define monterey_tsc_is_master_pll(pm)  \
    388      monterey_tsc_refclk_connect[pm].pll0_master_enable || \
    389      monterey_tsc_refclk_connect[pm].pll1_master_enable
    390 
    391 /* Forward declarations */
    392 STATIC int
    393 _soc_monterey_mdio_reg_read(int unit, uint32 phy_addr,
    394                             uint32 phy_reg, uint32 *phy_data);
    395 STATIC int
    396 _soc_monterey_mdio_reg_write(int unit, uint32 phy_addr,
    397                              uint32 phy_reg, uint32 phy_data);
    398 
    399 #define _SOC_MONTEREY_SER_TYPE_REG 0
    400 #define _SOC_MONTEREY_SER_TYPE_MEM 1
    401 #define _SOC_MONTEREY_SER_TYPE_BUS 2
    402 #define _SOC_MONTEREY_SER_TYPE_BUF 3
    403 
    404 /* These are now generated from the regsfile processing into bcm56670_a0.c
    405    structures are defined in chip.h */
    406 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_ip_mem_ser_info[];
    407 extern _soc_reg_ser_en_info_t _soc_bcm56670_a0_ip_reg_ser_info[];
    408 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_ep_mem_ser_info[];
    409 extern _soc_reg_ser_en_info_t _soc_bcm56670_a0_ep_reg_ser_info[];
    410 extern _soc_mem_ser_en_info_t _soc_bcm56670_a0_mmu_mem_ser_info[];
    411 #if defined(BCM_56670_B0) && defined(INCLUDE_XFLOW_MACSEC)
    412 extern _soc_mem_ser_en_info_t _soc_bcm56670_b0_macsec_mem_ser_info[];
    413 #endif
    414 
    415 /* These can be re-used from TD2P. As naming is SOC independent
    416  * and information is same we'll reuse them here
    417  */
    418 extern _soc_buffer_ser_en_info_t  _soc_mmu_buffer_ser_info[];
    419 
    420 
    421 static _soc_bus_ser_en_info_t _soc_monterey_ip_bus_ser_info [] = {
    422     { "IPARS", IPARS_SER_CONTROLr, IPARS_BUS_PARITY_ENf },
    423     { "IRSEL1", IRSEL1_SER_CONTROLr, IRSEL1_BUS_PARITY_ENf },
    424     { "IRSEL2", IRSEL2_SER_CONTROLr, IRSEL2_BUS_PARITY_ENf },
    425     { "ISW1", ISW1_SER_CONTROLr, ISW1_BUS_PARITY_ENf },
    426     { "IVXLT", IVXLT_SER_CONTROLr, IVXLT_BUS_PARITY_ENf },
    427     { "LEARN_FIFO", IARB_SER_CONTROLr, LEARN_FIFO_ECC_ENf },
    428     { "MPLS", MPLS_SER_CONTROLr, MPLS_BUS_PAR_ENf, },
    429     { "SW2_EOP_BUF_C", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_C_PARITY_ENf },
    430     { "SW2_EOP_BUF_A", ISW2_SER_CONTROL_1r, SW2_EOP_BUFFER_A_PARITY_ENf },
    431     { "VP", VP_SER_CONTROLr, VP_BUS_PAR_ENf },
    432     { "IFP", IFP_PARITY_CONTROLr, IFP_BUS_PARITY_ENf },
    433     { "IL2L3", IL2L3_BUS_SER_CONTROLr, PARITY_ENf },
    434     { "", INVALIDr } /* end */
    435 };
    436 
    437 static _soc_buffer_ser_en_info_t _soc_monterey_ip_buffer_ser_info[] = {
    438     { "COUNTER_STAGING", IFP_PARITY_CONTROLr, COUNTER_MUX_DATA_STAGING_PARITY_ENf },
    439     { "METER_STAGING", IFP_PARITY_CONTROLr, METER_MUX_DATA_STAGING_PARITY_ENf },
    440     { "CMIC", IARB_SER_CONTROLr, CMIC_BUF_ECC_ENf },
    441     { "IP STATS COUNTERS", ISW2_SER_CONTROL_1r, IP_COUNTERS_PARITY_ENf },
    442     { "RDISC/RUC/RPORTD/RDBGC0", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST0_PARITY_ENf },
    443     { "HG STATS COUNTERS", ISW2_SER_CONTROL_1r, HG_COUNTERS_PARITY_ENf },
    444     { "RDBGC5/RDBGC6/RDBGC7/RDBGC8", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST2_PARITY_ENf },
    445     { "RDBGC1/RDBGC2/RDBGC3/RDBGC4", ISW2_SER_CONTROL_1r, RDBGC_MEM_INST1_PARITY_ENf },
    446     { "ING_NIV_RX_FRAMES_ERRe", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_ERROR_DROP_PARITY_ENf },
    447     { "ING_NIV_RX_FRAMES_FRWD", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_FORWARDING_DROP_PARITY_ENf },
    448     { "ING_NIV_RX_FRAMES_VLAN", ISW2_SER_CONTROL_1r, ING_NIV_RX_FRAMES_VLAN_TAGGED_PARITY_ENf },
    449     { "DLB_HGT_FLOWSET_TIME", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_ENf },
    450     { "DLB_HGT_FLOWSET", DLB_HGT_SER_CONTROLr, DLB_HGT_FLOWSET_PARITY_ENf },
    451 
    452     { "", INVALIDr }
    453 };
    454 static _soc_buffer_ser_en_info_t _soc_monterey_ep_buffer_ser_info[] = {
    455     { "INITBUF", EGR_EL3_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf },
    456     { "EGR MPB",  EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf },
    457     { "EDB_CM_MEM", EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf },
    458     { "XLP5_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf  },
    459     { "XLP4_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf  },
    460     { "XLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf  },
    461     { "XLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf  },
    462     { "XLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf  },
    463     { "XLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf  },
    464     { "CLP9_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP9_ECC_ENf  },
    465     { "CLP8_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP8_ECC_ENf  },
    466     { "CLP7_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP7_ECC_ENf  },
    467     { "CLP6_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP6_ECC_ENf  },
    468     { "CLP5_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP5_ECC_ENf  },
    469     { "CLP4_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP4_ECC_ENf  },
    470     { "CLP3_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP3_ECC_ENf  },
    471     { "CLP2_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP2_ECC_ENf  },
    472     { "CLP1_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP1_ECC_ENf  },
    473     { "CLP0_CELL_BUF",  EGR_EDATABUF_PARITY_CONTROLr, CLP0_ECC_ENf  },
    474     { "LPBK_BUF",       EGR_EDATABUF_PARITY_CONTROLr, LBP_ECC_ENf  },
    475     { "XLP5_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP5_ECC_ENf  },
    476     { "XLP4_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP4_ECC_ENf  },
    477     { "XLP3_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP3_ECC_ENf  },
    478     { "XLP2_PREEMPT__CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP2_ECC_ENf  },
    479     { "XLP1_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP1_ECC_ENf  },
    480     { "XLP0_PREEMPT__CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, XLP0_ECC_ENf  },
    481     { "CLP9_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP9_ECC_ENf  },
    482     { "CLP8_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP8_ECC_ENf  },
    483     { "CLP7_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP7_ECC_ENf  },
    484     { "CLP_6PREEMPT__CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP6_ECC_ENf  },
    485     { "CLP5_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP5_ECC_ENf  },
    486     { "CLP4_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP4_ECC_ENf  },
    487     { "CLP3_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP3_ECC_ENf  },
    488     { "CLP2_PREEMPT__CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP2_ECC_ENf  },
    489     { "CLP1_PREEMPT_CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP1_ECC_ENf  },
    490     { "CLP_0PREEMPT__CELL_BUF",  EGR_EDB_PREEMPT_XFR_COUNT_PARITY_ENr, CLP0_ECC_ENf  },
    491     { "XLP5_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP5_ECC_ENf  },
    492     { "XLP4_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP4_ECC_ENf  },
    493     { "XLP3_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP3_ECC_ENf  },
    494     { "XLP2_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP2_ECC_ENf  },
    495     { "XLP1_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP1_ECC_ENf  },
    496     { "XLP0_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, XLP0_ECC_ENf  },
    497     { "CLP9_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP9_ECC_ENf  },
    498     { "CLP8_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP8_ECC_ENf  },
    499     { "CLP7_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP7_ECC_ENf  },
    500     { "CLP_6PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP6_ECC_ENf  },
    501     { "CLP5_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP5_ECC_ENf  },
    502     { "CLP4_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP4_ECC_ENf  },
    503     { "CLP3_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP3_ECC_ENf  },
    504     { "CLP2_PREEMPT__CELL_BUF1", EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP2_ECC_ENf  },
    505     { "CLP1_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP1_ECC_ENf  },
    506     { "CLP0_PREEMPT_CELL_BUF1",  EGR_EDB_PREEMPT_LOOKUP_PARITY_ENr, CLP0_ECC_ENf  },
    507     { "EP_XLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP5_ECC_ENf  },
    508     { "EP_XLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP4_ECC_ENf  },
    509     { "EP_XLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP3_ECC_ENf  },
    510     { "EP_XLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP2_ECC_ENf  },
    511     { "EP_XLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP1_ECC_ENf  },
    512     { "EP_XLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, XLP0_ECC_ENf  },
    513     { "EP_CLP9__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP9_ECC_ENf  },
    514     { "EP_CLP8__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP8_ECC_ENf  },
    515     { "EP_CLP7__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP7_ECC_ENf  },
    516     { "EP_CLP6__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP6_ECC_ENf  },
    517     { "EP_CLP5__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP5_ECC_ENf  },
    518     { "EP_CLP4__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP4_ECC_ENf  },
    519      { "EP_CLP3__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP3_ECC_ENf  },
    520     { "EP_CLP2__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP2_ECC_ENf  },
    521     { "EP_CLP1__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP1_ECC_ENf  },
    522     { "EP_CLP0__DATABUF_CONTROL_INFO", EGR_EDB_CTRL_PARITY_ENr, CLP0_ECC_ENf  },
    523     { "EP_XLP5__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP5_ECC_ENf  },
    524     { "EP_XLP4__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP4_ECC_ENf  },
    525     { "EP_XLP3__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP3_ECC_ENf  },
    526     { "EP_XLP2__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP2_ECC_ENf  },
    527     { "EP_XLP1__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP1_ECC_ENf  },
    528     { "EP_XLP0__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, XLP0_ECC_ENf  },
    529     { "EP_CLP9__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP9_ECC_ENf  },
    530     { "EP_CLP8__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP8_ECC_ENf  },
    531     { "EP_CLP7__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP7_ECC_ENf  },
    532     { "EP_CLP6__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP6_ECC_ENf  },
    533     { "EP_CLP5__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP5_ECC_ENf  },
    534     { "EP_CLP4__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP4_ECC_ENf  },
    535     { "EP_CLP3__PKT-LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP3_ECC_ENf  },
    536     { "EP_CLP2__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP2_ECC_ENf  },
    537     { "EP_CLP1__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP1_ECC_ENf  },
    538     { "EP_CLP0__PKT_LEN", EGR_EDB_PKT_LEN_PARITY_ENr, CLP0_ECC_ENf  },
    539 
    540 
    541     { "", INVALIDr }
    542 };
    543 
    544 
    545 
    546 static _soc_bus_ser_en_info_t _soc_ep_bus_ser_info [] = {
    547     { "EFP",     EFP_PARITY_CONTROLr,      EFP_BUS_PARITY_ENf     },
    548     { "EFPPARS", EGR_EFPPARS_SER_CONTROLr, EFPPARS_BUS_PARITY_ENf },
    549     { "EHCPM",   EGR_EHCPM_SER_CONTROLr,   EHCPM_BUS_PARITY_ENf },
    550     { "EPMOD",   EGR_EPMOD_SER_CONTROLr,   EPMOD_BUS_PARITY_ENf },
    551     { "EVLAN",   EGR_VLAN_SER_CONTROLr,    EVLAN_BUS_PARITY_ENf },
    552     { "", INVALIDr } /* end */
    553 };
    554 
    555 
    556 
    557 static const _soc_monterey_ser_block_info_t _soc_monterey_ser_block_info[] = {
    558     { _SOC_MONTEREY_SER_TYPE_REG, SOC_BLK_IPIPE, "IPIPE regs", INVALIDr, _soc_bcm56670_a0_ip_reg_ser_info },
    559     { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_IPIPE, "IPIPE mems", ING_SER_FIFO_CTRLr, _soc_bcm56670_a0_ip_mem_ser_info },
    560     { _SOC_MONTEREY_SER_TYPE_BUS, SOC_BLK_IPIPE, "IPIPE buses",INVALIDr, _soc_monterey_ip_bus_ser_info },
    561     { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_IPIPE, "IPIPE buff" ,INVALIDr, _soc_monterey_ip_buffer_ser_info },
    562     { _SOC_MONTEREY_SER_TYPE_REG, SOC_BLK_EPIPE, "EPIPE regs", INVALIDr, _soc_bcm56670_a0_ep_reg_ser_info },
    563     { _SOC_MONTEREY_SER_TYPE_BUS, SOC_BLK_EPIPE, "EPIPE buses",INVALIDr, _soc_ep_bus_ser_info },
    564     { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_EPIPE, "EPIPE buff" ,INVALIDr, _soc_monterey_ep_buffer_ser_info },
    565     { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_EPIPE, "EPIPE mems", EGR_SER_FIFO_CTRLr, _soc_bcm56670_a0_ep_mem_ser_info },
    566     { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_MMU,   "MMU mems", INVALIDr, _soc_bcm56670_a0_mmu_mem_ser_info },
    567     { _SOC_MONTEREY_SER_TYPE_BUF, SOC_BLK_MMU,   "MMU buff", INVALIDr, _soc_mmu_buffer_ser_info },
    568 #if defined(BCM_56670_B0) && defined(INCLUDE_XFLOW_MACSEC)
    569     { _SOC_MONTEREY_SER_TYPE_MEM, SOC_BLK_MACSEC,"MACSEC mems", INVALIDr, _soc_bcm56670_b0_macsec_mem_ser_info },
    570 #endif
    571     { -1, 0 }
    572 };
    573 
    574 
    575 STATIC _soc_monterey_ser_info_t _soc_monterey_mmu_ser_info[] = {
    576     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    577         DEQ_NOT_IP_ERR_ENf,
    578         DEQ_NOT_IP_ERRf,
    579         INVALIDm, "MMU DEQ NOT IP",
    580         INVALIDr, INVALIDf,
    581         INVALIDr, NULL,
    582         INVALIDr, INVALIDf, NULL }, 
    583     { _SOC_PARITY_TYPE_START_ERR, NULL, 0,
    584         START_BY_START_ERR_ENf,
    585         START_BY_START_ERRf,
    586         INVALIDm, "MMU START BY START", 
    587         INVALIDr, INVALIDf,
    588         INVALIDr, NULL,
    589         INVALIDr, INVALIDf, NULL }, 
    590     { _SOC_PARITY_TYPE_MMU_SER, NULL, 0,
    591         MEM_PAR_ERR_ENf,
    592         MEM_PAR_ERRf,
    593         INVALIDm, "MMU MEM PAR",
    594         INVALIDr, INVALIDf,
    595         MEM_FAIL_INT_STATr, NULL,
    596         INVALIDr, INVALIDf, NULL }, 
    597     { _SOC_PARITY_TYPE_BST, NULL, 0,
    598         INVALIDf,
    599         BST_THDI_INTf,
    600         INVALIDm, NULL, 
    601         INVALIDr, INVALIDf,
    602         INVALIDr, NULL,
    603         INVALIDr, INVALIDf, NULL },
    604     { _SOC_PARITY_TYPE_BST, NULL, 0,
    605         INVALIDf,
    606         BST_THDO_INTf,
    607         INVALIDm, NULL,
    608         INVALIDr, INVALIDf,
    609         INVALIDr, NULL,
    610         INVALIDr, INVALIDf, NULL },
    611     { _SOC_PARITY_TYPE_BST, NULL, 0,
    612             INVALIDf,
    613         BST_CFAP_INTf,
    614         INVALIDm, NULL,
    615         INVALIDr, INVALIDf,
    616         INVALIDr, NULL,
    617         INVALIDr, INVALIDf, NULL },
    618     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    619 };
    620 
    621 STATIC _soc_monterey_ser_reg_t _soc_monterey_pg_bod_status_reg[] = {
    622     { PGW_BOD_CA0_ECC_STATUSr, "PGW BOD CA0 ECC" },
    623     { PGW_BOD_CA1_ECC_STATUSr, "PGW BOD CA1 ECC" },
    624     { PGW_BOD_CA2_ECC_STATUSr, "PGW BOD CA2 ECC" },
    625     { PGW_BOD_CA3_ECC_STATUSr, "PGW BOD CA3 ECC" },
    626     { PGW_BOD_CA4_ECC_STATUSr, "PGW BOD CA4 ECC" },
    627     { PGW_BOD_CA5_ECC_STATUSr, "PGW BOD CA5 ECC" },
    628     { PGW_BOD_CA6_ECC_STATUSr, "PGW BOD CA6 ECC" },
    629     { PGW_BOD_CA7_ECC_STATUSr, "PGW BOD CA7 ECC" },
    630     { INVALIDr }
    631 };
    632 STATIC _soc_monterey_ser_info_t _soc_monterey_pg_ser_info[] = {
    633     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    634         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    635         PGW_OBM_DATA_MEM_ECC_ERRf,
    636         INVALIDm, "PGW OBM0",
    637         IDB_OBM0_SER_CONTROLr, DATA_ECC_ENABLEf,
    638         IDB_OBM0_DATA_ECC_STATUSr, NULL,
    639         INVALIDr, INVALIDf, NULL },
    640     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    641         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    642         PGW_OBM_DATA_MEM_ECC_ERRf,
    643         INVALIDm, "PGW OBM1",
    644         IDB_OBM1_SER_CONTROLr, DATA_ECC_ENABLEf,
    645         IDB_OBM1_DATA_ECC_STATUSr, NULL,
    646         INVALIDr, INVALIDf, NULL },
    647     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    648         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    649         PGW_OBM_DATA_MEM_ECC_ERRf,
    650         INVALIDm, "PGW OBM2",
    651         IDB_OBM2_SER_CONTROLr, DATA_ECC_ENABLEf,
    652         IDB_OBM2_DATA_ECC_STATUSr, NULL,
    653         INVALIDr, INVALIDf, NULL },
    654     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    655         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    656         PGW_OBM_DATA_MEM_ECC_ERRf,
    657         INVALIDm, "PGW OBM3",
    658         IDB_OBM3_SER_CONTROLr, DATA_ECC_ENABLEf,
    659         IDB_OBM3_DATA_ECC_STATUSr, NULL,
    660         INVALIDr, INVALIDf, NULL },
    661     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    662         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    663         PGW_OBM_DATA_MEM_ECC_ERRf,
    664         INVALIDm, "PGW OBM4",
    665         IDB_OBM4_SER_CONTROLr, DATA_ECC_ENABLEf,
    666         IDB_OBM4_DATA_ECC_STATUSr, NULL,
    667         INVALIDr, INVALIDf, NULL },
    668     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    669         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    670         PGW_OBM_DATA_MEM_ECC_ERRf,
    671         INVALIDm, "PGW OBM5",
    672         IDB_OBM5_SER_CONTROLr, DATA_ECC_ENABLEf,
    673         IDB_OBM5_DATA_ECC_STATUSr, NULL,
    674         INVALIDr, INVALIDf, NULL },
    675     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    676         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    677         PGW_OBM_DATA_MEM_ECC_ERRf,
    678         INVALIDm, "PGW OBM6",
    679         IDB_OBM6_SER_CONTROLr, DATA_ECC_ENABLEf,
    680         IDB_OBM6_DATA_ECC_STATUSr, NULL,
    681         INVALIDr, INVALIDf, NULL },
    682     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    683         PGW_OBM_DATA_MEM_ECC_ERR_ENf,
    684         PGW_OBM_DATA_MEM_ECC_ERRf,
    685         INVALIDm, "PGW OBM7",
    686         IDB_OBM7_SER_CONTROLr, DATA_ECC_ENABLEf,
    687         IDB_OBM7_DATA_ECC_STATUSr, NULL,
    688         INVALIDr, INVALIDf, NULL },
    689     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    690         PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    691         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    692         INVALIDm, "PGW OBM0",
    693         IDB_OBM0_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    694         IDB_OBM0_QUEUE_ECC_STATUSr, NULL,
    695         INVALIDr, INVALIDf, NULL },
    696     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    697        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    698         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    699         INVALIDm, "PGW OBM1",
    700         IDB_OBM1_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    701         IDB_OBM1_QUEUE_ECC_STATUSr, NULL,
    702         INVALIDr, INVALIDf, NULL },
    703     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    704        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    705         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    706         INVALIDm, "PGW OBM2",
    707         IDB_OBM2_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    708         IDB_OBM2_QUEUE_ECC_STATUSr, NULL,
    709         INVALIDr, INVALIDf, NULL },
    710     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    711        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    712         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    713         INVALIDm, "PGW OBM3",
    714         IDB_OBM3_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    715         IDB_OBM3_QUEUE_ECC_STATUSr, NULL,
    716         INVALIDr, INVALIDf, NULL },
    717     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    718        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    719         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    720         INVALIDm, "PGW OBM4",
    721         IDB_OBM4_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    722         IDB_OBM4_QUEUE_ECC_STATUSr, NULL,
    723         INVALIDr, INVALIDf, NULL },
    724     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    725        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    726         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    727         INVALIDm, "PGW OBM5",
    728         IDB_OBM5_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    729         IDB_OBM5_QUEUE_ECC_STATUSr, NULL,
    730         INVALIDr, INVALIDf, NULL },
    731     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    732        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    733         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    734         INVALIDm, "PGW OBM6",
    735         IDB_OBM6_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    736         IDB_OBM6_QUEUE_ECC_STATUSr, NULL,
    737         INVALIDr, INVALIDf, NULL },
    738     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    739        PGW_OBM_QUEUE_MEM_ECC_ERR_ENf ,
    740         PGW_OBM_QUEUE_MEM_ECC_ERRf,
    741         INVALIDm, "PGW OBM7",
    742         IDB_OBM7_QUEUE_SER_CONTROLr, ECC_ENABLEf,
    743         IDB_OBM7_QUEUE_ECC_STATUSr, NULL,
    744         INVALIDr, INVALIDf, NULL },
    745 
    746     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    747         PGW_CA_DATA_MEM_ECC_ERR_ENf,
    748         PGW_CA_DATA_MEM_ECC_ERRf,
    749         INVALIDm, "PGW BOD",
    750         PGW_BOD_ECC_ENABLEr, BOD_ECC_ENABLEf,
    751         INVALIDr, _soc_monterey_pg_bod_status_reg,
    752         INVALIDr, INVALIDf, NULL },
    753     { _SOC_PARITY_TYPE_OBM, NULL, 0,
    754         PGW_OBM_DROPS_OR_CA_OVERFLOW_ERR_ENf,
    755         PGW_OBM_DROPS_OR_CA_OVERFLOW_ERRf,
    756         INVALIDm, "PGW OBM",
    757         INVALIDr, INVALIDr,
    758         INVALIDr, NULL,
    759         INVALIDr, INVALIDf, NULL },
    760     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    761 };
    762 
    763 
    764 #ifdef INCLUDE_XFLOW_MACSEC
    765 STATIC _soc_monterey_ser_info_t _soc_monterey_macsec_ser_info[] = {
    766     { _SOC_PARITY_TYPE_MACSEC_SER, NULL, 0,
    767         ECCERR_INT_ENf,
    768         INVALIDf,
    769         INVALIDm, NULL,
    770         INVALIDr, INVALIDf,
    771         INVALIDr, NULL,
    772         INVALIDr, INVALIDf, NULL },
    773     { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0,
    774         EGRESS_SA_SOFT_EXPIRE_INT_ENf,
    775         INVALIDf,
    776         INVALIDm, NULL,
    777         INVALIDr, INVALIDf,
    778         INVALIDr, NULL,
    779         INVALIDr, INVALIDf, NULL },
    780     { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0,
    781         EGRESS_SA_EXPIRE_INT_ENf,
    782         INVALIDf,
    783         INVALIDm, NULL,
    784         INVALIDr, INVALIDf,
    785         INVALIDr, NULL,
    786         INVALIDr, INVALIDf, NULL },
    787     { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0,
    788         INGRESS_SA_SOFT_EXPIRE_INT_ENf,
    789         INVALIDf,
    790         INVALIDm, NULL,
    791         INVALIDr, INVALIDf,
    792         INVALIDr, NULL,
    793         INVALIDr, INVALIDf, NULL },
    794     { _SOC_PARITY_TYPE_MACSEC_FUNCTIONAL, NULL, 0,
    795         INGRESS_SA_EXPIRE_INT_ENf,
    796         INVALIDf,
    797         INVALIDm, NULL,
    798         INVALIDr, INVALIDf,
    799         INVALIDr, NULL,
    800         INVALIDr, INVALIDf, NULL },
    801     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    802 };
    803 #endif
    804 static const
    805 _soc_monterey_ser_route_block_t  _soc_monterey_ser_route_blocks_irq3[] = {
    806     { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */
    807       SOC_BLK_MMU, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, INVALIDf, 
    808       _soc_monterey_mmu_ser_info, 0 },
    809     { 0x00000002, /* EP1_TO_CMIC_PERR_INTR */
    810       SOC_BLK_EPIPE, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, NULL, 0 },
    811     { 0x00000004, /* EP2_TO_CMIC_PERR_INTR */
    812       SOC_BLK_EPIPE, EGR_INTR_ENABLEr, INVALIDr, SER_FIFO_NON_EMPTYf, NULL, 0 },
    813     { 0x00000008, /* IP0_TO_CMIC_PERR_INTR */
    814       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    815     { 0x00000010, /* IP1_TO_CMIC_PERR_INTR */
    816       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    817     { 0x00000020, /* IP2_TO_CMIC_PERR_INTR */
    818       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    819     { 0x00000040, /* IP3_TO_CMIC_PERR_INTR */
    820       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    821     { 0x00000080, /* IP4_TO_CMIC_PERR_INTR */
    822       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    823     { 0x00000100, /* IP5_TO_CMIC_PERR_INTR */
    824       SOC_BLK_IPIPE, INVALIDr, INVALIDr, INVALIDf, NULL, 0 },
    825     { 0x00000200, /* PGW_0_TO_CMIC_PERR_INTR */
    826       SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    827       _soc_monterey_pg_ser_info, 0 },
    828     { 0x00000400, /* PGW_1_TO_CMIC_PERR_INTR */
    829       SOC_BLK_PGW_CL, PGW_INTR_ENABLEr, PGW_INTR_STATUSr, INVALIDf,
    830       _soc_monterey_pg_ser_info, 1 },
    831     /* bits 11 12 13 and 14 do not look SER related. Leaving them alone */
    832     { 0 } /* table terminator */
    833 };
    834 /*
    835 static soc_field_t _soc_monterey_pm_rx_cdc_clear_field[] = {
    836     CLEAR_RX_CDC_SINGLE_BIT_ERRf, CLEAR_RX_CDC_DOUBLE_BIT_ERRf
    837 };
    838 static soc_field_t _soc_monterey_pm_tx_cdc_clear_field[] = {
    839     CLEAR_TX_CDC_SINGLE_BIT_ERRf, CLEAR_TX_CDC_DOUBLE_BIT_ERRf
    840 };
    841 
    842 
    843 static soc_field_t _soc_monterey_pm_rx_ts_clear_field[] = {
    844     CLEAR_RX_TS_MEM_SINGLE_BIT_ERRf, CLEAR_RX_TS_MEM_DOUBLE_BIT_ERRf
    845 };
    846 */
    847 static _soc_monterey_ser_reg_t _soc_monterey_pm_xlp_rx_status_reg[] = {
    848     { XLPORT_MIB_RSC0_ECC_STATUSr, "XLP MIB RSC0 ECC" },
    849     { XLPORT_MIB_RSC1_ECC_STATUSr, "XLP MIB RSC1 ECC"},
    850     { INVALIDr }
    851  
    852 };
    853 static _soc_monterey_ser_reg_t _soc_monterey_pm_xlp_tx_status_reg[] = {
    854     { XLPORT_MIB_TSC0_ECC_STATUSr, "XLP MIB TSC0 ECC" },
    855     { XLPORT_MIB_TSC1_ECC_STATUSr, "XLP MIB TSC1 ECC" },
    856     { INVALIDr }
    857 };
    858 
    859 static  _soc_monterey_ser_info_t _soc_monterey_xlport_ser_info[] = {
    860     /* In addition to below we have TSC_ERROR, RX_FLOWCONTROL_REQ_FULL
    861      * interrupts in XLPORT. Currently not being handled.
    862      */
    863     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    864       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    865       INVALIDm, "MIB RX Statistic Counter memory",
    866       XLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    867       INVALIDr, _soc_monterey_pm_xlp_rx_status_reg,
    868       XLPORT_MIB_RESETr, INVALIDf, NULL
    869     },
    870     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    871       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    872       INVALIDm, "MIB TX Statistic Counter memory",
    873       XLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    874       INVALIDr, _soc_monterey_pm_xlp_tx_status_reg,
    875       XLPORT_MIB_RESETr, INVALIDf, NULL
    876     },
    877     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    878 };
    879 
    880 static _soc_monterey_ser_reg_t _soc_monterey_pm_clp_rx_status_reg[] = {
    881     { CLPORT_MIB_RSC0_ECC_STATUSr, "CLP MIB RSC0 ECC" },
    882     { CLPORT_MIB_RSC1_ECC_STATUSr, "CLP MIB RSC1 ECC" }
    883 };
    884 
    885 static _soc_monterey_ser_reg_t _soc_monterey_pm_clp_tx_status_reg[] = {
    886     { CLPORT_MIB_TSC0_ECC_STATUSr, "CLP MIB TSC0 ECC" },
    887     { CLPORT_MIB_TSC1_ECC_STATUSr, "CLP MIB TSC1 ECC" }
    888 };
    889 static  _soc_monterey_ser_info_t _soc_monterey_clport_ser_info[] = {
    890     /* In addition to below we have TSC_ERROR, PMD_ERR, RX_FLOWCONTROL_REQ_FULL
    891      * interrupts in CLPORT. Currently not being handled
    892      */
    893     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    894       MIB_RX_MEM_ERRf, MIB_RX_MEM_ERRf,
    895       INVALIDm, "MIB RX Statistic Counter memory",
    896       CLPORT_ECC_CONTROLr, MIB_RSC_MEM_ENf,
    897       INVALIDr, _soc_monterey_pm_clp_rx_status_reg,
    898       CLPORT_MIB_RESETr, INVALIDf, NULL
    899     },
    900     { _SOC_PARITY_TYPE_MIB, NULL, 0,
    901       MIB_TX_MEM_ERRf, MIB_TX_MEM_ERRf,
    902       INVALIDm, "MIB TX Statistic Counter memory",
    903       CLPORT_ECC_CONTROLr, MIB_TSC_MEM_ENf,
    904       INVALIDr, _soc_monterey_pm_clp_tx_status_reg,
    905       CLPORT_MIB_RESETr, INVALIDf, NULL
    906     },
    907     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    908 };
    909 
    910 
    911 static const
    912 _soc_monterey_ser_route_block_t  _soc_monterey_ser_route_blocks_irq4[] = {
    913     {0x00000001, /* Port Macro0 (PM0) interrupt */
    914      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    915      _soc_monterey_clport_ser_info, 0},
    916     {0x00000002, /* Port Macro1 (PM1) interrupt */
    917      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    918      _soc_monterey_clport_ser_info, 1},
    919     {0x00000004, /* Port Macro2 (PM2) interrupt */
    920      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    921      _soc_monterey_clport_ser_info, 2},
    922     {0x00000008, /* Port Macro3 (PM3) interrupt */
    923      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    924      _soc_monterey_clport_ser_info, 3},
    925     {0x00000010, /* Port Macro4 (PM4) interrupt */
    926      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    927      _soc_monterey_clport_ser_info, 0},
    928     {0x00000020, /* Port Macro5 (PM5) interrupt */
    929      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    930      _soc_monterey_xlport_ser_info, 1},
    931     {0x00000040, /* Port Macro6 (PM6) interrupt */
    932      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    933      _soc_monterey_xlport_ser_info, 2},
    934     {0x00000080, /* Port Macro7 (PM7) interrupt */
    935      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    936      _soc_monterey_xlport_ser_info, 7},
    937     {0x00000100, /* Port Macro8 (PM8) interrupt */
    938      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    939      _soc_monterey_xlport_ser_info, 8},
    940     {0x00000200, /* Port Macro9 (PM9) interrupt */
    941      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    942      _soc_monterey_xlport_ser_info, 9},
    943     {0x00000400, /* Port Macro10 (PM10) interrupt */
    944      SOC_BLK_XLPORT, XLPORT_INTR_ENABLEr, XLPORT_INTR_STATUSr, INVALIDf,
    945      _soc_monterey_xlport_ser_info, 10},
    946     {0x00000800, /* Port Macro11 (PM11) interrupt */
    947      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    948      _soc_monterey_clport_ser_info, 1},
    949     {0x00001000, /* Port Macro12 (PM12) interrupt */
    950      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    951      _soc_monterey_clport_ser_info, 4},
    952     {0x00002000, /* Port Macro13 (PM13) interrupt */
    953      SOC_BLK_CLPORT, CLPORT_INTR_ENABLEr, CLPORT_INTR_STATUSr, INVALIDf,
    954      _soc_monterey_clport_ser_info, 5},
    955     /* Bits 14-31 are reserved */
    956     {0} /* table terminator */
    957 };
    958 
    959 #ifdef INCLUDE_XFLOW_MACSEC
    960 static const
    961 _soc_monterey_ser_route_block_t  _soc_monterey_macsec_ser_route_blocks_irq4[] = {
    962     { 0x400000, /* MACSEC_INTR */
    963       SOC_BLK_MACSEC, SP_GLB_INTR_ENr, SP_GLB_INTR_STATUSr, INVALIDf,
    964       _soc_monterey_macsec_ser_info, 0 },
    965     {0} /* table terminator */
    966 };
    967 #endif
    968 
    969 _soc_monterey_pm_cpri_intr_info_t  
    970  _soc_monterey_pm_cpri_intr_info_irq4[] = {    
    971     {0x00010000, /* Port Macro0 (PM0) CPRI interrupt */                         
    972      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,
    973      NULL, 0},
    974     {0x00020000, /* Port Macro1 (PM1) CPRI interrupt */
    975      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,              
    976      NULL, 1},
    977     {0x00040000, /* Port Macro2 (PM2) CPRI interrupt */
    978      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,              
    979      NULL, 2},
    980     {0x00080000, /* Port Macro13 (PM13) CPRI interrupt */
    981      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,              
    982      NULL, 3},
    983     {0x00100000, /* Port Macro14 (PM14) CPRI interrupt */
    984      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,              
    985      NULL, 4},
    986     {0x00200000, /* Port Macro15 (PM15) interrupt */
    987      SOC_BLK_CPRI, CPRI_INTR_ENABLEr, CPRI_INTR_STATUSr, INVALIDf,              
    988      NULL, 5},
    989      /* _soc_monterey_intr_info, 0}, */
    990     {0} /* table terminator */
    991 };
    992 
    993 static soc_ser_functions_t _monterey_ser_functions;
    994 static soc_pm_intr_functions_t _monterey_pm_intr_functions;
    995 
    996 extern uint8 _soc_alpm_mode[SOC_MAX_NUM_DEVICES];
    997 
    998 static uint32 _monterey_ser_delay = 0;
    999 
   1000 /* Values map to HW encodings */
   1001 enum soc_mn_port_ca_mode_e {
   1002     SOC_MN_PORT_CA_MODE_SINGLE      = 0,
   1003     SOC_MN_PORT_CA_MODE_DUAL        = 1,
   1004     SOC_MN_PORT_CA_MODE_QUAD        = 2,
   1005     SOC_MN_PORT_CA_MODE_TRI_211     = 3,
   1006     SOC_MN_PORT_CA_MODE_TRI_112     = 4,
   1007     SOC_MN_PORT_CA_MODE_TRI_411     = 5,
   1008     SOC_MN_PORT_CA_MODE_TRI_114     = 6,
   1009     SOC_MN_PORT_CA_MODE_COUNT       /* unused */
   1010 };
   1011 int IS_ROE_ENABLED(int unit) { 
   1012     uint16              dev_id;
   1013     uint8               rev_id;
   1014 
   1015     soc_cm_get_id(unit, &dev_id, &rev_id);
   1016     if (dev_id == BCM56675_DEVICE_ID) {
   1017         return FALSE;     
   1018     } else {
   1019         return TRUE;     
   1020     }
   1021 }
   1022 STATIC int
   1023 _soc_monterey_thdo_hw_set(int unit, soc_port_t port, int enable);
   1024 /*
   1025  * SINGLE   => {VALUE => 0, DESC => "Port 0 valid.  10G/20G/25G/40G/50G/100G."},
   1026  * DUAL     => {VALUE => 1, DESC => "Port 0 and 2 valid.  10G/20G/25G/40G/50G."},
   1027  * QUAD     => {VALUE => 2, DESC => "Port 0, 1, 2, and 3 valid.  10G/20G/25G."},
   1028  * TRI211   => {VALUE => 3, DESC => "Port 0 is 20G, port 2 10G, and port 3 10G."},
   1029  * TRI112   => {VALUE => 4, DESC => "Port 0 is 10G, port 1 10G, and port 2 20G."},
   1030  * TRI411   => {VALUE => 5, DESC => "Port 0 is 40G, port 2 10G, and port 3 10G."},
   1031  * TRI114   => {VALUE => 6, DESC => "Port 0 is 10G, port 1 10G, and port 2 40G."},
   1032  */
   1033 STATIC int
   1034 soc_monterey_port_ca_mode_get(int unit, int flexport, int xlp, int *mode)
   1035 {
   1036     soc_info_t *si;
   1037     int port, phy_port_base, lane;
   1038     int num_lanes[MONTEREY_PORTS_PER_TSC];
   1039     int speed_max[MONTEREY_PORTS_PER_TSC];
   1040 
   1041     si = &SOC_INFO(unit);
   1042     *mode = SOC_MN_PORT_CA_MODE_QUAD;
   1043 
   1044     phy_port_base = 1 + (xlp * MONTEREY_PORTS_PER_TSC);
   1045     for (lane = 0; lane < MONTEREY_PORTS_PER_TSC; lane++) {
   1046         port = si->port_p2l_mapping[phy_port_base + lane];
   1047         if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   1048             num_lanes[lane] = -1;
   1049             speed_max[lane] = -1;
   1050         } else {
   1051             num_lanes[lane] = si->port_num_lanes[port];
   1052             speed_max[lane] = si->port_speed_max[port];
   1053         }
   1054     }
   1055 
   1056     if (num_lanes[0] >= 4) {
   1057         *mode = SOC_MN_PORT_CA_MODE_SINGLE;
   1058     } else if ((num_lanes[0] == 2) && (num_lanes[2] == 2)) {
   1059         *mode = SOC_MN_PORT_CA_MODE_DUAL;
   1060     } else if ((num_lanes[0] == 1) && (num_lanes[1] == 1) &&
   1061                (num_lanes[2] == 1) && (num_lanes[3] == 1)) {
   1062         *mode = SOC_MN_PORT_CA_MODE_QUAD;
   1063     } else if (num_lanes[0] == 2) {
   1064         *mode = (speed_max[0] >= 40000) ?
   1065                 SOC_MN_PORT_CA_MODE_TRI_411 : SOC_MN_PORT_CA_MODE_TRI_211;
   1066     } else if (num_lanes[2] == 2) {
   1067         *mode = (speed_max[2] >= 40000) ?
   1068                 SOC_MN_PORT_CA_MODE_TRI_114 : SOC_MN_PORT_CA_MODE_TRI_112;
   1069     }
   1070     return SOC_E_NONE;
   1071 }
   1072 
   1073 
   1074 int
   1075 _soc_monterey_idb_port_init(int unit, int reset, int lossless, soc_port_t port)
   1076 {
   1077     soc_info_t *si;
   1078     soc_mem_t mem;
   1079     soc_reg_t reg;
   1080     int obm, pgw, pgw_inst, index;
   1081     int port_osub, phy_port, subport;
   1082     uint32 rval32 ;
   1083     uint64 rval64;
   1084     idb_obm0_pri_map_port0_entry_t entry;
   1085 
   1086     uint32 discard_limit = 0, express_discard = 0, lossy_discard = 0, lossy_low_pri = 0;
   1087     uint32 port_xon = 0, port_xoff = 0, lossless0_xon = 0 ,lossless0_xoff = 0;
   1088 
   1089     static const soc_reg_t obm_ctrl_regs[] = {
   1090         IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr,
   1091         IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr,
   1092         IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr,
   1093         IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr
   1094     };
   1095     static const soc_reg_t obm_thresh0_regs[] = {
   1096         IDB_OBM0_THRESHOLD_0r, IDB_OBM1_THRESHOLD_0r,
   1097         IDB_OBM2_THRESHOLD_0r, IDB_OBM3_THRESHOLD_0r,
   1098         IDB_OBM4_THRESHOLD_0r, IDB_OBM5_THRESHOLD_0r,
   1099         IDB_OBM6_THRESHOLD_0r, IDB_OBM7_THRESHOLD_0r
   1100     };
   1101     static const soc_reg_t obm_thresh1_regs[] = {
   1102         IDB_OBM0_THRESHOLD_1r, IDB_OBM1_THRESHOLD_1r,
   1103         IDB_OBM2_THRESHOLD_1r, IDB_OBM3_THRESHOLD_1r,
   1104         IDB_OBM4_THRESHOLD_1r, IDB_OBM5_THRESHOLD_1r,
   1105         IDB_OBM6_THRESHOLD_1r, IDB_OBM7_THRESHOLD_1r
   1106     };
   1107     static const soc_reg_t obm_fc_thresh0_regs[] = {
   1108         IDB_OBM0_FC_THRESHOLD_0r, IDB_OBM1_FC_THRESHOLD_0r,
   1109         IDB_OBM2_FC_THRESHOLD_0r, IDB_OBM3_FC_THRESHOLD_0r,
   1110         IDB_OBM4_FC_THRESHOLD_0r, IDB_OBM5_FC_THRESHOLD_0r,
   1111         IDB_OBM6_FC_THRESHOLD_0r, IDB_OBM7_FC_THRESHOLD_0r
   1112     };
   1113     static const soc_reg_t obm_fc_thresh1_regs[] = {
   1114         IDB_OBM0_FC_THRESHOLD_1r, IDB_OBM1_FC_THRESHOLD_1r,
   1115         IDB_OBM2_FC_THRESHOLD_1r, IDB_OBM3_FC_THRESHOLD_1r,
   1116         IDB_OBM4_FC_THRESHOLD_1r, IDB_OBM5_FC_THRESHOLD_1r,
   1117         IDB_OBM6_FC_THRESHOLD_1r, IDB_OBM7_FC_THRESHOLD_1r
   1118     };
   1119     static const soc_reg_t obm_shared_regs[] = {
   1120         IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr,
   1121         IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr,
   1122         IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr,
   1123         IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr
   1124     };
   1125     static const soc_reg_t obm_max_usage_regs[] = {
   1126         IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr,
   1127         IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr,
   1128         IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr,
   1129         IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr
   1130     };
   1131 
   1132     static const soc_reg_t obm_port_config_regs[] = {
   1133         IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr,
   1134         IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr,
   1135         IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr,
   1136         IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr
   1137     };
   1138     static const soc_reg_t obm_fc_config_regs[] = {
   1139         IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr,
   1140         IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr,
   1141         IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr,
   1142         IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr
   1143     };
   1144 
   1145     static const soc_reg_t obm_bank_config_regs[] = {
   1146         IDB_OBM0_BANK_CONFIGr, IDB_OBM1_BANK_CONFIGr,
   1147         IDB_OBM2_BANK_CONFIGr, IDB_OBM3_BANK_CONFIGr,
   1148         IDB_OBM4_BANK_CONFIGr, IDB_OBM5_BANK_CONFIGr,
   1149         IDB_OBM6_BANK_CONFIGr, IDB_OBM7_BANK_CONFIGr
   1150     };
   1151 
   1152     static const soc_field_t obm_oversub_fields[] = {
   1153         PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf,
   1154         PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf
   1155     };
   1156 
   1157     static const soc_mem_t obm_pri_map_port_mem[] = {
   1158         IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m,
   1159         IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m,
   1160         IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m,
   1161         IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m,
   1162         IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m,
   1163         IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m,
   1164         IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m,
   1165         IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m,
   1166         IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m,
   1167         IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m,
   1168         IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m,
   1169         IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m,
   1170         IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m,
   1171         IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m,
   1172         IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m,
   1173         IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m,
   1174         IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m,
   1175         IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m,
   1176     };
   1177 
   1178 
   1179     static const soc_field_t offset_ob_prio[] = {
   1180         OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf,
   1181         OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf,
   1182         OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf,
   1183         OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf,
   1184         OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf,
   1185         OFFSET15_OB_PRIORITYf,
   1186     };
   1187     static const soc_reg_t obm_ct_thresh_regs[] = {
   1188         IDB_OBM0_CT_THRESHOLDr, IDB_OBM1_CT_THRESHOLDr,
   1189         IDB_OBM2_CT_THRESHOLDr, IDB_OBM3_CT_THRESHOLDr,
   1190         IDB_OBM4_CT_THRESHOLDr, IDB_OBM5_CT_THRESHOLDr,
   1191         IDB_OBM6_CT_THRESHOLDr, IDB_OBM7_CT_THRESHOLDr,
   1192         IDB_OBM8_CT_THRESHOLDr,
   1193     };
   1194 
   1195     soc_pbmp_t pbmp_xport_roe_backplane;
   1196     soc_pbmp_t pbmp_xport_roe_bbu;
   1197     soc_pbmp_t pbmp_xport_roe_mcu;
   1198     soc_pbmp_t pbmp_xport_roe_fronthaul;
   1199 
   1200 
   1201     SOC_PBMP_CLEAR(pbmp_xport_roe_backplane);
   1202     SOC_PBMP_CLEAR(pbmp_xport_roe_bbu);
   1203     SOC_PBMP_CLEAR(pbmp_xport_roe_mcu);
   1204     SOC_PBMP_CLEAR(pbmp_xport_roe_fronthaul);
   1205     si = &SOC_INFO(unit);
   1206 
   1207     /* Calculation of obm and lanes(subport)
   1208        obm is 0 for phy_port 1 to 4
   1209        1 for phy port 5 to 8 and so on till 8 for phy_port 33 to 36
   1210        Similarly obm 0 for phy_port 37 to 40 and so on
   1211        lane(subport) is 0,1,2,3 for phy_port 1,2,3,4 resp
   1212        lane(subport) is 0,1,2,3 for phy_port 5,6,7,8 resp and so on
   1213        Block index is PGW0 for ports 1 to 36
   1214        Block index is PGW1 for ports 37 to 72
   1215     */
   1216     phy_port = si->port_l2p_mapping[port];
   1217 
   1218     /*  Deleting a port  */
   1219     if (phy_port == -1) {
   1220         return SOC_E_PARAM;
   1221     }
   1222 
   1223     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) {
   1224         /*  nothing to do for non-idb ports */
   1225         return SOC_E_NONE;
   1226     }
   1227 
   1228     /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1  */
   1229     obm = si->port_serdes[port];
   1230     obm %= MONTEREY_TSCS_PER_PGW;
   1231 
   1232     pgw = si->port_group[port];
   1233     pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   1234     subport = (phy_port - 1) % MONTEREY_PORTS_PER_TSC;
   1235     pbmp_xport_roe_backplane = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_BACKPLANE,
   1236                                  pbmp_xport_roe_backplane);
   1237     pbmp_xport_roe_bbu = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_BBU,
   1238                                  pbmp_xport_roe_bbu);
   1239     pbmp_xport_roe_mcu = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_MCU,
   1240                                  pbmp_xport_roe_mcu);
   1241     pbmp_xport_roe_fronthaul = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_ROE_FRONTHAUL,
   1242                                  pbmp_xport_roe_fronthaul);
   1243 
   1244     if(!IS_CPRI_PORT(unit,port)) {
   1245 
   1246        COMPILER_64_ZERO(rval64);
   1247        SOC_IF_ERROR_RETURN(READ_PGW_OBM_PARSING_CONTROLr(unit, port ,&rval64));
   1248        soc_reg64_field32_set(unit, PGW_OBM_PARSING_CONTROLr,
   1249                      &rval64, USE_PM_PREEMPT_INPUTf , 0);
   1250        SOC_IF_ERROR_RETURN(WRITE_PGW_OBM_PARSING_CONTROLr(unit, port, rval64));
   1251     }
   1252     if (si->port_speed_max[port] <= 11000) {
   1253             discard_limit = 375;
   1254             if(IS_CPRI_PORT(unit,port)) {
   1255                discard_limit = 383;
   1256                express_discard =  383;
   1257             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1258                express_discard =  187;
   1259             }
   1260             else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1261                express_discard = 0;
   1262             } else { 
   1263                express_discard = lossless ? 1535 : 375;
   1264             }
   1265             if(IS_CPRI_PORT(unit,port)) {
   1266                lossy_discard =  187;
   1267             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1268                lossy_discard =  187;
   1269             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) {
   1270                lossy_discard =  375;
   1271             } else { 
   1272                lossy_discard = lossless ? 196 : 371;
   1273             }
   1274             if(IS_CPRI_PORT(unit,port)) {
   1275                lossy_low_pri =  187;
   1276             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1277                lossy_low_pri =  165;
   1278             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1279                lossy_low_pri =  268;
   1280             } else { 
   1281                lossy_low_pri = lossless ? 100 : 282;
   1282             }
   1283             port_xon = lossless ? 223 : 1535;
   1284             port_xoff = lossless ? 233 : 1535;
   1285             lossless0_xon = lossless ? 36 : 1535;
   1286             lossless0_xoff = lossless ? 46 : 1535;
   1287     } else if (si->port_speed_max[port] <= 21000) {
   1288                discard_limit = 383;
   1289             if(IS_CPRI_PORT(unit,port)) {
   1290                express_discard =  383;
   1291                discard_limit = 383;
   1292             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1293                express_discard =  187;
   1294             }
   1295             else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1296                express_discard = 0;
   1297             } else { 
   1298             express_discard = lossless ? 1535 : 375;
   1299             }
   1300             if(IS_CPRI_PORT(unit,port)) {
   1301                lossy_discard =  187;
   1302             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1303                lossy_discard =  187;
   1304             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 
   1305                lossy_discard =  375;
   1306             } else { 
   1307                lossy_discard = lossless ? 196 : 371;
   1308             }
   1309             if(IS_CPRI_PORT(unit,port)) {
   1310                lossy_low_pri =  0;
   1311             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1312                lossy_low_pri =  165;
   1313             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1314                lossy_low_pri =  268;
   1315             } else { 
   1316                lossy_low_pri = lossless ? 100 : 282;
   1317             }
   1318             port_xon = lossless ? 206 : 1535;
   1319             port_xoff = lossless ? 216 : 1535;
   1320             lossless0_xon = lossless ? 36 : 1535;
   1321             lossless0_xoff = lossless ? 46 : 1535;
   1322     } else if (si->port_speed_max[port] <= 27000) {
   1323             discard_limit = 375;
   1324             if(IS_CPRI_PORT(unit,port)) {
   1325                express_discard =  383;
   1326                discard_limit = 383;
   1327             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1328                express_discard =  187;
   1329             }
   1330             else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1331                express_discard = 0;
   1332             } else { 
   1333             express_discard = lossless ? 1535 : 375;
   1334             }
   1335             if(IS_CPRI_PORT(unit,port)) {
   1336                lossy_discard =  0;
   1337             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1338                lossy_discard =  187;
   1339             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 
   1340                lossy_discard =  375;
   1341             } else { 
   1342                lossy_discard = lossless ? 196 : 371;
   1343             }
   1344             if(IS_CPRI_PORT(unit,port)) {
   1345                lossy_low_pri =  0;
   1346             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) {
   1347                lossy_low_pri =  165;
   1348             } else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1349                lossy_low_pri =  268;
   1350             } else { 
   1351                lossy_low_pri = lossless ? 100 : 282;
   1352             }
   1353             port_xon = lossless ? 198 : 1535;
   1354             port_xoff = lossless ? 208 : 1535;
   1355             lossless0_xon = lossless ? 36 : 1535;
   1356             lossless0_xoff = lossless ? 46 : 1535;
   1357     } else if (si->port_speed_max[port] <= 42000) {
   1358             if((SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) || 
   1359                 (SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port))) { 
   1360                discard_limit =  1512 ;
   1361              
   1362             } else {  
   1363                discard_limit = 754;
   1364             }
   1365             express_discard = lossless ? 1535 : 756;
   1366             if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1367                express_discard = 0;
   1368             }
   1369             if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port)) { 
   1370                lossy_discard =  756;
   1371             } else { 
   1372                lossy_discard = lossless ? 196 : 750;
   1373             }
   1374             if(SOC_PBMP_MEMBER(pbmp_xport_roe_backplane, port) || 
   1375                 SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 
   1376                lossy_low_pri = 670;
   1377             } else {    
   1378                lossy_low_pri = lossless ? 100 : 661;
   1379             }
   1380             port_xon = lossless ? 499 : 1535;
   1381             port_xoff = lossless ? 509 : 1535;
   1382             lossless0_xon = lossless ? 98 : 1535;
   1383             lossless0_xoff = lossless ? 108 : 1535;
   1384     } else if (si->port_speed_max[port] <= 53000) {
   1385             if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 
   1386                discard_limit =  754;
   1387             } else { 
   1388                discard_limit = 1512;
   1389             }
   1390             if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 
   1391                express_discard = 377;
   1392             }
   1393             else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1394                express_discard = 0;
   1395             } else { 
   1396                express_discard = 754;
   1397             }
   1398             if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 
   1399                lossy_discard = 377;
   1400             } else { 
   1401                lossy_discard = lossless ? 196 : 750;
   1402             }
   1403             if(SOC_PBMP_MEMBER(pbmp_xport_roe_bbu, port)) { 
   1404                lossy_low_pri = 334;
   1405             } else { 
   1406                lossy_low_pri = lossless ? 100 : 661;
   1407             }
   1408             port_xon = lossless ? 483 : 1535;
   1409             port_xoff = lossless ? 493 : 1535;
   1410             lossless0_xon = lossless ? 98 : 1535;
   1411             lossless0_xoff = lossless ? 108 : 1535;
   1412     } else { /* greter than 53000 including 106000 */
   1413                discard_limit = 1512;
   1414             if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 
   1415                express_discard =  756;
   1416             }
   1417             else if(SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) { 
   1418                express_discard = 0;
   1419             } else { 
   1420                express_discard = lossless ? 1535 : 1512;
   1421             }
   1422             if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 
   1423                lossy_discard = 756;
   1424             } else { 
   1425                lossy_discard = lossless ? 196 : 1508;
   1426             } 
   1427             if(SOC_PBMP_MEMBER(pbmp_xport_roe_fronthaul, port)) { 
   1428                lossy_low_pri = 670; 
   1429             } else { 
   1430                lossy_low_pri = lossless ? 100 : 1419;
   1431             }
   1432             port_xon = lossless ? 483 : 1535;
   1433             port_xoff = lossless ? 493 : 1535;
   1434             lossless0_xon = lossless ? 248 : 1535;
   1435             lossless0_xoff = lossless ? 258 : 1535;
   1436     }
   1437 
   1438     if (reset) {
   1439        discard_limit = 0;
   1440        lossy_discard = 0;
   1441        lossy_low_pri = 0;
   1442        port_xon = 0;
   1443        port_xoff = 0;
   1444        lossless0_xon = 0;
   1445        lossless0_xoff = 0;
   1446     }
   1447 
   1448 
   1449     rval32 = 0;
   1450     reg = obm_port_config_regs[obm];
   1451 
   1452     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32));
   1453     soc_reg_field_set(unit, reg, &rval32, PORT_PRIf, 2);
   1454     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32));
   1455 
   1456     rval32 = 0;
   1457     reg = obm_max_usage_regs[obm];
   1458 
   1459     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32));
   1460     soc_reg_field_set(unit, reg, &rval32, PRIORITY_SELECTf, 2);
   1461     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32));
   1462 
   1463     COMPILER_64_ZERO(rval64);
   1464     reg = obm_thresh0_regs[obm];
   1465 
   1466     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1467     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1535);
   1468     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1535);
   1469     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, lossy_discard);
   1470     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, lossy_low_pri);
   1471     soc_reg64_field32_set(unit, reg, &rval64, LOSSY_MINf, 0);
   1472     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1473 
   1474     COMPILER_64_ZERO(rval64);
   1475     reg = obm_thresh1_regs[obm];
   1476 
   1477     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1478     soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, discard_limit);
   1479     soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_DISCARDf, express_discard);
   1480     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1481 
   1482     rval32 = 0;
   1483     reg = obm_shared_regs[obm];
   1484 
   1485     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, subport, &rval32));
   1486     soc_reg_field_set(unit, reg, &rval32, SOP_DISCARD_MODEf,  1);
   1487     soc_reg_field_set(unit, reg, &rval32, SOP_THRESHOLDf,  1535);
   1488     soc_reg_field_set(unit, reg, &rval32, DISCARD_THRESHOLDf, 1535);
   1489     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, subport, rval32));
   1490 
   1491     COMPILER_64_ZERO(rval64);
   1492     reg = obm_fc_thresh0_regs[obm];
   1493 
   1494     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1495     soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, port_xoff);
   1496     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 1535);
   1497     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 1535);
   1498     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, lossless0_xon);
   1499     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, lossless0_xoff);
   1500     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1501 
   1502     COMPILER_64_ZERO(rval64);
   1503     reg = obm_fc_thresh1_regs[obm];
   1504 
   1505     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1506     soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, port_xon);
   1507     soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_XONf, 1535);
   1508     soc_reg64_field32_set(unit, reg, &rval64, EXPRESS_XOFFf, 1535);
   1509     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1510 
   1511     if (!IS_OVERSUB_PORT(unit, port) ||
   1512         ((IS_OVERSUB_PORT(unit, port)) &&
   1513             ((si->port_speed_max[port] == 40000) ||
   1514             (si->port_speed_max[port] == 42000)))) {
   1515         COMPILER_64_ZERO(rval64);
   1516         reg = obm_ct_thresh_regs[obm];
   1517 
   1518         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1519         soc_reg64_field32_set(unit, reg, &rval64, CUT_THROUGH_OKf, 2);
   1520         SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1521     }
   1522 
   1523     COMPILER_64_ZERO(rval64);
   1524     reg = obm_fc_config_regs[obm];
   1525 
   1526     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1527     soc_reg64_field32_set(unit, reg, &rval64, XOFF_REFRESH_TIMERf, 256);
   1528     soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, lossless ? 1 : 0);
   1529     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, lossless ? 1 : 0);
   1530     soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, 
   1531             lossless ? 65535 : 0);
   1532     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1533 
   1534     COMPILER_64_ZERO(rval64);
   1535     reg = obm_bank_config_regs[obm];
   1536 
   1537     SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, subport, &rval64));
   1538     soc_reg64_field32_set(unit, reg, &rval64, BANK_DISCARD_THRESHOLDf, 760);
   1539     SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, subport, rval64));
   1540 
   1541     rval32 = 0;
   1542     reg =  obm_ctrl_regs[obm];
   1543     port_osub = 1;
   1544 
   1545     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &rval32));
   1546     soc_reg_field_set(unit, reg, &rval32, obm_oversub_fields[subport], port_osub);
   1547     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, rval32));
   1548 
   1549     if (lossless) {
   1550         mem = obm_pri_map_port_mem[(phy_port - 1) % MONTEREY_PORTS_PER_PGW];
   1551         sal_memset(&entry, 0, sizeof(entry));
   1552         SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_get(unit, mem, pgw, &entry));
   1553         for (index = 0; index < COUNTOF(offset_ob_prio); index++) {
   1554             soc_mem_field32_set(unit, mem, &entry, offset_ob_prio[index], 2);
   1555         }
   1556         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry));
   1557         SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_set(unit, mem, pgw, &entry));
   1558     } else if (IS_ROE_ENABLED(unit)) { 
   1559         mem = obm_pri_map_port_mem[(phy_port - 1) % MONTEREY_PORTS_PER_PGW];
   1560         sal_memset(&entry, 0, sizeof(entry));
   1561         SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_get(unit, mem, pgw, &entry));
   1562 
   1563         for (index = 0; index < COUNTOF(offset_ob_prio); index++) {
   1564              if (IS_CPRI_PORT(unit,port)) {
   1565                           soc_mem_field32_set(unit, mem, &entry,
   1566                                               offset_ob_prio[index], 4);
   1567              } else if ((index == 1 ||  index == 2 || index == 3 )) {
   1568                  if (index == 3) {
   1569                      soc_mem_field32_set(unit, mem, &entry,
   1570                                          offset_ob_prio[index], 1);
   1571                  } else {
   1572                      if (!SOC_PBMP_MEMBER(pbmp_xport_roe_mcu, port)) {
   1573                          soc_mem_field32_set(unit, mem, &entry,
   1574                          offset_ob_prio[index], 4);
   1575                      }
   1576                  }
   1577              }   
   1578         }
   1579         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, PGW_CL_BLOCK(unit, pgw), 0, &entry));
   1580         SOC_IF_ERROR_RETURN(soc_monterey_shadow_entry_set(unit, mem, pgw, &entry));
   1581     }
   1582 
   1583     return SOC_E_NONE;
   1584 }
   1585 STATIC int
   1586 _soc_monterey_port_blk_ca_mode_set(int unit, int flexport, int xlp)
   1587 {
   1588     int rv;
   1589     soc_reg_t reg;
   1590     int ca_port_mode = 0;
   1591     int pgw_inst;
   1592     uint32 r32val0, r32val1;
   1593 
   1594     static const soc_reg_t obm_ca_ctrl_regs[] = {
   1595         IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr,
   1596         IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr,
   1597         IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 
   1598     };
   1599 
   1600     /* Calculate the mode of the Cell Assembly for the port block */
   1601     rv = soc_monterey_port_ca_mode_get(unit, flexport, xlp, &ca_port_mode);
   1602     SOC_IF_ERROR_RETURN(rv);
   1603 
   1604     r32val0 = 0;
   1605     reg = obm_ca_ctrl_regs[xlp % MONTEREY_TSCS_PER_PGW];
   1606     pgw_inst = ((xlp / MONTEREY_TSCS_PER_PGW) | SOC_REG_ADDR_INSTANCE_MASK);
   1607     /* Debug output */
   1608     LOG_VERBOSE(BSL_LS_SOC_PORT,
   1609                 (BSL_META_U(unit,
   1610                             "Port Block CellAssembly Mode: "
   1611                             "xlp=%d  pgw=%d reg=%s ca_mode=%d \n"),
   1612                  xlp, (xlp / MONTEREY_TSCS_PER_PGW), SOC_REG_NAME(unit, reg), ca_port_mode));
   1613 
   1614 
   1615     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pgw_inst, 0, &r32val0));
   1616     soc_reg_field_set(unit, reg, &r32val0, PORT_MODEf, ca_port_mode);
   1617     r32val1 = r32val0;
   1618     if (!flexport) {
   1619         soc_reg_field_set(unit, reg, &r32val0, PORT0_RESETf, 1);
   1620         soc_reg_field_set(unit, reg, &r32val0, PORT1_RESETf, 1);
   1621         soc_reg_field_set(unit, reg, &r32val0, PORT2_RESETf, 1);
   1622         soc_reg_field_set(unit, reg, &r32val0, PORT3_RESETf, 1);
   1623 
   1624         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val0));
   1625     }
   1626     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pgw_inst, 0, r32val1));
   1627 
   1628     return SOC_E_NONE;
   1629 }
   1630 
   1631 int
   1632 soc_monterey_idb_init(int unit)
   1633 {
   1634     int rv;
   1635     int lossless;
   1636     soc_port_t port;
   1637     int xlp, blk_index;
   1638     soc_block_t port_blocks[] = {SOC_BLK_XLPORT, 
   1639                                  SOC_BLK_CLPORT,
   1640                                  SOC_BLOCK_TYPE_INVALID};
   1641 
   1642     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
   1643     /* Per-port settings */
   1644     PBMP_ALL_ITER(unit, port) {
   1645         SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, FALSE, lossless, port));
   1646     }
   1647 
   1648     SOC_BLOCKS_ITER(unit, blk_index, port_blocks) {
   1649         port = SOC_BLOCK_PORT(unit, blk_index);
   1650         xlp = SOC_INFO(unit).port_serdes[port];
   1651         rv = _soc_monterey_port_blk_ca_mode_set(unit, FALSE, xlp);
   1652         SOC_IF_ERROR_RETURN(rv);
   1653     }
   1654 
   1655     return SOC_E_NONE;
   1656 }
   1657 
   1658 
   1659 STATIC int
   1660 soc_mn_mmu_delay_insertion_set (int unit, int port)
   1661 {
   1662     int phy_port, mmu_port;    
   1663     int val = 0;
   1664     uint32 rval;
   1665     soc_info_t *si;
   1666 
   1667     si = &SOC_INFO(unit);      
   1668 
   1669     phy_port = si->port_l2p_mapping[port];
   1670     mmu_port = si->port_p2m_mapping[phy_port];
   1671 
   1672 
   1673     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, 
   1674                 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, &rval));
   1675 
   1676     if (IS_OVERSUB_PORT(unit, port ) && si->port_speed_max[port] >= 20000) {
   1677         val = 120 + (sal_rand() % 20);
   1678     } else {
   1679         /* linerate port or OS with < 20G */
   1680     }
   1681     soc_reg_field_set(unit, ES_PIPE0_MMU_3DBG_Cr, &rval, FIELD_Af, val);
   1682 
   1683     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, 
   1684                 ES_PIPE0_MMU_3DBG_Cr, REG_PORT_ANY, mmu_port, rval));
   1685 
   1686     return SOC_E_NONE;
   1687 }
   1688 
   1689 
   1690 STATIC int
   1691 _soc_monterey_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1692                             soc_reg_t group_reg, uint64 *group_rval,
   1693                             const _soc_monterey_ser_info_t *info_list,
   1694                             soc_mem_t mem, int enable);
   1695 
   1696 STATIC int
   1697 _soc_monterey_ser_enable_mmu_1bit_ecc (int unit, int enable)
   1698 {
   1699     int i, f;
   1700     uint64 rval64;
   1701     uint32 rval;
   1702     soc_field_info_t *fieldp;
   1703     soc_reg_info_t   *regp;
   1704     soc_reg_t reg;
   1705     
   1706     soc_reg_t _1b_reg_list[] = {
   1707         CFAP_EN_COR_ERR_RPTr,
   1708         MMU_DEQ_EN_COR_ERR_RPTr,
   1709         MMU_ENQ_EN_COR_ERR_RPTr,
   1710         MMU_EPRG_EN_COR_ERR_RPTr,
   1711         INTFI_EN_COR_ERR_RPTr,
   1712         MMU_PQE_EN_COR_ERR_RPTr,
   1713         RQE_EN_COR_ERR_RPTr,
   1714         MMU_TDM_EN_COR_ERR_RPTr,
   1715         THDI_EN_COR_ERR_RPTr,
   1716         MMU_THDM_DB_EN_COR_ERR_RPTr,
   1717         MMU_THDM_MCQE_EN_COR_ERR_RPTr,
   1718         MMU_THDU_EN_COR_ERR_RPTr,
   1719         MMU_TOQ_EN_COR_ERR_RPTr,
   1720         HSP_EN_COR_ERR_RPTr
   1721     };
   1722     for (i = 0; i < COUNTOF(_1b_reg_list); i++) {
   1723         reg = _1b_reg_list[i];
   1724         regp = &(SOC_REG_INFO(unit, reg));
   1725         if (SOC_REG_IS_64(unit, reg)) {
   1726             SOC_IF_ERROR_RETURN
   1727                 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64));
   1728             for (f = 0; f < regp->nFields; f++) {
   1729                 fieldp = &(regp->fields[f]);
   1730                 soc_reg64_field32_set(unit, reg, &rval64, fieldp->field,
   1731                                       enable ? 1 : 0);
   1732             }
   1733             SOC_IF_ERROR_RETURN
   1734                 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64));
   1735         } else {
   1736             SOC_IF_ERROR_RETURN
   1737                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1738             for (f = 0; f < regp->nFields; f++) {
   1739                 fieldp = &(regp->fields[f]);
   1740                 soc_reg_field_set(unit, reg, &rval, fieldp->field,
   1741                                   enable ? 1 : 0);
   1742             }
   1743             SOC_IF_ERROR_RETURN
   1744                 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1745         }
   1746     }
   1747 
   1748     return SOC_E_NONE;
   1749 }
   1750 
   1751 
   1752 #ifdef INCLUDE_XFLOW_MACSEC
   1753 STATIC int
   1754 _soc_monterey_macsec_ser_enable (int unit, int enable)
   1755 {
   1756 #ifdef BCM_56670_B0
   1757     int i;
   1758     uint32 rval;
   1759     soc_reg_t reg;
   1760     soc_field_t field;
   1761     _soc_mem_ser_en_info_t * macsec_mem_ser_info = _soc_bcm56670_b0_macsec_mem_ser_info;
   1762 
   1763     for (i = 0; macsec_mem_ser_info[i].mem != INVALIDm; i++) {
   1764         reg = macsec_mem_ser_info[i].en_ctrl.ctrl_type.en_reg;
   1765         field = macsec_mem_ser_info[i].en_ctrl.en_fld;
   1766         SOC_IF_ERROR_RETURN
   1767             (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1768         soc_reg_field_set(unit, reg, &rval, field,
   1769                 enable ? 0 : 1);
   1770         SOC_IF_ERROR_RETURN
   1771             (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1772         LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1773                         "SER enable for: %s\n"),
   1774                     SOC_MEM_NAME(unit, macsec_mem_ser_info[i].mem)));
   1775 
   1776     }
   1777 #endif
   1778     return SOC_E_NONE;
   1779 }
   1780 #endif
   1781 
   1782 STATIC int
   1783 _soc_monterey_ser_enable_info(int unit, int block_info_idx, int inst, int port,
   1784                             soc_reg_t group_reg, uint64 *group_rval,
   1785                             const _soc_monterey_ser_info_t *info_list,
   1786                             soc_mem_t mem, int enable)
   1787 {
   1788     const _soc_monterey_ser_info_t *info;
   1789     int info_index, rv, rv1;
   1790     soc_reg_t reg;
   1791     uint32 rval;
   1792     uint64 rval64, mac_err_mask;
   1793 #ifdef INCLUDE_XFLOW_MACSEC
   1794     uint8 parity_enable = 0;
   1795 #endif
   1796 
   1797     rv = SOC_E_NOT_FOUND;
   1798 
   1799     /* Loop through each info entry in the list */
   1800     for (info_index = 0; ; info_index++) {
   1801         info = &info_list[info_index];
   1802         if (info->type == _SOC_PARITY_TYPE_NONE) {
   1803             /* End of table */
   1804             break;
   1805         }
   1806 
   1807         if (mem != INVALIDm && info->mem != mem) {
   1808             continue;
   1809         }
   1810 
   1811         rv = SOC_E_NONE;
   1812 
   1813         /* Enable the info entry in the group register */
   1814         if (info->group_reg_enable_field != INVALIDf) {
   1815             soc_reg64_field32_set(unit, group_reg, group_rval,
   1816                                   info->group_reg_enable_field, enable ? 1 : 0);
   1817         }
   1818 
   1819         /* Handle different parity error reporting style */
   1820         switch (info->type) {
   1821         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   1822         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   1823         case _SOC_PARITY_TYPE_MAC_RX_TS:
   1824             COMPILER_64_SET(mac_err_mask, 0, 0x7800);
   1825             if (info->group_reg_enable_field == INVALIDf) {
   1826                 COMPILER_64_OR(*group_rval, mac_err_mask);
   1827             }
   1828             /* fall through */
   1829         case _SOC_PARITY_TYPE_ECC:
   1830         case _SOC_PARITY_TYPE_PARITY:
   1831             reg = info->enable_reg;
   1832             if (!SOC_REG_IS_VALID(unit, reg)) {
   1833                 break;
   1834             }
   1835             if (SOC_REG_IS_64(unit, reg)) {
   1836                 SOC_IF_ERROR_RETURN
   1837                     (soc_reg_get(unit, reg, port, 0, &rval64));
   1838                 soc_reg64_field32_set(unit, reg, &rval64, info->enable_field,
   1839                                       enable ? 1 : 0);
   1840                 SOC_IF_ERROR_RETURN
   1841                     (soc_reg_set(unit, reg, port, 0, rval64));
   1842             } else {
   1843                 SOC_IF_ERROR_RETURN
   1844                     (soc_reg32_get(unit, reg, port, 0, &rval));
   1845                 soc_reg_field_set(unit, reg, &rval, info->enable_field,
   1846                                   enable ? 1 : 0);
   1847                 SOC_IF_ERROR_RETURN
   1848                     (soc_reg32_set(unit, reg, port, 0, rval));
   1849             }
   1850             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1851                         "SER enable for: %s\n"),
   1852                         (info->mem == INVALIDm) ? info->mem_str : 
   1853                         SOC_MEM_NAME(unit, info->mem)));
   1854             break;
   1855         case _SOC_PARITY_TYPE_MMU_SER:
   1856             rv1 = _soc_monterey_ser_enable_mmu_1bit_ecc(unit, enable);
   1857             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1858                 return rv;
   1859             }
   1860             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1861                         "SER enable for: %s\n"), 
   1862                         (info->mem == INVALIDm) ? info->mem_str : 
   1863                         SOC_MEM_NAME(unit, info->mem)));
   1864             break;
   1865 #ifdef INCLUDE_XFLOW_MACSEC
   1866         case _SOC_PARITY_TYPE_MACSEC_SER:
   1867             parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
   1868             if (info->group_reg_enable_field != INVALIDf) {
   1869                 soc_reg64_field32_set(unit, group_reg, group_rval,
   1870                                       info->group_reg_enable_field, (enable & parity_enable) ? 1 : 0);
   1871             }
   1872             rv1 = _soc_monterey_macsec_ser_enable(unit, (enable & parity_enable) ? 1 : 0);
   1873             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   1874                 return rv;
   1875             }
   1876             break;
   1877 #endif
   1878         case _SOC_PARITY_TYPE_GENERIC:
   1879         case _SOC_PARITY_TYPE_START_ERR:
   1880         case _SOC_PARITY_TYPE_BST:
   1881             LOG_VERBOSE(BSL_LS_SOC_SOCMEM, (BSL_META_U(unit,
   1882                         "SER enable for: %s\n"),
   1883                         (info->mem == INVALIDm) ? info->mem_str : 
   1884                         SOC_MEM_NAME(unit, info->mem)));
   1885         default:
   1886             break;
   1887         } /* Handle different parity error reporting style */
   1888         if (mem != INVALIDm) {
   1889             break;
   1890         }
   1891 
   1892     } /* Loop through each info entry in the route block */
   1893 
   1894     return rv;
   1895 }
   1896 
   1897 STATIC int
   1898 _soc_monterey_pm_cpri_intr_enable(int unit, int enable)
   1899 {
   1900     uint32    cmic_rval = 0, cmic_bit = 0;
   1901     int       rbi;
   1902     const _soc_monterey_pm_cpri_intr_info_t *rb;
   1903 
   1904     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval));
   1905 
   1906     for (rbi = 0; ; rbi++) {
   1907          rb = &_soc_monterey_pm_cpri_intr_info_irq4[rbi];
   1908         cmic_bit = rb->cmic_bit;
   1909         if (cmic_bit == 0) {
   1910             /* End of table */
   1911             break;
   1912         }
   1913 
   1914         if (enable) {
   1915             cmic_rval |= cmic_bit;
   1916         }
   1917 
   1918     } /* end of rbi for */
   1919 
   1920     if (enable) {
   1921         /* Write CMIC enable register */
   1922         (void)soc_cmicm_intr4_enable(unit, cmic_rval);
   1923     } else {
   1924         /* Write CMIC disable register */
   1925         (void)soc_cmicm_intr4_disable(unit, cmic_rval);
   1926     }
   1927 
   1928     return SOC_E_NONE;
   1929 }
   1930 #ifdef INCLUDE_XFLOW_MACSEC
   1931 STATIC int
   1932 _soc_monterey_macsec_intr_enable (int unit, int enable)
   1933 {
   1934     uint32    cmic_rval = 0, cmic_bit = 0;
   1935     uint64    rval64;
   1936     int       rbi, rv = SOC_E_NONE;
   1937     const _soc_monterey_ser_route_block_t   *rb;
   1938 
   1939     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval));
   1940 
   1941     for (rbi = 0; ; rbi++) {
   1942          rb = &_soc_monterey_macsec_ser_route_blocks_irq4[rbi];
   1943         cmic_bit = rb->cmic_bit;
   1944         if (cmic_bit == 0) {
   1945             /* End of table */
   1946             break;
   1947         }
   1948         if (rb->info == NULL) {
   1949             continue;
   1950         }
   1951         if (enable) {
   1952             cmic_rval |= cmic_bit;
   1953         }
   1954 
   1955         if (rb->enable_reg != INVALIDr) {
   1956             SOC_IF_ERROR_RETURN
   1957                 (soc_reg_get(unit, rb->enable_reg, REG_PORT_ANY, 0, &rval64));
   1958 
   1959             rv = _soc_monterey_ser_enable_info(unit, 0, rb->id, REG_PORT_ANY,
   1960                                          rb->enable_reg, &rval64,
   1961                                          rb->info, INVALIDm, enable);
   1962         }
   1963         if (rv == SOC_E_NOT_FOUND) {
   1964             continue;
   1965         } else if (SOC_FAILURE(rv)) {
   1966             return rv;
   1967         }
   1968 
   1969         if (rb->enable_reg != INVALIDr) {
   1970             /* Write per route block parity enable register */
   1971             SOC_IF_ERROR_RETURN
   1972                 (soc_reg_set(unit, rb->enable_reg, REG_PORT_ANY, 0, rval64));
   1973         }
   1974     } /* end of rbi for */
   1975 
   1976     if (enable) {
   1977         /* Write CMIC enable register */
   1978         (void)soc_cmicm_intr4_enable(unit, cmic_rval);
   1979     } else {
   1980         /* Write CMIC disable register */
   1981         (void)soc_cmicm_intr4_disable(unit, cmic_rval);
   1982     }
   1983 
   1984     return SOC_E_NONE;
   1985 }
   1986 #endif
   1987 
   1988 STATIC int
   1989 _soc_monterey_ser_enable_pm (int unit, int enable)
   1990 {
   1991     uint32    cmic_rval = 0, cmic_bit = 0;
   1992     uint64    rval64;
   1993     int       rbi, block_info_idx, port, rv = SOC_E_NONE;
   1994     const _soc_monterey_ser_route_block_t   *rb;
   1995     
   1996     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK4r(unit, &cmic_rval));
   1997 
   1998     for (rbi = 0; ; rbi++) {
   1999          rb = &_soc_monterey_ser_route_blocks_irq4[rbi];
   2000         cmic_bit = rb->cmic_bit;
   2001         if (cmic_bit == 0) {
   2002             /* End of table */
   2003             break;
   2004         }
   2005         if (rb->info == NULL) {
   2006             continue;
   2007         }
   2008         if (enable) {
   2009             cmic_rval |= cmic_bit;
   2010         }
   2011         port = INVALID_PORT;
   2012         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   2013             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   2014                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   2015                 break;
   2016             }
   2017         }
   2018 
   2019         if (port == INVALID_PORT) {
   2020             continue;
   2021         }
   2022 
   2023         if (rb->enable_reg != INVALIDr) {
   2024             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   2025                                   SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   2026                     /* This port block is not configured */
   2027                     continue;
   2028             }
   2029             SOC_IF_ERROR_RETURN
   2030                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64));
   2031 
   2032             rv = _soc_monterey_ser_enable_info(unit, block_info_idx, rb->id, port,
   2033                                          rb->enable_reg, &rval64,
   2034                                          rb->info, INVALIDm, enable);
   2035         }
   2036         if (rv == SOC_E_NOT_FOUND) {
   2037             continue;
   2038         } else if (SOC_FAILURE(rv)) {
   2039             return rv;
   2040         }
   2041 
   2042         if (rb->enable_reg != INVALIDr) {
   2043             /* Write per route block parity enable register */
   2044             SOC_IF_ERROR_RETURN
   2045                 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64));
   2046         }
   2047     } /* end of rbi for */
   2048 
   2049     if (enable) {
   2050         /* Write CMIC enable register */
   2051         (void)soc_cmicm_intr4_enable(unit, cmic_rval);
   2052     } else {
   2053         /* Write CMIC disable register */
   2054         (void)soc_cmicm_intr4_disable(unit, cmic_rval);
   2055     }
   2056 
   2057     return SOC_E_NONE;
   2058 }
   2059 
   2060 STATIC int
   2061 _soc_monterey_l3_mem_sram_info_get(int unit, int *base, int *count,
   2062                                  soc_mem_t *view,
   2063                                  int mem_index[][_SOC_SER_MAX_ENTRIES_PER_BKT])
   2064 {
   2065     int i, j, base_index;
   2066     int copyno;
   2067     uint8 *vmap;
   2068     uint32 *cache;
   2069     struct mem_list_s {
   2070         soc_mem_t mem;         /* view name */
   2071         int       ram_count;   /* Num of entries in the bucket */
   2072         int       entry_count; /* Num of writes to correct LP memory */
   2073     };
   2074     struct mem_list_s mem_list[] = {
   2075         /*
   2076          * If the hash bucket corresponding to the error LP index has
   2077          * all single wide entries, it is sufficient to write any of the one
   2078          * entry to hardware and the LP memory would be fixed in HW.
   2079          * For double wide entries also writing one entry would be sufficient
   2080          * to clear the error on the LP entry but for some keys we need to write
   2081          * all the entries (2) in the bucket for the LP memory to be fixed.
   2082          * For quad wide, anyway a single entry correction would fix the LP memory
   2083          * error because the QW entry touches all the physical entries in
   2084          * the bucket.
   2085          */
   2086         {L3_ENTRY_IPV4_UNICASTm,   4, 1},
   2087         {L3_ENTRY_IPV4_MULTICASTm, 2, 2},
   2088         {L3_ENTRY_IPV6_UNICASTm,   2, 2},
   2089         {L3_ENTRY_IPV6_MULTICASTm, 1, 1}
   2090     };
   2091     view[0] = view[1] = INVALIDm;
   2092     for (i = 0; i < COUNTOF(mem_list); i++) {
   2093         copyno = SOC_MEM_BLOCK_ANY(unit, mem_list[i].mem);
   2094         cache = SOC_MEM_STATE(unit, mem_list[i].mem).cache[copyno];
   2095         vmap = SOC_MEM_STATE(unit, mem_list[i].mem).vmap[copyno];
   2096         if (mem_list[i].mem == L3_ENTRY_IPV4_UNICASTm) {
   2097             /*
   2098              * Each LP memory index corresponds to 4 single wide entries.
   2099              * The ISS (shared) region will start after the dedicated region.
   2100              */
   2101             base_index = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 4)
   2102                          + (*base * 4);
   2103         } else if ((mem_list[i].mem == L3_ENTRY_IPV4_MULTICASTm) ||
   2104                    (mem_list[i].mem == L3_ENTRY_IPV6_UNICASTm)) {
   2105             /*
   2106              * Each LP memory index corresponds to 2 double wide entries.
   2107              * The ISS (shared) region will start after the dedicated region.
   2108              */
   2109             base_index = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 2)
   2110                          + (*base * 2);
   2111         } else {
   2112             /*
   2113              * Each LP memory index corresponds to 1 quad wide entry.
   2114              * The ISS (shared) region will start after the dedicated region.
   2115              */
   2116             base_index = soc_mem_index_count(unit, L3_ENTRY_LPm) + *base;
   2117         }
   2118 
   2119         for (j = 0; j < mem_list[i].ram_count; j++) {
   2120             if ((cache != NULL) && (vmap != NULL) &&
   2121                 (CACHE_VMAP_TST(vmap, base_index+j))) {
   2122                 if ((mem_list[i].mem == L3_ENTRY_IPV4_UNICASTm) ||
   2123                     (mem_list[i].mem == L3_ENTRY_IPV6_MULTICASTm)) {
   2124                     view[0] = mem_list[i].mem;
   2125                     *count = mem_list[i].entry_count;
   2126                     mem_index[0][0] = base_index;
   2127                 } else {
   2128                     view[j] = mem_list[i].mem;
   2129                     *count = mem_list[i].entry_count;
   2130                     mem_index[j][0] = base_index+j;
   2131                 }
   2132             }
   2133         }
   2134         if (*count == 1) {
   2135             break;
   2136         }
   2137     }
   2138     /*
   2139      * For double wide views, if only one entry is valid in a given bucket,
   2140      * the other entry in the same bucket also needs to be written (any double
   2141      * wide view is fine because we will be writing null-entry anyway).
   2142      * Using the same view as its neighbor here. The index for the view is
   2143      * either +1 or -1 based on the original base_index. E.g., if the base_index
   2144      * is 2048, the correction indexes would be 2048 (with the orig entry data)
   2145      * and 2049 (with null-entry). If the base_index is 2049, the correction
   2146      * indexes would be 2049 (with the orig entry data) and 2048 (with
   2147      * null-entry).
   2148      */
   2149     if (*count == 2) {
   2150         if ((view[0] == INVALIDm) && (view[1] != INVALIDm)) {
   2151             view[0] = view[1];
   2152             mem_index[0][0] = mem_index[1][0] - 1;
   2153         } else if ((view[1] == INVALIDm) && (view[0] != INVALIDm)) {
   2154             view[1] = view[0];
   2155             mem_index[1][0] = mem_index[0][0] + 1;
   2156         }
   2157     }
   2158     if (!(*count)) {
   2159         /* Default view as L3_ENTRY_IPV4_UNICASTm */
   2160         view[0] = mem_list[0].mem;
   2161         *count = mem_list[0].entry_count;
   2162         mem_index[0][0] = (soc_mem_index_count(unit, L3_ENTRY_LPm) * 4)
   2163                           + (*base * 4);
   2164     }
   2165     return SOC_E_NONE;
   2166 }
   2167 
   2168 STATIC int
   2169 _soc_monterey_ser_enable_all (int unit, int enable)
   2170 {
   2171     uint8                                 rbi, bcount, type;
   2172     uint16                                pcount;
   2173     uint32                                cmic_rval;
   2174     uint32                                rval, cmic_bit;
   2175     int                                   port = REG_PORT_ANY;
   2176     int                                   rv, block_info_idx;
   2177     uint64                                rval64;
   2178     soc_reg_t                             reg, ecc1b_reg;
   2179     soc_field_t                           field, ecc1b_field;
   2180     _soc_reg_ser_en_info_t                *reg_info;
   2181     _soc_mem_ser_en_info_t                *mem_info;
   2182     _soc_bus_ser_en_info_t                *bus_info;
   2183     _soc_buffer_ser_en_info_t             *buf_info;
   2184     char                                  *str_type;
   2185     char                                  *str_name;
   2186     const _soc_monterey_ser_route_block_t   *rb;
   2187     const _soc_monterey_ser_block_info_t    *ser_block_info;
   2188     static char *parity_module_str[4]     = {"REG", "MEM", "BUS", "BUF"};
   2189     int done = 0;
   2190 
   2191     /* coverity[result_independent_of_operands] */
   2192     SOC_IF_ERROR_RETURN(READ_CMIC_CMC0_PCIE_IRQ_MASK3r(unit, &cmic_rval));
   2193 
   2194     /* Enable new fifo mechanism based SER stuff */
   2195     ser_block_info = _soc_monterey_ser_block_info;
   2196     for (bcount = 0; ser_block_info[bcount].blocktype; bcount++) {
   2197         done = 0; 
   2198         if (SOC_BLK_MACSEC == ser_block_info[bcount].blocktype) {
   2199             continue;
   2200         }
   2201 
   2202         LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   2203                    (BSL_META_U(unit,
   2204                                "Unit %d SER enable for: %s\n"),
   2205                                     unit, ser_block_info[bcount].name));
   2206 
   2207         type = ser_block_info[bcount].type;
   2208         reg_info = (_soc_reg_ser_en_info_t*)ser_block_info[bcount].info;
   2209         mem_info = (_soc_mem_ser_en_info_t*)ser_block_info[bcount].info;
   2210         bus_info = (_soc_bus_ser_en_info_t*)ser_block_info[bcount].info;
   2211         buf_info = (_soc_buffer_ser_en_info_t*)ser_block_info[bcount].info;
   2212         for (pcount = 0; ; pcount++) {
   2213             ecc1b_reg = INVALIDr;    
   2214             ecc1b_field = INVALIDf;
   2215             switch (type) {
   2216             case _SOC_MONTEREY_SER_TYPE_REG: 
   2217                 if (reg_info[pcount].reg == INVALIDr) { 
   2218                     done = 1;
   2219                 } else {
   2220                     reg = reg_info[pcount].en_ctrl.ctrl_type.en_reg;
   2221                     field = reg_info[pcount].en_ctrl.en_fld;
   2222                     str_name = SOC_REG_NAME(unit, reg_info[pcount].reg);
   2223                 }
   2224                 break;
   2225             case _SOC_MONTEREY_SER_TYPE_MEM:
   2226                 if (mem_info[pcount].mem == INVALIDm) { 
   2227                     done = 1;
   2228                 } else {
   2229                     if (soc_feature(unit, soc_feature_parity_injection_l2)) {
   2230                         if ((mem_info[pcount].mem == L2_USER_ENTRYm) ||
   2231                             (mem_info[pcount].mem == L2_USER_ENTRY_DATA_ONLYm)){ 
   2232                             continue;
   2233                         }
   2234                     }
   2235                     if (SOC_MEM_INFO(unit, mem_info[pcount].mem).flags & 
   2236                         SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP) {
   2237                         continue;
   2238                     }
   2239                     reg = mem_info[pcount].en_ctrl.ctrl_type.en_reg;
   2240                     field = mem_info[pcount].en_ctrl.en_fld;
   2241                     ecc1b_reg = mem_info[pcount].ecc1b_ctrl.ctrl_type.en_reg;
   2242                     ecc1b_field = mem_info[pcount].ecc1b_ctrl.en_fld;
   2243                     str_name = SOC_MEM_NAME(unit, mem_info[pcount].mem);
   2244                 }
   2245                 break;
   2246             case _SOC_MONTEREY_SER_TYPE_BUS:
   2247                 if (bus_info[pcount].en_reg == INVALIDr) { 
   2248                     done = 1;
   2249                 } else {
   2250                     reg = bus_info[pcount].en_reg;
   2251                     field = bus_info[pcount].en_fld;
   2252                     str_name = bus_info[pcount].bus_name;
   2253                 }
   2254                 break;
   2255             case _SOC_MONTEREY_SER_TYPE_BUF:
   2256                 if (buf_info[pcount].en_reg == INVALIDr) {
   2257                     done = 1;
   2258                 } else {
   2259                     reg = buf_info[pcount].en_reg;
   2260                     field = buf_info[pcount].en_fld;
   2261                     str_name = buf_info[pcount].buffer_name;
   2262                 }
   2263                 break;
   2264             default:
   2265                 LOG_ERROR(BSL_LS_SOC_MEM,
   2266                           (BSL_META_U(unit,
   2267                                       "Unknown parity module [bcount: %d][pcount: %d].\n"),
   2268                                        bcount, pcount));
   2269                 return SOC_E_INTERNAL;
   2270             }
   2271             if (done) { 
   2272                 break;
   2273             } else {
   2274                 str_type = parity_module_str[type];
   2275             }
   2276             /* NOTE: Do not use the field modify routine in the following as
   2277                      some regs do not return the correct value due to which the
   2278                      modify routine skips the write */
   2279             if (SOC_REG_IS_64(unit, reg)) {
   2280                 SOC_IF_ERROR_RETURN
   2281                     (soc_reg_get(unit, reg, port, 0, &rval64));
   2282                 soc_reg64_field32_set(unit, reg, &rval64, field, enable ? 1 : 0);
   2283                 SOC_IF_ERROR_RETURN
   2284                     (soc_reg_set(unit, reg, port, 0, rval64));
   2285             } else {
   2286                 SOC_IF_ERROR_RETURN
   2287                     (soc_reg32_get(unit, reg, port, 0, &rval));
   2288                 soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   2289                 SOC_IF_ERROR_RETURN
   2290                     (soc_reg32_set(unit, reg, port, 0, rval));
   2291             }
   2292             if (ecc1b_reg != INVALIDr && ecc1b_field != INVALIDf) {
   2293                 if (SOC_REG_IS_64(unit, ecc1b_reg)) {
   2294                     SOC_IF_ERROR_RETURN
   2295                         (soc_reg_get(unit, ecc1b_reg, port, 0, &rval64));
   2296                     soc_reg64_field32_set(unit, ecc1b_reg, &rval64, ecc1b_field, enable ? 1 : 0);
   2297                     SOC_IF_ERROR_RETURN
   2298                         (soc_reg_set(unit, ecc1b_reg, port, 0, rval64));
   2299                 } else {
   2300                     SOC_IF_ERROR_RETURN
   2301                         (soc_reg32_get(unit, ecc1b_reg, port, 0, &rval));
   2302                     soc_reg_field_set(unit, ecc1b_reg, &rval, ecc1b_field, enable ? 1 : 0);
   2303                     if (20 == SOC_REG_ACC_TYPE(unit, ecc1b_reg)) {
   2304                         SOC_IF_ERROR_RETURN(
   2305                             soc_reg32_set(unit, ecc1b_reg, \
   2306                                           SOC_REG_ADDR_INSTANCE_MASK, 0, rval));
   2307                     } else {
   2308                         SOC_IF_ERROR_RETURN
   2309                             (soc_reg32_set(unit, ecc1b_reg, port, 0, rval));
   2310                     }
   2311                 }
   2312             }
   2313             LOG_VERBOSE(BSL_LS_SOC_SOCMEM,
   2314                       (BSL_META_U(unit,
   2315                                   "SER enable for %s: %s\n"),
   2316                                    str_type, str_name));
   2317         }
   2318 
   2319         /* Loop through each place-and-route of block entry 
   2320          Handle entries with valid REG & FIELD values */
   2321         for (rbi = 0; ; rbi++) {
   2322             rb = &_soc_monterey_ser_route_blocks_irq3[rbi];
   2323             cmic_bit = rb->cmic_bit;
   2324             if (cmic_bit == 0) {
   2325                 /* End of table */
   2326                 break;
   2327             }
   2328             if (rb->blocktype == ser_block_info[bcount].blocktype) {
   2329                 cmic_rval |= cmic_bit;
   2330                 if (rb->enable_reg != INVALIDr && rb->enable_field != INVALIDf) {
   2331                     SOC_IF_ERROR_RETURN
   2332                         (soc_reg_field32_modify(unit, rb->enable_reg,
   2333                             REG_PORT_ANY, rb->enable_field, enable ? 1 : 0));
   2334                 }
   2335             }
   2336         }
   2337 
   2338         /* reset (toggle) fifo if applicable */
   2339         if (ser_block_info[bcount].fifo_reset_reg != INVALIDr) {
   2340             SOC_IF_ERROR_RETURN
   2341                  (soc_reg_field32_modify(unit,
   2342                      ser_block_info[bcount].fifo_reset_reg,
   2343                                          REG_PORT_ANY, FIFO_RESETf, 1));
   2344             SOC_IF_ERROR_RETURN
   2345                  (soc_reg_field32_modify(unit,
   2346                      ser_block_info[bcount].fifo_reset_reg,
   2347                                          REG_PORT_ANY, FIFO_RESETf, 0));
   2348         }
   2349     }
   2350 
   2351     /* Enable 1B error reporting for some special items */
   2352 
   2353     /* Description of IARB_EN_COR_ERR_RPT says, supress these errors
   2354      * by setting bits. So basically we are supressing error reporting
   2355      * by setting bits.
   2356      * Then again, following TD2P code...
   2357      */
   2358     SOC_IF_ERROR_RETURN
   2359          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 
   2360                                  REG_PORT_ANY, 
   2361                                  CMIC_BUFFER_1BIT_ERROR_REPORTf,enable?1:0));
   2362     SOC_IF_ERROR_RETURN
   2363          (soc_reg_field32_modify(unit, IARB_EN_COR_ERR_RPTr, 
   2364                                  REG_PORT_ANY, 
   2365                                  LEARN_FIFO_1BIT_ERROR_REPORTf, enable?1:0));
   2366 
   2367     /* Loop through each place-and-route block 
   2368        Handle entries with non-null INFO */
   2369     for (rbi = 0; ; rbi++) {
   2370         rb = &_soc_monterey_ser_route_blocks_irq3[rbi];
   2371         cmic_bit = rb->cmic_bit;
   2372         if (cmic_bit == 0) {
   2373             /* End of table */
   2374             break;
   2375         }
   2376         if (rb->info == NULL) {
   2377             continue;
   2378         }
   2379         if (enable) {
   2380             cmic_rval |= cmic_bit;
   2381         }
   2382 
   2383         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   2384             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   2385                     port = SOC_BLOCK_PORT(unit, block_info_idx);
   2386                     break;
   2387             }
   2388         }
   2389         if (rb->enable_reg != INVALIDr) {
   2390             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block,
   2391                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   2392                     /* This port block is not configured */
   2393                     continue;
   2394             }
   2395             SOC_IF_ERROR_RETURN
   2396                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rval64));
   2397         }
   2398 
   2399         rv = _soc_monterey_ser_enable_info(unit, block_info_idx, rb->id, port,
   2400                                          rb->enable_reg, &rval64,
   2401                                          rb->info, INVALIDm, enable);
   2402         if (rv == SOC_E_NOT_FOUND) {
   2403             continue;
   2404         } else if (SOC_FAILURE(rv)) {
   2405             return rv;
   2406         }
   2407 
   2408         if (rb->enable_reg != INVALIDr) {
   2409             /* Write per route block parity enable register */
   2410             SOC_IF_ERROR_RETURN
   2411                 (soc_reg_set(unit, rb->enable_reg, port, 0, rval64));
   2412         }
   2413     }
   2414 
   2415     if (enable) {
   2416         uint32 rval1;
   2417         /* MMU enables */
   2418 
   2419         SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1));
   2420         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0);
   2421         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   2422 
   2423         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2424 
   2425         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 0);
   2426         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2427 
   2428         soc_reg_field_set(unit, MISCCONFIGr, &rval, INIT_MEMf, 1);
   2429         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2430 
   2431         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */
   2432 
   2433         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1);
   2434         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   2435 
   2436         /* Write CMIC enable register */
   2437         (void)soc_cmicm_intr3_enable(unit, cmic_rval);
   2438     } else {
   2439         /* MMU disables */
   2440         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2441         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_ENf, 0);
   2442         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2443         SOC_IF_ERROR_RETURN(WRITE_PARITY_ENr(unit, 0));
   2444 
   2445         /* Write CMIC disable register */
   2446         (void)soc_cmicm_intr3_disable(unit, cmic_rval);
   2447     }
   2448 
   2449     SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_pm(unit,enable));
   2450 
   2451     return SOC_E_NONE;
   2452 }
   2453 
   2454 STATIC int
   2455 _soc_monterey_clear_mmu_memory(int unit, soc_mem_t mem)
   2456 {
   2457     int i, count;
   2458     static soc_mem_t mmu_mems[] = {
   2459         MMU_INTFI_XPIPE_FC_MAP_TBL0m,
   2460         MMU_INTFI_XPIPE_FC_MAP_TBL1m,
   2461         MMU_INTFI_XPIPE_FC_MAP_TBL2m
   2462     };
   2463 
   2464     count = COUNTOF(mmu_mems);
   2465     /* MMU mem clear to avoid SER issue */
   2466     for (i = 0; i < count; i++) {
   2467         if (mem != INVALIDm) {
   2468             if (mem == mmu_mems[i]) {
   2469                 SOC_IF_ERROR_RETURN
   2470                     (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2471                 break;
   2472             }
   2473         } else {
   2474             SOC_IF_ERROR_RETURN
   2475                 (soc_mem_clear(unit, mmu_mems[i], COPYNO_ALL, TRUE));
   2476         }
   2477     }
   2478     return SOC_E_NONE;
   2479 }
   2480 
   2481 static int _soc_mn_num_shared_alpm_banks[SOC_MAX_NUM_DEVICES] = {0};
   2482 static soc_mem_t *_soc_monterey_alpm_bkt_view_map[SOC_MAX_NUM_DEVICES];
   2483 #define _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks)    ((num_uft_banks == 4) ? 0xFFFF : 0x7FFF)
   2484 #define _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)   ((num_uft_banks == 4) ? 16 : 15)
   2485 
   2486 int
   2487 _soc_monterey_mem_sram_info_get (int unit, soc_mem_t mem, int index,
   2488                                _soc_ser_sram_info_t *sram_info)
   2489 {
   2490     int i,  base,  offset ;
   2491     int entries_per_ram = 0,  contiguous = 0;
   2492 
   2493     sram_info->disable_reg = INVALIDr;
   2494     sram_info->disable_field = INVALIDf;
   2495     sram_info->force_reg = INVALIDr;
   2496     sram_info->force_field = INVALIDf;
   2497 
   2498     switch (mem) {
   2499     case L2Xm:
   2500     case L2_ENTRY_ONLY_ECCm:
   2501         if (mem == L2Xm) {
   2502             sram_info->disable_reg = L2_ENTRY_PARITY_CONTROLr;
   2503             sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2504         }
   2505 
   2506             sram_info->ram_count = SOC_MONTEREY_NUM_EL_L2;
   2507             entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L2_BANK;
   2508             offset = index % entries_per_ram;
   2509             base = offset;
   2510             if (index >= SOC_MONTEREY_NUM_ENTRIES_PER_L2_BANK) {
   2511                 base = offset + SOC_MONTEREY_NUM_ENTRIES_PER_L2_BANK;
   2512             }
   2513         break;
   2514     case L3_ENTRY_ONLYm:
   2515     case L3_ENTRY_IPV4_UNICASTm:
   2516     case L3_ENTRY_IPV4_MULTICASTm:
   2517     case L3_ENTRY_IPV6_UNICASTm:
   2518     case L3_ENTRY_IPV6_MULTICASTm:
   2519     case L3_ENTRY_ONLY_ECCm:
   2520             sram_info->ram_count = 4;
   2521             entries_per_ram = 2048;
   2522             base = index;
   2523         break;
   2524 
   2525     case VLAN_MACm:
   2526     case VLAN_XLATEm:
   2527     case VLAN_XLATE_ECCm:
   2528         contiguous = 1;
   2529         sram_info->disable_reg = VLAN_XLATE_DBGCTRL_0r;
   2530         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2531         sram_info->force_reg = VLAN_XLATE_DBGCTRL_0r;
   2532         sram_info->force_field = FORCE_XOR_GENf;
   2533         sram_info->ram_count = SOC_MONTEREY_NUM_EL_VLAN_XLATE;
   2534         base = (index/4) * 4;
   2535         break;
   2536     case EGR_VLAN_XLATEm:
   2537     case EGR_VLAN_XLATE_ECCm:
   2538         contiguous = 1;
   2539         sram_info->disable_reg = EGR_VLAN_XLATE_CONTROLr;
   2540         sram_info->disable_field = DISABLE_SBUS_MEMWR_PARITY_CHECKf;
   2541         sram_info->force_reg = EGR_VLAN_XLATE_CONTROLr;
   2542         sram_info->force_field = FORCE_XOR_GENf;
   2543         sram_info->ram_count = SOC_MONTEREY_NUM_EL_EGR_VLAN_XLATE;
   2544         base = (index/4) * 4;
   2545         break;
   2546     case ING_L3_NEXT_HOPm:
   2547         sram_info->ram_count = SOC_MONTEREY_NUM_EL_ING_L3_NEXT_HOP;
   2548         entries_per_ram = SOC_MONTEREY_RAM_OFFSET_ING_L3_NEXT_HOP;
   2549         base = index % entries_per_ram;
   2550         break;
   2551     case L3_IPMCm:
   2552         sram_info->ram_count = SOC_MONTEREY_NUM_EL_L3_IPMC;
   2553         entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L3_IPMC;
   2554         base = index % entries_per_ram;
   2555         break;
   2556     case L2MCm:
   2557         sram_info->ram_count = SOC_MONTEREY_NUM_EL_L2MC;
   2558         entries_per_ram = SOC_MONTEREY_RAM_OFFSET_L2MC;
   2559         base = index % entries_per_ram;
   2560         break;
   2561     case L2_ENTRY_LPm:
   2562     case L3_ENTRY_LPm:
   2563     case VLAN_XLATE_LPm:
   2564     case EGR_VLAN_XLATE_LPm:
   2565         sram_info->view[0] = mem;
   2566         sram_info->index_count[0] = 1;
   2567         sram_info->ram_count = 1;
   2568         entries_per_ram = 0;
   2569         base = index;
   2570         break;
   2571     case L2_ENTRY_ISS_LPm:
   2572         base = (soc_mem_index_count(unit, L2_ENTRY_LPm) * 4) + (index * 4);
   2573         sram_info->ram_count = 1;
   2574         sram_info->view[0] = L2Xm;
   2575         break;
   2576     case L3_ENTRY_ISS_LPm:
   2577         base = index;
   2578         SOC_IF_ERROR_RETURN(_soc_monterey_l3_mem_sram_info_get(unit, &base,
   2579                     &sram_info->ram_count, &sram_info->view[0],
   2580                     sram_info->mem_indexes));
   2581         return SOC_E_NONE;
   2582     default:
   2583         return SOC_E_PARAM;
   2584     }
   2585     sram_info->mem_indexes[0][0] = base;
   2586     if (contiguous) {
   2587         for (i = 1; i < sram_info->ram_count; i++) {
   2588             sram_info->mem_indexes[i][0] = sram_info->mem_indexes[i-1][0] + 1;
   2589         }
   2590     } else {
   2591         for (i = 1; i < sram_info->ram_count; i++) {
   2592             sram_info->mem_indexes[i][0] =  sram_info->mem_indexes[i-1][0] + entries_per_ram;
   2593         }
   2594     }
   2595     return SOC_E_NONE;
   2596 }
   2597 
   2598 
   2599 STATIC int
   2600 _soc_monterey_mmu_init_default_val(int unit)
   2601 {
   2602 
   2603     return SOC_E_NONE;
   2604 }
   2605 
   2606 int
   2607 _soc_monterey_mem_ser_control(int unit, soc_mem_t mem, int copyno,
   2608                             int enable)
   2609 {
   2610     if (enable) {
   2611         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2612                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 0));
   2613         sal_usleep(1000);
   2614         SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOP_SOFT_RESET_REGr,
   2615                                            REG_PORT_ANY, TOP_MMU_RST_Lf, 1));
   2616         sal_usleep(1000);
   2617     }
   2618     if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) {
   2619         SOC_IF_ERROR_RETURN(_soc_monterey_clear_mmu_memory(unit, INVALIDm));
   2620         SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_all(unit, enable));
   2621     }
   2622     if (enable) {
   2623         SOC_IF_ERROR_RETURN
   2624             (_soc_monterey_mmu_init_default_val(unit));
   2625     }
   2626     return SOC_E_NONE;
   2627 }
   2628 
   2629 void
   2630 _soc_monterey_mem_parity_info(int unit, int block_info_idx, int pipe,
   2631                          soc_field_t field_enum, uint32 *minfo)
   2632 {
   2633     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
   2634         | ((pipe & 0xff) << SOC_ERROR_PIPE_BP)
   2635         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
   2636 }
   2637 
   2638 int
   2639 _soc_monterey_mem_is_dyn(int unit, soc_mem_t mem)
   2640 {
   2641     if (SOC_MEM_FIELD_VALID(unit, mem, HITf) ||
   2642         SOC_MEM_FIELD_VALID(unit, mem, HIT0f) ||
   2643         SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) ||
   2644         SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) ||
   2645         SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) ||
   2646         SOC_MEM_FIELD_VALID(unit, mem, HITSAf) ||
   2647         SOC_MEM_FIELD_VALID(unit, mem, HITDAf) ||
   2648         SOC_MEM_FIELD_VALID(unit, mem, B0_HITf) ||
   2649         SOC_MEM_FIELD_VALID(unit, mem, B1_HITf)) {
   2650         return 1;
   2651     }
   2652     return 0;
   2653 }
   2654 
   2655 int
   2656 _soc_monterey_populate_ser_log(int unit, soc_reg_t parity_enable_reg,
   2657                           soc_field_t parity_enable_field,
   2658                           soc_mem_t mem,
   2659                           int mem_block,
   2660                           soc_acc_type_t acc_type,
   2661                           int index,
   2662                           sal_usecs_t detect_time,
   2663                           uint32 sblk,
   2664                           uint32 address)
   2665 {
   2666     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   2667     int log_entry_size, id, entry_dw;
   2668     uint32 *cache;
   2669     uint8 *vmap;
   2670     soc_ser_log_tlv_memory_t log_mem;
   2671     soc_ser_log_tlv_generic_t log_generic;
   2672 #ifdef INCLUDE_XFLOW_MACSEC
   2673     int block_type = SOC_BLOCK_TYPE(unit, mem_block);
   2674 #endif
   2675 
   2676     sal_memset(&log_generic, 0, sizeof(log_generic));
   2677     sal_memset(&log_mem, 0, sizeof(log_mem));
   2678 
   2679     /*
   2680     must be large enough for at least generic and terminator, as well as the
   2681     memory type since we might decode it in soc_ser_correction.
   2682     */
   2683     log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 +
   2684                      sizeof(soc_ser_log_tlv_generic_t) +
   2685                      sizeof(soc_ser_log_tlv_memory_t);
   2686 
   2687     if (mem == INVALIDm) {
   2688         mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address);
   2689         if (mem != INVALIDm) {
   2690             if (sblk) {
   2691                 SOC_MEM_BLOCK_ITER(unit, mem, mem_block) {
   2692                     if (SOC_BLOCK2OFFSET(unit, mem_block) == sblk) {
   2693                         break;
   2694                     }
   2695                 }
   2696             } else {
   2697                 mem_block = SOC_MEM_BLOCK_ANY(unit, mem);
   2698             }
   2699         }
   2700     }
   2701     /*
   2702     If we have decoded the memory we can record its contents/cache
   2703     */
   2704     if((mem != INVALIDm) &&
   2705        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) {
   2706         entry_dw = soc_mem_entry_words(unit, mem);
   2707 
   2708         /* Check to make sure this isn't a duplicate */
   2709         /* Search for a log entry with the same mem, and index with within the last 5 seconds */
   2710         if (soc_ser_log_find_recent(unit, mem, index, sal_time_usecs()) > 0) {
   2711             return 0;
   2712         }
   2713 
   2714         log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2715 
   2716         cache = SOC_MEM_STATE(unit, mem).cache[mem_block];
   2717         vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block];
   2718         if (SOC_MEM_INFO(unit, mem).flags & SOC_MEM_FLAG_CACHABLE) {
   2719             log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2720         }
   2721 
   2722         /* create the entry based on determined size, save id */
   2723         id = soc_ser_log_create_entry(unit, log_entry_size);
   2724 
   2725         /* Add the memory information to the log now so we can detect duplicate errors */
   2726         log_generic.time = detect_time;
   2727         log_mem.memory = mem;
   2728         log_mem.index = index;
   2729         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY,
   2730             sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2731         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC,
   2732             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   2733 
   2734         /* Disable Parity */
   2735         if (!_soc_monterey_mem_is_dyn(unit, mem) &&
   2736             (parity_enable_reg != INVALIDr) &&
   2737             (parity_enable_field != INVALIDf)) {
   2738 #ifdef INCLUDE_XFLOW_MACSEC
   2739             if (soc_feature(unit, soc_feature_xflow_macsec)) {
   2740                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2741                             REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 0 : 1) < 0) {
   2742                     return 0;
   2743                 }
   2744             } else
   2745 #endif
   2746             {
   2747                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2748                             REG_PORT_ANY, parity_enable_field, 0) < 0) {
   2749                     return 0;
   2750                 }
   2751             }
   2752         }
   2753 
   2754         /* Enable Parity */
   2755         if (!_soc_monterey_mem_is_dyn(unit, mem) &&
   2756             (parity_enable_reg != INVALIDr) &&
   2757             (parity_enable_field != INVALIDf)) {
   2758 #ifdef INCLUDE_XFLOW_MACSEC
   2759             if (soc_feature(unit, soc_feature_xflow_macsec)) {
   2760                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2761                             REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 0 : 1) < 0) {
   2762                     return 0;
   2763                 }
   2764             } else
   2765 #endif
   2766             {
   2767                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2768                             REG_PORT_ANY, parity_enable_field, 0) < 0) {
   2769                     return 0;
   2770                 }
   2771             }
   2772 
   2773              /*Enable NACK on read */
   2774               soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN,
   2775                               mem, 0, mem_block,
   2776                               index, tmp_entry);
   2777               /* fill in the memory contents tlv */
   2778               if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS,
   2779                   entry_dw*4, tmp_entry) < 0) {
   2780                   return 0;
   2781               }
   2782 
   2783 #ifdef INCLUDE_XFLOW_MACSEC
   2784             if (soc_feature(unit, soc_feature_xflow_macsec)) {
   2785                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2786                             REG_PORT_ANY, parity_enable_field, (block_type != SOC_BLK_MACSEC) ? 1 : 0) < 0) {
   2787                     return 0;
   2788                 }
   2789             } else
   2790 #endif
   2791             {
   2792                 if (soc_reg_field32_modify(unit, parity_enable_reg,
   2793                             REG_PORT_ANY, parity_enable_field, 1) < 0) {
   2794                     return 0;
   2795                 }
   2796 
   2797             }
   2798             
   2799         }
   2800 
   2801 
   2802         if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2803             /* fill in the memory cache tlv */
   2804             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE,
   2805                 entry_dw*4, (cache + index*entry_dw)) < 0) {
   2806                 return 0;
   2807             }
   2808         }
   2809     } else {
   2810         id = soc_ser_log_create_entry(unit, log_entry_size);
   2811     }
   2812 
   2813     return id;
   2814 }
   2815 
   2816 STATIC int
   2817 _soc_monterey_ser_process_parity(int unit, int block_info_idx, int pipe, 
   2818                                int port, const _soc_monterey_ser_info_t *info,
   2819                                int schan, char *prefix_str, char *mem_str)
   2820 {
   2821     int rv;
   2822     _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr;
   2823     soc_reg_t reg;
   2824     uint32 rval, minfo;
   2825     uint32 multiple, entry_idx, idx, has_error;
   2826     char *mem_str_ptr;
   2827     _soc_ser_correct_info_t spci;
   2828 
   2829     if (schan) {
   2830         /* Some table does not have NACK register */
   2831         return SOC_E_NONE;
   2832     } else {
   2833         if (info->intr_status_reg != INVALIDr) {
   2834             reg_entry[0].reg = info->intr_status_reg;
   2835             reg_entry[0].mem_str = NULL;
   2836             reg_entry[1].reg = INVALIDr;
   2837             reg_ptr = reg_entry;
   2838         } else if (info->intr_status_reg_list != NULL) {
   2839             reg_ptr = info->intr_status_reg_list;
   2840         } else {
   2841             return SOC_E_NONE;
   2842         }
   2843     }
   2844 
   2845     has_error = FALSE;
   2846     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2847         reg = reg_ptr[idx].reg;
   2848         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2849             reg_ptr[idx].mem_str : mem_str;
   2850         SOC_IF_ERROR_RETURN
   2851             (soc_reg32_get(unit, reg, port, 0, &rval));
   2852 
   2853         if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) {
   2854             has_error = TRUE;
   2855             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2856             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2857             _soc_monterey_mem_parity_info(unit, block_info_idx, pipe,
   2858                                      info->group_reg_status_field, &minfo);
   2859             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2860                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   2861                                entry_idx, minfo);
   2862             LOG_ERROR(BSL_LS_SOC_COMMON,
   2863                       (BSL_META_U(unit,
   2864                                   "%s %s entry %d parity error\n"),
   2865                        prefix_str, mem_str_ptr, entry_idx));
   2866             if (multiple) {
   2867                 LOG_ERROR(BSL_LS_SOC_COMMON,
   2868                           (BSL_META_U(unit,
   2869                                       "%s %s has multiple parity errors\n"),
   2870                            prefix_str, mem_str_ptr));
   2871             }
   2872             if (idx == 0 && info->mem != INVALIDm) {
   2873                 sal_memset(&spci, 0, sizeof(spci));
   2874                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   2875                 if (multiple) {
   2876                     spci.flags |= SOC_SER_ERR_MULTI;
   2877                 }
   2878                 spci.reg = INVALIDr;
   2879                 spci.mem = info->mem;
   2880                 spci.blk_type = -1;
   2881                 spci.index = entry_idx;
   2882                 spci.parity_type = info->type;
   2883                 spci.detect_time = sal_time_usecs();
   2884                 spci.log_id = _soc_monterey_populate_ser_log(unit,
   2885                                           info->enable_reg,
   2886                                           info->enable_field,
   2887                                           spci.mem,
   2888                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   2889                                           spci.acc_type,
   2890                                           spci.index,
   2891                                           spci.detect_time,
   2892                                           spci.sblk,
   2893                                           spci.addr);
   2894                 rv = soc_ser_correction(unit, &spci);
   2895                 if (spci.log_id != 0) {
   2896                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2897                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   2898                                        spci.log_id, 0);
   2899                 }
   2900                 if (SOC_FAILURE(rv)) {
   2901                     /* Add reporting failed to correct event flag to
   2902                      * application */
   2903                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2904                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   2905                             entry_idx, minfo);
   2906                     return rv;
   2907                 }
   2908             }
   2909         }
   2910 
   2911         /* Clear parity status */
   2912         SOC_IF_ERROR_RETURN
   2913             (soc_reg32_set(unit, reg, port, 0, 0));
   2914     }
   2915 
   2916     if (!has_error) {
   2917         LOG_ERROR(BSL_LS_SOC_COMMON,
   2918                   (BSL_META_U(unit,
   2919                               "%s %s parity hardware inconsistency\n"),
   2920                    prefix_str, mem_str));
   2921     }
   2922 
   2923     return SOC_E_NONE;
   2924 }
   2925 
   2926 STATIC int
   2927 _soc_monterey_ser_process_ecc(int unit, int block_info_idx, int pipe, int port,
   2928                               const _soc_monterey_ser_info_t *info,
   2929                               int schan, char *prefix_str, char *mem_str)
   2930 {
   2931     int rv;
   2932     _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr;
   2933     soc_reg_t reg = INVALIDr;
   2934     uint32 rval, minfo,has_error = 0;
   2935      uint64 rval64;
   2936     uint32 ecc_err, multiple, double_bit, entry_idx, idx;
   2937     char *mem_str_ptr;
   2938     _soc_ser_correct_info_t spci;
   2939 
   2940     if (schan) {
   2941         /* Some table does not have NACK register */
   2942         return SOC_E_NONE;
   2943     } else {
   2944         if (info->intr_status_reg != INVALIDr) {
   2945             reg_entry[0].reg = info->intr_status_reg;
   2946             reg_entry[0].mem_str = NULL;
   2947             reg_entry[1].reg = INVALIDr;
   2948             reg_ptr = reg_entry;
   2949         } else if (info->intr_status_reg_list != NULL) {
   2950             reg_ptr = info->intr_status_reg_list;
   2951         } else {
   2952             return SOC_E_NONE;
   2953         }
   2954     }
   2955 
   2956     has_error = FALSE;
   2957     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2958         reg = reg_ptr[idx].reg;
   2959         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2960             reg_ptr[idx].mem_str : mem_str;
   2961             if (SOC_REG_IS_64(unit, reg)) {
   2962                 SOC_IF_ERROR_RETURN
   2963                 (soc_reg64_get(unit, reg, port, 0, &rval64));
   2964                 ecc_err = soc_reg64_field32_get(unit, reg, rval64, ECC_ERRf);
   2965                 multiple = soc_reg64_field32_get(unit, reg, rval64, MULTIPLE_ERRf);
   2966                 double_bit = soc_reg64_field32_get(unit, reg, rval64, DOUBLE_BIT_ERRf);
   2967                 entry_idx = soc_reg64_field32_get(unit, reg, rval64, ENTRY_IDXf);
   2968             } else {
   2969                SOC_IF_ERROR_RETURN
   2970                 (soc_reg32_get(unit, reg, port, 0, &rval));
   2971           	  ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf);
   2972            	 multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2973            	 double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf);
   2974             	entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2975             }
   2976 
   2977              if (ecc_err) {
   2978                   has_error = TRUE;
   2979              }
   2980             _soc_monterey_mem_parity_info(unit, block_info_idx, pipe,
   2981                                      info->group_reg_status_field, &minfo);
   2982             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2983                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   2984                                entry_idx, minfo);
   2985             sal_memset(&spci, 0, sizeof(spci));
   2986             if (double_bit) {
   2987                 spci.double_bit = 1;
   2988                 LOG_ERROR(BSL_LS_SOC_COMMON,
   2989                           (BSL_META_U(unit,
   2990                                       "%s %s entry %d double-bit ECC error\n"),
   2991                            prefix_str, mem_str_ptr, entry_idx));
   2992             } else {
   2993                 LOG_ERROR(BSL_LS_SOC_COMMON,
   2994                           (BSL_META_U(unit,
   2995                                       "%s %s entry %d ECC error\n"),
   2996                            prefix_str, mem_str_ptr, entry_idx));
   2997             }
   2998             if (multiple) {
   2999                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3000                           (BSL_META_U(unit,
   3001                                       "%s %s has multiple ECC errors\n"),
   3002                            prefix_str, mem_str_ptr));
   3003             }
   3004             if (idx == 0 && info->mem != INVALIDm) {
   3005                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   3006                 if (multiple) {
   3007                     spci.flags |= SOC_SER_ERR_MULTI;
   3008                 }
   3009                 spci.reg = INVALIDr;
   3010                 spci.mem = info->mem;
   3011                 spci.blk_type = -1;
   3012                 spci.index = entry_idx;
   3013                 spci.parity_type = info->type;
   3014                 spci.detect_time = sal_time_usecs();
   3015                 spci.log_id = _soc_monterey_populate_ser_log(unit,
   3016                                           info->enable_reg,
   3017                                           info->enable_field,
   3018                                           spci.mem,
   3019                                           SOC_MEM_BLOCK_ANY(unit, spci.mem),
   3020                                           spci.acc_type,
   3021                                           spci.index,
   3022                                           spci.detect_time,
   3023                                           spci.sblk,
   3024                                           spci.addr);
   3025                 rv = soc_ser_correction(unit, &spci);
   3026                 if (spci.log_id != 0) {
   3027                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3028                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3029                                        spci.log_id, 0);
   3030                 }
   3031                 if (SOC_FAILURE(rv)) {
   3032                     /* Add reporting failed to correct event flag to
   3033                      * application */
   3034                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3035                             SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3036                             entry_idx, minfo);
   3037                     return rv;
   3038                 }
   3039             }
   3040         
   3041         if (SOC_REG_IS_64(unit, reg)) {
   3042             COMPILER_64_ZERO(rval64);  
   3043             SOC_IF_ERROR_RETURN
   3044                 (soc_reg64_set(unit, reg, port, 0, rval64));
   3045         } else {
   3046             SOC_IF_ERROR_RETURN
   3047                 (soc_reg32_set(unit, reg, port, 0, 0));
   3048         }
   3049       }
   3050     if (!has_error) {
   3051         LOG_ERROR(BSL_LS_SOC_COMMON,
   3052                   (BSL_META_U(unit,
   3053                               "%s %s ECC hardware inconsistency\n"),
   3054                    prefix_str, mem_str));
   3055     }
   3056 
   3057     return SOC_E_NONE;
   3058 }
   3059 
   3060 STATIC int
   3061 _soc_monterey_ser_process_mac(int unit, int block_info_idx, int pipe, int port,
   3062                             const _soc_monterey_ser_info_t *info,
   3063                             int schan, char *prefix_str, char *mem_str)
   3064 {
   3065     _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr;
   3066     soc_reg_t reg;
   3067     soc_field_t single_bit_f, double_bit_f;
   3068     uint64 rval;
   3069     uint32 single_bit = 0, double_bit = 0, idx;
   3070     char *mem_str_ptr;
   3071 
   3072     if (schan) {
   3073         /* Some table does not have NACK register */
   3074         return SOC_E_NONE;
   3075     } else {
   3076         if (info->intr_status_reg != INVALIDr) {
   3077             reg_entry[0].reg = info->intr_status_reg;
   3078             reg_entry[0].mem_str = NULL;
   3079             reg_entry[1].reg = INVALIDr;
   3080             reg_ptr = reg_entry;
   3081         } else if (info->intr_status_reg_list != NULL) {
   3082             reg_ptr = info->intr_status_reg_list;
   3083         } else {
   3084             return SOC_E_NONE;
   3085         }
   3086     }
   3087 
   3088     switch (info->type) {
   3089         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   3090             single_bit_f = TX_CDC_SINGLE_BIT_ERRf;
   3091             double_bit_f = TX_CDC_DOUBLE_BIT_ERRf;
   3092             break;
   3093         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   3094             single_bit_f = RX_CDC_SINGLE_BIT_ERRf;
   3095             double_bit_f = RX_CDC_DOUBLE_BIT_ERRf;
   3096             break;
   3097         case _SOC_PARITY_TYPE_MAC_RX_TS:
   3098             single_bit_f = RX_TS_MEM_SINGLE_BIT_ERRf;
   3099             double_bit_f = RX_TS_MEM_DOUBLE_BIT_ERRf;
   3100             break;
   3101         default:
   3102             return SOC_E_PARAM;
   3103     }
   3104 
   3105     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   3106         reg = reg_ptr[idx].reg;
   3107         mem_str_ptr = reg_ptr[idx].mem_str != NULL ? reg_ptr[idx].mem_str : mem_str;
   3108         SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, port, 0, &rval));
   3109 
   3110         single_bit = soc_reg64_field32_get(unit, reg, rval, single_bit_f);
   3111         double_bit = soc_reg64_field32_get(unit, reg, rval, double_bit_f);
   3112         if (single_bit || double_bit) {
   3113             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3114                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0);
   3115             if (double_bit) {
   3116                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3117                                    SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0);
   3118                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3119                           (BSL_META_U(unit,
   3120                                       "%s %s double-bit ECC error on port %d\n"),
   3121                            prefix_str, mem_str_ptr, port));
   3122             } else {
   3123                 soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3124                                    SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0);
   3125                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3126                           (BSL_META_U(unit,
   3127                                       "%s %s single-bit ECC error on port %d\n"),
   3128                            prefix_str, mem_str_ptr, port));
   3129             }
   3130         }
   3131 
   3132         /* Clear parity status by a rising edge on intr_clr_field in intr_clr_reg */
   3133         SOC_IF_ERROR_RETURN
   3134             (soc_reg64_get(unit, info->intr_clr_reg, port, 0, &rval));
   3135         if (single_bit) {
   3136             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 0);
   3137             SOC_IF_ERROR_RETURN
   3138                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   3139             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[0], 1);
   3140             SOC_IF_ERROR_RETURN
   3141                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   3142         }
   3143         if (double_bit) {
   3144             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 0);
   3145             SOC_IF_ERROR_RETURN
   3146                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   3147             soc_reg64_field32_set(unit, info->intr_clr_reg, &rval, info->intr_clr_field_list[1], 1);
   3148             SOC_IF_ERROR_RETURN
   3149                 (soc_reg64_set(unit, info->intr_clr_reg, port, 0, rval));
   3150         }
   3151     }
   3152 
   3153     return SOC_E_NONE;
   3154 }
   3155 STATIC int
   3156 _soc_monterey_ser_process_mib(int unit, int block_info_idx, int pipe, int port,
   3157                             const _soc_monterey_ser_info_t *info,
   3158                                                         int schan, char *prefix_str, char *mem_str)
   3159 {
   3160     _soc_monterey_ser_reg_t reg_entry[2], *reg_ptr;
   3161     soc_reg_t reg;
   3162     uint32 rval;
   3163     uint32 ecc_err, multiple, double_bit, entry_idx, idx, has_error;
   3164     char *mem_str_ptr;
   3165     if (schan) {
   3166     /* Some table does not have NACK register */
   3167         return SOC_E_NONE;
   3168     } else {
   3169        if (info->intr_status_reg != INVALIDr) {
   3170            reg_entry[0].reg = info->intr_status_reg;
   3171            reg_entry[0].mem_str = NULL;
   3172            reg_entry[1].reg = INVALIDr;
   3173            reg_ptr = reg_entry;
   3174        } else if (info->intr_status_reg_list != NULL) {
   3175            reg_ptr = info->intr_status_reg_list;
   3176        } else {
   3177         return SOC_E_NONE;
   3178        }
   3179     }
   3180     has_error = FALSE;
   3181         for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   3182              reg = reg_ptr[idx].reg;
   3183              mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   3184              reg_ptr[idx].mem_str : mem_str;
   3185              SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   3186              ecc_err = soc_reg_field_get(unit, reg, rval, ECC_ERRf);
   3187              multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   3188              double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf);
   3189              entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   3190              if (ecc_err) {
   3191                  has_error = TRUE;
   3192                  soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3193                                     SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0);
   3194                  if (double_bit) {
   3195                      soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3196                                         SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE,
   3197                                         entry_idx, 0);
   3198 
   3199                     LOG_ERROR(BSL_LS_SOC_COMMON,
   3200                               (BSL_META_U
   3201                               (unit, "%s %s double-bit ECC error on port %d\n"),
   3202                               prefix_str, mem_str_ptr, port));
   3203                  } else {
   3204                      soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3205                                         SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED,
   3206                                         entry_idx, 0);
   3207                       LOG_ERROR(BSL_LS_SOC_COMMON,
   3208                                 (BSL_META_U
   3209                                 (unit, "%s %s single-bit ECC error on port %d\n"),
   3210                                 prefix_str, mem_str_ptr, port));
   3211 
   3212                        }
   3213                        if (multiple) {
   3214                            LOG_ERROR(BSL_LS_SOC_COMMON,
   3215                            (BSL_META_U(unit, "%s %s has multiple ECC errors\n"),
   3216                             prefix_str, mem_str_ptr));
   3217                        }
   3218                        if (double_bit) {
   3219                            /* Entry Idx:
   3220                             * 0-15  Port 0
   3221                             * 16-31 Port 1
   3222                             * 32-47 Port 2
   3223                             * 48-63 Port 3
   3224                             * In case of double-bit error we need to reset MIB counters
   3225                             * for that port to recover
   3226                             */
   3227                             rval = 0x1 << ((entry_idx & 63) / 16);
   3228                             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, rval));
   3229                             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, info->intr_clr_reg, port, 0, 0x0));
   3230                       }
   3231             }
   3232 /* Clear parity status */
   3233                   SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, 0));
   3234      }
   3235     if (!has_error) {
   3236         LOG_ERROR(BSL_LS_SOC_COMMON,
   3237        (BSL_META_U(unit, "%s %s ECC hardware inconsistency\n"),
   3238         prefix_str, mem_str));
   3239     }
   3240     return SOC_E_NONE;
   3241 }
   3242 
   3243 STATIC void
   3244 _soc_monterey_ser_control_reg_get(int unit,
   3245                                 void *fifo_ser_list,
   3246                                 soc_mem_t   mem,
   3247                                 soc_reg_t   *ser_control_reg,
   3248                                 soc_field_t *ser_enable_field)
   3249 {
   3250     int i;
   3251     _soc_mem_ser_en_info_t *ser_en_info = NULL;
   3252 
   3253     if ((fifo_ser_list == NULL) || (ser_control_reg == NULL) || 
   3254         (ser_enable_field == NULL)) {
   3255         return;
   3256     }
   3257 
   3258     ser_en_info = (_soc_mem_ser_en_info_t*)fifo_ser_list;
   3259     for (i = 0; ser_en_info[i].mem != INVALIDm; i++) {
   3260         if (ser_en_info[i].mem == mem) {
   3261             *ser_control_reg = ser_en_info[i].en_ctrl.ctrl_type.en_reg;
   3262             *ser_enable_field = ser_en_info[i].en_ctrl.en_fld;
   3263             break;
   3264         }
   3265     }
   3266 }
   3267 
   3268 STATIC int
   3269 _soc_monterey_ser_process_mmu_err (int unit, int block_info_idx,
   3270                                  const _soc_monterey_ser_info_t *info,
   3271                                  char *prefix_str)
   3272 {
   3273     uint32 rval, err, addr, bidx;
   3274     uint64 rval64;
   3275     soc_reg_t reg = MMU_MEM_FAIL_ADDR_64r;
   3276     uint8 blk_idx;
   3277     uint32 sblk = 0;
   3278     int rv = SOC_E_NONE;
   3279     _soc_ser_correct_info_t spci;
   3280     soc_reg_t parity_enable_reg = INVALIDr;
   3281     soc_field_t parity_enable_field = INVALIDf;
   3282     
   3283     SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   3284     if (soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf)) {
   3285         LOG_ERROR(BSL_LS_SOC_COMMON,
   3286                   (BSL_META_U(unit,
   3287                               "MMU SER interrupt with empty fifo !!\n")));
   3288         SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   3289         LOG_ERROR(BSL_LS_SOC_COMMON,
   3290                   (BSL_META_U(unit,
   3291                               "MMU ERR status: 0x%08x\n"), rval));
   3292         SOC_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, 0));
   3293         return rv;
   3294     }
   3295     SOC_BLOCK_ITER(unit, blk_idx, SOC_BLK_MMU) {
   3296         sblk = SOC_BLOCK2SCH(unit, blk_idx);
   3297         break;
   3298     }
   3299     do {
   3300         SOC_IF_ERROR_RETURN(READ_MMU_MEM_FAIL_ADDR_64r(unit, &rval64));
   3301         err = soc_reg64_field32_get(unit, reg, rval64, ERR_TYPEf);
   3302         addr = soc_reg64_field32_get(unit, reg, rval64, EADDRf);
   3303         bidx = soc_reg64_field32_get(unit, reg, rval64, BIDXf);
   3304 
   3305         LOG_ERROR(BSL_LS_SOC_COMMON,
   3306                  (BSL_META_U(unit,
   3307                              "MMU ERR Type: %s, Addr: 0x%08x, module: %d\n"),
   3308                              (err == 1) ? "1B error" : "2B error", addr, bidx));
   3309 
   3310         /* Address reported in MMU_MEM_FAIL_ADDR_64 is the entry offset within 
   3311          * MMU sub block. The complete Sbus address is composed of MMU sub block 
   3312          * base address and offset within MMU sub block address space.
   3313          */
   3314         addr = (bidx << 26) | addr;
   3315         sal_memset(&spci, 0, sizeof(spci));
   3316         spci.flags |= SOC_SER_SRC_MEM;
   3317         spci.reg = INVALIDr;
   3318         spci.mem = INVALIDm;
   3319         spci.acc_type = -1;
   3320         spci.blk_type = SOC_BLK_MMU;
   3321         spci.sblk = sblk;
   3322         spci.detect_time = sal_time_usecs();
   3323         
   3324         /* Try to decode memory */
   3325         spci.mem = soc_addr_to_mem_extended(unit, sblk, _SOC_ACC_TYPE_PIPE_ANY, addr);
   3326         if (spci.mem != INVALIDm) {
   3327             spci.index = addr - soc_mem_base(unit, spci.mem);
   3328             spci.flags |= SOC_SER_REG_MEM_KNOWN;
   3329             _soc_monterey_ser_control_reg_get(unit,
   3330                                             _soc_bcm56670_a0_mmu_mem_ser_info,
   3331                                             spci.mem,
   3332                                             &parity_enable_reg,
   3333                                             &parity_enable_field);
   3334         } else {
   3335             spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   3336         }
   3337         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3338                            SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   3339                            sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3340         spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   3341         spci.log_id = _soc_monterey_populate_ser_log(unit, parity_enable_reg,
   3342                                                    parity_enable_field,
   3343                                                    spci.mem, blk_idx,
   3344                                                    _SOC_ACC_TYPE_PIPE_ANY,
   3345                                                    spci.index,
   3346                                                    spci.detect_time, spci.sblk,
   3347                                                    spci.addr);
   3348         if ((spci.mem == INVALIDm) ||
   3349             (SOC_MEM_SER_CORRECTION_TYPE(unit, spci.mem) != 0)) {
   3350             rv = soc_ser_correction(unit, &spci);
   3351             if (SOC_FAILURE(rv)) {
   3352                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3353                                    SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   3354                                    sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3355             }
   3356         } else {
   3357             rv = SOC_E_NONE;
   3358             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3359                                SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED,
   3360                                sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET, addr);
   3361         }
   3362 
   3363         if (spci.log_id != 0) {
   3364             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3365                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3366                                spci.log_id, 0);
   3367         }
   3368         SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_CTRr(unit, &rval));
   3369         LOG_ERROR(BSL_LS_SOC_COMMON,
   3370                   (BSL_META_U(unit,
   3371                               "MMU ERR ctr: %d\n"), rval));
   3372         SOC_IF_ERROR_RETURN(READ_MEM_SER_FIFO_STSr(unit, &rval));
   3373     } while (!soc_reg_field_get(unit, MEM_SER_FIFO_STSr, rval, EMPTYf));
   3374     SOC_IF_ERROR_RETURN
   3375         (soc_reg_field32_modify(unit, info->intr_status_reg, REG_PORT_ANY,
   3376                                 info->group_reg_status_field, 0));
   3377 
   3378     SOC_IF_ERROR_RETURN
   3379     (soc_reg_field32_modify(unit, MEM_FAIL_INT_CLEARr, REG_PORT_ANY,
   3380                            info->group_reg_status_field, 1));
   3381     return rv;
   3382 }
   3383 
   3384 STATIC int
   3385 _soc_monterey_ser_process_start_err(int unit, int block_info_idx,
   3386                                     const _soc_monterey_ser_info_t *info,
   3387                                     char *prefix_str)
   3388 {
   3389     soc_info_t *si;
   3390     uint64 rval64;
   3391     uint32 pbmp_31_0, pbmp_63_32; 
   3392     soc_pbmp_t pbmp;
   3393     uint32 minfo ;
   3394     int port, mmu_port, phy_port;
   3395     soc_ser_log_tlv_generic_t log_generic;
   3396     int log_id;
   3397 
   3398     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3399 
   3400     si = &SOC_INFO(unit);
   3401 
   3402     /* mmu port 52-0 */
   3403     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR_0r(unit, &rval64));
   3404     pbmp_31_0 = COMPILER_64_LO(rval64);
   3405     pbmp_63_32 = COMPILER_64_HI(rval64);
   3406     SOC_PBMP_CLEAR(pbmp);
   3407     SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0);
   3408     SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32);
   3409 
   3410     SOC_PBMP_ITER(pbmp, mmu_port) {
   3411         phy_port = si->port_m2p_mapping[mmu_port];
   3412         port = si->port_p2l_mapping[phy_port];
   3413         _soc_monterey_mem_parity_info(unit, block_info_idx, 0,
   3414                                  info->group_reg_status_field, &minfo);
   3415         /* Report uncorrectable event flag to application */
   3416         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3417                            SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3418                            minfo);
   3419 
   3420         log_generic.time = sal_time_usecs();
   3421         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3422         log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3423         log_generic.parity_type = info->type;
   3424 
   3425         log_id = soc_ser_log_create_entry(unit,
   3426             sizeof(soc_ser_log_tlv_generic_t) +
   3427             sizeof(soc_ser_log_tlv_hdr_t) *2);
   3428 
   3429         soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3430             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3431         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3432                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3433         LOG_ERROR(BSL_LS_SOC_COMMON,
   3434                   (BSL_META_U(unit,
   3435                               "%s port %d start error detected\n"), prefix_str,
   3436                               port));
   3437     }
   3438 
   3439     /* Clear parity status */
   3440     COMPILER_64_ZERO(rval64);
   3441     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_0r(unit, rval64));
   3442     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR_1r(unit, rval64));
   3443 
   3444     return SOC_E_NONE;
   3445 }
   3446 
   3447 STATIC int
   3448 _soc_monterey_process_ser (int unit, int block_info_idx, int inst, int pipe,
   3449                          int port, soc_reg_t group_reg, uint64 group_rval,
   3450                          const _soc_monterey_ser_info_t *info_list,
   3451                          char *prefix_str);
   3452 
   3453 STATIC _soc_monterey_bst_hw_cb monterey_bst_cb;
   3454 
   3455 STATIC int
   3456 _soc_monterey_process_mmu_bst(int unit)
   3457 {
   3458     int rv = SOC_E_NONE;
   3459     if (monterey_bst_cb) {
   3460         rv = monterey_bst_cb(unit);
   3461     }
   3462     return rv;
   3463 }
   3464 
   3465 int soc_monterey_set_bst_callback(int unit, _soc_monterey_bst_hw_cb cb)
   3466 {
   3467     monterey_bst_cb = cb;
   3468     return SOC_E_NONE;
   3469 }
   3470 
   3471 STATIC int
   3472 _soc_monterey_ser_process_pm_ecc(int unit, int port,
   3473                                  const _soc_monterey_pm_ecc_info_t *info)
   3474 {
   3475 
   3476     if (info->ecc_err_type) {
   3477 
   3478         soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3479                            SOC_SWITCH_EVENT_DATA_ERROR_ECC, 0, 0);
   3480 
   3481         if (info->ecc_err_type & PORTMOD_PM_CPRI_ECC_ERR_1_BIT) {
   3482 
   3483             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3484                            SOC_SWITCH_EVENT_DATA_ERROR_AUTO_CORRECTED, 0, 0);
   3485 
   3486             LOG_ERROR(BSL_LS_SOC_COMMON,
   3487                       (BSL_META_U(unit,
   3488                                   "\n%s[%s]\n\r " 
   3489                                   "single-bit ECC error on port %d\n"),
   3490                                   info->mem_str,
   3491                                   SOC_MEM_NAME(unit, info->mem), port));
   3492 
   3493         } else if (info->ecc_err_type & PORTMOD_PM_CPRI_ECC_ERR_2_BIT) {
   3494 
   3495             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3496                            SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0);
   3497 
   3498             LOG_ERROR(BSL_LS_SOC_COMMON,
   3499                       (BSL_META_U(unit,
   3500                                   "\n%s[%s]\n\r " 
   3501                                   "double-bit ECC error on port %d\n"),
   3502                                   info->mem_str,
   3503                                   SOC_MEM_NAME(unit, info->mem), port));
   3504 
   3505         } else {
   3506 
   3507             soc_event_generate(unit, SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3508                            SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0, 0);
   3509 
   3510             LOG_ERROR(BSL_LS_SOC_COMMON,
   3511                       (BSL_META_U(unit,
   3512                                   "\n%s[%s]\n\r " 
   3513                                   "multi-bit ECC error on port %d\n"),
   3514                                   info->mem_str,
   3515                                   SOC_MEM_NAME(unit, info->mem), port));
   3516 
   3517         }
   3518     }
   3519 
   3520     return SOC_E_NONE;
   3521 }
   3522 
   3523 STATIC int
   3524 _soc_monterey_process_ser (int unit, int block_info_idx, int inst, int pipe,
   3525                          int port, soc_reg_t group_reg, uint64 group_rval,
   3526                          const _soc_monterey_ser_info_t *info_list,
   3527                          char *prefix_str)
   3528 {
   3529     const _soc_monterey_ser_info_t *info;
   3530     int info_index;
   3531     char *mem_str = "INVALIDm" ;
   3532     uint32 minfo;
   3533     soc_ser_log_tlv_generic_t log_generic;
   3534     int log_id;
   3535 
   3536     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3537 
   3538     /* Loop through each info entry in the list */
   3539     for (info_index = 0; ; info_index++) {
   3540         info = &info_list[info_index];
   3541         if (info->type == _SOC_PARITY_TYPE_NONE) {
   3542             /* End of table */
   3543             break;
   3544         }
   3545 
   3546         /* Check status for the info entry in the group register */
   3547         if ((info->group_reg_status_field != INVALIDf) &&
   3548             (!soc_reg64_field32_get(unit, group_reg, group_rval,
   3549                                     info->group_reg_status_field))) {
   3550             continue;
   3551         }
   3552 
   3553         if (info->mem_str) {
   3554             mem_str = info->mem_str;
   3555         } else if (info->mem != INVALIDm) {
   3556             mem_str = SOC_MEM_NAME(unit, info->mem);
   3557         } else if (info->group_reg_status_field != INVALIDf) {
   3558             
   3559             mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field);
   3560         }
   3561 
   3562         /* Handle different parity error reporting style */
   3563         switch (info->type) {
   3564         case _SOC_PARITY_TYPE_GENERIC:
   3565             _soc_monterey_mem_parity_info(unit, block_info_idx, 0,
   3566                                      info->group_reg_status_field, &minfo);
   3567             /* Report uncorrectable event flag to application */
   3568             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3569                                SOC_SWITCH_EVENT_DATA_ERROR_UNCORRECTABLE, 0,
   3570                                minfo);
   3571 
   3572             log_generic.time = sal_time_usecs();
   3573             log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3574             log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3575             log_generic.parity_type = info->type;
   3576 
   3577             log_id = soc_ser_log_create_entry(unit,
   3578                 sizeof(soc_ser_log_tlv_generic_t) +
   3579                 sizeof(soc_ser_log_tlv_hdr_t) *2);
   3580 
   3581             soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC,
   3582                 sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3583             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3584                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3585 
   3586             LOG_ERROR(BSL_LS_SOC_COMMON,
   3587                       (BSL_META_U(unit,
   3588                                   "%s %s asserted\n"), prefix_str, mem_str));
   3589             break;
   3590         case _SOC_PARITY_TYPE_PARITY:
   3591             /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */
   3592             SOC_IF_ERROR_RETURN
   3593                 (_soc_monterey_ser_process_parity(unit, block_info_idx,
   3594                                                   pipe, port, info, FALSE,
   3595                                                   prefix_str, mem_str));
   3596             break;
   3597         case _SOC_PARITY_TYPE_ECC:
   3598             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   3599             SOC_IF_ERROR_RETURN
   3600                 (_soc_monterey_ser_process_ecc(unit, block_info_idx, pipe,
   3601                                                port, info, FALSE,
   3602                                                prefix_str, mem_str));
   3603             break;
   3604           case _SOC_PARITY_TYPE_MIB:
   3605              /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   3606                SOC_IF_ERROR_RETURN
   3607                  (_soc_monterey_ser_process_mib(unit, block_info_idx, pipe,
   3608                     port, info, FALSE,
   3609                     prefix_str, mem_str));
   3610                   /* MIB_RX_MEM_ERR and MIB_TX_MEM_ERR in PORT_INTR_STATUS are write 1 to clear
   3611                    * So we write back the status we read.
   3612                    */
   3613                  SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval));
   3614              break;
   3615         case _SOC_PARITY_TYPE_MAC_TX_CDC:
   3616         case _SOC_PARITY_TYPE_MAC_RX_CDC:
   3617         case _SOC_PARITY_TYPE_MAC_RX_TS:
   3618             /* xxx_SINGLE_BIT_ERRf, xxx_DOUBLE_BIT_ERRf */
   3619             SOC_IF_ERROR_RETURN
   3620                 (_soc_monterey_ser_process_mac(unit, block_info_idx, pipe,
   3621                                              port, info, FALSE,
   3622                                              prefix_str, mem_str));
   3623              /* MAC_RX_CDC_MEM_ERR, MAC_TX_CDC_MEM_ERR, MAC_RX_TS_CDC_MEM_ERR
   3624                           * in PORT_INTR_STATUS are write 1 to clear
   3625                                        * So we write back the status we read.
   3626                                                     */
   3627               SOC_IF_ERROR_RETURN(soc_reg_set(unit, group_reg, port, 0, group_rval));
   3628             break;
   3629         case _SOC_PARITY_TYPE_START_ERR:
   3630             SOC_IF_ERROR_RETURN
   3631                 (_soc_monterey_ser_process_start_err(unit, block_info_idx,
   3632                                                      info, prefix_str));
   3633             break;
   3634         case _SOC_PARITY_TYPE_MMU_SER:
   3635             SOC_IF_ERROR_RETURN
   3636                 (_soc_monterey_ser_process_mmu_err(unit, block_info_idx,
   3637                                                    info, prefix_str));
   3638             break;
   3639         case _SOC_PARITY_TYPE_BST:
   3640             SOC_IF_ERROR_RETURN(_soc_monterey_process_mmu_bst(unit));
   3641             break;
   3642         case _SOC_PARITY_TYPE_OBM:
   3643             SOC_IF_ERROR_RETURN(_soc_monterey_obm_interrupt_cb(unit));
   3644             break;
   3645         default:
   3646             break;
   3647         } /* Handle different parity error reporting style */
   3648     } /* Loop through each info entry in the list */
   3649 
   3650     return SOC_E_NONE;
   3651 }
   3652 
   3653 STATIC char *_soc_monterey_ser_hwmem_base_info[] = {
   3654     "CMIC PKT BUFFER - In Iarb",
   3655     "CPU PKT BUFFER - In Iarb",
   3656     "Invalid value",
   3657     "EINITBUF_PACKET_BUFFER - In Iarb",
   3658     "INGRESS PACKET BUFFER - In Ipars",
   3659     "Invalid value",
   3660     "Invalid value",
   3661     "Invalid value",
   3662     "Invalid value",
   3663     "SW2_EOP_BUFFER_A - In Iesmif",
   3664     "SW2_EOP_BUFFER_B - In Iesmif",
   3665     "SW2_EOP_BUFFER_C - In Iesmif",
   3666     "Invalid value",
   3667     "Invalid value",
   3668     "Invalid value",
   3669     "Invalid value",
   3670     "EP MPB DATA - In El3",
   3671     "EP INITBUF - In Ehcpm",
   3672     "CM DATA BUFFER - In Edatabuf",
   3673     "XLP0 DATA BUFFER - In Edatabuf",
   3674     "XLP1 DATA BUFFER - In Edatabuf",
   3675     "XLP2 DATA BUFFER - In Edatabuf",
   3676     "XLP3 DATA BUFFER - In Edatabuf",
   3677     "XLP4 DATA BUFFER - In Edatabuf",
   3678     "XLP5 DATA BUFFER - In Edatabuf",
   3679     "XLP6 DATA BUFFER - In Edatabuf",
   3680     "XLP7 DATA BUFFER - In Edatabuf",
   3681     "XLP8 DATA BUFFER - In Edatabuf",
   3682     "XLP9 DATA BUFFER - In Edatabuf",
   3683     "XLP10 DATA BUFFER - In Edatabuf",
   3684     "XLP11 DATA BUFFER - In Edatabuf",
   3685     "XLP12 DATA BUFFER - In Edatabuf",
   3686     "XLP13 DATA BUFFER - In Edatabuf",
   3687     "CLP0 DATA BUFFER - In Edatabuf",
   3688     "CLP1 DATA BUFFER - In Edatabuf",
   3689     "CLP2 DATA BUFFER - In Edatabuf",
   3690     "CLP3 DATA BUFFER - In Edatabuf",
   3691     "XLP RESI0 DATA BUFFER - In Edatabuf",
   3692     "XLP RESI1 DATA BUFFER - In Edatabuf",
   3693     "XLP RESI2 DATA BUFFER - In Edatabuf",
   3694     "XLP RESI3 DATA BUFFER - In Edatabuf",
   3695     "Invalid value",
   3696     "Invalid value",
   3697     "Invalid value",
   3698     "Invalid value",
   3699     "Invalid value",
   3700     "Invalid value",
   3701     "Invalid value",
   3702     "Invalid value",
   3703     "XLP0 EDB CTRL BUFFER - In Edatabuf",
   3704     "XLP1 EDB CTRL BUFFER - In Edatabuf",
   3705     "XLP2 EDB CTRL BUFFER - In Edatabuf",
   3706     "XLP3 EDB CTRL BUFFER - In Edatabuf",
   3707     "XLP4 EDB CTRL BUFFER - In Edatabuf",
   3708     "XLP5 EDB CTRL BUFFER - In Edatabuf",
   3709     "XLP6 EDB CTRL BUFFER - In Edatabuf",
   3710     "XLP7 EDB CTRL BUFFER - In Edatabuf",
   3711     "XLP8 EDB CTRL BUFFER - In Edatabuf",
   3712     "XLP9 EDB CTRL BUFFER - In Edatabuf",
   3713     "XLP10 EDB CTRL BUFFER - In Edatabuf",
   3714     "XLP11 EDB CTRL BUFFER - In Edatabuf",
   3715     "XLP12 EDB CTRL BUFFER - In Edatabuf",
   3716     "XLP13 EDB CTRL BUFFER - In Edatabuf",
   3717     "XLP14 EDB CTRL BUFFER - In Edatabuf",
   3718     "XLP15 EDB CTRL BUFFER - In Edatabuf",
   3719     "CLP0 EDB CTRL BUFFER - In Edatabuf",
   3720     "CLP1 EDB CTRL BUFFER - In Edatabuf",
   3721     "CLP2 EDB CTRL BUFFER - In Edatabuf",
   3722     "CLP3 EDB CTRL BUFFER - In Edatabuf",
   3723     "LEARN FIFO - In IARB",
   3724     "EGR VLAN BUS",
   3725     "EGR HCPM BUS",
   3726     "EGR PMOD BUS",
   3727     "EGR FPPARS BUS",
   3728     "EFP BUS",
   3729     "IVP BUS",
   3730     "ICFG BUS",
   3731     "Invalid value",
   3732     "Invalid value",
   3733     "Invalid value",
   3734     "Invalid value",
   3735     "Invalid value",
   3736     "Invalid value",
   3737     "Invalid value",
   3738     "Invalid value",
   3739     "Invalid value",
   3740     "IPARS BUS",
   3741     "IVXLT BUS",
   3742     "IMPLS BUS",
   3743     "IL2L3 BUS",
   3744     "Invalid value",
   3745     "IFP BUS",
   3746     "IRSEL1 BUS",
   3747     "ISW1 BUS",
   3748     "IRSEL2 BUS"
   3749 };
   3750 
   3751 #define _SOC_MONTEREY_SER_REG 1
   3752 #define _SOC_MONTEREY_SER_MEM 0
   3753 
   3754 STATIC void
   3755 _soc_monterey_print_ser_fifo_details (int unit, uint8 regmem, soc_block_t blk, 
   3756                                     uint32 sblk, int pipe, uint32 address, 
   3757                                     uint32 stage, uint32 base, uint32 index, 
   3758                                     uint32 hwmbase, uint32 type, uint32 drop, 
   3759                                     uint32 non_sbus)
   3760 {
   3761     uint32   hwmbase_max;
   3762     
   3763     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityError, unit)) {
   3764         switch (type) {
   3765         case 0:
   3766             LOG_ERROR(BSL_LS_SOC_COMMON,
   3767                       (BSL_META_U(unit,
   3768                                   "Error in: SOP cell.\n")));
   3769             break;
   3770         case 1:
   3771             LOG_ERROR(BSL_LS_SOC_COMMON,
   3772                       (BSL_META_U(unit,
   3773                                   "Error in: MOP cell.\n")));
   3774             break;
   3775         case 2:
   3776             LOG_ERROR(BSL_LS_SOC_COMMON,
   3777                       (BSL_META_U(unit,
   3778                                   "Error in: EOP cell.\n")));
   3779             break;
   3780         case 3:
   3781             LOG_ERROR(BSL_LS_SOC_COMMON,
   3782                       (BSL_META_U(unit,
   3783                                   "Error in: SBUS transaction.\n")));
   3784             break;
   3785         case 4:
   3786             LOG_ERROR(BSL_LS_SOC_COMMON,
   3787                       (BSL_META_U(unit,
   3788                                   "Error in: miscellaneous transaction.\n")));
   3789             break;
   3790         default:
   3791             LOG_ERROR(BSL_LS_SOC_COMMON,
   3792                       (BSL_META_U(unit,
   3793                                   "Invalid error reported !!\n")));
   3794             break;
   3795         }
   3796         LOG_ERROR(BSL_LS_SOC_COMMON,
   3797                   (BSL_META_U(unit,
   3798                               "Blk: %d, Pipe: %d, Address: 0x%08x, base: 0x%x, stage: %d, index: %d\n"),
   3799                               sblk, pipe, address, base, stage, index));
   3800         if (regmem == _SOC_MONTEREY_SER_MEM) {
   3801             if (hwmbase >= 0x80) {
   3802                 hwmbase -= 0x28; /* handle the gap */
   3803             }
   3804             if (non_sbus) {
   3805                 hwmbase_max = sizeof(_soc_monterey_ser_hwmem_base_info)/sizeof(_soc_monterey_ser_hwmem_base_info[0]);
   3806                 /* coverity[overrun-local] */
   3807                 LOG_ERROR(BSL_LS_SOC_COMMON,
   3808                           (BSL_META_U(unit,
   3809                                       "Mem hwbase: 0x%x [%s]\n"), hwmbase,
   3810                                       (hwmbase < hwmbase_max) ? _soc_monterey_ser_hwmem_base_info[hwmbase] : "--"));
   3811             }
   3812         }
   3813         if (drop) {
   3814             LOG_ERROR(BSL_LS_SOC_COMMON,
   3815                       (BSL_META_U(unit,
   3816                                   "SER caused packet drop.\n")));
   3817         }
   3818     }
   3819 }
   3820 
   3821 #define IF_IPIPE_ARBITER_LOCK(_unit_, _blk_) \
   3822     if (_blk_ == SOC_BLK_IPIPE) {\
   3823         IP_ARBITER_LOCK(_unit_);\
   3824     }
   3825 
   3826 #define IF_IPIPE_ARBITER_UNLOCK(_unit_, _blk_) \
   3827     if (_blk_ == SOC_BLK_IPIPE) {\
   3828         IP_ARBITER_UNLOCK(_unit_);\
   3829     }
   3830 
   3831 static uint32 _monterey_ser_status_bus_fmt_get (uint32 *entry, int fld)
   3832 {
   3833     switch(fld) {
   3834     case VALIDf: /* Bit 1*/
   3835         return (entry[0] & 0x00000001);
   3836     case INSTRUCTION_TYPEf: /* Bits 1-4 */
   3837         return ((entry[0] & 0x0000001E) >> 1);
   3838     case HWMEMBASEf: /* Bits 23-30 */
   3839     case MEMBASEf:
   3840         return ((entry[0] & 0x7F800000) >> 23);
   3841     case MEMINDEXf: /* Bits 5-22 */
   3842         return ((entry[0] & 0x007FFFE0) >> 5);
   3843     case REGINDEXf: /* Bits 5-12 */
   3844         return ((entry[0] & 0x00001FE0) >> 5);
   3845     case REGBASEf: /* Bits 13-29 */
   3846         return ((entry[0] & 0x3FFFE000) >> 13);
   3847     case PIPE_STAGEf: /* Bits 31-36 */
   3848         return (((entry[0] & 0x80000000) >> 30) |
   3849                 ((entry[1] & 0x0000001F) << 1));
   3850     case ADDRESSf: /* Bits 36-5 */
   3851         return ((entry[0] >> 5) | 
   3852                 ((entry[1] & 0x0000001F) << 27));
   3853     case DROPf: /* Bit 37 */
   3854         return (entry[1] & 0x00000020);
   3855     case ECC_PARITYf: /* Bits 38-39 */
   3856         return ((entry[1] & 0x000000C0) >> 6);
   3857     case MEM_TYPEf:/* Bit 40 */
   3858         return (entry[1] & 0x00000100);
   3859     case NON_SBUSf: /* Bit 41 */
   3860         return (entry[1] & 0x00000200);
   3861     case MULTIPLEf: /* Bit 42 */
   3862         return (entry[1] & 0x00000400);
   3863     default:
   3864         return -1;
   3865     }
   3866 }
   3867 
   3868 int
   3869 soc_monterey_mem_index_remap(int unit, int index, soc_mem_t *mem)
   3870 {
   3871     int logical_index = -1;
   3872     switch (*mem) {
   3873         case L3_DEFIPm:
   3874         case L3_DEFIP_PAIR_128m:
   3875         case L3_DEFIP_ONLYm:    
   3876         case L3_DEFIP_PAIR_128_ONLYm:
   3877         case L3_DEFIP_DATA_ONLYm:
   3878         case L3_DEFIP_PAIR_128_DATA_ONLYm:
   3879             logical_index =  soc_monterey_l3_defip_index_remap(unit, *mem, index);
   3880             if (logical_index == -1) {
   3881                 /* This case arises when the passed index (physical) belongs
   3882                  * to wider view, but the passed mem is narrow view 
   3883                  * Note that below API rewrites mem to the correct (wide) view.
   3884                  */
   3885                 logical_index = soc_monterey_l3_defip_mem_index_get(unit, index, mem);
   3886             }
   3887             return logical_index;
   3888         default:
   3889             return index;
   3890     }
   3891 }
   3892 
   3893 STATIC uint32
   3894 _soc_monterey_flex_ctr_addr_check (int unit, uint32 address, soc_block_t blk,
   3895                                  uint32 stage, uint32 index)
   3896 {
   3897     uint32 index2 = index;
   3898 
   3899     
   3900     if ((SOC_BLK_IPIPE == blk) && (22 == stage)) {
   3901         switch (address & 0xfffff000) {
   3902             /* ING_FLEX_CTR_OFFSET_TABLE_*m */
   3903         case 0x56800000:
   3904         case 0x56801000:
   3905         case 0x56802000:
   3906         case 0x56803000:
   3907         case 0x56840000:
   3908         case 0x56841000:
   3909         case 0x56842000:
   3910         case 0x56843000:
   3911             index2 = address & 0x3ff; break; /* 1K depth */
   3912             /* ING_FLEX_CTR_COUNTER_TABLE_*m */
   3913         case 0x56804000:
   3914         case 0x56808000:
   3915         case 0x5680c000:
   3916         case 0x56810000:
   3917         case 0x56844000:
   3918         case 0x56848000:
   3919         case 0x5684c000:
   3920         case 0x56850000:
   3921             index2 = address & 0xfff; break; /* 4K depth */
   3922         default:
   3923             break;
   3924         }
   3925     }
   3926 
   3927     if ((SOC_BLK_EPIPE == blk) && (10 == stage)) {
   3928         switch (address & 0XFFFFF000) {
   3929         case 0x2a800000:
   3930         case 0x2a801000:
   3931         case 0x2a802000:
   3932         case 0x2a803000:
   3933             index2 = address & 0x3ff; break; /* 1K depth */
   3934         case 0x2a804000:
   3935         case 0x2a808000:
   3936         case 0x2a80c000:
   3937         case 0x2a810000:
   3938             index2 = address & 0xfff; break; /* 4K depth */
   3939         default:
   3940             break;
   3941         }
   3942     }
   3943     return index2;
   3944 }
   3945 
   3946 STATIC int
   3947 _soc_monterey_process_ser_fifo (int unit, soc_block_t blk, char *prefix_str)
   3948 {
   3949     int            rv;
   3950     uint8          bidx;
   3951     soc_mem_t      mem;
   3952     char           blk_str[10];
   3953     void          *ser_info_table = NULL;
   3954     uint32         entry[SOC_MAX_MEM_WORDS], address = 0;
   3955     uint32         reg_val = 0, mask = 0;
   3956     uint32         stage = 0, addrbase = 0, index = 0, hwmbase = 0, type = 0;
   3957     uint32         sblk = 0, regmem = 0, non_sbus = 0, drop = 0, ecc_parity = 0;
   3958     soc_reg_t      parity_enable_reg = INVALIDr;
   3959     soc_field_t    parity_enable_field = INVALIDf;
   3960     _soc_ser_correct_info_t spci;
   3961     soc_reg_t reg = INVALIDr;
   3962 
   3963     switch (blk) {
   3964     case SOC_BLK_IPIPE:
   3965         mem = ING_SER_FIFOm;
   3966         ser_info_table = _soc_bcm56670_a0_ip_mem_ser_info;
   3967         sal_sprintf(blk_str, "IPIPE");
   3968         break;
   3969     case SOC_BLK_EPIPE:
   3970         mem = EGR_SER_FIFOm;
   3971         ser_info_table = _soc_bcm56670_a0_ep_mem_ser_info;
   3972         mask = 0x00000001; /* SER_FIFO_NON_EMPTYf */
   3973         reg = EGR_INTR_STATUSr;
   3974         sal_sprintf(blk_str, "EPIPE");
   3975         break;
   3976     default:
   3977         return SOC_E_PARAM;
   3978     }
   3979 
   3980     IF_IPIPE_ARBITER_LOCK(unit, blk);
   3981     do {
   3982         sal_memset(&spci, 0, sizeof(spci));
   3983         rv = soc_mem_pop(unit, mem, MEM_BLOCK_ANY, entry);
   3984         if (rv != SOC_E_NONE) {
   3985             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   3986         }
   3987         SOC_IF_ERROR_RETURN(rv);
   3988         /* process entry */
   3989         if (_monterey_ser_status_bus_fmt_get(entry,VALIDf)) {
   3990             ecc_parity = _monterey_ser_status_bus_fmt_get(entry, ECC_PARITYf);
   3991             regmem = _monterey_ser_status_bus_fmt_get(entry, MEM_TYPEf);
   3992             address = _monterey_ser_status_bus_fmt_get(entry, ADDRESSf);
   3993             stage = _monterey_ser_status_bus_fmt_get(entry, PIPE_STAGEf);
   3994             type = _monterey_ser_status_bus_fmt_get(entry, INSTRUCTION_TYPEf);
   3995             drop = _monterey_ser_status_bus_fmt_get(entry, DROPf);
   3996             SOC_BLOCK_ITER(unit, bidx, blk) {
   3997                 sblk = SOC_BLOCK2SCH(unit, bidx);
   3998                 break;
   3999             }
   4000             LOG_ERROR(BSL_LS_SOC_COMMON,
   4001                       (BSL_META_U(unit,
   4002                                   "%s\n"), prefix_str));
   4003             if (_monterey_ser_status_bus_fmt_get(entry, MULTIPLEf)) {
   4004                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4005                           (BSL_META_U(unit,
   4006                                       "Multiple: ")));
   4007             }
   4008             if (regmem == _SOC_MONTEREY_SER_REG ) {
   4009                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4010                           (BSL_META_U(unit,
   4011                                       "Reg: ")));
   4012             } else {
   4013                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4014                           (BSL_META_U(unit,
   4015                                       "Mem: ")));
   4016             }
   4017             spci.double_bit = 0;
   4018             switch (ecc_parity) {
   4019             case 0:
   4020                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4021                           (BSL_META_U(unit,
   4022                                       "Parity error..\n")));
   4023                  spci.parity_type = SOC_PARITY_TYPE_PARITY;
   4024                 break;
   4025 
   4026             case 1:
   4027                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4028                           (BSL_META_U(unit,
   4029                                       "Corrected single bit ECC error..\n")));
   4030                  spci.parity_type = SOC_PARITY_TYPE_ECC;
   4031                 break;
   4032             case 2:
   4033                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4034                           (BSL_META_U(unit,
   4035                                       "Double or Multiple bit ECC error..\n")));
   4036 
   4037                 spci.parity_type = SOC_PARITY_TYPE_ECC;
   4038                 spci.double_bit = 1;
   4039                 spci.flags |= SOC_SER_ERR_MULTI;
   4040 
   4041                 break;
   4042             default:
   4043                 LOG_ERROR(BSL_LS_SOC_COMMON,
   4044                           (BSL_META_U(unit,
   4045                                       "Invalid SER issue !!\n")));
   4046 
   4047                 IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   4048                 return SOC_E_INTERNAL;
   4049             }
   4050             if (regmem == _SOC_MONTEREY_SER_MEM) {
   4051                 /* process mem */
   4052                 non_sbus = _monterey_ser_status_bus_fmt_get(entry, NON_SBUSf);
   4053                 addrbase = _monterey_ser_status_bus_fmt_get(entry, MEMBASEf);
   4054                 index = _monterey_ser_status_bus_fmt_get(entry, MEMINDEXf);
   4055                 hwmbase = _monterey_ser_status_bus_fmt_get(entry, HWMEMBASEf);
   4056         
   4057 
   4058                 index = _soc_monterey_flex_ctr_addr_check(unit, address, blk,
   4059                                                         stage, index);
   4060                 if (non_sbus == 0) {
   4061                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4062                                        ecc_parity == 0 ?
   4063                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4064                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC,
   4065                                        sblk | SOC_SER_ERROR_DATA_BLK_ADDR_SET,
   4066                                        address);
   4067                     _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0,
   4068                                                        address, stage, addrbase,
   4069                                                        index, hwmbase, type,
   4070                                                        drop, non_sbus);
   4071                     spci.flags = SOC_SER_SRC_MEM;
   4072                     spci.reg = INVALIDr;
   4073                     spci.mem = INVALIDm;
   4074                     spci.blk_type = blk;
   4075                     spci.sblk = sblk;
   4076                     spci.addr = address - index;
   4077                     spci.index = index;
   4078                     spci.stage = stage;
   4079                     spci.detect_time = sal_time_usecs();
   4080                     spci.mem = soc_addr_to_mem_extended(unit,spci.sblk,
   4081                                                         -1,spci.addr);
   4082                     if (spci.mem != INVALIDm) {
   4083                         spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
   4084                         spci.flags |= SOC_SER_REG_MEM_KNOWN;
   4085                         spci.index = soc_monterey_mem_index_remap(unit, index, &(spci.mem));
   4086                     }
   4087                     else {
   4088                         /* Invalid mem, use the first acc_type_ptr*/
   4089                         spci.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
   4090                         spci.flags |= SOC_SER_REG_MEM_UNKNOWN;
   4091                     }
   4092 
   4093                     if (spci.mem != INVALIDm) {
   4094                         _soc_monterey_ser_control_reg_get(unit, ser_info_table, 
   4095                             spci.mem, 
   4096                             &parity_enable_reg, 
   4097                             &parity_enable_field);
   4098                     }
   4099                     spci.flags |= SOC_SER_LOG_WRITE_CACHE;
   4100                     spci.log_id = _soc_monterey_populate_ser_log(unit,
   4101                                               parity_enable_reg,
   4102                                               parity_enable_field,
   4103                                               spci.mem,
   4104                                               bidx,
   4105                                               spci.acc_type,
   4106                                               spci.index,
   4107                                               spci.detect_time,
   4108                                               spci.sblk,
   4109                                               spci.addr);
   4110 
   4111                     rv = soc_ser_correction(unit, &spci);
   4112                     if (SOC_FAILURE(rv)) {
   4113                         if (rv != SOC_E_NOT_FOUND) {
   4114                             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   4115                             /* Add reporting failed to correct event flag to
   4116                              * application */
   4117                             soc_event_generate(unit,
   4118                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   4119                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   4120                                     sblk |
   4121                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4122                             return rv;
   4123                         }
   4124                     }
   4125                     if (spci.log_id != 0) {
   4126                         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4127                                            SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   4128                                            spci.log_id, 0);
   4129                     }
   4130 
   4131                 } else {
   4132                     LOG_ERROR(BSL_LS_SOC_COMMON,
   4133                               (BSL_META_U(unit,
   4134                                           "%s SER mem address un-accessable !!\n"), blk_str));
   4135           _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0, address,
   4136                                              stage, addrbase, index, hwmbase,
   4137                                              type, drop, non_sbus);
   4138                 }
   4139             } else {
   4140                 /* process reg */
   4141                 non_sbus = _monterey_ser_status_bus_fmt_get(entry, NON_SBUSf);
   4142                 addrbase = _monterey_ser_status_bus_fmt_get(entry, REGBASEf);
   4143                 index = _monterey_ser_status_bus_fmt_get(entry, REGINDEXf);
   4144 
   4145                 if (non_sbus == 0) {
   4146                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4147                                        ecc_parity == 0 ? 
   4148                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY :
   4149                                        SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   4150                                        sblk |
   4151                                        SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4152                     _soc_monterey_print_ser_fifo_details(unit, 1, blk, sblk, 0,
   4153                                                        address, stage, addrbase,
   4154                                                        index, 0, type, drop,
   4155                                                        non_sbus);
   4156                     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_UNKNOWN;
   4157                     spci.reg = INVALIDr;
   4158                     spci.mem = INVALIDm;
   4159                     spci.blk_type = blk;
   4160                     spci.sblk = sblk;
   4161                     spci.addr = address;
   4162                     spci.index = index;
   4163                     spci.stage = stage;
   4164                     spci.detect_time = sal_time_usecs();
   4165                     spci.log_id = soc_ser_log_create_entry(unit,
   4166                             sizeof(soc_ser_log_tlv_generic_t) +
   4167                             sizeof(soc_ser_log_tlv_register_t) +
   4168                             sizeof(soc_ser_log_tlv_hdr_t) *3);
   4169                     rv = soc_ser_correction(unit, &spci);
   4170                     if (SOC_FAILURE(rv)) {
   4171                         IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   4172                         /* Add reporting failed to correct event flag to
   4173                          * application */
   4174                         soc_event_generate(unit,
   4175                                     SOC_SWITCH_EVENT_PARITY_ERROR,
   4176                                     SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT,
   4177                                     sblk |
   4178                                     SOC_SER_ERROR_DATA_BLK_ADDR_SET, address);
   4179                         return rv;
   4180                     }
   4181                     if (spci.log_id != 0) {
   4182                         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4183                                            SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   4184                                            spci.log_id, 0);
   4185                     }
   4186                 } else {
   4187                     LOG_ERROR(BSL_LS_SOC_COMMON,
   4188                               (BSL_META_U(unit,
   4189                                           "%s SER reg address un-accessable !!\n"), blk_str));
   4190                     _soc_monterey_print_ser_fifo_details(unit, 0, blk, sblk, 0,
   4191                                                        address, stage, addrbase,
   4192                                                        index, hwmbase, type,
   4193                                                        drop, non_sbus);
   4194                 }
   4195             }
   4196         } else {
   4197             LOG_ERROR(BSL_LS_SOC_COMMON,
   4198                       (BSL_META_U(unit,
   4199                                   "unit %d Got invalid mem pop from %s !!\n"),
   4200                                   unit, SOC_MEM_NAME(unit, mem)));
   4201         }
   4202 
   4203         if (rv != SOC_E_NONE) {
   4204             IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   4205         }
   4206 
   4207         /* check if any more pending */
   4208         if (reg == INVALIDr) {
   4209             rv = READ_CMIC_CMC0_IRQ_STAT2r(unit, &reg_val);
   4210         } else {
   4211             rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &reg_val);
   4212         }
   4213         SOC_IF_ERROR_RETURN(rv);
   4214     } while (reg_val & mask);
   4215     IF_IPIPE_ARBITER_UNLOCK(unit, blk);
   4216 
   4217     return SOC_E_NONE;
   4218 }
   4219 
   4220 STATIC int
   4221 _soc_monterey_ser_process_irq3 (int unit, int bit_pos)
   4222 {
   4223     uint8      rbi;
   4224     int        port = REG_PORT_ANY;
   4225     uint32     cmic_rval, cmic_bit;
   4226     uint64     rb_enable64, rb_rval64, tmp64;
   4227     const      _soc_monterey_ser_route_block_t *rb;
   4228     char       prefix_str[10];
   4229     int        block_info_idx;
   4230     soc_stat_t *stat = SOC_STAT(unit);
   4231     int ser_error = 0;
   4232     int pgw_inst = 0 ;
   4233     int pgw = 0;
   4234     sal_sprintf(prefix_str, "Unit: %d \n", unit);
   4235 
   4236     /* Read CMIC parity status register */
   4237     SOC_IF_ERROR_RETURN
   4238         (READ_CMIC_CMC0_IRQ_STAT3r(unit, &cmic_rval));
   4239     if (cmic_rval == 0) {
   4240         return SOC_E_NONE;
   4241     }
   4242     /* Loop through each place-and-route block entry */
   4243     for (rbi = 0; ; rbi++) {
   4244         rb = &_soc_monterey_ser_route_blocks_irq3[rbi];
   4245         cmic_bit = rb->cmic_bit;
   4246         if (cmic_bit == 0) {
   4247             /* End of table */
   4248             break;
   4249         }
   4250         if (cmic_bit != (1 << bit_pos)) {
   4251             continue;
   4252         }
   4253         if (!(cmic_rval & cmic_bit)) {
   4254             /* No interrupt bit asserted for the route block */
   4255             continue;
   4256         }
   4257         if (rb->blocktype == SOC_BLK_IPIPE || rb->blocktype == SOC_BLK_EPIPE) {
   4258             /* New fifo style processing */
   4259             (void)_soc_monterey_process_ser_fifo(unit, rb->blocktype, prefix_str);
   4260             stat->ser_err_fifo++;
   4261         } else {
   4262             /* Legacy processing */
   4263             
   4264             SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   4265                 if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   4266                     port = SOC_BLOCK_PORT(unit, block_info_idx);
   4267                     break;
   4268                 }
   4269             }
   4270             if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 
   4271                 SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   4272                     /* This port block is not configured */
   4273                     LOG_ERROR(BSL_LS_SOC_COMMON,
   4274                               (BSL_META_U(unit,
   4275                                           "unit %d SER error on disabled port block %d !!\n"),
   4276                                           unit, block_info_idx));
   4277                     sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */
   4278                     continue;
   4279             }
   4280             if(rb->blocktype == SOC_BLK_PGW_CL) {
   4281               for ( pgw = 0; pgw <= 1; pgw++) 
   4282               { 
   4283                    pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);   
   4284                    SOC_IF_ERROR_RETURN
   4285                    (soc_reg_get(unit, rb->status_reg, pgw_inst, 0, &rb_rval64));
   4286                    if (!COMPILER_64_IS_ZERO(rb_rval64)) {
   4287                        ser_error = 1; 
   4288                        break; 
   4289                    }
   4290               }
   4291               if(!ser_error) 
   4292               {
   4293                  continue; 
   4294               } 
   4295               
   4296             } else {
   4297             /* Read per route block parity status register */
   4298                SOC_IF_ERROR_RETURN
   4299                   (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64));
   4300                if (COMPILER_64_IS_ZERO(rb_rval64)) {
   4301                    continue;
   4302                }
   4303            }
   4304            SOC_IF_ERROR_RETURN
   4305                 (_soc_monterey_process_ser(unit, block_info_idx, rb->id, -1,
   4306                                          port, rb->status_reg, rb_rval64,
   4307                                          rb->info, prefix_str));
   4308             
   4309             SOC_IF_ERROR_RETURN
   4310                 (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64));
   4311             COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64));
   4312             COMPILER_64_NOT(tmp64);
   4313             COMPILER_64_AND(rb_enable64, tmp64);
   4314             SOC_IF_ERROR_RETURN
   4315                 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4316             COMPILER_64_OR(rb_enable64, rb_rval64);
   4317             SOC_IF_ERROR_RETURN
   4318                 (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4319             
   4320             stat->ser_err_int++;
   4321         }
   4322     }
   4323     return SOC_E_NONE;
   4324 }
   4325 
   4326 STATIC int
   4327 _soc_monterey_ser_process_irq4 (int unit, int bit_pos)
   4328 {
   4329     uint8      rbi;
   4330     int        port = REG_PORT_ANY;
   4331     uint32     cmic_rval, cmic_bit;
   4332     uint64     rb_enable64, rb_rval64, tmp64;
   4333     char       prefix_str[10];
   4334     int        block_info_idx;
   4335     soc_stat_t *stat = SOC_STAT(unit);
   4336 
   4337     const _soc_monterey_ser_route_block_t *rb;
   4338 
   4339     sal_sprintf(prefix_str, "\nUnit: %d: ", unit);
   4340 
   4341     /* Read CMIC parity status register */
   4342     SOC_IF_ERROR_RETURN
   4343         (READ_CMIC_CMC0_IRQ_STAT4r(unit, &cmic_rval));
   4344     if (cmic_rval == 0) {
   4345         return SOC_E_NONE;
   4346     }
   4347 
   4348     /* Loop through each place-and-route block entry */
   4349     for (rbi = 0; ; rbi++) {
   4350             rb = &_soc_monterey_ser_route_blocks_irq4[rbi];
   4351         cmic_bit = rb->cmic_bit;
   4352         if (cmic_bit == 0) {
   4353             /* End of table */
   4354             break;
   4355         }
   4356         if (cmic_bit != (1 << bit_pos)) {
   4357             continue;
   4358         }
   4359         if (!(cmic_rval & cmic_bit)) {
   4360             /* No interrupt bit asserted for the route block */
   4361             continue;
   4362         }
   4363 
   4364         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
   4365             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
   4366                 port = SOC_BLOCK_PORT(unit, block_info_idx);
   4367                 break;
   4368             }
   4369         }
   4370         
   4371         if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, rb->enable_reg).block, 
   4372                               SOC_BLK_PORT) && (port == REG_PORT_ANY)) {
   4373             /* This port block is not configured */
   4374             LOG_ERROR(BSL_LS_SOC_COMMON,
   4375                       (BSL_META_U(unit,
   4376                                   "unit %d SER error on disabled port block %d !!\n"),
   4377                        unit, block_info_idx));
   4378             sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : 1000000); /* Don't reenable too soon */
   4379             continue;
   4380         }
   4381          
   4382         /* Read per route block parity status register */
   4383         SOC_IF_ERROR_RETURN
   4384             (soc_reg_get(unit, rb->status_reg, port, 0, &rb_rval64));
   4385         if (COMPILER_64_IS_ZERO(rb_rval64)) {
   4386             continue;
   4387         }
   4388 
   4389         SOC_IF_ERROR_RETURN
   4390             (_soc_monterey_process_ser(unit, block_info_idx, rb->id, -1,
   4391                                      port, rb->status_reg, rb_rval64,
   4392                                      rb->info, prefix_str));
   4393         SOC_IF_ERROR_RETURN
   4394             (soc_reg_get(unit, rb->enable_reg, port, 0, &rb_enable64));
   4395         COMPILER_64_SET(tmp64, COMPILER_64_HI(rb_rval64), COMPILER_64_LO(rb_rval64));
   4396         COMPILER_64_NOT(tmp64);
   4397         COMPILER_64_AND(rb_enable64, tmp64);
   4398         SOC_IF_ERROR_RETURN
   4399             (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4400         COMPILER_64_OR(rb_enable64, rb_rval64);
   4401         SOC_IF_ERROR_RETURN
   4402             (soc_reg_set(unit, rb->enable_reg, port, 0, rb_enable64));
   4403             
   4404         stat->ser_err_int++;
   4405     }
   4406 
   4407     return SOC_E_NONE;
   4408 }
   4409 
   4410 #define IRQ3_STATUS_REG 3
   4411 #define IRQ4_STATUS_REG 4
   4412 STATIC int
   4413 _soc_monterey_ser_process_all (int unit, int top_irq, int bit_pos)
   4414 {
   4415     switch (top_irq) {
   4416     case IRQ3_STATUS_REG:
   4417         SOC_IF_ERROR_RETURN(_soc_monterey_ser_process_irq3(unit,bit_pos));
   4418         break;
   4419     case IRQ4_STATUS_REG:
   4420         SOC_IF_ERROR_RETURN(_soc_monterey_ser_process_irq4(unit,bit_pos));
   4421         break;
   4422     default:
   4423         return SOC_E_INTERNAL; /* Shouldn't come here */
   4424     }
   4425 
   4426     return SOC_E_NONE;
   4427 }
   4428 
   4429 void
   4430 soc_monterey_ser_set_long_delay(int delay)
   4431 {
   4432     _monterey_ser_delay = delay;
   4433     return;
   4434 }
   4435 
   4436 STATIC void
   4437 soc_monterey_ser_error (void *unit_vp, void *d1,
   4438                       void *d2, void *d3, void *d4)
   4439 {
   4440     int unit     = PTR_TO_INT(unit_vp);
   4441     int irq_reg  = PTR_TO_INT(d3);
   4442     int old_mask = 0;
   4443 
   4444     (void)_soc_monterey_ser_process_all(unit,irq_reg,PTR_TO_INT(d4));
   4445 
   4446     sal_usleep(SAL_BOOT_QUICKTURN ? 10000000 : (_monterey_ser_delay != 0 ? 10000000 : 100000));
   4447 
   4448     if (d2 != NULL) {
   4449         old_mask = PTR_TO_INT(d2);
   4450         if (irq_reg == 3) {
   4451             (void)soc_cmicm_intr3_enable(unit, old_mask);
   4452         } else if (irq_reg == 4) {
   4453             (void)soc_cmicm_intr4_enable(unit, old_mask);
   4454         }
   4455     }
   4456     /* soc_intr_enable(unit, IRQ_MEM_FAIL); */
   4457 }
   4458 
   4459 /* SER processing for TCAMs */
   4460 static _soc_generic_ser_info_t _soc_monterey_tcam_ser_info_template[] = {
   4461     /* HW SER engine protection */
   4462     { L3_DEFIPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4463       _SOC_SER_INTERLEAVE_MOD2,
   4464       { {0, 97}, {1, 97}, {98, 193}, {99, 193} }, 0, 0, 0, 0,
   4465       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA |
   4466       _SOC_SER_FLAG_REMAP_READ  | _SOC_SER_FLAG_SIZE_VERIFY},
   4467     { L3_DEFIP_PAIR_128m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4468       _SOC_SER_PARITY_8BITS,
   4469       _SOC_SER_INTERLEAVE_NONE,
   4470       { {0, 99}, {100, 195}, {196, 291}, {292, 387} }, 0, 0, 0, 0,
   4471       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA |
   4472       _SOC_SER_FLAG_REMAP_READ  | _SOC_SER_FLAG_SIZE_VERIFY},
   4473     { FP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4474       _SOC_SER_INTERLEAVE_MOD2,
   4475       { {0, 165}, {1, 165}, {166, 353}, {167, 353} }, 0, 0, 0, 0,
   4476       _SOC_SER_FLAG_XY_READ},
   4477     { EFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4478       _SOC_SER_INTERLEAVE_MOD2,
   4479       { {0, 237}, {1, 237}, {238, 473}, {239, 473} }, 0, 0, 0, 0,
   4480       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA},
   4481     { VFP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4482       _SOC_SER_INTERLEAVE_MOD2, 
   4483       { {0, 235}, {1, 235}, {236, 469}, {237, 469} }, 0, 0, 0, 0,
   4484       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_NO_DMA},
   4485     { ING_SNATm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4486       _SOC_SER_INTERLEAVE_MOD2,
   4487       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4488       _SOC_SER_FLAG_XY_READ},
   4489     { L3_TUNNELm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4490       _SOC_SER_INTERLEAVE_MOD2,
   4491       { {0, 145}, {2, 145}, {146, 289}, {148, 289} }, 0, 0, 0, 0,
   4492       _SOC_SER_FLAG_XY_READ},
   4493     { L2_USER_ENTRYm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4494       _SOC_SER_INTERLEAVE_MOD2,
   4495       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4496       _SOC_SER_FLAG_XY_READ},
   4497 
   4498     { VLAN_SUBNETm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4499       _SOC_SER_INTERLEAVE_MOD2,
   4500       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4501       _SOC_SER_FLAG_XY_READ},
   4502     { MY_STATION_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4503       _SOC_SER_PARITY_4BITS,
   4504       _SOC_SER_INTERLEAVE_MOD2,
   4505       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4506       _SOC_SER_FLAG_XY_READ},
   4507     { FP_UDF_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4508       _SOC_SER_INTERLEAVE_MOD2, 
   4509       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4510       _SOC_SER_FLAG_XY_READ},
   4511     { CPU_COS_MAPm, INVALIDm, _SOC_SER_TYPE_PARITY, _SOC_SER_PARITY_4BITS,
   4512       _SOC_SER_INTERLEAVE_MOD2,
   4513       { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0,
   4514       _SOC_SER_FLAG_XY_READ},
   4515     { IP_MULTICAST_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4516       _SOC_SER_PARITY_4BITS,
   4517       _SOC_SER_INTERLEAVE_MOD2,
   4518       { {0, 144}, {1, 144}, {145, 288}, {146, 288} }, 0, 0, 0, 0,
   4519       _SOC_SER_FLAG_XY_READ},
   4520 
   4521     /* SW memscan SER engine protection */
   4522     { UDF_CONDITIONAL_CHECK_TABLE_CAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4523       _SOC_SER_PARITY_4BITS,
   4524       _SOC_SER_INTERLEAVE_MOD2,
   4525       { {0, 64}, {1, 64}, {65, 128}, {66, 128} }, 0, 0, 0, 0,
   4526       _SOC_SER_FLAG_XY_READ},
   4527     { MY_STATION_TCAM_2m, INVALIDm, _SOC_SER_TYPE_PARITY,
   4528       _SOC_SER_PARITY_4BITS,
   4529       _SOC_SER_INTERLEAVE_MOD2,
   4530       { {0, 80}, {1, 80}, {81, 160}, {82, 160} }, 0, 0, 0, 0,
   4531       _SOC_SER_FLAG_XY_READ},
   4532      /* Below memories have SW memscan SER engine protection */
   4533     { FP_GLOBAL_MASK_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4534       -1, -1,
   4535       { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0,
   4536       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE |
   4537       _SOC_SER_FLAG_OVERLAY},
   4538     { FP_GM_FIELDSm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4539       -1, -1,
   4540       { {0, 177}, {2, 177}, {178, 353}, {179, 353} }, 0, 0, 0, 0,
   4541          _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE |
   4542       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE},
   4543 #ifdef INCLUDE_XFLOW_MACSEC
   4544     { ISEC_SP_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4545       -1, -1,
   4546       { {0, 239}, {1, 239}, {240, 480}, {241, 480} }, 0, 0, 0, 0,
   4547       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE
   4548       },
   4549     { ISEC_SC_TCAMm, INVALIDm, _SOC_SER_TYPE_PARITY,
   4550       -1, -1,
   4551       { {0, 75}, {2, 75}, {76,153 }, {78, 153} }, 0, 0, 0, 0,
   4552       _SOC_SER_FLAG_XY_READ | _SOC_SER_FLAG_SW_COMPARE
   4553       },
   4554 #endif
   4555     { INVALIDm },
   4556 };
   4557 
   4558 static _soc_generic_ser_info_t *_soc_monterey_tcam_ser_info[SOC_MAX_NUM_DEVICES];
   4559 
   4560 STATIC int
   4561 _soc_monterey_tcam_ser_init (int unit)
   4562 {
   4563     int alloc_size;
   4564 
   4565     /* First, make per-unit copy of the master TCAM list */
   4566     alloc_size = sizeof(_soc_monterey_tcam_ser_info_template);
   4567     if (NULL == _soc_monterey_tcam_ser_info[unit]) {
   4568         if ((_soc_monterey_tcam_ser_info[unit] =
   4569              sal_alloc(alloc_size, "monterey tcam list")) == NULL) {
   4570             return SOC_E_MEMORY;
   4571         }
   4572     }
   4573 
   4574     /* Make a fresh copy of the TCAM template info */
   4575     sal_memcpy(_soc_monterey_tcam_ser_info[unit],
   4576                &(_soc_monterey_tcam_ser_info_template),
   4577                alloc_size);
   4578 
   4579     return soc_generic_ser_init(unit, _soc_monterey_tcam_ser_info[unit]);
   4580 }
   4581 
   4582 STATIC void
   4583 soc_monterey_ser_fail (int unit)
   4584 {
   4585     soc_generic_ser_process_error(unit, _soc_monterey_tcam_ser_info[unit],
   4586                                   _SOC_PARITY_TYPE_SER);
   4587 }
   4588 
   4589 
   4590 int
   4591 soc_monterey_mem_config(int unit)
   4592 {
   4593     soc_persist_t *sop;
   4594     int l2_entries, cfg_l2_entries;
   4595     int l3_entries, cfg_l3_entries;
   4596     int min_l2_entries;
   4597     int min_l3_entries;
   4598     int max_l2_entries;
   4599     int max_l3_entries;
   4600     int num_ecmp_rh_flowset_entries;
   4601     int num_ipv6_128b_entries = 0;
   4602     int config_v6_entries = 0;
   4603     int defip_config = 0;
   4604     uint16              dev_id;
   4605     uint8               rev_id;
   4606 
   4607     sop = SOC_PERSIST(unit);
   4608     soc_cm_get_id(unit, &dev_id, &rev_id);
   4609 
   4610     min_l2_entries = 32; /* 32K dedicated L2 entries */
   4611     min_l3_entries = 8; /* 8K dedicated L3 entries */
   4612     max_l2_entries = 32; /* Dedicated (32K) + Shared (0)*/
   4613     max_l3_entries = 8; /* Dedicated (8K) + Shared (0)*/
   4614 
   4615     if (SAL_BOOT_SIMULATION) {
   4616         /*
   4617          * Smaller table lengths for BCMSIM environment.
   4618          */
   4619         max_l2_entries = min_l2_entries;
   4620         max_l3_entries = min_l3_entries;
   4621     }
   4622 
   4623     cfg_l2_entries = soc_property_get(unit, spn_L2_MEM_ENTRIES, -1);
   4624     l2_entries = cfg_l2_entries == -1 ? max_l2_entries * 1024 : cfg_l2_entries;
   4625 
   4626     if (l2_entries <= min_l2_entries * 1024) { /* Min table size */
   4627         l2_entries = min_l2_entries * 1024;
   4628     } else if (l2_entries <= max_l2_entries * 1024) {
   4629         /*
   4630          * COVERITY
   4631          * Future chips may have different min, max. Hence not removing it.
   4632          */
   4633         /* coverity[dead_error_line] */
   4634         l2_entries = min_l2_entries * 1024  ;
   4635     } else {
   4636         LOG_CLI((BSL_META_U(unit,
   4637                             "The specified l2_mem_entries (%d) exceeds 272K\n"),
   4638                             cfg_l2_entries));
   4639         return SOC_E_PARAM;
   4640     }
   4641 
   4642     cfg_l3_entries = soc_property_get(unit, spn_L3_MEM_ENTRIES, -1);
   4643     l3_entries = cfg_l3_entries == -1 ? (min_l3_entries * 1024 ) : cfg_l3_entries;
   4644     if (l3_entries <= min_l3_entries * 1024) { /* 4k dedicated L3 entries */
   4645         l3_entries = min_l3_entries * 1024;
   4646     } else if (l3_entries <= max_l3_entries * 1024) {
   4647         /*
   4648          * COVERITY
   4649          * Future chips may have different min, max. Hence not removing it.
   4650          */
   4651         /* coverity[dead_error_line] */
   4652         l3_entries = min_l3_entries * 1024 ;
   4653     } else {
   4654         LOG_CLI((BSL_META_U(unit,
   4655                             "The specified l3_mem_entries (%d) exceeds 260K\n"),
   4656                             cfg_l3_entries));
   4657         return SOC_E_PARAM;
   4658     }
   4659 
   4660 
   4661 
   4662     /* Adjust L2 table size */
   4663     sop->memState[L2Xm].index_max = l2_entries - 1;
   4664     sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
   4665     sop->memState[L2_ENTRY_ONLY_ECCm].index_max = l2_entries - 1;
   4666     sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 4 - 1;
   4667     sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 4 - 1;
   4668     sop->memState[L2_ENTRY_LPm].index_max = min_l2_entries*1024 / 4 - 1;
   4669     sop->memState[L2_ENTRY_ISS_LPm].index_max =
   4670         (l2_entries - min_l2_entries*1024) / 4 - 1;
   4671 
   4672     /* Adjust L3 table size */
   4673     sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1;
   4674     sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1;
   4675     sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = l3_entries / 2 - 1;
   4676     sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = l3_entries/ 2 - 1;
   4677     sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = l3_entries / 4 - 1;
   4678     sop->memState[L3_ENTRY_ONLY_ECCm].index_max = l3_entries - 1;
   4679     sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 4 - 1;
   4680     sop->memState[L3_ENTRY_LPm].index_max = min_l3_entries*1024 / 4 - 1;
   4681     sop->memState[L3_ENTRY_ISS_LPm].index_max =
   4682         (l3_entries - min_l3_entries*1024) / 4 - 1;
   4683 
   4684 
   4685     /* LAG and ECMP resilient hashing features share the same flow set table.
   4686      * The table can be configured in one of 3 modes:
   4687      * - dedicated to LAG resilient hashing,
   4688      * - dedicated to ECMP resilient hashing,
   4689      * - split evenly between LAG and ECMP resilient hashing.
   4690      */
   4691     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   4692             spn_ECMP_RESILIENT_HASH_SIZE, 512);
   4693     switch (num_ecmp_rh_flowset_entries) {
   4694         case 0:
   4695             sop->memState[RH_ECMP_FLOWSETm].index_max = -1;
   4696             break;
   4697         case 512:
   4698             sop->memState[RH_LAG_FLOWSETm].index_max /= 2;
   4699             sop->memState[RH_ECMP_FLOWSETm].index_max /= 2;
   4700             break;
   4701         case 1024:
   4702             sop->memState[RH_LAG_FLOWSETm].index_max = -1;
   4703             break;
   4704         default:
   4705             return SOC_E_CONFIG;
   4706     }
   4707 
   4708     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   4709         SOC_CONTROL(unit)->l3_defip_max_tcams = 0;
   4710     } else if (soc_feature(unit, soc_feature_l3_2k_defip_table)) {
   4711         SOC_CONTROL(unit)->l3_defip_max_tcams = 2;
   4712     } else {
   4713         SOC_CONTROL(unit)->l3_defip_max_tcams = _SOC_MONTEREY_DEFIP_MAX_TCAMS;
   4714     }
   4715     SOC_CONTROL(unit)->l3_defip_tcam_size = _SOC_MONTEREY_DEFIP_TCAM_DEPTH;
   4716 
   4717     if (!soc_feature(unit, soc_feature_lpm_tcam)) {
   4718         /* LPM is disabled, disable all L3_DEFIP memories */
   4719         sop->memState[L3_DEFIPm].index_max = -1;
   4720         sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   4721         sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   4722         sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   4723         sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   4724         sop->memState[L3_DEFIP_ONLYm].index_max = -1;
   4725         sop->memState[L3_DEFIP_DATA_ONLYm].index_max = -1;
   4726         sop->memState[L3_DEFIP_HIT_ONLYm].index_max = -1;
   4727         SOC_CONTROL(unit)->l3_defip_index_remap = 0;
   4728     } else if (soc_property_get(unit, "l3_defip_sizing", TRUE)) {
   4729         if (!soc_property_get(unit, spn_L3_ALPM_ENABLE, 0)) {
   4730             defip_config = soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1);
   4731 
   4732             num_ipv6_128b_entries = soc_property_get(unit,
   4733                                         spn_NUM_IPV6_LPM_128B_ENTRIES,
   4734                                         (defip_config ? 128 : 0));
   4735             num_ipv6_128b_entries = num_ipv6_128b_entries +
   4736                                     (num_ipv6_128b_entries % 2);
   4737 
   4738             config_v6_entries = num_ipv6_128b_entries;
   4739             if (soc_property_get(unit, spn_LPM_SCALING_ENABLE, 0)) {
   4740                 num_ipv6_128b_entries = 0;
   4741                 if (!soc_property_get(unit, spn_LPM_IPV6_128B_RESERVED, 1)) {
   4742                     config_v6_entries = ((config_v6_entries /
   4743                                         SOC_CONTROL(unit)->l3_defip_tcam_size) +
   4744                                         ((config_v6_entries %
   4745                                          SOC_CONTROL(unit)->l3_defip_tcam_size)
   4746                                         ? 1 : 0)) * SOC_CONTROL(unit)->l3_defip_tcam_size;
   4747                 }
   4748             }
   4749             sop->memState[L3_DEFIP_PAIR_128m].index_max =
   4750                                               num_ipv6_128b_entries - 1;
   4751             sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max =
   4752                                               num_ipv6_128b_entries - 1;
   4753             sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max =
   4754                                               num_ipv6_128b_entries - 1;
   4755             sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max =
   4756                                               num_ipv6_128b_entries - 1;
   4757             sop->memState[L3_DEFIPm].index_max =
   4758                                      (SOC_CONTROL(unit)->l3_defip_max_tcams *
   4759                                      SOC_CONTROL(unit)->l3_defip_tcam_size) -
   4760                                      (num_ipv6_128b_entries * 2) - 1;
   4761 
   4762             sop->memState[L3_DEFIP_ONLYm].index_max =
   4763                                           sop->memState[L3_DEFIPm].index_max;
   4764             sop->memState[L3_DEFIP_DATA_ONLYm].index_max =
   4765                                           sop->memState[L3_DEFIPm].index_max;
   4766             sop->memState[L3_DEFIP_HIT_ONLYm].index_max =
   4767                                           sop->memState[L3_DEFIPm].index_max;
   4768             SOC_CONTROL(unit)->l3_defip_index_remap = num_ipv6_128b_entries;
   4769         } else {
   4770             if (soc_property_get(unit, spn_IPV6_LPM_128B_ENABLE, 1)) {
   4771                 /* slightly different processing for v6-128 */
   4772                 num_ipv6_128b_entries = soc_property_get(unit, 
   4773                                             spn_NUM_IPV6_LPM_128B_ENTRIES, 
   4774                                             128);  
   4775                 num_ipv6_128b_entries = num_ipv6_128b_entries + 
   4776                                         (num_ipv6_128b_entries % 2);
   4777                 config_v6_entries = num_ipv6_128b_entries;
   4778                 sop->memState[L3_DEFIP_PAIR_128m].index_max = 
   4779                                                 num_ipv6_128b_entries - 1;
   4780                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = 
   4781                                                 num_ipv6_128b_entries - 1;
   4782                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = 
   4783                                                 num_ipv6_128b_entries - 1;
   4784                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = 
   4785                                                 num_ipv6_128b_entries - 1;
   4786                 sop->memState[L3_DEFIPm].index_max = 
   4787                                   (SOC_CONTROL(unit)->l3_defip_max_tcams * 
   4788                                   SOC_CONTROL(unit)->l3_defip_tcam_size) - 
   4789                                   (num_ipv6_128b_entries * 2) - 1;
   4790     
   4791                 sop->memState[L3_DEFIP_ONLYm].index_max = 
   4792                                        sop->memState[L3_DEFIPm].index_max;
   4793                 sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 
   4794                                        sop->memState[L3_DEFIPm].index_max;
   4795                 sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 
   4796                                        sop->memState[L3_DEFIPm].index_max;
   4797 
   4798                 SOC_CONTROL(unit)->l3_defip_index_remap = 
   4799                                               (num_ipv6_128b_entries / 2) * 2; 
   4800             } else {
   4801                 sop->memState[L3_DEFIP_PAIR_128m].index_max = -1;
   4802                 sop->memState[L3_DEFIP_PAIR_128_ONLYm].index_max = -1;
   4803                 sop->memState[L3_DEFIP_PAIR_128_DATA_ONLYm].index_max = -1;
   4804                 sop->memState[L3_DEFIP_PAIR_128_HIT_ONLYm].index_max = -1;
   4805             }
   4806         }
   4807         soc_l3_defip_indexes_init(unit, config_v6_entries); 
   4808     }
   4809 
   4810     if (NULL == _soc_monterey_alpm_bkt_view_map[unit]) {
   4811         if ((_soc_monterey_alpm_bkt_view_map[unit] = 
   4812              sal_alloc(sizeof(soc_mem_t) * SOC_MONTEREY_ALPM_MAX_BKTS, 
   4813                        "alpm_bkt_map")) == NULL) {
   4814             return SOC_E_MEMORY;
   4815         }
   4816     }
   4817 
   4818     memset(_soc_monterey_alpm_bkt_view_map[unit], INVALIDm,
   4819            sizeof(soc_mem_t) * SOC_MONTEREY_ALPM_MAX_BKTS);
   4820 
   4821     return SOC_E_NONE;
   4822 }
   4823 
   4824 int soc_monterey_get_alpm_banks(int unit)
   4825 {
   4826     int rv = SOC_E_NONE;
   4827     soc_reg_t reg = ISS_LOG_TO_PHY_BANK_MAP_2r;
   4828     uint32 bank_mode = 0;
   4829     uint32 map = 0;
   4830 
   4831     if (_soc_mn_num_shared_alpm_banks[unit] == 0) {
   4832         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &map);
   4833         if (rv >= 0) {
   4834             bank_mode = soc_reg_field_get(unit, reg, map, ALPM_BANK_MODEf);
   4835         }
   4836 
   4837         if (bank_mode == 1) {
   4838             _soc_mn_num_shared_alpm_banks[unit] = 2;
   4839         } else {
   4840             _soc_mn_num_shared_alpm_banks[unit] = 4;
   4841         }
   4842     }
   4843 
   4844     return _soc_mn_num_shared_alpm_banks[unit];
   4845 }
   4846 
   4847 int 
   4848 soc_monterey_alpm_mode_get(int unit)
   4849 {
   4850     return _soc_alpm_mode[unit];
   4851 }
   4852 
   4853 #define _MONTEREY_INDEX_1K_ENTRIES  1024
   4854 #define _MONTEREY_INDEX_2K_ENTRIES  2048
   4855 #define _MONTEREY_INDEX_3K_ENTRIES  3072
   4856 #define _MONTEREY_INDEX_4K_ENTRIES  4096
   4857 #define _MONTEREY_INDEX_6K_ENTRIES  6144
   4858 
   4859 /* Map logical (always starts from 0 and contiguous) index to physical index 
   4860    which can have a starting offset and/or holes.
   4861    Input  : logical index
   4862    Returns: physical index */
   4863 int
   4864 soc_monterey_l3_defip_index_map (int unit, soc_mem_t mem, int index)
   4865 {
   4866     int wide = 0;
   4867     int alpm_mode = _soc_alpm_mode[unit];
   4868     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   4869     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   4870 
   4871     /* don't remap for ALPM */
   4872     if (defip128_tbl_sz == 0) {
   4873         return index;
   4874     }
   4875 
   4876     if (mem == L3_DEFIP_PAIR_128m ||
   4877         mem == L3_DEFIP_PAIR_128_ONLYm ||
   4878         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   4879         mem == L3_DEFIP_PAIR_128_HIT_ONLYm) {
   4880         wide = 1;
   4881     }
   4882 
   4883     if (alpm_mode == 2) {
   4884         if (is_urpf_mode) { 
   4885             if (wide == 0) {
   4886                 if (index >= _MONTEREY_INDEX_2K_ENTRIES) {
   4887                     return index + (defip128_tbl_sz * 2);
   4888                 }
   4889                 return index + defip128_tbl_sz;
   4890             } else {
   4891                 if (index >= _MONTEREY_INDEX_1K_ENTRIES) {
   4892                     return index + defip128_tbl_sz / 2;
   4893                 }
   4894                 return index;
   4895             }
   4896         }
   4897 
   4898         /* not uRPF */
   4899         return (wide) ? index : index + (defip128_tbl_sz * 2);
   4900     } 
   4901     if (alpm_mode == 1) {
   4902         uint32 incr = soc_mem_index_count(unit, mem)/4;
   4903         uint32 entries_per_tcam = _MONTEREY_INDEX_1K_ENTRIES;
   4904         uint32 tcam_num, tcam_idx;
   4905         uint32 cnt_128;
   4906         uint32 tmp;
   4907         
   4908         if (is_urpf_mode) {
   4909             if (wide) {
   4910                 tcam_num = index/incr;
   4911                 tcam_idx = index % incr;
   4912                 return tcam_num * entries_per_tcam + tcam_idx;
   4913             }
   4914             incr = incr/2;
   4915             tcam_num = index/incr;
   4916             tcam_idx = index % incr;
   4917             return tcam_num * entries_per_tcam + tcam_idx + 
   4918                                 defip128_tbl_sz/4;
   4919         }
   4920         if (wide > 0) {
   4921             if (index < (soc_mem_index_count(unit, mem) / 2)) {
   4922                 return index;
   4923             } 
   4924             /* make index relative to upper half */
   4925             index -= (soc_mem_index_count(unit, mem) / 2);
   4926             return index + _MONTEREY_INDEX_2K_ENTRIES;
   4927         }
   4928 
   4929         cnt_128 = defip128_tbl_sz;
   4930  
   4931         if (cnt_128/2 <= _MONTEREY_INDEX_1K_ENTRIES) {
   4932             if ((cnt_128/2 + index) < _MONTEREY_INDEX_1K_ENTRIES) {
   4933                 return index + cnt_128/2;
   4934             } else if ((cnt_128 + index) < _MONTEREY_INDEX_4K_ENTRIES) {
   4935                 return index + cnt_128;
   4936             } else if ((cnt_128 + index + cnt_128/2) < 
   4937                        (_MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_1K_ENTRIES)) {
   4938                 return index + cnt_128 + cnt_128/2;
   4939             } else {
   4940                 return index + 2 * cnt_128;
   4941             }
   4942         } else if (cnt_128/2 <= _MONTEREY_INDEX_2K_ENTRIES) {
   4943             tmp = cnt_128 - _MONTEREY_INDEX_2K_ENTRIES;
   4944             if ((tmp/2 + index + _MONTEREY_INDEX_2K_ENTRIES) < _MONTEREY_INDEX_3K_ENTRIES) {
   4945                 return index + _MONTEREY_INDEX_2K_ENTRIES + tmp/2;
   4946             } else if ((cnt_128 + index) < _MONTEREY_INDEX_4K_ENTRIES) {
   4947                 return index + cnt_128;
   4948             } else if ((cnt_128 + tmp/2 + index + _MONTEREY_INDEX_2K_ENTRIES) < 
   4949                        (_MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_3K_ENTRIES)) {
   4950                 return index + cnt_128 + tmp/2 + _MONTEREY_INDEX_2K_ENTRIES;
   4951             } else {
   4952                 return index + cnt_128 * 2;
   4953             }
   4954         }
   4955         
   4956         if (index < soc_mem_index_count(unit, mem)/2) {
   4957             return index + defip128_tbl_sz;
   4958         } else {
   4959             /* make index relative to upper half */
   4960             index -= (soc_mem_index_count(unit, mem)/2);
   4961             return index + 2 * _MONTEREY_INDEX_2K_ENTRIES + 
   4962                    defip128_tbl_sz;
   4963        }
   4964     }
   4965 
   4966     if (is_urpf_mode) { /* URPF mode */
   4967         return soc_l3_defip_urpf_index_map(unit, wide, index);
   4968     }
   4969 
   4970     return soc_l3_defip_index_map(unit, wide, index);
   4971 }
   4972 
   4973 /* Reverse map physical index to logical index.
   4974    Input  : physical index
   4975    Returns: logical index */
   4976 int
   4977 soc_monterey_l3_defip_index_remap(int unit, soc_mem_t mem, int index)
   4978 {
   4979     int wide = 0;
   4980     int alpm_mode = _soc_alpm_mode[unit];
   4981     int is_urpf_mode = SOC_CONTROL(unit)->l3_defip_urpf;
   4982     int defip128_tbl_sz = SOC_CONTROL(unit)->l3_defip_index_remap;
   4983 
   4984     /* don't remap for ALPM */
   4985     if (defip128_tbl_sz == 0) {
   4986         return index;
   4987     }
   4988 
   4989     if (mem == L3_DEFIP_PAIR_128m ||
   4990         mem == L3_DEFIP_PAIR_128_ONLYm ||
   4991         mem == L3_DEFIP_PAIR_128_DATA_ONLYm ||
   4992         mem == L3_DEFIP_PAIR_128_HIT_ONLYm) {
   4993         wide = 1;
   4994     }
   4995 
   4996     if (alpm_mode == 2) {
   4997         if (is_urpf_mode) { /* URPF mode */
   4998             if (wide == 0) {
   4999                 if (index >= _MONTEREY_INDEX_6K_ENTRIES) {
   5000                     return index - (defip128_tbl_sz * 2);
   5001                 }
   5002                 return index - defip128_tbl_sz;
   5003             } else {
   5004                 if (index >= _MONTEREY_INDEX_1K_ENTRIES) {
   5005                     return index - defip128_tbl_sz / 2;
   5006                 }
   5007                 return index;
   5008             }
   5009         }
   5010         return (wide) ? index : index - (defip128_tbl_sz * 2);
   5011     } 
   5012     if (alpm_mode == 1) {
   5013         int cnt_128;
   5014         
   5015         if (is_urpf_mode) {
   5016             uint32 num_chunks, chunk_offset;
   5017             if (wide) {
   5018                 num_chunks = index / _MONTEREY_INDEX_1K_ENTRIES;
   5019                 chunk_offset = index % _MONTEREY_INDEX_1K_ENTRIES;
   5020                 return num_chunks * soc_mem_index_count(unit, mem)/4 
   5021                        + chunk_offset;
   5022             }
   5023             num_chunks = index / _MONTEREY_INDEX_1K_ENTRIES;
   5024             chunk_offset = index % _MONTEREY_INDEX_1K_ENTRIES;
   5025             chunk_offset -= (defip128_tbl_sz/4);
   5026             return num_chunks*soc_mem_index_count(unit, mem)/8 + chunk_offset;
   5027             
   5028         }
   5029 
   5030         cnt_128 = defip128_tbl_sz;
   5031         
   5032         if (wide) {
   5033             if (index < cnt_128/2) {
   5034                 return index;
   5035             } else if ((index >= _MONTEREY_INDEX_2K_ENTRIES) && 
   5036                        (index < _MONTEREY_INDEX_2K_ENTRIES + cnt_128/2)){
   5037                 return index - _MONTEREY_INDEX_2K_ENTRIES + cnt_128/2;               
   5038             } else {
   5039                 return -1;
   5040             }
   5041         }
   5042 
   5043         if (cnt_128/2 <= _MONTEREY_INDEX_1K_ENTRIES) {
   5044             if ((index < _MONTEREY_INDEX_1K_ENTRIES) &&
   5045                 (index >= cnt_128/2)) {
   5046                 return index - cnt_128/2;
   5047             } else if ((index >= _MONTEREY_INDEX_1K_ENTRIES + cnt_128/2) && 
   5048                            (index < _MONTEREY_INDEX_4K_ENTRIES)) {
   5049                 return index - cnt_128;
   5050             } else if ((index < _MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_1K_ENTRIES) &&
   5051                            (index >= _MONTEREY_INDEX_4K_ENTRIES + cnt_128/2)) {
   5052                 return index - cnt_128 - cnt_128/2;
   5053             } else {
   5054                 return index - cnt_128 * 2;
   5055             }
   5056         } else if (cnt_128/2 <= _MONTEREY_INDEX_2K_ENTRIES) {
   5057             if (index < _MONTEREY_INDEX_3K_ENTRIES) {
   5058                 return index - _MONTEREY_INDEX_2K_ENTRIES - \
   5059                        (cnt_128 - _MONTEREY_INDEX_2K_ENTRIES)/2;
   5060             } else if (index < _MONTEREY_INDEX_4K_ENTRIES) {
   5061                 return index - cnt_128;
   5062             } else if (index < _MONTEREY_INDEX_4K_ENTRIES + _MONTEREY_INDEX_3K_ENTRIES) {
   5063                 return index - cnt_128 - _MONTEREY_INDEX_2K_ENTRIES - \
   5064                        (cnt_128 - _MONTEREY_INDEX_2K_ENTRIES)/2;
   5065             } else {
   5066                 return index - cnt_128 * 2;
   5067             }
   5068         }
   5069     }
   5070     if (is_urpf_mode) { /* URPF mode */
   5071         return soc_l3_defip_urpf_index_remap(unit, wide, index);
   5072     }
   5073 
   5074     return soc_l3_defip_index_remap(unit, wide, index);
   5075 }
   5076 
   5077 /* Given a physical index (always in terms of the narrow entry) 
   5078    return the logical index and memory type */
   5079 int
   5080 soc_monterey_l3_defip_mem_index_get(int unit, int pindex, soc_mem_t *mem)
   5081 {
   5082     return soc_l3_defip_index_mem_map(unit, pindex, mem);
   5083 }
   5084 
   5085 void
   5086 _soc_monterey_alpm_bkt_view_set(int unit, int index, soc_mem_t view)
   5087 {
   5088     int bkt = soc_monterey_get_alpm_banks(unit) + 1;
   5089     bkt = (index >> (bkt / 2)) & SOC_MONTEREY_ALPM_BKT_MASK;
   5090 
   5091     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt set index:%d bkt:%d view:%s\n"),
   5092                  unit, index, bkt, SOC_MEM_NAME(unit, view)));
   5093     _soc_monterey_alpm_bkt_view_map[unit][bkt] = view;
   5094 }
   5095 
   5096 soc_mem_t
   5097 _soc_monterey_alpm_bkt_view_get(int unit, int index)
   5098 {
   5099     soc_mem_t view;
   5100     int bkt = soc_monterey_get_alpm_banks(unit) + 1;
   5101     bkt = (index >> (bkt / 2)) & SOC_MONTEREY_ALPM_BKT_MASK;
   5102 
   5103     view = _soc_monterey_alpm_bkt_view_map[unit][bkt];
   5104     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Unit:%d ALPM bkt get index:%d bkt:%d view:%s\n"),
   5105                  unit, index, bkt, SOC_MEM_NAME(unit, view)));
   5106     return view;
   5107 }
   5108  
   5109 int
   5110 _soc_monterey_mem_cpu_write_control(int unit, soc_mem_t mem, int copyno,
   5111                                     int enable, int *orig_enable)
   5112 {
   5113     soc_reg_t reg;
   5114     soc_field_t field;
   5115     int blk, port;
   5116     soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLK_XLPORTB0, SOC_BLOCK_TYPE_INVALID};
   5117     uint32 rval, fval, orig_fval, enable_fval, disable_fval;
   5118 
   5119     enable_fval = 1;
   5120     disable_fval = 0;
   5121 
   5122     switch (mem) {
   5123     case XLPORT_WC_UCMEM_DATAm:
   5124         reg = XLPORT_WC_UCMEM_CTRLr;
   5125         field = ACCESS_MODEf;
   5126         SOC_BLOCKS_ITER(unit, blk, xlport_blocks) {
   5127             port = SOC_BLOCK_PORT(unit, blk);
   5128             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval));
   5129             /* It will use the setting from the last block */
   5130             *orig_enable = soc_reg_field_get(unit, reg, rval, field);
   5131             soc_reg_field_set(unit, reg, &rval, field, enable ? 1 : 0);
   5132             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   5133         }
   5134         return SOC_E_NONE;
   5135     case L3_DEFIP_ALPM_RAWm:
   5136     case L3_DEFIP_ALPM_IPV4m:
   5137     case L3_DEFIP_ALPM_IPV4_1m:
   5138     case L3_DEFIP_ALPM_IPV6_64m:
   5139     case L3_DEFIP_ALPM_IPV6_64_1m:
   5140     case L3_DEFIP_ALPM_IPV6_128m:
   5141         reg = ISS_MEMORY_CONTROL_84r;
   5142         field = BYPASS_ISS_MEMORY_LPf;
   5143         enable_fval = 0xf;
   5144         break;
   5145     case MMU_INTFI_PFC_ST_TBLm:
   5146         reg = INTFI_CFGr;
   5147         field = PFC_ST_TBL_DISABLEf;
   5148         break;
   5149     case LINK_STATUSm:
   5150         reg = SW2_HW_CONTROLr;
   5151         field = LINK_STATUS_UPDATE_ENABLEf;
   5152         break;
   5153     case MMU_INTFO_QCN_CNM_TIMER_TBLm:
   5154     case MMU_INTFI_XPIPE_FC_MAP_TBL2m:
   5155     case MMU_MTRI_BKPMETERINGBUCKET_MEM_0m:
   5156     case MMU_MTRO_BUCKET_L0_MEM_0m:
   5157     case MMU_MTRO_BUCKET_L1_MEM_0m:
   5158     case MMU_MTRO_BUCKET_L1_MEM_1m:
   5159     case MMU_MTRO_BUCKET_L2_MEM_0m:
   5160     case MMU_MTRO_BUCKET_L2_MEM_1m:
   5161     case MMU_MTRO_BUCKET_L2_MEM_2m:
   5162     case MMU_MTRO_BUCKET_L2_MEM_3m:
   5163     case MMU_MTRO_BUCKET_L2_MEM_4m:
   5164     case MMU_MTRO_BUCKET_L2_MEM_5m:
   5165     case MMU_MTRO_BUCKET_L2_MEM_6m:
   5166     case MMU_MTRO_BUCKET_L2_MEM_7m:
   5167     case MMU_WRED_AVG_QSIZE_X_PIPEm:
   5168     case MMU_WRED_CONFIG_X_PIPEm:
   5169     case MMU_WRED_PORT_SP_DROP_THD_X_PIPEm:
   5170     case MMU_WRED_QGROUP_DROP_THD_X_PIPEm:
   5171     case MMU_WRED_UC_QUEUE_DROP_THD_DEQ_X_PIPE_0m:
   5172     case MMU_WRED_UC_QUEUE_DROP_THD_ENQ_X_PIPE_0m:
   5173         reg = MISCCONFIGr;
   5174         field = REFRESH_ENf;
   5175         enable_fval = 0;
   5176         disable_fval = 1;
   5177         break;
   5178     default:
   5179         return SOC_E_NONE;
   5180     }
   5181 
   5182     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   5183     orig_fval = soc_reg_field_get(unit, reg, rval, field);
   5184     fval = enable ? enable_fval : disable_fval;
   5185 
   5186     *orig_enable = orig_fval == enable_fval;
   5187     if (fval != orig_fval) {
   5188         soc_reg_field_set(unit, reg, &rval, field, fval);
   5189         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   5190     }
   5191 
   5192     return SOC_E_NONE;
   5193 }
   5194 
   5195 /*
   5196  * cpu port (mmu port 65): 48 queues (1300-1347)
   5197  * loopback port (mmu port 66): 10 queues (1290- 1299)
   5198  * MACSEC (mmu port 64) 10 queues (1280-1289)
   5199  */
   5200 #define _MONTEREY_CPU_QUEUE_BASE  1300
   5201 #define _MONTEREY_MACSEC_QUEUE_BASE   1280
   5202 #define _MONTEREY_LB_QUEUE_BASE   1290
   5203 #define _MONTEREY_HSP_PORTS       64
   5204 #define _MONTEREY_UC_QUEUE_BASE   0
   5205 #define _MONTEREY_MC_QUEUE_BASE   640
   5206 #define _MONTEREY_NUMBER_OF_UC_QUEUE   640
   5207 #define _MONTEREY_NUMBER_OF_MC_QUEUE   708
   5208 #define IS_MN_HSP_PORT(u,p)   \
   5209     ((_soc_apache_port_sched_type_get((u),(p)) == SOC_APACHE_SCHED_HSP) ? 1 : 0)
   5210 
   5211 
   5212 int
   5213 soc_monterey_num_cosq_init(int unit)
   5214 {
   5215     soc_info_t *si;
   5216     int port, phy_port, mmu_port;
   5217     int hsp_uc_cosq_base, hsp_mc_cosq_base;
   5218 
   5219     si = &SOC_INFO(unit);
   5220 
   5221     si->port_cosq_base[CMIC_PORT(unit)] = _MONTEREY_CPU_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE;
   5222     si->port_num_cosq[CMIC_PORT(unit)] = 48;
   5223     si->port_num_cosq[LB_PORT(unit)] = 10;
   5224     si->port_cosq_base[LB_PORT(unit)] = _MONTEREY_LB_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE ;
   5225     si->port_cosq_base[MACSEC_PORT(unit)] = _MONTEREY_MACSEC_QUEUE_BASE - _MONTEREY_MC_QUEUE_BASE ;
   5226     si->port_num_cosq[MACSEC_PORT(unit)] = 10;
   5227     si->port_cosq_base[64] = 1280 - _MONTEREY_MC_QUEUE_BASE;
   5228 
   5229 
   5230     hsp_uc_cosq_base = 0;
   5231     hsp_mc_cosq_base = 0;
   5232 
   5233     for (mmu_port = 0; mmu_port < _MONTEREY_MMU_PORTS_PER_PIPE; mmu_port++) {
   5234        phy_port = si->port_m2p_mapping[mmu_port];
   5235         if (phy_port == -1) {
   5236             continue;
   5237         }
   5238 
   5239         port = si->port_p2l_mapping[phy_port];
   5240         if (port == -1) {
   5241             continue;
   5242         }
   5243 
   5244         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) {
   5245             continue;
   5246         }
   5247 
   5248             si->port_num_cosq[port] = 10;
   5249             si->port_cosq_base[port] = hsp_mc_cosq_base + (mmu_port * si->port_num_cosq[port]);
   5250             si->port_num_uc_cosq[port] = 10;
   5251             /* Made port_uc_cosq_base a function of mmu_port number
   5252                 * rather than a running number (as calculated by
   5253                 * uc_cosq_base before). If it is a running number, &
   5254                 * the port numbers come & go dynamically (as in flex port)
   5255                 * uc_cosq_base overlap. With port_uc_cosq_base a function
   5256                 * of mmu_port, each port has a fixed offset
   5257  */
   5258             si->port_uc_cosq_base[port] = hsp_uc_cosq_base + (mmu_port * 10);
   5259 
   5260     }
   5261     return SOC_E_NONE;
   5262 
   5263 }
   5264 
   5265 STATIC int
   5266 soc_monterey_frequency_get(int unit, int *max_freq, int *def_freq)
   5267 {
   5268     if (soc_feature(unit, soc_feature_untethered_otp)) {
   5269         *max_freq = SOC_BOND_INFO(unit)->max_core_freq;
   5270         *def_freq = SOC_BOND_INFO(unit)->default_core_freq;
   5271     } else {
   5272         *def_freq = *max_freq = 862;
   5273     }
   5274 
   5275     return SOC_E_NONE;
   5276 }
   5277 
   5278 int
   5279 soc_monterey_tsc_map_get(int unit, uint32 *tsc_map, uint32 *force_hg)
   5280 {
   5281 
   5282     if (soc_feature(unit, soc_feature_untethered_otp)) {
   5283         *tsc_map = SOC_BOND_INFO(unit)->tsc_enable;
   5284         *force_hg = SOC_BOND_INFO(unit)->tsc_force_hg;
   5285     } else {
   5286         *tsc_map = 0xffffffff;
   5287         *force_hg = 0x0;
   5288     }
   5289 
   5290     return SOC_E_NONE;
   5291 }
   5292 
   5293 typedef struct soc_monterey_valid_fallback_cores_s {
   5294     soc_100g_lane_config_t lane_config;
   5295     int                    valid_lanes[3];
   5296 }soc_monterey_valid_fallback_cores_t;
   5297 
   5298 const soc_monterey_valid_fallback_cores_t soc_monterey_valid_an_cores[] = {
   5299     {SOC_LANE_CONFIG_100G_4_4_2, {TRUE, TRUE, TRUE} },
   5300     {SOC_LANE_CONFIG_100G_3_4_3, {TRUE, TRUE, TRUE} },
   5301     {SOC_LANE_CONFIG_100G_2_4_4, {TRUE, TRUE, TRUE} },
   5302     {SOC_INVALID_LANE_CONFIG}
   5303 };
   5304 /*
   5305 STATIC int
   5306 soc_monterey_port_is_cpri_supported(int unit, int phy_port) { 
   5307       if (((phy_port > 0) && (phy_port < 13)) ||
   5308            ((phy_port > 52) && (phy_port < 65))) { 
   5309              return TRUE;
   5310       }
   5311       return FALSE;   
   5312 }*/
   5313  int
   5314 soc_monterey_port_is_falcon(int unit, int phy_port)
   5315 {
   5316 
   5317     if (((phy_port >= 1) && (phy_port <= 20)) ||
   5318         ((phy_port >= 45) && (phy_port <= 64))) {
   5319         return TRUE;
   5320     }
   5321 
   5322     return FALSE;
   5323 }
   5324 
   5325 STATIC int
   5326 soc_monterey_port_is_2p5g_forced(int unit, int phy_port)
   5327 {
   5328     int tsc_id, bit_pos;
   5329     if (soc_monterey_port_is_falcon(unit, phy_port) ||
   5330         !soc_feature(unit, soc_feature_untethered_otp)) {
   5331         return FALSE;
   5332     }
   5333 
   5334     tsc_id = ((phy_port - 1) / MONTEREY_PORTS_PER_TSC);
   5335 
   5336     /* SOC_BOND_INFO(unit)->eagle_force_2p5g is 14bit wide representing 14 Eagle TSCs in AP
   5337      * In case TSC belongs in PGW 1, subtract 2 TSC falcons of PGW 0 to get correct bit pos
   5338      */
   5339     bit_pos = (tsc_id >= MONTEREY_TSCS_PER_PGW) ? (tsc_id - MONTEREY_NUM_CLP_PER_PGW) : tsc_id;
   5340 
   5341     if (!((SOC_BOND_INFO(unit)->tsce_max_2p5g) & (1 << bit_pos))) {
   5342         return FALSE;
   5343     }
   5344     return TRUE;
   5345 }
   5346 
   5347 /* If CLPORT0/1/2/3/4/5 block is disabled */
   5348 #define IS_100G_DISABLED(clp_block) \
   5349     (soc_feature(unit, soc_feature_untethered_otp) ? (!((SOC_BOND_INFO(unit)->clmac_map) & (1 << (clp_block)))) : (0))
   5350 
   5351 STATIC soc_error_t
   5352 _soc_monterey_port_lanes_set(int unit, int phy_port, int *lanes, int port_bandwidth)
   5353 {
   5354     if (soc_monterey_port_is_falcon(unit, phy_port)) {
   5355         *lanes =   (port_bandwidth > 53000) ?
   5356                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? -1
   5357                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? -1
   5358                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? -1
   5359                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? -1
   5360                      : 4
   5361                  : (port_bandwidth > 42000) ? 2
   5362                  : (port_bandwidth > 27000) ?
   5363                        (IS_100G_DISABLED(1) && (phy_port == 29)) ? 4
   5364                      : (IS_100G_DISABLED(2) && (phy_port == 33)) ? 4
   5365                      : (IS_100G_DISABLED(4) && (phy_port == 65)) ? 4
   5366                      : (IS_100G_DISABLED(5) && (phy_port == 69)) ? 4
   5367                      : 2
   5368                      : (port_bandwidth == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(21000)) ? 2 
   5369                  : 1;
   5370     } else {
   5371                  *lanes =  ((port_bandwidth > 21000)? 4
   5372                  :((port_bandwidth > 11000) ? 2
   5373                  : 1));
   5374     }
   5375     return ((*lanes == -1) ? SOC_E_CONFIG : SOC_E_NONE);
   5376 }
   5377 
   5378 /* Function to check legal BW values per port 
   5379  */
   5380 STATIC int
   5381 _soc_monterey_port_speed_supported(int unit, int port, int phy_port,
   5382                                  int port_lanes, int port_bandwidth)
   5383 {
   5384     soc_pbmp_t xe_pbmp;
   5385 
   5386     if (port_lanes == -1) {
   5387         if (SOC_FAILURE(_soc_monterey_port_lanes_set(unit, phy_port, &port_lanes, port_bandwidth))) {
   5388             return FALSE;
   5389         }
   5390     }
   5391 
   5392     switch (port_bandwidth) {
   5393     case 1000:
   5394         /*  Eagles or Falcons - 1 x lanes */
   5395         return (port_lanes == 1);
   5396     case 2500:
   5397     case 5000:
   5398         /*  Eagles or Falcons - 1 x lanes */
   5399         return (port_lanes == 1);
   5400     case 10000:
   5401         /*  Falcons - 1 x lanes and Eagles - 1, 2 or 4 lanes */
   5402         return (!soc_monterey_port_is_falcon(unit, phy_port) ||
   5403                 (soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 1)));
   5404     case 20000:
   5405         /*  Eagles or Falcons - 2 x lanes */
   5406         return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)) || (port_lanes == 2));
   5407     case 25000:
   5408         /*  Falcons only - 1 x lanes */
   5409         return ((soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 1)) ||
   5410                 (!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)));
   5411     case 30000:
   5412         /*  Eagles only - 4 x lanes */
   5413         return (!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4));
   5414     case 40000:
   5415         /*  Eagles - 4 x lanes; Falcons - 2, 4 lanes */
   5416         return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 4)) ||
   5417                 (soc_monterey_port_is_falcon(unit, phy_port) && ((port_lanes == 2) || (port_lanes == 4))));
   5418     case 50000:
   5419         /*  Falcons only - 2,4 lanes */
   5420         return (soc_monterey_port_is_falcon(unit, phy_port) && ((port_lanes == 2)));
   5421     case 100000:
   5422         /*  Eagles - 10 x lanes; Falcons - 4 lanes */
   5423         return ((!soc_monterey_port_is_falcon(unit, phy_port) && (port_lanes == 10)) ||
   5424                 (soc_monterey_port_is_falcon(unit, phy_port) &&  (port_lanes == 4)));
   5425 
   5426     case 11000:
   5427     case 21000:
   5428     case 27000:
   5429     case 42000:
   5430     case 53000:
   5431     case 106000:
   5432         SOC_PBMP_CLEAR(xe_pbmp);
   5433         xe_pbmp = soc_property_get_pbmp_default(unit,
   5434                                spn_PBMP_XPORT_XE, xe_pbmp);
   5435         if (!SOC_PBMP_MEMBER(xe_pbmp, port)) {
   5436             return _soc_monterey_port_speed_supported(unit, port, phy_port, port_lanes, SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(port_bandwidth));
   5437         } else {
   5438             LOG_CLI((BSL_META_U(unit,
   5439                                 "Port %d: Invalid HG2 bandwidth %d Gb\n"),
   5440                      port, port_bandwidth / 1000));
   5441             return FALSE;
   5442         }
   5443         break;
   5444 
   5445     default:
   5446         LOG_CLI((BSL_META_U(unit,
   5447                             "Port %d: Invalid bandwidth %d Gb\n"),
   5448                  port, port_bandwidth / 1000));
   5449         return FALSE;
   5450         break;
   5451     }
   5452 
   5453     return FALSE;
   5454 }
   5455 
   5456 int
   5457 soc_monterey_port_config_bandwidth_check(int unit)
   5458 {
   5459     int rv = SOC_E_NONE;
   5460     int oversub_mode;
   5461     int port_bandwidth;
   5462     int *blk_port = NULL;
   5463     int *blk_port_bandwidth = NULL;
   5464     int index, port, phy_port, lane_count, blk, pgw;
   5465 
   5466     int speed_lanes_1 = 0, speed_lanes_2 = 0;
   5467     int blk_linerate_bandwidth, blk_oversub_bandwidth;
   5468     int pgw_port[MONTEREY_PORTS_PER_PGW];
   5469     int pgw_port_bandwidth[MONTEREY_PORTS_PER_PGW];
   5470     int pgw_linerate_bandwidth[MONTEREY_PGWS_PER_DEV], pgw_oversub_bandwidth[MONTEREY_PGWS_PER_DEV];
   5471     int max_pgw_core_bandwidth[MONTEREY_PGWS_PER_DEV];
   5472     int max_pgw_oversub_bandwidth[MONTEREY_PGWS_PER_DEV];
   5473     int os_ratio[MONTEREY_PGWS_PER_DEV];
   5474     /* MAX OS ratio for a few FB5 configs is > 1.5 but is limited only to a single PGW */
   5475     int max_os_ratio = 1750, def_os_ratio = 1500;
   5476     uint32 blk_configured_map, blk_inactive_map, blk_oversub_map;
   5477     int falcon_lr_bandwidth = 0, falcon_os_bandwidth = 0, *falcon_bw_ptr = 0;
   5478 
   5479     for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) {
   5480         max_pgw_core_bandwidth[pgw] = (SOC_INFO(unit).bandwidth) / MONTEREY_PGWS_PER_DEV;
   5481         max_pgw_oversub_bandwidth[pgw] = (SOC_INFO(unit).io_bandwidth) / MONTEREY_PGWS_PER_DEV;
   5482     }
   5483 
   5484     oversub_mode = 1;
   5485 /*In monterey even the LR config is oversub as it is line rate only for 256 bytes packet*/
   5486 
   5487     /* Bandwidth check for ports in each XLPORT/CLPORT block */
   5488     for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) {
   5489         pgw_linerate_bandwidth[pgw] = 0;
   5490         pgw_oversub_bandwidth[pgw] = 0;
   5491 
   5492         /* Prepare per PGW local variables for ease of processing */
   5493         for (index = 0; index < MONTEREY_PORTS_PER_PGW; index++) {
   5494             phy_port = 1 + pgw * MONTEREY_PORTS_PER_PGW + index;
   5495             port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   5496             pgw_port[index] = port;
   5497             if (port == -1) {
   5498                 pgw_port_bandwidth[index] = 0;
   5499             } else {
   5500                  pgw_port_bandwidth[index] = SOC_INFO(unit).port_speed_max[port];
   5501                  MONTEREY_TDM_SPEED_ADJUST(unit, port, pgw_port_bandwidth[index]);
   5502             }
   5503         }
   5504 
   5505         for (blk = 0; blk < MONTEREY_TSCS_PER_PGW; blk++) {
   5506 
   5507             blk_port = &pgw_port[blk * MONTEREY_PORTS_PER_TSC];
   5508             blk_port_bandwidth = &pgw_port_bandwidth[blk * MONTEREY_PORTS_PER_TSC];
   5509 
   5510             blk_configured_map = 0;
   5511             for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) {
   5512                 if (blk_port[index] != -1) {
   5513                     blk_configured_map |= 1 << index;
   5514                 }
   5515             }
   5516             if (blk_configured_map == 0) {
   5517                 continue;
   5518             }
   5519 
   5520             /* Normal port block handling */
   5521             blk_inactive_map = 0;
   5522             blk_oversub_map = 0;
   5523             blk_linerate_bandwidth = 0;
   5524             blk_oversub_bandwidth = 0;
   5525             for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) {
   5526                 port = blk_port[index];
   5527                 phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   5528                 if (port == -1) {
   5529                     continue;
   5530                 }
   5531                 port_bandwidth = blk_port_bandwidth[index];
   5532                     blk_oversub_map |= 1 << index;
   5533                 if (SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5534                     blk_inactive_map |= 1 << index;
   5535                 } else {
   5536                     if (blk_oversub_map & (1 << index)) {
   5537                         falcon_bw_ptr = &falcon_os_bandwidth;
   5538                         blk_oversub_bandwidth += port_bandwidth;
   5539                     } else {
   5540                         falcon_bw_ptr = &falcon_lr_bandwidth;
   5541                         blk_linerate_bandwidth += port_bandwidth;
   5542                     }
   5543                 }
   5544 
   5545                 /* 0-4 Blocks are PM4x25(falcon) and 5-8 are PM4x10 eagle  in pgw0 */
   5546                 /* 0-2 eagle  Blocks are PM4x10(falcon) and 3-8- are PM4x25  in pgw1 */
   5547                 if ((pgw == 0 && blk >= 5  && blk <= 7) || 
   5548                      (pgw == 1 && blk >= 0  && blk <= 2)) {
   5549 
   5550                       if((port_bandwidth > 21000 && (index != 0)) ||
   5551                         (port_bandwidth > 11000 && (index & 1))) {
   5552 
   5553                         LOG_CLI((BSL_META_U(unit,
   5554                                             "Port %d: Physical port %d can not "
   5555                                             "be configured to %d Gb\n"),
   5556                                  port, phy_port, (port_bandwidth / 1000)));
   5557                         rv = SOC_E_FAIL;
   5558                     }
   5559 
   5560                     speed_lanes_1 = 11000;
   5561                     speed_lanes_2 = 21000;
   5562                }
   5563 
   5564                 if ((pgw == 0 && blk >= 0 && blk <= 4) ||
   5565                      (pgw == 1 && blk >=3 &&  blk <= 7)) {                              
   5566                     if ((port_bandwidth > 106000) ||
   5567                         (port_bandwidth > 53000 && (index != 0)) ||
   5568                         (port_bandwidth > 27000 && (index & 0))) {
   5569 
   5570                         LOG_CLI((BSL_META_U(unit,
   5571                                             "Port %d: Physical port %d can not "
   5572                                             "be configured to %d Gb\n"),
   5573                                  port, phy_port, (port_bandwidth / 1000)));
   5574                         rv = SOC_E_FAIL;
   5575                     }
   5576 
   5577                     speed_lanes_1 = 27000;
   5578                     speed_lanes_2 = 53000;
   5579                     if (falcon_bw_ptr) {  
   5580                         *falcon_bw_ptr += port_bandwidth;
   5581                     }
   5582                 }
   5583             }
   5584 
   5585             /* Check if any of the lanes used by first port of block is
   5586              * not used by other port */
   5587             port_bandwidth = blk_port_bandwidth[0];
   5588             if (port_bandwidth > speed_lanes_2) {
   5589                 lane_count = 4;
   5590             } else if (port_bandwidth > speed_lanes_1) {
   5591                 lane_count = 2;
   5592             } else {
   5593                 lane_count = 1;
   5594             }
   5595 
   5596             for (index = 1; index < lane_count; index++) {
   5597                 port = blk_port[index];
   5598                 if (port == -1 || SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5599                     continue;
   5600                 }
   5601                 LOG_CLI((BSL_META_U(unit,
   5602                                     "Port %d bandwidth %d Gb and "
   5603                                     "port %d can not be both configured\n"),
   5604                          blk_port[0], port_bandwidth / 1000, port));
   5605                 rv = SOC_E_FAIL;
   5606             }
   5607 
   5608             /* Check if any of the lanes used by third port of block is
   5609              * not used by other port */
   5610             port_bandwidth = blk_port_bandwidth[2];
   5611             if (port_bandwidth > speed_lanes_1) {
   5612                 port = blk_port[3];
   5613                 if (port != -1 && !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) {
   5614                     LOG_CLI((BSL_META_U(unit,
   5615                                         "Port %d bandwidth %d Gb and port %d "
   5616                                         "can not be both configured\n"),
   5617                              blk_port[2], port_bandwidth / 1000, port));
   5618                     rv = SOC_E_FAIL;
   5619                 }
   5620                 if (blk_port[0] == -1) {
   5621                     LOG_CLI((BSL_META_U(unit,
   5622                                "Physical port %d needs to be "
   5623                                "configured in order to work with "
   5624                                "port %d\n"),
   5625                                1 + pgw * MONTEREY_PORTS_PER_PGW +
   5626                                blk * MONTEREY_PORTS_PER_TSC,
   5627                                blk_port[2]));
   5628                     rv = SOC_E_FAIL;
   5629                 }
   5630             }
   5631 
   5632             if (blk_inactive_map == blk_configured_map) {
   5633                 LOG_CLI((BSL_META_U(unit, "Flex port")));
   5634                 for (index = 0; index < MONTEREY_PORTS_PER_TSC; index++) {
   5635                     if (blk_port[index] != -1) {
   5636                         LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index]));
   5637                     }
   5638                 }
   5639                 LOG_CLI((BSL_META_U(unit, ": Can not be all inactive\n")));
   5640                 rv = SOC_E_FAIL;
   5641                 continue;
   5642             }
   5643 
   5644             if (blk_inactive_map != 0) {
   5645                 if (blk_oversub_map != 0 &&
   5646                     blk_oversub_map != blk_configured_map) {
   5647                     LOG_CLI((BSL_META_U(unit, "Flex port")));
   5648                     for (index = 0; index < MONTEREY_PORTS_PER_TSC;
   5649                          index++) {
   5650                         if (blk_port[index] != -1) {
   5651                             LOG_CLI((BSL_META_U(unit, " %d"), blk_port[index]));
   5652                         }
   5653                     }
   5654                     LOG_CLI((BSL_META_U(unit,
   5655                                         ": Can not be configured to "
   5656                                         "different oversubscription "
   5657                                         "mode within a port block\n")));
   5658                     rv = SOC_E_FAIL;
   5659                     continue;
   5660                 }
   5661             }
   5662 
   5663             if (falcon_lr_bandwidth != 0 && falcon_os_bandwidth != 0) {
   5664                 LOG_CLI((BSL_META_U(unit,
   5665                                     "TDM algorith does not support mixed LR and OS ports "
   5666                                     "modes on PM4x25 ports. LR BW = %d Gbps & OS BW = %d Gbps\n"),
   5667                          falcon_lr_bandwidth / 1000, falcon_os_bandwidth / 1000));
   5668                 rv = SOC_E_FAIL;
   5669             }
   5670 
   5671 
   5672             if (blk_linerate_bandwidth != 0 && blk_oversub_map != 0) {
   5673                 LOG_CLI((BSL_META_U(unit,
   5674                                     "TSC %d cannot have mixed LR and OS ports "
   5675                                     "LR Bandwidth = %d Gbps & OS Bandwidth = %d Gbps\n"),
   5676                          blk, blk_linerate_bandwidth / 1000, blk_oversub_bandwidth / 1000));
   5677                 rv = SOC_E_FAIL;
   5678             }
   5679 
   5680              pgw_linerate_bandwidth[pgw] += blk_linerate_bandwidth;
   5681              pgw_oversub_bandwidth[pgw] += blk_oversub_bandwidth;
   5682         } /* for (blk = 0; blk < MONTEREY_TSCS_PER_PGW; blk++) */
   5683 
   5684         if ((oversub_mode == 1) && (pgw_linerate_bandwidth[pgw] != 0)) {
   5685             LOG_ERROR(BSL_LS_SOC_COMMON,
   5686                       (BSL_META_U(unit, "Oversub mode: Linerate BW for PGW %d is not 0.\n"), pgw));
   5687             rv = SOC_E_FAIL;
   5688         } else if ((oversub_mode == 0) && (pgw_oversub_bandwidth[pgw] != 0)) {
   5689             LOG_ERROR(BSL_LS_SOC_COMMON,
   5690                       (BSL_META_U(unit, "Linerate mode: Oversub BW for PGW %d is not 0.\n"), pgw));
   5691             rv = SOC_E_FAIL;
   5692         } else if (oversub_mode == 2) {
   5693             /*
   5694              * OS ratio = (IO BW - LR BW) / (MAX LR BW - IO LR BW)
   5695              */
   5696             os_ratio[pgw] = (((pgw_oversub_bandwidth[pgw]) * 1000) / (max_pgw_core_bandwidth[pgw] - pgw_linerate_bandwidth[pgw]));
   5697         }
   5698 
   5699         if (oversub_mode != 2) {
   5700             /* Linerate Bandwidth check */
   5701             if (pgw_linerate_bandwidth[pgw] > max_pgw_core_bandwidth[pgw]) {
   5702                 LOG_CLI((BSL_META_U(unit,
   5703                                     "PGW_CL%d total line rate bandwidth "
   5704                                     "(%d Gb) exceeds %d Gb\n"),
   5705                         pgw, (pgw_linerate_bandwidth[pgw] / 1000),
   5706                         (max_pgw_core_bandwidth[pgw] / 1000)));
   5707                 rv = SOC_E_FAIL;
   5708             }
   5709 
   5710             /* Oversub Bandwidth check */
   5711             if ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) {
   5712                 LOG_CLI((BSL_META_U(unit,
   5713                                     "PGW_CL%d total oversub bandwidth "
   5714                                     "(%d Gb) exceeds %d Gb\n"),
   5715                         pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000),
   5716                         (max_pgw_oversub_bandwidth[pgw] / 1000)));
   5717                 rv = SOC_E_FAIL;
   5718             }
   5719         }
   5720        /* Oversub Bandwidth check */
   5721         if ((pgw_linerate_bandwidth[pgw]+ pgw_oversub_bandwidth[pgw]) > max_pgw_oversub_bandwidth[pgw]) {
   5722             LOG_CLI((BSL_META_U(unit,
   5723                                 "PGW_CL%d total oversub bandwidth "
   5724                                 "(%d Gb) exceeds %d Gb\n"),
   5725                      pgw, ((pgw_linerate_bandwidth[pgw] + pgw_oversub_bandwidth[pgw]) / 1000),
   5726                      (max_pgw_oversub_bandwidth[pgw] / 1000)));
   5727             rv = SOC_E_FAIL;
   5728     }
   5729     } /* for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) */
   5730 
   5731     if (oversub_mode == 2) {
   5732         /* For mixed-mode we can have asymmetrical bandwidth distribution
   5733          * Check the OS ratio in this case
   5734          */
   5735         if ((os_ratio[MONTEREY_PGW0] > def_os_ratio) && (os_ratio[MONTEREY_PGW0] < max_os_ratio)) {
   5736             if (os_ratio[MONTEREY_PGW1] > def_os_ratio) {
   5737                 LOG_CLI((BSL_META_U(unit,
   5738                                     "PGW_CL1 total oversub bandwidth "
   5739                                     "(%d Gb) exceeds limit\n"),
   5740                                     ((pgw_oversub_bandwidth[MONTEREY_PGW1]) / 1000)));
   5741                 rv = SOC_E_FAIL;
   5742             }
   5743         } else if ((os_ratio[MONTEREY_PGW1] > def_os_ratio) && (os_ratio[MONTEREY_PGW1] < max_os_ratio)) {
   5744             if (os_ratio[MONTEREY_PGW0] > def_os_ratio) {
   5745                 LOG_CLI((BSL_META_U(unit,
   5746                                     "PGW_CL0 total oversub bandwidth "
   5747                                     "(%d Gb) exceeds limit\n"),
   5748                                     ((pgw_oversub_bandwidth[MONTEREY_PGW0]) / 1000)));
   5749                 rv = SOC_E_FAIL;
   5750             }
   5751         }
   5752     }
   5753 
   5754     return rv;
   5755 }
   5756 
   5757 
   5758 int
   5759 soc_monterey_mmu_hsp_port_reserve(int unit, int port, int speed_max)
   5760 {
   5761     int def_freq, max_freq;
   5762     int min_hsp_ovs_speed;
   5763 
   5764     SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_freq, &def_freq));
   5765     def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq);
   5766 
   5767     switch (def_freq) {
   5768         case 841:
   5769         case 793:
   5770             min_hsp_ovs_speed = 100000;
   5771             break;
   5772         default:
   5773             min_hsp_ovs_speed = 40000;
   5774             break;
   5775 
   5776     }
   5777 
   5778     if (IS_OVERSUB_PORT(unit, port) && speed_max >= min_hsp_ovs_speed) {
   5779         return TRUE;
   5780     }
   5781 
   5782     return FALSE;
   5783 }
   5784 
   5785 
   5786 STATIC int
   5787 soc_monterey_mmu_ports_assign(int unit)
   5788 {
   5789     int port, phy_port, mmu_port;
   5790     int port_is_hsp;
   5791     int num_phy_port = 67;
   5792     soc_info_t *si;
   5793     /*soc_pbmp_t pbmp;*/
   5794     int num_phy_ports = MONTEREY_PORTS_PER_PIPE;
   5795 
   5796     si = &SOC_INFO(unit);
   5797 
   5798     /* Setup vector-based scheduler (VBS)
   5799      * a.k.a high speed port scheduler (HSP) pbm */
   5800     for (phy_port = 1; phy_port <= num_phy_ports; phy_port++) {
   5801         port = si->port_p2l_mapping[phy_port];
   5802         if (port == -1) {
   5803             continue;
   5804         }
   5805 
   5806         /* Usage:
   5807          *  port_sched_hsp_<log_port> = 1 ;            Port is in HSP
   5808          *  port_sched_hsp_<log_port> = 0 ;            Port is in LLS
   5809          *  port_sched_hsp_<log_port> = -1 (default) ; SDK determines sched type
   5810  */
   5811         port_is_hsp = 1;
   5812 
   5813         if (port_is_hsp) {
   5814             SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   5815         } else {
   5816             SOC_PBMP_PORT_REMOVE(si->eq_pbm, port);
   5817         }
   5818 	
   5819     }
   5820 
   5821     mmu_port = 0;
   5822 
   5823 #if 0 
   5824     /* First assign the lowest MMU port number for VBS (HSP) ports */
   5825     pbmp = si->xpipe_pbm;
   5826     SOC_PBMP_AND(pbmp, si->eq_pbm);
   5827     SOC_PBMP_ITER(pbmp, port) {
   5828         if ( port <= _MONTEREY_LOG_PORTS_PER_PIPE ) {
   5829            phy_port = si->port_l2p_mapping[port];
   5830            if ( phy_port <= num_phy_port) { 
   5831                si->port_p2m_mapping[phy_port] = mmu_port;
   5832                si->port_m2p_mapping[mmu_port] = phy_port;
   5833                mmu_port++;
   5834             }
   5835         }   
   5836     }
   5837 #endif
   5838 
   5839     /* Assign MMU port for all OS ports with speed >= 100G */
   5840     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5841         if (si->port_p2m_mapping[phy_port] != -1) {
   5842             continue;
   5843         }
   5844 
   5845         port = si->port_p2l_mapping[phy_port];
   5846         if (port == -1) {
   5847             continue;
   5848         }
   5849 
   5850         if ((IS_OVERSUB_PORT(unit, port)) &&
   5851             (si->port_speed_max[port] >= 100000)) {
   5852             si->port_p2m_mapping[phy_port] = mmu_port;
   5853             si->port_m2p_mapping[mmu_port] = phy_port;
   5854             mmu_port++;
   5855         }
   5856     }
   5857 
   5858     /* Assign MMU port for all OS ports with speed >= 40G */
   5859     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5860         if (si->port_p2m_mapping[phy_port] != -1) {
   5861             continue;
   5862         }
   5863 
   5864         port = si->port_p2l_mapping[phy_port];
   5865         if (port == -1) {
   5866             continue;
   5867         }
   5868 
   5869         if ((IS_OVERSUB_PORT(unit, port)) &&
   5870             (si->port_speed_max[port] >= 40000)) {
   5871             si->port_p2m_mapping[phy_port] = mmu_port;
   5872             si->port_m2p_mapping[mmu_port] = phy_port;
   5873             mmu_port++;
   5874         }
   5875     }
   5876 
   5877     /* Assign MMU port for all ports with speed >= 100G */
   5878     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5879         if (si->port_p2m_mapping[phy_port] != -1) {
   5880             continue;
   5881         }
   5882 
   5883         port = si->port_p2l_mapping[phy_port];
   5884         if (port == -1) {
   5885             continue;
   5886         }
   5887 
   5888         if (si->port_speed_max[port] >= 100000) {
   5889             si->port_p2m_mapping[phy_port] = mmu_port;
   5890             si->port_m2p_mapping[mmu_port] = phy_port;
   5891             mmu_port++;
   5892         }
   5893     }
   5894 
   5895     /* Assign MMU port for all ports with speed >= 40G */
   5896     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5897         if (si->port_p2m_mapping[phy_port] != -1) {
   5898             continue;
   5899         }
   5900 
   5901         port = si->port_p2l_mapping[phy_port];
   5902         if (port == -1) {
   5903             continue;
   5904         }
   5905 
   5906         if (si->port_speed_max[port] >= 40000) {
   5907             si->port_p2m_mapping[phy_port] = mmu_port;
   5908             si->port_m2p_mapping[mmu_port] = phy_port;
   5909             mmu_port++;
   5910         }
   5911     }
   5912     /* Assign MMU port for 1st phy port in PM4x25|PM4x10 */
   5913     for (phy_port = 1; phy_port <= num_phy_port; phy_port += MONTEREY_PORTS_PER_TSC) {
   5914         if (si->port_p2m_mapping[phy_port] != -1) {
   5915             continue;
   5916         }
   5917 
   5918         if (si->port_p2l_mapping[phy_port] == -1) {
   5919             continue;
   5920         }
   5921 
   5922         si->port_p2m_mapping[phy_port] = mmu_port;
   5923         si->port_m2p_mapping[mmu_port] = phy_port;
   5924         mmu_port++;
   5925     }
   5926 
   5927     /* Assign MMU port for all remaining ports with speeds >= 25G */
   5928     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5929         if (si->port_p2m_mapping[phy_port] != -1) {
   5930             continue;
   5931         }
   5932 
   5933         port = si->port_p2l_mapping[phy_port];
   5934         if (port == -1) {
   5935             continue;
   5936         }
   5937 
   5938         if (si->port_speed_max[port] >= 25000) {
   5939             si->port_p2m_mapping[phy_port] = mmu_port;
   5940             si->port_m2p_mapping[mmu_port] = phy_port;
   5941             mmu_port++;
   5942         }
   5943     }
   5944 
   5945     /* Assign MMU port for all remaining ports with speeds >= 10G */
   5946     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   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 (si->port_speed_max[port] >= 10000) {
   5957             si->port_p2m_mapping[phy_port] = mmu_port;
   5958             si->port_m2p_mapping[mmu_port] = phy_port;
   5959             mmu_port++;
   5960         }
   5961     }
   5962     /* Assign MMU port for all remaining ports */
   5963     for (phy_port = 1; phy_port <= num_phy_port; phy_port++) {
   5964         if (si->port_p2m_mapping[phy_port] != -1) {
   5965             continue;
   5966         }
   5967 
   5968         si->port_p2m_mapping[phy_port] = mmu_port;
   5969         si->port_m2p_mapping[mmu_port] = phy_port;
   5970         mmu_port++;
   5971     }
   5972  
   5973 
   5974     return SOC_E_NONE;
   5975 }
   5976 STATIC int
   5977 _soc_mn_ports_speed_init_update(int unit)
   5978 {
   5979     int port;
   5980     soc_info_t *si = &SOC_INFO(unit);
   5981 
   5982     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   5983         /* Set init speed to max speed by default */
   5984         /* Used during port probe and portmod attach */
   5985         si->port_init_speed[port] = si->port_speed_max[port];
   5986     }
   5987 
   5988     return SOC_E_NONE;
   5989 }
   5990 
   5991 /*
   5992  * Monterey port mapping
   5993  *     64 physical ports: port 0-64 in X pipe 
   5994  *     106 logical ports
   5995  *     108 mmu ports: port 0-53 in X pipe, port 64-117 in Y pipe
   5996  *     cpu port number is fixed: physical 0, logical 0, mmu 65 
   5997  *     loopback port number is fixed: physical 65, logical 65, mmu 66 
   5998  *     management port can be:
   5999  *     - one 10G port
   6000  *     - one to four ports with speed up to 2.5G each
   6001  * Physical port number in eacc port group
   6002  * This routine will setup:
   6003  *     SOC_INFO(unit).port_p2l_mapping[]
   6004  *     SOC_INFO(unit).port_l2p_mapping[]
   6005  *     SOC_INFO(unit).port_p2m_mapping[]
   6006  *     SOC_INFO(unit).port_m2p_mapping[]
   6007  *     SOC_INFO(unit).port_speed_max[]
   6008  *     SOC_INFO(unit).port_group[]
   6009  *     SOC_INFO(unit).port_serdes[]
   6010  *     SOC_INFO(unit).port_num_lanes[]
   6011  *     SOC_INFO(unit).phy_port_base[]
   6012  *     SOC_INFO(unit).mmu_port_base[]
   6013  * 100+G port:
   6014  *     - can only be @ 760MHz
   6015  *     - needs to be HSP
   6016  *     - cannot be in oversubscribe mode
   6017  * 40/42G port:
   6018  *     - needs to be HSP except @ 760MHz
   6019  *     - oversubscribe mode can support both cut-through and store-and-forward
   6020  * sub-40G port:
   6021  *     - oversubscribe mode can only support store-and-forward
   6022  */
   6023 int
   6024 soc_monterey_port_config_init(int unit, uint16 dev_id, uint8 rev_id)
   6025 {
   6026     char *config_str, *sub_str, *sub_str_end;
   6027     static const char str_2p5[] = "2.5";
   6028     char str_buf[8];
   6029     soc_info_t *si;
   6030     int  rv;
   6031     int num_port, num_phy_port;
   6032     int port, phy_port;
   6033     int port_bandwidth, port_active_lanes;
   6034     int def_freq, max_freq;
   6035     soc_100g_lane_config_t lane_config = SOC_LANE_CONFIG_100G_DEFAULT;
   6036     int fallback_core = SOC_LANE_CONFIG_100G_DEFAULT;
   6037     int index, tsc_id;
   6038     char option_inactive, option_lanes;
   6039     int port_count;
   6040     int oversub_mode = 0;
   6041     soc_pbmp_t oversub_pbm;
   6042     soc_pbmp_t xe_pbmp;
   6043     soc_pbmp_t cpri_pbmp;
   6044     uint32 tsc_map, force_hg;
   6045     int freq_list_len;
   6046     int const *freq_list;
   6047     int tdm_freq = 0 ; 
   6048     static const int monterey_freq_list[] = { 862, 817, 667, 550, 450}; 
   6049     int int_ports[3][3] = {
   6050 
   6051                          /* {log, phy, mmu} */
   6052                             {0,   0,   65}, /* CPU */
   6053                             {65,  65,  66}, /* LB */
   6054                             {66,  66,  64}, /* MACSEC */
   6055         };
   6056 
   6057     SOC_PBMP_CLEAR(xe_pbmp);
   6058     SOC_PBMP_CLEAR(oversub_pbm);
   6059     SOC_PBMP_CLEAR(cpri_pbmp);
   6060     xe_pbmp = soc_property_get_pbmp_default(unit,
   6061                                             spn_PBMP_XPORT_XE, xe_pbmp);
   6062     cpri_pbmp = soc_property_get_pbmp_default(unit,
   6063                                             spn_PBMP_XPORT_CPRI, cpri_pbmp);
   6064     si = &SOC_INFO(unit);
   6065 
   6066     {
   6067         num_port = 64;
   6068         num_phy_port = 64;
   6069     }
   6070 
   6071     SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_freq, &def_freq));
   6072     def_freq = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, def_freq);
   6073     tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY, 0);
   6074     if (def_freq <= max_freq) {
   6075         freq_list = monterey_freq_list;
   6076         freq_list_len = sizeof(monterey_freq_list) / sizeof(int);
   6077         for (index = 0; index < freq_list_len; index++) {
   6078             if (def_freq == freq_list[index]) {
   6079                 break;
   6080             }
   6081         }
   6082 
   6083         if (index < freq_list_len) {
   6084             si->frequency = def_freq;
   6085         } else {
   6086             LOG_CLI((BSL_META_U(unit,
   6087                        "*** Input core clock frequency %dMHz is not "
   6088                        "supported!\n"), def_freq));
   6089         }
   6090     }
   6091     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   6092                     (BSL_META_U(unit, "Running core clock frequency %dMhz\n"), def_freq));
   6093 
   6094     /* Setup max I/O and core bandwidth */
   6095     switch (si->frequency) {
   6096     case 862:
   6097         if (tdm_freq == 862) {  
   6098             si->io_bandwidth = 1000000;
   6099         } else if (tdm_freq == 861) {  
   6100             si->io_bandwidth = 800000;
   6101         } else {
   6102           if (soc_feature(unit, soc_feature_xflow_macsec)) { 
   6103               si->io_bandwidth = 920000; 
   6104           } else  { 
   6105               si->io_bandwidth = 1000000; 
   6106           }
   6107         }
   6108         si->bandwidth = 548000;
   6109         break;
   6110     case 817:
   6111         if (tdm_freq == 815) {  
   6112             si->io_bandwidth = 760000;
   6113         } else if (tdm_freq == 816) {  
   6114             si->io_bandwidth = 700000;
   6115         } else if (tdm_freq == 666) {  
   6116             si->io_bandwidth = 800000;
   6117         } else if (tdm_freq == 667) {  
   6118             si->io_bandwidth = 800000;
   6119         } else {
   6120             si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 800000);
   6121             if (!(si->io_bandwidth == 800000 || si->io_bandwidth == 720000 || 
   6122                 si->io_bandwidth == 460000)) {
   6123                 LOG_CLI((BSL_META_U(unit,
   6124                        "*** Input  IO Bandwidth %d is not yet "
   6125                        "supported using default value %d !\n"), si->io_bandwidth,800000));
   6126                 si->io_bandwidth = 800000; 
   6127             }
   6128 
   6129         }
   6130         if (dev_id == BCM56675_DEVICE_ID) {
   6131             if (soc_feature(unit, soc_feature_xflow_macsec)) { 
   6132                 si->io_bandwidth = 860000; 
   6133             } else { 
   6134                 si->io_bandwidth = 920000; 
   6135             }
   6136             si->bandwidth = 515000;
   6137         } else {  
   6138             si->bandwidth = 490000;
   6139         }
   6140         break;
   6141     case 667: 
   6142         if (tdm_freq == 666) {  
   6143             si->io_bandwidth = 800000;
   6144         } else if (tdm_freq == 667) {  
   6145             si->io_bandwidth = 800000;
   6146         } else {
   6147             si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 780000);
   6148             if (!(si->io_bandwidth == 720000 || si->io_bandwidth == 580000 || 
   6149                 si->io_bandwidth == 360000 || si->io_bandwidth == 780000 ||
   6150                 si->io_bandwidth == 400000)) {
   6151                 LOG_CLI((BSL_META_U(unit,
   6152                        "*** Input  IO Bandwidth %d is not yet "
   6153                        "supported using default value %d !\n"), si->io_bandwidth,720000));
   6154                 si->io_bandwidth = 720000; 
   6155            }   
   6156         }
   6157         if (dev_id == BCM56675_DEVICE_ID) {
   6158             if (soc_feature(unit, soc_feature_xflow_macsec)) { 
   6159                 si->io_bandwidth = 680000; 
   6160             } else { 
   6161                 si->io_bandwidth = 720000; 
   6162             }
   6163             si->bandwidth = 420000;
   6164         } else { 
   6165             si->bandwidth = 490000;
   6166 
   6167         }
   6168         break;
   6169     case 550:
   6170         si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 400000);
   6171         if (!(si->io_bandwidth == 460000 || si->io_bandwidth == 580000 || 
   6172               si->io_bandwidth == 280000 || si->io_bandwidth == 400000)) {
   6173               LOG_CLI((BSL_META_U(unit,
   6174                        "*** Input  IO Bandwidth %d is not yet "
   6175                      "supported using default value %d !\n"), si->io_bandwidth,580000));
   6176               si->io_bandwidth = 580000; 
   6177         }   
   6178         if (dev_id == BCM56675_DEVICE_ID) {
   6179             si->io_bandwidth = 540000; 
   6180             si->bandwidth = 340000;
   6181         } else { 
   6182             si->bandwidth = 342000;
   6183         }
   6184     
   6185         
   6186         break;
   6187     case 450:
   6188         si->io_bandwidth = soc_property_get(unit, spn_BCM_TDM_IO_BANDWIDTH, 200000);
   6189         si->bandwidth = 275000;
   6190         if (!(si->io_bandwidth == 460000 || si->io_bandwidth == 360000 || 
   6191               si->io_bandwidth == 200000 || si->io_bandwidth == 400000) ) {
   6192               LOG_CLI((BSL_META_U(unit,
   6193                        "*** Input  IO Bandwidth %d is not yet "
   6194                      "supported using default value %d !\n"), si->io_bandwidth,460000));
   6195               si->io_bandwidth = 460000; 
   6196         }   
   6197         if (dev_id == BCM56675_DEVICE_ID) {
   6198             if (soc_feature(unit, soc_feature_xflow_macsec)) { 
   6199                 si->io_bandwidth = 420000; 
   6200             } else { 
   6201                 si->io_bandwidth = 480000; 
   6202             }
   6203         }
   6204     
   6205         break;
   6206     default:
   6207         LOG_CLI((BSL_META_U(unit,
   6208                        "*** Input core clock frequency %dMHz is not yet "
   6209                        "supported!\n"), si->frequency));
   6210         return SOC_E_INTERNAL; /* unknown frequency */
   6211     }
   6212 
   6213 
   6214     oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 0);
   6215     if (oversub_mode == 2) {
   6216         oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0);
   6217     }
   6218 
   6219     SOC_IF_ERROR_RETURN(soc_monterey_tsc_map_get(unit, &tsc_map, &force_hg));
   6220 
   6221     /* Initialize the soc_info params */
   6222     for (port = 0; port < SOC_MAX_NUM_PORTS; port++) {
   6223         si->port_l2p_mapping[port] = -1;
   6224         si->port_speed_max[port] = -1;
   6225         si->port_group[port] = -1;
   6226         si->port_serdes[port] = -1;
   6227         si->port_num_lanes[port] = -1;
   6228 
   6229         /* Indexed by physical port */
   6230         si->port_p2l_mapping[port] = -1;
   6231         si->port_p2m_mapping[port] = -1;
   6232 
   6233         /* Indexed by mmu port */
   6234         si->port_m2p_mapping[port] = -1;
   6235     }
   6236 
   6237 
   6238 
   6239     for (index = 0; index < COUNTOF(int_ports); index++) {
   6240         /* int_ports is an array of log, phy & mmu ports in that order */
   6241         si->port_p2l_mapping[int_ports[index][1]] = int_ports[index][0];
   6242         si->port_p2m_mapping[int_ports[index][1]] = int_ports[index][2];
   6243 
   6244         SOC_PBMP_PORT_SET(si->xpipe_pbm, int_ports[index][0]);
   6245     }
   6246 
   6247 
   6248     SOC_PBMP_CLEAR(si->oversub_pbm);
   6249     SOC_PBMP_CLEAR(si->management_pbm);
   6250     SOC_PBMP_CLEAR(si->all.disabled_bitmap);
   6251 
   6252     si->phy_port_base[0] = 1;               /* First physical port */
   6253     si->mmu_port_base[0] = 0;               /* First mmu port */
   6254     port_count = 0;
   6255 
   6256     rv = SOC_E_NONE;
   6257     for (port = 0; port <= num_port; port++) {
   6258 
   6259         config_str = soc_property_port_get_str(unit, port, spn_PORTMAP);
   6260         if (config_str == NULL) {
   6261             continue;
   6262         }
   6263 
   6264 	/*
   6265 	 * portmap.<port>=<physical port number>:<bandwidth in Gb>:[<num_lanes>]:[i]
   6266 	 */
   6267         sub_str = config_str;
   6268 
   6269         /* Parse physical port number */
   6270         phy_port = sal_ctoi(sub_str, &sub_str_end);
   6271         if (sub_str == sub_str_end) {
   6272             LOG_CLI((BSL_META_U(unit,
   6273                        "Port %d: Missing physical port information \"%s\"\n"),
   6274                        port, config_str));
   6275             rv = SOC_E_FAIL;
   6276             continue;
   6277         }
   6278 
   6279         /* phy_port valid range [1..72] */
   6280         if (phy_port < 1 || phy_port > num_phy_port) {
   6281             LOG_CLI((BSL_META_U(unit,
   6282                        "Port %d: Invalid physical port number %d\n"),
   6283                        port, phy_port));
   6284             rv = SOC_E_FAIL;
   6285             continue;
   6286         }
   6287 
   6288         tsc_id = (phy_port - 1) / MONTEREY_PORTS_PER_TSC;
   6289         if (!(tsc_map & (1 << tsc_id))) {
   6290             LOG_CLI((BSL_META_U(unit,
   6291                        "Port %d: Physical port %d is in disabled TSC %d\n"),
   6292                        port, phy_port, tsc_id));
   6293             rv = SOC_E_FAIL;
   6294             continue;
   6295         }
   6296 
   6297         if ((force_hg & (1 << tsc_id)) &&
   6298             (SOC_PBMP_MEMBER(xe_pbmp, port))) {
   6299             LOG_CLI((BSL_META_U(unit,
   6300                        "Port %d: non-hg port in TSC(%d) which is hg-only\n"),
   6301                        port, tsc_id));
   6302             rv = SOC_E_FAIL;
   6303             continue;
   6304         }
   6305 
   6306         if (si->port_p2l_mapping[phy_port] != -1) {
   6307             LOG_CLI((BSL_META_U(unit,
   6308                        "Port %d: Physical port %d is used by port %d\n"),
   6309                        port, phy_port, si->port_p2l_mapping[phy_port]));
   6310             rv = SOC_E_FAIL;
   6311             continue;
   6312         }
   6313 
   6314         if (port_count > num_port) {
   6315             LOG_CLI((BSL_META_U(unit,
   6316                        "Can not configure more than %d port\n"), num_port));
   6317             rv = SOC_E_FAIL;
   6318             continue;
   6319         }
   6320 
   6321         /* Skip ':' between physical port number and bandwidth */
   6322         sub_str = sub_str_end;
   6323         if (*sub_str != '\0') {
   6324             if (*sub_str != ':') {
   6325                 LOG_CLI((BSL_META_U(unit,
   6326                                     "Port %d: Bad config string \"%s\"\n"),
   6327                          port, config_str));
   6328                 rv = SOC_E_FAIL;
   6329                 continue;
   6330             }
   6331             sub_str++;
   6332         }
   6333 
   6334         /* Parse bandwidth - special case 2.5G */
   6335         for (index = 0; index < sizeof(str_2p5) - 1; index++) {
   6336             if (sub_str[index] == '\0') {
   6337                 break;
   6338             }
   6339             str_buf[index] = sub_str[index];
   6340         }
   6341         str_buf[index] = '\0';
   6342 
   6343         if (!sal_strcmp(str_buf, str_2p5)) {
   6344             port_bandwidth = 2500;
   6345             sub_str_end = &sub_str[sizeof(str_2p5) - 1];
   6346         } else {
   6347             port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000;
   6348             if (sub_str == sub_str_end) {
   6349                 LOG_CLI((BSL_META_U(unit,
   6350                                     "Port %d: Missing bandwidth "
   6351                                     "information \"%s\"\n"),
   6352                          port, config_str));
   6353                 rv = SOC_E_FAIL;
   6354                 continue;
   6355             }
   6356         }
   6357 
   6358         /* Check if option presents */
   6359         option_inactive = option_lanes = 0;
   6360         sub_str = sub_str_end;
   6361         if (*sub_str != '\0') {
   6362             /* Skip ':' between bandwidth and options */
   6363             if (*sub_str != ':') {
   6364                 LOG_CLI((BSL_META_U(unit,
   6365                                     "Port %d: Bad config string \"%s\"\n"),
   6366                            port, config_str));
   6367                 rv = SOC_E_FAIL;
   6368                 continue;
   6369             }
   6370             sub_str++;
   6371 
   6372             /* Read 100G lane configuration if present.
   6373              * Skip if options are present */
   6374             if (*sub_str != '\0') {
   6375                 if (*sub_str == 'i') {
   6376                     option_inactive = *sub_str;
   6377                     sub_str++;
   6378                 } else if ((*sub_str == '1') ||
   6379                            (*sub_str == '2') ||
   6380                            (*sub_str == '4')) {
   6381                     option_lanes = *sub_str;
   6382                     sub_str++;
   6383 
   6384                     if (*sub_str != '\0') {
   6385                         if (*sub_str != 'i') {
   6386                             LOG_CLI((BSL_META_U(unit,
   6387                                        "Port %d: Bad config string \"%s\"\n"),
   6388                                        port, config_str));
   6389                             rv = SOC_E_FAIL;
   6390                             continue;
   6391                         }
   6392                         option_inactive = *sub_str;
   6393                         sub_str++;
   6394                     }
   6395                 } else {
   6396                     LOG_CLI((BSL_META_U(unit,
   6397                                "Port %d: Bad config string \"%s\"\n"),
   6398                                port, config_str));
   6399                     rv = SOC_E_FAIL;
   6400                     continue;
   6401                 }
   6402             }
   6403         }
   6404 
   6405         /* Check trailing string */
   6406         if (*sub_str != '\0') {
   6407             LOG_CLI((BSL_META_U(unit,
   6408                        "Port %d: Bad config string \"%s\"\n"),
   6409                        port, config_str));
   6410             rv = SOC_E_FAIL;
   6411             continue;
   6412         }
   6413 
   6414         /*
   6415          * Use new properties for 100GE mode lane and
   6416          * fallback autoneg core if these are specified.
   6417          */
   6418         switch (option_lanes) {
   6419             case '1': port_active_lanes = 1; break;
   6420             case '2': port_active_lanes = 2; break;
   6421             case '4': port_active_lanes = 4; break;
   6422             default :
   6423                 if (SOC_FAILURE(_soc_monterey_port_lanes_set(unit, phy_port,
   6424                                                            &port_active_lanes,
   6425                                                            port_bandwidth))) {
   6426                     rv = SOC_E_FAIL;
   6427                 }
   6428                 break;
   6429         }
   6430         if (option_inactive == 'i') {
   6431             SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port);
   6432             port_active_lanes = -1;
   6433         }
   6434 
   6435         /* PORT bandwidth checks  */
   6436         if ((soc_monterey_port_is_2p5g_forced(unit, phy_port)) &&
   6437             (port_bandwidth > 2500)) {
   6438             rv = SOC_E_FAIL;
   6439             LOG_CLI((BSL_META_U(unit,
   6440                                 "Port %d: Invalid bandwidth %d Gb\n"
   6441                                 "Max bandwidth supported is 2.5G\n"),
   6442                      port, port_bandwidth / 1000));
   6443 
   6444             continue;
   6445         }
   6446         if (!_soc_monterey_port_speed_supported(unit, port, phy_port,
   6447                                               port_active_lanes, port_bandwidth)) {
   6448             rv = SOC_E_FAIL;
   6449             continue;
   6450         }
   6451 
   6452 
   6453         /* Update soc_info */
   6454         si->port_p2l_mapping[phy_port] = port;
   6455         si->port_l2p_mapping[port] = phy_port;
   6456         si->port_speed_max[port] = port_bandwidth;
   6457         si->port_100g_lane_config[port] = lane_config;
   6458         si->port_fallback_lane[port]    = fallback_core;
   6459         si->port_num_lanes[port] = port_active_lanes;
   6460 
   6461         if (SOC_PBMP_MEMBER(oversub_pbm,port) || (oversub_mode == 1)) {
   6462             SOC_PBMP_PORT_ADD(si->oversub_pbm, port);
   6463         }
   6464 
   6465         port_count++;
   6466     }
   6467     /* Legacy Flex config ":i" case detected, disabled ports in config */
   6468     if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all))) {
   6469         si->flex_eligible = TRUE;
   6470     }
   6471 
   6472 #ifdef BCM_WARM_BOOT_SUPPORT
   6473     if (SOC_WARM_BOOT(unit)) {
   6474         rv = soc_monterey_flexport_scache_recovery(unit);
   6475         if (SOC_FAILURE(rv)) {
   6476             if (rv == SOC_E_NOT_FOUND) {
   6477                 rv = SOC_E_NONE;
   6478             } else {
   6479                 return rv;
   6480             }
   6481         }
   6482     } else {
   6483         /* Cold boot create */
   6484         SOC_IF_ERROR_RETURN(soc_monterey_flexport_scache_allocate(unit));
   6485     }
   6486 #endif /* BCM_WARM_BOOT_SUPPORT */
   6487 
   6488     if (port_count == 0) {
   6489 #ifdef __KERNEL__
   6490         /* config.bcm is not parsed yet at the time 1st call of soc_attach
   6491            in Kernel mode SDK. Shouldn't return error code. */
   6492         return SOC_E_NONE;
   6493 #else
   6494 #if 0
   6495         if (SOC_CONTROL(unit)->soc_flags & SOC_F_ATTACHED) { /* not for PCID */
   6496             rv = SOC_E_FAIL;
   6497         }
   6498 #endif
   6499 #endif
   6500     }
   6501     /* Bandwidth check for ports in each XLPORT/CLPORT block */
   6502 
   6503     if (SOC_SUCCESS(rv)) {
   6504         rv = soc_monterey_port_config_bandwidth_check(unit);
   6505     }
   6506     if (SOC_FAILURE(rv)) {
   6507         for (phy_port = 1; phy_port < 66; phy_port++) {
   6508             si->port_p2l_mapping[phy_port] = -1;
   6509         }
   6510         return rv;
   6511     }
   6512 
   6513     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   6514         LOG_CLI((BSL_META_U(unit, "physical to logical mapping:")));
   6515         for (index = 0; index < num_phy_port; index++) {
   6516             if (index % 16 == 0) {
   6517                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6518             }
   6519             LOG_CLI((BSL_META_U(unit, " %3d"),
   6520                        si->port_p2l_mapping[index]));
   6521         }
   6522         LOG_CLI((BSL_META_U(unit, "\n")));
   6523         LOG_CLI((BSL_META_U(unit, "physical port bandwidth:")));
   6524         for (index = 0; index < num_phy_port; index++) {
   6525             if (index % 16 == 0) {
   6526                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6527             }
   6528             port = si->port_p2l_mapping[index];
   6529             if (port == -1) {
   6530                 LOG_CLI((BSL_META_U(unit, "  -1")));
   6531             } else if (si->port_speed_max[port] == 2500) {
   6532                 LOG_CLI((BSL_META_U(unit, " 2.5")));
   6533             } else {
   6534                 LOG_CLI((BSL_META_U(unit, " %3d"),
   6535                            si->port_speed_max[port] / 1000));
   6536             }
   6537         }
   6538         LOG_CLI((BSL_META_U(unit, "\n")));
   6539     }
   6540 
   6541     /* Setup port_group, num_lanes, xpipe_pbm  */
   6542     for (port = 0; port <= num_port; port++) {
   6543         phy_port = si->port_l2p_mapping[port];
   6544         if (phy_port == -1) { /* unused port */
   6545             continue;
   6546         }
   6547         /* 26 ports per PGW_CL */
   6548         si->port_group[port] = (phy_port - 1) / MONTEREY_PORTS_PER_PGW;
   6549         si->port_serdes[port] = (phy_port - 1) / MONTEREY_PORTS_PER_TSC;
   6550 
   6551         SOC_PBMP_PORT_ADD(si->xpipe_pbm, port);
   6552 
   6553     }
   6554      SOC_PBMP_ASSIGN(si->pipe_pbm[0], si->xpipe_pbm);
   6555     /* Assign mmu ports for all active and inactive ports */
   6556     SOC_IF_ERROR_RETURN(soc_monterey_mmu_ports_assign(unit));
   6557 
   6558     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   6559         LOG_CLI((BSL_META_U(unit, "physical to mmu mapping:")));
   6560         for (index = 0; index < num_phy_port; index++) {
   6561             if (index % 16 == 0) {
   6562                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   6563             }
   6564             LOG_CLI((BSL_META_U(unit, " %3d"),
   6565                        si->port_p2m_mapping[index]));
   6566         }
   6567         LOG_CLI((BSL_META_U(unit, "\n")));
   6568     }
   6569 
   6570     SOC_IF_ERROR_RETURN(soc_mn_phy_info_init(unit));
   6571      /*  update port_init_speed array for all ports */
   6572     SOC_IF_ERROR_RETURN(_soc_mn_ports_speed_init_update(unit));
   6573     SOC_IF_ERROR_RETURN(soc_mn_port_ovs_speed_group_validate(unit));
   6574     SOC_IF_ERROR_RETURN(soc_mn_port_mixed_sister_speed_validate(unit));
   6575     return SOC_E_NONE;
   6576 }
   6577 
   6578 soc_error_t
   6579 soc_monterey_port_reg_blk_index_get(int unit, int port, soc_block_type_t blktype, int *block)
   6580 {
   6581     uint16 dev_id;
   6582     uint8  rev_id;
   6583     int phy_port;
   6584 
   6585     soc_cm_get_id(unit, &dev_id, &rev_id);
   6586     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
   6587 
   6588     switch (blktype) {
   6589         case SOC_BLK_CLG2PORT:
   6590         case SOC_BLK_CLPORT:
   6591             if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit, port)) {
   6592                 if (phy_port == 17) {
   6593                     *block = (rev_id == BCM56560_A0_REV_ID ? 11 : 7);
   6594                 } else if (phy_port == 53) {
   6595                     *block = (rev_id == BCM56560_A0_REV_ID ? 14 : 8);
   6596                 } else {
   6597                     return SOC_E_PARAM;
   6598                 }
   6599             }
   6600             break;
   6601         case SOC_BLK_CXXPORT:
   6602             if ((phy_port >= 17) && (phy_port <= 28)) {
   6603                 *block = (rev_id == BCM56560_A0_REV_ID ? 18 : 10);
   6604             } else if ((phy_port >= 53) && (phy_port <= 64)) {
   6605                 *block = (rev_id == BCM56560_A0_REV_ID ? 19 : 11);
   6606             } else {
   6607                 return SOC_E_PARAM;
   6608             }
   6609             break;
   6610         default:
   6611             break;
   6612     }
   6613     return SOC_E_NONE;
   6614 }
   6615 
   6616 
   6617 #define _SOC_MN_DEF_TEMP_MAX   130
   6618 
   6619 static uint32 _soc_mn_temp_mon_mask[SOC_MAX_NUM_DEVICES];
   6620 
   6621 
   6622 /*
   6623  * Function: _soc_monterey_tsc_disable
   6624  *
   6625  * Purpose:
   6626  *     Function to dsiable unused TSCs in the chip.
   6627  */
   6628  int
   6629 soc_monterey_tsc_disable(int unit)
   6630 {
   6631     soc_info_t *si = &SOC_INFO(unit);
   6632     uint32 tsc_enable = 0;
   6633     int lane, phy_port, tsc, port;
   6634 
   6635     for (phy_port = 1;
   6636          phy_port <= MONTEREY_PORTS_PER_PIPE;
   6637          phy_port = (phy_port + MONTEREY_PORTS_PER_TSC)) {
   6638 
   6639         tsc = (phy_port - 1) / MONTEREY_PORTS_PER_TSC;
   6640         for (lane = 0; lane < MONTEREY_PORTS_PER_TSC; lane++) {
   6641             port = si->port_p2l_mapping[phy_port + lane];
   6642             if (port != -1) {
   6643                 tsc_enable |= (1 << tsc);
   6644                 if (IS_CXX_PORT(unit, port) && IS_CL_PORT(unit,port)) {
   6645                     tsc_enable |= (1 << (tsc + 1));
   6646                     tsc_enable |= (1 << (tsc + 2));
   6647                 }
   6648                 break;
   6649             }
   6650         }
   6651     }
   6652 
   6653     /* TSC2/3/6/9/12/13 are master PLL cores. Never disable them */
   6654     tsc_enable |= 0x324c;
   6655 
   6656     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, TOP_TSC_ENABLEr,
   6657                                       REG_PORT_ANY, 0, tsc_enable));
   6658 
   6659     return SOC_E_NONE;
   6660 }
   6661 
   6662 static int
   6663 _soc_monterey_tsc_refclk_set(int unit)
   6664 {
   6665     uint64    rval64;
   6666     soc_reg_t reg;
   6667     int phy_port, pm;
   6668     tsc_dpll_refclk_connect_t *refclk_connect;
   6669     int sleep_usec = SAL_BOOT_QUICKTURN ? 500000 : 1100;
   6670     soc_info_t *si = &SOC_INFO(unit);
   6671 
   6672     SHR_BITCLR_RANGE(si->pm_ref_master_bitmap, 0, SOC_MAX_NUM_BLKS);
   6673 
   6674     for(pm = 0; pm < PM_NUM; pm++) {
   6675         phy_port = pm * 4 + 1;
   6676         if (soc_monterey_port_is_falcon(unit, phy_port)) {
   6677             reg = CLPORT_XGXS0_CTRL_REGr;
   6678         } else {
   6679             reg = XLPORT_XGXS0_CTRL_REGr;
   6680         }
   6681         refclk_connect = &monterey_tsc_refclk_connect[pm];
   6682 
   6683         /* set refclock connect */
   6684         SOC_REG_RST_VAL_GET(unit, reg, rval64);
   6685 
   6686         soc_reg64_field32_set(unit, reg, &rval64, PLL0_REFIN_ENf, refclk_connect->pll0_refclk_select);
   6687         soc_reg64_field32_set(unit, reg, &rval64, PLL0_REFOUT_ENf, refclk_connect->pll0_master_enable);
   6688         soc_reg64_field32_set(unit, reg, &rval64, PLL0_LC_REFSELf, refclk_connect->pll0_lc_refclk_select);
   6689 
   6690         soc_reg64_field32_set(unit, reg, &rval64, PLL1_REFIN_ENf, refclk_connect->pll1_refclk_select);
   6691         soc_reg64_field32_set(unit, reg, &rval64, PLL1_REFOUT_ENf, refclk_connect->pll1_master_enable);
   6692         soc_reg64_field32_set(unit, reg, &rval64, PLL1_LC_REFSELf, !refclk_connect->pll1_lc_refclk_select);
   6693 
   6694         SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64));
   6695 
   6696          /* OOS master PLL core */
   6697          if(monterey_tsc_is_master_pll(pm)) {
   6698              /* De-assert IDDQ */
   6699              soc_reg64_field32_set(unit, reg, &rval64, IDDQf, 0);
   6700              SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64));
   6701 
   6702              /* De-assert power down */
   6703              soc_reg64_field32_set(unit, reg, &rval64, PWRDWNf, 0);
   6704              SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64));
   6705              sal_usleep(sleep_usec);
   6706 
   6707              /* Reset XGXS */
   6708              soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 0);
   6709              SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64));
   6710              sal_usleep(sleep_usec + 10000);
   6711 
   6712              /* Bring XGXS out of reset */
   6713              soc_reg64_field32_set(unit, reg, &rval64, RSTB_HWf, 1);
   6714              SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, phy_port, 0, rval64));
   6715 
   6716              /* Mark as master pll core */
   6717              SHR_BITSET(si->pm_ref_master_bitmap, SOC_PORT_BINDEX(unit, phy_port));
   6718          }
   6719 
   6720          /* set internal termination to 200 Ohm */
   6721          if (soc_monterey_port_is_falcon(unit, phy_port)) {
   6722              if (refclk_connect->pll0_master_enable) {
   6723                  SOC_REG_RST_VAL_GET(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, rval64);
   6724                  soc_reg64_field32_set(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, &rval64, PLL0_RTERM200f, 1);
   6725                  SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, CLPORT_PMD_PLL0_CTRL_CONFIGr, phy_port, 0, rval64));
   6726              }
   6727 
   6728              if (refclk_connect->pll1_master_enable) {
   6729                 SOC_REG_RST_VAL_GET(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, rval64);
   6730                 soc_reg64_field32_set(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, &rval64, PLL1_RTERM200f, 1);
   6731                 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, CLPORT_PMD_PLL1_CTRL_CONFIGr, phy_port, 0, rval64));
   6732              }
   6733          } else {
   6734             if (refclk_connect->pll0_master_enable || refclk_connect->pll1_master_enable) {
   6735                 SOC_REG_RST_VAL_GET(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, rval64);
   6736                 soc_reg64_field32_set(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, &rval64, REFCLK_TERM_SELf, 1);
   6737                 SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, XLPORT_PMD_PLL_CTRL_CONFIGr, phy_port, 0, rval64));
   6738             }
   6739          }
   6740     }
   6741 
   6742     return SOC_E_NONE;
   6743 }
   6744 
   6745 void
   6746 soc_monterey_sbus_ring_map_config(int unit)
   6747 {
   6748     uint16              dev_id;
   6749     uint8               rev_id;
   6750 
   6751     /*
   6752      *  SBUS Ring # Start   Through Blocks                                                      End
   6753      *      0       CMIC    IP                                                                  CMIC
   6754      *      1       CMIC    EP                                                                  CMIC
   6755      *      2       CMIC    MMU                                                                 CMIC
   6756      *      3       CMIC    TSC0 - TSC1 - TSC2 - TSC3 - PGW0 - TSC4_5_6 - TSC7 - TSC8           CMIC
   6757      *      4       CMIC    TSC9 - TSC10 - TSC11 - TSC12 - PGW1 - TSC13_14_15 - TSC16 - TSC17   CMIC
   6758      *      5       CMIC    TOP REGISTERS - OTPC - AVS - SER                                    CMIC
   6759      *      6       CMIC    RDB                                                                 CMIC
   6760      *      7       CMIC    Not used                                                            CMIC
   6761      */
   6762 
   6763     WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x43052100);
   6764     WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x33333333);
   6765     WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x44444333);
   6766     WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x50444444);
   6767     WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x00643055);
   6768     WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x00000000);
   6769     WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0x00000000);
   6770     WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x00000000);
   6771 
   6772 
   6773     soc_cm_get_id(unit, &dev_id, &rev_id);
   6774 
   6775     if (rev_id == BCM56560_A0_REV_ID) {
   6776         WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x1000);
   6777     } else {
   6778         WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x7d0);
   6779     }
   6780 
   6781     return;
   6782 }
   6783 
   6784 int
   6785 soc_monterey_chip_reset(int unit)
   6786 {
   6787     uint16 dev_id;
   6788     uint8 rev_id;
   6789     uint32 rval, to_usec;
   6790     soc_reg_t reg;
   6791     int index;
   6792     int num_ecmp_rh_flowset_entries;
   6793     int rh_table_config_encoding;
   6794 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   6795     int num_overlay_ecmp_rh_flowset_entries;
   6796     int rh_bank_sel = 0x0;
   6797     int ecmp_levels = 1;
   6798 #endif
   6799     soc_pbmp_t cpri_pbmp;
   6800     int temp_mask, temp_thr, power_reset = 0;
   6801     static const soc_reg_t temp_thr_reg[] = {
   6802         TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr,
   6803         TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr,
   6804         TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr,
   6805         TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr
   6806     };
   6807     static const char *temp_thr_prop[] = {
   6808         "temp0_threshold", "temp1_threshold", "temp2_threshold",
   6809         "temp3_threshold", "temp4_threshold", "temp5_threshold",
   6810         "temp6_threshold", "temp7_threshold"
   6811     };
   6812     static const soc_reg_t lcpll_reset_field[] = {
   6813        TOP_XG_PLL0_RST_Lf, TOP_XG_PLL1_RST_Lf,
   6814        TOP_XG_PLL2_RST_Lf, TOP_XG_PLL3_RST_Lf
   6815     };
   6816     static const soc_reg_t lcpll_post_reset_field[] = {
   6817        TOP_XG_PLL0_POST_RST_Lf, TOP_XG_PLL1_POST_RST_Lf,
   6818        TOP_XG_PLL2_POST_RST_Lf, TOP_XG_PLL3_POST_RST_Lf
   6819     };
   6820 
   6821 
   6822 #if 0 
   6823     static const soc_reg_t lcpll_ctrl1_reg[] = {
   6824         TOP_XG_PLL0_CTRL_1r, TOP_XG_PLL1_CTRL_1r,
   6825         TOP_XG_PLL2_CTRL_1r, TOP_XG_PLL3_CTRL_1r,
   6826     };
   6827     static const soc_reg_t lcpll_ctrl3_reg[] = {
   6828         TOP_XG_PLL0_CTRL_3r, TOP_XG_PLL1_CTRL_3r,
   6829         TOP_XG_PLL2_CTRL_3r, TOP_XG_PLL3_CTRL_3r
   6830     };
   6831     static const soc_reg_t lcpll_ctrl4_reg[] = {
   6832         TOP_XG_PLL0_CTRL_4r, TOP_XG_PLL1_CTRL_4r,
   6833         TOP_XG_PLL2_CTRL_4r, TOP_XG_PLL3_CTRL_4r
   6834     };
   6835 #endif
   6836     static const soc_reg_t lcpll_status_reg[] = {
   6837         TOP_XG_PLL0_STATUSr, TOP_XG_PLL1_STATUSr,
   6838         TOP_XG_PLL2_STATUSr, TOP_XG_PLL3_STATUSr
   6839     };
   6840 
   6841     /* Settings for 500 MHz TSPLL output clock. */
   6842     unsigned ts_ref_freq = 0;
   6843     unsigned ts_idx = 0;
   6844 
   6845     static const soc_pll_param_t ts_pll[] = {
   6846     /*     Fref, Ndiv_int, Ndiv_frac,  Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */
   6847       {12800000,      273,   0x70000,     1,    7,  0,  2,  3,        1}, /* Ndiv = 273.4375 */
   6848       {20000000,      175,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 175.0 */
   6849       {25000000,      140,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 140.0 */
   6850       {32000000,      109,   0x60000,     1,    7,  0,  2,  3,        1}, /* Ndiv = 109.375 */
   6851       {50000000,       70,         0,     1,    7,  0,  2,  3,        1}, /* Ndiv = 70.0 */
   6852       {       0,      140,         0,     1,    7,  0,  2,  3,        1} /* 25 MHz, from internal reference. */
   6853     };
   6854 
   6855     /* Settings for 20 MHz BSPLL output clock. */
   6856     unsigned bs_ref_freq = 0;
   6857     unsigned bs_idx = 0;
   6858     uint32 bs_ndiv_high, bs_ndiv_low;
   6859 
   6860     static const soc_pll_param_t bs_pll[] = {
   6861     /*     Fref, Ndiv_int,   Ndiv_frac,  Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */
   6862       {12800000,      273,  0x70000000,     1,  175,  0,  2,  3,        1},
   6863       {20000000,      175,           0,     1,  175,  0,  2,  3,        1},
   6864       {25000000,      140,           0,     1,  175,  0,  2,  3,        1},
   6865       {32000000,      109,  0x60000000,     1,  175,  0,  2,  3,        1},
   6866       {50000000,       70,           0,     1,  175,  0,  2,  3,        1},
   6867       {       0,       60,           0,     1,  150,  0,  2,  3,        1} /* 25 MHz, from internal reference. */
   6868     };
   6869     static const int monterey_freq_list[] = { 862, 817, 667, 550, 450};
   6870     int max_frequency, def_freq;
   6871     int freq_list_len = 0 , sel = 0;
   6872     int const *freq_list;
   6873     soc_info_t *si;
   6874     si = &SOC_INFO(unit);
   6875     to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) :
   6876                                    (10 * MILLISECOND_USEC);
   6877     soc_monterey_sbus_ring_map_config(unit);
   6878 
   6879     sal_usleep(to_usec);
   6880 
   6881     soc_cm_get_id(unit, &dev_id, &rev_id);
   6882     SOC_IF_ERROR_RETURN(soc_monterey_frequency_get(unit, &max_frequency, &def_freq));
   6883     freq_list = monterey_freq_list;
   6884     freq_list_len = sizeof(monterey_freq_list) / sizeof(int);
   6885     if (si->frequency != def_freq) {
   6886         for (sel = 0; sel < freq_list_len; sel++) {
   6887             if (si->frequency == freq_list[sel]) {
   6888                 break;
   6889             }
   6890         }
   6891 
   6892         LOG_CLI((BSL_META_U(unit,
   6893                    "*** change CORE_CLK_FREQ_SEL to %d\n"), sel));
   6894         LOG_CLI((BSL_META_U(unit,
   6895                    "*** change core clock frequency to %dMHz\n"),
   6896                    si->frequency));
   6897 
   6898         SOC_IF_ERROR_RETURN(READ_TOP_CORE_CLK_FREQ_SELr(unit, &rval));
   6899         soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   6900                           SW_CORE_CLK_SEL_ENf, 1);
   6901         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   6902         soc_reg_field_set(unit, TOP_CORE_CLK_FREQ_SELr, &rval,
   6903                           CORE_CLK_FREQ_SELf, sel);
   6904         SOC_IF_ERROR_RETURN(WRITE_TOP_CORE_CLK_FREQ_SELr(unit, rval));
   6905 
   6906         sal_usleep(to_usec);
   6907     }
   6908 
   6909 
   6910 
   6911     /*
   6912      * For TD2+ and TD+ compatible packages where there is no 1.25V supply in the package,
   6913      * ams_pll_drv_hv_disable needs to be set to 1.
   6914      *
   6915      * ams_pll_drv_hv_disable: This is the main TX driver mode for Falcon, and is properly enabled
   6916      * when TVDD1P25 = 1.25V, and tx_drv_hv_disable is set to its default value, "0".
   6917      * To prevent damage to the output driver, this bit must always be "0" if TVDD1P25 = 1.25V
   6918      */
   6919     
   6920     SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_5r(unit, &rval));
   6921     power_reset =  !soc_reg_field_get(unit, TOP_XG_PLL0_CTRL_5r, rval,
   6922                       RESERVEDf);
   6923     rval = 0 ; 
   6924     /* Put TS, BS PLLs to reset before changing PLL control registers */
   6925     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   6926     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6927                         TOP_TS_PLL_RST_Lf, 0);
   6928     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6929                         TOP_BS_PLL0_RST_Lf, 0);
   6930     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6931                         TOP_BS_PLL1_RST_Lf, 0);
   6932     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6933                         TOP_TS_PLL_POST_RST_Lf, 0);
   6934     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6935                         TOP_BS_PLL0_POST_RST_Lf, 0);
   6936     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6937                         TOP_BS_PLL1_POST_RST_Lf, 0);
   6938     if (power_reset) {
   6939         for (index = 0; index < COUNTOF(lcpll_reset_field); index++) {
   6940             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6941                               lcpll_reset_field[index], 0);
   6942         }
   6943 
   6944         for (index = 0; index < COUNTOF(lcpll_post_reset_field); index++) {
   6945             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   6946                               lcpll_post_reset_field[index], 0);
   6947         }
   6948     }
   6949     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   6950     if (power_reset && soc_property_get(unit, spn_LC_PLL_EXT_CLOCK, 0)) {
   6951         rval = 0;
   6952         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval));
   6953         soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval,
   6954                              LEGACY_HO_LOGIC_ENf,1);
   6955         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval));
   6956 
   6957         rval = 0;
   6958         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval));
   6959         soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval,
   6960                           LEGACY_HO_LOGIC_ENf,1);
   6961         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval));
   6962 
   6963         rval = 0;
   6964         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_0r(unit, &rval));
   6965         soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_0r, &rval,
   6966                               CH0_MDIVf,0x5);
   6967         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_0r(unit, rval));
   6968         rval = 0;
   6969         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval));
   6970         soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval,
   6971                            PLL_FBDIV_1f,0x580);
   6972         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval));
   6973         rval = 0;
   6974         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_0r(unit, &rval));
   6975         soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_0r, &rval,
   6976                                CH0_MDIVf,0x5);
   6977         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_0r(unit, rval));
   6978         rval = 0;
   6979         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval));
   6980         soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval,
   6981                             PLL_FBDIV_1f,0x580);
   6982         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval));
   6983         rval = 0;
   6984         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_8r(unit, &rval));
   6985         soc_reg_field_set(unit,TOP_XG_PLL0_CTRL_8r, &rval,
   6986                             LEGACY_HO_LOGIC_ENf,0);
   6987         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_8r(unit, rval));
   6988  
   6989         rval = 0;
   6990         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL3_CTRL_8r(unit, &rval));
   6991         soc_reg_field_set(unit,TOP_XG_PLL3_CTRL_8r, &rval,
   6992                              LEGACY_HO_LOGIC_ENf,0);
   6993         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL3_CTRL_8r(unit, rval));
   6994      }
   6995 
   6996  
   6997     rval = 0;
   6998 
   6999     SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_7r(unit, &rval));
   7000     soc_reg_field_set(unit, TOP_TS_PLL_CTRL_7r, &rval,
   7001                         PI_RESETf, 0);
   7002     SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_7r(unit, rval));
   7003 
   7004     rval = 0;
   7005     SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_0r(unit, &rval));
   7006     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_0r, &rval,
   7007                         DITHER_CTRL_N1f, SOC_MONTEREY_TS_PLL_N1);
   7008     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_0r, &rval,
   7009                         DITHER_CTRL_N2f, SOC_MONTEREY_TS_PLL_N2);
   7010     SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_0r(unit, rval));
   7011     rval = 0; 
   7012     SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_1r(unit, &rval));
   7013     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_1r, &rval,
   7014                         DITHER_CTRL_M1f, SOC_MONTEREY_TS_PLL_M1);
   7015     SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_1r(unit, rval));
   7016     rval = 0; 
   7017     SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_2r(unit, &rval));
   7018     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_2r, &rval,
   7019                         DITHER_CTRL_M2f, SOC_MONTEREY_TS_PLL_M1);
   7020     SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_2r(unit, rval));
   7021 
   7022     rval = 0; 
   7023     SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_DITHER_FSM_CTRL_3r(unit, &rval));
   7024     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_3r, &rval,
   7025                         DITHER_CTRL_PMAX1f, SOC_MONTEREY_TS_PLL_PMAX1);
   7026     soc_reg_field_set(unit, TOP_TS_PLL_DITHER_FSM_CTRL_3r, &rval,
   7027                        DITHER_CTRL_PMAX2f, SOC_MONTEREY_TS_PLL_PMAX2);
   7028     SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_DITHER_FSM_CTRL_3r(unit, rval));
   7029     rval = 0; 
   7030     /* Configure TS PLL */ 
   7031     ts_ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0);  /* 0->internal reference */
   7032 
   7033     for (ts_idx = 0; ts_idx < sizeof(ts_pll)/sizeof(ts_pll[0]); ++ts_idx) {
   7034         if (ts_pll[ts_idx].ref_freq == ts_ref_freq) {
   7035             break;
   7036         }
   7037     }
   7038     if (ts_idx == sizeof(ts_pll)/sizeof(ts_pll[0])) {
   7039         /* Valid configuration lookup failed. Use internal reference. */
   7040         ts_idx = 5;
   7041         ts_ref_freq = 0;
   7042     }
   7043 
   7044     /* Do not change PLL settings for internal reference */
   7045     if(ts_ref_freq) {
   7046         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit, &rval));
   7047         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, FREF_SELf, (ts_ref_freq != 0));
   7048         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_1r(unit, rval));
   7049 
   7050         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit,&rval));
   7051         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, PDIVf,
   7052                           soc_property_get(unit, spn_PTP_TS_PLL_PDIV, ts_pll[ts_idx].pdiv));
   7053         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, CH0_MDIVf,
   7054                           soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, ts_pll[ts_idx].mdiv));
   7055         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_3r(unit, rval));
   7056 
   7057         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval));
   7058         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_INTf,
   7059                           soc_property_get(unit, spn_PTP_TS_PLL_N, ts_pll[ts_idx].ndiv_int));
   7060         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, NDIV_FRACf, ts_pll[ts_idx].ndiv_frac);
   7061         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_4r(unit, rval));
   7062 
   7063         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_5r(unit,&rval));
   7064         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KAf,
   7065                           soc_property_get(unit, spn_PTP_TS_KA, ts_pll[ts_idx].ka));
   7066         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KIf,
   7067                           soc_property_get(unit, spn_PTP_TS_KI, ts_pll[ts_idx].ki));
   7068         soc_reg_field_set(unit, TOP_TS_PLL_CTRL_5r, &rval, KPf,
   7069                           soc_property_get(unit, spn_PTP_TS_KP, ts_pll[ts_idx].kp));
   7070         SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_5r(unit, rval));
   7071     }
   7072 
   7073     /* Set 250Mhz (implies 4ns resolution) default timesync clock to 
   7074        calculate assymentric delays */
   7075     SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */
   7076      
   7077     /* Configure BroadSync PLLs. */
   7078     bs_ref_freq = soc_property_get(unit, spn_PTP_BS_FREF, 0);  /* 0->internal reference */
   7079 
   7080     for (bs_idx = 0; bs_idx < sizeof(bs_pll)/sizeof(bs_pll[0]); ++bs_idx) {
   7081         if (bs_pll[bs_idx].ref_freq == bs_ref_freq) {
   7082             break;
   7083         }
   7084     }
   7085     if (bs_idx == sizeof(bs_pll)/sizeof(bs_pll[0])) {
   7086         /* Valid configuration lookup failed. Use internal reference. */
   7087         bs_idx = 5;
   7088         bs_ref_freq = 0;
   7089     }
   7090 
   7091         /* PLL settings for internal & external reference */
   7092 
   7093         bs_ndiv_high = ((soc_property_get(unit, spn_PTP_BS_NDIV_INT,
   7094                             bs_pll[bs_idx].ndiv_int) << 6) |
   7095                        ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC,
   7096                             bs_pll[bs_idx].ndiv_frac) >> 26) & 0x3f));
   7097         bs_ndiv_low = ((soc_property_get(unit, spn_PTP_BS_NDIV_FRAC,
   7098                             bs_pll[bs_idx].ndiv_frac) << 6) & 0xffffc000);
   7099 
   7100         /* Configure BS PLL0 */
   7101         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_1r(unit, &rval));
   7102         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0));
   7103         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_1r(unit, rval));
   7104 
   7105         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval));
   7106         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, PDIVf,
   7107                           soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv));
   7108         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, CH0_MDIVf,
   7109                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7110         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval));
   7111         /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */
   7112         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_5r(unit,&rval));
   7113         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low);
   7114         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_5r(unit, rval));
   7115 
   7116         /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */
   7117         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_6r(unit,&rval));
   7118         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high);
   7119         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_6r(unit, rval));
   7120 
   7121 #if 0
   7122         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_4r(unit, &rval));
   7123         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KAf,
   7124                           soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka));
   7125         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KIf,
   7126                           soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki));
   7127         soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KPf,
   7128                           soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp));
   7129         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_4r(unit, rval));
   7130 #endif
   7131 
   7132         /* Configure BS PLL1 */
   7133         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_1r(unit, &rval));
   7134         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, & rval, FREF_SELf, (bs_ref_freq != 0));
   7135         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_1r(unit, rval));
   7136 
   7137         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval));
   7138         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, PDIVf,
   7139                           soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv));
   7140         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, CH0_MDIVf,
   7141                           soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv));
   7142         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval));
   7143 
   7144         /* bs_ndiv_low maps to lower 32 bits (i.e., first 32bits) of the 48 bit Ndiv */
   7145         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_5r(unit,&rval));
   7146         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_5r, &rval, PLL_FBDIV_0f, bs_ndiv_low);
   7147         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_5r(unit, rval));
   7148 
   7149         /* bs_ndiv_high maps to higher 16 bits (i.e., last 16bits) of the 48 bit Ndiv */
   7150         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_6r(unit,&rval));
   7151         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_6r, &rval, PLL_FBDIV_1f, bs_ndiv_high);
   7152         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_6r(unit, rval));
   7153 
   7154 #if 0
   7155         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_4r(unit, &rval));
   7156         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KAf,
   7157                           soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka));
   7158         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KIf,
   7159                           soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki));
   7160         soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KPf,
   7161                           soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp));
   7162         SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_4r(unit, rval));
   7163 
   7164 #endif
   7165 
   7166     /* Set the BS PLL update rate to 12.5M */
   7167     SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_7r(unit, &rval));
   7168     soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_7r, &rval, PROG_DIV_CTRLf, 0x2);
   7169     SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_7r(unit, rval));
   7170 
   7171     SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_7r(unit, &rval));
   7172     soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_7r, &rval, PROG_DIV_CTRLf, 0x2);
   7173     SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_7r(unit, rval));
   7174 
   7175     /* Bring LCPLL, time sync PLL, BroadSync PLL out of reset */
   7176     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   7177     if (power_reset) {
   7178         for (index = 0; index < COUNTOF(lcpll_reset_field); index++) {
   7179             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7180                               lcpll_reset_field[index], 1);
   7181         }
   7182     }
   7183     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
   7184                       1);
   7185     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf,
   7186                       1);
   7187     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf,
   7188                       1);
   7189     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PMB_RST_Lf, 1);
   7190     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_ARS_RST_Lf, 1);
   7191     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1);
   7192     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   7193     sal_usleep(to_usec);
   7194     SOC_PBMP_CLEAR(cpri_pbmp);
   7195     cpri_pbmp = soc_property_get_pbmp_default(unit,
   7196                                             spn_PBMP_XPORT_CPRI, cpri_pbmp);
   7197     if (!SAL_BOOT_SIMULATION) {
   7198         /* Check LCPLL lock status */
   7199         for (index = 0; index < 4; index++) {
   7200            if ((index == 0 || index == 3)  && SOC_PBMP_IS_NULL(cpri_pbmp)) {
   7201                continue;
   7202            } 
   7203             reg = lcpll_status_reg[index];
   7204             SOC_IF_ERROR_RETURN
   7205                 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   7206             if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) {
   7207                 LOG_ERROR(BSL_LS_SOC_COMMON,
   7208                           (BSL_META_U(unit, "LCPLL %d not locked on unit %d "
   7209                                  "status = 0x%08x\n"), index, unit, rval));
   7210             }
   7211         }
   7212         /* Check time sync lock status */
   7213         SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_STATUSr(unit, &rval));
   7214         if (!soc_reg_field_get(unit, TOP_TS_PLL_STATUSr, rval, PLL_LOCKf)) {
   7215             LOG_ERROR(BSL_LS_SOC_COMMON,
   7216                           (BSL_META_U(unit, "TS_PLL not locked on unit %d "
   7217                              "status = 0x%08x\n"), unit, rval));
   7218         }
   7219 
   7220         /* Check BroadSync lock status */
   7221         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_STATUSr(unit, &rval));
   7222         if (!soc_reg_field_get(unit, TOP_BS_PLL0_STATUSr, rval, PLL_LOCKf)) {
   7223             LOG_ERROR(BSL_LS_SOC_COMMON,
   7224                           (BSL_META_U(unit, "BS_PLL0 not locked on unit %d "
   7225                              "status = 0x%08x\n"), unit, rval));
   7226         }
   7227 
   7228         SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_STATUSr(unit, &rval));
   7229         if (!soc_reg_field_get(unit, TOP_BS_PLL1_STATUSr, rval, PLL_LOCKf)) {
   7230             LOG_ERROR(BSL_LS_SOC_COMMON,
   7231                           (BSL_META_U(unit, "BS_PLL1 not locked on unit %d "
   7232                              "status = 0x%08x\n"), unit, rval));
   7233         }
   7234     }
   7235 
   7236     /* De-assert LCPLL's post reset */
   7237     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
   7238     
   7239     if (power_reset) {
   7240         for (index = 0; index < COUNTOF(lcpll_post_reset_field); index++) {
   7241             soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7242                               lcpll_post_reset_field[index], 1);
   7243         }
   7244     }
   7245 
   7246 
   7247     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7248                       TOP_TS_PLL_POST_RST_Lf, 1);
   7249     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7250                       TOP_BS_PLL0_POST_RST_Lf, 1);
   7251     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7252                       TOP_BS_PLL1_POST_RST_Lf, 1);
   7253 
   7254     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
   7255                       TOP_PVT_MON_MIN_RST_Lf, 1);
   7256 
   7257     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
   7258     if (power_reset ) { 
   7259         rval = 0 ;
   7260         SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_5r(unit, &rval));
   7261         soc_reg_field_set(unit, TOP_XG_PLL0_CTRL_5r, &rval,
   7262                           RESERVEDf, 1);
   7263         SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_5r(unit, rval));
   7264     } 
   7265     
   7266     rval = 0; 
   7267     sal_usleep(to_usec);
   7268 
   7269     /* Running TS1 time-staper for now.  Might be changed later during
   7270      * time-module porting
   7271      */
   7272     if (!SAL_BOOT_SIMULATION) {
   7273 
   7274         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval));
   7275         soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval,
   7276                           ENABLEf, 0);
   7277         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval));
   7278 
   7279         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, &rval));
   7280         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r, &rval,
   7281                           ACC2f, 0);
   7282         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_2r(unit, rval));
   7283 
   7284         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, &rval));
   7285         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r, &rval,
   7286                           ACC1f, 0);
   7287         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_1r(unit, rval));
   7288 
   7289         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, &rval));
   7290         soc_reg_field_set(unit, NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r, &rval,
   7291                           ACC0f, 0);
   7292         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_INIT_ACCUMULATOR_0r(unit, rval));
   7293 
   7294         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, &rval));
   7295         soc_reg_field_set(unit, NS_TIMESYNC_TS1_COUNTER_ENABLEr, &rval,
   7296                           ENABLEf, 1);
   7297         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_COUNTER_ENABLEr(unit, rval));
   7298 
   7299         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, &rval));
   7300         soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr, &rval,
   7301                           UINCf, 0x2000);
   7302         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_UPPERr(unit, rval));
   7303 
   7304         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, &rval));
   7305         soc_reg_field_set(unit, NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr, &rval,
   7306                           LINCf, 0x0);
   7307         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS1_FREQ_CTRL_FRAC_LOWERr(unit, rval));
   7308 
   7309         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval));
   7310         soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval,
   7311                           ENABLEf, 0);
   7312         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval));
   7313 
   7314         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, &rval));
   7315         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r, &rval,
   7316                           ACC2f, 0);
   7317         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_2r(unit, rval));
   7318 
   7319         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, &rval));
   7320         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r, &rval,
   7321                           ACC1f, 0);
   7322         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_1r(unit, rval));
   7323 
   7324         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, &rval));
   7325         soc_reg_field_set(unit, NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r, &rval,
   7326                           ACC0f, 0);
   7327         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_INIT_ACCUMULATOR_0r(unit, rval));
   7328 
   7329         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval));
   7330         soc_reg_field_set(unit, NS_TIMESYNC_TS0_COUNTER_ENABLEr, &rval,
   7331                           ENABLEf, 1);
   7332         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval));
   7333 
   7334         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, &rval));
   7335         soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr, &rval,
   7336                           UINCf, 0x2000);
   7337         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_UPPERr(unit, rval));
   7338 
   7339         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, &rval));
   7340         soc_reg_field_set(unit, NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr, &rval,
   7341                           LINCf, 0x0);
   7342         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_TS0_FREQ_CTRL_FRAC_LOWERr(unit, rval));
   7343 
   7344         SOC_IF_ERROR_RETURN(READ_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, &rval));
   7345         soc_reg_field_set(unit, NS_TIMESYNC_COUNTER_CONFIG_SELECTr, &rval,
   7346                           ENABLE_COMMON_CONTROLf, 0x0);
   7347         SOC_IF_ERROR_RETURN(WRITE_NS_TIMESYNC_COUNTER_CONFIG_SELECTr(unit, rval));
   7348     }
   7349 
   7350     /* Set correct value for BG_ADJ */
   7351     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval));
   7352     soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 0);
   7353     soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, MODEf, 2);
   7354     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval));
   7355 
   7356     /* Enable high temperature interrupt monitoring.
   7357      * Default on: pvtmon6 (close to core_plls at center of die).
   7358      */
   7359     temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<6);
   7360     /* The above is a 9 bit mask to indicate which temp sensor to hook up to
   7361      * the interrupt.
   7362      */
   7363     rval = 0;
   7364     for (index = 0; index <COUNTOF(temp_thr_reg); index++) {
   7365         uint32 trval;
   7366 
   7367         /* data = 410.04-(temp/0.48705) = (410040-(temp*1000))/487
   7368          * Note: Since this is a high temp value we can safely assume it to
   7369          * always be a +ive number. This is in degrees celcius.
   7370          */
   7371         temp_thr = soc_property_get(unit, temp_thr_prop[index], _SOC_MN_DEF_TEMP_MAX);
   7372         if (temp_thr > 410) {
   7373             LOG_ERROR(BSL_LS_SOC_COMMON,
   7374                       (BSL_META_U(unit,
   7375                                   "Unsupported temp value %d !! Max 410. Using %d.\n"),
   7376                        temp_thr, _SOC_MN_DEF_TEMP_MAX));
   7377             temp_thr = _SOC_MN_DEF_TEMP_MAX;
   7378         }
   7379         /* Convert temperature to config data */
   7380         temp_thr = (410040-(temp_thr*1000))/487;
   7381         SOC_IF_ERROR_RETURN
   7382             (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval));
   7383         soc_reg_field_set(unit, temp_thr_reg[index], &trval, MAX_THRESHOLDf,
   7384                           temp_thr);
   7385         SOC_IF_ERROR_RETURN
   7386             (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval));
   7387         if (temp_mask & (1 << index)) {
   7388             rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */
   7389         }
   7390     }
   7391     _soc_mn_temp_mon_mask[unit] = temp_mask;
   7392 
   7393     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_MASKr(unit, rval));
   7394     /* Enable temp mon interrupt */
   7395     (void)soc_cmicm_intr3_enable(unit, 0x4); /* PVTMON_INTR bit 2 */
   7396 
   7397     /* Bring port blocks out of reset */
   7398     rval = 0;
   7399     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 1);
   7400     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 1);
   7401     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1);
   7402     WRITE_TOP_SOFT_RESET_REGr(unit, rval);
   7403 
   7404     sal_usleep(to_usec);
   7405 
   7406     /* Bring IP, EP, and MMU blocks out of reset */
   7407     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval));
   7408     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1);
   7409 
   7410     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1);
   7411     soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1);
   7412 
   7413     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval));
   7414 
   7415     sal_usleep(to_usec);
   7416 
   7417     /* Bring PMs out of reset */
   7418     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_3r(unit, &rval));
   7419     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM0_RST_Lf, 1);
   7420     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM1_RST_Lf, 1);
   7421     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM2_RST_Lf, 1);
   7422     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM3_RST_Lf, 1);
   7423     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM4_RST_Lf, 1);
   7424     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM5_RST_Lf, 1);
   7425     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM6_RST_Lf, 1);
   7426     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM7_RST_Lf, 1);
   7427     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM8_RST_Lf, 1);
   7428     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM9_RST_Lf, 1);
   7429     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM10_RST_Lf, 1);
   7430     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM11_RST_Lf, 1);
   7431     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM12_RST_Lf, 1);
   7432     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM13_RST_Lf, 1);
   7433     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM14_RST_Lf, 1);
   7434     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_PM15_RST_Lf, 1);
   7435     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_3r, &rval, TOP_MACSEC_RST_Lf, 1);
   7436     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, rval));
   7437     sal_usleep(to_usec);
   7438 
   7439 
   7440 
   7441     num_ecmp_rh_flowset_entries = soc_property_get(unit,
   7442             spn_ECMP_RESILIENT_HASH_SIZE, 32768);
   7443     switch (num_ecmp_rh_flowset_entries) {
   7444         case 0:
   7445             rh_table_config_encoding = 2;
   7446             break;
   7447         case 32768:
   7448             rh_table_config_encoding = 0;
   7449             break;
   7450         case 65536:
   7451             rh_table_config_encoding = 1;
   7452             break;
   7453         default:
   7454             return SOC_E_CONFIG;
   7455     }
   7456 
   7457 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
   7458     ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1);
   7459     if ((soc_feature(unit, soc_feature_riot) ||
   7460          soc_feature(unit, soc_feature_multi_level_ecmp)) &&
   7461         ecmp_levels > 1) {
   7462 
   7463         num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit,
   7464             spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0);
   7465 
   7466         if (SOC_FIELD_RANGE_CHECK(
   7467             num_overlay_ecmp_rh_flowset_entries, 0, 16384)) {
   7468 
   7469             num_overlay_ecmp_rh_flowset_entries = 16384;
   7470         } else if (SOC_FIELD_RANGE_CHECK(
   7471             num_overlay_ecmp_rh_flowset_entries, 16384, 32768)) {
   7472 
   7473             num_overlay_ecmp_rh_flowset_entries = 32768;
   7474         } else if (SOC_FIELD_RANGE_CHECK(
   7475             num_overlay_ecmp_rh_flowset_entries, 32768, 49152)) {
   7476 
   7477             num_overlay_ecmp_rh_flowset_entries = 49152;
   7478         } else if (SOC_FIELD_RANGE_CHECK(
   7479             num_overlay_ecmp_rh_flowset_entries, 49152, 65536)) {
   7480 
   7481             num_overlay_ecmp_rh_flowset_entries = 65536;
   7482         }
   7483 
   7484         switch (num_overlay_ecmp_rh_flowset_entries) {
   7485         case 0:
   7486             rh_bank_sel = 0x0;
   7487             break;
   7488         case 16384:
   7489             if (num_ecmp_rh_flowset_entries >= 16384) {
   7490                 rh_bank_sel = 0x1;
   7491             } else {
   7492                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7493                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7494                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7495                     num_overlay_ecmp_rh_flowset_entries));
   7496                 return SOC_E_CONFIG;
   7497             }
   7498             break;
   7499         case 32768:
   7500             if (num_ecmp_rh_flowset_entries >= 32768) {
   7501                 rh_bank_sel = 0x3;
   7502             } else {
   7503                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7504                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7505                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7506                     num_overlay_ecmp_rh_flowset_entries));
   7507                 return SOC_E_CONFIG;
   7508             }
   7509             break;
   7510         case 49152:
   7511             if (num_ecmp_rh_flowset_entries >= 49152) {
   7512                 rh_bank_sel = 0x7;
   7513             } else {
   7514                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7515                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7516                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7517                     num_overlay_ecmp_rh_flowset_entries));
   7518                 return SOC_E_CONFIG;
   7519             }
   7520             break;
   7521         case 65536:
   7522             if (num_ecmp_rh_flowset_entries >= 65536) {
   7523                 rh_bank_sel = 0xf;
   7524             } else {
   7525                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7526                     "%s:Total ECMP entries %d are less than RH entries :%d \n"),
   7527                     FUNCTION_NAME(),  num_ecmp_rh_flowset_entries,
   7528                     num_overlay_ecmp_rh_flowset_entries));
   7529                 return SOC_E_CONFIG;
   7530             }
   7531             break;
   7532         default:
   7533                 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit,
   7534                     "%s: Value for overlay RH entries is not correct : %d \n"),
   7535                     FUNCTION_NAME(),  num_overlay_ecmp_rh_flowset_entries));
   7536             return SOC_E_CONFIG;
   7537     }
   7538     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, RH_ECMP_FLOWSET_BANK_SELr,
   7539                 REG_PORT_ANY, BANK_SELf,
   7540                 rh_bank_sel));
   7541   }
   7542 #endif
   7543     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr,
   7544                 REG_PORT_ANY, RH_FLOWSET_TABLE_CONFIG_ENCODINGf,
   7545                 rh_table_config_encoding));
   7546 
   7547     READ_TOP_PVTMON_CTRL_1r(unit, &rval);
   7548     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   7549     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7550     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0);
   7551     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7552     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
   7553     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
   7554     /* Bypass unused Port Blocks */
   7555      /* Bypass unused Port Blocks */
   7556     if (soc_property_get(unit, "disable_unused_port_blocks", TRUE)) {
   7557         SOC_IF_ERROR_RETURN(soc_monterey_tsc_disable(unit));
   7558     }
   7559 
   7560 
   7561     /* Do not use SBUS MDIO by default */
   7562     SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = NULL;
   7563     SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = NULL;
   7564 
   7565     /* Optionally allow SBUS MDIO for debug */
   7566     if (soc_property_get(unit, "monterey_sbus_mdio", 1)) {
   7567         SOC_FUNCTIONS(unit)->soc_sbus_mdio_read = _soc_monterey_mdio_reg_read;
   7568         SOC_FUNCTIONS(unit)->soc_sbus_mdio_write = _soc_monterey_mdio_reg_write;
   7569     }
   7570 
   7571     if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED) &&
   7572             soc_feature(unit, soc_feature_turbo_boot)) {
   7573         SOC_HW_RESET_START(unit);
   7574     }
   7575 
   7576     return SOC_E_NONE;
   7577 }
   7578 
   7579 int
   7580 soc_monterey_tsc_reset(int unit)
   7581 {
   7582     int blk, port;
   7583     uint32 rval;
   7584     uint64 rval64;
   7585 
   7586 
   7587     /* Set tsc reference clock connection */
   7588     SOC_IF_ERROR_RETURN(_soc_monterey_tsc_refclk_set(unit));
   7589 
   7590     /* Though TSC/MAC reset is controlled by PortMod internally,
   7591      * this is needed in case access to MAC registers is needed
   7592      * before PortMod attach for cases like:
   7593      * - To enable SER MAC interrupts
   7594      * - Various sanity register read/write tests
   7595      */
   7596 
   7597     SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) {
   7598         port = SOC_BLOCK_PORT(unit, blk);
   7599         if(!(monterey_tsc_is_master_pll(SOC_INFO(unit).port_serdes[port]))) {
   7600             SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7601         }
   7602 
   7603         SOC_IF_ERROR_RETURN(READ_CLPORT_MAC_CONTROLr(unit, port, &rval));
   7604         soc_reg_field_set(unit, CLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7605         SOC_IF_ERROR_RETURN(WRITE_CLPORT_MAC_CONTROLr(unit, port, rval));
   7606     }
   7607 
   7608     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   7609         port = SOC_BLOCK_PORT(unit, blk);
   7610         if(!(monterey_tsc_is_master_pll(SOC_INFO(unit).port_serdes[port]))) {
   7611             SOC_IF_ERROR_RETURN(soc_tsc_xgxs_reset(unit, port, 0));
   7612         }
   7613 
   7614         SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, port, &rval));
   7615         soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0);
   7616         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, port, rval));
   7617     }
   7618 
   7619     PBMP_PORT_ITER(unit, port) {
   7620         if(IS_CPRI_PORT(unit, port)) {
   7621             /* PLL0 select pll0_lc_refclk for CPRI, keep PLL1 pll1_lc_refclk for Ethernet */
   7622             SOC_IF_ERROR_RETURN(soc_reg_get(unit, CLPORT_XGXS0_CTRL_REGr, port, 0, &rval64));
   7623             soc_reg64_field32_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval64, PLL0_LC_REFSELf, 0);
   7624             SOC_IF_ERROR_RETURN(soc_reg_set(unit, CLPORT_XGXS0_CTRL_REGr, port, 0, rval64));
   7625 
   7626             SOC_IF_ERROR_RETURN(READ_TOP_CTRL_CONFIGr(unit, port, &rval));
   7627             soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, CIP_TOP_CTRLf, 0);
   7628             soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, PMD_IDDQf, 0);
   7629             soc_reg_field_set(unit, TOP_CTRL_CONFIGr, &rval, CIP_TOP_CTRLf, 0);
   7630             SOC_IF_ERROR_RETURN(WRITE_TOP_CTRL_CONFIGr(unit, port, rval));
   7631             SOC_IF_ERROR_RETURN(READ_CPMPORT_PMD_CTRLr(unit, port, &rval));
   7632             soc_reg_field_set(unit, CPMPORT_PMD_CTRLr, &rval, PMD_POR_H_RSTBf, 0);
   7633             SOC_IF_ERROR_RETURN(WRITE_CPMPORT_PMD_CTRLr(unit, port, rval));
   7634 
   7635             if (!SAL_BOOT_PLISIM) {
   7636                 SOC_IF_ERROR_RETURN(READ_CPRI_RST_CTRLr(unit, port, &rval));
   7637                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_TX_Hf, 0);
   7638                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_RX_Hf, 0);
   7639                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_CIP_TX_Hf, 0);
   7640                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_CIP_RX_Hf, 0);
   7641                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_DATAPATH_RX_Hf, 0);
   7642                 soc_reg_field_set(unit, CPRI_RST_CTRLr, &rval, RESET_DATAPATH_TX_Hf, 0);
   7643                 SOC_IF_ERROR_RETURN(WRITE_CPRI_RST_CTRLr(unit, port, rval));
   7644             }
   7645         }
   7646     }
   7647 /*
   7648 */
   7649     return SOC_E_NONE;
   7650 }
   7651 
   7652 
   7653 STATIC int
   7654 _soc_monterey_clear_enabled_port_data (int unit)
   7655 {
   7656     uint64 rval64;
   7657     int    port;
   7658     uint32 evc = 0;
   7659     egr_vlan_control_1_entry_t entry1;
   7660     egr_vlan_control_2_entry_t entry2;
   7661     egr_vlan_control_3_entry_t entry3;
   7662 
   7663     sal_memset(&entry1, 0, sizeof(entry1));
   7664     sal_memset(&entry2, 0, sizeof(entry2));
   7665     sal_memset(&entry3, 0, sizeof(entry3));
   7666 
   7667     /* Some registers are implemented in memory, need to clear them in order
   7668      * to have correct parity value */
   7669     COMPILER_64_ZERO(rval64);
   7670     PBMP_ALL_ITER(unit, port) {
   7671         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry1));
   7672         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_2m(unit, MEM_BLOCK_ANY, port, &entry2));
   7673         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry3));
   7674 
   7675         SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, 0));
   7676         SOC_IF_ERROR_RETURN(WRITE_EGR_SF_SRC_MODID_CHECKr(unit, port, rval64));
   7677         SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64));
   7678         SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ALL, port, &evc));
   7679         SOC_IF_ERROR_RETURN(WRITE_STORM_CONTROL_METER_CONFIGr(unit, port, 0));
   7680         SOC_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, 0));
   7681     }
   7682 
   7683     return SOC_E_NONE;
   7684 }
   7685 
   7686 STATIC int
   7687 _soc_monterey_clear_all_port_data (int unit)
   7688 {
   7689     int    r, p;
   7690     uint32 addr;
   7691     
   7692     SOC_IF_ERROR_RETURN(_soc_monterey_clear_enabled_port_data(unit));
   7693 
   7694     
   7695     
   7696     /* Clear TDBGCn regs for all indexes */
   7697     for (r = 0; r < 12; r++) {
   7698         addr = 0x28000000 + r*0x100;
   7699         for (p = 0; p < 106; p++) {
   7700             _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7701             _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7702         }
   7703     }
   7704 
   7705     /* Clear TPCE */
   7706     addr = 0x28000f00;
   7707     for (p = 0; p < 106; p++) {
   7708         _soc_reg32_set(unit, 0x2, 1, addr+p, 0);
   7709         _soc_reg32_set(unit, 0x2, 2, addr+p, 0);
   7710     }
   7711     return SOC_E_NONE;
   7712 }
   7713 
   7714 STATIC int
   7715 _soc_monterey_clear_all_memory(int unit, int mmu_init)
   7716 {
   7717     int                 blk;
   7718     int                 pgw, pgw_inst, num_pgw = 0;
   7719     uint32              rval, in_progress[1];
   7720     int                 hw_reset_to, index, count;
   7721     soc_reg_t           hw_reset_reg;
   7722     soc_timeout_t       to;
   7723     static const struct {
   7724         soc_mem_t mem;
   7725         uint32 skip_flags; /* always skip on QUICKTURN or XGSSIM */
   7726     } cam_list[] = {
   7727         { CPU_COS_MAPm,                     BOOT_F_PLISIM },
   7728         { EFP_TCAMm,                        BOOT_F_PLISIM },
   7729         { FP_GLOBAL_MASK_TCAMm,             BOOT_F_PLISIM },
   7730         { FP_TCAMm,                         BOOT_F_PLISIM },
   7731         { VFP_TCAMm,                        BOOT_F_PLISIM },
   7732         { FP_UDF_TCAMm,                     BOOT_F_PLISIM },
   7733         { ING_SNATm,                        BOOT_F_PLISIM },
   7734         { IP_MULTICAST_TCAMm,               BOOT_F_PLISIM },
   7735         { L2_USER_ENTRYm,                   BOOT_F_PLISIM },
   7736         { L3_DEFIPm,                        BOOT_F_PLISIM },
   7737         { L3_DEFIP_PAIR_128m,               BOOT_F_PLISIM },
   7738         { L3_TUNNELm,                       BOOT_F_PLISIM },
   7739         { MY_STATION_TCAMm,                 BOOT_F_PLISIM },
   7740         { UDF_CONDITIONAL_CHECK_TABLE_CAMm, BOOT_F_PLISIM },
   7741         { MY_STATION_TCAM_2m,               BOOT_F_PLISIM },
   7742         { VLAN_SUBNETm,                     0 },/* VLAN API needs all 0 mask */
   7743         { MY_STATION_TCAM_2m,               BOOT_F_PLISIM },
   7744 #ifdef PLISIM
   7745         /* In HW, these are the same as FP_GLOBAL_MASK_TCAM.
   7746          * In simulation, they are separate instances.
   7747          */
   7748         { FP_GM_FIELDSm,                    BOOT_F_PLISIM }
   7749 #endif
   7750     };
   7751 
   7752     if (mmu_init) {
   7753         uint32 rval1;
   7754         /* Start MMU memory initialization */
   7755         SOC_IF_ERROR_RETURN
   7756             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 0));
   7757 
   7758         SOC_IF_ERROR_RETURN(READ_MMU_CCP_EN_COR_ERR_RPTr(unit, &rval1));
   7759         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 0);
   7760         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   7761         SOC_IF_ERROR_RETURN
   7762             (soc_reg_field32_modify(unit, MISCCONFIGr, REG_PORT_ANY, INIT_MEMf, 1));
   7763 
   7764         sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 10); /* Allow things to stabalize */
   7765         soc_reg_field_set(unit, MMU_CCP_EN_COR_ERR_RPTr, &rval1,CCP0_RESEQf, 1);
   7766         SOC_IF_ERROR_RETURN(WRITE_MMU_CCP_EN_COR_ERR_RPTr(unit, rval1));
   7767     }
   7768 
   7769     SOC_IF_ERROR_RETURN
   7770         (_soc_monterey_mmu_init_default_val(unit));
   7771 
   7772     /*
   7773      * Reset the PGW, IPIPE and EPIPE block
   7774      */
   7775     rval = 0;
   7776     hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r;
   7777     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7778     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7779 
   7780     SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) {
   7781         num_pgw += 1;
   7782         pgw = SOC_BLOCK_NUMBER(unit, blk);
   7783         pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   7784         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, pgw_inst, 0, rval));
   7785     }
   7786 
   7787     rval = 0;
   7788     hw_reset_reg = ING_HW_RESET_CONTROL_2r;
   7789     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   7790     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7791     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7792 
   7793     /* Set count to # entries of largest IPIPE table */
   7794     count = (1 << soc_reg_field_length(unit, hw_reset_reg, COUNTf)) - 1;
   7795     soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count);
   7796     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval));
   7797 
   7798     sal_usleep(500);
   7799     rval = 0;
   7800     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   7801 
   7802     hw_reset_reg = EGR_HW_RESET_CONTROL_1r;
   7803     soc_reg_field_set(unit, hw_reset_reg, &rval, RESET_ALLf, 1);
   7804     soc_reg_field_set(unit, hw_reset_reg, &rval, VALIDf, 1);
   7805     /* Set count to # entries of largest EPIPE table (EGR_L3_NEXT_HOP) */
   7806     count = (1 << soc_reg_field_length(unit, hw_reset_reg, COUNTf)) - 1;
   7807     soc_reg_field_set(unit, hw_reset_reg, &rval, COUNTf, count);
   7808     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, hw_reset_reg, REG_PORT_ANY, 0, rval));
   7809 
   7810     sal_usleep(500);
   7811     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   7812     if (SAL_BOOT_QUICKTURN) {
   7813         hw_reset_to = 10000000;
   7814     } else {
   7815         hw_reset_to = 50000;
   7816     }
   7817     soc_timeout_init(&to, hw_reset_to, 0);
   7818 
   7819     /* Wait for PGW memory initialization done. */
   7820     hw_reset_reg = PGW_ING_HW_RESET_CONTROL_2r;
   7821     /*  in_progress = ((1 << num_pgw) - 1); */  /* 1b for each PGW */
   7822     in_progress[0] = 0;
   7823     SHR_BITSET_RANGE(in_progress, 0, num_pgw);  /* 1b for each PGW */
   7824 
   7825     do {
   7826         SOC_BLOCK_ITER(unit, blk, SOC_BLK_PGW_CL) {
   7827             pgw = SOC_BLOCK_NUMBER(unit, blk);
   7828             pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK);
   7829             if (SHR_BITGET(in_progress, pgw)) { /* PGW RESET not done yet */
   7830                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg,
   7831                                                   pgw_inst, 0, &rval));
   7832 
   7833                 if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7834                     SHR_BITCLR(in_progress, pgw); /* Clear bit corresponding to the PGW */
   7835                 }
   7836             }
   7837         }
   7838 
   7839         if (soc_timeout_check(&to)) {
   7840             if (!SAL_BOOT_BCMSIM) {
   7841                 LOG_WARN(BSL_LS_SOC_COMMON,
   7842                          (BSL_META_U(unit, "PGW_ING_HW_RESET timeout\n")));
   7843             }
   7844             break;
   7845         }
   7846     } while (in_progress[0] != 0);
   7847 
   7848     /* Wait for EPIPE memory initialization done. */
   7849     in_progress[0] = 1;
   7850     hw_reset_reg = EGR_HW_RESET_CONTROL_1r;
   7851     do {
   7852         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval));
   7853         if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7854             in_progress[0] = 0;
   7855         }
   7856         if (soc_timeout_check(&to)) {
   7857             if (!SAL_BOOT_BCMSIM) {
   7858                 LOG_WARN(BSL_LS_SOC_COMMON,
   7859                          (BSL_META_U(unit, "EGR_HW_RESET timeout\n")));
   7860             }
   7861             break;
   7862         }
   7863     } while (in_progress[0] != 0);
   7864 
   7865     /* Wait for IPIPE memory initialization done. */
   7866     in_progress[0] = 1;
   7867     hw_reset_reg = ING_HW_RESET_CONTROL_2r;
   7868     do {
   7869         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, hw_reset_reg, REG_PORT_ANY, 0, &rval));
   7870         if (soc_reg_field_get(unit, hw_reset_reg, rval, DONEf)) {
   7871             in_progress[0] = 0;
   7872         }
   7873 
   7874         if (soc_timeout_check(&to)) {
   7875             if (!SAL_BOOT_BCMSIM) {
   7876                 LOG_WARN(BSL_LS_SOC_COMMON,
   7877                          (BSL_META_U(unit, "ING_HW_RESET timeout\n")));
   7878             }
   7879             break;
   7880         }
   7881     } while (in_progress[0] != 0);
   7882 
   7883     /* TCAM tables are not handled by hardware reset control */
   7884     if (!SAL_BOOT_QUICKTURN && !SAL_BOOT_XGSSIM && !SAL_BOOT_BCMSIM) {
   7885         for (index = 0; index < sizeof(cam_list) / sizeof(cam_list[0]);
   7886              index++) {
   7887             if (sal_boot_flags_get() & cam_list[index].skip_flags) {
   7888                 continue;
   7889             }
   7890             SOC_IF_ERROR_RETURN
   7891                 (soc_mem_clear(unit, cam_list[index].mem, COPYNO_ALL, TRUE));
   7892         }
   7893     }
   7894 
   7895     return SOC_E_NONE;
   7896 }
   7897 
   7898 
   7899 STATIC int
   7900 _soc_monterey_port_mapping_init(int unit)
   7901 {
   7902     soc_info_t *si;
   7903     soc_mem_t mem;
   7904     uint32 rval;
   7905     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
   7906     int port, phy_port;
   7907     int num_port, num_phy_port;
   7908 
   7909     si = &SOC_INFO(unit);
   7910 
   7911     /* Ingress physical to logical port mapping */
   7912     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
   7913     num_phy_port = soc_mem_index_count(unit, mem);
   7914     sal_memset(&entry, 0, sizeof(entry));
   7915     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
   7916         port = si->port_p2l_mapping[phy_port];
   7917         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
   7918                             port == -1 ? 0x7f : port);
   7919         SOC_IF_ERROR_RETURN
   7920             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
   7921     }
   7922 
   7923     /* Ingress logical to physical port mapping */
   7924     num_port = soc_mem_index_count(unit, PORT_TABm) - 1;
   7925 
   7926     for (port = 0; port < num_port; port++) {
   7927         phy_port = si->port_l2p_mapping[port];
   7928         rval = 0;
   7929         if (phy_port != -1) {
   7930             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   7931                               VALIDf, 1);
   7932 
   7933             /* IFP_GM_LOGICAL_TO_PHYSICAL_MAPP?ING.PHYSICAL_PORT_NUM is
   7934              * merely a unique stream ID, it's not physical port number */
   7935             soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   7936                               PHYSICAL_PORT_NUMf,
   7937                               si->port_p2m_mapping[phy_port] & 0x7f);
   7938         }
   7939         SOC_IF_ERROR_RETURN
   7940             (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval));
   7941     }
   7942 
   7943     /* Egress logical to physical port mapping */
   7944     for (port = 0; port < num_port; port++) {
   7945         phy_port = si->port_l2p_mapping[port];
   7946         rval = 0;
   7947         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
   7948                           &rval, PHYSICAL_PORT_NUMBERf,
   7949                           phy_port == -1 ? 0x7f : phy_port);
   7950         SOC_IF_ERROR_RETURN
   7951             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
   7952                                                                 rval));
   7953     }
   7954 
   7955     /* MMU to physical port mapping and MMU to logical port mapping */
   7956     for (port = 0; port < num_port; port++) {
   7957         phy_port = si->port_l2p_mapping[port];
   7958         if (phy_port == -1) {
   7959             continue;
   7960         }
   7961         rval = 0;
   7962         soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval,
   7963                           PHY_PORTf, phy_port);
   7964         SOC_IF_ERROR_RETURN
   7965             (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, port, 0,
   7966                            rval));
   7967 
   7968         rval = 0;
   7969         soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval,
   7970                           LOGIC_PORTf, port);
   7971         SOC_IF_ERROR_RETURN
   7972             (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, port, 0,
   7973                            rval));
   7974     }
   7975 
   7976     return SOC_E_NONE;
   7977 }
   7978 
   7979 #define MONTEREY_PGW_TDM_LENGTH                 MN_LR_LLS_LEN
   7980 #define MONTEREY_PGW_TDM_OVS_SIZE               MN_OS_LLS_GRP_LEN
   7981 #define MONTEREY_PGW_TDM_SLOTS_PER_REG          4
   7982 #define MONTEREY_MMU_TDM_LENGTH                 512
   7983 #define MONTEREY_MMU_OVS_GROUP_COUNT            MN_OS_VBS_GRP_NUM
   7984 #define MONTEREY_MMU_OVS_WT_GROUP_COUNT         8 
   7985 #define MONTEREY_MMU_OVS_GROUP_TDM_LENGTH       MN_OS_VBS_GRP_LEN
   7986 #define MONTEREY_IARB_TDM_LENGTH                MN_LR_IARB_STATIC_LEN
   7987 
   7988 
   7989 #define OVS_TOKEN MN_OVSB_TOKEN
   7990 #define IDL1_TOKEN MN_IDL1_TOKEN
   7991 #define IDL2_TOKEN MN_IDL2_TOKEN
   7992 #define AUX_TOKEN  MN_AUX_TOKEN
   7993 #define SBUS_TOKEN MN_SBUS_TOKEN
   7994 
   7995 #define NUM_EXT_PORTS MN_NUM_EXT_PORTS
   7996 
   7997 #define PORT_STATE_UNUSED          0   /*  PORT_STATE__DISABLED */
   7998 #define PORT_STATE_LINERATE        1   /*  PORT_STATE__LINERATE */
   7999 #define PORT_STATE_OVERSUB         2   /*  PORT_STATE__OVERSUB  */
   8000 #define PORT_STATE_SUBPORT         3   /*  PORT_STATE__COMBINED */
   8001 
   8002 enum _mn_ovs_speed_classes {
   8003     mn_ovs_speed_None = 0,
   8004     mn_ovs_speed_5G   = 2,
   8005     mn_ovs_speed_10G  = 4,
   8006     mn_ovs_speed_20G  = 8,
   8007     mn_ovs_speed_25G  = 10,
   8008     mn_ovs_speed_40G  = 16,
   8009     mn_ovs_speed_50G  = 20,
   8010     mn_ovs_speed_100G = 40
   8011 };
   8012 
   8013 /*
   8014  * MMU OVS TDM min. slot bandwidth is 5G.
   8015  * Anything less than 5G will be grouped together and will have provision for up to 5G.
   8016  */
   8017 #define MONTEREY_TDM_MMU_SPEED_GET(unit, speed)             \
   8018     do {                                                  \
   8019         speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);   \
   8020         if ((speed <= 5000) && (speed > 0)) {             \
   8021             speed = 5000;                                 \
   8022         }                                                 \
   8023     } while (0)
   8024 
   8025  int
   8026 _soc_monterey_mmu_ovs_speed_class_map_get(int unit, int *speed, int *spg, uint32 *sp_spacing)
   8027 {
   8028  MONTEREY_TDM_MMU_SPEED_GET(unit, *speed);
   8029     switch (*speed) {
   8030         case 5000:
   8031             *sp_spacing = 0x14;
   8032             *spg = mn_ovs_speed_5G;
   8033             break;
   8034         case 10000:
   8035             *sp_spacing = 0x14;
   8036             *spg = mn_ovs_speed_10G;
   8037             break;
   8038         case 20000:
   8039             *sp_spacing = 0x0a;
   8040             *spg = mn_ovs_speed_20G;
   8041             break;
   8042         case 25000:
   8043             *sp_spacing = 0x0a;
   8044             *spg = mn_ovs_speed_25G;
   8045             break;
   8046         case 40000:
   8047             *sp_spacing = 0x0a;
   8048             *spg = mn_ovs_speed_40G;
   8049             break;
   8050         case 50000:
   8051             *sp_spacing = 0x0a;
   8052             *spg = mn_ovs_speed_50G;
   8053             break;
   8054         case 100000:
   8055             *sp_spacing = 0x04;
   8056             *spg = mn_ovs_speed_100G;
   8057             break;
   8058         default:
   8059             *sp_spacing = 0x0;
   8060             *spg = mn_ovs_speed_None;
   8061             return SOC_E_FAIL;
   8062     }
   8063 
   8064     return SOC_E_NONE;
   8065 
   8066 }
   8067 
   8068 
   8069 typedef struct soc_monterey_tdm_s {
   8070     int tdm_bw;
   8071     int is_oversub;
   8072 
   8073     int speed[NUM_EXT_PORTS];
   8074     int port_state[NUM_EXT_PORTS];
   8075 
   8076     int pgw_tdm[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH];
   8077     int mmu_tdm[MONTEREY_MMU_TDM_LENGTH + 1];
   8078 
   8079     struct {
   8080         int pgw_ovs_tdm[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH];
   8081         int pgw_ovs_spacing[MONTEREY_PGWS_PER_DEV][MONTEREY_PGW_TDM_LENGTH];
   8082     } ingress_ovs_tdm;
   8083 
   8084     struct {
   8085         int mmu_ovs_group_tdm[MONTEREY_MMU_OVS_GROUP_COUNT][MONTEREY_MMU_OVS_GROUP_TDM_LENGTH];
   8086         int mmu_ovs_group_speed[MONTEREY_MMU_OVS_GROUP_COUNT]; /* Speed for each OVS grp */
   8087         int mmu_ovs_group_wt_group[MONTEREY_MMU_OVS_GROUP_COUNT]; /* Weighti group for each OVS grp */
   8088     } egress_ovs_tdm;
   8089 
   8090     int iarb_tdm_wrap_ptr;
   8091     int iarb_tdm[MONTEREY_IARB_TDM_LENGTH];
   8092     int pgw0len;
   8093     int pgw1len;
   8094 } soc_monterey_tdm_t;
   8095 
   8096 
   8097 
   8098 struct soc_monterey_misc_info_s {
   8099     int tdm_active_cal;
   8100     uint16 tdm_wtg_used[MONTEREY_MMU_OVS_WT_GROUP_COUNT];
   8101     soc_monterey_tdm_t tdm0;
   8102     soc_monterey_tdm_t tdm1;
   8103 } *soc_monterey_misc_info[SOC_MAX_NUM_DEVICES] = {0};
   8104 
   8105 #define MN_MISC(unit) (soc_monterey_misc_info[unit])
   8106 
   8107 
   8108 
   8109 
   8110 static const soc_field_t mn_mmu_ovs_group_wt_select_fields[] = {
   8111     GRP0f, GRP1f, GRP2f, GRP3f, GRP4f, GRP5f, GRP6f, GRP7f
   8112 };
   8113 
   8114 
   8115 static const soc_reg_t mn_pgw_lr_tdm_regs[2][40] = {
   8116     {
   8117         PGW_LR_TDM_REG_0r,  PGW_LR_TDM_REG_1r,
   8118         PGW_LR_TDM_REG_2r,  PGW_LR_TDM_REG_3r,
   8119         PGW_LR_TDM_REG_4r,  PGW_LR_TDM_REG_5r,
   8120         PGW_LR_TDM_REG_6r,  PGW_LR_TDM_REG_7r,
   8121         PGW_LR_TDM_REG_8r,  PGW_LR_TDM_REG_9r,
   8122         PGW_LR_TDM_REG_10r, PGW_LR_TDM_REG_11r,
   8123         PGW_LR_TDM_REG_12r, PGW_LR_TDM_REG_13r,
   8124         PGW_LR_TDM_REG_14r, PGW_LR_TDM_REG_15r,
   8125         PGW_LR_TDM_REG_16r,  PGW_LR_TDM_REG_17r,
   8126         PGW_LR_TDM_REG_18r,  PGW_LR_TDM_REG_19r,
   8127         PGW_LR_TDM_REG_20r,  PGW_LR_TDM_REG_21r,
   8128         PGW_LR_TDM_REG_22r,  PGW_LR_TDM_REG_23r,
   8129         PGW_LR_TDM_REG_24r,  PGW_LR_TDM_REG_25r,
   8130         PGW_LR_TDM_REG_26r, PGW_LR_TDM_REG_27r,
   8131         PGW_LR_TDM_REG_28r, PGW_LR_TDM_REG_29r,
   8132         PGW_LR_TDM_REG_30r, PGW_LR_TDM_REG_31r,
   8133         PGW_LR_TDM_REG_32r, PGW_LR_TDM_REG_33r,
   8134         PGW_LR_TDM_REG_34r, PGW_LR_TDM_REG_35r,
   8135         PGW_LR_TDM_REG_36r, PGW_LR_TDM_REG_37r,
   8136         PGW_LR_TDM_REG_38r, PGW_LR_TDM_REG_39r
   8137     },
   8138     {
   8139         PGW_LR_TDM2_REG_0r,  PGW_LR_TDM2_REG_1r,
   8140         PGW_LR_TDM2_REG_2r,  PGW_LR_TDM2_REG_3r,
   8141         PGW_LR_TDM2_REG_4r,  PGW_LR_TDM2_REG_5r,
   8142         PGW_LR_TDM2_REG_6r,  PGW_LR_TDM2_REG_7r,
   8143         PGW_LR_TDM2_REG_8r,  PGW_LR_TDM2_REG_9r,
   8144         PGW_LR_TDM2_REG_10r, PGW_LR_TDM2_REG_11r,
   8145         PGW_LR_TDM2_REG_12r, PGW_LR_TDM2_REG_13r,
   8146         PGW_LR_TDM2_REG_14r, PGW_LR_TDM2_REG_15r,
   8147         PGW_LR_TDM2_REG_16r,  PGW_LR_TDM2_REG_17r,
   8148         PGW_LR_TDM2_REG_18r,  PGW_LR_TDM2_REG_19r,
   8149         PGW_LR_TDM2_REG_20r,  PGW_LR_TDM2_REG_21r,
   8150         PGW_LR_TDM2_REG_22r,  PGW_LR_TDM2_REG_23r,
   8151         PGW_LR_TDM2_REG_24r,  PGW_LR_TDM2_REG_25r,
   8152         PGW_LR_TDM2_REG_26r, PGW_LR_TDM2_REG_27r,
   8153         PGW_LR_TDM2_REG_28r, PGW_LR_TDM2_REG_29r,
   8154         PGW_LR_TDM2_REG_30r, PGW_LR_TDM2_REG_31r,
   8155         PGW_LR_TDM2_REG_32r, PGW_LR_TDM2_REG_33r,
   8156         PGW_LR_TDM2_REG_34r, PGW_LR_TDM2_REG_35r,
   8157         PGW_LR_TDM2_REG_36r, PGW_LR_TDM2_REG_37r,
   8158         PGW_LR_TDM2_REG_38r, PGW_LR_TDM2_REG_39r
   8159     }
   8160 };
   8161 
   8162 static const soc_field_t mn_pgw_tdm_fields[] = {
   8163     TDM_ENTRY0_PORT_IDf,  TDM_ENTRY1_PORT_IDf,
   8164     TDM_ENTRY2_PORT_IDf,  TDM_ENTRY3_PORT_IDf,
   8165     TDM_ENTRY4_PORT_IDf,  TDM_ENTRY5_PORT_IDf,
   8166     TDM_ENTRY6_PORT_IDf,  TDM_ENTRY7_PORT_IDf,
   8167     TDM_ENTRY8_PORT_IDf,  TDM_ENTRY9_PORT_IDf,
   8168     TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf,
   8169     TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf,
   8170     TDM_ENTRY14_PORT_IDf, TDM_ENTRY15_PORT_IDf,
   8171     TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf,
   8172     TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf,
   8173     TDM_ENTRY20_PORT_IDf, TDM_ENTRY21_PORT_IDf,
   8174     TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf,
   8175     TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf,
   8176     TDM_ENTRY26_PORT_IDf, TDM_ENTRY27_PORT_IDf,
   8177     TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf,
   8178     TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf,
   8179     TDM_ENTRY32_PORT_IDf, TDM_ENTRY33_PORT_IDf,
   8180     TDM_ENTRY34_PORT_IDf, TDM_ENTRY35_PORT_IDf,
   8181     TDM_ENTRY36_PORT_IDf, TDM_ENTRY37_PORT_IDf,
   8182     TDM_ENTRY38_PORT_IDf, TDM_ENTRY39_PORT_IDf,
   8183     TDM_ENTRY40_PORT_IDf, TDM_ENTRY41_PORT_IDf,
   8184     TDM_ENTRY42_PORT_IDf, TDM_ENTRY43_PORT_IDf,
   8185     TDM_ENTRY44_PORT_IDf, TDM_ENTRY45_PORT_IDf,
   8186     TDM_ENTRY46_PORT_IDf, TDM_ENTRY47_PORT_IDf,
   8187     TDM_ENTRY48_PORT_IDf, TDM_ENTRY49_PORT_IDf,
   8188     TDM_ENTRY50_PORT_IDf, TDM_ENTRY51_PORT_IDf,
   8189     TDM_ENTRY52_PORT_IDf, TDM_ENTRY53_PORT_IDf,
   8190     TDM_ENTRY54_PORT_IDf, TDM_ENTRY55_PORT_IDf,
   8191     TDM_ENTRY56_PORT_IDf, TDM_ENTRY57_PORT_IDf,
   8192     TDM_ENTRY58_PORT_IDf, TDM_ENTRY59_PORT_IDf,
   8193     TDM_ENTRY60_PORT_IDf, TDM_ENTRY61_PORT_IDf,
   8194     TDM_ENTRY62_PORT_IDf, TDM_ENTRY63_PORT_IDf,
   8195     TDM_ENTRY64_PORT_IDf,  TDM_ENTRY65_PORT_IDf,
   8196     TDM_ENTRY66_PORT_IDf,  TDM_ENTRY67_PORT_IDf,
   8197     TDM_ENTRY68_PORT_IDf,  TDM_ENTRY69_PORT_IDf,
   8198     TDM_ENTRY70_PORT_IDf,  TDM_ENTRY71_PORT_IDf,
   8199     TDM_ENTRY72_PORT_IDf,  TDM_ENTRY73_PORT_IDf,
   8200     TDM_ENTRY74_PORT_IDf, TDM_ENTRY75_PORT_IDf,
   8201     TDM_ENTRY76_PORT_IDf, TDM_ENTRY77_PORT_IDf,
   8202     TDM_ENTRY78_PORT_IDf, TDM_ENTRY79_PORT_IDf,
   8203     TDM_ENTRY80_PORT_IDf, TDM_ENTRY81_PORT_IDf,
   8204     TDM_ENTRY82_PORT_IDf, TDM_ENTRY83_PORT_IDf,
   8205     TDM_ENTRY84_PORT_IDf, TDM_ENTRY85_PORT_IDf,
   8206     TDM_ENTRY86_PORT_IDf, TDM_ENTRY87_PORT_IDf,
   8207     TDM_ENTRY88_PORT_IDf, TDM_ENTRY89_PORT_IDf,
   8208     TDM_ENTRY90_PORT_IDf, TDM_ENTRY91_PORT_IDf,
   8209     TDM_ENTRY92_PORT_IDf, TDM_ENTRY93_PORT_IDf,
   8210     TDM_ENTRY94_PORT_IDf, TDM_ENTRY95_PORT_IDf,
   8211     TDM_ENTRY96_PORT_IDf, TDM_ENTRY97_PORT_IDf,
   8212     TDM_ENTRY98_PORT_IDf, TDM_ENTRY99_PORT_IDf,
   8213     TDM_ENTRY100_PORT_IDf, TDM_ENTRY101_PORT_IDf,
   8214     TDM_ENTRY102_PORT_IDf, TDM_ENTRY103_PORT_IDf,
   8215     TDM_ENTRY104_PORT_IDf, TDM_ENTRY105_PORT_IDf,
   8216     TDM_ENTRY106_PORT_IDf, TDM_ENTRY107_PORT_IDf,
   8217     TDM_ENTRY108_PORT_IDf, TDM_ENTRY109_PORT_IDf,
   8218     TDM_ENTRY110_PORT_IDf, TDM_ENTRY111_PORT_IDf,
   8219     TDM_ENTRY112_PORT_IDf, TDM_ENTRY113_PORT_IDf,
   8220     TDM_ENTRY114_PORT_IDf, TDM_ENTRY115_PORT_IDf,
   8221     TDM_ENTRY116_PORT_IDf, TDM_ENTRY117_PORT_IDf,
   8222     TDM_ENTRY118_PORT_IDf, TDM_ENTRY119_PORT_IDf,
   8223     TDM_ENTRY120_PORT_IDf, TDM_ENTRY121_PORT_IDf,
   8224     TDM_ENTRY122_PORT_IDf, TDM_ENTRY123_PORT_IDf,
   8225     TDM_ENTRY124_PORT_IDf, TDM_ENTRY125_PORT_IDf,
   8226     TDM_ENTRY126_PORT_IDf, TDM_ENTRY127_PORT_IDf,
   8227     TDM_ENTRY128_PORT_IDf, TDM_ENTRY129_PORT_IDf,
   8228     TDM_ENTRY130_PORT_IDf, TDM_ENTRY131_PORT_IDf,
   8229     TDM_ENTRY132_PORT_IDf, TDM_ENTRY133_PORT_IDf,
   8230     TDM_ENTRY134_PORT_IDf, TDM_ENTRY135_PORT_IDf,
   8231     TDM_ENTRY136_PORT_IDf, TDM_ENTRY137_PORT_IDf,
   8232     TDM_ENTRY138_PORT_IDf, TDM_ENTRY139_PORT_IDf,
   8233     TDM_ENTRY140_PORT_IDf, TDM_ENTRY141_PORT_IDf,
   8234     TDM_ENTRY142_PORT_IDf, TDM_ENTRY143_PORT_IDf,
   8235     TDM_ENTRY144_PORT_IDf, TDM_ENTRY145_PORT_IDf,
   8236     TDM_ENTRY146_PORT_IDf, TDM_ENTRY147_PORT_IDf,
   8237     TDM_ENTRY148_PORT_IDf, TDM_ENTRY149_PORT_IDf,
   8238     TDM_ENTRY150_PORT_IDf, TDM_ENTRY151_PORT_IDf,
   8239     TDM_ENTRY152_PORT_IDf, TDM_ENTRY153_PORT_IDf,
   8240     TDM_ENTRY154_PORT_IDf, TDM_ENTRY155_PORT_IDf,
   8241     TDM_ENTRY156_PORT_IDf, TDM_ENTRY157_PORT_IDf,
   8242     TDM_ENTRY158_PORT_IDf, TDM_ENTRY159_PORT_IDf,
   8243 };
   8244 
   8245 static const soc_reg_t mn_pgw_ovs_tdm_regs[] = {
   8246     PGW_OS_TDM_REG_0r, PGW_OS_TDM_REG_1r,
   8247     PGW_OS_TDM_REG_2r, PGW_OS_TDM_REG_3r,
   8248     PGW_OS_TDM_REG_4r, PGW_OS_TDM_REG_5r,
   8249     PGW_OS_TDM_REG_6r, PGW_OS_TDM_REG_7r,
   8250     PGW_OS_TDM_REG_8r, PGW_OS_TDM_REG_9r,
   8251     PGW_OS_TDM_REG_10r, PGW_OS_TDM_REG_11r
   8252 };
   8253 static const soc_reg_t mn_pgw_ovs_spacing_regs[] = {
   8254     PGW_OS_PORT_SPACING_REG_0r, PGW_OS_PORT_SPACING_REG_1r,
   8255     PGW_OS_PORT_SPACING_REG_2r, PGW_OS_PORT_SPACING_REG_3r,
   8256     PGW_OS_PORT_SPACING_REG_4r, PGW_OS_PORT_SPACING_REG_5r,
   8257     PGW_OS_PORT_SPACING_REG_6r, PGW_OS_PORT_SPACING_REG_7r,
   8258     PGW_OS_PORT_SPACING_REG_8r, PGW_OS_PORT_SPACING_REG_9r,
   8259     PGW_OS_PORT_SPACING_REG_10r, PGW_OS_PORT_SPACING_REG_11r
   8260 };
   8261 static const soc_field_t mn_pgw_spacing_fields[] = {
   8262     SLOT0f, SLOT1f, SLOT2f, SLOT3f, SLOT4f, SLOT5f, SLOT6f, SLOT7f,
   8263     SLOT8f, SLOT9f, SLOT10f, SLOT11f, SLOT12f, SLOT13f, SLOT14f, SLOT15f,
   8264     SLOT16f, SLOT17f, SLOT18f, SLOT19f, SLOT20f, SLOT21f, SLOT22f, SLOT23f,
   8265     SLOT24f, SLOT25f, SLOT26f, SLOT27f, SLOT28f, SLOT29f, SLOT30f, SLOT31f,
   8266     SLOT32f, SLOT33f, SLOT34f, SLOT35f, SLOT36f, SLOT37f, SLOT38f, SLOT39f,
   8267     SLOT40f, SLOT41f, SLOT42f, SLOT43f, SLOT44f, SLOT45f, SLOT46f, SLOT47f
   8268 };
   8269 #define MONTEREY_PGW_TDM_HSP_SLOTS 9
   8270 static const soc_reg_t pgw_hsp_config_regs[MONTEREY_PGW_TDM_HSP_SLOTS] = {
   8271     PGW_HSP_CONFIG_0r, PGW_HSP_CONFIG_1r, PGW_HSP_CONFIG_2r, 
   8272     PGW_HSP_CONFIG_3r, PGW_HSP_CONFIG_4r, PGW_HSP_CONFIG_5r,
   8273     PGW_HSP_CONFIG_6r, PGW_HSP_CONFIG_7r, PGW_HSP_CONFIG_8r, 
   8274 };
   8275 
   8276 static const soc_reg_t pgw_hsp_config_fields[MONTEREY_PGW_TDM_HSP_SLOTS] = {
   8277     PHY_PORT_NO_0f, PHY_PORT_NO_1f, PHY_PORT_NO_2f,
   8278     PHY_PORT_NO_3f, PHY_PORT_NO_4f, PHY_PORT_NO_5f,
   8279     PHY_PORT_NO_6f, PHY_PORT_NO_7f, PHY_PORT_NO_8f, 
   8280 };
   8281 
   8282 static const soc_reg_t mn_tdm_pgw_ctrl = PGW_TDM_CONTROLr;
   8283 static const soc_reg_t mn_tdm_mmu_ctrl = ES_PIPE0_TDM_CONFIGr;
   8284 static const soc_reg_t mmu_ovs_group_regs[MONTEREY_MMU_OVS_GROUP_COUNT] = {
   8285     ES_PIPE0_OVR_SUB_GRP0_TBLr, ES_PIPE0_OVR_SUB_GRP1_TBLr,
   8286     ES_PIPE0_OVR_SUB_GRP2_TBLr, ES_PIPE0_OVR_SUB_GRP3_TBLr,
   8287     ES_PIPE0_OVR_SUB_GRP4_TBLr, ES_PIPE0_OVR_SUB_GRP5_TBLr,
   8288     ES_PIPE0_OVR_SUB_GRP6_TBLr, ES_PIPE0_OVR_SUB_GRP7_TBLr
   8289 };
   8290 
   8291 static const soc_reg_t mmu_ovs_group_wt_regs[8] = {
   8292     ES_PIPE0_OVR_SUB_GRP_WT0r, ES_PIPE0_OVR_SUB_GRP_WT1r,
   8293     ES_PIPE0_OVR_SUB_GRP_WT2r, ES_PIPE0_OVR_SUB_GRP_WT3r,
   8294     ES_PIPE0_OVR_SUB_GRP_WT4r, ES_PIPE0_OVR_SUB_GRP_WT5r,
   8295     ES_PIPE0_OVR_SUB_GRP_WT6r, ES_PIPE0_OVR_SUB_GRP_WT7r
   8296 };
   8297 
   8298 
   8299 
   8300 #define MN_TDM_WT_GRP_SPG_GET(unit, _wtg)     ((MN_MISC(unit)->tdm_wtg_used[_wtg] & 0xff))
   8301 #define MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg)  ((MN_MISC(unit)->tdm_wtg_used[_wtg] >> 8) & 0xff)
   8302 
   8303 #define MONTEREY_TDM_WT_GRP_SPEED_GET(unit, _wtg)   ((MN_TDM_WT_GRP_SPG_GET(unit, _wtg) * 2500))
   8304 
   8305 
   8306 #define MONTEREY_TDM_WT_GRP_RESERVE(unit, _wtg, _spg)                    \
   8307     do {                                                               \
   8308         uint16 _tmp = (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) + 1);      \
   8309         MN_MISC(unit)->tdm_wtg_used[_wtg] = ((_spg) | (_tmp << 8));    \
   8310     } while (0)
   8311 
   8312 #define MONTEREY_TDM_WT_GRP_FREE(unit, _wtg)                             \
   8313     do {                                                               \
   8314         uint16 _tmp = (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) - 1);      \
   8315         if (MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) <= 1) {               \
   8316             soc_monterey_misc_info[unit]->tdm_wtg_used[_wtg] = 0;        \
   8317         } else {                                                       \
   8318             soc_monterey_misc_info[unit]->tdm_wtg_used[_wtg] =           \
   8319                 (MN_TDM_WT_GRP_SPG_GET(unit, _wtg) | (_tmp << 8));     \
   8320         }                                                              \
   8321     } while (0)
   8322 
   8323 #define MONTEREY_TDM_WT_GRP_LOG(unit)                                             \
   8324     do {                                                                        \
   8325         int _wtg;                                                               \
   8326         LOG_VERBOSE(BSL_LS_SOC_TDM,                                             \
   8327                     (BSL_META_U(unit,                                           \
   8328                                 "Weight groups and reference counts: \n\t")));  \
   8329         for (_wtg = 0; _wtg < 4; _wtg++)  {                                     \
   8330             LOG_VERBOSE(BSL_LS_SOC_TDM,                                         \
   8331                         (BSL_META_U(unit,                                       \
   8332                             "Grp = %d Refcnt = %d Speed Grp = %d Speed = %d;"), \
   8333                             _wtg, MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg),         \
   8334                             MN_TDM_WT_GRP_SPG_GET(unit, _wtg),                  \
   8335                             MONTEREY_TDM_WT_GRP_SPEED_GET(unit, _wtg)));          \
   8336         }                                                                       \
   8337         LOG_VERBOSE(BSL_LS_SOC_TDM, (BSL_META_U(unit, "\n")));                  \
   8338     } while (0)
   8339 
   8340 #define MONTEREY_TDM_WT_GRP_USABLE(unit, _wtg, _spg)   \
   8341     ((MN_TDM_WT_GRP_REFCNT_GET(unit, _wtg) == 0) || (MN_TDM_WT_GRP_SPG_GET(unit, _wtg) == _spg))
   8342 
   8343 #define MONTEREY_TDM_ACTIVE_CAL(unit) soc_monterey_misc_info[unit]->tdm_active_cal
   8344 #define MONTEREY_TDM_STRUCT_ACTIVE(unit) (!MONTEREY_TDM_ACTIVE_CAL(unit)) ? \
   8345             &(soc_monterey_misc_info[unit]->tdm0) : &(soc_monterey_misc_info[unit]->tdm1)
   8346 #define MONTEREY_TDM_STRUCT_BACKUP(unit) (MONTEREY_TDM_ACTIVE_CAL(unit)) ? \
   8347             &(soc_monterey_misc_info[unit]->tdm0) : &(soc_monterey_misc_info[unit]->tdm1)
   8348 
   8349 #define MONTEREY_TDM_PGW_LR_REG(cur_cal, slot) mn_pgw_lr_tdm_regs[cur_cal][slot/4]
   8350 
   8351 #define MONTEREY_TDM_PGW_OS_REG(slot) mn_pgw_ovs_tdm_regs[slot/4]
   8352 
   8353 #define MONTEREY_TDM_PGW_OS_SPACING_REG(slot) mn_pgw_ovs_spacing_regs[slot/4]
   8354 
   8355 #define MONTEREY_TDM_PGW_SLOT(slot)  mn_pgw_tdm_fields[slot]
   8356 #define MONTEREY_TDM_PGW_OS_SPACING_FIELD(slot)  mn_pgw_spacing_fields[slot]
   8357 
   8358 #define MONTEREY_TDM_MMU_TBL(cur_cal) \
   8359             (!cur_cal) ? ES_PIPE0_TDM_TABLE_0m : ES_PIPE0_TDM_TABLE_1m
   8360 
   8361 #if !defined(SOC_NO_NAMES)
   8362 #define MONTEREY_TDM_PGW_LOG(_u, _desc, _r, _f, _v)            \
   8363             LOG_INFO(BSL_LS_SOC_COMMON,                      \
   8364                         (BSL_META_U(_u,                      \
   8365                                     _desc ": %s.%s = %d\n"), \
   8366                                     SOC_REG_NAME(_u, _r),    \
   8367                                     soc_fieldnames[_f], _v))
   8368 #else
   8369 #define MONTEREY_TDM_PGW_LOG(_u, _desc, _r, _f, _v) \
   8370             LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(_u, _desc ": = %d\n"), _v))
   8371 #endif
   8372 
   8373 STATIC int
   8374 soc_monterey_tdm_calc(int unit, soc_monterey_tdm_t *monterey_tdm)
   8375 {
   8376     int rv, pgw, group, index;
   8377     soc_info_t *si = &SOC_INFO(unit);
   8378     tdm_soc_t monterey_chip_pkg;
   8379     tdm_mod_t *monterey_tdm_pkg;
   8380     int tdm_freq = 0, io_bw ;
   8381     uint16      dev_id;
   8382     uint8       rev_id;
   8383     int         is_macsec = 0;
   8384     sal_memset(&monterey_chip_pkg, 0, sizeof(tdm_soc_t));
   8385 
   8386     monterey_chip_pkg.unit = unit;
   8387     monterey_chip_pkg.num_ext_ports = MN_NUM_EXT_PORTS;
   8388     monterey_chip_pkg.state = sal_alloc((monterey_chip_pkg.num_ext_ports)*sizeof(int *), "port state list");
   8389     monterey_chip_pkg.speed = sal_alloc((monterey_chip_pkg.num_ext_ports)*sizeof(int *), "port speed list");
   8390 
   8391     for (index = 1; index < monterey_chip_pkg.num_ext_ports; index++) {
   8392         monterey_chip_pkg.state[index] = monterey_tdm->port_state[index];
   8393     }
   8394     monterey_chip_pkg.state[0] = 1;  /* enable cpu port */
   8395     monterey_chip_pkg.state[65] = 1; /* enable loopback port */
   8396     monterey_chip_pkg.state[66] = 1; /* enable MACSEC port */
   8397 
   8398     for (index = 0; index < monterey_chip_pkg.num_ext_ports; index++) {
   8399         monterey_chip_pkg.speed[index] = monterey_tdm->speed[index];
   8400     }
   8401     if (soc_property_get(unit, "tdm_check_disable", 0)) {
   8402         monterey_chip_pkg.soc_vars.mn.tdm_chk_en = 1;
   8403     } else {
   8404         monterey_chip_pkg.soc_vars.mn.tdm_chk_en = 0;
   8405     }
   8406 
   8407     /*
   8408      * Map detected core clk frequency to TDM algorithm internal code
   8409      * value.
   8410      */
   8411     tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,0);
   8412     if ( tdm_freq) {   
   8413          monterey_chip_pkg.clk_freq =tdm_freq;
   8414     } else {
   8415          monterey_chip_pkg.clk_freq = si->frequency;
   8416     }
   8417     if ( !tdm_freq) {   
   8418          soc_cm_get_id(unit, &dev_id, &rev_id);
   8419          if (dev_id == BCM56675_DEVICE_ID) { 
   8420              monterey_chip_pkg.soc_vars.mn.sku_core_bw = si->bandwidth/1000;
   8421          } else {
   8422              monterey_chip_pkg.soc_vars.mn.sku_core_bw = si->io_bandwidth/1000;
   8423          }
   8424     } else { 
   8425          monterey_chip_pkg.soc_vars.mn.sku_core_bw = 0;
   8426    }
   8427    if (soc_feature(unit, soc_feature_xflow_macsec)) { 
   8428        monterey_chip_pkg.soc_vars.mn.is_macsec = 1;
   8429        if (dev_id == BCM56675_DEVICE_ID) { 
   8430            monterey_chip_pkg.soc_vars.mn.sku_core_bw -= 40;
   8431        }
   8432    } 
   8433     
   8434     monterey_tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&monterey_chip_pkg));
   8435 
   8436     if (!monterey_tdm_pkg) {
   8437         LOG_CLI((BSL_META_U(unit,
   8438             "Unable to configure TDM, please contact your "
   8439             "Field Applications Engineer or Sales Manager for "
   8440             "additional assistance.\n")));
   8441         return SOC_E_FAIL;
   8442     }
   8443     monterey_tdm->pgw0len =
   8444                monterey_tdm_pkg->_chip_data.soc_pkg.soc_vars.mn.pgw0_len;
   8445     monterey_tdm->pgw1len =
   8446                monterey_tdm_pkg->_chip_data.soc_pkg.soc_vars.mn.pgw1_len;
   8447     /*  PGW0 LR/OS Calendars */
   8448     sal_memcpy(monterey_tdm->pgw_tdm[0],
   8449                monterey_tdm_pkg->_chip_data.cal_0.cal_main,
   8450                sizeof(int)*MONTEREY_PGW_TDM_LENGTH);
   8451     sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[0],
   8452                monterey_tdm_pkg->_chip_data.cal_0.cal_grp[0],
   8453                sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE);
   8454     sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[0],
   8455                monterey_tdm_pkg->_chip_data.cal_0.cal_grp[1],
   8456                sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE);
   8457 
   8458     /*  PGW1 LR/OS Calendars */
   8459     sal_memcpy(monterey_tdm->pgw_tdm[1],
   8460                monterey_tdm_pkg->_chip_data.cal_1.cal_main,
   8461                sizeof(int)*MONTEREY_PGW_TDM_LENGTH);
   8462     sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[1],
   8463                monterey_tdm_pkg->_chip_data.cal_1.cal_grp[0],
   8464                sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE);
   8465     sal_memcpy(monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[1],
   8466                monterey_tdm_pkg->_chip_data.cal_1.cal_grp[1],
   8467                sizeof(int)*MONTEREY_PGW_TDM_OVS_SIZE);
   8468 
   8469     sal_memcpy(monterey_tdm->mmu_tdm,
   8470                monterey_tdm_pkg->_chip_data.cal_2.cal_main,
   8471                sizeof(int)*MONTEREY_MMU_TDM_LENGTH);
   8472 
   8473     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[0],
   8474                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[0],
   8475                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8476     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[1],
   8477                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[1],
   8478                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8479     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[2],
   8480                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[2],
   8481                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8482     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[3],
   8483                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[3],
   8484                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8485     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[4],
   8486                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[4],
   8487                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8488     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[5],
   8489                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[5],
   8490                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8491     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[6],
   8492                monterey_tdm_pkg->_chip_data.cal_2.cal_grp[6],
   8493                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8494     sal_memcpy(monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[7],
   8495               monterey_tdm_pkg->_chip_data.cal_2.cal_grp[7],
   8496                sizeof(int)*MONTEREY_MMU_OVS_GROUP_TDM_LENGTH);
   8497 
   8498     sal_free(monterey_chip_pkg.state);
   8499     sal_free(monterey_chip_pkg.speed);
   8500 
   8501     monterey_tdm_pkg->_chip_exec[TDM_CHIP_EXEC__FREE](monterey_tdm_pkg);
   8502     sal_free(monterey_tdm_pkg); 
   8503     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   8504         for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) {
   8505             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_tdm:"), pgw));
   8506             for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) {
   8507                 if (index % 16 == 0) {
   8508                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8509                 }
   8510                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8511                            monterey_tdm->pgw_tdm[pgw][index]));
   8512             }
   8513             LOG_CLI((BSL_META_U(unit, "\n")));
   8514             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_tdm:"), pgw));
   8515             for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) {
   8516                 if (index % 16 == 0) {
   8517                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8518                 }
   8519                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8520                            monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][index]));
   8521             }
   8522             LOG_CLI((BSL_META_U(unit, "\n")));
   8523             LOG_CLI((BSL_META_U(unit, "PGW_CL%d pgw_ovs_spacing:"), pgw));
   8524             for (index = 0; index < MONTEREY_PGW_TDM_LENGTH; index++) {
   8525                 if (index % 16 == 0) {
   8526                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8527                 }
   8528                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8529                              monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][index]));
   8530             }
   8531             LOG_CLI((BSL_META_U(unit, "\n")));
   8532         }
   8533         LOG_CLI((BSL_META_U(unit, "mmu_tdm:")));
   8534         for (index = 0; index < MONTEREY_MMU_TDM_LENGTH; index++) {
   8535             if (index % 16 == 0) {
   8536                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   8537             }
   8538             LOG_CLI((BSL_META_U(unit, " %3d"),
   8539                        monterey_tdm->mmu_tdm[index]));
   8540         }
   8541         LOG_CLI((BSL_META_U(unit, "\n")));
   8542         for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
   8543             LOG_CLI((BSL_META_U(unit, "group %d ovs_group_tdm"), group));
   8544             for (index = 0; index < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH;
   8545                  index++) {
   8546                 if (index % 16 == 0) {
   8547                     LOG_CLI((BSL_META_U(unit, "\n    ")));
   8548                 }
   8549                 LOG_CLI((BSL_META_U(unit, " %3d"),
   8550                            monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][index]));
   8551             }
   8552             LOG_CLI((BSL_META_U(unit, "\n")));
   8553         }
   8554     }
   8555 
   8556     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   8557         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), monterey_tdm->tdm_bw));
   8558         LOG_CLI((BSL_META_U(unit, "ovs state: %d\n"),
   8559                    monterey_tdm->is_oversub));
   8560     }
   8561     if (!tdm_freq) {
   8562         tdm_freq = si->frequency;
   8563         if (dev_id == BCM56675_DEVICE_ID) {
   8564             io_bw = si->bandwidth/1000;
   8565             if (soc_feature(unit, soc_feature_xflow_macsec)) {
   8566                 io_bw -= 40 ;
   8567                 is_macsec = 1; 
   8568             }  
   8569         } else {  
   8570              io_bw = si->io_bandwidth/1000;
   8571         } 
   8572     } else {
   8573         io_bw = 0;
   8574 
   8575     } 
   8576 
   8577     rv = tdm_mn_set_iarb_tdm(tdm_freq,
   8578                             monterey_tdm->is_oversub,
   8579                             &monterey_tdm->iarb_tdm_wrap_ptr,
   8580                             monterey_tdm->iarb_tdm,io_bw,is_macsec);
   8581 
   8582     if (rv == 0) {
   8583         LOG_CLI((BSL_META_U(unit,
   8584                    "Unable to configure IARB TDM, please contact your "
   8585                    "Field Applications Engineer or Sales Manager for "
   8586                    "additional assistance.\n")));
   8587         return SOC_E_FAIL;
   8588     }
   8589 
   8590     if ((LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO))) {
   8591         LOG_CLI((BSL_META_U(unit,
   8592                    "iarb_tdm: (wrap_ptr %d)"),
   8593                    monterey_tdm->iarb_tdm_wrap_ptr));
   8594         for (index = 0; index < MONTEREY_IARB_TDM_LENGTH; index++) {
   8595             if (index > monterey_tdm->iarb_tdm_wrap_ptr) {
   8596                 break;
   8597             }
   8598             if (index % 16 == 0) {
   8599                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   8600             }
   8601             LOG_CLI((BSL_META_U(unit, " %3d"),
   8602                        monterey_tdm->iarb_tdm[index]));
   8603         }
   8604         LOG_CLI((BSL_META_U(unit, "\n")));
   8605     }
   8606 
   8607     return SOC_E_NONE;
   8608 }
   8609 
   8610 #define MONTEREY_PGW0_TDM_WRAP_PTR  0x8b
   8611 #define MONTEREY_PGW1_TDM_WRAP_PTR  0x97
   8612 
   8613 STATIC int 
   8614 _soc_monterey_tdm_min_spacing_init(int unit) 
   8615 {
   8616     int phy_port,mmu_port  ;
   8617     int port,profile_x;     
   8618     soc_info_t *si;
   8619     uint32 rval;
   8620     si = &SOC_INFO(unit);
   8621    
   8622     PBMP_PORT_ITER(unit, port) {
   8623         phy_port = si->port_l2p_mapping[port];
   8624          if (phy_port == -1 ) {
   8625                  continue;
   8626          }
   8627          mmu_port = si->port_p2m_mapping[phy_port];
   8628          if (mmu_port == -1) {
   8629                  continue;
   8630          }
   8631          if (mmu_port < 16 ) { 
   8632              if (si->port_speed_max[port] < 50000) { 
   8633                  SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ES_PIPE0_MIN_SPACINGr,
   8634                                         REG_PORT_ANY, 0, &rval));
   8635                  profile_x = soc_reg_field_get(unit, ES_PIPE0_MIN_SPACINGr, rval, PROFILEf );
   8636                  profile_x = (profile_x | (1 << mmu_port)) ;  
   8637                  soc_reg_field_set(unit, ES_PIPE0_MIN_SPACINGr, &rval, PROFILEf, profile_x);
   8638                  SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ES_PIPE0_MIN_SPACINGr,
   8639                                                       REG_PORT_ANY, 0, rval));
   8640 
   8641 
   8642              } 
   8643 
   8644          }
   8645     } 
   8646 
   8647     return SOC_E_NONE;
   8648 }
   8649 
   8650 STATIC int
   8651 soc_monterey_tdm_update(int unit, int init_time, int cur_cal,
   8652                       soc_monterey_tdm_t *monterey_tdm)
   8653 {
   8654     int ix, rv;
   8655     int count, slot;
   8656     int pgw, pgw_inst, length;
   8657     int pgw_hsp_config_index[2] = {0, 0};    /* for each pgw */
   8658     int mmu_idle_port_ix = 0;
   8659     int mmu_idle_ports[] = {76, 78, 79, 80}; /* IDLE MMU ports in Apache */
   8660 
   8661     soc_port_t port, phy_port, mmu_port;
   8662     soc_port_t pgw_hsp_ports[2][MONTEREY_TSCS_PER_PGW] = {{0}, {0}};
   8663 
   8664     soc_mem_t mem;
   8665     soc_reg_t reg, hsp_reg;
   8666     soc_field_t field, cal_end_f, cal_end_single_f, lr_tdm_wrap_f, hsp_fields[2];
   8667     es_pipe0_tdm_table_0_entry_t entry;
   8668 
   8669     uint32 rval, hsp_values[2];
   8670     uint64 rval64, ctrl_rval64;
   8671 
   8672     soc_info_t *si;
   8673 
   8674     int  group, weight, wt_group;
   8675     int speed_class, speed_group ,speed = 0 ;
   8676     uint32 wt_group_select = 0;
   8677     uint32 same_spacing = 0;
   8678     uint32 speed_spacing = 0;
   8679     int tdm_freq = 0;
   8680 
   8681     si = &SOC_INFO(unit);
   8682     /* Configure PGW TDM for MONTEREY */
   8683     for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV; pgw++) {
   8684 
   8685         /* coverity[negative_returns : FALSE] */
   8686         if (!SOC_INFO(unit).block_valid[PGW_CL_BLOCK(unit, pgw)]) {
   8687             continue;
   8688         }
   8689 
   8690         pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK;
   8691 
   8692         rv = soc_reg_get(unit, mn_tdm_pgw_ctrl, pgw_inst, 0, &ctrl_rval64);
   8693         SOC_IF_ERROR_RETURN(rv);
   8694 
   8695         /* Configure PGW line rate ports TDM */
   8696         count = 0;
   8697         COMPILER_64_ZERO(rval64);
   8698 
   8699         for (slot= 0; slot < MONTEREY_PGW_TDM_LENGTH; slot++) {
   8700 
   8701             reg = MONTEREY_TDM_PGW_LR_REG(cur_cal, slot);
   8702             field = MONTEREY_TDM_PGW_SLOT(slot);
   8703 
   8704             phy_port = monterey_tdm->pgw_tdm[pgw][slot];
   8705 
   8706             if (phy_port == NUM_EXT_PORTS) {
   8707                 phy_port = 0xff;
   8708             } else {
   8709                 if (phy_port == OVS_TOKEN) {
   8710                     phy_port = 0x44;
   8711                 }  
   8712             }
   8713 
   8714 
   8715             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8716 
   8717             MONTEREY_TDM_PGW_LOG(unit, "PGW LR TDM config", reg, field, phy_port);
   8718 
   8719             if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) {
   8720 
   8721                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8722                 COMPILER_64_ZERO(rval64);
   8723             }
   8724         }
   8725         tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,0); 
   8726         switch (tdm_freq) { 
   8727 
   8728                case 815: 
   8729                          if ( pgw == 0 ) { 
   8730                              count =0x8b;
   8731                          } else { 
   8732                              count = 0x97;
   8733                          }  
   8734                          break;  
   8735                case 816: 
   8736                          if ( pgw == 0 ) { 
   8737                              count =0x83;
   8738                          } else { 
   8739                              count = 0x87;
   8740                          }   
   8741                          break;  
   8742                case 817: 
   8743                          if ( pgw == 0 ) { 
   8744                              count =0x8b;
   8745                          } else { 
   8746                              count = 0x97;
   8747                          }   
   8748                          break;  
   8749 
   8750                case 818 : 
   8751                          count = 0x9f;
   8752                          break;  
   8753                case 819 : 
   8754                          count =0x7f;
   8755                          break;  
   8756                case 820 : 
   8757                              count =0x97;
   8758                          break;  
   8759                case 666: 
   8760                          if ( pgw == 0 ) { 
   8761                              count =0x4F;
   8762                          } else { 
   8763                              count = 0x2B;
   8764                          }  
   8765                          break;  
   8766                case 667: 
   8767                          if ( pgw == 0 ) { 
   8768                              count =0x37;
   8769                          } else { 
   8770                              count = 0x4F;
   8771                          }  
   8772                          break;  
   8773                case 550 : 
   8774                          if ( pgw == 0 ) { 
   8775                              count =0x54;
   8776                          } else { 
   8777                              count = 0x50;
   8778                          }   
   8779                          break;  
   8780                case 861 : 
   8781                          count =0x2f;
   8782                          break;  
   8783                case 862 : 
   8784                          count =0x2f;
   8785                          break;  
   8786                default: 
   8787                          if ( pgw == 0 ) { 
   8788                              count =monterey_tdm->pgw0len - 1 ;
   8789                          } else { 
   8790                              count =monterey_tdm->pgw1len - 1;
   8791                          }
   8792                          break;  
   8793         } 
   8794         lr_tdm_wrap_f = (!cur_cal) ? LR_TDM_WRAP_PTRf : LR_TDM2_WRAP_PTRf;
   8795   
   8796         if (count > 0) {
   8797             soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8798                                   lr_tdm_wrap_f, count );
   8799         }
   8800         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8801                               LR_TDM_SELf, cur_cal);
   8802         /* Always set both LR_TDM_ENABLE and LR_TDM2_ENABLE.
   8803          * Even when switching, we need to make sure the the current
   8804          * calendar is active so that it services the slots until the
   8805          * end of the calendar when it actually switches to the new one.
   8806  */
   8807         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8808                               LR_TDM_ENABLEf, 1);
   8809         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8810                               LR_TDM2_ENABLEf, 1);
   8811 
   8812         /* Configure PGW oversubscription ports TDM */
   8813         count = 0;
   8814         COMPILER_64_ZERO(rval64);
   8815         for (slot= 0; slot < MONTEREY_PGW_TDM_OVS_SIZE; slot++) {
   8816 
   8817             reg = MONTEREY_TDM_PGW_OS_REG(slot);
   8818             field = MONTEREY_TDM_PGW_SLOT(slot);
   8819 
   8820             phy_port = monterey_tdm->ingress_ovs_tdm.pgw_ovs_tdm[pgw][slot];;
   8821             MONTEREY_TDM_PGW_LOG(unit, "PGW OS TDM config", reg, field, phy_port);
   8822 
   8823             if (phy_port == NUM_EXT_PORTS) {
   8824                 phy_port = 0xff;
   8825             } else {
   8826                 count++;
   8827             }
   8828 
   8829             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8830 
   8831             if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) {
   8832 
   8833                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8834                 COMPILER_64_ZERO(rval64);
   8835             }
   8836             if (phy_port == 0xff) {
   8837                 continue;
   8838             }
   8839             port = SOC_INFO(unit).port_p2l_mapping[phy_port];
   8840             if (SOC_INFO(unit).port_speed_max[port] >= 40000) {
   8841                 for (ix = 0; ix < pgw_hsp_config_index[pgw]; ix++) {
   8842                     if (pgw_hsp_ports[pgw][ix] == phy_port) {
   8843                         break;
   8844                     }
   8845                 }
   8846                 if (ix < pgw_hsp_config_index[pgw]) {
   8847                     continue;
   8848                 }
   8849                 pgw_hsp_ports[pgw][pgw_hsp_config_index[pgw]] = phy_port;
   8850                 hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]];
   8851                 hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]];
   8852                 hsp_values[0] = phy_port;
   8853                 hsp_fields[1] = ENTRIES_IN_CALf;
   8854                 speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(SOC_INFO(unit).port_speed_max[port]);
   8855                 hsp_values[1] = speed < 10000 ? 1 : ((speed + 5000) / 10000);
   8856 
   8857                 rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst,
   8858                                              2, hsp_fields, hsp_values);
   8859                 SOC_IF_ERROR_RETURN(rv);
   8860 
   8861                 pgw_hsp_config_index[pgw] += 1;
   8862             }
   8863         }
   8864 
   8865         /* Enable os_skip_cnt_arb_sel by default in Apache */
   8866         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8867                               OS_SKIP_CNT_ARB_SELf, TRUE);
   8868 
   8869         while (pgw_hsp_config_index[pgw] < MONTEREY_TSCS_PER_PGW) {
   8870             hsp_reg = pgw_hsp_config_regs[pgw_hsp_config_index[pgw]];
   8871             hsp_fields[0] = pgw_hsp_config_fields[pgw_hsp_config_index[pgw]];
   8872             hsp_values[0] = 0x0;
   8873             hsp_fields[1] = ENTRIES_IN_CALf;
   8874             hsp_values[1] = 0x0;
   8875 
   8876             rv = soc_reg_fields32_modify(unit, hsp_reg, pgw_inst,
   8877                                          2, hsp_fields, hsp_values);
   8878             SOC_IF_ERROR_RETURN(rv);
   8879             pgw_hsp_config_index[pgw] += 1;
   8880 
   8881         }
   8882 
   8883         /* OS_TDM_WRAP_PTR and OS_TDM_ENABLE programming */
   8884         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8885                               OS_TDM_WRAP_PTRf, (count - 1));
   8886         soc_reg64_field32_set(unit, mn_tdm_pgw_ctrl, &ctrl_rval64,
   8887                               OS_TDM_ENABLEf, count ? 1 : 0);
   8888 
   8889         /* Configure PGW oversubscription port spacing */
   8890         COMPILER_64_ZERO(rval64);
   8891         for (slot= 0; slot < MONTEREY_PGW_TDM_OVS_SIZE; slot++) {
   8892 
   8893             reg = MONTEREY_TDM_PGW_OS_SPACING_REG(slot);
   8894             field = MONTEREY_TDM_PGW_OS_SPACING_FIELD(slot);
   8895 
   8896             phy_port = monterey_tdm->ingress_ovs_tdm.pgw_ovs_spacing[pgw][slot];
   8897             MONTEREY_TDM_PGW_LOG(unit, "PGW OS Spacing config", reg, field, phy_port);
   8898 
   8899             soc_reg64_field32_set(unit, reg, &rval64, field, phy_port);
   8900 
   8901             if (((slot + 1) % MONTEREY_PGW_TDM_SLOTS_PER_REG) == 0) {
   8902                 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, pgw_inst, 0, rval64));
   8903                 COMPILER_64_ZERO(rval64);
   8904             }
   8905         }
   8906 
   8907         rv = soc_reg_set(unit, mn_tdm_pgw_ctrl, pgw_inst, 0, ctrl_rval64);
   8908         SOC_IF_ERROR_RETURN(rv);
   8909     }
   8910 
   8911 
   8912     /* Configure MMU TDM */
   8913     mem = MONTEREY_TDM_MMU_TBL(cur_cal);
   8914 
   8915     length = MONTEREY_MMU_TDM_LENGTH;
   8916     while ((monterey_tdm->mmu_tdm[length] == NUM_EXT_PORTS)) {
   8917         length--;
   8918     }
   8919 
   8920     rv = soc_reg32_get(unit, mn_tdm_mmu_ctrl, REG_PORT_ANY, 0, &rval);
   8921     SOC_IF_ERROR_RETURN(rv);
   8922 
   8923     sal_memset(&entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
   8924 
   8925     for (slot = 0; slot <= length; slot++) {
   8926         if (!(slot % 2)) { 
   8927             sal_memset(&entry, 0, soc_mem_entry_words
   8928                                         (unit, mem) * sizeof(uint32));
   8929         } 
   8930         phy_port = monterey_tdm->mmu_tdm[slot];
   8931 
   8932         /*
   8933          * TDM algo inserts CMIC, LB and ANC tokens for Auxillary
   8934          * bandwidth in each TDM. ANC token needs to be replaced with
   8935          * internal port 77 and CMIC & LB will be mapped to their mmu ports.
   8936          *
   8937          * Each TDM will also have a dedicated slot for guaranteed SBUS ops.
   8938          * While the ANC slots can be used for SBUS as well, there could be
   8939          * cases where the PRG (being of higher priority over SBUS) hogs SBUS
   8940          * operations from getting handled. MMU port 81 will be programmed for
   8941          * these tokens appearing in the algorithm.
   8942          *
   8943          * For unclaimed bandwidth (compared to max LR BW) from each config,
   8944          * TDM algo inserts IDLE tokens. The idle tokens needs to be replaced
   8945          * with internal mmu ports for Purge or SBUS operations. However, since
   8946          * Hardware flags 1in4 violation errors even with these internal mmu
   8947          * ports, we would iterate over all available internal ports (leaving out
   8948          * ANC port - 77, of course).
   8949  */
   8950 
   8951         if ((phy_port == SBUS_TOKEN)) {
   8952             mmu_port = 81; /* Dedicated token for guaranteed SBUS ops */
   8953         } else if (phy_port == AUX_TOKEN) {
   8954             mmu_port = 77; /* Dedicated ANC slot */ 
   8955         } else if(phy_port == IDL1_TOKEN) {
   8956             /* iter over all available internal ports to avoid 1:4 violation */
   8957             mmu_port = mmu_idle_ports[mmu_idle_port_ix];
   8958             mmu_idle_port_ix = (mmu_idle_port_ix + 1) % COUNTOF(mmu_idle_ports);
   8959         } else if (phy_port == OVS_TOKEN) {
   8960             mmu_port = 0x44; /* Oversub port */
   8961         } else if (phy_port >= NUM_EXT_PORTS) {
   8962             mmu_port = 0x7f; /* Invalid Port */
   8963         } else {
   8964             mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
   8965         }
   8966         field = (slot % 2) ? PORT_NUM_ODDf : PORT_NUM_EVENf;
   8967         soc_mem_field32_set(unit, mem, &entry, field, mmu_port);
   8968         /* two slots in each entry; length can be odd too */
   8969         if ((slot % 2) || (slot == length)) { 
   8970             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   8971                                               (slot / 2), &entry));
   8972         }
   8973     }
   8974 
   8975     cal_end_f = (cur_cal) ? CAL1_ENDf : CAL0_ENDf;
   8976     cal_end_single_f = (cur_cal) ? CAL1_END_SINGLEf : CAL0_END_SINGLEf;
   8977 
   8978     /*
   8979      * Examples:
   8980      *   1) cal length = 401; cal_end = 401/2 - 0 = 200, cal_end_single = 1
   8981      *   2) cal length = 402; cal_end = 402/2 - 1 = 200, cal_end_single = 0
   8982  */
   8983     soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, cal_end_f,
   8984                       (slot % 2) ? (slot / 2): ((slot / 2) - 1));
   8985     if (slot % 2) {
   8986         soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, cal_end_single_f, 1);
   8987     }
   8988     
   8989     soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, OPP_CPULB_ENf, 1);
   8990     soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, ENABLEf, 1);
   8991     soc_reg_field_set(unit, mn_tdm_mmu_ctrl, &rval, CURR_CALf, cur_cal);
   8992     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, mn_tdm_mmu_ctrl, REG_PORT_ANY, 0, rval));
   8993 
   8994 
   8995     rval = 0;
   8996     for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
   8997         speed_class = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group];
   8998         reg = mmu_ovs_group_regs[group];
   8999         for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
   9000 
   9001             phy_port = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot];
   9002             if (phy_port >= NUM_EXT_PORTS) {
   9003                 mmu_port = 0x7f;
   9004             } else {
   9005                 mmu_port = si->port_p2m_mapping[phy_port];
   9006                 if (speed_class == 0) {
   9007                     speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]];
   9008                 }
   9009             }
   9010             soc_reg_field_set(unit, reg, &rval, MMU_PORTf, (mmu_port & 0x7f));
   9011             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval));
   9012         }
   9013 
   9014          if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get(
   9015                         unit, &speed_class, &speed_group, &speed_spacing))) {
   9016             continue;
   9017         }
   9018         if (init_time) {
   9019 
   9020             for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
   9021                 if (MONTEREY_TDM_WT_GRP_USABLE(unit, wt_group, speed_group)) {
   9022                     MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
   9023                     break;
   9024                 }
   9025             }
   9026 
   9027             MONTEREY_TDM_WT_GRP_LOG(unit);
   9028 
   9029             monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
   9030             monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
   9031 
   9032         } else {
   9033             wt_group = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group];
   9034             speed_class = monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group];
   9035         }
   9036  
   9037         if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) {
   9038             return SOC_E_INTERNAL;
   9039         }
   9040 
   9041         /* Apache supports 4 oversub speeds only */
   9042         soc_reg_field_set(unit, ES_PIPE0_GRP_WT_SELECTr, &wt_group_select,
   9043                          mn_mmu_ovs_group_wt_select_fields[group], wt_group);
   9044         reg = ES_PIPE0_OVR_SUB_GRP_CFGr;
   9045         soc_reg_field_set(unit, reg, &same_spacing, SAME_SPACINGf, speed_spacing);
   9046         rv = soc_reg32_set(unit, reg, REG_PORT_ANY, group, same_spacing);
   9047         SOC_IF_ERROR_RETURN(rv);
   9048 
   9049     }
   9050 
   9051     for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
   9052 
   9053         speed_class = MONTEREY_TDM_WT_GRP_SPEED_GET(unit, wt_group);
   9054         if (speed_class == 0) {
   9055             weight = 0x0;
   9056         } else {
   9057             /* use 2500M as weight unit */
   9058             weight = (speed_class > 2500 ? speed_class : 2500) / 2500;
   9059         }
   9060         reg = mmu_ovs_group_wt_regs[wt_group];
   9061         rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval);
   9062         SOC_IF_ERROR_RETURN(rv);
   9063 
   9064         /* The proportional weights are already programmed  */
   9065         if (soc_reg_field_get(unit, reg, rval, WEIGHTf) == weight) {
   9066             continue;
   9067         }
   9068         soc_reg_field_set(unit, reg, &rval, WEIGHTf, (weight ));
   9069         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   9070     }
   9071 
   9072 
   9073     reg = ES_PIPE0_GRP_WT_SELECTr;
   9074     rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, wt_group_select);
   9075     SOC_IF_ERROR_RETURN(rv);
   9076 
   9077     SOC_IF_ERROR_RETURN(_soc_monterey_tdm_min_spacing_init(unit));
   9078   
   9079     return SOC_E_NONE;
   9080 }
   9081 
   9082 STATIC int soc_mn_port_resource_tdm_calculate(int unit, soc_monterey_tdm_t *tdm);
   9083 
   9084 
   9085 STATIC int
   9086 soc_monterey_tdm_reinit(int unit)
   9087 {
   9088     soc_reg_t reg;
   9089     int phy_port, mmu_port;
   9090     int slot, group, wt_group, speed_group, speed_class;
   9091     uint32 rval, wt_group_select, speed_spacing;
   9092 
   9093     soc_monterey_tdm_t *monterey_tdm;
   9094     soc_info_t *si = &SOC_INFO(unit);
   9095 
   9096     reg = ES_PIPE0_TDM_CONFIGr;
   9097     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   9098     MONTEREY_TDM_ACTIVE_CAL(unit) = soc_reg_field_get(unit, reg, rval, CURR_CALf);
   9099 
   9100     monterey_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit);
   9101 
   9102     SOC_IF_ERROR_RETURN(soc_mn_port_resource_tdm_calculate(unit, monterey_tdm));
   9103 
   9104     reg = ES_PIPE0_GRP_WT_SELECTr;
   9105     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &wt_group_select));
   9106 
   9107 
   9108     for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
   9109         speed_class = 0;
   9110         speed_group = 0;
   9111         reg = mmu_ovs_group_regs[group];
   9112 
   9113         wt_group = soc_reg_field_get(unit, ES_PIPE0_GRP_WT_SELECTr, wt_group_select,
   9114                                      mn_mmu_ovs_group_wt_select_fields[group]);
   9115 
   9116         for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
   9117 
   9118             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, slot, &rval));
   9119             mmu_port = soc_reg_field_get(unit, reg, rval, MMU_PORTf);
   9120 
   9121             if (mmu_port == 0x7f) {
   9122                 phy_port = NUM_EXT_PORTS;
   9123             } else {
   9124                 phy_port = SOC_INFO(unit).port_m2p_mapping[mmu_port];
   9125                 if (speed_class == 0) {
   9126                     speed_class = si->port_speed_max[si->port_p2l_mapping[phy_port]];
   9127                     if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get(
   9128                                     unit, &speed_class, &speed_group, &speed_spacing))) {
   9129                         continue;
   9130                     }
   9131                     MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
   9132                 }
   9133             }
   9134             monterey_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port;
   9135         }
   9136         MONTEREY_TDM_WT_GRP_LOG(unit);
   9137 
   9138         monterey_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
   9139         monterey_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
   9140     }
   9141 
   9142     return SOC_E_NONE;
   9143 }
   9144 
   9145 STATIC int
   9146 soc_monterey_tdm_init(int unit)
   9147 {
   9148     soc_info_t *si;
   9149     soc_pbmp_t pbmp;
   9150 
   9151     int rv, index, cur_cal;
   9152     int slot, port, phy_port, mmu_port;
   9153     soc_monterey_tdm_t *monterey_tdm;
   9154 
   9155     uint32 entry[SOC_MAX_MEM_WORDS];
   9156     uint32 values[4];
   9157     soc_field_t fields[4];
   9158     soc_mem_t mem;
   9159     static const soc_mem_t iarb_tdm_mem = IARB_MAIN_TDMm;
   9160 
   9161     cur_cal = MONTEREY_TDM_ACTIVE_CAL(unit);
   9162     monterey_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit);
   9163 
   9164     sal_memset(monterey_tdm, 0, sizeof(soc_monterey_tdm_t));
   9165 
   9166     si = &SOC_INFO(unit);
   9167 
   9168     PBMP_PORT_ITER(unit, port) {
   9169         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
   9170             continue;
   9171         }
   9172         phy_port = si->port_l2p_mapping[port];
   9173 
   9174         monterey_tdm->speed[phy_port] = si->port_speed_max[port];
   9175         MONTEREY_TDM_SPEED_ADJUST(unit, port, monterey_tdm->speed[phy_port]);
   9176 
   9177         monterey_tdm->port_state[phy_port] =
   9178             IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE;
   9179 
   9180         /*
   9181          * Primary port will be setup as line-rate or oversub.
   9182          * Subsequent physical ports (sister-ports) will be either
   9183          * DISABLED or SUBPORT/COMBINED mode.
   9184          *
   9185          * TDM Algo expects lanes info based on speed.
   9186          */
   9187         if (soc_monterey_port_is_falcon(unit, phy_port)) { /*  Falcons  */
   9188             if (monterey_tdm->speed[phy_port] > 25000) {
   9189                 monterey_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
   9190             }
   9191             if (monterey_tdm->speed[phy_port] > 50000) {
   9192                 monterey_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
   9193                 monterey_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
   9194             }
   9195         } else {                                         /*  Eagles  */
   9196             if (monterey_tdm->speed[phy_port] > 10000) {
   9197                 monterey_tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
   9198             }
   9199             if (monterey_tdm->speed[phy_port] > 20000) {
   9200                 monterey_tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
   9201                 monterey_tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
   9202             }
   9203             if (monterey_tdm->speed[phy_port] > 40000) {
   9204                 monterey_tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT;
   9205                 monterey_tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT;
   9206                 monterey_tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT;
   9207                 monterey_tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT;
   9208                 monterey_tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT;
   9209                 monterey_tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT;
   9210             }
   9211         }
   9212 
   9213     }
   9214 
   9215     /* CPU, LB and MACSEC ports */
   9216     monterey_tdm->speed[0] = 1000;
   9217     monterey_tdm->speed[65] = 1000;
   9218     monterey_tdm->speed[66] = 20000;
   9219 
   9220     monterey_tdm->tdm_bw = si->bandwidth / 1000;
   9221 
   9222     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
   9223     SOC_PBMP_AND(pbmp, si->xpipe_pbm);
   9224 
   9225     /* tell tdm code the device is oversub if any ports is oversub */
   9226     monterey_tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp);
   9227     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
   9228 
   9229     for (slot = 0; slot <= MONTEREY_MMU_TDM_LENGTH; slot++) {
   9230         monterey_tdm->mmu_tdm[slot] = NUM_EXT_PORTS;
   9231     }
   9232 
   9233     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
   9234         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), monterey_tdm->tdm_bw));
   9235         LOG_CLI((BSL_META_U(unit, "port speed:")));
   9236         for (index = 0; index < NUM_EXT_PORTS; index++) {
   9237             if (index % 8 == 0) {
   9238                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   9239             }
   9240             LOG_CLI((BSL_META_U(unit, " %06d(%03d)"),
   9241                      monterey_tdm->speed[index], index));
   9242         }
   9243         LOG_CLI((BSL_META_U(unit, "\n")));
   9244         LOG_CLI((BSL_META_U(unit, "port state map:")));
   9245         for (index = 0; index < NUM_EXT_PORTS; index++) {
   9246             if (index % 8 == 0) {
   9247                 LOG_CLI((BSL_META_U(unit, "\n    ")));
   9248             }
   9249             if (index == 0 || index == (NUM_EXT_PORTS - 1)) {
   9250                 LOG_CLI((BSL_META_U(unit, " --------")));
   9251             } else {
   9252                 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"),
   9253                          monterey_tdm->port_state[index], index));
   9254             }
   9255         }
   9256         LOG_CLI((BSL_META_U(unit, "\n")));
   9257     }
   9258 
   9259 
   9260     SOC_IF_ERROR_RETURN(soc_monterey_tdm_calc(unit, monterey_tdm));
   9261 
   9262     SOC_IF_ERROR_RETURN(soc_monterey_tdm_update(unit, 1, cur_cal, monterey_tdm));
   9263 
   9264 
   9265     /* Configure IARB TDM */
   9266     mem = iarb_tdm_mem;
   9267     sal_memset(entry, 0, soc_mem_entry_words(unit, mem) * sizeof(uint32));
   9268     for (slot = 0; slot < MONTEREY_IARB_TDM_LENGTH; slot++) {
   9269         if (slot > monterey_tdm->iarb_tdm_wrap_ptr) {
   9270             break;
   9271         }
   9272 /* temp fix for tdm issue once new tdm is in place this check shold be removed*/
   9273      if ((monterey_tdm->iarb_tdm[slot] > 0x7 || monterey_tdm->iarb_tdm[slot] < 0) &&
   9274             slot == monterey_tdm->iarb_tdm_wrap_ptr) {  
   9275             monterey_tdm->iarb_tdm[slot] = 3;
   9276      } 
   9277         if (monterey_tdm->iarb_tdm[slot] > 0x7)  {
   9278             LOG_ERROR(BSL_LS_SOC_COMMON,
   9279                       (BSL_META_U(unit,
   9280                                   "Invalid IARB TDM slot(%d) = %d !!\n"),
   9281                                   slot, monterey_tdm->iarb_tdm[slot]));
   9282         }
   9283         soc_mem_field32_set(unit, mem, entry, TDM_SLOTf,
   9284                             monterey_tdm->iarb_tdm[slot]);
   9285         SOC_IF_ERROR_RETURN
   9286             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry));
   9287     }
   9288 
   9289     /* IARB_TDM_CONTROL */
   9290     fields[0] = TDM_WRAP_PTRf;
   9291     values[0] = monterey_tdm->iarb_tdm_wrap_ptr - 1;
   9292     fields[1] = DISABLEf;
   9293     values[1] = 0;
   9294     SOC_IF_ERROR_RETURN
   9295         (soc_reg_fields32_modify(unit, IARB_TDM_CONTROLr, REG_PORT_ANY, 2,
   9296                                  fields, values));
   9297 
   9298 
   9299     fields[0] = FIELD_Af;
   9300     values[0] = 1023;
   9301     fields[1] = FIELD_Bf;
   9302     values[1] = 9215;
   9303     fields[2] = FIELD_Cf;
   9304     values[2] = 16;
   9305     rv = soc_reg_fields32_modify(unit, EGR_FORCE_SAF_CONFIGr, REG_PORT_ANY, 3, fields, values);
   9306     SOC_IF_ERROR_RETURN(rv);
   9307 
   9308     fields[0] = FIELD_Af;
   9309     values[0] = 1;
   9310     fields[1] = DI_ACT_THRf;
   9311     values[1] = 20;
   9312     rv = soc_reg_fields32_modify(unit, ES_PIPE0_MMU_1DBG_Cr, REG_PORT_ANY, 2, fields, values);
   9313     SOC_IF_ERROR_RETURN(rv);
   9314 
   9315     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_DI_THRr, REG_PORT_ANY, OS_SLT_LMTf, 1000);
   9316     SOC_IF_ERROR_RETURN(rv);
   9317 
   9318     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_1r, REG_PORT_ANY, FIELD_Bf, 0);
   9319     SOC_IF_ERROR_RETURN(rv);
   9320     rv = soc_reg_field32_modify(unit, ES_PIPE0_MMU_2DBG_C_0r, REG_PORT_ANY,
   9321                                 FIELD_Af, (si->frequency * 200));
   9322     SOC_IF_ERROR_RETURN(rv);
   9323 
   9324 
   9325     /* values array for filling mmu_1dbg_a regs  */
   9326     values[0] = values[1] = values[2] = 0;
   9327 
   9328     PBMP_PORT_ITER(unit, port) {
   9329 
   9330         phy_port = si->port_l2p_mapping[port];
   9331         if (phy_port == -1 ) {
   9332             continue;
   9333         }
   9334         mmu_port = si->port_p2m_mapping[phy_port];
   9335         if (mmu_port == -1) {
   9336             continue;
   9337         }
   9338 
   9339         SOC_IF_ERROR_RETURN(soc_mn_mmu_delay_insertion_set(unit, port));
   9340 
   9341 
   9342     }
   9343     return SOC_E_NONE;
   9344 }
   9345 
   9346 STATIC int
   9347 _soc_monterey_hash_init(int unit)
   9348 {
   9349     soc_field_t fields[4];
   9350     uint32 values[4];
   9351 
   9352     /* L2 dedicated banks */
   9353     fields[0] = BANK0_HASH_OFFSETf;
   9354     values[0] = 0;  /* CRC32_LOWER */
   9355     fields[1] = BANK1_HASH_OFFSETf;
   9356     values[1] = 16; /* CRC32_UPPER */
   9357     SOC_IF_ERROR_RETURN
   9358         (soc_reg_fields32_modify(unit, L2_TABLE_HASH_CONTROLr, REG_PORT_ANY, 2,
   9359                                  fields, values));
   9360 
   9361     /* L3 dedicated banks */
   9362     fields[0] = BANK6_HASH_OFFSETf;
   9363     values[0] = 0;  /* CRC32_LOWER */
   9364     fields[1] = BANK7_HASH_OFFSETf;
   9365     values[1] = 12;  /* CRC32 >> 12 */
   9366     fields[2] = BANK8_HASH_OFFSETf;
   9367     values[2] = 24; /* CRC16_LOWER << 8 | CRC32 >> 24 */
   9368     fields[3] = BANK9_HASH_OFFSETf;
   9369     values[3] = 36; /* CRC16 >> 4 */
   9370     SOC_IF_ERROR_RETURN
   9371         (soc_reg_fields32_modify(unit, L3_TABLE_HASH_CONTROLr, REG_PORT_ANY, 4,
   9372                                  fields, values));
   9373 
   9374     return SOC_E_NONE;
   9375 }
   9376 
   9377 #define PORTS_PER_LED_CHAIN 64
   9378 
   9379 STATIC int
   9380 _soc_monterey_ledup_init(int unit)
   9381 {
   9382     uint32 rval = 0, ix;
   9383     uint8 remap_value[SOC_MAX_NUM_PORTS];
   9384     int phy_port;
   9385 
   9386     /* configure the LED scan delay cycles */
   9387     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval));
   9388     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 0xd);
   9389     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_INTRA_PORT_DELAYf, 4);
   9390     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval));
   9391 
   9392     rval =0;
   9393     /* Initialize LED Port remap registers */
   9394 
   9395     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval));
   9396     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval));
   9397     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval));
   9398     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval));
   9399     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval));
   9400     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval));
   9401     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval));
   9402     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval));
   9403     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval));
   9404     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r(unit, rval));
   9405     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r(unit, rval));
   9406     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r(unit, rval));
   9407     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r(unit, rval));
   9408     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r(unit, rval));
   9409     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r(unit, rval));
   9410 
   9411      for (ix = 0; ix < PORTS_PER_LED_CHAIN; ix++) {
   9412         /* Chain 0: Phy Ports 1-64
   9413          * LED HW Status arrives descending order to CMIC
   9414          * i.e Status for Port 64 comes first and for Port 1 last
   9415          */
   9416         phy_port = PORTS_PER_LED_CHAIN - ix;
   9417         remap_value[ix] = phy_port - 1   ;
   9418 
   9419     }
   9420 
   9421     /* Configure LED Port remap registers */
   9422     ix = 0;
   9423     rval = 0;
   9424     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_0f,  remap_value[ix++]); 
   9425     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_1f, remap_value[ix++] ); 
   9426     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_2f, remap_value[ix++]); 
   9427     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, &rval, REMAP_PORT_3f, remap_value[ix++]); 
   9428     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r(unit, rval));
   9429 
   9430     rval = 0;
   9431     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_4f, remap_value[ix++]); 
   9432     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_5f, remap_value[ix++]); 
   9433     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_6f, remap_value[ix++]);
   9434     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, &rval, REMAP_PORT_7f, remap_value[ix++]); 
   9435     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r(unit, rval));
   9436 
   9437     rval = 0;
   9438     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_8f,  remap_value[ix++]); 
   9439     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_9f,  remap_value[ix++]); 
   9440     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_10f, remap_value[ix++]); 
   9441     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, &rval, REMAP_PORT_11f, remap_value[ix++]); 
   9442     /* coverity[result_independent_of_operands] */
   9443     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r(unit, rval));
   9444 
   9445     rval = 0;
   9446     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_12f, remap_value[ix++]); 
   9447     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_13f, remap_value[ix++]); 
   9448     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_14f, remap_value[ix++]); 
   9449     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, &rval, REMAP_PORT_15f, remap_value[ix++]); 
   9450     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r(unit, rval));
   9451 
   9452     rval = 0;
   9453     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval,REMAP_PORT_16f,  remap_value[ix++]); 
   9454     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_17f, remap_value[ix++]); 
   9455     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_18f, remap_value[ix++]); 
   9456     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, &rval, REMAP_PORT_19f, remap_value[ix++]);
   9457     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r(unit, rval));
   9458 
   9459     rval = 0;
   9460     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_20f, remap_value[ix++]); 
   9461     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_21f, remap_value[ix++]);
   9462     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_22f, remap_value[ix++]);
   9463     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, &rval, REMAP_PORT_23f, remap_value[ix++]); 
   9464     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r(unit, rval));
   9465 
   9466     rval = 0;
   9467     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_24f, remap_value[ix++]); 
   9468     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_25f, remap_value[ix++]); 
   9469     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_26f, remap_value[ix++]); 
   9470     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, &rval, REMAP_PORT_27f, remap_value[ix++]); 
   9471     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r(unit, rval));
   9472 
   9473     rval = 0;
   9474     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_28f, remap_value[ix++]); 
   9475     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval,REMAP_PORT_29f,  remap_value[ix++]);
   9476     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_30f, remap_value[ix++]); 
   9477     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, &rval, REMAP_PORT_31f, remap_value[ix++]); 
   9478     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r(unit, rval));
   9479 
   9480     rval = 0;
   9481     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_32f, remap_value[ix++]); 
   9482     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_33f, remap_value[ix++]); 
   9483     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_34f, remap_value[ix++]);
   9484     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, &rval, REMAP_PORT_35f, remap_value[ix++]);
   9485     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r(unit, rval));
   9486 
   9487 
   9488 
   9489 
   9490     rval = 0;
   9491     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_36f, remap_value[ix++]);
   9492     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_37f, remap_value[ix++]); 
   9493     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_38f, remap_value[ix++]); 
   9494     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, &rval, REMAP_PORT_39f, remap_value[ix++]); 
   9495     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r(unit, rval));
   9496 
   9497     rval = 0;
   9498     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_40f, remap_value[ix++]); 
   9499     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_41f, remap_value[ix++]); 
   9500     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_42f, remap_value[ix++]); 
   9501     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, &rval, REMAP_PORT_43f, remap_value[ix++]); 
   9502     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r(unit, rval));
   9503 
   9504     rval = 0;
   9505     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_44f, remap_value[ix++]);
   9506     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_45f, remap_value[ix++]); 
   9507     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_46f, remap_value[ix++]); 
   9508     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, &rval, REMAP_PORT_47f, remap_value[ix++]); 
   9509     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r(unit, rval));
   9510 
   9511     rval = 0;
   9512     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_48f, remap_value[ix++]);
   9513     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_49f, remap_value[ix++]); 
   9514     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_50f, remap_value[ix++]); 
   9515     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, &rval, REMAP_PORT_51f, remap_value[ix++]); 
   9516     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r(unit, rval));
   9517 
   9518     rval = 0;
   9519     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_52f, remap_value[ix++]); 
   9520     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_53f, remap_value[ix++]); 
   9521     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_54f, remap_value[ix++]);
   9522     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, &rval, REMAP_PORT_55f, remap_value[ix++]);
   9523     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r(unit, rval));
   9524 
   9525     rval = 0;
   9526     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_56f, remap_value[ix++]); 
   9527     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_57f, remap_value[ix++]); 
   9528     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_58f, remap_value[ix++]); 
   9529     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, &rval, REMAP_PORT_59f, remap_value[ix++]); 
   9530     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r(unit, rval));
   9531 
   9532     rval = 0;
   9533     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_60f, remap_value[ix++]); 
   9534     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_61f, remap_value[ix++]); 
   9535     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_62f, remap_value[ix++]); 
   9536     soc_reg_field_set(unit, CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r, &rval, REMAP_PORT_63f, remap_value[ix++]); 
   9537     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r(unit, rval));
   9538 
   9539 
   9540 
   9541     /* initialize the UP0, UP1 data ram */
   9542     rval = 0;
   9543     for (ix = 0; ix < 256; ix++) {
   9544         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval));
   9545     }
   9546 
   9547     return SOC_E_NONE;
   9548 }
   9549 int
   9550 bcm_monterey_send_packetport(int unit , int port , int cos , int num )
   9551 {
   9552 
   9553 	int     j=0;
   9554 	int   pkt_size = 256 ;
   9555 	bcm_pkt_t         *pkt = NULL;
   9556 	char pkt_DA_SA[12] = {0x00,0x00,0x33,0x44,0x55,0x66,0x00,0x01,0x02,0x03,0x04,0x05};
   9557 	uint8 pkt_vlan_lengthtype[6] = {0x81,0x00,0x00,0x20,0x0,0x00};
   9558 	SOC_IF_ERROR_RETURN(bcm_pkt_alloc(unit, pkt_size, BCM_TX_CRC_REGEN, &pkt));
   9559 	sal_memset(pkt->pkt_data[0].data, 0xAA, pkt_size);
   9560 	sal_memcpy(pkt->pkt_data->data, pkt_DA_SA, 12);
   9561 	sal_memcpy(pkt->pkt_data->data+12, pkt_vlan_lengthtype, 6);
   9562 	SOC_PBMP_CLEAR(pkt->tx_pbmp); /* with ether mode, clear destination pbmp */
   9563 	SOC_PBMP_PORT_SET(pkt->tx_pbmp, port);
   9564 	SOC_PBMP_CLEAR(pkt->tx_upbmp); /* send all packets tagged */
   9565 	pkt->cos = cos ;
   9566 	for ( j =0 ; j < num ; j++ )  {
   9567        	     bcm_tx(unit, pkt, NULL);
   9568 	}
   9569 	return SOC_E_NONE;
   9570 
   9571 }
   9572 
   9573 
   9574 #if defined(SER_TR_TEST_SUPPORT)
   9575 soc_ser_test_functions_t ser_monterey_test_fun;
   9576 #endif
   9577 /*
   9578 STATIC int
   9579 _soc_monterey_egr_buf_reset(int unit, int port, int reset)
   9580 {
   9581     uint32 entry[SOC_MAX_MEM_WORDS];
   9582 
   9583     SOC_IF_ERROR_RETURN(
   9584         READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
   9585                                             port, entry));
   9586     soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
   9587                         entry, ENABLEf, reset);
   9588     SOC_IF_ERROR_RETURN(
   9589         WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
   9590                                              port, entry));
   9591 
   9592     return SOC_E_NONE;
   9593 }
   9594 */
   9595 STATIC int
   9596 _soc_portctrl_monterey_port_init(int unit)
   9597 {
   9598     soc_info_t *si;
   9599     int port;
   9600 
   9601     si = &SOC_INFO(unit);
   9602 
   9603 
   9604     /* Cut through settings for all ports */
   9605     PBMP_ALL_ITER(unit, port) {
   9606         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)  ) {
   9607             continue;
   9608         }
   9609         SOC_IF_ERROR_RETURN(soc_monterey_port_asf_set(unit, port, si->port_speed_max[port]));
   9610     }
   9611 
   9612     return SOC_E_NONE;
   9613 }
   9614 
   9615 
   9616 /*
   9617  * Function:
   9618  *      soc_monterey_idb_buf_reset
   9619  * Purpose:
   9620  *      Poll until Cell Assembly and OBM buffers are empty.
   9621  * Parameters:
   9622  *      unit    - (IN) Unit number.
   9623  *      port    - (IN) Logical SOC port number.
   9624  *      reset   - (IN) Reset.
   9625  * Returns:
   9626  *      SOC_E_XXX
   9627  */
   9628 int
   9629 soc_monterey_idb_buf_reset(int unit, soc_port_t port, int reset)
   9630 {
   9631     soc_info_t *si = &SOC_INFO(unit);
   9632     soc_reg_t reg;
   9633     soc_field_t field;
   9634     uint64 rval64;
   9635     int phy_port, port_index, xlp, pgw, obm, pgw_inst;
   9636     soc_timeout_t to;
   9637     int use_count, fifo_empty;
   9638     int wait_time = 250000;
   9639 
   9640     static const soc_reg_t pgw_obm_use_counter_regs[] = {
   9641         IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, IDB_OBM2_USAGEr,
   9642         IDB_OBM3_USAGEr, IDB_OBM4_USAGEr, IDB_OBM5_USAGEr,
   9643         IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, IDB_OBM8_USAGEr
   9644     };
   9645     static const soc_reg_t obm_ctrl_regs[] = {
   9646         IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, IDB_OBM2_CONTROLr,
   9647         IDB_OBM3_CONTROLr, IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr,
   9648         IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, IDB_OBM8_CONTROLr
   9649     };
   9650     static const soc_reg_t obm_ca_ctrl_regs[] = {
   9651         IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, IDB_OBM2_CA_CONTROLr,
   9652         IDB_OBM3_CA_CONTROLr, IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr,
   9653         IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, IDB_OBM8_CA_CONTROLr
   9654     };
   9655     static const soc_field_t port_reset_fields[] = {
   9656         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf
   9657     };
   9658 
   9659     if (SAL_BOOT_QUICKTURN) {
   9660         wait_time *= 20;
   9661         wait_time *= 3;
   9662     }
   9663     /* Get physical port PGW information */
   9664     phy_port = si->port_l2p_mapping[port];
   9665     pgw = si->port_group[port];
   9666     xlp = si->port_serdes[port];
   9667     port_index = (phy_port - 1) % 4;
   9668 
   9669     obm = xlp % MONTEREY_TSCS_PER_PGW;
   9670     pgw_inst = pgw | SOC_REG_ADDR_INSTANCE_MASK;
   9671 
   9672     /* Assume values returned above are valid */
   9673     reg = pgw_obm_use_counter_regs[obm];
   9674     field = TOTAL_COUNTf;
   9675 
   9676     if (reset && (!SAL_BOOT_BCMSIM)) {
   9677         /* Poll until Cell Assembly and OBM buffers are empty */
   9678         soc_timeout_init(&to, wait_time, 0);
   9679         for (;;) {
   9680             /* Get PGW use counter */
   9681             SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst, port_index, &rval64));
   9682             use_count = soc_reg64_field32_get(unit, reg, rval64, field);
   9683 
   9684             /* Get PGW fifo empty flag */
   9685             SOC_IF_ERROR_RETURN(READ_PGW_BOD_STATUSr(unit, port, &rval64));
   9686             fifo_empty = soc_reg64_field32_get(unit, PGW_BOD_STATUSr,
   9687                                                rval64, EXP_PGW_BOD_FIFO_EMPTYf);
   9688 
   9689             fifo_empty |= soc_reg64_field32_get(unit, PGW_BOD_STATUSr,
   9690                                                rval64, PREEMPT_PGW_BOD_FIFO_EMPTYf);
   9691             LOG_INFO(BSL_LS_SOC_PORT,
   9692                       (BSL_META_U(unit,
   9693                                   "PGW/OBM buffer reset : port %d, %s (log=%d phy=%d), "
   9694                                   "subport: %d tsc: %d obm:%d pgw: %d"
   9695                                   "(use_count: %d) "
   9696                                   "(pgw_bod_fifo_emty:%d)\n"),
   9697                        unit, SOC_PORT_NAME(unit, port), port, phy_port,
   9698                        port_index, xlp, obm, pgw,
   9699                        use_count, fifo_empty));
   9700 
   9701             if ((use_count == 0) && (fifo_empty == 1)) {
   9702                 break;
   9703             }
   9704 
   9705             if (soc_timeout_check(&to)) {
   9706                 LOG_ERROR(BSL_LS_SOC_PORT,
   9707                           (BSL_META_U(unit,
   9708                                       "PGW/OBM buffer reset timeout: port %d, %s, "
   9709                                       "timeout (use_count: %d) "
   9710                                       "(pgw_bod_fifo_emty:%d)\n"),
   9711                            unit, SOC_PORT_NAME(unit, port),
   9712                            use_count, fifo_empty));
   9713                 return SOC_E_INTERNAL;
   9714             }
   9715         }
   9716     }
   9717 
   9718     reg = obm_ctrl_regs[obm];
   9719     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst,
   9720                                                port_reset_fields[port_index], reset));
   9721 
   9722     reg = obm_ca_ctrl_regs[obm];
   9723     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, reg, pgw_inst,
   9724                                                port_reset_fields[port_index], reset));
   9725 
   9726     return SOC_E_NONE;
   9727 }
   9728 
   9729 STATIC int
   9730 _soc_monterey_pm_intr_init(int unit)
   9731 {
   9732     memset(&_monterey_pm_intr_functions, 0,
   9733            sizeof(_monterey_pm_intr_functions));
   9734     _monterey_pm_intr_functions._soc_port_macro_intr_f =
   9735         &soc_monterey_ser_error;
   9736     return SOC_E_NONE;
   9737 }
   9738 
   9739 
   9740 /*
   9741  * Function:
   9742  *      _soc_monterey_mmu_ep_credit_reset
   9743  * Purpose:
   9744  *      Initalize EP credits in MMU so EP is in charge
   9745  *      of distributing the correct number of credits.
   9746  * Parameters:
   9747  *      unit    - (IN) Unit number.
   9748  *      port    - (IN) Logical SOC port number.
   9749  * Returns:
   9750  *      SOC_E_XXX
   9751  */
   9752 STATIC int
   9753 _soc_monterey_mmu_ep_credit_reset(int unit, soc_port_t port)
   9754 {
   9755     soc_info_t *si = &SOC_INFO(unit);
   9756     int phy_port;
   9757     int mmu_port;
   9758     soc_reg_t reg;
   9759     soc_reg_t reg1;
   9760     uint32 rval;
   9761 
   9762     /* Get physical port */
   9763     phy_port = si->port_l2p_mapping[port];
   9764     if (phy_port == -1) {
   9765         return SOC_E_INTERNAL;
   9766     }
   9767 
   9768     /* Get MMU port */
   9769     mmu_port = si->port_p2m_mapping[phy_port];
   9770     if (mmu_port == -1) {
   9771         return SOC_E_INTERNAL;
   9772     }
   9773     reg = ES_PIPE0_MMU_PORT_CREDIT_PREEMPTr;
   9774     reg1 = ES_PIPE0_MMU_PORT_CREDIT_EXPRESSr;
   9775 
   9776     SOC_IF_ERROR_RETURN
   9777         (soc_reg32_get(unit, reg1, REG_PORT_ANY, mmu_port, &rval));
   9778     soc_reg_field_set(unit, reg1, &rval, INIT_CREDITf, 0);
   9779     SOC_IF_ERROR_RETURN
   9780         (soc_reg32_set(unit, reg1, REG_PORT_ANY, mmu_port, rval));
   9781     SOC_IF_ERROR_RETURN
   9782         (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval));
   9783     soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, 0);
   9784     SOC_IF_ERROR_RETURN
   9785         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
   9786     return SOC_E_NONE;
   9787 }
   9788 
   9789 
   9790 STATIC int
   9791 _soc_monterey_port_credit_size_get(int unit, soc_port_t port, int *ep_credit_size)
   9792 {
   9793     soc_info_t *si;
   9794     si = &SOC_INFO(unit);
   9795 
   9796     /*
   9797      * For MACSEC, CPU and LB port port_speed_max is -1.
   9798      */
   9799     if (si->port_speed_max[port] == -1) {
   9800         if (IS_MACSEC_PORT(unit, port) ) {
   9801             *ep_credit_size =  20;
   9802         } else {
   9803             *ep_credit_size =  11;
   9804         }
   9805     } else if (si->port_speed_max[port] <= 11000) {
   9806         *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11;
   9807     } else if (si->port_speed_max[port] <= 27000) {
   9808         *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : 16;
   9809     } else if (si->port_speed_max[port] <= 42000) {
   9810         *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 23 : 20;
   9811     } else if (si->port_speed_max[port] <= 53000) {
   9812         *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : 23;
   9813     } else {
   9814         *ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39;
   9815     }
   9816 
   9817     *ep_credit_size = *ep_credit_size - 1;
   9818 
   9819      return SOC_E_NONE;
   9820  }
   9821 /*
   9822   * Function:
   9823   *      _soc_monterey_mmu_ep_credit_set
   9824   * Purpose:
   9825   *      Initalize EP credits in MMU so EP is in charge
   9826   *      of distributing the correct number of credits.
   9827   * Parameters:
   9828   *      unit    - (IN) Unit number.
   9829  *      port    - (IN) Logical SOC port number.
   9830  * Returns:
   9831  *      SOC_E_XXX
   9832  */
   9833 STATIC int
   9834 _soc_monterey_mmu_ep_credit_set(int unit, soc_port_t port)
   9835 {
   9836     soc_info_t *si = &SOC_INFO(unit);
   9837     int phy_port;
   9838     int mmu_port;
   9839     int ep_credit_size = 0;
   9840     soc_reg_t reg;
   9841     uint32 rval;
   9842 
   9843     /* Get physical port */
   9844     phy_port = si->port_l2p_mapping[port];
   9845     if (phy_port == -1) {
   9846         return SOC_E_INTERNAL;
   9847     }
   9848 
   9849     /* Get MMU port */
   9850     mmu_port = si->port_p2m_mapping[phy_port];
   9851     if (mmu_port == -1) {
   9852         return SOC_E_INTERNAL;
   9853     }
   9854 
   9855     /* Wait until credits are initialised at non-optimum value
   9856      * EP passes MMU 1 credit per cycle, so worse case delay is
   9857      *  95 cycles after EGR_ENABLE is set.
   9858      * @793.75MHz, this is ~120ns.
   9859      */
   9860     sal_usleep(1);
   9861 
   9862     reg = ES_PIPE0_MMU_PORT_CREDIT_EXPRESSr;
   9863 
   9864     SOC_IF_ERROR_RETURN(_soc_monterey_port_credit_size_get(unit, port, &ep_credit_size));
   9865     SOC_IF_ERROR_RETURN
   9866         (soc_reg32_get(unit, reg, REG_PORT_ANY, mmu_port, &rval));
   9867     soc_reg_field_set(unit, reg, &rval, INIT_CREDITf, ep_credit_size);
   9868     SOC_IF_ERROR_RETURN
   9869         (soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
   9870 
   9871      return SOC_E_NONE;
   9872  }
   9873 /*
   9874  * Function:
   9875  *      soc_monterey_edb_buf_reset
   9876  * Purpose:
   9877  *      Initialize EP credits in MMU, release EDB port buffer and
   9878  *      enable cell request in EP.
   9879  * Parameters:
   9880  *      unit    - (IN) Unit number.
   9881  *      port    - (IN) Logical SOC port number.
   9882  *      reset   - (IN) Reset.
   9883  * Returns:
   9884  *      SOC_E_XXX
   9885  */
   9886 int
   9887 soc_monterey_edb_buf_reset(int unit, soc_port_t port, int reset)
   9888 {
   9889     soc_info_t *si = &SOC_INFO(unit);
   9890     uint32 entry[SOC_MAX_MEM_WORDS];
   9891     int phy_port;
   9892     uint32 rval;
   9893     int level;
   9894     soc_timeout_t to;
   9895     int wait_time = 250000;
   9896     uint32 preemption_enable = 0;
   9897     if (SAL_BOOT_QUICKTURN) {
   9898         wait_time *= 20;
   9899     }
   9900 
   9901     /* Get physical port */
   9902     phy_port = si->port_l2p_mapping[port];
   9903     if (phy_port == -1) {
   9904         return SOC_E_INTERNAL;
   9905     }
   9906 
   9907     if (reset) {
   9908         /* Set register to get number of used entries in EDB buffer */
   9909         SOC_IF_ERROR_RETURN
   9910             (READ_EGR_EDB_MISC_CTRLr(unit, &rval));
   9911         soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval,
   9912                           SELECT_CURRENT_USED_ENTRIESf, 1);
   9913         SOC_IF_ERROR_RETURN
   9914             (WRITE_EGR_EDB_MISC_CTRLr(unit, rval));
   9915 
   9916         soc_timeout_init(&to, wait_time, 0);
   9917         
   9918         /* Poll until EDB buffer is empty */
   9919         for (;;) {
   9920             SOC_IF_ERROR_RETURN
   9921                 (READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL,
   9922                                             phy_port, entry));
   9923             level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm,
   9924                                         entry, LEVELf);
   9925             if (level == 0) {
   9926                 break;
   9927             }
   9928             if (soc_timeout_check(&to)) {
   9929                 LOG_ERROR(BSL_LS_SOC_PORT,
   9930                           (BSL_META_U(unit,
   9931                                       "EDB buffer drain timeout: "
   9932                                       "port %d, %s, "
   9933                                       "timeout (pending: %d)\n"),
   9934                            unit, SOC_PORT_NAME(unit, port), level));
   9935                 return SOC_E_INTERNAL;
   9936             }
   9937         }
   9938 
   9939         /*
   9940          * Hold EDB port buffer in reset state and disable cell
   9941          * request generation in EP.
   9942          */
   9943         SOC_IF_ERROR_RETURN
   9944             (READ_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   9945                                                  phy_port, entry));
   9946         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm,
   9947                             entry, VALUEf, 1);
   9948         SOC_IF_ERROR_RETURN
   9949             (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   9950                                                   phy_port, entry));
   9951         SOC_IF_ERROR_RETURN
   9952             (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9953         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 0);
   9954         SOC_IF_ERROR_RETURN
   9955             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9956         SOC_IF_ERROR_RETURN
   9957             (READ_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9958         soc_mem_field32_set(unit, EGR_PREEMPT_ENABLEm, entry, PRT_ENABLEf, 0);
   9959         SOC_IF_ERROR_RETURN
   9960                 (WRITE_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9961     } else {
   9962 
   9963 
   9964         /*
   9965          * Release EDB port buffer reset and
   9966          * enable cell request generation in EP.
   9967          */
   9968         SOC_IF_ERROR_RETURN
   9969             (READ_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   9970                                                  phy_port, entry));
   9971         soc_mem_field32_set(unit, EGR_PORT_CREDIT_RESETm,
   9972                             entry, VALUEf, 0);
   9973         SOC_IF_ERROR_RETURN
   9974             (WRITE_EGR_PORT_CREDIT_RESETm(unit, MEM_BLOCK_ALL,
   9975                                                   phy_port, entry));
   9976 
   9977         SOC_IF_ERROR_RETURN
   9978             (READ_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9979         soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
   9980         SOC_IF_ERROR_RETURN
   9981             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9982 
   9983         SOC_IF_ERROR_RETURN(
   9984         bcmi_mn_preemption_capability_get(unit , port , &preemption_enable)); 
   9985         if (preemption_enable ) {  
   9986             SOC_IF_ERROR_RETURN
   9987                (READ_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9988             soc_mem_field32_set(unit, EGR_PREEMPT_ENABLEm, entry, PRT_ENABLEf, 1);
   9989             SOC_IF_ERROR_RETURN
   9990                 (WRITE_EGR_PREEMPT_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   9991         } 
   9992     }
   9993     return SOC_E_NONE;
   9994 }
   9995 
   9996 int
   9997 soc_monterey_ports_edb_config(int unit, int asf, soc_pbmp_t pbm)
   9998 {
   9999     int rv;
  10000    /* uint32 osct_pbm;
  10001     uint64  lrct_pbm;*/
  10002     soc_info_t *si;
  10003     soc_port_t port, phy_port ;
  10004     /*int pm_id, pgw_inst;*/
  10005       int linerate;
  10006 
  10007     soc_mem_t edb_mem = EGR_EDB_XMIT_CTRLm;
  10008     soc_mem_t edb_mem1 = EGR_PREEMPT_EDB_XMIT_CTRLm;
  10009     soc_field_t edb_fields[3] = {START_CNTf, WAIT_FOR_MOPf, WAIT_FOR_2ND_MOPf};
  10010     uint32 edb_values[3] = {0};
  10011 
  10012 
  10013     si = &SOC_INFO(unit);
  10014 
  10015     /* Remove extraneous ports from the input list */
  10016    /*osct_pbm = 0;
  10017     COMPILER_64_ZERO(lrct_pbm);*/ 
  10018     SOC_PBMP_AND(pbm, PBMP_ALL(unit));
  10019 
  10020     SOC_PBMP_ITER(pbm, port) {
  10021         phy_port = si->port_l2p_mapping[port];
  10022         /*mmu_port = si->port_p2m_mapping[phy_port];
  10023         pgw_inst = si->port_group[port] | SOC_REG_ADDR_INSTANCE_MASK;*/
  10024         linerate = (!SOC_PBMP_MEMBER(si->oversub_pbm, port));
  10025 
  10026         /* *pm_id = ((phy_port - 1) / MONTEREY_PORTS_PER_TSC) % MONTEREY_TSCS_PER_PGW;*/
  10027         if (!soc_monterey_port_is_falcon(unit, phy_port)) { /* Eagle Cores */
  10028             if (si->port_speed_max[port] <= 21000) {  /* 0-21G */
  10029                 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 7);
  10030                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10031                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10032 
  10033             } else if (si->port_speed_max[port] <= 42000) {  /* 21G-42G */
  10034                 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 11 : 7);
  10035                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10036                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10037 
  10038             } else { /* 42G or more (100G)  */
  10039                 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4);
  10040                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10041                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10042 
  10043             }
  10044         } else { /*  Falcon Cores  */
  10045             if (si->port_speed_max[port] <= 11000) {  /* 0-11G */
  10046                 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 0 : 4);
  10047                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10048                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10049 
  10050             } else if (si->port_speed_max[port] <= 27000) {  /* 11G-27G */
  10051                 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 0 : 4);
  10052                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10053                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10054 
  10055             } else if (si->port_speed_max[port] <= 42000) {  /* 27G-42G */
  10056                 edb_values[0] = (linerate) ? (asf ? 3 : 0) : (asf ? 5 : 4);
  10057                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10058                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10059 
  10060             } else { /* 42G or more (50G, 53G, 100G, 106G)  */
  10061                 edb_values[0] = (linerate) ? (asf ? 7 : 0) : (asf ? 0 : 4);
  10062                 edb_values[1] = (linerate) ? (asf ? 0 : 1) : 0;
  10063                 edb_values[2] = 0; /* linerate/oversub and cut-thru or no cut-thru */
  10064             }
  10065         }
  10066 
  10067         rv = soc_mem_fields32_modify(unit, edb_mem, phy_port, 3, edb_fields, edb_values);
  10068         SOC_IF_ERROR_RETURN(rv);
  10069         rv = soc_mem_fields32_modify(unit, edb_mem1, phy_port, 3, edb_fields, edb_values);
  10070 
  10071         SOC_IF_ERROR_RETURN(rv);
  10072 
  10073     }
  10074 
  10075 
  10076     return SOC_E_NONE;
  10077 }
  10078 
  10079 
  10080 STATIC int
  10081 soc_monterey_edb_init(int unit)
  10082 {
  10083     soc_pbmp_t pbm;
  10084 
  10085     SOC_PBMP_ASSIGN(pbm, PBMP_PORT_ALL(unit));
  10086     SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, 0, pbm));
  10087 
  10088     return SOC_E_NONE;
  10089 }
  10090 
  10091 
  10092 
  10093 STATIC int
  10094 _soc_monterey_misc_deinit (int unit)
  10095 {
  10096 
  10097     SOC_IF_ERROR_RETURN(soc_mn_phy_info_deinit(unit));
  10098 
  10099     if (soc_monterey_misc_info[unit] != NULL) {
  10100         sal_free(soc_monterey_misc_info[unit]);
  10101         soc_monterey_misc_info[unit] = NULL;
  10102     }
  10103 
  10104     return SOC_E_NONE;
  10105 }
  10106 
  10107 STATIC int
  10108 soc_mnc_mem_modify_range(int unit, soc_mem_t mem, int min_idx, int max_idx,
  10109                          int nfields, soc_field_t *fields, uint32 *values)
  10110 {
  10111     uint8 *mbuf;
  10112     void  *entry_ptr;
  10113     int    e_idx, f_idx, size, rv;
  10114 
  10115     size = SOC_MEM_TABLE_BYTES(unit, mem);
  10116     mbuf = soc_cm_salloc(unit, size, "soc_mem_name[mem]");
  10117 
  10118     if (NULL == mbuf) {
  10119         return SOC_E_MEMORY;
  10120     }
  10121 
  10122     rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf);
  10123     if (SOC_FAILURE(rv)) {
  10124         soc_cm_sfree(unit, mbuf);
  10125         return rv;
  10126     }
  10127 
  10128     for (e_idx = min_idx; e_idx <= max_idx; e_idx++) {
  10129         entry_ptr = soc_mem_table_idx_to_pointer(unit, mem, void *, mbuf, e_idx);
  10130         for (f_idx = 0; f_idx < nfields; f_idx++) {
  10131             /* If value is -1, program entry_idx */
  10132             soc_mem_field32_set(unit, mem, entry_ptr, fields[f_idx],
  10133                                 (values[f_idx] == -1 ? e_idx : values[f_idx]));
  10134         }
  10135     }
  10136 
  10137     rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, min_idx, max_idx, mbuf);
  10138     soc_cm_sfree(unit, mbuf);
  10139     SOC_IF_ERROR_RETURN(rv);
  10140 
  10141     return SOC_E_NONE;
  10142 }
  10143 
  10144 STATIC int
  10145 _soc_monterey_misc_init (int unit)
  10146 {
  10147     static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 };
  10148     soc_info_t *si;
  10149     uint32 rval = 0;
  10150     uint64 rval64;
  10151     uint32 entry[SOC_MAX_MEM_WORDS];
  10152     soc_pbmp_t pbmp;
  10153     int port, min_port, max_port;
  10154     int block_info_idx;
  10155     int index, count, sub_sel, offset;
  10156     int freq, target_freq, divisor, dividend, delay;
  10157     int parity_enable = 0, cache_fpgm;
  10158     soc_field_t fields[2];
  10159     uint32 values[2];
  10160 
  10161 
  10162     si = &SOC_INFO(unit);
  10163 
  10164     if (soc_monterey_misc_info[unit] == NULL) {
  10165         soc_monterey_misc_info[unit] = sal_alloc(sizeof(*soc_monterey_misc_info[unit]),
  10166                                                "monterey misc info");
  10167         if (soc_monterey_misc_info[unit] == NULL) {
  10168             return SOC_E_MEMORY;
  10169         }
  10170     }
  10171 
  10172 
  10173     sal_memset(soc_monterey_misc_info[unit], 0, (sizeof(*soc_monterey_misc_info[unit])));
  10174 
  10175     /* Stop the mem scan task before all of the parity init takes place */
  10176     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
  10177     SOC_IF_ERROR_RETURN(soc_monterey_shadow_create(unit));
  10178     if (!SOC_WARM_BOOT(unit)) {
  10179         /*  Initialize PORT MIB counter */
  10180         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) {
  10181             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10182             soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10183             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval));
  10184             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0));
  10185         }
  10186         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLG2PORT) {
  10187             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10188             soc_reg_field_set(unit, CLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10189             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, rval));
  10190             SOC_IF_ERROR_RETURN(WRITE_CLPORT_MIB_RESETr(unit, port, 0));
  10191         }
  10192         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) {
  10193             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10194             soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10195             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval));
  10196             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0));
  10197         }
  10198         SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORTB0) {
  10199             port = SOC_BLOCK_PORT(unit, block_info_idx);
  10200             soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, 0xf);
  10201             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, rval));
  10202             SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, port, 0));
  10203         }
  10204 
  10205     }
  10206 
  10207     /* Stop the mem scan task before all of the parity init takes place */
  10208     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
  10209     SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit));
  10210 
  10211     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
  10212     if (parity_enable) {
  10213         if ((!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) &&
  10214             !SOC_WARM_BOOT(unit)) {
  10215             /* Certain mems/regs need to be cleared before enabling SER */
  10216             SOC_IF_ERROR_RETURN(_soc_monterey_clear_mmu_memory(unit, INVALIDm));
  10217             SOC_IF_ERROR_RETURN(_soc_monterey_clear_all_port_data(unit));
  10218         }
  10219         SOC_IF_ERROR_RETURN(_soc_monterey_tcam_ser_init(unit));
  10220         SOC_IF_ERROR_RETURN(_soc_monterey_ser_enable_all(unit, TRUE));
  10221 #ifdef INCLUDE_MEM_SCAN
  10222         soc_mem_scan_ser_list_register(unit, TRUE,
  10223                                        _soc_monterey_tcam_ser_info[unit]);
  10224 #endif
  10225         memset(&_monterey_ser_functions, 0, sizeof(soc_ser_functions_t));
  10226         _monterey_ser_functions._soc_ser_fail_f = &soc_monterey_ser_fail;
  10227         _monterey_ser_functions._soc_ser_parity_error_cmicm_intr_f = 
  10228             &soc_monterey_ser_error;
  10229         soc_ser_function_register(unit, &_monterey_ser_functions);
  10230         soc_monterey_ser_set_long_delay(FALSE);
  10231 #if defined(SER_TR_TEST_SUPPORT)
  10232         /*Initialize chip-specific functions for SER testing*/
  10233         memset(&ser_monterey_test_fun, 0, sizeof(soc_ser_test_functions_t));
  10234         ser_monterey_test_fun.inject_error_f = &soc_monterey_ser_inject_error;
  10235         ser_monterey_test_fun.test_mem = &soc_monterey_ser_test_mem;
  10236         ser_monterey_test_fun.test = &soc_monterey_ser_test;
  10237         ser_monterey_test_fun.parity_control = &_ser_test_parity_control_reg_set;
  10238         ser_monterey_test_fun.injection_support = &soc_monterey_ser_error_injection_support;
  10239         soc_ser_test_functions_register(unit, &ser_monterey_test_fun);
  10240 #endif /*defined(SER_TR_TEST_SUPPORT*/
  10241 
  10242     }
  10243 
  10244     if (!SOC_WARM_BOOT(unit)) {
  10245         SOC_IF_ERROR_RETURN
  10246             (_soc_monterey_clear_all_memory(unit, (parity_enable ? 0 : 1)));
  10247         if (!parity_enable) {
  10248             /* Clear enabled port's regs if not done above */
  10249             SOC_IF_ERROR_RETURN(_soc_monterey_clear_enabled_port_data(unit));
  10250         }
  10251     }
  10252 
  10253     
  10254     SOC_IF_ERROR_RETURN(_soc_monterey_port_mapping_init(unit));
  10255 
  10256     if (!(SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM)) { 
  10257         if (!SOC_WARM_BOOT(unit)) {
  10258             if(!soc_property_get(unit, "skip_tdm_init", 0)) {
  10259                SOC_IF_ERROR_RETURN(soc_monterey_tdm_init(unit));
  10260             }
  10261             SOC_IF_ERROR_RETURN(soc_monterey_idb_init(unit));
  10262             SOC_IF_ERROR_RETURN(soc_monterey_edb_init(unit));
  10263         } else {
  10264             SOC_IF_ERROR_RETURN(soc_monterey_tdm_reinit(unit));
  10265         }
  10266     }
  10267 
  10268     sal_memset(entry, 0, sizeof(cpu_pbm_entry_t));
  10269     soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit));
  10270     SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry));
  10271 
  10272     sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t));
  10273     soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit));
  10274     SOC_IF_ERROR_RETURN(soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry));
  10275 
  10276     sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t));
  10277     soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf,
  10278                            &PBMP_LB(unit));
  10279     SOC_IF_ERROR_RETURN(soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm,
  10280                                       MEM_BLOCK_ALL, 0, entry));
  10281 
  10282     sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
  10283     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
  10284     PBMP_HG_ITER(unit, port) {
  10285         SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm,
  10286                                           MEM_BLOCK_ALL, port, entry));
  10287     }
  10288     SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL,
  10289                                       si->cpu_hg_index, entry));
  10290     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2);
  10291     SOC_IF_ERROR_RETURN(soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL,
  10292                                       LB_PORT(unit), entry));
  10293 
  10294     /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to
  10295      * initialize the cache until now.  This is the time to check for
  10296      * the cache permission of this table.
  10297      */
  10298     cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 
  10299             soc_property_get(unit, spn_MEM_CACHE_ENABLE, 
  10300                              (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1);
  10301     if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) {
  10302         char mem_name[100];
  10303         char *mptr;
  10304 
  10305         sal_memset(mem_name, 0, sizeof(mem_name));
  10306         sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_"));
  10307         mptr = &mem_name[sal_strlen(mem_name)];
  10308         sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm),
  10309                     sizeof(mem_name) - sal_strlen(mem_name) - 1);
  10310         if (soc_property_get(unit, mem_name, 0)) {
  10311             cache_fpgm = 0;
  10312         }
  10313     }
  10314 
  10315     if (cache_fpgm && (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) {
  10316         SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |=
  10317             SOC_MEM_FLAG_CACHABLE;
  10318         SOC_IF_ERROR_RETURN
  10319             (soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm,
  10320                                MEM_BLOCK_ALL, TRUE));
  10321 
  10322         SOC_MEM_INFO(unit, FP_GM_FIELDSm).flags |=
  10323             SOC_MEM_FLAG_CACHABLE;
  10324         SOC_IF_ERROR_RETURN
  10325             (soc_mem_cache_set(unit, FP_GM_FIELDSm,
  10326                                MEM_BLOCK_ALL, TRUE));
  10327     }
  10328 
  10329     SOC_IF_ERROR_RETURN(_soc_portctrl_monterey_port_init(unit));
  10330     SOC_IF_ERROR_RETURN(_soc_monterey_pm_intr_init(unit));
  10331     SOC_IF_ERROR_RETURN(_soc_monterey_pm_cpri_intr_enable(unit, TRUE));
  10332 
  10333     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
  10334     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
  10335     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
  10336     /* Enable dual hash tables */
  10337     SOC_IF_ERROR_RETURN(_soc_monterey_hash_init(unit));
  10338     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L3_ENTRY_CONTROL_10r, 
  10339                         REG_PORT_ANY, DISABLE_L3_ENTRY_LPf, 0xf));
  10340 
  10341     rval = 0;
  10342     soc_reg_field_set(unit, L2_AGE_DEBUGr, &rval, AGE_COUNTf,
  10343                       soc_mem_index_max(unit, L2Xm));
  10344     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_DEBUGr(unit, rval));
  10345     /*
  10346      * Egress Enable (for non-serdes ports).
  10347      * For PM ports, it is set during port enable/disable sequence.
  10348      */
  10349     sal_memset(entry, 0, sizeof(egr_enable_entry_t));
  10350     soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
  10351 
  10352     /* Only enable internal ports in EGR_ENABLE.
  10353      *  The packet processing ports are enabled via port enable sequence.
  10354      */
  10355     SOC_PBMP_CLEAR(pbmp);
  10356     SOC_PBMP_PORT_ADD(pbmp, CMIC_PORT(unit));
  10357     SOC_PBMP_PORT_ADD(pbmp, LB_PORT(unit));
  10358     SOC_PBMP_PORT_ADD(pbmp, MACSEC_PORT(unit));
  10359 
  10360     PBMP_ITER(pbmp, port) {
  10361         SOC_IF_ERROR_RETURN
  10362             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, port, entry));
  10363         SOC_IF_ERROR_RETURN(_soc_monterey_mmu_ep_credit_set(unit, port));
  10364     }
  10365 
  10366     SOC_PBMP_CLEAR(pbmp);
  10367     SOC_PBMP_ASSIGN(pbmp, PBMP_CMIC(unit));
  10368     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, &pbmp);
  10369     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry));
  10370 
  10371     /*
  10372      * Enable all ports (except RDB port)
  10373      * RDB port is an ingress-only port that should not have any packets
  10374      * enqueued against it, even if the port is added to any vlan or other
  10375      * forwarding table by mistake.
  10376      */
  10377 #if __GNUC__ > 6
  10378 #pragma GCC diagnostic push
  10379 #pragma GCC diagnostic ignored "-Wmemset-elt-size"
  10380 #endif
  10381     /*
  10382      * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for
  10383      * performance reasons, because the actual soc_mem_field_set()
  10384      * will only write sizeof(ing_dest_port_enable_entry_t)=20
  10385      * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651
  10386      * depending on which devices are compiled in.
  10387      */
  10388     sal_memset(entry, 0, sizeof(ing_dest_port_enable_entry_t));
  10389 #if __GNUC__ > 6
  10390 #pragma GCC diagnostic pop
  10391 #endif
  10392     SOC_PBMP_CLEAR(pbmp);
  10393     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  10394     soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, entry, PORT_BITMAPf, &pbmp);
  10395     SOC_IF_ERROR_RETURN(WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, entry));
  10396 
  10397     min_port = SOC_PORT_MIN(unit, all);
  10398     max_port = SOC_PORT_MAX(unit, all);
  10399 
  10400     fields[0] = DESTf; values[0] = -1; /* -1 => port */
  10401     fields[1] = ENABLEf; values[1] = 1;
  10402     SOC_IF_ERROR_RETURN(soc_mnc_mem_modify_range(unit, MODPORT_MAP_SUBPORTm,
  10403                                                  min_port, max_port,
  10404                                                  2, fields, values));
  10405 
  10406     /* setting up my_modid */
  10407     SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64));
  10408 
  10409     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  10410                           MODID_0_VALIDf, 1);
  10411     soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64,
  10412                           MODID_0f, SOC_BASE_MODID(unit));
  10413 
  10414     SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64));
  10415 
  10416 
  10417     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64));
  10418     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10419                           L3SRC_HIT_ENABLEf, 1);
  10420     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10421                           L2DST_HIT_ENABLEf, 1);
  10422     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10423                           APPLY_EGR_MASK_ON_L2f, 1);
  10424     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10425                           APPLY_EGR_MASK_ON_L3f, 1);
  10426     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10427                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
  10428     soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10429                           ARP_VALIDATION_ENf, 1);
  10430 
  10431     /*
  10432      * If riot is enabled,
  10433      *     MY_STATION1 will be used for tunnels.
  10434      *     MY_STATION2 will be used for routing.
  10435      * Else,
  10436      *     MY_STATION1 should be used for both tunnels and routing.
  10437      *     For this, USE_MY_STATION1_FOR_NON_TUNNELS should be set to TRUE.
  10438      */
  10439     if (!soc_feature(unit, soc_feature_riot)) {
  10440         soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64,
  10441                 USE_MY_STATION1_FOR_NON_TUNNELSf, 1);
  10442     }
  10443 
  10444     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64));
  10445 
  10446     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1r,
  10447                                                REG_PORT_ANY, RING_MODEf, 1));
  10448 
  10449 
  10450     /* T2OQ needs to be setup for all ports that require 1 in 9 spacing or less
  10451      *  In Apache, it is safe to program all mmu ports 0-15 in T2OQ (whether in 
  10452      *  high speed mode or not). In TD2+, part of the MCQDB memory was re-used
  10453      *  for T2OQ; Apache has separate 160 deep MCQDB memory */
  10454     SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, TOQ_MC_CFG1r,
  10455                                                REG_PORT_ANY, IS_MC_T2OQ_PORT0f,
  10456                                                0xffff));
  10457 
  10458     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
  10459      * causes the outer tag to be removed from packets that don't have
  10460      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
  10461      */
  10462     fields[0] = VT_MISS_UNTAGf; values[0] = 0;
  10463     fields[1] = REMARK_OUTER_DOT1Pf; values[1] = 1;
  10464     SOC_IF_ERROR_RETURN(soc_mnc_mem_modify_range(unit, EGR_VLAN_CONTROL_1m,
  10465                                                  min_port, max_port,
  10466                                                  2, fields, values));
  10467     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
  10468     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
  10469     SOC_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit));
  10470     SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
  10471                                      MEM_BLOCK_ANY, 0, &entry));
  10472     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, &pbmp);
  10473     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
  10474                                       MEM_BLOCK_ANY, 0, &entry));
  10475 
  10476     /* Multicast range initialization */
  10477     SOC_IF_ERROR_RETURN
  10478         (soc_hbx_higig2_mcast_sizes_set(unit,
  10479              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
  10480                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
  10481              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
  10482                               soc_mem_index_count(unit, L2MCm) / 2),
  10483              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
  10484                               soc_mem_index_count(unit, L2MCm) / 2)));
  10485     SOC_IF_ERROR_RETURN
  10486         (soc_hbx_mcast_size_set(unit, soc_property_get(unit,
  10487              spn_MULTICAST_L2_RANGE, soc_mem_index_count(unit, L2MCm) / 2)));
  10488     SOC_IF_ERROR_RETURN
  10489         (soc_hbx_ipmc_size_set(unit, soc_property_get(unit,
  10490              spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L2MCm) / 2)));
  10491 
  10492     /* Setup SW2_FP_DST_ACTION_CONTROL */
  10493     fields[0] = HGTRUNK_RES_ENf;
  10494     values[0] = 1;
  10495     fields[1] = LAG_RES_ENf;
  10496     values[1] = 1;
  10497     SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr,
  10498                                                 REG_PORT_ANY, 2, fields, values));
  10499 
  10500     /* Populate and enable RTAG7 Macro flow offset table */
  10501     if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) {
  10502         count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm);
  10503         sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t));
  10504         for (index = 0; index < count; ) {
  10505             for (sub_sel = 0; (sub_sel < 8) && (index < count); sub_sel++) {
  10506                 for (offset = 0;
  10507                      offset < rtag7_field_width[sub_sel] && index < count;
  10508                      offset++) {
  10509                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10510                                         SUB_SEL_ECMPf, sub_sel);
  10511                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10512                                         OFFSET_ECMPf, offset);
  10513 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  10514                     if ((soc_feature(unit, soc_feature_riot) ||
  10515                         soc_feature(unit, soc_feature_multi_level_ecmp))) {
  10516 
  10517                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10518                                             SUB_SEL_ECMP_LEVEL1f, sub_sel);
  10519                         soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
  10520                                             OFFSET_ECMP_LEVEL1f, offset);
  10521                     }
  10522 #endif
  10523                     SOC_IF_ERROR_RETURN
  10524                         (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm,
  10525                                        MEM_BLOCK_ANY, index, &entry));
  10526                     index++;
  10527                 }
  10528             }
  10529         }
  10530 
  10531         rval = 0;
  10532         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, USE_FLOW_SEL_ECMPf, 1);
  10533 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT)
  10534         if ((soc_feature(unit, soc_feature_riot) ||
  10535             soc_feature(unit, soc_feature_multi_level_ecmp))) {
  10536 
  10537             soc_reg_field_set(unit, RTAG7_HASH_SELr,
  10538                 &rval, USE_FLOW_SEL_ECMP1f, 1);
  10539         }
  10540 #endif
  10541         soc_reg_field_set(unit, RTAG7_HASH_SELr, &rval, 
  10542                                                 USE_FLOW_SEL_TRILL_ECMPf, 1);
  10543         SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_SELr(unit, rval));
  10544     }
  10545 
  10546     freq = si->frequency;
  10547 
  10548     /*
  10549      * Set external MDIO freq to around 6MHz
  10550      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  10551      */
  10552     target_freq = 6;
  10553     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  10554     divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, divisor);
  10555     dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1);
  10556     rval = 0;
  10557     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
  10558     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
  10559     WRITE_CMIC_RATE_ADJUSTr(unit, rval);
  10560 
  10561     /*
  10562      * Set internal MDIO freq to around 12MHz
  10563      * Valid range is from 2.5MHz to 20MHz
  10564      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
  10565      * or
  10566      * DIVISOR = core_clock_freq * DIVIDENT / (target_freq * 2)
  10567      */
  10568     target_freq = 12;
  10569     divisor = (freq + (target_freq * 2 - 1)) / (target_freq * 2);
  10570     divisor = soc_property_get(unit, spn_RATE_INT_MDIO_DIVISOR, divisor);
  10571     dividend = soc_property_get(unit, spn_RATE_INT_MDIO_DIVIDEND, 1);
  10572     rval = 0;
  10573     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf,
  10574                        divisor);
  10575     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf,
  10576                        dividend);
  10577     WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval);
  10578 
  10579     delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1);
  10580     if (delay >= 1  && delay <= 15) {
  10581         /* coverity[result_independent_of_operands] */
  10582         SOC_IF_ERROR_RETURN(READ_CMIC_MIIM_CONFIGr(unit, &rval));
  10583         soc_reg_field_set(unit, CMIC_MIIM_CONFIGr, &rval, MDIO_OUT_DELAYf,
  10584                           delay);
  10585         /* coverity[result_independent_of_operands] */
  10586         SOC_IF_ERROR_RETURN(WRITE_CMIC_MIIM_CONFIGr(unit, rval));
  10587     }
  10588 
  10589     if (!SOC_WARM_BOOT(unit)) {
  10590         SOC_IF_ERROR_RETURN(_soc_monterey_ledup_init(unit));
  10591     }
  10592 
  10593     if (soc_mspi_init(unit) != SOC_E_NONE) {
  10594         LOG_ERROR(BSL_LS_SOC_COMMON,
  10595                  (BSL_META_U(unit,
  10596                              "unit %d : MSPI Init Failed\n"), unit));
  10597     }
  10598 
  10599     if (parity_enable) {
  10600         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
  10601         SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit));
  10602     }
  10603 
  10604     soc_ser_log_init(unit, NULL, 0);
  10605 
  10606     /* Setup config needed for EP-Redirection */
  10607     /* Enable re-direction */
  10608     rval = 0;
  10609     soc_reg_field_set(unit, EP_REDIR_CONTROLr, &rval, ENABLEf, 1);
  10610     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, EP_REDIR_CONTROLr,
  10611                                       REG_PORT_ANY, 0, rval));
  10612 
  10613 #ifdef INCLUDE_XFLOW_MACSEC
  10614     if (soc_feature(unit, soc_feature_xflow_macsec)) {
  10615         SOC_IF_ERROR_RETURN(_soc_xflow_macsec_init(unit));
  10616         if (!soc_feature(unit, soc_feature_xflow_macsec_poll_intr)) {
  10617             /* MACSEC has single CMIC bit for both functional and ECC interrupts */
  10618             SOC_IF_ERROR_RETURN(_soc_monterey_macsec_intr_enable(unit, TRUE));
  10619         }
  10620     }
  10621 #endif
  10622     return SOC_E_NONE;
  10623 }
  10624 
  10625 uint32 _soc_monterey_mmu_port(int unit, int port)
  10626 {
  10627     soc_info_t *si = &SOC_INFO(unit);
  10628     return si->port_p2m_mapping[si->port_l2p_mapping[port]];
  10629 }
  10630 
  10631 uint32 _soc_monterey_piped_mem_index(int unit, soc_port_t port,
  10632                                      soc_mem_t mem, int arr_off)
  10633 {
  10634     int     mmu_port;
  10635 
  10636     mmu_port = SOC_MONTEREY_MMU_PORT(unit, port);
  10637 
  10638     switch (mem) {
  10639     case MMU_THDM_DB_PORTSP_CONFIG_0m:
  10640     case MMU_THDM_MCQE_PORTSP_CONFIG_0m:
  10641 
  10642        return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_POOL + arr_off;
  10643     case THDI_PORT_SP_CONFIG_Xm:
  10644     case MMU_THDU_XPIPE_CONFIG_PORTm:
  10645     case MMU_THDU_XPIPE_RESUME_PORTm:
  10646         return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_POOL + arr_off;
  10647     case THDI_PORT_PG_CONFIG_Xm:
  10648         return (mmu_port & 0x7f) * _MONTEREY_MMU_NUM_PG + arr_off;
  10649    default:
  10650         return 0xffffffff;
  10651     }
  10652 }
  10653 
  10654 #define _MONTEREY_MMU_BYTES_TO_CELLS(_byte_)  \
  10655     (((_byte_) + _MONTEREY_MMU_BYTES_PER_CELL - 1) / _MONTEREY_MMU_BYTES_PER_CELL)
  10656 
  10657 STATIC void
  10658 _soc_monterey_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg,
  10659                              int lossless)
  10660 {
  10661     soc_info_t *si;
  10662     si = &SOC_INFO(unit);
  10663 
  10664     sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t));
  10665 
  10666     devcfg->max_pkt_byte = si->max_mtu;
  10667     devcfg->mmu_hdr_byte = _MONTEREY_MMU_PACKET_HEADER_BYTES;
  10668     devcfg->jumbo_pkt_size = _MONTEREY_MMU_JUMBO_FRAME_BYTES;
  10669     devcfg->default_mtu_size = _MONTEREY_MMU_DEFAULT_MTU_BYTES;
  10670     devcfg->mmu_cell_size = _MONTEREY_MMU_BYTES_PER_CELL;
  10671 
  10672 
  10673     devcfg->mmu_total_cell = _MONTEREY_MMU_TOTAL_CELLS  -
  10674                              (lossless ? 16 : 0); 
  10675 
  10676     devcfg->num_pg = _MONTEREY_MMU_NUM_PG;
  10677     devcfg->num_service_pool = _MONTEREY_MMU_NUM_POOL;
  10678     devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN |
  10679                     SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY;
  10680     devcfg->total_mcq_entry = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit);
  10681     devcfg->rqe_queue_num = 11;
  10682 }
  10683 
  10684 STATIC int
  10685 _soc_monterey_default_lossless_pg_headroom(int unit, soc_port_t port)
  10686 {
  10687     soc_info_t *si;
  10688     if (IS_ROE_ENABLED(unit)) { 
  10689         return 0; 
  10690     } 
  10691     if (IS_CPU_PORT(unit, port) ) {
  10692         return 50;
  10693     }
  10694     if (IS_LB_PORT(unit, port)) {
  10695         return 162;
  10696     }
  10697 
  10698     if (IS_MACSEC_PORT(unit, port)) {
  10699         return 117;
  10700     }
  10701 
  10702     si = &SOC_INFO(unit);
  10703     if (SOC_PBMP_MEMBER(si->oversub_pbm, port)) {
  10704         if (si->port_speed_max[port] >= 100000) {
  10705             return 687;
  10706         } else if (si->port_speed_max[port] >= 50000) {
  10707              return 352;
  10708         } else if (si->port_speed_max[port] >= 40000) {
  10709             return 338;
  10710         } else if (si->port_speed_max[port] >= 25000) {
  10711             return 214;
  10712         } else if (si->port_speed_max[port] >= 20000) {
  10713             return 206;
  10714         } else {
  10715             return 185;
  10716         }
  10717     } else {
  10718         if (si->port_speed_max[port] >= 100000) {
  10719             return 558;
  10720         } else if (si->port_speed_max[port] >= 50000) {
  10721              return 298;    
  10722         } else if (si->port_speed_max[port] >= 40000) {
  10723             return 284;
  10724         } else if (si->port_speed_max[port] >= 25000) {
  10725             return 191;
  10726         } else if (si->port_speed_max[port] >= 20000) {
  10727             return 183;
  10728         } else {
  10729             return 162;
  10730         }
  10731     }
  10732 
  10733     return 0;
  10734 }
  10735 
  10736 STATIC int
  10737 _soc_monterey_min_cell_rsvd_per_mcq(int unit, int port, int default_val)
  10738 {
  10739     int freq, speed, osub;
  10740     soc_info_t *si;
  10741     uint8 rev_id;
  10742 
  10743     soc_cm_get_id(unit, NULL, &rev_id);
  10744 
  10745     if (rev_id == BCM56850_A1_REV_ID) {
  10746         si = &SOC_INFO(unit);
  10747         speed = si->port_speed_max[port];
  10748         osub = (SOC_PBMP_MEMBER(si->oversub_pbm, port)) ? 1 : 0;
  10749 
  10750         if (speed <= 11000) {
  10751             return (osub) ? 10 : 5;
  10752         } else if (speed <= 42000) {
  10753             freq = si->frequency;
  10754             return ((freq >= 760) && !osub) ? 9 : 16;
  10755         }
  10756     }
  10757 
  10758     return default_val;
  10759 }
  10760 
  10761 
  10762 /*
  10763 * Function:
  10764 *     soc_monterey_mcq_entries_rsvd_port
  10765 * Purpose:
  10766 *     For a given port, soc_mn_mcq_entries_rsvd_port calculates
  10767 *     the number of MC q entries (Reserved Egress Queue Entries).
  10768 *     This function only gives MC q entries for
  10769 *     for flex disabled ports.
  10770 *     For flex enabled port macros, this function is not used.
  10771 * Parameters:
  10772 *     unit    - (IN) Unit number.
  10773 *     port    - (IN) logical port num
  10774 * Returns:
  10775 *     Reserved Egress Queue Entries for a given port
  10776  */
  10777 int soc_mn_mcq_entries_rsvd_port(int unit, int port)
  10778 {
  10779     int port_num_cosq;
  10780     soc_info_t *si;
  10781     int mcq_entry = 0;
  10782 
  10783     si = &SOC_INFO(unit);
  10784     port_num_cosq = si->port_num_cosq[port];
  10785     mcq_entry = port_num_cosq * _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD;
  10786     return mcq_entry;
  10787 }
  10788 
  10789 /*
  10790 * Function:
  10791 *     soc_mn_egr_buf_rsvd_port
  10792 * Purpose:
  10793 *     For Cpu port or loopback port,
  10794 *     soc_td2p_egr_buf_rsvd_port calculates
  10795 *     the reserved queue min/guarantee.
  10796 *     This function only gives cumulative (for all queues)
  10797 *     queue guarantee for CPU port or Loopback port.
  10798 * Parameters:
  10799 *     unit    - (IN) Unit number.
  10800 *     port    - (IN) logical port num for CPU port or LB port
  10801 * Returns:
  10802 *     Reserved Cumulative (total for all queues) Queue Min/Guarantee value
  10803  */
  10804 int soc_mn_egr_buf_rsvd_port(int unit, int port, int default_mtu_cells)
  10805 {
  10806     int port_num_cosq;
  10807     soc_info_t *si;
  10808     int egr_rsvd = 0;
  10809     int min_cell_per_mcq;
  10810 
  10811     if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) {
  10812         return 0;
  10813     }
  10814 
  10815     si = &SOC_INFO(unit);
  10816 
  10817     port_num_cosq = si->port_num_cosq[port];
  10818 
  10819     if (soc_feature(unit, soc_feature_min_cell_per_queue)) {
  10820         min_cell_per_mcq = _soc_monterey_min_cell_rsvd_per_mcq
  10821                              (unit, port, default_mtu_cells);
  10822     } else {
  10823         min_cell_per_mcq = default_mtu_cells;
  10824     }
  10825 
  10826     egr_rsvd = port_num_cosq * min_cell_per_mcq;
  10827     return egr_rsvd;
  10828 }
  10829 
  10830 STATIC void
  10831 _soc_monterey_mmu_config_buf_default(int unit, _soc_mmu_cfg_buf_t *buf,
  10832                                 _soc_mmu_device_info_t *devcfg, int lossless)
  10833 {
  10834     soc_info_t *si;
  10835     _soc_mmu_cfg_buf_pool_t *buf_pool;
  10836     _soc_mmu_cfg_buf_port_t *buf_port;
  10837     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  10838     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  10839     _soc_mmu_cfg_buf_queue_t *buf_queue;
  10840     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  10841     int max_packet_cells, pg_min, default_mtu_cells;
  10842     int port, idx, per_q_guarentee;
  10843     int total_pool_size = 0, egr_shared_total = 0;
  10844     int q_reserved = 0, in_reserved = 0;
  10845     int mcq_entry_reserved = 0;
  10846     int mcq_entry_shared_total;
  10847     int rqe_entry_shared_total;
  10848     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  10849     int asf_rsvd = 0, ing_rsvd = 0, egr_rsvd = 0;
  10850     int pool0_share = 0 ;
  10851     int pool1_share = 0;
  10852     int mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_1;
  10853     int tdm_freq = 0 ;
  10854     si = &SOC_INFO(unit);
  10855     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  10856                 (BSL_META_U(unit,
  10857                             "Initializing default MMU config (u=%d)\n"), unit));
  10858     max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte +
  10859                                                    devcfg->mmu_hdr_byte,
  10860                                                    devcfg->mmu_cell_size);
  10861     pg_min = _MONTEREY_MMU_PG_MIN;
  10862     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  10863                                                    devcfg->mmu_hdr_byte,
  10864                                                    devcfg->mmu_cell_size);
  10865 
  10866     total_pool_size = devcfg->mmu_total_cell;
  10867 
  10868     buf->headroom = 2 * _MONTEREY_MMU_GLOBAL_HEADROOM_CELL_PER_PIPE;
  10869 
  10870     in_reserved += (buf->headroom/2);
  10871 
  10872     per_q_guarentee = (lossless) ? 0 : default_mtu_cells;
  10873     if (asf_rsvd < buf->rsvd_buffers[0].asf_rsvd_cells) {
  10874             asf_rsvd = buf->rsvd_buffers[0].asf_rsvd_cells;
  10875     }
  10876     if (egr_rsvd < buf->rsvd_buffers[0].egr_rsvd_cells) {
  10877         egr_rsvd = buf->rsvd_buffers[0].egr_rsvd_cells;
  10878     }
  10879     if (ing_rsvd < buf->rsvd_buffers[0].ing_rsvd_cells) {
  10880         ing_rsvd = buf->rsvd_buffers[0].ing_rsvd_cells;
  10881     }
  10882     PBMP_ALL_ITER(unit, port) {
  10883         mcq_entry_reserved += si->port_num_cosq[port] *
  10884             _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD;
  10885         q_reserved += (si->port_num_cosq[port] + si->port_num_uc_cosq[port]) *
  10886             per_q_guarentee;
  10887     }
  10888     egr_shared_total = total_pool_size - q_reserved - 168;
  10889    
  10890 
  10891     mcq_entry_shared_total = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit) - mcq_entry_reserved;
  10892 
  10893     rqe_entry_shared_total = _MONTEREY_MMU_TOTAL_RQE_ENTRY(unit) - 160 - 88;
  10894 
  10895 /* the division needs to be diffrent for ethernet and the other sku supported
  10896  *  based on sku type we should update the share values
  10897  */
  10898     tdm_freq = soc_property_get(unit, spn_BCM_TDM_FREQUENCY,si->frequency); 
  10899     if (IS_ROE_ENABLED(unit)) {
  10900         if (tdm_freq == 815 || tdm_freq == 666) {
  10901             mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_1;
  10902         } else {
  10903             mn_mmu_express_buffer_total = _MN_MMU_EXPRESS_BUFFER_TOTAL_2;
  10904         }
  10905     } else {
  10906         mn_mmu_express_buffer_total = 0;
  10907     }
  10908     if (IS_ROE_ENABLED(unit)) { 
  10909         pool0_share = total_pool_size - mn_mmu_express_buffer_total;
  10910         pool1_share = mn_mmu_express_buffer_total;
  10911     } else { 
  10912         pool0_share =  10000 | _MMU_CFG_BUF_PERCENT_FLAG;
  10913         pool1_share = 0;
  10914     }  
  10915     for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  10916         buf_pool = &buf->pools[idx];
  10917 
  10918         if (idx == 0) {  /* 43 % */
  10919             buf_pool->size = pool0_share ;
  10920             buf_pool->yellow_size = pool0_share ;
  10921             buf_pool->red_size = pool0_share ;
  10922             buf_pool->total_mcq_entry = _MONTEREY_MMU_TOTAL_MCQ_ENTRY(unit)  ;
  10923             buf_pool->total_rqe_entry = rqe_entry_shared_total ;
  10924             buf_pool->mcq_entry_reserved = mcq_entry_reserved;
  10925          }  else if (idx == 1 && IS_ROE_ENABLED(unit)) {  /* 56 % of total is reservef for express traffic */
  10926             buf_pool->size = pool1_share ;
  10927             buf_pool->yellow_size = pool1_share ;
  10928             buf_pool->red_size = pool1_share ;
  10929             buf_pool->total_mcq_entry =  0;
  10930             buf_pool->total_rqe_entry = 0 ;
  10931             buf_pool->mcq_entry_reserved = 0;
  10932         } else {
  10933             buf_pool->size = 0;
  10934             buf_pool->yellow_size = 0;
  10935             buf_pool->red_size = 0;
  10936             buf_pool->total_mcq_entry = 0;
  10937             buf_pool->total_rqe_entry = 0;
  10938             buf_pool->mcq_entry_reserved = 0;
  10939         }
  10940     }
  10941 
  10942     for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) {
  10943         queue_grp = &buf->qgroups[idx];
  10944         queue_grp->pool_limit = egr_shared_total;
  10945         if (lossless) {
  10946             queue_grp->guarantee = 0;
  10947             queue_grp->pool_scale = -1;
  10948             queue_grp->discard_enable = 0;
  10949             queue_grp->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  10950             queue_grp->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  10951         } else {
  10952             queue_grp->guarantee = 16;
  10953             queue_grp->discard_enable = 1;
  10954             queue_grp->pool_scale = 8;
  10955         }
  10956         queue_grp->pool_resume = default_mtu_cells * 2;
  10957         queue_grp->yellow_resume = default_mtu_cells * 2;
  10958         queue_grp->red_resume = default_mtu_cells * 2;
  10959     }
  10960 
  10961     PBMP_ALL_ITER(unit, port) {
  10962         buf_port = &buf->ports[port];
  10963 
  10964         /* internal priority to priority group mapping */
  10965         for (idx = 0; idx < 16; idx++) {
  10966             buf_port->pri_to_prigroup[idx] = 7;
  10967             if (IS_ROE_ENABLED(unit)) {
  10968                 switch (idx) {
  10969                      case 1:
  10970                      buf_port->pri_to_prigroup[idx] = 1;
  10971                      break;
  10972                      case 3:
  10973                      buf_port->pri_to_prigroup[idx] = 3;
  10974                      break;
  10975                      case 5:
  10976                      buf_port->pri_to_prigroup[idx] = 5;
  10977                      break;
  10978                      case 7:
  10979                      buf_port->pri_to_prigroup[idx] = 7;
  10980                      break;
  10981                      default :
  10982                      buf_port->pri_to_prigroup[idx] = 0;
  10983                  } 
  10984             }
  10985             if (lossless && IS_RDB_PORT(unit, port)) {
  10986                 if (idx < 5) {
  10987                     buf_port->pri_to_prigroup[idx] = idx + 2;
  10988                 }
  10989             }
  10990         }
  10991 
  10992         /* priority group to pool mapping */
  10993         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  10994              if (IS_ROE_ENABLED(unit) && (idx == 5 || idx == 7)) {
  10995                  buf_port->prigroups[idx].pool_idx = 1;
  10996              } else { 
  10997                  buf_port->prigroups[idx].pool_idx = 0;
  10998              }
  10999         }
  11000 
  11001         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11002             buf_port_pool = &buf_port->pools[idx];
  11003             buf_port_pool->guarantee = 0;
  11004             buf_port_pool->pool_limit = 0;
  11005             buf_port_pool->pool_resume = 0;
  11006             if (idx == 0) {
  11007                 buf_port_pool->pool_limit = total_pool_size -  mn_mmu_express_buffer_total;
  11008                 buf_port_pool->pool_resume =
  11009                             total_pool_size - (default_mtu_cells * 2) - mn_mmu_express_buffer_total;
  11010             } else if (IS_ROE_ENABLED(unit) && (idx == 1)) {
  11011                 buf_port_pool->pool_limit =  mn_mmu_express_buffer_total;
  11012                 buf_port_pool->pool_resume =
  11013                             mn_mmu_express_buffer_total - (default_mtu_cells * 2) ;
  11014             }
  11015             in_reserved += buf_port_pool->guarantee;
  11016         }
  11017 
  11018         buf_port->pkt_size = max_packet_cells;
  11019         /* priority group */
  11020         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  11021             buf_prigroup = &buf_port->prigroups[idx];
  11022             buf_prigroup->guarantee = 0;
  11023             buf_prigroup->user_delay = -1;
  11024             buf_prigroup->switch_delay = -1;
  11025             buf_prigroup->pkt_size = max_packet_cells;
  11026             buf_prigroup->device_headroom_enable = 0;
  11027             buf_prigroup->pool_limit = 0;
  11028             buf_prigroup->pool_floor = 0;
  11029             buf_prigroup->pool_scale = -1;
  11030             buf_prigroup->headroom = 0;
  11031             buf_prigroup->pool_resume = 0;
  11032             buf_prigroup->flow_control_enable = 0;
  11033             if (idx == 7) {
  11034                 buf_prigroup->device_headroom_enable = 1;
  11035                 buf_prigroup->flow_control_enable = lossless;
  11036                 if (lossless) {
  11037                     buf_prigroup->headroom =
  11038                         _soc_monterey_default_lossless_pg_headroom(unit, port);
  11039                     buf_prigroup->guarantee = pg_min;
  11040                     buf_prigroup->pool_scale = 8;
  11041                     buf_prigroup->pool_resume = default_mtu_cells * 2;
  11042                 }
  11043                 if (!lossless && IS_CPU_PORT(unit, port)) {
  11044                     buf_prigroup->headroom =
  11045                         _soc_monterey_default_lossless_pg_headroom(unit, port);
  11046                 }
  11047             } else { 
  11048                 buf_prigroup->device_headroom_enable = 1;
  11049             }
  11050             in_reserved += buf_prigroup->guarantee + buf_prigroup->headroom;
  11051         }
  11052 
  11053         /* multicast queue */
  11054         for (idx = 0; idx < si->port_num_cosq[port]; idx++) {
  11055             buf_queue = &buf_port->queues[idx];
  11056             buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 0 : -1;
  11057             buf_queue->mcq_entry_guarantee = 0;
  11058             if (lossless) {
  11059                 buf_queue->guarantee = (((1 <= port) && (port <= 64)) ||
  11060                                         IS_CPU_PORT(unit, port) ||
  11061                                         IS_LB_PORT(unit, port)) ? 0 : default_mtu_cells;
  11062                 buf_queue->discard_enable = IS_MACSEC_PORT(unit, port) ? 1 : 0;
  11063                 buf_queue->pool_scale = IS_MACSEC_PORT(unit, port) ? 8 : -1;
  11064                 buf_queue->pool_limit = egr_shared_total;
  11065                 buf_queue->mcqe_limit = mcq_entry_shared_total;
  11066                 buf_queue->yellow_limit = mcq_entry_shared_total;
  11067                 buf_queue->red_limit = mcq_entry_shared_total;
  11068                 buf_queue->color_discard_enable = 0;
  11069                 buf_queue->pool_resume = 16;
  11070             } else {
  11071                 buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 0 : default_mtu_cells;
  11072                 buf_queue->discard_enable = 1;
  11073                 buf_queue->pool_scale = 8;
  11074                 buf_queue->pool_limit = 0;
  11075                 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11076                                             | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11077                 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11078                                          | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11079                 buf_queue->color_discard_enable = 0;
  11080                 buf_queue->pool_resume = 16;
  11081             }
  11082         }
  11083 
  11084         /* unicast queue */
  11085         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
  11086             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
  11087             if (IS_ROE_ENABLED(unit) && (idx == 5 || idx == 7)) {  
  11088                 buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 2 : 1;
  11089             }else { 
  11090                 buf_queue->qgroup_id = ((1 <= port) && (port <= 64)) ? 0 : 1;
  11091             }
  11092             if (lossless) {
  11093                 buf_queue->guarantee = 0;
  11094                 buf_queue->discard_enable = 0;
  11095                 buf_queue->pool_scale = -1;
  11096                 buf_queue->pool_limit = egr_shared_total ;
  11097                 buf_queue->yellow_limit = egr_shared_total;
  11098                 buf_queue->red_limit = egr_shared_total;
  11099                 buf_queue->color_discard_enable = 0;
  11100                 buf_queue->pool_resume = default_mtu_cells * 2;
  11101                 buf_queue->yellow_resume = default_mtu_cells * 2;
  11102                 buf_queue->red_resume = default_mtu_cells * 2;
  11103             } else {
  11104                 if (IS_ROE_ENABLED(unit) && (idx == 1 || idx == 3))  {
  11105                     buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 8 : 0;
  11106                 } else {  
  11107                     buf_queue->guarantee = ((1 <= port) && (port <= 64)) ? 0 : default_mtu_cells;
  11108                 } 
  11109                 buf_queue->discard_enable = 1;
  11110                 buf_queue->pool_scale = 8;
  11111                 buf_queue->pool_limit = 0;
  11112                 buf_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11113                                             | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11114                 buf_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG
  11115                                          | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1;
  11116                 buf_queue->color_discard_enable = 0;
  11117                 buf_queue->pool_resume = default_mtu_cells * 2;
  11118                 buf_queue->yellow_resume = default_mtu_cells * 2;
  11119                 buf_queue->red_resume = default_mtu_cells * 2;
  11120             }
  11121         }
  11122 
  11123         /* queue to pool mapping */
  11124         for (idx = 0;
  11125              idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) {
  11126             if(IS_ROE_ENABLED(unit) && ((idx == 15 || idx == 17) 
  11127                && !IS_CPU_PORT(unit, port))) { 
  11128                buf_port->queues[idx].pool_idx = 1;
  11129             } else { 
  11130                buf_port->queues[idx].pool_idx = 0;
  11131             }
  11132         }
  11133     }
  11134 
  11135     PBMP_ALL_ITER(unit, port) {
  11136         buf_port = &buf->ports[port];
  11137         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  11138              buf_prigroup = &buf_port->prigroups[idx];
  11139              if (!lossless) {
  11140                  if (IS_ROE_ENABLED(unit) && (idx == 5 || idx ==7)) 
  11141                        buf_prigroup->pool_limit = mn_mmu_express_buffer_total;
  11142                  else {  
  11143                        buf_prigroup->pool_limit = total_pool_size - in_reserved - 
  11144                                            mn_mmu_express_buffer_total - 16;
  11145                  }     
  11146              }
  11147        } 
  11148     }
  11149 
  11150     /* RQE */
  11151     for (idx = 0; idx < 11; idx++) {
  11152         buf_rqe_queue = &buf->rqe_queues[idx];
  11153         buf_rqe_queue->pool_idx = 0;
  11154         buf_rqe_queue->yellow_limit = egr_shared_total;
  11155         buf_rqe_queue->red_limit = egr_shared_total;
  11156         if (lossless) {
  11157             buf_rqe_queue->guarantee = 8;
  11158             buf_rqe_queue->discard_enable = 0;
  11159             buf_rqe_queue->pool_scale = -1;
  11160             buf_rqe_queue->pool_limit = egr_shared_total;
  11161         } else {
  11162             buf_rqe_queue->guarantee = default_mtu_cells;
  11163             buf_rqe_queue->discard_enable = 1;
  11164             buf_rqe_queue->pool_scale = 8;
  11165             buf_rqe_queue->pool_limit = 0;
  11166             buf_rqe_queue->yellow_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11167             buf_rqe_queue->red_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG;
  11168         }
  11169     }
  11170 
  11171 }
  11172 
  11173 STATIC int
  11174 _soc_monterey_pool_scale_to_limit(int size, int scale)
  11175 {
  11176     int factor = 1000;
  11177 
  11178     switch (scale) {
  11179         case 7: factor = 875; break;
  11180         case 6: factor = 750; break;
  11181         case 5: factor = 625; break;
  11182         case 4: factor = 500; break;
  11183         case 3: factor = 375; break;
  11184         case 2: factor = 250; break;
  11185         case 1: factor = 125; break;
  11186         case 0:
  11187         default:
  11188             factor = 1000; break;
  11189     }
  11190     return (size * factor)/1000;
  11191 }
  11192 STATIC int
  11193 _soc_monterey_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf,
  11194                                _soc_mmu_device_info_t *devcfg, int lossless,
  11195                                soc_port_t input_port)
  11196 {
  11197     soc_info_t *si;
  11198     _soc_mmu_cfg_buf_pool_t *buf_pool;
  11199     _soc_mmu_cfg_buf_port_t *buf_port;
  11200     _soc_mmu_cfg_buf_prigroup_t *buf_prigroup;
  11201     _soc_mmu_cfg_buf_queue_t *buf_queue;
  11202     _soc_mmu_cfg_buf_port_pool_t *buf_port_pool;
  11203     _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue;
  11204     soc_mem_t mem, mem1, mem2, mem3;
  11205     uint32 rval, fval, rval2, rval3;
  11206     uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS];
  11207     thdi_port_pg_config_entry_t pg_config_mem;
  11208     thdi_port_sp_config_entry_t thdi_sp_config;
  11209     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  11210     mmu_thdu_xpipe_offset_qgroup_entry_t offset_qgrp;
  11211     int default_mtu_cells, limit, midx, pri, rlimit, min_resume_limit;
  11212     int port, base, numq, idx;
  11213     int jumbo_frame_cells, pval, rqlen, qbase;
  11214     _soc_mmu_cfg_buf_qgroup_t *queue_grp;
  11215     int port_count = 0;
  11216     soc_reg_t reg = INVALIDr;
  11217     static const soc_field_t prigroup_reg[] = {
  11218         THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r
  11219     };
  11220     static const soc_field_t prigroup_field[] = {
  11221         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
  11222         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf,
  11223         PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
  11224         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
  11225     };
  11226     static const soc_field_t prigroup_spid_field[] = {
  11227         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  11228         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  11229     };
  11230     int index1;
  11231     int pool_resume = 0;
  11232     uint16      dev_id;
  11233     uint8       rev_id;
  11234     int         ing_rsvd = 0, egr_rsvd = 0, asf_rsvd = 0;
  11235     int total_rsvd = 0 ;
  11236     int  cpu_hdrm = 0; 
  11237     int jumbo_packet_cells = 45;
  11238     soc_cm_get_id(unit, &dev_id, &rev_id);
  11239 
  11240     min_resume_limit = soc_feature(unit, soc_feature_min_resume_limit_1) ? 8 : 0;
  11241 
  11242     si = &SOC_INFO(unit);
  11243 
  11244     jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size +
  11245                                                    devcfg->mmu_hdr_byte,
  11246                                                    devcfg->mmu_cell_size);
  11247     default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size +
  11248                                                    devcfg->mmu_hdr_byte,
  11249                                                    devcfg->mmu_cell_size);
  11250 
  11251     idx = 0 ; 
  11252     rval = 0;
  11253     fval = _MONTEREY_CFAPFULLSETPOINT;
  11254     if (input_port == -1) {
  11255         soc_reg_field_set(unit, CFAPFULLSETPOINTr, &rval, CFAPFULLSETPOINTf,
  11256                 fval);
  11257         SOC_IF_ERROR_RETURN(WRITE_CFAPFULLSETPOINTr(unit, rval));
  11258         rval = 0;
  11259         soc_reg_field_set(unit, CFAPFULLRESETPOINTr, &rval,
  11260                 CFAPFULLRESETPOINTf, fval - 2 * jumbo_frame_cells);
  11261         SOC_IF_ERROR_RETURN(WRITE_CFAPFULLRESETPOINTr(unit, rval));
  11262         rval = 0;
  11263         SOC_IF_ERROR_RETURN(WRITE_TOQ_MC_CFG0r(unit, rval));
  11264     }
  11265     if (asf_rsvd < buf->rsvd_buffers[idx].asf_rsvd_cells) {
  11266             asf_rsvd = buf->rsvd_buffers[idx].asf_rsvd_cells;
  11267     }
  11268     if (egr_rsvd < buf->rsvd_buffers[idx].egr_rsvd_cells) {
  11269            egr_rsvd = buf->rsvd_buffers[idx].egr_rsvd_cells;
  11270     }
  11271     if (ing_rsvd < buf->rsvd_buffers[idx].ing_rsvd_cells) {
  11272             ing_rsvd = buf->rsvd_buffers[idx].ing_rsvd_cells;
  11273     }
  11274     LOG_VERBOSE(BSL_LS_SOC_MMU,
  11275                 (BSL_META_U(unit,
  11276                             "MMU config set HW: Cells rsvd : %d\n"),
  11277                             (ing_rsvd + egr_rsvd + asf_rsvd)));
  11278 
  11279     /* internal priority to priority group mapping */
  11280     PBMP_ALL_ITER(unit, port) {
  11281         if ((input_port != port) &&
  11282                 (input_port != -1)) {
  11283             continue;
  11284         }
  11285         buf_port = &buf->ports[port];
  11286 
  11287         for (idx = 0; idx < 16; idx++) {
  11288             if (idx % 8 == 0) { /* 8 fields per register */
  11289                 reg = prigroup_reg[idx / 8];
  11290                 rval = 0;
  11291             }
  11292             soc_reg_field_set(unit, reg, &rval, prigroup_field[idx],
  11293                               buf_port->pri_to_prigroup[idx]);
  11294             if (idx % 8 == 7) { /* 8 fields per register */
  11295                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
  11296             }
  11297         }
  11298     }
  11299     if (input_port == -1) {
  11300         /* Input thresholds */
  11301         rval = 0;
  11302         soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr,
  11303                 &rval, GLOBAL_HDRM_LIMITf, buf->headroom/2);
  11304         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMIT_PIPEXr,
  11305                     REG_PORT_ANY, 0, rval));
  11306 
  11307 
  11308         fval = 0;
  11309         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11310             if ((buf->pools[idx].size & ~_MMU_CFG_BUF_PERCENT_FLAG) != 0) {
  11311                 fval |= 1 << idx;
  11312             }
  11313         }
  11314 
  11315         rval = 0;
  11316         soc_reg_field_set(unit, THDI_BYPASSr, &rval, INPUT_THRESHOLD_BYPASSf, 0);
  11317         SOC_IF_ERROR_RETURN(WRITE_THDI_BYPASSr(unit, rval));
  11318 
  11319 
  11320         rval = 0;
  11321         soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, COLOR_AWAREf, 0);
  11322         soc_reg_field_set(unit, THDI_POOL_CONFIGr, &rval, PUBLIC_ENABLEf, 1);
  11323         SOC_IF_ERROR_RETURN(WRITE_THDI_POOL_CONFIGr(unit, rval));
  11324 
  11325         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11326             buf_pool = &buf->pools[idx];
  11327             if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  11328                 continue;
  11329             }
  11330             ing_rsvd = buf_pool->prigroup_headroom + buf_pool->prigroup_guarantee;
  11331 
  11332 
  11333             if (lossless) {
  11334                 limit = devcfg->mmu_total_cell - (ing_rsvd+
  11335                         (buf->headroom/2) +
  11336                         buf_pool->queue_guarantee + asf_rsvd);
  11337             } else {
  11338                     cpu_hdrm = _soc_monterey_default_lossless_pg_headroom(
  11339                             unit,
  11340                             CMIC_PORT(unit));
  11341                 if(idx == 0) { 
  11342                    if (IS_ROE_ENABLED(unit)) { 
  11343                        cpu_hdrm = 0 ;
  11344                    }   
  11345                    limit = buf_pool->total -
  11346                    (buf->headroom/2) -  cpu_hdrm - asf_rsvd  - 16 ;
  11347                 } else { 
  11348                    limit = buf_pool->total; 
  11349                 }
  11350             }
  11351 
  11352             PBMP_ALL_ITER(unit, port) {
  11353                 port_count++;
  11354             }
  11355             port_count -= 3; /*macsec, cpu and lb */
  11356             if (IS_ROE_ENABLED(unit)) { 
  11357                 pool_resume = jumbo_packet_cells * 2;
  11358             } else {  
  11359                 pool_resume = (port_count / 2) *  default_mtu_cells;
  11360             }
  11361             rval = 0;
  11362             soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit);
  11363             SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_SPr(unit, idx, rval));
  11364 
  11365             rval = 0;
  11366             soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval,
  11367                     OFFSETf, pool_resume);
  11368             SOC_IF_ERROR_RETURN(WRITE_THDI_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval));
  11369         }
  11370 
  11371         rval = 0;
  11372         SOC_IF_ERROR_RETURN(WRITE_THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr(unit, rval));
  11373 
  11374         /* output thresholds */
  11375         SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval));
  11376         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_QUEUE_AND_GROUP_TICKETf, 1);
  11377         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, ENABLE_UPDATE_COLOR_RESUMEf, 1);
  11378         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  11379         soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  11380         SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval));
  11381 
  11382         SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  11383         soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, MOP_POLICYf, 1);
  11384         SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  11385 
  11386         /* per service pool settings */
  11387         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11388             buf_pool = &buf->pools[idx];
  11389             if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) {
  11390                 continue;
  11391             }
  11392             total_rsvd = buf_pool->queue_guarantee  ;
  11393             if (idx == 0) { 
  11394                 limit = buf_pool->total - (total_rsvd + asf_rsvd +
  11395                                            (IS_ROE_ENABLED(unit) ? 0 : 16));
  11396              } else { 
  11397                 limit = buf_pool->total ;
  11398              }
  11399             if (limit <= 0) {
  11400                 limit = 0;
  11401             }
  11402 
  11403             rval = 0;
  11404             soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval,
  11405                     SHARED_LIMITf, limit);
  11406             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, idx, rval));
  11407 
  11408             rval = 0;
  11409             soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr,
  11410                     &rval, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  11411             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, idx, rval));
  11412 
  11413             rval = 0;
  11414             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr,
  11415                     &rval, RED_SHARED_LIMITf, (limit + 7)/8);
  11416             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, idx, rval));
  11417 
  11418             rval = 0;
  11419             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr,
  11420                     &rval, RESUME_LIMITf, (limit + 7) /8);
  11421             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, idx, rval));
  11422 
  11423             rval = 0;
  11424             soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr,
  11425                     &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8);
  11426             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, idx, rval));
  11427 
  11428             rval = 0;
  11429             soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr,
  11430                     &rval, RED_RESUME_LIMITf, (limit + 7)/8);
  11431             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, idx, rval));
  11432 
  11433             total_rsvd = 0 ;
  11434             total_rsvd = buf_pool->mcq_entry_reserved;
  11435 
  11436             /* mcq entries */
  11437             limit = buf_pool->total_mcq_entry - total_rsvd;
  11438 
  11439             rval = 0;
  11440             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr,
  11441                     &rval, SHARED_LIMITf, limit/4);
  11442             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit,
  11443                         idx, rval));
  11444 
  11445             rval = 0;
  11446             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr,
  11447                     &rval, YELLOW_SHARED_LIMITf, (limit + 7)/ 8);
  11448             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit,
  11449                         idx, rval));
  11450 
  11451             rval = 0;
  11452             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr,
  11453                     &rval, RED_SHARED_LIMITf, (limit + 7)/8);
  11454             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit,
  11455                         idx, rval));
  11456 
  11457             rval = 0;
  11458             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr,
  11459                     &rval, RESUME_LIMITf, (limit + 7)/8);
  11460             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit,
  11461                         idx, rval));
  11462 
  11463             rval = 0;
  11464             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr,
  11465                     &rval, YELLOW_RESUME_LIMITf, (limit + 7)/8);
  11466             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit,
  11467                         idx, rval));
  11468 
  11469             rval = 0;
  11470             soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr,
  11471                     &rval, RED_RESUME_LIMITf, (limit + 7)/8);
  11472             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit,
  11473                         idx, rval));
  11474         }
  11475 
  11476         rval = 0;
  11477         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval,
  11478                 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  11479         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1);
  11480         soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0);
  11481         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval));
  11482 
  11483         rval = 0;
  11484         soc_reg_field_set(unit, MMU_THDR_QE_CONFIGr, &rval,
  11485                 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1);
  11486         SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIGr(unit, rval));
  11487 
  11488         /* configure Q-groups */
  11489         for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) {
  11490             queue_grp = &buf->qgroups[idx];
  11491 
  11492             mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  11493             mem1 = MMU_THDU_XPIPE_OFFSET_QGROUPm;
  11494 
  11495             sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  11496             sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp));
  11497 
  11498             soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11499                     Q_MIN_LIMIT_CELLf, queue_grp->guarantee);
  11500 
  11501             if (queue_grp->pool_scale != -1) {
  11502                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11503                         Q_SHARED_ALPHA_CELLf, queue_grp->pool_scale);
  11504                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11505                         Q_LIMIT_DYNAMIC_CELLf, 1);
  11506             } else {
  11507                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11508                         Q_SHARED_LIMIT_CELLf, queue_grp->pool_limit);
  11509             }
  11510 
  11511             if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  11512                 pval = _soc_monterey_pool_scale_to_limit(queue_grp->pool_limit,
  11513                         queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  11514                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11515                         LIMIT_RED_CELLf, (pval + 7)/8);
  11516 
  11517             } else {
  11518                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11519                         LIMIT_RED_CELLf, queue_grp->red_limit);
  11520                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11521                         Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  11522             }
  11523 
  11524             if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) {
  11525                 pval = _soc_monterey_pool_scale_to_limit(queue_grp->pool_limit,
  11526                         queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG);
  11527                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11528                         LIMIT_YELLOW_CELLf, (pval + 7)/8);
  11529 
  11530             } else {
  11531                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11532                         LIMIT_YELLOW_CELLf, queue_grp->yellow_limit);
  11533                 soc_mem_field32_set(unit, mem, &cfg_qgrp,
  11534                         Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  11535             }
  11536             SOC_IF_ERROR_RETURN
  11537                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  11538 
  11539             soc_mem_field32_set(unit, mem1,
  11540                     &offset_qgrp, RESET_OFFSET_CELLf, queue_grp->pool_resume / 8);
  11541             soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_YELLOW_CELLf,
  11542                     queue_grp->yellow_resume / 8);
  11543             soc_mem_field32_set(unit, mem1, &offset_qgrp , RESET_OFFSET_RED_CELLf,
  11544                     queue_grp->red_resume / 8);
  11545 
  11546             SOC_IF_ERROR_RETURN
  11547                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp));
  11548         }
  11549     }
  11550 
  11551     /* Input port per port settings */
  11552     PBMP_ALL_ITER(unit, port) {
  11553         if ((input_port != port) &&
  11554                 (input_port != -1)) {
  11555             continue;
  11556         }
  11557 
  11558         buf_port = &buf->ports[port];
  11559 
  11560         rval = 0;
  11561         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  11562             soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval,
  11563                               prigroup_spid_field[idx],
  11564                               buf_port->prigroups[idx].pool_idx);
  11565         }
  11566         SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval));
  11567 
  11568         mem = THDI_PORT_SP_CONFIG_Xm;
  11569         /* Per port per pool settings */
  11570         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11571             buf_port_pool = &buf_port->pools[idx];
  11572             midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  11573             sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config));
  11574             soc_mem_field32_set(unit, mem, &thdi_sp_config,
  11575                                 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee);
  11576             soc_mem_field32_set(unit, mem, &thdi_sp_config,
  11577                            PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume);
  11578             soc_mem_field32_set(unit, mem, &thdi_sp_config,
  11579                                PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit);
  11580             SOC_IF_ERROR_RETURN
  11581                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, midx, &thdi_sp_config));
  11582         }
  11583 
  11584         fval = 0;
  11585         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  11586             if (buf_port->prigroups[idx].flow_control_enable != 0) {
  11587                 for (pri=0; pri < 16; pri++) {
  11588                     if (buf_port->pri_to_prigroup[pri] == idx) {
  11589                         fval |= 1 << pri;
  11590                     }
  11591                 }
  11592             }
  11593         }
  11594 
  11595         rval = 0;
  11596         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  11597                                           INPUT_PORT_RX_ENABLEf, 1);
  11598         /* For CPU and MACSEC port we don't configure pause enable */
  11599         if (IS_CPU_PORT(unit, port) || IS_MACSEC_PORT(unit, port)) {
  11600             fval = 0;
  11601         }
  11602         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  11603                           PORT_PRI_XON_ENABLEf, fval);
  11604         soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval,
  11605                           PORT_PAUSE_ENABLEf, fval ? 1 : 0);
  11606         SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval));
  11607 
  11608         rval = 0;
  11609         soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval,
  11610                             PORT_MAX_PKT_SIZEf, buf_port->pkt_size);
  11611         SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval));
  11612 
  11613         /* Input port per port per priority group settings */
  11614         mem = THDI_PORT_PG_CONFIG_Xm;
  11615         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  11616             buf_prigroup = &buf->ports[port].prigroups[idx];
  11617 
  11618             midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  11619             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  11620             soc_mem_field32_set(unit, mem, &pg_config_mem,
  11621                                 PG_MIN_LIMITf, buf_prigroup->guarantee);
  11622 
  11623             if (buf_prigroup->pool_scale != -1) {
  11624                 soc_mem_field32_set(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf, 1);
  11625                 soc_mem_field32_set(unit, mem, &pg_config_mem,
  11626                                     PG_SHARED_LIMITf, buf_prigroup->pool_scale);
  11627             } else {
  11628                 soc_mem_field32_set(unit, mem, &pg_config_mem,
  11629                                    PG_SHARED_LIMITf, buf_prigroup->pool_limit);
  11630             }
  11631 
  11632             soc_mem_field32_set(unit, mem, &pg_config_mem,
  11633                          PG_GBL_HDRM_ENf, buf_prigroup->device_headroom_enable);
  11634             soc_mem_field32_set(unit, mem, &pg_config_mem,
  11635                                        PG_HDRM_LIMITf, buf_prigroup->headroom);
  11636 
  11637             soc_mem_field32_set(unit, mem, &pg_config_mem,
  11638                                  PG_RESET_OFFSETf, buf_prigroup->pool_resume);
  11639 
  11640             soc_mem_field32_set(unit, mem, &pg_config_mem,
  11641                                   PG_RESET_FLOORf, buf_prigroup->pool_floor);
  11642 
  11643             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem,
  11644                                            MEM_BLOCK_ALL, midx, &pg_config_mem));
  11645         }
  11646     }
  11647 
  11648     /***********************************
  11649      * THDO 
  11650  */
  11651     /* Output port per port per queue setting for regular multicast queue */
  11652     PBMP_ALL_ITER(unit, port) {
  11653         if ((input_port != port) &&
  11654                 (input_port != -1)) {
  11655             continue;
  11656         }
  11657 
  11658         numq = si->port_num_cosq[port];
  11659         qbase = si->port_cosq_base[port];
  11660         if (numq == 0) {
  11661             continue;
  11662         }
  11663 
  11664         mem = MMU_THDM_DB_QUEUE_CONFIG_0m;
  11665 
  11666         base = soc_monterey_l2_hw_index(unit, qbase, 0) - _MONTEREY_MC_QUEUE_BASE;
  11667 
  11668         mem1 = MMU_THDM_DB_QUEUE_OFFSET_0m;
  11669         mem2 = MMU_THDM_MCQE_QUEUE_OFFSET_0m;
  11670 
  11671         for (idx = 0; idx < numq; idx++) {
  11672             buf_queue = &buf->ports[port].queues[idx];
  11673 
  11674             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  11675 
  11676             soc_mem_field32_set(unit, mem, entry0,
  11677                                 Q_MIN_LIMITf, buf_queue->guarantee);
  11678             if (buf_queue->discard_enable) {
  11679                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  11680             }
  11681             if (buf_queue->color_discard_enable) {
  11682                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  11683             }
  11684             if (buf_queue->pool_scale != -1) {
  11685                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  11686                 soc_mem_field32_set(unit, mem, entry0,
  11687                            Q_SHARED_ALPHAf, buf_queue->pool_scale);
  11688             } else {
  11689                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  11690                 soc_mem_field32_set(unit, mem, entry0,
  11691                                Q_SHARED_LIMITf, buf_queue->pool_limit);
  11692             }
  11693             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  11694                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  11695                 soc_mem_field32_set(unit, mem, entry0,
  11696                                     Q_COLOR_LIMIT_DYNAMICf, 1);
  11697                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  11698                      buf_queue->yellow_limit
  11699                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11700                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11701                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  11702                      buf_queue->red_limit
  11703                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11704                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11705             } else {
  11706                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  11707                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  11708                      (buf_queue->pool_limit + 7) / 8);
  11709                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  11710                      (buf_queue->pool_limit + 7) / 8);
  11711             }
  11712 
  11713             soc_mem_field32_set(unit, mem, entry0,
  11714                                 Q_SPIDf, buf_queue->pool_idx);
  11715 
  11716             SOC_IF_ERROR_RETURN
  11717                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  11718                                entry0));
  11719 
  11720             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t));
  11721 
  11722             soc_mem_field32_set(unit, mem1, entry0,
  11723                                 RESUME_OFFSETf, (default_mtu_cells * 2)/8);
  11724             soc_mem_field32_set(unit, mem1, entry0,
  11725                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  11726             soc_mem_field32_set(unit, mem1, entry0,
  11727                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
  11728             SOC_IF_ERROR_RETURN
  11729                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  11730                                entry0));
  11731 
  11732             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_0_entry_t));
  11733             soc_mem_field32_set(unit, mem1, entry0,
  11734                     RESUME_OFFSETf, 1);
  11735             SOC_IF_ERROR_RETURN
  11736                 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx,
  11737                                entry0));
  11738 
  11739             SOC_IF_ERROR_RETURN
  11740                 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0,
  11741                                         YELLOW_RESUME_OFFSETf,
  11742                                         2));
  11743 
  11744             SOC_IF_ERROR_RETURN
  11745                 (soc_reg_field32_modify(unit, MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0,
  11746                                         RED_RESUME_OFFSETf,
  11747                                         2));
  11748         }
  11749 
  11750         mem = MMU_THDM_MCQE_QUEUE_CONFIG_0m;
  11751         for (idx = 0; idx < numq; idx++) {
  11752             buf_queue = &buf->ports[port].queues[idx];
  11753 
  11754             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_0_entry_t));
  11755 
  11756             soc_mem_field32_set(unit, mem, entry0,
  11757                                 Q_MIN_LIMITf, buf_queue->mcq_entry_guarantee/4);
  11758             if (buf_queue->discard_enable) {
  11759                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_ENABLEf, 1);
  11760             }
  11761             if (buf_queue->color_discard_enable) {
  11762                 soc_mem_field32_set(unit, mem, entry0, Q_COLOR_LIMIT_ENABLEf, 1);
  11763             }
  11764             if (buf_queue->pool_scale != -1) {
  11765                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMICf, 1);
  11766                 soc_mem_field32_set(unit, mem, entry0,
  11767                            Q_SHARED_ALPHAf, buf_queue->pool_scale);
  11768             } else {
  11769                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  11770                 soc_mem_field32_set(unit, mem, entry0,
  11771                                Q_SHARED_LIMITf, buf_queue->mcqe_limit/4);
  11772             }
  11773             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  11774                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  11775                 soc_mem_field32_set(unit, mem, entry0,
  11776                                     Q_COLOR_LIMIT_DYNAMICf, 1);
  11777                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  11778                      buf_queue->yellow_limit
  11779                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11780                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11781                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  11782                      buf_queue->red_limit
  11783                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11784                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11785             } else {
  11786                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  11787                 soc_mem_field32_set(unit, mem, entry0, YELLOW_SHARED_LIMITf,
  11788                      (buf_queue->yellow_limit + 7) / 8);
  11789                 soc_mem_field32_set(unit, mem, entry0, RED_SHARED_LIMITf,
  11790                      (buf_queue->red_limit + 7)/ 8);
  11791             }
  11792 
  11793             soc_mem_field32_set(unit, mem, entry0,
  11794                                 Q_SPIDf, buf_queue->pool_idx);
  11795 
  11796             SOC_IF_ERROR_RETURN
  11797                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  11798                                entry0));
  11799 
  11800             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_0_entry_t));
  11801 
  11802             soc_mem_field32_set(unit, mem1, entry0,
  11803                                 RESUME_OFFSETf, (default_mtu_cells * 2)/8);
  11804             soc_mem_field32_set(unit, mem1, entry0,
  11805                                 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0);
  11806             soc_mem_field32_set(unit, mem1, entry0,
  11807                                 RED_RESUME_OFFSET_PROFILE_SELf, 0);
  11808             SOC_IF_ERROR_RETURN
  11809                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx,
  11810                                entry0));
  11811 
  11812             SOC_IF_ERROR_RETURN
  11813                 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr, 0,
  11814                                         YELLOW_RESUME_OFFSETf,
  11815                                         1));
  11816 
  11817             SOC_IF_ERROR_RETURN
  11818                 (soc_reg_field32_modify(unit, MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr, 0,
  11819                                         RED_RESUME_OFFSETf,
  11820                                         1));
  11821         }
  11822 
  11823         /* Per  port per pool */
  11824         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11825             buf_pool = &buf->pools[idx];
  11826             if (buf_pool->total == 0  || idx > 0 ) {
  11827                 continue;
  11828             }
  11829 
  11830             if (IS_ROE_ENABLED(unit)) {
  11831                 limit = _MONTEREY_MMU_TOTAL_CELLS - 16  ;
  11832             } else { 
  11833                 limit = buf_pool->total - buf_pool->queue_guarantee  ;
  11834             }
  11835             if ((limit - 2 * default_mtu_cells) > 0) {
  11836                 rlimit = ((limit - 2 * default_mtu_cells) < min_resume_limit) ?
  11837                     min_resume_limit : limit - 2 * default_mtu_cells;
  11838             } else {
  11839                 rlimit = min_resume_limit;
  11840             }
  11841             mem2 = MMU_THDM_DB_PORTSP_CONFIG_0m;
  11842             index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  11843             sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  11844 
  11845             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  11846             soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8);
  11847             soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  11848 
  11849             soc_mem_field32_set(unit, mem2, entry0,
  11850                                             SHARED_LIMIT_ENABLEf, !lossless);
  11851 
  11852             soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf, (rlimit + 7)/8);
  11853             soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf, (rlimit + 7)/8);
  11854             soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf, (rlimit + 7)/8);
  11855 
  11856             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  11857                                 index1, entry0));
  11858 
  11859             mem2 = MMU_THDM_MCQE_PORTSP_CONFIG_0m;
  11860             sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_0_entry_t));
  11861 
  11862             limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved;
  11863             rlimit = (limit < min_resume_limit) ? min_resume_limit : limit;
  11864 
  11865             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, (limit + 3)/4);
  11866             soc_mem_field32_set(unit, mem2, entry0, SHARED_RESUME_LIMITf,
  11867                     ((rlimit/8) - 1));
  11868             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMIT_ENABLEf, !lossless);
  11869             soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, (limit + 7)/8);
  11870             soc_mem_field32_set(unit, mem2, entry0, RED_RESUME_LIMITf,
  11871                     ((rlimit + 7)/8 - 1));
  11872             soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, (limit + 7)/8);
  11873             soc_mem_field32_set(unit, mem2, entry0, YELLOW_RESUME_LIMITf,
  11874                     ((rlimit + 7)/8 -1));
  11875 
  11876             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  11877                                 index1, entry0));
  11878         }
  11879     }
  11880 
  11881     /* Output port per port per queue setting for regular unicast queue */
  11882     PBMP_PORT_ITER(unit, port) {
  11883         if ((input_port != port) &&
  11884                 (input_port != -1)) {
  11885             continue;
  11886         }
  11887 
  11888         if(IS_RDB_PORT(unit, port)) {
  11889             continue;
  11890         }
  11891         /* per port regular unicast queue */
  11892         numq = si->port_num_uc_cosq[port];
  11893         qbase = si->port_uc_cosq_base[port];
  11894         if (numq == 0) {
  11895             continue;
  11896         }
  11897         base = soc_monterey_l2_hw_index(unit, qbase, 1);
  11898         mem = MMU_THDU_XPIPE_CONFIG_QUEUEm;
  11899         mem1 = MMU_THDU_XPIPE_OFFSET_QUEUEm;
  11900         mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm;
  11901         for (idx = 0; idx < numq; idx++) {
  11902             buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx];
  11903 
  11904             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  11905             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_offset_queue_entry_t));
  11906 
  11907             soc_mem_field32_set(unit, mem, entry0,
  11908                                 Q_MIN_LIMIT_CELLf, buf_queue->guarantee);
  11909             if (buf_queue->pool_scale != -1) {
  11910                 soc_mem_field32_set(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf, 1);
  11911                 soc_mem_field32_set(unit, mem, entry0,
  11912                            Q_SHARED_ALPHA_CELLf, buf_queue->pool_scale);
  11913             } else {
  11914                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
  11915                 soc_mem_field32_set(unit, mem, entry0,
  11916                                Q_SHARED_LIMIT_CELLf, buf_queue->pool_limit);
  11917             }
  11918             soc_mem_field32_set(unit, mem1,
  11919                 entry1, RESET_OFFSET_CELLf, buf_queue->pool_resume / 8);
  11920 
  11921             if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  11922                 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  11923                 soc_mem_field32_set(unit, mem, entry0,
  11924                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
  11925                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  11926                      buf_queue->yellow_limit
  11927                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11928                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11929                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  11930                      buf_queue->red_limit
  11931                               & ~_MMU_CFG_BUF_DYNAMIC_FLAG
  11932                               & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1);
  11933             } else {
  11934                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
  11935                 soc_mem_field32_set(unit, mem, entry0, LIMIT_YELLOW_CELLf,
  11936                                          (buf_queue->yellow_limit + 7) / 8);
  11937                 soc_mem_field32_set(unit, mem, entry0, LIMIT_RED_CELLf,
  11938                                          (buf_queue->red_limit + 7) / 8);
  11939             }
  11940             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf,
  11941                                 buf_queue->yellow_resume / 8);
  11942             soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf,
  11943                                 buf_queue->red_resume / 8);
  11944             SOC_IF_ERROR_RETURN
  11945                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  11946 
  11947             SOC_IF_ERROR_RETURN
  11948                 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1));
  11949 
  11950             sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t));
  11951             soc_mem_field32_set(unit, mem2,
  11952                     entry0, Q_SPIDf, buf_queue->pool_idx);
  11953                 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, lossless ? 0 : 1);
  11954                 if (IS_ROE_ENABLED(unit) && (idx ==5 || idx ==7)) {
  11955                     soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf,  0 ) ;
  11956                     soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf,  1);
  11957                     soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf,0);
  11958                 } else { 
  11959                     soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, lossless ? 0 : 1);
  11960                     soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, lossless ? 0 : 1);
  11961                     soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf,lossless ? 0 :1);
  11962                 }
  11963                 soc_mem_field32_set(unit, mem2, entry0, QGROUPf,
  11964                                     (buf_queue->qgroup_id == -1) ? 0 : buf_queue->qgroup_id);
  11965 
  11966             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  11967                                 base + idx, entry0));
  11968         }
  11969 
  11970         /* Per  port per pool unicast */
  11971         for (idx = 0; idx < _MONTEREY_MMU_NUM_POOL; idx++) {
  11972             buf_pool = &buf->pools[idx];
  11973 
  11974             if (buf_pool->total == 0) {
  11975                 continue;
  11976             }
  11977             if (IS_ROE_ENABLED(unit)) {
  11978                 limit = _MONTEREY_MMU_TOTAL_CELLS - 16  ;
  11979             } else { 
  11980                 limit = buf_pool->total - buf_pool->queue_guarantee  ;
  11981             }
  11982             mem2 = MMU_THDU_XPIPE_CONFIG_PORTm;
  11983             index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem2, idx);
  11984             mem3 = MMU_THDU_XPIPE_RESUME_PORTm;
  11985             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  11986             sal_memset(entry1, 0, sizeof(mmu_thdu_xpipe_resume_port_entry_t));
  11987 
  11988             soc_mem_field32_set(unit, mem2, entry0, SHARED_LIMITf, limit);
  11989             soc_mem_field32_set(unit, mem3, entry1,
  11990                          SHARED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  11991 
  11992             soc_mem_field32_set(unit, mem2, entry0, YELLOW_LIMITf, (limit + 7)/8);
  11993             soc_mem_field32_set(unit, mem3, entry1,
  11994                             YELLOW_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  11995 
  11996             soc_mem_field32_set(unit, mem2, entry0, RED_LIMITf, (limit + 7)/8);
  11997             soc_mem_field32_set(unit, mem3, entry1,
  11998                               RED_RESUMEf, ((limit - (default_mtu_cells * 2)) + 7)/8);
  11999 
  12000             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL,
  12001                                 index1, entry0));
  12002             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem3, MEM_BLOCK_ALL,
  12003                                 index1, entry1));
  12004         }
  12005     }
  12006         
  12007 
  12008 
  12009     if (input_port == -1) {
  12010         /* RQE */
  12011         for (idx = 0; idx < 11; idx++) {
  12012             buf_rqe_queue = &buf->rqe_queues[idx];
  12013 
  12014             rval = 0;
  12015             soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr,
  12016                     &rval, MIN_LIMITf, buf_rqe_queue->guarantee);
  12017             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval));
  12018 
  12019             rval = 0;
  12020             rval2 = 0;
  12021             rval3 = 0;
  12022             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  12023                     &rval, SPIDf, buf_rqe_queue->pool_idx);
  12024 
  12025             if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) ||
  12026                     (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) {
  12027                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  12028                         &rval, COLOR_LIMIT_DYNAMICf, 1);
  12029                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  12030                         SHARED_RED_LIMITf, buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  12031                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  12032                         SHARED_YELLOW_LIMITf, buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG);
  12033             } else {
  12034                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  12035                         SHARED_RED_LIMITf, (buf_rqe_queue->red_limit + 7)/ 8);
  12036 
  12037                 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3,
  12038                         SHARED_YELLOW_LIMITf, (buf_rqe_queue->yellow_limit + 7) / 8);
  12039             }
  12040 
  12041             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf,
  12042                     (buf_rqe_queue->discard_enable ? 1 : 0));
  12043 
  12044             if (buf_rqe_queue->pool_scale != -1) {
  12045                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr,
  12046                         &rval, DYNAMIC_ENABLEf, 1);
  12047                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2,
  12048                         SHARED_ALPHAf, buf_rqe_queue->pool_scale);
  12049             } else {
  12050                 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2,
  12051                         SHARED_LIMITf, buf_rqe_queue->pool_limit);
  12052             }
  12053             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 2);
  12054 
  12055             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval));
  12056             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2));
  12057             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  12058 
  12059             rval = 0;
  12060             soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
  12061                     &rval, RESET_OFFSET_REDf, (default_mtu_cells * 2)/8);
  12062             soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr,
  12063                     &rval, RESET_OFFSET_YELLOWf, (default_mtu_cells * 2)/8);
  12064             SOC_IF_ERROR_RETURN(
  12065                     WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  12066 
  12067             /* queue entry */
  12068             buf_pool = &buf->pools[buf_rqe_queue->pool_idx];
  12069             fval = ((buf_pool->total_rqe_entry + 7) / 8);
  12070             rval = 0;
  12071             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr,
  12072                     &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8);
  12073             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval));
  12074 
  12075             rval = 0;
  12076             rval2 = 0;
  12077             rval3 = 0;
  12078             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  12079                     &rval, SPIDf, buf_rqe_queue->pool_idx);
  12080 
  12081             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr,
  12082                     &rval, COLOR_LIMIT_DYNAMICf, lossless ? 0 : 1);
  12083             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
  12084                     &rval3, SHARED_RED_LIMITf, lossless ? fval : 0);
  12085             soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr,
  12086                     &rval3, SHARED_YELLOW_LIMITf, lossless ? fval : 0);
  12087             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, DYNAMIC_ENABLEf,
  12088                     lossless ? 0 :1);
  12089             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf,
  12090                     lossless ? 0 :1);
  12091             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2,
  12092                     SHARED_LIMITf, lossless ? fval : 8);
  12093             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, RESET_OFFSETf, 1);
  12094             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval));
  12095             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2));
  12096             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3));
  12097 
  12098             rval = 0;
  12099             soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
  12100                     &rval, RESET_OFFSET_REDf, default_mtu_cells/8);
  12101             soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr,
  12102                     &rval, RESET_OFFSET_YELLOWf, default_mtu_cells/8);
  12103             SOC_IF_ERROR_RETURN(
  12104                     WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval));
  12105 
  12106         }
  12107 
  12108         /* per pool RQE settings */
  12109         total_rsvd = 0;
  12110         for (idx = 0; idx < 4; idx++) {
  12111             if (idx > 0 && IS_ROE_ENABLED(unit)) { 
  12112                 continue;
  12113             } 
  12114             buf_pool = &buf->pools[idx];
  12115             if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) ||
  12116                     (buf_pool->total == 0)) {
  12117                 continue;
  12118             }
  12119             total_rsvd = buf_pool->queue_guarantee;
  12120             if (idx == 0) {  
  12121                 limit = buf_pool->total - total_rsvd - asf_rsvd - 16;
  12122             } else { 
  12123                 limit = buf_pool->total ;
  12124             }
  12125 
  12126 
  12127             rval = 0;
  12128             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr,
  12129                     &rval, SHARED_LIMITf, limit);
  12130             soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf,
  12131                     (limit - (default_mtu_cells * 2) + 7)/8);
  12132             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr_REG32(unit, idx, rval));
  12133 
  12134             rval = 0;
  12135             soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
  12136                     SHARED_RED_LIMITf, (limit + 7)/8);
  12137             soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval,
  12138                     SHARED_YELLOW_LIMITf, (limit + 7)/8);
  12139             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval));
  12140 
  12141             rval = 0;
  12142             soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
  12143                     RESUME_RED_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8);
  12144             soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval,
  12145                     RESUME_YELLOW_LIMITf, (limit - (default_mtu_cells * 2) + 7)/8);
  12146             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit,
  12147                         idx, rval));
  12148             if (lossless) {
  12149                 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) - 1 ;
  12150             } else {
  12151                 rqlen = ((buf_pool->total_rqe_entry + 7) / 8) ;
  12152             }
  12153             if (rqlen == 0) {
  12154                 continue;
  12155             }
  12156 
  12157             rval = 0;
  12158             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, SHARED_LIMITf, rqlen);
  12159             soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, RESUME_LIMITf, rqlen - 1);
  12160             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval));
  12161 
  12162             rval = 0;
  12163             soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
  12164                     SHARED_RED_LIMITf, rqlen);
  12165             soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval,
  12166                     SHARED_YELLOW_LIMITf, rqlen);
  12167             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, idx, rval));
  12168 
  12169             rval = 0;
  12170             soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
  12171                     RESUME_RED_LIMITf, rqlen - 1);
  12172             soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval,
  12173                     RESUME_YELLOW_LIMITf, rqlen - 1);
  12174             SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit,
  12175                         idx, rval));
  12176         }
  12177 
  12178         /* Device level config setting */
  12179         if (soc_property_get(unit, spn_PORT_UC_MC_ACCOUNTING_COMBINE, 0)) {
  12180             SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval));
  12181             soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval,
  12182                     UC_MC_PORTSP_COMB_ACCT_ENABLEf, 1);
  12183             SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval));
  12184         }
  12185     }
  12186     return SOC_E_NONE;
  12187 }
  12188 
  12189 STATIC int
  12190 _soc_monterey_mmu_config_shared_update_check(int unit, int val1, int val2, int flags)
  12191 {
  12192     int rv = 0;
  12193     if (flags == 1) {
  12194         if (val1 > val2) {
  12195             rv = 1;
  12196         }
  12197     } else {
  12198         if (val1 < val2) {
  12199             rv = 1;
  12200         }
  12201     }
  12202     return rv;
  12203 }
  12204 
  12205 int
  12206 soc_monterey_mmu_config_shared_buf_recalc(int unit, uint32 spid, int shared_size, int flags)
  12207 {
  12208     soc_info_t *si;
  12209     soc_mem_t mem, mem2;
  12210     soc_reg_t reg = INVALIDr;
  12211     soc_field_t field = INVALIDf;
  12212     uint32 rval, rval2;
  12213     uint32 entry0[SOC_MAX_MEM_WORDS];
  12214     thdi_port_pg_config_entry_t pg_config_mem;
  12215     mmu_thdo_config_qgroup_entry_t cfg_qgrp;
  12216     int port, base, qbase, numq, idx;
  12217     int cur_limit, midx, index1;
  12218     int granularity;
  12219     uint16      dev_id;
  12220     uint8       rev_id;
  12221 
  12222     static const soc_field_t pg_spid_field[] = {
  12223         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
  12224         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
  12225     };
  12226 
  12227     if (spid >= _MONTEREY_MMU_NUM_POOL) {
  12228         return SOC_E_PARAM;
  12229     }
  12230     
  12231     soc_cm_get_id(unit, &dev_id, &rev_id);
  12232 
  12233     si = &SOC_INFO(unit);
  12234 
  12235     /* per service pool settings */
  12236     idx = spid;     
  12237     rval = 0;
  12238     reg = MMU_THDM_DB_POOL_SHARED_LIMITr;
  12239     field = SHARED_LIMITf;
  12240     granularity = 1;
  12241     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12242     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12243     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12244         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12245         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12246     }
  12247 
  12248     rval = 0;
  12249     reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr;
  12250     field = YELLOW_SHARED_LIMITf;
  12251     granularity = 8;
  12252     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12253     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12254     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12255         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12256         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12257     }
  12258 
  12259     rval = 0;
  12260     reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr;
  12261     field = RED_SHARED_LIMITf;
  12262     granularity = 8;
  12263     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval));
  12264     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12265     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12266         soc_reg_field_set(unit, reg, &rval, field, (shared_size/granularity)); 
  12267         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval));
  12268     }
  12269 
  12270     /* configure Q-groups */
  12271     mem = MMU_THDU_XPIPE_CONFIG_QGROUPm;
  12272     for (idx = 0; idx < SOC_MONTEREY_MMU_CFG_QGROUP_MAX; idx++) {
  12273         sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp));
  12274 
  12275         SOC_IF_ERROR_RETURN
  12276                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  12277 
  12278         field = Q_SHARED_LIMIT_CELLf;
  12279         granularity = 1;
  12280         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) {
  12281             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12282             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12283                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12284                                     field, shared_size/granularity);
  12285             }
  12286         }
  12287         
  12288         granularity = 8;
  12289         if (!soc_mem_field32_get(unit, mem, &cfg_qgrp,
  12290                                  Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  12291             field = LIMIT_RED_CELLf;
  12292             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12293             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12294                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12295                                     field, shared_size/granularity);
  12296             }
  12297 
  12298             field = LIMIT_YELLOW_CELLf;
  12299             cur_limit = soc_mem_field32_get(unit, mem, &cfg_qgrp, field);
  12300             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12301                 soc_mem_field32_set(unit, mem, &cfg_qgrp, 
  12302                                     field, shared_size/granularity);
  12303             }
  12304         }
  12305 
  12306         SOC_IF_ERROR_RETURN
  12307                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp));
  12308 
  12309     }
  12310 
  12311     /* Input port per port settings */
  12312     PBMP_ALL_ITER(unit, port) {
  12313         rval = 0;
  12314         /* Input port per port per priority group settings */
  12315         mem = THDI_PORT_PG_CONFIG_Xm;
  12316         field = PG_SHARED_LIMITf;
  12317         granularity = 1;
  12318         for (idx = 0; idx < _MONTEREY_MMU_NUM_PG; idx++) {
  12319             SOC_IF_ERROR_RETURN(READ_THDI_PORT_PG_SPIDr(unit, port, &rval));
  12320             if (spid != soc_reg_field_get(unit, THDI_PORT_PG_SPIDr, rval, 
  12321                             pg_spid_field[idx])){
  12322                 continue;
  12323             }
  12324             midx = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12325             sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem));
  12326             SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, 
  12327                                              MEM_BLOCK_ALL, midx, &pg_config_mem));
  12328             if (!soc_mem_field32_get(unit, mem, &pg_config_mem, PG_SHARED_DYNAMICf)) {
  12329                 cur_limit = soc_mem_field32_get(unit, mem, &pg_config_mem, field);
  12330                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12331                     soc_mem_field32_set(unit, mem, &pg_config_mem, 
  12332                                         field, shared_size/granularity);
  12333                 }
  12334             }
  12335         
  12336             SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 
  12337                                            MEM_BLOCK_ALL, midx, &pg_config_mem));
  12338         }
  12339     }
  12340 
  12341     /***********************************
  12342      * THDO 
  12343  */
  12344     /* Output port per port per queue setting for regular multicast queue */
  12345     PBMP_PORT_ITER(unit, port) {
  12346 
  12347         numq = si->port_num_cosq[port];
  12348         qbase = si->port_cosq_base[port];
  12349         if (numq == 0) {
  12350             continue;
  12351         }
  12352 
  12353         mem = MMU_THDM_DB_QUEUE_CONFIG_0m;
  12354         base = soc_monterey_l2_hw_index(unit, qbase, 0) - _MONTEREY_MC_QUEUE_BASE;
  12355 
  12356         for (idx = 0; idx < numq; idx++) {
  12357             sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t));
  12358 
  12359             SOC_IF_ERROR_RETURN
  12360                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  12361 
  12362             if (spid != soc_mem_field32_get(unit, mem, entry0, Q_SPIDf)){
  12363                 continue;
  12364             }
  12365             field = Q_SHARED_LIMITf;
  12366             granularity = 1;
  12367             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) {
  12368                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12369                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12370                     soc_mem_field32_set(unit, mem, entry0, 
  12371                                         field, shared_size/granularity);
  12372                 }
  12373             }
  12374 
  12375             granularity = 8;
  12376             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) {
  12377                 field = YELLOW_SHARED_LIMITf;
  12378                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12379                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12380                     soc_mem_field32_set(unit, mem, entry0, 
  12381                                         field, shared_size/granularity);
  12382                 }
  12383                 field = RED_SHARED_LIMITf;
  12384                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12385                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12386                     soc_mem_field32_set(unit, mem, entry0, 
  12387                                         field, shared_size/granularity);
  12388                 }
  12389             }
  12390             SOC_IF_ERROR_RETURN
  12391                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx,
  12392                                entry0));
  12393         }
  12394 
  12395         /* Per  port per pool */
  12396         idx = spid;    
  12397         mem = MMU_THDM_DB_PORTSP_CONFIG_0m;
  12398         index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12399         sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_0_entry_t));
  12400 
  12401         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 
  12402                             index1, entry0));
  12403 
  12404         field = SHARED_LIMITf;
  12405         granularity = 1;
  12406         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12407         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12408             soc_mem_field32_set(unit, mem, entry0, 
  12409                                 field, shared_size/granularity);
  12410         }
  12411 
  12412         field = RED_SHARED_LIMITf;
  12413         granularity = 8;
  12414         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12415         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12416             soc_mem_field32_set(unit, mem, entry0, 
  12417                                 field, shared_size/granularity);
  12418         }
  12419 
  12420         field = YELLOW_SHARED_LIMITf;
  12421         granularity = 8;
  12422         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12423         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12424             soc_mem_field32_set(unit, mem, entry0, 
  12425                                 field, shared_size/granularity);
  12426         }
  12427         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 
  12428                             index1, entry0));
  12429     }
  12430 
  12431     /* Output port per port per queue setting for regular unicast queue */
  12432     PBMP_PORT_ITER(unit, port) {
  12433         /* per port regular unicast queue */
  12434         numq = si->port_num_uc_cosq[port];
  12435         qbase = si->port_uc_cosq_base[port];
  12436 
  12437         if (numq == 0) {
  12438             continue;
  12439         }
  12440         base = soc_monterey_l2_hw_index(unit, qbase, 1);
  12441         mem = MMU_THDU_XPIPE_CONFIG_QUEUEm;
  12442         mem2 = MMU_THDU_XPIPE_Q_TO_QGRP_MAPm;
  12443         for (idx = 0; idx < numq; idx++) {
  12444             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_q_to_qgrp_map_entry_t));
  12445             SOC_IF_ERROR_RETURN
  12446                 (soc_mem_read(unit, mem2, MEM_BLOCK_ALL, base+idx, entry0));
  12447             if (spid != soc_mem_field32_get(unit, mem2, entry0, Q_SPIDf)){
  12448                 continue;
  12449             }
  12450             sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t));
  12451 
  12452             SOC_IF_ERROR_RETURN
  12453                 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  12454 
  12455             field = Q_SHARED_LIMIT_CELLf;
  12456             granularity = 1;
  12457             if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) {
  12458                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12459                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12460                     soc_mem_field32_set(unit, mem, entry0, 
  12461                                         field, shared_size/granularity);
  12462                 }
  12463             }
  12464 
  12465             granularity = 8;
  12466             if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) {
  12467                 field = LIMIT_YELLOW_CELLf;
  12468                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12469                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12470                     soc_mem_field32_set(unit, mem, entry0, 
  12471                                         field, shared_size/granularity);
  12472                 }
  12473                 field = LIMIT_RED_CELLf;
  12474                 cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12475                 if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12476                     soc_mem_field32_set(unit, mem, entry0, 
  12477                                         field, shared_size/granularity);
  12478                 }
  12479             }
  12480             SOC_IF_ERROR_RETURN
  12481                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, base + idx, entry0));
  12482         }
  12483         
  12484         /* Per  port per pool unicast */
  12485         idx = spid;
  12486         mem = MMU_THDU_XPIPE_CONFIG_PORTm;
  12487         index1 = SOC_MONTEREY_MMU_PIPED_MEM_INDEX(unit, port, mem, idx);
  12488         sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_port_entry_t));
  12489 
  12490         SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, 
  12491                             index1, entry0));
  12492 
  12493         field = SHARED_LIMITf;
  12494         granularity = 1;
  12495         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12496         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12497             soc_mem_field32_set(unit, mem, entry0, 
  12498                                 field, shared_size/granularity);
  12499         }
  12500 
  12501         granularity = 8;
  12502         field = YELLOW_LIMITf;
  12503         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12504         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12505             soc_mem_field32_set(unit, mem, entry0, 
  12506                                 field, shared_size/granularity);
  12507         }
  12508         field = RED_LIMITf;
  12509         cur_limit = soc_mem_field32_get(unit, mem, entry0, field);
  12510         if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12511             soc_mem_field32_set(unit, mem, entry0, 
  12512                                 field, shared_size/granularity);
  12513         }
  12514         
  12515         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 
  12516                             index1, entry0));
  12517     }
  12518 
  12519     /* RQE */
  12520     for (idx = 0; idx < 11; idx++) {
  12521         rval = 0;
  12522         rval2 = 0;
  12523 
  12524         SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval));
  12525         if (spid != soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, SPIDf)){
  12526             continue;
  12527         }
  12528 
  12529         reg = MMU_THDR_DB_CONFIG_PRIQr;
  12530         field = SHARED_LIMITf;
  12531         granularity = 1;
  12532         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  12533         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  12534                                DYNAMIC_ENABLEf)) {
  12535             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  12536             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12537                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  12538                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  12539             }
  12540         }
  12541 
  12542         rval2 = 0;
  12543         reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr;
  12544         granularity = 8;
  12545         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  12546 
  12547         if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval,
  12548                                COLOR_LIMIT_DYNAMICf)) {
  12549             field = SHARED_RED_LIMITf;
  12550             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  12551             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12552                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  12553             }
  12554 
  12555             field = SHARED_YELLOW_LIMITf;
  12556             cur_limit = soc_reg_field_get(unit, reg, rval2, field);
  12557             if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12558                 soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  12559             }
  12560             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  12561         }
  12562 
  12563     }
  12564 
  12565     /* per pool RQE settings */
  12566     idx = spid;    
  12567     reg = MMU_THDR_DB_CONFIG_SPr;
  12568     field = SHARED_LIMITf;
  12569     granularity = 1;
  12570 
  12571     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  12572 
  12573     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12574 
  12575     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)) {
  12576         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity)); 
  12577         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  12578     }
  12579 
  12580     reg = MMU_THDR_DB_SP_SHARED_LIMITr;
  12581     granularity = 8;
  12582 
  12583     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval2));
  12584 
  12585     field =SHARED_YELLOW_LIMITf;
  12586     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12587 
  12588     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){
  12589         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  12590     }
  12591 
  12592     field = SHARED_RED_LIMITf;
  12593     cur_limit = soc_reg_field_get(unit, reg, rval, field);
  12594 
  12595     if (_soc_monterey_mmu_config_shared_update_check(unit, cur_limit, shared_size/granularity, flags)){
  12596         soc_reg_field_set(unit, reg, &rval2, field, (shared_size/granularity));
  12597     }
  12598     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval2));
  12599     return SOC_E_NONE;
  12600 }
  12601 
  12602 int
  12603 soc_monterey_mmu_config_init(int unit, int test_only, soc_port_t port)
  12604 {
  12605     int rv, tport;
  12606     int lossless;
  12607     _soc_mmu_cfg_buf_t *buf;
  12608     _soc_mmu_device_info_t devcfg;
  12609     soc_info_t *si;
  12610 
  12611     buf = soc_mmu_cfg_alloc(unit);
  12612     if (!buf) {
  12613         return SOC_E_MEMORY;
  12614     }
  12615     si = &SOC_INFO(unit);
  12616     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  12617 
  12618     _soc_monterey_mmu_init_dev_config(unit, &devcfg, lossless);
  12619     _soc_monterey_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  12620     if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) {
  12621         _soc_mmu_cfg_buf_read(unit, buf, &devcfg);
  12622     }
  12623     rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg);
  12624     if (!test_only) {
  12625         if (SOC_FAILURE(rv)) {
  12626             LOG_VERBOSE(BSL_LS_SOC_COMMON,
  12627                         (BSL_META_U(unit,
  12628                                     "MMU config: Use default setting\n")));
  12629             _soc_monterey_mmu_config_buf_default(unit, buf, &devcfg, lossless);
  12630             _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg);
  12631             PBMP_ALL_ITER(unit, tport) {
  12632             buf->pools[0].mcq_entry_reserved += (si->port_num_cosq[tport] *
  12633              _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD);
  12634             } 
  12635         }
  12636         PBMP_ALL_ITER(unit, tport) {
  12637             buf->pools[0].mcq_entry_reserved += (si->port_num_cosq[tport] *
  12638              _MN_MMU_PER_COSQ_EGRESS_QENTRY_RSVD);
  12639         }
  12640         rv = _soc_monterey_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, port);
  12641     }
  12642 
  12643     soc_mmu_cfg_free(unit, buf);
  12644 
  12645     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  12646                 (BSL_META_U(unit,
  12647                             "MMU THDI/THDO init done\n")));
  12648     return rv;
  12649 }
  12650 
  12651 STATIC int
  12652 _soc_monterey_mmu_init(int unit)
  12653 {
  12654     uint32 rval;
  12655     uint64 rval64;
  12656     soc_info_t *si;
  12657     int total_entries, clock_period, refresh_time_val;
  12658     int cpu_slots;
  12659     int msbus_idle_enable;
  12660     int alloc_size;
  12661     int port = 0;
  12662 
  12663 
  12664     /*Monterey has fixed 12Mb can not override through OTP */
  12665     _soc_mn_skew_index = 0;
  12666 
  12667     /* MMU Settings Configuration */
  12668     
  12669     SOC_IF_ERROR_RETURN(soc_monterey_mmu_config_init(unit, 0 /* for testing SAL_BOOT_BCMSIM */, -1));
  12670     /* Enable IP to CMICM credit transfer */
  12671     rval = 0;
  12672     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  12673                       TRANSFER_ENABLEf, 1);
  12674     soc_reg_field_set(unit, IP_TO_CMICM_CREDIT_TRANSFERr, &rval,
  12675                       NUM_OF_CREDITSf, 32);
  12676     SOC_IF_ERROR_RETURN(WRITE_IP_TO_CMICM_CREDIT_TRANSFERr(unit, rval));
  12677     COMPILER_64_ZERO(rval64);
  12678     rval = 0;
  12679     SOC_IF_ERROR_RETURN(
  12680                     READ_VBS_FC_CONFIGr(unit, &rval));
  12681     soc_reg_field_set(unit, VBS_FC_CONFIGr, &rval,
  12682                       FORCE_COSMASK_51_48f , 3);
  12683     SOC_IF_ERROR_RETURN(WRITE_VBS_FC_CONFIGr(unit, rval));
  12684 
  12685     rval = 0;
  12686     SOC_IF_ERROR_RETURN(
  12687                     READ_TOQ_STATUSr(unit, &rval));
  12688     soc_reg_field_set(unit, TOQ_STATUSr, &rval,
  12689                       FORCE_INIT_DONEf, 1);
  12690     SOC_IF_ERROR_RETURN(WRITE_TOQ_STATUSr(unit, rval));
  12691 
  12692     if (_fwd_ctrl_lock[unit] == NULL) {
  12693         _fwd_ctrl_lock[unit] = sal_mutex_create("_fwd_ctrl_lock");
  12694     }
  12695     
  12696     if (_fwd_ctrl_lock[unit] == NULL) {
  12697         return SOC_E_MEMORY;
  12698     }
  12699 
  12700     /*mmu traffic control*/
  12701     alloc_size = sizeof(_soc_monterey_mmu_traffic_ctrl_t);
  12702     if (_soc_monterey_mmu_traffic_ctrl[unit] == NULL) {
  12703         _soc_monterey_mmu_traffic_ctrl[unit] = 
  12704             sal_alloc(alloc_size,"_soc_monterey_mmu_traffic_ctrl");
  12705         if (_soc_monterey_mmu_traffic_ctrl[unit] == NULL) {
  12706             return SOC_E_MEMORY;
  12707         }
  12708     }
  12709     sal_memset(_soc_monterey_mmu_traffic_ctrl[unit], 0, alloc_size);
  12710 
  12711 
  12712     /* Enable all ports */
  12713     PBMP_ALL_ITER(unit, port)
  12714     { 
  12715       if (IS_CPU_PORT(unit, port) ||   
  12716           IS_MN_HSP_PORT(unit,port) || 
  12717           IS_MACSEC_PORT(unit,port) ||
  12718           IS_LB_PORT(unit, port))
  12719           { _soc_monterey_thdo_hw_set(unit, port, 1);  
  12720         
  12721        }
  12722     }
  12723     si = &SOC_INFO(unit);
  12724 
  12725     /*
  12726      * Refresh Value = 
  12727      *  ((total no of entities to be refreshed) X Core clk period in ns)/Wred tick period 50 ns
  12728      */
  12729 
  12730     total_entries = 4096 + 1024;
  12731     cpu_slots = (total_entries * 2) / 16; /* 2 slots for every 16 entries refreshed */
  12732     clock_period = (1 * 1000 * 1000) / si->frequency; /*clock period in microseconds */
  12733 
  12734     SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval));    
  12735     msbus_idle_enable = soc_reg_field_get(unit, WRED_REFRESH_CONTROLr,
  12736             rval, MSBUS_IDLE_ENABLEf);
  12737 
  12738     if (msbus_idle_enable) {
  12739         refresh_time_val = ((total_entries + cpu_slots) * clock_period) / 50;
  12740     } else {
  12741         refresh_time_val = (total_entries * clock_period) / 50;
  12742     }
  12743     refresh_time_val = refresh_time_val / 1000;  /* micro to nano seconds */
  12744 
  12745     soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
  12746             REFRESH_TIME_VALf, refresh_time_val);
  12747     soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval,
  12748             REFRESH_DISABLEf, 0);
  12749     SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval));
  12750 
  12751     PBMP_ALL_ITER(unit, port) {
  12752         if (IS_CPU_PORT(unit, port) ||   
  12753             IS_LB_PORT(unit, port))
  12754         {
  12755               continue;
  12756         }
  12757         COMPILER_64_ZERO(rval64);
  12758         soc_reg64_field32_set(unit, INTFO_CONGST_STr, &rval64, ENf, 1);
  12759         SOC_IF_ERROR_RETURN(WRITE_INTFO_CONGST_STr(unit, port, rval64));
  12760         rval = 0;   
  12761         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12762                                                   COS0_E2E_DS_ENf , 1);
  12763         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12764                                                   COS1_E2E_DS_ENf , 1);
  12765         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12766                                                   COS2_E2E_DS_ENf , 1);
  12767         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12768                                                   COS3_E2E_DS_ENf , 1);
  12769         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12770                                                   COS4_E2E_DS_ENf , 1);
  12771         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12772                                                   COS5_E2E_DS_ENf , 1);
  12773         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12774                                                   COS6_E2E_DS_ENf , 1);
  12775         soc_reg_field_set(unit, THDU_PORT_E2ECC_COS_SPIDr, &rval, 
  12776                                                   COS7_E2E_DS_ENf , 1);
  12777         WRITE_THDU_PORT_E2ECC_COS_SPIDr(unit , port , rval);
  12778     }
  12779 
  12780     /*  update port_init_speed array for all ports */
  12781     SOC_IF_ERROR_RETURN(_soc_mn_ports_speed_init_update(unit));
  12782 
  12783     return SOC_E_NONE;
  12784 }
  12785 
  12786 
  12787 STATIC int
  12788 _soc_monterey_age_timer_get(int unit, int *age_seconds, int *enabled)
  12789 {
  12790     soc_control_t *soc = SOC_CONTROL(unit);
  12791     uint32 rval;
  12792 
  12793     if (!soc->l2x_sw_aging) {
  12794         SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval));
  12795         *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf);
  12796         *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf);
  12797     } else {
  12798         *enabled = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  12799                    soc->l2x_age_enable ?
  12800                    1 : 0;
  12801         *age_seconds = soc->l2x_age_pid != SAL_THREAD_ERROR &&
  12802                        soc->l2x_age_enable ?
  12803                        soc->l2x_age_interval : 0;
  12804     }
  12805 
  12806     return SOC_E_NONE;
  12807 }
  12808 
  12809 STATIC int
  12810 _soc_monterey_age_timer_max_get(int unit, int *max_seconds)
  12811 {
  12812     soc_control_t *soc = SOC_CONTROL(unit);
  12813 
  12814     if (!soc->l2x_sw_aging) {
  12815         *max_seconds =
  12816             soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
  12817     } else {
  12818         *max_seconds = 0x7fffffff;
  12819     }
  12820 
  12821     return SOC_E_NONE;
  12822 }
  12823 
  12824 STATIC int
  12825 _soc_monterey_age_timer_set(int unit, int age_seconds, int enable)
  12826 {
  12827     soc_control_t *soc = SOC_CONTROL(unit);
  12828     sal_usecs_t interval = soc->l2x_age_interval;
  12829     uint32 rval = 0;
  12830 
  12831     if (!soc->l2x_sw_aging) {
  12832         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable);
  12833         soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds);
  12834         SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval));
  12835     } else if (soc->l2x_age_interval) {
  12836         if (!enable) {
  12837             soc->l2x_age_enable = 0;
  12838         } else {
  12839             if (age_seconds) {
  12840                 SOC_CONTROL_LOCK(unit);
  12841                 soc->l2x_age_interval = age_seconds;
  12842                 SOC_CONTROL_UNLOCK(unit);
  12843             }
  12844             soc->l2x_age_enable = 1;
  12845             if (interval != age_seconds) {
  12846                 sal_sem_give(soc->l2x_age_notify);
  12847             }
  12848         }
  12849     } else {
  12850         if (enable) {
  12851             SOC_IF_ERROR_RETURN
  12852                 (soc_td2_l2_bulk_age_start(unit, age_seconds));
  12853         }
  12854     }
  12855 
  12856     return SOC_E_NONE;
  12857 }
  12858 
  12859 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \
  12860         ((_phy_reg) |= ((_phyad) & 0x1f) << 19)
  12861 
  12862 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \
  12863         ((_phy_reg) |= ((_phyad) & 0x1f) << 19)
  12864 
  12865 STATIC int
  12866 _soc_monterey_mdio_addr_to_port(uint32 phy_addr)
  12867 {
  12868     int bus, offset = 0;
  12869     int mdio_addr = (phy_addr & 0x1f);
  12870 
  12871     /* Must be internal MDIO address */
  12872     if ((phy_addr & 0x80) == 0) {
  12873         return 0;
  12874     }
  12875 
  12876     bus = PHY_ID_BUS_NUM(phy_addr);
  12877     if (bus > 2) {
  12878         return 0;
  12879     }
  12880 
  12881     switch (bus) {
  12882     case 0: offset = (mdio_addr < 0xd)? 0 : 40; break;
  12883     case 1: offset = (mdio_addr < 0x9)? 12 : 36; break;
  12884     case 2: offset = 20; break;
  12885     }
  12886 
  12887     return (mdio_addr + offset);
  12888 }
  12889 
  12890 STATIC int
  12891 _soc_monterey_mdio_reg_read(int unit, uint32 phy_addr,
  12892                             uint32 phy_reg, uint32 *phy_data)
  12893 {
  12894     int port, phy_port, blk;
  12895     soc_mem_t ucmem_data;
  12896     soc_reg_t ucmem_ctrl;
  12897 
  12898     /* Physical port based on MDIO address */
  12899     phy_port = _soc_monterey_mdio_addr_to_port(phy_addr);
  12900     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
  12901     blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0);
  12902     if ((((phy_port > 0) && (phy_port < 13)) ||
  12903                  ((phy_port > 52) && (phy_port < 65)))
  12904                && !(IS_CPRI_PORT(unit, port))) {
  12905         blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1);
  12906     }
  12907 
  12908     if (soc_monterey_port_is_falcon(unit, phy_port)) {
  12909         if ((((phy_port > 0) && (phy_port < 13)) ||
  12910                  ((phy_port > 52) && (phy_port < 65)))
  12911              && (IS_CPRI_PORT(unit, port)))  {
  12912             ucmem_data = CPMPORT_WC_UCMEM_DATAm;
  12913             ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  12914         } else {
  12915             ucmem_data = CLPORT_WC_UCMEM_DATAm;
  12916             ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  12917         }
  12918     } else {
  12919         ucmem_data = XLPORT_WC_UCMEM_DATAm;
  12920         ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr;
  12921     }
  12922 
  12923     LOG_INFO(BSL_LS_SOC_MII,
  12924              (BSL_META_U(unit,
  12925                          "soc_monterey_mdio_reg_read[%d]: %d/%d/%d\n"),
  12926               unit, phy_addr, phy_port, port));
  12927 
  12928     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
  12929 
  12930     /* Call common S-bus MDIO read function */
  12931     return soc_sbus_mdio_reg_read(unit, port, blk, 0,
  12932                                   phy_addr, phy_reg, phy_data,
  12933                                   ucmem_data, ucmem_ctrl);
  12934 
  12935 }
  12936 
  12937 STATIC int
  12938 _soc_monterey_mdio_reg_write(int unit, uint32 phy_addr,
  12939                              uint32 phy_reg, uint32 phy_data)
  12940 {
  12941     int port, phy_port, blk;
  12942     soc_mem_t ucmem_data;
  12943     soc_reg_t ucmem_ctrl;
  12944 
  12945     /* Physical port based on MDIO address */
  12946     phy_port = _soc_monterey_mdio_addr_to_port(phy_addr);
  12947     port = SOC_INFO(unit).port_p2l_mapping[phy_port];
  12948     blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0);
  12949     if ((((phy_port > 0) && (phy_port < 13)) ||
  12950                  ((phy_port > 52) && (phy_port < 65)))
  12951                && !(IS_CPRI_PORT(unit, port))) {
  12952      blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1);
  12953     }
  12954 
  12955     if (soc_monterey_port_is_falcon(unit, phy_port)) {
  12956         if ((((phy_port > 0) && (phy_port < 13)) ||
  12957                  ((phy_port > 52) && (phy_port < 65)))
  12958                   && (IS_CPRI_PORT(unit, port))) {
  12959             ucmem_data = CPMPORT_WC_UCMEM_DATAm;
  12960             ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  12961         } else {
  12962             ucmem_data = CLPORT_WC_UCMEM_DATAm;
  12963             ucmem_ctrl = CLPORT_WC_UCMEM_CTRLr;
  12964         }
  12965     } else {
  12966         ucmem_data = XLPORT_WC_UCMEM_DATAm;
  12967         ucmem_ctrl = XLPORT_WC_UCMEM_CTRLr;
  12968     }
  12969 
  12970     LOG_INFO(BSL_LS_SOC_MII,
  12971              (BSL_META_U(unit,
  12972                          "soc_monterey_mdio_reg_read[%d]: %d/%d/%d\n"),
  12973               unit, phy_addr, phy_port, port));
  12974 
  12975     TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr);
  12976 
  12977 
  12978     /* Call common S-bus MDIO read function */
  12979     return soc_sbus_mdio_reg_write(unit, port, blk, 0,
  12980                                    phy_addr, phy_reg, phy_data,
  12981                                    ucmem_data, ucmem_ctrl);
  12982 }
  12983 
  12984 static const soc_reg_t pvtmon_result_reg[] = {
  12985     TOP_PVTMON_RESULT_0r, TOP_PVTMON_RESULT_1r,
  12986     TOP_PVTMON_RESULT_2r, TOP_PVTMON_RESULT_3r,
  12987     TOP_PVTMON_RESULT_4r, TOP_PVTMON_RESULT_5r,
  12988     TOP_PVTMON_RESULT_6r, TOP_PVTMON_RESULT_7r,
  12989 };
  12990 
  12991 
  12992 STATIC void
  12993 soc_monterey_temperature_intr(int unit)
  12994 {
  12995     uint32 rval, trval;
  12996     int i, rv;
  12997     soc_port_t port;
  12998     soc_block_t blk;
  12999     soc_block_t xlport_blocks[] = {SOC_BLK_XLPORT, SOC_BLOCK_TYPE_INVALID};
  13000     soc_block_t clport_blocks[] = {SOC_BLK_CLPORT, SOC_BLOCK_TYPE_INVALID};
  13001 
  13002     /* Raise event to app for it to take further graceful actions */
  13003     for (i = 0; i < COUNTOF(pvtmon_result_reg); i++) {
  13004         if ((0x1 << i)  & _soc_mn_temp_mon_mask[unit]) {
  13005             if ((rv = soc_reg32_get(unit, pvtmon_result_reg[i], REG_PORT_ANY, 0,
  13006                                     &trval)) != SOC_E_NONE) {
  13007                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13008                           (BSL_META_U(unit,
  13009                                       "MN Top Intr, Reg access error.\n")));
  13010             }
  13011             trval = soc_reg_field_get(unit, pvtmon_result_reg[i], trval,
  13012                                       PVT_DATAf);
  13013             /* Convert data to temperature.
  13014              * temp = 410.04-(data*0.48705) = (410040-(data*487))/1000
  13015              * Note: Since this is a high temp interrupt we can safely assume
  13016              * that this will end up being a +ive value.
  13017              */
  13018             trval = (410040-(trval*487))/1000;
  13019             LOG_ERROR(BSL_LS_SOC_COMMON,
  13020                       (BSL_META_U(unit,
  13021                                   "TempMon %d: %d deg C.\n"), i, trval));
  13022             (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM,
  13023                                      SOC_SWITCH_EVENT_ALARM_HIGH_TEMP, i, trval);
  13024         }
  13025     }
  13026 
  13027     /* Optionally hold system in reset.
  13028      * Note: The main intention is to stop the chip from getting fried and halt
  13029      *       all schan accesses as the h/w will not respond anymore.
  13030      *       We are not implementing a gracefull recovery, the unit needs to be
  13031      *       rebooted after this.
  13032      */
  13033     if (soc_property_get(unit, "temp_monitor_shutdown", 1)) {
  13034         if ((rv = WRITE_TOP_PVTMON_INTR_MASKr(unit, 0)) != SOC_E_NONE) {
  13035             LOG_ERROR(BSL_LS_SOC_COMMON,
  13036                       (BSL_META_U(unit,
  13037                                   "MN Temp Intr, Reg access error.\n")));
  13038         }
  13039 
  13040         /* Stop all schan transactions on this unit */
  13041 #ifdef  INCLUDE_I2C
  13042         if ((rv = soc_i2c_detach(unit)) != SOC_E_NONE) {
  13043             LOG_ERROR(BSL_LS_SOC_COMMON,
  13044                       (BSL_META_U(unit,
  13045                                   "MN Temp Intr, i2c detach error.\n")));
  13046         }
  13047 #endif
  13048         if (!SOC_IS_RCPU_ONLY(unit)) {
  13049             /* Free up DMA memory */
  13050             if ((rv = soc_dma_detach(unit)) != SOC_E_NONE) {
  13051                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13052                           (BSL_META_U(unit,
  13053                                       "MN Temp Intr, dma detach error.\n")));
  13054             }
  13055         }
  13056 #ifdef INCLUDE_MEM_SCAN        
  13057         if ((rv = soc_mem_scan_stop(unit)) != SOC_E_NONE) {
  13058             LOG_ERROR(BSL_LS_SOC_COMMON,
  13059                       (BSL_META_U(unit,
  13060                                   "MN Temp Intr, mem scan stop error.\n")));
  13061         }
  13062 #endif /* INCLUDE_MEM_SCAN */      
  13063         /* Terminate counter module */
  13064         if ((rv = soc_counter_stop(unit)) != SOC_E_NONE) {
  13065             LOG_ERROR(BSL_LS_SOC_COMMON,
  13066                       (BSL_META_U(unit,
  13067                                   "MN Temp Intr, counter stop error.\n")));
  13068         }
  13069         if (SOC_SBUSDMA_DM_INFO(unit)) {
  13070             if ((rv = soc_sbusdma_desc_detach(unit)) != SOC_E_NONE) {
  13071                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13072                           (BSL_META_U(unit,
  13073                                       "MN Temp Intr, sbusdma stop error.\n")));
  13074             }
  13075         }
  13076         if (soc_feature(unit, soc_feature_arl_hashed)) {
  13077             /* Stop L2X thread */
  13078             if ((rv = soc_l2x_stop(unit)) != SOC_E_NONE) {
  13079                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13080                           (BSL_META_U(unit,
  13081                                       "MN Temp Intr, L2x stop error.\n")));
  13082             }
  13083 
  13084         }
  13085 
  13086         rv = READ_TOP_SOFT_RESET_REGr(unit, &rval);
  13087         if (SOC_E_NONE != rv) {
  13088             LOG_ERROR(BSL_LS_SOC_COMMON,
  13089                       (BSL_META_U(unit,
  13090                                   "MN Temp Intr, Reg access error.\n")));
  13091         }
  13092         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 0);
  13093         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0);
  13094         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 0);
  13095         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 0);
  13096         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_RDB_RST_Lf, 0);
  13097         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW0_RST_Lf, 0);
  13098         soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PGW1_RST_Lf, 0);
  13099         rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval);
  13100         if (SOC_E_NONE != rv) {
  13101             LOG_ERROR(BSL_LS_SOC_COMMON,
  13102                       (BSL_META_U(unit,
  13103                                   "MN Temp Intr, Reg access error.\n")));
  13104         }
  13105 
  13106         if ((rv = READ_TOP_SOFT_RESET_REG_2r(unit, &rval)) != SOC_E_NONE) {
  13107             LOG_ERROR(BSL_LS_SOC_COMMON,
  13108                       (BSL_META_U(unit,
  13109                                   "MN Temp Intr, Reg access error.\n")));
  13110         }
  13111         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf,
  13112                           0);
  13113         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL1_RST_Lf,
  13114                           0);
  13115         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL2_RST_Lf,
  13116                           0);
  13117         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL3_RST_Lf,
  13118                           0);
  13119         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf,
  13120                           1);
  13121         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf,
  13122                           0);
  13123         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf,
  13124                           0);
  13125         soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1);
  13126         if ((rv = WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)) != SOC_E_NONE) {
  13127             LOG_ERROR(BSL_LS_SOC_COMMON,
  13128                       (BSL_META_U(unit,
  13129                                   "MN Temp Intr, Reg access error.\n")));
  13130         }
  13131         /* Powerdown Falcon analog cores */
  13132         SOC_BLOCKS_ITER(unit, blk, clport_blocks) {
  13133             port = SOC_BLOCK_PORT(unit, blk);
  13134             rv = READ_CLPORT_XGXS0_CTRL_REGr(unit, port, &rval);
  13135             if (SOC_E_NONE != rv) {
  13136                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13137                           (BSL_META_U(unit,
  13138                                       "MN Temp Intr, Reg access error.\n")));
  13139             }
  13140             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1);
  13141             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1);
  13142             soc_reg_field_set(unit, CLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0);
  13143             rv = WRITE_CLPORT_XGXS0_CTRL_REGr(unit, port, rval);
  13144             if (SOC_E_NONE != rv) {
  13145                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13146                           (BSL_META_U(unit,
  13147                                       "MN Temp Intr, Reg access error.\n")));
  13148             }
  13149         }
  13150         /* Powerdown Eagle analog cores */
  13151         SOC_BLOCKS_ITER(unit, blk, xlport_blocks) {
  13152             port = SOC_BLOCK_PORT(unit, blk);
  13153             rv = READ_XLPORT_XGXS0_CTRL_REGr(unit, port, &rval);
  13154             if (SOC_E_NONE != rv) {
  13155                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13156                           (BSL_META_U(unit,
  13157                                       "MN Temp Intr, Reg access error.\n")));
  13158             }
  13159             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 1);
  13160             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 1);
  13161             soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 0);
  13162             rv = WRITE_XLPORT_XGXS0_CTRL_REGr(unit, port, rval);
  13163             if (SOC_E_NONE != rv) {
  13164                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13165                           (BSL_META_U(unit,
  13166                                       "MN Temp Intr, Reg access error.\n")));
  13167             }
  13168         }
  13169 
  13170         /* Disable all interrupts */
  13171         soc_cmicm_intr0_disable(unit, ~0);
  13172         soc_cmicm_intr1_disable(unit, ~0);
  13173         soc_cmicm_intr2_disable(unit, ~0);
  13174         soc_cmicm_intr3_disable(unit, ~0);
  13175         soc_cmicm_intr4_disable(unit, ~0);
  13176         soc_cmicm_intr5_disable(unit, ~0);
  13177 
  13178         /* Power down core PLL, once this is done all SCHAN accesses
  13179          * will fail.
  13180          */
  13181         rv = READ_TOP_CORE_PLL_CTRL_1r(unit, &rval);
  13182         if (SOC_E_NONE != rv) {
  13183             LOG_ERROR(BSL_LS_SOC_COMMON,
  13184                       (BSL_META_U(unit,
  13185                                   "MN Temp Intr, Reg access error.\n")));
  13186         }
  13187         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, ISO_INf, 1);
  13188         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRONf, 0);
  13189         soc_reg_field_set(unit, TOP_CORE_PLL_CTRL_1r, &rval, PWRON_LDOf, 0);
  13190         WRITE_TOP_CORE_PLL_CTRL_1r(unit, rval);
  13191         SCHAN_LOCK(unit);
  13192 
  13193         /* Clear all outstanding DPCs owned by this unit */
  13194         sal_dpc_cancel(INT_TO_PTR(unit));
  13195         LOG_ERROR(BSL_LS_SOC_COMMON,
  13196                   (BSL_META_U(unit,
  13197                               "\nReboot the system..")));
  13198     }
  13199 }
  13200 
  13201 
  13202 void
  13203 soc_monterey_top_intr(void *unit_vp, void *d1, void *d2,
  13204                                    void *d3, void *d4)
  13205 {
  13206     uint32 rval, pvtrval;
  13207     int rv, unit = PTR_TO_INT(unit_vp);
  13208 
  13209     if ((rv = READ_TOP_INTR_STATUSr(unit, &rval)) != SOC_E_NONE) {
  13210         LOG_ERROR(BSL_LS_SOC_COMMON,
  13211                   (BSL_META_U(unit,
  13212                               "MN TOP Intr, Reg access error.\n")));
  13213     }
  13214 
  13215     /* Bits 0-17 for PVTMON and rest for AVS */
  13216     pvtrval = rval & ((1 << 18) - 1);
  13217     if (pvtrval) {
  13218         LOG_ERROR(BSL_LS_SOC_COMMON,
  13219                   (BSL_META_U(unit,
  13220                               "High temp interrupt: 0x%08x\n"), rval));
  13221 
  13222         soc_monterey_temperature_intr(unit);
  13223         return;
  13224     }
  13225 
  13226     
  13227 
  13228     return;
  13229 }
  13230 
  13231 int
  13232 soc_monterey_temperature_monitor_get(int unit, 
  13233             int temperature_max,
  13234             soc_switch_temperature_monitor_t *temperature_array,
  13235             int *temperature_count)
  13236 {
  13237     soc_reg_t reg;
  13238     int index;
  13239     uint32 rval;
  13240     int fval, cur, peak,valid = 0 ,done = 0;
  13241     int num_entries_out;
  13242     soc_timeout_t to;
  13243 	
  13244     if (temperature_count) {
  13245         *temperature_count = 0;
  13246     }
  13247     if (COUNTOF(pvtmon_result_reg) > temperature_max) {
  13248         num_entries_out = temperature_max;
  13249     } else {
  13250         num_entries_out = COUNTOF(pvtmon_result_reg);
  13251     }
  13252 
  13253 
  13254     SOC_IF_ERROR_RETURN
  13255         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13256                                    PVTMON_SELECTf, 0));
  13257      /* Sequence for AVS PVTMON measurements starts here
  13258      * Needed before reading Monitor #8: TOP_PVTMON_RESULT_8
  13259      */
  13260     /* Stop on going measurements */
  13261     SOC_IF_ERROR_RETURN
  13262         (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, REG_PORT_ANY,
  13263                                 SEQUENCER_INITf, 1));
  13264     /* Clear all measurements */
  13265     SOC_IF_ERROR_RETURN
  13266         (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, REG_PORT_ANY,
  13267                                 M_INIT_PVT_MNTRf, 0xff));
  13268     SOC_IF_ERROR_RETURN
  13269         (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_MEASUREMENTS_INIT_PVT_MNTRr, REG_PORT_ANY,
  13270                                 M_INIT_PVT_MNTRf, 0x0));
  13271 
  13272     /* Restart measurements */
  13273     SOC_IF_ERROR_RETURN
  13274         (soc_reg_field32_modify(unit, AVS_REG_HW_MNTR_SEQUENCER_INITr, REG_PORT_ANY,
  13275                                 SEQUENCER_INITf, 0));
  13276 
  13277     soc_timeout_init(&to, 1500, 1);
  13278     /* Poll until valid bit is set */
  13279     for (;;) {
  13280         SOC_IF_ERROR_RETURN(READ_AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr(unit,
  13281                             &rval));
  13282         valid = soc_reg_field_get(unit, AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr,
  13283                                   rval, VALID_DATAf);
  13284         done = soc_reg_field_get(unit, AVS_REG_RO_REGISTERS_0_PVT_TEMPERATURE_MNTR_STATUSr,
  13285                                  rval, DONEf);
  13286         if (valid && done) {
  13287             break;
  13288         }
  13289         if (soc_timeout_check(&to)) {
  13290             LOG_ERROR(BSL_LS_SOC_DIAG,
  13291                       (BSL_META_U(unit, "AVS Temperature Monitor: Timeout\n")));
  13292             return SOC_E_INTERNAL;
  13293         }
  13294     }
  13295 
  13296     /* Sequence for AVS PVTMON measurements end here */
  13297     SOC_IF_ERROR_RETURN
  13298         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13299             PVTMON_ADC_RESETBf, 1));
  13300     SOC_IF_ERROR_RETURN
  13301         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13302             PVTMON_ADC_RESETBf, 0));
  13303     SOC_IF_ERROR_RETURN
  13304         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13305             PVTMON_ADC_RESETBf, 1));
  13306 
  13307 
  13308     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  13309     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13310                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13311     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13312                       TOP_PVT_MON_MIN_RST_Lf, 1);
  13313     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13314 
  13315     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13316                       TOP_PVT_MON_MAX_RST_Lf, 0);
  13317     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13318                       TOP_PVT_MON_MIN_RST_Lf, 0);
  13319     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13320 
  13321     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13322                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13323     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13324                       TOP_PVT_MON_MIN_RST_Lf, 1);
  13325     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13326     sal_usleep(1000);
  13327 
  13328     for (index = 0; index < num_entries_out; index++) {
  13329         reg = pvtmon_result_reg[index];
  13330         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13331 
  13332         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13333         cur = (4100400 - (4870 * fval)) / 1000;
  13334         fval = soc_reg_field_get(unit, reg, rval, MIN_PVT_DATAf);
  13335         peak = (4100400 - (4870 * fval)) / 1000;
  13336         (temperature_array + index)->curr = cur;
  13337         (temperature_array + index)->peak    = peak;
  13338     }
  13339     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  13340     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13341                       TOP_PVT_MON_MAX_RST_Lf, 0);
  13342     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13343     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval,
  13344                       TOP_PVT_MON_MAX_RST_Lf, 1);
  13345     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13346 
  13347     if (temperature_count) {
  13348         *temperature_count=num_entries_out;
  13349     }
  13350 
  13351     return SOC_E_NONE;
  13352 }
  13353 
  13354 int
  13355 soc_monterey_show_material_process(int unit)
  13356 {
  13357     soc_reg_t reg;
  13358     int index;
  13359     uint32 rval, fval, nmos[COUNTOF(pvtmon_result_reg)], n_avg, p_avg;
  13360 
  13361     READ_TOP_PVTMON_CTRL_1r(unit, &rval);
  13362     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 0);
  13363     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  13364     sal_usleep(1000);
  13365     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_PWRDNf, 1);
  13366     WRITE_TOP_PVTMON_CTRL_1r(unit, rval);
  13367     sal_usleep(1000);
  13368 
  13369     SOC_IF_ERROR_RETURN
  13370         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_1r, REG_PORT_ANY,
  13371                                 PVTMON_SELECTf, 1));
  13372     sal_usleep(1000);
  13373 
  13374     p_avg = 0;
  13375 
  13376     /* Read NMOS information */
  13377     SOC_IF_ERROR_RETURN
  13378         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  13379                                 MEASUREMENT_CALLIBRATIONf, 5));
  13380 
  13381     sal_usleep(1000);
  13382 
  13383     n_avg = 0;
  13384     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  13385         reg = pvtmon_result_reg[index];
  13386         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13387         nmos[index] = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13388         n_avg += nmos[index];
  13389     }
  13390 
  13391     /* Read PMOS information and print both NMOS and PMOS value */
  13392     SOC_IF_ERROR_RETURN
  13393         (soc_reg_field32_modify(unit, TOP_PVTMON_CTRL_0r, REG_PORT_ANY,
  13394                                 MEASUREMENT_CALLIBRATIONf, 7));
  13395 
  13396     sal_usleep(1000);
  13397 
  13398     p_avg = 0;
  13399     for (index = 0; index < COUNTOF(pvtmon_result_reg); index++) {
  13400         reg = pvtmon_result_reg[index];
  13401         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13402         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13403         p_avg += fval;
  13404 
  13405         LOG_CLI((BSL_META_U(unit,
  13406                    "Material process location %d: NMOS = %3d PMOS = %3d\n"),
  13407                    index, nmos[index], fval));
  13408     }
  13409 
  13410     LOG_CLI((BSL_META_U(unit,
  13411                "Average:                     NMOS = %3d PMOS = %3d\n"),
  13412                n_avg / COUNTOF(pvtmon_result_reg),
  13413                p_avg / COUNTOF(pvtmon_result_reg)));
  13414 
  13415     return SOC_E_NONE;
  13416 }
  13417 
  13418 int
  13419 soc_monterey_show_ring_osc(int unit)
  13420 {
  13421     static const struct {
  13422         int osc_sel;
  13423         soc_field_t field0;
  13424         int value0;
  13425         soc_field_t field1;
  13426         int value1;
  13427         char *name;
  13428     } osc_tbl[] = {
  13429         { 2, IROSC_SELf, 0, INVALIDf, -1, "Core ring 0 five stages" },
  13430         { 2, IROSC_SELf, 1, INVALIDf, -1, "Core ring 0 nine stages" },
  13431         { 3, IROSC_SELf, 0, INVALIDf, -1, "Core ring 1 five stages" },
  13432         { 3, IROSC_SELf, 1, INVALIDf, -1, "Core ring 1 nine stages" },
  13433         { 4, SRAM_OSC_0_PENf, 0, SRAM_OSC_0_NENf, 1, "SRAM ring 0 NMOS" },
  13434         { 5, SRAM_OSC_0_PENf, 1, SRAM_OSC_0_NENf, 0, "SRAM ring 0 PMOS" },
  13435         { 6, SRAM_OSC_1_PENf, 0, SRAM_OSC_1_NENf, 1, "SRAM ring 1 NMOS" },
  13436         { 7, SRAM_OSC_1_PENf, 1, SRAM_OSC_1_NENf, 0, "SRAM ring 1 PMOS" },
  13437         { 8, SRAM_OSC_2_PENf, 0, SRAM_OSC_2_NENf, 1, "SRAM ring 2 NMOS" },
  13438         { 9, SRAM_OSC_2_PENf, 1, SRAM_OSC_2_NENf, 0, "SRAM ring 2 PMOS" },
  13439         { 10, SRAM_OSC_3_PENf, 0, SRAM_OSC_3_NENf, 1, "SRAM ring 3 NMOS" },
  13440         { 11, SRAM_OSC_3_PENf, 1, SRAM_OSC_3_NENf, 0, "SRAM ring 3 PMOS" }
  13441     };
  13442     soc_reg_t ctrl_reg, stat_reg;
  13443     uint32 rval, fval;
  13444     int index, core_clk, quo, rem, frac, retry;
  13445 
  13446     core_clk = SOC_INFO(unit).frequency * 1024;
  13447     ctrl_reg = TOP_RING_OSC_CTRLr;
  13448     stat_reg = TOP_OSC_COUNT_STATr;
  13449 
  13450     for (index = 0; index < COUNTOF(osc_tbl); index++) {
  13451         rval = 0;
  13452         /*
  13453          * set OSC_CNT_RSTBf to 0 to do softreset
  13454          * set OSC_CNT_START to 0 to hold the counter until it selects
  13455          * the input signal
  13456          */
  13457         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  13458         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_ENABLEf, 1);
  13459         soc_reg_field_set(unit, ctrl_reg, &rval, IROSC_ENf, 1);
  13460         soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field0,
  13461                           osc_tbl[index].value0);
  13462         if (osc_tbl[index].field1 != INVALIDf) {
  13463             soc_reg_field_set(unit, ctrl_reg, &rval, osc_tbl[index].field1,
  13464                               osc_tbl[index].value1);
  13465         }
  13466         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_SELf,
  13467                           osc_tbl[index].osc_sel);
  13468         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  13469         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_RSTBf, 1);
  13470         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  13471         soc_reg_field_set(unit, ctrl_reg, &rval, OSC_CNT_STARTf, 1);
  13472         SOC_IF_ERROR_RETURN(WRITE_TOP_RING_OSC_CTRLr(unit, rval));
  13473 
  13474         for (retry = 0; retry < 10; retry++) {
  13475             sal_usleep(1000);
  13476             SOC_IF_ERROR_RETURN(READ_TOP_OSC_COUNT_STATr(unit, &rval));
  13477             if (!soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_DONEf)) {
  13478                 continue;
  13479             }
  13480 
  13481             fval = soc_reg_field_get(unit, stat_reg, rval, OSC_CNT_VALUEf);
  13482             quo = core_clk / fval;
  13483             rem = core_clk - quo * fval;
  13484             frac = (rem * 10000) / fval;
  13485             LOG_CLI((BSL_META_U(unit, "%s: %d.%04d Mhz\n"),
  13486                        osc_tbl[index].name, quo, frac));
  13487             break;
  13488         }
  13489     }
  13490 
  13491     return SOC_E_NONE;
  13492 }
  13493 
  13494 int
  13495 soc_monterey_show_voltage(int unit)
  13496 {
  13497     soc_reg_t reg;
  13498     int index;
  13499     uint32 rval, fval, avg;
  13500 
  13501     SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval));
  13502     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 0);
  13503     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval));
  13504     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_ADC_RESETBf, 1);
  13505     soc_reg_field_set(unit, TOP_PVTMON_CTRL_1r, &rval, PVTMON_SELECTf, 4);
  13506     SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval));
  13507     SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval));
  13508     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 0);
  13509     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13510     soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_PVTMON_RST_Lf, 1);
  13511     SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval));
  13512 
  13513     sal_sleep(1);
  13514     avg = 0;
  13515 
  13516     /* Read Voltages. Ignores result of PVTMON8 */
  13517     for (index = 0; index < COUNTOF(pvtmon_result_reg)  ; index++) {
  13518         reg = pvtmon_result_reg[index];
  13519         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
  13520         fval = soc_reg_field_get(unit, reg, rval, PVT_DATAf);
  13521         /* (PVT_DATA * 880) / 1024 * 0.7 */
  13522         fval = (fval * 880 * 10) / (1024 * 7);
  13523         avg += fval;
  13524         LOG_CLI((BSL_META_U(unit,
  13525                             "Voltage monitor %d: voltage = %d.%03dV\n"),
  13526                  index, (fval/1000), (fval %1000)));
  13527     }
  13528 
  13529     avg /= (COUNTOF(pvtmon_result_reg) );
  13530     LOG_CLI((BSL_META_U(unit,
  13531                         "Average voltage is = %d.%03dV\n"),
  13532              (avg/1000), (avg %1000)));
  13533 
  13534     return SOC_E_NONE;
  13535 }
  13536 
  13537 /*
  13538  * Function:
  13539  *      soc_monterey_process_func_intr
  13540  * Description:
  13541  *      Chip specific DPC function to service interrupts
  13542  * Parameters:
  13543  *      unit_vp       - Device number
  13544  *      d1            - IRQ3 mask
  13545  *      d2            - IRQ3 number (to distinguish between
  13546  *                      different types of interrupts).
  13547  */
  13548 void
  13549 soc_monterey_process_func_intr(void *unit_vp, void *d1, void *d2, void *d3, void *d4)
  13550 {
  13551     int unit = PTR_TO_INT(unit_vp);
  13552     int irq3_num = PTR_TO_INT(d2);
  13553     uint32 rval;
  13554 
  13555     if ((irq3_num == 13) /* L2LU INTR */ &&
  13556         soc_feature(unit, soc_feature_l2_overflow)) {
  13557         if (READ_IL2LU_INTR_STATUSr(unit, &rval)) {
  13558             LOG_ERROR(BSL_LS_SOC_COMMON,
  13559                       (BSL_META_U(unit,
  13560                                   "unit %d: Error reading %s reg !!\n"),
  13561                                   unit, SOC_REG_NAME(unit, IL2LU_INTR_STATUSr)));
  13562             return;
  13563         }
  13564         if (soc_reg_field_get(unit, IL2LU_INTR_STATUSr, rval,
  13565                               L2_LEARN_INSERT_FAILUREf)) {
  13566             soc_td2_l2_overflow_interrupt_handler(unit);
  13567         }
  13568     }
  13569 
  13570     sal_usleep(SAL_BOOT_QUICKTURN ? 100000 : 1000); /* Don't reenable too soon */
  13571     if (d1 != NULL) {
  13572         (void)soc_cmicm_intr3_enable(unit, 
  13573                                      PTR_TO_INT(d1));
  13574     }
  13575 
  13576     return;
  13577 }
  13578 
  13579 int
  13580 soc_monterey_port_asf_speed_set(int unit, soc_port_t port, int speed)
  13581 {
  13582     soc_monterey_port_ct_speed_t asf_speed_mode;
  13583     uint32 rval; 
  13584 
  13585     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  13586     
  13587     switch (speed) {
  13588         case 10:
  13589             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_10M_FULL;
  13590             break;
  13591         case 100:
  13592             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_100M_FULL;
  13593             break;
  13594         case 1000:
  13595             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_1000M_FULL;
  13596             break;
  13597         case 2500:
  13598             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_2500M_FULL;
  13599             break;
  13600         case 5000:
  13601             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_5000M_FULL;
  13602             break;
  13603         case 10000:
  13604             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_10000M_FULL;
  13605             break;
  13606         case 11000:
  13607             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_11000M_FULL;
  13608             break;
  13609         case 20000:
  13610             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_20000M_FULL;
  13611             break;
  13612         case 21000:
  13613             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_21000M_FULL;
  13614             break;
  13615         case 25000:
  13616             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_25000M_FULL;
  13617             break;
  13618         case 27000:
  13619             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_27000M_FULL;
  13620             break;
  13621         case 40000:
  13622             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_40000M_FULL;
  13623             break;
  13624         case 42000:
  13625             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_42000M_FULL;
  13626             break;
  13627         case 50000:
  13628             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_50000M_FULL;
  13629             break;
  13630         case 53000:
  13631             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_53000M_FULL;
  13632             break;
  13633         case 100000:
  13634             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_100000M_FULL;
  13635             break;
  13636         case 106000:
  13637             asf_speed_mode = SOC_MONTEREY_PORT_CT_SPEED_106000M_FULL;
  13638             break;
  13639         case 0:
  13640             return SOC_E_NONE;
  13641         default:
  13642             return SOC_E_PARAM;
  13643     }   
  13644     
  13645     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval,
  13646                       ASF_PORT_SPEEDf, asf_speed_mode);
  13647     
  13648     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));  
  13649     return SOC_E_NONE;
  13650 }
  13651 
  13652 
  13653 int
  13654 soc_monterey_port_asf_set(int unit, soc_port_t port, int speed)
  13655 {
  13656     uint32 rval;
  13657     soc_reg_t reg;
  13658     int mmu_port, phy_port;
  13659     int asf_credit_thresh_lo, asf_credit_thresh_hi;
  13660     int ep_credit_size = 0, pfc_watermark = 0;
  13661     egr_pfc_control_entry_t pfc_control;
  13662     egr_mmu_credit_limit_entry_t egr_mmu_credit_entry;
  13663 
  13664     phy_port = SOC_INFO(unit).port_l2p_mapping[port];
  13665     mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
  13666 if (SOC_IS_MONTEREY(unit)) { 
  13667     return SOC_E_NONE;  
  13668 
  13669 }
  13670     
  13671     if (!soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) {
  13672         if (speed <= 11000) {
  13673             asf_credit_thresh_lo = 4;
  13674             asf_credit_thresh_hi = 9;
  13675         } else if (speed <= 21000) {
  13676             asf_credit_thresh_lo = 8;
  13677             asf_credit_thresh_hi = 18;
  13678         } else if (speed <= 42000) {
  13679             asf_credit_thresh_lo = 18;
  13680             asf_credit_thresh_hi = 36;
  13681         } else {
  13682             asf_credit_thresh_lo = 30;
  13683             asf_credit_thresh_hi = 72;
  13684         }
  13685     } else {
  13686         if (speed <= 11000) {
  13687             asf_credit_thresh_lo = 3;
  13688             asf_credit_thresh_hi = 7;
  13689             ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 7 : 11;
  13690             pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 13 : 19;
  13691         } else if (speed <= 27000) {
  13692             asf_credit_thresh_lo = 4;
  13693             asf_credit_thresh_hi = 12;
  13694             ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 11 : 16;
  13695             pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 25 : 19;
  13696         } else if (speed <= 42000) {
  13697             asf_credit_thresh_lo = 5;
  13698             asf_credit_thresh_hi = 16;
  13699             ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 23 : 20;
  13700             pfc_watermark = 31;
  13701         } else if (speed <= 53000) {
  13702             asf_credit_thresh_lo = 5;
  13703             asf_credit_thresh_hi = 17;
  13704             ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 17 : 23;
  13705             pfc_watermark = IS_OVERSUB_PORT(unit,port) ? 37 : 31;
  13706         } else {
  13707             asf_credit_thresh_lo = 7;
  13708             asf_credit_thresh_hi = 30;
  13709             ep_credit_size = IS_OVERSUB_PORT(unit,port) ? 30 : 39;
  13710             pfc_watermark = 61;
  13711         }
  13712     }
  13713 
  13714     ep_credit_size = ep_credit_size - 1;
  13715     rval = 0;
  13716     reg = ES_PIPE0_ASF_CREDIT_THRESH_LOr;
  13717     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_lo);
  13718     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
  13719 
  13720     rval = 0;
  13721     reg = ES_PIPE0_ASF_CREDIT_THRESH_HIr;
  13722     soc_reg_field_set(unit, reg, &rval, THRESHf, asf_credit_thresh_hi);
  13723     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, mmu_port, rval));
  13724     SOC_IF_ERROR_RETURN(soc_monterey_port_asf_speed_set(unit, port, speed));
  13725 
  13726 
  13727     
  13728     if (soc_property_port_get(unit, port, "pfc_optimized_settings", 1)) {
  13729 
  13730         /* EGR_PFC_CONTROL */
  13731         sal_memset(&pfc_control, 0, sizeof(egr_pfc_control_entry_t));
  13732 
  13733         soc_mem_field32_set(unit, EGR_PFC_CONTROLm, &pfc_control, ENABLEf, 1);
  13734         soc_mem_field32_set(unit, EGR_PFC_CONTROLm, &pfc_control, WATERMARKf, pfc_watermark);
  13735 
  13736         SOC_IF_ERROR_RETURN(WRITE_EGR_PFC_CONTROLm(unit, MEM_BLOCK_ALL, phy_port, &pfc_control));
  13737 
  13738         /* EGR_MMU_CREDIT_LIMIT */
  13739         sal_memset(&egr_mmu_credit_entry, 0, sizeof(egr_mmu_credit_limit_entry_t));
  13740 
  13741         soc_mem_field32_set(unit, EGR_MMU_CREDIT_LIMITm, &egr_mmu_credit_entry, ENABLEf, 1);
  13742         soc_mem_field32_set(unit, EGR_MMU_CREDIT_LIMITm, &egr_mmu_credit_entry, CELL_COUNTSf, ep_credit_size);
  13743 
  13744         SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CREDIT_LIMITm(unit, MEM_BLOCK_ALL, phy_port, &egr_mmu_credit_entry));
  13745     }
  13746 
  13747     return SOC_E_NONE;
  13748 }
  13749 
  13750 int
  13751 soc_monterey_port_speed_update(int unit, soc_port_t port, int speed)
  13752 {
  13753     soc_pbmp_t pbm;
  13754     int lossless;
  13755 
  13756     /* Update Edatabuf transmit start count */
  13757     SOC_PBMP_CLEAR(pbm);
  13758     SOC_PBMP_PORT_ADD(pbm, port);
  13759     SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, 0, pbm));
  13760 
  13761     SOC_IF_ERROR_RETURN(soc_monterey_port_asf_set(unit, port, speed));
  13762 
  13763     /* Update oversubscription buffer manager (OBM) threshold */
  13764     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  13765     SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, FALSE, lossless, port));
  13766 
  13767     SOC_IF_ERROR_RETURN(soc_mn_mmu_delay_insertion_set(unit, port));
  13768 
  13769     return SOC_E_NONE;
  13770 }
  13771 
  13772 
  13773 
  13774 STATIC int
  13775 _soc_monterey_thdo_hw_set(int unit, soc_port_t port, int enable)
  13776 {
  13777     uint64 rval64, rval64_tmp;
  13778     int mmu_port, phy_port, i,mmu_port_tmp;
  13779     soc_info_t *si;
  13780     soc_reg_t reg_tmp;
  13781     soc_reg_t reg[3][2] = {
  13782         {
  13783             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  13784             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  13785         },
  13786         {
  13787             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  13788             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  13789         },
  13790         {
  13791             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  13792             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  13793         }
  13794     };
  13795 
  13796     si = &SOC_INFO(unit);
  13797 
  13798     phy_port = si->port_l2p_mapping[port];
  13799     mmu_port = si->port_p2m_mapping[phy_port];
  13800     if (mmu_port > 67) {
  13801         return SOC_E_PARAM;
  13802     }
  13803 
  13804     for (i = 0; i < 3; i++) {
  13805         COMPILER_64_ZERO(rval64);
  13806         COMPILER_64_ZERO(rval64_tmp);
  13807         if (mmu_port < 64) {
  13808             reg_tmp = reg[i][0];
  13809             mmu_port_tmp = mmu_port; 
  13810         } else {
  13811             if (i == 0) { 
  13812                 continue; 
  13813             } 
  13814             reg_tmp = reg[i][1];
  13815             mmu_port_tmp = mmu_port - 64;
  13816         }
  13817 
  13818         SOC_IF_ERROR_RETURN(
  13819             soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  13820 
  13821         if (mmu_port_tmp < 32) {
  13822             COMPILER_64_SET(rval64_tmp, 0, 1 << mmu_port_tmp);
  13823         } else {
  13824             COMPILER_64_SET(rval64_tmp, 1 << (mmu_port_tmp - 32), 0);
  13825         }
  13826 
  13827         if (enable) {
  13828             COMPILER_64_OR(rval64, rval64_tmp);
  13829         } else {
  13830             COMPILER_64_NOT(rval64_tmp);
  13831             COMPILER_64_AND(rval64, rval64_tmp);
  13832         }
  13833 
  13834         SOC_IF_ERROR_RETURN(
  13835             soc_reg_set(unit, reg_tmp, REG_PORT_ANY, 0, rval64));
  13836     }
  13837 
  13838     return SOC_E_NONE;
  13839 }
  13840 STATIC int
  13841 _soc_monterey_thdo_hw_get(int unit, soc_port_t port, int *enable)
  13842 {
  13843     uint64 rval64;
  13844     int mmu_port, phy_port, i, reg_grp = 0;
  13845     int rv = SOC_E_NONE;
  13846     soc_info_t *si;
  13847     soc_reg_t reg_tmp;
  13848     soc_reg_t reg[3][2] = {
  13849         {
  13850             THDU_OUTPUT_PORT_RX_ENABLE0_64r,
  13851             THDU_OUTPUT_PORT_RX_ENABLE1_64r
  13852         },
  13853         {
  13854             MMU_THDM_DB_PORTSP_RX_ENABLE0_64r,
  13855             MMU_THDM_DB_PORTSP_RX_ENABLE1_64r
  13856         },
  13857         {
  13858             MMU_THDM_MCQE_PORTSP_RX_ENABLE0_64r,
  13859             MMU_THDM_MCQE_PORTSP_RX_ENABLE1_64r
  13860         }
  13861     };
  13862     int max_reg = 3;
  13863 
  13864     si = &SOC_INFO(unit);
  13865 
  13866     phy_port = si->port_l2p_mapping[port];
  13867     mmu_port = si->port_p2m_mapping[phy_port];
  13868 
  13869     COMPILER_64_ZERO(rval64);
  13870     if (mmu_port  < 64 ) {
  13871         mmu_port &= 0x3f;
  13872     } else {
  13873         mmu_port &= 0x7;
  13874         reg_grp = 1;
  13875     }
  13876 
  13877     for (i = 0; i < max_reg; i++) {
  13878         reg_tmp = reg[i][reg_grp];
  13879 
  13880         SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg_tmp, REG_PORT_ANY, 0, &rval64));
  13881 
  13882         if (COMPILER_64_BITTEST(rval64 , mmu_port)) {
  13883             *enable = TRUE;
  13884         } else {
  13885             *enable = FALSE;
  13886         }
  13887     }
  13888     return rv;
  13889 }
  13890 
  13891 /*
  13892  * Function:
  13893  *      _soc_monterey_port_thdo_rx_enable_set
  13894  * Purpose:
  13895  *     enable/disable  the traffic to the port according to
  13896  *     different callers.
  13897  *  the traffic to the port can be enabled only if all of the callers
  13898  *  are to enable it.
  13899  * Parameters:
  13900  *     unit                - (IN) unit number
  13901  *     port                - (IN) local port
  13902  *     enable              - (IN) enable/disable the traffic to the port.
  13903  *     flag                - (IN) different callers.
  13904  * Returns:
  13905  *     BCM_E_XXX
  13906  */
  13907 STATIC int
  13908 _soc_monterey_port_thdo_rx_enable_set(int unit, soc_port_t port, 
  13909                                  int enable, uint8 flag)
  13910 {
  13911     int   rv = SOC_E_NONE;
  13912     uint8 *thdo_drop_bmp;
  13913     _soc_monterey_mmu_traffic_ctrl_t *mmu_traffic_ctrl;
  13914     int cur_enable =0 ;
  13915     FWD_CTRL_LOCK(unit);
  13916 
  13917     mmu_traffic_ctrl = _soc_monterey_mmu_traffic_ctrl[unit];
  13918     if (mmu_traffic_ctrl ==  NULL) {
  13919         FWD_CTRL_UNLOCK(unit);
  13920         return SOC_E_INIT;
  13921     }
  13922     thdo_drop_bmp =
  13923         &(mmu_traffic_ctrl->thdo_drop_bmp[port]);
  13924 
  13925     if (!enable) {
  13926         if (*thdo_drop_bmp & flag) {
  13927             FWD_CTRL_UNLOCK(unit);
  13928             return rv;
  13929         }
  13930 
  13931         if (*thdo_drop_bmp == 0) {
  13932             rv = _soc_monterey_thdo_hw_set(unit, port, enable);
  13933             if (SOC_FAILURE(rv)) {
  13934                 LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Clearing the registers failed.\n")));
  13935                 FWD_CTRL_UNLOCK(unit);
  13936                 return rv;
  13937             }
  13938         }
  13939 
  13940         *thdo_drop_bmp |= flag;
  13941 
  13942         FWD_CTRL_UNLOCK(unit);
  13943         return rv;
  13944     } else {
  13945         if (0 == *thdo_drop_bmp) {
  13946             rv = _soc_monterey_thdo_hw_get(unit, port, &cur_enable);
  13947             if (SOC_FAILURE(rv)) {
  13948                 LOG_ERROR(BSL_LS_SOC_COMMON,
  13949                           (BSL_META_U(unit,
  13950                                       "Get the registers fail.\n")));
  13951                 FWD_CTRL_UNLOCK(unit);
  13952                 return rv;
  13953             }
  13954             /* Warmboot: latest value of *thdo_drop_bmp is not sync to WB cache.
  13955             * We execute "sc controlsync=1" when one port is link up. But when we exit SDK,
  13956             * the port is link down, so the conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  13957             * of the port is zero.  After WarmBoot SDK,
  13958             * we can't set conrresponding bit in THDU_OUTPUT_PORT_RX_ENABLE0_64r
  13959             * for the port when it is link up, because, the value of thdo_drop_bmp is zero.
  13960             */
  13961             if(cur_enable == FALSE) {
  13962                 LOG_INFO(BSL_LS_SOC_COMMON,
  13963                           (BSL_META_U(unit,
  13964                                       "Latest thdo_drop_bmp was not updated to WB cache!!!\n")));
  13965                 *thdo_drop_bmp |= flag;
  13966             }
  13967         }
  13968 
  13969         if (*thdo_drop_bmp != flag) {
  13970             /*other callers are in thdo drop*/
  13971             *thdo_drop_bmp &= ~flag;
  13972             FWD_CTRL_UNLOCK(unit);
  13973             return rv;
  13974         }
  13975 
  13976         /*Ok, only self is in thdo drop, enbable it*/
  13977         rv = _soc_monterey_thdo_hw_set(unit, port, enable);
  13978         if (SOC_FAILURE(rv)) {
  13979             LOG_ERROR(BSL_LS_SOC_COMMON,(BSL_META_U(unit, "Setting the registers failed.\n")));
  13980             FWD_CTRL_UNLOCK(unit);
  13981             return rv;
  13982         }
  13983 
  13984         *thdo_drop_bmp &= ~flag;
  13985 
  13986         FWD_CTRL_UNLOCK(unit);
  13987         return rv;
  13988     }
  13989 
  13990     FWD_CTRL_UNLOCK(unit);
  13991     return rv;
  13992 }
  13993 
  13994 
  13995 int
  13996 soc_monterey_port_traffic_egr_enable_set(int unit, soc_port_t port,
  13997                                int enable)
  13998 {
  13999     return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 
  14000                                             COSQ_SCHED_SET_CTRL);
  14001 }
  14002 
  14003 int
  14004 soc_monterey_port_mmu_tx_enable_set(int unit, soc_port_t port,
  14005                                int enable)
  14006 {
  14007     return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 
  14008                                            MMU_TRAFFIC_EN_CTRL); 
  14009 }
  14010 
  14011 int
  14012 soc_monterey_port_edb_reset(int unit, soc_port_t port) 
  14013 {
  14014      soc_info_t *si = &SOC_INFO(unit);
  14015      uint32 entry[SOC_MAX_MEM_WORDS];
  14016      int phy_port ;
  14017      /* Get physical port */
  14018      phy_port = si->port_l2p_mapping[port];
  14019      if (phy_port == -1) {
  14020            return SOC_E_INTERNAL;
  14021      }
  14022      SOC_IF_ERROR_RETURN
  14023        (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  14024                                           phy_port, entry));
  14025      soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
  14026                          entry, ENABLEf, 1);
  14027      SOC_IF_ERROR_RETURN
  14028      (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  14029                                            phy_port, entry));
  14030      /* Initialize EP credits in MMU */
  14031      SOC_IF_ERROR_RETURN(_soc_monterey_mmu_ep_credit_reset(unit, port));
  14032 
  14033      SOC_IF_ERROR_RETURN
  14034        (READ_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  14035                                           phy_port, entry));
  14036      soc_mem_field32_set(unit, EGR_PER_PORT_BUFFER_SFT_RESETm,
  14037                          entry, ENABLEf, 0);
  14038      SOC_IF_ERROR_RETURN
  14039      (WRITE_EGR_PER_PORT_BUFFER_SFT_RESETm(unit, MEM_BLOCK_ALL,
  14040                                            phy_port, entry));
  14041      return SOC_E_NONE; 
  14042 }
  14043 int
  14044 soc_monterey_port_thdo_rx_enable_set(int unit, soc_port_t port, 
  14045                                      int enable)
  14046 {
  14047     return _soc_monterey_port_thdo_rx_enable_set(unit, port, enable, 
  14048                                             MAC_ENABLE_SET_CTRL);
  14049 }
  14050 
  14051 
  14052 STATIC int
  14053 _soc_mn_resource_data_check(int unit, int num_res, soc_port_resource_t *res)
  14054 {
  14055     int i, j;
  14056     /* null check for all resource data before accessing register */
  14057     for (i = 0 ; i < num_res ; ++i) {
  14058         soc_port_resource_t *p = &res[i];
  14059         if (NULL == p) {
  14060             /* 
  14061             * COVERITY 
  14062             * It is kept intentionally as a defensive check. 
  14063             */
  14064             /* coverity[dead_error_line] */
  14065             return SOC_E_PARAM;
  14066         }
  14067         for (j = 0; j < p->num_lanes ; ++j) {
  14068             soc_port_lane_info_t *p_lane_info = p->lane_info[j];
  14069             if (NULL == p_lane_info) {
  14070                 return SOC_E_PARAM;
  14071             }
  14072         }
  14073     }
  14074     return SOC_E_NONE;
  14075 }
  14076 
  14077 /*
  14078  * Function:
  14079  *      soc_mn_pgw_obm_set
  14080  * Purpose:
  14081  *      Reconfigure PGW_OBM registers in flex port sequence
  14082  *      This function will do two things,
  14083  *      1. clear all registers for old ports which exists in pre-Flex status
  14084  *      2. initialize all registers for new ports which exists in post-Flex status
  14085  *
  14086  * Parameters:
  14087  *      unit         - (IN) Unit number.
  14088  *      pre_num_res  - (IN) Number of resource data which exist in pre-Flex status
  14089  *      post_num_res - (IN) Number of resource data which exist in post-Flex status
  14090  *      pre_res      - (IN) Resource data structure pointer in pre-Flex status
  14091  *      post_res     - (IN) Resource data structure pointer in post-Flex status
  14092  *
  14093  * Returns:
  14094  *      SOC_E_XXX
  14095  */
  14096 int
  14097 soc_mn_pgw_obm_set(int unit,
  14098                      int pre_num_res,  soc_port_resource_t *pre_res,
  14099                      int post_num_res, soc_port_resource_t *post_res)
  14100 {
  14101     int i;
  14102     int port, xlp;
  14103     int lossless;
  14104 
  14105     SOC_IF_ERROR_RETURN(
  14106         _soc_mn_resource_data_check(unit, pre_num_res, pre_res));
  14107     SOC_IF_ERROR_RETURN(
  14108         _soc_mn_resource_data_check(unit, post_num_res, post_res));
  14109 
  14110     lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0);
  14111     for (i = 0; i < pre_num_res; i++) {
  14112         if (pre_res[i].flags & SOC_PORT_RESOURCE_I_MAP) {
  14113             continue;
  14114         }
  14115         if (pre_res[i].physical_port == -1) {
  14116             continue;
  14117         }
  14118         port = pre_res[i].logical_port;
  14119         _soc_monterey_idb_port_init(unit, TRUE, lossless, port);
  14120         xlp = (pre_res[i].physical_port % (MONTEREY_TSCS_PER_PGW * MONTEREY_PGWS_PER_DEV));
  14121         SOC_IF_ERROR_RETURN(_soc_monterey_port_blk_ca_mode_set(unit, TRUE, xlp));
  14122     }
  14123 
  14124     for (i = 0; i < post_num_res; i++) {
  14125         port = post_res[i].logical_port;
  14126         _soc_monterey_idb_port_init(unit, FALSE, lossless, port);
  14127         xlp = SOC_INFO(unit).port_serdes[port];
  14128         SOC_IF_ERROR_RETURN(_soc_monterey_port_blk_ca_mode_set(unit, TRUE, xlp));
  14129     }
  14130 
  14131 
  14132     return SOC_E_NONE;
  14133 }
  14134 
  14135 
  14136 /*
  14137  * Function:
  14138  *      soc_mn_obm_threshold_default_set
  14139  * Purpose:
  14140  *      Reconfigure PGW Threshold in flex port sequence
  14141  *      In this function following registers will be initialized.
  14142  *          PGW_OBM[0-3]_THRESHOLD
  14143  *          PGW_OBM[0-3]_THRESHOLD2
  14144  *      If default_flag is PGW_OBM_INIT_HW_DEFAULT,
  14145  *      register will be intialized by HW reset value
  14146  *      If default_flag is PGW_OBM_INIT_SW_DEFAULT,
  14147  *      register will be intialized by SW reset value
  14148  *
  14149  * Parameters:
  14150  *      unit         - (IN) Unit number
  14151  *      num_res      - (IN) Number of resource
  14152  *      res          - (IN) Resource data structure
  14153  *      lossless     - (IN) Lossless configuration of device
  14154  *      default_flag - (IN) PGW_OBM_INIT_HW_DEFAULT
  14155  *                          Use HW reset value for register value
  14156  *                   - (IN) PGW_OBM_INIT_SW_DEFAULT
  14157  *                          Use SW default value
  14158  *
  14159  * Assumption:
  14160  *      This function cannot access SOC_INFO data structure.
  14161  *      So assume followings condition should be checked
  14162  *      before calling this function.
  14163  *
  14164  *      1. pgw block is valid
  14165  *             si->block_valid[PGW_CL_BLOCK(unit, pgw)] is true
  14166  *      2. port block is used
  14167  *             block = PGW_CL_BLOCK(unit, pgw);
  14168  *             SOC_BLOCK_PORT(unit, block) < 0
  14169  *      3. num_res should be correct number of resource data structure.
  14170  *         all resource data structure should be accessed by using
  14171  *         pointer offset by res_num. If the pointer of resource data is NULL,
  14172  *         returns SOC_E_PARAM.
  14173  *
  14174  * Returns:
  14175  *      SOC_E_XXX
  14176  */
  14177 STATIC
  14178 soc_error_t soc_mn_obm_threshold_default_set(int unit,
  14179                                                int num_res,
  14180                                                soc_port_resource_t *res,
  14181                                                int lossless,
  14182                                                int reset)
  14183 {
  14184     int i;
  14185 
  14186     for (i = 0 ; i < num_res ; ++i) {
  14187 
  14188         
  14189         SOC_IF_ERROR_RETURN(_soc_monterey_idb_port_init(unit, reset, lossless, res->logical_port));
  14190 
  14191     }
  14192 
  14193     return SOC_E_NONE;
  14194 }
  14195 
  14196 STATIC int
  14197 soc_mn_obm_threshold_hw_default_set(int unit, int num_res,
  14198                                       soc_port_resource_t *res,
  14199                                       int lossless)
  14200 {
  14201 
  14202     SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_default_set(unit, num_res, res,
  14203                                                lossless,
  14204                                                TRUE));
  14205     return SOC_E_NONE;
  14206 }
  14207 
  14208 STATIC int
  14209 soc_mn_obm_threshold_sw_default_set(int unit, int num_res,
  14210                                       soc_port_resource_t *res,
  14211                                       int lossless)
  14212 {
  14213     SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_default_set(unit, num_res, res,
  14214                                                lossless,
  14215                                                FALSE));
  14216     return SOC_E_NONE;
  14217 }
  14218 
  14219 /*
  14220  * Function:
  14221  *      soc_mn_obm_threshold_set
  14222  * Purpose:
  14223  *  Reconfigure PGW registers in flex port sequence
  14224  *  In this function PGW OBM threshold registers will be initialized.
  14225  *  This function will do two things,
  14226  *  1. clear all registers for old ports which exists in pre-Flex status
  14227  *  2. initialize all registers for new ports which exists in post-Flex status
  14228  *
  14229  * Parameters:
  14230  *  unit         - (IN) Unit number.
  14231  *  pre_num_res  - (IN) Number of resource data which exist in pre-Flex status
  14232  *  post_num_res - (IN) Number of resource data which exist in post-Flex status
  14233  *  pre_res      - (IN) Resource data structure pointer in pre-Flex status
  14234  *  post_res     - (IN) Resource data structure pointer in post-Flex status
  14235  *  lossless     - (IN) mmu lossless information
  14236  *
  14237  * Returns:
  14238  *  SOC_E_XXX
  14239  *
  14240  * Note : For 100G port, this functions expects the ovsersub field to be
  14241  * disabled.
  14242  */
  14243 soc_error_t soc_mn_obm_threshold_set(int unit,
  14244                          int pre_num_res, soc_port_resource_t *pre_res,
  14245                          int post_num_res, soc_port_resource_t *post_res,
  14246                          int lossless)
  14247 {
  14248     
  14249     SOC_IF_ERROR_RETURN(_soc_mn_resource_data_check(unit, pre_num_res,
  14250                                                       pre_res));
  14251     SOC_IF_ERROR_RETURN(_soc_mn_resource_data_check(unit, post_num_res,
  14252                                                       post_res));
  14253     SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_hw_default_set(unit,
  14254                         pre_num_res, pre_res, lossless));
  14255 
  14256     SOC_IF_ERROR_RETURN(soc_mn_obm_threshold_sw_default_set(unit, 
  14257                         post_num_res, post_res, lossless));
  14258 
  14259     return SOC_E_NONE;
  14260 }
  14261 
  14262 
  14263 /*
  14264  * This function is used to enable or disable cut through when a port is 
  14265  * operating in store and forward mode. 
  14266  * Refer TD2_Cutthrough_programming_guideline.pdf
  14267  * Caller must pass the correct port_info pointer, corresponding to the port
  14268  * being configured (and sent by the BCM layer)
  14269  * To enable cut-through, pass enable = 1
  14270  * To disable cut-through, pass enable = 0
  14271  */
  14272 int
  14273 soc_mn_cut_thru_enable_disable(int unit, soc_port_t port, int enable)
  14274 {
  14275     uint32 rval;
  14276     uint32 speed;
  14277     soc_pbmp_t pbm;
  14278 
  14279     /* Cut-through not supported on non-packet-forwarding ports */
  14280     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  14281         return SOC_E_PORT;
  14282     }
  14283 
  14284     /* When in Oversub, only 40G speeds support CT  */
  14285     speed = SOC_INFO(unit).port_speed_max[port];
  14286     speed = SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(speed);
  14287     if (IS_OVERSUB_PORT(unit, port) && speed != 40000) {
  14288         LOG_ERROR(BSL_LS_SOC_COMMON,
  14289                   (BSL_META_U(unit,
  14290                               "ASF supported only on 40G/42G ports "
  14291                               "when in Oversub\n")));
  14292         return SOC_E_PORT;
  14293     }
  14294 
  14295 
  14296     /* Mask unnecessary bits */
  14297     enable &= 0x1;
  14298 
  14299     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  14300 
  14301     speed = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, ASF_PORT_SPEEDf);
  14302 
  14303     /* Set port speed to 0 */
  14304     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, 0);
  14305     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14306 
  14307     if (!enable) {
  14308         /* Wait 8ms for draining all cells */
  14309         sal_usleep(8000);
  14310     }
  14311 
  14312 
  14313     SOC_PBMP_CLEAR(pbm);
  14314     SOC_PBMP_PORT_ADD(pbm, port);
  14315     SOC_IF_ERROR_RETURN(soc_monterey_ports_edb_config(unit, enable, pbm));
  14316 
  14317 
  14318     /* Set UC_ASF_ENABLE, MC_ASF_ENABLE bits to 1 */
  14319     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, UC_ASF_ENABLEf, enable);
  14320     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, MC_ASF_ENABLEf, enable);
  14321     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14322 
  14323     if (enable) {
  14324         /* Wait 1 micro-sec */
  14325         sal_usleep(1);
  14326     }
  14327 
  14328     soc_reg_field_set(unit, ASF_PORT_CFGr, &rval, ASF_PORT_SPEEDf, speed);
  14329     SOC_IF_ERROR_RETURN(WRITE_ASF_PORT_CFGr(unit, port, rval));
  14330 
  14331     return SOC_E_NONE;
  14332 }
  14333 
  14334 
  14335 int soc_mn_max_speed_port_find(int phy_port, 
  14336                                         soc_port_resource_t *port_info,
  14337                                         int port_info_arr_size) 
  14338 {
  14339     int idx, index, speed;
  14340   
  14341     index = 0;
  14342     speed = port_info[index].speed;
  14343 
  14344     for (idx = 1; idx < port_info_arr_size; idx++) {
  14345         /* If all speeds are equal, '>' will return the 1st index,
  14346          * '>=' will return the last index
  14347          */
  14348         if (port_info[idx].speed > speed) {
  14349             speed = port_info[idx].speed;
  14350             index = idx;
  14351         }
  14352     }
  14353 
  14354     return index;
  14355 }
  14356 
  14357 /*
  14358  * This function checks if cut-through is enabled for a given port.
  14359  * If either unicast or multicast cut-through is enabled, the function
  14360  * returns TRUE else FALSE is returned
  14361  */
  14362 int
  14363 soc_monterey_is_cut_thru_enabled(int unit, soc_port_t port, int *enable)
  14364 {
  14365     uint32 rval;
  14366     uint32 uc_enable, mc_enable;
  14367 
  14368     /* Cut-through not supported on following ports */
  14369     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  14370         return SOC_E_PARAM;
  14371     }
  14372 
  14373     SOC_IF_ERROR_RETURN(READ_ASF_PORT_CFGr(unit, port, &rval));
  14374 
  14375     uc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, UC_ASF_ENABLEf);
  14376     mc_enable = soc_reg_field_get(unit, ASF_PORT_CFGr, rval, MC_ASF_ENABLEf);
  14377 
  14378     if (uc_enable || mc_enable) {
  14379         *enable = TRUE;
  14380     } else {
  14381         *enable = FALSE;
  14382     }
  14383 
  14384     return SOC_E_NONE;
  14385 }
  14386 
  14387 /*
  14388  * This function is used to clear various counters in EP block. The 
  14389  * counters to clear are mentioned in 'Reconfigure EP' section of TD2+ Flexport
  14390  */
  14391 STATIC int soc_mn_ep_counters_clear(int unit, soc_port_resource_t *port_info)
  14392 {
  14393     uint64 val64;
  14394 
  14395     COMPILER_64_ZERO(val64);
  14396 
  14397    SOC_IF_ERROR_RETURN(WRITE_TPCEr(unit, port_info->logical_port, val64));
  14398 
  14399     SOC_IF_ERROR_RETURN(WRITE_TDBGC0r(unit, port_info->logical_port, val64));
  14400     SOC_IF_ERROR_RETURN(WRITE_TDBGC1r(unit, port_info->logical_port, val64));
  14401     SOC_IF_ERROR_RETURN(WRITE_TDBGC2r(unit, port_info->logical_port, val64));
  14402     SOC_IF_ERROR_RETURN(WRITE_TDBGC3r(unit, port_info->logical_port, val64));
  14403     SOC_IF_ERROR_RETURN(WRITE_TDBGC4r(unit, port_info->logical_port, val64));
  14404     SOC_IF_ERROR_RETURN(WRITE_TDBGC5r(unit, port_info->logical_port, val64));
  14405     SOC_IF_ERROR_RETURN(WRITE_TDBGC6r(unit, port_info->logical_port, val64));
  14406     SOC_IF_ERROR_RETURN(WRITE_TDBGC7r(unit, port_info->logical_port, val64));
  14407     SOC_IF_ERROR_RETURN(WRITE_TDBGC8r(unit, port_info->logical_port, val64));
  14408     SOC_IF_ERROR_RETURN(WRITE_TDBGC9r(unit, port_info->logical_port, val64));
  14409     SOC_IF_ERROR_RETURN(WRITE_TDBGC10r(unit, port_info->logical_port, val64));
  14410     SOC_IF_ERROR_RETURN(WRITE_TDBGC11r(unit, port_info->logical_port, val64));
  14411 
  14412     return SOC_E_NONE;
  14413 }
  14414 
  14415 
  14416 STATIC int
  14417 soc_mn_port_resource_tdm_calculate(int unit, soc_monterey_tdm_t *tdm)
  14418 {
  14419     int index;
  14420     soc_info_t *si;
  14421     soc_pbmp_t pbmp;
  14422     int port = 0, slot = 0, phy_port = 0;
  14423     int roe_speed_cpri,roe_speed_rsvd4;
  14424     /* soc info has new values */
  14425     si = &SOC_INFO(unit);
  14426 
  14427     sal_memset(tdm, 0, sizeof(soc_monterey_tdm_t));
  14428 
  14429     PBMP_PORT_ITER(unit, port) {
  14430         if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
  14431             continue;
  14432         }
  14433         phy_port = si->port_l2p_mapping[port];
  14434         tdm->speed[phy_port] = si->port_speed_max[port];
  14435         if(IS_CPRI_PORT(unit,port) || IS_RSVD4_PORT(unit,port)) {
  14436            if (si->port_speed_max[port] > 10100)  {
  14437                tdm->speed[phy_port] = 25000;
  14438            }else { 
  14439                if (SOC_PBMP_MEMBER(si->roe_compression, port)) {
  14440                    roe_speed_cpri = soc_property_port_get(unit, port, spn_CPRI_PORT_INIT_SPEED_ID, -1);
  14441                    roe_speed_rsvd4 =  soc_property_port_get(unit, port, spn_RSVD4_PORT_INIT_SPEED_ID, -1); 
  14442                    if ((roe_speed_cpri > 0) && IS_CPRI_PORT(unit,port)) {
  14443                        if ((roe_speed_cpri > 6144)) {
  14444                             tdm->speed[phy_port] = 25000;
  14445                        } else {
  14446                             tdm->speed[phy_port] = 10000;
  14447                        }
  14448                    } else if ((roe_speed_rsvd4 > 0) && IS_RSVD4_PORT(unit,port)) {
  14449                        if ((roe_speed_cpri > 6144)) {
  14450                             tdm->speed[phy_port] = 25000;
  14451                        } else {
  14452                             tdm->speed[phy_port] = 10000;
  14453                        }
  14454                    } else {
  14455                        if (si->port_speed_max[port] > 6144)  {
  14456                            tdm->speed[phy_port] = 25000;
  14457                        } else {  
  14458                             tdm->speed[phy_port] = 10000;
  14459                        } 
  14460                    }
  14461                } else {
  14462                    tdm->speed[phy_port] = 10000;
  14463                }
  14464            }
  14465                 
  14466         }
  14467             
  14468         MONTEREY_TDM_SPEED_ADJUST(unit, port, tdm->speed[phy_port]);
  14469 
  14470         tdm->port_state[phy_port] =
  14471             IS_OVERSUB_PORT(unit, port) ? PORT_STATE_OVERSUB : PORT_STATE_LINERATE;
  14472 
  14473         /*
  14474          * Primary port will be setup as line-rate or oversub.
  14475          * Subsequent physical ports (sister-ports) will be either
  14476          * DISABLED or SUBPORT/COMBINED mode.
  14477          *
  14478          * TDM Algo expects lanes info based on speed.
  14479          */
  14480         if (soc_monterey_port_is_falcon(unit, phy_port)) { /*  Falcons  */
  14481             if (tdm->speed[phy_port] > 25000) {
  14482                 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
  14483             }
  14484             if (tdm->speed[phy_port] > 50000) {
  14485                 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
  14486                 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
  14487             }
  14488         } else {                                         /*  Eagles  */
  14489             if (tdm->speed[phy_port] > 10000) {
  14490                 tdm->port_state[phy_port + 1] = PORT_STATE_SUBPORT;
  14491             }
  14492             if (tdm->speed[phy_port] > 20000) {
  14493                 tdm->port_state[phy_port + 2] = PORT_STATE_SUBPORT;
  14494                 tdm->port_state[phy_port + 3] = PORT_STATE_SUBPORT;
  14495             }
  14496             if (tdm->speed[phy_port] > 40000) {
  14497                 tdm->port_state[phy_port + 4] = PORT_STATE_SUBPORT;
  14498                 tdm->port_state[phy_port + 5] = PORT_STATE_SUBPORT;
  14499                 tdm->port_state[phy_port + 6] = PORT_STATE_SUBPORT;
  14500                 tdm->port_state[phy_port + 7] = PORT_STATE_SUBPORT;
  14501                 tdm->port_state[phy_port + 8] = PORT_STATE_SUBPORT;
  14502                 tdm->port_state[phy_port + 9] = PORT_STATE_SUBPORT;
  14503             }
  14504         }
  14505     }
  14506     /* CPU, LB and RDB ports */
  14507     tdm->speed[0] = 1000;
  14508     tdm->speed[65] = 1000;
  14509 /*Macsec port is 20G in monterey*/
  14510     tdm->speed[66] = 20000;
  14511     tdm->tdm_bw = si->bandwidth / 1000;
  14512     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  14513     SOC_PBMP_AND(pbmp, si->xpipe_pbm);
  14514     /* tell tdm code the device is oversub if any ports is oversub */
  14515     tdm->is_oversub = SOC_PBMP_NOT_NULL(pbmp);
  14516     SOC_PBMP_ASSIGN(pbmp, si->oversub_pbm);
  14517 
  14518     for (slot = 0; slot <= MONTEREY_MMU_TDM_LENGTH; slot++) {
  14519         tdm->mmu_tdm[slot] = NUM_EXT_PORTS;
  14520     }
  14521 
  14522     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
  14523         LOG_CLI((BSL_META_U(unit, "tdm_bw: %dG\n"), tdm->tdm_bw));
  14524         LOG_CLI((BSL_META_U(unit, "port speed:")));
  14525         for (index = 0; index < NUM_EXT_PORTS; index++) {
  14526             if (index % 8 == 0) {
  14527                 LOG_CLI((BSL_META_U(unit, "\n    ")));
  14528             }
  14529             LOG_CLI((BSL_META_U(unit, " %06d(%03d)"),
  14530                      tdm->speed[index], index));
  14531         }
  14532         LOG_CLI((BSL_META_U(unit, "\n")));
  14533         LOG_CLI((BSL_META_U(unit, "port state map:")));
  14534         for (index = 0; index < NUM_EXT_PORTS; index++) {
  14535             if (index % 8 == 0) {
  14536                 LOG_CLI((BSL_META_U(unit, "\n    ")));
  14537             }
  14538             if (index == 0 || index == (NUM_EXT_PORTS - 1)) {
  14539                 LOG_CLI((BSL_META_U(unit, " --------")));
  14540             } else {
  14541                 LOG_CLI((BSL_META_U(unit, " %03d(%03d)"),
  14542                          tdm->port_state[index], index));
  14543             }
  14544         }
  14545         LOG_CLI((BSL_META_U(unit, "\n")));
  14546     }
  14547 
  14548 
  14549     SOC_IF_ERROR_RETURN(soc_monterey_tdm_calc(unit, tdm));
  14550 
  14551 
  14552     return SOC_E_NONE;
  14553 }
  14554 
  14555 
  14556 
  14557 STATIC int
  14558 soc_mn_ovr_sub_tdm_update(int unit,
  14559                           soc_monterey_tdm_t *tdm,
  14560                           int pre_count,
  14561                           soc_port_resource_t *pre_res,
  14562                           int post_count,
  14563                           soc_port_resource_t *post_res)
  14564 {
  14565     int phy_port;
  14566     int group, wt_group, speed_group;
  14567     int res_count, speed_class;
  14568     int slot, empty_slot_cnt;
  14569     uint32 speed_spacing;
  14570     soc_monterey_tdm_t *cur_tdm;
  14571 
  14572 
  14573     tdm = MONTEREY_TDM_STRUCT_BACKUP(unit);
  14574     cur_tdm = MONTEREY_TDM_STRUCT_ACTIVE(unit);
  14575 
  14576     /* Remove old ports from the existing egress overusb groups */
  14577     for (res_count = 0; res_count < pre_count; res_count++) {
  14578         soc_port_resource_t *p = &pre_res[res_count];
  14579 
  14580         /* If OBM is not enabled then continue */
  14581         if (!p->oversub) {
  14582             continue;
  14583         }
  14584 
  14585         if (p->flags & SOC_PORT_RESOURCE_INACTIVE) {
  14586             continue;
  14587         }
  14588 
  14589         phy_port = p->physical_port;
  14590 
  14591         for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
  14592             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) {
  14593                 continue;
  14594             }
  14595             empty_slot_cnt = 0;
  14596             for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
  14597                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] == phy_port) {
  14598                     cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = NUM_EXT_PORTS;
  14599 
  14600                 }
  14601                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) {
  14602                     empty_slot_cnt++;
  14603                 }
  14604             }
  14605 
  14606             /* Mark group that has no more valid mmu ports as free */
  14607             if (empty_slot_cnt == MONTEREY_MMU_OVS_GROUP_TDM_LENGTH) {
  14608                 MONTEREY_TDM_WT_GRP_FREE(unit, cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group]);
  14609                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = 0;
  14610                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = MONTEREY_MMU_OVS_WT_GROUP_COUNT;
  14611                 break;
  14612             }
  14613          }
  14614     }
  14615 
  14616     /* Add 'new' ports to the egress schedulers */
  14617     for (res_count = 0; res_count < post_count; res_count++) {
  14618         soc_port_resource_t *p = &post_res[res_count];
  14619 
  14620         /* If OBM is not enabled then continue */
  14621         if (!p->oversub) {
  14622             continue;
  14623         }
  14624 
  14625         if (p->flags & SOC_PORT_RESOURCE_INACTIVE) {
  14626             continue;
  14627         }
  14628 
  14629         speed_class = p->speed;
  14630         phy_port = p->physical_port;
  14631 
  14632        
  14633         if (SOC_FAILURE(_soc_monterey_mmu_ovs_speed_class_map_get(
  14634                         unit, &speed_class, &speed_group, &speed_spacing))) {
  14635 
  14636             LOG_ERROR(BSL_LS_SOC_PORT,
  14637                       (BSL_META_U(unit,
  14638                                   "Invalid Speed Class %d for port %d (physical = %d)"),
  14639                        speed_class, p->logical_port, phy_port));
  14640 
  14641             return SOC_E_INTERNAL;
  14642         }
  14643 
  14644         MONTEREY_TDM_WT_GRP_LOG(unit);
  14645 
  14646         /* Try to fit the new port in the group with same speed ports */
  14647         for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
  14648             /* Group with different speed ports; skip! */
  14649             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] != speed_class) {
  14650                 continue;
  14651             }
  14652 
  14653             for (slot = 0; slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH; slot++) {
  14654                 /*  break when an empty slot is found */
  14655                 if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] >= NUM_EXT_PORTS) {
  14656                     break;
  14657                 }
  14658             }
  14659             if (slot < MONTEREY_MMU_OVS_GROUP_TDM_LENGTH) {
  14660                 cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][slot] = phy_port;
  14661                 phy_port = NUM_EXT_PORTS;
  14662                 break;
  14663             }
  14664         }
  14665 
  14666         if (phy_port == NUM_EXT_PORTS) {
  14667             /* Found an empty slot and filled; continue to next */
  14668             continue;
  14669         }
  14670 
  14671         /* Could not get a group with same speed ports, try a free group  */
  14672         for (group = 0; group < MONTEREY_MMU_OVS_GROUP_COUNT; group++) {
  14673             if (cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] == 0) {
  14674                 break;
  14675             }
  14676         }
  14677 
  14678         if (group < MONTEREY_MMU_OVS_GROUP_COUNT) {
  14679             cur_tdm->egress_ovs_tdm.mmu_ovs_group_tdm[group][0] = phy_port;
  14680             cur_tdm->egress_ovs_tdm.mmu_ovs_group_speed[group] = speed_class;
  14681 
  14682             for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
  14683                 if (MN_TDM_WT_GRP_SPG_GET(unit, wt_group) == speed_group) {
  14684                     MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
  14685                     break;
  14686                 }
  14687             }
  14688 
  14689             if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) {
  14690                 for (wt_group = 0; wt_group < MONTEREY_MMU_OVS_WT_GROUP_COUNT; wt_group++) {
  14691                     if (MN_TDM_WT_GRP_REFCNT_GET(unit, wt_group) == 0) {
  14692                         MONTEREY_TDM_WT_GRP_RESERVE(unit, wt_group, speed_group);
  14693                         break;
  14694                     }
  14695                 }
  14696             }
  14697 
  14698             if (wt_group >= MONTEREY_MMU_OVS_WT_GROUP_COUNT) {
  14699                 /* We could not find a weight group for this new port */
  14700                 LOG_ERROR(BSL_LS_SOC_PORT,
  14701                     (BSL_META_U(unit,
  14702                                 "Could not find a usable weight group for "
  14703                                 "port %d (physical = %d; speed_class = %d)"),
  14704                     p->logical_port, phy_port, speed_class));
  14705                 return SOC_E_INTERNAL;
  14706             }
  14707 
  14708             cur_tdm->egress_ovs_tdm.mmu_ovs_group_wt_group[group] = wt_group;
  14709 
  14710             continue;
  14711         }
  14712 
  14713         /* We could not find a group that can fit this new port */
  14714         LOG_ERROR(BSL_LS_SOC_PORT,
  14715                   (BSL_META_U(unit,
  14716                               "Could not find a usable oversub group for "
  14717                               "port %d (physical = %d; speed_class = %d)"),
  14718                    p->logical_port, phy_port, speed_class));
  14719 
  14720         return SOC_E_INTERNAL;
  14721      }
  14722 
  14723     sal_memcpy(&(tdm->egress_ovs_tdm), &(cur_tdm->egress_ovs_tdm), sizeof(tdm->egress_ovs_tdm));
  14724 
  14725     return SOC_E_NONE;
  14726 }
  14727 
  14728 
  14729 /*
  14730  * Function:
  14731  *      soc_mn_port_resource_tdm_set
  14732  * Purpose:
  14733  *      Reconfigure the ingress and egress schedulers for
  14734  *      the new port configuration.
  14735  *
  14736  *      This includes reconfiguration of:
  14737  *      - OBM Thresholds
  14738  *      - EDB Prebuffer
  14739  *      - Ingress Oversub Scheduler
  14740  *      - Egress Oversub Scheduler
  14741  *      - Line-Rate Scheduler
  14742  * Parameters:
  14743  *      unit                 - (IN) Unit number.
  14744  *      curr_port_info_size  - (IN) Size of current port information array
  14745  *      curr_port_info       - (IN) Per-port array with current flexing info
  14746  *      new_port_info_size   - (IN) Size of new port information array
  14747  *      new_port_info        - (IN) Per-port array with new flexing info
  14748  *      si_info              - (IN) Contains subset of fields from
  14749  *                             soc_info_t structure
  14750  *                             prior to the flexing operation
  14751  *      lossless             - (IN) MMU lossless information
  14752  * Returns:
  14753  *      SOC_E_XXX
  14754  * Note:
  14755  *      Assumptions
  14756  *      - soc info structure members have been updated to reflect the latest
  14757  *        flexing operation
  14758  *      - There is no overlapping between logical or physical ports in the 
  14759  *        arrays passed, that is, operations like 4x10->1x40->4x10 on the same
  14760  *        set of ports have been rejected at bcm layer itself, and do not reach
  14761  *        this function
  14762  *      - Pre-FlexPort array
  14763  *        Contains current information on ports to be modified after
  14764  *        the FlexPort operation.  This should include ports whose
  14765  *        mappings are either deleted or remapped.
  14766  *      - Post-FlexPort array
  14767  *        Contains information on new configuration for
  14768  *        ports that are active (present) after the FlexPort operation.
  14769  *        This should include ports whose mappings that are remapped or new.
  14770  */
  14771 int soc_mn_port_resource_tdm_set(int unit, int curr_port_info_size,
  14772                                    soc_port_resource_t *curr_port_info,
  14773                                    int new_port_info_size,
  14774                                    soc_port_resource_t *new_port_info,
  14775                                    soc_mn_info_t *si_info,
  14776                                    int lossless)
  14777 {
  14778     int rv;
  14779     uint32 rval;
  14780     soc_monterey_tdm_t *tdm;
  14781 
  14782     /* Sec 6.6.3.2, #1 and #2 will be filled as part of oversubscription
  14783      * code changes
  14784      */
  14785 
  14786     /* Reconfigure EDB prebuffer 6.6.3.2 (#3) */
  14787 
  14788     SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval));
  14789     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14790                       CLPORT_CELL_COUNTSf, 0x1);
  14791     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14792                       XLPORT_CELL_COUNTSf, 0x3);
  14793     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14794                       ENABLEf, 0x1);
  14795     SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval));
  14796 
  14797     /* Reconfigure EDB prebuffer back up calendar 6.6.3.2 (#4), for line rate
  14798      * TDM calendar. Oversub related portion will be added later
  14799      */
  14800 
  14801     /* Configure ingress scheduler back up calendar 6.6.3.2.2 (#1, bullet #2) */
  14802     tdm = MONTEREY_TDM_STRUCT_BACKUP(unit);
  14803     SOC_IF_ERROR_RETURN(soc_mn_port_resource_tdm_calculate(unit, tdm));
  14804 
  14805     /* Reconfigure oversub scheduler (Sections 6.6.3.2.3, 6.6.3.2.4).
  14806      * Function internally determines if oversub is enabled/disabled
  14807      */
  14808     rv = soc_mn_ovr_sub_tdm_update(unit, tdm, 
  14809                                    curr_port_info_size, curr_port_info,
  14810                                    new_port_info_size, new_port_info);
  14811     SOC_IF_ERROR_RETURN(rv);
  14812 
  14813 
  14814     /* toggle the active calendar */
  14815     MONTEREY_TDM_ACTIVE_CAL(unit) ^= 1;
  14816 
  14817     /* update the tdm calendar config in the hardware */
  14818     SOC_IF_ERROR_RETURN(soc_monterey_tdm_update(unit, 0, MONTEREY_TDM_ACTIVE_CAL(unit), tdm));
  14819 
  14820     /* Reconfigure EDB prebuffer 6.6.3.2 (#6) */
  14821 
  14822     sal_usleep(1);
  14823 
  14824     SOC_IF_ERROR_RETURN(READ_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, &rval));
  14825     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14826                       CLPORT_CELL_COUNTSf, 0x1);
  14827     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14828                       XLPORT_CELL_COUNTSf, 0x3);
  14829     soc_reg_field_set(unit, EGR_FLEXPORT_EXTRA_HOLDINGr, &rval,
  14830                       ENABLEf, 0x0);
  14831     SOC_IF_ERROR_RETURN(WRITE_EGR_FLEXPORT_EXTRA_HOLDINGr(unit, rval));
  14832 
  14833 
  14834     return SOC_E_NONE;
  14835 }
  14836 
  14837 /*
  14838  * Function:
  14839  *      soc_mn_port_resource_pgw_set
  14840  * Purpose:
  14841  *      Reconfigure PGW registers in flex port sequence
  14842  *      In this function following registers will be initialized.
  14843  *      This function will do two things,
  14844  *      1. clear all registers for old ports which exists in pre-Flex status
  14845  *      2. initialize all registers for new ports which exists in post-Flex
  14846  *         status
  14847  *
  14848  * Parameters:
  14849  *      unit         - (IN) Unit number.
  14850  *      pre_num_res  - (IN) Number of resource data which exist in pre-Flex
  14851  *                          status
  14852  *      post_num_res - (IN) Number of resource data which exist in post-Flex
  14853  *                          status
  14854  *      pre_res      - (IN) Resource data structure pointer in pre-Flex status
  14855  *      post_res     - (IN) Resource data structure pointer in post-Flex status
  14856  *      lossless     - (IN) MMU lossless information
  14857  *
  14858  * Returns:
  14859  *      SOC_E_XXX
  14860  * Note: 
  14861  *      - Assumes FlexPort cases are valid.
  14862  *      - Pre-FlexPort array
  14863  *        Contains current information on ports to be modified after
  14864  *        the FlexPort operation.  This should include ports whose
  14865  *        mappings are either deleted or remapped.
  14866  *      - Post-FlexPort array
  14867  *        Contains information on new configuration for
  14868  *        ports that are active (present) after the FlexPort operation.
  14869  *        This should include ports whose mappings that are remapped or new.
  14870  */
  14871 int
  14872 soc_mn_port_resource_pgw_set(int unit,
  14873                       int pre_num_res,  soc_port_resource_t *pre_res,
  14874                       int post_num_res, soc_port_resource_t *post_res,
  14875                       int lossless)
  14876 {
  14877     int i;
  14878 
  14879     SOC_IF_ERROR_RETURN(
  14880         _soc_mn_resource_data_check(unit, pre_num_res, pre_res));
  14881     SOC_IF_ERROR_RETURN(
  14882         _soc_mn_resource_data_check(unit, post_num_res, post_res));
  14883 
  14884     for (i = 0; i < post_num_res; i++) {
  14885          /* Reconfigure the Port Mode for Port Macro */
  14886         SOC_IF_ERROR_RETURN(
  14887             soc_portctrl_port_mode_set(unit, post_res[i].logical_port, post_res[i].mode));
  14888     }
  14889 
  14890     SOC_IF_ERROR_RETURN(soc_mn_pgw_obm_set(unit,
  14891                                            pre_num_res, pre_res,
  14892                                            post_num_res, post_res));
  14893 
  14894     return SOC_E_NONE;
  14895 }
  14896 
  14897 /*
  14898  * Function:
  14899  *      soc_mn_port_resource_ip_set
  14900  * Purpose:
  14901  *      Reconfigure IP.
  14902  * Parameters:
  14903  *      unit     - (IN) Unit number.
  14904  *      curr_port_info_size - (IN) Size of current port information array
  14905  *      curr_port_info - (IN) Per-port array with current flexing info
  14906  *      new_port_info_size - (IN) Size of new port information array
  14907  *      new_port_info - (IN) Per-port array with new flexing info
  14908  *      si_info - (IN) Contains subset of fields from soc_info_t structure
  14909  *                     prior to the flexing operation
  14910  * Returns:
  14911  *      SOC_E_XXX
  14912  * Note:
  14913  *      Assumptions
  14914  *      - soc info structure members have been updated to reflect the latest
  14915  *        flexing operation
  14916  *      - There is no overlapping between logical or physical ports in the 
  14917  *        arrays passed, example, operations like 4x10->1x40->4x10 on the same
  14918  *        set of ports have been rejected at bcm layer itself, and do not reach
  14919  *        this function
  14920  *      - Pre-FlexPort array
  14921  *        Contains current information on ports to be modified after
  14922  *        the FlexPort operation.  This should include ports whose
  14923  *        mappings are either deleted or remapped.
  14924  *      - Post-FlexPort array
  14925  *        Contains information on new configuration for
  14926  *        ports that are active (present) after the FlexPort operation.
  14927  *        This should include ports whose mappings that are remapped or new.
  14928  */
  14929 int soc_mn_port_resource_ip_set(int unit, int curr_port_info_size,
  14930                                   soc_port_resource_t *curr_port_info,
  14931                                   int new_port_info_size,
  14932                                   soc_port_resource_t *new_port_info,
  14933                                   soc_mn_info_t *si_info)
  14934 {
  14935     soc_info_t *si;
  14936     soc_mem_t mem;
  14937     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
  14938     int port, phy_port;
  14939     int num_phy_port;
  14940 
  14941     si = &SOC_INFO(unit);
  14942 
  14943     /* Ingress physical to logical port mapping */
  14944     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
  14945     num_phy_port = soc_mem_index_count(unit, mem);
  14946 
  14947     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
  14948         sal_memset(&entry, 0, sizeof(entry));
  14949 
  14950         /* The p2l mapping has been updated before this function is called */
  14951         port = si->port_p2l_mapping[phy_port];
  14952 
  14953         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
  14954                             port == -1 ? 0x7F : port);
  14955         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port,
  14956                                           &entry));
  14957     }
  14958 
  14959     return SOC_E_NONE;
  14960 }
  14961 
  14962 /*
  14963  * Function:
  14964  *      soc_mn_port_resource_ep_set
  14965  * Purpose:
  14966  *      Reconfigure EP.
  14967  * Parameters:
  14968  *      unit     - (IN) Unit number.
  14969  *      curr_port_info_size - (IN) Size of current port information array
  14970  *      curr_port_info - (IN) Per-port array with current flexing info
  14971  *      new_port_info_size - (IN) Size of new port information array
  14972  *      new_port_info - (IN) Per-port array with new flexing info
  14973  *      si_info - (IN) Contains subset of fields from soc_info_t structure
  14974  *                     prior to the flexing operation
  14975  * Returns:
  14976  *      SOC_E_XXX
  14977  * Note:
  14978  *      Assumptions
  14979  *      - soc info structure members have been updated to reflect the latest
  14980  *        flexing operation
  14981  *      - There is no overlapping between logical or physical ports in the 
  14982  *        arrays passed, example, operations like 4x10->1x40->4x10 on the same
  14983  *        set of ports have been rejected at bcm layer itself, and do not reach
  14984  *        this function
  14985  *      - Pre-FlexPort array
  14986  *        Contains current information on ports to be modified after
  14987  *        the FlexPort operation.  This should include ports whose
  14988  *        mappings are either deleted or remapped.
  14989  *      - Post-FlexPort array
  14990  *        Contains information on new configuration for
  14991  *        ports that are active (present) after the FlexPort operation.
  14992  *        This should include ports whose mappings that are remapped or new.
  14993  */
  14994 int soc_mn_port_resource_ep_set(int unit, int curr_port_info_size,
  14995                                   soc_port_resource_t *curr_port_info,
  14996                                   int new_port_info_size,
  14997                                   soc_port_resource_t *new_port_info,
  14998                                   soc_mn_info_t *si_info)
  14999 {
  15000     soc_info_t *si;
  15001     uint32 rval;
  15002     int num_port, port, idx, phy_port;
  15003 
  15004     si = &SOC_INFO(unit);
  15005 
  15006     /* Ingress logical to physical port mapping */
  15007     num_port = soc_mem_index_count(unit, PORT_TABm) - 1;
  15008 
  15009     /* Egress logical to physical port mapping */
  15010     for (port = 0; port < num_port; port++) {
  15011         /*
  15012          * Use logical to physical number mapping from soc info structure
  15013          * since it has been updated before this function is called
  15014          */
  15015         phy_port = si->port_l2p_mapping[port];
  15016 
  15017         rval = 0;
  15018         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
  15019                           &rval, PHYSICAL_PORT_NUMBERf,
  15020                           phy_port == -1 ? 0x7F : phy_port);
  15021         SOC_IF_ERROR_RETURN
  15022             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
  15023                                                                 rval));
  15024     }
  15025 
  15026     /* Clear counters for the newly added ports */
  15027     for (idx = 0; idx < new_port_info_size; idx++) {
  15028         SOC_IF_ERROR_RETURN(soc_mn_ep_counters_clear(unit,
  15029                                                        &new_port_info[idx]));
  15030     }
  15031 
  15032     return SOC_E_NONE;
  15033 }
  15034 
  15035 /*
  15036  * Function: 
  15037  *      soc_mn_port_resource_mmu_mapping_set
  15038  * Purpose:
  15039  *      Set the HW MMU Port mappings.
  15040  * Parameters:
  15041  *      unit      - (IN) Unit number.
  15042  *      nport     - (IN) Number of elements in array resource.
  15043  *      resource  - (IN) Port Resource FlexPort configuration.
  15044  * Returns:
  15045  *      SOC_E_XXX
  15046  * Note:
  15047  *      Assumes FlexPort cases are valid.
  15048  *      Assumes SOC INFO data structure has been updated.
  15049  */
  15050 int
  15051 soc_mn_port_resource_mmu_mapping_set(int unit, int nport,
  15052                                        soc_port_resource_t *resource)
  15053 {
  15054     soc_info_t *si = &SOC_INFO(unit);
  15055     soc_port_resource_t *pr;
  15056     int i;
  15057     int logic_port;
  15058     int phy_port;
  15059     uint32 rval;
  15060 
  15061     for (i = 0, pr = &resource[0]; i < nport; i++, pr++) {
  15062         /*
  15063          * Skip for legacy inactive configurations since
  15064          * MMU mappings are kept the same.
  15065          */
  15066         if (pr->flags & SOC_PORT_RESOURCE_I_MAP) {
  15067             LOG_VERBOSE(BSL_LS_SOC_PORT,
  15068                         (BSL_META_U(unit,
  15069                                     "  Skip port with inactive configuration, "
  15070                                     "mappings are kept the same, "
  15071                                     "mmu=%d logical=%d physical=%d\n"),
  15072                          si->port_p2m_mapping
  15073                          [si->port_l2p_mapping[pr->logical_port]],
  15074                          pr->logical_port,
  15075                          si->port_l2p_mapping[pr->logical_port]));
  15076             continue;
  15077         }
  15078 
  15079         if (pr->physical_port == -1) {
  15080             /* Remove old MMU mappings. */
  15081             logic_port = 0x7F;
  15082             phy_port = 0x7F;
  15083 
  15084         } else {
  15085             logic_port = pr->logical_port;
  15086             phy_port = pr->physical_port;
  15087         }
  15088 
  15089         rval = 0;
  15090         soc_reg_field_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, &rval,
  15091                           PHY_PORTf, phy_port);
  15092         SOC_IF_ERROR_RETURN
  15093             (soc_reg32_set(unit, MMU_PORT_TO_PHY_PORT_MAPPINGr, pr->logical_port,
  15094                            0, rval));
  15095 
  15096         rval = 0;
  15097         soc_reg_field_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, &rval,
  15098                           LOGIC_PORTf, logic_port);
  15099         SOC_IF_ERROR_RETURN
  15100             (soc_reg32_set(unit, MMU_PORT_TO_LOGIC_PORT_MAPPINGr, pr->logical_port,
  15101                            0, rval));
  15102 
  15103         LOG_VERBOSE(BSL_LS_SOC_PORT,
  15104                     (BSL_META_U(unit,
  15105                                 "MMU port mappings: "
  15106                                 "mmu=%d logical=%d physical=%d\n"),
  15107                      si->port_p2m_mapping
  15108                      [si->port_l2p_mapping[pr->logical_port]],
  15109                      logic_port, phy_port));
  15110     }
  15111 
  15112     return SOC_E_NONE;
  15113 }
  15114 
  15115 
  15116 /*
  15117  * Function:
  15118  *      soc_mn_port_resource_mmu_set
  15119  * Purpose:
  15120  *      Called to reconfigure the MMU hardware.
  15121  * Parameters:
  15122  *      unit           - (IN) Device Number
  15123  *      nport          - (IN) The number of port modifications in flexport_data
  15124  *      flexport_data  - (IN) An array of port changes that are being done
  15125  * Returns:
  15126  *      SOC_E_NONE if parameters are valid, an error otherwise. 
  15127  * Note:
  15128  *      Assumes FlexPort cases are valid.
  15129  *      Assumes SOC INFO data structure has been updated.
  15130  */
  15131 int
  15132 soc_mn_port_resource_mmu_set(int unit, int nport,
  15133                                soc_port_resource_t *flexport_data)
  15134 {
  15135     int i;
  15136 
  15137     /* Update MMU Port Mappings */
  15138     SOC_IF_ERROR_RETURN
  15139         (soc_mn_port_resource_mmu_mapping_set(unit, nport,
  15140                                                 flexport_data));
  15141 
  15142     /* Configure all MMU registers for new ports */
  15143     for (i = 0; i < nport; i++) {
  15144         if (flexport_data[i].physical_port != -1) {
  15145             SOC_IF_ERROR_RETURN(
  15146             soc_monterey_mmu_port_resource_set(unit, flexport_data[i].logical_port,
  15147                                            flexport_data[i].speed));
  15148         }
  15149     }
  15150 
  15151     return SOC_E_NONE;
  15152 }
  15153 
  15154 /*
  15155  * Function:
  15156  *     soc_mn_is_port_flex_enable
  15157  * Purpose:
  15158  *     Find out if port_flex_enable{physical port num} config
  15159  *     is present on the given physical port in config.bcm
  15160  * Parameters:
  15161  *     unit    - (IN) Unit number.
  15162  *     phy_port - (IN) physical port num
  15163  * Returns:
  15164  *     TRUE or FALSE
  15165  */
  15166 STATIC int
  15167 soc_mn_is_port_flex_enable(int unit, int phy_port)
  15168 {
  15169     int enable = 0;
  15170 
  15171     /* This property does not apply to cpu port &
  15172      * loopback port
  15173  */
  15174 
  15175     if (phy_port > 0 && phy_port < 129) {
  15176         enable = soc_property_phys_port_get(unit,
  15177                                             phy_port,
  15178                                             spn_PORT_FLEX_ENABLE, 0);
  15179     }
  15180 
  15181     return enable;
  15182 }
  15183 
  15184 
  15185 /* Tells if a port macro (indexed by TSC4, not TSC12) is flex port enabled.
  15186  *  
  15187  * Port macro flex on or off is determined by the first port in that macro. 
  15188  * For TSC12 it's the first port in the first TSC4. For a TSC4 that is NOT 
  15189  * part of a TSC12, it's also the first port of that port macro.  For a TSC4 
  15190  * that is a part of a TSC12, refer to the first port of the first port macro 
  15191  * for that TSC12. 
  15192  *  
  15193  * Parameters:
  15194  *      unit          - (IN) Unit number.
  15195  *      port_macro    - (IN) port macro desired
  15196  *      flex_enabled  - (OUT) whether the port macro is enabled or disabled
  15197  *  
  15198  *  Returns: 
  15199  *      SOC_E_xxx
  15200  */
  15201 int
  15202 soc_mn_port_macro_flex_enabled(int unit, int port_macro, int * flex_enabled)
  15203 {
  15204     int port_num = -1;
  15205 
  15206     if ((port_macro < 0) || (port_macro > 18)) {
  15207         return SOC_E_PARAM;
  15208     }
  15209 
  15210     port_num = (MONTEREY_PORTS_PER_TSC * port_macro) + 1;
  15211 
  15212     *flex_enabled = soc_mn_is_port_flex_enable(unit, port_num);
  15213 
  15214     return SOC_E_NONE;
  15215 }
  15216 
  15217 
  15218 /*
  15219 * Function:
  15220 *     soc_monterey_port_icc_width_set
  15221 * Purpose:
  15222 *     Program PORT_INITIAL_COPY_COUNT_WIDTHr
  15223 * Parameters:
  15224 *     unit    - (IN) Unit number.
  15225 *     port    - (IN) Logical SOC port number.
  15226 * Returns:
  15227 *     SOC_E_XXX
  15228  */
  15229 STATIC int
  15230 soc_monterey_port_icc_width_set(int unit, soc_port_t port)
  15231 {
  15232     int count_width = 0;
  15233 
  15234     if (SOC_INFO(unit).port_speed_max[port] < 25000) {
  15235         count_width = 1; /* 1 ICC bit  */
  15236     } else if (SOC_INFO(unit).port_speed_max[port] <= 53000) {
  15237         count_width = 2; /* 2 ICC bits  */
  15238     } else {
  15239         count_width = 3; /* 3 ICC bits  */
  15240     }
  15241 
  15242     SOC_IF_ERROR_RETURN(
  15243         soc_reg_field32_modify(unit, PORT_INITIAL_COPY_COUNT_WIDTHr,
  15244             port, BIT_WIDTHf, count_width ? (count_width - 1) : 0));
  15245 
  15246     return SOC_E_NONE;
  15247 }
  15248 
  15249 /*
  15250  * Function:
  15251  *     soc_monterey_repl_port_agg_map_init
  15252  * Purpose:
  15253  *     Initialize L3MC Port Agg Map.
  15254  * Parameters:
  15255  *     unit    - (IN) Unit number.
  15256  *     port    - (IN) Logical SOC port number.
  15257  * Returns:
  15258  *     SOC_E_xxx
  15259  */
  15260 STATIC int
  15261 soc_monterey_repl_port_agg_map_init(int unit, soc_port_t port)
  15262 {
  15263     soc_info_t *si;
  15264     int phy_port, mmu_port;
  15265     uint32 regval;
  15266 
  15267     si = &SOC_INFO(unit);
  15268     phy_port = si->port_l2p_mapping[port];
  15269     mmu_port = si->port_p2m_mapping[phy_port];
  15270 
  15271     /* configure mmu port to repl aggregateId map */
  15272     regval = 0;
  15273     soc_reg_field_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr, &regval,
  15274                       L3MC_PORT_AGG_IDf, mmu_port % 74);
  15275     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, MMU_TOQ_REPL_PORT_AGG_MAPr,
  15276                 port,0,regval));
  15277 
  15278     return SOC_E_NONE;
  15279 }
  15280 
  15281 /*
  15282 * Function:
  15283 *     soc_monterey_ipmc_repl_init
  15284 * Purpose:
  15285 *     Initialize IPMC Replication settings
  15286 * Parameters:
  15287 *     unit    - (IN) Unit number.
  15288 *     port    - (IN) Logical SOC port number.
  15289 * Returns:
  15290 *     SOC_E_XXX
  15291  */
  15292 STATIC int
  15293 soc_monterey_ipmc_repl_init(int unit, soc_port_t port)
  15294 {
  15295     /* Program MMU_TOQ_REPL_PORT_AGG_MAP
  15296  */
  15297     SOC_IF_ERROR_RETURN(soc_monterey_repl_port_agg_map_init(unit, port));
  15298 
  15299     return SOC_E_NONE;
  15300 }
  15301 
  15302 /*
  15303 * Function:
  15304 * soc_monterey_mmu_port_resource_set
  15305 * Purpose:
  15306 * Reconfigure MMU for flexport operation
  15307 * Parameters:
  15308 * unit    - (IN) Unit number.
  15309 * port    - (IN) Logical SOC port number.
  15310 * reset   - (IN) Reset.
  15311 * Returns:
  15312 * SOC_E_XXX
  15313  */
  15314 int soc_monterey_mmu_port_resource_set(int unit, soc_port_t port, int speed)
  15315 {
  15316 
  15317     /* Flex port operation not allowed on CPU or loopback port
  15318  */
  15319      if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_RDB_PORT(unit, port)) {
  15320          return SOC_E_PARAM;
  15321      }
  15322 
  15323     /* Configure all MMU registers for new ports whose setting is
  15324      * based on port speed.
  15325  */
  15326     SOC_IF_ERROR_RETURN(soc_monterey_port_speed_update(unit, port, speed));
  15327 
  15328     /* Program PORT_INITIAL_COPY_COUNT_WIDTH
  15329  */
  15330     SOC_IF_ERROR_RETURN(soc_monterey_port_icc_width_set(unit, port));
  15331 
  15332     /* Reconfigure IPMC replication
  15333  */
  15334     SOC_IF_ERROR_RETURN(soc_monterey_ipmc_repl_init(unit, port));
  15335 
  15336     return SOC_E_NONE;
  15337 }
  15338 
  15339 /*
  15340 * Function:
  15341 *     soc_monterey_is_any_port_flex_enable
  15342 * Purpose:
  15343 *     Find out if
  15344 *     port_flex_enable=1 OR
  15345 *     port_flex_enable{physical port num}=1
  15346 *     config is present in config.bcm
  15347 * Parameters:
  15348 *     unit    - (IN) Unit number.
  15349 * Returns:
  15350 *     TRUE or FALSE
  15351 *     If such a config is present, this function
  15352 *     returns 1 - implying that flex is enable on
  15353 *     at least 1 port (port macro) in the system
  15354 *     This function returns 0, if flex is not enabled
  15355 *     on any port (port macro) in the system
  15356  */
  15357 int soc_monterey_is_any_port_flex_enable(int unit)
  15358 {
  15359     int phy_port, num_phy_port;
  15360 
  15361     num_phy_port = 67;
  15362     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
  15363         if (soc_property_phys_port_get(unit,
  15364                                        phy_port,
  15365                                        spn_PORT_FLEX_ENABLE, 0)) {
  15366             return TRUE;
  15367         }
  15368     }
  15369 
  15370     return FALSE;
  15371 }
  15372 
  15373 
  15374 
  15375 
  15376 #if defined(SER_TR_TEST_SUPPORT)
  15377 
  15378 #define MAX_HW_TCAMS  32
  15379 typedef struct ser_monterey_skipped_mem_s {
  15380     soc_mem_t mem;
  15381     soc_acc_type_t acc_type;
  15382 } ser_monterey_skipped_mem_t;
  15383 
  15384 const ser_monterey_skipped_mem_t monterey_skipped_mems[] = {
  15385     /* Below memories have only one entry */
  15386     {L2_BULK_MATCH_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15387     {L2_BULK_MATCH_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  15388     {L2_BULK_REPLACE_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15389     {L2_BULK_REPLACE_MASKm, _SOC_ACC_TYPE_PIPE_ANY},
  15390     {L2_LEARN_INSERT_FAILUREm, _SOC_ACC_TYPE_PIPE_ANY},
  15391     {MPLS_ENTROPY_LABEL_DATAm, _SOC_ACC_TYPE_PIPE_ANY},
  15392     {ING_SNAT_ONLYm, _SOC_ACC_TYPE_PIPE_ANY},
  15393 
  15394    /* FP_GLOBAL_MASK_TCAM and FP_GM_FILEDSm have special handling in memscan
  15395     * since H/W space is shared between these two mems.
  15396     * It is protected by SW memscan SER engine
  15397     */
  15398     {FP_GLOBAL_MASK_TCAMm, _SOC_ACC_TYPE_PIPE_ANY},
  15399 /*  MMU_MTRO_EGRMETERINGCONFIG_MEM will be tested below two are for debug */  
  15400     {MMU_MTRO_EGRMETERINGCONFIG_MEM_Am, _SOC_ACC_TYPE_PIPE_ANY},  
  15401     {MMU_MTRO_EGRMETERINGCONFIG_MEM_Bm, _SOC_ACC_TYPE_PIPE_ANY},  
  15402 /*debug memory*/
  15403     {MMU_MAPPER_X_LSBm, _SOC_ACC_TYPE_PIPE_ANY},  
  15404 /*ser flags not proper in regfile*/
  15405     {EGR_LPORT_PROFILEm, _SOC_ACC_TYPE_PIPE_ANY},  
  15406 /*Not able to write to this table need to check*/
  15407     {L3_ENTRY_LPm, _SOC_ACC_TYPE_PIPE_ANY},  
  15408     {INVALIDm}
  15409 };
  15410 
  15411 int
  15412 ser_test_monterey_mem_index_remap(int unit, ser_test_data_t *test_data,
  15413                                   int *mem_has_ecc)
  15414 {
  15415     int uft_bkt_bank = 0;
  15416     int num_uft_banks = 0;
  15417     int uft_le_fv = 0;
  15418     int uft_le_ecc = 0;
  15419     int remap_status = 0;
  15420 
  15421     *mem_has_ecc = 0;
  15422     test_data->mem = test_data->mem_fv;
  15423     test_data->index = test_data->index_fv;
  15424 
  15425     num_uft_banks = 0;
  15426     switch (test_data->mem_fv) {
  15427     case VLAN_XLATEm:
  15428     case VLAN_MACm:
  15429         test_data->mem = VLAN_XLATE_ECCm;
  15430         *mem_has_ecc = 1;
  15431         break;
  15432     case EGR_VLAN_XLATEm:
  15433         test_data->mem = EGR_VLAN_XLATE_ECCm;
  15434         *mem_has_ecc = 1;
  15435         break;
  15436     case L2Xm:
  15437     case L2_ENTRY_ONLYm:
  15438         test_data->mem = L2_ENTRY_ONLY_ECCm;
  15439         *mem_has_ecc = 1;
  15440         break;
  15441     case L3_ENTRY_ONLYm:
  15442     case L3_ENTRY_IPV4_UNICASTm:
  15443         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15444         test_data->index = test_data->index_fv;
  15445         *mem_has_ecc = 1;
  15446         break;
  15447     case L3_ENTRY_IPV4_MULTICASTm:
  15448     case L3_ENTRY_IPV6_UNICASTm:
  15449         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15450         test_data->index = test_data->index_fv*2;
  15451         *mem_has_ecc = 1;
  15452         break;
  15453     case L3_ENTRY_IPV6_MULTICASTm:
  15454         test_data->mem = L3_ENTRY_ONLY_ECCm;
  15455         test_data->index = test_data->index_fv*4;
  15456         *mem_has_ecc = 1;
  15457         break;
  15458     case L3_DEFIP_ALPM_IPV4m: /* 6:4 */
  15459         *mem_has_ecc = 1;
  15460         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15461         uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks);
  15462         uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks);
  15463         switch (uft_le_fv) {
  15464         case 0: uft_le_ecc = 0; break;
  15465         case 1: uft_le_ecc = 0; break; /* or 1 */
  15466         case 2: uft_le_ecc = 1; break;
  15467         case 3: uft_le_ecc = 2; break;
  15468         case 4: uft_le_ecc = 2; break; /* or 3 */
  15469         case 5: uft_le_ecc = 3; break;
  15470         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15471         }
  15472         test_data->index = (uft_le_ecc <<
  15473             _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15474         break;
  15475     case L3_DEFIP_ALPM_IPV4_1m: /* 4:4 */
  15476     case L3_DEFIP_ALPM_IPV6_64m:
  15477         *mem_has_ecc = 1;
  15478         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15479         test_data->index = test_data->index_fv;
  15480         break;
  15481     case L3_DEFIP_ALPM_IPV6_64_1m: /* 3:4 */
  15482         *mem_has_ecc = 1;
  15483         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15484             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks);
  15485             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks);
  15486         switch (uft_le_fv) {
  15487         case 0: uft_le_ecc = 0; break; /* or 1 */
  15488         case 1: uft_le_ecc = 1; break; /* or 2 */
  15489         case 2: uft_le_ecc = 2; break; /* or 3 */
  15490         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15491         }
  15492         test_data->index = (uft_le_ecc <<
  15493             _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15494         break;
  15495     case L3_DEFIP_ALPM_IPV6_128m: /* 2:4 */
  15496         *mem_has_ecc = 1;
  15497         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15498             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks);
  15499             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks);
  15500         switch (uft_le_fv) {
  15501         case 0: uft_le_ecc = 0; break; /* or 1 */
  15502         case 1: uft_le_ecc = 2; break; /* or 3 */
  15503         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15504         }
  15505         test_data->index = (uft_le_ecc <<
  15506             _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15507         break;
  15508     case L3_DEFIP_ALPM_RAWm: /* 1:4 */
  15509         *mem_has_ecc = 1;
  15510         test_data->mem = L3_DEFIP_ALPM_ECCm;
  15511             uft_bkt_bank = test_data->index_fv & _SER_TEST_MEM_MN_ALPM_MASK(num_uft_banks);
  15512             uft_le_fv = test_data->index_fv >> _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks);
  15513         switch (uft_le_fv) {
  15514         case 0: uft_le_ecc = 0; break; /* or 1,2,3 */
  15515         default: remap_status = SOC_E_PARAM; uft_le_ecc = uft_le_fv; break;
  15516         }
  15517         test_data->index = (uft_le_ecc <<
  15518             _SER_TEST_MEM_MN_ALPM_SHIFT(num_uft_banks)) + uft_bkt_bank;
  15519         break;
  15520     default:
  15521         test_data->mem = test_data->mem_fv;
  15522         test_data->index = test_data->index_fv;
  15523         break;
  15524     }
  15525     if ((test_data->mem != test_data->mem_fv) ||
  15526         (test_data->index != test_data->index_fv)) {
  15527         LOG_VERBOSE(BSL_LS_SOC_SER,
  15528             (BSL_META_U(unit,
  15529                         "unit %d, ser_test_mem_index_remap: "
  15530                         "mem_fv %s, index_fv %0d, mem %s, index %0d, "
  15531                         "uft_bkt_bank %0d, uft_le_fv %0d, "
  15532                         "uft_le_ecc %0d, remap_status %0d \n"),
  15533              unit, SOC_MEM_NAME(unit, test_data->mem_fv), test_data->index_fv,
  15534              SOC_MEM_NAME(unit, test_data->mem), test_data->index,
  15535              uft_bkt_bank, uft_le_fv, uft_le_ecc, remap_status));
  15536     }
  15537     return remap_status;
  15538 }
  15539 
  15540 int
  15541 soc_monterey_mem_is_eligible_for_scan(int unit, soc_mem_t mem)
  15542 {
  15543     switch (mem) {
  15544         case L3_DEFIP_ALPM_ECCm:
  15545         case L2_ENTRY_LPm:
  15546         case L3_ENTRY_LPm:
  15547         case VLAN_XLATE_LPm:
  15548         case EGR_VLAN_XLATE_LPm:
  15549         case L2_ENTRY_ISS_LPm:
  15550         case L3_ENTRY_ISS_LPm:
  15551         return 1;
  15552         
  15553         default:
  15554         break;
  15555     }
  15556     return 0;
  15557 }
  15558 
  15559 int
  15560 soc_monterey_ser_test_skip_check (int unit, soc_mem_t mem)
  15561 {
  15562     int i;
  15563 
  15564     if (!SOC_MEM_IS_VALID(unit, mem) ||
  15565         ((mem != INVALIDm) &&
  15566          ((SOC_MEM_INFO(unit, mem).flags &
  15567            SOC_MEM_FLAG_SER_PARITY_ENABLE_SKIP)))) {
  15568         return 1;
  15569     }
  15570 
  15571     if (soc_mem_index_count(unit, mem) <= 0) {
  15572         return 1;
  15573     }
  15574 
  15575     for (i = 0; monterey_skipped_mems[i].mem != INVALIDm; i++) {
  15576         if (monterey_skipped_mems[i].mem == mem) {
  15577             return 1;
  15578         }
  15579     }
  15580     if (!(SOC_MEM_INFO(unit, mem).flags & SOC_MEM_SER_FLAGS)) {
  15581         return 1;
  15582     }
  15583     /* Skip the memory if the relevant feature and memory is disabled. */
  15584     if (!soc_feature(unit, soc_feature_l3)
  15585         || !soc_feature(unit, soc_feature_lpm_tcam) ) {
  15586         /* Skip L3_DEFIP memorys */
  15587         if ((L3_DEFIPm == mem) || (L3_DEFIP_PAIR_128m == mem)) return 1;
  15588     }
  15589     if (!soc_feature(unit, soc_feature_l3) ||
  15590         soc_feature(unit, soc_feature_no_tunnel)) {
  15591         /* Skip ING L3 Tunnel memorys */
  15592         if ((L3_TUNNELm == mem) || (L3_TUNNEL_DATA_ONLYm == mem)) return 1;
  15593     }
  15594     if (!soc_feature(unit, soc_feature_nat)) {
  15595         /* Skip NAT  memorys */
  15596         if (ING_SNATm == mem) return 1;
  15597     }
  15598     
  15599     /* Skip MPLS memories */
  15600 
  15601     if (ING_MPLS_EXP_MAPPINGm == mem) {
  15602         return 1;
  15603     }
  15604 
  15605     return 0;
  15606 }
  15607 
  15608 STATIC 
  15609 soc_error_t
  15610 _soc_monterey_tcam_ser_mem_info_get (int unit, soc_mem_t mem, int *index_p)
  15611 {
  15612     int i;
  15613     _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit];
  15614     
  15615     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  15616         if (tcams[i].mem == mem) {
  15617             *index_p = i;
  15618             return SOC_E_NONE;
  15619         }
  15620     }
  15621     return SOC_E_NOT_FOUND;
  15622 }
  15623 
  15624 STATIC soc_error_t
  15625 _soc_monterey_ser_mem_info_get (int unit, soc_mem_t mem, _soc_mem_ser_en_info_t** ser_mem_info)
  15626 {
  15627     int i, j;
  15628     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  15629 
  15630     for (i = 0; _soc_monterey_ser_block_info[i].blocktype != 0; i++) {
  15631         if ((_soc_monterey_ser_block_info[i].type == _SOC_MONTEREY_SER_TYPE_MEM) &&
  15632             ((_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  15633              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  15634 #ifdef INCLUDE_XFLOW_MACSEC
  15635              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MACSEC) ||
  15636 #endif
  15637              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  15638             ser_en_info = _soc_monterey_ser_block_info[i].info;
  15639             for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  15640                 if (ser_en_info[j].mem == mem) {
  15641                     *ser_mem_info = &ser_en_info[j];
  15642                     return SOC_E_NONE;
  15643                 }
  15644             }
  15645         }
  15646     }
  15647 
  15648     return SOC_E_NOT_FOUND;
  15649 }
  15650 /*
  15651  * Function:
  15652  *      soc_monterey_ser_error_injection_support
  15653  * Purpose:
  15654  *      Checks if a memory is supported by error injection interface
  15655  *
  15656  * Parameters:
  15657  *      unit        - (IN) Device Number
  15658  *      memory      - (IN) Test data required for SER test
  15659  *      pipe        - (IN) How many indices to test for each memory
  15660  *
  15661  * Returns:
  15662  *  SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported
  15663  */
  15664 soc_error_t
  15665 soc_monterey_ser_error_injection_support (int unit, soc_mem_t mem,
  15666                                         int pipe)
  15667 {
  15668     int        rv = SOC_E_UNAVAIL;
  15669     _soc_mem_ser_en_info_t      *ser_mem_info = NULL;
  15670     int        tcam_idx = 0;
  15671 
  15672     if (soc_monterey_ser_test_skip_check (unit,mem)) {
  15673         return rv;
  15674     }
  15675 
  15676     rv = _soc_monterey_ser_mem_info_get(unit, mem, &ser_mem_info);
  15677     if (rv == SOC_E_NONE) {
  15678         return rv;
  15679     }
  15680     
  15681     rv = _soc_monterey_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  15682     if (rv == SOC_E_NONE) {
  15683         return rv;
  15684     }
  15685     
  15686     return rv;
  15687 }
  15688 
  15689 /*
  15690  * Function:
  15691  *      _soc_monterey_perform_ser_test
  15692  * Purpose:
  15693  *      Performs test operations common to TCAM and FIFO memory tests before
  15694  *      invoking common SER test.
  15695  * Parameters:
  15696  *      unit        - (IN) Device Number
  15697  *      test_data   - (IN) Test data required for SER test
  15698  *      test_type   - (IN) How many indices to test for each memory
  15699  *      mem_failed  - (OUT) Incremented when memories fail the test.
  15700  * Returns:
  15701  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  15702  *      possible.)
  15703  */
  15704 soc_error_t
  15705 _soc_monterey_perform_ser_test (int unit, ser_test_data_t *test_data,
  15706                               _soc_ser_test_t test_type,
  15707                               int *mem_skipped, int *mem_failed)
  15708 {
  15709     int skip_mem = FALSE;
  15710     soc_error_t rv = SOC_E_NONE;
  15711     uint32 flags = 0;
  15712 
  15713     if (soc_monterey_ser_test_skip_check (unit,test_data->mem)) {
  15714         skip_mem = TRUE;
  15715     }
  15716 #ifdef INCLUDE_XFLOW_MACSEC
  15717     if(soc_feature(unit, soc_feature_xflow_macsec) &&
  15718        ((ISEC_SP_TCAMm == test_data->mem) ||
  15719        (ISEC_SC_TCAMm == test_data->mem))) {
  15720         skip_mem = TRUE;
  15721     }
  15722 #endif
  15723     if (!skip_mem) {
  15724          if (test_data->mem == ING_VLAN_VFI_MEMBERSHIPm ||
  15725              test_data->mem == MMU_MTRI_BKPMETERINGCONFIG_MEM_0m ||
  15726              test_data->mem == MMU_MTRO_EGRMETERINGCONFIG_MEMm) {
  15727              flags |= SOC_INJECT_ERROR_2BIT_ECC;
  15728         }
  15729         rv = ser_test_mem(unit, flags, test_data, test_type, mem_failed);
  15730     } else {
  15731         LOG_VERBOSE(BSL_LS_SOC_COMMON,
  15732                     (BSL_META_U(unit,
  15733                                 "Memory %s skipped due to known issues.\n"),
  15734                      SOC_MEM_NAME(unit,test_data->mem)));
  15735         (*mem_skipped)++;
  15736     }
  15737 
  15738     return rv;
  15739 }
  15740 
  15741 /*
  15742  * Function:
  15743  *      soc_monterey_ser_tcam_test
  15744  * Purpose:
  15745  *      Tests that SER is working for fifo and SRAM memories
  15746  * Parameters:
  15747  *      unit        - (IN) Device Number
  15748  *      test_type   - (IN) How many indices to test for each memory
  15749  * Returns:
  15750  *  the number of tests which are failed
  15751  */
  15752 int
  15753 soc_monterey_ser_tcam_test (int unit, _soc_ser_test_t test_type) {
  15754     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  15755     ser_test_data_t test_data;
  15756     int mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  15757     _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit];
  15758     int i,rv=0;
  15759     soc_acc_type_t acc_type;
  15760     soc_field_t    test_field = VALIDf;
  15761 
  15762     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  15763         mem_tests++;
  15764         if ( i >= MAX_HW_TCAMS) {
  15765             mem_skipped++;
  15766             LOG_VERBOSE(BSL_LS_SOC_COMMON,
  15767                         (BSL_META_U(unit,
  15768                                     "Memory %s skipped due to lack of test mechanism \
  15769                                     for Software-protected TCAMS.\n"),
  15770                          SOC_MEM_NAME(unit,test_data.mem)));
  15771             continue;
  15772         }
  15773 
  15774         acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  15775 
  15776         if (tcams[i].mem == L3_DEFIPm) {
  15777             test_field = VALID0f;
  15778         } else if (tcams[i].mem == L3_DEFIP_PAIR_128m) {
  15779             test_field = VALID0_LWRf;
  15780         } else
  15781 #ifdef INCLUDE_XFLOW_MACSEC
  15782             if (soc_feature(unit, soc_feature_xflow_macsec) &&
  15783                 (tcams[i].mem == ISEC_SP_TCAMm)) {
  15784             test_field = MASKf;
  15785         } else
  15786 #endif
  15787         {
  15788             test_field = VALIDf;
  15789         }
  15790 
  15791         soc_ser_create_test_data(unit, tmp_entry, fieldData, SER_RANGE_ENABLEr,
  15792                                  i, INVALIDf, tcams[i].mem, test_field,
  15793                                  MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0,
  15794                                  &test_data);
  15795 
  15796        rv = _soc_monterey_perform_ser_test(unit, &test_data, test_type,
  15797                                      &mem_skipped, &mem_failed);
  15798         if (SOC_FAILURE(rv)) {
  15799            LOG_CLI((BSL_META_U(unit,
  15800            "TCAM SER test fail for mem: \t %s\n\n"),
  15801             SOC_MEM_NAME(unit,test_data.mem)));
  15802         }
  15803     }
  15804 
  15805     LOG_CLI((BSL_META_U(unit,
  15806                "\nTCAM memories tested on unit %d: %d\n"), unit, mem_tests));
  15807     LOG_CLI((BSL_META_U(unit,
  15808                "TCAM tests passed:\t%d\n"),
  15809                mem_tests - mem_failed - mem_skipped));
  15810     LOG_CLI((BSL_META_U(unit,
  15811                "TCAM tests skipped:\t%d (use verbose option to see "
  15812                "skipped memories)\n"),
  15813                mem_skipped));
  15814     LOG_CLI((BSL_META_U(unit,
  15815                "TCAM tests failed:\t%d\n\n"), mem_failed));
  15816 
  15817     return mem_failed;
  15818 }
  15819 
  15820 /*
  15821  * Function:
  15822  *      soc_monterey_ser_hardware_test
  15823  * Purpose:
  15824  *      Tests that SER is working for fifo and SRAM memories
  15825  * Parameters:
  15826  *      unit        - (IN) Device Number
  15827  *      test_type   - (IN) How many indices to test for each memory
  15828  * Returns:
  15829  *  the number of tests which are failed
  15830  */
  15831 int
  15832 soc_monterey_ser_hardware_test (int unit, _soc_ser_test_t test_type) {
  15833     ser_test_data_t      test_data;
  15834     int                  mem_failed = 0, mem_tests = 0, mem_skipped = 0;
  15835     int                  i,j,rv;
  15836     soc_acc_type_t       acc_type;
  15837     _soc_mem_ser_en_info_t *ser_en_info = NULL;
  15838     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  15839 
  15840     for (i = 0; _soc_monterey_ser_block_info[i].blocktype != 0; i++) {
  15841         if ((_soc_monterey_ser_block_info[i].type == _SOC_MONTEREY_SER_TYPE_MEM) &&
  15842             ((_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_IPIPE) ||
  15843              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_EPIPE) ||
  15844 #ifdef INCLUDE_XFLOW_MACSEC
  15845              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MACSEC) ||
  15846 #endif
  15847              (_soc_monterey_ser_block_info[i].blocktype == SOC_BLK_MMU))) {
  15848             ser_en_info = _soc_monterey_ser_block_info[i].info;
  15849             for (j = 0; ser_en_info[j].mem != INVALIDm; j++) {
  15850                 mem_tests += 1;
  15851                 test_data.test_field = EVEN_PARITYf;
  15852                 acc_type = -1;
  15853                 soc_ser_create_test_data(unit, tmp_entry, fieldData,
  15854                                          ser_en_info[j].en_ctrl.ctrl_type.en_reg,
  15855                                          SOC_INVALID_TCAM_PARITY_BIT,
  15856                                          ser_en_info[j].en_ctrl.en_fld,
  15857                                          ser_en_info[j].mem,
  15858                                          test_data.test_field, 
  15859                                          MEM_BLOCK_ANY,
  15860                                          REG_PORT_ANY, acc_type, 0, 
  15861                                          &test_data);
  15862                 if ((test_data.mem_info == NULL) || 
  15863                     (!(soc_mem_index_count(unit, ser_en_info[j].mem) > 0))) {
  15864                     mem_skipped++;
  15865                     LOG_VERBOSE(BSL_LS_SOC_COMMON,
  15866                                 (BSL_META_U(unit,
  15867                                  "Memory %s skipped due to lack of"
  15868                                  " mem_info structure or being disabled.\n"),
  15869                                  SOC_MEM_NAME(unit,test_data.mem)));
  15870                     continue;
  15871                 }
  15872                 rv = _soc_monterey_perform_ser_test(unit, &test_data,
  15873                                                   test_type, &mem_skipped,
  15874                                                   &mem_failed);
  15875                 if (SOC_FAILURE(rv)) {
  15876                     LOG_CLI((BSL_META_U(unit,
  15877                                         " H/W SER  test fail for mem: \t %s\n\n"),
  15878                              SOC_MEM_NAME(unit,test_data.mem)));
  15879                 }
  15880             }
  15881         }
  15882     }
  15883 
  15884     LOG_CLI((BSL_META_U(unit,
  15885                "\nH/W memories tested on unit %d: %d\n"), unit, mem_tests));
  15886     LOG_CLI((BSL_META_U(unit,
  15887                "H/W tests passed:\t%d\n"),
  15888                mem_tests - mem_failed - mem_skipped));
  15889     LOG_CLI((BSL_META_U(unit,
  15890                "H/W tests skipped:\t%d (use verbose option to see "
  15891                "skipped memories)\n"),
  15892                mem_skipped));
  15893     LOG_CLI((BSL_META_U(unit,
  15894                "H/W tests failed:\t%d\n\n"), mem_failed));
  15895     return mem_failed;
  15896 }
  15897 
  15898 
  15899 /*
  15900  * Function:
  15901  *      soc_monterey_ser_test
  15902  * Purpose:
  15903  *      Tests that SER is working for all supported memories.
  15904  * Parameters:
  15905  *      unit        - (IN) Device Number
  15906  *      test_type   - (IN) How many indices to test for each memory
  15907  * Returns:
  15908  *  SOC_E_NONE if test passes, an error otherwise (multiple types of errors are
  15909  *      possible.)
  15910  */
  15911 soc_error_t
  15912 soc_monterey_ser_test (int unit, _soc_ser_test_t test_type) {
  15913     int errors = 0;
  15914 
  15915     /*Test TCAM memories*/
  15916     errors += soc_monterey_ser_tcam_test(unit, test_type);
  15917 
  15918     /*Test for FIFO memories*/
  15919     errors += soc_monterey_ser_hardware_test(unit, test_type);
  15920 
  15921     if (errors == 0) {
  15922         return SOC_E_NONE;
  15923     } else {
  15924         return SOC_E_FAIL;
  15925     }
  15926 }
  15927 
  15928 #define TR_MEM_NAME_SIZE_MAX    100
  15929 
  15930 #ifdef SOC_MEM_NAME
  15931 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem) do {                    \
  15932         const char *_mem_name = SOC_MEM_NAME(_unit_, _mem);             \
  15933         if (sal_strlen(_mem_name) < TR_MEM_NAME_SIZE_MAX) {             \
  15934             sal_strcpy(_msg, _mem_name);                                \
  15935         }                                                               \
  15936     } while (0)
  15937 #else
  15938 #define TR_TEST_MEM_NAME_GET(_unit, _msg, _mem)
  15939 #endif
  15940 
  15941 #define TR_TEST_MEM_PRINT(_unit, _msg, _mem) do {                       \
  15942         sal_sprintf(_msg, "Mem ID: %d", _mem);                          \
  15943         TR_TEST_MEM_NAME_GET(_unit, _msg, _mem);                        \
  15944         LOG_CLI((BSL_META_U(_unit,                                      \
  15945                             "Memory %s is valid, but not currently testable.\n"), \
  15946                  _msg));                                                \
  15947     } while (0)
  15948 
  15949 /*
  15950  * Function:
  15951  *      soc_monterey_ser_inject_or_test_mem
  15952  * Purpose:
  15953  *      Provide a common function for injecting errors and testing single
  15954  *      single memories
  15955  * Parameters:
  15956  *      unit        - (IN) Device Number
  15957  *      mem         - (IN) The memory into which an error will be injected
  15958  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  15959  *      index       - (IN) The index into which the error will be injected.
  15960  *      test_type   - (IN) How many indices to test in the passes memory
  15961  *      cmd         - (IN) TRUE if a command-line test is desired.
  15962  * Returns:
  15963  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  15964  *      are possible.)
  15965  */
  15966 soc_error_t
  15967 soc_monterey_ser_inject_or_test_mem (int unit, soc_mem_t mem, int pipe_target,
  15968                                    int block, int index, 
  15969                                    _soc_ser_test_t test_type,
  15970                                    int inject_only, int cmd, uint32 flags)
  15971 {
  15972     uint32 tmp_entry[SOC_MAX_MEM_WORDS], fieldData[SOC_MAX_REG_FIELD_WORDS];
  15973     ser_test_data_t tcam_test_data, hw_test_data, *test_data;
  15974     int             tcam_idx = 0;
  15975         _soc_generic_ser_info_t *tcams = _soc_monterey_tcam_ser_info[unit];
  15976     int error_count = 0, skip_count = 0, found_mem = FALSE;
  15977     char fail_message[400];
  15978     soc_error_t rv = SOC_E_NONE;
  15979     soc_field_t test_field = INVALIDf;
  15980     soc_acc_type_t soc_acc_type_target = _SOC_ACC_TYPE_PIPE_ANY;
  15981     _soc_mem_ser_en_info_t * ser_mem_info = NULL;
  15982     int mem_has_ecc = 0, is_tcam = 0, is_fifo_mem = 0;
  15983 
  15984 
  15985     rv = _soc_monterey_tcam_ser_mem_info_get(unit, mem, &tcam_idx);
  15986     if (rv == SOC_E_NONE) {
  15987         if (tcams[tcam_idx].mem == L3_DEFIPm) {
  15988             test_field = VALID0f;
  15989         } else if (tcams[tcam_idx].mem == L3_DEFIP_PAIR_128m) {
  15990             test_field = VALID0_LWRf;
  15991         } else
  15992 #ifdef INCLUDE_XFLOW_MACSEC
  15993             if (soc_feature(unit, soc_feature_xflow_macsec) &&
  15994                 (tcams[tcam_idx].mem == ISEC_SP_TCAMm)) {
  15995             test_field = MASKf;
  15996         } else
  15997 #endif
  15998         {
  15999             test_field = VALIDf;
  16000         }
  16001         soc_ser_create_test_data(unit, tmp_entry, fieldData,
  16002                                  SER_RANGE_ENABLEr, tcam_idx, INVALIDf, mem,
  16003                                  test_field, block, REG_PORT_ANY,
  16004                                  soc_acc_type_target, index, &tcam_test_data);
  16005         found_mem = TRUE;
  16006         is_tcam = 1;
  16007     }
  16008 
  16009         rv = _soc_monterey_ser_mem_info_get (unit, mem, &ser_mem_info);
  16010         if (rv == SOC_E_NONE) {
  16011             if (mem == ING_L3_NEXT_HOPm) {
  16012                 test_field= ECC_1f;
  16013             } else {
  16014                 test_field = EVEN_PARITYf;
  16015             }
  16016 #ifdef INCLUDE_XFLOW_MACSEC
  16017             /* ESEC_SA_TABLEm has 4 banks of memory with individyal SER control and status */
  16018             if (soc_feature(unit, soc_feature_xflow_macsec) &&
  16019                     mem == ESEC_SA_TABLEm) {
  16020                 switch (index % 4) {
  16021                     case 0:
  16022                         ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL0r;
  16023                         ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL0r;
  16024                         break;
  16025                     case 1:
  16026                         ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL1r;
  16027                         ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL1r;
  16028                         break;
  16029                     case 2:
  16030                         ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL2r;
  16031                         ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL2r;
  16032                         break;
  16033                     case 3:
  16034                         ser_mem_info->en_ctrl.ctrl_type.en_reg =ECC_CTLSTS_ESATBL3r;
  16035                         ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg = ECC_CTLSTS_ESATBL3r;
  16036                         break;
  16037                     default:
  16038                         break;
  16039                 }
  16040             }
  16041 #endif
  16042         soc_ser_create_test_data(unit, tmp_entry, fieldData,
  16043                            ser_mem_info->en_ctrl.ctrl_type.en_reg,
  16044                            SOC_INVALID_TCAM_PARITY_BIT,
  16045                            ser_mem_info->en_ctrl.en_fld,
  16046                            mem, test_field, block,
  16047                            REG_PORT_ANY, soc_acc_type_target,
  16048                            index, &hw_test_data);
  16049         if (SOC_REG_IS_VALID(unit, ser_mem_info->ecc1b_ctrl.ctrl_type.en_reg) &&
  16050                         (INVALIDf != ser_mem_info->ecc1b_ctrl.en_fld)) {
  16051                                         flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16052         }
  16053          SOC_IF_ERROR_RETURN
  16054                      (ser_test_mem_index_remap(unit, &hw_test_data, &mem_has_ecc));
  16055          if (mem_has_ecc) {
  16056              flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16057          }
  16058 /* ING_VLAN_VFI_MEMBERSHIP is ECC protected, however
  16059          * there is no 1bit error reporting control register for it.
  16060                   */
  16061          if (mem == ING_VLAN_VFI_MEMBERSHIPm) {
  16062              flags |= SOC_INJECT_ERROR_2BIT_ECC;
  16063          }
  16064          found_mem = TRUE;
  16065          is_fifo_mem = 1;
  16066     }
  16067     if (found_mem) {
  16068        test_data = is_tcam ? &tcam_test_data : &hw_test_data;
  16069                 test_data->acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16070                 if (inject_only) {
  16071                     /* Check if the memory is to be skipped */
  16072                     if (soc_monterey_ser_test_skip_check(unit,mem)) {
  16073                        TR_TEST_MEM_PRINT(unit, fail_message, mem);
  16074                        return SOC_E_UNAVAIL;
  16075                     }
  16076         
  16077                     /*Disable parity*/
  16078                     SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, test_data, 0));
  16079                     /*Read the memory (required for successful injection)*/
  16080                     SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, test_data));
  16081                      /*Inject error*/
  16082                     SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags,
  16083                                                                  test_data));
  16084                     /*Enable parity*/
  16085                     rv = _ser_test_parity_control(unit, test_data, 1);
  16086                 } else {
  16087                     if (cmd) {
  16088                         tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16089                         ser_test_cmd_generate(unit, &tcam_test_data);
  16090                         hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16091                         ser_test_cmd_generate(unit, &hw_test_data);
  16092                     } else {
  16093                         if (is_tcam) {
  16094                             tcam_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16095                             rv = _soc_monterey_perform_ser_test(unit, &tcam_test_data, test_type,
  16096                                                               &skip_count, &error_count);
  16097                             if (SOC_SUCCESS(rv)) {
  16098                                 LOG_CLI((BSL_META_U(unit,
  16099                                         "TCAM SER test PASSED for memory %s\n\n"),
  16100                                         tcam_test_data.mem_name));
  16101                             } else {
  16102                                 LOG_CLI((BSL_META_U(unit,
  16103                                         "TCAM SER test FAILED for memory %s\n\n"),
  16104                                         tcam_test_data.mem_name));
  16105                             }
  16106                     }
  16107      
  16108                     if (is_fifo_mem) {
  16109                         hw_test_data.acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  16110                        rv = _soc_monterey_perform_ser_test(unit, &hw_test_data, test_type,
  16111                                                                      &skip_count, &error_count);
  16112                                       if (SOC_SUCCESS(rv)) {
  16113                                            LOG_CLI((BSL_META_U(unit,
  16114                                                    "H/W SER test PASSED for memory %s\n\n"),
  16115                                                    hw_test_data.mem_name));
  16116                                        } else {
  16117                                            LOG_CLI((BSL_META_U(unit,
  16118                                                   "H/W SER test FAILED for memory %s\n\n"),
  16119                                                    hw_test_data.mem_name));
  16120                                        }
  16121                                    }
  16122                    
  16123                                    if (skip_count != 0 ) {
  16124                                        LOG_CLI((BSL_META_U(unit,
  16125                                                   "Test skipped due to known issues with "
  16126                                                   "this memory.\n")));
  16127                                    }
  16128                                }
  16129                            }
  16130     } else {
  16131         TR_TEST_MEM_PRINT(unit, fail_message, mem);
  16132         rv = SOC_E_UNAVAIL;
  16133     }
  16134     return rv;
  16135 }
  16136 #undef TR_TEST_MEM_PRINT
  16137 
  16138 /*
  16139  * Function:
  16140  *      soc_monterey_ser_inject_error
  16141  * Purpose:
  16142  *      Injects an error into a single monterey memory
  16143  * Parameters:
  16144  *      unit        - (IN) Device Number
  16145  *      mem         - (IN) The memory into which an error will be injected
  16146  *      pipeTarget  - (IN) The pipe (x/y) to use when injecting the error
  16147  *      index       - (IN) The index into which the error will be injected.
  16148  */
  16149 soc_error_t
  16150 soc_monterey_ser_inject_error (int unit, uint32 flags, soc_mem_t mem,
  16151                              int pipe_target, int block, int index)
  16152 {
  16153     /* Check if memory needs to be skipped */
  16154     if (ser_monterey_test_fun.injection_support) {
  16155         SOC_IF_ERROR_RETURN(
  16156             soc_monterey_ser_error_injection_support(unit, mem, pipe_target));
  16157     }
  16158 
  16159     return soc_monterey_ser_inject_or_test_mem(unit, mem, pipe_target, block,
  16160                                              index, SER_SINGLE_INDEX, TRUE,
  16161                                              FALSE, flags);
  16162 }
  16163 
  16164 /*
  16165  * Function:
  16166  *      soc_monterey_ser_test_mem
  16167  * Purpose:
  16168  *      Perform SER test on a single memory, or generate a test the user can
  16169  *      enter by the command line.
  16170  * Parameters:
  16171  *      unit        - (IN) Device Number
  16172  *      mem         - (IN) The memory into which an error will be injected
  16173  *      test_type   - (IN) How many indices to test in the passes memory
  16174  *      cmd         - (IN) TRUE if a command-line test is desired.
  16175  * Returns:
  16176  *      SOC_E_NONE if test passes, an error otherwise (multiple types of errors
  16177  *      are possible.)
  16178  */
  16179 soc_error_t
  16180 soc_monterey_ser_test_mem (int unit, soc_mem_t mem, _soc_ser_test_t test_type,
  16181                         int cmd)
  16182 {
  16183     return soc_monterey_ser_inject_or_test_mem (unit, mem, _SOC_ACC_TYPE_PIPE_ANY,
  16184                                               MEM_BLOCK_ANY, 0,
  16185                                               test_type, FALSE, cmd, FALSE);
  16186 }
  16187 #endif /*defined(SER_TR_TEST_SUPPORT)*/
  16188 
  16189 soc_error_t
  16190 soc_monterey_gatingconfig_init(int unit) { 
  16191 
  16192 
  16193      uint32 rval = 0;
  16194 
  16195      soc_reg_field_set(unit, IP_SER_CLK_GATE_CTRLr , &rval, DISABLE_CLK_GATEf, 1);
  16196      SOC_IF_ERROR_RETURN(WRITE_IP_SER_CLK_GATE_CTRLr(unit ,rval)); 
  16197      rval = 0;
  16198      soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16199      soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16200      soc_reg_field_set(unit, ICFG_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IPRC_DATAf,1);
  16201      SOC_IF_ERROR_RETURN(WRITE_ICFG_CLK_GATING_CONTROLr(unit ,rval)); 
  16202      rval = 0;
  16203      soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16204      soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16205      soc_reg_field_set(unit, EGR_EFPPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16206      SOC_IF_ERROR_RETURN(WRITE_EGR_EFPPARS_CLK_GATING_CONTROLr(unit ,rval)); 
  16207      rval = 0;
  16208 
  16209      soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16210      soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr, &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16211      soc_reg_field_set(unit, EGR_EHCPM_CLK_GATING_CONTROLr, &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16212      SOC_IF_ERROR_RETURN(WRITE_EGR_EHCPM_CLK_GATING_CONTROLr(unit ,rval)); 
  16213      rval = 0;
  16214 
  16215      soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16216      soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16217      soc_reg_field_set(unit, IPARS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IPRC_DATAf,1);
  16218      SOC_IF_ERROR_RETURN(WRITE_IPARS_CLK_GATING_CONTROLr(unit ,rval)); 
  16219      rval = 0; 
  16220 
  16221  
  16222      soc_reg_field_set(unit, EGR_EIPT_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16223      soc_reg_field_set(unit, EGR_EIPT_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1);
  16224      SOC_IF_ERROR_RETURN(WRITE_EGR_EIPT_CLK_GATING_CONTROLr(unit ,rval)); 
  16225      rval = 0; 
  16226 
  16227      soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16228      soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16229      soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_SER_STATUS_BUSf,1);
  16230      soc_reg_field_set(unit, EGR_EL3_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16231      SOC_IF_ERROR_RETURN(WRITE_EGR_EL3_CLK_GATING_CONTROLr(unit ,rval)); 
  16232      rval = 0; 
  16233 
  16234      soc_reg_field_set(unit,IVXLT_CONTROLr, &rval, DISABLE_CLK_GATINGf, 1);
  16235      soc_reg_field_set(unit, IVXLT_CONTROLr , &rval, VLAN_XLATE_DISABLE_CLK_GATINGf, 1);
  16236      SOC_IF_ERROR_RETURN(WRITE_IVXLT_CONTROLr(unit ,rval)); 
  16237      rval = 0; 
  16238 
  16239      soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16240      soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16241      soc_reg_field_set(unit, EGR_EPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16242      SOC_IF_ERROR_RETURN(WRITE_EGR_EPMOD_CLK_GATING_CONTROLr(unit ,rval)); 
  16243      rval = 0; 
  16244 
  16245      soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16246      soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1);
  16247      SOC_IF_ERROR_RETURN(WRITE_EGR_ESW_CLK_GATING_CONTROLr(unit ,rval)); 
  16248      rval = 0; 
  16249 
  16250      soc_reg_field_set(unit, EGR_ESW_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16251      SOC_IF_ERROR_RETURN(WRITE_EGR_ESW_CLK_GATING_CONTROLr(unit ,rval)); 
  16252      rval = 0; 
  16253      soc_reg_field_set(unit, IVP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16254      SOC_IF_ERROR_RETURN(WRITE_IVP_CLK_GATING_CONTROLr(unit ,rval)); 
  16255      rval = 0; 
  16256      soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16257      soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_IN_HASH_TABLESf, 1);
  16258      soc_reg_field_set(unit, EGR_EVLAN_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1);
  16259      SOC_IF_ERROR_RETURN(WRITE_EGR_EVLAN_CLK_GATING_CONTROLr(unit ,rval)); 
  16260      rval = 0; 
  16261 
  16262      soc_reg_field_set(unit, IMPLS_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16263      SOC_IF_ERROR_RETURN(WRITE_IMPLS_CLK_GATING_CONTROLr(unit ,rval)); 
  16264      rval = 0; 
  16265 
  16266      soc_reg_field_set(unit,EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16267      soc_reg_field_set(unit, EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16268      soc_reg_field_set(unit, EGR_EFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16269      WRITE_EGR_EFP_CLK_GATING_CONTROLr(unit ,rval); 
  16270      rval = 0; 
  16271 
  16272      soc_reg_field_set(unit,EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16273      soc_reg_field_set(unit, EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_DATA_BUSf,1);
  16274      soc_reg_field_set(unit, EGR_EFPMOD_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf,1);
  16275      WRITE_EGR_EFPMOD_CLK_GATING_CONTROLr(unit ,rval); 
  16276 
  16277      soc_reg_field_set(unit, IDISC_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16278      WRITE_IDISC_CLK_GATING_CONTROLr(unit ,rval); 
  16279      rval = 0; 
  16280 
  16281      soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16282      soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, L2_ISS_DISABLE_CLK_GATINGf, 1);
  16283      soc_reg_field_set(unit, IL2LU_CONTROLr , &rval, L2_IPRC_DATA_DISABLE_CLK_GATINGf, 1);
  16284      SOC_IF_ERROR_RETURN(WRITE_IL2LU_CONTROLr(unit ,rval)); 
  16285      rval = 0; 
  16286 
  16287      soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16288      soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, L3_ISS_DISABLE_CLK_GATINGf, 1);
  16289      soc_reg_field_set(unit, IL3LU_CONTROLr , &rval, L3_IPRC_DATA_DISABLE_CLK_GATINGf, 1);
  16290      SOC_IF_ERROR_RETURN(WRITE_IL3LU_CONTROLr(unit ,rval)); 
  16291      rval = 0; 
  16292      soc_reg_field_set(unit, ILPM_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16293      soc_reg_field_set(unit, ILPM_CONTROLr , &rval, LPM_IPRC_DATA_DISABLE_CLK_GATINGf, 1);
  16294      SOC_IF_ERROR_RETURN(WRITE_ILPM_CONTROLr(unit ,rval)); 
  16295      rval = 0; 
  16296 
  16297      soc_reg_field_set(unit, IRSEL1_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16298      SOC_IF_ERROR_RETURN(WRITE_IRSEL1_CLK_GATING_CONTROLr(unit ,rval)); 
  16299      rval = 0; 
  16300      
  16301      soc_reg_field_set(unit, ISW1_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16302      SOC_IF_ERROR_RETURN(WRITE_ISW1_CLK_GATING_CONTROLr(unit ,rval)); 
  16303      rval = 0; 
  16304 
  16305      soc_reg_field_set(unit, IFP_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16306      SOC_IF_ERROR_RETURN(WRITE_IFP_CLK_GATING_CONTROLr(unit ,rval)); 
  16307      rval = 0; 
  16308 
  16309      soc_reg_field_set(unit, IRSEL2_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATINGf, 1);
  16310      soc_reg_field_set(unit, IRSEL2_CLK_GATING_CONTROLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1);
  16311      SOC_IF_ERROR_RETURN(WRITE_IRSEL2_CLK_GATING_CONTROLr(unit ,rval)); 
  16312      rval = 0; 
  16313 
  16314      soc_reg_field_set(unit,  ISW2_CLK_GATING_CTRLr , &rval, DISABLE_CLK_GATINGf, 1);
  16315      soc_reg_field_set(unit,  ISW2_CLK_GATING_CTRLr , &rval, DISABLE_CLK_GATING_ARRAYSf, 1);
  16316      SOC_IF_ERROR_RETURN(WRITE_ISW2_CLK_GATING_CTRLr(unit ,rval)); 
  16317      rval = 0; 
  16318      return SOC_E_NONE; 
  16319 }
  16320 
  16321 #ifdef INCLUDE_XFLOW_MACSEC
  16322 /*
  16323  * Function:
  16324  *      soc_monterey_process_macsec_intr
  16325  * Description:
  16326  *      Monterey specific DPC function to service MACSEC interrupts
  16327  * Parameters:
  16328  *      unit_vp       - Device number
  16329  *      d1            - IRQ4 mask
  16330  *      d2            - IRQ4 number (to distinguish between
  16331  *                      different types of interrupts).
  16332  */
  16333 void
  16334 soc_monterey_process_macsec_intr(void *unit_vp, void *d1,
  16335                                  void *d2, void *d3, void *d4)
  16336 {
  16337     int unit = PTR_TO_INT(unit_vp);
  16338     int irq4_num = PTR_TO_INT(d4);
  16339     int mask = PTR_TO_INT(d2);
  16340     uint8 rbi;
  16341     const _soc_monterey_ser_route_block_t *rb;
  16342     uint64 rb_rval64;
  16343 
  16344     for (rbi = 0; ; rbi++) {
  16345         rb = &_soc_monterey_macsec_ser_route_blocks_irq4[rbi];
  16346         if (rb->cmic_bit == 0) {
  16347             break;
  16348         }
  16349 
  16350         if (rb->cmic_bit != (1 << irq4_num)) {
  16351             continue;
  16352         }
  16353         /* Read per route block status register */
  16354         soc_reg_get(unit, rb->status_reg, REG_PORT_ANY, 0, &rb_rval64);
  16355         if (COMPILER_64_IS_ZERO(rb_rval64)) {
  16356             continue;
  16357         }
  16358 
  16359         /* Process ECC interrupts */
  16360         if(soc_reg64_field32_get(unit, rb->status_reg, rb_rval64,
  16361                                  ECCERR_INTf)) {
  16362             (void)xflow_macsec_process_ecc_intr(unit);
  16363         }
  16364         /* Process MACSEC functional interrupts */
  16365         (void)xflow_macsec_process_functional_intr(unit, rb_rval64);
  16366 
  16367     } /* For loop */
  16368 
  16369     /* Enable the interrupts */
  16370     if (d2 != NULL) {
  16371         (void)soc_cmicm_intr4_enable(unit, mask);
  16372     }
  16373 
  16374     return;
  16375 }
  16376 #endif
  16377 /*
  16378  * Function:
  16379  *      soc_monterey_process_pm_intr
  16380  * Description:
  16381  *      Monterey specific DPC function to service PM interrupts
  16382  * Parameters:
  16383  *      unit_vp       - Device number
  16384  *      d1            - IRQ4 mask
  16385  *      d2            - IRQ4 number (to distinguish between
  16386  *                      different types of interrupts).
  16387  */
  16388 void
  16389 soc_monterey_process_pm_intr(void *unit_vp, void *d1,
  16390                              void *d2, void *d3, void *d4)
  16391 {
  16392     int unit = PTR_TO_INT(unit_vp);
  16393     int irq4_num = PTR_TO_INT(d4);
  16394     int mask = PTR_TO_INT(d2);
  16395     uint8 rbi;
  16396     int port = -1, block_info_idx;
  16397     const _soc_monterey_pm_cpri_intr_info_t *rb;
  16398     portmod_cpri_ecc_intr_info_t ecc_info;
  16399     _soc_monterey_pm_ecc_info_t  pm_ecc_info;
  16400 
  16401     for (rbi = 0; ; rbi++) {
  16402         rb = &_soc_monterey_pm_cpri_intr_info_irq4[rbi];
  16403         if (rb->cmic_bit == 0) {
  16404             break;
  16405         }
  16406 
  16407         if (rb->cmic_bit != (1 << irq4_num)) {
  16408             continue;
  16409         }
  16410 
  16411         SOC_BLOCK_ITER(unit, block_info_idx, rb->blocktype) {
  16412             if (SOC_BLOCK_INFO(unit, block_info_idx).number == rb->id) {
  16413                 port = SOC_BLOCK_PORT(unit, block_info_idx);
  16414                 break;
  16415             }
  16416         }
  16417 
  16418         if (port != -1) {
  16419 
  16420             /* Process other CPRI interrupts */
  16421             (void)portmod_cpri_port_interrupt_process(unit, port);
  16422 
  16423             memset(&ecc_info, 0, sizeof(ecc_info));
  16424 
  16425             /* Process ECC interrupts */
  16426             (void)portmod_cpri_port_ecc_interrupt_status_get(unit, port,
  16427                                                              &ecc_info);
  16428 
  16429             /* Report ECC errors */
  16430             if (ecc_info.ecc_num_bits_err != PORTMOD_PM_CPRI_ECC_ERR_NONE) {
  16431                 pm_ecc_info.type = _SOC_PARITY_TYPE_ECC;
  16432                 pm_ecc_info.ecc_err_type =
  16433                                      ecc_info.ecc_num_bits_err;
  16434                 pm_ecc_info.mem = ecc_info.err_mem_info;
  16435                 pm_ecc_info.mem_index = ecc_info.err_addr;
  16436                 pm_ecc_info.port = ecc_info.port;
  16437                 pm_ecc_info.mem_str = ecc_info.mem_str;
  16438 
  16439                 _soc_monterey_ser_process_pm_ecc(unit,
  16440                                   ecc_info.port, &pm_ecc_info);
  16441 
  16442                 LOG_VERBOSE(BSL_LS_SOC_COMMON,
  16443                            (BSL_META_U(unit, "ECC interrupt info\n"
  16444                          "m - %s, ecc_num_bits - %d, addr %x\n"),
  16445                          SOC_MEM_NAME(unit, ecc_info.err_mem_info),
  16446                          ecc_info.ecc_num_bits_err,
  16447                          ecc_info.err_addr));
  16448             }
  16449         } /* (port != -1) */
  16450     } /* For loop */
  16451 
  16452     /* Enable the interrupts */
  16453     if (d2 != NULL) {
  16454         (void)soc_cmicm_intr4_enable(unit, mask);
  16455     }
  16456 
  16457     return;
  16458 }
  16459 
  16460 /*
  16461  * Apache chip driver functions.
  16462  */
  16463 soc_functions_t soc_monterey_drv_funs = {
  16464     _soc_monterey_misc_init,
  16465     _soc_monterey_mmu_init,
  16466     _soc_monterey_age_timer_get,
  16467     _soc_monterey_age_timer_max_get,
  16468     _soc_monterey_age_timer_set,
  16469     NULL,
  16470     _soc_monterey_mdio_reg_read,
  16471     _soc_monterey_mdio_reg_write,
  16472      soc_monterey_bond_info_init,
  16473     _soc_monterey_misc_deinit
  16474 };
  16475 
  16476 
  16477 #endif /* BCM_MONTEREY_SUPPORT */