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

trident.c (478224B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        trident.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 
     15 #include <sal/core/boot.h>
     16 #include <shared/bsl.h>
     17 #include <soc/trident.h>
     18 #include <soc/bradley.h>
     19 #include <soc/drv.h>
     20 #include <soc/error.h>
     21 #include <soc/debug.h>
     22 #include <soc/mem.h>
     23 #include <soc/hash.h>
     24 #include <sal/appl/config.h>
     25 #include <soc/soc_ser_log.h>
     26 
     27 #ifdef BCM_TRIDENT_SUPPORT
     28 
     29 typedef enum {
     30     _SOC_PARITY_TYPE_NONE,
     31     _SOC_PARITY_TYPE_GENERIC,
     32     _SOC_PARITY_TYPE_PARITY,
     33     _SOC_PARITY_TYPE_ECC,
     34     _SOC_PARITY_TYPE_HASH,
     35     _SOC_PARITY_TYPE_EDATABUF,
     36     _SOC_PARITY_TYPE_COUNTER,
     37     _SOC_PARITY_TYPE_XLPORT,
     38     _SOC_PARITY_TYPE_MMU_THDO,
     39     _SOC_PARITY_TYPE_START_ERR,
     40     _SOC_PARITY_TYPE_MMU_WRED,
     41     _SOC_PARITY_TYPE_MMU_THDI,
     42     _SOC_PARITY_TYPE_MMU_MTRO,
     43     _SOC_PARITY_TYPE_MMU_ES,
     44     _SOC_PARITY_TYPE_MMU_IPMC,
     45     _SOC_PARITY_TYPE_MMU_VLAN,
     46     _SOC_PARITY_TYPE_SER,
     47     _SOC_PARITY_TYPE_MMU_AGING,
     48     _SOC_PARITY_TYPE_MMU_CTR
     49 } _soc_trident_parity_info_type_t;
     50 
     51 typedef struct _soc_trident_parity_reg_s {
     52     soc_reg_t               reg;
     53     char                    *mem_str;
     54 } _soc_trident_parity_reg_t;
     55 
     56 typedef struct _soc_trident_parity_mmu_bit_s {
     57     uint32 bit_pos;
     58     soc_mem_t mem;
     59 } _soc_trident_parity_mmu_bit_t;
     60 
     61 typedef struct _soc_trident_parity_info_s {
     62     _soc_trident_parity_info_type_t   type;
     63     struct _soc_trident_parity_info_s *info;
     64     int                               id;
     65     soc_field_t                       group_reg_enable_field;
     66     soc_field_t                       group_reg_status_field;
     67     soc_mem_t                         mem;
     68     char                              *mem_str;
     69     soc_reg_t                         enable_reg;
     70     soc_field_t                       enable_field;
     71     soc_reg_t                         intr_status_reg;
     72     _soc_trident_parity_reg_t         *intr_status_reg_list;
     73     soc_reg_t                         nack_status_reg;
     74     _soc_trident_parity_reg_t         *nack_status_reg_list;
     75 } _soc_trident_parity_info_t;
     76 
     77 typedef struct _soc_trident_parity_route_block_s {
     78     uint32             cmic_bit;
     79     soc_block_t        blocktype;
     80     int                pipe;
     81     soc_reg_t          enable_reg;
     82     soc_reg_t          status_reg;
     83     _soc_trident_parity_info_t *info;
     84 } _soc_trident_parity_route_block_t;
     85 
     86 STATIC _soc_trident_parity_reg_t _soc_trident_egr_vlan_xlate_intr_reg[] = {
     87     { EGR_VLAN_XLATE_PARITY_STATUS_INTR_0r, NULL },
     88     { EGR_VLAN_XLATE_PARITY_STATUS_INTR_1r, NULL } };
     89 STATIC _soc_trident_parity_reg_t _soc_trident_egr_vlan_xlate_nack_reg[] = {
     90     { EGR_VLAN_XLATE_PARITY_STATUS_NACK_0r, NULL },
     91     { EGR_VLAN_XLATE_PARITY_STATUS_NACK_1r, NULL } };
     92 STATIC _soc_trident_parity_reg_t _soc_trident_vlan_xlate_intr_reg[] = {
     93     { VLAN_XLATE_PARITY_STATUS_INTR_0r, NULL },
     94     { VLAN_XLATE_PARITY_STATUS_INTR_1r, NULL } };
     95 STATIC _soc_trident_parity_reg_t _soc_trident_vlan_xlate_nack_reg[] = {
     96     { VLAN_XLATE_PARITY_STATUS_NACK_0r, NULL },
     97     { VLAN_XLATE_PARITY_STATUS_NACK_1r, NULL } };
     98 STATIC _soc_trident_parity_reg_t _soc_trident_mpls_entry_intr_reg[] = {
     99     { MPLS_ENTRY_PARITY_STATUS_INTR_0r, NULL },
    100     { MPLS_ENTRY_PARITY_STATUS_INTR_1r, NULL } };
    101 STATIC _soc_trident_parity_reg_t _soc_trident_mpls_entry_nack_reg[] = {
    102     { MPLS_ENTRY_PARITY_STATUS_NACK_0r, NULL },
    103     { MPLS_ENTRY_PARITY_STATUS_NACK_1r, NULL } };
    104 STATIC _soc_trident_parity_reg_t _soc_trident_l3_entry_only_intr_reg[] = {
    105     { L3_ENTRY_PARITY_STATUS_INTR_0r, NULL },
    106     { L3_ENTRY_PARITY_STATUS_INTR_1r, NULL } };
    107 STATIC _soc_trident_parity_reg_t _soc_trident_l3_entry_only_nack_reg[] = {
    108     { L3_ENTRY_PARITY_STATUS_NACK_0r, NULL },
    109     { L3_ENTRY_PARITY_STATUS_NACK_1r, NULL } };
    110 STATIC _soc_trident_parity_reg_t _soc_trident_l2_entry_only_intr_reg[] = {
    111     { L2_ENTRY_PARITY_STATUS_INTR_0r, NULL },
    112     { L2_ENTRY_PARITY_STATUS_INTR_1r, NULL } };
    113 STATIC _soc_trident_parity_reg_t _soc_trident_l2_entry_only_nack_reg[] = {
    114     { L2_ENTRY_PARITY_STATUS_NACK_0r, NULL },
    115     { L2_ENTRY_PARITY_STATUS_NACK_1r, NULL } };
    116 STATIC _soc_trident_parity_reg_t _soc_trident_pg5_fifo_intr_reg[] = {
    117     { PORT_GROUP5_XLP0_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP0 BOD FIFO" },
    118     { PORT_GROUP5_XLP0_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP0 CTRL FIFO" },
    119     { PORT_GROUP5_XLP1_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP1 BOD FIFO" },
    120     { PORT_GROUP5_XLP1_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP1 CTRL FIFO" },
    121     { PORT_GROUP5_XLP2_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP2 BOD FIFO" },
    122     { PORT_GROUP5_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP2 CTRL FIFO" },
    123     { PORT_GROUP5_XLP3_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP3 BOD FIFO" },
    124     { PORT_GROUP5_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP3 CTRL FIFO" },
    125     { PORT_GROUP5_XLP4_BOD_FIFO_ECC_STATUS_INTRr, "PG5 XLP4 BOD FIFO" },
    126     { PORT_GROUP5_XLP4_CTRL_FIFO_ECC_STATUS_INTRr, "PG5 XLP4 CTRL FIFO" },
    127     { INVALIDr } };
    128 STATIC _soc_trident_parity_reg_t _soc_trident_pg4_fifo_intr_reg[] = {
    129     { PORT_GROUP4_XLP0_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP0 BOD FIFO" },
    130     { PORT_GROUP4_XLP0_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP0 CTRL FIFO" },
    131     { PORT_GROUP4_XLP1_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP1 BOD FIFO" },
    132     { PORT_GROUP4_XLP1_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP1 CTRL FIFO" },
    133     { PORT_GROUP4_XLP2_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP2 BOD FIFO" },
    134     { PORT_GROUP4_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP2 CTRL FIFO" },
    135     { PORT_GROUP4_XLP3_BOD_FIFO_ECC_STATUS_INTRr, "PG4 XLP3 BOD FIFO" },
    136     { PORT_GROUP4_XLP3_CTRL_FIFO_ECC_STATUS_INTRr, "PG4 XLP3 CTRL FIFO" },
    137     { INVALIDr } };
    138 
    139 STATIC _soc_trident_parity_info_t _soc_trident_xlport_parity_info[] = {
    140     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    141         TXFIFO_MEM_ERRf,
    142         TXFIFO_MEM_ERRf,
    143         INVALIDm, "TX FIFO",
    144         INVALIDr, INVALIDf,
    145         XLPORT_TXFIFO_MEM_ECC_STATUSr, NULL,
    146         INVALIDr, NULL },
    147     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    148         MIB_TSC_MEM0_ERRf,
    149         MIB_TSC_MEM0_ERRf,
    150         INVALIDm, "TX MIB MEM0",
    151         INVALIDr, INVALIDf,
    152         XLPORT_MIB_TSC_MEM0_ECC_STATUSr, NULL,
    153         INVALIDr, NULL },
    154     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    155         MIB_TSC_MEM1_ERRf,
    156         MIB_TSC_MEM1_ERRf,
    157         INVALIDm, "TX MIB MEM1",
    158         INVALIDr, INVALIDf,
    159         XLPORT_MIB_TSC_MEM1_ECC_STATUSr, NULL,
    160         INVALIDr, NULL },
    161     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    162         MIB_TSC_MEM2_ERRf,
    163         MIB_TSC_MEM2_ERRf,
    164         INVALIDm, "TX MIB MEM2",
    165         INVALIDr, INVALIDf,
    166         XLPORT_MIB_TSC_MEM2_ECC_STATUSr, NULL,
    167         INVALIDr, NULL },
    168     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    169         MIB_TSC_MEM3_ERRf,
    170         MIB_TSC_MEM3_ERRf,
    171         INVALIDm, "TX MIB MEM3",
    172         INVALIDr, INVALIDf,
    173         XLPORT_MIB_TSC_MEM3_ECC_STATUSr, NULL,
    174         INVALIDr, NULL },
    175     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    176         MIB_RSC_MEM0_ERRf,
    177         MIB_RSC_MEM0_ERRf,
    178         INVALIDm, "RX MIB MEM0",
    179         INVALIDr, INVALIDf,
    180         XLPORT_MIB_RSC_MEM0_ECC_STATUSr, NULL,
    181         INVALIDr, NULL },
    182     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    183         MIB_RSC_MEM1_ERRf,
    184         MIB_RSC_MEM1_ERRf,
    185         INVALIDm, "RX MIB MEM1",
    186         INVALIDr, INVALIDf,
    187         XLPORT_MIB_RSC_MEM1_ECC_STATUSr, NULL,
    188         INVALIDr, NULL },
    189     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    190         MIB_RSC_MEM2_ERRf,
    191         MIB_RSC_MEM2_ERRf,
    192         INVALIDm, "RX MIB MEM2",
    193         INVALIDr, INVALIDf,
    194         XLPORT_MIB_RSC_MEM2_ECC_STATUSr, NULL,
    195         INVALIDr, NULL },
    196     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    197         MIB_RSC_MEM3_ERRf,
    198         MIB_RSC_MEM3_ERRf,
    199         INVALIDm, "RX MIB MEM3",
    200         INVALIDr, INVALIDf,
    201         XLPORT_MIB_RSC_MEM3_ECC_STATUSr, NULL,
    202         INVALIDr, NULL },
    203     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    204         MIB_RSC_MEM4_ERRf,
    205         MIB_RSC_MEM4_ERRf,
    206         INVALIDm, "RX MIB MEM4",
    207         INVALIDr, INVALIDf,
    208         XLPORT_MIB_RSC_MEM4_ECC_STATUSr, NULL,
    209         INVALIDr, NULL },
    210     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    211 };
    212 
    213 STATIC _soc_trident_parity_info_t _soc_trident_xlport1_parity_info[] = {
    214     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    215         TXFIFO_MEM_ENf,
    216         TXFIFO_MEM_ENf,
    217         INVALIDm, "TX FIFO",
    218         INVALIDr, INVALIDf,
    219         INVALIDr, NULL,
    220         INVALIDr, NULL },
    221     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    222         MIB_TSC_MEM_ENf,
    223         MIB_TSC_MEM_ENf,
    224         INVALIDm, "TX FIFO",
    225         INVALIDr, INVALIDf,
    226         INVALIDr, NULL,
    227         INVALIDr, NULL },
    228     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    229         MIB_RSC_MEM_ENf,
    230         MIB_RSC_MEM_ENf,
    231         INVALIDm, "TX FIFO",
    232         INVALIDr, INVALIDf,
    233         INVALIDr, NULL,
    234         INVALIDr, NULL },
    235     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    236 };
    237 
    238 STATIC _soc_trident_parity_info_t _soc_trident_mmu_parity_info[] = {
    239     { _SOC_PARITY_TYPE_MMU_AGING, NULL, 0,
    240         AGING_CTR_PAR_ERR_ENf,
    241         AGING_CTR_PAR_ERRf,
    242         MMU_AGING_CTRm, NULL,
    243         INVALIDr, INVALIDf,
    244         INVALIDr, NULL,
    245         INVALIDr, NULL },
    246     { _SOC_PARITY_TYPE_MMU_AGING, NULL, 0,
    247         AGING_EXP_PAR_ERR_ENf,
    248         AGING_EXP_PAR_ERRf,
    249         MMU_AGING_EXPm, NULL,
    250         INVALIDr, INVALIDf,
    251         INVALIDr, NULL,
    252         INVALIDr, NULL },
    253     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    254         CCP_PAR_ERR_ENf,
    255         CCP_PAR_ERRf,
    256         INVALIDm, "MMU CCP",
    257         INVALIDr, INVALIDf,
    258         INVALIDr, NULL,
    259         INVALIDr, NULL },
    260     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    261         CFAP_PAR_ERR_ENf,
    262         CFAP_PAR_ERRf,
    263         INVALIDm, "MMU CFAP",
    264         INVALIDr, INVALIDf,
    265         INVALIDr, NULL,
    266         INVALIDr, NULL },
    267     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    268         CFAP_MEM_FAIL_ENf,
    269         CFAP_MEM_FAILf,
    270         INVALIDm, "MMU CFAP FAIL",
    271         INVALIDr, INVALIDf,
    272         INVALIDr, NULL,
    273         INVALIDr, NULL },
    274     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    275         DEQ_MPB_ERR_ENf,
    276         DEQ_MPB_ERRf,
    277         INVALIDm, "MMU DEQ MPB",
    278         MEM_FAIL_INT_ENr, DEQ_MPB_ERR_ENf,
    279         INVALIDr, NULL,
    280         INVALIDr, NULL },
    281     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    282         DEQ_PKTHDR_ERR_ENf,
    283         DEQ_PKTHDR_ERRf,
    284         INVALIDm, "MMU DEQ PKTHDR",
    285         INVALIDr, INVALIDf,
    286         INVALIDr, NULL,
    287         INVALIDr, NULL },
    288     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    289         DEQ_NOT_IP_ERR_ENf,
    290         DEQ_NOT_IP_ERRf,
    291         INVALIDm, "MMU DEQ NOT IP",
    292         INVALIDr, INVALIDf,
    293         INVALIDr, NULL,
    294         INVALIDr, NULL },
    295     { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0,
    296         CTR_UC_CNT_ENf,
    297         CTR_UC_CNTf,
    298         MMU_CTR_UC_DROP_MEMm, NULL,
    299         INVALIDr, INVALIDf,
    300         INVALIDr, NULL,
    301         INVALIDr, NULL },
    302     { _SOC_PARITY_TYPE_START_ERR, NULL, 0,
    303         START_BY_START_ERR_ENf,
    304         START_BY_START_ERRf,
    305         INVALIDm, "MMU START BY START",
    306         INVALIDr, INVALIDf,
    307         INVALIDr, NULL,
    308         INVALIDr, NULL },
    309     { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0,
    310         CTR_MC_CNT_ENf,
    311         CTR_MC_CNTf,
    312         MMU_CTR_MC_DROP_MEMm, NULL,
    313         INVALIDr, INVALIDf,
    314         INVALIDr, NULL,
    315         INVALIDr, NULL },
    316     { _SOC_PARITY_TYPE_MMU_CTR, NULL, 0,
    317         CTR_COLOR_CNT_ERR_ENf,
    318         CTR_COLOR_CNT_ERRf,
    319         MMU_CTR_COLOR_DROP_MEMm, NULL,
    320         INVALIDr, INVALIDf,
    321         INVALIDr, NULL,
    322         INVALIDr, NULL },
    323     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    324         TOQ0_UCQ_RP_PAR_ERR_ENf,
    325         TOQ0_UCQ_RP_PAR_ERRf,
    326         INVALIDm, "MMU UCQ RP",
    327         INVALIDr, INVALIDf,
    328         INVALIDr, NULL,
    329         INVALIDr, NULL },
    330     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    331         TOQ0_UCQ_WP_PAR_ERR_ENf,
    332         TOQ0_UCQ_WP_PAR_ERRf,
    333         INVALIDm, "MMU UCQ WP",
    334         INVALIDr, INVALIDf,
    335         INVALIDr, NULL,
    336         INVALIDr, NULL },
    337     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    338         TOQ0_PKTLINK_PAR_ERR_ENf,
    339         TOQ0_PKTLINK_PAR_ERRf,
    340         INVALIDm, "MMU PKTLINK",
    341         INVALIDr, INVALIDf,
    342         INVALIDr, NULL,
    343         INVALIDr, NULL },
    344     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    345         TOQ0_CELLLINK_PAR_ERR_ENf,
    346         TOQ0_CELLLINK_PAR_ERRf,
    347         INVALIDm, "MMU CELLLINK",
    348         INVALIDr, INVALIDf,
    349         INVALIDr, NULL,
    350         INVALIDr, NULL },
    351     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    352         TOQ0_CPQLINK_PAR_ERR_ENf,
    353         TOQ0_CPQLINK_PAR_ERRf,
    354         INVALIDm, "MMU CPQLINK",
    355         INVALIDr, INVALIDf,
    356         INVALIDr, NULL,
    357         INVALIDr, NULL },
    358     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    359         TOQ0_IPMC_MC_FIFO_PAR_ERR_ENf,
    360         TOQ0_IPMC_MC_FIFO_PAR_ERRf,
    361         INVALIDm, "MMU IPMC MC FIFO",
    362         INVALIDr, INVALIDf,
    363         INVALIDr, NULL,
    364         INVALIDr, NULL },
    365     { _SOC_PARITY_TYPE_MMU_IPMC, NULL, 0,
    366         TOQ0_IPMC_TBL_PAR_ERR_ENf,
    367         TOQ0_IPMC_TBL_PAR_ERRf,
    368         INVALIDm, "MMU IPMC TBLI",
    369         INVALIDr, INVALIDf,
    370         INVALIDr, NULL,
    371         INVALIDr, NULL },
    372     { _SOC_PARITY_TYPE_MMU_VLAN, NULL, 0,
    373         TOQ0_VLAN_TBL_PAR_ERR_ENf,
    374         TOQ0_VLAN_TBL_PAR_ERRf,
    375         INVALIDm, "MMU VLAN TBL",
    376         INVALIDr, INVALIDf,
    377         INVALIDr, NULL,
    378         INVALIDr, NULL },
    379     { _SOC_PARITY_TYPE_MMU_MTRO, NULL, 0,
    380         MTRO_PAR_ERR_ENf,
    381         MTRO_PAR_ERRf,
    382         INVALIDm, "MMU MTRO PAR",
    383         INVALIDr, INVALIDf,
    384         INVALIDr, NULL,
    385         INVALIDr, NULL },
    386     { _SOC_PARITY_TYPE_MMU_WRED, NULL, 0,
    387         WRED_PAR_ERR_ENf,
    388         WRED_PAR_ERRf,
    389         INVALIDm, "MMU WRED",
    390         INVALIDr, INVALIDf,
    391         INVALIDr, NULL,
    392         INVALIDr, NULL },
    393     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    394         OVQ_PAR_ERR_ENf,
    395         OVQ_PAR_ERRf,
    396         INVALIDm, "MMU OVQ",
    397         INVALIDr, INVALIDf,
    398         INVALIDr, NULL,
    399         INVALIDr, NULL },
    400     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    401         PQE_PAR_ERR_ENf,
    402         PQE_PAR_ERRf,
    403         INVALIDm, "MMU PQE PAR",
    404         INVALIDr, INVALIDf,
    405         INVALIDr, NULL,
    406         INVALIDr, NULL },
    407     { _SOC_PARITY_TYPE_GENERIC, NULL, 0,
    408         QCN_PAR_ERR_ENf,
    409         QCN_PAR_ERRf,
    410         INVALIDm, "MMU QCN PAR",
    411         INVALIDr, INVALIDf,
    412         INVALIDr, NULL,
    413         INVALIDr, NULL },
    414     { _SOC_PARITY_TYPE_MMU_THDO, NULL, 0,
    415         THDO_PAR_ERR_ENf,
    416         THDO_PAR_ERRf,
    417         INVALIDm, "MMU THDO",
    418         INVALIDr, INVALIDf,
    419         INVALIDr, NULL,
    420         INVALIDr, NULL },
    421     { _SOC_PARITY_TYPE_MMU_THDI, NULL, 0,
    422         THDI_PAR_ERR_ENf,
    423         THDI_PAR_ERRf,
    424         INVALIDm, "MMU THDI",
    425         INVALIDr, INVALIDf,
    426         INVALIDr, NULL,
    427         INVALIDr, NULL },
    428     { _SOC_PARITY_TYPE_MMU_ES, NULL, 0,
    429         ES_PAR_ERR_ENf,
    430         ES_PAR_ERRf,
    431         INVALIDm, "MMU ES",
    432         INVALIDr, INVALIDf,
    433         INVALIDr, NULL,
    434         INVALIDr, NULL },
    435     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    436 };
    437 
    438 STATIC _soc_trident_parity_info_t _soc_trident_ep0_parity_info[] = {
    439     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    440         EGR_NHOP_PAR_ERRf,
    441         EGR_NHOP_PAR_ERRf,
    442         EGR_L3_NEXT_HOPm, NULL,
    443         EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_NEXT_HOP_PARITY_ENf,
    444         EGR_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL,
    445         EGR_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL },
    446     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    447         EGR_L3_INTF_PAR_ERRf,
    448         EGR_L3_INTF_PAR_ERRf,
    449         EGR_L3_INTFm, NULL,
    450         EGR_EL3_ECC_PARITY_CONTROLr, EGR_L3_INTF_PARITY_ENf,
    451         EGR_L3_INTF_PARITY_STATUS_INTRr, NULL,
    452         EGR_L3_INTF_PARITY_STATUS_NACKr, NULL },
    453     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    454         EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PAR_ERRf,
    455         EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PAR_ERRf,
    456         EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, NULL,
    457         EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_ENf,
    458         EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_STATUS_INTRr, NULL,
    459         EGR_MPLS_VC_AND_SWAP_LABEL_TABLE_PARITY_STATUS_NACKr, NULL },
    460     /* The parity enable scheme does not work for EGR_VLAN table */
    461     /*{ _SOC_PARITY_TYPE_PARITY, NULL, 0,
    462         EGR_VLAN_PAR_ERRf,
    463         EGR_VLAN_PAR_ERRf,
    464         EGR_VLANm, NULL,
    465         EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_PARITY_ENf,
    466         EGR_VLAN_PARITY_STATUS_INTRr, NULL,
    467         EGR_VLAN_PARITY_STATUS_NACKr, NULL },*/
    468     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    469         EGR_VLAN_STG_PAR_ERRf,
    470         EGR_VLAN_STG_PAR_ERRf,
    471         EGR_VLAN_STGm, NULL,
    472         EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_STG_PARITY_ENf,
    473         EGR_VLAN_STG_PARITY_STATUS_INTRr, NULL,
    474         EGR_VLAN_STG_PARITY_STATUS_NACKr, NULL },
    475     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    476         EGR_IP_TUNNEL_PAR_ERRf,
    477         EGR_IP_TUNNEL_PAR_ERRf,
    478         EGR_IP_TUNNELm, NULL,
    479         EGR_VLAN_PARITY_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
    480         EGR_IP_TUNNEL_PARITY_STATUS_INTRr, NULL,
    481         EGR_IP_TUNNEL_PARITY_STATUS_NACKr, NULL },
    482     { _SOC_PARITY_TYPE_HASH, NULL, 0,
    483         EGR_VLAN_XLATE_PAR_ERRf,
    484         EGR_VLAN_XLATE_PAR_ERRf,
    485         EGR_VLAN_XLATEm, NULL,
    486         EGR_VLAN_PARITY_CONTROLr, EGR_VLAN_XLATE_PARITY_ENf,
    487         INVALIDr, _soc_trident_egr_vlan_xlate_intr_reg,
    488         INVALIDr, _soc_trident_egr_vlan_xlate_nack_reg },
    489     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    490         EGR_FRAGMENT_ID_TABLE_PAR_ERRf,
    491         EGR_FRAGMENT_ID_TABLE_PAR_ERRf,
    492         EGR_FRAGMENT_ID_TABLEm, NULL,
    493         EGR_VLAN_PARITY_CONTROLr, EGR_FRAGMENT_ID_TABLE_PARITY_ENf,
    494         EGR_FRAGMENT_ID_TABLE_PARITY_STATUS_INTRr, NULL,
    495         EGR_FRAGMENT_ID_TABLE_PARITY_STATUS_NACKr, NULL },
    496     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    497         EGR_INITBUF_ECC_ERRf,
    498         EGR_INITBUF_ECC_ERRf,
    499         INVALIDm, "EGR_INITBUF",
    500         EGR_EHCPM_ECC_PARITY_CONTROLr, INITBUF_ECC_ENf,
    501         EGR_INITBUF_ECC_STATUS_INTRr, NULL,
    502         INVALIDr, NULL },
    503     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    504         EGR_PORT_PAR_ERRf,
    505         EGR_PORT_PAR_ERRf,
    506         EGR_PORTm, NULL,
    507         EGR_EL3_ECC_PARITY_CONTROLr, EGR_PORT_PARITY_ENf,
    508         EGR_PORT_PARITY_STATUS_INTRr, NULL,
    509         EGR_PORT_PARITY_STATUS_NACKr, NULL },
    510     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    511         EGR_GPP_ATTRIBUTES_PAR_ERRf,
    512         EGR_GPP_ATTRIBUTES_PAR_ERRf,
    513         EGR_GPP_ATTRIBUTESm, NULL,
    514         EGR_VLAN_PARITY_CONTROLr, EGR_GPP_ATTRIBUTES_PARITY_ENf,
    515         EGR_GPP_ATTRIBUTES_PARITY_STATUS_INTRr, NULL,
    516         EGR_GPP_ATTRIBUTES_PARITY_STATUS_NACKr, NULL },
    517     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    518         EGR_MOD_MAP_TABLE_PAR_ERRf,
    519         EGR_MOD_MAP_TABLE_PAR_ERRf,
    520         EGR_MOD_MAP_TABLEm, NULL,
    521         EGR_EHCPM_ECC_PARITY_CONTROLr, MOD_MAP_PARITY_ENf,
    522         EGR_MOD_MAP_PARITY_STATUS_INTRr, NULL,
    523         EGR_MOD_MAP_PARITY_STATUS_NACKr, NULL },
    524     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    525         EGR_MAC_DA_PROFILE_PAR_ERRf,
    526         EGR_MAC_DA_PROFILE_PAR_ERRf,
    527         EGR_MAC_DA_PROFILEm, NULL,
    528         EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAC_DA_PROFILE_PARITY_ENf,
    529         EGR_MAC_DA_PROFILE_PARITY_STATUS_INTRr, NULL,
    530         EGR_MAC_DA_PROFILE_PARITY_STATUS_NACKr, NULL },
    531     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    532         EGR_DVP_ATTRIBUTE_PAR_ERRf,
    533         EGR_DVP_ATTRIBUTE_PAR_ERRf,
    534         EGR_DVP_ATTRIBUTEm, NULL,
    535         EGR_EL3_ECC_PARITY_CONTROLr, EGR_DVP_ATTRIBUTE_PARITY_ENf,
    536         EGR_DVP_ATTRIBUTE_PARITY_STATUS_INTRr, NULL,
    537         EGR_DVP_ATTRIBUTE_PARITY_STATUS_NACKr, NULL },
    538     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    539         EGR_VFI_PAR_ERRf,
    540         EGR_VFI_PAR_ERRf,
    541         EGR_VFIm, NULL,
    542         EGR_EL3_ECC_PARITY_CONTROLr, EGR_VFI_PARITY_ENf,
    543         EGR_VFI_PARITY_STATUS_INTRr, NULL,
    544         EGR_VFI_PARITY_STATUS_NACKr, NULL },
    545     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    546         EGR_IPMC_PAR_ERRf,
    547         EGR_IPMC_PAR_ERRf,
    548         EGR_IPMCm, NULL,
    549         EGR_EL3_ECC_PARITY_CONTROLr, EGR_IPMC_PARITY_ENf,
    550         EGR_IPMC_PARITY_STATUS_INTRr, NULL,
    551         EGR_IPMC_PARITY_STATUS_NACKr, NULL },
    552     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    553         EGR_MPLS_EXP_MAPPING_2_PAR_ERRf,
    554         EGR_MPLS_EXP_MAPPING_2_PAR_ERRf,
    555         EGR_MPLS_EXP_MAPPING_2m, NULL,
    556         EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_EXP_MAPPING_2_PARITY_ENf,
    557         EGR_MPLS_EXP_MAPPING_2_PARITY_STATUS_INTRr, NULL,
    558         EGR_MPLS_EXP_MAPPING_2_PARITY_STATUS_NACKr, NULL },
    559     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    560         EGR_MPLS_PRI_MAPPING_PAR_ERRf,
    561         EGR_MPLS_PRI_MAPPING_PAR_ERRf,
    562         EGR_MPLS_PRI_MAPPINGm, NULL,
    563         EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_PRI_MAPPING_PARITY_ENf,
    564         EGR_MPLS_PRI_MAPPING_PARITY_STATUS_INTRr, NULL,
    565         EGR_MPLS_PRI_MAPPING_PARITY_STATUS_NACKr, NULL },
    566     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    567         EGR_PRI_CNG_MAP_PAR_ERRf,
    568         EGR_PRI_CNG_MAP_PAR_ERRf,
    569         EGR_PRI_CNG_MAPm, NULL,
    570         EGR_VLAN_PARITY_CONTROLr, EGR_PRI_CNG_MAP_PARITY_ENf,
    571         EGR_PRI_CNG_MAP_PARITY_STATUS_INTRr, NULL,
    572         EGR_PRI_CNG_MAP_PARITY_STATUS_NACKr, NULL },
    573     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    574         EGR_DSCP_TABLE_PAR_ERRf,
    575         EGR_DSCP_TABLE_PAR_ERRf,
    576         EGR_DSCP_TABLEm, NULL,
    577         EGR_VLAN_PARITY_CONTROLr, EGR_DSCP_TABLE_PARITY_ENf,
    578         EGR_DSCP_TABLE_PARITY_STATUS_INTRr, NULL,
    579         EGR_DSCP_TABLE_PARITY_STATUS_NACKr, NULL },
    580     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    581         EGR_MPB_ECC_ERRf,
    582         EGR_MPB_ECC_ERRf,
    583         INVALIDm, "EGR_MPB",
    584         EGR_EL3_ECC_PARITY_CONTROLr, EGR_MPB_ECC_ENf,
    585         EGR_MPB_ECC_STATUS_INTRr, NULL,
    586         INVALIDr, NULL },
    587     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    588         EGR_MAP_MH_PAR_ERRf,
    589         EGR_MAP_MH_PAR_ERRf,
    590         EGR_MAP_MHm, NULL,
    591         EGR_EL3_ECC_PARITY_CONTROLr, EGR_MAP_MH_PARITY_ENf,
    592         EGR_MAP_MH_PARITY_STATUS_INTRr, NULL,
    593         EGR_MAP_MH_PARITY_STATUS_NACKr, NULL },
    594     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    595         EGR_VLAN_CONTROL_1_PAR_ERRf,
    596         EGR_VLAN_CONTROL_1_PAR_ERRf,
    597         INVALIDm, "EGR_VLAN_CONTROL_1",
    598         EGR_EL3_ECC_PARITY_CONTROLr, EGR_VLAN_CONTROL_1_PARITY_ENf,
    599         EGR_VLAN_CONTROL_1_PARITY_STATUS_INTRr, NULL,
    600         EGR_VLAN_CONTROL_1_PARITY_STATUS_NACKr, NULL },
    601     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    602         EGR_IPMC_CFG2_PAR_ERRf,
    603         EGR_IPMC_CFG2_PAR_ERRf,
    604         INVALIDm, "EGR_IPMC_CFG2",
    605         EGR_EL3_ECC_PARITY_CONTROLr, EGR_IPMC_CFG2_PARITY_ENf,
    606         EGR_IPMC_CFG2_PARITY_STATUS_INTRr, NULL,
    607         EGR_IPMC_CFG2_PARITY_STATUS_NACKr, NULL },
    608     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    609         EGR_GPP_ATTRIBUTES_MODBASE_PAR_ERRf,
    610         EGR_GPP_ATTRIBUTES_MODBASE_PAR_ERRf,
    611         EGR_GPP_ATTRIBUTES_MODBASEm, NULL,
    612         EGR_VLAN_PARITY_CONTROLr, EGR_GPP_ATTRIBUTES_MODBASE_PARITY_ENf,
    613         EGR_GPP_ATTRIBUTES_MODBASE_PARITY_STATUS_INTRr, NULL,
    614         EGR_GPP_ATTRIBUTES_MODBASE_PARITY_STATUS_NACKr, NULL },
    615     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    616         EGR_MPLS_EXP_MAPPING_1_PAR_ERRf,
    617         EGR_MPLS_EXP_MAPPING_1_PAR_ERRf,
    618         EGR_MPLS_EXP_MAPPING_1m, NULL,
    619         EGR_VLAN_PARITY_CONTROLr, EGR_MPLS_EXP_MAPPING_1_PARITY_ENf,
    620         EGR_MPLS_EXP_MAPPING_1_PARITY_STATUS_INTRr, NULL,
    621         EGR_MPLS_EXP_MAPPING_1_PARITY_STATUS_NACKr, NULL },
    622     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    623 };
    624 
    625 STATIC _soc_trident_parity_info_t _soc_trident_ep1_parity_info[] = {
    626     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    627         CM_PAR_ERRf,
    628         CM_PAR_ERRf,
    629         INVALIDm, "EP_EDATABUF_CM_MEM",
    630         EGR_EDATABUF_PARITY_CONTROLr, CM_ECC_ENf,
    631         EGR_CM_BUFFER_STATUS_INTRr, NULL,
    632         INVALIDr, NULL },
    633     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    634         XLP0_PAR_ERRf,
    635         XLP0_PAR_ERRf,
    636         INVALIDm, "EP_EDATABUF_XLP0_MEM",
    637         EGR_EDATABUF_PARITY_CONTROLr, XLP0_ECC_ENf,
    638         EGR_XLP0_BUFFER_STATUS_INTRr, NULL,
    639         INVALIDr, NULL },
    640     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    641         XLP1_PAR_ERRf,
    642         XLP1_PAR_ERRf,
    643         INVALIDm, "EP_EDATABUF_XLP1_MEM",
    644         EGR_EDATABUF_PARITY_CONTROLr, XLP1_ECC_ENf,
    645         EGR_XLP1_BUFFER_STATUS_INTRr, NULL,
    646         INVALIDr, NULL },
    647     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    648         XLP2_PAR_ERRf,
    649         XLP2_PAR_ERRf,
    650         INVALIDm, "EP_EDATABUF_XLP2_MEM",
    651         EGR_EDATABUF_PARITY_CONTROLr, XLP2_ECC_ENf,
    652         EGR_XLP2_BUFFER_STATUS_INTRr, NULL,
    653         INVALIDr, NULL },
    654     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    655         XLP3_PAR_ERRf,
    656         XLP3_PAR_ERRf,
    657         INVALIDm, "EP_EDATABUF_XLP3_MEM",
    658         EGR_EDATABUF_PARITY_CONTROLr, XLP3_ECC_ENf,
    659         EGR_XLP3_BUFFER_STATUS_INTRr, NULL,
    660         INVALIDr, NULL },
    661     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    662         XLP4_PAR_ERRf,
    663         XLP4_PAR_ERRf,
    664         INVALIDm, "EP_EDATABUF_XLP4_MEM",
    665         EGR_EDATABUF_PARITY_CONTROLr, XLP4_ECC_ENf,
    666         EGR_XLP4_BUFFER_STATUS_INTRr, NULL,
    667         INVALIDr, NULL },
    668     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    669         XLP5_PAR_ERRf,
    670         XLP5_PAR_ERRf,
    671         INVALIDm, "EP_EDATABUF_XLP5_MEM",
    672         EGR_EDATABUF_PARITY_CONTROLr, XLP5_ECC_ENf,
    673         EGR_XLP5_BUFFER_STATUS_INTRr, NULL,
    674         INVALIDr, NULL },
    675     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    676         XLP6_PAR_ERRf,
    677         XLP6_PAR_ERRf,
    678         INVALIDm, "EP_EDATABUF_XLP6_MEM",
    679         EGR_EDATABUF_PARITY_CONTROLr, XLP6_ECC_ENf,
    680         EGR_XLP6_BUFFER_STATUS_INTRr, NULL,
    681         INVALIDr, NULL },
    682     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    683         XLP7_PAR_ERRf,
    684         XLP7_PAR_ERRf,
    685         INVALIDm, "EP_EDATABUF_XLP7_MEM",
    686         EGR_EDATABUF_PARITY_CONTROLr, XLP7_ECC_ENf,
    687         EGR_XLP7_BUFFER_STATUS_INTRr, NULL,
    688         INVALIDr, NULL },
    689     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    690         XLP8_PAR_ERRf,
    691         XLP8_PAR_ERRf,
    692         INVALIDm, "EP_EDATABUF_XLP8_MEM",
    693         EGR_EDATABUF_PARITY_CONTROLr, XLP8_ECC_ENf,
    694         EGR_XLP8_BUFFER_STATUS_INTRr, NULL,
    695         INVALIDr, NULL },
    696     { _SOC_PARITY_TYPE_EDATABUF, NULL, 0,
    697         LBP_PAR_ERRf,
    698         LBP_PAR_ERRf,
    699         INVALIDm, "EP_EDATABUF_LBP_MEM",
    700         EGR_EDATABUF_PARITY_CONTROLr, LBP_ECC_ENf,
    701         EGR_LBP_BUFFER_STATUS_INTRr, NULL,
    702         INVALIDr, NULL },
    703     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
    704         EGR_STATS_COUNTER_TABLE_PAR_ERRf,
    705         EGR_STATS_COUNTER_TABLE_PAR_ERRf,
    706         INVALIDm, "TX Debug Counter",
    707         EGR_EDATABUF_PARITY_CONTROLr, STATS_PAR_ENf,
    708         EGR_STATS_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
    709         EGR_STATS_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
    710     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    711         EGR_EFP_COUNTER_TABLE_PAR_ERRf,
    712         EGR_EFP_COUNTER_TABLE_PAR_ERRf,
    713         EFP_COUNTER_TABLEm, NULL,
    714         EGR_EDATABUF_PARITY_CONTROLr, EFPCTR_PAR_ENf,
    715         EGR_EFP_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
    716         EGR_EFP_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
    717     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    718         EGR_PERQ_XMT_COUNTERS_PAR_ERRf,
    719         EGR_PERQ_XMT_COUNTERS_PAR_ERRf,
    720         EGR_PERQ_XMT_COUNTERSm, NULL,
    721         EGR_EDATABUF_PARITY_CONTROLr, PERQ_PAR_ENf,
    722         EGR_PERQ_XMT_COUNTERS_PARITY_STATUS_INTRr, NULL,
    723         EGR_PERQ_XMT_COUNTERS_PARITY_STATUS_NACKr, NULL },
    724     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    725         EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PAR_ERRf,
    726         EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PAR_ERRf,
    727         EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, NULL,
    728         EGR_EDATABUF_PARITY_CONTROLr, PERQ_BASE_ADDR_PAR_ENf,
    729         EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PARITY_STATUS_INTRr, NULL,
    730         EGR_PERQ_XMT_COUNTERS_BASE_ADDR_PARITY_STATUS_NACKr, NULL },
    731     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    732         EGR_VINTF_COUNTER_TABLE_PAR_ERRf,
    733         EGR_VINTF_COUNTER_TABLE_PAR_ERRf,
    734         EGR_VINTF_COUNTER_TABLEm, NULL,
    735         EGR_EDATABUF_PARITY_CONTROLr, VINTFCTR_PAR_ENf,
    736         EGR_VINTF_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
    737         EGR_VINTF_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
    738     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    739         EGR_SERVICE_COUNTER_TABLE_PAR_ERRf,
    740         EGR_SERVICE_COUNTER_TABLE_PAR_ERRf,
    741         EGR_SERVICE_COUNTER_TABLEm, NULL,
    742         EGR_EDATABUF_PARITY_CONTROLr, SVCCTR_PAR_ENf,
    743         EGR_SERVICE_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
    744         EGR_SERVICE_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
    745     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    746         EGR_EFP_METER_TABLE_PAR_ERRf,
    747         EGR_EFP_METER_TABLE_PAR_ERRf,
    748         EFP_METER_TABLEm, NULL,
    749         EFP_METER_PARITY_CONTROLr, PARITY_ENf,
    750         EFP_METER_PARITY_STATUS_INTRr, NULL,
    751         EFP_METER_PARITY_STATUS_NACKr, NULL },
    752     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    753         EGR_EFP_POLICY_TABLE_PAR_ERRf,
    754         EGR_EFP_POLICY_TABLE_PAR_ERRf,
    755         EFP_POLICY_TABLEm, NULL,
    756         EFP_POLICY_PARITY_CONTROLr, PARITY_ENf,
    757         EFP_POLICY_PARITY_STATUS_INTRr, NULL,
    758         EFP_POLICY_PARITY_STATUS_NACKr, NULL },
    759     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    760         EGR_EFP_PW_INIT_COUNTERS_PAR_ERRf,
    761         EGR_EFP_PW_INIT_COUNTERS_PAR_ERRf,
    762         EGR_PW_INIT_COUNTERSm, NULL,
    763         EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, PARITY_ENf,
    764         EGR_PW_INIT_COUNTERS_PARITY_STATUS_INTRr, NULL,
    765         EGR_PW_INIT_COUNTERS_PARITY_STATUS_NACKr, NULL },
    766     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    767 };
    768 
    769 STATIC _soc_trident_parity_info_t _soc_trident_ip0_parity_info[] = {
    770     /* IP0_INTR_STATUS.PPA_CMD_COMPLETE */
    771     /* IP0_INTR_STATUS.MEM_RESET_COMPLETE */
    772     /* IP0_INTR_STATUS.AGE_CMD_COMPLETE */
    773     /* LMEP is a broadcom propietary memory, and removed from the regs file
    774        before release.
    775     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    776         LMEP_PAR_ERRf,
    777         LMEP_PAR_ERRf,
    778         LMEPm, NULL,
    779         LMEP_PARITY_CONTROLr, PARITY_ENf,
    780         LMEP_PARITY_STATUS_INTRr, NULL,
    781         LMEP_PARITY_STATUS_NACKr, NULL },*/
    782     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    783         IARB_PKT_ERRf,
    784         IARB_PKT_ERRf,
    785         INVALIDm, "IARB_PKT_BUF",
    786         IARB_PKT_ECC_CONTROLr, ECC_ENf,
    787         IARB_PKT_ECC_STATUS_INTRr, NULL,
    788         INVALIDr, NULL },
    789     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    790         IARB_HDR_ERRf,
    791         IARB_HDR_ERRf,
    792         INVALIDm, "IARB_PKT_HDR",
    793         IARB_HDR_ECC_CONTROLr, ECC_ENf,
    794         IARB_HDR_ECC_STATUS_INTRr, NULL,
    795         INVALIDr, NULL },
    796     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    797         IARB_PIPE_X_LERAN_FIFO_ECC_ERRf,
    798         IARB_PIPE_X_LERAN_FIFO_ECC_ERRf,
    799         INVALIDm, "IARB_LERAN_FIFO_PIPE_X",
    800         IARB_LEARN_FIFO_ECC_CONTROLr, ECC_ENf,
    801         IARB_PIPE_X_LERAN_FIFO_ECC_STATUS_INTRr, NULL,
    802         INVALIDr, NULL },
    803     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    804         IARB_PIPE_Y_LERAN_FIFO_ECC_ERRf,
    805         IARB_PIPE_Y_LERAN_FIFO_ECC_ERRf,
    806         INVALIDm, "IARB_LERAN_FIFO_PIPE_Y",
    807         IARB_LEARN_FIFO_ECC_CONTROLr, ECC_ENf,
    808         IARB_PIPE_Y_LERAN_FIFO_ECC_STATUS_INTRr, NULL,
    809         INVALIDr, NULL },
    810     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    811 };
    812 
    813 STATIC _soc_trident_parity_info_t _soc_trident_ip1_parity_info[] = {
    814     { _SOC_PARITY_TYPE_HASH, NULL, 0,
    815         VXLT_PAR_ERRf,
    816         VXLT_PAR_ERRf,
    817         VLAN_XLATEm, NULL,
    818         VLAN_XLATE_PARITY_CONTROLr, PARITY_ENf,
    819         INVALIDr, _soc_trident_vlan_xlate_intr_reg,
    820         INVALIDr, _soc_trident_vlan_xlate_nack_reg },
    821     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    822         VFP_POLICY_PAR_ERRf,
    823         VFP_POLICY_PAR_ERRf,
    824         VFP_POLICY_TABLEm, NULL,
    825         VFP_POLICY_PARITY_CONTROLr, PARITY_ENf,
    826         VFP_POLICY_PARITY_STATUS_INTRr, NULL,
    827         VFP_POLICY_PARITY_STATUS_NACKr, NULL },
    828     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    829         VLAN_PROT_PAR_ERRf,
    830         VLAN_PROT_PAR_ERRf,
    831         VLAN_PROTOCOL_DATAm, NULL,
    832         VLAN_PROT_PARITY_CONTROLr, PARITY_ENf,
    833         VLAN_PROT_PARITY_STATUS_INTRr, NULL,
    834         VLAN_PROT_PARITY_STATUS_NACKr, NULL },
    835     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    836         VLAN_SUBNET_PAR_ERRf,
    837         VLAN_SUBNET_PAR_ERRf,
    838         VLAN_SUBNET_DATA_ONLYm, NULL,
    839         VLAN_SUBNET_PARITY_CONTROLr, PARITY_ENf,
    840         VLAN_SUBNET_PARITY_STATUS_INTRr, NULL,
    841         VLAN_SUBNET_PARITY_STATUS_NACKr, NULL },
    842     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    843         CPU_TS_POLICY_PAR_ERRf,
    844         CPU_TS_POLICY_PAR_ERRf,
    845         CPU_TS_MAPm, NULL,
    846         CPU_TS_PARITY_CONTROLr, PARITY_ENf,
    847         CPU_TS_PARITY_STATUS_INTRr, NULL,
    848         CPU_TS_PARITY_STATUS_NACKr, NULL },
    849     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    850         VLAN_RANGE_PAR_ERRf,
    851         VLAN_RANGE_PAR_ERRf,
    852         ING_VLAN_RANGEm, NULL,
    853         VLAN_RANGE_PARITY_CONTROLr, PARITY_ENf,
    854         VLAN_RANGE_PARITY_STATUS_INTRr, NULL,
    855         VLAN_RANGE_PARITY_STATUS_NACKr, NULL },
    856     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    857         MOD_MAP_PAR_ERRf,
    858         MOD_MAP_PAR_ERRf,
    859         ING_MOD_MAP_TABLEm, NULL,
    860         MOD_MAP_PARITY_CONTROLr, PARITY_ENf,
    861         MOD_MAP_PARITY_STATUS_INTRr, NULL,
    862         MOD_MAP_PARITY_STATUS_NACKr, NULL },
    863     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    864         FP_UDF_PAR_ERRf,
    865         FP_UDF_PAR_ERRf,
    866         FP_UDF_OFFSETm, NULL,
    867         FP_UDF_PARITY_CONTROLr, PARITY_ENf,
    868         FP_UDF_PARITY_STATUS_INTRr, NULL,
    869         FP_UDF_PARITY_STATUS_NACKr, NULL },
    870     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    871         L3_TUNNEL_PAR_ERRf,
    872         L3_TUNNEL_PAR_ERRf,
    873         L3_TUNNELm, NULL,
    874         L3_TUNNEL_PARITY_CONTROLr, PARITY_ENf,
    875         L3_TUNNEL_PARITY_STATUS_INTRr, NULL,
    876         L3_TUNNEL_PARITY_STATUS_NACKr, NULL },
    877     /* IP1_INTR_STATUS.WLAN_SVP_PAR_ERR */
    878     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    879         SRC_TRUNK_PAR_ERRf,
    880         SRC_TRUNK_PAR_ERRf,
    881         SOURCE_TRUNK_MAP_TABLEm, NULL,
    882         SRC_TRUNK_ECC_CONTROLr, ECC_ENf,
    883         SRC_TRUNK_ECC_STATUS_INTRr, NULL,
    884         SRC_TRUNK_ECC_STATUS_NACKr, NULL },
    885     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    886         LPORT_PAR_ERRf,
    887         LPORT_PAR_ERRf,
    888         LPORT_TABm, NULL,
    889         LPORT_ECC_CONTROLr, ECC_ENf,
    890         LPORT_ECC_STATUS_INTRr, NULL,
    891         LPORT_ECC_STATUS_NACKr, NULL },
    892     { _SOC_PARITY_TYPE_HASH, NULL, 0,
    893         MPLS_ENTRY_PAR_ERRf,
    894         MPLS_ENTRY_PAR_ERRf,
    895         MPLS_ENTRYm, NULL,
    896         MPLS_ENTRY_PARITY_CONTROLr, PARITY_ENf,
    897         INVALIDr, _soc_trident_mpls_entry_intr_reg,
    898         INVALIDr, _soc_trident_mpls_entry_nack_reg },
    899     { _SOC_PARITY_TYPE_ECC, NULL, 0,
    900         PORT_TABLE_PAR_ERRf,
    901         PORT_TABLE_PAR_ERRf,
    902         PORT_TABm, NULL,
    903         PORT_TABLE_ECC_CONTROLr, ECC_ENf,
    904         PORT_TABLE_ECC_STATUS_INTRr, NULL,
    905         PORT_TABLE_ECC_STATUS_NACKr, NULL },
    906     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    907         SYS_CONFIG_PAR_ERRf,
    908         SYS_CONFIG_PAR_ERRf,
    909         SYSTEM_CONFIG_TABLEm, NULL,
    910         SYSTEM_CONFIG_PARITY_CONTROLr, PARITY_ENf,
    911         SYSTEM_CONFIG_PARITY_STATUS_INTRr, NULL,
    912         SYSTEM_CONFIG_PARITY_STATUS_NACKr, NULL },
    913     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    914         SYSTEM_CONFIG_MODVIEW_PAR_ERRf,
    915         SYSTEM_CONFIG_MODVIEW_PAR_ERRf,
    916         SYSTEM_CONFIG_TABLE_MODBASEm, NULL,
    917         SYSTEM_CONFIG_MODVIEW_PARITY_CONTROLr, PARITY_ENf,
    918         SYSTEM_CONFIG_MODVIEW_PARITY_STATUS_INTRr, NULL,
    919         SYSTEM_CONFIG_MODVIEW_PARITY_STATUS_NACKr, NULL },
    920     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    921         SOURCE_TRUNK_MAP_MODVIEW_PAR_ERRf,
    922         SOURCE_TRUNK_MAP_MODVIEW_PAR_ERRf,
    923         SOURCE_TRUNK_MAP_MODBASEm, NULL,
    924         SOURCE_TRUNK_MAP_MODVIEW_PARITY_CONTROLr, PARITY_ENf,
    925         SOURCE_TRUNK_MAP_MODVIEW_PARITY_STATUS_INTRr, NULL,
    926         SOURCE_TRUNK_MAP_MODVIEW_PARITY_STATUS_NACKr, NULL },
    927     { _SOC_PARITY_TYPE_NONE } /* table terminator */
    928 };
    929 
    930 STATIC _soc_trident_parity_info_t _soc_trident_ip2_parity_info[] = {
    931     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    932         NHOP_PAR_ERRf,
    933         NHOP_PAR_ERRf,
    934         INITIAL_ING_L3_NEXT_HOPm, NULL,
    935         INITIAL_ING_L3_NEXT_HOP_PARITY_CONTROLr, PARITY_ENf,
    936         INITIAL_ING_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL,
    937         INITIAL_ING_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL },
    938     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    939         ECMP_GRP_PAR_ERRf,
    940         ECMP_GRP_PAR_ERRf,
    941         INITIAL_L3_ECMP_GROUPm, NULL,
    942         INITIAL_L3_ECMP_GROUP_PARITY_CONTROLr, PARITY_ENf,
    943         INITIAL_L3_ECMP_GROUP_PARITY_STATUS_INTRr, NULL,
    944         INITIAL_L3_ECMP_GROUP_PARITY_STATUS_NACKr, NULL },
    945     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    946         L3_ECMP_PAR_ERRf,
    947         L3_ECMP_PAR_ERRf,
    948         INITIAL_L3_ECMPm, NULL,
    949         INITIAL_L3_ECMP_PARITY_CONTROLr, PARITY_ENf,
    950         INITIAL_L3_ECMP_PARITY_STATUS_INTRr, NULL,
    951         INITIAL_L3_ECMP_PARITY_STATUS_NACKr, NULL },
    952     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    953         ING_DVP_PAR_ERRf,
    954         ING_DVP_PAR_ERRf,
    955         ING_DVP_TABLEm, NULL,
    956         ING_DVP_TABLE_PARITY_CONTROLr, PARITY_ENf,
    957         ING_DVP_TABLE_PARITY_STATUS_INTRr, NULL,
    958         ING_DVP_TABLE_PARITY_STATUS_NACKr, NULL },
    959     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    960         PROT_NHI_PAR_ERRf,
    961         PROT_NHI_PAR_ERRf,
    962         INITIAL_PROT_NHI_TABLEm, NULL,
    963         INITIAL_PROT_NHI_TABLE_PARITY_CONTROLr, PARITY_ENf,
    964         INITIAL_PROT_NHI_TABLE_PARITY_STATUS_INTRr, NULL,
    965         INITIAL_PROT_NHI_TABLE_PARITY_STATUS_NACKr, NULL },
    966 /*  { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    967         PORT_CBL_PAR_ERRf,
    968         PORT_CBL_PAR_ERRf,
    969         PORT_CBL_TABLEm, NULL,
    970         PORT_CBL_TABLE_PARITY_CONTROLr, PARITY_ENf,
    971         PORT_CBL_TABLE_PARITY_STATUS_INTRr, NULL,
    972         PORT_CBL_TABLE_PARITY_STATUS_NACKr, NULL }, */
    973     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    974         PORT_CBL_MODBASE_PAR_ERRf,
    975         PORT_CBL_MODBASE_PAR_ERRf,
    976         PORT_CBL_TABLE_MODBASEm, NULL,
    977         PORT_CBL_TABLE_MODBASE_PARITY_CONTROLr, PARITY_ENf,
    978         PORT_CBL_TABLE_MODBASE_PARITY_STATUS_INTRr, NULL,
    979         PORT_CBL_TABLE_MODBASE_PARITY_STATUS_NACKr, NULL },
    980     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    981         L3_IPMC_1_PAR_ERRf,
    982         L3_IPMC_1_PAR_ERRf,
    983         L3_IPMC_1m, NULL,
    984         L3_IPMC_1_PARITY_CONTROLr, PARITY_ENf,
    985         L3_IPMC_1_PARITY_STATUS_INTRr, NULL,
    986         L3_IPMC_1_PARITY_STATUS_NACKr, NULL },
    987 /*  { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    988         MA_INDEX_PAR_ERRf,
    989         MA_INDEX_PAR_ERRf,
    990         MA_INDEXm, NULL,
    991         MA_INDEX_PARITY_CONTROLr, PARITY_ENf,
    992         MA_INDEX_PARITY_STATUS_INTRr, NULL,
    993         MA_INDEX_PARITY_STATUS_NACKr, NULL },
    994     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
    995         RMEP_PAR_ERRf,
    996         RMEP_PAR_ERRf,
    997         RMEPm, NULL,
    998         RMEP_PARITY_CONTROLr, PARITY_ENf,
    999         RMEP_PARITY_STATUS_INTRr, NULL,
   1000         RMEP_PARITY_STATUS_NACKr, NULL },
   1001     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1002         MAID_REDUCTION_PAR_ERRf,
   1003         MAID_REDUCTION_PAR_ERRf,
   1004         MAID_REDUCTIONm, NULL,
   1005         MAID_REDUCTION_PARITY_CONTROLr, PARITY_ENf,
   1006         MAID_REDUCTION_PARITY_STATUS_INTRr, NULL,
   1007         MAID_REDUCTION_PARITY_STATUS_NACKr, NULL },
   1008     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1009         MA_STATE_PAR_ERRf,
   1010         MA_STATE_PAR_ERRf,
   1011         MA_STATEm, NULL,
   1012         MA_STATE_PARITY_CONTROLr, PARITY_ENf,
   1013         MA_STATE_PARITY_STATUS_INTRr, NULL,
   1014         MA_STATE_PARITY_STATUS_NACKr, NULL },*/
   1015     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1016         VLAN_PAR_ERRf,
   1017         VLAN_PAR_ERRf,
   1018         VLAN_TABm, NULL,
   1019         VLAN_PARITY_CONTROLr, PARITY_ENf,
   1020         VLAN_PARITY_STATUS_INTRr, NULL,
   1021         VLAN_PARITY_STATUS_NACKr, NULL },
   1022     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1023         SVP_PAR_ERRf,
   1024         SVP_PAR_ERRf,
   1025         SOURCE_VPm, NULL,
   1026         SOURCE_VP_PARITY_CONTROLr, PARITY_ENf,
   1027         SOURCE_VP_PARITY_STATUS_INTRr, NULL,
   1028         SOURCE_VP_PARITY_STATUS_NACKr, NULL },
   1029     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1030         L3_IIF_PAR_ERRf,
   1031         L3_IIF_PAR_ERRf,
   1032         L3_IIFm, NULL,
   1033         L3_IIF_PARITY_CONTROLr, PARITY_ENf,
   1034         L3_IIF_PARITY_STATUS_INTRr, NULL,
   1035         L3_IIF_PARITY_STATUS_NACKr, NULL },
   1036     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1037         VFI_INTRf,
   1038         VFI_INTRf,
   1039         VFIm, NULL,
   1040         VFI_PARITY_CONTROLr, PARITY_ENf,
   1041         VFI_PARITY_STATUS_INTRr, NULL,
   1042         VFI_PARITY_STATUS_NACKr, NULL },
   1043     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1044         VLAN_MPLS_INTRf,
   1045         VLAN_MPLS_INTRf,
   1046         VLAN_MPLSm, NULL,
   1047         VLAN_MPLS_PARITY_CONTROLr, PARITY_ENf,
   1048         VLAN_MPLS_PARITY_STATUS_INTRr, NULL,
   1049         VLAN_MPLS_PARITY_STATUS_NACKr, NULL },
   1050     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1051         VLAN_STG_INTRf,
   1052         VLAN_STG_INTRf,
   1053         STG_TABm, NULL,
   1054         VLAN_STG_PARITY_CONTROLr, PARITY_ENf,
   1055         VLAN_STG_PARITY_STATUS_INTRr, NULL,
   1056         VLAN_STG_PARITY_STATUS_NACKr, NULL },
   1057     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1058         VRF_INTRf,
   1059         VRF_INTRf,
   1060         VRFm, NULL,
   1061         VRF_PARITY_CONTROLr, PARITY_ENf,
   1062         VRF_PARITY_STATUS_INTRr, NULL,
   1063         VRF_PARITY_STATUS_NACKr, NULL },
   1064     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1065         VFI_1_INTRf,
   1066         VFI_1_INTRf,
   1067         VFI_1m, NULL,
   1068         VFI_1_PARITY_CONTROLr, PARITY_ENf,
   1069         VFI_1_PARITY_STATUS_INTRr, NULL,
   1070         VFI_1_PARITY_STATUS_NACKr, NULL },
   1071     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1072         L3_ENTRY_PAR_ERRf,
   1073         L3_ENTRY_PAR_ERRf,
   1074         L3_ENTRY_ONLYm, NULL,
   1075         L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1076         INVALIDr, _soc_trident_l3_entry_only_intr_reg,
   1077         INVALIDr, _soc_trident_l3_entry_only_nack_reg },
   1078     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1079         L3_ENTRY_PAR_ERRf,
   1080         L3_ENTRY_PAR_ERRf,
   1081         L3_ENTRY_IPV4_UNICASTm, NULL,
   1082         L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1083         INVALIDr, _soc_trident_l3_entry_only_intr_reg,
   1084         INVALIDr, _soc_trident_l3_entry_only_nack_reg },
   1085     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1086         L3_ENTRY_PAR_ERRf,
   1087         L3_ENTRY_PAR_ERRf,
   1088         L3_ENTRY_IPV4_MULTICASTm, NULL,
   1089         L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1090         INVALIDr, _soc_trident_l3_entry_only_intr_reg,
   1091         INVALIDr, _soc_trident_l3_entry_only_nack_reg },
   1092     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1093         L3_ENTRY_PAR_ERRf,
   1094         L3_ENTRY_PAR_ERRf,
   1095         L3_ENTRY_IPV6_UNICASTm, NULL,
   1096         L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1097         INVALIDr, _soc_trident_l3_entry_only_intr_reg,
   1098         INVALIDr, _soc_trident_l3_entry_only_nack_reg },
   1099     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1100         L3_ENTRY_PAR_ERRf,
   1101         L3_ENTRY_PAR_ERRf,
   1102         L3_ENTRY_IPV6_MULTICASTm, NULL,
   1103         L3_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1104         INVALIDr, _soc_trident_l3_entry_only_intr_reg,
   1105         INVALIDr, _soc_trident_l3_entry_only_nack_reg },
   1106     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1107         L3_DEFIP_DATA_PAR_ERRf,
   1108         L3_DEFIP_DATA_PAR_ERRf,
   1109         L3_DEFIP_DATA_ONLYm, NULL,
   1110         L3_DEFIP_DATA_PARITY_CONTROLr, PARITY_ENf,
   1111         L3_DEFIP_DATA_PARITY_STATUS_INTRr, NULL,
   1112         L3_DEFIP_DATA_PARITY_STATUS_NACKr, NULL },
   1113     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1114         L3_DEFIP_128_DATA_PAR_ERRf,
   1115         L3_DEFIP_128_DATA_PAR_ERRf,
   1116         L3_DEFIP_128_DATA_ONLYm, NULL,
   1117         L3_DEFIP_128_DATA_PARITY_CONTROLr, PARITY_ENf,
   1118         L3_DEFIP_128_DATA_PARITY_STATUS_INTRr, NULL,
   1119         L3_DEFIP_128_DATA_PARITY_STATUS_NACKr, NULL },
   1120     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1121         TTL_FN_PAR_ERRf,
   1122         TTL_FN_PAR_ERRf,
   1123         TTL_FNm, NULL,
   1124         TTL_FN_PARITY_CONTROLr, PARITY_ENf,
   1125         TTL_FN_PARITY_STATUS_INTRr, NULL,
   1126         TTL_FN_PARITY_STATUS_NACKr, NULL },
   1127     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1128         TOS_FN_PAR_ERRf,
   1129         TOS_FN_PAR_ERRf,
   1130         TOS_FNm, NULL,
   1131         TOS_FN_PARITY_CONTROLr, PARITY_ENf,
   1132         TOS_FN_PARITY_STATUS_INTRr, NULL,
   1133         TOS_FN_PARITY_STATUS_NACKr, NULL },
   1134     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1135         ING_PRI_CNG_MAP_PAR_ERRf,
   1136         ING_PRI_CNG_MAP_PAR_ERRf,
   1137         ING_PRI_CNG_MAPm, NULL,
   1138         ING_PRI_CNG_MAP_PARITY_CONTROLr, PARITY_ENf,
   1139         ING_PRI_CNG_MAP_PARITY_STATUS_INTRr, NULL,
   1140         ING_PRI_CNG_MAP_PARITY_STATUS_NACKr, NULL },
   1141     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1142         ING_UNTAGGED_PHB_PAR_ERRf,
   1143         ING_UNTAGGED_PHB_PAR_ERRf,
   1144         ING_UNTAGGED_PHBm, NULL,
   1145         ING_UNTAGGED_PHB_PARITY_CONTROLr, PARITY_ENf,
   1146         ING_UNTAGGED_PHB_PARITY_STATUS_INTRr, NULL,
   1147         ING_UNTAGGED_PHB_PARITY_STATUS_NACKr, NULL },
   1148     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1149         DSCP_TABLE_PAR_ERRf,
   1150         DSCP_TABLE_PAR_ERRf,
   1151         DSCP_TABLEm, NULL,
   1152         DSCP_TABLE_PARITY_CONTROLr, PARITY_ENf,
   1153         DSCP_TABLE_PARITY_STATUS_INTRr, NULL,
   1154         DSCP_TABLE_PARITY_STATUS_NACKr, NULL },
   1155     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1156         FP_FIELD_SEL_PAR_ERRf,
   1157         FP_FIELD_SEL_PAR_ERRf,
   1158         FP_PORT_FIELD_SELm, NULL,
   1159         FP_FIELD_SEL_PARITY_CONTROLr, PARITY_ENf,
   1160         FP_FIELD_SEL_PARITY_STATUS_INTRr, NULL,
   1161         FP_FIELD_SEL_PARITY_STATUS_NACKr, NULL },
   1162     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1163 };
   1164 
   1165 STATIC _soc_trident_parity_info_t _soc_trident_ip2_2_parity_info[] = {
   1166     /* IP2_INTR_STATUS_2.SOME_RDI_DEFECT_INTR */
   1167     /* IP2_INTR_STATUS_2.SOME_RMEP_CCM_DEFECT_INTR */
   1168     /* IP2_INTR_STATUS_2.ERROR_CCM_DEFECT_INTR */
   1169     /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_PORT_DOWN_INTR */
   1170     /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_PORT_UP_INTR */
   1171     /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_INTERFACE_DOWN_INTR */
   1172     /* IP2_INTR_STATUS_2.ANY_RMEP_TLV_INTERFACE_UP_INTR */
   1173     /* IP2_INTR_STATUS_2.XCON_CCM_DEFECT_INTR */
   1174     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1175 };
   1176 
   1177 STATIC _soc_trident_parity_info_t _soc_trident_ip3_parity_info[] = {
   1178     { _SOC_PARITY_TYPE_HASH, NULL, 0,
   1179         L2_ENTRY_PAR_ERRf,
   1180         L2_ENTRY_PAR_ERRf,
   1181         L2_ENTRY_ONLYm, NULL,
   1182         L2_ENTRY_PARITY_CONTROLr, PARITY_ENf,
   1183         INVALIDr, _soc_trident_l2_entry_only_intr_reg,
   1184         INVALIDr, _soc_trident_l2_entry_only_nack_reg },
   1185     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1186         L2_MOD_FIFO_INTRf,
   1187         L2_MOD_FIFO_INTRf,
   1188         L2_MOD_FIFOm, NULL,
   1189         L2_MOD_FIFO_PARITY_CONTROLr, PARITY_ENf,
   1190         L2_MOD_FIFO_PARITY_STATUS_INTRr, NULL,
   1191         L2_MOD_FIFO_PARITY_STATUS_NACKr, NULL },
   1192     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1193         L2_USER_ENTRY_DATA_INTRf,
   1194         L2_USER_ENTRY_DATA_INTRf,
   1195         L2_USER_ENTRY_DATA_ONLYm, NULL,
   1196         L2_USER_ENTRY_DATA_PARITY_CONTROLr, PARITY_ENf,
   1197         L2_USER_ENTRY_DATA_PARITY_STATUS_INTRr, NULL,
   1198         L2_USER_ENTRY_DATA_PARITY_STATUS_NACKr, NULL },
   1199     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1200 };
   1201 
   1202 STATIC _soc_trident_parity_info_t _soc_trident_ip4_parity_info[] = {
   1203     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1204         IFP_POLICY_PAR_ERRf,
   1205         IFP_POLICY_PAR_ERRf,
   1206         FP_POLICY_TABLEm, NULL,
   1207         IFP_POLICY_PARITY_CONTROLr, PARITY_ENf,
   1208         IFP_POLICY_PARITY_STATUS_INTRr, NULL,
   1209         IFP_POLICY_PARITY_STATUS_NACKr, NULL },
   1210     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1211         IFP_STORM_CONTROL_PAR_ERRf,
   1212         IFP_STORM_CONTROL_PAR_ERRf,
   1213         FP_STORM_CONTROL_METERSm, NULL,
   1214         IFP_STORM_CONTROL_PARITY_CONTROLr, PARITY_ENf,
   1215         IFP_STORM_CONTROL_PARITY_STATUS_INTRr, NULL,
   1216         IFP_STORM_CONTROL_PARITY_STATUS_NACKr, NULL },
   1217     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1218         IFP_COUNTER_PAR_ERRf,
   1219         IFP_COUNTER_PAR_ERRf,
   1220         FP_COUNTER_TABLEm, NULL,
   1221         IFP_COUNTER_PARITY_CONTROLr, PARITY_ENf,
   1222         IFP_COUNTER_PARITY_STATUS_INTRr, NULL,
   1223         IFP_COUNTER_PARITY_STATUS_NACKr, NULL },
   1224     /*{ _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1225         IFP_METER_PAR_ERRf,
   1226         IFP_METER_PAR_ERRf,
   1227         FP_METER_TABLEm, NULL,
   1228         IFP_METER_PARITY_CONTROLr, PARITY_ENf,
   1229         IFP_METER_PARITY_STATUS_INTRr, NULL,
   1230         IFP_METER_PARITY_STATUS_NACKr, NULL },*/
   1231     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1232         IFP_ING_DVP_2_PAR_ERRf,
   1233         IFP_ING_DVP_2_PAR_ERRf,
   1234         ING_DVP_2_TABLEm, NULL,
   1235         IFP_ING_DVP_2_PARITY_CONTROLr, PARITY_ENf,
   1236         IFP_ING_DVP_2_PARITY_STATUS_INTRr, NULL,
   1237         IFP_ING_DVP_2_PARITY_STATUS_NACKr, NULL },
   1238 #if 0 /* Do not enable parity since there is no simple way to clear these
   1239        * 2 memory buffers during init */
   1240     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1241         IFP_METER_MUX_DATA_STAGING_PAR_ERRf,
   1242         IFP_METER_MUX_DATA_STAGING_PAR_ERRf,
   1243         INVALIDm, "IFP_METER_MUX_DATA_STAGING",
   1244         IFP_METER_MUX_DATA_STAGING_PARITY_CONTROLr, PARITY_ENf,
   1245         IFP_METER_MUX_DATA_STAGING_PARITY_STATUS_INTRr, NULL,
   1246         INVALIDr, NULL },
   1247     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1248         IFP_COUNTER_MUX_DATA_STAGING_PAR_ERRf,
   1249         IFP_COUNTER_MUX_DATA_STAGING_PAR_ERRf,
   1250         INVALIDm, "IFP_COUNTER_MUX_DATA_STAGING",
   1251         IFP_COUNTER_MUX_DATA_STAGING_PARITY_CONTROLr, PARITY_ENf,
   1252         IFP_COUNTER_MUX_DATA_STAGING_PARITY_STATUS_INTRr, NULL,
   1253         INVALIDr, NULL },
   1254 #endif
   1255     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1256         IRSEL2_EGR_MASK_MODBASE_PAR_ERRf,
   1257         IRSEL2_EGR_MASK_MODBASE_PAR_ERRf,
   1258         EGR_MASK_MODBASEm, NULL,
   1259         EGR_MASK_MODBASE_PARITY_CONTROLr, PARITY_ENf,
   1260         EGR_MASK_MODBASE_PARITY_STATUS_INTRr, NULL,
   1261         EGR_MASK_MODBASE_PARITY_STATUS_NACKr, NULL },
   1262     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1263         IRSEL2_ICONTROL_OPCODE_BITMAP_PAR_ERRf,
   1264         IRSEL2_ICONTROL_OPCODE_BITMAP_PAR_ERRf,
   1265         ICONTROL_OPCODE_BITMAPm, NULL,
   1266         ICONTROL_OPCODE_BITMAP_PARITY_CONTROLr, PARITY_ENf,
   1267         ICONTROL_OPCODE_BITMAP_PARITY_STATUS_INTRr, NULL,
   1268         ICONTROL_OPCODE_BITMAP_PARITY_STATUS_NACKr, NULL },
   1269     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1270         IRSEL2_IFP_REDIRECTION_PROFILE_PAR_ERRf,
   1271         IRSEL2_IFP_REDIRECTION_PROFILE_PAR_ERRf,
   1272         IFP_REDIRECTION_PROFILEm, NULL,
   1273         IFP_REDIRECTION_PROFILE_PARITY_CONTROLr, PARITY_ENf,
   1274         IFP_REDIRECTION_PROFILE_PARITY_STATUS_INTRr, NULL,
   1275         IFP_REDIRECTION_PROFILE_PARITY_STATUS_NACKr, NULL },
   1276     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1277         IRSEL2_ING_L3_NEXT_HOP_PAR_ERRf,
   1278         IRSEL2_ING_L3_NEXT_HOP_PAR_ERRf,
   1279         ING_L3_NEXT_HOPm, NULL,
   1280         ING_L3_NEXT_HOP_PARITY_CONTROLr, PARITY_ENf,
   1281         ING_L3_NEXT_HOP_PARITY_STATUS_INTRr, NULL,
   1282         ING_L3_NEXT_HOP_PARITY_STATUS_NACKr, NULL },
   1283     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1284         IRSEL2_L2MC_PAR_ERRf,
   1285         IRSEL2_L2MC_PAR_ERRf,
   1286         L2MCm, NULL,
   1287         L2MC_PARITY_CONTROLr, PARITY_ENf,
   1288         L2MC_PARITY_STATUS_INTRr, NULL,
   1289         L2MC_PARITY_STATUS_NACKr, NULL },
   1290     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1291         IRSEL2_L3_ECMP_GROUP_PAR_ERRf,
   1292         IRSEL2_L3_ECMP_GROUP_PAR_ERRf,
   1293         L3_ECMP_COUNTm, NULL,
   1294         L3_ECMP_GROUP_PARITY_CONTROLr, PARITY_ENf,
   1295         L3_ECMP_GROUP_PARITY_STATUS_INTRr, NULL,
   1296         L3_ECMP_GROUP_PARITY_STATUS_NACKr, NULL },
   1297     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1298         IRSEL2_L3_ECMP_PAR_ERRf,
   1299         IRSEL2_L3_ECMP_PAR_ERRf,
   1300         L3_ECMPm, NULL,
   1301         L3_ECMP_PARITY_CONTROLr, PARITY_ENf,
   1302         L3_ECMP_PARITY_STATUS_INTRr, NULL,
   1303         L3_ECMP_PARITY_STATUS_NACKr, NULL },
   1304     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1305         IRSEL2_L3_IPMC_PAR_ERRf,
   1306         IRSEL2_L3_IPMC_PAR_ERRf,
   1307         L3_IPMCm, NULL,
   1308         L3_IPMC_PARITY_CONTROLr, PARITY_ENf,
   1309         L3_IPMC_PARITY_STATUS_INTRr, NULL,
   1310         L3_IPMC_PARITY_STATUS_NACKr, NULL },
   1311     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1312         IRSEL2_L3_IPMC_REMAP_PAR_ERRf,
   1313         IRSEL2_L3_IPMC_REMAP_PAR_ERRf,
   1314         L3_IPMC_REMAPm, NULL,
   1315         L3_IPMC_REMAP_PARITY_CONTROLr, PARITY_ENf,
   1316         L3_IPMC_REMAP_PARITY_STATUS_INTRr, NULL,
   1317         L3_IPMC_REMAP_PARITY_STATUS_NACKr, NULL },
   1318     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1319         IRSEL2_TRUNK_GROUP_PAR_ERRf,
   1320         IRSEL2_TRUNK_GROUP_PAR_ERRf,
   1321         TRUNK_GROUPm, NULL,
   1322         TRUNK_GROUP_PARITY_CONTROLr, PARITY_ENf,
   1323         TRUNK_GROUP_PARITY_STATUS_INTRr, NULL,
   1324         TRUNK_GROUP_PARITY_STATUS_NACKr, NULL },
   1325     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1326 };
   1327 
   1328 STATIC _soc_trident_parity_info_t _soc_trident_ip5_parity_info[] = {
   1329     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1330         VOQ_COS_MAP_PAR_ERRf,
   1331         VOQ_COS_MAP_PAR_ERRf,
   1332         VOQ_COS_MAPm, NULL,
   1333         VOQ_COS_MAP_PARITY_CONTROLr, PARITY_ENf,
   1334         VOQ_COS_MAP_PARITY_STATUS_INTRr, NULL,
   1335         VOQ_COS_MAP_PARITY_STATUS_NACKr, NULL },
   1336     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1337         DLB_HGT_FLOWSET_PORT_PAR_ERRf,
   1338         DLB_HGT_FLOWSET_PORT_PAR_ERRf,
   1339         DLB_HGT_FLOWSET_PORTm, NULL,
   1340         DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr, PARITY_ENf,
   1341         DLB_HGT_FLOWSET_PORT_PARITY_STATUS_INTRr, NULL,
   1342         DLB_HGT_FLOWSET_PORT_PARITY_STATUS_NACKr, NULL },
   1343     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1344         DLB_HGT_FLOWSET_TIMESTAMP_PAR_ERRf,
   1345         DLB_HGT_FLOWSET_TIMESTAMP_PAR_ERRf,
   1346         DLB_HGT_FLOWSET_TIMESTAMPm, NULL,
   1347         DLB_HGT_FLOWSET_TIMESTAMP_PARITY_CONTROLr, PARITY_ENf,
   1348         DLB_HGT_FLOWSET_TIMESTAMP_PARITY_STATUS_INTRr, NULL,
   1349         DLB_HGT_FLOWSET_TIMESTAMP_PARITY_STATUS_NACKr, NULL },
   1350     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1351         DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PAR_ERRf,
   1352         DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PAR_ERRf,
   1353         DLB_HGT_FLOWSET_TIMESTAMP_PAGEm, NULL,
   1354         DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_CONTROLr, PARITY_ENf,
   1355         DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_STATUS_INTRr, NULL,
   1356         DLB_HGT_FLOWSET_TIMESTAMP_PAGE_PARITY_STATUS_NACKr, NULL },
   1357     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1358 };
   1359 
   1360 STATIC _soc_trident_parity_info_t _soc_trident_ip5_1_parity_info[] = {
   1361     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1362         EGR_MASK_PAR_ERRf,
   1363         EGR_MASK_PAR_ERRf,
   1364         EGR_MASKm, NULL,
   1365         EGR_MASK_PARITY_CONTROLr, PARITY_ENf,
   1366         EGR_MASK_PARITY_STATUS_INTRr, NULL,
   1367         EGR_MASK_PARITY_STATUS_NACKr, NULL },
   1368     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1369         TRUNK_BITMAP_PAR_ERRf,
   1370         TRUNK_BITMAP_PAR_ERRf,
   1371         TRUNK_BITMAPm, NULL,
   1372         TRUNK_BITMAP_TABLE_PARITY_CONTROLr, PARITY_ENf,
   1373         TRUNK_BITMAP_TABLE_PARITY_STATUS_INTRr, NULL,
   1374         TRUNK_BITMAP_TABLE_PARITY_STATUS_NACKr, NULL },
   1375     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1376         NONUCAST_TRUNK_BLOCK_MASK_PAR_ERRf,
   1377         NONUCAST_TRUNK_BLOCK_MASK_PAR_ERRf,
   1378         NONUCAST_TRUNK_BLOCK_MASKm, NULL,
   1379         NONUCAST_TRUNK_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf,
   1380         NONUCAST_TRUNK_BLOCK_MASK_PARITY_STATUS_INTRr, NULL,
   1381         NONUCAST_TRUNK_BLOCK_MASK_PARITY_STATUS_NACKr, NULL },
   1382     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1383         MAC_BLOCK_TABLE_PAR_ERRf,
   1384         MAC_BLOCK_TABLE_PAR_ERRf,
   1385         MAC_BLOCKm, NULL,
   1386         MAC_BLOCK_TABLE_PARITY_CONTROLr, PARITY_ENf,
   1387         MAC_BLOCK_TABLE_PARITY_STATUS_INTRr, NULL,
   1388         MAC_BLOCK_TABLE_PARITY_STATUS_NACKr, NULL },
   1389     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1390         MODPORT_MAP_SW_PAR_ERRf,
   1391         MODPORT_MAP_SW_PAR_ERRf,
   1392         MODPORT_MAP_SWm, NULL,
   1393         MODPORT_MAP_SW_PARITY_CONTROLr, PARITY_ENf,
   1394         MODPORT_MAP_SW_PARITY_STATUS_INTRr, NULL,
   1395         MODPORT_MAP_SW_PARITY_STATUS_NACKr, NULL },
   1396     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1397         MODPORT_MAP_M0_PAR_ERRf,
   1398         MODPORT_MAP_M0_PAR_ERRf,
   1399         MODPORT_MAP_M0m, NULL,
   1400         MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf,
   1401         MODPORT_MAP_M0_PARITY_STATUS_INTRr, NULL,
   1402         MODPORT_MAP_M0_PARITY_STATUS_NACKr, NULL },
   1403     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1404         MODPORT_MAP_M1_PAR_ERRf,
   1405         MODPORT_MAP_M1_PAR_ERRf,
   1406         MODPORT_MAP_M1m, NULL,
   1407         MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf,
   1408         MODPORT_MAP_M1_PARITY_STATUS_INTRr, NULL,
   1409         MODPORT_MAP_M1_PARITY_STATUS_NACKr, NULL },
   1410     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1411         MODPORT_MAP_M2_PAR_ERRf,
   1412         MODPORT_MAP_M2_PAR_ERRf,
   1413         MODPORT_MAP_M2m, NULL,
   1414         MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf,
   1415         MODPORT_MAP_M2_PARITY_STATUS_INTRr, NULL,
   1416         MODPORT_MAP_M2_PARITY_STATUS_NACKr, NULL },
   1417     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1418         MODPORT_MAP_M3_PAR_ERRf,
   1419         MODPORT_MAP_M3_PAR_ERRf,
   1420         MODPORT_MAP_M3m, NULL,
   1421         MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf,
   1422         MODPORT_MAP_M3_PARITY_STATUS_INTRr, NULL,
   1423         MODPORT_MAP_M3_PARITY_STATUS_NACKr, NULL },
   1424     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1425         SRC_MODID_INGRESS_BLOCK_PAR_ERRf,
   1426         SRC_MODID_INGRESS_BLOCK_PAR_ERRf,
   1427         SRC_MODID_INGRESS_BLOCKm, NULL,
   1428         SRC_MODID_INGRESS_BLOCK_PARITY_CONTROLr, PARITY_ENf,
   1429         SRC_MODID_INGRESS_BLOCK_PARITY_STATUS_INTRr, NULL,
   1430         SRC_MODID_INGRESS_BLOCK_PARITY_STATUS_NACKr, NULL },
   1431     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1432         SRC_MODID_EGRESS_PAR_ERRf,
   1433         SRC_MODID_EGRESS_PAR_ERRf,
   1434         SRC_MODID_EGRESSm, NULL,
   1435         SRC_MODID_EGRESS_PARITY_CONTROLr, PARITY_ENf,
   1436         SRC_MODID_EGRESS_PARITY_STATUS_INTRr, NULL,
   1437         SRC_MODID_EGRESS_PARITY_STATUS_NACKr, NULL },
   1438     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1439         ALTERNATE_EMIRROR_BITMAP_PAR_ERRf,
   1440         ALTERNATE_EMIRROR_BITMAP_PAR_ERRf,
   1441         ALTERNATE_EMIRROR_BITMAPm, NULL,
   1442         ALTERNATE_EMIRROR_BITMAP_PARITY_CONTROLr, PARITY_ENf,
   1443         ALTERNATE_EMIRROR_BITMAP_PARITY_STATUS_INTRr, NULL,
   1444         ALTERNATE_EMIRROR_BITMAP_PARITY_STATUS_NACKr, NULL },
   1445     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1446         PORT_LAG_FAILOVER_SET_PAR_ERRf,
   1447         PORT_LAG_FAILOVER_SET_PAR_ERRf,
   1448         PORT_LAG_FAILOVER_SETm, NULL,
   1449         PORT_LAG_FAILOVER_SET_PARITY_CONTROLr, PARITY_ENf,
   1450         PORT_LAG_FAILOVER_SET_PARITY_STATUS_INTRr, NULL,
   1451         PORT_LAG_FAILOVER_SET_PARITY_STATUS_NACKr, NULL },
   1452     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1453         VLAN_PROFILE_2_PAR_ERRf,
   1454         VLAN_PROFILE_2_PAR_ERRf,
   1455         VLAN_PROFILE_2m, NULL,
   1456         VLAN_PROFILE_2_PARITY_CONTROLr, PARITY_ENf,
   1457         VLAN_PROFILE_2_PARITY_STATUS_INTRr, NULL,
   1458         VLAN_PROFILE_2_PARITY_STATUS_NACKr, NULL },
   1459     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1460         L3_MTU_VALUES_PAR_ERRf,
   1461         L3_MTU_VALUES_PAR_ERRf,
   1462         L3_MTU_VALUESm, NULL,
   1463         L3_MTU_VALUES_PARITY_CONTROLr, PARITY_ENf,
   1464         L3_MTU_VALUES_PARITY_STATUS_INTRr, NULL,
   1465         L3_MTU_VALUES_PARITY_STATUS_NACKr, NULL },
   1466     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1467         ING_PW_TERM_SEQ_NUM_PAR_ERRf,
   1468         ING_PW_TERM_SEQ_NUM_PAR_ERRf,
   1469         ING_PW_TERM_SEQ_NUMm, NULL,
   1470         ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf,
   1471         ING_PW_TERM_SEQ_NUM_PARITY_STATUS_INTRr, NULL,
   1472         ING_PW_TERM_SEQ_NUM_PARITY_STATUS_NACKr, NULL },
   1473     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1474         ING_SERVICE_COUNTER_TABLE_PAR_ERRf,
   1475         ING_SERVICE_COUNTER_TABLE_PAR_ERRf,
   1476         ING_SERVICE_COUNTER_TABLEm, NULL,
   1477         ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr, PARITY_ENf,
   1478         ING_SERVICE_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
   1479         ING_SERVICE_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
   1480     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1481         ING_VINTF_COUNTER_TABLE_PAR_ERRf,
   1482         ING_VINTF_COUNTER_TABLE_PAR_ERRf,
   1483         ING_VINTF_COUNTER_TABLEm, NULL,
   1484         ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr, PARITY_ENf,
   1485         ING_VINTF_COUNTER_TABLE_PARITY_STATUS_INTRr, NULL,
   1486         ING_VINTF_COUNTER_TABLE_PARITY_STATUS_NACKr, NULL },
   1487     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1488         VLAN_COS_MAP_PAR_ERRf,
   1489         VLAN_COS_MAP_PAR_ERRf,
   1490         VLAN_COS_MAPm, NULL,
   1491         VLAN_COS_MAP_PARITY_CONTROLr, PARITY_ENf,
   1492         VLAN_COS_MAP_PARITY_STATUS_INTRr, NULL,
   1493         VLAN_COS_MAP_PARITY_STATUS_NACKr, NULL },
   1494     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1495         E2E_HOL_STATUS_PAR_ERRf,
   1496         E2E_HOL_STATUS_PAR_ERRf,
   1497         E2E_HOL_STATUSm, NULL,
   1498         E2E_HOL_STATUS_PARITY_CONTROLr, PARITY_ENf,
   1499         E2E_HOL_STATUS_PARITY_STATUS_INTRr, NULL,
   1500         E2E_HOL_STATUS_PARITY_STATUS_NACKr, NULL },
   1501     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1502         E2E_HOL_STATUS_1_PAR_ERRf,
   1503         E2E_HOL_STATUS_1_PAR_ERRf,
   1504         E2E_HOL_STATUS_1m, NULL,
   1505         E2E_HOL_STATUS_1_PARITY_CONTROLr, PARITY_ENf,
   1506         E2E_HOL_STATUS_1_PARITY_STATUS_INTRr, NULL,
   1507         E2E_HOL_STATUS_1_PARITY_STATUS_NACKr, NULL },
   1508     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1509         UNKNOWN_UCAST_BLOCK_MASK_PAR_ERRf,
   1510         UNKNOWN_UCAST_BLOCK_MASK_PAR_ERRf,
   1511         UNKNOWN_UCAST_BLOCK_MASKm, NULL,
   1512         UNKNOWN_UCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf,
   1513         UNKNOWN_UCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL,
   1514         UNKNOWN_UCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL },
   1515     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1516         UNKNOWN_MCAST_BLOCK_MASK_PAR_ERRf,
   1517         UNKNOWN_MCAST_BLOCK_MASK_PAR_ERRf,
   1518         UNKNOWN_MCAST_BLOCK_MASKm, NULL,
   1519         UNKNOWN_MCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf,
   1520         UNKNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL,
   1521         UNKNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL },
   1522     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1523         BCAST_BLOCK_MASK_PAR_ERRf,
   1524         BCAST_BLOCK_MASK_PAR_ERRf,
   1525         BCAST_BLOCK_MASKm, NULL,
   1526         BCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf,
   1527         BCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL,
   1528         BCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL },
   1529     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1530         KNOWN_MCAST_BLOCK_MASK_PAR_ERRf,
   1531         KNOWN_MCAST_BLOCK_MASK_PAR_ERRf,
   1532         KNOWN_MCAST_BLOCK_MASKm, NULL,
   1533         KNOWN_MCAST_BLOCK_MASK_PARITY_CONTROLr, PARITY_ENf,
   1534         KNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_INTRr, NULL,
   1535         KNOWN_MCAST_BLOCK_MASK_PARITY_STATUS_NACKr, NULL },
   1536     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1537         ING_EGRMSKBMAP_PAR_ERRf,
   1538         ING_EGRMSKBMAP_PAR_ERRf,
   1539         ING_EGRMSKBMAPm, NULL,
   1540         ING_EGRMSKBMAP_PARITY_CONTROLr, PARITY_ENf,
   1541         ING_EGRMSKBMAP_PARITY_STATUS_INTRr, NULL,
   1542         ING_EGRMSKBMAP_PARITY_STATUS_NACKr, NULL },
   1543     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1544         LOCAL_SW_DISABLE_DEFAULT_PBM_PAR_ERRf,
   1545         LOCAL_SW_DISABLE_DEFAULT_PBM_PAR_ERRf,
   1546         LOCAL_SW_DISABLE_DEFAULT_PBMm, NULL,
   1547         LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_CONTROLr, PARITY_ENf,
   1548         LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_STATUS_INTRr, NULL,
   1549         LOCAL_SW_DISABLE_DEFAULT_PBM_PARITY_STATUS_NACKr, NULL },
   1550     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1551         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PAR_ERRf,
   1552         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PAR_ERRf,
   1553         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRRm, NULL,
   1554         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_CONTROLr, PARITY_ENf,
   1555         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_STATUS_INTRr, NULL,
   1556         LOCAL_SW_DISABLE_DEFAULT_PBM_MIRR_PARITY_STATUS_NACKr, NULL },
   1557     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1558         IMIRROR_BITMAP_PAR_ERRf,
   1559         IMIRROR_BITMAP_PAR_ERRf,
   1560         IMIRROR_BITMAPm, NULL,
   1561         IMIRROR_BITMAP_PARITY_CONTROLr, PARITY_ENf,
   1562         IMIRROR_BITMAP_PARITY_STATUS_INTRr, NULL,
   1563         IMIRROR_BITMAP_PARITY_STATUS_NACKr, NULL },
   1564     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1565         UNKNOWN_HGI_BITMAP_PAR_ERRf,
   1566         UNKNOWN_HGI_BITMAP_PAR_ERRf,
   1567         UNKNOWN_HGI_BITMAPm, NULL,
   1568         UNKNOWN_HGI_BITMAP_PARITY_CONTROLr, PARITY_ENf,
   1569         UNKNOWN_HGI_BITMAP_PARITY_STATUS_INTRr, NULL,
   1570         UNKNOWN_HGI_BITMAP_PARITY_STATUS_NACKr, NULL },
   1571     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1572         TRUNK_MEMBER_PAR_ERRf,
   1573         TRUNK_MEMBER_PAR_ERRf,
   1574         TRUNK_MEMBERm, NULL,
   1575         TRUNK_MEMBER_PARITY_CONTROLr, PARITY_ENf,
   1576         TRUNK_MEMBER_PARITY_STATUS_INTRr, NULL,
   1577         TRUNK_MEMBER_PARITY_STATUS_NACKr, NULL },
   1578     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1579         ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PAR_ERRf,
   1580         ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PAR_ERRf,
   1581         ING_HIGIG_TRUNK_OVERRIDE_PROFILEm, NULL,
   1582         ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_CONTROLr, PARITY_ENf,
   1583         ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_STATUS_INTRr, NULL,
   1584         ING_HIGIG_TRUNK_OVERRIDE_PROFILE_PARITY_STATUS_NACKr, NULL },
   1585     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1586 };
   1587 
   1588 STATIC _soc_trident_parity_info_t _soc_trident_ip5_2_parity_info[] = {
   1589     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1590         EMIRROR_CONTROL_PAR_ERRf,
   1591         EMIRROR_CONTROL_PAR_ERRf,
   1592         EMIRROR_CONTROLm, NULL,
   1593         EMIRROR_CONTROL_PARITY_CONTROLr, PARITY_ENf,
   1594         EMIRROR_CONTROL_PARITY_STATUS_INTRr, NULL,
   1595         EMIRROR_CONTROL_PARITY_STATUS_NACKr, NULL },
   1596     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1597         EMIRROR_CONTROL1_PAR_ERRf,
   1598         EMIRROR_CONTROL1_PAR_ERRf,
   1599         EMIRROR_CONTROL1m, NULL,
   1600         EMIRROR_CONTROL1_PARITY_CONTROLr, PARITY_ENf,
   1601         EMIRROR_CONTROL1_PARITY_STATUS_INTRr, NULL,
   1602         EMIRROR_CONTROL1_PARITY_STATUS_NACKr, NULL },
   1603     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1604         EMIRROR_CONTROL2_PAR_ERRf,
   1605         EMIRROR_CONTROL2_PAR_ERRf,
   1606         EMIRROR_CONTROL2m, NULL,
   1607         EMIRROR_CONTROL2_PARITY_CONTROLr, PARITY_ENf,
   1608         EMIRROR_CONTROL2_PARITY_STATUS_INTRr, NULL,
   1609         EMIRROR_CONTROL2_PARITY_STATUS_NACKr, NULL },
   1610     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1611         EMIRROR_CONTROL3_PAR_ERRf,
   1612         EMIRROR_CONTROL3_PAR_ERRf,
   1613         EMIRROR_CONTROL3m, NULL,
   1614         EMIRROR_CONTROL3_PARITY_CONTROLr, PARITY_ENf,
   1615         EMIRROR_CONTROL3_PARITY_STATUS_INTRr, NULL,
   1616         EMIRROR_CONTROL3_PARITY_STATUS_NACKr, NULL },
   1617     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1618         SW2_EOP_BUFFER_A_PAR_ERRf,
   1619         SW2_EOP_BUFFER_A_PAR_ERRf,
   1620         INVALIDm, "SW2_EOP_BUFFER_A",
   1621         SW2_EOP_BUFFER_A_PARITY_CONTROLr, PARITY_ENf,
   1622         SW2_EOP_BUFFER_A_PARITY_STATUS_INTRr, NULL,
   1623         INVALIDr, NULL },
   1624     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1625         SW2_EOP_BUFFER_B_PAR_ERRf,
   1626         SW2_EOP_BUFFER_B_PAR_ERRf,
   1627         INVALIDm, "SW2_EOP_BUFFER_B",
   1628         SW2_EOP_BUFFER_B_PARITY_CONTROLr, PARITY_ENf,
   1629         SW2_EOP_BUFFER_B_PARITY_STATUS_INTRr, NULL,
   1630         INVALIDr, NULL },
   1631     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1632         SW2_EOP_BUFFER_C_PAR_ERRf,
   1633         SW2_EOP_BUFFER_C_PAR_ERRf,
   1634         INVALIDm, "SW2_EOP_BUFFER_C",
   1635         SW2_EOP_BUFFER_C_PARITY_CONTROLr, PARITY_ENf,
   1636         SW2_EOP_BUFFER_C_PARITY_STATUS_INTRr, NULL,
   1637         INVALIDr, NULL },
   1638     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1639         IP_COUNTERS_PAR_ERRf,
   1640         IP_COUNTERS_PAR_ERRf,
   1641         INVALIDm, "Ingress Pipeline Counter",
   1642         IP_COUNTERS_PARITY_CONTROLr, PARITY_ENf,
   1643         IP_COUNTERS_PARITY_STATUS_INTRr, NULL,
   1644         IP_COUNTERS_PARITY_STATUS_NACKr, NULL },
   1645     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1646         RDBGC_MEM_INST0_PAR_ERRf,
   1647         RDBGC_MEM_INST0_PAR_ERRf,
   1648         INVALIDm, "Ingress Pipeline Counter",
   1649         RDBGC_MEM_INST0_PARITY_CONTROLr, PARITY_ENf,
   1650         RDBGC_MEM_INST0_PARITY_STATUS_INTRr, NULL,
   1651         RDBGC_MEM_INST0_PARITY_STATUS_NACKr, NULL },
   1652     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1653         RDBGC_MEM_INST1_PAR_ERRf,
   1654         RDBGC_MEM_INST1_PAR_ERRf,
   1655         INVALIDm, "RX Debug Counter",
   1656         RDBGC_MEM_INST1_PARITY_CONTROLr, PARITY_ENf,
   1657         RDBGC_MEM_INST1_PARITY_STATUS_INTRr, NULL,
   1658         RDBGC_MEM_INST1_PARITY_STATUS_NACKr, NULL },
   1659     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1660         RDBGC_MEM_INST2_PAR_ERRf,
   1661         RDBGC_MEM_INST2_PAR_ERRf,
   1662         INVALIDm, "RX Debug Counter",
   1663         RDBGC_MEM_INST2_PARITY_CONTROLr, PARITY_ENf,
   1664         RDBGC_MEM_INST2_PARITY_STATUS_INTRr, NULL,
   1665         RDBGC_MEM_INST2_PARITY_STATUS_NACKr, NULL },
   1666     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1667         HG_COUNTERS_PAR_ERRf,
   1668         HG_COUNTERS_PAR_ERRf,
   1669         INVALIDm, "Ingress Pipeline HG Counter",
   1670         HG_COUNTERS_PARITY_CONTROLr, PARITY_ENf,
   1671         HG_COUNTERS_PARITY_STATUS_INTRr, NULL,
   1672         HG_COUNTERS_PARITY_STATUS_NACKr, NULL },
   1673     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1674         NIV_ERROR_DROP_PAR_ERRf,
   1675         NIV_ERROR_DROP_PAR_ERRf,
   1676         INVALIDm, "ING_NIV_RX_FRAMES_ERROR_DROP",
   1677         NIV_ERROR_DROP_PARITY_CONTROLr, PARITY_ENf,
   1678         NIV_ERROR_DROP_PARITY_STATUS_INTRr, NULL,
   1679         NIV_ERROR_DROP_PARITY_STATUS_NACKr, NULL },
   1680     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1681         NIV_FORWARDING_DROP_PAR_ERRf,
   1682         NIV_FORWARDING_DROP_PAR_ERRf,
   1683         INVALIDm, "ING_NIV_RX_FRAMES_FORWARDING_DROP",
   1684         NIV_FORWARDING_DROP_PARITY_CONTROLr, PARITY_ENf,
   1685         NIV_FORWARDING_DROP_PARITY_STATUS_INTRr, NULL,
   1686         NIV_FORWARDING_DROP_PARITY_STATUS_NACKr, NULL },
   1687     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1688         NIV_VLAN_TAGGED_PAR_ERRf,
   1689         NIV_VLAN_TAGGED_PAR_ERRf,
   1690         INVALIDm, "ING_NIV_RX_FRAMES_VLAN_TAGGED",
   1691         NIV_VLAN_TAGGED_PARITY_CONTROLr, PARITY_ENf,
   1692         NIV_VLAN_TAGGED_PARITY_STATUS_INTRr, NULL,
   1693         NIV_VLAN_TAGGED_PARITY_STATUS_NACKr, NULL },
   1694     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1695         TRILL_RX_PKTS_PAR_ERRf,
   1696         TRILL_RX_PKTS_PAR_ERRf,
   1697         INVALIDm, "ING_TRILL_RX_PKTS",
   1698         TRILL_RX_PKTS_PARITY_CONTROLr, PARITY_ENf,
   1699         TRILL_RX_PKTS_PARITY_STATUS_INTRr, NULL,
   1700         TRILL_RX_PKTS_PARITY_STATUS_NACKr, NULL },
   1701     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1702         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PAR_ERRf,
   1703         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PAR_ERRf,
   1704         INVALIDm, "ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED",
   1705         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_CONTROLr, PARITY_ENf,
   1706         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr, NULL,
   1707         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, NULL },
   1708     { _SOC_PARITY_TYPE_COUNTER, NULL, 0,
   1709         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PAR_ERRf,
   1710         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PAR_ERRf,
   1711         INVALIDm, "ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED",
   1712         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_CONTROLr, PARITY_ENf,
   1713         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr, NULL,
   1714         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr, NULL },
   1715     { _SOC_PARITY_TYPE_PARITY, NULL, 0,
   1716         CPB_PAR_ERRf,
   1717         CPB_PAR_ERRf,
   1718         INVALIDm, "CPB",
   1719         CPB_PARITY_CONTROLr, PARITY_ENf,
   1720         CPB_PARITY_STATUS_INTRr, NULL,
   1721         INVALIDr, NULL },
   1722     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1723 };
   1724 
   1725 STATIC _soc_trident_parity_info_t _soc_trident_pg5_parity_info[] = {
   1726     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 0,
   1727         XLP0_PERR_INTRf,
   1728         XLP0_PERR_INTRf,
   1729         INVALIDm, "XLPORT",
   1730         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1731         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1732         INVALIDr, NULL },
   1733     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 0,
   1734         XLP0_PERR_INTRf,
   1735         XLP0_PERR_INTRf,
   1736         INVALIDm, "XLPORT",
   1737         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1738         INVALIDr, NULL,
   1739         INVALIDr, NULL },
   1740     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 1,
   1741         XLP1_PERR_INTRf,
   1742         XLP1_PERR_INTRf,
   1743         INVALIDm, "XLPORT",
   1744         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1745         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1746         INVALIDr, NULL },
   1747     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 1,
   1748         XLP1_PERR_INTRf,
   1749         XLP1_PERR_INTRf,
   1750         INVALIDm, "XLPORT",
   1751         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1752         INVALIDr, NULL,
   1753         INVALIDr, NULL },
   1754     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 2,
   1755         XLP2_PERR_INTRf,
   1756         XLP2_PERR_INTRf,
   1757         INVALIDm, "XLPORT",
   1758         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1759         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1760         INVALIDr, NULL },
   1761     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 2,
   1762         XLP2_PERR_INTRf,
   1763         XLP2_PERR_INTRf,
   1764         INVALIDm, "XLPORT",
   1765         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1766         INVALIDr, NULL,
   1767         INVALIDr, NULL },
   1768     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 3,
   1769         XLP3_PERR_INTRf,
   1770         XLP3_PERR_INTRf,
   1771         INVALIDm, "XLPORT",
   1772         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1773         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1774         INVALIDr, NULL },
   1775     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 3,
   1776         XLP3_PERR_INTRf,
   1777         XLP3_PERR_INTRf,
   1778         INVALIDm, "XLPORT",
   1779         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1780         INVALIDr, NULL,
   1781         INVALIDr, NULL },
   1782     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 4,
   1783         XLP4_PERR_INTRf,
   1784         XLP4_PERR_INTRf,
   1785         INVALIDm, "XLPORT",
   1786         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1787         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1788         INVALIDr, NULL },
   1789     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 4,
   1790         XLP4_PERR_INTRf,
   1791         XLP4_PERR_INTRf,
   1792         INVALIDm, "XLPORT",
   1793         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1794         INVALIDr, NULL,
   1795         INVALIDr, NULL },
   1796     { _SOC_PARITY_TYPE_ECC, NULL, 0,
   1797         PG5_PERR_INTRf,
   1798         PG5_PERR_INTRf,
   1799         INVALIDm, "PG5 FIFO",
   1800         PORT_GROUP5_BOD_FIFO_ECC_ENABLEr, BOD_FIFO_ECC_ENABLEf,
   1801         INVALIDr, _soc_trident_pg5_fifo_intr_reg,
   1802         INVALIDr, NULL },
   1803     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1804 };
   1805 
   1806 STATIC _soc_trident_parity_info_t _soc_trident_pg4_parity_info[] = {
   1807     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 5,
   1808         XLP0_PERR_INTRf,
   1809         XLP0_PERR_INTRf,
   1810         INVALIDm, "XLPORT",
   1811         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1812         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1813         INVALIDr, NULL },
   1814     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 5,
   1815         XLP0_PERR_INTRf,
   1816         XLP0_PERR_INTRf,
   1817         INVALIDm, "XLPORT",
   1818         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1819         INVALIDr, NULL,
   1820         INVALIDr, NULL },
   1821     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 6,
   1822         XLP1_PERR_INTRf,
   1823         XLP1_PERR_INTRf,
   1824         INVALIDm, "XLPORT",
   1825         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1826         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1827         INVALIDr, NULL },
   1828     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 6,
   1829         XLP1_PERR_INTRf,
   1830         XLP1_PERR_INTRf,
   1831         INVALIDm, "XLPORT",
   1832         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1833         INVALIDr, NULL,
   1834         INVALIDr, NULL },
   1835     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 7,
   1836         XLP2_PERR_INTRf,
   1837         XLP2_PERR_INTRf,
   1838         INVALIDm, "XLPORT",
   1839         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1840         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1841         INVALIDr, NULL },
   1842     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 7,
   1843         XLP2_PERR_INTRf,
   1844         XLP2_PERR_INTRf,
   1845         INVALIDm, "XLPORT",
   1846         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1847         INVALIDr, NULL,
   1848         INVALIDr, NULL },
   1849     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport_parity_info, 8,
   1850         XLP3_PERR_INTRf,
   1851         XLP3_PERR_INTRf,
   1852         INVALIDm, "XLPORT",
   1853         XLPORT_INTR_ENABLEr, INVALIDf, /* group enable */
   1854         XLPORT_INTR_STATUSr, NULL,     /* group status */
   1855         INVALIDr, NULL },
   1856     { _SOC_PARITY_TYPE_XLPORT, _soc_trident_xlport1_parity_info, 8,
   1857         XLP3_PERR_INTRf,
   1858         XLP3_PERR_INTRf,
   1859         INVALIDm, "XLPORT",
   1860         XLPORT_ECC_CONTROLr, INVALIDf, /* group enable */
   1861         INVALIDr, NULL,
   1862         INVALIDr, NULL },
   1863     { _SOC_PARITY_TYPE_ECC, NULL, 0,
   1864         PG4_PERR_INTRf,
   1865         PG4_PERR_INTRf,
   1866         INVALIDm, "PG4 FIFO",
   1867         PORT_GROUP4_BOD_FIFO_ECC_ENABLEr, BOD_FIFO_ECC_ENABLEf,
   1868         INVALIDr, _soc_trident_pg4_fifo_intr_reg,
   1869         INVALIDr, NULL },
   1870     { _SOC_PARITY_TYPE_NONE } /* table terminator */
   1871 };
   1872 
   1873 STATIC const
   1874 _soc_trident_parity_route_block_t  _soc_trident_parity_route_blocks[] = {
   1875     { 0x00000001, /* MMU_TO_CMIC_MEMFAIL_INTR */
   1876         SOC_BLK_MMU, -1, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr,
   1877         _soc_trident_mmu_parity_info },
   1878     { 0x00000002, /* X_EP1_TO_CMIC_PERR_INTR */
   1879         SOC_BLK_EPIPE, 0, EGR_INTR0_ENABLEr, EGR_INTR0_STATUSr,
   1880         _soc_trident_ep0_parity_info },
   1881     { 0x00000004, /* Y_EP1_TO_CMIC_PERR_INTR */
   1882         SOC_BLK_EPIPE, 1, EGR_INTR0_ENABLEr, EGR_INTR0_STATUSr,
   1883         _soc_trident_ep0_parity_info },
   1884     { 0x00000008, /* X_EP2_TO_CMIC_PERR_INTR */
   1885         SOC_BLK_EPIPE, 0, EGR_INTR1_ENABLEr, EGR_INTR1_STATUSr,
   1886         _soc_trident_ep1_parity_info },
   1887     { 0x00000010, /* Y_EP2_TO_CMIC_PERR_INTR */
   1888         SOC_BLK_EPIPE, 1, EGR_INTR1_ENABLEr, EGR_INTR1_STATUSr,
   1889         _soc_trident_ep1_parity_info },
   1890     { 0x00000020, /* X_IP0_TO_CMIC_PERR_INTR */
   1891         SOC_BLK_IPIPE, 0, IP0_INTR_ENABLEr, IP0_INTR_STATUSr,
   1892         _soc_trident_ip0_parity_info },
   1893     { 0x00000040, /* Y_IP0_TO_CMIC_PERR_INTR */
   1894         SOC_BLK_IPIPE, 1, IP0_INTR_ENABLEr, IP0_INTR_STATUSr,
   1895         _soc_trident_ip0_parity_info },
   1896     { 0x00000080, /* X_IP1_TO_CMIC_PERR_INTR */
   1897         SOC_BLK_IPIPE, 0, IP1_INTR_ENABLEr, IP1_INTR_STATUSr,
   1898         _soc_trident_ip1_parity_info },
   1899     { 0x00000100, /* Y_IP1_TO_CMIC_PERR_INTR */
   1900         SOC_BLK_IPIPE, 1, IP1_INTR_ENABLEr, IP1_INTR_STATUSr,
   1901         _soc_trident_ip1_parity_info },
   1902     { 0x00000200, /* X_IP2_TO_CMIC_PERR_INTR */
   1903         SOC_BLK_IPIPE, 0, IP2_INTR_ENABLEr, IP2_INTR_STATUSr,
   1904         _soc_trident_ip2_parity_info },
   1905     { 0x00000200, /* X_IP2_TO_CMIC_PERR_INTR */
   1906         SOC_BLK_IPIPE, 0, IP2_INTR_ENABLE_2r, IP2_INTR_STATUS_2r,
   1907         _soc_trident_ip2_2_parity_info },
   1908     { 0x00000400, /* Y_IP2_TO_CMIC_PERR_INTR */
   1909         SOC_BLK_IPIPE, 1, IP2_INTR_ENABLEr, IP2_INTR_STATUSr,
   1910         _soc_trident_ip2_parity_info },
   1911     { 0x00000400, /* Y_IP2_TO_CMIC_PERR_INTR */
   1912         SOC_BLK_IPIPE, 1, IP2_INTR_ENABLE_2r, IP2_INTR_STATUS_2r,
   1913         _soc_trident_ip2_2_parity_info },
   1914     { 0x00000800, /* X_IP3_TO_CMIC_PERR_INTR */
   1915         SOC_BLK_IPIPE, 0, IP3_INTR_ENABLEr, IP3_INTR_STATUSr,
   1916         _soc_trident_ip3_parity_info },
   1917     { 0x00001000, /* Y_IP3_TO_CMIC_PERR_INTR */
   1918         SOC_BLK_IPIPE, 1, IP3_INTR_ENABLEr, IP3_INTR_STATUSr,
   1919         _soc_trident_ip3_parity_info },
   1920     { 0x00002000, /* X_IP4_TO_CMIC_PERR_INTR */
   1921         SOC_BLK_IPIPE, 0, IP4_INTR_ENABLEr, IP4_INTR_STATUSr,
   1922         _soc_trident_ip4_parity_info },
   1923     { 0x00004000, /* Y_IP4_TO_CMIC_PERR_INTR */
   1924         SOC_BLK_IPIPE, 1, IP4_INTR_ENABLEr, IP4_INTR_STATUSr,
   1925         _soc_trident_ip4_parity_info },
   1926     { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */
   1927         SOC_BLK_IPIPE, 0, IP5_INTR_ENABLEr, IP5_INTR_STATUSr,
   1928         _soc_trident_ip5_parity_info },
   1929     { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */
   1930         SOC_BLK_IPIPE, 0, IP5_INTR_ENABLE_1r, IP5_INTR_STATUS_1r,
   1931         _soc_trident_ip5_1_parity_info },
   1932     { 0x00008000, /* X_IP5_TO_CMIC_PERR_INTR */
   1933         SOC_BLK_IPIPE, 0, IP5_INTR_ENABLE_2r, IP5_INTR_STATUS_2r,
   1934         _soc_trident_ip5_2_parity_info },
   1935     { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */
   1936         SOC_BLK_IPIPE, 1, IP5_INTR_ENABLEr, IP5_INTR_STATUSr,
   1937         _soc_trident_ip5_parity_info },
   1938     { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */
   1939         SOC_BLK_IPIPE, 1, IP5_INTR_ENABLE_1r, IP5_INTR_STATUS_1r,
   1940         _soc_trident_ip5_1_parity_info },
   1941     { 0x00010000, /* Y_IP5_TO_CMIC_PERR_INTR */
   1942         SOC_BLK_IPIPE, 1, IP5_INTR_ENABLE_2r, IP5_INTR_STATUS_2r,
   1943         _soc_trident_ip5_2_parity_info },
   1944     /*  0x00020000 PCIE_REPLAY_PERR */
   1945     { 0x00040000, /* PG5_0_TO_CMIC_PERR_INTR */
   1946         SOC_BLK_PORT_GROUP5, 0, PG5_INTR_ENABLEr, PG5_INTR_STATUSr,
   1947         _soc_trident_pg5_parity_info },
   1948     { 0x00080000, /* PG5_1_TO_CMIC_PERR_INTR */
   1949         SOC_BLK_PORT_GROUP5, 1, PG5_INTR_ENABLEr, PG5_INTR_STATUSr,
   1950         _soc_trident_pg5_parity_info },
   1951     { 0x00100000, /* PG4_0_TO_CMIC_PERR_INTR */
   1952         SOC_BLK_PORT_GROUP4, 0, PG4_INTR_ENABLEr, PG4_INTR_STATUSr,
   1953         _soc_trident_pg4_parity_info },
   1954     { 0x00200000, /* PG4_1_TO_CMIC_PERR_INTR */
   1955         SOC_BLK_PORT_GROUP4, 1, PG4_INTR_ENABLEr, PG4_INTR_STATUSr,
   1956         _soc_trident_pg4_parity_info },
   1957     { 0 } /* table terminator */
   1958 };
   1959 
   1960 STATIC soc_ser_functions_t _td_ser_functions;
   1961 
   1962 STATIC void
   1963 _soc_mem_parity_info(int unit, int block_info_idx, int pipe,
   1964                      soc_field_t field_enum, uint32 *minfo)
   1965 {
   1966     *minfo = (SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP)
   1967         | ((pipe & 0xff) << SOC_ERROR_PIPE_BP)
   1968         | (field_enum & SOC_ERROR_FIELD_ENUM_MASK);
   1969 }
   1970 
   1971 #if 0
   1972 /* 
   1973  * This code can be used to spit out a C struct database of all
   1974  * reportable memory errors and their associated arg3 values.
   1975  *
   1976  * This database can be used to maintain statistics on reported memory
   1977  * errors on a per-memory basis (versus globally).
   1978  * 
   1979  * To generate a new database, set #if 1 above, and run this code
   1980  * from a diagnostic shell command.
   1981  *
   1982  * This code must remain in this file because the error reporting
   1983  * information used to generate arg3 values is local to this file.
   1984  */
   1985 void
   1986 _soc_trident_print_memories(int unit)
   1987 {
   1988     const _soc_trident_parity_route_block_t *rb;
   1989     _soc_trident_parity_info_t *mi, *mi0;
   1990     char prefix[64];
   1991     char *mn;
   1992     uint32 id;
   1993     int ecc, blk_num, blk;
   1994 
   1995     for (rb = _soc_trident_parity_route_blocks; rb->cmic_bit; rb++) {
   1996         for (mi = rb->info; mi->type != _SOC_PARITY_TYPE_NONE; mi++) {
   1997             if (mi->type != _SOC_PARITY_TYPE_GENERIC
   1998                 && mi->intr_status_reg == INVALIDr
   1999                 && !mi->intr_status_reg_list) {
   2000                 continue;
   2001             }
   2002             if (mi->type == _SOC_PARITY_TYPE_XLPORT) {
   2003                 mi0 = mi->info;
   2004             } else {
   2005                 mi0 = mi;
   2006             }
   2007             
   2008             if (mi0->mem_str) {
   2009                 mn = mi0->mem_str;
   2010             } else if (mi0->mem != INVALIDm) {
   2011                 mn = SOC_MEM_NAME(unit, mi0->mem);
   2012             } else {
   2013                 mn = SOC_FIELD_NAME(unit, mi0->group_reg_status_field);
   2014             }
   2015             
   2016             blk = rb->blocktype;
   2017             if (mi->type == _SOC_PARITY_TYPE_XLPORT) {
   2018                 blk_num = mi->id + rb->pipe * 9;
   2019                 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   2020                     if (SOC_BLOCK_INFO(unit, blk).number == blk_num) break;
   2021                 }
   2022                 sal_sprintf(prefix, "%s,XLPORT%d", mn, blk_num);
   2023                 _soc_mem_parity_info(unit, blk, rb->pipe, 
   2024                                      mi0->group_reg_status_field, &id);
   2025             } else {
   2026                 if (rb->pipe >= 0) {
   2027                     sal_sprintf(prefix, "%s,%d", mn, rb->pipe);
   2028                 } else {
   2029                     sal_sprintf(prefix, "%s", mn);
   2030                 }
   2031                 _soc_mem_parity_info(unit, rb->blocktype, rb->pipe, 
   2032                                      mi0->group_reg_status_field, &id);
   2033             }
   2034             ecc = mi0->type == _SOC_PARITY_TYPE_ECC;
   2035             LOG_CLI((BSL_META_U(unit,
   2036                                 "      {\"%s\"), %d, 0x%08x},\n", prefix, ecc, id));
   2037         }
   2038     }
   2039 }
   2040 #endif
   2041 
   2042 STATIC int
   2043 _soc_trident_parity_reg_set(int unit, int block_info_idx, int pipe,
   2044                             soc_reg_t reg, uint32 rval)
   2045 {
   2046     int rv, egress, port;
   2047 
   2048     switch (SOC_BLOCK_INFO(unit, block_info_idx).type) {
   2049     case SOC_BLK_IPIPE:
   2050         egress = 0;
   2051         port = REG_PORT_ANY;
   2052         break;
   2053     case SOC_BLK_EPIPE:
   2054         egress = 1;
   2055         port = REG_PORT_ANY;
   2056         break;
   2057     case SOC_BLK_PORT_GROUP4:
   2058     case SOC_BLK_PORT_GROUP5:
   2059         egress = -1;
   2060         port = pipe;
   2061         break;
   2062      case SOC_BLK_XLPORT:
   2063         egress = -1;
   2064         port = SOC_BLOCK_PORT(unit, block_info_idx);
   2065         break; 
   2066     default:
   2067         egress = -1;
   2068         port = REG_PORT_ANY;
   2069         break;
   2070     }
   2071 
   2072     if (egress != -1) {
   2073         SOC_IF_ERROR_RETURN(soc_trident_pipe_select(unit, egress, pipe));
   2074     }
   2075 
   2076     rv = soc_reg32_set(unit, reg, port, 0, rval);
   2077 
   2078     if (egress != -1) {
   2079         (void)soc_trident_pipe_select(unit, egress, 0);
   2080     }
   2081 
   2082     return rv;
   2083 }
   2084 
   2085 STATIC int
   2086 _soc_trident_parity_reg_get(int unit, int block_info_idx, int pipe,
   2087                             soc_reg_t reg, uint32 *rval)
   2088 {
   2089     int rv, egress, port;
   2090 
   2091     switch (SOC_BLOCK_INFO(unit, block_info_idx).type) {
   2092     case SOC_BLK_IPIPE:
   2093         egress = 0;
   2094         port = REG_PORT_ANY;
   2095         break;
   2096     case SOC_BLK_EPIPE:
   2097         egress = 1;
   2098         port = REG_PORT_ANY;
   2099         break;
   2100     case SOC_BLK_PORT_GROUP4:
   2101     case SOC_BLK_PORT_GROUP5:
   2102         egress = -1;
   2103         port = pipe;
   2104         break;
   2105      case SOC_BLK_XLPORT:
   2106         egress = -1;
   2107         port = SOC_BLOCK_PORT(unit, block_info_idx);
   2108         break;
   2109     default:
   2110         egress = -1;
   2111         port = REG_PORT_ANY;
   2112         break;
   2113     }
   2114 
   2115     if (egress != -1) {
   2116         SOC_IF_ERROR_RETURN(soc_trident_pipe_select(unit, egress, pipe));
   2117     }
   2118 
   2119     rv = soc_reg32_get(unit, reg, port, 0, rval);
   2120 
   2121     if (egress != -1) {
   2122         (void)soc_trident_pipe_select(unit, egress, 0);
   2123     }
   2124 
   2125     return rv;
   2126 }
   2127 
   2128 STATIC int
   2129 _soc_trident_parity_enable_info(int unit, int block_info_idx, int pipe,
   2130                                 soc_reg_t group_reg, uint32 *group_rval,
   2131                                 const _soc_trident_parity_info_t *info_list,
   2132                                 soc_mem_t mem, int enable);
   2133 
   2134 STATIC int
   2135 _soc_trident_parity_enable_xlport(int unit, int pipe,
   2136                                   const _soc_trident_parity_info_t *info,
   2137                                   soc_mem_t mem, int enable)
   2138 {
   2139     soc_reg_t xlport_reg;
   2140     uint32 xlport_rval;
   2141     int block_info_idx, inst_num, port;
   2142 
   2143     port = -1;
   2144     inst_num = info->id + pipe * 9;
   2145     SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) {
   2146         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   2147             port = SOC_BLOCK_PORT(unit, block_info_idx);
   2148             break;
   2149         }
   2150     }
   2151     if (port < 0) {
   2152         return SOC_E_NONE;
   2153     }
   2154 
   2155     xlport_reg = info->enable_reg;
   2156     SOC_IF_ERROR_RETURN
   2157         (soc_reg32_get(unit, xlport_reg, port, 0, &xlport_rval));
   2158 
   2159     SOC_IF_ERROR_RETURN
   2160         (_soc_trident_parity_enable_info(unit, block_info_idx, pipe,
   2161                                          xlport_reg, &xlport_rval,
   2162                                          info->info, mem, enable));
   2163 
   2164     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, xlport_reg, port, 0, xlport_rval));
   2165 
   2166     return SOC_E_NONE;
   2167 }
   2168 
   2169 STATIC int
   2170 _soc_trident_parity_enable_info(int unit, int block_info_idx, int pipe,
   2171                                 soc_reg_t group_reg, uint32 *group_rval,
   2172                                 const _soc_trident_parity_info_t *info_list,
   2173                                 soc_mem_t mem,
   2174                                 int enable)
   2175 {
   2176     const _soc_trident_parity_info_t *info;
   2177     int info_index, rv, rv1;
   2178     soc_reg_t reg;
   2179     uint32 rval;
   2180 
   2181     rv = SOC_E_NOT_FOUND;
   2182 
   2183     /* Loop through each info entry in the list */
   2184     for (info_index = 0; ; info_index++) {
   2185         info = &info_list[info_index];
   2186         if (info->type == _SOC_PARITY_TYPE_NONE) {
   2187             /* End of table */
   2188             break;
   2189         }
   2190 
   2191         if (mem != INVALIDm && info->mem != mem) {
   2192             continue;
   2193         }
   2194 
   2195         rv = SOC_E_NONE;
   2196 
   2197         /* Enable the info entry in the group register */
   2198         soc_reg_field_set(unit, group_reg, group_rval,
   2199                           info->group_reg_enable_field, enable ? 1 : 0);
   2200 
   2201         /* Handle different parity error reporting style */
   2202         switch (info->type) {
   2203         case _SOC_PARITY_TYPE_PARITY:
   2204         case _SOC_PARITY_TYPE_ECC:
   2205         case _SOC_PARITY_TYPE_HASH:
   2206         case _SOC_PARITY_TYPE_EDATABUF:
   2207         case _SOC_PARITY_TYPE_COUNTER:
   2208             reg = info->enable_reg;
   2209             if (!SOC_REG_IS_VALID(unit, reg)) {
   2210                 break;
   2211             }
   2212             SOC_IF_ERROR_RETURN
   2213                 (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg,
   2214                                              &rval));
   2215             soc_reg_field_set(unit, reg, &rval, info->enable_field,
   2216                               enable ? 1 : 0);
   2217             SOC_IF_ERROR_RETURN
   2218                 (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg,
   2219                                              rval));
   2220             break;
   2221         case _SOC_PARITY_TYPE_XLPORT:
   2222             /* One more level of report tree structure */
   2223             rv1 = _soc_trident_parity_enable_xlport(unit, pipe, info, mem,
   2224                                                     enable);
   2225             if (SOC_FAILURE(rv1) && rv1 != SOC_E_NOT_FOUND) {
   2226                 return rv;
   2227             }
   2228             break;
   2229         case _SOC_PARITY_TYPE_GENERIC:
   2230         case _SOC_PARITY_TYPE_MMU_THDO:
   2231         case _SOC_PARITY_TYPE_START_ERR:
   2232         case _SOC_PARITY_TYPE_MMU_WRED:
   2233         case _SOC_PARITY_TYPE_MMU_THDI:
   2234         case _SOC_PARITY_TYPE_MMU_MTRO:
   2235         case _SOC_PARITY_TYPE_MMU_ES:
   2236         case _SOC_PARITY_TYPE_MMU_IPMC:
   2237         case _SOC_PARITY_TYPE_MMU_VLAN:
   2238         default:
   2239             break;
   2240         } /* Handle different parity error reporting style */
   2241         if (mem != INVALIDm) {
   2242             break;
   2243         }
   2244 
   2245     } /* Loop through each info entry in the route block */
   2246 
   2247     return rv;
   2248 }
   2249 
   2250 STATIC int
   2251 _soc_trident_parity_enable_all(int unit, int enable)
   2252 {
   2253     const _soc_trident_parity_route_block_t *route_block;
   2254     int route_block_index;
   2255     uint32 rval;
   2256     uint32 cmic_rval, route_block_rval;
   2257     uint32 cmic_bit;
   2258     int block_info_idx, inst_num;
   2259     int rv;
   2260     uint16 dev_id, drv_dev_id;
   2261     uint8 rev_id, drv_rev_id;
   2262 
   2263     soc_cm_get_id(unit, &dev_id, &rev_id);
   2264     soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id);
   2265 
   2266     /* Read CMIC enable register */
   2267     /* coverity[result_independent_of_operands] */
   2268     SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, &cmic_rval));
   2269 
   2270     /* Loop through each place-and-route block entry */
   2271     for (route_block_index = 0; ; route_block_index++) {
   2272         route_block = &_soc_trident_parity_route_blocks[route_block_index];
   2273         cmic_bit = route_block->cmic_bit;
   2274         if (cmic_bit == 0) {
   2275             /* End of table */
   2276             break;
   2277         }
   2278         /* Enable the route block entry in the CMIC register */
   2279         if (enable) {
   2280             cmic_rval |= cmic_bit;
   2281         }
   2282 
   2283         if (route_block->blocktype == SOC_BLK_PORT_GROUP4 ||
   2284             route_block->blocktype == SOC_BLK_PORT_GROUP5) {
   2285             inst_num = route_block->pipe;
   2286         } else {
   2287             inst_num = 0;
   2288         }
   2289         SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) {
   2290             if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   2291                 break;
   2292             }
   2293         }
   2294 
   2295         SOC_IF_ERROR_RETURN
   2296             (_soc_trident_parity_reg_get(unit, block_info_idx,
   2297                                          route_block->pipe,
   2298                                          route_block->enable_reg,
   2299                                          &route_block_rval));
   2300 
   2301         rv = _soc_trident_parity_enable_info(unit, block_info_idx,
   2302                                              route_block->pipe,
   2303                                              route_block->enable_reg,
   2304                                              &route_block_rval,
   2305                                              route_block->info, INVALIDm,
   2306                                              enable);
   2307         if (rv == SOC_E_NOT_FOUND) {
   2308             continue;
   2309         } else if (SOC_FAILURE(rv)) {
   2310             return rv;
   2311         }
   2312 
   2313         /* Write per route block parity enable register */
   2314         SOC_IF_ERROR_RETURN
   2315             (_soc_trident_parity_reg_set(unit, block_info_idx,
   2316                                          route_block->pipe,
   2317                                          route_block->enable_reg,
   2318                                          route_block_rval));
   2319     } /* Loop through each place-and-route block entry */
   2320 
   2321     /* Write CMIC enable register */
   2322     /* coverity[result_independent_of_operands] */    
   2323     SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, cmic_rval));
   2324 
   2325     /* MMU enables */
   2326     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2327     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   2328     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2329 
   2330     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 1);
   2331     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 1);
   2332     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   2333     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2334 
   2335     SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval));
   2336 
   2337     if (!(drv_rev_id == BCM56840_A0_REV_ID && rev_id == BCM56840_A0_REV_ID)) {
   2338         /* Do not serve interrupt for Trident A0 */
   2339         soc_intr_enable(unit, IRQ_MEM_FAIL);
   2340     }
   2341 
   2342     return SOC_E_NONE;
   2343 }
   2344 
   2345 void
   2346 _soc_trident_mem_rename(soc_mem_t *memory)
   2347 {
   2348     soc_mem_t mem = *memory;
   2349     
   2350     switch(*memory) {
   2351     case MY_STATION_TCAMm:
   2352         mem = MY_STATION_TCAM_DATA_ONLYm;
   2353         break;
   2354 
   2355         /* ep0 */
   2356     case EGR_IP_TUNNEL_IPV6m:
   2357     case EGR_IP_TUNNEL_MPLSm:
   2358         mem = EGR_IP_TUNNELm;
   2359         break;
   2360     case EGR_FRAGMENT_ID_TABLE_Xm:
   2361     case EGR_FRAGMENT_ID_TABLE_Ym:
   2362         mem = EGR_FRAGMENT_ID_TABLEm;
   2363         break;
   2364     case EGR_VLAN_Xm:
   2365     case EGR_VLAN_Ym:
   2366         mem = EGR_VLANm;
   2367         break;
   2368 
   2369         /* ep1 */
   2370     case EFP_COUNTER_TABLE_Xm:
   2371     case EFP_COUNTER_TABLE_Ym:
   2372         mem = EFP_COUNTER_TABLEm;
   2373         break;
   2374     case EGR_PERQ_XMT_COUNTERS_Xm:
   2375     case EGR_PERQ_XMT_COUNTERS_Ym:
   2376         mem = EGR_PERQ_XMT_COUNTERSm;
   2377         break;
   2378     case EGR_VINTF_COUNTER_TABLE_Xm:
   2379     case EGR_VINTF_COUNTER_TABLE_Ym:
   2380         mem = EGR_VINTF_COUNTER_TABLEm;
   2381         break;
   2382     case EGR_SERVICE_COUNTER_TABLE_Xm:
   2383     case EGR_SERVICE_COUNTER_TABLE_Ym:
   2384         mem = EGR_SERVICE_COUNTER_TABLEm;
   2385         break;
   2386     case EFP_METER_TABLE_Xm:
   2387     case EFP_METER_TABLE_Ym:
   2388         mem = EFP_METER_TABLEm;
   2389         break;
   2390     case EGR_PW_INIT_COUNTERS_Xm:
   2391     case EGR_PW_INIT_COUNTERS_Ym:
   2392         mem = EGR_PW_INIT_COUNTERSm;
   2393         break;
   2394 
   2395         /* ip0 */
   2396 
   2397         /* ip1 */
   2398     case VLAN_MACm:
   2399         mem = VLAN_XLATEm;
   2400         break;
   2401     case VLAN_SUBNETm:
   2402         mem = VLAN_SUBNET_DATA_ONLYm;
   2403         break;
   2404 
   2405         /* ip2 */
   2406     case L3_DEFIPm:
   2407     case L3_DEFIP_Xm:
   2408     case L3_DEFIP_Ym:
   2409         mem = L3_DEFIP_DATA_ONLYm;
   2410         break;
   2411     case L3_DEFIP_128m:
   2412         mem = L3_DEFIP_128_DATA_ONLYm;
   2413         break;
   2414 
   2415         /* ip2_2 */
   2416 
   2417         /* ip3 */
   2418     case L2Xm:
   2419         mem = L2_ENTRY_ONLYm;
   2420         break;
   2421     case L2_USER_ENTRYm:
   2422         mem = L2_USER_ENTRY_DATA_ONLYm;
   2423         break;
   2424 
   2425         /* ip4 */
   2426     case FP_COUNTER_TABLE_Xm:
   2427     case FP_COUNTER_TABLE_Ym:
   2428         mem = FP_COUNTER_TABLEm;
   2429         break;
   2430 
   2431         /* ip5 */
   2432     case DLB_HGT_FLOWSET_PORT_Xm:
   2433     case DLB_HGT_FLOWSET_PORT_Ym:
   2434         mem = DLB_HGT_FLOWSET_PORTm;
   2435         break;
   2436 
   2437         /* ip5_1 */
   2438     case MODPORT_MAP_MIRRORm:
   2439         mem = MODPORT_MAP_M0m;
   2440         break;
   2441     case ING_PW_TERM_SEQ_NUM_Xm:
   2442     case ING_PW_TERM_SEQ_NUM_Ym:
   2443         mem = ING_PW_TERM_SEQ_NUMm;
   2444         break;
   2445     case ING_SERVICE_COUNTER_TABLE_Xm:
   2446     case ING_SERVICE_COUNTER_TABLE_Ym:
   2447         mem = ING_SERVICE_COUNTER_TABLEm;
   2448         break;
   2449     case ING_VINTF_COUNTER_TABLE_Xm:
   2450     case ING_VINTF_COUNTER_TABLE_Ym:
   2451         mem = ING_VINTF_COUNTER_TABLEm;
   2452         break;
   2453     default:
   2454         break;
   2455     }
   2456     *memory = mem;
   2457 }
   2458 
   2459 int
   2460 _soc_trident_mem_parity_control(int unit, soc_mem_t mem, int copyno,
   2461                                 int enable)
   2462 {
   2463     const _soc_trident_parity_route_block_t *route_block;
   2464     int route_block_index;
   2465     uint32 rval;
   2466     uint32 cmic_rval, route_block_rval;
   2467     uint32 cmic_bit;
   2468     int block_info_idx, inst_num;
   2469     int rv = SOC_E_NOT_FOUND;
   2470 
   2471     /* coverity[result_independent_of_operands] */
   2472     SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, &cmic_rval));
   2473     if (cmic_rval == 0) {
   2474         return SOC_E_NONE;
   2475     }
   2476 
   2477     /* Convert component/aggregate memories to the table for which
   2478      * the parity registers correspond. */
   2479     _soc_trident_mem_rename(&mem);
   2480 
   2481     /* Loop through each place-and-route block entry */
   2482     for (route_block_index = 0; ; route_block_index++) {
   2483         route_block = &_soc_trident_parity_route_blocks[route_block_index];
   2484         cmic_bit = route_block->cmic_bit;
   2485         if (cmic_bit == 0) {
   2486             /* End of table */
   2487             break;
   2488         }
   2489 
   2490         if (route_block->blocktype == SOC_BLK_PORT_GROUP4 ||
   2491             route_block->blocktype == SOC_BLK_PORT_GROUP5) {
   2492             inst_num = route_block->pipe;
   2493         } else {
   2494             inst_num = 0;
   2495         }
   2496         SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) {
   2497             if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   2498                 break;
   2499             }
   2500         }
   2501 
   2502         SOC_IF_ERROR_RETURN
   2503             (_soc_trident_parity_reg_get(unit, block_info_idx,
   2504                                          route_block->pipe,
   2505                                          route_block->enable_reg,
   2506                                          &route_block_rval));
   2507 
   2508         rv = _soc_trident_parity_enable_info(unit, block_info_idx,
   2509                                              route_block->pipe,
   2510                                              route_block->enable_reg,
   2511                                              &route_block_rval,
   2512                                              route_block->info, mem, enable);
   2513         if ((rv != SOC_E_NOT_FOUND) && (SOC_FAILURE(rv))) {
   2514             return rv;
   2515         }
   2516 
   2517         /* Write per route block parity enable register */
   2518         SOC_IF_ERROR_RETURN
   2519             (_soc_trident_parity_reg_set(unit, block_info_idx,
   2520                                          route_block->pipe,
   2521                                          route_block->enable_reg,
   2522                                          route_block_rval));
   2523         if ((rv == SOC_E_NONE) && ((route_block->pipe == 1) || 
   2524         	                         (route_block->pipe == -1))) {     
   2525             /* Both pipes have been configured, or MMU block */
   2526             break;
   2527         }
   2528     }
   2529 
   2530     if ((rv == SOC_E_NONE) &&
   2531     	  (SOC_BLOCK_TYPE(unit, SOC_MEM_BLOCK_ANY(unit, mem))) == SOC_BLK_MMU) {
   2532         /* MMU controls */
   2533         if (enable) {
   2534             SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2535             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   2536             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2537             
   2538             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 1);
   2539             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 1);
   2540             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   2541             soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   2542             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2543         } else {
   2544             SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   2545             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_CHK_ENf, 0);
   2546             soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_GEN_ENf, 0);
   2547             soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 0);
   2548             SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   2549         }
   2550     }
   2551 
   2552     return SOC_E_NONE;
   2553 }
   2554 
   2555 STATIC int
   2556 _soc_trident_mem_is_dyn(int unit, soc_mem_t mem)
   2557 {
   2558     if (SOC_MEM_FIELD_VALID(unit, mem, HITf) ||
   2559         SOC_MEM_FIELD_VALID(unit, mem, HIT0f) ||
   2560         SOC_MEM_FIELD_VALID(unit, mem, HIT_0f) ||
   2561         SOC_MEM_FIELD_VALID(unit, mem, HITDA_0f) ||
   2562         SOC_MEM_FIELD_VALID(unit, mem, HITSA_0f) ||
   2563         SOC_MEM_FIELD_VALID(unit, mem, HITSAf) ||
   2564         SOC_MEM_FIELD_VALID(unit, mem, HITDAf) ||
   2565         SOC_MEM_FIELD_VALID(unit, mem, L3_HIT_DCMf) ||
   2566         SOC_MEM_FIELD_VALID(unit, mem, L3_HIT_PMf)) {
   2567         return 1;
   2568     }
   2569     return 0;
   2570 }
   2571 
   2572 STATIC const char *nack_register_name[] = {
   2573     "EGR_VLAN_CONTROL_1",
   2574     "EGR_IPMC_CFG2"
   2575 };
   2576 
   2577 /* Registers whose parity error need to be handled by S/W */
   2578 STATIC const soc_reg_t nack_register[] = {
   2579     EGR_VLAN_CONTROL_1r,
   2580     EGR_IPMC_CFG2r
   2581 };
   2582 
   2583 /* Get the mapping reg for given reg name */
   2584 STATIC int
   2585 _soc_trident_nack_reg_get(int unit, soc_reg_t *reg, char *reg_name)
   2586 {
   2587     int rv = SOC_E_NOT_FOUND,i;
   2588 
   2589     if (reg == NULL || reg_name == NULL) {
   2590         return rv;
   2591     }
   2592 
   2593     for (i = 0; i < COUNTOF(nack_register); i++) {
   2594         if (!sal_strcmp(reg_name, nack_register_name[i])) {
   2595             *reg = nack_register[i];
   2596             rv = SOC_E_NONE;
   2597             break;
   2598         }
   2599     }
   2600     return rv;
   2601 }
   2602 
   2603 /* Check whether the reg is proper to do correction and reg_name is mapping */
   2604 STATIC int
   2605 _soc_trident_nack_reg_check(int unit, soc_reg_t reg, char *reg_name)
   2606 {
   2607     int rv = SOC_E_NOT_FOUND,i;
   2608 
   2609     if ((reg_name == NULL) || !SOC_REG_IS_VALID(unit, reg)) {
   2610         return rv;
   2611     }
   2612 
   2613     for (i = 0; i < COUNTOF(nack_register); i++) {
   2614         if ((nack_register[i] == reg) &&
   2615             !sal_strcmp(nack_register_name[i], reg_name)) {
   2616             rv = SOC_E_NONE;
   2617             break;
   2618         }
   2619     }
   2620     return rv;
   2621 }
   2622 
   2623 STATIC int 
   2624 _soc_trident_populate_ser_log(int unit, soc_reg_t parity_enable_reg,
   2625                               soc_field_t parity_enable_field, 
   2626                               soc_mem_t mem,
   2627                               soc_block_t mem_block, 
   2628                               soc_acc_type_t acc_type,
   2629                               int index,
   2630                               sal_usecs_t detect_time,
   2631                               uint32 sblk,
   2632                               uint32 address)
   2633 {
   2634     uint32 tmp_entry[SOC_MAX_MEM_WORDS]; 
   2635     int log_entry_size, id, entry_dw;
   2636     uint32 *cache;
   2637     uint8 *vmap;
   2638     soc_ser_log_tlv_memory_t log_mem;
   2639     soc_ser_log_tlv_generic_t log_generic;
   2640 
   2641     sal_memset(&log_generic, 0, sizeof(log_generic));
   2642     sal_memset(&log_mem, 0, sizeof(log_mem));
   2643 
   2644     /* 
   2645     must be large enough for at least generic and terminator, as well as the
   2646     memory type since we might decode it in soc_ser_correction. 
   2647     */
   2648     log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 +
   2649                      sizeof(soc_ser_log_tlv_generic_t) +
   2650                      sizeof(soc_ser_log_tlv_memory_t);
   2651 
   2652     if (mem == INVALIDm) {
   2653         mem = soc_addr_to_mem_extended(unit, sblk, acc_type, address);
   2654     }
   2655     /*
   2656     If we have decoded the memory we can record its contents/cache
   2657     */
   2658     if((mem != INVALIDm) &&
   2659        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != SOC_MEM_FLAG_SER_SPECIAL) &&
   2660        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) {
   2661         entry_dw = soc_mem_entry_words(unit, mem);
   2662 
   2663         /* Check to make sure this isn't a duplicate */
   2664         /* Search for a log entry with the same mem, and id with within the last 5 seconds */
   2665         if (soc_ser_log_find_recent(unit, mem, index, detect_time) > 0) {
   2666             return 0;
   2667         }
   2668 
   2669         log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2670 
   2671         cache = SOC_MEM_STATE(unit, mem).cache[mem_block];
   2672         vmap = SOC_MEM_STATE(unit, mem).vmap[mem_block];
   2673         if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2674             log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   2675         }
   2676 
   2677         /* create the entry based on determined size, save id */
   2678         id = soc_ser_log_create_entry(unit, log_entry_size);
   2679         
   2680         /* Add the memory information to the log now so we can detect duplicate errors */
   2681         log_generic.time = detect_time;
   2682         log_mem.memory = mem;
   2683         log_mem.index = index;
   2684         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_MEMORY, 
   2685             sizeof(soc_ser_log_tlv_memory_t), &log_mem);
   2686         soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_GENERIC, 
   2687             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   2688 
   2689         /* Disable Parity */
   2690         if (!_soc_trident_mem_is_dyn(unit, mem) &&
   2691             (parity_enable_reg != INVALIDr) &&
   2692             (parity_enable_field != INVALIDf)) {
   2693             if (soc_reg_field32_modify(unit, parity_enable_reg,
   2694                 REG_PORT_ANY, parity_enable_field, 0) < 0) {
   2695                 return 0;
   2696             }
   2697         }
   2698 
   2699         /*Don't need to select pipe again, because before invoking this function 
   2700                 it has already select the pipe*/
   2701         /* read the memory into a buffer */
   2702         if (acc_type == _SOC_ACC_TYPE_PIPE_Y) {
   2703             soc_mem_pipe_select_read(unit, SOC_MEM_NO_FLAGS, mem, mem_block,
   2704                                      acc_type, index, tmp_entry);
   2705         } else {
   2706             /*Enable NACK on read */
   2707              soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN,
   2708                                    mem, 0, mem_block,
   2709                                    index, tmp_entry);
   2710         }
   2711 
   2712         /* Enable Parity */
   2713         if (!_soc_trident_mem_is_dyn(unit, mem) &&
   2714             (parity_enable_reg != INVALIDr) &&
   2715             (parity_enable_field != INVALIDf)) {
   2716             if (soc_reg_field32_modify(unit, parity_enable_reg,
   2717                 REG_PORT_ANY, parity_enable_field, 1) < 0) {
   2718                 return 0;
   2719             }
   2720         }
   2721 
   2722         /* fill in the memory contents tlv */
   2723         if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS,
   2724             entry_dw*4, tmp_entry) < 0) {
   2725             return 0;
   2726         }
   2727 
   2728 
   2729         if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   2730             /* fill in the memory cache tlv */
   2731             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE,
   2732                 entry_dw*4, (cache + index*entry_dw)) < 0) {
   2733                 return 0;
   2734             }
   2735         }
   2736     } else {
   2737         id = soc_ser_log_create_entry(unit, log_entry_size);
   2738     }
   2739 
   2740     return id;
   2741 }
   2742 
   2743 static int
   2744 _soc_trident_parity_process_info(int unit, soc_block_t blocktype,
   2745                                  int block_info_idx, int pipe,
   2746                                  soc_reg_t reg, uint32 group_rval,
   2747                                  const _soc_trident_parity_info_t *info_list,
   2748                                  char *prefix_str);
   2749 
   2750 /* source: source of h/w access and error: 0=hw, 1=cpu */
   2751 STATIC int
   2752 _soc_trident_parity_process_parity(int unit, int source, int block_info_idx, 
   2753                                    int pipe, const _soc_trident_parity_info_t *info,
   2754                                    int schan, char *prefix_str, char *mem_str)
   2755 {
   2756     int at;
   2757     _soc_trident_parity_reg_t reg_entry[2], *reg_ptr;
   2758     soc_reg_t reg, nack_reg = INVALIDr;
   2759     uint32 rval, minfo;
   2760     uint32 multiple, entry_idx, idx, has_error;
   2761     char *mem_str_ptr;
   2762     _soc_ser_correct_info_t spci;
   2763 
   2764     sal_memset(&spci, 0, sizeof(spci));
   2765     if (schan) {
   2766         /* Some table does not have NACK register */
   2767         if (info->nack_status_reg == INVALIDr &&
   2768             info->nack_status_reg_list == NULL) {
   2769             return SOC_E_NONE;
   2770         }
   2771         reg_entry[0].reg = info->nack_status_reg;
   2772         reg_entry[0].mem_str = NULL;
   2773         reg_entry[1].reg = INVALIDr;
   2774         reg_ptr = reg_entry;
   2775     } else {
   2776         if (info->intr_status_reg != INVALIDr) {
   2777             reg_entry[0].reg = info->intr_status_reg;
   2778             reg_entry[0].mem_str = NULL;
   2779             reg_entry[1].reg = INVALIDr;
   2780             reg_ptr = reg_entry;
   2781         } else if (info->intr_status_reg_list != NULL) {
   2782             reg_ptr = info->intr_status_reg_list;
   2783         } else {
   2784             return SOC_E_NONE;
   2785         }
   2786     }
   2787 
   2788     (void)_soc_trident_nack_reg_get(unit, &nack_reg, info->mem_str);
   2789 
   2790     has_error = FALSE;
   2791     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2792         reg = reg_ptr[idx].reg;
   2793         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2794             reg_ptr[idx].mem_str : mem_str;
   2795         SOC_IF_ERROR_RETURN
   2796             (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg,
   2797                                          &rval));
   2798 
   2799         if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) {
   2800             has_error = TRUE;
   2801             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2802             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2803             _soc_mem_parity_info(unit, block_info_idx, pipe,
   2804                                  info->group_reg_status_field, &minfo);
   2805             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2806                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   2807                                entry_idx, minfo);
   2808             LOG_WARN(BSL_LS_SOC_SER,
   2809                       (BSL_META_U(unit,
   2810                                   "%s %s entry %d parity error\n"),
   2811                        prefix_str, mem_str_ptr, entry_idx));
   2812             if (multiple) {
   2813                 LOG_WARN(BSL_LS_SOC_SER,
   2814                           (BSL_META_U(unit,
   2815                                       "%s %s has multiple parity errors\n"),
   2816                            prefix_str, mem_str_ptr));
   2817             }
   2818             if (idx == 0 && info->mem != INVALIDm) {
   2819                 /* Enable pipe select control if needed */
   2820                 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \
   2821                       _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   2822                 if ((pipe == 1) &&  (at == _SOC_MEM_ADDR_ACC_TYPE_PIPE_SBS)) {
   2823                     soc_trident_pipe_select(unit, 
   2824                         SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   2825                         pipe);
   2826                 }
   2827                 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   2828                 if (source) {
   2829                     spci.flags |= SOC_SER_ERR_CPU;
   2830                 }
   2831                 if (multiple) {
   2832                     spci.flags |= SOC_SER_ERR_MULTI;
   2833                 }
   2834                 spci.reg = INVALIDr;
   2835                 spci.mem = info->mem;
   2836                 spci.blk_type = -1;
   2837                 spci.index = entry_idx;
   2838                 spci.acc_type = at;
   2839                 spci.pipe_num = pipe;
   2840                 spci.parity_type = info->type;
   2841                 spci.detect_time = sal_time_usecs();
   2842                 spci.log_id = _soc_trident_populate_ser_log(unit,
   2843                     info->enable_reg, info->enable_field, spci.mem,
   2844                     SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   2845                     spci.index, spci.detect_time, spci.sblk, spci.addr);
   2846                 (void)soc_ser_correction(unit, &spci);
   2847                 if (spci.log_id != 0) {
   2848                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2849                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   2850                                        spci.log_id, 0);
   2851                 }
   2852                 /* Revert pipe select control if needed */
   2853                 if ((pipe == 1) &&  (at == _SOC_MEM_ADDR_ACC_TYPE_PIPE_SBS)) {
   2854                     soc_trident_pipe_select(unit, 
   2855                         SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   2856                         0);
   2857                 }
   2858             } else if (idx == 0 && SOC_REG_IS_VALID(unit, nack_reg)) {
   2859                 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   2860                 if (source) {
   2861                     spci.flags |= SOC_SER_ERR_CPU;
   2862                 }
   2863                 if (multiple) {
   2864                     spci.flags |= SOC_SER_ERR_MULTI;
   2865                 }
   2866                 spci.reg = nack_reg;
   2867                 spci.mem = INVALIDm;
   2868                 spci.blk_type = -1;
   2869                 spci.port = entry_idx;
   2870                 spci.index = 0;
   2871                 spci.pipe_num = pipe;
   2872                 spci.parity_type = info->type;
   2873                 spci.detect_time = sal_time_usecs();
   2874                 spci.log_id = soc_ser_log_create_entry(unit,
   2875                     sizeof(soc_ser_log_tlv_generic_t) +
   2876                     sizeof(soc_ser_log_tlv_register_t) +
   2877                     sizeof(soc_ser_log_tlv_hdr_t) *3);
   2878                 (void)soc_ser_correction(unit, &spci);
   2879                 if (spci.log_id != 0) {
   2880                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   2881                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   2882                                        spci.log_id, 0);
   2883                 }
   2884             }
   2885         }
   2886 
   2887         /* Clear parity status */
   2888         SOC_IF_ERROR_RETURN
   2889             (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0));
   2890     }
   2891 
   2892     if (!has_error) {
   2893         LOG_ERROR(BSL_LS_SOC_SER,
   2894                   (BSL_META_U(unit,
   2895                               "%s %s parity hardware inconsistency\n"),
   2896                    prefix_str, mem_str));
   2897     }
   2898 
   2899     return SOC_E_NONE;
   2900 }
   2901 
   2902 STATIC int
   2903 _soc_trident_parity_process_ecc(int unit, int block_info_idx, int pipe,
   2904                                 const _soc_trident_parity_info_t *info,
   2905                                 int schan, char *prefix_str, char *mem_str)
   2906 {
   2907     int at;
   2908     _soc_trident_parity_reg_t reg_entry[2], *reg_ptr;
   2909     soc_reg_t reg;
   2910     uint32 rval, minfo;
   2911     uint32 multiple, double_bit, entry_idx, idx, has_error;
   2912     char *mem_str_ptr;
   2913     _soc_ser_correct_info_t spci;
   2914 
   2915     sal_memset(&spci, 0, sizeof(spci));
   2916 
   2917     if (schan) {
   2918         /* Some table does not have NACK register */
   2919         if (info->nack_status_reg == INVALIDr &&
   2920             info->nack_status_reg_list == NULL) {
   2921             return SOC_E_NONE;
   2922         }
   2923         reg_entry[0].reg = info->nack_status_reg;
   2924         reg_entry[0].mem_str = NULL;
   2925         reg_entry[1].reg = INVALIDr;
   2926         reg_ptr = reg_entry;
   2927     } else {
   2928         if (info->intr_status_reg != INVALIDr) {
   2929             reg_entry[0].reg = info->intr_status_reg;
   2930             reg_entry[0].mem_str = NULL;
   2931             reg_entry[1].reg = INVALIDr;
   2932             reg_ptr = reg_entry;
   2933         } else if (info->intr_status_reg_list != NULL) {
   2934             reg_ptr = info->intr_status_reg_list;
   2935         } else {
   2936             return SOC_E_NONE;
   2937         }
   2938     }
   2939 
   2940     has_error = FALSE;
   2941     for (idx = 0; reg_ptr[idx].reg != INVALIDr; idx++) {
   2942         reg = reg_ptr[idx].reg;
   2943         mem_str_ptr = reg_ptr[idx].mem_str != NULL ?
   2944             reg_ptr[idx].mem_str : mem_str;
   2945         SOC_IF_ERROR_RETURN
   2946             (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg,
   2947                                          &rval));
   2948 
   2949         if (soc_reg_field_get(unit, reg, rval, ECC_ERRf)) {
   2950             has_error = TRUE;
   2951             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   2952             double_bit = soc_reg_field_get(unit, reg, rval, DOUBLE_BIT_ERRf);
   2953             entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   2954             _soc_mem_parity_info(unit, block_info_idx, pipe,
   2955                                  info->group_reg_status_field, &minfo);
   2956             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   2957                                SOC_SWITCH_EVENT_DATA_ERROR_ECC, 
   2958                                entry_idx, minfo);
   2959             if (double_bit) {
   2960                 spci.double_bit = 1;
   2961                 LOG_WARN(BSL_LS_SOC_SER,
   2962                           (BSL_META_U(unit,
   2963                                       "%s %s entry %d double-bit ECC error\n"),
   2964                            prefix_str, mem_str_ptr, entry_idx));
   2965             } else {
   2966                 LOG_WARN(BSL_LS_SOC_SER,
   2967                           (BSL_META_U(unit,
   2968                                       "%s %s entry %d ECC error\n"),
   2969                            prefix_str, mem_str_ptr, entry_idx));
   2970             }
   2971             if (multiple) {
   2972                 LOG_WARN(BSL_LS_SOC_SER,
   2973                           (BSL_META_U(unit,
   2974                                       "%s %s has multiple ECC errors\n"),
   2975                            prefix_str, mem_str_ptr));
   2976                 spci.flags |= SOC_SER_ERR_MULTI; 
   2977             }
   2978             if (schan) {
   2979                 spci.flags |= SOC_SER_ERR_CPU;
   2980             }
   2981             if (idx == 0 && info->mem != INVALIDm) {
   2982                 /* Enable pipe select control if needed */
   2983                 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \
   2984                       _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   2985 
   2986                 if (pipe == 1) {
   2987                     soc_trident_pipe_select(unit, 
   2988                         SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   2989                         pipe);
   2990                 }
   2991                 spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   2992                 spci.reg = INVALIDr;
   2993                 spci.mem = info->mem;
   2994                 spci.blk_type = -1;
   2995                 spci.index = entry_idx;
   2996                 spci.acc_type = at;
   2997                 spci.pipe_num = pipe;
   2998                 spci.detect_time = sal_time_usecs();
   2999                 spci.parity_type = SOC_PARITY_TYPE_ECC;
   3000                 spci.log_id = _soc_trident_populate_ser_log(unit, 
   3001                     info->enable_reg, info->enable_field, info->mem,
   3002                     SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   3003                     spci.index, spci.detect_time, spci.sblk, spci.addr);
   3004                 (void)soc_ser_correction(unit, &spci);
   3005                 if (spci.log_id != 0) {
   3006                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3007                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3008                                        spci.log_id, 0);
   3009                 }
   3010                 
   3011                 if (pipe == 1) {
   3012                     soc_trident_pipe_select(unit, 
   3013                         SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   3014                         0);
   3015                 }
   3016             }
   3017         }
   3018 
   3019         /* Clear parity status */
   3020         SOC_IF_ERROR_RETURN
   3021             (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0));
   3022     }
   3023 
   3024     if (!has_error) {
   3025         LOG_ERROR(BSL_LS_SOC_SER,
   3026                   (BSL_META_U(unit,
   3027                               "%s %s ECC hardware inconsistency\n"),
   3028                    prefix_str, mem_str));
   3029     }
   3030 
   3031     return SOC_E_NONE;
   3032 }
   3033 
   3034 int
   3035 _soc_trident_l3_entry_idx_map(soc_mem_t mem, int entry_idx) 
   3036 {
   3037     int new_id = entry_idx;
   3038     
   3039     switch (mem) {
   3040         case L3_ENTRY_IPV6_UNICASTm:
   3041         case L3_ENTRY_IPV4_MULTICASTm:
   3042             new_id = entry_idx/2;
   3043             break;
   3044         case L3_ENTRY_IPV6_MULTICASTm:
   3045             new_id = entry_idx/4;
   3046             break;
   3047         default:
   3048             break;
   3049     }
   3050     return new_id;
   3051 }
   3052 
   3053 STATIC int
   3054 _soc_trident_parity_process_hash(int unit, int block_info_idx, int pipe,
   3055                                  const _soc_trident_parity_info_t *info,
   3056                                  int schan, char *prefix_str, char *mem_str)
   3057 {
   3058     _soc_trident_parity_reg_t *reg_ptr;
   3059     soc_reg_t reg;
   3060     uint32 rval, minfo;
   3061     uint32 bitmap, multiple, bucket_idx;
   3062     int bucket_size, entry_idx, idx, bank_bkt_idx, bits, has_error, at;
   3063     _soc_ser_correct_info_t spci;
   3064 
   3065     if (schan) {
   3066         reg_ptr = info->nack_status_reg_list;
   3067     } else {
   3068         reg_ptr = info->intr_status_reg_list;
   3069     }
   3070 
   3071     has_error = FALSE;
   3072     for (idx = 0; idx < 2; idx ++) {
   3073         reg = reg_ptr[idx].reg;
   3074         SOC_IF_ERROR_RETURN
   3075             (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg,
   3076                                          &rval));
   3077 
   3078         bitmap = soc_reg_field_get(unit, reg, rval, PARITY_ERR_BMf);
   3079         if (bitmap != 0) {
   3080             has_error = TRUE;
   3081             multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   3082             bucket_size = soc_reg_field_length(unit, reg, PARITY_ERR_BMf);
   3083             bucket_idx = soc_reg_field_get(unit, reg, rval, BUCKET_IDXf) * bucket_size * 2;
   3084             bank_bkt_idx = idx * bucket_size + bucket_idx;
   3085             for (bits = 0; bits < bucket_size; bits++) {
   3086                 if (bitmap & (1 << bits)) {
   3087                     entry_idx = bank_bkt_idx + bits;
   3088                     entry_idx = _soc_trident_l3_entry_idx_map(info->mem, entry_idx);
   3089                     _soc_mem_parity_info(unit, block_info_idx, pipe,
   3090                                          info->group_reg_status_field, &minfo);
   3091                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3092                                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   3093                                        entry_idx, minfo);
   3094                     if (info->mem != INVALIDm) {
   3095                         at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \
   3096                               _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   3097 
   3098                         if ((pipe ==1) && (at != _SOC_MEM_ADDR_ACC_TYPE_PIPE_X)) {
   3099                             soc_trident_pipe_select(unit, 
   3100                                 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   3101                                 pipe);
   3102                         }
   3103                         sal_memset(&spci, 0, sizeof(spci));
   3104                         if (schan) {
   3105                             spci.flags |= SOC_SER_ERR_CPU;
   3106                         }
   3107                         if (multiple) {
   3108                             spci.flags |= SOC_SER_ERR_MULTI;
   3109                         }
   3110                         LOG_WARN(BSL_LS_SOC_SER,
   3111                                   (BSL_META_U(unit,
   3112                                               "%s %s entry %d parity error\n"),
   3113                                               prefix_str, mem_str, entry_idx));
   3114                         spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   3115                         spci.reg = INVALIDr;
   3116                         spci.mem = info->mem == L2_ENTRY_ONLYm ? L2Xm : info->mem;
   3117                         spci.blk_type = -1;
   3118                         spci.index = entry_idx;
   3119                         spci.acc_type = at;
   3120                         spci.pipe_num = pipe;
   3121                         spci.detect_time = sal_time_usecs();
   3122                         spci.log_id = _soc_trident_populate_ser_log(unit,
   3123                             info->enable_reg, info->enable_field, spci.mem,
   3124                             SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   3125                             spci.index, spci.detect_time, spci.sblk, spci.addr);
   3126                         (void)soc_ser_correction(unit, &spci);
   3127                         if (spci.log_id != 0) {
   3128                             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3129                                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3130                                                spci.log_id, 0);
   3131                         }
   3132 
   3133                         if ((pipe ==1) && (at != _SOC_MEM_ADDR_ACC_TYPE_PIPE_X)) {
   3134                             soc_trident_pipe_select(unit, 
   3135                                 SOC_BLOCK_INFO(unit, block_info_idx).type == SOC_BLK_EPIPE ? 1 : 0,
   3136                                 0);
   3137                         }
   3138                     }
   3139                 }    
   3140             }        
   3141             if (multiple) {
   3142                 LOG_WARN(BSL_LS_SOC_SER,
   3143                           (BSL_META_U(unit,
   3144                                       "%s %s has multiple parity errors\n"),
   3145                            prefix_str, mem_str));
   3146             }         
   3147         }             
   3148                       
   3149         /* Clear parity status */
   3150         SOC_IF_ERROR_RETURN
   3151             (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0));
   3152     }
   3153 
   3154     if (!has_error) {
   3155         LOG_ERROR(BSL_LS_SOC_SER,
   3156                   (BSL_META_U(unit,
   3157                               "%s %s parity hardware inconsistency\n"),
   3158                    prefix_str, mem_str));
   3159     }
   3160 
   3161     return SOC_E_NONE;
   3162 }
   3163 
   3164 STATIC soc_acc_type_t
   3165 _soc_trident_pipe_to_acc_type(int pipe);
   3166 
   3167 
   3168 STATIC int
   3169 _soc_trident_parity_process_l2x(int unit, int block_info_idx, int pipe,
   3170                                  const _soc_trident_parity_info_t *info,
   3171                                  int schan, char *prefix_str, char *mem_str, uint32 address)
   3172 {
   3173     uint32 minfo;
   3174     int bucket_size, entry_idx, idx, bits, at, entry_base, bucket_boundary;
   3175     _soc_ser_correct_info_t spci;
   3176     uint32 entry[SOC_MAX_MEM_WORDS] = {0};
   3177 
   3178     /* process DA table : use original function _soc_trident_parity_process_hash()  */
   3179     SOC_IF_ERROR_RETURN(_soc_trident_parity_process_hash(unit, block_info_idx,
   3180                                                         pipe, info, schan,
   3181                                                         prefix_str, mem_str));
   3182 
   3183     /* process SA table .
   3184         For  L2_ENTRY_PARITY_STATUS_NACK_0/1 will not report SA entry_id with parity error,
   3185         caculate each entry's parity status in same bucket by sw
   3186        */
   3187     bucket_size = 4;
   3188     entry_base = address & (~SOC_MEM_INFO(unit, info->mem).index_max);
   3189     bucket_boundary = (address - entry_base) >> 3;
   3190     bucket_boundary = entry_base + (bucket_boundary << 3);
   3191 
   3192     for (idx = 0; idx < 2; idx ++) {
   3193         bucket_boundary += idx * bucket_size;
   3194 
   3195         for (bits = 0; bits < bucket_size; bits++) {
   3196             entry_idx = bucket_boundary + bits;
   3197 
   3198             sal_memset(&entry,0,sizeof(entry));
   3199 
   3200             _soc_mem_parity_info(unit, block_info_idx, pipe,
   3201                                  info->group_reg_status_field, &minfo);
   3202             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3203                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY,
   3204                                (entry_idx - entry_base), minfo);
   3205             if (info->mem != INVALIDm) {
   3206                 at = ((SOC_MEM_INFO(unit, info->mem).base & 0xE0000) >> \
   3207                       _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   3208                 sal_memset(&spci, 0, sizeof(spci));
   3209                 if (schan) {
   3210                     spci.flags |= SOC_SER_ERR_CPU;
   3211                 }
   3212                 LOG_WARN(BSL_LS_SOC_SER,
   3213                           (BSL_META_U(unit,
   3214                                       "%s %s entry 0x%x parity error\n"),
   3215                                       prefix_str, mem_str, (entry_idx - entry_base)));
   3216                 spci.flags |= SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   3217                 spci.reg = INVALIDr;
   3218                 spci.mem = info->mem == L2_ENTRY_ONLYm ? L2Xm : info->mem;
   3219                 spci.blk_type = -1;
   3220                 spci.index = entry_idx - entry_base;
   3221                 spci.acc_type = at;
   3222                 spci.pipe_num = 0;
   3223                 spci.detect_time = sal_time_usecs();
   3224                 spci.log_id = _soc_trident_populate_ser_log(unit,
   3225                     info->enable_reg, info->enable_field, spci.mem,
   3226                     SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   3227                     spci.index, spci.detect_time, spci.sblk, spci.addr);
   3228                 (void)soc_ser_correction(unit, &spci);
   3229                 if (spci.log_id != 0) {
   3230                     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3231                                        SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3232                                        spci.log_id, 0);
   3233                 }
   3234             }
   3235         }
   3236 
   3237     }
   3238 
   3239     return SOC_E_NONE;
   3240 }
   3241 
   3242 
   3243 STATIC int
   3244 _soc_trident_parity_process_edatabuf(int unit, int block_info_idx, int pipe,
   3245                                      const _soc_trident_parity_info_t *info,
   3246                                      int schan, char *prefix_str,
   3247                                      char *mem_str)
   3248 {
   3249     soc_reg_t reg;
   3250     uint32 rval, minfo;
   3251     uint32 double_bit = 0, multiple = 0;
   3252     soc_ser_log_tlv_generic_t log_generic;
   3253     int log_id;
   3254 
   3255     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3256 
   3257     if (schan) {
   3258         /* Some table may not have NACK status register */
   3259         if (info->nack_status_reg == INVALIDr) {
   3260             return SOC_E_NONE;
   3261         }
   3262         reg = info->nack_status_reg;
   3263     } else {
   3264         reg = info->intr_status_reg;
   3265     }
   3266 
   3267     SOC_IF_ERROR_RETURN
   3268         (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, &rval));
   3269 
   3270     if (soc_reg_field_get(unit, reg, rval, ECC_ERR_MGRPf)) {
   3271         double_bit = soc_reg_field_get(unit, reg, rval, ECC_ERR_2B_MGRPf);
   3272         multiple = soc_reg_field_get(unit, reg, rval, ECC_MULTI_MGRPf);
   3273         _soc_mem_parity_info(unit, block_info_idx, pipe,
   3274                              info->group_reg_status_field, &minfo);
   3275         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3276                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0, 
   3277                            minfo);
   3278         if (double_bit) {
   3279             LOG_WARN(BSL_LS_SOC_SER,
   3280                       (BSL_META_U(unit,
   3281                                   "%s %s double-bit ECC error\n"),
   3282                        prefix_str, mem_str));
   3283         } else {
   3284             LOG_WARN(BSL_LS_SOC_SER,
   3285                       (BSL_META_U(unit,
   3286                                   "%s %s ECC error\n"),
   3287                        prefix_str, mem_str));
   3288         }
   3289         if (multiple) {
   3290             LOG_WARN(BSL_LS_SOC_SER,
   3291                       (BSL_META_U(unit,
   3292                                   "%s %s has multiple ECC errors\n"),
   3293                        prefix_str, mem_str));
   3294         }
   3295     } else {
   3296         LOG_ERROR(BSL_LS_SOC_SER,
   3297                   (BSL_META_U(unit,
   3298                               "%s %s ECC hardware inconsistency\n"),
   3299                    prefix_str, mem_str));
   3300     }
   3301 
   3302     if (multiple) {
   3303         log_generic.flags |= SOC_SER_LOG_FLAG_MULTIBIT;
   3304     }
   3305     if (double_bit) {
   3306         log_generic.flags |= SOC_SER_LOG_FLAG_DOUBLEBIT;
   3307     }
   3308     if (schan) {
   3309         log_generic.flags |= SOC_SER_LOG_FLAG_ERR_SRC;
   3310     }
   3311     log_generic.time = sal_time_usecs();
   3312     log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3313     log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3314     log_generic.parity_type = info->type;
   3315 
   3316     log_id = soc_ser_log_create_entry(unit, 
   3317         sizeof(soc_ser_log_tlv_generic_t) +
   3318         sizeof(soc_ser_log_tlv_hdr_t) *2);
   3319 
   3320     soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 
   3321         sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3322     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3323                        SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3324     /* Clear parity status */
   3325     SOC_IF_ERROR_RETURN
   3326         (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0));
   3327 
   3328     return SOC_E_NONE;
   3329 }
   3330 
   3331 typedef struct _soc_trident_parity_counter_info_s {
   3332     soc_reg_t               counter_reg;
   3333     soc_reg_t               status_reg[2];
   3334 } _soc_trident_parity_counter_info_t;
   3335 
   3336 STATIC _soc_trident_parity_counter_info_t soc_trident_trill_niv_counter_parity_info[] = {
   3337     { ING_TRILL_RX_PKTSr,
   3338       { TRILL_RX_PKTS_PARITY_STATUS_NACKr,
   3339         TRILL_RX_PKTS_PARITY_STATUS_INTRr}
   3340     },
   3341     { ING_TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDEDr,
   3342       { TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr,
   3343         TRILL_RX_ACCESS_PORT_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr}
   3344     },
   3345     { ING_TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDEDr,
   3346       { TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_NACKr,
   3347         TRILL_RX_NETWORK_PORT_NON_TRILL_PKTS_DISCARDED_PARITY_STATUS_INTRr}
   3348     },
   3349 
   3350     { ING_NIV_RX_FRAMES_ERROR_DROPr,
   3351       { NIV_ERROR_DROP_PARITY_STATUS_NACKr,
   3352         NIV_ERROR_DROP_PARITY_STATUS_INTRr}
   3353     },
   3354     { ING_NIV_RX_FRAMES_FORWARDING_DROPr,
   3355       { NIV_FORWARDING_DROP_PARITY_STATUS_NACKr,
   3356         NIV_FORWARDING_DROP_PARITY_STATUS_INTRr}
   3357     },
   3358     { ING_NIV_RX_FRAMES_VLAN_TAGGEDr,
   3359       { NIV_VLAN_TAGGED_PARITY_STATUS_NACKr,
   3360         NIV_VLAN_TAGGED_PARITY_STATUS_INTRr}
   3361     },
   3362 
   3363     { INVALIDr },
   3364 };
   3365 
   3366 STATIC int
   3367 _soc_trident_trill_niv_counter_find(int schan, soc_reg_t status_reg, soc_reg_t * p_reg)
   3368 {
   3369     uint16 i = 0;
   3370     uint16 found = 0;
   3371     uint16 reg_select = schan ? 0 : 1;
   3372 
   3373     for( ; soc_trident_trill_niv_counter_parity_info[i].counter_reg!= INVALIDr; i++ ) {
   3374         if (soc_trident_trill_niv_counter_parity_info[i].status_reg[reg_select]
   3375             == status_reg) {
   3376             found = 1;
   3377             break;
   3378         }
   3379     }
   3380 
   3381     if (found) {
   3382         *p_reg = soc_trident_trill_niv_counter_parity_info[i].counter_reg;
   3383     }
   3384 
   3385     return found;
   3386 }
   3387 
   3388 
   3389 static int _stat_error_fixed[SOC_MAX_NUM_DEVICES];
   3390 
   3391 STATIC int
   3392 _soc_trident_parity_process_counter(int unit, soc_block_t blocktype, 
   3393                                     int block_info_idx, int pipe,
   3394                                     const _soc_trident_parity_info_t *info,
   3395                                     int schan, char *prefix_str, char *mem_str)
   3396 {
   3397     soc_cmap_t *cmap;
   3398     soc_reg_t reg;
   3399     soc_reg_t counter_reg = INVALIDr;
   3400     uint32 rval, minfo;
   3401     uint32 multiple, counter_idx, port_idx, entry_idx;
   3402     char *counter_name;
   3403     _soc_ser_correct_info_t spci;
   3404     int trill_niv_counter_found = 0;
   3405     sal_memset(&spci, 0, sizeof(spci));
   3406 
   3407     if (schan) {
   3408         reg = info->nack_status_reg;
   3409     } else {
   3410         reg = info->intr_status_reg;
   3411     }
   3412     SOC_IF_ERROR_RETURN
   3413         (_soc_trident_parity_reg_get(unit, block_info_idx, pipe, reg, &rval));
   3414 
   3415     trill_niv_counter_found = _soc_trident_trill_niv_counter_find(schan, reg, &counter_reg);
   3416 
   3417     if (soc_reg_field_get(unit, reg, rval, PARITY_ERRf)) {
   3418         multiple = soc_reg_field_get(unit, reg, rval, MULTIPLE_ERRf);
   3419         entry_idx = soc_reg_field_get(unit, reg, rval, ENTRY_IDXf);
   3420         if (trill_niv_counter_found) {
   3421             port_idx = entry_idx;
   3422         } else {
   3423             counter_idx = soc_reg_field_get(unit, reg, rval, COUNTER_IDXf);
   3424             port_idx = soc_reg_field_get(unit, reg, rval, PORT_IDXf);
   3425 
   3426             /* TDBGC starts at index 0x20 of counter DMA table */
   3427             if (info->group_reg_status_field == EGR_STATS_COUNTER_TABLE_PAR_ERRf) {
   3428                 counter_idx += 0x20;
   3429             }
   3430             cmap = soc_port_cmap_get(unit, port_idx);
   3431             counter_reg = cmap->cmap_base[counter_idx].reg;
   3432         }
   3433 
   3434         if (SOC_REG_IS_VALID(unit, counter_reg)) {
   3435             _soc_mem_parity_info(unit, block_info_idx, pipe,
   3436                                  info->group_reg_status_field, &minfo);
   3437             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3438                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 
   3439                                entry_idx, minfo);
   3440             counter_name = SOC_REG_NAME(unit, counter_reg);
   3441             LOG_WARN(BSL_LS_SOC_SER,
   3442                       (BSL_META_U(unit,
   3443                                   "%s %s port %d %s entry %d parity error\n"),
   3444                        prefix_str, mem_str, port_idx, counter_name,
   3445                        entry_idx));
   3446             if (schan) {
   3447                 spci.flags |= SOC_SER_ERR_CPU;
   3448             }
   3449             if (multiple) {
   3450                 spci.flags |= SOC_SER_ERR_MULTI;
   3451             }
   3452             spci.flags |= SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   3453             spci.mem = INVALIDm;
   3454             spci.port = port_idx;
   3455             spci.index = 0;
   3456             spci.pipe_num = pipe;
   3457             spci.reg = counter_reg;
   3458             spci.blk_type = blocktype;
   3459             spci.detect_time = sal_time_usecs();
   3460             spci.parity_type = info->type;
   3461             spci.log_id = soc_ser_log_create_entry(unit, 
   3462                 sizeof(soc_ser_log_tlv_generic_t) +
   3463                 sizeof(soc_ser_log_tlv_register_t) +
   3464                 sizeof(soc_ser_log_tlv_hdr_t) *3);
   3465             (void)soc_ser_correction(unit, &spci);    
   3466             if (spci.log_id != 0) {
   3467                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3468                                    SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3469                                    spci.log_id, 0);
   3470             }
   3471             if (multiple) {
   3472                 LOG_WARN(BSL_LS_SOC_SER,
   3473                           (BSL_META_U(unit,
   3474                                       "%s %s has multiple parity errors\n"),
   3475                            prefix_str, mem_str));
   3476             }
   3477             _stat_error_fixed[unit]++;
   3478         } else {
   3479             LOG_ERROR(BSL_LS_SOC_SER,
   3480                       (BSL_META_U(unit,
   3481                                   "%s %s parity hardware inconsistency\n"),
   3482                        prefix_str, mem_str));
   3483         }
   3484     } else {
   3485         if (!schan) {
   3486             LOG_ERROR(BSL_LS_SOC_SER,
   3487                       (BSL_META_U(unit,
   3488                                   "%s %s parity hardware inconsistency\n"),
   3489                        prefix_str, mem_str));
   3490         }
   3491     }
   3492 
   3493     /* Clear parity status */
   3494     SOC_IF_ERROR_RETURN
   3495         (_soc_trident_parity_reg_set(unit, block_info_idx, pipe, reg, 0));
   3496 
   3497     return SOC_E_NONE;
   3498 }
   3499 
   3500 STATIC int
   3501 _soc_trident_parity_mmu_clear(int unit, soc_field_t status_field);
   3502 
   3503 STATIC int
   3504 _soc_trident_parity_process_mmu_thdo(int unit, int block_info_idx,
   3505                                      const _soc_trident_parity_info_t *info,
   3506                                      char *prefix_str)
   3507 {
   3508     uint64 rval64;
   3509     uint32 entry_idx, rval_hi, rval_lo, minfo;
   3510     int i, size;
   3511     _soc_ser_correct_info_t spci;
   3512 
   3513     static const _soc_trident_parity_mmu_bit_t thdo[] = {
   3514         /* { 0, MMU_THDO_QREDRST_EX_1m }, */
   3515         /* { 1, MMU_THDO_QYELRST_EX_1m }, */
   3516         /* { 4, MMU_THDO_QDRPRST_EX_1m }, */
   3517         { 6, THDO_OFFSET_EX_1Bm },
   3518         { 7, THDO_OFFSET_EX_1Am },
   3519         { 8, THDO_CONFIG_EX_1Bm },
   3520         { 9, THDO_CONFIG_EX_1Am },
   3521         /* { 14, MMU_THDO_QREDRST_EX_0m }, */
   3522         /* { 15, MMU_THDO_QYELRST_EX_0m }, */
   3523         /* { 18, MMU_THDO_QDRPRST_EX_0m }, */
   3524         { 20, THDO_OFFSET_EX_0Bm },
   3525         { 21, THDO_OFFSET_EX_0Am },
   3526         { 22, THDO_CONFIG_EX_0Bm },
   3527         { 23, THDO_CONFIG_EX_0Am },
   3528         /* { 28, MMU_THDO_QREDRST_1m }, */
   3529         /* { 29, MMU_THDO_QYELRST_1m }, */
   3530         /* { 30, MMU_THDO_QDRPRST_1m }, */
   3531         { 31, THDO_OFFSET_1Bm },
   3532         { 32, THDO_OFFSET_1Am },
   3533         { 33, THDO_CONFIG_1Bm },
   3534         { 34, THDO_CONFIG_1Am },
   3535         /* { 35, MMU_THDO_QREDRST_0m }, */
   3536         /* { 36, MMU_THDO_QYELRST_0m }, */
   3537         /* { 37, MMU_THDO_QDRPRST_0m }, */
   3538         { 38, THDO_OFFSET_0Bm },
   3539         { 39, THDO_OFFSET_0Am },
   3540         { 40, THDO_CONFIG_0Bm },
   3541         { 41, THDO_CONFIG_0Am }
   3542     };
   3543 
   3544     sal_memset(&spci, 0, sizeof(spci));
   3545     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   3546     spci.reg = INVALIDr;
   3547     spci.blk_type = SOC_BLK_MMU;
   3548 
   3549     SOC_IF_ERROR_RETURN(READ_THDO_PARITY_ERROR_STATUS_64r(unit, &rval64));
   3550     rval_hi = COMPILER_64_HI(rval64);
   3551     rval_lo = COMPILER_64_LO(rval64);
   3552 
   3553     SOC_IF_ERROR_RETURN(READ_THDO_PARITY_ERROR_ADDRESSr(unit, &entry_idx));
   3554 
   3555     size = COUNTOF(thdo);
   3556     for (i = 0; i < size; i++) {
   3557         if (thdo[i].bit_pos < 32) {
   3558             if (!(rval_lo & (1 << thdo[i].bit_pos))) {
   3559                 continue;
   3560             }
   3561         } else {
   3562             if (!(rval_hi & (1 << (thdo[i].bit_pos - 32)))) {
   3563                 continue;
   3564             }
   3565         }
   3566         spci.mem = thdo[i].mem;
   3567         spci.index = entry_idx;
   3568         _soc_mem_parity_info(unit, block_info_idx, 0,
   3569                              info->group_reg_status_field, &minfo);
   3570         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3571                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0,
   3572                            minfo);
   3573         spci.detect_time = sal_time_usecs();
   3574         spci.parity_type = info->type;
   3575         spci.log_id = _soc_trident_populate_ser_log(unit,
   3576             info->enable_reg, info->enable_field, spci.mem,
   3577             SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   3578             spci.index, spci.detect_time, spci.sblk, spci.addr);
   3579 
   3580         (void)soc_ser_correction(unit, &spci);
   3581         if (spci.log_id != 0) {
   3582             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3583                                SOC_SWITCH_EVENT_DATA_ERROR_LOG,
   3584                                spci.log_id, 0);
   3585         }
   3586 
   3587         LOG_WARN(BSL_LS_SOC_SER,
   3588                   (BSL_META_U(unit,
   3589                               "%s %s entry %d parity error\n"), prefix_str,
   3590                               SOC_MEM_NAME(unit, thdo[i].mem), entry_idx));
   3591     }
   3592 
   3593     /* Clear parity error status */
   3594     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   3595 
   3596     return SOC_E_NONE;
   3597 }
   3598 
   3599 STATIC int
   3600 _soc_trident_parity_process_start_err(int unit, int block_info_idx,
   3601                                       const _soc_trident_parity_info_t *info,
   3602                                       char *prefix_str)
   3603 {
   3604     soc_info_t *si;
   3605     uint64 rval64;
   3606     uint32 pbmp_31_0, pbmp_63_32, pbmp_65_64;
   3607     soc_pbmp_t pbmp;
   3608     uint32 minfo;
   3609     int port, mmu_port, phy_port;
   3610     soc_ser_log_tlv_generic_t log_generic;
   3611     int log_id;
   3612 
   3613     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   3614 
   3615     si = &SOC_INFO(unit);
   3616 
   3617     /* mmu port 32-0 */
   3618     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR0_64r(unit, &rval64));
   3619     pbmp_31_0 = COMPILER_64_LO(rval64);
   3620     pbmp_63_32 = COMPILER_64_HI(rval64);
   3621     /* mmu port 65-33 */
   3622     SOC_IF_ERROR_RETURN(READ_START_BY_START_ERROR1_64r(unit, &rval64));
   3623     pbmp_63_32 |= COMPILER_64_LO(rval64) << 1;
   3624     pbmp_65_64 = (COMPILER_64_HI(rval64) << 1) |
   3625         (COMPILER_64_LO(rval64) >> 31);
   3626     SOC_PBMP_CLEAR(pbmp);
   3627     SOC_PBMP_WORD_SET(pbmp, 0, pbmp_31_0);
   3628     SOC_PBMP_WORD_SET(pbmp, 1, pbmp_63_32);
   3629     SOC_PBMP_WORD_SET(pbmp, 2, pbmp_65_64);
   3630 
   3631     SOC_PBMP_ITER(pbmp, mmu_port) {
   3632         phy_port = si->port_m2p_mapping[mmu_port];
   3633         port = si->port_p2l_mapping[phy_port];
   3634         _soc_mem_parity_info(unit, block_info_idx, 0,
   3635                              info->group_reg_status_field, &minfo);
   3636         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3637                            SOC_SWITCH_EVENT_DATA_ERROR_UNSPECIFIED, 0,
   3638                            minfo);
   3639 
   3640         log_generic.time = sal_time_usecs();
   3641         log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   3642         log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   3643         log_generic.parity_type = info->type;
   3644 
   3645         log_id = soc_ser_log_create_entry(unit, 
   3646             sizeof(soc_ser_log_tlv_generic_t) +
   3647             sizeof(soc_ser_log_tlv_hdr_t) *2);
   3648 
   3649         soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 
   3650             sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   3651         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   3652                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   3653 
   3654         LOG_WARN(BSL_LS_SOC_SER,
   3655                   (BSL_META_U(unit,
   3656                               "%s port %d start error detected\n"), prefix_str,
   3657                               port));
   3658     }
   3659 
   3660     /* Clear parity status */
   3661     COMPILER_64_ZERO(rval64);
   3662     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR0_64r(unit, rval64));
   3663     SOC_IF_ERROR_RETURN(WRITE_START_BY_START_ERROR1_64r(unit, rval64));
   3664 
   3665     return SOC_E_NONE;
   3666 }
   3667 
   3668 STATIC int
   3669 _soc_trident_parity_mmu_clear(int unit, soc_field_t status_field)
   3670 {
   3671     uint32 rval;
   3672     
   3673     /* Clear parity error status */
   3674     SOC_IF_ERROR_RETURN
   3675         (READ_MEM_FAIL_INT_STATr(unit, &rval));
   3676     soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0);
   3677     SOC_IF_ERROR_RETURN
   3678         (WRITE_MEM_FAIL_INT_STATr(unit, rval));
   3679     
   3680     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   3681     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   3682     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   3683     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   3684     soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   3685     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   3686     return SOC_E_NONE;
   3687 }
   3688 
   3689 int
   3690 _soc_trident_parity_generic_clear(int unit, soc_block_t blocktype, int pipe,
   3691                                soc_reg_t group_reg, const _soc_trident_parity_info_t *info,
   3692                                char *prefix_str, char *mem_str)
   3693 {
   3694     uint32 rval;
   3695     soc_field_t group_field = info->group_reg_status_field;
   3696 
   3697     /* Clear parity error status */
   3698     if (blocktype == SOC_BLK_MMU) {
   3699         SOC_IF_ERROR_RETURN
   3700             (soc_reg32_get(unit, group_reg, REG_PORT_ANY, 0,  &rval));
   3701     
   3702         soc_reg_field_set(unit, group_reg, &rval, group_field, 0);
   3703     
   3704         SOC_IF_ERROR_RETURN
   3705             (soc_reg32_set(unit, group_reg, REG_PORT_ANY, 0, rval));
   3706     
   3707         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   3708         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1);
   3709         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   3710         SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   3711         soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0);
   3712         SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   3713 
   3714         LOG_INFO(BSL_LS_SOC_SER,
   3715                   (BSL_META_U(unit,
   3716                               "%s %s asserted, status register %s, field %s\n"),
   3717                   prefix_str, mem_str, SOC_REG_NAME(unit, group_reg), 
   3718                   SOC_FIELD_NAME(unit, group_field)));
   3719         return SOC_E_NONE;
   3720     } else {
   3721         LOG_ERROR(BSL_LS_SOC_SER,
   3722                   (BSL_META_U(unit,
   3723                               "%s %s asserted\n"),
   3724                   prefix_str, mem_str));
   3725         /* need to add new way to clear parity status */
   3726         return SOC_E_NONE;
   3727     }
   3728 }
   3729 
   3730 STATIC int
   3731 _soc_trident_parity_process_mmu_wred(int unit, int block_info_idx,
   3732                                      const _soc_trident_parity_info_t *info,
   3733                                      char *prefix_str)
   3734 {
   3735     int i = 0;
   3736     int at = -1;
   3737     uint8 found = 0;
   3738     uint32 value = 0;
   3739     uint32 minfo, rval, rval_bitmap, log;
   3740     soc_mem_t mem = INVALIDm;
   3741     soc_reg_t clear_reg = INVALIDr;
   3742     _soc_ser_correct_info_t spci;
   3743     soc_info_t *si = &SOC_INFO(unit);
   3744 
   3745     SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_BITMAPr(unit, &rval_bitmap));
   3746     LOG_VERBOSE(BSL_LS_SOC_SER,
   3747                 (BSL_META_U(unit,
   3748                             "wred bitmap: 0x%08x\n"), rval_bitmap));
   3749 
   3750     SOC_IF_ERROR_RETURN(READ_WRED_PARITY_ERROR_INFOr(unit, &rval));
   3751     LOG_VERBOSE(BSL_LS_SOC_SER,
   3752                 (BSL_META_U(unit,
   3753                             "wred info: 0x%08x\n"), rval));
   3754     log = rval;
   3755 
   3756     for (i = 0; i < 12; i++) {
   3757         value = rval_bitmap & 1 << i;
   3758         switch(value) {
   3759             case 0x1:
   3760             case 0x2:
   3761                 mem = INVALIDm;
   3762                 found = 1;
   3763                 break;
   3764             case 0x4:
   3765                 mem = MMU_WRED_DROP_CURVE_PROFILE_0m;
   3766                 found = 1;
   3767                 break;
   3768             case 0x8:
   3769                 mem = MMU_WRED_DROP_CURVE_PROFILE_1m;
   3770                 found = 1;
   3771                 break;
   3772             case 0x10:
   3773                 mem = MMU_WRED_DROP_CURVE_PROFILE_2m;
   3774                 found = 1;
   3775                 break;
   3776             case 0x20:
   3777                 mem = MMU_WRED_DROP_CURVE_PROFILE_3m;
   3778                 found = 1;
   3779                 break;
   3780             case 0x40:
   3781                 mem = MMU_WRED_DROP_CURVE_PROFILE_4m;
   3782                 found = 1;
   3783                 break;
   3784             case 0x80:
   3785                 mem = MMU_WRED_DROP_CURVE_PROFILE_5m;
   3786                 found = 1;
   3787                 break;
   3788             case 0x100:
   3789                 mem = MMU_WRED_DROP_THD_UC_ENQ0m;
   3790                 found = 1;
   3791                 break;
   3792             case 0x200:
   3793                 mem = MMU_WRED_DROP_THD_UC_ENQ1m;
   3794                 found = 1;
   3795                 break;
   3796             case 0x400:
   3797                 mem = MMU_WRED_DROP_THD_UC_DEQ0m;
   3798                 found = 1;
   3799                 break;
   3800             case 0x800:
   3801                 mem = MMU_WRED_DROP_THD_UC_DEQ1m;
   3802                 found = 1;
   3803                 break;
   3804             default:
   3805                 found = 0;
   3806                 break;
   3807         }
   3808 
   3809         if (found == 0) {
   3810             continue;
   3811         }
   3812 
   3813         sal_memset(&spci, 0, sizeof(spci));
   3814 
   3815         if (mem == INVALIDm) {
   3816             spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   3817             spci.mem = INVALIDm;
   3818 
   3819             rval = rval & 0xfff;
   3820             if ((rval & 0xff0) == 0x540) {
   3821                 spci.port = REG_PORT_ANY;
   3822                 spci.index = rval & 0xf;
   3823                 spci.reg = GLOBAL_SP_WRED_CONFIGr;
   3824                 clear_reg = GLOBAL_SP_WRED_AVG_QSIZEr;
   3825             } else if (((rval & 0xf00) == 0x200) || ((rval & 0xf00) == 0x300)) {
   3826                 spci.reg = WRED_CONFIGr;
   3827                 clear_reg = WRED_AVG_QSIZEr;
   3828                 rval -= 0x200;
   3829                 if (rval < 0x8) {
   3830                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[64]];
   3831                     spci.index = rval;
   3832                 } else if (rval >= 0x108 && rval <= 0x10f) {
   3833                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[65]];
   3834                     spci.index = rval - 0x108;
   3835                 } else {
   3836                     if (rval < 0x108) {
   3837                         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/8]];
   3838                         spci.index = rval % 8;
   3839                     } else {
   3840                         rval -= 0x110;
   3841                         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/8 + 34]];
   3842                         spci.index = rval % 8;
   3843                     }
   3844                 }
   3845             } else if ((rval & 0xf00) == 0x400) {
   3846                 spci.reg = PORT_SP_WRED_CONFIGr;
   3847                 clear_reg = PORT_SP_WRED_AVG_QSIZEr;
   3848                 rval -= 0x400;
   3849                 if (rval < 0x4) {
   3850                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[64]];
   3851                     spci.index = rval;
   3852                 } else if (rval >= 0x84 && rval <= 0x87) {
   3853                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[65]];
   3854                     spci.index = rval - 0x84;
   3855                 } else {
   3856                     if (rval < 0x84) {
   3857                         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/4]];
   3858                         spci.index = rval % 4;
   3859                     } else {
   3860                         rval -= 0x88;
   3861                         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[rval/4 + 34]];
   3862                         spci.index = rval % 4;
   3863                     }
   3864                 }
   3865             } else if ((rval < 0x200) || ((rval & 0xf00) == 0x500)) {
   3866                 spci.reg = DMVOQ_WRED_CONFIGr;
   3867                 clear_reg = VOQ_WRED_AVG_QSIZEr;
   3868                 if (rval < 0x200) {
   3869                     spci.port = rval/0x40 + 1;
   3870                     if (spci.port > 4) {
   3871                         spci.port += 29;
   3872                     }
   3873                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[spci.port]];
   3874                     spci.index = rval % 0x40;
   3875                 } else {
   3876                     rval -= 0x500;
   3877                     spci.port = rval/8 + 1;
   3878                     if (spci.port > 4) {
   3879                         spci.port += 29;
   3880                     }
   3881                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[spci.port]];
   3882                     spci.index = (rval % 8) + 64;
   3883                 }
   3884             } else {
   3885                 return SOC_E_INTERNAL;
   3886             }
   3887             _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo);
   3888             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3889                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, log, minfo);
   3890                                        
   3891             spci.blk_type = SOC_BLK_MMU;
   3892             LOG_WARN(BSL_LS_SOC_SER,
   3893                       (BSL_META_U(unit,
   3894                                   "%s %s port %d index %d parity error\n"), prefix_str,
   3895                                   SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   3896             (void)soc_ser_correction(unit, &spci);
   3897             
   3898             spci.reg = clear_reg;
   3899             LOG_WARN(BSL_LS_SOC_SER,
   3900                       (BSL_META_U(unit,
   3901                                   "%s %s port %d index %d parity error\n"), prefix_str,
   3902                                   SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   3903 
   3904             spci.detect_time = sal_time_usecs();
   3905             spci.parity_type = info->type;
   3906             spci.log_id = soc_ser_log_create_entry(unit, 
   3907                 sizeof(soc_ser_log_tlv_generic_t) +
   3908                 sizeof(soc_ser_log_tlv_register_t) +
   3909                 sizeof(soc_ser_log_tlv_hdr_t) *3);
   3910             (void)soc_ser_correction(unit, &spci);
   3911         } else {
   3912             at = ((SOC_MEM_INFO(unit, mem).base & 0xE0000) >> \
   3913                   _SOC_MEM_ADDR_ACC_TYPE_SHIFT);
   3914 
   3915             spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN;
   3916             spci.reg = INVALIDr;
   3917             spci.mem = mem;
   3918             spci.blk_type = -1;
   3919             spci.index = rval;
   3920             spci.acc_type = at;
   3921             spci.pipe_num = -1;
   3922             spci.parity_type = info->type;
   3923             spci.detect_time = sal_time_usecs();
   3924             spci.log_id = soc_ser_log_create_entry(unit, 
   3925                 sizeof(soc_ser_log_tlv_generic_t) +
   3926                 sizeof(soc_ser_log_tlv_register_t) +
   3927                 sizeof(soc_ser_log_tlv_hdr_t) *3);
   3928             (void)soc_ser_correction(unit, &spci);
   3929         }
   3930         if (spci.log_id != 0) {
   3931             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3932                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3933                                spci.log_id, 0);
   3934         }
   3935     }
   3936 
   3937     /* Clear parity error status */
   3938     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   3939     return SOC_E_NONE;
   3940 }
   3941 
   3942 STATIC int
   3943 _soc_trident_parity_process_mmu_thdi(int unit, int block_info_idx,
   3944                                      const _soc_trident_parity_info_t *info,
   3945                                      char *prefix_str)
   3946 {
   3947     uint64 rval64;
   3948     uint32 rval, addr, minfo;
   3949     soc_info_t *si = &SOC_INFO(unit);
   3950     _soc_ser_correct_info_t spci;
   3951     
   3952     sal_memset(&spci, 0, sizeof(spci));
   3953     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   3954     spci.mem = INVALIDm;
   3955     spci.blk_type = SOC_BLK_MMU;
   3956     SOC_IF_ERROR_RETURN(READ_PARITY_ERROR_STATUS_0r(unit, &rval64));
   3957     rval = COMPILER_64_LO(rval64);
   3958     if (rval) {
   3959         LOG_VERBOSE(BSL_LS_SOC_SER,
   3960                     (BSL_META_U(unit,
   3961                                 "thdi pipe 0 status: 0x%08x\n"), rval));
   3962         if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_HITf)) {
   3963             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_ADDRf);
   3964             spci.reg = PG_RESET_FLOOR_CELLr;
   3965         } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_HITf)) {
   3966             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_ADDRf);
   3967             spci.reg = PG_RESET_OFFSET_CELLr;
   3968         } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_HITf)) {
   3969             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_ADDRf);
   3970             spci.reg = PG_SHARED_LIMIT_CELLr;
   3971         } else {
   3972             return SOC_E_INTERNAL;
   3973         }
   3974         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]];
   3975         spci.index = addr%8;        
   3976         _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo);
   3977 
   3978         spci.detect_time = sal_time_usecs();
   3979         spci.parity_type = info->type;
   3980         spci.log_id = soc_ser_log_create_entry(unit, 
   3981             sizeof(soc_ser_log_tlv_generic_t) +
   3982             sizeof(soc_ser_log_tlv_register_t) +
   3983             sizeof(soc_ser_log_tlv_hdr_t) *3);
   3984         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3985                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo);
   3986         LOG_WARN(BSL_LS_SOC_SER,
   3987                   (BSL_META_U(unit,
   3988                               "%s %s port %d index %d parity error\n"), prefix_str,
   3989                               SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   3990         (void)soc_ser_correction(unit, &spci);
   3991         if (spci.log_id != 0) {
   3992             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   3993                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   3994                                spci.log_id, 0);
   3995         }
   3996     }
   3997 
   3998     SOC_IF_ERROR_RETURN(READ_PARITY_ERROR_STATUS_1r(unit, &rval64));
   3999     rval = COMPILER_64_LO(rval64);
   4000     if (rval) {
   4001         LOG_VERBOSE(BSL_LS_SOC_SER,
   4002                     (BSL_META_U(unit,
   4003                                 "thdi pipe 1 status: 0x%08x\n"), rval));
   4004         if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_HITf)) {
   4005             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_FLOOR_ADDRf);
   4006             spci.reg = PG_RESET_FLOOR_CELLr;
   4007         } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_HITf)) {
   4008             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, RESET_OFFSET_ADDRf);
   4009             spci.reg = PG_RESET_OFFSET_CELLr;
   4010         } else if (soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_HITf)) {
   4011             addr = soc_reg_field_get(unit, PARITY_ERROR_STATUS_0r, rval, SHARED_LIMIT_ADDRf);
   4012             spci.reg = PG_SHARED_LIMIT_CELLr;
   4013         } else {
   4014             return SOC_E_INTERNAL;
   4015         }
   4016         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]];
   4017         spci.index = addr%8;        
   4018         _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo);
   4019 
   4020         spci.detect_time = sal_time_usecs();
   4021         spci.parity_type = info->type;
   4022         spci.log_id = soc_ser_log_create_entry(unit, 
   4023             sizeof(soc_ser_log_tlv_generic_t) +
   4024             sizeof(soc_ser_log_tlv_register_t) +
   4025             sizeof(soc_ser_log_tlv_hdr_t) *3);
   4026 
   4027         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4028                            SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo);
   4029         LOG_WARN(BSL_LS_SOC_SER,
   4030                   (BSL_META_U(unit,
   4031                               "%s %s port %d index %d parity error\n"), prefix_str,
   4032                               SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   4033         (void)soc_ser_correction(unit, &spci);
   4034         if (spci.log_id != 0) {
   4035             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4036                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4037                                spci.log_id, 0);
   4038         }
   4039     }
   4040     /* Clear parity error status */
   4041     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4042     return SOC_E_NONE;
   4043 }
   4044 
   4045 STATIC void
   4046 __soc_trident_parity_process_mmu_mtro(int unit, int block_info_idx, 
   4047                                       const _soc_trident_parity_info_t *info,
   4048                                       _soc_ser_correct_info_t spci, uint32 addr,
   4049                                       char *prefix_str)
   4050 {
   4051     uint32 minfo;
   4052     
   4053     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo);
   4054     LOG_WARN(BSL_LS_SOC_SER,
   4055               (BSL_META_U(unit,
   4056                           "%s %s port %d index %d parity error\n"), prefix_str,
   4057                           SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   4058     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4059                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, minfo);
   4060     spci.detect_time = sal_time_usecs();
   4061     spci.parity_type = info->type;
   4062     spci.log_id = soc_ser_log_create_entry(unit, 
   4063         sizeof(soc_ser_log_tlv_generic_t) +
   4064         sizeof(soc_ser_log_tlv_register_t) +
   4065         sizeof(soc_ser_log_tlv_hdr_t) *3);
   4066     (void)soc_ser_correction(unit, &spci);
   4067     if (spci.log_id != 0) {
   4068         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4069                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4070                            spci.log_id, 0);
   4071     }
   4072 }
   4073 
   4074 STATIC int
   4075 _soc_trident_parity_process_mmu_mtro(int unit, int block_info_idx,
   4076                                      const _soc_trident_parity_info_t *info,
   4077                                      char *prefix_str)
   4078 {
   4079     uint32 val, addr;
   4080     soc_info_t *si = &SOC_INFO(unit);
   4081     _soc_ser_correct_info_t spci;
   4082     
   4083     sal_memset(&spci, 0, sizeof(spci));
   4084     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   4085     spci.mem = INVALIDm;
   4086     spci.blk_type = SOC_BLK_MMU;
   4087     
   4088     SOC_IF_ERROR_RETURN(READ_EGRSHAPEPARITYERRORPTRr(unit, &addr));
   4089     LOG_VERBOSE(BSL_LS_SOC_SER,
   4090                 (BSL_META_U(unit,
   4091                             "MTRO addr: %d\n"), addr));
   4092     
   4093     /* Disable parity */
   4094     SOC_IF_ERROR_RETURN
   4095         (READ_MISCCONFIGr(unit, &val));
   4096     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0);
   4097     SOC_IF_ERROR_RETURN
   4098         (WRITE_MISCCONFIGr(unit, val));
   4099     
   4100     if (addr < 48) { /* Xpipe first port */
   4101         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[0]];
   4102         spci.index = addr;
   4103         spci.reg = MINBUCKETCONFIG_64r;
   4104         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4105                                               addr, prefix_str);
   4106         spci.reg = MAXBUCKETCONFIG_64r;
   4107         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4108                                               addr, prefix_str);
   4109         spci.reg = MINBUCKETr;
   4110         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4111                                               addr, prefix_str);
   4112         spci.reg = MAXBUCKETr;
   4113         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4114                                               addr, prefix_str);
   4115         if (addr < 5) { /* Ypipe first port */
   4116             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[0 + 33]];
   4117             spci.reg = MINBUCKETCONFIG_64r;
   4118             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4119                                                   addr, prefix_str);
   4120             spci.reg = MAXBUCKETCONFIG_64r;
   4121             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4122                                                   addr, prefix_str);
   4123             spci.reg = MINBUCKETr;
   4124             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4125                                                   addr, prefix_str);
   4126             spci.reg = MAXBUCKETr;
   4127             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4128                                                   addr, prefix_str);
   4129         }
   4130     } else {
   4131         if (addr < 364) {
   4132             val = addr;
   4133             val -= 48;
   4134             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/79 + 1]];
   4135             spci.index = val%79;
   4136             spci.reg = MINBUCKETCONFIG_64r;
   4137             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4138                                                   addr, prefix_str);
   4139             spci.reg = MAXBUCKETCONFIG_64r;
   4140             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4141                                                   addr, prefix_str);
   4142             spci.reg = MINBUCKETr;
   4143             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4144                                                   addr, prefix_str);
   4145             spci.reg = MAXBUCKETr;
   4146             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4147                                                   addr, prefix_str);
   4148         } else if (addr <= 393 || addr >= 396) { /* skip hole */
   4149             val = addr;
   4150             if (addr > 393) { /* re-align */
   4151                 val -= 2;
   4152             }
   4153             val -= 364;
   4154             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/15 + 5]];
   4155             spci.index = val%15;
   4156             spci.reg = MINBUCKETCONFIG_64r;
   4157             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4158                                                   addr, prefix_str);
   4159             spci.reg = MAXBUCKETCONFIG_64r;
   4160             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4161                                                   addr, prefix_str);
   4162             spci.reg = MINBUCKETr;
   4163             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4164                                                   addr, prefix_str);
   4165             spci.reg = MAXBUCKETr;
   4166             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4167                                                   addr, prefix_str);
   4168         }
   4169         if (addr < 321) {
   4170             val = addr;
   4171             val -= 5;
   4172             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/79 + 34]];
   4173             spci.index = val%79;
   4174             spci.reg = MINBUCKETCONFIG_64r;
   4175             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4176                                                   addr, prefix_str);
   4177             spci.reg = MAXBUCKETCONFIG_64r;
   4178             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4179                                                   addr, prefix_str);
   4180             spci.reg = MINBUCKETr;
   4181             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4182                                                   addr, prefix_str);
   4183             spci.reg = MAXBUCKETr;
   4184             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4185                                                   addr, prefix_str);
   4186         } else if (addr <= 350 || addr >= 396) { /* skip hole */
   4187             val = addr;
   4188             if (addr > 350) {
   4189                 val -= 45; /* re-align */
   4190             }
   4191             val -= 321;
   4192             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/15 + 38]];
   4193             spci.index = val%15;
   4194             spci.reg = MINBUCKETCONFIG_64r;
   4195             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4196                                                   addr, prefix_str);
   4197             spci.reg = MAXBUCKETCONFIG_64r;
   4198             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4199                                                   addr, prefix_str);
   4200             spci.reg = MINBUCKETr;
   4201             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4202                                                   addr, prefix_str);
   4203             spci.reg = MAXBUCKETr;
   4204             __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4205                                                   addr, prefix_str);
   4206         }
   4207     }
   4208     if (addr <= 131) { /* S2, S3 */
   4209         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/4]];
   4210         spci.index = addr%4;
   4211         spci.reg = S2_MINBUCKETCONFIG_64r;
   4212         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4213                                               addr, prefix_str);
   4214         spci.reg = S2_MAXBUCKETCONFIG_64r;
   4215         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4216                                               addr, prefix_str);
   4217         spci.reg = S3_MINBUCKETCONFIG_64r;
   4218         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4219                                               addr, prefix_str);
   4220         spci.reg = S3_MAXBUCKETCONFIG_64r;
   4221         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4222                                               addr, prefix_str);
   4223         spci.reg = S2_MINBUCKETr;
   4224         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4225                                               addr, prefix_str);
   4226         spci.reg = S2_MAXBUCKETr;
   4227         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4228                                               addr, prefix_str);
   4229         spci.reg = S3_MINBUCKETr;
   4230         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4231                                               addr, prefix_str);
   4232         spci.reg = S3_MAXBUCKETr;
   4233         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4234                                               addr, prefix_str);
   4235 
   4236         spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/4 + 33]];
   4237         spci.reg = S2_MINBUCKETCONFIG_64r;
   4238         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4239                                               addr, prefix_str);
   4240         spci.reg = S2_MAXBUCKETCONFIG_64r;
   4241         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4242                                               addr, prefix_str);
   4243         spci.reg = S3_MINBUCKETCONFIG_64r;
   4244         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4245                                               addr, prefix_str);
   4246         spci.reg = S3_MAXBUCKETCONFIG_64r;
   4247         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4248                                               addr, prefix_str);
   4249         spci.reg = S2_MINBUCKETr;
   4250         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4251                                               addr, prefix_str);
   4252         spci.reg = S2_MAXBUCKETr;
   4253         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4254                                               addr, prefix_str);
   4255         spci.reg = S3_MINBUCKETr;
   4256         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4257                                               addr, prefix_str);
   4258         spci.reg = S3_MAXBUCKETr;
   4259         __soc_trident_parity_process_mmu_mtro(unit, block_info_idx, info, spci,
   4260                                               addr, prefix_str);
   4261     }
   4262     /* Clear parity error status */
   4263     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4264 
   4265     /* Enable parity */
   4266     SOC_IF_ERROR_RETURN
   4267         (READ_MISCCONFIGr(unit, &val));
   4268     soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1);
   4269     SOC_IF_ERROR_RETURN
   4270         (WRITE_MISCCONFIGr(unit, val));
   4271     return SOC_E_NONE;
   4272 }
   4273 
   4274 STATIC void
   4275 __soc_trident_parity_process_mmu_es(int unit, int block_info_idx, 
   4276                                     const _soc_trident_parity_info_t *info,
   4277                                     _soc_ser_correct_info_t spci, uint32 addr,
   4278                                     char *prefix_str)
   4279 {
   4280     uint32 minfo;
   4281     
   4282     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field, &minfo);
   4283     LOG_WARN(BSL_LS_SOC_SER,
   4284               (BSL_META_U(unit,
   4285                           "%s %s port %d index %d parity error\n"), prefix_str,
   4286                           SOC_REG_NAME(unit, spci.reg), spci.port, spci.index));
   4287     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4288                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, addr, minfo);
   4289     
   4290     spci.detect_time = sal_time_usecs();
   4291     spci.parity_type = info->type;
   4292     spci.log_id = soc_ser_log_create_entry(unit, 
   4293         sizeof(soc_ser_log_tlv_generic_t) +
   4294         sizeof(soc_ser_log_tlv_register_t) +
   4295         sizeof(soc_ser_log_tlv_hdr_t) *3);
   4296     (void)soc_ser_correction(unit, &spci);
   4297     if (spci.log_id != 0) {
   4298         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4299                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4300                            spci.log_id, 0);
   4301     }
   4302 }
   4303 
   4304 STATIC int
   4305 _soc_trident_parity_process_mmu_es(int unit, int block_info_idx,
   4306                                    const _soc_trident_parity_info_t *info,
   4307                                    char *prefix_str)
   4308 {
   4309     uint32 val, addr = 0;
   4310     uint64 rval64;
   4311     soc_info_t *si = &SOC_INFO(unit);
   4312     _soc_ser_correct_info_t spci;
   4313     
   4314     sal_memset(&spci, 0, sizeof(spci));
   4315     spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN;
   4316     spci.mem = INVALIDm;
   4317     spci.blk_type = SOC_BLK_MMU;
   4318     
   4319     SOC_IF_ERROR_RETURN(READ_ES_S2_MEMORY_PARITY_STATUS_0r(unit, &rval64));
   4320     if (!COMPILER_64_IS_ZERO(rval64)) {
   4321         LOG_VERBOSE(BSL_LS_SOC_SER,
   4322                     (BSL_META_U(unit,
   4323                                 "ES S2 pipe 0 status: 0x%02x%08x\n"),
   4324                                 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)));
   4325         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4326                                   CREDIT_SHAPE_BUS_HITf)) {
   4327             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4328                                          CREDIT_SHAPE_BUS_ADDRESSf);
   4329             spci.reg = S2_WERRCOUNTr;
   4330             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]];
   4331             spci.index = addr%12;
   4332             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4333                                                 addr, prefix_str);
   4334         }
   4335         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4336                                   CREDIT_CELL_XMIT_BUS_HITf)) {
   4337             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4338                                          CREDIT_CELL_XMIT_BUS_ADDRESSf);
   4339             spci.reg = S2_WERRCOUNTr;
   4340             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]];
   4341             spci.index = addr%12;
   4342             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4343                                                 addr, prefix_str);
   4344         }
   4345         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4346                                   WEIGHT_SHAPE_BUS_HITf)) {
   4347             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4348                                          WEIGHT_SHAPE_BUS_ADDRESSf);
   4349             spci.reg = S2_COSWEIGHTSr;
   4350             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]];
   4351             spci.index = addr%12;
   4352             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4353                                                 addr, prefix_str);
   4354         }
   4355         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4356                                   WEIGHT_CELL_XMIT_BUS_HITf)) {
   4357             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_0r, rval64,
   4358                                          WEIGHT_CELL_XMIT_BUS_ADDRESSf);
   4359             spci.reg = S2_COSWEIGHTSr;
   4360             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12]];
   4361             spci.index = addr%12;
   4362             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4363                                                 addr, prefix_str);
   4364         }
   4365     }
   4366     SOC_IF_ERROR_RETURN(READ_ES_S2_MEMORY_PARITY_STATUS_1r(unit, &rval64));
   4367     if (!COMPILER_64_IS_ZERO(rval64)) {
   4368         LOG_VERBOSE(BSL_LS_SOC_SER,
   4369                     (BSL_META_U(unit,
   4370                                 "ES S2 pipe 1 status: 0x%02x%08x\n"),
   4371                                 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)));
   4372         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4373                                   CREDIT_SHAPE_BUS_HITf)) {
   4374             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4375                                          CREDIT_SHAPE_BUS_ADDRESSf);
   4376             spci.reg = S2_WERRCOUNTr;
   4377             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]];
   4378             spci.index = addr%12;
   4379             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4380                                                 addr, prefix_str);
   4381         }
   4382         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4383                                   CREDIT_CELL_XMIT_BUS_HITf)) {
   4384             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4385                                          CREDIT_CELL_XMIT_BUS_ADDRESSf);
   4386             spci.reg = S2_WERRCOUNTr;
   4387             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]];
   4388             spci.index = addr%12;
   4389             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4390                                                 addr, prefix_str);
   4391         }
   4392         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4393                                   WEIGHT_SHAPE_BUS_HITf)) {
   4394             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4395                                          WEIGHT_SHAPE_BUS_ADDRESSf);
   4396             spci.reg = S2_COSWEIGHTSr;
   4397             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]];
   4398             spci.index = addr%12;
   4399             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4400                                                 addr, prefix_str);
   4401         }
   4402         if (soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4403                                   WEIGHT_CELL_XMIT_BUS_HITf)) {
   4404             addr = soc_reg64_field32_get(unit, ES_S2_MEMORY_PARITY_STATUS_1r, rval64,
   4405                                          WEIGHT_CELL_XMIT_BUS_ADDRESSf);
   4406             spci.reg = S2_COSWEIGHTSr;
   4407             spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/12 + 33]];
   4408             spci.index = addr%12;
   4409             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4410                                                 addr, prefix_str);
   4411         }
   4412     }
   4413     SOC_IF_ERROR_RETURN(READ_ES_S3_MEMORY_PARITY_STATUS_0r(unit, &rval64));
   4414     if (!COMPILER_64_IS_ZERO(rval64)) {
   4415         LOG_VERBOSE(BSL_LS_SOC_SER,
   4416                     (BSL_META_U(unit,
   4417                                 "ES S3 pipe 0 status: 0x%04x%08x\n"),
   4418                                 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)));
   4419         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4420                                   CREDIT_SHAPE_BUS_HITf)) {
   4421             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4422                                          CREDIT_SHAPE_BUS_ADDRESSf);
   4423             if (addr > 7 && addr < 296) {
   4424                 val = addr-8;
   4425                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]];
   4426                 spci.index = val%72;
   4427             } else {
   4428                 if (addr > 295) {
   4429                     val = addr - 296;
   4430                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]];
   4431                     spci.index = val%8;
   4432                 } else {
   4433                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]];
   4434                     spci.index = addr%8;
   4435                 }
   4436             }
   4437             spci.reg = S3_WERRCOUNTr;
   4438             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4439                                                 addr, prefix_str);
   4440         }
   4441         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4442                                   CREDIT_CELL_XMIT_BUS_HITf)) {
   4443             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4444                                          CREDIT_CELL_XMIT_BUS_ADDRESSf);
   4445             if (addr > 7 && addr < 296) {
   4446                 val = addr - 8;
   4447                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]];
   4448                 spci.index = val%72;
   4449             } else {
   4450                 if (addr > 295) {
   4451                     val = addr - 296;
   4452                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]];
   4453                     spci.index = val%8;
   4454                 } else {
   4455                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]];
   4456                     spci.index = addr%8;
   4457                 }
   4458             }
   4459             spci.reg = S3_WERRCOUNTr;
   4460             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4461                                                 addr, prefix_str);
   4462         }
   4463         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4464                                   WEIGHT_SHAPE_BUS_HITf)) {
   4465             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4466                                          WEIGHT_SHAPE_BUS_ADDRESSf);
   4467             if (addr > 7 && addr < 296) {
   4468                 val = addr - 8;
   4469                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]];
   4470                 spci.index = val%72;
   4471             } else {
   4472                 if (addr > 295) {
   4473                     val = addr - 296;
   4474                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]];
   4475                     spci.index = val%8;
   4476                 } else {
   4477                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]];
   4478                     spci.index = addr%8;
   4479                 }
   4480             }
   4481             spci.reg = S3_COSWEIGHTSr;
   4482             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4483                                                 addr, prefix_str);
   4484         }
   4485         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4486                                   WEIGHT_CELL_XMIT_BUS_HITf)) {
   4487             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_0r, rval64,
   4488                                          WEIGHT_CELL_XMIT_BUS_ADDRESSf);
   4489             if (addr > 7 && addr < 296) {
   4490                 val = addr - 8;
   4491                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 1]];
   4492                 spci.index = val%72;
   4493             } else {
   4494                 if (addr > 295) {
   4495                     val = addr - 296;
   4496                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 5]];
   4497                     spci.index = val%8;
   4498                 } else {
   4499                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8]];
   4500                     spci.index = addr%8;
   4501                 }
   4502             }
   4503             spci.reg = S3_COSWEIGHTSr;
   4504             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4505                                                 addr, prefix_str);
   4506         }
   4507     }
   4508     SOC_IF_ERROR_RETURN(READ_ES_S3_MEMORY_PARITY_STATUS_1r(unit, &rval64));
   4509     if (!COMPILER_64_IS_ZERO(rval64)) {
   4510         LOG_VERBOSE(BSL_LS_SOC_SER,
   4511                     (BSL_META_U(unit,
   4512                                 "ES S3 pipe 1 status: 0x%04x%08x\n"),
   4513                                 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)));
   4514         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4515                                   CREDIT_SHAPE_BUS_HITf)) {
   4516             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4517                                          CREDIT_SHAPE_BUS_ADDRESSf);
   4518             if (addr > 7 && addr < 296) {
   4519                 val = addr - 8;
   4520                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]];
   4521                 spci.index = val%72;
   4522             } else {
   4523                 if (addr > 295) {
   4524                     val = addr - 296;
   4525                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]];
   4526                     spci.index = val%8;
   4527                 } else {
   4528                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]];
   4529                     spci.index = addr%8;
   4530                 }
   4531             }
   4532             spci.reg = S3_WERRCOUNTr;
   4533             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4534                                                 addr, prefix_str);
   4535         }
   4536         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4537                                   CREDIT_CELL_XMIT_BUS_HITf)) {
   4538             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4539                                          CREDIT_CELL_XMIT_BUS_ADDRESSf);
   4540             if (addr > 7 && addr < 296) {
   4541                 val = addr - 8;
   4542                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]];
   4543                 spci.index = val%72;
   4544             } else {
   4545                 if (addr > 295) {
   4546                     val = addr - 296;
   4547                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]];
   4548                     spci.index = val%8;
   4549                 } else {
   4550                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]];
   4551                     spci.index = addr%8;
   4552                 }
   4553             }
   4554             spci.reg = S3_WERRCOUNTr;
   4555             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4556                                                 addr, prefix_str);
   4557         }
   4558         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4559                                   WEIGHT_SHAPE_BUS_HITf)) {
   4560             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4561                                          WEIGHT_SHAPE_BUS_ADDRESSf);
   4562             if (addr > 7 && addr < 296) {
   4563                 val = addr - 8;
   4564                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]];
   4565                 spci.index = val%72;
   4566             } else {
   4567                 if (addr > 295) {
   4568                     val = addr - 296;
   4569                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]];
   4570                     spci.index = val%8;
   4571                 } else {
   4572                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]];
   4573                     spci.index = addr%8;
   4574                 }
   4575             }
   4576             spci.reg = S3_COSWEIGHTSr;
   4577             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4578                                                 addr, prefix_str);
   4579         }
   4580         if (soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4581                                   WEIGHT_CELL_XMIT_BUS_HITf)) {
   4582             addr = soc_reg64_field32_get(unit, ES_S3_MEMORY_PARITY_STATUS_1r, rval64,
   4583                                          WEIGHT_CELL_XMIT_BUS_ADDRESSf);
   4584             if (addr > 7 && addr < 296) {
   4585                 val = addr - 8;
   4586                 spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/72 + 34]];
   4587                 spci.index = val%72;
   4588             } else {
   4589                 if (addr > 295) {
   4590                     val = addr - 296;
   4591                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[val/8 + 38]];
   4592                     spci.index = val%8;
   4593                 } else {
   4594                     spci.port = si->port_p2l_mapping[si->port_m2p_mapping[addr/8 + 33]];
   4595                     spci.index = addr%8;
   4596                 }
   4597             }
   4598             spci.reg = S3_COSWEIGHTSr;
   4599             __soc_trident_parity_process_mmu_es(unit, block_info_idx, info, spci,
   4600                                                 addr, prefix_str);
   4601         }
   4602     }
   4603     
   4604     /* Clear parity error status */
   4605     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4606     return SOC_E_NONE;
   4607 }
   4608 
   4609 STATIC int
   4610 _soc_trident_parity_process_mmu_ipmc(int unit, int block_info_idx,
   4611                                      const _soc_trident_parity_info_t *info,
   4612                                      char *prefix_str)
   4613 {
   4614 #define _SOC_TD_MMU_IPMC_GROUP_MAX     17
   4615 #define _SOC_TD_MMU_IPMC_SUB_GROUP_MAX  4
   4616     static soc_mem_t ipmc_mems[_SOC_TD_MMU_IPMC_GROUP_MAX]
   4617                               [_SOC_TD_MMU_IPMC_SUB_GROUP_MAX] = {
   4618         { MMU_IPMC_GROUP_TBL1m,  MMU_IPMC_GROUP_TBL5m, 
   4619           MMU_IPMC_GROUP_TBL9m,  MMU_IPMC_GROUP_TBL13m },
   4620         { MMU_IPMC_GROUP_TBL2m,  MMU_IPMC_GROUP_TBL6m,
   4621           MMU_IPMC_GROUP_TBL10m, MMU_IPMC_GROUP_TBL14m },
   4622         { MMU_IPMC_GROUP_TBL3m,  MMU_IPMC_GROUP_TBL7m,
   4623           MMU_IPMC_GROUP_TBL11m, MMU_IPMC_GROUP_TBL15m },
   4624         { MMU_IPMC_GROUP_TBL4m,  MMU_IPMC_GROUP_TBL8m,
   4625           MMU_IPMC_GROUP_TBL12m, MMU_IPMC_GROUP_TBL16m },
   4626         { MMU_IPMC_GROUP_TBL17m, MMU_IPMC_GROUP_TBL21m,
   4627           MMU_IPMC_GROUP_TBL25m, MMU_IPMC_GROUP_TBL29m },
   4628         { MMU_IPMC_GROUP_TBL18m, MMU_IPMC_GROUP_TBL22m,
   4629           MMU_IPMC_GROUP_TBL26m, MMU_IPMC_GROUP_TBL30m },
   4630         { MMU_IPMC_GROUP_TBL19m, MMU_IPMC_GROUP_TBL23m,
   4631           MMU_IPMC_GROUP_TBL27m, MMU_IPMC_GROUP_TBL31m },
   4632         { MMU_IPMC_GROUP_TBL20m, MMU_IPMC_GROUP_TBL24m,
   4633           MMU_IPMC_GROUP_TBL28m, MMU_IPMC_GROUP_TBL32m },
   4634         { MMU_IPMC_GROUP_TBL34m, MMU_IPMC_GROUP_TBL38m,
   4635           MMU_IPMC_GROUP_TBL42m, MMU_IPMC_GROUP_TBL46m },
   4636         { MMU_IPMC_GROUP_TBL35m, MMU_IPMC_GROUP_TBL39m,
   4637           MMU_IPMC_GROUP_TBL43m, MMU_IPMC_GROUP_TBL47m },
   4638         { MMU_IPMC_GROUP_TBL36m, MMU_IPMC_GROUP_TBL40m,
   4639           MMU_IPMC_GROUP_TBL44m, MMU_IPMC_GROUP_TBL48m },
   4640         { MMU_IPMC_GROUP_TBL37m, MMU_IPMC_GROUP_TBL41m,
   4641           MMU_IPMC_GROUP_TBL45m, MMU_IPMC_GROUP_TBL49m },
   4642         { MMU_IPMC_GROUP_TBL50m, MMU_IPMC_GROUP_TBL54m,
   4643           MMU_IPMC_GROUP_TBL58m, MMU_IPMC_GROUP_TBL62m },
   4644         { MMU_IPMC_GROUP_TBL51m, MMU_IPMC_GROUP_TBL55m,
   4645           MMU_IPMC_GROUP_TBL59m, MMU_IPMC_GROUP_TBL63m },
   4646         { MMU_IPMC_GROUP_TBL52m, MMU_IPMC_GROUP_TBL56m,
   4647           MMU_IPMC_GROUP_TBL60m, MMU_IPMC_GROUP_TBL64m },
   4648         { MMU_IPMC_GROUP_TBL53m, MMU_IPMC_GROUP_TBL57m,
   4649           MMU_IPMC_GROUP_TBL61m, MMU_IPMC_GROUP_TBL65m },
   4650         { MMU_IPMC_GROUP_TBL33m, INVALIDm, 
   4651           INVALIDm, INVALIDm },
   4652     };
   4653     uint32 rval, minfo;
   4654     uint32 grp, sub_grp, index;
   4655     _soc_ser_correct_info_t spci;
   4656     
   4657     sal_memset(&spci, 0, sizeof(spci));
   4658     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   4659     spci.reg = INVALIDr;
   4660     spci.blk_type = SOC_BLK_MMU;
   4661     
   4662     SOC_IF_ERROR_RETURN(READ_MCQ_GRPTBLERRPTRr(unit, &rval));
   4663     grp = soc_reg_field_get(unit, MCQ_GRPTBLERRPTRr, rval, GRPTBLERRORINSTANCEf);
   4664     sub_grp = grp & 0x3;
   4665     grp = grp >> 2;
   4666     index = soc_reg_field_get(unit, MCQ_GRPTBLERRPTRr, rval, GRPTBLERRORPOINTERf);
   4667     if (grp >= _SOC_TD_MMU_IPMC_GROUP_MAX || 
   4668         sub_grp >= _SOC_TD_MMU_IPMC_SUB_GROUP_MAX ||        
   4669         index > soc_mem_index_max(unit, ipmc_mems[0][0])) {
   4670         return SOC_E_INTERNAL;
   4671     }
   4672     if (INVALIDm == ipmc_mems[grp][sub_grp]) {
   4673         return SOC_E_INTERNAL;
   4674     }
   4675     spci.mem = ipmc_mems[grp][sub_grp];
   4676     spci.index = index;
   4677     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field,
   4678                          &minfo);
   4679     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4680                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo);
   4681     LOG_WARN(BSL_LS_SOC_SER,
   4682               (BSL_META_U(unit,
   4683                           "%s %s index %d parity error\n"), prefix_str,
   4684                           SOC_MEM_NAME(unit, spci.mem), spci.index));
   4685     spci.detect_time = sal_time_usecs();
   4686     spci.parity_type = info->type;
   4687     spci.log_id = _soc_trident_populate_ser_log(unit,
   4688         info->enable_reg, info->enable_field, spci.mem,
   4689         SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   4690         spci.index, spci.detect_time, spci.sblk, spci.addr);
   4691 
   4692     (void)soc_ser_correction(unit, &spci);
   4693     if (spci.log_id != 0) {
   4694         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4695                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4696                            spci.log_id, 0);
   4697     }
   4698     /* Clear parity error status */
   4699     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4700     
   4701     return SOC_E_NONE;
   4702 }
   4703 
   4704 STATIC int
   4705 _soc_trident_parity_process_mmu_vlan(int unit, int block_info_idx,
   4706                                      const _soc_trident_parity_info_t *info,
   4707                                      char *prefix_str)
   4708 {
   4709     uint32 index, rval, minfo;
   4710     _soc_ser_correct_info_t spci;
   4711     
   4712     sal_memset(&spci, 0, sizeof(spci));
   4713     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   4714     spci.reg = INVALIDr;
   4715     spci.blk_type = SOC_BLK_MMU;
   4716 
   4717     SOC_IF_ERROR_RETURN(READ_MCQ_VLANTBLERRPTRr(unit, &rval));
   4718     index = soc_reg_field_get(unit, MCQ_VLANTBLERRPTRr, rval, VLANTBLERRORPOINTERf);
   4719     
   4720     if (index > soc_mem_index_max(unit, MMU_IPMC_VLAN_TBLm)) {
   4721         return SOC_E_INTERNAL;
   4722     }
   4723     spci.mem = MMU_IPMC_VLAN_TBLm;
   4724     spci.index = index;
   4725     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field,
   4726                          &minfo);
   4727     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4728                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, rval, minfo);
   4729     LOG_WARN(BSL_LS_SOC_SER,
   4730               (BSL_META_U(unit,
   4731                           "%s %s index %d parity error\n"), prefix_str,
   4732                           SOC_MEM_NAME(unit, spci.mem), spci.index));
   4733     spci.detect_time = sal_time_usecs();
   4734     spci.parity_type = info->type;
   4735     spci.log_id = _soc_trident_populate_ser_log(unit,
   4736         info->enable_reg, info->enable_field, spci.mem,
   4737         SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   4738         spci.index, spci.detect_time, spci.sblk, spci.addr);
   4739     (void)soc_ser_correction(unit, &spci);
   4740     if (spci.log_id != 0) {
   4741         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4742                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4743                            spci.log_id, 0);
   4744     }
   4745     /* Clear parity error status */
   4746     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4747     return SOC_E_NONE;
   4748 }
   4749 
   4750 STATIC int
   4751 _soc_trident_parity_process_mmu_aging(int unit, int block_info_idx,
   4752                                      const _soc_trident_parity_info_t *info,
   4753                                      char *prefix_str)
   4754 {
   4755     uint32 index, status, rval, minfo;
   4756     _soc_ser_correct_info_t spci;
   4757     
   4758     sal_memset(&spci, 0, sizeof(spci));
   4759     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   4760     spci.reg = INVALIDr;
   4761     spci.blk_type = SOC_BLK_MMU;
   4762 
   4763     SOC_IF_ERROR_RETURN(READ_PERR_STATr(unit, &status));
   4764     if (soc_reg_field_get(unit, PERR_STATr, status, EXP_ERRf)) {
   4765         SOC_IF_ERROR_RETURN(READ_PERR_PTR_EXPr(unit, &rval));
   4766         index = soc_reg_field_get(unit, PERR_PTR_EXPr, rval, PTRf);
   4767         spci.mem = MMU_AGING_EXPm;
   4768     } else if (soc_reg_field_get(unit, PERR_STATr, status, CTR_ERRf)) {
   4769         SOC_IF_ERROR_RETURN(READ_PERR_PTR_CTRr(unit, &rval));
   4770         index = soc_reg_field_get(unit, PERR_PTR_CTRr, rval, PTRf);
   4771         spci.mem = MMU_AGING_CTRm;
   4772     } else {
   4773         LOG_ERROR(BSL_LS_SOC_SER,
   4774                   (BSL_META_U(unit,
   4775                               "%s %s parity hardware inconsistency\n"),
   4776                               prefix_str, "mmu aging"));
   4777         return SOC_E_NONE;
   4778     }
   4779 
   4780     spci.index = index;
   4781     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field,
   4782                          &minfo);
   4783     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4784                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, status, minfo);
   4785     LOG_WARN(BSL_LS_SOC_SER,
   4786               (BSL_META_U(unit,
   4787                           "%s %s index %d parity error\n"), prefix_str,
   4788                           SOC_MEM_NAME(unit, spci.mem), spci.index));
   4789     spci.detect_time = sal_time_usecs();
   4790     spci.parity_type = info->type;
   4791     spci.log_id = _soc_trident_populate_ser_log(unit,
   4792         info->enable_reg, info->enable_field, spci.mem,
   4793         SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   4794         spci.index, spci.detect_time, spci.sblk, spci.addr);
   4795     (void)soc_ser_correction(unit, &spci);
   4796     if (spci.log_id != 0) {
   4797         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4798                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4799                            spci.log_id, 0);
   4800     }
   4801     /* Clear parity error status */
   4802     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4803     return SOC_E_NONE;
   4804 }
   4805 
   4806 STATIC int
   4807 _soc_trident_parity_process_mmu_ctr(int unit, int block_info_idx,
   4808                                      const _soc_trident_parity_info_t *info,
   4809                                      char *prefix_str)
   4810 {
   4811     uint32 index, status, memid, minfo;
   4812     _soc_ser_correct_info_t spci;
   4813     
   4814     sal_memset(&spci, 0, sizeof(spci));
   4815     spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN | SOC_SER_LOG_WRITE_CACHE;
   4816     spci.reg = INVALIDr;
   4817     spci.blk_type = SOC_BLK_MMU;
   4818 
   4819     SOC_IF_ERROR_RETURN(READ_MMU_CTR_PARITY_ERRr(unit, &status));
   4820     memid = soc_reg_field_get(unit, MMU_CTR_PARITY_ERRr, status, MEMIDf);
   4821     if (memid == 0x1 || memid == 0x2) {
   4822         spci.mem = MMU_CTR_UC_DROP_MEMm;
   4823     } else if (memid == 0x4) {
   4824         spci.mem = MMU_CTR_MC_DROP_MEMm;
   4825     } else if (memid == 0x8) {
   4826         spci.mem = MMU_CTR_COLOR_DROP_MEMm;
   4827     } else {
   4828         LOG_ERROR(BSL_LS_SOC_SER,
   4829                   (BSL_META_U(unit,
   4830                               "%s %s parity hardware inconsistency\n"),
   4831                               prefix_str, "mmu ctr"));
   4832         return SOC_E_NONE;
   4833     }
   4834     index = soc_reg_field_get(unit, MMU_CTR_PARITY_ERRr, status, ERRADDRf);
   4835     spci.index = index;
   4836     _soc_mem_parity_info(unit, block_info_idx, 0, info->group_reg_status_field,
   4837                          &minfo);
   4838     soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4839                        SOC_SWITCH_EVENT_DATA_ERROR_PARITY, status, minfo);
   4840     LOG_WARN(BSL_LS_SOC_SER,
   4841               (BSL_META_U(unit,
   4842                           "%s %s index %d parity error\n"), prefix_str,
   4843                           SOC_MEM_NAME(unit, spci.mem), spci.index));     
   4844     spci.detect_time = sal_time_usecs();
   4845     spci.parity_type = info->type;
   4846     spci.log_id = _soc_trident_populate_ser_log(unit,
   4847         info->enable_reg, info->enable_field, spci.mem,
   4848         SOC_MEM_BLOCK_ANY(unit, spci.mem), spci.acc_type,
   4849         spci.index, spci.detect_time, spci.sblk, spci.addr);
   4850     (void)soc_ser_correction(unit, &spci);
   4851     if (spci.log_id != 0) {
   4852         soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4853                            SOC_SWITCH_EVENT_DATA_ERROR_LOG, 
   4854                            spci.log_id, 0);
   4855     }
   4856     /* Clear parity error status */
   4857     _soc_trident_parity_mmu_clear(unit, info->group_reg_status_field);
   4858     return SOC_E_NONE;
   4859 }
   4860 
   4861 
   4862 STATIC int
   4863 _soc_trident_parity_process_xlport(int unit, soc_block_t blocktype, int pipe,
   4864                                    const _soc_trident_parity_info_t *info)
   4865 {
   4866     soc_reg_t xlport_reg;
   4867     uint32 xlport_rval;
   4868     int block_info_idx, inst_num, port;
   4869     char prefix_str[24];
   4870 
   4871     if (info->intr_status_reg == INVALIDr) {
   4872         return SOC_E_NONE;
   4873     }
   4874 
   4875     port = -1;
   4876     inst_num = info->id + pipe * 9;
   4877     SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_XLPORT) {
   4878         if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   4879             port = SOC_BLOCK_PORT(unit, block_info_idx);
   4880             break;
   4881         }
   4882     }
   4883     if (port < 0) {
   4884         return SOC_E_NONE;
   4885     }
   4886 
   4887     xlport_reg = info->intr_status_reg;
   4888     SOC_IF_ERROR_RETURN
   4889         (soc_reg32_get(unit, xlport_reg, port, 0, &xlport_rval));
   4890     if (xlport_rval == 0) {
   4891         return SOC_E_NONE;
   4892     }
   4893 
   4894     sal_sprintf(prefix_str, "unit %d XLPORT%d", unit, inst_num);
   4895     SOC_IF_ERROR_RETURN
   4896         (_soc_trident_parity_process_info(unit, blocktype, block_info_idx, pipe,
   4897                                           xlport_reg, xlport_rval,
   4898                                           info->info, prefix_str));
   4899 
   4900     return SOC_E_NONE;
   4901 }
   4902 
   4903 STATIC int
   4904 _soc_trident_parity_process_info(int unit, soc_block_t blocktype,
   4905                                  int block_info_idx, int pipe,
   4906                                  soc_reg_t group_reg, uint32 group_rval,
   4907                                  const _soc_trident_parity_info_t *info_list,
   4908                                  char *prefix_str)
   4909 {
   4910     const _soc_trident_parity_info_t *info;
   4911     int info_index;
   4912     char *mem_str;
   4913     uint32 minfo;
   4914     soc_ser_log_tlv_generic_t log_generic;
   4915     int log_id;
   4916 
   4917     sal_memset(&log_generic, 0, sizeof(soc_ser_log_tlv_generic_t));
   4918     /* Loop through each info entry in the list */
   4919     for (info_index = 0; ; info_index++) {
   4920         info = &info_list[info_index];
   4921         if (info->type == _SOC_PARITY_TYPE_NONE) {
   4922             /* End of table */
   4923             break;
   4924         }
   4925 
   4926         /* Check status for the info entry in the group register */
   4927         if (!soc_reg_field_get(unit, group_reg, group_rval,
   4928                                info->group_reg_status_field)) {
   4929             continue;
   4930         }
   4931 
   4932         if (info->mem_str) {
   4933             mem_str = info->mem_str;
   4934         } else if (info->mem != INVALIDm) {
   4935             mem_str = SOC_MEM_NAME(unit, info->mem);
   4936         } else {
   4937             mem_str = SOC_FIELD_NAME(unit, info->group_reg_status_field);
   4938         }
   4939 
   4940         /* Handle different parity error reporting style */
   4941         switch (info->type) {
   4942         case _SOC_PARITY_TYPE_GENERIC:
   4943             _soc_mem_parity_info(unit, block_info_idx, pipe,
   4944                                  info->group_reg_status_field, &minfo);
   4945             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 
   4946                                SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 0,
   4947                                minfo);
   4948 
   4949             log_generic.time = sal_time_usecs();
   4950             log_generic.boot_count = soc_ser_log_get_boot_count(unit);
   4951             log_generic.block_type = SOC_BLOCK_INFO(unit, block_info_idx).type;
   4952             log_generic.parity_type = info->type;
   4953 
   4954             log_id = soc_ser_log_create_entry(unit, 
   4955                 sizeof(soc_ser_log_tlv_generic_t) +
   4956                 sizeof(soc_ser_log_tlv_hdr_t) *2);
   4957 
   4958             soc_ser_log_add_tlv(unit, log_id, SOC_SER_LOG_TLV_GENERIC, 
   4959                 sizeof(soc_ser_log_tlv_generic_t), &log_generic);
   4960             soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
   4961                                SOC_SWITCH_EVENT_DATA_ERROR_LOG, log_id, 0);
   4962 
   4963             _soc_trident_parity_generic_clear(unit, blocktype, pipe,
   4964                                       group_reg, info, prefix_str, mem_str);
   4965             break;
   4966         case _SOC_PARITY_TYPE_PARITY:
   4967             /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */
   4968             SOC_IF_ERROR_RETURN
   4969                 (_soc_trident_parity_process_parity(unit, 0, block_info_idx,
   4970                                                     pipe, info, FALSE,
   4971                                                     prefix_str, mem_str));
   4972             break;
   4973         case _SOC_PARITY_TYPE_ECC:
   4974             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   4975             SOC_IF_ERROR_RETURN
   4976                 (_soc_trident_parity_process_ecc(unit, block_info_idx, pipe,
   4977                                                  info, FALSE,
   4978                                                  prefix_str, mem_str));
   4979             break;
   4980         case _SOC_PARITY_TYPE_HASH:
   4981             /* PARITY_ERR_BMf, MULTIPLE_ERRf, BUCKET_IDXf */
   4982             SOC_IF_ERROR_RETURN
   4983                 (_soc_trident_parity_process_hash(unit, block_info_idx,
   4984                                                   pipe, info, FALSE,
   4985                                                   prefix_str, mem_str));
   4986             break;
   4987         case _SOC_PARITY_TYPE_EDATABUF:
   4988             /* ECC_ERR_MGRPf, ECC_ERR_2B_MGRPf, ECC_MULTI_MGRPf */
   4989             SOC_IF_ERROR_RETURN
   4990                 (_soc_trident_parity_process_edatabuf(unit, block_info_idx,
   4991                                                       pipe, info, FALSE,
   4992                                                       prefix_str, mem_str));
   4993             break;
   4994         case _SOC_PARITY_TYPE_COUNTER:
   4995             /* PARITY_ERRf, MULTIPLE_ERRf, COUNTER_IDXf, PORT_IDX,
   4996                ENTRY_IDXf */
   4997             SOC_IF_ERROR_RETURN
   4998                 (_soc_trident_parity_process_counter(unit, blocktype, block_info_idx,
   4999                                                      pipe, info, FALSE,
   5000                                                      prefix_str, mem_str));
   5001             break;
   5002         case _SOC_PARITY_TYPE_XLPORT:
   5003             /* One more level of report tree structure */
   5004             SOC_IF_ERROR_RETURN
   5005                 (_soc_trident_parity_process_xlport(unit, blocktype, pipe, info));
   5006             break;
   5007         case _SOC_PARITY_TYPE_MMU_THDO:
   5008             SOC_IF_ERROR_RETURN
   5009                 (_soc_trident_parity_process_mmu_thdo(unit, block_info_idx,
   5010                                                       info, prefix_str));
   5011             break;
   5012         case _SOC_PARITY_TYPE_START_ERR:
   5013             SOC_IF_ERROR_RETURN
   5014                 (_soc_trident_parity_process_start_err(unit, block_info_idx,
   5015                                                        info, prefix_str));
   5016             break;
   5017         case _SOC_PARITY_TYPE_MMU_WRED:
   5018             SOC_IF_ERROR_RETURN
   5019                 (_soc_trident_parity_process_mmu_wred(unit, block_info_idx,
   5020                                                       info, prefix_str));
   5021             break;
   5022         case _SOC_PARITY_TYPE_MMU_THDI:
   5023             SOC_IF_ERROR_RETURN
   5024                 (_soc_trident_parity_process_mmu_thdi(unit, block_info_idx,
   5025                                                       info, prefix_str));
   5026             break;
   5027         case _SOC_PARITY_TYPE_MMU_MTRO:
   5028             SOC_IF_ERROR_RETURN
   5029                 (_soc_trident_parity_process_mmu_mtro(unit, block_info_idx,
   5030                                                       info, prefix_str));
   5031             break;
   5032         case _SOC_PARITY_TYPE_MMU_ES:
   5033             SOC_IF_ERROR_RETURN
   5034                 (_soc_trident_parity_process_mmu_es(unit, block_info_idx,
   5035                                                     info, prefix_str));
   5036             break;
   5037         case _SOC_PARITY_TYPE_MMU_IPMC:
   5038             SOC_IF_ERROR_RETURN
   5039                 (_soc_trident_parity_process_mmu_ipmc(unit, block_info_idx,
   5040                                                       info, prefix_str));
   5041             break;
   5042         case _SOC_PARITY_TYPE_MMU_VLAN:
   5043             SOC_IF_ERROR_RETURN
   5044                 (_soc_trident_parity_process_mmu_vlan(unit, block_info_idx,
   5045                                                       info, prefix_str));
   5046             break;
   5047         case _SOC_PARITY_TYPE_MMU_AGING:
   5048             SOC_IF_ERROR_RETURN
   5049                 (_soc_trident_parity_process_mmu_aging(unit, block_info_idx,
   5050                                                       info, prefix_str));
   5051             break;
   5052         case _SOC_PARITY_TYPE_MMU_CTR:
   5053             SOC_IF_ERROR_RETURN
   5054                 (_soc_trident_parity_process_mmu_ctr(unit, block_info_idx,
   5055                                                       info, prefix_str));
   5056             break;
   5057         default:
   5058             break;
   5059         } /* Handle different parity error reporting style */
   5060     } /* Loop through each info entry in the list */
   5061 
   5062     return SOC_E_NONE;
   5063 }
   5064 
   5065 static int
   5066 _soc_trident_parity_process_all(int unit)
   5067 {
   5068     const _soc_trident_parity_route_block_t *route_block;
   5069     int route_block_index;
   5070     uint32 cmic_rval, route_block_rval;
   5071     uint32 route_block_enable;
   5072     uint32 cmic_bit;
   5073     int block_info_idx, inst_num;
   5074     char prefix_str[10];
   5075 
   5076     sal_sprintf(prefix_str, "unit %d", unit);
   5077 
   5078     /* Read CMIC parity status register */
   5079     /* coverity[result_independent_of_operands] */
   5080     SOC_IF_ERROR_RETURN
   5081         (READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, &cmic_rval));
   5082     if (cmic_rval == 0) {
   5083         return SOC_E_NONE;
   5084     }
   5085 
   5086     /* Loop through each place-and-route block entry */
   5087     for (route_block_index = 0; ; route_block_index++) {
   5088         route_block = &_soc_trident_parity_route_blocks[route_block_index];
   5089         cmic_bit = route_block->cmic_bit;
   5090         if (cmic_bit == 0) {
   5091             /* End of table */
   5092             break;
   5093         }
   5094 
   5095         /* Check status for the route block in the CMIC register */
   5096         if (!(cmic_rval & cmic_bit)) {
   5097             /* No interrupt bit asserted for the route block */
   5098             continue;
   5099         }
   5100 
   5101         if (route_block->blocktype == SOC_BLK_PORT_GROUP4 ||
   5102             route_block->blocktype == SOC_BLK_PORT_GROUP5) {
   5103             inst_num = route_block->pipe;
   5104         } else {
   5105             inst_num = 0;
   5106         }
   5107         SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) {
   5108             if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   5109                 break;
   5110             }
   5111         }
   5112 
   5113         /* Read per route block parity status register */
   5114         SOC_IF_ERROR_RETURN
   5115             (_soc_trident_parity_reg_get(unit, block_info_idx,
   5116                                          route_block->pipe,
   5117                                          route_block->status_reg,
   5118                                          &route_block_rval));
   5119         if (route_block_rval == 0) {
   5120             continue;
   5121         }
   5122         SOC_IF_ERROR_RETURN
   5123             (_soc_trident_parity_reg_get(unit, block_info_idx,
   5124                                          route_block->pipe,
   5125                                          route_block->enable_reg,
   5126                                          &route_block_enable));
   5127         route_block_rval &= route_block_enable;
   5128         route_block_enable &= ~route_block_rval;
   5129         SOC_IF_ERROR_RETURN
   5130             (_soc_trident_parity_reg_set(unit, block_info_idx,
   5131                                          route_block->pipe,
   5132                                          route_block->enable_reg,
   5133                                          route_block_enable));
   5134         SOC_IF_ERROR_RETURN
   5135             (_soc_trident_parity_process_info(unit, route_block->blocktype, 
   5136                                               block_info_idx,
   5137                                               route_block->pipe,
   5138                                               route_block->status_reg,
   5139                                               route_block_rval,
   5140                                               route_block->info,
   5141                                               prefix_str));
   5142         route_block_enable |= route_block_rval;
   5143         SOC_IF_ERROR_RETURN
   5144             (_soc_trident_parity_reg_set(unit, block_info_idx,
   5145                                          route_block->pipe,
   5146                                          route_block->enable_reg,
   5147                                          route_block_enable));
   5148     } /* Loop through each place-and-route block entry */
   5149 
   5150     return SOC_E_NONE;
   5151 }
   5152 #ifdef _SER_TIME_STAMP
   5153 extern sal_usecs_t ser_time_1;
   5154 sal_usecs_t ser_time_3;
   5155 sal_usecs_t ser_time_2;
   5156 #endif
   5157 STATIC void
   5158 soc_trident_parity_error(void *unit_vp, void *d1, void *d2, void *d3, void *d4)
   5159 {
   5160     int unit = PTR_TO_INT(unit_vp);
   5161     soc_stat_t *stat = SOC_STAT(unit);
   5162 #ifdef _SER_TIME_STAMP
   5163     ser_time_2 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   5164 #endif
   5165     _soc_trident_parity_process_all(unit);
   5166 #ifdef _SER_TIME_STAMP
   5167     ser_time_3 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   5168     LOG_CLI((BSL_META_U(unit,
   5169                         "Start after: %d, Exist after: %d\n"), ser_time_2, ser_time_3));
   5170 #endif
   5171     sal_usleep(1000); /* Don't reenable too soon */
   5172     soc_intr_enable(unit, IRQ_MEM_FAIL);
   5173     stat->ser_err_int++;
   5174 }
   5175 
   5176 typedef union _td_ser_nack_reg_mem_u {
   5177     soc_reg_t reg;
   5178     soc_mem_t mem;
   5179 } _td_ser_nack_reg_mem_t;
   5180 
   5181 #define _SOC_TD_SER_REG 1
   5182 #define _SOC_TD_SER_MEM 0
   5183 
   5184 STATIC int
   5185 _soc_trident_mem_nack_process_info(int unit, int stat, soc_block_t blocktype, 
   5186                                    int block_info_idx, int pipe, int reg_mem, 
   5187                                    _td_ser_nack_reg_mem_t nack_reg_mem, int copyno,
   5188                                    const _soc_trident_parity_info_t *info_list,
   5189                                    char *prefix_str, uint32 address)
   5190 {
   5191     const _soc_trident_parity_info_t *info;
   5192     int info_index;
   5193     char *mem_str;
   5194 
   5195     /* Loop through each info entry in the list */
   5196     for (info_index = 0; ; info_index++) {
   5197         info = &info_list[info_index];
   5198         if (info->type == _SOC_PARITY_TYPE_NONE) {
   5199             /* End of table */
   5200             break;
   5201         }
   5202         if (reg_mem == _SOC_TD_SER_MEM && !(info->mem == nack_reg_mem.mem ||
   5203             info->type == _SOC_PARITY_TYPE_MMU_IPMC)) {
   5204             continue;
   5205         }
   5206         if ((reg_mem == _SOC_TD_SER_REG) && !(info->type == _SOC_PARITY_TYPE_COUNTER ||
   5207                         info->type == _SOC_PARITY_TYPE_MMU_WRED || info->type== _SOC_PARITY_TYPE_PARITY)) {
   5208             continue;
   5209         }
   5210 
   5211         if ((reg_mem == _SOC_TD_SER_REG) && (info->type== _SOC_PARITY_TYPE_PARITY)) {
   5212             int rv = SOC_E_NONE;
   5213             /* For parity type, only handle the registers in nack_register array */
   5214             rv = _soc_trident_nack_reg_check(unit, nack_reg_mem.reg,
   5215                                              info->mem_str);
   5216 
   5217             if (rv == SOC_E_NOT_FOUND) {
   5218                 continue;
   5219             }
   5220         }
   5221 
   5222         if (info->mem_str) {
   5223             mem_str = info->mem_str;
   5224         } else {
   5225             mem_str = SOC_MEM_NAME(unit, info->mem);
   5226         }
   5227         /* Handle different parity error reporting style */
   5228         switch (info->type) {
   5229         case _SOC_PARITY_TYPE_PARITY:
   5230             if (stat) {
   5231                 continue;
   5232             }
   5233             /* PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf */
   5234             SOC_IF_ERROR_RETURN
   5235                 (_soc_trident_parity_process_parity(unit, 1, block_info_idx,
   5236                                                     pipe, info, TRUE,
   5237                                                     prefix_str, mem_str));
   5238             break;
   5239         case _SOC_PARITY_TYPE_ECC:
   5240             if (stat) {
   5241                 continue;
   5242             }
   5243             /* ECC_ERRf, MULTIPLE_ERRf, DOUBLE_BIT_ERRf, ENTRY_IDXf */
   5244             SOC_IF_ERROR_RETURN
   5245                 (_soc_trident_parity_process_ecc(unit, block_info_idx, pipe,
   5246                                                  info, TRUE,
   5247                                                  prefix_str, mem_str));
   5248             break;
   5249         case _SOC_PARITY_TYPE_HASH:
   5250             if (stat) {
   5251                 continue;
   5252             }
   5253             /* PARITY_ERR_BMf, MULTIPLE_ERRf, BUCKET_IDXf */
   5254             if (((info->mem == L2Xm) || (info->mem == L2_ENTRY_ONLYm)) 
   5255                && (address != 0)) {
   5256                 SOC_IF_ERROR_RETURN
   5257                     (_soc_trident_parity_process_l2x(unit, block_info_idx,
   5258                                                       pipe, info, TRUE,
   5259                                                       prefix_str, mem_str, address));
   5260                 }
   5261             else {            
   5262                 SOC_IF_ERROR_RETURN
   5263                     (_soc_trident_parity_process_hash(unit, block_info_idx,
   5264                                                       pipe, info, TRUE,
   5265                                                       prefix_str, mem_str));
   5266             }
   5267             break;
   5268         case _SOC_PARITY_TYPE_EDATABUF:
   5269             if (stat) {
   5270                 continue;
   5271             }
   5272             /* ECC_ERR_MGRPf, ECC_ERR_2B_MGRPf, ECC_MULTI_MGRPf */
   5273             SOC_IF_ERROR_RETURN
   5274                 (_soc_trident_parity_process_edatabuf(unit, block_info_idx,
   5275                                                       pipe, info, TRUE,
   5276                                                       prefix_str, mem_str));
   5277             break;
   5278         case _SOC_PARITY_TYPE_COUNTER:
   5279             /* PARITY_ERRf, MULTIPLE_ERRf, COUNTER_IDXf, PORT_IDX,
   5280                ENTRY_IDXf */
   5281             SOC_IF_ERROR_RETURN
   5282                 (_soc_trident_parity_process_counter(unit, blocktype, block_info_idx,
   5283                                                      pipe, info, TRUE,
   5284                                                      prefix_str, mem_str));
   5285             break;
   5286         case _SOC_PARITY_TYPE_MMU_WRED:
   5287             if (stat) {
   5288                 continue;
   5289             }
   5290             SOC_IF_ERROR_RETURN
   5291                 (_soc_trident_parity_process_mmu_wred(unit, block_info_idx,
   5292                                                       info, prefix_str));
   5293             break;
   5294         case _SOC_PARITY_TYPE_MMU_THDI:
   5295             if (stat) {
   5296                 continue;
   5297             }
   5298             SOC_IF_ERROR_RETURN
   5299                 (_soc_trident_parity_process_mmu_thdi(unit, block_info_idx,
   5300                                                       info, prefix_str));
   5301             break;
   5302         case _SOC_PARITY_TYPE_MMU_MTRO:
   5303             if (stat) {
   5304                 continue;
   5305             }
   5306             SOC_IF_ERROR_RETURN
   5307                 (_soc_trident_parity_process_mmu_mtro(unit, block_info_idx,
   5308                                                       info, prefix_str));
   5309             break;
   5310         case _SOC_PARITY_TYPE_MMU_ES:
   5311             if (stat) {
   5312                 continue;
   5313             }
   5314             SOC_IF_ERROR_RETURN
   5315                 (_soc_trident_parity_process_mmu_es(unit, block_info_idx,
   5316                                                     info, prefix_str));
   5317             break;
   5318         case _SOC_PARITY_TYPE_MMU_IPMC:
   5319             if (stat) {
   5320                 continue;
   5321             }
   5322             SOC_IF_ERROR_RETURN
   5323                 (_soc_trident_parity_process_mmu_ipmc(unit, block_info_idx,
   5324                                                       info, prefix_str));
   5325             break;
   5326         case _SOC_PARITY_TYPE_MMU_VLAN:
   5327             if (stat) {
   5328                 continue;
   5329             }
   5330             SOC_IF_ERROR_RETURN
   5331                 (_soc_trident_parity_process_mmu_vlan(unit, block_info_idx,
   5332                                                       info, prefix_str));
   5333             break;
   5334         default:
   5335             break;
   5336         } /* Handle different parity error reporting style */
   5337     } /* Loop through each info entry in the list */
   5338 
   5339     return SOC_E_NONE;
   5340 }
   5341 
   5342 STATIC int
   5343 _soc_trident_mem_nack_error_process(int unit, int stat, int reg_mem,
   5344                                     _td_ser_nack_reg_mem_t nack_reg_mem, 
   5345                                     int copyno, int pipe, uint32 address)
   5346 {
   5347     const _soc_trident_parity_route_block_t *route_block;
   5348     int route_block_index;
   5349     uint32 cmic_bit;
   5350     int block_info_idx, inst_num;
   5351     char prefix_str[10];
   5352 
   5353     sal_sprintf(prefix_str, "unit %d", unit);
   5354 
   5355     /* Loop through each place-and-route block entry */
   5356     for (route_block_index = 0; ; route_block_index++) {
   5357         route_block = &_soc_trident_parity_route_blocks[route_block_index];
   5358         cmic_bit = route_block->cmic_bit;
   5359         if (cmic_bit == 0) {
   5360             /* End of table */
   5361             break;
   5362         }
   5363         if (pipe >= 0 && pipe != route_block->pipe) {
   5364             continue;
   5365         }
   5366 
   5367         if (route_block->blocktype == SOC_BLK_PORT_GROUP4 ||
   5368             route_block->blocktype == SOC_BLK_PORT_GROUP5) {
   5369             inst_num = route_block->pipe;
   5370         } else {
   5371             inst_num = 0;
   5372         }
   5373         SOC_BLOCK_ITER(unit, block_info_idx, route_block->blocktype) {
   5374             if (SOC_BLOCK_INFO(unit, block_info_idx).number == inst_num) {
   5375                 break;
   5376             }
   5377         }
   5378 
   5379         SOC_IF_ERROR_RETURN
   5380             (_soc_trident_mem_nack_process_info(unit, stat, route_block->blocktype, 
   5381                                                 block_info_idx, route_block->pipe, 
   5382                                                 reg_mem, nack_reg_mem, copyno,
   5383                                                 route_block->info,
   5384                                                 prefix_str, address));
   5385     } /* Loop through each place-and-route block entry */
   5386 
   5387     return SOC_E_NONE;
   5388 }
   5389 
   5390 STATIC void
   5391 soc_trident_mem_nack(void *unit_vp, void *addr_vp, void *blk_vp, 
   5392                      void *d3, void *d4)
   5393 {
   5394     soc_mem_t mem = INVALIDm;
   5395     int rv, pipe = PTR_TO_INT(d4), unit = PTR_TO_INT(unit_vp);
   5396     uint32 address = PTR_TO_INT(addr_vp);
   5397     uint32 block = PTR_TO_INT(blk_vp);
   5398     uint32 offset = 0, min_addr = 0, max_addr = 0;
   5399     soc_regaddrinfo_t ainfo;
   5400     int reg_mem = PTR_TO_INT(d3);
   5401     _td_ser_nack_reg_mem_t nack_reg_mem;
   5402     soc_stat_t *stat = SOC_STAT(unit);
   5403     int at = (reg_mem == _SOC_TD_SER_REG) ?
   5404                         (address & 0xE00) >> 9 : (address & 0xE0000) >> \
   5405                         _SOC_MEM_ADDR_ACC_TYPE_SHIFT;
   5406 #ifdef _SER_TIME_STAMP
   5407     ser_time_2 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   5408 #endif
   5409     nack_reg_mem.reg = INVALIDr;
   5410     nack_reg_mem.mem = INVALIDm;
   5411     if (reg_mem == _SOC_TD_SER_REG) {
   5412         if (address) {
   5413             soc_regaddrinfo_get(unit, &ainfo, address);
   5414             nack_reg_mem.reg = ainfo.reg;
   5415         }
   5416     } else {
   5417         offset = address & ~0xC0f00000; /* Strip block ID */
   5418         mem = soc_addr_to_mem(unit, address, &block);
   5419         if (mem == INVALIDm) {
   5420             LOG_ERROR(BSL_LS_SOC_SER,
   5421                       (BSL_META_U(unit,
   5422                                   "unit %d mem decode failed, "
   5423                                   "SCHAN NACK analysis failure\n"), unit));
   5424             return;
   5425         }
   5426         _soc_trident_mem_rename(&mem);
   5427         nack_reg_mem.mem = mem;
   5428         
   5429         min_addr = max_addr = SOC_MEM_INFO(unit, mem).base;
   5430         min_addr += SOC_MEM_INFO(unit, mem).index_min;
   5431         max_addr += SOC_MEM_INFO(unit, mem).index_max;
   5432 
   5433     }
   5434     
   5435     switch (at) { 
   5436     case 0: break;
   5437     case 1: break;
   5438     case 2: pipe = 1; 
   5439             break;
   5440     case 3: break;
   5441     case 4: break;
   5442     case 5: break;
   5443     case 6: break;
   5444     default: break;
   5445     }
   5446     if (reg_mem == _SOC_TD_SER_MEM) {
   5447         if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem,
   5448                       nack_reg_mem, block, pipe, address)) < 0) {
   5449             LOG_ERROR(BSL_LS_SOC_SER,
   5450                       (BSL_META_U(unit,
   5451                                   "unit %d %s entry %d SCHAN NACK analysis failure\n"),
   5452                        unit, SOC_MEM_NAME(unit, mem),
   5453                        min_addr - offset));
   5454         }
   5455     } else {
   5456         /* In stat collection case there is no address info, thus try both pipes */
   5457         if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem, 
   5458                       nack_reg_mem, block, 0, address)) < 0) {
   5459             LOG_ERROR(BSL_LS_SOC_SER,
   5460                       (BSL_META_U(unit,
   5461                                   "unit %d pipe: 0 REG SCHAN NACK analysis failure.\n"), unit));
   5462         }
   5463         if ((rv = _soc_trident_mem_nack_error_process(unit, FALSE, reg_mem,
   5464                       nack_reg_mem, block, 1, address)) < 0) {
   5465             LOG_ERROR(BSL_LS_SOC_SER,
   5466                       (BSL_META_U(unit,
   5467                                   "unit %d pipe: 1 REG SCHAN NACK analysis failure.\n"), unit));
   5468         }
   5469     }
   5470 #ifdef _SER_TIME_STAMP
   5471     ser_time_3 = SAL_USECS_SUB(sal_time_usecs(), ser_time_1);
   5472     LOG_CLI((BSL_META_U(unit,
   5473                         "Start after: %d, Exist after: %d\n"), ser_time_2, ser_time_3));
   5474 #endif
   5475     stat->ser_err_nak++;
   5476 }
   5477 
   5478 STATIC void
   5479 soc_trident_stat_nack(int unit, int *fixed)
   5480 {
   5481     int rv;
   5482     _td_ser_nack_reg_mem_t nack_reg_mem;
   5483     
   5484     _stat_error_fixed[unit] = 0;
   5485     nack_reg_mem.reg = -1;
   5486     if ((rv = _soc_trident_mem_nack_error_process(unit, TRUE, _SOC_TD_SER_REG,
   5487                                                   nack_reg_mem, 0, 0, 0)) < 0) {
   5488         LOG_ERROR(BSL_LS_SOC_SER,
   5489                   (BSL_META_U(unit,
   5490                               "unit %d pipe: 0 STAT SCHAN NACK analysis failure.\n"), unit));
   5491     }
   5492     if ((rv = _soc_trident_mem_nack_error_process(unit, TRUE, _SOC_TD_SER_REG,
   5493                                                   nack_reg_mem, 0, 1, 0)) < 0) {
   5494         LOG_ERROR(BSL_LS_SOC_SER,
   5495                   (BSL_META_U(unit,
   5496                               "unit %d pipe: 1 STAT SCHAN NACK analysis failure.\n"), unit));
   5497     }
   5498     *fixed = _stat_error_fixed[unit];
   5499 }
   5500 
   5501 int
   5502 _soc_trident_ser_error_test(int unit)
   5503 {
   5504     return SOC_E_NONE;
   5505 }
   5506 
   5507 /* SER processing for TCAMs */
   5508 static _soc_ser_parity_info_t _soc_td_ser_parity_info_template[] = {
   5509     { L3_DEFIPm, _SOC_SER_PARITY_MODE_2BITS,
   5510       CMIC_SER_START_ADDR_0r, CMIC_SER_END_ADDR_0r,
   5511       CMIC_SER_MEM_ADDR_0r, CMIC_SER_PARITY_MODE_SELr,
   5512       RANGE_0_PARITY_BITSf, 178, CMIC_SER_RANGE0_DATAENTRY_LENr, 0, 0, 0,
   5513       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5514     { L3_DEFIPm, _SOC_SER_PARITY_MODE_2BITS,
   5515       CMIC_SER_START_ADDR_1r, CMIC_SER_END_ADDR_1r,
   5516       CMIC_SER_MEM_ADDR_1r, CMIC_SER_PARITY_MODE_SELr,
   5517       RANGE_1_PARITY_BITSf, 178, CMIC_SER_RANGE1_DATAENTRY_LENr, 0, 0, 0,
   5518       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5519       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5520     { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5521       CMIC_SER_START_ADDR_2r, CMIC_SER_END_ADDR_2r,
   5522       CMIC_SER_MEM_ADDR_2r, CMIC_SER_PARITY_MODE_SELr,
   5523       RANGE_2_PARITY_BITSf, 470, CMIC_SER_RANGE2_DATAENTRY_LENr, 0, 0, 0,
   5524       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5525     { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5526       CMIC_SER_START_ADDR_3r, CMIC_SER_END_ADDR_3r,
   5527       CMIC_SER_MEM_ADDR_3r, CMIC_SER_PARITY_MODE_SELr,
   5528       RANGE_3_PARITY_BITSf, 470, CMIC_SER_RANGE3_DATAENTRY_LENr, 0, 0, 0,
   5529       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5530       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5531     { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5532       CMIC_SER_START_ADDR_4r, CMIC_SER_END_ADDR_4r,
   5533       CMIC_SER_MEM_ADDR_4r, CMIC_SER_PARITY_MODE_SELr,
   5534       RANGE_4_PARITY_BITSf, 470, CMIC_SER_RANGE4_DATAENTRY_LENr, 0, 0, 0,
   5535       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5536     { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5537       CMIC_SER_START_ADDR_5r, CMIC_SER_END_ADDR_5r,
   5538       CMIC_SER_MEM_ADDR_5r, CMIC_SER_PARITY_MODE_SELr,
   5539       RANGE_5_PARITY_BITSf, 470, CMIC_SER_RANGE5_DATAENTRY_LENr, 0, 0, 0,
   5540       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5541       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5542     { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5543       CMIC_SER_START_ADDR_6r, CMIC_SER_END_ADDR_6r,
   5544       CMIC_SER_MEM_ADDR_6r, CMIC_SER_PARITY_MODE_SELr,
   5545       RANGE_6_PARITY_BITSf, 430, CMIC_SER_RANGE6_DATAENTRY_LENr, 0, 0, 0,
   5546       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5547     { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5548       CMIC_SER_START_ADDR_7r, CMIC_SER_END_ADDR_7r,
   5549       CMIC_SER_MEM_ADDR_7r, CMIC_SER_PARITY_MODE_SELr,
   5550       RANGE_7_PARITY_BITSf, 430, CMIC_SER_RANGE7_DATAENTRY_LENr, 0, 0, 0,
   5551       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5552       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5553     { L3_TUNNELm, _SOC_SER_PARITY_MODE_2BITS,
   5554       CMIC_SER_START_ADDR_8r, CMIC_SER_END_ADDR_8r,
   5555       CMIC_SER_MEM_ADDR_8r, CMIC_SER_PARITY_MODE_SELr,
   5556       RANGE_8_PARITY_BITSf, 211, CMIC_SER_RANGE8_DATAENTRY_LENr, 0, 0, 0,
   5557       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5558     { L3_TUNNELm, _SOC_SER_PARITY_MODE_2BITS,
   5559       CMIC_SER_START_ADDR_9r, CMIC_SER_END_ADDR_9r,
   5560       CMIC_SER_MEM_ADDR_9r, CMIC_SER_PARITY_MODE_SELr,
   5561       RANGE_9_PARITY_BITSf, 211, CMIC_SER_RANGE9_DATAENTRY_LENr, 0, 0, 0,
   5562       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5563       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5564     { L3_DEFIP_128m, _SOC_SER_PARITY_MODE_2BITS,
   5565       CMIC_SER_START_ADDR_10r, CMIC_SER_END_ADDR_10r,
   5566       CMIC_SER_MEM_ADDR_10r, CMIC_SER_PARITY_MODE_SELr,
   5567       RANGE_10_PARITY_BITSf, 282, CMIC_SER_RANGE10_DATAENTRY_LENr, 0, 0, 0,
   5568       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5569     { L3_DEFIP_128m, _SOC_SER_PARITY_MODE_2BITS,
   5570       CMIC_SER_START_ADDR_11r, CMIC_SER_END_ADDR_11r,
   5571       CMIC_SER_MEM_ADDR_11r, CMIC_SER_PARITY_MODE_SELr,
   5572       RANGE_11_PARITY_BITSf, 282, CMIC_SER_RANGE11_DATAENTRY_LENr, 0, 0, 0,
   5573       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5574       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5575     { FP_UDF_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5576       CMIC_SER_START_ADDR_12r, CMIC_SER_END_ADDR_12r,
   5577       CMIC_SER_MEM_ADDR_12r, CMIC_SER_PARITY_MODE_SELr,
   5578       RANGE_12_PARITY_BITSf, 139, CMIC_SER_RANGE12_DATAENTRY_LENr, 0, 0, 0,
   5579       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5580     { FP_UDF_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5581       CMIC_SER_START_ADDR_13r, CMIC_SER_END_ADDR_13r,
   5582       CMIC_SER_MEM_ADDR_13r, CMIC_SER_PARITY_MODE_SELr,
   5583       RANGE_13_PARITY_BITSf, 139, CMIC_SER_RANGE13_DATAENTRY_LENr, 0, 0, 0,
   5584       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5585       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5586     { MY_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5587       CMIC_SER_START_ADDR_14r, CMIC_SER_END_ADDR_14r,
   5588       CMIC_SER_MEM_ADDR_14r, CMIC_SER_PARITY_MODE_SELr,
   5589       RANGE_14_PARITY_BITSf, 135, CMIC_SER_RANGE14_DATAENTRY_LENr, 0, 0, 0,
   5590       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ},
   5591     { MY_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5592       CMIC_SER_START_ADDR_15r, CMIC_SER_END_ADDR_15r,
   5593       CMIC_SER_MEM_ADDR_15r, CMIC_SER_PARITY_MODE_SELr,
   5594       RANGE_15_PARITY_BITSf, 135, CMIC_SER_RANGE15_DATAENTRY_LENr, 0, 0, 0,
   5595       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5596       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5597     { VLAN_SUBNETm, _SOC_SER_PARITY_MODE_2BITS,
   5598       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 129, INVALIDr,
   5599       0, 0, 0,
   5600       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5601       _SOC_SER_FLAG_SW_COMPARE},
   5602     { VLAN_SUBNETm, _SOC_SER_PARITY_MODE_2BITS,
   5603       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 129, INVALIDr,
   5604       0, 0, 0,
   5605       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5606       _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5607     { L2_USER_ENTRYm, _SOC_SER_PARITY_MODE_2BITS,
   5608       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 123, INVALIDr,
   5609       0, 0, 0,
   5610       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5611       _SOC_SER_FLAG_SW_COMPARE},
   5612     { L2_USER_ENTRYm, _SOC_SER_PARITY_MODE_2BITS,
   5613       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 123, INVALIDr,
   5614       0, 0, 0,
   5615       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5616       _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5617     { CPU_COS_MAPm, _SOC_SER_PARITY_MODE_2BITS,
   5618       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 141, INVALIDr,
   5619       0, 0, 0,
   5620       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5621       _SOC_SER_FLAG_SW_COMPARE},
   5622     { CPU_COS_MAPm, _SOC_SER_PARITY_MODE_2BITS,
   5623       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 141, INVALIDr,
   5624       0, 0, 0,
   5625       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5626       _SOC_SER_FLAG_SW_COMPARE | _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5627     { FP_GLOBAL_MASK_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5628       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr,
   5629       0, 0, 0,
   5630       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5631       _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY},
   5632     { FP_GLOBAL_MASK_TCAMm, _SOC_SER_PARITY_MODE_2BITS,
   5633       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr,
   5634       0, 0, 0,
   5635       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5636       _SOC_SER_FLAG_SW_COMPARE | _SOC_SER_FLAG_OVERLAY |
   5637       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5638     { FP_GM_FIELDSm, _SOC_SER_PARITY_MODE_2BITS,
   5639       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr,
   5640       0, 0, 0,
   5641       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5642       _SOC_SER_FLAG_SW_COMPARE |
   5643       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE},
   5644     { FP_GM_FIELDSm, _SOC_SER_PARITY_MODE_2BITS,
   5645       INVALIDr, INVALIDr, INVALIDr, INVALIDr, INVALIDf, 133, INVALIDr,
   5646       0, 0, 0,
   5647       _SOC_SER_FLAG_MULTI_PIPE | _SOC_SER_FLAG_XY_READ |
   5648       _SOC_SER_FLAG_SW_COMPARE |
   5649       _SOC_SER_FLAG_OVERLAY | _SOC_SER_FLAG_OVERLAY_CASE |
   5650       _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y},
   5651     { INVALIDm, _SOC_SER_PARITY_MODE_NUM},
   5652 };
   5653 
   5654 static _soc_ser_parity_info_t *_soc_td_ser_parity_info[SOC_MAX_NUM_DEVICES];
   5655 
   5656 #define SOC_TD_SER_MEM_AVAILABLE       (2048 * 32)  /* bits */
   5657 
   5658 STATIC int
   5659 _soc_trident_ser_init(int unit)
   5660 {
   5661     int alloc_size;
   5662 
   5663     /* First, make per-unit copy of the master TCAM list */
   5664     alloc_size = sizeof(_soc_td_ser_parity_info_template);
   5665     if (NULL == _soc_td_ser_parity_info[unit]) {
   5666         if ((_soc_td_ser_parity_info[unit] =
   5667              sal_alloc(alloc_size, "td tcam list")) == NULL) {
   5668             return SOC_E_MEMORY;
   5669         }
   5670     }
   5671     /* Make a fresh copy of the TCAM template info */
   5672     sal_memcpy(_soc_td_ser_parity_info[unit],
   5673                &(_soc_td_ser_parity_info_template),
   5674                alloc_size);
   5675 
   5676     return soc_ser_init(unit, _soc_td_ser_parity_info[unit],
   5677                         SOC_TD_SER_MEM_AVAILABLE);
   5678 }
   5679 
   5680 int
   5681 soc_trident_ser_mem_clear(int unit, soc_mem_t mem)
   5682 {
   5683     return soc_ser_mem_clear(unit, _soc_td_ser_parity_info[unit], mem);
   5684 }
   5685 
   5686 STATIC int
   5687 soc_trident_populate_tcam_log(int unit, soc_mem_t mem, soc_acc_type_t acc_type_target, int index)
   5688 {
   5689     int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1;
   5690     int i;
   5691     soc_acc_type_t acc_type;
   5692     _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit];
   5693     uint32 tmp_entry[SOC_MAX_MEM_WORDS];
   5694     int log_entry_size, id = 0, entry_dw, entry_found=0;
   5695     uint32 *cache;
   5696     uint8 *vmap;
   5697     uint32 regAddr;
   5698 
   5699     /* 
   5700     must be large enough for at least generic and terminator, as well as the
   5701     memory type since we might decode it in soc_ser_correction. 
   5702     */
   5703     log_entry_size = sizeof(soc_ser_log_tlv_hdr_t)*3 +
   5704                      sizeof(soc_ser_log_tlv_generic_t) +
   5705                      sizeof(soc_ser_log_tlv_memory_t);
   5706 
   5707     if((mem != INVALIDm) &&
   5708        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != SOC_MEM_FLAG_SER_SPECIAL) &&
   5709        (SOC_MEM_SER_CORRECTION_TYPE(unit, mem) != 0)) {
   5710         for (i = 0; i < num_tcams; i++) {
   5711             if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) ==
   5712                 _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) {
   5713                 acc_type = _SOC_ACC_TYPE_PIPE_Y;
   5714             } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) ==
   5715                         _SOC_SER_FLAG_MULTI_PIPE) {
   5716                 acc_type = _SOC_ACC_TYPE_PIPE_X;
   5717             } else {
   5718                 acc_type = _SOC_ACC_TYPE_PIPE_ANY;
   5719             }
   5720             if (tcam_info[i].mem == mem && 
   5721                 ((acc_type == acc_type_target) ||
   5722                  (acc_type_target == _SOC_ACC_TYPE_PIPE_GROUP))) {
   5723                 /*Disable parity*/
   5724                 MEM_LOCK(unit,mem);
   5725                 regAddr = soc_reg_addr(unit, CMIC_SER_PROTECT_ADDR_RANGE_VALIDr,
   5726                     REG_PORT_ANY, i/16);
   5727                 if (soc_pci_write(unit, regAddr, 0) < 0) {
   5728                     /* coverity[dead_error_line] */
   5729                     MEM_UNLOCK(unit,mem);
   5730                     return 0;
   5731                 }
   5732                 /*Read the memory */
   5733                 soc_trident_pipe_select(unit, TRUE, 
   5734                     (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0));
   5735                 soc_trident_pipe_select(unit, FALSE, 
   5736                     (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0));
   5737                 if (acc_type == _SOC_ACC_TYPE_PIPE_Y) {
   5738                     soc_mem_pipe_select_read(unit, SOC_MEM_NO_FLAGS, mem, 
   5739                                              MEM_BLOCK_ANY, acc_type,
   5740                                              index, tmp_entry);
   5741                 } else {
   5742                     /*Enable NACK on read */
   5743                     soc_mem_read_extended(unit, SOC_MEM_SCHAN_ERR_RETURN,
   5744                                            mem, 0, MEM_BLOCK_ANY,
   5745                                            index, tmp_entry);
   5746                 }
   5747 
   5748                 soc_trident_pipe_select(unit, TRUE, 0);
   5749                 soc_trident_pipe_select(unit, FALSE, 0);
   5750                 /*Enable parity*/
   5751                 /* coverity[result_independent_of_operands] */
   5752                 if (soc_pci_write(unit, regAddr, 0xFFFF) < 0) {
   5753                     /* coverity[dead_error_line] */
   5754                     MEM_UNLOCK(unit,mem);
   5755                     return 0;
   5756                 }
   5757                 entry_found = 1;
   5758                 MEM_UNLOCK(unit,mem);
   5759                 break;
   5760             }
   5761         }
   5762         if (entry_found != 0) {
   5763             entry_dw = soc_mem_entry_words(unit, mem);
   5764             log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   5765 
   5766             cache = SOC_MEM_STATE(unit, mem).cache[SOC_MEM_BLOCK_ANY(unit, mem)];
   5767             vmap = SOC_MEM_STATE(unit, mem).vmap[SOC_MEM_BLOCK_ANY(unit, mem)];
   5768             if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   5769                 log_entry_size += sizeof(soc_ser_log_tlv_hdr_t) + entry_dw*4;
   5770             }
   5771             
   5772             /* create the entry based on determined size, save id */
   5773             id = soc_ser_log_create_entry(unit, log_entry_size);
   5774 
   5775             /* fill in the memory contents tlv */
   5776             if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CONTENTS, entry_dw*4, tmp_entry) < 0) {
   5777                 return 0;
   5778             }
   5779             if(cache != NULL && CACHE_VMAP_TST(vmap, index)) {
   5780                 /* fill in the memory cache tlv */
   5781                 if (soc_ser_log_add_tlv(unit, id, SOC_SER_LOG_TLV_CACHE, 
   5782                         entry_dw*4, (cache + index*entry_dw)) < 0) {
   5783                     return 0;
   5784                 }
   5785             }
   5786         }
   5787     } else {
   5788         id = soc_ser_log_create_entry(unit, log_entry_size);
   5789     }
   5790     return id;
   5791 }
   5792 
   5793 STATIC void
   5794 soc_trident_ser_fail(int unit)
   5795 
   5796 {
   5797     soc_process_ser_parity_error(unit, _soc_td_ser_parity_info[unit],
   5798                                  _SOC_PARITY_TYPE_SER);
   5799     return;
   5800 }
   5801 
   5802 /* FCOE standard FC header configurations */
   5803 STATIC _soc_fcoe_header_info_t _soc_td_fcoe_header_info[] = {
   5804     { SOC_FCOE_HDR_TYPE_STD ,   0,     7 },
   5805     { SOC_FCOE_HDR_TYPE_STD ,   33,   35 },
   5806     { SOC_FCOE_HDR_TYPE_STD ,   50,   51 },
   5807     { SOC_FCOE_HDR_TYPE_STD ,   64,   71 },
   5808     { SOC_FCOE_HDR_TYPE_VFT ,   80,   80 },
   5809     { SOC_FCOE_HDR_TYPE_IFR ,   81,   81 },
   5810     { SOC_FCOE_HDR_TYPE_ENCAP,  82,   82 },
   5811     { SOC_FCOE_HDR_TYPE_STD,   128,  134 },
   5812     { SOC_FCOE_HDR_TYPE_STD,   192,  201 },
   5813     {0} /* end of headers */
   5814 };
   5815 
   5816 static int
   5817 _soc_trident_fcoe_config_init(int unit)
   5818 {
   5819     int index, rctl;
   5820 
   5821     for (index = 0; ;index++)
   5822     {
   5823         if (_soc_td_fcoe_header_info[index].fc_hdr_type == 0) {
   5824             /* End of the table */
   5825             break;
   5826         }
   5827 
   5828         /* Configure FCOE header for routing control indexes */
   5829         for (rctl = _soc_td_fcoe_header_info[index].r_ctl_min; 
   5830              rctl <= _soc_td_fcoe_header_info[index].r_ctl_max; rctl++)
   5831         {
   5832             SOC_IF_ERROR_RETURN(
   5833                 soc_mem_field32_modify(unit, FC_HEADER_TYPEm, rctl, 
   5834                 FC_HDR_ENCODEf, _soc_td_fcoe_header_info[index].fc_hdr_type));
   5835         }
   5836     }
   5837     return SOC_E_NONE;
   5838 }
   5839 
   5840 #define SOC_TD_MAX_EPIPE_TABLE_SIZE  (1024 * 16)
   5841 
   5842 STATIC int
   5843 _soc_trident_clear_all_memory(int unit)
   5844 {
   5845     soc_info_t          *si;
   5846     uint32              rval, fval;
   5847     int                 pipe_init_usec, index, count;
   5848     soc_timeout_t       to;
   5849     uint32              entry[SOC_MAX_MEM_WORDS];
   5850     int                 port, phy_port, blk_port, blk, bindex;
   5851     int                 tcam_protect_write;
   5852     static const soc_mem_t cam[] = {
   5853         CPU_COS_MAPm,
   5854         FP_GLOBAL_MASK_TCAMm,
   5855         FP_TCAMm,
   5856         FP_UDF_TCAMm,
   5857         L2_USER_ENTRYm,
   5858         L3_DEFIP_128m,
   5859         L3_DEFIPm,
   5860         L3_TUNNELm,
   5861         MY_STATION_TCAMm,
   5862         VFP_TCAMm,
   5863         VLAN_SUBNETm,
   5864         EFP_TCAMm,
   5865 #ifdef PLISIM
   5866         /* In HW, these are the same as FP_GLOBAL_MASK_TCAM.
   5867          * In simulation, they are separate instances.
   5868          */
   5869         FP_GM_FIELDSm,
   5870         FP_GLOBAL_MASK_TCAM_Xm,
   5871         FP_GLOBAL_MASK_TCAM_Ym
   5872 #endif
   5873     };
   5874 
   5875     si = &SOC_INFO(unit);
   5876 
   5877     /*
   5878      * Reset the IPIPE and EPIPE block
   5879      */
   5880     rval = 0;
   5881     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval));
   5882     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1);
   5883     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1);
   5884     /* Set count to # entries in largest IPIPE table (L2X) */
   5885     count = soc_mem_index_count(unit, L2Xm);
   5886     soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, count);
   5887     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   5888 
   5889     rval = 0;
   5890     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval));
   5891     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1);
   5892     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1);
   5893     /* Set count to maximum table size 16k */
   5894     count = SOC_TD_MAX_EPIPE_TABLE_SIZE;
   5895     soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, count);
   5896     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   5897 
   5898     /* For simulation, set timeout to 10 sec.  Otherwise, timeout = 50 ms */
   5899     if (SAL_BOOT_SIMULATION) {
   5900         pipe_init_usec = 10000000;
   5901     } else {
   5902         pipe_init_usec = 50000;
   5903     }
   5904     soc_timeout_init(&to, pipe_init_usec, 0);
   5905 
   5906     /* Wait for IPIPE memory initialization done. */
   5907     do {
   5908         SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval));
   5909         if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) {
   5910             break;
   5911         }
   5912         if (soc_timeout_check(&to)) {
   5913             LOG_WARN(BSL_LS_SOC_COMMON,
   5914                      (BSL_META_U(unit,
   5915                                  "unit %d : ING_HW_RESET timeout\n"), unit));
   5916             break;
   5917         }
   5918     } while (TRUE);
   5919 
   5920     /* Wait for EPIPE memory initialization done. */
   5921     do {
   5922         SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval));
   5923         if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) {
   5924             break;
   5925         }
   5926         if (soc_timeout_check(&to)) {
   5927             LOG_WARN(BSL_LS_SOC_COMMON,
   5928                      (BSL_META_U(unit,
   5929                                  "unit %d : EGR_HW_RESET timeout\n"), unit));
   5930             break;
   5931         }
   5932     } while (TRUE);
   5933 
   5934     rval = 0;
   5935     SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval));
   5936     SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval));
   5937 
   5938     /* TCAM tables are not handled by hardware reset control */
   5939     tcam_protect_write = SOC_CONTROL(unit)->tcam_protect_write;
   5940     SOC_CONTROL(unit)->tcam_protect_write = FALSE;
   5941     for (index = 0; index < sizeof(cam) / sizeof(soc_mem_t); index++) {
   5942 #ifdef PLISIM
   5943         if (!SAL_BOOT_PLISIM) {
   5944             if( (cam[index]==FP_GM_FIELDSm) ||
   5945                 (cam[index]==FP_GLOBAL_MASK_TCAM_Xm) ||
   5946                 (cam[index]==FP_GLOBAL_MASK_TCAM_Ym) ) {
   5947                 continue;
   5948             }
   5949         }
   5950 #endif
   5951         SOC_IF_ERROR_RETURN(soc_mem_clear(unit, cam[index], COPYNO_ALL, TRUE));
   5952     }
   5953     SOC_CONTROL(unit)->tcam_protect_write = tcam_protect_write;
   5954 
   5955     /* Do dummy read to clear the parity status latch */
   5956     SOC_IF_ERROR_RETURN
   5957         (READ_INITIAL_L3_ECMP_Xm(unit, MEM_BLOCK_ANY, 0, entry));
   5958     SOC_IF_ERROR_RETURN
   5959         (READ_INITIAL_L3_ECMP_Ym(unit, MEM_BLOCK_ANY, 0, entry));
   5960 
   5961     /* Some registers are implemented in memory, need to clear them in order
   5962      * to have correct parity value */
   5963     PBMP_ALL_ITER(unit, port) {
   5964         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, 0));
   5965         SOC_IF_ERROR_RETURN(WRITE_EGR_IPMC_CFG2r(unit, port, 0));
   5966     }
   5967 
   5968     /* Reset XLPORT MIB counter (registers implemented in memory). The clear
   5969      * function is implemented with read-modify-write, parity needs to be
   5970      * disabled */
   5971     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   5972         blk_port = SOC_BLOCK_PORT(unit, blk);
   5973         if (blk_port < 0) {
   5974             continue;
   5975         }
   5976         phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1;
   5977         fval = 0;
   5978         for (bindex = 0; bindex < 4; bindex++) {
   5979             if (si->port_p2l_mapping[phy_port + bindex] != -1) {
   5980                 fval |= 1 << bindex;
   5981             }
   5982         }
   5983         rval = 0;
   5984         soc_reg_field_set(unit, XLPORT_MIB_RESETr, &rval, CLR_CNTf, fval);
   5985         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, rval));
   5986         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, blk_port, 0));
   5987     }
   5988 
   5989     return SOC_E_NONE;
   5990 }
   5991 
   5992 int
   5993 soc_trident_pipe_select(int unit, int egress, int pipe)
   5994 {
   5995     soc_reg_t reg;
   5996     int rv;
   5997 
   5998     reg = egress ? EGR_SBS_CONTROLr : SBS_CONTROLr;
   5999 
   6000     SOC_ALLOW_WB_WRITE(unit,
   6001         soc_reg_field32_modify(unit, reg, REG_PORT_ANY, PIPE_SELECTf, pipe),
   6002         rv);
   6003 
   6004     return rv;
   6005 }
   6006 
   6007 int
   6008 _soc_trident_port_mapping_init(int unit)
   6009 {
   6010     soc_info_t *si;
   6011     soc_mem_t mem;
   6012     uint32 rval;
   6013     ing_physical_to_logical_port_number_mapping_table_entry_t entry;
   6014     int port, phy_port, mmu_port;
   6015     int num_port, num_phy_port, num_mmu_port;
   6016 
   6017     si = &SOC_INFO(unit);
   6018 
   6019     /* Ingress physical to logical port mapping */
   6020     mem = ING_PHYSICAL_TO_LOGICAL_PORT_NUMBER_MAPPING_TABLEm;
   6021     num_phy_port = soc_mem_index_count(unit, mem);
   6022     sal_memset(&entry, 0, sizeof(entry));
   6023     for (phy_port = 0; phy_port < num_phy_port; phy_port++) {
   6024         port = si->port_p2l_mapping[phy_port];
   6025         soc_mem_field32_set(unit, mem, &entry, LOGICAL_PORT_NUMBERf,
   6026                             port == -1 ? 0x7f : port);
   6027         SOC_IF_ERROR_RETURN
   6028             (soc_mem_write(unit, mem, MEM_BLOCK_ALL, phy_port, &entry));
   6029     }
   6030 
   6031     /* Ingress logical to physical port mapping */
   6032     num_port = soc_mem_index_count(unit, PORT_TABm);
   6033     rval = 0;
   6034     for (port = 0; port < num_port; port++) {
   6035         phy_port = si->port_l2p_mapping[port];
   6036         soc_reg_field_set(unit, IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   6037                           PHYSICAL_PORT_NUMf,
   6038                           phy_port == -1 ? 0x7f : phy_port);
   6039         SOC_IF_ERROR_RETURN
   6040             (WRITE_IFP_GM_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval));
   6041     }
   6042 
   6043     /* Egress logical to physical port mapping */
   6044     for (port = 0; port < num_port; port++) {
   6045         phy_port = si->port_l2p_mapping[port];
   6046         rval = 0;
   6047         soc_reg_field_set(unit, EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr,
   6048                           &rval, PHYSICAL_PORT_NUMBERf,
   6049                           phy_port == -1 ? 0x7f : phy_port);
   6050         SOC_IF_ERROR_RETURN
   6051             (WRITE_EGR_LOGICAL_TO_PHYSICAL_PORT_NUMBER_MAPPINGr(unit, port,
   6052                                                                 rval));
   6053 
   6054         rval = 0;
   6055         soc_reg_field_set(unit, EGR_VLAN_LOGICAL_TO_PHYSICAL_MAPPINGr, &rval,
   6056                           PHYSICAL_PORT_NUMf,
   6057                           phy_port == -1 ? 0x7f : phy_port);
   6058         SOC_IF_ERROR_RETURN
   6059             (WRITE_EGR_VLAN_LOGICAL_TO_PHYSICAL_MAPPINGr(unit, port, rval));
   6060     }
   6061 
   6062     /* MMU to physical port mapping and MMU to logical port mapping */
   6063     num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr);
   6064     for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) {
   6065         phy_port = si->port_m2p_mapping[mmu_port];
   6066         port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port];
   6067 
   6068         rval = 0;
   6069         soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf,
   6070                           phy_port == -1 ? 0x7f : phy_port);
   6071         SOC_IF_ERROR_RETURN
   6072             (WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval));
   6073 
   6074         rval = 0;
   6075         soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf,
   6076                           port == -1 ? 0x7f : port);
   6077         SOC_IF_ERROR_RETURN
   6078             (WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval));
   6079     }
   6080 
   6081     return SOC_E_NONE;
   6082 }
   6083 
   6084 /*
   6085  * cpu port (mmu port 0): 48 queues (0-47)
   6086  * loopback port (mmu port 33): 9 queues (0-8)
   6087  * extended ports (mmu port 1-4, 34-37): 74 unicast queues (0-9, 64-127)
   6088  *                                       5 multicast queues (0-4)
   6089  * regular port: 10 unicast queues (0-9)
   6090  *               5 multicast queues (0-4)
   6091  */
   6092 int
   6093 soc_trident_num_cosq_init(int unit)
   6094 {
   6095     soc_info_t *si;
   6096     int port, phy_port, mmu_port, mmu_cmic_port, mmu_lb_port;
   6097     int base_x, base_y;
   6098 
   6099     si = &SOC_INFO(unit);
   6100 
   6101     mmu_cmic_port = si->port_p2m_mapping[si->port_l2p_mapping[si->cmic_port]];
   6102     mmu_lb_port = si->port_p2m_mapping[si->port_l2p_mapping[si->lb_port]];
   6103 
   6104     base_x = 0;
   6105     base_y = 0;
   6106 
   6107     PBMP_ALL_ITER(unit, port) {
   6108         phy_port = si->port_l2p_mapping[port];
   6109         mmu_port = si->port_p2m_mapping[phy_port];
   6110 
   6111         si->port_num_cosq[port] = 5;
   6112         si->port_num_uc_cosq[port] = 10;
   6113         if (phy_port <= 36) { /* X pipe */
   6114             if (mmu_port == mmu_cmic_port) {
   6115                 si->port_num_cosq[port] = 48;
   6116                 si->port_num_uc_cosq[port] = 0;
   6117                 si->port_group[port] = -1;
   6118             } else {
   6119                 if (mmu_port <= mmu_cmic_port + 4) {
   6120                     si->port_num_ext_cosq[port] = 64;
   6121                 }
   6122                 if (phy_port <= 20) {
   6123                     si->port_group[port] = 0; /* PORT_GROUP5_X */
   6124                 } else {
   6125                     si->port_group[port] = 1; /* PORT_GROUP4_X */
   6126                 }
   6127             }
   6128             if (si->port_num_uc_cosq[port] != 0) {
   6129                 si->port_uc_cosq_base[port] = base_x;
   6130                 base_x += si->port_num_uc_cosq[port];
   6131             }
   6132             if (si->port_num_cosq[port] != 0) {
   6133                 si->port_cosq_base[port] = base_x;
   6134                 base_x += si->port_num_cosq[port];
   6135             }
   6136             if (si->port_num_ext_cosq[port] != 0) {
   6137                 si->port_ext_cosq_base[port] = base_x;
   6138                 base_x += si->port_num_ext_cosq[port];
   6139             }
   6140         } else { /* Y pipe */
   6141             if (mmu_port == mmu_lb_port) {
   6142                 si->port_num_cosq[port] = 9;
   6143                 si->port_num_uc_cosq[port] = 0;
   6144                 si->port_group[port] = -1;
   6145             } else {
   6146                 if (mmu_port <= mmu_lb_port + 4) {
   6147                     si->port_num_ext_cosq[port] = 64;
   6148                 }
   6149                 if (phy_port <= 56) {
   6150                     si->port_group[port] = 2; /* PORT_GROUP5_Y */
   6151                 } else {
   6152                     si->port_group[port] = 3; /* PORT_GROUP4_Y */
   6153                 }
   6154             }
   6155             if (si->port_num_uc_cosq[port] != 0) {
   6156                 si->port_uc_cosq_base[port] = base_y;
   6157                 base_y += si->port_num_uc_cosq[port];
   6158             }
   6159             if (si->port_num_cosq[port] != 0) {
   6160                 si->port_cosq_base[port] = base_y;
   6161                 base_y += si->port_num_cosq[port];
   6162             }
   6163             if (si->port_num_ext_cosq[port] != 0) {
   6164                 si->port_ext_cosq_base[port] = base_y;
   6165                 base_y += si->port_num_ext_cosq[port];
   6166             }
   6167         }
   6168     }
   6169 
   6170     return SOC_E_NONE;
   6171 }
   6172 
   6173 /*
   6174  * EGR_PERQ_XMT_COUNTERS_BASE_ADDR is indexed by:
   6175  * port number[6:0], queue number[6], mcast(1)/ucast(0)
   6176  *
   6177  * EGR_PERQ_XMT_COUNTERS_X: can hold up to 784 counters
   6178  *                          (cpu + 28 regular + 4 extended)
   6179  * EGR_PERQ_XMT_COUNTERS_Y: can hold up to 745 counters
   6180  *                          (loopback + 28 regular + 4 extended)
   6181  */
   6182 int
   6183 soc_trident_get_egr_perq_xmt_counters_size(int unit, int *num_entries_x,
   6184                                            int *num_entries_y)
   6185 {
   6186     soc_info_t *si;
   6187     soc_port_t port;
   6188 
   6189     si = &SOC_INFO(unit);
   6190 
   6191     *num_entries_x = *num_entries_y = 0;
   6192     PBMP_ALL_ITER(unit, port) {
   6193         if (IS_CPU_PORT(unit, port) ||
   6194             (si->port_group[port] >= 0 && si->port_group[port] <= 1)) {
   6195             *num_entries_x += si->port_num_cosq[port] +
   6196                 si->port_num_uc_cosq[port] + si->port_num_ext_cosq[port];
   6197         } else {
   6198             *num_entries_y += si->port_num_cosq[port] +
   6199                 si->port_num_uc_cosq[port] + si->port_num_ext_cosq[port];
   6200         }
   6201     }
   6202 
   6203     return SOC_E_NONE;
   6204 }
   6205 
   6206 STATIC int
   6207 _soc_trident_egr_perq_xmt_counters_init(int unit)
   6208 {
   6209     soc_info_t *si;
   6210     soc_port_t port;
   6211     egr_perq_xmt_counters_base_addr_entry_t entry;
   6212 
   6213     si = &SOC_INFO(unit);
   6214     sal_memset(&entry, 0, sizeof(entry));
   6215     PBMP_ALL_ITER(unit, port) {
   6216         if (si->port_num_uc_cosq[port] != 0) {
   6217             soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry,
   6218                                 BASEf, si->port_uc_cosq_base[port]);
   6219             SOC_IF_ERROR_RETURN
   6220                 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm,
   6221                                MEM_BLOCK_ALL, port << 2, &entry));
   6222         }
   6223         if (si->port_num_cosq[port] != 0) {
   6224             soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry,
   6225                                 BASEf, si->port_cosq_base[port]);
   6226             SOC_IF_ERROR_RETURN
   6227                 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm,
   6228                                MEM_BLOCK_ALL, (port << 2) + 1, &entry));
   6229         }
   6230         if (si->port_num_ext_cosq[port] != 0) {
   6231             soc_mem_field32_set(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm, &entry,
   6232                                 BASEf, si->port_ext_cosq_base[port]);
   6233             SOC_IF_ERROR_RETURN
   6234                 (soc_mem_write(unit, EGR_PERQ_XMT_COUNTERS_BASE_ADDRm,
   6235                                MEM_BLOCK_ALL, (port << 2) + 2, &entry));
   6236         }
   6237     }
   6238 
   6239     return SOC_E_NONE;
   6240 }
   6241 
   6242 
   6243 #define _TD_BLKS_PER_PIPE    9
   6244 #define _TD_BLKS_PER_GROUP   5 /* can be 4 or 5 */
   6245 #define _TD_PORTS_PER_BLK    4
   6246 #define _TD_TDM_SLOT_IDLE   -1
   6247 #define _TD_TDM_SLOT_NULL   -2
   6248 #define _TD_TDM_NUM_COLUMNS 4
   6249 #define _TD_TDM_NUM_SLOTS   8
   6250 
   6251 /*
   6252  * Trident port mapping
   6253  *     74 physical ports: port 0-36 in X pipe, port 37-73 in Y pipe
   6254  *     66 logical ports
   6255  *     66 mmu ports: port 0-32 in X pipe, port 33-65 in Y pipe
   6256  *     cpu port number is fixed: physical 0, logical 0, mmu 0
   6257  *     loopback port number is fixed: physical 73, logical 65, mmu 33
   6258  *     physical port 1-4 can be converted to GE port
   6259  *     mmu port can only map to physical port ID in the same pipe
   6260  * This routine will setup:
   6261  *     SOC_INFO(unit).port_p2l_mapping[]
   6262  *     SOC_INFO(unit).port_l2p_mapping[]
   6263  *     SOC_INFO(unit).port_p2m_mapping[]
   6264  *     SOC_INFO(unit).port_m2p_mapping[]
   6265  *     SOC_INFO(unit).port_speed_max[]
   6266  *     SOC_INFO(unit).port_num_lanes[]
   6267  *     SOC_INFO(unit).eq_pbm
   6268  */
   6269 int
   6270 soc_trident_port_config_init(int unit, uint16 dev_id)
   6271 {
   6272     soc_info_t *si;
   6273     char *config_str, *sub_str, *sub_str_end;
   6274     static const char str_eq[] = "EQ";
   6275     static const char str_2p5[] = "2.5";
   6276     char option1;
   6277     char str_buf[8];
   6278     int rv;
   6279     int port, phy_port, mmu_port;
   6280     int pipe, group, blk;
   6281     int port_bandwidth, blk_bandwidth, pg_bandwidth;
   6282     int ext_queue, index, count;
   6283     int port_count[2], eq_port_count[2];
   6284     int blk_port[4], blk_port_bandwidth[4];
   6285     int eq_port[2][4], mmu_port_base[2];
   6286     int fifo_index, fifo_count[2], extra_fifo_count[2], unused_fifo[12];
   6287     pbmp_t pbmp_4fifo[2], pbmp_2fifo[2], pbmp_1fifo[2];
   6288 
   6289 
   6290     si = &SOC_INFO(unit);
   6291 
   6292     switch (dev_id) {
   6293     case BCM56841_DEVICE_ID:
   6294     case BCM56842_DEVICE_ID:
   6295     case BCM56549_DEVICE_ID:
   6296     case BCM56053_DEVICE_ID:
   6297     case BCM56742_DEVICE_ID:
   6298     case BCM56838_DEVICE_ID:
   6299         si->bandwidth = 320000;
   6300         break;
   6301     case BCM56840_DEVICE_ID:
   6302     case BCM56843_DEVICE_ID:
   6303     case BCM56743_DEVICE_ID:
   6304     case BCM56844_DEVICE_ID:
   6305     case BCM56744_DEVICE_ID:
   6306         si->bandwidth = 480000;
   6307         break;
   6308     case BCM56845_DEVICE_ID:
   6309     case BCM56847_DEVICE_ID:        
   6310     case BCM56745_DEVICE_ID:
   6311     case BCM56846_DEVICE_ID:
   6312     case BCM56746_DEVICE_ID:
   6313     case BCM56831_DEVICE_ID:
   6314     case BCM56835_DEVICE_ID:
   6315     case BCM56849_DEVICE_ID:
   6316         si->bandwidth = 640000;
   6317         break;
   6318     default:
   6319         return SOC_E_INTERNAL;
   6320     }
   6321 
   6322     /* cpu port is physical port 0, logical port 0, mmu port 0 */
   6323     /* coverity[result_independent_of_operands] */
   6324     SOC_PORT_P2L_MAPPING_SET(unit, 0, 0);
   6325     /* coverity[result_independent_of_operands] */
   6326     SOC_PORT_P2M_MAPPING_SET(unit, 0, 0);
   6327     /* loopback port is physical port 73, logical port 65, mmu port 33 */
   6328     SOC_PORT_P2L_MAPPING_SET(unit, 73, 65);
   6329     SOC_PORT_P2M_MAPPING_SET(unit, 73, 33);
   6330     for (phy_port = 1; phy_port < 73; phy_port++) {
   6331         SOC_PORT_P2L_MAPPING_SET(unit, phy_port, -1);
   6332         SOC_PORT_P2M_MAPPING_SET(unit, phy_port, -1);
   6333     }
   6334     for (port = 0; port < 66; port++) {
   6335         SOC_PORT_L2P_MAPPING_SET(unit, port, -1);
   6336         SOC_PORT_M2P_MAPPING_SET(unit, port, -1);
   6337         SOC_PORT_SPEED_MAX_SET(unit, port, -1);
   6338     }
   6339     SOC_PBMP_CLEAR(si->eq_pbm);
   6340     SOC_PBMP_PORT_SET(si->xpipe_pbm, 0);  /* cpu port */
   6341     SOC_PBMP_PORT_SET(si->ypipe_pbm, 65); /* loopback port */
   6342 
   6343     port_count[0] = eq_port_count[0] = 0; /* X pipe */
   6344     port_count[1] = eq_port_count[1] = 0; /* Y pipe */
   6345 
   6346     rv = SOC_E_NONE;
   6347 
   6348     if (dev_id == BCM56849_DEVICE_ID) {
   6349         if (soc_property_get(unit, spn_BCM56849_56X2POINT5_8X10, 1)) {
   6350             /* 56x1GE/2.5GE + 8x10GE */
   6351             for (port = 1; port < 65; port++) {
   6352                 if (port < 57) {
   6353                     port_bandwidth = 2500;                    
   6354                     if (port < 29) {
   6355                         phy_port = port; 
   6356                     } else  {
   6357                         phy_port = port + 16;
   6358                     }
   6359                 } else {
   6360                     port_bandwidth = 10000;
   6361                     if (port < 61) {
   6362                         phy_port = port - 28; 
   6363                     } else  {
   6364                         phy_port = port - 24;
   6365                     }                     
   6366                 }
   6367 
   6368                 if (si->port_p2l_mapping[phy_port] != -1) {
   6369                     LOG_CLI((BSL_META_U(unit,
   6370                                         "Port %d: Physical port %d is used by port %d\n"),
   6371                              port, phy_port, si->port_p2l_mapping[phy_port]));
   6372                     rv = SOC_E_FAIL;
   6373                     continue;
   6374                 }
   6375 
   6376                 pipe = phy_port < 37 ? 0 : 1;
   6377                 if (port_count[pipe] >= 32) {
   6378                     LOG_CLI((BSL_META_U(unit,
   6379                                         "Can not configure more than 32 port in "
   6380                                         "%c pipeline\n"), pipe ? 'Y' : 'X'));
   6381                     rv = SOC_E_FAIL;
   6382                     continue;
   6383                 }
   6384                 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port);
   6385                 SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port);
   6386                 SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth);
   6387                 port_count[pipe]++;                
   6388             }
   6389         } else {
   6390             /* 60x1GE/2.5GE +2x40GE */
   6391             for (port = 1; port < 63; port++) {
   6392                 if (port < 61) {
   6393                     port_bandwidth = 2500;                    
   6394                     if (port < 31) {
   6395                         phy_port = port; 
   6396                     } else if (port < 33){
   6397                         phy_port = port + 6;
   6398                     } else {
   6399                         phy_port = port + 12;
   6400                     }
   6401                 } else {
   6402                     port_bandwidth = 40000;
   6403                     if (port == 61) {
   6404                         phy_port = 33; 
   6405                     } else  {
   6406                         phy_port = 41;
   6407                     }                     
   6408                 }
   6409 
   6410                 if (si->port_p2l_mapping[phy_port] != -1) {
   6411                     LOG_CLI((BSL_META_U(unit,
   6412                                         "Port %d: Physical port %d is used by port %d\n"),
   6413                              port, phy_port, si->port_p2l_mapping[phy_port]));
   6414                     rv = SOC_E_FAIL;
   6415                     continue;
   6416                 }
   6417 
   6418                 pipe = phy_port < 37 ? 0 : 1;
   6419                 if (port_count[pipe] >= 32) {
   6420                     LOG_CLI((BSL_META_U(unit,
   6421                                         "Can not configure more than 32 port in "
   6422                                         "%c pipeline\n"), pipe ? 'Y' : 'X'));
   6423                     rv = SOC_E_FAIL;
   6424                     continue;
   6425                 }
   6426                 SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port);
   6427                 SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port);
   6428                 SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth);
   6429                 port_count[pipe]++;                
   6430             }
   6431         }
   6432     } else {
   6433         for (port = 1; port < 65; port++) {
   6434             config_str = soc_property_port_get_str(unit, port, spn_PORTMAP);
   6435             if (config_str == NULL) {
   6436                 continue;
   6437             }
   6438 
   6439             /*
   6440              * portmap.<port>=<physical port number>:<bandwidth in Gb>[:<4(num lanes)>]
   6441              *                [:<queue config>]
   6442              * [<4(num lanes)>] only used for 20G port.
   6443              */
   6444             sub_str = config_str;
   6445 
   6446             /* Parsing physical port number */
   6447             phy_port = sal_ctoi(sub_str, &sub_str_end);
   6448             if (sub_str == sub_str_end) {
   6449                 LOG_CLI((BSL_META_U(unit,
   6450                                     "Port %d: Missing physical port information \"%s\"\n"),
   6451                          port, config_str));
   6452                 rv = SOC_E_FAIL;
   6453                 continue;
   6454             }
   6455             if (phy_port < 1 || phy_port > 72) {
   6456                 LOG_CLI((BSL_META_U(unit,
   6457                                     "Port %d: Invalid physical port number %d\n"),
   6458                          port, phy_port));
   6459                 rv = SOC_E_FAIL;
   6460                 continue;
   6461             }
   6462             if (si->port_p2l_mapping[phy_port] != -1) {
   6463                 LOG_CLI((BSL_META_U(unit,
   6464                                     "Port %d: Physical port %d is used by port %d\n"),
   6465                          port, phy_port, si->port_p2l_mapping[phy_port]));
   6466                 rv = SOC_E_FAIL;
   6467                 continue;
   6468             }
   6469             pipe = phy_port < 37 ? 0 : 1;
   6470             if (port_count[pipe] >= 32) {
   6471                 LOG_CLI((BSL_META_U(unit,
   6472                                     "Can not configure more than 32 port in "
   6473                                     "%c pipeline\n"), pipe ? 'Y' : 'X'));
   6474                 rv = SOC_E_FAIL;
   6475                 continue;
   6476             }
   6477 
   6478             /* Skip ':' */
   6479             sub_str = sub_str_end;
   6480             if (*sub_str != '\0') {
   6481                 if (*sub_str != ':') {
   6482                     LOG_CLI((BSL_META_U(unit,
   6483                                         "Port %d: Bad config string \"%s\"\n"),
   6484                              port, config_str));
   6485                     rv = SOC_E_FAIL;
   6486                     continue;
   6487                 }
   6488                 sub_str++;
   6489             }
   6490 
   6491             /* Parsing bandwidth */
   6492             for (index = 0; index < sizeof(str_2p5) - 1; index++) {
   6493                 if (sub_str[index] == '\0') {
   6494                     break;
   6495                 }
   6496                 str_buf[index] = sub_str[index];
   6497             }
   6498             str_buf[index] = '\0';
   6499             if (!sal_strcmp(str_buf, str_2p5)) {
   6500                 port_bandwidth = 2500;
   6501                 sub_str_end = &sub_str[sizeof(str_2p5) - 1];
   6502             } else {
   6503                 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000;
   6504                 if (sub_str == sub_str_end) {
   6505                     LOG_CLI((BSL_META_U(unit,
   6506                                         "Port %d: Missing bandwidth information \"%s\"\n"),
   6507                              port, config_str));
   6508                     rv = SOC_E_FAIL;
   6509                     continue;
   6510                 }
   6511                 if (port_bandwidth != 1000 && port_bandwidth != 10000 &&
   6512                     port_bandwidth != 15000 && port_bandwidth != 20000 &&
   6513                     port_bandwidth != 21000 && port_bandwidth != 25000 &&
   6514                     port_bandwidth != 30000 && port_bandwidth != 40000) {
   6515                     LOG_CLI((BSL_META_U(unit,
   6516                                         "Port %d: Invalid bandwidth %d Gb\n"),
   6517                              port, port_bandwidth / 1000));
   6518                     rv = SOC_E_FAIL;
   6519                     continue;
   6520                 }
   6521             }
   6522 
   6523             /* Skip ':' */
   6524             sub_str = sub_str_end;
   6525             if (*sub_str != '\0') {
   6526                 if (*sub_str != ':') {
   6527                     LOG_CLI((BSL_META_U(unit,
   6528                                         "Port %d: Bad config string \"%s\"\n"),
   6529                              port, config_str));
   6530                     rv = SOC_E_FAIL;
   6531                     continue;
   6532                 }
   6533                 sub_str++;
   6534             }
   6535 
   6536             /* Parsing optional lane num  */
   6537             option1 = 0;
   6538             if (*sub_str != '\0') {
   6539                 if ((*sub_str == '2') || (*sub_str == '4')) {
   6540                     if (port_bandwidth != 20000) {
   6541                         LOG_CLI((BSL_META_U(unit,
   6542                                             "Port %d: Invalid bandwidth %d Gb\n"),
   6543                                  port, port_bandwidth / 1000));
   6544                         rv = SOC_E_FAIL;
   6545                         continue;
   6546                     }
   6547                     option1 = *sub_str;
   6548                     sub_str++;
   6549                 }
   6550             }
   6551 
   6552             /* Skip ':' */
   6553             if (*sub_str != '\0' && option1) {
   6554                 if (*sub_str != ':') {
   6555                     LOG_CLI((BSL_META_U(unit,
   6556                                         "Port %d: Bad config string \"%s\"\n"),
   6557                              port, config_str));
   6558                     rv = SOC_E_FAIL;
   6559                     continue;
   6560                 }
   6561                 sub_str++;
   6562             }
   6563 
   6564             /* Parsing optional queue config */
   6565             ext_queue = FALSE;
   6566             for (index = 0; index < sizeof(str_eq) - 1; index++) {
   6567                 if (sub_str[index] == '\0') {
   6568                     break;
   6569                 }
   6570                 if (sub_str[index] > 'a' && sub_str[index] < 'z') {
   6571                     str_buf[index] = sub_str[index] & ~0x20;
   6572                 } else {
   6573                     str_buf[index] = sub_str[index];
   6574                 }
   6575             }
   6576             str_buf[index] = '\0';
   6577             if (!sal_strcmp(str_buf, str_eq)) {
   6578                 if ((dev_id == BCM56838_DEVICE_ID)
   6579                     || (dev_id == BCM56831_DEVICE_ID)) {
   6580                     LOG_CLI((BSL_META_U(unit,
   6581                                         "Chip %s: Can not support extended "
   6582                                         "queue \n"),
   6583                              soc_dev_name(unit)));
   6584                     rv = SOC_E_FAIL;
   6585                     continue;
   6586                 }
   6587                 ext_queue = TRUE;
   6588                 sub_str += sizeof(str_eq) - 1;
   6589 
   6590                 if (eq_port_count[pipe] >= 4) {
   6591                     LOG_CLI((BSL_META_U(unit,
   6592                                         "Port %d %d %d %d %d: Can not configure more than"
   6593                                         " 4 extended queue port in %c pipeline\n"),
   6594                              si->port_p2l_mapping[eq_port[pipe][0]],
   6595                              si->port_p2l_mapping[eq_port[pipe][1]],
   6596                              si->port_p2l_mapping[eq_port[pipe][2]],
   6597                              si->port_p2l_mapping[eq_port[pipe][3]],
   6598                              port, pipe ? 'Y' : 'X'));
   6599                     rv = SOC_E_FAIL;
   6600                     continue;
   6601                 }
   6602             }
   6603 
   6604             /* Checking trailing string */
   6605             if (*sub_str != '\0') {
   6606                 LOG_CLI((BSL_META_U(unit,
   6607                                     "Port %d: Bad config string \"%s\"\n"),
   6608                          port, config_str));
   6609                 rv = SOC_E_FAIL;
   6610                 continue;
   6611             }
   6612 
   6613             SOC_PORT_P2L_MAPPING_SET(unit, phy_port, port);
   6614             SOC_PORT_L2P_MAPPING_SET(unit, port, phy_port);
   6615             SOC_PORT_SPEED_MAX_SET(unit, port, port_bandwidth);
   6616             if (option1 == '4') {
   6617                 SOC_PORT_NUM_LANES_SET(unit, port, 4);
   6618             }
   6619             port_count[pipe]++;
   6620             if (ext_queue) {
   6621                 eq_port[pipe][eq_port_count[pipe]] = port;
   6622                 eq_port_count[pipe]++;
   6623             }
   6624         }
   6625     } 
   6626     
   6627     /* Bandwidth check for ports in each XLPORT block */
   6628     for (pipe = 0; pipe < 2; pipe++) {
   6629         for (group = 0; group < 2; group++) {
   6630             pg_bandwidth = 0;
   6631             for (blk = 0; blk < (group ? 4 : 5); blk++) {
   6632                 /* Skip QGPORT (1G x 4) in XLPORT0 block (if present) */
   6633                 if (pipe == 0 && group == 0 && blk == 0) {
   6634                     for (index = 0; index < _TD_PORTS_PER_BLK; index++) {
   6635                         port = si->port_p2l_mapping[1 + index];
   6636                         if (port != -1 && si->port_speed_max[port] > 1000) {
   6637                             break;
   6638                         }
   6639                     }
   6640                     if (index == _TD_PORTS_PER_BLK) {
   6641                         continue;
   6642                     }
   6643                 }
   6644                 blk_bandwidth = 0;
   6645                 for (index = 0; index < 4; index++) {
   6646                     phy_port = 1 + pipe * 36 + group * 20 + blk * 4 + index;
   6647                     port = si->port_p2l_mapping[phy_port];
   6648                     blk_port[index] = port;
   6649                     if (port == -1) {
   6650                         blk_port_bandwidth[index] = 0;
   6651                         continue;
   6652                     }
   6653                     blk_port_bandwidth[index] = si->port_speed_max[port];
   6654                     if ((blk_port_bandwidth[index] > 20000 && index != 0) ||
   6655                         (blk_port_bandwidth[index] > 10000 && (index & 1))) {
   6656                         LOG_CLI((BSL_META_U(unit,
   6657                                             "Port %d: Physical port %d can not be "
   6658                                             "configured to %d Gb\n"),
   6659                                  port, phy_port,
   6660                                  blk_port_bandwidth[index] / 1000));
   6661                         rv = SOC_E_FAIL;
   6662                         continue;
   6663                     }
   6664                     blk_bandwidth += blk_port_bandwidth[index];
   6665 
   6666                     /* 21G uses same bandwidth as 20G in higig2 mode */
   6667                     if (blk_port_bandwidth[index] == 21000) {
   6668                         blk_bandwidth -= 1000;
   6669                     }
   6670                 }
   6671                 if ((blk_port_bandwidth[0] > 20000) ||
   6672                     ((blk_port[0] != -1) &&
   6673                     (si->port_num_lanes[blk_port[0]] == 4))) {
   6674                     for (index = 1; index < 4; index++) {
   6675                         if (blk_port[index] == -1) {
   6676                             continue;
   6677                         }
   6678                         LOG_CLI((BSL_META_U(unit,
   6679                                             "Port %d bandwidth %d Gb and "
   6680                                             "port %d can not be both configured\n"),
   6681                                  blk_port[0], blk_port_bandwidth[0] / 1000,
   6682                                  blk_port[index]));
   6683                         rv = SOC_E_FAIL;
   6684                     }
   6685                 } else if (blk_port_bandwidth[0] > 10000 ||
   6686                            blk_port_bandwidth[2] > 10000) {
   6687                     if (blk_port_bandwidth[0] > 10000 && blk_port[1] != -1) {
   6688                         LOG_CLI((BSL_META_U(unit,
   6689                                             "Port %d bandwidth %d Gb and "
   6690                                             "port %d can not be both configured\n"),
   6691                                  blk_port[0],
   6692                                  si->port_speed_max[blk_port[0]] / 1000,
   6693                                  blk_port[1]));
   6694                         rv = SOC_E_FAIL;
   6695                     }
   6696                     if (blk_port_bandwidth[2] > 10000 && blk_port[3] != -1) {
   6697                         LOG_CLI((BSL_META_U(unit,
   6698                                             "Port %d bandwidth %d Gb and "
   6699                                             "port %d can not be both configured\n"),
   6700                                  blk_port[2],
   6701                                  si->port_speed_max[blk_port[2]] / 1000,
   6702                                  blk_port[3]));
   6703                         rv = SOC_E_FAIL;
   6704                     }
   6705                     if (blk_port[0] == -1) {
   6706                         LOG_CLI((BSL_META_U(unit,
   6707                                             "Physical port %d needs to be configred "
   6708                                             "in order to work with port %d\n"),
   6709                                  1 + pipe * 36 + group * 20 + blk * 4,
   6710                                  blk_port[2]));
   6711                         rv = SOC_E_FAIL;
   6712                     } else if (blk_port[2] != -1 &&
   6713                                si->port_speed_max[blk_port[0]] !=
   6714                                si->port_speed_max[blk_port[2]]) {
   6715                         LOG_CLI((BSL_META_U(unit,
   6716                                             "Port %d bandwidth %d Gb can not have "
   6717                                             "different bandwidth with port %d "
   6718                                             "bandwidth %d Gb\n"),
   6719                                  blk_port[0],
   6720                                  si->port_speed_max[blk_port[0]] / 1000,
   6721                                  blk_port[2],
   6722                                  si->port_speed_max[blk_port[2]] / 1000));
   6723                         rv = SOC_E_FAIL;
   6724                     }
   6725                 }
   6726                 if (blk_bandwidth > 40000) {
   6727                     LOG_CLI((BSL_META_U(unit,
   6728                                         "XLPORT%d bandwidth %d Gb exceed limit\n"),
   6729                              pipe * 9 + group * 5 + blk,
   6730                              blk_bandwidth / 1000));
   6731                     rv = SOC_E_FAIL;
   6732                 }
   6733                 pg_bandwidth += blk_bandwidth;
   6734             }
   6735             if (pg_bandwidth > si->bandwidth / 4) {
   6736                 LOG_CLI((BSL_META_U(unit,
   6737                                     "PORT_GROUP%d_%c bandwidth %d Gb exceed limit\n"),
   6738                          group ? 4 : 5, pipe ? 'Y' : 'X',
   6739                          pg_bandwidth / 1000));
   6740                 rv = SOC_E_FAIL;
   6741             }
   6742         }
   6743     }
   6744 
   6745     if (SOC_FAILURE(rv)) {
   6746         for (phy_port = 1; phy_port < 73; phy_port++) {
   6747             SOC_PORT_P2L_MAPPING_SET(unit, phy_port, -1);
   6748         }
   6749         return rv;
   6750     }
   6751 
   6752     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   6753         LOG_CLI((BSL_META_U(unit,
   6754                             "physical to logical mapping:")));
   6755         for (index = 0; index < 74; index++) {
   6756             if (index % 16 == 0) {
   6757                 LOG_CLI((BSL_META_U(unit,
   6758                                     "\n    ")));
   6759             }
   6760             LOG_CLI((BSL_META_U(unit,
   6761                                 " %3d"),
   6762                      si->port_p2l_mapping[index]));
   6763         }
   6764         LOG_CLI((BSL_META_U(unit,
   6765                             "\n")));
   6766         LOG_CLI((BSL_META_U(unit,
   6767                             "physical port bandwidth:")));
   6768         for (index = 0; index < 74; index++) {
   6769             if (index % 16 == 0) {
   6770                 LOG_CLI((BSL_META_U(unit,
   6771                                     "\n    ")));
   6772             }
   6773             port = si->port_p2l_mapping[index];
   6774             if (port == -1) {
   6775                 LOG_CLI((BSL_META_U(unit,
   6776                                     "  -1")));
   6777             } else if (si->port_speed_max[port] == 2500) {
   6778                 LOG_CLI((BSL_META_U(unit,
   6779                                     " 2.5")));
   6780             } else {
   6781                 LOG_CLI((BSL_META_U(unit,
   6782                                     " %3d"),
   6783                          si->port_speed_max[port] / 1000));
   6784             }
   6785         }
   6786         LOG_CLI((BSL_META_U(unit,
   6787                             "\n")));
   6788     }
   6789 
   6790     /* Assign MMU port */
   6791     mmu_port_base[0] = 1;
   6792     mmu_port_base[1] = 34;
   6793     fifo_count[0] = fifo_count[1] = 0;
   6794 
   6795     /*
   6796      * To improve multicast performace, try assigning 4 fifo (instead of 1)
   6797      * for ports in single mode or 2 fifo for ports in dual mode. It is not
   6798      * always possible to assign such extra fifo when special GE port in
   6799      * XLPORT0 is in user portmap.
   6800      */
   6801     SOC_PBMP_CLEAR(pbmp_4fifo[0]);
   6802     SOC_PBMP_CLEAR(pbmp_4fifo[1]);
   6803     SOC_PBMP_CLEAR(pbmp_2fifo[0]);
   6804     SOC_PBMP_CLEAR(pbmp_2fifo[1]);
   6805     SOC_PBMP_CLEAR(pbmp_1fifo[0]);
   6806     SOC_PBMP_CLEAR(pbmp_1fifo[1]);
   6807     extra_fifo_count[0] = 0;
   6808     extra_fifo_count[1] = 0;
   6809 
   6810     si->port_pipe[0] = 0;
   6811     si->port_pipe[65]  = 1;
   6812 
   6813     for (port = 1; port < 65; port++) {
   6814         phy_port = si->port_l2p_mapping[port];
   6815         if (phy_port == -1) {
   6816             continue;
   6817         }
   6818         if (phy_port < 37) { /* X-pipe */
   6819             pipe = 0;
   6820             SOC_PBMP_PORT_ADD(si->xpipe_pbm, port);
   6821         } else { /* Y-pipe */
   6822             pipe = 1;
   6823             SOC_PBMP_PORT_ADD(si->ypipe_pbm, port);
   6824         }
   6825 
   6826         si->port_pipe[port] = pipe;
   6827 
   6828         if (si->port_speed_max[port] > 20000 ||
   6829             si->port_num_lanes[port] == 4) {
   6830             if (port_count[pipe] + extra_fifo_count[pipe] + 3 <= 32) {
   6831                 /* has more than 3 unused fifo can be assigned to this port */
   6832                 SOC_PBMP_PORT_ADD(pbmp_4fifo[pipe], port);
   6833                 extra_fifo_count[pipe] += 3;
   6834             } else {
   6835                 SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port);
   6836             }
   6837         } else if (si->port_speed_max[port] > 10000) {
   6838             /* has more than 1 unused fifo can be assigned to this port */
   6839             if (port_count[pipe] + extra_fifo_count[pipe] + 1 <= 32) {
   6840                 SOC_PBMP_PORT_ADD(pbmp_2fifo[pipe], port);
   6841                 extra_fifo_count[pipe] += 1;
   6842             } else {
   6843                 SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port);
   6844             }
   6845         } else {
   6846             SOC_PBMP_PORT_ADD(pbmp_1fifo[pipe], port);
   6847         }
   6848     }
   6849 
   6850     for (pipe = 0; pipe < SOC_MAX_NUM_PIPES; pipe++) {
   6851         if (0 == pipe) {
   6852             SOC_PBMP_ASSIGN(si->pipe_pbm[pipe], si->xpipe_pbm);
   6853         } else if (1 == pipe) {
   6854             SOC_PBMP_ASSIGN(si->pipe_pbm[pipe], si->ypipe_pbm);
   6855         }
   6856     }
   6857     
   6858     /* User specified extended queuing ports */
   6859     for (pipe = 0; pipe < 2; pipe++) {
   6860         for (index = 0; index < eq_port_count[pipe]; index++) {
   6861             port = eq_port[pipe][index];
   6862             phy_port = si->port_l2p_mapping[port];
   6863             mmu_port = mmu_port_base[pipe] + index;
   6864             SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port);
   6865             SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port);
   6866             SOC_PBMP_PORT_ADD(si->eq_pbm, port);
   6867             fifo_count[pipe] += 4;
   6868         }
   6869     }
   6870 
   6871     /* Assign all 4 fifo in a MCQ group to each single mode XLPORT */
   6872     for (pipe = 0; pipe < 2; pipe++) {
   6873         SOC_PBMP_ITER(pbmp_4fifo[pipe], port) {
   6874             phy_port = si->port_l2p_mapping[port];
   6875             if (si->port_p2m_mapping[phy_port] != -1) {
   6876                 continue;
   6877             }
   6878             if (fifo_count[pipe] == 32) {
   6879                 break;
   6880             }
   6881             fifo_index = fifo_count[pipe];
   6882             /* 1, 2, 3, 4, 17, 18, 19, 20 */
   6883             mmu_port = mmu_port_base[pipe] +
   6884                 ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2));
   6885             fifo_count[pipe] += 4;
   6886             SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port);
   6887             SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port);
   6888         }
   6889     }
   6890 
   6891     /* Assign 2 consective fifo in a MCQ group to each dual mode XLPORT */
   6892     for (pipe = 0; pipe < 2; pipe++) {
   6893         /* Find unused fifo from the user specified extended queue ports */
   6894         count = 0;
   6895         for (index = 0; index < eq_port_count[pipe]; index++) {
   6896             port = eq_port[pipe][index];
   6897             if (!SOC_PBMP_MEMBER(pbmp_4fifo[pipe], port)) {
   6898                 unused_fifo[count] = index + 8;
   6899                 count++;
   6900             }
   6901         }
   6902 
   6903         index = 0;
   6904         SOC_PBMP_ITER(pbmp_2fifo[pipe], port) {
   6905             phy_port = si->port_l2p_mapping[port];
   6906             if (si->port_p2m_mapping[phy_port] != -1) {
   6907                 continue;
   6908             }
   6909             if (index < count) {
   6910                 mmu_port = mmu_port_base[pipe] + unused_fifo[index];
   6911                 index++;
   6912             } else if (fifo_count[pipe] == 32) {
   6913                 break;
   6914             } else {
   6915                 fifo_index = fifo_count[pipe];
   6916                 /* 1, 9, 2, 10, 3, 11, 4, 12, 17, 25, 18, 26, 19, 27, 20, 28 */
   6917                 mmu_port =  mmu_port_base[pipe] +
   6918                     ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2) |
   6919                      ((fifo_index & 0x2) << 2));
   6920                 fifo_count[pipe] += 2;
   6921             }
   6922             SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port);
   6923             SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port);
   6924         }
   6925     }
   6926 
   6927     /* Assign fifo to each quad mode XLPORT */
   6928     for (pipe = 0; pipe < 2; pipe++) {
   6929         /* Find unused fifo from the user specified extended queue ports */
   6930         count = 0;
   6931         for (index = 0; index < eq_port_count[pipe]; index++) {
   6932             port = eq_port[pipe][index];
   6933             if (SOC_PBMP_MEMBER(pbmp_1fifo[pipe], port)) {
   6934                 unused_fifo[count] = index + 4;
   6935                 count++;
   6936             }
   6937             if (!SOC_PBMP_MEMBER(pbmp_4fifo[pipe], port) &&
   6938                 si->port_m2p_mapping[mmu_port_base[pipe] + index + 8] == -1) {
   6939                 unused_fifo[count] = index + 8;
   6940                 count++;
   6941                 unused_fifo[count] = index + 12;
   6942                 count++;
   6943             }
   6944         }
   6945 
   6946         index = 0;
   6947         SOC_PBMP_ITER(pbmp_1fifo[pipe], port) {
   6948             phy_port = si->port_l2p_mapping[port];
   6949             if (si->port_p2m_mapping[phy_port] != -1) {
   6950                 continue;
   6951             }
   6952             if (index < count) {
   6953                 mmu_port = mmu_port_base[pipe] + unused_fifo[index];
   6954                 index++;
   6955             } else  if (fifo_count[pipe] == 32) {
   6956                 break;
   6957             } else {
   6958                 fifo_index = fifo_count[pipe];
   6959                 /* 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, 4, 8, 12, 16,
   6960                  * 17, 21, 25, 29, 18, 22, 26, 30, 19, 23, 27, 31, 20, 24,
   6961                  * 28, 32
   6962                  */
   6963                 mmu_port = mmu_port_base[pipe] +
   6964                 ((fifo_index & 0x10) | ((fifo_index & 0xc) >> 2) |
   6965                  ((fifo_index & 0x3) << 2));
   6966                 fifo_count[pipe]++;
   6967             }
   6968             SOC_PORT_P2M_MAPPING_SET(unit, phy_port, mmu_port);
   6969             SOC_PORT_M2P_MAPPING_SET(unit, mmu_port, phy_port);
   6970         }
   6971     }
   6972 
   6973     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   6974         LOG_CLI((BSL_META_U(unit,
   6975                             "physical to mmu mapping:")));
   6976         for (index = 0; index < 74; index++) {
   6977             if (index % 16 == 0) {
   6978                 LOG_CLI((BSL_META_U(unit,
   6979                                     "\n    ")));
   6980             }
   6981             LOG_CLI((BSL_META_U(unit,
   6982                                 " %3d"),
   6983                      si->port_p2m_mapping[index]));
   6984         }
   6985         LOG_CLI((BSL_META_U(unit,
   6986                             "\n")));
   6987     }
   6988 
   6989     return SOC_E_NONE;
   6990 }
   6991 
   6992 STATIC void
   6993 _soc_trident_tdm_add_spacing(int target_len, int *target, int source_len,
   6994                              int *source, int pad)
   6995 {
   6996     int source_index, target_index;
   6997     int result[_TD_TDM_NUM_SLOTS];
   6998 
   6999     /* Space out sequence with IDLE or NULL slot.
   7000      *   IDLE slot occupies a space in hardware TDM table
   7001      *   NULL slot will be removed from the merge result of this routine
   7002      * Following is the slot usage for spreading sequence into 8 slots:
   7003      *   40G bandwidth block: 40-40-40-40-40-40-40-40
   7004      *   30G bandwidth block: xx-30-30-30-xx-30-30-30
   7005      *   20G bandwidth block: xx-20-xx-20-xx-20-xx-20
   7006      *   15G bandwidth block: xx-xx-15-xx-xx-15-xx-15
   7007      *   10G bandwidth block: xx-xx-xx-10-xx-xx-xx-10
   7008      *    5G bandwidth block: xx-xx-xx-xx-xx-xx-xx-5 (for 1G or 2.5G port)
   7009      * Following is the slot usage for spreading sequence into 6 slots:
   7010      *   30G bandwidth block: 30-30-30-30-30-30
   7011      *   20G bandwidth block: xx-20-20-xx-20-20
   7012      *   15G bandwidth block: xx-15-xx-15-xx-15
   7013      *   10G bandwidth block: xx-xx-10-xx-xx-10
   7014      *    5G bandwidth block: xx-xx-xx-xx-xx-5 (for 1G or 2.5G port)
   7015      */
   7016     for (target_index = 0; target_index < target_len; target_index++) {
   7017         result[target_index] = pad;
   7018     }
   7019     for (source_index = 0; source_index < source_len; source_index++) {
   7020         target_index = target_len - 1 -
   7021             (source_len - 1 - source_index) * target_len / source_len;
   7022         result[target_index] = source[source_index];
   7023     }
   7024     for (target_index = 0; target_index < target_len; target_index++) {
   7025         target[target_index] = result[target_index];
   7026     }
   7027 }
   7028 
   7029 STATIC void
   7030 _soc_trident_tdm_merge(int target_num_seq, int target_len, int source_num_seq,
   7031                        int padded_len0, int source_len0, int *seq0,
   7032                        int padded_len1, int source_len1, int *seq1,
   7033                        int padded_len2, int source_len2, int *seq2,
   7034                        int padded_len3, int source_len3, int *seq3)
   7035 {
   7036     int padded_len[_TD_TDM_NUM_COLUMNS], source_len[_TD_TDM_NUM_COLUMNS];
   7037     int *seq[_TD_TDM_NUM_COLUMNS];
   7038     int adjust_seq[_TD_TDM_NUM_COLUMNS][_TD_TDM_NUM_SLOTS];
   7039     int seq_len, *seq_ptr;
   7040     int column, slot, count;
   7041 
   7042     padded_len[0] = padded_len0;
   7043     padded_len[1] = padded_len1;
   7044     padded_len[2] = padded_len2;
   7045     padded_len[3] = padded_len3;
   7046     source_len[0] = source_len0;
   7047     source_len[1] = source_len1;
   7048     source_len[2] = source_len2;
   7049     source_len[3] = source_len3;
   7050     seq[0] = seq0;
   7051     seq[1] = seq1;
   7052     seq[2] = seq2;
   7053     seq[3] = seq3;
   7054 
   7055     for (column = 0; column < source_num_seq; column++) {
   7056         seq_len = source_len[column];
   7057         seq_ptr = seq[column];
   7058         if (padded_len[column] > seq_len) {
   7059             /* pad with evenly distributed idle slots */
   7060             _soc_trident_tdm_add_spacing
   7061                 (padded_len[column], adjust_seq[column], source_len[column],
   7062                  seq[column], _TD_TDM_SLOT_IDLE);
   7063             seq_len = padded_len[column];
   7064             seq_ptr = adjust_seq[column];
   7065         }
   7066         /* pad with evenly distributed null slots */
   7067         _soc_trident_tdm_add_spacing(target_len, adjust_seq[column], seq_len,
   7068                                      seq_ptr, _TD_TDM_SLOT_NULL);
   7069     }
   7070 
   7071     count = 0;
   7072     for (slot = 0; slot < target_len; slot++) {
   7073         for (column = 0; column < source_num_seq; column++) {
   7074             if (adjust_seq[column][slot] != _TD_TDM_SLOT_NULL) {
   7075                 seq[count % target_num_seq][count / target_num_seq] =
   7076                     adjust_seq[column][slot];
   7077                 count++;
   7078             }
   7079         }
   7080     }
   7081     for (; count < target_len * target_num_seq; count++) {
   7082         seq[count % target_num_seq][count / target_num_seq] =
   7083             _TD_TDM_SLOT_NULL;
   7084     }
   7085 }
   7086 
   7087 STATIC int
   7088 _soc_trident_calculate_tdm_sequence(int unit, int pipe, int group,
   7089                                     int *tdm_seq, int *tdm_seq_len,
   7090                                     int extra_port, int extra_port_bandwidth)
   7091 {
   7092     soc_info_t *si;
   7093     int group_min, group_max;
   7094     int num_blk, blk_offset, blk_offset1;
   7095     int num_col, num_row;
   7096     int port, phy_port, index, port_index;
   7097     int slot, slot_size, count, last_swap;
   7098     int port_speed_max;
   7099     int slot_count[_TD_PORTS_PER_BLK], max_slot_count;
   7100     int blk_bandwidth[_TD_BLKS_PER_GROUP], max_blk_bandwidth;
   7101     int blk_seq[_TD_BLKS_PER_GROUP][8], group_seq[2][32];
   7102     int sort_blk_list[_TD_BLKS_PER_GROUP];
   7103     int sort_blk_len[_TD_BLKS_PER_GROUP];
   7104     int blk_count, blk_index;
   7105 
   7106     si = &SOC_INFO(unit);
   7107 
   7108     if (pipe < 0 || pipe > 1 || group < -1 || group > 1) {
   7109         return SOC_E_FAIL;
   7110     }
   7111 
   7112     if (group == -1) {
   7113         group_min = 0;
   7114         group_max = 1;
   7115     } else {
   7116         group_min = group_max = group;
   7117     }
   7118 
   7119     /* Collect port information */
   7120     sal_memset(group_seq, -1, sizeof(group_seq));
   7121     slot_size = 5000;
   7122     for (group = group_min; group <= group_max; group++) {
   7123         sal_memset(sort_blk_list, -1, sizeof(sort_blk_list));
   7124         sal_memset(blk_bandwidth, 0, sizeof(blk_bandwidth));
   7125         sal_memset(blk_seq, -1, sizeof(blk_seq));
   7126         blk_count = 0;
   7127         max_blk_bandwidth = 0;
   7128         num_blk = group ? 4 : 5;
   7129         blk_index = pipe * _TD_BLKS_PER_PIPE + group * _TD_BLKS_PER_GROUP;
   7130         for (blk_offset = 0; blk_offset < num_blk; blk_offset++) {
   7131             phy_port = 1 + (blk_index + blk_offset) * _TD_PORTS_PER_BLK;
   7132             /* Skip QGPORT (1G x 4) in XLPORT0 block (if present) */
   7133             if (phy_port == 1) {
   7134                 for (port_index = 0; port_index < _TD_PORTS_PER_BLK;
   7135                      port_index++) {
   7136                     port = si->port_p2l_mapping[phy_port + port_index];
   7137                     if (port != -1 && si->port_speed_max[port] > 1000) {
   7138                         break;
   7139                     }
   7140                 }
   7141                 if (port_index == _TD_PORTS_PER_BLK) {
   7142                     continue;
   7143                 }
   7144             }
   7145 
   7146             /* Find the number of slots needed for each port in the block */
   7147             max_slot_count = 0;
   7148             for (port_index = 0; port_index < _TD_PORTS_PER_BLK;
   7149                  port_index++) {
   7150                 port = si->port_p2l_mapping[phy_port + port_index];
   7151                 if (port == -1) {
   7152                     continue;
   7153                 }
   7154                 port_speed_max = si->port_speed_max[port];
   7155                 if (port_speed_max == 1000 || port_speed_max == 2500) {
   7156                     port_speed_max = 5000;
   7157                 }
   7158                 blk_bandwidth[blk_offset] += port_speed_max;
   7159                 slot_count[port_index] = port_speed_max / slot_size;
   7160                 if (max_slot_count < slot_count[port_index]) {
   7161                     max_slot_count = slot_count[port_index];
   7162                 }
   7163             }
   7164 
   7165             if (blk_bandwidth[blk_offset] == 0) {
   7166                 continue;
   7167             }
   7168             if (max_blk_bandwidth < blk_bandwidth[blk_offset]) {
   7169                 max_blk_bandwidth = blk_bandwidth[blk_offset];
   7170             }
   7171             blk_count++;
   7172 
   7173             /* Construct per block TDM sequence */
   7174             count = 0;
   7175             for (slot = 0; slot < max_slot_count; slot++) {
   7176                 for (port_index = 0; port_index < _TD_PORTS_PER_BLK;
   7177                      port_index++) {
   7178                     port = si->port_p2l_mapping[phy_port + port_index];
   7179                     if (port == -1) {
   7180                         continue;
   7181                     }
   7182                     if (slot_count[port_index] == 0) {
   7183                         continue;
   7184                     }
   7185                     blk_seq[blk_offset][count] = port;
   7186                     slot_count[port_index]--;
   7187                     count++;
   7188                 }
   7189             }
   7190         }
   7191 
   7192         if (blk_count == 0) {
   7193             continue;
   7194         }
   7195 
   7196         /* Sort block by bandwidth, place highest bandwidth block first */
   7197         count = 0;
   7198         for (blk_offset = 0; blk_offset < num_blk; blk_offset++) {
   7199             if (blk_bandwidth[blk_offset] > 0) {
   7200                 sort_blk_list[count++] = blk_offset;
   7201             }
   7202         }
   7203         do {
   7204             last_swap = 0;
   7205             for (index = 0; index < count - 1; index++) {
   7206                 blk_offset = sort_blk_list[index];
   7207                 blk_offset1 = sort_blk_list[index + 1];
   7208                 if (blk_bandwidth[blk_offset] >= blk_bandwidth[blk_offset1]) {
   7209                     continue;
   7210                 }
   7211                 sort_blk_list[index] = blk_offset1;
   7212                 sort_blk_list[index + 1] = blk_offset;
   7213                 last_swap = index + 1;
   7214             }
   7215             count = last_swap;
   7216         } while (count > 1);
   7217 
   7218         for (blk_index = 0; blk_index < _TD_BLKS_PER_GROUP; blk_index++) {
   7219             blk_offset = sort_blk_list[blk_index];
   7220             sort_blk_len[blk_index] =
   7221                 blk_offset < 0 ? 0 : blk_bandwidth[blk_offset] / slot_size;
   7222         }
   7223 
   7224         if (si->bandwidth == 640000) { /* 640G */
   7225             num_col = 4;
   7226             num_row = 8;
   7227             if (blk_count == num_col + 1) { /* need to get rid of 1 column */
   7228                 if (sort_blk_len[3] + sort_blk_len[4] <= num_row) {
   7229                     if (sort_blk_len[3] == 6) { /* *-*-*-30-x (x <= 10) */
   7230                         /* merge 30, (padded) 10 into 1 column */
   7231                         _soc_trident_tdm_merge
   7232                             (1, num_row, 2,
   7233                              -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7234                              2, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7235                              -1, 0, 0, -1, 0, 0);
   7236                     } else { /* *-*-*-x-y (x <= 20, y <= 20) */
   7237                         /* merge (padded) 20, (padded) 20 into 1 column */
   7238                         _soc_trident_tdm_merge
   7239                             (1, num_row, 2,
   7240                              4, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7241                              4, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7242                              -1, 0, 0, -1, 0, 0);
   7243                     }
   7244                     /* add spacing for sort_blk_list[0] is at below */
   7245                     _soc_trident_tdm_add_spacing(num_row,
   7246                                                  blk_seq[sort_blk_list[1]],
   7247                                                  sort_blk_len[1],
   7248                                                  blk_seq[sort_blk_list[1]],
   7249                                                  _TD_TDM_SLOT_IDLE);
   7250                     _soc_trident_tdm_add_spacing(num_row,
   7251                                                  blk_seq[sort_blk_list[2]],
   7252                                                  sort_blk_len[2],
   7253                                                  blk_seq[sort_blk_list[2]],
   7254                                                  _TD_TDM_SLOT_IDLE);
   7255                 } else if (sort_blk_len[4] == 6) { /* *-30-30-30-30 */
   7256                     /* merge 30, 30, 30, 30 into 3 columns */
   7257                     _soc_trident_tdm_merge
   7258                         (3, num_row, 4,
   7259                          -1, sort_blk_len[1], blk_seq[sort_blk_list[1]],
   7260                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7261                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7262                          -1, sort_blk_len[4], blk_seq[sort_blk_list[4]]);
   7263                 } else { /* *-*-30-30-x (x == 15 || x == 20) */
   7264                     /* merge 30, 30, (padded) 20 into 2 columns */
   7265                     _soc_trident_tdm_merge
   7266                         (2, num_row, 3,
   7267                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7268                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7269                          4, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7270                          -1, 0, 0);
   7271                     /* add spacing for sort_blk_list[0] is at below */
   7272                     _soc_trident_tdm_add_spacing(num_row,
   7273                                                  blk_seq[sort_blk_list[1]],
   7274                                                  sort_blk_len[1],
   7275                                                  blk_seq[sort_blk_list[1]],
   7276                                                  _TD_TDM_SLOT_IDLE);
   7277                 }
   7278                 _soc_trident_tdm_add_spacing(num_row,
   7279                                              blk_seq[sort_blk_list[0]],
   7280                                              sort_blk_len[0],
   7281                                              blk_seq[sort_blk_list[0]],
   7282                                              _TD_TDM_SLOT_IDLE);
   7283             }
   7284         } else if (max_blk_bandwidth <= 30000) {  /* 480G/320G case 1 */
   7285             num_col = 4;
   7286             num_row = 6;
   7287             if (blk_count == num_col + 1) { /* need to get rid of 1 column */
   7288                 if (sort_blk_len[3] + sort_blk_len[4] <= num_row) {
   7289                     if (sort_blk_len[3] == 4) { /* *-*-*-20-x (x <= 10) */
   7290                         /* merge 20, (padded) 10 into 1 column */
   7291                         _soc_trident_tdm_merge
   7292                             (1, num_row, 2,
   7293                              -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7294                              2, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7295                              -1, 0, 0, -1, 0, 0);
   7296                     } else { /* *-*-*-x-y (x <= 15, y <= 15) */
   7297                         /* merge (padded) 15, (padded) 15 into 1 column */
   7298                         _soc_trident_tdm_merge
   7299                             (1, num_row, 2,
   7300                              3, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7301                              3, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7302                              -1, 0, 0, -1, 0, 0);
   7303                     }
   7304                     /* add spacing for sort_blk_list[0] is at below */
   7305                     /* add spacing for sort_blk_list[1] is at below */
   7306                     _soc_trident_tdm_add_spacing(num_row,
   7307                                                  blk_seq[sort_blk_list[2]],
   7308                                                  sort_blk_len[2],
   7309                                                  blk_seq[sort_blk_list[2]],
   7310                                                  _TD_TDM_SLOT_IDLE);
   7311                 } else { /* *-*-20-20-x (x == 15 || x == 20) */
   7312                     /* merge 20, 20, (padded) 20 into 2 columns */
   7313                     _soc_trident_tdm_merge
   7314                         (2, num_row, 3,
   7315                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7316                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7317                          4, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7318                          -1, 0, 0);
   7319                 }
   7320                 _soc_trident_tdm_add_spacing(num_row,
   7321                                              blk_seq[sort_blk_list[0]],
   7322                                              sort_blk_len[0],
   7323                                              blk_seq[sort_blk_list[0]],
   7324                                              _TD_TDM_SLOT_IDLE);
   7325                 _soc_trident_tdm_add_spacing(num_row,
   7326                                              blk_seq[sort_blk_list[1]],
   7327                                              sort_blk_len[1],
   7328                                              blk_seq[sort_blk_list[1]],
   7329                                              _TD_TDM_SLOT_IDLE);
   7330             }
   7331         } else { /* 480G/320G case 2 */
   7332             num_col = 3;
   7333             num_row = 8;
   7334             if (blk_count == num_col + 1) { /* need to get rid of 1 column */
   7335                 if (sort_blk_len[2] + sort_blk_len[3] <= num_row) {
   7336                     if (sort_blk_len[2] == 6) { /* 40-*-30-x (x <= 10) */
   7337                         /* merge 30, (padded) 10 into 1 column */
   7338                         _soc_trident_tdm_merge
   7339                             (1, num_row, 2,
   7340                              -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7341                              2, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7342                              -1, 0, 0, -1, 0, 0);
   7343                     } else { /* 40-*-x-y (x <= 20, y <= 20) */
   7344                         /* merge (padded) 20, (padded) 20 into 1 column */
   7345                         _soc_trident_tdm_merge
   7346                             (1, num_row, 2,
   7347                              4, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7348                              4, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7349                              -1, 0, 0, -1, 0, 0);
   7350                     }
   7351                     _soc_trident_tdm_add_spacing(num_row,
   7352                                                  blk_seq[sort_blk_list[1]],
   7353                                                  sort_blk_len[1],
   7354                                                  blk_seq[sort_blk_list[1]],
   7355                                                  _TD_TDM_SLOT_IDLE);
   7356                 } else { /* 40-30-30-x (x == 15 || x == 20) */
   7357                     /* merge 30, 30, (padded) 20 into 2 columns */
   7358                     _soc_trident_tdm_merge
   7359                         (2, num_row, 3,
   7360                          -1, sort_blk_len[1], blk_seq[sort_blk_list[1]],
   7361                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7362                          4, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7363                          -1, 0, 0);
   7364                 }
   7365             } else if (blk_count == num_col + 2) {
   7366                 /* need to get rid of 2 columns */
   7367                 if (sort_blk_len[2] + sort_blk_len[3] + sort_blk_len[4] <=
   7368                     num_row) {
   7369                     if (sort_blk_len[2] >= 4) { /* 40-*-x-y-z (x >= 20) */
   7370                         /* first merge columns 3 and 4 into 1 column */
   7371                         _soc_trident_tdm_merge
   7372                             (1, num_row, 2,
   7373                              -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7374                              -1, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7375                              -1, 0, 0, -1, 0, 0);
   7376                         /* then merge columns 2 and merged 3+4 into 1 column */
   7377                         _soc_trident_tdm_merge
   7378                             (1, num_row, 2,
   7379                              -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7380                              -1, sort_blk_len[3] + sort_blk_len[4],
   7381                              blk_seq[sort_blk_list[3]],
   7382                              -1, 0, 0, -1, 0, 0);
   7383                     } else { /* 40-*-x-y-z (x < 20) */
   7384                         /* directly merge all 3 columns into 1 column */
   7385                         _soc_trident_tdm_merge
   7386                             (1, num_row, 3,
   7387                              -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7388                              -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7389                              -1, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7390                              -1, 0, 0);
   7391                     }
   7392                     _soc_trident_tdm_add_spacing(num_row,
   7393                                                  blk_seq[sort_blk_list[1]],
   7394                                                  sort_blk_len[1],
   7395                                                  blk_seq[sort_blk_list[1]],
   7396                                                  _TD_TDM_SLOT_IDLE);
   7397                 } else if (sort_blk_len[1] + sort_blk_len[4] <= 8  &&
   7398                            sort_blk_len[2] + sort_blk_len[3] <= 8) {
   7399                     /* merge columns 1 and 4 into 1 column */
   7400                     _soc_trident_tdm_merge
   7401                         (1, num_row, 2,
   7402                          -1, sort_blk_len[1], blk_seq[sort_blk_list[1]],
   7403                          -1, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7404                          -1, 0, 0, -1, 0, 0);
   7405                     /* merge columns 2 and 3 into 1 column */
   7406                     _soc_trident_tdm_merge
   7407                         (1, num_row, 2,
   7408                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7409                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7410                          -1, 0, 0, -1, 0, 0);
   7411                 } else if (sort_blk_len[2] == 6) { /* 40-30-30-15-5 */
   7412                     /* first merge columns 3 and 4 into 1 column */
   7413                     _soc_trident_tdm_merge
   7414                         (1, num_row, 2,
   7415                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7416                          -1, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7417                          -1, 0, 0, -1, 0, 0);
   7418                     /* then merge 30, 30, merged 3+4 into 2 columns */
   7419                     _soc_trident_tdm_merge
   7420                         (2, num_row, 3,
   7421                          -1, sort_blk_len[1], blk_seq[sort_blk_list[1]],
   7422                          -1, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7423                          -1, sort_blk_len[3] + sort_blk_len[4],
   7424                          blk_seq[sort_blk_list[3]],
   7425                          -1, 0, 0);
   7426                 } else { /* 40-30-x-15-15 (x == 15 || x == 20) */
   7427                     /* first merge columns 3 and 4 into 1 column */
   7428                     _soc_trident_tdm_merge
   7429                         (1, num_row, 2,
   7430                          -1, sort_blk_len[3], blk_seq[sort_blk_list[3]],
   7431                          -1, sort_blk_len[4], blk_seq[sort_blk_list[4]],
   7432                          -1, 0, 0, -1, 0, 0);
   7433                     /* then merge 30, merged 3+4, (padded) 20 into 2 columns */
   7434                     _soc_trident_tdm_merge
   7435                         (2, num_row, 3,
   7436                          -1, sort_blk_len[1], blk_seq[sort_blk_list[1]],
   7437                          -1, sort_blk_len[3] + sort_blk_len[4],
   7438                          blk_seq[sort_blk_list[3]],
   7439                          4, sort_blk_len[2], blk_seq[sort_blk_list[2]],
   7440                          -1, 0, 0);
   7441                 }
   7442             }
   7443         }
   7444 
   7445         if (blk_count <= num_col) {
   7446             /* If no merge was done, just evenly distributed the sequence
   7447              * in each block */
   7448             for (blk_index = 0; blk_index < num_col; blk_index++) {
   7449                 blk_offset = sort_blk_list[blk_index];
   7450                 if (blk_offset < 0) {
   7451                     break;
   7452                 }
   7453                 _soc_trident_tdm_add_spacing
   7454                     (num_row, blk_seq[blk_offset], sort_blk_len[blk_index],
   7455                      blk_seq[blk_offset], _TD_TDM_SLOT_IDLE);
   7456             }
   7457         }
   7458 
   7459         for (blk_index = 0; blk_index < num_col; blk_index++) {
   7460             blk_offset = sort_blk_list[blk_index];
   7461             if (blk_offset < 0) {
   7462                 break;
   7463             }
   7464             for (index = 0; index < num_row; index++) {
   7465                 group_seq[group][index * num_col + blk_index] =
   7466                     blk_seq[blk_offset][index];
   7467             }
   7468         }
   7469     }
   7470 
   7471     /* Construct final TDM sequence from 2 group TDM sequences */
   7472     count = si->bandwidth == 640000 ? 32 : 24;
   7473     index = 0;
   7474     for (slot = 0; slot < count; slot++) {
   7475         for (group = group_min; group <= group_max; group++) {
   7476             tdm_seq[index++] = group_seq[group][slot];
   7477         }
   7478         if (extra_port != -1) {
   7479             if (slot == count - 1 ||
   7480                 (extra_port_bandwidth == 10000 && slot == count / 2 - 1)) {
   7481                 tdm_seq[index++] = extra_port;
   7482             }
   7483         }
   7484     }
   7485     *tdm_seq_len = index;
   7486 
   7487     return SOC_E_NONE;
   7488 }
   7489 
   7490 STATIC int
   7491 _soc_trident_pg_tdm_init(int unit)
   7492 {
   7493     static const soc_field_t tdm_field[] = {
   7494         TDM_ENTRY0_PORT_IDf, TDM_ENTRY1_PORT_IDf, TDM_ENTRY2_PORT_IDf,
   7495         TDM_ENTRY3_PORT_IDf, TDM_ENTRY4_PORT_IDf, TDM_ENTRY5_PORT_IDf,
   7496         TDM_ENTRY6_PORT_IDf, TDM_ENTRY7_PORT_IDf, TDM_ENTRY8_PORT_IDf,
   7497         TDM_ENTRY9_PORT_IDf, TDM_ENTRY10_PORT_IDf, TDM_ENTRY11_PORT_IDf,
   7498         TDM_ENTRY12_PORT_IDf, TDM_ENTRY13_PORT_IDf, TDM_ENTRY14_PORT_IDf,
   7499         TDM_ENTRY15_PORT_IDf, TDM_ENTRY16_PORT_IDf, TDM_ENTRY17_PORT_IDf,
   7500         TDM_ENTRY18_PORT_IDf, TDM_ENTRY19_PORT_IDf, TDM_ENTRY20_PORT_IDf,
   7501         TDM_ENTRY21_PORT_IDf, TDM_ENTRY22_PORT_IDf, TDM_ENTRY23_PORT_IDf,
   7502         TDM_ENTRY24_PORT_IDf, TDM_ENTRY25_PORT_IDf, TDM_ENTRY26_PORT_IDf,
   7503         TDM_ENTRY27_PORT_IDf, TDM_ENTRY28_PORT_IDf, TDM_ENTRY29_PORT_IDf,
   7504         TDM_ENTRY30_PORT_IDf, TDM_ENTRY31_PORT_IDf
   7505     };
   7506     static const soc_reg_t tdm_reg[2][8] = {
   7507         {
   7508             PORT_GROUP5_TDM_REG_0r, PORT_GROUP5_TDM_REG_1r,
   7509             PORT_GROUP5_TDM_REG_2r, PORT_GROUP5_TDM_REG_3r,
   7510             PORT_GROUP5_TDM_REG_4r, PORT_GROUP5_TDM_REG_5r,
   7511             PORT_GROUP5_TDM_REG_6r, PORT_GROUP5_TDM_REG_7r
   7512         },
   7513         {
   7514             PORT_GROUP4_TDM_REG_0r, PORT_GROUP4_TDM_REG_1r,
   7515             PORT_GROUP4_TDM_REG_2r, PORT_GROUP4_TDM_REG_3r,
   7516             PORT_GROUP4_TDM_REG_4r, PORT_GROUP4_TDM_REG_5r,
   7517             PORT_GROUP4_TDM_REG_6r, PORT_GROUP4_TDM_REG_7r
   7518         }
   7519     };
   7520     static const soc_reg_t tdm_control[2] = {
   7521         PORT_GROUP5_TDM_CONTROLr, PORT_GROUP4_TDM_CONTROLr
   7522     };
   7523     soc_info_t *si;
   7524     soc_reg_t reg;
   7525     soc_field_t field;
   7526     uint32 rval;
   7527     int rv, pipe, group, port, phy_port, index;
   7528     int tdm_seq[32], tdm_seq_len;
   7529 
   7530     si = &SOC_INFO(unit);
   7531 
   7532     for (pipe = 0; pipe < 2; pipe++) {
   7533         for (group = 0; group < 2; group++) {
   7534             rv = _soc_trident_calculate_tdm_sequence(unit, pipe, group,
   7535                                                      tdm_seq, &tdm_seq_len, -1,
   7536                                                      0);
   7537             if (rv == SOC_E_EMPTY) {
   7538                 continue;
   7539             } else if (SOC_FAILURE(rv)) {
   7540                 return rv;
   7541             }
   7542             if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   7543                 LOG_CLI((BSL_META_U(unit,
   7544                                     "PORT_GROUP%c_%c TDM:"),
   7545                          group ? '4' : '5', pipe ? 'Y' : 'X'));
   7546                 for (index = 0; index < tdm_seq_len; index++) {
   7547                     if (index % 16 == 0) {
   7548                         LOG_CLI((BSL_META_U(unit,
   7549                                             "\n    ")));
   7550                     }
   7551                     LOG_CLI((BSL_META_U(unit,
   7552                                         " %2d"), tdm_seq[index]));
   7553                 }
   7554                 LOG_CLI((BSL_META_U(unit,
   7555                                     "\n")));
   7556             }
   7557             rval = 0;
   7558             for (index = 0; index < tdm_seq_len; index++) {
   7559                 reg = tdm_reg[group][index / 4];
   7560                 field = tdm_field[index];
   7561                 port = tdm_seq[index];
   7562                 if (port != _TD_TDM_SLOT_IDLE && port != _TD_TDM_SLOT_NULL) {
   7563                     phy_port = si->port_l2p_mapping[port];
   7564                     soc_reg_field_set(unit, reg, &rval, field, phy_port);
   7565                 } else {
   7566                     soc_reg_field_set(unit, reg, &rval, field, 0x7f);
   7567                 }
   7568                 if (index % 4 == 3 || index == tdm_seq_len - 1) {
   7569                     SOC_IF_ERROR_RETURN
   7570                         (soc_reg32_set(unit, reg, pipe, 0, rval));
   7571                     rval = 0;
   7572                 }
   7573             }
   7574             reg = tdm_control[group];
   7575             rval = 0;
   7576             soc_reg_field_set(unit, reg, &rval, TDM_WRAP_PTRf,
   7577                               tdm_seq_len - 1);
   7578             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pipe, 0, rval));
   7579         }
   7580     }
   7581 
   7582     return SOC_E_NONE;
   7583 }
   7584 
   7585 STATIC int
   7586 _soc_trident_mmu_tdm_init(int unit)
   7587 {
   7588     static const soc_mem_t tdm_mem[] = {
   7589         ARB_TDM_TABLE_0m, ARB_TDM_TABLE_1m
   7590     };
   7591     soc_info_t *si;
   7592     soc_mem_t mem;
   7593     union {
   7594         arb_tdm_table_0_entry_t table_0;
   7595         arb_tdm_table_1_entry_t table_1;
   7596     } entry;
   7597     int rv, pipe, port, phy_port, mmu_port, index, base;
   7598     int tdm_seq[128], tdm_seq_len;
   7599     int extra_port;
   7600 
   7601     si = &SOC_INFO(unit);
   7602 
   7603     for (pipe = 0; pipe < 2; pipe++) {
   7604         if (pipe == 0) { /* X pipe */
   7605             extra_port = 0;
   7606             base = 0;
   7607         } else { /* Y pipe */
   7608             extra_port = 65;
   7609             base = 33;
   7610         }
   7611         rv = _soc_trident_calculate_tdm_sequence(unit, pipe, -1, tdm_seq,
   7612                                                  &tdm_seq_len, extra_port,
   7613                                                  si->bandwidth == 640000 ?
   7614                                                  5000 : 10000);
   7615         if (rv == SOC_E_EMPTY) {
   7616             continue;
   7617         } else if (SOC_FAILURE(rv)) {
   7618             return rv;
   7619         }
   7620         if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   7621             LOG_CLI((BSL_META_U(unit,
   7622                                 "%c pipe MMU TDM:"), pipe ? 'Y' : 'X'));
   7623             for (index = 0; index < tdm_seq_len; index++) {
   7624                 if (index % 16 == 0) {
   7625                     LOG_CLI((BSL_META_U(unit,
   7626                                         "\n    ")));
   7627                 }
   7628                 LOG_CLI((BSL_META_U(unit,
   7629                                     " %2d"), tdm_seq[index]));
   7630             }
   7631             LOG_CLI((BSL_META_U(unit,
   7632                                 "\n")));
   7633         }
   7634 
   7635         mem = tdm_mem[pipe];
   7636         sal_memset(&entry, 0, sizeof(entry));
   7637         for (index = 0; index < tdm_seq_len; index++) {
   7638             port = tdm_seq[index];
   7639             if (port != _TD_TDM_SLOT_IDLE && port != _TD_TDM_SLOT_NULL) {
   7640                 phy_port = si->port_l2p_mapping[port];
   7641                 mmu_port = si->port_p2m_mapping[phy_port];
   7642                 soc_mem_field32_set(unit, mem, &entry, PORT_NUMf,
   7643                                     mmu_port - base);
   7644             } else {
   7645                 soc_mem_field32_set(unit, mem, &entry, PORT_NUMf, 0x3f);
   7646             }
   7647             if (index == tdm_seq_len - 1) {
   7648                 soc_mem_field32_set(unit, mem, &entry, WRAP_ENf, 1);
   7649             }
   7650             SOC_IF_ERROR_RETURN
   7651                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &entry));
   7652         }
   7653     }
   7654 
   7655     return SOC_E_NONE;
   7656 }
   7657 
   7658 extern int (*_phy_wc40_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *,int);
   7659 
   7660 int
   7661 trident_wc40_firmware_set(int unit, int port, uint8 *array,int datalen)
   7662 {
   7663     return soc_warpcore_firmware_set(unit, port, array, datalen, 0,
   7664                                      XLPORT_WC_UCMEM_DATAm,
   7665                                      XLPORT_WC_UCMEM_CTRLr);
   7666 }
   7667 
   7668 STATIC int
   7669 _trident_ledup_init(int unit)
   7670 {
   7671     int ix;
   7672     uint32 rval = 0;
   7673     struct led_remap {
   7674        uint32 reg_addr;
   7675        uint32 port0;
   7676        uint32 port1;
   7677        uint32 port2;
   7678        uint32 port3;
   7679     } led1_remap[] = {
   7680         {CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r,
   7681                     REMAP_PORT_0f,REMAP_PORT_1f,REMAP_PORT_2f,REMAP_PORT_3f},
   7682         {CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r,
   7683                     REMAP_PORT_4f,REMAP_PORT_5f,REMAP_PORT_6f,REMAP_PORT_7f},
   7684         {CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r,
   7685                     REMAP_PORT_8f,REMAP_PORT_9f,REMAP_PORT_10f,REMAP_PORT_11f},
   7686         {CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r,
   7687                     REMAP_PORT_12f,REMAP_PORT_13f,REMAP_PORT_14f,REMAP_PORT_15f},
   7688         {CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r,
   7689                     REMAP_PORT_16f,REMAP_PORT_17f,REMAP_PORT_18f,REMAP_PORT_19f},
   7690         {CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r,
   7691                     REMAP_PORT_20f,REMAP_PORT_21f,REMAP_PORT_22f,REMAP_PORT_23f},
   7692         {CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r,
   7693                     REMAP_PORT_24f,REMAP_PORT_25f,REMAP_PORT_26f,REMAP_PORT_27f},
   7694         {CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r,
   7695                     REMAP_PORT_28f,REMAP_PORT_29f,REMAP_PORT_30f,REMAP_PORT_31f},
   7696         {CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r,
   7697                     REMAP_PORT_32f,REMAP_PORT_33f,REMAP_PORT_34f,REMAP_PORT_35f}
   7698     };
   7699 
   7700     /* initialize the led1 remap register settings to match the led0's default.
   7701      * port 0 entry will not be used for easy index of the physical port starting 1
   7702      */   
   7703     for (ix = 0; ix < sizeof(led1_remap)/sizeof(led1_remap[0]); ix++) {
   7704         rval = 0;
   7705         soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 
   7706                          led1_remap[ix].port0, 36 - ix * 4);
   7707         soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 
   7708                          led1_remap[ix].port1, 35 - ix * 4);
   7709         soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 
   7710                          led1_remap[ix].port2, 34 - ix * 4);
   7711         soc_reg_field_set(unit, led1_remap[ix].reg_addr, &rval, 
   7712                          led1_remap[ix].port3, 33 - ix * 4);
   7713         /* coverity[result_independent_of_operands] */
   7714         SOC_IF_ERROR_RETURN
   7715             (soc_pci_write(unit, 
   7716                 soc_reg_addr(unit, led1_remap[ix].reg_addr, REG_PORT_ANY, 0), 
   7717                 rval));
   7718     }
   7719 
   7720     /* set the LED scanchain start address */
   7721     rval = 0x4A;
   7722     /* coverity[result_independent_of_operands] */
   7723     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_SCANCHAIN_ASSEMBLY_ST_ADDRr(unit, rval));
   7724     /* coverity[result_independent_of_operands] */
   7725     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_SCANCHAIN_ASSEMBLY_ST_ADDRr(unit, rval));
   7726 
   7727     /* configure the LED scan delay cycles */
   7728     /* coverity[result_independent_of_operands] */
   7729     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP0_CTRLr(unit, &rval));
   7730     soc_reg_field_set(unit, CMIC_LEDUP0_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 11);
   7731     /* coverity[result_independent_of_operands] */
   7732     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_CTRLr(unit, rval));
   7733 
   7734     /* coverity[result_independent_of_operands] */
   7735     SOC_IF_ERROR_RETURN(READ_CMIC_LEDUP1_CTRLr(unit, &rval));
   7736     soc_reg_field_set(unit, CMIC_LEDUP1_CTRLr, &rval, LEDUP_SCAN_START_DELAYf, 15);
   7737     /* coverity[result_independent_of_operands] */
   7738     SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_CTRLr(unit, rval));
   7739 
   7740     /* initialize the UP0 and UP1 data ram */
   7741     rval = 0;
   7742     for (ix = 0; ix < 256; ix++) {
   7743         /* coverity[result_independent_of_operands] */
   7744         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP0_DATA_RAMr(unit,ix, rval));
   7745         /* coverity[result_independent_of_operands] */
   7746         SOC_IF_ERROR_RETURN(WRITE_CMIC_LEDUP1_DATA_RAMr(unit,ix, rval));
   7747     }
   7748     return SOC_E_NONE;  
   7749 }
   7750 
   7751 #if defined(SER_TR_TEST_SUPPORT)
   7752 soc_ser_test_functions_t ser_trident_test_fun;
   7753 #endif
   7754 STATIC int
   7755 _soc_trident_misc_init(int unit)
   7756 
   7757 {    static const soc_field_t port_field[4] = {
   7758         PORT0f, PORT1f, PORT2f, PORT3f
   7759     };
   7760     static const soc_field_t mac_mode_field[4] = {
   7761         PORT0_MAC_MODEf, PORT1_MAC_MODEf, PORT2_MAC_MODEf, PORT3_MAC_MODEf
   7762     };
   7763     static int rtag7_field_width[] = { 16, 16, 4, 16, 8, 8, 16, 16 };
   7764     soc_info_t *si;
   7765     uint32 rval;
   7766     uint32 reset_status;
   7767     uint32 entry[SOC_MAX_MEM_WORDS];
   7768     soc_pbmp_t pbmp;
   7769     int port, phy_port, blk_port, blk, bindex;
   7770     uint32 core_mode, phy_mode;
   7771     int num_lanes;
   7772     int blk_bandwidth;
   7773     int index, count, sub_sel, offset;
   7774     int divisor, dividend, delay;
   7775     uint64 reg64;
   7776     uint16 dev_id;
   7777     uint8 rev_id;
   7778     int parity_enable, cache_fpgm;
   7779     soc_field_t fields[3];
   7780     uint32 values[3];
   7781     int higig2;
   7782 
   7783     soc_cm_get_id(unit, &dev_id, &rev_id);
   7784 
   7785     si = &SOC_INFO(unit);
   7786 
   7787     /* Stop the mem scan task before all of the parity init takes place */
   7788     SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit));
   7789 
   7790     parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE);
   7791     if (parity_enable) {
   7792         soc_ser_log_init(unit, NULL, 0);
   7793         (void) _soc_trident_ser_init(unit);
   7794 #if defined(SER_TR_TEST_SUPPORT)
   7795         /*Initialize chip-specific functions for SER testing*/
   7796         memset(&ser_trident_test_fun, 0, sizeof(soc_ser_test_functions_t));
   7797         ser_trident_test_fun.inject_error_f = &soc_td_ser_inject_error;
   7798         ser_trident_test_fun.test_mem = &soc_td_ser_mem_test;
   7799         ser_trident_test_fun.test     = &soc_td_ser_test;
   7800         ser_trident_test_fun.parity_control = &_ser_test_parity_control_pci_write;
   7801         ser_trident_test_fun.injection_support = &soc_td_ser_error_injection_support;
   7802         soc_ser_test_functions_register(unit, &ser_trident_test_fun);
   7803 #endif /*defined(SER_TR_TEST_SUPPORT*/
   7804 #ifdef INCLUDE_MEM_SCAN
   7805         soc_mem_scan_ser_list_register(unit, FALSE,
   7806                                        _soc_td_ser_parity_info[unit]);
   7807 #endif
   7808         memset(&_td_ser_functions, 0, sizeof(soc_ser_functions_t));
   7809         _td_ser_functions._soc_ser_stat_nack_f = &soc_trident_stat_nack;
   7810         _td_ser_functions._soc_ser_mem_nack_f = &soc_trident_mem_nack;
   7811         _td_ser_functions._soc_ser_fail_f = &soc_trident_ser_fail;
   7812         _td_ser_functions._soc_ser_parity_error_intr_f = &soc_trident_parity_error;
   7813         _td_ser_functions._soc_ser_populate_tcam_log_f = &soc_trident_populate_tcam_log; 
   7814         soc_ser_function_register(unit, &_td_ser_functions);
   7815     }
   7816 
   7817     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   7818         SOC_IF_ERROR_RETURN(_soc_trident_clear_all_memory(unit));
   7819     }
   7820 
   7821     if (parity_enable) {
   7822         (void)_soc_trident_parity_enable_all(unit, TRUE);
   7823     }
   7824     SOC_IF_ERROR_RETURN(_soc_trident_port_mapping_init(unit));
   7825 
   7826     sal_memset(entry, 0, sizeof(cpu_pbm_entry_t));
   7827     soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit));
   7828     SOC_IF_ERROR_RETURN
   7829         (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry));
   7830 
   7831     sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t));
   7832     soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit));
   7833     SOC_IF_ERROR_RETURN
   7834         (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry));
   7835 
   7836     sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t));
   7837     soc_mem_pbmp_field_set(unit, MULTIPASS_LOOPBACK_BITMAPm, entry, BITMAPf,
   7838                            &PBMP_LB(unit));
   7839     SOC_IF_ERROR_RETURN
   7840         (soc_mem_write(unit, MULTIPASS_LOOPBACK_BITMAPm, MEM_BLOCK_ALL, 0,
   7841                        entry));
   7842 
   7843     sal_memset(entry, 0, sizeof(isbs_port_to_pipe_mapping_entry_t));
   7844     soc_mem_pbmp_field_set(unit, ISBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf,
   7845                            &PBMP_YPIPE(unit));
   7846     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ISBS_PORT_TO_PIPE_MAPPINGm,
   7847                                       MEM_BLOCK_ALL, 0, entry));
   7848 
   7849     sal_memset(entry, 0, sizeof(esbs_port_to_pipe_mapping_entry_t));
   7850     soc_mem_pbmp_field_set(unit, ESBS_PORT_TO_PIPE_MAPPINGm, entry, BITMAPf,
   7851                            &PBMP_YPIPE(unit));
   7852     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ESBS_PORT_TO_PIPE_MAPPINGm,
   7853                                       MEM_BLOCK_ALL, 0, entry));
   7854 
   7855     sal_memset(entry, 0, sizeof(egr_ing_port_entry_t));
   7856     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1);
   7857     PBMP_HG_ITER(unit, port) {
   7858         SOC_IF_ERROR_RETURN
   7859             (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry));
   7860     }
   7861     higig2 = soc_property_port_get(unit, CMIC_PORT(unit), spn_HIGIG2_HDR_MODE,
   7862                                    0) ? 1 : 0;
   7863     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, higig2);
   7864     SOC_IF_ERROR_RETURN
   7865         (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index,
   7866                        entry));
   7867     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2);
   7868     soc_mem_field32_set(unit, EGR_ING_PORTm, entry, HIGIG2f, 0);
   7869     SOC_IF_ERROR_RETURN
   7870         (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, LB_PORT(unit),
   7871                        entry));
   7872 
   7873     /* For FP_GLOBAL_MASK_TCAM, we don't have the pbmp's necessary to
   7874      * initialize the cache until now.  This is the time to check for
   7875      * the cache permission of this table.
   7876      */
   7877     cache_fpgm = soc_feature(unit, soc_feature_mem_cache) && 
   7878             soc_property_get(unit, spn_MEM_CACHE_ENABLE, 
   7879                              (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1);
   7880     if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) {
   7881         char mem_name[100];
   7882         char *mptr;
   7883 
   7884         sal_memset(mem_name, 0, sizeof(mem_name));
   7885         sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_"));
   7886         mptr = &mem_name[sal_strlen(mem_name)];
   7887         sal_strncpy(mptr, SOC_MEM_NAME(unit, FP_GLOBAL_MASK_TCAMm),
   7888                     sizeof(mem_name) - sal_strlen(mem_name) - 1);
   7889         if (soc_property_get(unit, mem_name, 0)) {
   7890             cache_fpgm = 0;
   7891         }
   7892     }
   7893 
   7894     if (cache_fpgm) {
   7895         SOC_MEM_INFO(unit, FP_GLOBAL_MASK_TCAMm).flags |=
   7896             SOC_MEM_FLAG_CACHABLE;
   7897         SOC_IF_ERROR_RETURN
   7898             (soc_mem_cache_set(unit, FP_GLOBAL_MASK_TCAMm,
   7899                                MEM_BLOCK_ALL, TRUE));
   7900     }
   7901 
   7902     if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) {
   7903         /* Must clear FP_GLOBAL_MASK_TCAM after port to pipe mappings
   7904          * are initialized. */
   7905         SOC_IF_ERROR_RETURN
   7906             (soc_mem_clear(unit, FP_GLOBAL_MASK_TCAMm, COPYNO_ALL, TRUE));
   7907     }
   7908 
   7909     /* Enable XPAUSE (both TX and RX) on higig port */
   7910     values[0] = 0;
   7911     soc_reg_field_set(unit, XLPORT_CONFIGr, &values[0], HIGIG_MODEf, 1); 
   7912     soc_reg_field_set(unit, XLPORT_CONFIGr, &values[0], XPAUSE_ENf, 1); 
   7913     /* Enable RX XPAUSE on ethernet port to handle XMAC RX pause errata,
   7914      * set MY_MODID to any non-zero value */
   7915     values[1] = 0;
   7916     soc_reg_field_set(unit, XLPORT_CONFIGr, &values[1], XPAUSE_RX_ENf, 1); 
   7917     soc_reg_field_set(unit, XLPORT_CONFIGr, &values[1], MY_MODIDf, 2); 
   7918     PBMP_PORT_ITER(unit, port) {
   7919         SOC_IF_ERROR_RETURN
   7920             (WRITE_XLPORT_CONFIGr(unit, port,
   7921                                   values[IS_HG_PORT(unit, port) ? 0 : 1]));
   7922     }
   7923 
   7924     SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) {
   7925         blk_port = SOC_BLOCK_PORT(unit, blk);
   7926         if (blk_port < 0) {
   7927             continue;
   7928         }
   7929         /*
   7930          * Program XLPORT mode and default Warpcore lanes setting
   7931          * core_mode: the number of ports on the system side of XMAC
   7932          * phy_mode: the number of ports on the Warpcore side of XMAC
   7933          * num_lanes: the number of lanes on the line side of Warpcore
   7934          */
   7935         if (si->port_speed_max[blk_port] > 20000) {
   7936             core_mode = 0; /* single, XMAC works as a single MAC */
   7937             phy_mode = 0; /* single, use all 16 lanes for a port */
   7938             num_lanes = 4;
   7939         } else if (si->port_speed_max[blk_port] > 10000) {
   7940             if ((si->port_speed_max[blk_port] == 20000) &&
   7941                 (si->port_num_lanes[blk_port] == 4)){
   7942                 core_mode = 0; /* single, XMAC works as a single MAC */
   7943                 phy_mode = 1; /* dual, use 8 lanes per port  */
   7944                 num_lanes = 4;
   7945             } else {
   7946                 core_mode = 1; /* dual, XMAC works as 2 MACs */
   7947                 phy_mode = 1; /* dual, use 8 lanes per port  */
   7948                 num_lanes = 2;
   7949             }
   7950         } else {
   7951             core_mode = 2; /* quad, XMAC works as 4 MACs */
   7952             phy_mode = 2; /* quad, use 4 lanes per port */
   7953             num_lanes = 1;
   7954         }
   7955         rval = 0;
   7956         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf,
   7957                           core_mode);
   7958         soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf,
   7959                           phy_mode);
   7960         phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1;
   7961         for (bindex = 0; bindex < 4; bindex++) {
   7962             port = si->port_p2l_mapping[phy_port + bindex];
   7963             if (port == -1) {
   7964                 continue;
   7965             }
   7966             if (si->port_speed_max[port] < 10000) {
   7967                 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval,
   7968                                   mac_mode_field[bindex], 1);
   7969             }
   7970             si->port_num_lanes[port] = num_lanes;
   7971         }
   7972         SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, blk_port, rval));
   7973 
   7974         /* Do XMAC reset when port mode is changed */
   7975         SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, blk_port, &rval));
   7976         reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf);
   7977         if (reset_status != 1) {
   7978             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1);
   7979             SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, blk_port, rval));
   7980             sal_udelay(10);
   7981             soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0);
   7982             SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, blk_port, rval));
   7983         }
   7984 
   7985         /* Enable XLPORT */
   7986         rval = 0;
   7987         for (bindex = 0; bindex < 4; bindex++) {
   7988             if (si->port_p2l_mapping[phy_port + bindex] != -1) {
   7989                 soc_reg_field_set(unit, XLPORT_PORT_ENABLEr, &rval,
   7990                                   port_field[bindex], 1);
   7991             }
   7992         }
   7993         SOC_IF_ERROR_RETURN(WRITE_XLPORT_PORT_ENABLEr(unit, blk_port, rval));
   7994     }
   7995 
   7996     /* Enable QGPORT (1G x 4) in XLPORT0 block (if present) */
   7997     blk_bandwidth = 0;
   7998     for (phy_port = 1; phy_port < 5; phy_port++) {
   7999         port = si->port_p2l_mapping[phy_port];
   8000         if (port != -1) {
   8001             blk_bandwidth += si->port_speed_max[port];
   8002         }
   8003     }
   8004     if (blk_bandwidth > 0 && blk_bandwidth <= 4000) {
   8005         rval = 0;
   8006         soc_reg_field_set(unit, PORT_GROUP5_QGPORT_ENABLEr, &rval,
   8007                           QGPORT_ENABLEf, 1);
   8008         SOC_IF_ERROR_RETURN(WRITE_PORT_GROUP5_QGPORT_ENABLEr(unit, 0, rval));
   8009     }
   8010 
   8011     /* Setup TDM within each port group */
   8012     SOC_IF_ERROR_RETURN(_soc_trident_pg_tdm_init(unit));
   8013 
   8014     /* Setup main TDM between each port group */
   8015     sal_memset(entry, 0, sizeof(iarb_main_tdm_entry_t));
   8016     count = si->bandwidth == 640000 ? 64 : 32;
   8017     for (index = 0; index < count; index++) {
   8018         soc_mem_field32_set(unit, IARB_MAIN_TDMm, entry, TDM_SLOTf, index & 1);
   8019         SOC_IF_ERROR_RETURN
   8020             (soc_mem_write(unit, IARB_MAIN_TDMm, MEM_BLOCK_ALL, index, entry));
   8021     }
   8022     soc_mem_field32_set(unit, IARB_MAIN_TDMm, entry, TDM_SLOTf, 2);
   8023     SOC_IF_ERROR_RETURN
   8024         (soc_mem_write(unit, IARB_MAIN_TDMm, MEM_BLOCK_ALL, count, entry));
   8025 
   8026     /* Setup main TDM control */
   8027     SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval));
   8028     /* BCMSIM handles Single Cell packets */
   8029     if (SAL_BOOT_BCMSIM) {
   8030         soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 1);
   8031     } else {
   8032         soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0);
   8033     }
   8034     soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_WRAP_PTRf, count);
   8035     SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval));
   8036 
   8037     /* Setup EGR_PERQ_XMT_COUNTERS_BASE_ADDR for each port */
   8038     _soc_trident_egr_perq_xmt_counters_init(unit);
   8039 
   8040     SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval));
   8041     soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1);
   8042     SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval));
   8043 
   8044     /* Enable dual hash on L2, L3 and MPLS_ENTRY tables */
   8045     fields[0] = ENABLEf;
   8046     values[0] = 1;
   8047     fields[1] = HASH_SELECTf;
   8048     values[1] = FB_HASH_CRC32_LOWER;
   8049     fields[2] = INSERT_LEAST_FULL_HALFf;
   8050     values[2] = 1;
   8051     SOC_IF_ERROR_RETURN
   8052         (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   8053                                  fields, values));
   8054     SOC_IF_ERROR_RETURN
   8055         (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3,
   8056                                  fields, values));
   8057     SOC_IF_ERROR_RETURN
   8058         (soc_reg_field32_modify(unit, MPLS_ENTRY_HASH_CONTROLr, REG_PORT_ANY,
   8059                                 INSERT_LEAST_FULL_HALFf, 1));
   8060 
   8061     if (soc_reg_field_valid(unit, ARB_EOP_DEBUGr, ISW2_TD_B0f)) {
   8062         SOC_IF_ERROR_RETURN
   8063             (soc_reg_field32_modify(unit, ARB_EOP_DEBUGr, REG_PORT_ANY,
   8064                                     ISW2_TD_B0f, 1));
   8065     }
   8066 
   8067     if (SOC_SWITCH_BYPASS_MODE(unit) == SOC_SWITCH_BYPASS_MODE_L3_AND_FP) {
   8068         rval = 0;
   8069         soc_reg_field_set(unit, ING_BYPASS_CTRLr, &rval, IFP_BYPASS_ENABLEf,
   8070                           1);
   8071         SOC_IF_ERROR_RETURN(WRITE_ING_BYPASS_CTRLr(unit, rval));
   8072 
   8073         rval = 0;
   8074         soc_reg_field_set(unit, EGR_BYPASS_CTRLr, &rval, EFP_BYPASSf, 1);
   8075         SOC_IF_ERROR_RETURN(WRITE_EGR_BYPASS_CTRLr(unit, rval));
   8076     }
   8077 
   8078     /*
   8079      * Egress Enable
   8080      */
   8081     sal_memset(entry, 0, sizeof(egr_enable_entry_t));
   8082     soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1);
   8083     PBMP_ALL_ITER(unit, port) {
   8084         phy_port = si->port_l2p_mapping[port];
   8085         SOC_IF_ERROR_RETURN
   8086             (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry));
   8087     }
   8088 
   8089     sal_memset(entry, 0, sizeof(epc_link_bmap_entry_t));
   8090     soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf,
   8091                            &PBMP_CMIC(unit));
   8092     SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry));
   8093 
   8094 
   8095     SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &reg64));
   8096     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8097                           L3SRC_HIT_ENABLEf, 1);
   8098     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8099                           L2DST_HIT_ENABLEf, 1);
   8100     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8101                           APPLY_EGR_MASK_ON_L2f, 1);
   8102     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8103                           APPLY_EGR_MASK_ON_L3f, 1);
   8104     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8105                           ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */
   8106     soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8107                           ARP_VALIDATION_ENf, 1);
   8108     if (soc_feature(unit, soc_feature_port_lag_failover)) {
   8109         soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8110                 IGNORE_HG_HDR_LAG_FAILOVERf, 0);
   8111     } else {
   8112         soc_reg64_field32_set(unit, ING_CONFIG_64r, &reg64,
   8113                 IGNORE_HG_HDR_LAG_FAILOVERf, 1);
   8114     }
   8115     SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64));
   8116 
   8117     SOC_IF_ERROR_RETURN
   8118         (soc_reg_field32_modify(unit, EGR_CONFIG_1r, REG_PORT_ANY, RING_MODEf,
   8119                                 1));
   8120 
   8121     /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which
   8122      * causes the outer tag to be removed from packets that don't have
   8123      * a hit in the egress vlan tranlation table. Set to 0 to disable this.
   8124      */
   8125     rval = 0;
   8126     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0);
   8127 
   8128     /* Enable pri/cfi remarking on egress ports. */
   8129     soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,
   8130                       1);
   8131     PBMP_ALL_ITER(unit, port) {
   8132         SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval));
   8133     }
   8134 
   8135     SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit));
   8136     SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit));
   8137     SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm,
   8138                                      MEM_BLOCK_ANY, 0, &entry));
   8139     soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf,
   8140                            &pbmp);
   8141     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm,
   8142                                       MEM_BLOCK_ANY, 0, &entry));
   8143 
   8144     /* Multicast range initialization */
   8145     SOC_IF_ERROR_RETURN
   8146         (soc_hbx_higig2_mcast_sizes_set(unit,
   8147              soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE,
   8148                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   8149              soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE,
   8150                               SOC_HBX_MULTICAST_RANGE_DEFAULT),
   8151              soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE,
   8152                               SOC_HBX_MULTICAST_RANGE_DEFAULT)));
   8153     SOC_IF_ERROR_RETURN
   8154         (soc_hbx_mcast_size_set(unit, soc_property_get(unit,
   8155              spn_MULTICAST_L2_RANGE, SOC_HBX_MULTICAST_RANGE_DEFAULT)));
   8156     SOC_IF_ERROR_RETURN
   8157         (soc_hbx_ipmc_size_set(unit, soc_property_get(unit,
   8158              spn_MULTICAST_L3_RANGE, soc_mem_index_count(unit, L3_IPMCm))));
   8159 
   8160     /* Setup SW2_FP_DST_ACTION_CONTROL */
   8161     fields[0] = HGTRUNK_RES_ENf;
   8162     values[0] = 1;
   8163     fields[1] = LAG_RES_ENf;
   8164     values[1] = 1;
   8165     SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit,
   8166         SW2_FP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values));
   8167 
   8168     /* Populate and enable RTAG7 macro flow offset table */
   8169     if (soc_mem_is_valid(unit, RTAG7_FLOW_BASED_HASHm)) {
   8170         count = soc_mem_index_max(unit, RTAG7_FLOW_BASED_HASHm);
   8171         sal_memset(entry, 0, sizeof(rtag7_flow_based_hash_entry_t));
   8172         for (index = 0; index < count; ) {
   8173             for (sub_sel = 0; sub_sel < 8 && index < count; sub_sel++) {
   8174                 for (offset = 0;
   8175                      offset < rtag7_field_width[sub_sel] && index < count;
   8176                      offset++) {
   8177                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
   8178                                         SUB_SEL_ECMPf, sub_sel);
   8179                     soc_mem_field32_set(unit, RTAG7_FLOW_BASED_HASHm, &entry,
   8180                                         OFFSET_ECMPf, offset);
   8181                     SOC_IF_ERROR_RETURN
   8182                         (soc_mem_write(unit, RTAG7_FLOW_BASED_HASHm,
   8183                                        MEM_BLOCK_ANY, index, &entry));
   8184                     index++;
   8185                 }
   8186             }
   8187         }
   8188         rval = 0;
   8189         soc_reg_field_set(unit, RTAG7_HASH_ECMPr, &rval, USE_FLOW_HASHf, 1);
   8190         for (index = 0; index < 2; index++) {
   8191             SOC_IF_ERROR_RETURN(WRITE_RTAG7_HASH_ECMPr(unit, index, rval));
   8192         }
   8193         rval = 0;
   8194         soc_reg_field_set(unit, RTAG7_HASH_TRILL_ECMPr, &rval, USE_FLOW_HASHf,
   8195                           1);
   8196         for (index = 0; index < 2; index++) {
   8197             SOC_IF_ERROR_RETURN
   8198                 (WRITE_RTAG7_HASH_TRILL_ECMPr(unit, index, rval));
   8199         }
   8200     }
   8201 
   8202     /* Configure FCOE standard Headers */
   8203     SOC_IF_ERROR_RETURN(_soc_trident_fcoe_config_init(unit)); 
   8204 
   8205     /*
   8206      * Set I2C freq to 128KHz (495MHz) or 108KHz (415MHz)
   8207      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / CCR_divisor / 10
   8208      * CCR_divosor = (M + 1) * 2 ** (N + 1)
   8209      * The write only CCR register is at the same address as CMIC_I2C_STAT
   8210      * M is bit [6:3] of CCR register
   8211      * N is bit [2:0] of CCR register
   8212      */
   8213     rval = 0x10; /* M=2, N=0, CCR_divisor = (2+1)*2**(0+1)=6 */
   8214     /* coverity[result_independent_of_operands] */
   8215     SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval));
   8216 
   8217     rval = 0;
   8218     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf, 64);
   8219     soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1);
   8220     /* coverity[result_independent_of_operands] */
   8221     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval));
   8222 
   8223     rval = 0;
   8224     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf, 16);
   8225     soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1);
   8226     /* coverity[result_independent_of_operands] */
   8227     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval));
   8228 
   8229     /*
   8230      * Set external MDIO freq to 6.19MHz (495MHz) or 5.19MHz (415MHz)
   8231      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
   8232      */
   8233     divisor = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVISOR, 40);
   8234     dividend = soc_property_get(unit, spn_RATE_EXT_MDIO_DIVIDEND, 1);
   8235     rval = 0;
   8236     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
   8237     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
   8238     /* coverity[result_independent_of_operands] */
   8239     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
   8240 
   8241     /*
   8242      * Set internal MDIO freq to 16.5MHz (495MHz) or 13.83MHz (415MHz)
   8243      * Valid range is from 2.5MHz to 20MHz
   8244      * target_freq = core_clock_freq * DIVIDEND / DIVISOR / 2
   8245      */
   8246     rval = 0;
   8247     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 15);
   8248     soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1);
   8249     /* coverity[result_independent_of_operands] */
   8250     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval));
   8251 
   8252     delay = soc_property_get(unit, spn_MDIO_OUTPUT_DELAY, -1);
   8253     if (delay >= 1  && delay <= 7) {
   8254         /* coverity[result_independent_of_operands] */
   8255         SOC_IF_ERROR_RETURN(READ_CMIC_CONFIGr(unit, &rval));
   8256         soc_reg_field_set(unit, CMIC_CONFIGr, &rval, MDIO_OUT_DELAYf, delay);
   8257         /* coverity[result_independent_of_operands] */
   8258         SOC_IF_ERROR_RETURN(WRITE_CMIC_CONFIGr(unit, rval));
   8259     }
   8260 
   8261     /* initialize LED UP0 and LED UP1 */
   8262     if (!SOC_WARM_BOOT(unit)) {
   8263         SOC_IF_ERROR_RETURN(_trident_ledup_init(unit));
   8264     }
   8265 
   8266     _phy_wc40_firmware_set_helper[unit] = trident_wc40_firmware_set;
   8267     if (parity_enable) {
   8268         SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit));
   8269     }
   8270 
   8271     return SOC_E_NONE;
   8272 }
   8273 
   8274 #define _TD_MMU_MAX_PACKET_BYTES          10240 /* bytes */
   8275 #define _TD_MMU_PACKET_HEADER_BYTES       64    /* bytes */
   8276 #define _TD_MMU_JUMBO_FRAME_BYTES         9216  /* bytes */
   8277 #define _TD_MMU_DEFAULT_MTU_BYTES         1536  /* bytes */
   8278 
   8279 #define _TD_MMU_TOTAL_CELLS               46080 /* 45k cells */
   8280 
   8281 #define _TD_MMU_BYTES_PER_CELL            208   /* bytes (1664 bits) */
   8282 #define _TD_MMU_NUM_PG                    8
   8283 #define _TD_MMU_NUM_POOL                  4
   8284 
   8285 #define _TD_MMU_BYTES_TO_CELLS(_byte_)  \
   8286     (((_byte_) + _TD_MMU_BYTES_PER_CELL - 1) / _TD_MMU_BYTES_PER_CELL)
   8287 
   8288 /*
   8289  * general syntax: buf.object[id].attribute[.port]="string"
   8290  * Some examples of "cell value" string type:
   8291  *   1000b (b for byte)
   8292  *   1000k (k for kilobyte)
   8293  *   1000m (m for megabyte)
   8294  *   1000c (c for cell)
   8295  *
   8296  * objects    attributes         string type
   8297  * ========================================================================
   8298  * device
   8299  *            headroom           cell value
   8300  *
   8301  * pool#                         # is pool id
   8302  *            size               cell value or %
   8303  *                               This size will affect both ingress and egress
   8304  *                               pool size, it is recommended to use percentage
   8305  *                               since the total pool size calculate for
   8306  *                               ingress and egress are different.
   8307  *            yellow_size        cell value or %
   8308  *                               If the specified value is percentage, it is
   8309  *                               the percentage of the value specified by the
   8310  *                               size attribute
   8311  *                               Use the same value for size, yellow_size, and
   8312  *                               red_size or use 100% for yellow_size and
   8313  *                               red_size to disable color aware.
   8314  *            red_size           cell value or %
   8315  *                               (see notes for yellow_size)
   8316  *
   8317  * port
   8318  *            guarantee          cell value
   8319  *            pool_limit         cell value
   8320  *            pool_resume        cell value
   8321  *            pkt_size           cell value
   8322  *
   8323  * prigroup#                     # is priority group
   8324  *            guarantee          cell value
   8325  *                               specify 0 to disable
   8326  *            headroom           cell value
   8327  *            user_delay         nanosecond
   8328  *            switch_delay       nanosecond
   8329  *            pkt_size           cell value
   8330  *            device_headroom_enable boolean
   8331  *            port_guarantee_enable boolean
   8332  *            port_max_enable    boolean
   8333  *            pool_scale         floating point number value between 1/64 and 8
   8334  *                               Dynamic method will be enabled if this
   8335  *                               attribute is specified.
   8336  *            pool_limit         cell value
   8337  *            pool_resume        cell value
   8338  *            pool_floor         cell value
   8339  *            flow_control_enable boolean
   8340  *
   8341  * queue#                        # is queue id
   8342  * equeue#                       # is extended queue id
   8343  * mqueue#                       # is multicast queue id
   8344  *            guarantee          cell value
   8345  *            discard_enable     boolean
   8346  *            pool_scale         floating point number value between 1/64 and 8
   8347  *                               Dynamic method will be enabled if this
   8348  *                               attribute is specified.
   8349  *            pool_limit         cell value
   8350  *                               Specify 0 to indicate disabling queue limit
   8351  *                               and allow to use shared space.
   8352  *            pool_resume        cell value
   8353  *            color_discard_enable boolean
   8354  *            yellow_limit       cell value for static or % for dynamic
   8355  *                               Use the same value for pool_limit,
   8356  *                               yellow_limit and red_limit to disable color
   8357  *                               aware.
   8358  *                               Use percentage (such as 12.5%, ... 100%) to
   8359  *                               indicate dynamic color limit
   8360  *            red_limit          cell value for static or % for dynamic
   8361  *                               (see notes for yellow_limit)
   8362  *            yellow_resume      cell value
   8363  *            red_resume         cell value
   8364  *
   8365  * ===== mapping =====
   8366  * general syntax: buf.map.from_object.to_object[.port]="string"
   8367  * string is a command separated value list, use 0 if the value is missing
   8368  * for example:
   8369  *     "a,b,c" has same effect as "a,b,c,0,0,0"
   8370  *     "a,,c" has same effect as "a,0,c"
   8371  *
   8372  * buf.map.pri.prigroup[.port]="a,b,c,..."
   8373  *   a is priority group id for priority 0
   8374  *   b is priority group id for priority 1
   8375  *   ...
   8376  *
   8377  * buf.map.prigroup.pool[.port]="a,b,c,..."
   8378  *   a is service pool id for priority group 0
   8379  *   b is service pool id for priority group 1
   8380  *   ...
   8381  *
   8382  * buf.map.queue.pool[.port]="a,b,c,..."
   8383  * buf.map.mqueue.pool[.port]="a,b,c,..."
   8384  *   a is service pool id for queue 0
   8385  *   b is service pool id for queue 1
   8386  *   ...
   8387  */
   8388 
   8389 #define _TD_BUF_DYNAMIC_FLAG        (0x80000000)
   8390 #define _TD_BUF_PERCENT_FLAG        (0x40000000)
   8391 
   8392 typedef struct _soc_trident_buf_prigroup_s {
   8393     int pool_idx; /* from mapping variable */
   8394     int guarantee;
   8395     int headroom;
   8396     int user_delay;
   8397     int switch_delay;
   8398     int pkt_size;
   8399     int device_headroom_enable;
   8400     int port_guarantee_enable;
   8401     int port_max_enable;
   8402     int pool_scale;
   8403     int pool_limit;
   8404     int pool_resume;
   8405     int pool_floor;
   8406     int flow_control_enable;
   8407 } _soc_trident_buf_prigroup_t;
   8408 
   8409 typedef struct _soc_trident_buf_queue_s
   8410 {
   8411     int pool_idx; /* from mapping variable */
   8412     int guarantee;
   8413     int discard_enable;
   8414     int pool_scale;
   8415     int pool_limit;
   8416     int pool_resume;
   8417     int color_discard_enable;
   8418     int yellow_limit;
   8419     int red_limit;
   8420     int yellow_resume;
   8421     int red_resume;
   8422 } _soc_trident_buf_queue_t;
   8423 
   8424 typedef struct _soc_trident_buf_pool_s {
   8425     int size;
   8426     int yellow_size;
   8427     int red_size;
   8428     int total; /* calculated value (not from config variable) */
   8429     int prigroup_guarantee; /* calculated value (not from config variable) */
   8430     int prigroup_headroom; /* calculated value (not from config variable) */
   8431     int queue_guarantee; /* calculated value (not from config variable) */
   8432 } _soc_trident_buf_pool_t;
   8433 
   8434 typedef struct _soc_trident_buf_port_s
   8435 {
   8436     int guarantee;
   8437     int pool_limit;
   8438     int pool_resume;
   8439     int pkt_size;
   8440     _soc_trident_buf_prigroup_t prigroups[8];
   8441     _soc_trident_buf_queue_t *queues;
   8442     int pri_to_prigroup[16]; /* from mapping variable */
   8443 } _soc_trident_buf_port_t;
   8444 
   8445 typedef struct _soc_trident_buf_s
   8446 {
   8447     int headroom;
   8448     _soc_trident_buf_pool_t pools[4];
   8449     _soc_trident_buf_port_t ports[66];
   8450     int port_guarantee; /* calculated value (not from config variable) */
   8451 } _soc_trident_buf_t;
   8452 
   8453 STATIC void
   8454 _soc_trident_property_get(int unit, soc_port_t port, const char *obj,
   8455                           int index, const char *attr, int *setting)
   8456 {
   8457     char suffix;
   8458 
   8459     if (port < 0) {
   8460         *setting = soc_property_obj_attr_get
   8461             (unit, spn_BUF, obj, index, attr, 0, &suffix, *setting);
   8462     } else {
   8463         *setting = soc_property_port_obj_attr_get
   8464             (unit, port, spn_BUF, obj, index, attr, 0, &suffix, *setting);
   8465     }
   8466 }
   8467 
   8468 STATIC void
   8469 _soc_trident_property_get_cells(int unit, soc_port_t port, const char *obj,
   8470                                 int index, const char *attr, int allow_dynamic,
   8471                                 int *setting)
   8472 {
   8473     int val;
   8474     char suffix;
   8475 
   8476     /* scale up by 10 during calculation */
   8477     if (*setting & _TD_BUF_DYNAMIC_FLAG) {
   8478         suffix =  '%';
   8479         val = *setting & ~_TD_BUF_DYNAMIC_FLAG;
   8480         val = (val + 1) * 125; /* 0:125 (12.5%), ... 7:1000 (100%) */
   8481 
   8482     } else {
   8483         suffix = '\0';
   8484         val = *setting * 10;
   8485     }
   8486 
   8487     if (port < 0) {
   8488         val = soc_property_obj_attr_get
   8489             (unit, spn_BUF, obj, index, attr, 1, &suffix, val);
   8490     } else {
   8491         val = soc_property_port_obj_attr_get
   8492             (unit, port, spn_BUF, obj, index, attr, 1, &suffix, val);
   8493     }
   8494 
   8495     if (val < 0) { /* treat negative number as zero */
   8496         val = 0;
   8497     }
   8498 
   8499     /* scale down by 10 after calculation */
   8500     if (allow_dynamic && suffix == '%') {
   8501         val = val > 1000 ? 7 : (val - 1) / 125; /* each unit represent 12.5% */
   8502         val |= _TD_BUF_DYNAMIC_FLAG;
   8503     } else {
   8504         val /= 10;
   8505         switch (suffix) {
   8506         case 'B': /* byte */
   8507         case 'b':
   8508             val = _TD_MMU_BYTES_TO_CELLS(val);
   8509             break;
   8510         case 'K': /* kilobyte */
   8511         case 'k':
   8512             val = _TD_MMU_BYTES_TO_CELLS(val * 1024);
   8513             break;
   8514         case 'M': /* megabyte */
   8515         case 'm':
   8516             val = _TD_MMU_BYTES_TO_CELLS(val * 1048576);
   8517             break;
   8518         default:
   8519             break;
   8520         }
   8521     }
   8522 
   8523     *setting = val;
   8524 }
   8525 
   8526 STATIC void
   8527 _soc_trident_property_get_percentage_x100(int unit, soc_port_t port,
   8528                                           const char *obj, int index,
   8529                                           const char *attr, int *setting)
   8530 {
   8531     int val;
   8532     char suffix;
   8533 
   8534     if (*setting & _TD_BUF_PERCENT_FLAG) {
   8535         suffix =  '%';
   8536         val = *setting & ~_TD_BUF_PERCENT_FLAG;
   8537     } else {
   8538         suffix =  '\0';
   8539         val = *setting;
   8540     }
   8541 
   8542     if (port < 0) {
   8543         val = soc_property_obj_attr_get
   8544             (unit, spn_BUF, obj, index, attr, 2, &suffix, val);
   8545     } else {
   8546         val = soc_property_port_obj_attr_get
   8547             (unit, port, spn_BUF, obj, index, attr, 2, &suffix, val);
   8548     }
   8549 
   8550     if (suffix == '%') {
   8551         if (val < 0) { /* treat negative number as zero */
   8552             val = 0;
   8553         } else if (val > 10000) { /* treat number larger than 100% as 100% */
   8554             val = 10000;
   8555         }
   8556         *setting = val | _TD_BUF_PERCENT_FLAG;
   8557     } else {
   8558         *setting = val;
   8559     }
   8560 }
   8561 
   8562 STATIC void
   8563 _soc_trident_property_get_scale(int unit, soc_port_t port,
   8564                                 const char *obj, int index,
   8565                                 const char *attr, int *setting)
   8566 {
   8567     int val, alpha;
   8568     char suffix;
   8569 
   8570     alpha = 15625;  /* 1/64 = 0.015625, scale up by 1000000 (2**6) */
   8571     val = *setting < 0 ? -1 : alpha << *setting;
   8572 
   8573     if (port < 0) {
   8574         val = soc_property_obj_attr_get
   8575             (unit, spn_BUF, obj, index, attr, 6, &suffix, val);
   8576     } else {
   8577         val = soc_property_port_obj_attr_get
   8578             (unit, port, spn_BUF, obj, index, attr, 6, &suffix, val);
   8579     }
   8580 
   8581     if (val < 0) { /* ignore negative number */
   8582         *setting = -1;
   8583     } else {
   8584         for (*setting = 0; *setting < 9; (*setting)++) {
   8585             if (val <= (alpha << *setting)) {
   8586                 break;
   8587             }
   8588         }
   8589     }
   8590 }
   8591 
   8592 STATIC void
   8593 _soc_trident_mmu_config_buf_default(int unit, _soc_trident_buf_t *buf)
   8594 {
   8595     soc_info_t *si;
   8596     _soc_trident_buf_pool_t *buf_pool;
   8597     _soc_trident_buf_port_t *buf_port;
   8598     _soc_trident_buf_prigroup_t *buf_prigroup;
   8599     _soc_trident_buf_queue_t *buf_queue;
   8600     int max_packet_cells, jumbo_frame_cells, default_mtu_cells;
   8601     int default_pg_headroom_cells;
   8602     int port, idx, count, num_cosq;
   8603 
   8604     si = &SOC_INFO(unit);
   8605 
   8606     max_packet_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_MAX_PACKET_BYTES +
   8607                                               _TD_MMU_PACKET_HEADER_BYTES);
   8608     jumbo_frame_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_JUMBO_FRAME_BYTES +
   8609                                                _TD_MMU_PACKET_HEADER_BYTES);
   8610     default_mtu_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_DEFAULT_MTU_BYTES +
   8611                                                _TD_MMU_PACKET_HEADER_BYTES);
   8612     default_pg_headroom_cells = 160;
   8613 
   8614     buf->headroom = NUM_PORT(unit) * default_mtu_cells;
   8615 
   8616     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   8617         buf_pool = &buf->pools[idx];
   8618 
   8619         if (idx == 0) {  /* 100% scale up by 100 */
   8620             buf_pool->size = 10000 | _TD_BUF_PERCENT_FLAG;
   8621             buf_pool->yellow_size = 10000 | _TD_BUF_PERCENT_FLAG;
   8622             buf_pool->red_size = 10000 | _TD_BUF_PERCENT_FLAG;
   8623         } else {
   8624             buf_pool->size = 0;
   8625             buf_pool->yellow_size = 0;
   8626             buf_pool->red_size = 0;
   8627         }
   8628     }
   8629 
   8630     num_cosq = 0;
   8631     PBMP_ALL_ITER(unit, port) {
   8632         buf_port = &buf->ports[port];
   8633 
   8634         buf_port->guarantee = jumbo_frame_cells;
   8635         buf_port->pool_limit = _TD_MMU_TOTAL_CELLS;
   8636         buf_port->pool_resume = _TD_MMU_TOTAL_CELLS - default_mtu_cells * 2;
   8637         buf_port->pkt_size = max_packet_cells;
   8638 
   8639         /* priority group */
   8640         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   8641             buf_prigroup = &buf_port->prigroups[idx];
   8642 
   8643             buf_prigroup->guarantee = 0;
   8644             buf_prigroup->user_delay = -1;
   8645             buf_prigroup->switch_delay = -1;
   8646             buf_prigroup->pkt_size = max_packet_cells;
   8647             buf_prigroup->device_headroom_enable = 1;
   8648             buf_prigroup->pool_limit = 0;
   8649             buf_prigroup->pool_floor = 0;
   8650             if (idx == 7) {
   8651                 buf_prigroup->headroom = default_pg_headroom_cells;
   8652                 buf_prigroup->port_guarantee_enable = 1;
   8653                 buf_prigroup->port_max_enable = 1;
   8654                 buf_prigroup->pool_scale = 7;
   8655                 buf_prigroup->pool_resume = default_mtu_cells * 2;
   8656                 buf_prigroup->flow_control_enable = 1;
   8657             } else {
   8658                 buf_prigroup->headroom = 0;
   8659                 buf_prigroup->port_guarantee_enable = 0;
   8660                 buf_prigroup->port_max_enable = 0;
   8661                 buf_prigroup->pool_scale = -1;
   8662                 buf_prigroup->pool_resume = 0;
   8663                 buf_prigroup->flow_control_enable = 0;
   8664             }
   8665         }
   8666 
   8667         /* multicast queue */
   8668         count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port];
   8669         num_cosq += count;
   8670         for (idx = 0; idx < count; idx++) {
   8671             buf_queue = &buf_port->queues[idx];
   8672 
   8673             buf_queue->guarantee = default_mtu_cells;
   8674             buf_queue->discard_enable = 0;
   8675             buf_queue->pool_scale = 7;
   8676             buf_queue->pool_limit = 0;
   8677             buf_queue->pool_resume = 8;
   8678             buf_queue->color_discard_enable = 0;
   8679             buf_queue->red_limit = 7 | _TD_BUF_DYNAMIC_FLAG;
   8680         }
   8681 
   8682         /* unicast queue */
   8683         num_cosq += si->port_num_uc_cosq[port];
   8684         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
   8685             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
   8686 
   8687             buf_queue->guarantee = default_mtu_cells;
   8688             buf_queue->discard_enable = 0;
   8689             buf_queue->pool_scale = 7;
   8690             buf_queue->pool_limit = 0;
   8691             buf_queue->pool_resume = 8;
   8692             buf_queue->color_discard_enable = 0;
   8693             buf_queue->yellow_limit = 7 | _TD_BUF_DYNAMIC_FLAG;
   8694             buf_queue->red_limit = 7 | _TD_BUF_DYNAMIC_FLAG;
   8695             buf_queue->yellow_resume = 8;
   8696             buf_queue->red_resume = 8;
   8697         }
   8698 
   8699         /* extended unicast queue */
   8700         count = SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   8701             si->port_num_ext_cosq[port] : 0;
   8702         num_cosq += count;
   8703         for (idx = 0; idx < count; idx++) {
   8704             buf_queue = &buf_port->queues[si->port_num_cosq[port] +
   8705                                           si->port_num_uc_cosq[port] + idx];
   8706 
   8707             buf_queue->guarantee = default_mtu_cells;
   8708             buf_queue->discard_enable = 0;
   8709             buf_queue->pool_scale = 7;
   8710             buf_queue->pool_limit = 0;
   8711             buf_queue->pool_resume = 8;
   8712             buf_queue->color_discard_enable = 0;
   8713             buf_queue->yellow_limit = 7 | _TD_BUF_DYNAMIC_FLAG;
   8714             buf_queue->red_limit = 6 | _TD_BUF_DYNAMIC_FLAG;
   8715             buf_queue->yellow_resume = 8;
   8716             buf_queue->red_resume = 8;
   8717         }
   8718 
   8719         /* internal priority to priority group mapping */
   8720         for (idx = 0; idx < 16; idx++) {
   8721             buf_port->pri_to_prigroup[idx] = 7;
   8722         }
   8723 
   8724         /* priority group to pool mapping */
   8725         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   8726             buf_port->prigroups[idx].pool_idx = 0;
   8727         }
   8728 
   8729         /* queue to pool mapping */
   8730         count = si->port_num_cosq[port] + si->port_num_uc_cosq[port] +
   8731             si->port_num_ext_cosq[port];
   8732         for (idx = 0; idx < count; idx++) {
   8733             buf_port->queues[idx].pool_idx = 0;
   8734         }
   8735     }
   8736 }
   8737 
   8738 STATIC void
   8739 _soc_trident_mmu_config_buf_read(int unit, _soc_trident_buf_t *buf)
   8740 {
   8741     soc_info_t *si;
   8742     _soc_trident_buf_pool_t *buf_pool;
   8743     _soc_trident_buf_port_t *buf_port;
   8744     _soc_trident_buf_prigroup_t *buf_prigroup;
   8745     _soc_trident_buf_queue_t *buf_queue;
   8746     int port, idx, count;
   8747     char name[80];
   8748     int values[64];
   8749 
   8750     si = &SOC_INFO(unit);
   8751 
   8752     _soc_trident_property_get_cells
   8753         (unit, -1, spn_DEVICE, -1, spn_HEADROOM, FALSE, &buf->headroom);
   8754 
   8755     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   8756         buf_pool = &buf->pools[idx];
   8757 
   8758         _soc_trident_property_get_percentage_x100
   8759             (unit, -1, spn_POOL, idx, spn_SIZE, &buf_pool->size);
   8760 
   8761         _soc_trident_property_get_percentage_x100
   8762             (unit, -1, spn_POOL, idx, spn_YELLOW_SIZE, &buf_pool->yellow_size);
   8763 
   8764         _soc_trident_property_get_percentage_x100
   8765             (unit, -1, spn_POOL, idx, spn_RED_SIZE, &buf_pool->red_size);
   8766     }
   8767 
   8768     PBMP_ALL_ITER(unit, port) {
   8769         buf_port = &buf->ports[port];
   8770 
   8771         _soc_trident_property_get_cells
   8772             (unit, port, spn_PORT, -1, spn_GUARANTEE, FALSE,
   8773              &buf_port->guarantee);
   8774 
   8775         _soc_trident_property_get_cells
   8776             (unit, port, spn_PORT, -1, spn_POOL_LIMIT, FALSE,
   8777              &buf_port->pool_limit);
   8778 
   8779         _soc_trident_property_get_cells
   8780             (unit, port, spn_PORT, -1, spn_POOL_RESUME, FALSE,
   8781              &buf_port->pool_resume);
   8782 
   8783         _soc_trident_property_get_cells
   8784             (unit, port, spn_PORT, -1, spn_PKT_SIZE, FALSE,
   8785              &buf_port->pkt_size);
   8786 
   8787         /* priority group */
   8788         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   8789             buf_prigroup = &buf_port->prigroups[idx];
   8790 
   8791             _soc_trident_property_get_cells
   8792                 (unit, port, spn_PRIGROUP, idx, spn_GUARANTEE, FALSE,
   8793                  &buf_prigroup->guarantee);
   8794             buf_prigroup->guarantee = 
   8795                 buf_prigroup->guarantee > 1 ? buf_prigroup->guarantee : 1;
   8796 			
   8797             _soc_trident_property_get_cells
   8798                 (unit, port, spn_PRIGROUP, idx, spn_HEADROOM, FALSE,
   8799                  &buf_prigroup->headroom);
   8800 
   8801             _soc_trident_property_get
   8802                 (unit, port, spn_PRIGROUP, idx, spn_USER_DELAY,
   8803                  &buf_prigroup->user_delay);
   8804 
   8805             _soc_trident_property_get
   8806                 (unit, port, spn_PRIGROUP, idx, spn_SWITCH_DELAY,
   8807                  &buf_prigroup->switch_delay);
   8808 
   8809             _soc_trident_property_get_cells
   8810                 (unit, port, spn_PRIGROUP, idx, spn_PKT_SIZE, FALSE,
   8811                  &buf_prigroup->pkt_size);
   8812 
   8813             _soc_trident_property_get
   8814                 (unit, port, spn_PRIGROUP, idx, spn_DEVICE_HEADROOM_ENABLE,
   8815                  &buf_prigroup->device_headroom_enable);
   8816 
   8817             _soc_trident_property_get
   8818                 (unit, port, spn_PRIGROUP, idx, spn_PORT_GUARANTEE_ENABLE,
   8819                  &buf_prigroup->port_guarantee_enable);
   8820 
   8821             _soc_trident_property_get
   8822                 (unit, port, spn_PRIGROUP, idx, spn_PORT_MAX_ENABLE,
   8823                  &buf_prigroup->port_max_enable);
   8824 
   8825             _soc_trident_property_get_scale
   8826                 (unit, port, spn_PRIGROUP, idx, spn_POOL_SCALE,
   8827                  &buf_prigroup->pool_scale);
   8828 
   8829             _soc_trident_property_get_cells
   8830                 (unit, port, spn_PRIGROUP, idx, spn_POOL_LIMIT, FALSE,
   8831                  &buf_prigroup->pool_limit);
   8832 
   8833             _soc_trident_property_get_cells
   8834                 (unit, port, spn_PRIGROUP, idx, spn_POOL_RESUME, FALSE,
   8835                  &buf_prigroup->pool_resume);
   8836 
   8837             _soc_trident_property_get_cells
   8838                 (unit, port, spn_PRIGROUP, idx, spn_POOL_FLOOR, FALSE,
   8839                  &buf_prigroup->pool_floor);
   8840 
   8841             _soc_trident_property_get
   8842                 (unit, port, spn_PRIGROUP, idx, spn_FLOW_CONTROL_ENABLE,
   8843                  &buf_prigroup->flow_control_enable);
   8844         }
   8845 
   8846         /* multicast queue */
   8847         count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port];
   8848         for (idx = 0; idx < count; idx++) {
   8849             buf_queue = &buf_port->queues[idx];
   8850 
   8851             _soc_trident_property_get_cells
   8852                 (unit, port, spn_MQUEUE, idx, spn_GUARANTEE, FALSE,
   8853                  &buf_queue->guarantee);
   8854 
   8855             _soc_trident_property_get
   8856                 (unit, port, spn_MQUEUE, idx, spn_DISCARD_ENABLE,
   8857                  &buf_queue->discard_enable);
   8858 
   8859             _soc_trident_property_get_scale
   8860                 (unit, port, spn_MQUEUE, idx, spn_POOL_SCALE,
   8861                  &buf_queue->pool_scale);
   8862 
   8863             _soc_trident_property_get_cells
   8864                 (unit, port, spn_MQUEUE, idx, spn_POOL_LIMIT, FALSE,
   8865                  &buf_queue->pool_limit);
   8866 
   8867             _soc_trident_property_get_cells
   8868                 (unit, port, spn_MQUEUE, idx, spn_POOL_RESUME, FALSE,
   8869                  &buf_queue->pool_resume);
   8870 
   8871             _soc_trident_property_get
   8872                 (unit, port, spn_MQUEUE, idx, spn_COLOR_DISCARD_ENABLE,
   8873                  &buf_queue->color_discard_enable);
   8874 
   8875             _soc_trident_property_get_cells
   8876                 (unit, port, spn_MQUEUE, idx, spn_RED_LIMIT, TRUE,
   8877                  &buf_queue->red_limit);
   8878         }
   8879 
   8880         /* unicast queue */
   8881         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
   8882             buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx];
   8883 
   8884             _soc_trident_property_get_cells
   8885                 (unit, port, spn_QUEUE, idx, spn_GUARANTEE, FALSE,
   8886                  &buf_queue->guarantee);
   8887 
   8888             _soc_trident_property_get
   8889                 (unit, port, spn_QUEUE, idx, spn_DISCARD_ENABLE,
   8890                  &buf_queue->discard_enable);
   8891 
   8892             _soc_trident_property_get_scale
   8893                 (unit, port, spn_QUEUE, idx, spn_POOL_SCALE,
   8894                  &buf_queue->pool_scale);
   8895 
   8896             _soc_trident_property_get_cells
   8897                 (unit, port, spn_QUEUE, idx, spn_POOL_LIMIT, FALSE,
   8898                  &buf_queue->pool_limit);
   8899 
   8900             _soc_trident_property_get_cells
   8901                 (unit, port, spn_QUEUE, idx, spn_POOL_RESUME, FALSE,
   8902                  &buf_queue->pool_resume);
   8903 
   8904             _soc_trident_property_get
   8905                 (unit, port, spn_QUEUE, idx, spn_COLOR_DISCARD_ENABLE,
   8906                  &buf_queue->color_discard_enable);
   8907 
   8908             _soc_trident_property_get_cells
   8909                 (unit, port, spn_QUEUE, idx, spn_YELLOW_LIMIT, TRUE,
   8910                  &buf_queue->yellow_limit);
   8911 
   8912             _soc_trident_property_get_cells
   8913                 (unit, port, spn_QUEUE, idx, spn_RED_LIMIT, TRUE,
   8914                  &buf_queue->red_limit);
   8915 
   8916             _soc_trident_property_get_cells
   8917                 (unit, port, spn_QUEUE, idx, spn_YELLOW_RESUME, FALSE,
   8918                  &buf_queue->yellow_resume);
   8919 
   8920             _soc_trident_property_get_cells
   8921                 (unit, port, spn_QUEUE, idx, spn_RED_RESUME, FALSE,
   8922                  &buf_queue->red_resume);
   8923         }
   8924 
   8925         /* extended unicast queue */
   8926         count = SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   8927             si->port_num_ext_cosq[port] : 0;
   8928         for (idx = 0; idx < count; idx++) {
   8929             buf_queue = &buf_port->queues[si->port_num_cosq[port] +
   8930                                           si->port_num_uc_cosq[port] + idx];
   8931 
   8932             _soc_trident_property_get_cells
   8933                 (unit, port, spn_EQUEUE, idx, spn_GUARANTEE, FALSE,
   8934                  &buf_queue->guarantee);
   8935 
   8936             _soc_trident_property_get
   8937                 (unit, port, spn_EQUEUE, idx, spn_DISCARD_ENABLE,
   8938                  &buf_queue->discard_enable);
   8939 
   8940             _soc_trident_property_get_scale
   8941                 (unit, port, spn_EQUEUE, idx, spn_POOL_SCALE,
   8942                  &buf_queue->pool_scale);
   8943 
   8944             _soc_trident_property_get_cells
   8945                 (unit, port, spn_EQUEUE, idx, spn_POOL_LIMIT, FALSE,
   8946                  &buf_queue->pool_limit);
   8947 
   8948             _soc_trident_property_get_cells
   8949                 (unit, port, spn_EQUEUE, idx, spn_POOL_RESUME, FALSE,
   8950                  &buf_queue->pool_resume);
   8951 
   8952             _soc_trident_property_get
   8953                 (unit, port, spn_EQUEUE, idx, spn_COLOR_DISCARD_ENABLE,
   8954                  &buf_queue->color_discard_enable);
   8955 
   8956             _soc_trident_property_get_cells
   8957                 (unit, port, spn_EQUEUE, idx, spn_YELLOW_LIMIT, TRUE,
   8958                  &buf_queue->yellow_limit);
   8959 
   8960             _soc_trident_property_get_cells
   8961                 (unit, port, spn_EQUEUE, idx, spn_RED_LIMIT, TRUE,
   8962                  &buf_queue->red_limit);
   8963 
   8964             _soc_trident_property_get_cells
   8965                 (unit, port, spn_EQUEUE, idx, spn_YELLOW_RESUME, FALSE,
   8966                  &buf_queue->yellow_resume);
   8967 
   8968             _soc_trident_property_get_cells
   8969                 (unit, port, spn_EQUEUE, idx, spn_RED_RESUME, FALSE,
   8970                  &buf_queue->red_resume);
   8971         }
   8972 
   8973         /* internal priority to priority group mapping */
   8974         sal_sprintf(name, "%s.%s.%s.%s",
   8975                     spn_BUF, spn_MAP, spn_PRI, spn_PRIGROUP);
   8976         (void)soc_property_port_get_csv(unit, port, name, 16,
   8977                                         buf_port->pri_to_prigroup);
   8978 
   8979         /* priority group to pool mapping */
   8980         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   8981             values[idx] = buf_port->prigroups[idx].pool_idx;
   8982         }
   8983         sal_sprintf(name, "%s.%s.%s.%s",
   8984                     spn_BUF, spn_MAP, spn_PRIGROUP, spn_POOL);
   8985         count = soc_property_port_get_csv(unit, port, name, _TD_MMU_NUM_PG,
   8986                                           values);
   8987         for (idx = 0; idx < count; idx++) {
   8988             buf_port->prigroups[idx].pool_idx = values[idx];
   8989         }
   8990 
   8991         /* multicast queue to pool mapping */
   8992         count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port];
   8993         buf_queue = &buf_port->queues[0];
   8994         for (idx = 0; idx < count; idx++) {
   8995             values[idx] = buf_queue[idx].pool_idx;
   8996         }
   8997         sal_sprintf(name, "%s.%s.%s.%s",
   8998                     spn_BUF, spn_MAP, spn_MQUEUE, spn_POOL);
   8999         count = soc_property_port_get_csv(unit, port, name, count, values);
   9000         for (idx = 0; idx < count; idx++) {
   9001             buf_queue[idx].pool_idx = values[idx];
   9002         }
   9003 
   9004         /* regular unicast queue to pool mapping */
   9005         count = si->port_num_uc_cosq[port];
   9006         if (count > 0) {
   9007             buf_queue = &buf_port->queues[si->port_num_cosq[port]];
   9008             for (idx = 0; idx < count; idx++) {
   9009                 values[idx] = buf_queue[idx].pool_idx;
   9010             }
   9011             sal_sprintf(name, "%s.%s.%s.%s",
   9012                         spn_BUF, spn_MAP, spn_QUEUE, spn_POOL);
   9013             (void)soc_property_port_get_csv(unit, port, name, count, values);
   9014             for (idx = 0; idx < count; idx++) {
   9015                 buf_queue[idx].pool_idx = values[idx];
   9016             }
   9017         }
   9018 
   9019         /* extended unicast queue to pool mapping */
   9020         count = SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   9021             si->port_num_ext_cosq[port] : 0;
   9022         if (count > 0) {
   9023             buf_queue = &buf_port->queues[si->port_num_cosq[port] +
   9024                                           si->port_num_uc_cosq[port]];
   9025             for (idx = 0; idx < count; idx++) {
   9026                 values[idx] = buf_queue[idx].pool_idx;
   9027             }
   9028             sal_sprintf(name, "%s.%s.%s.%s",
   9029                         spn_BUF, spn_MAP, spn_EQUEUE, spn_POOL);
   9030             (void)soc_property_port_get_csv(unit, port, name, count, values);
   9031             for (idx = 0; idx < count; idx++) {
   9032                 buf_queue[idx].pool_idx = values[idx];
   9033             }
   9034         }
   9035     }
   9036 }
   9037 
   9038 STATIC void
   9039 _soc_trident_mmu_config_buf_calculate(int unit, _soc_trident_buf_t *buf)
   9040 {
   9041     soc_info_t *si;
   9042     _soc_trident_buf_pool_t *buf_pool;
   9043     _soc_trident_buf_port_t *buf_port;
   9044     _soc_trident_buf_prigroup_t *buf_prigroup;
   9045     _soc_trident_buf_queue_t *buf_queue;
   9046     int port, idx, count;
   9047 
   9048     si = &SOC_INFO(unit);
   9049 
   9050     PBMP_ALL_ITER(unit, port) {
   9051         buf_port = &buf->ports[port];
   9052         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9053             buf_prigroup = &buf_port->prigroups[idx];
   9054             if (buf_prigroup->user_delay != -1 &&
   9055                 buf_prigroup->switch_delay != -1) {
   9056                 /*
   9057                  * number of max leftever cells =
   9058                  *   port speed (megabits per sec) * 10**6 (megabits to bit) *
   9059                  *   delay (nsec) / 10**9 (nsecs to second) /
   9060                  *   8 (bits per byte) /
   9061                  *   (IPG (12 bytes) + preamble (8 bytes) +
   9062                  *    worse case packet size (145 bytes)) *
   9063                  *   worse case packet size (2 cells)
   9064                  * heandroom =
   9065                  *   mtu (cells) + number of leftover cells
   9066                  */
   9067                 buf_prigroup->headroom = buf_prigroup->pkt_size +
   9068                     si->port_speed_max[port] *
   9069                     (buf_prigroup->user_delay + buf_prigroup->switch_delay) *
   9070                     2 / (8 * (12 + 8 + 145) * 1000);
   9071             }
   9072         }
   9073     }
   9074 
   9075     /*
   9076      * Input port pool allocation precedence:
   9077      *   reserved space: per port per priority group minimum space
   9078      *   reserved space: per port minimum space (include cpu port)
   9079      *   shared space = total - input port reserved - output port reserved
   9080      *   reserved space: per port per priority group headroom
   9081      *   reserved space: device global headroom
   9082      * Output port:
   9083      *   reserved space: per port per queue minimum space
   9084      *   shared space = total - output port reserved
   9085      *
   9086      * Total memory space equals to
   9087      *     total cells
   9088      *     minus (#1) device global headroom
   9089      * Per pool memory space qeuals to
   9090      *     total memory space * percentage
   9091      * Per pool shared limit equals to
   9092      *     Per pool memory space
   9093      *     minus (#2) input port minimum space (include cpu port)
   9094      *     minus (#3) input port per priority group minimum space (in the pool)
   9095      *     minus (#4) input port per priority group headroom (in the pool)
   9096      *     minus (#5) output port per queue minimum space (in the pool)
   9097      */
   9098 
   9099     buf->port_guarantee = 0;
   9100     PBMP_ALL_ITER(unit, port) {
   9101         buf_port = &buf->ports[port];
   9102         buf->port_guarantee += buf_port->guarantee; /* #2 */
   9103     }
   9104 
   9105     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9106         buf_pool = &buf->pools[idx];
   9107         buf_pool->prigroup_guarantee = 0;
   9108         buf_pool->prigroup_headroom = 0;
   9109         buf_pool->queue_guarantee = 0;
   9110         if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9111             continue;
   9112         }
   9113 
   9114         if (buf_pool->size & _TD_BUF_PERCENT_FLAG) {
   9115             buf_pool->total = (buf_pool->size & ~_TD_BUF_PERCENT_FLAG) *
   9116                 (_TD_MMU_TOTAL_CELLS - buf->headroom) / 10000; /* #1 */
   9117         }
   9118         buf_pool->total -= buf->port_guarantee;
   9119     }
   9120 
   9121     PBMP_ALL_ITER(unit, port) {
   9122         buf_port = &buf->ports[port];
   9123         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9124             buf_prigroup = &buf_port->prigroups[idx];
   9125             buf_pool = &buf->pools[buf_prigroup->pool_idx];
   9126             buf_pool->prigroup_guarantee += buf_prigroup->guarantee; /* #3 */
   9127             buf_pool->prigroup_headroom += buf_prigroup->headroom; /* #4 */
   9128         }
   9129         count = (IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]) +
   9130             si->port_num_uc_cosq[port];
   9131         count += SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   9132             si->port_num_ext_cosq[port] : 0;
   9133         for (idx = 0; idx < count; idx++) {
   9134             buf_queue = &buf_port->queues[idx];
   9135             buf_pool = &buf->pools[buf_queue->pool_idx];
   9136             buf_pool->queue_guarantee += buf_queue->guarantee; /* #5 */
   9137         }
   9138     }
   9139 
   9140     if (bsl_check(bslLayerSoc, bslSourceCommon, bslSeverityVerbose, unit)) {
   9141         LOG_CLI((BSL_META_U(unit,
   9142                             "MMU buffer usage:\n")));
   9143         LOG_CLI((BSL_META_U(unit,
   9144                             "  Global headroom: %d\n"), buf->headroom));
   9145         LOG_CLI((BSL_META_U(unit,
   9146                             "  Total port guarantee: %d\n"), buf->port_guarantee));
   9147         for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9148             buf_pool = &buf->pools[idx];
   9149             if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9150                 continue;
   9151             }
   9152             LOG_CLI((BSL_META_U(unit,
   9153                                 "  Pool %d total prigroup guarantee: %d\n"),
   9154                      idx, buf_pool->prigroup_guarantee));
   9155             LOG_CLI((BSL_META_U(unit,
   9156                                 "  Pool %d total prigroup headroom: %d\n"),
   9157                      idx, buf_pool->prigroup_headroom));
   9158             LOG_CLI((BSL_META_U(unit,
   9159                                 "  Pool %d total queue guarantee: %d\n"),
   9160                      idx, buf_pool->queue_guarantee));
   9161         }
   9162     }
   9163 }
   9164 
   9165 int
   9166 _soc_trident_mmu_config_buf_check(int unit, _soc_trident_buf_t *buf)
   9167 {
   9168     soc_info_t *si;
   9169     _soc_trident_buf_pool_t *buf_pool;
   9170     _soc_trident_buf_port_t *buf_port;
   9171     _soc_trident_buf_prigroup_t *buf_prigroup;
   9172     _soc_trident_buf_queue_t *buf_queue;
   9173     int yellow_cells, red_cells;
   9174     int port, dft_pool, idx, queue_idx, count;
   9175     uint32 pool_map;
   9176     char queue_name[10];
   9177 
   9178     si = &SOC_INFO(unit);
   9179 
   9180     _soc_trident_mmu_config_buf_calculate(unit, buf);
   9181 
   9182     count = 0;
   9183     dft_pool =0;
   9184     pool_map = 0;
   9185     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9186         buf_pool = &buf->pools[idx];
   9187         if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9188             continue;
   9189         }
   9190 
   9191         if (buf_pool->total <=
   9192             buf_pool->prigroup_guarantee + buf_pool->prigroup_headroom +
   9193             buf_pool->queue_guarantee) {
   9194             LOG_CLI((BSL_META_U(unit,
   9195                                 "MMU config: Pool %d memory space size is zero\n"),
   9196                      idx));
   9197             return SOC_E_FAIL;
   9198         }
   9199 
   9200         if (pool_map == 0) {
   9201             dft_pool = idx;
   9202         }
   9203         pool_map |= 1 << idx;
   9204 
   9205         count += buf_pool->total + buf->port_guarantee;
   9206 
   9207         if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) {
   9208             yellow_cells = (buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) *
   9209                 buf_pool->total / 10000;
   9210         } else {
   9211             yellow_cells = buf_pool->yellow_size;
   9212         }
   9213         if (buf_pool->red_size & _TD_BUF_PERCENT_FLAG) {
   9214             red_cells = (buf_pool->red_size & ~_TD_BUF_PERCENT_FLAG) *
   9215                 buf_pool->total / 10000;
   9216         } else {
   9217             red_cells = buf_pool->red_size;
   9218         }
   9219 
   9220         if (yellow_cells > red_cells) {
   9221             LOG_CLI((BSL_META_U(unit,
   9222                                 "MMU config pool %d: Yellow cells offset is higher "
   9223                                 "than red cells\n"), idx));
   9224         }
   9225         if (red_cells > buf_pool->total) {
   9226             LOG_CLI((BSL_META_U(unit,
   9227                                 "MMU config pool %d: Red cells offset is higher "
   9228                                 "than pool shared cells\n"), idx));
   9229         }
   9230     }
   9231     if (count > _TD_MMU_TOTAL_CELLS - buf->headroom) {
   9232         LOG_CLI((BSL_META_U(unit,
   9233                             "MMU config: The summary of pool shared cells is more "
   9234                             "than total shared cells available\n")));
   9235     }
   9236 
   9237     
   9238 
   9239     PBMP_ALL_ITER(unit, port) {
   9240         buf_port = &buf->ports[port];
   9241 
   9242         /* internal priority to priority group mapping */
   9243         for (idx = 0; idx < 16; idx++) {
   9244             if (buf_port->pri_to_prigroup[idx] < 0 ||
   9245                 buf_port->pri_to_prigroup[idx] >= _TD_MMU_NUM_PG) {
   9246                 LOG_CLI((BSL_META_U(unit,
   9247                                     "MMU config port %d: Invalid prigroup value (%d) "
   9248                                     "for internal priority %d\n"),
   9249                          port, buf_port->pri_to_prigroup[idx], idx));
   9250                 buf_port->pri_to_prigroup[idx] = 0; /* use prigroup 0 */
   9251             }
   9252         }
   9253 
   9254         /* priority group to pool mapping */
   9255         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9256             buf_prigroup = &buf_port->prigroups[idx];
   9257             if (buf_prigroup->pool_idx < 0 ||
   9258                 buf_prigroup->pool_idx >= _TD_MMU_NUM_POOL) {
   9259                 LOG_CLI((BSL_META_U(unit,
   9260                                     "MMU config port %d prigroup %d: "
   9261                                     "Invalid pool value (%d)\n"),
   9262                          port, idx, buf_prigroup->pool_idx));
   9263                 /* use first non-empty pool */
   9264                 buf_prigroup->pool_idx = dft_pool;
   9265             } else if (!(pool_map & (1 << buf_prigroup->pool_idx))) {
   9266                 LOG_CLI((BSL_META_U(unit,
   9267                                     "MMU config port %d prigroup %d: "
   9268                                     "Pool %d is empty\n"),
   9269                          port, idx, buf_prigroup->pool_idx));
   9270             }
   9271         }
   9272 
   9273         /* queue to pool mapping */
   9274         count = (IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port]) +
   9275             si->port_num_uc_cosq[port];
   9276         count += SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   9277             si->port_num_ext_cosq[port] : 0;
   9278         for (idx = 0; idx < count; idx++) {
   9279             buf_queue = &buf->ports[port].queues[idx];
   9280 
   9281             queue_idx = idx;
   9282             if (queue_idx < si->port_num_cosq[port]) {
   9283                 sal_sprintf(queue_name, "mqueue %d", queue_idx);
   9284             } else {
   9285                 queue_idx -= si->port_num_cosq[port];
   9286                 if (queue_idx < si->port_num_uc_cosq[port]) {
   9287                     sal_sprintf(queue_name, "queue %d", queue_idx);
   9288                 } else {
   9289                     queue_idx -= si->port_num_uc_cosq[port];
   9290                     sal_sprintf(queue_name, "equeue %d", queue_idx);
   9291                 }
   9292             }
   9293 
   9294             if (buf_queue->pool_idx < 0 ||
   9295                 buf_queue->pool_idx >= _TD_MMU_NUM_POOL) {
   9296                 LOG_CLI((BSL_META_U(unit,
   9297                                     "MMU config port %d %s: "
   9298                          "Invalid pool value (%d)\n"),
   9299                          port, queue_name, buf_queue->pool_idx));
   9300                 buf_queue->pool_idx = dft_pool; /* use first non-empty pool */
   9301             } else if (!(pool_map & (1 << buf_queue->pool_idx))) {
   9302                 LOG_CLI((BSL_META_U(unit,
   9303                                     "MMU config port %d %s: Pool %d is empty\n"),
   9304                          port, queue_name, buf_queue->pool_idx));
   9305             }
   9306         }
   9307     }
   9308 
   9309     return SOC_E_NONE;
   9310 }
   9311 
   9312 STATIC int
   9313 _soc_trident_mmu_config_buf_set_hw(int unit, _soc_trident_buf_t *buf)
   9314 {
   9315     soc_info_t *si;
   9316     _soc_trident_buf_pool_t *buf_pool;
   9317     _soc_trident_buf_port_t *buf_port;
   9318     _soc_trident_buf_prigroup_t *buf_prigroup;
   9319     _soc_trident_buf_queue_t *buf_queue;
   9320     soc_reg_t reg = INVALIDr;
   9321     soc_mem_t config_mem, offset_mem;
   9322     uint32 rval, fval;
   9323     uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS];
   9324     int default_mtu_cells, limit;
   9325     int port, phy_port, mmu_port, base, idx, count;
   9326     static const soc_field_t prigroup_reg[] = {
   9327         PORT_PRI_GRP0r, PORT_PRI_GRP1r
   9328     };
   9329     static const soc_field_t prigroup_field[] = {
   9330         PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf,
   9331         PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf,
   9332         PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf,
   9333         PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf
   9334     };
   9335     static const soc_field_t prigroup_spid_field[] = {
   9336         PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf,
   9337         PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf
   9338     };
   9339     static const soc_field_t uc_spid_field[] = {
   9340         COS0_SPIDf, COS1_SPIDf, COS2_SPIDf, COS3_SPIDf,
   9341         COS4_SPIDf, COS5_SPIDf, COS6_SPIDf, COS7_SPIDf,
   9342         COS8_SPIDf, COS9_SPIDf
   9343     };
   9344     static const soc_field_t ext_spid_reg[] = {
   9345         OP_EX_PORT_CONFIG_SPID_0r, OP_EX_PORT_CONFIG_SPID_1r,
   9346         OP_EX_PORT_CONFIG_SPID_2r, OP_EX_PORT_CONFIG_SPID_3r,
   9347         OP_EX_PORT_CONFIG_SPID_4r
   9348     };
   9349     static const soc_field_t ext_spid_field[] = {
   9350         Q0_SPIDf, Q1_SPIDf, Q2_SPIDf, Q3_SPIDf,
   9351         Q4_SPIDf, Q5_SPIDf, Q6_SPIDf, Q7_SPIDf,
   9352         Q8_SPIDf, Q9_SPIDf, Q10_SPIDf, Q11_SPIDf,
   9353         Q12_SPIDf, Q13_SPIDf, Q14_SPIDf, Q15_SPIDf,
   9354         Q16_SPIDf, Q17_SPIDf, Q18_SPIDf, Q19_SPIDf,
   9355         Q20_SPIDf, Q21_SPIDf, Q22_SPIDf, Q23_SPIDf,
   9356         Q24_SPIDf, Q25_SPIDf, Q26_SPIDf, Q27_SPIDf,
   9357         Q28_SPIDf, Q29_SPIDf, Q30_SPIDf, Q31_SPIDf,
   9358         Q32_SPIDf, Q33_SPIDf, Q34_SPIDf, Q35_SPIDf,
   9359         Q36_SPIDf, Q37_SPIDf, Q38_SPIDf, Q39_SPIDf,
   9360         Q40_SPIDf, Q41_SPIDf, Q42_SPIDf, Q43_SPIDf,
   9361         Q44_SPIDf, Q45_SPIDf, Q46_SPIDf, Q47_SPIDf,
   9362         Q48_SPIDf, Q49_SPIDf, Q50_SPIDf, Q51_SPIDf,
   9363         Q52_SPIDf, Q53_SPIDf, Q54_SPIDf, Q55_SPIDf,
   9364         Q56_SPIDf, Q57_SPIDf, Q58_SPIDf, Q59_SPIDf,
   9365         Q60_SPIDf, Q61_SPIDf, Q62_SPIDf, Q63_SPIDf,
   9366         Q64_SPIDf, Q65_SPIDf, Q66_SPIDf, Q67_SPIDf,
   9367         Q68_SPIDf, Q69_SPIDf, Q70_SPIDf, Q71_SPIDf,
   9368         Q72_SPIDf, Q73_SPIDf
   9369     };
   9370 
   9371     si = &SOC_INFO(unit);
   9372 
   9373     default_mtu_cells = _TD_MMU_BYTES_TO_CELLS(_TD_MMU_DEFAULT_MTU_BYTES +
   9374                                                _TD_MMU_PACKET_HEADER_BYTES);
   9375 
   9376     /* internal priority to priority group mapping */
   9377     PBMP_ALL_ITER(unit, port) {
   9378         buf_port = &buf->ports[port];
   9379 
   9380         for (idx = 0; idx < 16; idx++) {
   9381             if (idx % 8 == 0) { /* 8 fields per register */
   9382                 reg = prigroup_reg[idx / 8];
   9383                 rval = 0;
   9384             }
   9385             soc_reg_field_set(unit, reg, &rval, prigroup_field[idx],
   9386                               buf_port->pri_to_prigroup[idx]);
   9387             if (idx % 8 == 7) { /* 8 fields per register */
   9388                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval));
   9389             }
   9390         }
   9391     }
   9392 
   9393     /* Input port device settings */
   9394     rval = 0;
   9395     soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &rval, GLOBAL_HDRM_LIMITf,
   9396                       buf->headroom);
   9397     SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, rval));
   9398 
   9399     fval = 0;
   9400     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9401         if ((buf->pools[idx].size & ~_TD_BUF_PERCENT_FLAG) != 0) {
   9402             fval |= 1 << idx;
   9403         }
   9404     }
   9405     rval = 0;
   9406     soc_reg_field_set(unit, USE_SP_SHAREDr, &rval, ENABLEf, fval);
   9407     SOC_IF_ERROR_RETURN(WRITE_USE_SP_SHAREDr(unit, rval));
   9408 
   9409     fval = 0;
   9410     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9411         buf_pool = &buf->pools[idx];
   9412         if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9413             continue;
   9414         }
   9415 
   9416         if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) {
   9417             if ((buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) < 10000) {
   9418                 fval |= 1 << idx;
   9419             }
   9420         } else {
   9421             if (buf->pools[idx].size != buf->pools[idx].yellow_size) {
   9422                 fval |= 1 << idx;
   9423             }
   9424         }
   9425     }
   9426     rval = 0;
   9427     soc_reg_field_set(unit, COLOR_AWAREr, &rval, ENABLEf, fval);
   9428     SOC_IF_ERROR_RETURN(WRITE_COLOR_AWAREr(unit, rval));
   9429 
   9430     /* Input port per service pool settings */
   9431     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9432         buf_pool = &buf->pools[idx];
   9433         if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9434             continue;
   9435         }
   9436 
   9437         limit = buf_pool->total - buf_pool->prigroup_guarantee -
   9438             buf_pool->prigroup_headroom - buf_pool->queue_guarantee;
   9439 
   9440         rval = 0;
   9441         soc_reg_field_set(unit, BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, limit);
   9442         SOC_IF_ERROR_RETURN(WRITE_BUFFER_CELL_LIMIT_SPr(unit, idx, rval));
   9443 
   9444         rval = 0;
   9445         soc_reg_field_set(unit, CELL_RESET_LIMIT_OFFSET_SPr, &rval, OFFSETf,
   9446                           NUM_PORT(unit) * default_mtu_cells / 2);
   9447         SOC_IF_ERROR_RETURN
   9448             (WRITE_CELL_RESET_LIMIT_OFFSET_SPr(unit, idx, rval));
   9449 
   9450         if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) {
   9451             if ((buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) == 10000) {
   9452                 continue;
   9453             }
   9454         } else {
   9455             if (buf->pools[idx].size == buf->pools[idx].yellow_size) {
   9456                 continue;
   9457             }
   9458         }
   9459 
   9460         if (buf_pool->yellow_size & _TD_BUF_PERCENT_FLAG) {
   9461             fval = (buf_pool->yellow_size & ~_TD_BUF_PERCENT_FLAG) * limit /
   9462                 10000;
   9463         } else {
   9464             fval = buf_pool->yellow_size;
   9465         }
   9466         rval = 0;
   9467         soc_reg_field_set(unit, CELL_SPAP_YELLOW_OFFSET_SPr, &rval, OFFSETf,
   9468                           fval);
   9469         SOC_IF_ERROR_RETURN
   9470             (WRITE_CELL_SPAP_YELLOW_OFFSET_SPr(unit, idx, rval));
   9471 
   9472         if (buf_pool->red_size & _TD_BUF_PERCENT_FLAG) {
   9473             fval = (buf_pool->red_size & ~_TD_BUF_PERCENT_FLAG) * limit /
   9474                 10000;
   9475         } else {
   9476             fval = buf_pool->red_size;
   9477         }
   9478         rval = 0;
   9479         soc_reg_field_set(unit, CELL_SPAP_RED_OFFSET_SPr, &rval, OFFSETf,
   9480                           fval);
   9481         SOC_IF_ERROR_RETURN(WRITE_CELL_SPAP_RED_OFFSET_SPr(unit, idx, rval));
   9482     }
   9483 
   9484     /* Input port per port settings */
   9485     PBMP_ALL_ITER(unit, port) {
   9486         buf_port = &buf->ports[port];
   9487 
   9488         rval = 0;
   9489         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9490             soc_reg_field_set(unit, PORT_PG_SPIDr, &rval,
   9491                               prigroup_spid_field[idx],
   9492                               buf_port->prigroups[idx].pool_idx);
   9493         }
   9494         SOC_IF_ERROR_RETURN(WRITE_PORT_PG_SPIDr(unit, port, rval));
   9495 
   9496         rval = 0;
   9497         soc_reg_field_set(unit, PORT_MIN_CELLr, &rval, PORT_MINf,
   9498                           buf_port->guarantee);
   9499         SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_CELLr(unit, port, rval));
   9500 
   9501         rval = 0;
   9502         soc_reg_field_set(unit, PORT_MAX_SHARED_CELLr, &rval, PORT_MAXf,
   9503                           buf_port->pool_limit);
   9504         SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_SHARED_CELLr(unit, port, rval));
   9505 
   9506         rval = 0;
   9507         soc_reg_field_set(unit, PORT_RESUME_LIMIT_CELLr, &rval, CELLSf,
   9508                           buf_port->pool_resume);
   9509         SOC_IF_ERROR_RETURN(WRITE_PORT_RESUME_LIMIT_CELLr(unit, port, rval));
   9510 
   9511         fval = 0;
   9512         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9513             if (buf_port->prigroups[idx].port_guarantee_enable != 0) {
   9514                 fval |= 1 << idx;
   9515             }
   9516         }
   9517         rval = 0;
   9518         soc_reg_field_set(unit, PORT_MIN_PG_ENABLEr, &rval, PG_BMPf, fval);
   9519         SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_PG_ENABLEr(unit, port, rval));
   9520 
   9521         fval = 0;
   9522         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9523             if (buf_port->prigroups[idx].port_max_enable != 0) {
   9524                 fval |= 1 << idx;
   9525             }
   9526         }
   9527         rval = 0;
   9528         soc_reg_field_set(unit, PORT_SHARED_MAX_PG_ENABLEr, &rval, PG_BMPf,
   9529                           fval);
   9530         SOC_IF_ERROR_RETURN
   9531             (WRITE_PORT_SHARED_MAX_PG_ENABLEr(unit, port, rval));
   9532 
   9533         fval = 0;
   9534         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9535             if (buf_port->prigroups[idx].flow_control_enable != 0) {
   9536                 fval |= 1 << idx;
   9537             }
   9538         }
   9539         rval = 0;
   9540         soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval,
   9541                           PORT_PRI_XON_ENABLEf, fval);
   9542         SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval));
   9543 
   9544         rval = 0;
   9545         soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval, PORT_MAX_PKT_SIZEf,
   9546                           buf_port->pkt_size);
   9547         SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval));
   9548 
   9549         /* Input port per port per priority group settings */
   9550         for (idx = 0; idx < _TD_MMU_NUM_PG; idx++) {
   9551             buf_prigroup = &buf->ports[port].prigroups[idx];
   9552 
   9553             rval = 0;
   9554             soc_reg_field_set(unit, PG_MIN_CELLr, &rval, PG_MINf,
   9555                               buf_prigroup->guarantee > 1 ? buf_prigroup->guarantee : 1);
   9556             SOC_IF_ERROR_RETURN
   9557                 (soc_reg32_set(unit, PG_MIN_CELLr, port, idx, rval));
   9558 
   9559             rval = 0;
   9560             soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &rval, PG_GEf,
   9561                               buf_prigroup->device_headroom_enable);
   9562             soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &rval, PG_HDRM_LIMITf,
   9563                               buf_prigroup->headroom);
   9564             SOC_IF_ERROR_RETURN
   9565                 (soc_reg32_set(unit, PG_HDRM_LIMIT_CELLr, port, idx, rval));
   9566 
   9567             rval = 0;
   9568             if (buf_prigroup->pool_scale != -1) {
   9569                 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval,
   9570                                   PG_SHARED_DYNAMICf, 1);
   9571                 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval,
   9572                                   PG_SHARED_LIMITf, buf_prigroup->pool_scale);
   9573             } else {
   9574                 /* PG_SHARED_DYNAMICf is 0 */
   9575                 soc_reg_field_set(unit, PG_SHARED_LIMIT_CELLr, &rval,
   9576                                   PG_SHARED_LIMITf, buf_prigroup->pool_limit);
   9577             }
   9578             SOC_IF_ERROR_RETURN
   9579                 (soc_reg32_set(unit, PG_SHARED_LIMIT_CELLr, port, idx, rval));
   9580 
   9581             rval = 0;
   9582             soc_reg_field_set(unit, PG_RESET_OFFSET_CELLr, &rval,
   9583                               PG_RESET_OFFSETf, buf_prigroup->pool_resume);
   9584             SOC_IF_ERROR_RETURN
   9585                 (soc_reg32_set(unit, PG_RESET_OFFSET_CELLr, port, idx, rval));
   9586 
   9587             rval = 0;
   9588             soc_reg_field_set(unit, PG_RESET_FLOOR_CELLr, &rval,
   9589                               PG_RESET_FLOORf, buf_prigroup->pool_floor);
   9590             SOC_IF_ERROR_RETURN
   9591                 (soc_reg32_set(unit, PG_RESET_FLOOR_CELLr, port, idx, rval));
   9592         }
   9593     }
   9594 
   9595     /* Output port per port per queue setting for multicast queue */
   9596     PBMP_ALL_ITER(unit, port) {
   9597         count = IS_LB_PORT(unit, port) ? 5 : si->port_num_cosq[port];
   9598         for (idx = 0; idx < count; idx++) {
   9599             buf_queue = &buf->ports[port].queues[idx];
   9600 
   9601             rval = 0;
   9602             soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval, Q_MIN_CELLf,
   9603                               buf_queue->guarantee);
   9604             if (buf_queue->pool_scale != -1) {
   9605                 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval,
   9606                                   Q_SHARED_ALPHA_CELLf,
   9607                                   buf_queue->pool_scale);
   9608             } else {
   9609                 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &rval,
   9610                                   Q_SHARED_LIMIT_CELLf,
   9611                                   buf_queue->pool_limit);
   9612             }
   9613             SOC_IF_ERROR_RETURN
   9614                 (WRITE_OP_QUEUE_CONFIG_CELLr(unit, port, idx, rval));
   9615 
   9616             rval = 0;
   9617             if (buf_queue->discard_enable) {
   9618                 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9619                                   Q_LIMIT_ENABLE_CELLf, 1);
   9620             } else {
   9621                 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9622                                   Q_LIMIT_ENABLE_CELLf, 0);
   9623             }
   9624             if (buf_queue->pool_scale != -1) {
   9625                 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9626                                   Q_LIMIT_DYNAMIC_CELLf, 1);
   9627             }
   9628             if (buf_queue->color_discard_enable) {
   9629                 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9630                                   Q_COLOR_ENABLE_CELLf, 1);
   9631             }
   9632             if (buf_queue->red_limit & _TD_BUF_DYNAMIC_FLAG) {
   9633                 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9634                                   Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
   9635             }
   9636             soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval,
   9637                               Q_SPIDf, buf_queue->pool_idx);
   9638             SOC_IF_ERROR_RETURN
   9639                 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval));
   9640 
   9641             rval = 0;
   9642             soc_reg_field_set(unit, OP_QUEUE_LIMIT_COLOR_CELLr, &rval, REDf,
   9643                               buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG);
   9644             SOC_IF_ERROR_RETURN
   9645                 (WRITE_OP_QUEUE_LIMIT_COLOR_CELLr(unit, port, idx, rval));
   9646 
   9647             rval = 0;
   9648             soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_CELLr, &rval,
   9649                               Q_RESET_OFFSET_CELLf,
   9650                               buf_queue->pool_resume / 8);
   9651             SOC_IF_ERROR_RETURN
   9652                 (WRITE_OP_QUEUE_RESET_OFFSET_CELLr(unit, port, idx, rval));
   9653         }
   9654     }
   9655 
   9656     /* Output port per port per queue setting for regular unicast queue */
   9657     PBMP_PORT_ITER(unit, port) {
   9658         phy_port = si->port_l2p_mapping[port];
   9659         mmu_port = si->port_p2m_mapping[phy_port];
   9660         if (si->port_num_ext_cosq[port] == 0) {
   9661             if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */
   9662                 config_mem = MMU_THDO_CONFIG_0m;
   9663                 offset_mem = MMU_THDO_OFFSET_0m;
   9664                 /* Index starts from mmu port 5, 10 entries per port */
   9665                 base = (mmu_port - 5) * 10;
   9666             } else { /* Y pipe */
   9667                 config_mem = MMU_THDO_CONFIG_1m;
   9668                 offset_mem = MMU_THDO_OFFSET_1m;
   9669                 /* Index starts from mmu port 38, 10 entries per port */
   9670                 base = (mmu_port - 38) * 10;
   9671             }
   9672         } else {
   9673             /*
   9674              * Depends on OP_VOQ_PORT_CONFIG mode setting for the extended
   9675              * queue port:
   9676              * - cos mode
   9677              *     use MMU_THDO_CONFIG_SP_x table, 10 entries per port
   9678              * - queue mode
   9679              *     use MMU_THDO_CONFIG_EX_x table, 74 entries per port
   9680              *     extended unicast queues: index 0-63
   9681              *     regular unicast queue: index 64-73
   9682              */
   9683             if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */
   9684                 config_mem = MMU_THDO_CONFIG_EX_0m;
   9685                 offset_mem = MMU_THDO_OFFSET_EX_0m;
   9686                 /* Index starts from mmu port 1, 74 entries per port */
   9687                 base = (mmu_port - 1) * 74 + 64;
   9688             } else { /* Y pipe */
   9689                 config_mem = MMU_THDO_CONFIG_EX_1m;
   9690                 offset_mem = MMU_THDO_OFFSET_EX_1m;
   9691                 /* Index starts from mmu port 34, 74 entries per port */
   9692                 base = (mmu_port - 34) * 74 + 64;
   9693             }
   9694         }
   9695         for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) {
   9696             buf_queue = &buf->ports[port].queues
   9697                 [si->port_num_cosq[port] + idx];
   9698 
   9699             sal_memset(entry0, 0, sizeof(mmu_thdo_config_0_entry_t));
   9700             sal_memset(entry1, 0, sizeof(mmu_thdo_offset_0_entry_t));
   9701 
   9702             soc_mem_field32_set(unit, config_mem, entry0, Q_MIN_CELLf,
   9703                                 buf_queue->guarantee);
   9704             if (buf_queue->discard_enable) {
   9705                 soc_mem_field32_set(unit, config_mem, entry0,
   9706                                     Q_LIMIT_ENABLE_CELLf, 1);
   9707             } else {
   9708                 soc_mem_field32_set(unit, config_mem, entry0,
   9709                                     Q_LIMIT_ENABLE_CELLf, 0);
   9710             }
   9711             if (buf_queue->pool_scale != -1) {
   9712                 soc_mem_field32_set(unit, config_mem, entry0,
   9713                                     Q_LIMIT_DYNAMIC_CELLf, 1);
   9714                 soc_mem_field32_set(unit, config_mem, entry0,
   9715                                     Q_SHARED_ALPHA_CELLf,
   9716                                     buf_queue->pool_scale);
   9717             } else {
   9718                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
   9719                 soc_mem_field32_set(unit, config_mem, entry0,
   9720                                     Q_SHARED_LIMIT_CELLf,
   9721                                     buf_queue->pool_limit);
   9722             }
   9723             soc_mem_field32_set(unit, offset_mem, entry1, RESET_OFFSET_CELLf,
   9724                                 buf_queue->pool_resume / 8);
   9725             if (buf_queue->color_discard_enable) {
   9726                 soc_mem_field32_set(unit, config_mem, entry0,
   9727                                     Q_COLOR_ENABLE_CELLf, fval);
   9728             }
   9729             if (buf_queue->yellow_limit & _TD_BUF_DYNAMIC_FLAG) {
   9730                 soc_mem_field32_set(unit, config_mem, entry0,
   9731                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
   9732                 soc_mem_field32_set
   9733                     (unit, config_mem, entry0, LIMIT_YELLOW_CELLf,
   9734                      buf_queue->yellow_limit & ~_TD_BUF_DYNAMIC_FLAG);
   9735                 soc_mem_field32_set
   9736                     (unit, offset_mem, entry1, LIMIT_RED_CELLf,
   9737                      buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG);
   9738             } else {
   9739                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
   9740                 soc_mem_field32_set
   9741                     (unit, config_mem, entry0, LIMIT_YELLOW_CELLf,
   9742                      buf_queue->yellow_limit / 8);
   9743                 soc_mem_field32_set
   9744                     (unit, offset_mem, entry1, LIMIT_RED_CELLf,
   9745                      buf_queue->red_limit / 8);
   9746             }
   9747             soc_mem_field32_set
   9748                 (unit, offset_mem, entry1, RESET_OFFSET_YELLOW_CELLf,
   9749                  buf_queue->yellow_resume / 8);
   9750             soc_mem_field32_set
   9751                 (unit, offset_mem, entry1, RESET_OFFSET_RED_CELLf,
   9752                  buf_queue->red_resume / 8);
   9753             SOC_IF_ERROR_RETURN
   9754                 (soc_mem_write(unit, config_mem, MEM_BLOCK_ALL,
   9755                                base + idx, entry0));
   9756             SOC_IF_ERROR_RETURN
   9757                 (soc_mem_write(unit, offset_mem, MEM_BLOCK_ALL,
   9758                                base + idx, entry1));
   9759         }
   9760     }
   9761 
   9762     /* Output port per port per queue setting for extended unicast queue */
   9763     SOC_PBMP_ITER(si->eq_pbm, port) {
   9764         /* coverity[overrun-local : FALSE] */
   9765         phy_port = si->port_l2p_mapping[port];
   9766         mmu_port = si->port_p2m_mapping[phy_port];
   9767 
   9768         /*
   9769          * 74 entries per port:
   9770          *     extended unicast queues: index 0-63
   9771          *     regular unicast queue: index 64-73 (when in queue mode)
   9772          */
   9773         if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* X pipe */
   9774             config_mem = MMU_THDO_CONFIG_EX_0m;
   9775             offset_mem = MMU_THDO_OFFSET_EX_0m;
   9776             /* Index starts from mmu port 1, 74 entries per port */
   9777             base = (mmu_port - 1) * 74;
   9778         } else { /* Y pipe */
   9779             config_mem = MMU_THDO_CONFIG_EX_1m;
   9780             offset_mem = MMU_THDO_OFFSET_EX_1m;
   9781             /* Index starts from mmu port 34, 74 entries per port */
   9782             base = (mmu_port - 34) * 74;
   9783         }
   9784 
   9785         for (idx = 0; idx < si->port_num_ext_cosq[port]; idx++) {
   9786             /* coverity[overrun-local : FALSE] */
   9787             buf_queue = &buf->ports[port].queues
   9788                 [si->port_num_cosq[port] + si->port_num_uc_cosq[port] + idx];
   9789 
   9790             sal_memset(entry0, 0, sizeof(mmu_thdo_config_ex_0_entry_t));
   9791             sal_memset(entry1, 0, sizeof(mmu_thdo_offset_ex_0_entry_t));
   9792 
   9793             soc_mem_field32_set(unit, config_mem, entry0, Q_MIN_CELLf,
   9794                                 buf_queue->guarantee);
   9795             if (buf_queue->discard_enable) {
   9796                 soc_mem_field32_set(unit, config_mem, entry0,
   9797                                     Q_LIMIT_ENABLE_CELLf, 1);
   9798             } else {
   9799                 soc_mem_field32_set(unit, config_mem, entry0,
   9800                                     Q_LIMIT_ENABLE_CELLf, 0);
   9801             }
   9802             if (buf_queue->pool_scale != -1) {
   9803                 soc_mem_field32_set(unit, config_mem, entry0,
   9804                                     Q_LIMIT_DYNAMIC_CELLf, 1);
   9805                 soc_mem_field32_set(unit, config_mem, entry0,
   9806                                     Q_SHARED_ALPHA_CELLf,
   9807                                     buf_queue->pool_scale);
   9808             } else {
   9809                 /* Q_LIMIT_DYNAMIC_CELLf is 0 */
   9810                 soc_mem_field32_set(unit, config_mem, entry0,
   9811                                     Q_SHARED_LIMIT_CELLf,
   9812                                     buf_queue->pool_limit);
   9813             }
   9814             soc_mem_field32_set(unit, offset_mem, entry1, RESET_OFFSET_CELLf,
   9815                                 buf_queue->pool_resume / 8);
   9816             if (buf_queue->color_discard_enable) {
   9817                 soc_mem_field32_set(unit, config_mem, entry0,
   9818                                     Q_COLOR_ENABLE_CELLf, fval);
   9819             }
   9820             if (buf_queue->yellow_limit & _TD_BUF_DYNAMIC_FLAG) {
   9821                 soc_mem_field32_set(unit, config_mem, entry0,
   9822                                     Q_COLOR_LIMIT_DYNAMIC_CELLf, 1);
   9823                 soc_mem_field32_set
   9824                     (unit, config_mem, entry0, LIMIT_YELLOW_CELLf,
   9825                      buf_queue->yellow_limit & ~_TD_BUF_DYNAMIC_FLAG);
   9826                 soc_mem_field32_set
   9827                     (unit, offset_mem, entry1, LIMIT_RED_CELLf,
   9828                      buf_queue->red_limit & ~_TD_BUF_DYNAMIC_FLAG);
   9829             } else {
   9830                 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */
   9831                 soc_mem_field32_set
   9832                     (unit, config_mem, entry0, LIMIT_YELLOW_CELLf,
   9833                      buf_queue->yellow_limit / 8);
   9834                 soc_mem_field32_set
   9835                     (unit, offset_mem, entry1, LIMIT_RED_CELLf,
   9836                      buf_queue->red_limit / 8);
   9837             }
   9838             soc_mem_field32_set
   9839                 (unit, offset_mem, entry1, RESET_OFFSET_YELLOW_CELLf,
   9840                  buf_queue->yellow_resume / 8);
   9841             soc_mem_field32_set
   9842                 (unit, offset_mem, entry1, RESET_OFFSET_RED_CELLf,
   9843                  buf_queue->red_resume / 8);
   9844             SOC_IF_ERROR_RETURN
   9845                 (soc_mem_write(unit, config_mem, MEM_BLOCK_ALL,
   9846                                base + idx, entry0));
   9847             SOC_IF_ERROR_RETURN
   9848                 (soc_mem_write(unit, offset_mem, MEM_BLOCK_ALL,
   9849                                base + idx, entry1));
   9850         }
   9851     }
   9852 
   9853     /* Output port per port settings */
   9854     PBMP_PORT_ITER(unit, port) {
   9855         buf_port = &buf->ports[port];
   9856 
   9857         /* regular unicast queue to pool mapping */
   9858         count = si->port_num_uc_cosq[port];
   9859         if (count > 0) {
   9860             buf_queue = &buf->ports[port].queues[si->port_num_cosq[port]];
   9861             rval = 0;
   9862             if (si->port_num_ext_cosq[port] == 0) {
   9863                 for (idx = 0; idx < count; idx++) {
   9864                     soc_reg_field_set(unit, OP_UC_PORT_CONFIG1_CELLr, &rval,
   9865                                       uc_spid_field[idx],
   9866                                       buf_queue[idx].pool_idx);
   9867                 }
   9868                 SOC_IF_ERROR_RETURN
   9869                     (WRITE_OP_UC_PORT_CONFIG1_CELLr(unit, port, rval));
   9870             } else {
   9871                 for (idx = 0; idx < count; idx++) {
   9872                     soc_reg_field_set(unit, OP_EX_PORT_CONFIG_SPID_4r, &rval,
   9873                                       ext_spid_field[idx + 64],
   9874                                       buf_queue[idx].pool_idx);
   9875                 }
   9876                 SOC_IF_ERROR_RETURN
   9877                     (WRITE_OP_EX_PORT_CONFIG_SPID_4r(unit, port, rval));
   9878             }
   9879         }
   9880 
   9881         /* extended unicast queue to pool mapping */
   9882         count = SOC_PBMP_MEMBER(si->eq_pbm, port) ?
   9883             si->port_num_ext_cosq[port] : 0;
   9884         if (count > 0) {
   9885             buf_queue = &buf_port->queues[si->port_num_cosq[port] +
   9886                                           si->port_num_uc_cosq[port]];
   9887             for (idx = 0; idx < count; idx++) {
   9888                 if (idx % 16 == 0) { /* 16 fields per register */
   9889                     reg = ext_spid_reg[idx / 16];
   9890                     rval = 0;
   9891                 }
   9892                 soc_reg_field_set(unit, reg, &rval, ext_spid_field[idx],
   9893                                   buf_queue[idx].pool_idx);
   9894                 if (idx % 16 == 15) { /* 16 fields per register */
   9895                     SOC_IF_ERROR_RETURN
   9896                         (soc_reg32_set(unit, reg, port, 0, rval));
   9897                 }
   9898             }
   9899         }
   9900     }
   9901 
   9902     /* Output port per pool settings */
   9903     for (idx = 0; idx < _TD_MMU_NUM_POOL; idx++) {
   9904         buf_pool = &buf->pools[idx];
   9905         if ((buf_pool->size & ~_TD_BUF_PERCENT_FLAG) == 0) {
   9906             continue;
   9907         }
   9908         limit = buf_pool->total + buf->port_guarantee -
   9909             buf_pool->queue_guarantee;
   9910 
   9911         rval = 0;
   9912         soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, &rval,
   9913                           OP_BUFFER_SHARED_LIMIT_CELLf, limit);
   9914         SOC_IF_ERROR_RETURN
   9915             (soc_reg32_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, REG_PORT_ANY,
   9916                            idx, rval));
   9917 
   9918         rval = 0;
   9919         soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, &rval,
   9920                           OP_BUFFER_LIMIT_YELLOW_CELLf, limit / 8);
   9921         SOC_IF_ERROR_RETURN
   9922             (soc_reg32_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, REG_PORT_ANY,
   9923                            idx, rval));
   9924 
   9925         rval = 0;
   9926         soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_CELLr, &rval,
   9927                           OP_BUFFER_LIMIT_RED_CELLf, limit / 8);
   9928         SOC_IF_ERROR_RETURN
   9929             (soc_reg32_set(unit, OP_BUFFER_LIMIT_RED_CELLr, REG_PORT_ANY,
   9930                            idx, rval));
   9931 
   9932         rval = 0;
   9933         soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr, &rval,
   9934                           OP_BUFFER_SHARED_LIMIT_RESUME_CELLf, limit);
   9935         SOC_IF_ERROR_RETURN
   9936             (soc_reg32_set(unit, OP_BUFFER_SHARED_LIMIT_RESUME_CELLr,
   9937                            REG_PORT_ANY, idx, rval));
   9938 
   9939         rval = 0;
   9940         soc_reg_field_set(unit, OP_BUFFER_LIMIT_RESUME_YELLOW_CELLr, &rval,
   9941                           OP_BUFFER_LIMIT_RESUME_YELLOW_CELLf, limit / 8);
   9942         SOC_IF_ERROR_RETURN
   9943             (soc_reg32_set(unit, OP_BUFFER_LIMIT_RESUME_YELLOW_CELLr,
   9944                            REG_PORT_ANY, idx, rval));
   9945 
   9946         rval = 0;
   9947         soc_reg_field_set(unit, OP_BUFFER_LIMIT_RESUME_RED_CELLr, &rval,
   9948                           OP_BUFFER_LIMIT_RESUME_RED_CELLf, limit / 8);
   9949         SOC_IF_ERROR_RETURN
   9950             (soc_reg32_set(unit, OP_BUFFER_LIMIT_RESUME_RED_CELLr,
   9951                            REG_PORT_ANY, idx, rval));
   9952 
   9953         /* Output port per port per pool setting for unicast queues */
   9954         PBMP_PORT_ITER(unit, port) {
   9955             rval = 0;
   9956             soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval,
   9957                               OP_SHARED_LIMIT_CELLf, limit);
   9958             soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval,
   9959                               OP_SHARED_RESET_VALUE_CELLf,
   9960                               limit - default_mtu_cells);
   9961             SOC_IF_ERROR_RETURN
   9962                 (WRITE_OP_UC_PORT_CONFIG_CELLr(unit, port, idx, rval));
   9963 
   9964             rval = 0;
   9965             soc_reg_field_set(unit, OP_UC_PORT_LIMIT_COLOR_CELLr, &rval, YELf,
   9966                               limit / 8);
   9967             soc_reg_field_set(unit, OP_UC_PORT_LIMIT_COLOR_CELLr, &rval, REDf,
   9968                               limit / 8);
   9969             SOC_IF_ERROR_RETURN
   9970                 (WRITE_OP_UC_PORT_LIMIT_COLOR_CELLr(unit, port, idx, rval));
   9971 
   9972             rval = 0;
   9973             soc_reg_field_set
   9974                 (unit, OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, YELf,
   9975                  (limit - default_mtu_cells) / 8);
   9976             soc_reg_field_set
   9977                 (unit, OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, REDf,
   9978                  (limit - default_mtu_cells) / 8);
   9979             SOC_IF_ERROR_RETURN
   9980                 (WRITE_OP_UC_PORT_LIMIT_RESUME_COLOR_CELLr
   9981                  (unit, port, idx, rval));
   9982 
   9983             rval = 0;
   9984         }
   9985 
   9986         /* Output port per port per pool setting for multicast queues */
   9987         PBMP_ALL_ITER(unit, port) {
   9988             rval = 0;
   9989             soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &rval,
   9990                               OP_SHARED_LIMIT_CELLf, limit);
   9991             soc_reg_field_set(unit, OP_UC_PORT_CONFIG_CELLr, &rval,
   9992                               OP_SHARED_RESET_VALUE_CELLf,
   9993                               limit - default_mtu_cells);
   9994             SOC_IF_ERROR_RETURN
   9995                 (soc_reg32_set(unit, OP_PORT_CONFIG_CELLr, port, idx, rval));
   9996 
   9997             rval = 0;
   9998             soc_reg_field_set(unit, OP_PORT_LIMIT_COLOR_CELLr, &rval, REDf,
   9999                               limit / 8);
  10000             SOC_IF_ERROR_RETURN
  10001                 (soc_reg32_set(unit, OP_PORT_LIMIT_COLOR_CELLr, port, idx,
  10002                                rval));
  10003 
  10004             rval = 0;
  10005             soc_reg_field_set
  10006                 (unit, OP_PORT_LIMIT_RESUME_COLOR_CELLr, &rval, REDf,
  10007                               (limit - default_mtu_cells) / 8);
  10008             SOC_IF_ERROR_RETURN
  10009                 (soc_reg32_set(unit, OP_PORT_LIMIT_RESUME_COLOR_CELLr, port,
  10010                                idx, rval));
  10011         }
  10012     }
  10013 
  10014     return SOC_E_NONE;
  10015 }
  10016 
  10017 int
  10018 soc_trident_mmu_config_init(int unit, int test_only)
  10019 {
  10020     soc_info_t *si;
  10021     _soc_trident_buf_t *buf;
  10022     _soc_trident_buf_queue_t *buf_queue;
  10023     int rv, port, alloc_size, num_cosq;
  10024 
  10025     si = &SOC_INFO(unit);
  10026 
  10027     alloc_size = sizeof(_soc_trident_buf_t);
  10028     PBMP_ALL_ITER(unit, port) {
  10029         num_cosq = si->port_num_cosq[port] + si->port_num_uc_cosq[port] +
  10030             si->port_num_ext_cosq[port];
  10031         alloc_size += sizeof(_soc_trident_buf_queue_t) * num_cosq;
  10032     }
  10033     buf = sal_alloc(alloc_size, "MMU config buffer");
  10034     if (buf == NULL) {
  10035         return SOC_E_MEMORY;
  10036     }
  10037 
  10038     sal_memset(buf, 0, alloc_size);
  10039     buf_queue = (_soc_trident_buf_queue_t *)&buf[1];
  10040     PBMP_ALL_ITER(unit, port) {
  10041         num_cosq = si->port_num_cosq[port] + si->port_num_uc_cosq[port] +
  10042             si->port_num_ext_cosq[port];
  10043         buf->ports[port].queues = buf_queue;
  10044         buf_queue += num_cosq;
  10045     }
  10046 
  10047     _soc_trident_mmu_config_buf_default(unit, buf);
  10048     _soc_trident_mmu_config_buf_read(unit, buf);
  10049     rv = _soc_trident_mmu_config_buf_check(unit, buf);
  10050     if (!test_only) {
  10051         if (SOC_FAILURE(rv)) {
  10052             LOG_CLI((BSL_META_U(unit,
  10053                                 "MMU config: Use default setting\n")));
  10054             _soc_trident_mmu_config_buf_default(unit, buf);
  10055             _soc_trident_mmu_config_buf_calculate(unit, buf);
  10056         }
  10057         rv = _soc_trident_mmu_config_buf_set_hw(unit, buf);
  10058     }
  10059 
  10060     sal_free(buf);
  10061 
  10062     return rv;
  10063 }
  10064 
  10065 STATIC int
  10066 _soc_trident_mmu_init(int unit)
  10067 {
  10068     soc_info_t *si;
  10069     uint64 r64val0, r64val1, r64val2;
  10070     uint32 rval0, rval1;
  10071     uint32 rval_base[3][4], rval_credit[3];
  10072     soc_pbmp_t pbmp0, pbmp1;
  10073     int credit;
  10074     int port, phy_port, mmu_port, idx, mode_idx, mode;
  10075     int blk_bandwidth;
  10076     uint32 mode4_bmp, mode2_bmp;
  10077     static const soc_field_t gb_field[] = {
  10078         GB_PORT0f, GB_PORT1f, GB_PORT2f, GB_PORT3f
  10079     };
  10080 
  10081     si = &SOC_INFO(unit);
  10082 
  10083     /* Setup TDM for MMU */
  10084     SOC_IF_ERROR_RETURN(_soc_trident_mmu_tdm_init(unit));
  10085 
  10086     /* Enable QGPORT (1G x 4) in XLPORT0 block (if present) */
  10087     blk_bandwidth = 0;
  10088     for (phy_port = 1; phy_port < 5; phy_port++) {
  10089         port = si->port_p2l_mapping[phy_port];
  10090         if (port != -1) {
  10091             blk_bandwidth += si->port_speed_max[port];
  10092         }
  10093     }
  10094     COMPILER_64_ZERO(r64val0);
  10095     if (blk_bandwidth > 0 && blk_bandwidth <= 4000) {
  10096         for (phy_port = 1; phy_port < 5; phy_port++) {
  10097             mmu_port = si->port_p2m_mapping[phy_port];
  10098             if (mmu_port < 0) {
  10099                 soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0,
  10100                                       gb_field[phy_port - 1], 0x3f);
  10101             } else {
  10102                 soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0,
  10103                                       gb_field[phy_port - 1], mmu_port);
  10104             }
  10105         }
  10106         soc_reg64_field32_set(unit, ES_TDM_CONFIGr, &r64val0,
  10107                               EN_CPU_SLOT_SHARINGf, 1);
  10108     }
  10109     SOC_IF_ERROR_RETURN(WRITE_ES_TDM_CONFIGr(unit, r64val0));
  10110 
  10111     mode4_bmp = mode2_bmp = 0;
  10112     for (mode_idx = 0; mode_idx < 16; mode_idx++) {
  10113         /* 1, 2, 3, 4, 17, 18, 19, 20, 34, 35, 36, 37, 50, 51, 52, 53 */
  10114         mmu_port = (((mode_idx & 0xc) << 2) | (mode_idx & 0x3)) +
  10115             (mode_idx < 8 ? 1 : 2);
  10116         if (si->port_m2p_mapping[mmu_port] == -1) {
  10117             continue;
  10118         }
  10119         phy_port = si->port_m2p_mapping[mmu_port];
  10120         port = si->port_p2l_mapping[phy_port];
  10121         if (si->port_speed_max[port] > 20000) {
  10122             if (si->port_m2p_mapping[mmu_port + 4] == -1 &&
  10123                 si->port_m2p_mapping[mmu_port + 8] == -1 &&
  10124                 si->port_m2p_mapping[mmu_port + 12] == -1) {
  10125                 mode4_bmp |= 1 << mode_idx;
  10126             }
  10127         } else if (si->port_speed_max[port] > 10000) {
  10128             if ((si->port_speed_max[port] == 20000) &&
  10129                 (si->port_num_lanes[port] == 4)) {
  10130                 if (si->port_m2p_mapping[mmu_port + 4] == -1 &&
  10131                     si->port_m2p_mapping[mmu_port + 8] == -1 &&
  10132                     si->port_m2p_mapping[mmu_port + 12] == -1) {
  10133                     mode4_bmp |= 1 << mode_idx;
  10134                 }
  10135             } else {
  10136                 if (si->port_m2p_mapping[mmu_port + 4] == -1 &&
  10137                     si->port_m2p_mapping[mmu_port + 12] == -1) {
  10138                     mode2_bmp |= 1 << mode_idx;
  10139                 }
  10140             }
  10141         }
  10142     }
  10143     rval0 = 0;
  10144     soc_reg_field_set(unit, MCQ_CONFIGr, &rval0, MODE_4f, mode4_bmp);
  10145     soc_reg_field_set(unit, MCQ_CONFIGr, &rval0, MODE_2f, mode2_bmp);
  10146     SOC_IF_ERROR_RETURN(WRITE_MCQ_CONFIGr(unit, rval0));
  10147 
  10148     SOC_IF_ERROR_RETURN(soc_trident_mmu_config_init(unit, FALSE));
  10149 
  10150     rval0 = 0;
  10151     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, MOP_POLICYf, 7);
  10152     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, ASF_PKT_SIZEf, 3);
  10153     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, ASF_QUEUE_SIZEf, 3);
  10154     soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, YELLOW_CELL_DS_SELECTf, 1);
  10155     SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval0));
  10156 
  10157     /* Set extended queue ports to use queue mode accounting */
  10158     rval0 = 0;
  10159     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P1f, 1);
  10160     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P2f, 1);
  10161     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P3f, 1);
  10162     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P4f, 1);
  10163     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P34f, 1);
  10164     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P35f, 1);
  10165     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P36f, 1);
  10166     soc_reg_field_set(unit, OP_VOQ_PORT_CONFIGr, &rval0, Q_SEL_P37f, 1);
  10167     SOC_IF_ERROR_RETURN(WRITE_OP_VOQ_PORT_CONFIGr(unit, rval0));
  10168 
  10169     /* OVQ settings */
  10170     rval0 = 0;
  10171     soc_reg_field_set(unit, OVQ_DROP_THRESHOLD0r, &rval0,
  10172                       OVQ_DROP_THRESHOLD0f, _TD_MMU_TOTAL_CELLS / 4);
  10173     SOC_IF_ERROR_RETURN(WRITE_OVQ_DROP_THRESHOLD0r(unit, rval0));
  10174 
  10175     rval0 = 0;
  10176     soc_reg_field_set(unit, OVQ_DROP_THRESHOLD_RESET_LIMITr, &rval0,
  10177                       OVQ_DROP_THRESHOLD_RESET_LIMITf,
  10178                       _TD_MMU_TOTAL_CELLS / 4);
  10179     SOC_IF_ERROR_RETURN
  10180         (WRITE_OVQ_DROP_THRESHOLD_RESET_LIMITr(unit, rval0));
  10181 
  10182     rval0 = 0;
  10183     soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0, OVQ_FC_ENABLEf,
  10184                       1);
  10185     soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0,
  10186                       OVQ_FC_THRESHOLDf, 11250);
  10187     soc_reg_field_set(unit, OVQ_FLOWCONTROL_THRESHOLDr, &rval0,
  10188                       OVQ_FC_THRESHOLD_RESET_LIMITf, 11249);
  10189     SOC_IF_ERROR_RETURN(WRITE_OVQ_FLOWCONTROL_THRESHOLDr(unit, rval0));
  10190 
  10191     sal_memset(rval_base, 0, sizeof(rval_base));
  10192     sal_memset(rval_credit, 0, sizeof(rval_credit));
  10193     for (mode = 0; mode < 3; mode++) { /* MODE_1, MODE_2, MODE_4 */
  10194         /* MODE_x means a port has x subports, each subport has 1000 credits,
  10195          * divide total credit from all subports by 5 multicast queues,
  10196          * then truncate the result to multiple of 16 */
  10197         credit = ((1 << mode) * 1000 / 5) & ~0xf;
  10198         soc_reg_field_set(unit, OVQ_MCQ_CREDITSr, &rval_credit[mode], CREDITSf,
  10199                           credit);
  10200         for (idx = 0; idx < 4; idx++) {
  10201             soc_reg_field_set(unit, MCQ_FIFO_BASE_REGr, &rval_base[mode][idx],
  10202                           Q_MCQ_FIFO_BASEf, credit / 16 * (idx + 1));
  10203         }
  10204     }
  10205     PBMP_ALL_ITER(unit, port) {
  10206         if (IS_CPU_PORT(unit, port)) {
  10207             continue;
  10208         }
  10209         if (IS_LB_PORT(unit, port)) {
  10210             mode = 0; /* MODE_1 */
  10211         } else {
  10212             phy_port = si->port_l2p_mapping[port];
  10213             mmu_port = si->port_p2m_mapping[phy_port];
  10214             /* 1, 2, 3, 4, 17, 18, 19, 20, 34, 35, 36, 37, 50, 51, 52, 53 */
  10215             mode_idx = mmu_port - 1 - (mmu_port > 33 ? 1 : 0);
  10216             mode_idx = ((mode_idx & 0x30) >> 2) + (mode_idx & 3);
  10217             if (mode4_bmp & (1 << mode_idx)) {
  10218                 mode = 2; /* MODE_4 */
  10219             } else if (mode2_bmp & (1 << mode_idx)) {
  10220                 mode = 1; /* MODE_2 */
  10221             } else {
  10222                 mode = 0; /* MODE_1 */
  10223             }
  10224         }
  10225         for (idx = 0; idx < 5; idx++) {
  10226             SOC_IF_ERROR_RETURN
  10227                 (WRITE_OVQ_MCQ_CREDITSr(unit, port, idx, rval_credit[mode]));
  10228             if (idx > 0) {
  10229                 SOC_IF_ERROR_RETURN
  10230                     (WRITE_MCQ_FIFO_BASE_REGr(unit, port, idx,
  10231                                               rval_base[mode][idx - 1]));
  10232             }
  10233         }
  10234     }
  10235 
  10236     SOC_PBMP_CLEAR(pbmp0);
  10237     SOC_PBMP_CLEAR(pbmp1);
  10238     PBMP_ALL_ITER(unit, port) {
  10239         mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]];
  10240         if (IS_CPU_PORT(unit, port) ||
  10241             (si->port_group[port] >= 0 && si->port_group[port] <= 1)) {
  10242             SOC_PBMP_PORT_ADD(pbmp0, mmu_port);
  10243         } else {
  10244             SOC_PBMP_PORT_ADD(pbmp1, mmu_port - 33);
  10245         }
  10246     }
  10247 
  10248     /* Enable pause */
  10249     COMPILER_64_ZERO(r64val0);
  10250     soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE0_64r, &r64val0,
  10251                           PORT_PAUSE_ENABLE_LOf,
  10252                           SOC_PBMP_WORD_GET(pbmp0, 0));
  10253     soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE0_64r, &r64val0,
  10254                           PORT_PAUSE_ENABLE_HIf,
  10255                           SOC_PBMP_WORD_GET(pbmp0, 1));
  10256     SOC_IF_ERROR_RETURN(WRITE_PORT_PAUSE_ENABLE0_64r(unit, r64val0));
  10257     COMPILER_64_ZERO(r64val0);
  10258     soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE1_64r, &r64val0,
  10259                           PORT_PAUSE_ENABLE_LOf,
  10260                           SOC_PBMP_WORD_GET(pbmp1, 0));
  10261     soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE1_64r, &r64val0,
  10262                           PORT_PAUSE_ENABLE_HIf,
  10263                           SOC_PBMP_WORD_GET(pbmp1, 1));
  10264     SOC_IF_ERROR_RETURN(WRITE_PORT_PAUSE_ENABLE1_64r(unit, r64val0));
  10265 
  10266     /* Enable input port */
  10267     COMPILER_64_ZERO(r64val0);
  10268     soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE0_64r, &r64val0,
  10269                           INPUT_PORT_RX_ENABLE_LOf,
  10270                           SOC_PBMP_WORD_GET(pbmp0, 0));
  10271     soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE0_64r, &r64val0,
  10272                           INPUT_PORT_RX_ENABLE_HIf,
  10273                           SOC_PBMP_WORD_GET(pbmp0, 1));
  10274     SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE0_64r(unit, r64val0));
  10275     COMPILER_64_ZERO(r64val0);
  10276     soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE1_64r, &r64val0,
  10277                           INPUT_PORT_RX_ENABLE_LOf,
  10278                           SOC_PBMP_WORD_GET(pbmp1, 0));
  10279     soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE1_64r, &r64val0,
  10280                           INPUT_PORT_RX_ENABLE_HIf,
  10281                           SOC_PBMP_WORD_GET(pbmp1, 1));
  10282     SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE1_64r(unit, r64val0));
  10283 
  10284     /* Enable output port */
  10285     COMPILER_64_ZERO(r64val0);
  10286     soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE0_64r, &r64val0,
  10287                           OUTPUT_PORT_RX_ENABLE0_LOf,
  10288                           SOC_PBMP_WORD_GET(pbmp0, 0));
  10289     soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE0_64r, &r64val0,
  10290                           OUTPUT_PORT_RX_ENABLE0_HIf,
  10291                           SOC_PBMP_WORD_GET(pbmp0, 1));
  10292     SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLE0_64r(unit, r64val0));
  10293     COMPILER_64_ZERO(r64val0);
  10294     soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE1_64r, &r64val0,
  10295                           OUTPUT_PORT_RX_ENABLE1_LOf,
  10296                           SOC_PBMP_WORD_GET(pbmp1, 0));
  10297     soc_reg64_field32_set(unit, OUTPUT_PORT_RX_ENABLE1_64r, &r64val0,
  10298                           OUTPUT_PORT_RX_ENABLE1_HIf,
  10299                           SOC_PBMP_WORD_GET(pbmp1, 1));
  10300     SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLE1_64r(unit, r64val0));
  10301 
  10302     /*
  10303      * default scheduling:
  10304      *     unicast queue 0 and multicast queue 0 connect to S3.0
  10305      *     unicast queue 1 and multicast queue 1 connect to S3.1
  10306      *     unicast queue 2 and multicast queue 2 connect to S3.2
  10307      *     unicast queue 3 and multicast queue 3 connect to S3.3
  10308      *     S3.0 - S3.3 and unicast queue 4 - 7 connect to S2.0
  10309      *     S2.1, S2.2, MC group are not used
  10310      */
  10311     rval0 = 0;
  10312     soc_reg_field_set(unit, S3_CONFIGr, &rval0, SCHEDULING_SELECTf, 0x55);
  10313 
  10314     rval1 = 0;
  10315     soc_reg_field_set(unit, S2_CONFIGr, &rval1, SCHEDULING_SELECTf, 0x15);
  10316 
  10317     /* S3.0 - S3.3 and unicast queues 4 - 7 to S2.0 */
  10318     COMPILER_64_ZERO(r64val0);
  10319     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I0f, 0);
  10320     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I1f, 1);
  10321     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I2f, 2);
  10322     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I3f, 3);
  10323     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I4f, 8);
  10324     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I5f, 9);
  10325     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I6f, 10);
  10326     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I7f, 11);
  10327     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val0, S3_GROUP_NO_I8f,
  10328                           0x1f);
  10329 
  10330     COMPILER_64_ZERO(r64val1);
  10331     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I0f,
  10332                           0x1f);
  10333     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I1f,
  10334                           0x1f);
  10335     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I2f,
  10336                           0x1f);
  10337     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I3f,
  10338                           0x1f);
  10339     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I4f,
  10340                           0x1f);
  10341     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I5f,
  10342                           0x1f);
  10343     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I6f,
  10344                           0x1f);
  10345     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I7f,
  10346                           0x1f);
  10347     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I7f,
  10348                           0x1f);
  10349     soc_reg64_field32_set(unit, S2_S3_ROUTINGr, &r64val1, S3_GROUP_NO_I8f,
  10350                           0x1f);
  10351     /* S2.1 and S2.2 are not used */
  10352     r64val2 = r64val1;
  10353 
  10354     PBMP_ALL_ITER(unit, port) {
  10355         if (IS_CPU_PORT(unit, port)) {
  10356             continue;
  10357         }
  10358         SOC_IF_ERROR_RETURN(WRITE_S3_CONFIGr(unit, port, rval0));
  10359         SOC_IF_ERROR_RETURN(WRITE_S2_CONFIGr(unit, port, rval1));
  10360         SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 0, r64val0));
  10361         SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 1, r64val1));
  10362         SOC_IF_ERROR_RETURN(WRITE_S2_S3_ROUTINGr(unit, port, 2, r64val2));
  10363     }
  10364 
  10365     return SOC_E_NONE;
  10366 }
  10367 
  10368 int
  10369 soc_trident_mem_config(int unit)
  10370 {
  10371     uint16              dev_id;
  10372     uint8               rev_id;
  10373     int                 index_max;
  10374     int                 l2_entries; 
  10375     int                 l3_entries;
  10376     soc_persist_t *sop;    
  10377 
  10378     sop = SOC_PERSIST(unit);
  10379 
  10380     soc_cm_get_id(unit, &dev_id, &rev_id);
  10381     switch (dev_id) {
  10382         case BCM56838_DEVICE_ID:
  10383             /* Trunk groups */             
  10384             index_max = 127;
  10385             sop->memState[TRUNK_GROUPm].index_max = index_max;
  10386             sop->memState[TRUNK_BITMAPm].index_max = index_max;
  10387             sop->memState[TRUNK_CBL_TABLEm].index_max = index_max;
  10388 
  10389             /* ECMP entry */
  10390             index_max = 1023;
  10391             sop->memState[L3_ECMPm].index_max = index_max;         
  10392             sop->memState[INITIAL_L3_ECMPm].index_max = index_max;
  10393             sop->memState[INITIAL_L3_ECMP_Xm].index_max = index_max;
  10394             sop->memState[INITIAL_L3_ECMP_Ym].index_max = index_max;           
  10395             break;
  10396         case BCM56831_DEVICE_ID:
  10397             /* Trunk groups */            
  10398             index_max = 47;
  10399             sop->memState[TRUNK_GROUPm].index_max = index_max;
  10400             sop->memState[TRUNK_BITMAPm].index_max = index_max;
  10401             sop->memState[TRUNK_CBL_TABLEm].index_max = index_max;
  10402 
  10403             /* L2MC */
  10404             sop->memState[L2MCm].index_max = 12287;
  10405             break;
  10406         case BCM56847_DEVICE_ID:
  10407             /* L2 entry : 64K */
  10408             l2_entries = 65536;            
  10409             sop->memState[L2Xm].index_max = l2_entries - 1;
  10410             sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
  10411             sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1;
  10412             sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1;
  10413 
  10414             /* L2MC: 4K L2MC + 2K IPMC */
  10415             sop->memState[L2MCm].index_max = 6143;            
  10416 
  10417             /* L3 entry : 8K */
  10418             l3_entries = 8192;
  10419             sop->memState[L3_ENTRY_ONLYm].index_max = l3_entries - 1;
  10420             sop->memState[L3_ENTRY_IPV4_UNICASTm].index_max = l3_entries - 1;
  10421             sop->memState[L3_ENTRY_IPV4_UNICAST_Xm].index_max = l3_entries - 1;
  10422             sop->memState[L3_ENTRY_IPV4_UNICAST_Ym].index_max = l3_entries - 1;            
  10423             sop->memState[L3_ENTRY_IPV4_MULTICASTm].index_max = 
  10424                 l3_entries / 2 - 1;
  10425             sop->memState[L3_ENTRY_IPV4_MULTICAST_Xm].index_max = 
  10426                 l3_entries / 2 - 1;
  10427             sop->memState[L3_ENTRY_IPV4_MULTICAST_Ym].index_max = 
  10428                 l3_entries / 2 - 1;            
  10429             sop->memState[L3_ENTRY_IPV6_UNICASTm].index_max = 
  10430                 l3_entries/ 2 - 1;
  10431             sop->memState[L3_ENTRY_IPV6_UNICAST_Xm].index_max = 
  10432                 l3_entries/ 2 - 1;
  10433             sop->memState[L3_ENTRY_IPV6_UNICAST_Ym].index_max = 
  10434                 l3_entries/ 2 - 1;            
  10435             sop->memState[L3_ENTRY_IPV6_MULTICASTm].index_max = 
  10436                 l3_entries / 4 - 1;
  10437             sop->memState[L3_ENTRY_IPV6_MULTICAST_Xm].index_max = 
  10438                 l3_entries / 4 - 1;
  10439             sop->memState[L3_ENTRY_IPV6_MULTICAST_Ym].index_max = 
  10440                 l3_entries / 4 - 1;            
  10441             sop->memState[L3_ENTRY_HIT_ONLYm].index_max = l3_entries / 16 - 1;
  10442             sop->memState[L3_ENTRY_HIT_ONLY_Xm].index_max = l3_entries / 16 - 1;
  10443             sop->memState[L3_ENTRY_HIT_ONLY_Ym].index_max = l3_entries / 16 - 1;
  10444             
  10445             /* L3 IPMC groups: 2K */
  10446             sop->memState[L3_IPMCm].index_max = 2047;
  10447             sop->memState[L3_IPMC_1m].index_max = 2047;
  10448             sop->memState[L3_IPMC_REMAPm].index_max = 2047;
  10449             sop->memState[EGR_IPMCm].index_max = 2047;
  10450             sop->memState[MMU_REPL_GROUPm].index_max = 2047;
  10451 
  10452             /* L3 Next hop: 4K */
  10453             sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 4095;
  10454             sop->memState[ING_L3_NEXT_HOPm].index_max = 4095;
  10455             sop->memState[EGR_L3_NEXT_HOPm].index_max = 4095;
  10456             sop->memState[INITIAL_PROT_NHI_TABLEm].index_max = 4095;
  10457 
  10458             /* IPv4 LPM : 4K */
  10459             sop->memState[L3_DEFIPm].index_max = 8191;
  10460             sop->memState[L3_DEFIP_Xm].index_max = 8191;
  10461             sop->memState[L3_DEFIP_Ym].index_max = 8191;
  10462             sop->memState[L3_DEFIP_ONLYm].index_max = 8191;
  10463             sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 8191;
  10464             sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 8191;
  10465             sop->memState[L3_DEFIP_HIT_ONLY_Xm].index_max = 8191;
  10466             sop->memState[L3_DEFIP_HIT_ONLY_Ym].index_max = 8191;
  10467  
  10468             /* MPLS Labels : 4K */
  10469             sop->memState[MPLS_ENTRYm].index_max = 4095;
  10470             sop->memState[EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm].index_max = 4095;
  10471            
  10472             /* Virtual Ports : 4K */
  10473             sop->memState[SOURCE_VPm].index_max = 4095;
  10474             sop->memState[ING_DVP_TABLEm].index_max = 4095;
  10475             sop->memState[ING_DVP_2_TABLEm].index_max = 4095;
  10476             sop->memState[EGR_DVP_ATTRIBUTEm].index_max = 4095;
  10477             sop->memState[EGR_SERVICE_COUNTER_TABLEm].index_max = 4095;
  10478             sop->memState[EGR_SERVICE_COUNTER_TABLE_Xm].index_max = 4095;  
  10479             sop->memState[EGR_SERVICE_COUNTER_TABLE_Ym].index_max = 4095; 
  10480             sop->memState[EGR_VINTF_COUNTER_TABLEm].index_max = 4095;            
  10481             sop->memState[EGR_VINTF_COUNTER_TABLE_Xm].index_max = 4095; 
  10482             sop->memState[EGR_VINTF_COUNTER_TABLE_Ym].index_max = 4095; 
  10483             
  10484             /* MSTP : 255 */
  10485             sop->memState[EGR_VLAN_STGm].index_max = 255; 
  10486             sop->memState[STG_TABm].index_max = 255;
  10487             break;
  10488         case BCM56835_DEVICE_ID:
  10489             /* L2 entry */
  10490             l2_entries = 65536;            
  10491             sop->memState[L2Xm].index_max = l2_entries - 1;
  10492             sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
  10493             sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1;
  10494             sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1;
  10495 
  10496             /* L2MC */
  10497             sop->memState[L2MCm].index_max = 4351;            
  10498             
  10499             /* L3 IPMC groups */
  10500             sop->memState[L3_IPMCm].index_max = 255;
  10501             sop->memState[L3_IPMC_1m].index_max = 255;
  10502             sop->memState[L3_IPMC_REMAPm].index_max = 255;
  10503             sop->memState[EGR_IPMCm].index_max = 255;
  10504             sop->memState[MMU_REPL_GROUPm].index_max = 255;
  10505 
  10506             /* L3 Next hop */
  10507             sop->memState[INITIAL_ING_L3_NEXT_HOPm].index_max = 1023;
  10508             sop->memState[ING_L3_NEXT_HOPm].index_max = 1023;
  10509             sop->memState[EGR_L3_NEXT_HOPm].index_max = 1023;
  10510             sop->memState[INITIAL_PROT_NHI_TABLEm].index_max = 1023;
  10511 
  10512             /* L3 LPM */
  10513             sop->memState[L3_DEFIPm].index_max = 511;
  10514             sop->memState[L3_DEFIP_ONLYm].index_max = 511;
  10515             sop->memState[L3_DEFIP_DATA_ONLYm].index_max = 511;
  10516             sop->memState[L3_DEFIP_HIT_ONLYm].index_max = 511;
  10517 
  10518             /* MSTP */
  10519             sop->memState[EGR_VLAN_STGm].index_max = 255; 
  10520             sop->memState[STG_TABm].index_max = 255;
  10521 
  10522             /* Trunk */
  10523             index_max = 511;
  10524             sop->memState[TRUNK_GROUPm].index_max = index_max;
  10525             sop->memState[TRUNK_BITMAPm].index_max = index_max;
  10526             sop->memState[TRUNK_CBL_TABLEm].index_max = index_max;            
  10527             break;              
  10528         case BCM56742_DEVICE_ID:
  10529             /* L2 entry : 64K */
  10530             l2_entries = 65536;            
  10531             sop->memState[L2Xm].index_max = l2_entries - 1;
  10532             sop->memState[L2_ENTRY_ONLYm].index_max = l2_entries - 1;
  10533             sop->memState[L2_HITDA_ONLYm].index_max = l2_entries / 8 - 1;
  10534             sop->memState[L2_HITSA_ONLYm].index_max = l2_entries / 8 - 1;
  10535             break;
  10536         default:
  10537             break;
  10538     }  
  10539     
  10540     return SOC_E_NONE;
  10541 }
  10542 
  10543 STATIC int
  10544 _soc_trident_age_timer_get(int unit, int *age_seconds, int *enabled)
  10545 {
  10546     uint32 rval;
  10547 
  10548     SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &rval));
  10549     *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_ENAf);
  10550     *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, rval, AGE_VALf);
  10551 
  10552     return SOC_E_NONE;
  10553 }
  10554 
  10555 STATIC int
  10556 _soc_trident_age_timer_max_get(int unit, int *max_seconds)
  10557 {
  10558     *max_seconds =
  10559         soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf);
  10560 
  10561     return SOC_E_NONE;
  10562 }
  10563 
  10564 STATIC int
  10565 _soc_trident_age_timer_set(int unit, int age_seconds, int enable)
  10566 {
  10567     uint32 rval;
  10568 
  10569     rval = 0;
  10570     soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable);
  10571     soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds);
  10572     SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval));
  10573 
  10574     return SOC_E_NONE;
  10575 }
  10576 
  10577 static const soc_reg_t thermal_reg[] = {
  10578     CMIC_THERMAL_MON_RESULT_0r, CMIC_THERMAL_MON_RESULT_1r,
  10579     CMIC_THERMAL_MON_RESULT_2r, CMIC_THERMAL_MON_RESULT_3r,
  10580     CMIC_THERMAL_MON_RESULT_4r, CMIC_THERMAL_MON_RESULT_5r,
  10581     CMIC_THERMAL_MON_RESULT_6r, CMIC_THERMAL_MON_RESULT_7r
  10582 };
  10583 
  10584 int
  10585 soc_trident_temperature_monitor_get(int unit,
  10586           int temperature_max,
  10587           soc_switch_temperature_monitor_t *temperature_array,
  10588           int *temperature_count)
  10589 
  10590 {
  10591     uint32 rval, addr;
  10592     soc_reg_t reg;
  10593     int index;
  10594     int fval, cur, peak;
  10595     uint16 dev_id, drv_dev_id;
  10596     uint8 rev_id, drv_rev_id;
  10597     int num_entries_out;
  10598 
  10599     if (COUNTOF(thermal_reg) > temperature_max) {
  10600         num_entries_out = temperature_max;
  10601     } else {
  10602         num_entries_out = COUNTOF(thermal_reg);
  10603     }
  10604     soc_cm_get_id(unit, &dev_id, &rev_id);
  10605     soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id);
  10606 
  10607     if (!(drv_rev_id == BCM56840_A0_REV_ID && rev_id < BCM56840_B0_REV_ID)) {
  10608         reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r;
  10609         READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10610         soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 0);
  10611         soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3);
  10612         soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1);
  10613         WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10614     }
  10615 
  10616     sal_usleep(1000);
  10617 
  10618     READ_CMIC_THERMAL_MON_CTRLr(unit, &rval);
  10619     soc_reg_field_set(unit, CMIC_THERMAL_MON_CTRLr, &rval, BG_ADJf, 1);
  10620     soc_reg_field_set(unit, CMIC_THERMAL_MON_CTRLr, &rval, VTMON_RSTBf, 1);
  10621     WRITE_CMIC_THERMAL_MON_CTRLr(unit, rval);
  10622 
  10623     sal_usleep(1000);
  10624 
  10625     for (index = 0; index < num_entries_out; index++) {
  10626         reg = thermal_reg[index];
  10627         addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10628         soc_pci_getreg(unit, addr, &rval);
  10629         fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10630         cur = (4100000 - (5424 * fval)) / 1000;
  10631         fval = soc_reg_field_get(unit, reg, rval, PEAK_TEMP_DATAf);
  10632         peak = (4100000 - (5424 * fval)) / 1000;
  10633         (temperature_array + index)->curr = cur;
  10634         (temperature_array + index)->peak    = peak;
  10635     }
  10636 
  10637     READ_CMIC_SOFT_RESET_REGr(unit, &rval);
  10638     soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval,
  10639                       CMIC_TEMP_MON_PEAK_RST_Lf, 0);
  10640     WRITE_CMIC_SOFT_RESET_REGr(unit, rval);
  10641     soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval,
  10642                       CMIC_TEMP_MON_PEAK_RST_Lf, 1);
  10643     WRITE_CMIC_SOFT_RESET_REGr(unit, rval);
  10644     
  10645     *temperature_count=num_entries_out;
  10646     return SOC_E_NONE;
  10647 }
  10648 int
  10649 soc_trident_show_material_process(int unit)
  10650 {
  10651     soc_reg_t reg;
  10652     uint32 addr, rval, fval, nmos_4, nmos_7_0, nmos_7_1, n_avg, p_avg;
  10653     uint16 dev_id, drv_dev_id;
  10654     uint8 rev_id, drv_rev_id;
  10655 
  10656     soc_cm_get_id(unit, &dev_id, &rev_id);
  10657     soc_cm_get_id_driver(dev_id, rev_id, &drv_dev_id, &drv_rev_id);
  10658 
  10659     if (drv_rev_id == BCM56840_A0_REV_ID && rev_id < BCM56840_B0_REV_ID) {
  10660         return SOC_E_UNAVAIL;
  10661     }
  10662 
  10663     n_avg = 0;
  10664     p_avg = 0;
  10665 
  10666     /* Read NMOS information */
  10667     reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r;
  10668     READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10669     soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 1);
  10670     soc_reg_field_set(unit, reg, &rval, PROG_RESISTORf, 3);
  10671     soc_reg_field_set(unit, reg, &rval, MEASUREMENT_CALLIBRATIONf, 5);
  10672     soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3);
  10673     soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1);
  10674     WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10675 
  10676     sal_usleep(1000);
  10677 
  10678     reg = thermal_reg[4];
  10679     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10680     soc_pci_getreg(unit, addr, &rval);
  10681     nmos_4 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10682     n_avg += nmos_4;
  10683 
  10684     reg = thermal_reg[7];
  10685     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10686     soc_pci_getreg(unit, addr, &rval);
  10687     nmos_7_1 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10688     n_avg += nmos_7_1;
  10689 
  10690     READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10691     soc_reg_field_set(unit, CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r,
  10692                       &rval, VTMON_7_OR_PVTMON_SELf, 0);
  10693     WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10694 
  10695     reg = thermal_reg[7];
  10696     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10697     soc_pci_getreg(unit, addr, &rval);
  10698     nmos_7_0 = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10699     n_avg += nmos_7_0;
  10700 
  10701     /* Read PMOS information */
  10702     reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r;
  10703     READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10704     soc_reg_field_set(unit, reg, &rval, MEASUREMENT_CALLIBRATIONf, 7);
  10705     WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10706 
  10707     sal_usleep(1000);
  10708 
  10709     reg = thermal_reg[4];
  10710     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10711     soc_pci_getreg(unit, addr, &rval);
  10712     fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10713     LOG_CLI((BSL_META_U(unit,
  10714                         "material process location 4  : NMOS = %3d PMOS = %3d\n"),
  10715              nmos_4, fval));
  10716     p_avg += fval;
  10717 
  10718     reg = thermal_reg[7];
  10719     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10720     soc_pci_getreg(unit, addr, &rval);
  10721     fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10722     LOG_CLI((BSL_META_U(unit,
  10723                         "material process location 7-1: NMOS = %3d PMOS = %3d\n"),
  10724              nmos_7_1, fval));
  10725     p_avg += fval;
  10726 
  10727     READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10728     soc_reg_field_set(unit, CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r, &rval,
  10729                       VTMON_7_OR_PVTMON_SELf, 0);
  10730     WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10731 
  10732     reg = thermal_reg[7];
  10733     addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0);
  10734     soc_pci_getreg(unit, addr, &rval);
  10735     fval = soc_reg_field_get(unit, reg, rval, TEMP_DATAf);
  10736     LOG_CLI((BSL_META_U(unit,
  10737                         "material process location 7-0: NMOS = %3d PMOS = %3d\n"),
  10738              nmos_7_0, fval));
  10739     LOG_CLI((BSL_META_U(unit,
  10740                         "average:                       NMOS = %3d PMOS = %3d\n"),
  10741              n_avg / 3, p_avg / 3));
  10742 
  10743     reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r;
  10744     READ_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, &rval);
  10745     soc_reg_field_set(unit, reg, &rval, PVTMON_SELECTf, 0);
  10746     soc_reg_field_set(unit, reg, &rval, BG_ADJf, 3);
  10747     soc_reg_field_set(unit, reg, &rval, VTMON_7_OR_PVTMON_SELf, 1);
  10748     WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_3r(unit, rval);
  10749 
  10750     sal_usleep(1000);
  10751 
  10752     READ_CMIC_SOFT_RESET_REGr(unit, &rval);
  10753     soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval,
  10754                       CMIC_TEMP_MON_PEAK_RST_Lf, 0);
  10755     WRITE_CMIC_SOFT_RESET_REGr(unit, rval);
  10756     soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval,
  10757                       CMIC_TEMP_MON_PEAK_RST_Lf, 1);
  10758     WRITE_CMIC_SOFT_RESET_REGr(unit, rval);
  10759 
  10760     return SOC_E_NONE;
  10761 }
  10762 
  10763 int
  10764 soc_trident_show_ring_osc(int unit)
  10765 {
  10766     soc_info_t *si;
  10767     soc_reg_t reg;
  10768     static const soc_field_t fields[] = {
  10769         OSC_0_SELf, OSC_1_SELf, IROSC_SELf, IROSC_SELf
  10770     };
  10771     static const int counts[] = { 4, 4, 2, 2 };
  10772     static char *names[] = {
  10773         "IO ring 0", "IO ring 1", "Core ring 0", "Core ring 1"
  10774     };
  10775     uint32 rval;
  10776     int ring, set, core_clk, div, quo, rem, frac;
  10777 
  10778     si = &SOC_INFO(unit);
  10779     core_clk = (si->bandwidth == 640000 ? 495 : 415) * 1024;
  10780 
  10781     reg = CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r;
  10782     if (!soc_reg_field_valid(unit, reg, OSC_ENABLEf)) {
  10783         return SOC_E_UNAVAIL;
  10784     }
  10785 
  10786     /*
  10787      * IO ring osc 0 has 4 sets of value
  10788      * IO ring osc 1 has 4 sets of value
  10789      * Core ring osc 0 has 2 sets of value
  10790      * Core ring osc 1 has 2 sets of value
  10791      */
  10792     for (ring = 0; ring < 4; ring++) {
  10793         for (set = 0; set < counts[ring]; set++) {
  10794             rval = 0;
  10795             /*
  10796              * set OSC_CNT_RSTBf to 0 to do softreset
  10797              * set OSC_CNT_START to 0 to hold the counter until it selects
  10798              * the input signal
  10799              */
  10800             /* coverity[result_independent_of_operands] */
  10801             SOC_IF_ERROR_RETURN
  10802                 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval));
  10803             soc_reg_field_set(unit, reg, &rval, OSC_ENABLEf, 1);
  10804             soc_reg_field_set(unit, reg, &rval, IROSC_ENf, 1);
  10805             soc_reg_field_set(unit, reg, &rval, fields[ring], set);
  10806             soc_reg_field_set(unit, reg, &rval, OSC_SELf, ring);
  10807             /* coverity[result_independent_of_operands] */
  10808             SOC_IF_ERROR_RETURN
  10809                 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval));
  10810             soc_reg_field_set(unit, reg, &rval, OSC_CNT_RSTBf, 1);
  10811             /* coverity[result_independent_of_operands] */
  10812             SOC_IF_ERROR_RETURN
  10813                 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval));
  10814             soc_reg_field_set(unit, reg, &rval, OSC_CNT_STARTf, 1);
  10815             /* coverity[result_independent_of_operands] */
  10816             SOC_IF_ERROR_RETURN
  10817                 (WRITE_CMIC_CORE_PLL3_CTRL_STATUS_REGISTER_2r(unit, rval));
  10818 
  10819             sal_usleep(1000);
  10820 
  10821             /*
  10822              * ring_osc_freq = core_clock_freq * 1024 / div
  10823              * core ring 0 set 1 or core ring 1 set 1:
  10824              *    div = CMIC_IRQ_STAT_1[15:0] + 65536
  10825              * otherwise
  10826              *    div = CMIC_IRQ_STAT_1[15:0]
  10827              */
  10828             /* coverity[result_independent_of_operands] */
  10829             SOC_IF_ERROR_RETURN(READ_CMIC_IRQ_STAT_1r(unit, &rval));
  10830             div = rval & 0xffff;
  10831             if (ring >= 2 && set == 1) { /* core ring 0/1 set 1 */
  10832                 div += 65536;
  10833             }
  10834             quo = core_clk / div;
  10835             rem = core_clk - quo * div;
  10836             frac = (rem * 10000) / div;
  10837             LOG_CLI((BSL_META_U(unit,
  10838                                 "%s set %d: %d.%04d Mhz\n"),
  10839                      names[ring], set, quo, frac));
  10840         }
  10841     }
  10842 
  10843     return SOC_E_NONE;
  10844 }
  10845 
  10846 int
  10847 soc_trident_cmic_rate_param_get(int unit, int *dividend, int *divisor)
  10848 {
  10849     uint32 rval;
  10850 
  10851     /* coverity[result_independent_of_operands] */
  10852     SOC_IF_ERROR_RETURN(READ_CMIC_RATE_ADJUSTr(unit, &rval));
  10853     *dividend = soc_reg_field_get(unit, CMIC_RATE_ADJUSTr, rval, DIVIDENDf);
  10854     *divisor = soc_reg_field_get(unit, CMIC_RATE_ADJUSTr, rval, DIVISORf);
  10855 
  10856     return SOC_E_NONE;
  10857 }
  10858 
  10859 
  10860 int
  10861 soc_trident_cmic_rate_param_set(int unit, int dividend, int divisor)
  10862 {
  10863     uint32 rval;
  10864 
  10865     rval = 0;
  10866     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, dividend);
  10867     soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, divisor);
  10868     /* coverity[result_independent_of_operands] */
  10869     SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval));
  10870 
  10871     return SOC_E_NONE;
  10872 }
  10873 
  10874 STATIC int
  10875 _soc_trident_parity_block_port(int unit, soc_block_t block, soc_port_t *port)
  10876 {
  10877     *port = SOC_BLOCK_PORT(unit, block);
  10878     if ((*port != REG_PORT_ANY) && !SOC_PORT_VALID(unit, *port)) {
  10879         return SOC_E_PORT;
  10880     }
  10881 
  10882     return SOC_E_NONE;
  10883 }
  10884 
  10885 #if defined(SER_TR_TEST_SUPPORT)
  10886 STATIC soc_acc_type_t
  10887 _soc_trident_pipe_to_acc_type(int pipe)
  10888 {
  10889     soc_acc_type_t rv;
  10890     switch (pipe) {
  10891         case -1:
  10892         case 0:
  10893             rv = _SOC_ACC_TYPE_PIPE_X;
  10894             break;
  10895         case 1:
  10896             rv = _SOC_ACC_TYPE_PIPE_Y;
  10897             break;
  10898         default:
  10899             rv =_SOC_ACC_TYPE_PIPE_ALL;
  10900     };
  10901     return rv;
  10902 }
  10903 typedef struct skipped_mem_s {
  10904     soc_mem_t mem;
  10905     soc_acc_type_t acc_type;
  10906 } skipped_mem_t;
  10907 
  10908 const skipped_mem_t ser_test_skipped_mems[] = {
  10909     { EGR_VLANm, _SOC_ACC_TYPE_PIPE_X},
  10910     { EGR_VLANm, _SOC_ACC_TYPE_PIPE_Y},
  10911     { EGR_VLANm, _SOC_ACC_TYPE_PIPE_ALL},
  10912     { L2MCm, _SOC_ACC_TYPE_PIPE_Y},
  10913     { L3_IPMCm, _SOC_ACC_TYPE_PIPE_Y},
  10914     { EGR_MASKm, _SOC_ACC_TYPE_PIPE_Y},
  10915     { MMU_AGING_CTRm, _SOC_ACC_TYPE_PIPE_ANY},
  10916     { MMU_AGING_EXPm, _SOC_ACC_TYPE_PIPE_ANY},
  10917     { MMU_CTR_UC_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY},
  10918     { MMU_CTR_MC_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY},
  10919     { MMU_CTR_COLOR_DROP_MEMm, _SOC_ACC_TYPE_PIPE_ANY},
  10920     { L2_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_Y},
  10921     {INVALIDm}
  10922 };
  10923 
  10924 /*
  10925  * Function:
  10926  *      soc_td_ser_error_injection_support
  10927  * Purpose:
  10928  *      Checks if a memory is supported by error injection interface
  10929  *
  10930  * Parameters:
  10931  *      unit        - (IN) Device Number
  10932  *      memory      - (IN) Test data required for SER test
  10933  *      pipe        - (IN) How many indices to test for each memory
  10934  *
  10935  * Returns:
  10936  *  SOC_E_NONE if memory / reg is supported, SOC_E_UNAVAIL if unsupported
  10937  */
  10938 soc_error_t
  10939 soc_td_ser_error_injection_support (int unit, soc_mem_t mem, int pipe)
  10940 {
  10941     int i;
  10942     int rv        = SOC_E_UNAVAIL;
  10943     _soc_trident_parity_info_t *info = NULL;
  10944     int mem_acc_type;
  10945     int group, table;
  10946     soc_port_t block_port;
  10947     soc_block_t blk;
  10948     soc_acc_type_t acc_type = _soc_trident_pipe_to_acc_type(pipe);
  10949     _soc_ser_parity_info_t *tcams = _soc_td_ser_parity_info[unit];
  10950     const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks;
  10951 
  10952     _soc_trident_mem_rename(&mem);
  10953     /* Check if memory is listed in skipped mems structure */
  10954     for (i = 0; ser_test_skipped_mems[i].mem != INVALIDm; i++) {
  10955         if ((ser_test_skipped_mems[i].mem == mem) &&
  10956             (ser_test_skipped_mems[i].acc_type == acc_type)) {
  10957             return rv;
  10958         }
  10959     }
  10960 
  10961     for (group = 0; route_block[group].cmic_bit; group++) {
  10962         info = route_block[group].info;
  10963         SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) {
  10964             if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) {
  10965                 continue;
  10966             }
  10967             mem_acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe);
  10968             for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) {
  10969                 if (info[table].mem != mem) {
  10970                     continue;
  10971                 }
  10972                 if (acc_type != mem_acc_type) {
  10973                     continue;
  10974                 }
  10975                 return SOC_E_NONE;
  10976             }
  10977         }
  10978     }
  10979 
  10980     /*Search TCAMs*/
  10981     for (i = 0; tcams[i].mem != INVALIDm; i++) {
  10982         if (tcams[i].mem == mem) {
  10983             return SOC_E_NONE;
  10984         }
  10985     }
  10986 
  10987     return rv;
  10988 }
  10989 
  10990 /*This is the maximum number of tcams that have Hardware SER protection*/
  10991 #define MAX_HW_TCAMS 16
  10992 
  10993 STATIC int
  10994 _soc_td_mem_nack_error_test(int unit, _soc_ser_test_t test_type)
  10995 {
  10996     int group, table, i;
  10997     _soc_trident_parity_info_t *info;
  10998     soc_mem_t memTable;
  10999     soc_field_t test_field = INVALIDf;
  11000     soc_port_t block_port;
  11001     soc_block_t blk;
  11002     soc_acc_type_t acc_type;
  11003     soc_reg_t enable_reg;
  11004     soc_field_t enable_field;
  11005     int num_par_mems = 0;
  11006     int rv = SOC_E_NONE;
  11007     int skip_mem;
  11008     int skip_count = 0;
  11009     int tests_passed = 0;
  11010     int tests_failed = 0;
  11011     const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks;
  11012     /*H/W memory Test*/
  11013     for (group = 0; route_block[group].cmic_bit; group++) {
  11014         info = route_block[group].info;
  11015 
  11016         SOC_BLOCK_ITER (unit, blk,route_block[group].blocktype) {
  11017             if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) {
  11018                 continue;
  11019             }
  11020             acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe);
  11021             for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) {
  11022                 memTable = info[table].mem;
  11023                 skip_mem = FALSE;
  11024                 if (memTable == INVALIDm) {
  11025                     continue;
  11026                 }
  11027                 switch (info[table].type) {
  11028                     case _SOC_PARITY_TYPE_PARITY:
  11029                         test_field = EVEN_PARITYf;
  11030                         if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) {
  11031                             test_field = PARITYf;
  11032                             if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) {
  11033                                 test_field = EVEN_PARITY_0f;
  11034                             }
  11035                         }
  11036                         break;
  11037                     case _SOC_PARITY_TYPE_SER:
  11038                     case _SOC_PARITY_TYPE_COUNTER:
  11039                     case _SOC_PARITY_TYPE_ECC:
  11040                         break;
  11041                     default:
  11042                     /* No field to check. */
  11043                         continue;
  11044                 }
  11045                 num_par_mems++;
  11046                 if (!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) {
  11047                     test_field = INVALIDf;
  11048                 }
  11049                 /*
  11050                  * NOTE:  this loop and the skipping of memories it performs SHOULD be temporary
  11051                  * it exists for now until the memories in ser_test_skipped_mems are investigated.
  11052                  */
  11053                 for (i = 0; ser_test_skipped_mems[i].mem != INVALIDm; i++) {
  11054                     if (((ser_test_skipped_mems[i].mem == memTable) &&
  11055                         (ser_test_skipped_mems[i].acc_type == acc_type))) {
  11056                         LOG_VERBOSE(BSL_LS_SOC_SER,
  11057                                     (BSL_META_U(unit,
  11058                                                 "SER test disabled for memory %s, skipping.\n"),
  11059                                                 SOC_MEM_NAME(unit,memTable)));
  11060                         skip_mem = TRUE;
  11061                         skip_count++;
  11062                         break;
  11063                     }
  11064                 }
  11065                 if (!skip_mem){
  11066                     if (info[table].enable_field == INVALIDf) {
  11067                         enable_field = info[table].group_reg_enable_field;
  11068                         enable_reg   = route_block[group].enable_reg;
  11069                     } else {
  11070                         enable_field = info[table].enable_field;
  11071                         enable_reg   = info[table].enable_reg;
  11072                     }
  11073                     soc_trident_pipe_select(unit, TRUE,
  11074                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11075                     soc_trident_pipe_select(unit, FALSE,
  11076                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11077                     rv = ser_test_mem_pipe(unit, enable_reg, -1, enable_field,
  11078                                            info[table].mem, test_field,
  11079                                            test_type, blk, block_port, acc_type,
  11080                                            &tests_failed);
  11081                     soc_trident_pipe_select(unit, TRUE, 0);
  11082                     soc_trident_pipe_select(unit, FALSE, 0);
  11083                     if (rv == SOC_E_NONE) {
  11084                         tests_passed++;
  11085                     }
  11086                 }
  11087             }
  11088         }
  11089     }
  11090     LOG_CLI((BSL_META_U(unit,
  11091                         "\nStandard memories tested on unit %d: %d\n"),
  11092              unit, num_par_mems));
  11093     LOG_CLI((BSL_META_U(unit,
  11094                         "Tests passed: \t%d\n"), tests_passed));
  11095     LOG_CLI((BSL_META_U(unit,
  11096                         "Tests skipped: \t%d (Use verbose argument to see "
  11097                         "skipped memories.)\n"), skip_count));
  11098     LOG_CLI((BSL_META_U(unit,
  11099                         "Tests failed: \t%d\n"), tests_failed));
  11100 
  11101     if (tests_failed != 0)  {
  11102         LOG_CLI((BSL_META_U(unit,
  11103                 "TR 144 test failed.\n")));		
  11104     }
  11105 	
  11106     return rv;
  11107 }
  11108 
  11109 
  11110 /*
  11111  * Function:
  11112  *      soc_td_ser_mem_test
  11113  * Purpose:
  11114  *      Performs a SER test on a single td memory
  11115  * Parameters:
  11116  *      unit        - (IN) Device Number
  11117  *      memscan     - (IN) The memory to test
  11118  *      test_type   - (IN) How many indices in the memory to test
  11119  *      cmd         - (IN) A test flag that if non-0, causes a test to be printed to the
  11120  *                             commandline capable of testing the passed memory.
  11121  */
  11122 soc_error_t
  11123 soc_td_ser_mem_test(int unit, soc_mem_t mem, _soc_ser_test_t test_type, int cmd)
  11124 {
  11125     int i, rv = SOC_E_NONE;
  11126     int test_errors = 0;
  11127     _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit];
  11128     int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1;
  11129     int group, table;
  11130     _soc_trident_parity_info_t *info;
  11131     soc_mem_t memTable;
  11132     soc_field_t test_field = INVALIDf;
  11133     soc_port_t block_port;
  11134     soc_block_t blk;
  11135     const _soc_trident_parity_route_block_t *route_block = _soc_trident_parity_route_blocks;
  11136     int found_mem = FALSE;
  11137     uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_REG_FIELD_WORDS];
  11138     soc_acc_type_t acc_type;
  11139     ser_test_data_t test_data;
  11140     num_tcams = ((num_tcams > MAX_HW_TCAMS) ? MAX_HW_TCAMS : num_tcams);
  11141     /*TCAM_test*/
  11142     _soc_trident_mem_rename(&mem);
  11143     for(i = 0; i < num_tcams; i++) {
  11144         if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) ==
  11145             _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) {
  11146            acc_type = _SOC_ACC_TYPE_PIPE_Y;
  11147         } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) ==
  11148                     _SOC_SER_FLAG_MULTI_PIPE) {
  11149             acc_type = _SOC_ACC_TYPE_PIPE_X;
  11150         } else {
  11151             acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  11152         }
  11153         if(tcam_info[i].mem == mem) {
  11154             /*If the user has passed in the cmd flag high, just print a
  11155              * command-line method to test this memory instead of testing it.
  11156              */
  11157             found_mem = TRUE;
  11158             if (mem == L3_DEFIPm) {
  11159                 test_field = VALID0f;
  11160             } else if (mem == L3_DEFIP_PAIR_128m) {
  11161                 test_field = VALID0_LWRf;
  11162             } else {
  11163                 test_field = VALIDf;
  11164             }
  11165             soc_ser_create_test_data(unit, tmp_entry, field_data,
  11166                                      CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i,
  11167                                      INVALIDf, tcam_info[i].mem, test_field,
  11168                                      MEM_BLOCK_ANY, REG_PORT_ANY, acc_type, 0,
  11169                                      &test_data);
  11170             if (cmd) {
  11171                 ser_test_cmd_generate(unit, &test_data);
  11172             } else {
  11173                 soc_trident_pipe_select(unit, TRUE,
  11174                                         ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ?
  11175                                         1 : 0));
  11176                 soc_trident_pipe_select(unit, FALSE,
  11177                                         ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ?
  11178                                         1 : 0));
  11179                 rv = ser_test_mem(unit, 0, &test_data, test_type, &test_errors);
  11180                 soc_trident_pipe_select(unit, TRUE, 0);
  11181                 soc_trident_pipe_select(unit, FALSE, 0);
  11182                 if (rv != SOC_E_NONE) {
  11183                     LOG_CLI((BSL_META_U(unit,
  11184                                         "Error during TCAM test.  Aborting.\n")));
  11185                     return rv;
  11186                 }
  11187             }
  11188         }
  11189     }
  11190     /*H/W memory Test*/
  11191     for (group = 0; route_block[group].cmic_bit; group++) {
  11192         info = route_block[group].info;
  11193 
  11194         SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) {
  11195             if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) {
  11196                 continue;
  11197             }
  11198             acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe);
  11199             for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) {
  11200                 memTable = info[table].mem;
  11201                 if (memTable == INVALIDm) {
  11202                     continue;
  11203                 }
  11204                 /*Select the parity field to be toggled to inject the error.*/
  11205                 switch (info[table].type) {
  11206                     case _SOC_PARITY_TYPE_PARITY:
  11207                         test_field = EVEN_PARITYf;
  11208                         if(!SOC_MEM_FIELD_VALID(unit,info[table].mem,
  11209                                                 test_field)) {
  11210                             test_field = PARITYf;
  11211                             if(!SOC_MEM_FIELD_VALID(unit,info[table].mem,
  11212                                                     test_field)) {
  11213                                 test_field = EVEN_PARITY_0f;
  11214                             }
  11215                         }
  11216                         break;
  11217                     case _SOC_PARITY_TYPE_SER:
  11218                     case _SOC_PARITY_TYPE_COUNTER:
  11219                     case _SOC_PARITY_TYPE_ECC:
  11220                         break;
  11221                     default:
  11222                     /* No field to check. */
  11223                         continue;
  11224                 }                
  11225                 if(!SOC_MEM_FIELD_VALID(unit,info[table].mem,test_field)) {
  11226                         test_field = INVALIDf;
  11227                 }
  11228                 if (memTable == mem) {
  11229                     /*If the user has passed in the cmd flag high, just print a
  11230                      * command-line method to test this memory instead of
  11231                      * testing it.
  11232                      */
  11233                     found_mem = TRUE;
  11234                     soc_ser_create_test_data(unit, tmp_entry, field_data,
  11235                                              info[table].enable_reg, -1,
  11236                                              info[table].enable_field,
  11237                                              info[table].mem, test_field, blk,
  11238                                              block_port, acc_type, 0, &test_data);
  11239                     if (cmd) {
  11240                         ser_test_cmd_generate(unit, &test_data);
  11241                     } else {
  11242                         soc_trident_pipe_select(unit, TRUE,
  11243                                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ?
  11244                                                 1 : 0));
  11245                         soc_trident_pipe_select(unit, FALSE,
  11246                                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ?
  11247                                                 1 : 0));
  11248                         rv = ser_test_mem(unit, 0, &test_data, test_type,
  11249                                           &test_errors);
  11250                         soc_trident_pipe_select(unit, TRUE, 0);
  11251                         soc_trident_pipe_select(unit, FALSE, 0);
  11252                         if (rv != SOC_E_NONE) {
  11253                             LOG_CLI((BSL_META_U(unit,
  11254                                                 "Error during H/W test.  Aborting.\n")));
  11255                             return rv;
  11256                         }
  11257                     }
  11258                 }
  11259             }
  11260         }
  11261     }
  11262     if (found_mem && !cmd) {
  11263         if (test_errors == 0) {
  11264             LOG_CLI((BSL_META_U(unit,
  11265                                 "SER Test passed on unit: %d for memory %s\n "),
  11266                      unit, SOC_MEM_NAME(unit,mem)));
  11267         }
  11268         else {
  11269             LOG_CLI((BSL_META_U(unit,
  11270                                 "SER Test failed on unit: %d for memory %s\n"),
  11271                      unit, SOC_MEM_NAME(unit,mem)));
  11272             rv = SOC_E_INTERNAL;
  11273         }
  11274     } else if (!cmd){
  11275         LOG_CLI((BSL_META_U(unit,
  11276                             "Memory %s not found.\n"), SOC_MEM_NAME(unit, mem)));
  11277     }
  11278     return rv;
  11279 }
  11280 
  11281 
  11282 /*
  11283  * Function:
  11284  *      soc_td_ser_test
  11285  * Purpose:
  11286  * Parameters:
  11287  *      unit            - (IN) Device Number
  11288  *      test_type       - (IN) Determines how comprehensive of a test to run
  11289  */
  11290 soc_error_t
  11291 soc_td_ser_test(int unit, _soc_ser_test_t test_type)
  11292 {
  11293     soc_error_t rv = SOC_E_NONE;
  11294     int tcam_failed  = 0, tcam_skipped = 0, i;
  11295     _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit];
  11296     int num_tcams    = COUNTOF(_soc_td_ser_parity_info_template) - 1;
  11297     soc_acc_type_t acc_type;
  11298     soc_field_t test_field = INVALIDf;
  11299 #ifdef INCLUDE_MEM_SCAN
  11300     int memscan_running, rate;
  11301     sal_usecs_t interval;
  11302 
  11303     memscan_running = soc_mem_scan_running(unit, &rate, &interval);
  11304     if (memscan_running) {
  11305         rv = soc_mem_scan_stop(unit);
  11306         if (rv != SOC_E_NONE) {
  11307             LOG_CLI((BSL_META_U(unit,
  11308                                 "Error disabling memscan.  Aborting SER test.\n")));
  11309             return rv;
  11310         }
  11311     }
  11312 #endif
  11313     soc_td_ser_test_overlay(unit, test_type);
  11314     _soc_td_mem_nack_error_test(unit, test_type);
  11315     /*This is a NACK test for TCAM memories*/
  11316     for(i = 0; i < num_tcams; i++) {
  11317         if (i >= MAX_HW_TCAMS) {
  11318             tcam_skipped++;
  11319             LOG_VERBOSE(BSL_LS_SOC_SER,
  11320                         (BSL_META_U(unit,
  11321                                     "SER test disabled for TCAM memory %s, skipping.\n"),
  11322                          SOC_MEM_NAME(unit, tcam_info[i].mem)));
  11323             continue;
  11324         }
  11325         if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) ==
  11326             _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) {
  11327             acc_type = _SOC_ACC_TYPE_PIPE_Y;
  11328         } else {
  11329             acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  11330         }
  11331 
  11332         if (tcam_info[i].mem == L3_DEFIPm) {
  11333             test_field = VALID0f;
  11334         } else if (tcam_info[i].mem == L3_DEFIP_128m) {
  11335             test_field = VALID_0f;
  11336         } else {
  11337             test_field = VALIDf;
  11338         }
  11339         
  11340         soc_trident_pipe_select(unit, TRUE,
  11341                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11342         soc_trident_pipe_select(unit, FALSE, 
  11343                                 ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11344 
  11345         /* coverity[negative_returns : FALSE] */
  11346         rv = ser_test_mem_pipe(unit, CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i, -1,
  11347                                tcam_info[i].mem, test_field, test_type,
  11348                                MEM_BLOCK_ANY, REG_PORT_ANY, acc_type,
  11349                                &tcam_failed);
  11350         if (SOC_FAILURE(rv)) {
  11351             LOG_CLI((BSL_META_U(unit,
  11352                     "Error during TCAM:%s SER test\n"),
  11353                     SOC_MEM_NAME(unit, tcam_info[i].mem)));
  11354         }
  11355         soc_trident_pipe_select(unit, TRUE, 0);
  11356         soc_trident_pipe_select(unit, FALSE, 0);
  11357 
  11358     }
  11359 #ifdef INCLUDE_MEM_SCAN
  11360     if (memscan_running) {
  11361         rv = soc_mem_scan_start(unit, rate, interval);
  11362         if (rv != SOC_E_NONE) {
  11363             LOG_CLI((BSL_META_U(unit,
  11364                                 "Error starting memscan.\n")));
  11365             return rv;
  11366         }
  11367     }
  11368 #endif
  11369     LOG_CLI((BSL_META_U(unit,
  11370                         "\nTCAM memories tested on unit %d: %d\n"), unit, num_tcams));
  11371     LOG_CLI((BSL_META_U(unit,
  11372                         "TCAM tests passed:\t%d\n"),
  11373              num_tcams - tcam_skipped - tcam_failed));
  11374     LOG_CLI((BSL_META_U(unit,
  11375                         "TCAM tests skipped:\t%d (use verbose option to see "
  11376                         "skipped memories)\n"), tcam_skipped));
  11377     LOG_CLI((BSL_META_U(unit,
  11378                         "TCAM tests failed:\t%d\n"), tcam_failed));
  11379 	
  11380     if (tcam_failed != 0)  {
  11381         LOG_CLI((BSL_META_U(unit,
  11382                 "TR 144 test failed.\n")));		
  11383     }
  11384 	
  11385     /*Re-innitting init soc and misc to enact force_read_through options*/
  11386     /*init soc*/
  11387     return SOC_E_NONE;
  11388 }
  11389 
  11390 
  11391 const soc_ser_overlay_test_t soc_ser_td_overlay_mems[] = {
  11392     {EGR_IP_TUNNEL_IPV6m, EGR_VLAN_PARITY_CONTROLr,
  11393      EGR_IP_TUNNEL_PARITY_ENf, EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X},
  11394     {EGR_IP_TUNNEL_MPLSm, EGR_VLAN_PARITY_CONTROLr, EGR_IP_TUNNEL_PARITY_ENf,
  11395      EGR_IP_TUNNELm, _SOC_ACC_TYPE_PIPE_X},
  11396     {EGR_FRAGMENT_ID_TABLE_Xm, EGR_VLAN_PARITY_CONTROLr,
  11397      EGR_FRAGMENT_ID_TABLE_PARITY_ENf, EGR_FRAGMENT_ID_TABLEm,
  11398      _SOC_ACC_TYPE_PIPE_X},
  11399     {EGR_FRAGMENT_ID_TABLE_Ym, EGR_VLAN_PARITY_CONTROLr,
  11400      EGR_FRAGMENT_ID_TABLE_PARITY_ENf, EGR_FRAGMENT_ID_TABLEm,
  11401      _SOC_ACC_TYPE_PIPE_Y},
  11402     {EFP_COUNTER_TABLE_Xm, EGR_EDATABUF_PARITY_CONTROLr,
  11403      EFPCTR_PAR_ENf, EFP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11404     {EFP_COUNTER_TABLE_Ym, EGR_EDATABUF_PARITY_CONTROLr,
  11405      EFPCTR_PAR_ENf,EFP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11406     {EGR_PERQ_XMT_COUNTERS_Xm,EGR_EDATABUF_PARITY_CONTROLr,
  11407      PERQ_PAR_ENf,EGR_PERQ_XMT_COUNTERSm, _SOC_ACC_TYPE_PIPE_X},
  11408     {EGR_PERQ_XMT_COUNTERS_Ym,EGR_EDATABUF_PARITY_CONTROLr,
  11409      PERQ_PAR_ENf,EGR_PERQ_XMT_COUNTERSm, _SOC_ACC_TYPE_PIPE_Y},
  11410     {EGR_VINTF_COUNTER_TABLE_Xm,EGR_EDATABUF_PARITY_CONTROLr,
  11411      VINTFCTR_PAR_ENf,EGR_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11412     {EGR_VINTF_COUNTER_TABLE_Ym,EGR_EDATABUF_PARITY_CONTROLr,
  11413      VINTFCTR_PAR_ENf,EGR_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11414     {EGR_SERVICE_COUNTER_TABLE_Xm,EGR_EDATABUF_PARITY_CONTROLr,
  11415      SVCCTR_PAR_ENf,EGR_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11416     {EGR_SERVICE_COUNTER_TABLE_Ym,EGR_EDATABUF_PARITY_CONTROLr,
  11417      SVCCTR_PAR_ENf,EGR_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11418     {EFP_METER_TABLE_Xm, EFP_METER_PARITY_CONTROLr,
  11419      PARITY_ENf,EFP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11420     {EFP_METER_TABLE_Ym, EFP_METER_PARITY_CONTROLr,
  11421      PARITY_ENf,EFP_METER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11422     {EGR_PW_INIT_COUNTERS_Xm, EGR_PW_INIT_COUNTERS_PARITY_CONTROLr,
  11423      PARITY_ENf,EGR_PW_INIT_COUNTERSm, _SOC_ACC_TYPE_PIPE_X},
  11424     {EGR_PW_INIT_COUNTERS_Ym, EGR_PW_INIT_COUNTERS_PARITY_CONTROLr,
  11425      PARITY_ENf,EGR_PW_INIT_COUNTERSm, _SOC_ACC_TYPE_PIPE_Y},
  11426     {VLAN_MACm,VLAN_XLATE_PARITY_CONTROLr, PARITY_ENf, VLAN_XLATEm,
  11427      _SOC_ACC_TYPE_PIPE_X},
  11428     {VLAN_SUBNETm,VLAN_SUBNET_PARITY_CONTROLr,
  11429      PARITY_ENf,VLAN_SUBNET_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11430     {L3_ENTRY_IPV4_UNICASTm,L3_ENTRY_PARITY_CONTROLr,
  11431      PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11432     {L3_ENTRY_IPV4_MULTICASTm,L3_ENTRY_PARITY_CONTROLr,
  11433      PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11434     {L3_ENTRY_IPV6_UNICASTm,L3_ENTRY_PARITY_CONTROLr,
  11435      PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11436     {L3_ENTRY_IPV6_MULTICASTm,L3_ENTRY_PARITY_CONTROLr,
  11437      PARITY_ENf,L3_ENTRY_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11438     {L3_DEFIPm,L3_DEFIP_DATA_PARITY_CONTROLr,
  11439      PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11440     {L3_DEFIP_Xm,L3_DEFIP_DATA_PARITY_CONTROLr,
  11441      PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11442     {L3_DEFIP_Ym,L3_DEFIP_DATA_PARITY_CONTROLr,
  11443      PARITY_ENf,L3_DEFIP_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_Y},
  11444     {L2Xm ,L2_ENTRY_PARITY_CONTROLr, PARITY_ENf,L2_ENTRY_ONLYm,
  11445      _SOC_ACC_TYPE_PIPE_X},
  11446     {L2_USER_ENTRYm, L2_USER_ENTRY_DATA_PARITY_CONTROLr,
  11447      PARITY_ENf,L2_USER_ENTRY_DATA_ONLYm, _SOC_ACC_TYPE_PIPE_X},
  11448     {FP_COUNTER_TABLE_Xm, IFP_COUNTER_PARITY_CONTROLr,
  11449      PARITY_ENf,FP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11450     {FP_COUNTER_TABLE_Ym, IFP_COUNTER_PARITY_CONTROLr,
  11451      PARITY_ENf,FP_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11452     /* DLB_HGT_FLOWSET_PORT overlay memories disabled as their base address is
  11453       currently skipped.  When those issues are sorted these can be un-commented
  11454     {DLB_HGT_FLOWSET_PORT_Xm, DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr,
  11455      PARITY_ENf, DLB_HGT_FLOWSET_PORTm, _SOC_ACC_TYPE_PIPE_X},
  11456     {DLB_HGT_FLOWSET_PORT_Ym, DLB_HGT_FLOWSET_PORT_PARITY_CONTROLr,
  11457      PARITY_ENf,DLB_HGT_FLOWSET_PORTm, _SOC_ACC_TYPE_PIPE_Y},*/
  11458     {MODPORT_MAP_MIRRORm, MODPORT_MAP_MIRROR_PARITY_CONTROLr, PARITY_ENf,
  11459      MODPORT_MAP_M0m, _SOC_ACC_TYPE_PIPE_X},
  11460     {ING_PW_TERM_SEQ_NUM_Xm, ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf,
  11461      ING_PW_TERM_SEQ_NUMm, _SOC_ACC_TYPE_PIPE_X},
  11462     {ING_PW_TERM_SEQ_NUM_Ym, ING_PW_TERM_SEQ_NUM_PARITY_CONTROLr, PARITY_ENf,
  11463      ING_PW_TERM_SEQ_NUMm, _SOC_ACC_TYPE_PIPE_Y},
  11464     {ING_SERVICE_COUNTER_TABLE_Xm, ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr,
  11465      PARITY_ENf,ING_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11466     {ING_SERVICE_COUNTER_TABLE_Ym, ING_SERVICE_COUNTER_TABLE_PARITY_CONTROLr,
  11467     PARITY_ENf,ING_SERVICE_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11468     {ING_VINTF_COUNTER_TABLE_Xm, ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr,
  11469      PARITY_ENf,ING_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_X},
  11470     {ING_VINTF_COUNTER_TABLE_Ym, ING_VINTF_COUNTER_TABLE_PARITY_CONTROLr,
  11471      PARITY_ENf, ING_VINTF_COUNTER_TABLEm, _SOC_ACC_TYPE_PIPE_Y},
  11472     {INVALIDm}
  11473 };
  11474 
  11475 
  11476 /*
  11477  * Function:
  11478  *      soc_td_ser_test_overlay
  11479  * Purpose:
  11480  *      performs a test of all overlay memories along with their base memories
  11481  * Parameters:
  11482  *      unit        - (IN) Device Number
  11483  *      test_type   - (IN) how to test memories
  11484  */
  11485 int
  11486 soc_td_ser_test_overlay (int unit, _soc_ser_test_t test_type)
  11487 {
  11488     int rv = 0;
  11489     int numOverlays = COUNTOF(soc_ser_td_overlay_mems) - 1;
  11490     rv =soc_ser_test_overlays(unit, test_type, soc_ser_td_overlay_mems,
  11491                               soc_trident_pipe_select);
  11492     if (rv >= 0) {
  11493         LOG_CLI((BSL_META_U(unit,
  11494                             " Overlay memories tested: \t %d\n"), numOverlays));
  11495         LOG_CLI((BSL_META_U(unit,
  11496                             " Overlay memories passed: \t %d\n"), numOverlays - rv));
  11497         LOG_CLI((BSL_META_U(unit,
  11498                             " Overlay memories failed: \t %d\n\n"), rv));
  11499     } else {
  11500         LOG_CLI((BSL_META_U(unit,
  11501                             "TR 144 test failed. Internal Error during overlay test.\n")));
  11502     }
  11503     return rv;
  11504 }
  11505 
  11506 /*
  11507  * Function:
  11508  *      soc_td_ser_inject_error
  11509  * Purpose:
  11510  *      injects an error into a single td memory
  11511  * Parameters:
  11512  *      unit        - (IN) Device Number
  11513  *      mem     - (IN) The memory to test
  11514  */
  11515 soc_error_t
  11516 soc_td_ser_inject_error(int unit, uint32 flags, soc_mem_t mem, int pipe_target,
  11517                         int block, int index)
  11518 {
  11519     _soc_ser_parity_info_t *tcam_info = _soc_td_ser_parity_info[unit];
  11520     int num_tcams = COUNTOF(_soc_td_ser_parity_info_template) - 1;
  11521     int group, table, i;
  11522     soc_acc_type_t acc_type, acc_type_target;
  11523     _soc_trident_parity_info_t *info;
  11524     soc_mem_t memTable;
  11525     soc_port_t block_port;
  11526     soc_block_t blk;
  11527     uint32 tmp_entry[SOC_MAX_MEM_WORDS], field_data[SOC_MAX_MEM_FIELD_WORDS];
  11528     const _soc_trident_parity_route_block_t *route_block =
  11529                                             _soc_trident_parity_route_blocks;
  11530     ser_test_data_t test_data;
  11531     soc_field_t field;
  11532     SOC_IF_ERROR_RETURN(soc_td_ser_error_injection_support(unit, mem, 
  11533                                                            pipe_target));
  11534     acc_type_target = _soc_trident_pipe_to_acc_type(pipe_target);
  11535 
  11536     num_tcams = ((num_tcams > MAX_HW_TCAMS) ? MAX_HW_TCAMS : num_tcams);
  11537     /*TCAM_injection*/
  11538     for (i = 0; i < num_tcams; i++) {
  11539         if ((tcam_info[i].ser_flags & _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) ==
  11540             _SOC_MEM_ADDR_ACC_TYPE_PIPE_Y) {
  11541             acc_type = _SOC_ACC_TYPE_PIPE_Y;
  11542         } else if ((tcam_info[i].ser_flags & _SOC_SER_FLAG_MULTI_PIPE) ==
  11543                     _SOC_SER_FLAG_MULTI_PIPE) {
  11544             acc_type = _SOC_ACC_TYPE_PIPE_X;
  11545         } else {
  11546             acc_type = _SOC_ACC_TYPE_PIPE_ANY;
  11547         }
  11548         if (tcam_info[i].mem == mem && 
  11549             ((acc_type == acc_type_target)  ||
  11550              (acc_type_target == _SOC_ACC_TYPE_PIPE_ANY))) {
  11551             if (mem == L3_DEFIPm) {
  11552                 field = VALID0f;
  11553             } else if (mem == L3_DEFIP_PAIR_128m) {
  11554                 field = VALID0_LWRf;
  11555             } else {
  11556                 field = VALIDf;
  11557             }
  11558             /*Inject error*/
  11559             soc_ser_create_test_data(unit, tmp_entry, field_data,
  11560                                      CMIC_SER_PROTECT_ADDR_RANGE_VALIDr, i, 
  11561                                      INVALIDf, mem,
  11562                                      field, MEM_BLOCK_ANY, REG_PORT_ANY,
  11563                                      acc_type_target, index, &test_data);
  11564             soc_trident_pipe_select(unit, TRUE, 
  11565                 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0));
  11566             soc_trident_pipe_select(unit, FALSE, 
  11567                 (acc_type == _SOC_ACC_TYPE_PIPE_Y ? 1 : 0));
  11568             /*Read the memory for successful injection*/
  11569             SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, &test_data));
  11570             /*Disable parity*/
  11571             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0));
  11572             /*Inject error*/
  11573             SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags, 
  11574                                                          &test_data));
  11575             /*Enable parity*/
  11576             SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1));
  11577             soc_trident_pipe_select(unit, TRUE, 0);
  11578             soc_trident_pipe_select(unit, FALSE, 0);
  11579             return SOC_E_NONE;
  11580         }
  11581     }
  11582     /*H/W memory Test*/
  11583     _soc_trident_mem_rename(&mem);
  11584     for (group = 0; route_block[group].cmic_bit; group++) {
  11585         info = route_block[group].info;
  11586         SOC_BLOCK_ITER(unit, blk,route_block[group].blocktype) {
  11587             if (_soc_trident_parity_block_port(unit, blk, &block_port) < 0) {
  11588                 continue;
  11589             }
  11590             acc_type = _soc_trident_pipe_to_acc_type(route_block[group].pipe);
  11591             for (table = 0; info[table].type != _SOC_PARITY_TYPE_NONE; table++) {
  11592                 memTable = info[table].mem;
  11593                 if ((memTable == INVALIDm) || (memTable != mem)) {
  11594                     continue;
  11595                 }
  11596                 /*Select the parity field to be toggled to inject the error.*/
  11597                 switch (info[table].type) {
  11598                     case _SOC_PARITY_TYPE_PARITY:
  11599                         test_data.test_field = EVEN_PARITYf;
  11600                         if(!SOC_MEM_FIELD_VALID(unit,
  11601                                 info[table].mem,test_data.test_field)) {
  11602                             test_data.test_field = PARITYf;
  11603                             if(!SOC_MEM_FIELD_VALID(unit,
  11604                                 info[table].mem,test_data.test_field)) {
  11605                                 test_data.test_field = EVEN_PARITY_0f;
  11606                             }
  11607                         }
  11608                         break;
  11609                     case _SOC_PARITY_TYPE_SER:
  11610                     case _SOC_PARITY_TYPE_COUNTER:
  11611                     case _SOC_PARITY_TYPE_ECC:
  11612                     case _SOC_PARITY_TYPE_HASH:
  11613                         break;
  11614                     default:
  11615                     /* No field to check. */
  11616                         continue;
  11617                 }                
  11618                 if (memTable == mem) {
  11619                     if (((blk == block) || (block == MEM_BLOCK_ANY)) &&
  11620                           ((acc_type == acc_type_target)  ||
  11621                           (acc_type_target == _SOC_ACC_TYPE_PIPE_ANY))) {
  11622                         /*Inject error*/
  11623                         if (mem == SOURCE_TRUNK_MAP_TABLEm) {
  11624                             field = ECCf;
  11625                             flags |= SOC_INJECT_ERROR_2BIT_ECC;
  11626                         } else if (mem == PORT_TABm || mem == LPORT_TABm) {
  11627                             field = ECC_0f;
  11628                             flags |= SOC_INJECT_ERROR_2BIT_ECC;
  11629                         } else {
  11630                             field = EVEN_PARITYf;
  11631                         }
  11632                         soc_ser_create_test_data(unit, tmp_entry, field_data,
  11633                                                  info[table].enable_reg,
  11634                                                  SOC_INVALID_TCAM_PARITY_BIT,
  11635                                                  info[table].enable_field,
  11636                                                  mem, field, blk,
  11637                                                  block_port, 
  11638                                                  acc_type, index, 
  11639                                                  &test_data);
  11640                         soc_trident_pipe_select(unit, TRUE, 
  11641                             ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11642                         soc_trident_pipe_select(unit, FALSE, 
  11643                             ((acc_type == _SOC_ACC_TYPE_PIPE_Y) ? 1 : 0));
  11644                         /*Disable parity*/
  11645                         SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 0));
  11646                         /*Read the memory for successful injection*/
  11647                         SOC_IF_ERROR_RETURN(ser_test_mem_read(unit, 0, &test_data));
  11648                         /*Inject error*/
  11649                         SOC_IF_ERROR_RETURN(soc_ser_test_inject_full(unit, flags,
  11650                                                         &test_data));
  11651                         /*Enable parity*/
  11652                         SOC_IF_ERROR_RETURN(_ser_test_parity_control(unit, &test_data, 1));
  11653                         soc_trident_pipe_select(unit, TRUE, 0);
  11654                         soc_trident_pipe_select(unit, FALSE, 0);
  11655                         return SOC_E_NONE;
  11656                     }
  11657                 }
  11658             }
  11659         }
  11660     }   
  11661     return SOC_E_UNAVAIL;
  11662 }
  11663 #endif /*#if defined(SER_TR_TEST_SUPPORT)*/
  11664 
  11665 /*
  11666  * Trident chip driver functions.
  11667  */
  11668 soc_functions_t soc_trident_drv_funs = {
  11669     _soc_trident_misc_init,
  11670     _soc_trident_mmu_init,
  11671     _soc_trident_age_timer_get,
  11672     _soc_trident_age_timer_max_get,
  11673     _soc_trident_age_timer_set,
  11674 };
  11675 
  11676 int soc_trident_ser_dual_pipe_correction(int unit, soc_mem_t reported_mem, int copyno,
  11677                                              int index, _soc_ser_correct_info_t *si )
  11678 {
  11679     int entry_dw, rv;
  11680     int num_mems = 0, m = 0, cache_restore = 0;
  11681     soc_mem_t mem;
  11682     soc_mem_t mem_list[3] = {INVALIDm, INVALIDm, INVALIDm};
  11683     uint8  *vmap;
  11684     uint32 *cache;
  11685     uint32 entry[SOC_MAX_MEM_WORDS];
  11686 
  11687     mem_list[0] = reported_mem;
  11688     switch(reported_mem)
  11689     {
  11690         case FP_STORM_CONTROL_METERSm:
  11691             {
  11692                 num_mems = 3;
  11693                 mem_list[1] = FP_STORM_CONTROL_METERS_Xm;
  11694                 mem_list[2] = FP_STORM_CONTROL_METERS_Ym;
  11695                 break;
  11696             }
  11697         case DLB_HGT_FLOWSET_PORTm:
  11698             {
  11699                 num_mems = 3;
  11700                 mem_list[1] = DLB_HGT_FLOWSET_PORT_Xm;
  11701                 mem_list[2] = DLB_HGT_FLOWSET_PORT_Ym;
  11702                 break;
  11703             }
  11704         case EFP_METER_TABLEm:
  11705             {
  11706                 num_mems = 3;
  11707                 mem_list[1] = EFP_METER_TABLE_Xm;
  11708                 mem_list[2] = EFP_METER_TABLE_Ym;
  11709                 break;
  11710             }
  11711             break;
  11712         default:
  11713             break;
  11714     }
  11715 
  11716     if (copyno == MEM_BLOCK_ANY) {
  11717         copyno = SOC_MEM_BLOCK_ANY(unit, reported_mem);
  11718     }
  11719 
  11720     for (m = 0; m < num_mems; m++) {
  11721         mem = mem_list[m];
  11722         cache = SOC_MEM_STATE(unit, mem).cache[copyno];
  11723         vmap = SOC_MEM_STATE(unit, mem).vmap[copyno];
  11724         entry_dw = soc_mem_entry_words(unit, mem);
  11725 
  11726         if (cache != NULL && CACHE_VMAP_TST(vmap, index))
  11727         {
  11728             sal_memcpy(entry, cache + (index * entry_dw),
  11729                        entry_dw * 4);
  11730             rv = soc_mem_write(unit, mem, copyno, index, entry);
  11731 
  11732             if (rv == SOC_E_NONE) {
  11733                 cache_restore = 1;
  11734                 break;
  11735             }
  11736         }
  11737     }
  11738 
  11739     if (cache_restore == 1) {
  11740         if (NULL != si) {
  11741             if ((si->log_id != 0) &&
  11742                 (si->flags & SOC_SER_LOG_WRITE_CACHE)) {
  11743                 (void)soc_ser_log_add_tlv(unit, si->log_id,
  11744                                           SOC_SER_LOG_TLV_CACHE,
  11745                                           soc_mem_entry_words(unit, mem) * 4,
  11746                                           entry);
  11747             }
  11748 
  11749             if (soc_property_get(unit, spn_ENHANCED_SER_CORRECTION_EVENT_REPORT, 0)) {
  11750                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
  11751                     SOC_SWITCH_EVENT_DATA_ERROR_PARITY_CORRECTED, reported_mem, index);
  11752             } else {
  11753                 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR,
  11754                     SOC_SWITCH_EVENT_DATA_ERROR_CORRECTED, reported_mem, index);
  11755             }
  11756 
  11757             LOG_WARN(BSL_LS_SOC_SER,
  11758                       (BSL_META_U(unit,
  11759                               "CACHE_RESTORE: %s[%d] blk: %s index: %d : [%d][%x]\n"),
  11760                                SOC_MEM_NAME(unit, mem), mem,
  11761                                SOC_BLOCK_NAME(unit, copyno),
  11762                                index, si->sblk, si->addr));
  11763         }
  11764 
  11765         return SOC_E_NONE;
  11766     }else {
  11767         return SOC_E_UNAVAIL;
  11768     }
  11769 }
  11770 
  11771 static soc_multi_cp_mem_t soc_td_mem_cp_list[] = {
  11772     {MMU_THDO_CONFIG_0m,
  11773         {THDO_CONFIG_0Am, THDO_CONFIG_0Bm, INVALIDm, INVALIDm}},
  11774     {MMU_THDO_CONFIG_1m,
  11775         {THDO_CONFIG_1Am, THDO_CONFIG_1Bm, INVALIDm, INVALIDm}},
  11776     {MMU_THDO_CONFIG_EX_0m,
  11777         {THDO_CONFIG_EX_0Am, THDO_CONFIG_EX_0Bm, INVALIDm, INVALIDm}},
  11778     {MMU_THDO_CONFIG_EX_1m,
  11779         {THDO_CONFIG_EX_1Am, THDO_CONFIG_EX_1Bm, INVALIDm, INVALIDm}},
  11780     {MMU_THDO_OFFSET_0m,
  11781         {THDO_OFFSET_0Am, THDO_OFFSET_0Bm, INVALIDm, INVALIDm}},
  11782     {MMU_THDO_OFFSET_1m,
  11783         {THDO_OFFSET_1Am, THDO_OFFSET_1Bm, INVALIDm, INVALIDm}},
  11784     {MMU_THDO_OFFSET_EX_0m,
  11785         {THDO_OFFSET_EX_0Am, THDO_OFFSET_EX_0Bm, INVALIDm, INVALIDm}},
  11786     {MMU_THDO_OFFSET_EX_1m,
  11787         {THDO_OFFSET_EX_1Am, THDO_OFFSET_EX_1Bm, INVALIDm, INVALIDm}},
  11788     { INVALIDm },
  11789 };
  11790 
  11791 /* Get physical copies for specific mem */
  11792 int soc_trident_mem_cp_get(int unit, soc_mem_t mem,
  11793                            soc_mem_t *mem_cp_array)
  11794 {
  11795     int i = 0;
  11796     int num = COUNTOF(soc_td_mem_cp_list) - 1;
  11797     soc_multi_cp_mem_t *mem_info = soc_td_mem_cp_list;
  11798 
  11799     if (NULL == mem_cp_array) {
  11800         return SOC_E_PARAM;
  11801     }
  11802 
  11803     for (i = 0; i < num; i++) {
  11804         if (mem == mem_info[i].mem) {
  11805             sal_memcpy(mem_cp_array, mem_info[i].mem_cp,
  11806                        sizeof(soc_mem_t) * SOC_MEM_CP_MAX_NUM);
  11807             return SOC_E_NONE;
  11808         }
  11809     }
  11810     return SOC_E_NOT_FOUND;
  11811 }
  11812 #endif /* BCM_TRIDENT_SUPPORT */