triumph.c (282650B)
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: triumph.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <sal/core/boot.h> 14 #include <shared/bsl.h> 15 #include <soc/firebolt.h> 16 #include <soc/bradley.h> 17 #include <soc/triumph.h> 18 #include <soc/triumph2.h> 19 #include <soc/drv.h> 20 #include <soc/mem.h> 21 #include <soc/lpm.h> 22 #include <soc/error.h> 23 #include <soc/debug.h> 24 #include <soc/er_tcam.h> 25 #include <soc/memtune.h> 26 #include <soc/devids.h> 27 #include <soc/l2x.h> 28 #include <soc/pbsmh.h> 29 #include <soc/dcbformats.h> 30 31 #ifdef BCM_TRIUMPH_SUPPORT 32 33 /* 34 * Triumph chip driver functions. 35 */ 36 soc_functions_t soc_triumph_drv_funs = { 37 soc_triumph_misc_init, 38 soc_triumph_mmu_init, 39 soc_triumph_age_timer_get, 40 soc_triumph_age_timer_max_get, 41 soc_triumph_age_timer_set, 42 }; 43 44 typedef enum { 45 _SOC_PARITY_INFO_TYPE_GENERIC, 46 _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 47 _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 48 _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 49 _SOC_PARITY_INFO_TYPE_DUAL_TABLE2, 50 _SOC_PARITY_INFO_TYPE_MMUIPMC, 51 _SOC_PARITY_INFO_TYPE_MMUWRED, 52 _SOC_PARITY_INFO_TYPE_MMUMTRO 53 } _soc_parity_info_type_t; 54 55 typedef struct _soc_parity_info_s { 56 soc_field_t enable_field; 57 soc_field_t error_field; 58 char *msg; 59 soc_mem_t mem; 60 _soc_parity_info_type_t type; 61 soc_reg_t control_reg; 62 soc_reg_t status0_reg; 63 soc_reg_t status1_reg; 64 } _soc_parity_info_t; 65 66 STATIC _soc_parity_info_t _soc_tr_ip0_parity_info[] = { 67 { VXLT_PAR_ERRf, VXLT_PAR_ERRf, NULL, 68 VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 69 VLAN_XLATE_PARITY_CONTROLr, 70 VLAN_XLATE_PARITY_STATUSr, INVALIDr }, 71 { INVALIDf, INVALIDf }, /* table terminator */ 72 }; 73 74 STATIC _soc_parity_info_t _soc_tr_ip1_parity_info[] = { 75 { VLAN_PAR_ERRf, VLAN_PAR_ERRf, NULL, 76 VLAN_TABm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 77 VLAN_PARITY_CONTROLr, 78 VLAN_PARITY_STATUSr, INVALIDr }, 79 { SVP_PAR_ERRf, SVP_PAR_ERRf, NULL, 80 SOURCE_VPm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 81 SOURCE_VP_PARITY_CONTROLr, 82 SOURCE_VP_PARITY_STATUSr, INVALIDr }, 83 { L3_IIF_PAR_ERRf, L3_IIF_PAR_ERRf, NULL, 84 L3_IIFm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 85 L3_IIF_PARITY_CONTROLr, 86 L3_IIF_PARITY_STATUSr, INVALIDr }, 87 { MPLS_ENTRY_PAR_ERRf, MPLS_ENTRY_PAR_ERRf, NULL, 88 MPLS_ENTRYm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 89 MPLS_ENTRY_PARITY_CONTROLr, 90 MPLS_ENTRY_PARITY_STATUSr, INVALIDr }, 91 { L2_ENTRY_PAR_ERRf, L2_ENTRY_PAR_ERRf, NULL, 92 L2Xm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE2, 93 L2_ENTRY_PARITY_CONTROLr, 94 L2_ENTRY_PARITY_STATUS_0r, L2_ENTRY_PARITY_STATUS_1r }, 95 { L2MC_PAR_ERRf, L2MC_PAR_ERRf, NULL, 96 L2MCm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 97 L2MC_PARITY_CONTROLr, 98 L2MC_PARITY_STATUSr, INVALIDr }, 99 { L3_ENTRY_PAR_ERRf, L3_ENTRY_PAR_ERRf, NULL, 100 L3_ENTRY_ONLYm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE2, 101 L3_ENTRY_PARITY_CONTROLr, 102 L3_ENTRY_PARITY_STATUS_0r, L3_ENTRY_PARITY_STATUS_1r }, 103 { L3_DEFIP_DATA_PAR_ERRf, L3_DEFIP_DATA_PAR_ERRf, NULL, 104 L3_DEFIP_DATA_ONLYm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 105 L3_DEFIP_PARITY_CONTROLr, 106 L3_DEFIP_PARITY_STATUSr, INVALIDr }, 107 /* { IESMIF_INTRf }, */ 108 { INVALIDf, INVALIDf }, /* table terminator */ 109 }; 110 111 STATIC _soc_parity_info_t _soc_tr_ip2_parity_info[] = { 112 { L3_IPMC_PAR_ERRf, L3_IPMC_PAR_ERRf, NULL, 113 L3_IPMCm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 114 L3_IPMC_PARITY_CONTROLr, 115 L3_IPMC_PARITY_STATUSr, INVALIDr }, 116 { INITIAL_ING_NHOP_PAR_ERRf, INITIAL_ING_NHOP_PAR_ERRf, NULL, 117 INITIAL_ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 118 INITIAL_NHOP_PARITY_CONTROLr, 119 INITIAL_NHOP_PARITY_STATUSr, INVALIDr }, 120 /* { IL3MC_ERB_INTRf }, */ 121 { INVALIDf, INVALIDf }, /* table terminator */ 122 }; 123 124 STATIC _soc_parity_info_t _soc_tr_ip3_parity_info[] = { 125 { ING_NHOP_PAR_ERRf, ING_NHOP_PAR_ERRf, NULL, 126 ING_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 127 ING_L3_NEXT_HOP_PARITY_CONTROLr, 128 ING_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr }, 129 { ING_IPFIX_SESS_PAR_ERRf, ING_IPFIX_SESS_PAR_ERRf, NULL, 130 ING_IPFIX_SESSION_TABLEm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 131 ING_IPFIX_SESSION_PARITY_CONTROLr, 132 ING_IPFIX_SESSION_PARITY_STATUSr, INVALIDr }, 133 { ING_IPFIX_EXPORT_PAR_ERRf, ING_IPFIX_EXPORT_PAR_ERRf, NULL, 134 ING_IPFIX_EXPORT_FIFOm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 135 ING_IPFIX_EXPORT_FIFO_PARITY_CONTROLr, 136 ING_IPFIX_EXPORT_FIFO_PARITY_STATUSr, INVALIDr }, 137 { L3_MTU_VALUES_PAR_ERRf, L3_MTU_VALUES_PAR_ERRf, NULL, 138 L3_MTU_VALUESm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 139 L3_MTU_VALUES_PARITY_CONTROLr, 140 L3_MTU_VALUES_PARITY_STATUSr, INVALIDr }, 141 { EGR_MASK_PAR_ERRf, EGR_MASK_PAR_ERRf, NULL, 142 EGR_MASKm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 143 EGR_MASK_PARITY_CONTROLr, 144 EGR_MASK_PARITY_STATUSr, INVALIDr }, 145 { INVALIDf, INVALIDf }, /* table terminator */ 146 }; 147 148 STATIC _soc_parity_info_t _soc_tr_ep_parity_info[] = { 149 { EGR_NHOP_PAR_ERRf, EGR_NHOP_PAR_ERRf, NULL, 150 EGR_L3_NEXT_HOPm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 151 EGR_L3_NEXT_HOP_PARITY_CONTROLr, 152 EGR_L3_NEXT_HOP_PARITY_STATUSr, INVALIDr }, 153 { EGR_L3_INTF_PAR_ERRf, EGR_L3_INTF_PAR_ERRf, NULL, 154 EGR_L3_INTFm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 155 EGR_L3_INTF_PARITY_CONTROLr, 156 EGR_L3_INTF_PARITY_STATUSr, INVALIDr }, 157 { EGR_MPLS_LABEL_PAR_ERRf, EGR_MPLS_LABEL_PAR_ERRf, NULL, 158 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 159 EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_CONTROLr, 160 EGR_MPLS_VC_AND_SWAP_LABEL_PARITY_STATUSr, INVALIDr }, 161 { EGR_VLAN_PAR_ERRf, EGR_VLAN_PAR_ERRf, NULL, 162 EGR_VLANm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 163 EGR_VLAN_PARITY_CONTROLr, 164 EGR_VLAN_PARITY_STATUSr, INVALIDr }, 165 { EGR_VXLT_PAR_ERRf, EGR_VXLT_PAR_ERRf, NULL, 166 EGR_VLAN_XLATEm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 167 EGR_VLAN_XLATE_PARITY_CONTROLr, 168 EGR_VLAN_XLATE_PARITY_STATUSr, INVALIDr }, 169 { EGR_IP_TUNNEL_PAR_ERRf, EGR_IP_TUNNEL_PAR_ERRf, NULL, 170 EGR_IP_TUNNELm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 171 EGR_IP_TUNNEL_PARITY_CONTROLr, 172 EGR_IP_TUNNEL_PARITY_STATUSr, INVALIDr }, 173 { EGR_PW_COUNT_PAR_ERRf, EGR_PW_COUNT_PAR_ERRf, NULL, 174 EGR_PW_INIT_COUNTERSm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 175 EGR_PW_INIT_COUNTERS_PARITY_CONTROLr, 176 EGR_PW_INIT_COUNTERS_PARITY_STATUSr, INVALIDr }, 177 { EGR_IPFIX_SESS_PAR_ERRf, EGR_IPFIX_SESS_PAR_ERRf, NULL, 178 EGR_IPFIX_SESSION_TABLEm, _SOC_PARITY_INFO_TYPE_DUAL_TABLE1, 179 EGR_IPFIX_SESSION_PARITY_CONTROLr, 180 EGR_IPFIX_SESSION_PARITY_STATUSr, INVALIDr }, 181 { EGR_IPFIX_EXPORT_PAR_ERRf, EGR_IPFIX_EXPORT_PAR_ERRf, NULL, 182 EGR_IPFIX_EXPORT_FIFOm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 183 EGR_IPFIX_EXPORT_FIFO_PARITY_CONTROLr, 184 EGR_IPFIX_EXPORT_FIFO_PARITY_STATUSr, INVALIDr }, 185 { EP_INITBUF_DBEf, EP_INITBUF_DBEf, "EP_INITBUF", 186 INVALIDm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2, 187 EGR_INITBUF_ECC_CONTROLr, 188 EGR_INITBUF_ECC_STATUS_DBEr, INVALIDr }, 189 /* { EP_INITBUF_SBEf, EP_INITBUF_SBEf, NULL, 190 EGR_INITBUFm, _SOC_PARITY_INFO_TYPE_SPECIAL, 191 EGR_INITBUF_ECC_CONTROLr, 192 EGR_INITBUF_ECC_STATUS_SBEr, INVALIDr }, */ 193 { INVALIDf, INVALIDf }, /* table terminator */ 194 }; 195 196 /* 197 * Is DEQ_CBPERRPTRr for MMU_CBPDATA0 - MMU_CBPDATA31 (15-bit address)? 198 * How does MMU_CELLCHKm (15-bit address) report parity error? 199 */ 200 STATIC _soc_parity_info_t _soc_tr_mmu_parity_info[] = { 201 { AGING_CTR_PAR_ERR_ENf, AGING_CTR_PAR_ERRf, NULL, 202 MMU_AGING_CTRm, _SOC_PARITY_INFO_TYPE_GENERIC, 203 INVALIDr, 204 INVALIDr, INVALIDr }, 205 { AGING_EXP_PAR_ERR_ENf, AGING_EXP_PAR_ERRf, NULL, 206 MMU_AGING_EXPm, _SOC_PARITY_INFO_TYPE_GENERIC, 207 INVALIDr, 208 INVALIDr, INVALIDr }, 209 { CCP_PAR_ERR_ENf, CCP_PAR_ERRf, NULL, 210 MMU_CCP_MEMm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 211 INVALIDr, 212 CCPPARITYERRORPTRr, INVALIDr }, 213 { CFAP_PAR_ERR_ENf, CFAP_PAR_ERRf, NULL, 214 MMU_CFAP_MEMm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 215 INVALIDr, 216 CFAPPARITYERRORPTRr, INVALIDr }, 217 { CFAP_MEM_FAIL_ENf, CFAP_MEM_FAILf, NULL, 218 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 219 INVALIDr, 220 INVALIDr, INVALIDr }, 221 { DEQ_PKTHDR_CPU_ERR_ENf, DEQ_PKTHDR_CPU_ERRf, NULL, 222 MMU_CBPPKTHEADERCPUm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 223 INVALIDr, 224 DEQ_PKTHDRCPUERRPTRr, INVALIDr }, 225 { DEQ_PKTHDR0_ERR_ENf, DEQ_PKTHDR0_ERRf, NULL, 226 MMU_CBPPKTHEADER0_MEM0m, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 227 INVALIDr, 228 DEQ_PKTHDR0ERRPTRr, INVALIDr }, 229 { DEQ0_NOT_IP_ERR_ENf, DEQ0_NOT_IP_ERRf, NULL, 230 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 231 INVALIDr, 232 INVALIDr, INVALIDr }, 233 { DEQ0_CELLCRC_ERR_ENf, DEQ0_CELLCRC_ERRf, NULL, 234 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 235 INVALIDr, 236 INVALIDr, INVALIDr }, 237 { START_BY_START_ERR_ENf, START_BY_START_ERRf, NULL, 238 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 239 INVALIDr, 240 INVALIDr, INVALIDr }, 241 { MEM1_IPMC_TBL_PAR_ERR_ENf, MEM1_IPMC_TBL_PAR_ERRf, "MMU_IPMC_GROUP_TBL", 242 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUIPMC, 243 INVALIDr, 244 MEM1_IPMCGRP_TBL_PARITYERRORPTRr, MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr }, 245 { MEM1_VLAN_TBL_PAR_ERR_ENf, MEM1_VLAN_TBL_PAR_ERRf, NULL, 246 MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 247 INVALIDr, 248 MEM1_IPMCVLAN_TBL_PARITYERRORPTRr, INVALIDr }, 249 { TOQ0_CELLHDR_PAR_ERR_ENf, TOQ0_CELLHDR_PAR_ERRf, NULL, 250 MMU_CBPCELLHEADERm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 251 INVALIDr, 252 TOQ_CELLHDRERRPTRr, INVALIDr }, 253 { TOQ0_PKTHDR1_PAR_ERR_ENf, TOQ0_PKTHDR1_PAR_ERRf, NULL, 254 MMU_CBPPKTHEADER1_MEM0m, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 255 INVALIDr, 256 TOQ_PKTHDR1ERRPTRr, INVALIDr }, 257 { TOQ0_PKTLINK_PAR_ERR_ENf, TOQ0_PKTLINK_PAR_ERRf, NULL, 258 MMU_PKTLINK0m, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 259 INVALIDr, 260 TOQ_PKTLINKERRPTRr, INVALIDr }, 261 { TOQ0_CELLLINK_PAR_ERR_ENf, TOQ0_CELLLINK_PAR_ERRf, NULL, 262 MMU_CELLLINKm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 263 INVALIDr, 264 TOQ_CELLLINKERRPTRr, INVALIDr }, 265 { TOQ0_IPMC_TBL_PAR_ERR_ENf, TOQ0_IPMC_TBL_PAR_ERRf, NULL, 266 MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 267 INVALIDr, 268 TOQ_IPMCGRPERRPTR0r, INVALIDr }, 269 { TOQ0_VLAN_TBL_PAR_ERR_ENf, TOQ0_VLAN_TBL_PAR_ERRf, NULL, 270 MMU_IPMC_VLAN_TBLm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 271 INVALIDr, 272 TOQ_IPMCVLANERRPTRr, INVALIDr }, 273 { MTRO_PAR_ERR_ENf, MTRO_PAR_ERRf, NULL, 274 INVALIDm,_SOC_PARITY_INFO_TYPE_MMUMTRO, 275 INVALIDr, 276 EGRSHAPEPARITYERRORPTRr, INVALIDr }, 277 { PFAP_PAR_ERR_ENf, PFAP_PAR_ERRf, NULL, 278 MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 279 INVALIDr, 280 PFAPPARITYERRORPTRr, INVALIDr }, 281 { PFAP_MEM_FAIL_ENf, PFAP_MEM_FAILf, NULL, 282 MMU_PFAP_MEMm, _SOC_PARITY_INFO_TYPE_GENERIC, 283 INVALIDr, 284 INVALIDr, INVALIDr }, 285 { WRED_PAR_ERR_ENf, WRED_PAR_ERRf, NULL, 286 INVALIDm, _SOC_PARITY_INFO_TYPE_MMUWRED, 287 INVALIDr, 288 WRED_PARITY_ERROR_INFOr, WRED_PARITY_ERROR_BITMAPr }, 289 { DEQ_PKTHDR2_ERR_ENf, DEQ_PKTHDR2_PAR_ERRf, NULL, 290 MMU_CBPPKTHEADER2m, _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1, 291 INVALIDr, 292 DEQ_PKTHDR2ERRPTRr, INVALIDr }, 293 /* what memory is this for? use E2EFC_PARITYERRORPTRr.PTRf for index */ 294 { E2EFC_ERR_ENf, E2EFC_PAR_ERRf, NULL, 295 INVALIDm, _SOC_PARITY_INFO_TYPE_GENERIC, 296 INVALIDr, 297 INVALIDr, INVALIDr }, 298 { INVALIDf, INVALIDf }, /* table terminator */ 299 }; 300 301 STATIC struct { 302 uint32 cpi_bit; 303 soc_reg_t enable_reg; 304 soc_reg_t status_reg; 305 _soc_parity_info_t *info; 306 } _soc_tr_parity_block_info[] = { 307 { 0x01, MEM_FAIL_INT_ENr, MEM_FAIL_INT_STATr, _soc_tr_mmu_parity_info }, 308 { 0x02, EP_INTR_ENABLEr, EP_INTR_STATUSr, _soc_tr_ep_parity_info }, 309 { 0x04, IP0_INTR_ENABLEr, IP0_INTR_STATUSr, _soc_tr_ip0_parity_info }, 310 { 0x08, IP1_INTR_ENABLEr, IP1_INTR_STATUSr, _soc_tr_ip1_parity_info }, 311 { 0x10, IP2_INTR_ENABLEr, IP2_INTR_STATUSr, _soc_tr_ip2_parity_info }, 312 { 0x20, IP3_INTR_ENABLEr, IP3_INTR_STATUSr, _soc_tr_ip3_parity_info }, 313 /* { 0x40, PCIE_REPLAY_PERR, }, */ 314 { 0 }, /* table terminator */ 315 }; 316 317 /* MMU MTRO conversion structure*/ 318 #define MMU_MTRO_MAX_GROUP 19 319 #define MMU_MTRO_MAX_PORT_IN_GROUP 6 320 #define SOC_TRIUMPH_MEM_PARITY_INFO(unit, block_info_idx, field_enum) \ 321 ((SOC_BLOCK2SCH(unit, block_info_idx) << SOC_ERROR_BLK_BP) \ 322 | (field_enum & SOC_ERROR_FIELD_ENUM_MASK)) 323 324 STATIC struct { 325 int num_port; 326 int port_list[MMU_MTRO_MAX_PORT_IN_GROUP]; 327 int base_queue; 328 int numq; 329 } _soc_tr_mtro_group_info[MMU_MTRO_MAX_GROUP] = { 330 {1, {1,-1,-1,-1,-1,-1}, 0, 8}, 331 {2, {2, 3,-1,-1,-1,-1}, 0, 24}, 332 {5, {4, 5, 6, 7, 8,-1}, 0, 8}, 333 {5, {9, 10, 11, 12, 13,-1}, 0, 8}, 334 {2, {14, 15,-1,-1,-1,-1}, 0, 24}, 335 {5, {16, 17, 18, 19, 20, -1}, 0, 8}, 336 {5, {21, 22, 23, 24, 25, -1}, 0, 8}, 337 {2, {26, 27,-1,-1,-1,-1}, 0, 24}, 338 {2, {28, 29,-1,-1,-1,-1}, 0, 24}, 339 {2, {30, 31,-1,-1,-1,-1}, 0, 24}, 340 {1, {32, -1,-1,-1,-1,-1}, 0, 24}, 341 {5, {33, 34, 35, 36, 37,-1}, 0, 8}, 342 {5, {38, 39, 40, 41, 42,-1}, 0, 8}, 343 {1, {43,-1,-1,-1,-1,-1}, 0, 24}, 344 {5, {44, 45, 46, 47, 48,-1}, 0, 8}, 345 {5, {49, 50, 51, 52, 53,-1}, 0, 8}, 346 {6, {2, 3, 14, 15, 26, 27}, 24, 2}, 347 {6, {28, 29, 30, 31, 32, 43}, 24, 2}, 348 {1, {REG_PORT_ANY,-1,-1,-1,-1,-1}, 0, 48} 349 }; 350 351 static soc_ser_functions_t _tr_ser_functions; 352 353 STATIC int 354 _soc_triumph_parity_enable(int unit, int enable) 355 { 356 int block, table; 357 uint32 addr, cmic_enable, block_enable, regval, misc_cfg; 358 _soc_parity_info_t *info; 359 soc_reg_t block_reg, reg; 360 361 cmic_enable = 0; 362 /* loop through each block */ 363 for (block = 0; _soc_tr_parity_block_info[block].cpi_bit; block++) { 364 cmic_enable |= _soc_tr_parity_block_info[block].cpi_bit; 365 info = _soc_tr_parity_block_info[block].info; 366 block_reg = _soc_tr_parity_block_info[block].enable_reg; 367 block_enable = 0; 368 369 /* loop through each table in the block */ 370 for (table = 0; info[table].enable_field != INVALIDf; table++) { 371 /* handle different parity error reporting style */ 372 switch (info[table].type) { 373 case _SOC_PARITY_INFO_TYPE_GENERIC: 374 case _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1: 375 break; 376 case _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2: 377 case _SOC_PARITY_INFO_TYPE_DUAL_TABLE1: 378 case _SOC_PARITY_INFO_TYPE_DUAL_TABLE2: 379 reg = info[table].control_reg; 380 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 381 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 382 enable ? 1 : 0)); 383 break; 384 default: 385 break; 386 } /* handle different parity error reporting style */ 387 soc_reg_field_set(unit, block_reg, &block_enable, 388 info[table].enable_field, enable ? 1 : 0); 389 } /* loop through each table in the block */ 390 391 addr = soc_reg_addr(unit, block_reg, REG_PORT_ANY, 0); 392 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, block_enable)); 393 } /* loop through each block */ 394 395 /* Disable parity error support on specific tables */ 396 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 397 ING_L3_NEXT_HOP_PARITY_CONTROLr, 398 REG_PORT_ANY, PARITY_ENf, 0x0)); 399 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, L3_IPMC_PARITY_CONTROLr, 400 REG_PORT_ANY, PARITY_ENf, 0x0)); 401 402 /* coverity[result_independent_of_operands] */ 403 SOC_IF_ERROR_RETURN 404 (WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, cmic_enable)); 405 406 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &misc_cfg)); 407 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 1); 408 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 409 410 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_CHK_ENf, 1); 411 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_GEN_ENf, 1); 412 soc_reg_field_set(unit, MISCCONFIGr, &misc_cfg, PARITY_STAT_CLEARf, 0); 413 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, misc_cfg)); 414 415 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, ®val)); 416 soc_intr_enable(unit, IRQ_MEM_FAIL); 417 418 return SOC_E_NONE; 419 } 420 421 /* 422 * status0_reg has entry index of the parity error 423 * or 424 * status0_reg == INVALIDr (no furthur information) 425 */ 426 STATIC int 427 _soc_triumph_parity_process_single_table1(int unit, char *msg, 428 _soc_parity_info_t *info, int block, 429 int * intr_enable) 430 { 431 _soc_ser_correct_info_t spci; 432 soc_reg_t reg; 433 uint32 addr, entry_idx; 434 uint32 rval; 435 int rv = 0; 436 437 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 438 439 reg = info->status0_reg; 440 if (reg == INVALIDr) { 441 LOG_ERROR(BSL_LS_SOC_COMMON, 442 (BSL_META_U(unit, 443 "unit %d %s parity error\n"), 444 unit, msg)); 445 *intr_enable = 0; 446 return SOC_E_NONE; 447 } 448 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 449 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &entry_idx)); 450 LOG_ERROR(BSL_LS_SOC_COMMON, 451 (BSL_META_U(unit, 452 "unit %d %s entry %d parity error\n"), 453 unit, msg, entry_idx)); 454 455 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 456 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 457 info->error_field); 458 459 if (info->mem != INVALIDm) { 460 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 461 spci.reg = INVALIDr; 462 spci.mem = info->mem; 463 spci.blk_type = block; 464 spci.index = entry_idx; 465 rv = soc_ser_correction(unit, &spci); 466 if (SOC_FAILURE(rv)) { 467 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 468 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 469 info->mem, info->error_field); 470 } 471 } else { 472 *intr_enable = 0; 473 } 474 475 /* update soc stats for some cases */ 476 if (info->error_field == CCP_PAR_ERRf) { 477 SOC_CONTROL(unit)->stat.err_cpcrc++; 478 } else if (info->error_field == CFAP_PAR_ERRf) { 479 SOC_CONTROL(unit)->stat.err_cfap++; 480 } 481 482 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 483 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 484 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 485 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 486 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 487 488 return SOC_E_NONE; 489 } 490 491 /* 492 * IP EP parity error info format for single table: 493 * XXX_CONTROLr: PARITY_ENf 494 * XXX_STATUSr: PARITY_ERRf, MULTIPLE_ERRf, ENTRY_IDXf 495 * or 496 * XXX_STATUSr: DOUBLE_BIT_ERRf, MULTUPLE_ERRf, ENTRY_IDXf 497 */ 498 STATIC int 499 _soc_triumph_parity_process_single_table2(int unit, char *msg, 500 _soc_parity_info_t *info, int block, 501 int * intr_enable) 502 { 503 soc_reg_t reg; 504 uint32 addr, entry_idx, status; 505 _soc_ser_correct_info_t spci; 506 int rv = 0; 507 508 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 509 510 reg = info->status0_reg; 511 if (reg == INVALIDr) { 512 LOG_ERROR(BSL_LS_SOC_COMMON, 513 (BSL_META_U(unit, 514 "unit %d %s parity error\n"), 515 unit, msg)); 516 *intr_enable = 0; 517 return SOC_E_NONE; 518 } 519 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 520 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 521 if (soc_reg_field_valid(unit, reg, PARITY_ERRf)) { 522 if (!soc_reg_field_get(unit, reg, status, PARITY_ERRf)) { 523 LOG_ERROR(BSL_LS_SOC_COMMON, 524 (BSL_META_U(unit, 525 "unit %d %s parity hardware inconsistency\n"), 526 unit, msg)); 527 *intr_enable = 0; 528 return SOC_E_NONE; 529 } 530 entry_idx = soc_reg_field_get(unit, reg, status, 531 ENTRY_IDXf); 532 LOG_ERROR(BSL_LS_SOC_COMMON, 533 (BSL_META_U(unit, 534 "unit %d %s entry %d parity error\n"), 535 unit, msg, entry_idx)); 536 537 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 538 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 539 info->error_field); 540 541 if (info->mem != INVALIDm) { 542 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 543 spci.reg = INVALIDr; 544 spci.mem = info->mem; 545 spci.blk_type = block; 546 spci.index = entry_idx; 547 rv = soc_ser_correction(unit, &spci); 548 if (SOC_FAILURE(rv)) { 549 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 550 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 551 info->mem, info->error_field); 552 } 553 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 554 } else { 555 *intr_enable = 0; 556 } 557 } else if (soc_reg_field_valid(unit, reg, DOUBLE_BIT_ERRf)) { 558 if (!soc_reg_field_get(unit, reg, status, 559 DOUBLE_BIT_ERRf)) { 560 LOG_ERROR(BSL_LS_SOC_COMMON, 561 (BSL_META_U(unit, 562 "unit %d %s parity hardware inconsistency\n"), 563 unit, msg)); 564 *intr_enable = 0; 565 return SOC_E_NONE; 566 } 567 entry_idx = soc_reg_field_get(unit, reg, status, 568 ENTRY_IDXf); 569 LOG_ERROR(BSL_LS_SOC_COMMON, 570 (BSL_META_U(unit, 571 "unit %d %s entry %d double bit error\n"), 572 unit, msg, entry_idx)); 573 574 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 575 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 576 info->error_field); 577 578 if (info->mem != INVALIDm) { 579 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 580 spci.reg = INVALIDr; 581 spci.mem = info->mem; 582 spci.blk_type = block; 583 spci.index = entry_idx; 584 rv = soc_ser_correction(unit, &spci); 585 if (SOC_FAILURE(rv)) { 586 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 587 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 588 info->mem, info->error_field); 589 } 590 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 591 } else { 592 *intr_enable = 0; 593 } 594 } 595 596 return SOC_E_NONE; 597 } 598 599 /* 600 * IP EP parity error info format 1 for dual table: 601 * XXX_CONTROLr: PARITY_ENf 602 * XXX_STATUSr: PARITY_ERR_BMf, MULTIPLE_ERRf, BUCKET_IDX_0f, 603 * BUCKET_IDX_1f 604 * lower half of PARITY_ERR_BMf is for BUCKET_IDX_0f 605 * upper half of PARITY_ERR_BMf is for BUCKET_IDX_1f 606 */ 607 STATIC int 608 _soc_triumph_parity_process_dual_table1(int unit, char *msg, 609 _soc_parity_info_t *info, int block, 610 int * intr_enable) 611 { 612 int size; 613 int err_count = 0; 614 int index, rv = 0; 615 soc_reg_t reg; 616 uint32 addr, entry_idx, status, bitmap0, bitmap1; 617 _soc_ser_correct_info_t spci; 618 619 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 620 621 reg = info->status0_reg; 622 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 623 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 624 size = soc_reg_field_length(unit, reg, PARITY_ERR_BMf) / 2; 625 bitmap0 = soc_reg_field_get(unit, reg, status, PARITY_ERR_BMf); 626 bitmap1 = (bitmap0 >> size) & ((1 << size) - 1); 627 bitmap0 &= (1 << size) - 1; 628 entry_idx = 629 soc_reg_field_get(unit, reg, status, BUCKET_IDX_0f) * 630 size * 2; 631 for (index = 0; index < size; index++, bitmap0 >>= 1) { 632 if (!bitmap0) { 633 break; 634 } 635 if (!(bitmap0 & 1)) { 636 continue; 637 } 638 err_count++; 639 LOG_ERROR(BSL_LS_SOC_COMMON, 640 (BSL_META_U(unit, 641 "unit %d %s entry %d parity error\n"), 642 unit, msg, entry_idx + index)); 643 644 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 645 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 646 info->error_field); 647 648 if (info->mem != INVALIDm) { 649 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 650 spci.reg = INVALIDr; 651 spci.mem = info->mem; 652 spci.blk_type = block; 653 spci.index = entry_idx + index; 654 rv = soc_ser_correction(unit, &spci); 655 if (SOC_FAILURE(rv)) { 656 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 657 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 658 info->mem, info->error_field); 659 } 660 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 661 } else { 662 *intr_enable = 0; 663 } 664 } 665 entry_idx = 666 soc_reg_field_get(unit, reg, status, BUCKET_IDX_1f) * 667 size * 2 + size; 668 for (index = 0; index < size; index++, bitmap1 >>= 1) { 669 if (!bitmap1) { 670 break; 671 } 672 if (!(bitmap1 & 1)) { 673 continue; 674 } 675 err_count++; 676 LOG_ERROR(BSL_LS_SOC_COMMON, 677 (BSL_META_U(unit, 678 "unit %d %s entry %d parity error\n"), 679 unit, msg, entry_idx + index)); 680 681 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 682 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 683 info->error_field); 684 685 if (info->mem != INVALIDm) { 686 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 687 spci.reg = INVALIDr; 688 spci.mem = info->mem; 689 spci.blk_type = block; 690 spci.index = entry_idx + index; 691 rv = soc_ser_correction(unit, &spci); 692 if (SOC_FAILURE(rv)) { 693 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 694 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 695 info->mem, info->error_field); 696 } 697 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 698 } else { 699 *intr_enable = 0; 700 } 701 } 702 703 if (err_count == 0) { 704 LOG_ERROR(BSL_LS_SOC_COMMON, 705 (BSL_META_U(unit, 706 "unit %d %s parity hardware inconsistency\n"), 707 unit, msg)); 708 } 709 710 return SOC_E_NONE; 711 } 712 713 /* 714 * IP EP parity error info format 2 for dual table: 715 * XXX_CONTROLr: PARITY_ENf 716 * XXX_STATUS0r: PARITY_ERR_BM_0f, MULTIPLE_ERR_0f, 717 * BUCKET_IDX_0f 718 * XXX_STATUS1r: PARITY_ERR_BM_1f, MULTIPLE_ERR_1f, 719 * BUCKET_IDX_1f 720 */ 721 STATIC int 722 _soc_triumph_parity_process_dual_table2(int unit, char *msg, 723 _soc_parity_info_t *info, int block, 724 int * intr_enable) 725 { 726 int size, index, rv = 0; 727 int err_count = 0; 728 soc_reg_t reg; 729 uint32 addr, entry_idx, status, bitmap0, bitmap1; 730 _soc_ser_correct_info_t spci; 731 732 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 733 734 reg = info->status0_reg; 735 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 736 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 737 size = soc_reg_field_length(unit, reg, PARITY_ERR_BM_0f); 738 bitmap0 = soc_reg_field_get(unit, reg, status, 739 PARITY_ERR_BM_0f); 740 entry_idx = 741 soc_reg_field_get(unit, reg, status, BUCKET_IDX_0f) * 742 size * 2; 743 for (index = 0; index < size; index++, bitmap0 >>= 1) { 744 if (!bitmap0) { 745 break; 746 } 747 if (!(bitmap0 & 1)) { 748 continue; 749 } 750 err_count++; 751 LOG_ERROR(BSL_LS_SOC_COMMON, 752 (BSL_META_U(unit, 753 "unit %d %s entry %d parity error\n"), 754 unit, msg, entry_idx + index)); 755 756 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 757 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 758 info->error_field); 759 760 if (info->mem != INVALIDm) { 761 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 762 spci.reg = INVALIDr; 763 spci.mem = info->mem; 764 spci.blk_type = block; 765 spci.index = entry_idx + index; 766 rv = soc_ser_correction(unit, &spci); 767 if (SOC_FAILURE(rv)) { 768 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 769 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 770 info->mem, info->error_field); 771 } 772 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 773 } else { 774 *intr_enable = 0; 775 } 776 } 777 reg = info->status1_reg; 778 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 779 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 780 size = soc_reg_field_length(unit, reg, PARITY_ERR_BM_1f); 781 bitmap1 = soc_reg_field_get(unit, reg, status, 782 PARITY_ERR_BM_1f); 783 entry_idx = 784 soc_reg_field_get(unit, reg, status, BUCKET_IDX_1f) * 785 size * 2 + size; 786 for (index = 0; index < size; index++, bitmap1 >>= 1) { 787 if (!bitmap1) { 788 break; 789 } 790 if (!(bitmap1 & 1)) { 791 continue; 792 } 793 err_count++; 794 LOG_ERROR(BSL_LS_SOC_COMMON, 795 (BSL_META_U(unit, 796 "unit %d %s entry %d parity error\n"), 797 unit, msg, entry_idx + index)); 798 799 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 800 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 801 info->error_field); 802 803 if (info->mem != INVALIDm) { 804 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 805 spci.reg = INVALIDr; 806 spci.mem = info->mem; 807 spci.blk_type = block; 808 spci.index = entry_idx + index; 809 rv = soc_ser_correction(unit, &spci); 810 if (SOC_FAILURE(rv)) { 811 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 812 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 813 info->mem, info->error_field); 814 } 815 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 816 } else { 817 *intr_enable = 0; 818 } 819 } 820 821 if (err_count == 0) { 822 LOG_ERROR(BSL_LS_SOC_COMMON, 823 (BSL_META_U(unit, 824 "unit %d %s parity hardware inconsistency\n"), 825 unit, msg)); 826 } 827 828 return SOC_E_NONE; 829 } 830 831 832 /* 833 * status0 (MEM1_IPMCGRP_TBL_PARITYERRORPTRr) is index 834 * status1 (MEM1_IPMCGRP_TBL_PARITYERROR_STATUSr) is table id 835 * MMU_IPMC_GROUP_TBL0m - MMU_IPMC_GROUP_TBL8m 836 */ 837 STATIC int 838 _soc_triumph_parity_process_mmuipmc(int unit, char *msg, 839 _soc_parity_info_t *info, int block, 840 int * intr_enable) 841 { 842 int size, index, rv = 0; 843 soc_reg_t reg; 844 uint32 addr, entry_idx, status; 845 _soc_ser_correct_info_t spci; 846 847 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 848 849 reg = info->status1_reg; 850 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 851 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 852 size = soc_reg_field_length(unit, reg, STATUSf); 853 reg = info->status0_reg; 854 for (index = 0; index < size; index++, status >>= 1) { 855 if (!(status & 1)) { 856 continue; 857 } 858 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, index); 859 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, 860 &entry_idx)); 861 LOG_ERROR(BSL_LS_SOC_COMMON, 862 (BSL_META_U(unit, 863 "unit %d %s%d entry %d parity error\n"), 864 unit, msg, index, entry_idx)); 865 866 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 867 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 868 info->error_field); 869 870 if (info->mem != INVALIDm) { 871 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 872 spci.reg = INVALIDr; 873 spci.mem = info->mem; 874 spci.blk_type = block; 875 spci.index = entry_idx; 876 rv = soc_ser_correction(unit, &spci); 877 if (SOC_FAILURE(rv)) { 878 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 879 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 880 info->mem, info->error_field); 881 } 882 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 883 } else { 884 *intr_enable = 0; 885 } 886 } 887 return SOC_E_NONE; 888 } 889 890 /* 891 * status0 (WRED_PARITY_ERROR_INFOr) is index 892 * status1 (WRED_PARITY_ERROR_BITMAPr) is table id 893 */ 894 STATIC int 895 _soc_triumph_parity_process_mmuwred(int unit, char *msg, 896 _soc_parity_info_t *info, int block, 897 int * intr_enable) 898 { 899 soc_reg_t reg; 900 uint32 addr0, entry_idx, status, addr1, mconf, mconf_addr; 901 _soc_ser_correct_info_t spci; 902 int rv = 0; 903 904 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 905 906 reg = info->status0_reg; 907 addr0 = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 908 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr0, &entry_idx)); 909 reg = info->status1_reg; 910 addr1 = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 911 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr1, &status)); 912 spci.mem = info->mem; 913 if (status & 0x000003) { 914 msg = "WRED_CFG_CELL"; 915 spci.mem = MMU_WRED_CFG_CELLm; 916 } else if (status & 0x00000c) { 917 msg = "WRED_THD_0_CELL"; 918 spci.mem = MMU_WRED_THD_0_CELLm; 919 } else if (status & 0x000030) { 920 msg = "WRED_THD_1_CELL"; 921 spci.mem = MMU_WRED_THD_1_CELLm; 922 } else if (status & 0x0000c0) { 923 msg = "WRED_CFG_PACKET"; 924 spci.mem = MMU_WRED_CFG_PACKETm; 925 } else if (status & 0x000300) { 926 msg = "WRED_THD_0_PACKET"; 927 spci.mem = MMU_WRED_THD_0_PACKETm; 928 } else if (status & 0x000c00) { 929 msg = "WRED_THD_1_PACKET"; 930 spci.mem = MMU_WRED_THD_1_PACKETm; 931 } else if (status & 0x003000) { 932 msg = "WRED_PORT_CFG_CELL"; 933 spci.mem = MMU_WRED_PORT_CFG_CELLm; 934 } else if (status & 0x00c000) { 935 msg = "WRED_PORT_THD_0_CELL"; 936 spci.mem = MMU_WRED_PORT_THD_0_CELLm; 937 } else if (status & 0x030000) { 938 msg = "WRED_PORT_THD_1_CELL"; 939 spci.mem = MMU_WRED_PORT_THD_1_CELLm; 940 } else if (status & 0x0c0000) { 941 msg = "WRED_PORT_CFG_PACKET"; 942 spci.mem = MMU_WRED_PORT_CFG_PACKETm; 943 } else if (status & 0x300000) { 944 msg = "WRED_PORT_THD_0_PACKET"; 945 spci.mem = MMU_WRED_PORT_THD_0_PACKETm; 946 } else if (status & 0xc00000) { 947 msg = "WRED_PORT_THD_1_PACKET"; 948 spci.mem = MMU_WRED_PORT_THD_1_PACKETm; 949 } else { 950 LOG_ERROR(BSL_LS_SOC_COMMON, 951 (BSL_META_U(unit, 952 "unit %d %s parity hardware inconsistency\n"), 953 unit, msg)); 954 *intr_enable = 0; 955 return SOC_E_NONE; 956 } 957 LOG_ERROR(BSL_LS_SOC_COMMON, 958 (BSL_META_U(unit, 959 "unit %d %s entry %d parity error\n"), 960 unit, msg, entry_idx)); 961 962 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 963 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, info->mem, 964 info->error_field); 965 966 if (spci.mem != INVALIDm) { 967 spci.flags = SOC_SER_SRC_MEM | SOC_SER_REG_MEM_KNOWN; 968 spci.reg = INVALIDr; 969 spci.blk_type = block; 970 spci.index = entry_idx; 971 rv = soc_ser_correction(unit, &spci); 972 if (SOC_FAILURE(rv)) { 973 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 974 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 975 info->mem, info->error_field); 976 } 977 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr0, 0)); 978 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr1, 0)); 979 980 mconf_addr = soc_reg_addr(unit, MISCCONFIGr, REG_PORT_ANY, 0); 981 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, mconf_addr, &mconf)); 982 soc_reg_field_set(unit, MISCCONFIGr, &mconf, PARITY_STAT_CLEARf, 1); 983 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, mconf_addr, mconf)); 984 soc_reg_field_set(unit, MISCCONFIGr, &mconf, PARITY_STAT_CLEARf, 0); 985 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, mconf_addr, mconf)); 986 } else { 987 *intr_enable = 0; 988 } 989 990 return SOC_E_NONE; 991 } 992 993 STATIC int 994 _soc_triumph_mtro_mmu_port_index_get(int instance_num, int ptr, 995 int *port, int *queue) 996 { 997 int num_port, numq, base_queue, port_index; 998 999 /* Check if instance_num is valid */ 1000 if ((instance_num < 0) || 1001 (instance_num >= MMU_MTRO_MAX_GROUP)) { 1002 return SOC_E_INTERNAL; 1003 } 1004 1005 num_port = _soc_tr_mtro_group_info[instance_num].num_port; 1006 numq = _soc_tr_mtro_group_info[instance_num].numq; 1007 base_queue = _soc_tr_mtro_group_info[instance_num].base_queue; 1008 1009 /* Check if ptr is valid */ 1010 if ((ptr < 0) || (ptr >= (num_port * numq))) { 1011 return SOC_E_INTERNAL; 1012 } 1013 1014 port_index = ptr / numq; 1015 *port = _soc_tr_mtro_group_info[instance_num].port_list[port_index]; 1016 *queue = base_queue + ptr % numq; 1017 1018 return SOC_E_NONE; 1019 } 1020 1021 STATIC int 1022 _soc_triumph_parity_mmu_clear(int unit, soc_field_t status_field) 1023 { 1024 uint32 rval; 1025 SOC_IF_ERROR_RETURN 1026 (READ_MEM_FAIL_INT_STATr(unit, &rval)); 1027 if (soc_reg_field_valid(unit, MEM_FAIL_INT_STATr, status_field)) { 1028 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, status_field, 0); 1029 } else { 1030 return SOC_E_INTERNAL; 1031 } 1032 SOC_IF_ERROR_RETURN 1033 (WRITE_MEM_FAIL_INT_STATr(unit, rval)); 1034 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1035 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 1); 1036 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1037 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1038 soc_reg_field_set(unit, MISCCONFIGr, &rval, PARITY_STAT_CLEARf, 0); 1039 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 1040 return SOC_E_NONE; 1041 } 1042 1043 1044 STATIC int 1045 _soc_triumph_parity_process_mmumtro(int unit, _soc_parity_info_t *info, 1046 soc_block_t block) 1047 { 1048 static soc_reg_t mtro_regs[] = { 1049 MINBUCKETCONFIG_64r, 1050 MINBUCKETr, 1051 MAXBUCKETCONFIG_64r, 1052 MAXBUCKETr 1053 }; 1054 static soc_reg_t cpu_mtro_regs[] = { 1055 CPUMAXBUCKETCONFIG_64r, 1056 CPUMAXBUCKETr 1057 }; 1058 uint32 i, rval, status, val, minfo; 1059 _soc_ser_correct_info_t spci; 1060 int rv, port, index, instance_num, ptr; 1061 1062 memset(&spci, 0, sizeof(_soc_ser_correct_info_t)); 1063 spci.flags = SOC_SER_SRC_REG | SOC_SER_REG_MEM_KNOWN; 1064 spci.mem = INVALIDm; 1065 spci.blk_type = SOC_BLK_MMU; 1066 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &status)); 1067 if (!soc_reg_field_get(unit, MEM_FAIL_INT_STATr, status, 1068 MTRO_PAR_ERRf)) { 1069 LOG_ERROR(BSL_LS_SOC_COMMON, 1070 (BSL_META_U(unit, 1071 "unit %d MTRO: parity hardware" 1072 " inconsistency\n"), 1073 unit)); 1074 return SOC_E_NONE; 1075 } 1076 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGRSHAPEPARITYERRORPTRr, 1077 REG_PORT_ANY, 0, &rval)); 1078 instance_num = soc_reg_field_get(unit, EGRSHAPEPARITYERRORPTRr, 1079 rval, INSTANCE_NUMf); 1080 ptr = soc_reg_field_get(unit, EGRSHAPEPARITYERRORPTRr, rval, PTRf); 1081 SOC_IF_ERROR_RETURN( 1082 _soc_triumph_mtro_mmu_port_index_get(instance_num, ptr, 1083 &port, &index)); 1084 /* Disable parity */ 1085 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1086 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 0); 1087 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1088 1089 if (port == REG_PORT_ANY) { 1090 for (i = 0; i < COUNTOF(cpu_mtro_regs); i++) { 1091 spci.port = port; 1092 spci.index = index; 1093 spci.reg = cpu_mtro_regs[i]; 1094 minfo = SOC_TRIUMPH_MEM_PARITY_INFO(unit, block, info->error_field); 1095 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1096 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1097 index, minfo); 1098 rv = soc_ser_correction(unit, &spci); 1099 if (SOC_FAILURE(rv)) { 1100 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1101 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1102 index, minfo); 1103 } 1104 } 1105 } else if (port >=1 && port <= 53) { 1106 for (i = 0; i < COUNTOF(mtro_regs); i++) { 1107 spci.port = port; 1108 spci.index = index; 1109 spci.reg = mtro_regs[i]; 1110 minfo = SOC_TRIUMPH_MEM_PARITY_INFO(unit, block, info->error_field); 1111 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1112 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1113 index, minfo); 1114 rv = soc_ser_correction(unit, &spci); 1115 if (SOC_FAILURE(rv)) { 1116 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1117 SOC_SWITCH_EVENT_DATA_ERROR_FAILEDTOCORRECT, 1118 index, minfo); 1119 } 1120 } 1121 } else { 1122 LOG_ERROR(BSL_LS_SOC_COMMON, 1123 (BSL_META_U(unit, 1124 "unit %d MTRO: parity hardware inconsistency\n"), 1125 unit)); 1126 } 1127 SOC_IF_ERROR_RETURN(_soc_triumph_parity_mmu_clear(unit, MTRO_PAR_ERRf)); 1128 /* Enable parity */ 1129 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &val)); 1130 soc_reg_field_set(unit, MISCCONFIGr, &val, PARITY_CHK_ENf, 1); 1131 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, val)); 1132 return SOC_E_NONE; 1133 } 1134 1135 STATIC int 1136 _soc_triumph_process_parity_error(int unit) 1137 { 1138 int block, table, intr_enable; 1139 uint32 addr, cmic_status, block_status, block_enable; 1140 uint32 enable_addr; 1141 _soc_parity_info_t *info; 1142 soc_reg_t block_reg, enable_reg; 1143 char *msg; 1144 1145 /* coverity[result_independent_of_operands] */ 1146 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, 1147 &cmic_status)); 1148 1149 /* loop through each block */ 1150 for (block = 0; _soc_tr_parity_block_info[block].cpi_bit; block++) { 1151 if (!(cmic_status & _soc_tr_parity_block_info[block].cpi_bit)) { 1152 continue; 1153 } 1154 info = _soc_tr_parity_block_info[block].info; 1155 block_reg = _soc_tr_parity_block_info[block].status_reg; 1156 addr = soc_reg_addr(unit, block_reg, REG_PORT_ANY, 0); 1157 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &block_status)); 1158 1159 enable_reg = _soc_tr_parity_block_info[block].enable_reg; 1160 enable_addr = soc_reg_addr(unit, enable_reg, REG_PORT_ANY, 0); 1161 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, enable_addr, &block_enable)); 1162 1163 /* loop through each table in the block */ 1164 for (table = 0; info[table].error_field != INVALIDf; table++) { 1165 if (!soc_reg_field_get(unit, block_reg, block_status, 1166 info[table].error_field)) { 1167 continue; 1168 } 1169 if (info[table].msg) { 1170 msg = info[table].msg; 1171 } else if (info[table].mem != INVALIDm) { 1172 msg = SOC_MEM_NAME(unit, info[table].mem); 1173 } else { 1174 msg = SOC_FIELD_NAME(unit, info[table].error_field); 1175 } 1176 1177 intr_enable = 1; 1178 1179 /* handle different parity error reporting style */ 1180 switch (info[table].type) { 1181 case _SOC_PARITY_INFO_TYPE_SINGLE_TABLE1: 1182 SOC_IF_ERROR_RETURN( 1183 _soc_triumph_parity_process_single_table1(unit, msg, 1184 &info[table], block, &intr_enable)); 1185 break; 1186 case _SOC_PARITY_INFO_TYPE_SINGLE_TABLE2: 1187 SOC_IF_ERROR_RETURN( 1188 _soc_triumph_parity_process_single_table2(unit, msg, 1189 &info[table], block, &intr_enable)); 1190 break; 1191 case _SOC_PARITY_INFO_TYPE_DUAL_TABLE1: 1192 SOC_IF_ERROR_RETURN( 1193 _soc_triumph_parity_process_dual_table1(unit, msg, 1194 &info[table], block, &intr_enable)); 1195 break; 1196 case _SOC_PARITY_INFO_TYPE_DUAL_TABLE2: 1197 SOC_IF_ERROR_RETURN( 1198 _soc_triumph_parity_process_dual_table2(unit, msg, 1199 &info[table], block, &intr_enable)); 1200 break; 1201 case _SOC_PARITY_INFO_TYPE_MMUIPMC: 1202 SOC_IF_ERROR_RETURN( 1203 _soc_triumph_parity_process_mmuipmc(unit, msg, 1204 &info[table], block, &intr_enable)); 1205 break; 1206 case _SOC_PARITY_INFO_TYPE_MMUWRED: 1207 SOC_IF_ERROR_RETURN( 1208 _soc_triumph_parity_process_mmuwred(unit, msg, 1209 &info[table], block, &intr_enable)); 1210 break; 1211 case _SOC_PARITY_INFO_TYPE_MMUMTRO: 1212 SOC_IF_ERROR_RETURN( 1213 _soc_triumph_parity_process_mmumtro(unit, 1214 &info[table], block)); 1215 break; 1216 /* Coverity:- This is intentional and not a bug. 1217 * The generic case is hit only when we are not able 1218 * to fix an issue, there is no analysis/correction code, 1219 * just an err msg - same as the default. 1220 * This is an old device for which we do not have 1221 * full SER correction implemented. 1222 */ 1223 /* coverity[unterminated_case] */ 1224 case _SOC_PARITY_INFO_TYPE_GENERIC: 1225 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 1226 SOC_SWITCH_EVENT_DATA_ERROR_PARITY, 1227 info[table].mem, 1228 info[table].error_field); 1229 LOG_ERROR(BSL_LS_SOC_COMMON, 1230 (BSL_META_U(unit, 1231 "unit %d %s asserted\n"), 1232 unit, msg)); 1233 default: 1234 intr_enable = 0; 1235 break; 1236 } /* handle different parity error reporting style */ 1237 /* Disable error reporting on this memory to avoid continuous 1238 interrupts */ 1239 soc_reg_field_set(unit, enable_reg, &block_enable, 1240 info[table].enable_field, intr_enable); 1241 } /* loop through each table in the block */ 1242 1243 /* Exclude non-parity status bits */ 1244 block_status &= block_enable; 1245 block_enable &= ~block_status; 1246 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, enable_addr, block_enable)); 1247 block_enable |= block_status; 1248 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, enable_addr, block_enable)); 1249 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0)); 1250 } /* loop through each block */ 1251 1252 return SOC_E_NONE; 1253 } 1254 1255 void 1256 soc_triumph_parity_error(void *unit_vp, void *d1, void *d2, 1257 void *d3, void *d4) 1258 { 1259 int unit = PTR_TO_INT(unit_vp); 1260 1261 _soc_triumph_process_parity_error(unit); 1262 soc_intr_enable(unit, IRQ_MEM_FAIL); 1263 } 1264 1265 typedef struct _soc_esm_intr_reg_info_s { 1266 soc_field_t error_field; 1267 char *msg; 1268 soc_reg_t detail_reg[3]; 1269 } _soc_esm_intr_reg_info_t; 1270 1271 STATIC _soc_esm_intr_reg_info_t _soc_tr_etu_intr_reg_info[] = { 1272 { ILL_SRAM_ACCf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1273 { SBUS_REQACK_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1274 { BKGND_PROC_SECf, NULL, 1275 { ETU_BKGND_PROC_SEC_INFOr, INVALIDr, INVALIDr } }, 1276 { BKGND_PROC_ERRf, NULL, 1277 { ETU_BKGND_PROC_ERR_INFOr, INVALIDr, INVALIDr } }, 1278 { SBUS_CMD_SECf, NULL, { ETU_SBUS_CMD_SEC_INFOr, INVALIDr, INVALIDr } }, 1279 { SBUS_CMD_ERRf, NULL, 1280 { ETU_SBUS_CMD_ERR_INFO1r, ETU_SBUS_CMD_ERR_INFO2r, INVALIDr} }, 1281 { ET_DPEO_PERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1282 { ET_S1_MWS_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1283 { ET_S0_MWS_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1284 { ET_S1_NORV_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1285 { ET_S0_NORV_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1286 { ET_S1_RBUS_PERRf, NULL, { ETU_S1_RBUS_PERR_INFOr, INVALIDr, INVALIDr } }, 1287 { ET_S0_RBUS_PERRf, NULL, { ETU_S0_RBUS_PERR_INFOr, INVALIDr, INVALIDr } }, 1288 /* PPA_COMPLETEf */ 1289 /* ET_INST_REQ_COMPLETEf */ 1290 /* MRST_COMPLETEf */ 1291 { CIF_LOST2_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_LUREQFIFO */ 1292 { LUREQFIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_LUREQFIFO */ 1293 { ADREQ1FIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ1FIFO */ 1294 { ADREQ1FIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ1FIFO */ 1295 { ADREQ0FIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ0FIFO */ 1296 { ADREQ0FIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ0FIFO */ 1297 { L2MODFIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1298 { L2MODFIFO_UNDERRUNf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1299 { L2MODFIFO_NOTEMPTYf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1300 { EXT_TCAM_SE_O_L_PINf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1301 { INVALIDf } /* table terminator */ 1302 }; 1303 1304 STATIC _soc_esm_intr_reg_info_t _soc_tr_es01_intr_reg_info[] = { 1305 { CIF_LOST2_HITHR1f, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ1FIFO */ 1306 { ADREQ1FIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ1FIFO */ 1307 { CIF_LOST2_HITHR0f, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ0FIFO */ 1308 { ADREQ0FIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ADREQ0FIFO */ 1309 { ADL3DST_SECf, NULL, { ES01_ADL3DST_SEC_INFOr, INVALIDr, INVALIDr } }, 1310 { ADL3DST_DEDf, NULL, { ES01_ADL3DST_DED_INFOr, INVALIDr, INVALIDr } }, 1311 { ADL3SRC_SECf, NULL, { ES01_ADL3SRC_SEC_INFOr, INVALIDr, INVALIDr } }, 1312 { ADL3SRC_DEDf, NULL, { ES01_ADL3SRC_DED_INFOr, INVALIDr, INVALIDr } }, 1313 { ADL2DST_SECf, NULL, { ES01_ADL2DST_SEC_INFOr, INVALIDr, INVALIDr } }, 1314 { ADL2DST_DEDf, NULL, { ES01_ADL2DST_DED_INFOr, INVALIDr, INVALIDr } }, 1315 { ADL2SRC_SECf, NULL, { ES01_ADL2SRC_SEC_INFOr, INVALIDr, INVALIDr } }, 1316 { ADL2SRC_DEDf, NULL, { ES01_ADL2SRC_DED_INFOr, INVALIDr, INVALIDr } }, 1317 { L2L3RSPFIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_L2L3RSPFIFO */ 1318 { L2L3RSPFIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_L2L3RSPFIFO */ 1319 { FP0RSPFIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP0RSPFIFO */ 1320 { FP0RSPFIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP0RSPFIFO */ 1321 { FP1RSPFIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP1RSPFIFO */ 1322 { FP1RSPFIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP1RSPFIFO */ 1323 { PKT_CNT_WRAPf, NULL, { ES01_PKT_CNT_WRAP_INFOr, INVALIDr, INVALIDr } }, 1324 { BYT_CNT_WRAPf, NULL, { ES01_BYT_CNT_WRAP_INFOr, INVALIDr, INVALIDr } }, 1325 { ADFPCNTR_SECf, NULL, { ES01_ADFPCNTR_SEC_INFOr, INVALIDr, INVALIDr } }, 1326 { ADFPCNTR_DEDf, NULL, { ES01_ADFPCNTR_DED_INFOr, INVALIDr, INVALIDr } }, 1327 { INVALIDf } /* table terminator */ 1328 }; 1329 1330 STATIC _soc_esm_intr_reg_info_t _soc_tr_iesmif_intr_reg_info[] = { 1331 { AGE_IPFIX_ERRf, NULL, { IPFIX_AGE_CONTROLr, INVALIDr, INVALIDr } }, 1332 { FP_REFRESH_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1333 { BK2BK_ESM_ELIGIBLEf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1334 { ESU_ASF_HI_ACCUMf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_L2L3RSPFIFO, chk_FP0RSPFIFO, chk_FP1RSPFIFO */ 1335 { LUREQFIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_LUREQFIFO */ 1336 { ECB_HI_ACCUMf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ECBFIFO */ 1337 { ECB_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ECBFIFO */ 1338 { DROPPED_CELLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1339 { CNP_ES_COUNT_WRAPf, NULL, { IESMIF_STATUS7r, INVALIDr, INVALIDr } }, 1340 { CNP_EXT_SEARCHf, NULL, { IESMIF_STATUS7r, INVALIDr, INVALIDr } }, 1341 { NEW_MAX_LATENCYf, NULL, { IESMIF_STATUS3r, INVALIDr, INVALIDr } }, 1342 { ECB_SEC_COUNT_WRAPf, NULL, { IESMIF_STATUS5r, INVALIDr, INVALIDr } }, 1343 { ECB_SEC_ERRf, NULL, 1344 { IESMIF_STATUS5r, IESMIF_ECB_ECC_STATUS_SBEr, 1345 IESMIF_ECB_SBE_SYNDROME12r } }, 1346 { ECB_DED_COUNT_WRAPf, NULL, { IESMIF_STATUS6r, INVALIDr, INVALIDr } }, 1347 { ECB_DED_ERRf, NULL, 1348 { IESMIF_STATUS6r, IESMIF_ECB_ECC_STATUS_DBEr, INVALIDr } }, 1349 { INVALIDf } /* table terminator */ 1350 }; 1351 1352 STATIC _soc_esm_intr_reg_info_t _soc_tr_il3mc_erb_intr_reg_info[] = { 1353 { EXTFP_POLICY_SECf, NULL, 1354 { IL3MC_EXTFP_POLICY_SEC_INFOr, INVALIDr, INVALIDr } }, 1355 { EXTFP_POLICY_DEDf, NULL, 1356 { IL3MC_EXTFP_POLICY_DED_INFOr, INVALIDr, INVALIDr } }, 1357 { EXT_LU_ERRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1358 { FPCREQFIFO_BK2BK_WRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, 1359 { FPCREQFIFO_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /*chk_FPCREQFIFO */ 1360 { FPCREQFIFO_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /*chk_FPCREQFIFO */ 1361 { FP1RSPFIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP1RSPFIFO */ 1362 { FP0RSPFIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_FP0RSPFIFO */ 1363 { L2L3RSPFIFOCOUNT_GTE_HITHRf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_L2L3RSPFIFO */ 1364 { IPCF_PTR_MISMATCHf, NULL, 1365 { IL3MC_IPCF_PTR_MISMATCH_INFOr, INVALIDr, INVALIDr } }, 1366 { ERB_OVERFLOWf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ERBFIFO */ 1367 { ERB_FULLf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ERBFIFO */ 1368 { ERB_UNDERRUNf, NULL, { INVALIDr, INVALIDr, INVALIDr } }, /* chk_ERBFIFO */ 1369 { INVALIDf } /* table terminator */ 1370 }; 1371 1372 STATIC struct { 1373 soc_reg_t enable_reg; 1374 soc_reg_t clear_reg; 1375 soc_reg_t status_reg; 1376 _soc_esm_intr_reg_info_t *reg_info; 1377 } _soc_tr_esm_intr_info[] = { 1378 { ETU_INTR_ENABLEr, ETU_INTR_CLEARr, ETU_INTR_STATUSr, 1379 _soc_tr_etu_intr_reg_info }, 1380 { ES01_INTR_ENABLEr, ES01_INTR_CLEARr, ES01_INTR_STATUSr, 1381 _soc_tr_es01_intr_reg_info }, 1382 { IESMIF_INTR_ENABLEr, IESMIF_INTR_CLEARr, IESMIF_INTR_STATUSr, 1383 _soc_tr_iesmif_intr_reg_info }, 1384 { IL3MC_ERB_INTR_ENABLEr, IL3MC_ERB_INTR_CLEARr, IL3MC_ERB_INTR_STATUSr, 1385 _soc_tr_il3mc_erb_intr_reg_info }, 1386 { INVALIDr, INVALIDr, INVALIDr } /* table terminator */ 1387 }; 1388 1389 STATIC int 1390 _soc_triumph_esm_intr_enable(int unit, int enable) 1391 { 1392 int reg_index; 1393 uint32 addr, rval; 1394 soc_reg_t reg; 1395 _soc_esm_intr_reg_info_t *intr_reg_info; 1396 1397 if (SOC_CONTROL(unit)->tcam_info == NULL) { 1398 return SOC_E_NONE; 1399 } 1400 1401 for (reg_index = 0; 1402 _soc_tr_esm_intr_info[reg_index].status_reg != INVALIDf; 1403 reg_index++) { 1404 reg = _soc_tr_esm_intr_info[reg_index].status_reg; 1405 rval = 0; 1406 1407 for (intr_reg_info = _soc_tr_esm_intr_info[reg_index].reg_info; 1408 intr_reg_info->error_field != INVALIDf; intr_reg_info++) { 1409 soc_reg_field_set(unit, reg, &rval, intr_reg_info->error_field, 1410 enable ? 1 : 0); 1411 } 1412 reg = _soc_tr_esm_intr_info[reg_index].enable_reg; 1413 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 1414 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 1415 } 1416 1417 soc_intr_enable(unit, IRQ_CHIP_FUNC_3); 1418 1419 return SOC_E_NONE; 1420 } 1421 1422 STATIC int 1423 _soc_triumph_esm_process_intr_status(int unit) 1424 { 1425 int reg_index, field_index, i; 1426 uint32 addr, status, rval; 1427 soc_reg_t reg, detail_reg; 1428 _soc_esm_intr_reg_info_t *intr_reg_info; 1429 soc_reg_info_t *reg_info; 1430 soc_field_info_t *field_info; 1431 char *msg; 1432 char line_buf[80], field_buf[80]; 1433 int line_len, field_len; 1434 1435 for (reg_index = 0; _soc_tr_esm_intr_info[reg_index].clear_reg != INVALIDf; 1436 reg_index++) { 1437 reg = _soc_tr_esm_intr_info[reg_index].status_reg; 1438 1439 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 1440 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &status)); 1441 for (intr_reg_info = _soc_tr_esm_intr_info[reg_index].reg_info; 1442 intr_reg_info->error_field != INVALIDf; intr_reg_info++) { 1443 if (!soc_reg_field_get(unit, reg, status, 1444 intr_reg_info->error_field)) { 1445 continue; 1446 } 1447 msg = intr_reg_info->msg; 1448 if (msg == NULL) { 1449 msg = SOC_FIELD_NAME(unit, intr_reg_info->error_field); 1450 } 1451 LOG_ERROR(BSL_LS_SOC_COMMON, 1452 (BSL_META_U(unit, 1453 "unit %d %s asserted\n"), unit, msg)); 1454 1455 for (i = 0; intr_reg_info->detail_reg[i] != INVALIDr; i++) { 1456 detail_reg = intr_reg_info->detail_reg[i]; 1457 addr = soc_reg_addr(unit, detail_reg, REG_PORT_ANY, 0); 1458 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 1459 sal_sprintf(line_buf, "%s=0x%08x: ", 1460 SOC_REG_NAME(unit, detail_reg), rval); 1461 line_len = sal_strlen(line_buf); 1462 reg_info = &SOC_REG_INFO(unit, detail_reg); 1463 for (field_index = reg_info->nFields - 1; field_index >= 0; 1464 field_index--) { 1465 field_info = ®_info->fields[field_index]; 1466 sal_sprintf(field_buf, "%s%s=0x%x", 1467 field_index == reg_info->nFields - 1 ? 1468 "<" : " ", 1469 SOC_FIELD_NAME(unit, field_info->field), 1470 soc_reg_field_get(unit, detail_reg, rval, 1471 field_info->field)); 1472 field_len = sal_strlen(field_buf); 1473 if (line_len + field_len >= 64) { 1474 LOG_ERROR(BSL_LS_SOC_COMMON, 1475 (BSL_META_U(unit, 1476 " %s\n"), line_buf)); 1477 line_len = 0; 1478 } 1479 sal_sprintf(&line_buf[line_len], "%s", field_buf); 1480 line_len += field_len; 1481 } 1482 LOG_ERROR(BSL_LS_SOC_COMMON, 1483 (BSL_META_U(unit, 1484 " %s>\n"), line_buf)); 1485 } 1486 } 1487 reg = _soc_tr_esm_intr_info[reg_index].clear_reg; 1488 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 1489 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, 0xffffffff)); 1490 } 1491 1492 return SOC_E_NONE; 1493 } 1494 1495 void 1496 soc_triumph_esm_intr_status(void *unit_vp, void *d1, void *d2, 1497 void *d3, void *d4) 1498 { 1499 int unit = PTR_TO_INT(unit_vp); 1500 1501 _soc_triumph_esm_process_intr_status(unit); 1502 soc_intr_enable(unit, IRQ_CHIP_FUNC_3); 1503 } 1504 1505 STATIC int 1506 soc_triumph_pipe_mem_clear(int unit) 1507 { 1508 uint32 rval; 1509 int pipe_init_usec; 1510 soc_timeout_t to; 1511 1512 /* 1513 * Reset the IPIPE and EPIPE block 1514 */ 1515 rval = 0; 1516 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 1517 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 1518 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 1519 /* Set count to # entries in largest IPIPE table, L2_ENTRYm */ 1520 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x8000); 1521 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 1522 1523 rval = 0; 1524 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 1525 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 1526 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 1527 /* Set count to # entries in largest EPIPE table, EGR_L3_NEXT_HOPm */ 1528 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, 0x4000); 1529 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 1530 1531 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 1532 if (SAL_BOOT_SIMULATION) { 1533 pipe_init_usec = 10000000; 1534 } else { 1535 pipe_init_usec = 50000; 1536 } 1537 soc_timeout_init(&to, pipe_init_usec, 0); 1538 1539 /* Wait for IPIPE memory initialization done. */ 1540 do { 1541 SOC_IF_ERROR_RETURN(READ_ING_HW_RESET_CONTROL_2r(unit, &rval)); 1542 if (soc_reg_field_get(unit, ING_HW_RESET_CONTROL_2r, rval, DONEf)) { 1543 break; 1544 } 1545 if (soc_timeout_check(&to)) { 1546 LOG_WARN(BSL_LS_SOC_COMMON, 1547 (BSL_META_U(unit, 1548 "unit %d : ING_HW_RESET timeout\n"), unit)); 1549 break; 1550 } 1551 } while (TRUE); 1552 1553 /* Wait for EPIPE memory initialization done. */ 1554 do { 1555 SOC_IF_ERROR_RETURN(READ_EGR_HW_RESET_CONTROL_1r(unit, &rval)); 1556 if (soc_reg_field_get(unit, EGR_HW_RESET_CONTROL_1r, rval, DONEf)) { 1557 break; 1558 } 1559 if (soc_timeout_check(&to)) { 1560 LOG_WARN(BSL_LS_SOC_COMMON, 1561 (BSL_META_U(unit, 1562 "unit %d : EGR_HW_RESET timeout\n"), unit)); 1563 break; 1564 } 1565 } while (TRUE); 1566 1567 rval = 0; 1568 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 1569 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 1570 1571 if (!SAL_BOOT_QUICKTURN) { 1572 /* ING_PW_TERM_COUNTERS is not handled by reset control */ 1573 SOC_IF_ERROR_RETURN 1574 (soc_mem_clear(unit, ING_PW_TERM_COUNTERSm, COPYNO_ALL, TRUE)); 1575 /* Egress IPFIX tables are not properly handled by reset control */ 1576 SOC_IF_ERROR_RETURN 1577 (soc_mem_clear(unit, EGR_IPFIX_SESSION_TABLEm, COPYNO_ALL, TRUE)); 1578 SOC_IF_ERROR_RETURN 1579 (soc_mem_clear(unit, EGR_IPFIX_EXPORT_FIFOm, COPYNO_ALL, TRUE)); 1580 } 1581 1582 return SOC_E_NONE; 1583 } 1584 1585 /* SER processing for TCAMs */ 1586 STATIC _soc_ser_parity_info_t _soc_triumph_ser_parity_info[] = { 1587 { EFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 1588 -1, -1, -1, -1, -1, 1589 430, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1590 { EGR_ERSPANm, _SOC_SER_PARITY_MODE_2BITS, 1591 -1, -1, -1, -1, -1, 1592 339, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1593 /* { FP_SLICE_MAPm, _SOC_SER_PARITY_MODE_2BITS, 1594 -1, -1, -1, -1, -1, 1595 510, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE},*/ 1596 { FP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 1597 -1, -1, -1, -1, -1, 1598 430, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1599 { ING_IPFIX_PROFILEm, _SOC_SER_PARITY_MODE_2BITS, 1600 -1, -1, -1, -1, -1, 1601 14, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1602 { MPLS_STATION_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 1603 -1, -1, -1, -1, -1, 1604 121, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1605 { VFP_TCAMm, _SOC_SER_PARITY_MODE_2BITS, 1606 -1, -1, -1, -1, -1, 1607 430, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1608 { L3_TUNNELm, _SOC_SER_PARITY_MODE_2BITS, 1609 -1, -1, -1, -1, -1, 1610 223, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1611 { VLAN_SUBNETm, _SOC_SER_PARITY_MODE_2BITS, 1612 -1, -1, -1, -1, -1, 1613 162, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1614 { L3_DEFIPm, _SOC_SER_PARITY_MODE_2BITS, 1615 -1, -1, -1, -1, -1, 1616 235, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1617 { L3_DEFIP_128m, _SOC_SER_PARITY_MODE_2BITS, 1618 -1, -1, -1, -1, -1, 1619 308, INVALIDr, 0, 0, 0, _SOC_SER_FLAG_SW_COMPARE}, 1620 { INVALIDm, _SOC_SER_PARITY_MODE_NUM}, 1621 }; 1622 1623 1624 int 1625 soc_triumph_misc_init(int unit) 1626 { 1627 uint16 dev_id; 1628 uint8 rev_id; 1629 uint32 rval; 1630 uint64 reg64; 1631 int first_valid_xgport[4], gxport_12g; 1632 int port, blk, i; 1633 uint32 mode[4] = {0}; 1634 soc_pbmp_t pbmp_gport_block; 1635 soc_field_t fields[3]; 1636 uint32 values[3]; 1637 int cache_fpmem; 1638 soc_mem_t fp_tcams[3] = {FP_TCAMm, EFP_TCAMm, VFP_TCAMm}; 1639 uint8 fp_tcam_len = 3; 1640 uint8 fp_tcam_iter = 0; 1641 1642 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 1643 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, DISABLEf, 0); 1644 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 1645 1646 soc_cm_get_id(unit, &dev_id, &rev_id); 1647 1648 /* 1649 * XGPORT0: 2-13 1650 * XGPORT1: 14-25 1651 * XGPORT2: 26, 32-42 1652 * XGPORT3: 27, 43-53 1653 */ 1654 for (i = 0; i < 4; i++) { 1655 first_valid_xgport[i] = -1; 1656 } 1657 PBMP_XG_ITER(unit, port) { 1658 blk = SOC_PORT_BLOCK(unit, port); 1659 if (first_valid_xgport[SOC_BLOCK_INFO(unit, blk).number] == -1) { 1660 first_valid_xgport[SOC_BLOCK_INFO(unit, blk).number] = port; 1661 } 1662 } 1663 1664 gxport_12g = FALSE; 1665 switch (dev_id) { 1666 case BCM56684_DEVICE_ID: 1667 case BCM56680_DEVICE_ID: 1668 mode[0] = mode[1] = mode[2] = mode[3] = 3; /* 2.5G-mode */ 1669 gxport_12g = TRUE; 1670 1671 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1672 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP0_MODEf, 3); 1673 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP1_MODEf, 3); 1674 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 3); 1675 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 3); 1676 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, HG_16GBPS_BMPf, 0x0f); 1677 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1678 break; 1679 1680 case BCM56686_DEVICE_ID: 1681 mode[0] = mode[3] = 2; /* xport-mode */ 1682 1683 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1684 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP0_MODEf, 2); 1685 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 2); 1686 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, HG_16GBPS_BMPf, 0xf9); 1687 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1688 1689 /* use 7 requestors mode instead of the default 8 requestors mode */ 1690 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 1691 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, TDM_MODEf, 1); 1692 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 1693 1694 /* 1695 * move the XPORT3 (XGOIRT3) to within 7 slots 1696 * (i.e. swap w/ unused block XGPORT1 or XGPORT2) 1697 */ 1698 SOC_IF_ERROR_RETURN(READ_IARB_TDM_MAPr(unit, &rval)); 1699 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT2f, 0x7); 1700 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT3f, 0x5); 1701 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_MAPr(unit, rval)); 1702 1703 soc_port_cmap_set(unit, 2, SOC_CTR_TYPE_XE); 1704 soc_port_cmap_set(unit, 27, SOC_CTR_TYPE_XE); 1705 break; 1706 1707 case BCM56620_DEVICE_ID: 1708 mode[0] = mode[1] = mode[2] = mode[3] = 3; /* 2.5G-mode */ 1709 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1710 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP0_MODEf, 3); 1711 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP1_MODEf, 3); 1712 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 3); 1713 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 3); 1714 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1715 break; 1716 1717 case BCM56624_DEVICE_ID: 1718 mode[0] = mode[1] = mode[2] = mode[3] = 1; /* gport-mode */ 1719 break; 1720 1721 case BCM56626_DEVICE_ID: 1722 mode[0] = mode[1] = 1; /* gport-mode */ 1723 for (i = 2; i < 4; i++) { 1724 port = first_valid_xgport[i]; 1725 if (SOC_INFO(unit).port_speed_max[port] >= 10000) { 1726 mode[i] = 2; /* xport-mode */ 1727 } else { 1728 mode[i] = 1; /* gport-mode */ 1729 } 1730 } 1731 1732 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1733 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 2); 1734 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 2); 1735 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1736 1737 soc_port_cmap_set(unit, 26, SOC_CTR_TYPE_XE); 1738 soc_port_cmap_set(unit, 27, SOC_CTR_TYPE_XE); 1739 break; 1740 1741 case BCM56628_DEVICE_ID: 1742 for (i = 0; i < 4; i++) { 1743 port = first_valid_xgport[i]; 1744 if (SOC_INFO(unit).port_speed_max[port] >= 10000) { 1745 mode[i] = 2; /* xport-mode */ 1746 } else { 1747 mode[i] = 1; /* gport-mode */ 1748 } 1749 } 1750 1751 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1752 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP0_MODEf, 2); 1753 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP1_MODEf, 2); 1754 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 2); 1755 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 2); 1756 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1757 1758 soc_port_cmap_set(unit, 2, SOC_CTR_TYPE_XE); 1759 soc_port_cmap_set(unit, 14, SOC_CTR_TYPE_XE); 1760 soc_port_cmap_set(unit, 26, SOC_CTR_TYPE_XE); 1761 soc_port_cmap_set(unit, 27, SOC_CTR_TYPE_XE); 1762 break; 1763 1764 case BCM56629_DEVICE_ID: 1765 if (soc_feature(unit, soc_feature_xgport_one_xe_six_ge)) { 1766 gxport_12g = TRUE; 1767 if (soc_property_get(unit, spn_BCM56629_40GE, 0)) { 1768 mode[0] = mode[1] = mode[2] = mode[3] = 1; /* gport-mode */ 1769 break; 1770 } else { 1771 mode[0] = mode[1] = mode[2] = mode[3] = 4; /* spank-mode */ 1772 1773 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1774 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP0_MODEf, 1); 1775 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP1_MODEf, 1); 1776 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 1); 1777 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 1); 1778 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, HG_16GBPS_BMPf, 1779 0x0f); 1780 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1781 1782 soc_port_cmap_set(unit, 2, SOC_CTR_TYPE_XE); 1783 soc_port_cmap_set(unit, 14, SOC_CTR_TYPE_XE); 1784 soc_port_cmap_set(unit, 26, SOC_CTR_TYPE_XE); 1785 soc_port_cmap_set(unit, 27, SOC_CTR_TYPE_XE); 1786 } 1787 } else { 1788 mode[0] = mode[1] = 1; /* gport-mode */ 1789 mode[2] = mode[3] = 2; /* xport-mode */ 1790 1791 SOC_IF_ERROR_RETURN(READ_ESTDMCONFIGr(unit, &rval)); 1792 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP2_MODEf, 2); 1793 soc_reg_field_set(unit, ESTDMCONFIGr, &rval, GROUP3_MODEf, 2); 1794 SOC_IF_ERROR_RETURN(WRITE_ESTDMCONFIGr(unit, rval)); 1795 1796 soc_port_cmap_set(unit, 26, SOC_CTR_TYPE_XE); 1797 soc_port_cmap_set(unit, 27, SOC_CTR_TYPE_XE); 1798 } 1799 break; 1800 1801 default: 1802 break; 1803 } 1804 1805 SOC_PBMP_CLEAR(pbmp_gport_block); 1806 1807 /* SPORT */ 1808 /* coverity[result_independent_of_operands] */ 1809 if (SOC_PORT_VALID(unit, 1)) { 1810 SOC_IF_ERROR_RETURN(READ_SPORT_CTL_REGr(unit, 1, &rval)); 1811 soc_reg_field_set(unit, SPORT_CTL_REGr, &rval, SPORT_EN_BITf, 1); 1812 SOC_IF_ERROR_RETURN(WRITE_SPORT_CTL_REGr(unit, 1, rval)); 1813 SOC_PBMP_PORT_ADD(pbmp_gport_block, 1); 1814 } 1815 1816 /* For FP_TCAMs, we don't have the logic necessary to 1817 * set the software cache until now. This is the time to check for 1818 * the cache permission of this table. 1819 */ 1820 cache_fpmem = soc_feature(unit, soc_feature_mem_cache) && 1821 soc_property_get(unit, spn_MEM_CACHE_ENABLE, 1822 (SAL_BOOT_RTLSIM || SAL_BOOT_XGSSIM) ? 0 : 1); 1823 1824 for (fp_tcam_iter=0; fp_tcam_iter < fp_tcam_len; fp_tcam_iter++) { 1825 1826 if (soc_property_get(unit, spn_MEM_CHECK_NOCACHE_OVERRIDE, 0)) { 1827 char mem_name[100]; 1828 char *mptr; 1829 1830 sal_memset(mem_name, 0, sizeof(mem_name)); 1831 sal_strncpy(mem_name, "mem_nocache_", sal_strlen("mem_nocache_")); 1832 mptr = &mem_name[sal_strlen(mem_name)]; 1833 sal_strncpy(mptr, SOC_MEM_NAME(unit, fp_tcams[fp_tcam_iter]), 1834 sizeof(mem_name) - sal_strlen(mem_name) - 1); 1835 if (soc_property_get(unit, mem_name, 0)) { 1836 cache_fpmem = 0; 1837 } 1838 } 1839 1840 if (cache_fpmem) { 1841 SOC_MEM_INFO(unit, fp_tcams[fp_tcam_iter]).flags |= 1842 SOC_MEM_FLAG_CACHABLE; 1843 SOC_IF_ERROR_RETURN 1844 (soc_mem_cache_set(unit, fp_tcams[fp_tcam_iter], 1845 MEM_BLOCK_ALL, TRUE)); 1846 } 1847 1848 if (!SOC_WARM_BOOT(unit)) { 1849 /* Must clear FP_TCAM after port to pipe mappings 1850 * are initialized. */ 1851 SOC_IF_ERROR_RETURN 1852 (soc_mem_clear(unit, fp_tcams[fp_tcam_iter], 1853 COPYNO_ALL, TRUE)); 1854 } 1855 } 1856 1857 /* set the mode for XGPORT blocks */ 1858 for (i = 0; i < 4; i++) { 1859 port = first_valid_xgport[i]; 1860 if (port == -1) { 1861 continue; 1862 } 1863 SOC_IF_ERROR_RETURN(READ_XGPORT_MODE_REGr(unit, port, &rval)); 1864 soc_reg_field_set(unit, XGPORT_MODE_REGr, &rval, XGPORT_MODE_BITSf, 1865 mode[i]); 1866 SOC_IF_ERROR_RETURN(WRITE_XGPORT_MODE_REGr(unit, port, rval)); 1867 SOC_PBMP_PORT_ADD(pbmp_gport_block, port); 1868 } 1869 1870 /* set the mode for GXPORT blocks */ 1871 PBMP_GX_ITER(unit, port) { 1872 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 1873 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, XPORT_MODE_BITSf, 1); 1874 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 1875 SOC_PBMP_PORT_ADD(pbmp_gport_block, port); 1876 } 1877 1878 /* 1879 * program IARB TDM request slot 1880 * IARB XPORT0 to XPORT3 represent XGPORT0 to XGPORT3 1881 * IARB XPORT4 to XPORT7 represent GXPORT0 to GXPORT3 1882 * each port block in slot 0, 2, 4, 6 has its own 16G TDM bandwidth 1883 * port blocks in slot 1, 3, 5, 7 share 3 16G TDM bandwidth in round robin 1884 * manner to behave like 4 12G slots 1885 */ 1886 if (gxport_12g) { 1887 SOC_IF_ERROR_RETURN(READ_IARB_TDM_MAPr(unit, &rval)); 1888 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT0f, 0x0); 1889 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT1f, 0x2); 1890 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT2f, 0x4); 1891 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT3f, 0x6); 1892 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT4f, 0x1); 1893 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT5f, 0x3); 1894 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT6f, 0x5); 1895 soc_reg_field_set(unit, IARB_TDM_MAPr, &rval, XPORT7f, 0x7); 1896 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_MAPr(unit, rval)); 1897 } 1898 1899 if (soc_feature(unit, soc_feature_esm_support)) { 1900 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 1901 /* description for ESM_ELIGIBLE_MODE in regsfile is wrong, 1902 * it should be 1 for odd slots and 2 for even slots */ 1903 if (soc_property_get(unit, spn_EXT_LOOKUP_ON_XPORT, 0)) { 1904 /* Enable ESM lookup on back-panel ports (XPORT blocks) */ 1905 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, 1906 ESM_ELIGIBLE_MODEf, 0x2); /* use even slot */ 1907 } else { 1908 /* Enable ESM lookup on front-panel ports (XGPORT blocks) */ 1909 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, 1910 ESM_ELIGIBLE_MODEf, 0x1); /* use odd slot */ 1911 } 1912 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 1913 } 1914 1915 /* 1916 * Remap LED if XGPORT block is configured as single 10G port 1917 * use the last port of the block instead of the first port of the block 1918 * (swap the first and the last port number of the block in remap table) 1919 * Default REMAP_PORT_x to port mapping (hardware reset value): 1920 * REMAP_PORT_0 .. REMAP_PORT_3: GXPORT3 .. GXPORT0 1921 * REMAP_PORT_4: SPORT 1922 * REMAP_PORT_5 .. REMAP_PORT_16: 12th .. 1st port of XGPORT3 1923 * REMAP_PORT_17 .. REMAP_PORT_28: 12th .. 1st port of XGPORT2 1924 * REMAP_PORT_29 .. REMAP_PORT_40: 12th .. 1st port of XGPORT1 1925 * REMAP_PORT_41 .. REMAP_PORT_52: 12th .. 1st port of XGPORT0 1926 */ 1927 if (mode[0] == 2) { 1928 /* use the last port of the block (swap the first and the last port) */ 1929 READ_CMIC_LED_PORT_ORDER_REMAP_50_54r(unit, &rval); 1930 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_50_54r, &rval, 1931 REMAP_PORT_52f, 13); 1932 WRITE_CMIC_LED_PORT_ORDER_REMAP_50_54r(unit, rval); 1933 READ_CMIC_LED_PORT_ORDER_REMAP_40_44r(unit, &rval); 1934 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_40_44r, &rval, 1935 REMAP_PORT_41f, 2); 1936 WRITE_CMIC_LED_PORT_ORDER_REMAP_40_44r(unit, rval); 1937 } 1938 if (mode[1] == 2) { 1939 /* use the last port of the block (swap the first and the last port) */ 1940 READ_CMIC_LED_PORT_ORDER_REMAP_40_44r(unit, &rval); 1941 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_40_44r, &rval, 1942 REMAP_PORT_40f, 25); 1943 WRITE_CMIC_LED_PORT_ORDER_REMAP_40_44r(unit, rval); 1944 READ_CMIC_LED_PORT_ORDER_REMAP_25_29r(unit, &rval); 1945 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_25_29r, &rval, 1946 REMAP_PORT_29f, 14); 1947 WRITE_CMIC_LED_PORT_ORDER_REMAP_25_29r(unit, rval); 1948 } 1949 if (mode[2] == 2) { 1950 /* use the last port of the block (swap the first and the last port) */ 1951 READ_CMIC_LED_PORT_ORDER_REMAP_25_29r(unit, &rval); 1952 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_25_29r, &rval, 1953 REMAP_PORT_28f, 42); 1954 WRITE_CMIC_LED_PORT_ORDER_REMAP_25_29r(unit, rval); 1955 READ_CMIC_LED_PORT_ORDER_REMAP_15_19r(unit, &rval); 1956 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_15_19r, &rval, 1957 REMAP_PORT_17f, 26); 1958 WRITE_CMIC_LED_PORT_ORDER_REMAP_15_19r(unit, rval); 1959 } 1960 if (mode[3] == 2) { 1961 READ_CMIC_LED_PORT_ORDER_REMAP_15_19r(unit, &rval); 1962 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_15_19r, &rval, 1963 REMAP_PORT_16f, 53); 1964 WRITE_CMIC_LED_PORT_ORDER_REMAP_15_19r(unit, rval); 1965 READ_CMIC_LED_PORT_ORDER_REMAP_5_9r(unit, &rval); 1966 soc_reg_field_set(unit, CMIC_LED_PORT_ORDER_REMAP_5_9r, &rval, 1967 REMAP_PORT_5f, 27); 1968 WRITE_CMIC_LED_PORT_ORDER_REMAP_5_9r(unit, rval); 1969 } 1970 1971 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 1972 /* Clear IPIPE/EIPIE Memories */ 1973 SOC_IF_ERROR_RETURN(soc_triumph_pipe_mem_clear(unit)); 1974 } 1975 1976 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 1977 1978 /* Turn on ingress/egress/mmu/esm parity */ 1979 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 1980 _soc_triumph_parity_enable(unit, TRUE); 1981 if (soc_feature(unit, soc_feature_esm_support)) { 1982 SOC_IF_ERROR_RETURN(_soc_triumph_esm_intr_enable(unit, TRUE)); 1983 } 1984 #ifdef INCLUDE_MEM_SCAN 1985 if (soc_feature(unit, soc_feature_ser_parity)) { 1986 soc_mem_scan_ser_list_register(unit, FALSE, 1987 _soc_triumph_ser_parity_info); 1988 } 1989 #endif /* INCLUDE_MEM_SCAN */ 1990 1991 memset(&_tr_ser_functions, 0, sizeof(soc_ser_functions_t)); 1992 _tr_ser_functions._soc_ser_parity_error_intr_f = 1993 &soc_triumph_parity_error; 1994 soc_ser_function_register(unit, &_tr_ser_functions); 1995 } 1996 1997 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 1998 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 1999 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2000 2001 /* Enable dual hash on L2, L3 and MPLS_ENTRY tables */ 2002 fields[0] = ENABLEf; 2003 values[0] = 1; 2004 fields[1] = HASH_SELECTf; 2005 values[1] = FB_HASH_CRC32_LOWER; 2006 fields[2] = INSERT_LEAST_FULL_HALFf; 2007 values[2] = 1; 2008 SOC_IF_ERROR_RETURN 2009 (soc_reg_fields32_modify(unit, L2_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 2010 fields, values)); 2011 SOC_IF_ERROR_RETURN 2012 (soc_reg_fields32_modify(unit, L3_AUX_HASH_CONTROLr, REG_PORT_ANY, 3, 2013 fields, values)); 2014 SOC_IF_ERROR_RETURN 2015 (soc_reg_field32_modify(unit, MPLS_ENTRY_HASH_CONTROLr, REG_PORT_ANY, 2016 INSERT_LEAST_FULL_HALFf, 1)); 2017 2018 /* 2019 * Egress Enable 2020 */ 2021 rval = 0; 2022 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1); 2023 PBMP_ALL_ITER(unit, port) { 2024 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval)); 2025 } 2026 2027 COMPILER_64_ZERO(reg64); 2028 soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, ®64, PORT_BITMAP_LOf, 2029 SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 0)); 2030 soc_reg64_field32_set(unit, EPC_LINK_BMAP_64r, ®64, PORT_BITMAP_HIf, 2031 SOC_PBMP_WORD_GET(PBMP_CMIC(unit), 1)); 2032 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAP_64r(unit, reg64)); 2033 2034 /* Clear GPORT blocks port stats */ 2035 rval = 0; 2036 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 1); 2037 PBMP_ITER(pbmp_gport_block, port) { 2038 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2039 } 2040 soc_reg_field_set(unit, GPORT_CONFIGr, &rval, CLR_CNTf, 0); 2041 PBMP_ITER(pbmp_gport_block, port) { 2042 SOC_IF_ERROR_RETURN(WRITE_GPORT_CONFIGr(unit, port, rval)); 2043 } 2044 2045 /* Drop the packet when traffic exceeds available IP bandwidth */ 2046 rval = 0; 2047 soc_reg_field_set(unit, PKT_DROP_ENABLEr, &rval, PKT_DROP_ENABLEf, 1); 2048 PBMP_ITER(pbmp_gport_block, port) { 2049 SOC_IF_ERROR_RETURN(WRITE_PKT_DROP_ENABLEr(unit, port, rval)); 2050 } 2051 2052 /* XMAC init should be moved to mac */ 2053 if (SOC_PBMP_NOT_NULL(PBMP_XE_ALL(unit)) || 2054 SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) { 2055 rval = 0; 2056 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1); 2057 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1); 2058 PBMP_HG_ITER(unit, port) { 2059 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 2060 } 2061 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 0); 2062 PBMP_XE_ITER(unit, port) { 2063 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 2064 } 2065 } 2066 2067 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 2068 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2069 L3SRC_HIT_ENABLEf, 1); 2070 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2071 L2DST_HIT_ENABLEf, 1); 2072 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2073 APPLY_EGR_MASK_ON_L2f, 1); 2074 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2075 APPLY_EGR_MASK_ON_L3f, 1); 2076 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2077 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 2078 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2079 ARP_VALIDATION_ENf, 1); 2080 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2081 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 2082 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 2083 2084 /* Backwards compatible mirroring by default */ 2085 SOC_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 2086 soc_reg_field_set(unit, MISCCONFIGr, &rval, 2087 DRACO_1_5_MIRRORING_MODE_ENf, 1); 2088 SOC_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 2089 2090 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®64)); 2091 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®64, 2092 DRACO1_5_MIRRORf, 1); 2093 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, reg64)); 2094 2095 SOC_IF_ERROR_RETURN(READ_EGR_CONFIGr(unit, &rval)); 2096 soc_reg_field_set(unit, EGR_CONFIGr, &rval, DRACO1_5_MIRRORf, 1); 2097 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIGr(unit, rval)); 2098 2099 2100 SOC_IF_ERROR_RETURN(READ_EGR_CONFIG_1r(unit, &rval)); 2101 soc_reg_field_set(unit, EGR_CONFIG_1r, &rval, RING_MODEf, 1); 2102 SOC_IF_ERROR_RETURN(WRITE_EGR_CONFIG_1r(unit, rval)); 2103 2104 /* 2105 * Set reference clock (based on 200MHz core clock) 2106 * to be 200MHz * (1/40) = 5MHz 2107 */ 2108 rval = 0; 2109 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVISORf, 40); 2110 soc_reg_field_set(unit, CMIC_RATE_ADJUSTr, &rval, DIVIDENDf, 1); 2111 /* coverity[result_independent_of_operands] */ 2112 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUSTr(unit, rval)); 2113 2114 /* Match the Internal MDC freq with above for External MDC */ 2115 rval = 0; 2116 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVISORf, 40); 2117 soc_reg_field_set (unit, CMIC_RATE_ADJUST_INT_MDIOr, &rval, DIVIDENDf, 1); 2118 /* coverity[result_independent_of_operands] */ 2119 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_INT_MDIOr(unit, rval)); 2120 2121 /* 2122 * Set reference clock (based on 200MHz core clock) 2123 * to be 200MHz * (1/8) = 25MHz 2124 */ 2125 rval = 0; 2126 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVISORf, 8); 2127 soc_reg_field_set(unit, CMIC_RATE_ADJUST_I2Cr, &rval, DIVIDENDf, 1); 2128 /* coverity[result_independent_of_operands] */ 2129 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_I2Cr(unit, rval)); 2130 2131 rval = 0; 2132 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVISORf, 8); 2133 soc_reg_field_set(unit, CMIC_RATE_ADJUST_STDMAr, &rval, DIVIDENDf, 1); 2134 /* coverity[result_independent_of_operands] */ 2135 SOC_IF_ERROR_RETURN(WRITE_CMIC_RATE_ADJUST_STDMAr(unit, rval)); 2136 2137 rval = 0x01; /* 125KHz I2C sampling rate based on 5Mhz reference clock */ 2138 /* coverity[result_independent_of_operands] */ 2139 SOC_IF_ERROR_RETURN(WRITE_CMIC_I2C_STATr(unit, rval)); 2140 2141 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 2142 * causes the outer tag to be removed from packets that don't have 2143 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 2144 */ 2145 rval = 0; 2146 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0); 2147 2148 /* Enable pri/cfi remarking on egress ports. */ 2149 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf, 2150 1); 2151 PBMP_ALL_ITER(unit, port) { 2152 SOC_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, port, rval)); 2153 } 2154 2155 /* Multicast range initialization */ 2156 SOC_IF_ERROR_RETURN 2157 (soc_hbx_higig2_mcast_sizes_set(unit, 2158 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 2159 SOC_HBX_MULTICAST_RANGE_DEFAULT), 2160 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 2161 SOC_HBX_MULTICAST_RANGE_DEFAULT), 2162 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 2163 SOC_HBX_MULTICAST_RANGE_DEFAULT))); 2164 2165 /* Enable vrf based l3 lookup by default. */ 2166 SOC_IF_ERROR_RETURN 2167 (soc_reg_field32_modify(unit, VRF_MASKr, REG_PORT_ANY, MASKf, 0)); 2168 2169 /* Setup SW2_FP_DST_ACTION_CONTROL */ 2170 fields[0] = HGTRUNK_RES_ENf; 2171 fields[1] = LAG_RES_ENf; 2172 values[0] = values[1] = 1; 2173 SOC_IF_ERROR_RETURN 2174 (soc_reg_fields32_modify(unit, SW2_FP_DST_ACTION_CONTROLr, 2175 REG_PORT_ANY, 2, fields, values)); 2176 2177 /* Use same value as CAMBIST screen test */ 2178 rval = 0; 2179 soc_reg_field_set(unit, FP_CAM_CONTROL_TM_7_THRU_0r, &rval, 2180 ALL_TCAMS_TM_7_0f, 0x10); 2181 SOC_IF_ERROR_RETURN(WRITE_FP_CAM_CONTROL_TM_7_THRU_0r(unit, rval)); 2182 rval = 0; 2183 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval, CAM0_TMf, 0x10); 2184 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL0r, &rval, CAM1_TMf, 0x10); 2185 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL0r(unit, rval)); 2186 rval = 0; 2187 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval, CAM2_TMf, 0x10); 2188 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL1r, &rval, CAM3_TMf, 0x10); 2189 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL1r(unit, rval)); 2190 rval = 0; 2191 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval, CAM4_TMf, 0x10); 2192 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL2r, &rval, CAM5_TMf, 0x10); 2193 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL2r(unit, rval)); 2194 rval = 0; 2195 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL3r, &rval, CAM6_TMf, 0x10); 2196 soc_reg_field_set(unit, L3_DEFIP_CAM_DBGCTRL3r, &rval, CAM7_TMf, 0x10); 2197 SOC_IF_ERROR_RETURN(WRITE_L3_DEFIP_CAM_DBGCTRL3r(unit, rval)); 2198 2199 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 2200 return SOC_E_NONE; 2201 } 2202 2203 int 2204 soc_triumph_esm_init_read_config(int unit) 2205 { 2206 soc_control_t *soc; 2207 soc_tcam_info_t *tcam_info; 2208 int table_size[TCAM_PARTITION_COUNT]; 2209 int tcam_freq, sram_freq, i, count; 2210 2211 soc = SOC_CONTROL(unit); 2212 2213 tcam_freq = soc_property_get(unit, spn_EXT_TCAM_FREQ, 500); 2214 sram_freq = soc_property_get(unit, spn_EXT_SRAM_FREQ, 334); 2215 if (!tcam_freq || !sram_freq) { 2216 return SOC_E_NONE; 2217 } 2218 2219 sal_memset(table_size, 0, sizeof(table_size)); 2220 2221 table_size[TCAM_PARTITION_FWD_L2] = 2222 soc_property_get(unit, spn_EXT_L2_FWD_TABLE_SIZE, 0); 2223 table_size[TCAM_PARTITION_FWD_IP4] = 2224 soc_property_get(unit, spn_EXT_IP4_FWD_TABLE_SIZE, 0); 2225 table_size[TCAM_PARTITION_FWD_IP6U] = 2226 soc_property_get(unit, spn_EXT_IP6U_FWD_TABLE_SIZE, 0); 2227 table_size[TCAM_PARTITION_FWD_IP6] = 2228 soc_property_get(unit, spn_EXT_IP6_FWD_TABLE_SIZE, 0); 2229 table_size[TCAM_PARTITION_ACL_L2] = 2230 soc_property_get(unit, spn_EXT_L2_ACL_TABLE_SIZE, 0); 2231 table_size[TCAM_PARTITION_ACL_IP4] = 2232 soc_property_get(unit, spn_EXT_IP4_ACL_TABLE_SIZE, 0); 2233 table_size[TCAM_PARTITION_ACL_IP6S] = 2234 soc_property_get(unit, spn_EXT_IP6S_ACL_TABLE_SIZE, 0); 2235 table_size[TCAM_PARTITION_ACL_IP6F] = 2236 soc_property_get(unit, spn_EXT_IP6F_ACL_TABLE_SIZE, 0); 2237 table_size[TCAM_PARTITION_ACL_L2C] = 2238 soc_property_get(unit, spn_EXT_L2C_ACL_TABLE_SIZE, 0); 2239 table_size[TCAM_PARTITION_ACL_IP4C] = 2240 soc_property_get(unit, spn_EXT_IP4C_ACL_TABLE_SIZE, 0); 2241 table_size[TCAM_PARTITION_ACL_IP6C] = 2242 soc_property_get(unit, spn_EXT_IP6C_ACL_TABLE_SIZE, 0); 2243 table_size[TCAM_PARTITION_ACL_L2IP4] = 2244 soc_property_get(unit, spn_EXT_L2IP4_ACL_TABLE_SIZE, 0); 2245 table_size[TCAM_PARTITION_ACL_L2IP6] = 2246 soc_property_get(unit, spn_EXT_L2IP6_ACL_TABLE_SIZE, 0); 2247 2248 count = 0; 2249 for (i = TCAM_PARTITION_RAW + 1; i < TCAM_PARTITION_COUNT; i++) { 2250 count += table_size[i]; 2251 } 2252 2253 /* No table is configured, done! */ 2254 if (!count) { 2255 return SOC_E_NONE; 2256 } 2257 2258 if (soc->tcam_info == NULL) { 2259 soc->tcam_info = sal_alloc(sizeof(soc_tcam_info_t), "tcam info"); 2260 if (soc->tcam_info == NULL) { 2261 return SOC_E_MEMORY; 2262 } 2263 /* Clear ESM information */ 2264 sal_memset(soc->tcam_info, 0, sizeof(soc_tcam_info_t)); 2265 } 2266 2267 tcam_info = soc->tcam_info; 2268 2269 for (i = TCAM_PARTITION_RAW + 1; i < TCAM_PARTITION_COUNT; i++) { 2270 tcam_info->partitions[i].num_entries = table_size[i]; 2271 } 2272 tcam_info->tcam_freq = tcam_freq; 2273 tcam_info->sram_freq = sram_freq; 2274 2275 return SOC_E_NONE; 2276 } 2277 2278 int 2279 soc_triumph_esm_init_set_tcam_freq(int unit, int freq) 2280 { 2281 uint32 rval, vco_rng, mdiv, ndiv_int; 2282 2283 /* freq = (NDIV_INT / MDIV) * 25 */ 2284 if (freq <= 28) { mdiv = 64; 2285 } else if (freq <= 56) { mdiv = 32; 2286 } else if (freq <= 113) { mdiv = 16; 2287 } else if (freq <= 225) { mdiv = 8; 2288 } else if (freq <= 425) { mdiv = 4; 2289 } else { mdiv = 2; } 2290 2291 if (freq * mdiv < 1600 ) { vco_rng = 0; /* 800 - 1600MHz */ 2292 } else { vco_rng = 1; } /* 1600 - 2400MHz */ 2293 2294 ndiv_int = freq * mdiv / 25; 2295 /* coverity[result_independent_of_operands] */ 2296 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_1r(unit, 2297 &rval)); 2298 soc_reg_field_set(unit, CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_1r, &rval, 2299 VCO_RNGf, vco_rng); 2300 /* coverity[result_independent_of_operands] */ 2301 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_1r(unit, 2302 rval)); 2303 /* coverity[result_independent_of_operands] */ 2304 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_2r(unit, 2305 &rval)); 2306 soc_reg_field_set(unit, CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_2r, &rval, 2307 M1DIVf, mdiv); 2308 /* coverity[result_independent_of_operands] */ 2309 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_2r(unit, 2310 rval)); 2311 /* coverity[result_independent_of_operands] */ 2312 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_3r(unit, 2313 &rval)); 2314 soc_reg_field_set(unit, CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_3r, &rval, 2315 NDIV_INTf, ndiv_int); 2316 /* coverity[result_independent_of_operands] */ 2317 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL2_CTRL_STATUS_REGISTER_3r(unit, 2318 rval)); 2319 2320 return SOC_E_NONE; 2321 } 2322 2323 int 2324 soc_triumph_esm_init_set_sram_freq(int unit, int freq) 2325 { 2326 uint32 rval, vco_rng, mdiv, ndiv_int; 2327 2328 if (soc_feature(unit, soc_feature_use_double_freq_for_ddr_pll)) { 2329 freq *= 2; 2330 } 2331 2332 /* freq = (NDIV_INT / MDIV) * 25 */ 2333 if (freq <= 28) { mdiv = 64; 2334 } else if (freq <= 56) { mdiv = 32; 2335 } else if (freq <= 113) { mdiv = 16; 2336 } else if (freq <= 225) { mdiv = 8; 2337 } else if (freq <= 425) { mdiv = 4; 2338 } else { mdiv = 2; } 2339 2340 if (freq * mdiv < 1600 ) { vco_rng = 0; /* 800 - 1600MHz */ 2341 } else { vco_rng = 1; } /* 1600 - 2400MHz */ 2342 2343 ndiv_int = freq * mdiv / 25; 2344 /* coverity[result_independent_of_operands] */ 2345 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_1r(unit, 2346 &rval)); 2347 soc_reg_field_set(unit, CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_1r, &rval, 2348 VCO_RNGf, vco_rng); 2349 /* coverity[result_independent_of_operands] */ 2350 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_1r(unit, 2351 rval)); 2352 /* coverity[result_independent_of_operands] */ 2353 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_2r(unit, 2354 &rval)); 2355 soc_reg_field_set(unit, CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_2r, &rval, 2356 M1DIVf, mdiv); 2357 /* coverity[result_independent_of_operands] */ 2358 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_2r(unit, 2359 rval)); 2360 2361 /* coverity[result_independent_of_operands] */ 2362 SOC_IF_ERROR_RETURN(READ_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_3r(unit, 2363 &rval)); 2364 soc_reg_field_set(unit, CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_3r, &rval, 2365 NDIV_INTf, ndiv_int); 2366 /* coverity[result_independent_of_operands] */ 2367 SOC_IF_ERROR_RETURN(WRITE_CMIC_CORE_PLL1_CTRL_STATUS_REGISTER_3r(unit, 2368 rval)); 2369 2370 return SOC_E_NONE; 2371 } 2372 2373 void 2374 soc_triumph_esm_init_mem_config(int unit) 2375 { 2376 soc_persist_t *sop; 2377 sop_memstate_t *memState; 2378 2379 sop = SOC_PERSIST(unit); 2380 memState = sop->memState; 2381 2382 /* L2 forwarding partition */ 2383 memState[EXT_L2_ENTRYm].index_max = -1; /* TCAM + SRAM */ 2384 memState[EXT_L2_ENTRY_TCAMm].index_max = -1; /* TCAM */ 2385 memState[EXT_L2_ENTRY_DATAm].index_max = -1; /* SRAM */ 2386 memState[EXT_SRC_HIT_BITS_L2m].index_max = -1; /* SRC hit bit */ 2387 memState[EXT_DST_HIT_BITS_L2m].index_max = -1; /* DST hit bit */ 2388 2389 /* IP4 forwarding partition */ 2390 memState[EXT_IPV4_DEFIPm].index_max = -1; /* TCAM + SRAM */ 2391 memState[EXT_IPV4_DEFIP_TCAMm].index_max = -1; /* TCAM */ 2392 memState[EXT_DEFIP_DATA_IPV4m].index_max = -1; /* SRAM */ 2393 memState[EXT_SRC_HIT_BITS_IPV4m].index_max = -1; /* SRC hit bit */ 2394 memState[EXT_DST_HIT_BITS_IPV4m].index_max = -1; /* DST hit bit */ 2395 2396 /* IP6 64-bit prefix forwarding partition */ 2397 memState[EXT_IPV6_64_DEFIPm].index_max = -1; /* TCAM + SRAM */ 2398 memState[EXT_IPV6_64_DEFIP_TCAMm].index_max = -1; /* TCAM */ 2399 memState[EXT_DEFIP_DATA_IPV6_64m].index_max = -1; /* SRAM */ 2400 memState[EXT_SRC_HIT_BITS_IPV6_64m].index_max = -1; /* SRC hit bit */ 2401 memState[EXT_DST_HIT_BITS_IPV6_64m].index_max = -1; /* DST hit bit */ 2402 2403 /* IP6 128-bit prefix forwarding partition */ 2404 memState[EXT_IPV6_128_DEFIPm].index_max = -1; /* TCAM + SRAM */ 2405 memState[EXT_IPV6_128_DEFIP_TCAMm].index_max = -1; /* TCAM */ 2406 memState[EXT_DEFIP_DATA_IPV6_128m].index_max = -1; /* SRAM */ 2407 memState[EXT_SRC_HIT_BITS_IPV6_128m].index_max = -1; /* SRC hit bit */ 2408 memState[EXT_DST_HIT_BITS_IPV6_128m].index_max = -1; /* DST hit bit */ 2409 2410 /* L2 288-bit ACL partition */ 2411 memState[EXT_ACL288_TCAM_L2m].index_max = -1; /* TCAM */ 2412 memState[EXT_FP_POLICY_ACL288_L2m].index_max = -1; /* SRAM */ 2413 memState[EXT_FP_CNTR_ACL288_L2m].index_max = -1; /* SRAM counter */ 2414 memState[EXT_FP_CNTR8_ACL288_L2m].index_max = -1; /* SRAM counter */ 2415 2416 /* IP4 288-bit ACL partition */ 2417 memState[EXT_ACL288_TCAM_IPV4m].index_max = -1; /* TCAM */ 2418 memState[EXT_FP_POLICY_ACL288_IPV4m].index_max = -1; /* SRAM */ 2419 memState[EXT_FP_CNTR_ACL288_IPV4m].index_max = -1; /* SRAM counter */ 2420 memState[EXT_FP_CNTR8_ACL288_IPV4m].index_max = -1; /* SRAM counter */ 2421 2422 /* IP6 short form 360-bit ACL partition */ 2423 memState[EXT_ACL360_TCAM_DATA_IPV6_SHORTm].index_max = -1; /* TCAM data */ 2424 memState[EXT_FP_POLICY_ACL360_IPV6_SHORTm].index_max = -1; /* SRAM */ 2425 memState[EXT_FP_CNTR_ACL360_IPV6_SHORTm].index_max = -1; /* SRAM counter */ 2426 memState[EXT_FP_CNTR8_ACL360_IPV6_SHORTm].index_max = -1; /* SRAM counter */ 2427 2428 /* IP6 full form 432-bit ACL partition */ 2429 memState[EXT_ACL432_TCAM_DATA_IPV6_LONGm].index_max = -1; /* TCAM data */ 2430 memState[EXT_FP_POLICY_ACL432_IPV6_LONGm].index_max = -1; /* SRAM */ 2431 memState[EXT_FP_CNTR_ACL432_IPV6_LONGm].index_max = -1; /* SRAM counter */ 2432 memState[EXT_FP_CNTR8_ACL432_IPV6_LONGm].index_max = -1; /* SRAM counter */ 2433 2434 /* L2 compact form 144-bit ACL partition */ 2435 memState[EXT_ACL144_TCAM_L2m].index_max = -1; /* TCAM */ 2436 memState[EXT_FP_POLICY_ACL144_L2m].index_max = -1; /* SRAM */ 2437 memState[EXT_FP_CNTR_ACL144_L2m].index_max = -1; /* SRAM counter */ 2438 memState[EXT_FP_CNTR8_ACL144_L2m].index_max = -1; /* SRAM counter */ 2439 2440 /* IP4 compact form 144-bit ACL partition */ 2441 memState[EXT_ACL144_TCAM_IPV4m].index_max = -1; /* TCAM */ 2442 memState[EXT_FP_POLICY_ACL144_IPV4m].index_max = -1; /* SRAM */ 2443 memState[EXT_FP_CNTR_ACL144_IPV4m].index_max = -1; /* SRAM counter */ 2444 memState[EXT_FP_CNTR8_ACL144_IPV4m].index_max = -1; /* SRAM counter */ 2445 2446 /* IP6 compact form 144-bit ACL partition */ 2447 memState[EXT_ACL144_TCAM_IPV6m].index_max = -1; /* TCAM */ 2448 memState[EXT_FP_POLICY_ACL144_IPV6m].index_max = -1; /* SRAM */ 2449 memState[EXT_FP_CNTR_ACL144_IPV6m].index_max = -1; /* SRAM counter */ 2450 memState[EXT_FP_CNTR8_ACL144_IPV6m].index_max = -1; /* SRAM counter */ 2451 2452 /* L2+IP4 432-bit ACL partition */ 2453 memState[EXT_ACL432_TCAM_DATA_L2_IPV4m].index_max = -1; /* TCAM data */ 2454 memState[EXT_FP_POLICY_ACL432_L2_IPV4m].index_max = -1; /* SRAM */ 2455 memState[EXT_FP_CNTR_ACL432_L2_IPV4m].index_max = -1; /* SRAM counter */ 2456 memState[EXT_FP_CNTR8_ACL432_L2_IPV4m].index_max = -1; /* SRAM counter */ 2457 2458 /* L2+IP6 432-bit ACL partition */ 2459 memState[EXT_ACL432_TCAM_DATA_L2_IPV6m].index_max = -1; /* TCAM data */ 2460 memState[EXT_FP_POLICY_ACL432_L2_IPV6m].index_max = -1; /* SRAM */ 2461 memState[EXT_FP_CNTR_ACL432_L2_IPV6m].index_max = -1; /* SRAM counter */ 2462 memState[EXT_FP_CNTR8_ACL432_L2_IPV6m].index_max = -1; /* SRAM counter */ 2463 2464 /* All L2+L3 forwarding entries */ 2465 memState[EXT_SRC_HIT_BITSm].index_max = -1; /* SRC hit bit */ 2466 memState[EXT_DST_HIT_BITSm].index_max = -1; /* DST hit bit */ 2467 2468 /* All L3 forwarding entries */ 2469 memState[EXT_DEFIP_DATAm].index_max = -1; /* SRAM */ 2470 2471 /* All 144-bit ACL entries */ 2472 memState[EXT_ACL144_TCAMm].index_max = -1; /* TCAM */ 2473 2474 /* All 288-bit ACL entries */ 2475 memState[EXT_ACL288_TCAMm].index_max = -1; /* TCAM */ 2476 2477 /* All 360-bit ACL entries */ 2478 memState[EXT_ACL360_TCAM_DATAm].index_max = -1; /* TCAM data */ 2479 2480 /* All 432-bit ACL entries */ 2481 memState[EXT_ACL432_TCAM_DATAm].index_max = -1; /* TCAM data */ 2482 2483 /* All ACL entries */ 2484 memState[EXT_FP_POLICYm].index_max = -1; /* SRAM */ 2485 memState[EXT_FP_CNTRm].index_max = -1; /* SRAM counter */ 2486 memState[EXT_FP_CNTR8m].index_max = -1; /* SRAM counter */ 2487 } 2488 2489 /* 2490 * AD_MODE: 2491 * 1: 250 MHz, l2 only, require sram0 installed 2492 * 2: 250 MHz, l2 only, require sram1 installed 2493 * 3: 250 MHz, l3 only, require sram0 installed 2494 * 4: 250 MHz, l3 only, require sram1 installed 2495 * 5: 250 MHz, no acl, require sram0 installed 2496 * 6: 250 MHz, no acl, require sram1 installed 2497 * 7: 334 MHz, acl only, require sram0 installed 2498 * 8: 334 MHz, acl only, require sram1 installed 2499 * 9: 250 MHz, acl only, require both sram installed 2500 * 10: 250 MHz, no l3, require both sram installed 2501 * 11: 250 MHz, no l2, require both sram installed 2502 * 12: 334 MHz, any table, require both sram installed 2503 */ 2504 STATIC int 2505 _soc_triumph_esm_init_select_ad_mode(int unit, int *ad_mode) 2506 { 2507 soc_tcam_info_t *tcam_info; 2508 soc_tcam_partition_t *partitions; 2509 uint32 l2_flags, l3_flags, acl_flags; 2510 int l2_entries, l3_entries, acl_entries; 2511 int cfg_ad_mode, cfg_sram_speed, cfg_sram0_present, cfg_sram1_present; 2512 2513 tcam_info = SOC_CONTROL(unit)->tcam_info; 2514 partitions = tcam_info->partitions; 2515 l2_entries = partitions[TCAM_PARTITION_FWD_L2].num_entries; 2516 l3_entries = partitions[TCAM_PARTITION_FWD_IP4].num_entries + 2517 partitions[TCAM_PARTITION_FWD_IP6U].num_entries + 2518 partitions[TCAM_PARTITION_FWD_IP6].num_entries; 2519 acl_entries = partitions[TCAM_PARTITION_ACL_L2].num_entries + 2520 partitions[TCAM_PARTITION_ACL_IP4].num_entries + 2521 partitions[TCAM_PARTITION_ACL_IP6S].num_entries + 2522 partitions[TCAM_PARTITION_ACL_IP6F].num_entries + 2523 partitions[TCAM_PARTITION_ACL_L2C].num_entries + 2524 partitions[TCAM_PARTITION_ACL_IP4C].num_entries + 2525 partitions[TCAM_PARTITION_ACL_IP6C].num_entries + 2526 partitions[TCAM_PARTITION_ACL_L2IP4].num_entries + 2527 partitions[TCAM_PARTITION_ACL_L2IP6].num_entries; 2528 2529 l2_flags = TCAM_PARTITION_FLAGS_TYPE_L2; 2530 l3_flags = TCAM_PARTITION_FLAGS_TYPE_L3; 2531 acl_flags = TCAM_PARTITION_FLAGS_TYPE_ACL; 2532 2533 cfg_ad_mode = soc_property_get(unit, spn_EXT_AD_MODE, 0); 2534 if (cfg_ad_mode < 0 || cfg_ad_mode > 12) { 2535 LOG_ERROR(BSL_LS_SOC_COMMON, 2536 (BSL_META_U(unit, 2537 "ESM init: unit %d bad %s %d\n"), 2538 unit, spn_EXT_AD_MODE, cfg_ad_mode)); 2539 return SOC_E_PARAM; 2540 } 2541 2542 /* it AD_MODE is not specified in config, figure it out from SRAM config */ 2543 if (!cfg_ad_mode) { 2544 /* 0: 250 MHz, 1: 334 Mhz, default to 334 MHz */ 2545 cfg_sram_speed = soc_property_get(unit, spn_EXT_SRAM_SPEED, 1); 2546 2547 /* default set to both ES0 and ES1 installed */ 2548 cfg_sram0_present = soc_property_get(unit, spn_EXT_SRAM0_PRESENT, 1); 2549 cfg_sram1_present = soc_property_get(unit, spn_EXT_SRAM1_PRESENT, 1); 2550 if (!cfg_sram0_present && !cfg_sram1_present) { /* no SRAM at all */ 2551 LOG_ERROR(BSL_LS_SOC_COMMON, 2552 (BSL_META_U(unit, 2553 "ESM init: unit %d both ES0 and ES1 are configured " 2554 "as not present\n"), 2555 unit)); 2556 return SOC_E_PARAM; 2557 } 2558 2559 if (cfg_sram_speed) { /* 334 Mhz DDR2+ */ 2560 if (!l2_entries && !l3_entries) { /* ACL only */ 2561 /* mode 7 ES0:ACL, mode 8 ES1:ACL */ 2562 *ad_mode = cfg_sram0_present ? 7 : 8; 2563 } else { /* any L2/L3/ACL combination */ 2564 if (cfg_sram0_present && cfg_sram1_present) { 2565 *ad_mode = 12; /* ES0:ACL, ES1:L2/L3 */ 2566 } else { 2567 LOG_ERROR(BSL_LS_SOC_COMMON, 2568 (BSL_META_U(unit, 2569 "ESM init: unit %d require both ES0 and ES1 " 2570 "in configuration\n"), 2571 unit)); 2572 return SOC_E_PARAM; 2573 } 2574 } 2575 } else { /* 250 Mhz DDR2 */ 2576 if (!acl_entries) { 2577 if (!l3_entries) { /* L2 only */ 2578 /* mode 1 ES0:L2, mode 2 ES1:L2 */ 2579 *ad_mode = cfg_sram0_present ? 1 : 2; 2580 } else if (!l2_entries) { /* L3 only */ 2581 /* mode 3 ES0:L3, mode 4 ES1:L3 */ 2582 *ad_mode = cfg_sram0_present ? 3 : 4; 2583 } else { /* L2+L3 only */ 2584 /* mode 5 ES0:L2+L3, mode 6 ES1:L2+L3 */ 2585 *ad_mode = cfg_sram0_present ? 5 : 6; 2586 } 2587 } else { 2588 if (!cfg_sram0_present || !cfg_sram1_present) { 2589 LOG_ERROR(BSL_LS_SOC_COMMON, 2590 (BSL_META_U(unit, 2591 "ESM init: unit %d require both ES0 and ES1 " 2592 "in configuration\n"), 2593 unit)); 2594 return SOC_E_PARAM; 2595 } 2596 if (!l2_entries && !l3_entries) { /* ACL only */ 2597 *ad_mode = 9; /* ES0:counter, ES1:policy */ 2598 } else { 2599 if (!l3_entries) { /* L2+ACL only */ 2600 *ad_mode = 10; /* ES0:counter/policy, ES1:L2/policy */ 2601 } else if (!l2_entries) { /* L3+ACL only */ 2602 *ad_mode = 11; /* ES0:counter/policy, ES1:L3/policy */ 2603 } else { /* can't do L2+L3+ACL */ 2604 LOG_ERROR(BSL_LS_SOC_COMMON, 2605 (BSL_META_U(unit, 2606 "ESM init: unit %d can't support L2 + L3 " 2607 "+ ACL on current sram speed %d MHz\n"), 2608 unit, 2609 cfg_sram_speed ? 334 : 250)); 2610 return SOC_E_PARAM; 2611 } 2612 } 2613 } 2614 } 2615 } else { 2616 *ad_mode = cfg_ad_mode; 2617 } 2618 2619 switch (*ad_mode) { 2620 case 1: /* ES0:L2 */ 2621 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM0; 2622 break; 2623 case 2: /* ES1:L2 */ 2624 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2625 break; 2626 case 3: /* ES0:L3 */ 2627 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM0; 2628 break; 2629 case 4: /* ES1:L3 */ 2630 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2631 break; 2632 case 5: /* ES0:L2/L3 */ 2633 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM0; 2634 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM0; 2635 break; 2636 case 6: /* ES1:L2/L3 */ 2637 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2638 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2639 break; 2640 case 7: /* ES0:ACL */ 2641 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM0 | 2642 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0); 2643 break; 2644 case 8: /* ES1:ACL */ 2645 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM1 | 2646 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM1); 2647 break; 2648 case 9: /* ES0:counter, ES1:policy */ 2649 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM1 | 2650 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0); 2651 break; 2652 case 10: /* ES0:counter/policy, ES1:L2/policy */ 2653 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2654 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM0 | 2655 TCAM_PARTITION_FLAGS_AD_IN_SRAM1 | 2656 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0); 2657 break; 2658 case 11: /* ES0:counter/policy, ES1:L3/policy */ 2659 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2660 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM0 | 2661 TCAM_PARTITION_FLAGS_AD_IN_SRAM1 | 2662 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0); 2663 break; 2664 case 12: /* ES0:ACL, ES1:L2/L3 */ 2665 l2_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2666 l3_flags |= TCAM_PARTITION_FLAGS_AD_IN_SRAM1; 2667 acl_flags |= (TCAM_PARTITION_FLAGS_AD_IN_SRAM0 | 2668 TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0); 2669 break; 2670 default: 2671 break; 2672 } 2673 2674 partitions[TCAM_PARTITION_FWD_L2].flags = l2_flags; 2675 partitions[TCAM_PARTITION_FWD_IP4].flags = l3_flags; 2676 partitions[TCAM_PARTITION_FWD_IP6U].flags = l3_flags; 2677 partitions[TCAM_PARTITION_FWD_IP6].flags = l3_flags; 2678 partitions[TCAM_PARTITION_ACL_L2].flags = acl_flags; 2679 partitions[TCAM_PARTITION_ACL_IP4].flags = acl_flags; 2680 partitions[TCAM_PARTITION_ACL_IP6S].flags = acl_flags; 2681 partitions[TCAM_PARTITION_ACL_IP6F].flags = acl_flags; 2682 partitions[TCAM_PARTITION_ACL_L2C].flags = acl_flags; 2683 partitions[TCAM_PARTITION_ACL_IP4C].flags = acl_flags; 2684 partitions[TCAM_PARTITION_ACL_IP6C].flags = acl_flags; 2685 partitions[TCAM_PARTITION_ACL_L2IP4].flags = acl_flags; 2686 partitions[TCAM_PARTITION_ACL_L2IP6].flags = acl_flags; 2687 2688 return SOC_E_NONE; 2689 } 2690 2691 STATIC int 2692 _soc_triumph_esm_init_set_sram_tuning_result(int unit, int intf_num) 2693 { 2694 soc_tcam_info_t *tcam_info; 2695 soc_reg_t reg; 2696 uint32 tune_data, addr, rval, fval; 2697 int freq; 2698 char name_str[20]; 2699 static const struct { 2700 soc_reg_t sram_ctl_reg; 2701 soc_reg_t tmode0_reg; 2702 soc_reg_t config_reg1; 2703 soc_reg_t config_reg2; 2704 soc_reg_t config_reg3; 2705 } ddr_reg[2] = { 2706 { 2707 ES0_SRAM_CTLr, 2708 ES0_DTU_LTE_TMODE0r, 2709 ES0_DDR36_CONFIG_REG1_ISr, 2710 ES0_DDR36_CONFIG_REG2_ISr, 2711 ES0_DDR36_CONFIG_REG3_ISr 2712 }, 2713 { 2714 ES1_SRAM_CTLr, 2715 ES1_DTU_LTE_TMODE0r, 2716 ES1_DDR36_CONFIG_REG1_ISr, 2717 ES1_DDR36_CONFIG_REG2_ISr, 2718 ES1_DDR36_CONFIG_REG3_ISr 2719 } 2720 }; 2721 2722 tcam_info = SOC_CONTROL(unit)->tcam_info; 2723 2724 sal_sprintf(name_str, "%s%d", spn_EXT_SRAM_TUNING, intf_num); 2725 tune_data = soc_property_get(unit, name_str, 0); 2726 if (tune_data) { 2727 freq = (tune_data >> SOC_TR_MEMTUNE_DDR_FREQ_SHIFT) & 2728 SOC_TR_MEMTUNE_DDR_FREQ_MASK; 2729 if (freq != tcam_info->sram_freq) { 2730 tune_data = 0; 2731 LOG_CLI((BSL_META_U(unit, 2732 "SRAM%d: Ignore %s, config was tuned at %d MHz, " 2733 "current frequency is %d MHz\n"), 2734 intf_num, name_str, freq, tcam_info->sram_freq)); 2735 } 2736 } 2737 2738 if (!tune_data) { 2739 /* ESx_SRAM_CTL register */ 2740 reg = ddr_reg[intf_num].sram_ctl_reg; 2741 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2742 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2743 soc_reg_field_set(unit, reg, &rval, NUM_R2W_NOPSf, 3); 2744 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2745 return SOC_E_NOT_FOUND; 2746 } 2747 2748 /* ESx_SRAM_CTL register */ 2749 reg = ddr_reg[intf_num].sram_ctl_reg; 2750 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2751 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2752 fval = (tune_data >> SOC_TR_MEMTUNE_W2R_NOPS_SHIFT) & 2753 SOC_TR_MEMTUNE_W2R_NOPS_MASK; 2754 soc_reg_field_set(unit, reg, &rval, NUM_W2R_NOPSf, fval); 2755 fval = (tune_data >> SOC_TR_MEMTUNE_R2W_NOPS_SHIFT) & 2756 SOC_TR_MEMTUNE_R2W_NOPS_MASK; 2757 if (!fval) { 2758 fval = 1; /* min r2w_nops encoding is 1, 0 means 4 nops */ 2759 } 2760 soc_reg_field_set(unit, reg, &rval, NUM_R2W_NOPSf, fval); 2761 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2762 2763 /* ESx_DTU_LTE_TMODE0 register */ 2764 reg = ddr_reg[intf_num].tmode0_reg; 2765 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2766 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2767 fval = (tune_data >> SOC_TR_MEMTUNE_EM_LATENCY_SHIFT) & 2768 SOC_TR_MEMTUNE_EM_LATENCY_MASK; 2769 soc_reg_field_set(unit, reg, &rval, EM_LATENCYf, fval); 2770 if (soc_reg_field_valid(unit, reg, EM_LATENCY8f)) { 2771 soc_reg_field_set(unit, reg, &rval, EM_LATENCY8f, fval == 0 ? 1 : 0); 2772 } 2773 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2774 2775 /* ESx_DDR36_CONFIG_REG1_IS register */ 2776 reg = ddr_reg[intf_num].config_reg1; 2777 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2778 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2779 fval = (tune_data >> SOC_TR_MEMTUNE_DDR_TX_OFFSET_SHIFT) & 2780 SOC_TR_MEMTUNE_DDR_TX_OFFSET_MASK; 2781 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_TXf, fval & 0x0f); 2782 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_TX4f, fval >> 4); 2783 fval = (tune_data >> SOC_TR_MEMTUNE_DDR_RX_OFFSET_SHIFT) & 2784 SOC_TR_MEMTUNE_DDR_RX_OFFSET_MASK; 2785 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_QKf, fval & 0xf); 2786 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_QK4f, fval >> 4); 2787 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_QKBf, fval & 0xf); 2788 soc_reg_field_set(unit, reg, &rval, DLL90_OFFSET_QKB4f, fval >> 4); 2789 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2790 2791 /* ESx_DDR36_CONFIG_REG2_IS register */ 2792 reg = ddr_reg[intf_num].config_reg2; 2793 if (soc_reg_field_valid(unit, reg, SEL_EARLY1_0f)) { 2794 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2795 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2796 fval = (tune_data >> SOC_TR_MEMTUNE_DDR_LATENCY_SHIFT) & 2797 SOC_TR_MEMTUNE_DDR_LATENCY_MASK; 2798 soc_reg_field_set(unit, reg, &rval, SEL_EARLY2_0f, fval == 0 ? 1 : 0); 2799 soc_reg_field_set(unit, reg, &rval, SEL_EARLY1_0f, fval == 1 ? 1 : 0); 2800 soc_reg_field_set(unit, reg, &rval, SEL_EARLY2_1f, fval == 0 ? 1 : 0); 2801 soc_reg_field_set(unit, reg, &rval, SEL_EARLY1_1f, fval == 1 ? 1 : 0); 2802 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2803 } 2804 2805 /* ESx_DDR36_CONFIG_REG3_IS register */ 2806 reg = ddr_reg[intf_num].config_reg3; 2807 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2808 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2809 fval = (tune_data >> SOC_TR_MEMTUNE_OVRD_SM_SHIFT) & 2810 SOC_TR_MEMTUNE_OVRD_SM_MASK; 2811 if (fval) { 2812 fval = (tune_data >> SOC_TR_MEMTUNE_PHASE_SEL_SHIFT) & 2813 SOC_TR_MEMTUNE_PHASE_SEL_MASK; 2814 soc_reg_field_set(unit, reg, &rval, PHASE_SELf, fval); 2815 soc_reg_field_set(unit, reg, &rval, OVRD_SM_ENf, 1); 2816 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2817 } 2818 2819 return SOC_E_NONE; 2820 } 2821 2822 STATIC int 2823 _soc_triumph_esm_init_set_tcam_tuning_result(int unit) 2824 { 2825 soc_tcam_info_t *tcam_info; 2826 uint32 tune_data[2], rval, fval; 2827 int freq, use_midl, cur_use_midl; 2828 char name_str[20]; 2829 2830 tcam_info = SOC_CONTROL(unit)->tcam_info; 2831 2832 sal_sprintf(name_str, "%s0", spn_EXT_TCAM_TUNING); 2833 tune_data[0] = soc_property_get(unit, name_str, 0); 2834 sal_sprintf(name_str, "%s1", spn_EXT_TCAM_TUNING); 2835 tune_data[1] = soc_property_get(unit, name_str, 0); 2836 if (tune_data[1]) { 2837 freq = (tune_data[1] >> SOC_TR_MEMTUNE_TCAM_FREQ_SHIFT) & 2838 SOC_TR_MEMTUNE_TCAM_FREQ_MASK; 2839 if (freq != tcam_info->tcam_freq) { 2840 tune_data[0] = tune_data[1] = 0; 2841 LOG_CLI((BSL_META_U(unit, 2842 "TCAM: Ignore %s0 and %s1, config was tuned at %d " 2843 "MHz, current frequency is %d MHz\n"), 2844 spn_EXT_TCAM_TUNING, spn_EXT_TCAM_TUNING, 2845 freq, tcam_info->tcam_freq)); 2846 } 2847 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG1_ISr(unit, &rval)); 2848 cur_use_midl = 2849 soc_reg_field_get(unit, ETU_DDR72_CONFIG_REG1_ISr, rval, 2850 MIDL_TX_ENf) && 2851 soc_reg_field_get(unit, ETU_DDR72_CONFIG_REG1_ISr, rval, 2852 SEL_TX_CLKDLY_BLKf) ? 1 : 0; 2853 use_midl = (tune_data[1] >> SOC_TR_MEMTUNE_USE_MIDL_SHIFT) & 2854 SOC_TR_MEMTUNE_USE_MIDL_MASK; 2855 if (use_midl != cur_use_midl) { 2856 tune_data[0] = tune_data[1] = 0; 2857 LOG_CLI((BSL_META_U(unit, 2858 "TCAM: Ignore %s0 and %s1, config was tuned using %s " 2859 "current setting is %s\n"), 2860 spn_EXT_TCAM_TUNING, spn_EXT_TCAM_TUNING, 2861 use_midl ? "MIDL" : "VCDL", 2862 cur_use_midl ? "MIDL" : "VCDL")); 2863 } 2864 } 2865 2866 if (tune_data[0]) { 2867 SOC_IF_ERROR_RETURN(READ_ETC_CTLr(unit, &rval)); 2868 fval = (tune_data[0] >> SOC_TR_MEMTUNE_RBUS_SYNC_DLY_SHIFT) & 2869 SOC_TR_MEMTUNE_RBUS_SYNC_DLY_MASK; 2870 soc_reg_field_set(unit, ETC_CTLr, &rval, RBUS_SYNC_DLYf, fval); 2871 fval = (tune_data[0] >> SOC_TR_MEMTUNE_DPEO_SYNC_DLY_SHIFT) & 2872 SOC_TR_MEMTUNE_DPEO_SYNC_DLY_MASK; 2873 soc_reg_field_set(unit, ETC_CTLr, &rval, DPEO_SYNC_DLYf, fval); 2874 SOC_IF_ERROR_RETURN(WRITE_ETC_CTLr(unit, rval)); 2875 2876 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG3_ISr(unit, &rval)); 2877 fval = (tune_data[0] >> SOC_TR_MEMTUNE_FCD_DPEO_SHIFT) & 2878 SOC_TR_MEMTUNE_FCD_DPEO_MASK; 2879 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_DPEO_0f, 2880 fval); 2881 #if 0 /* this is for 2nd device */ 2882 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_DPEO_1f, 2883 fval); 2884 #endif 2885 fval = (tune_data[0] >> SOC_TR_MEMTUNE_FCD_RBUS_SHIFT) & 2886 SOC_TR_MEMTUNE_FCD_RBUS_MASK; 2887 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_SMFL_0f, 2888 fval + 1); 2889 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_SMFL_1f, 2890 fval + 1); 2891 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_RBUSf, 2892 fval); 2893 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, FCD_RVf, 2894 fval); 2895 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG3_ISr(unit, rval)); 2896 } 2897 if (tune_data[1]) { 2898 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG1_ISr(unit, &rval)); 2899 fval = (tune_data[1] >> SOC_TR_MEMTUNE_TCAM_RX_OFFSET_SHIFT) & 2900 SOC_TR_MEMTUNE_TCAM_RX_OFFSET_MASK; 2901 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 2902 VCDL_RX_OFFSETf, fval & 0x1f); 2903 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 2904 MSBMIDL_OFFSET_RXf, fval >> 5); 2905 fval = (tune_data[1] >> SOC_TR_MEMTUNE_TCAM_TX_OFFSET_SHIFT) & 2906 SOC_TR_MEMTUNE_TCAM_TX_OFFSET_MASK; 2907 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 2908 VCDL_TX_OFFSETf, fval & 0x1f); 2909 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 2910 MSBMIDL_OFFSET_TXf, fval >> 5); 2911 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG1_ISr(unit, rval)); 2912 if (soc_reg_field_valid(unit, ETU_DDR72_CONFIG_REG3_ISr, 2913 INVERT_TXCLKf)) { 2914 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG3_ISr(unit, &rval)); 2915 fval = (tune_data[1] >> SOC_TR_MEMTUNE_INVERT_TXCLK_SHIFT) & 2916 SOC_TR_MEMTUNE_INVERT_TXCLK_MASK; 2917 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, 2918 INVERT_TXCLKf, fval & 0x1f); 2919 fval = (tune_data[1] >> SOC_TR_MEMTUNE_INVERT_RXCLK_SHIFT) & 2920 SOC_TR_MEMTUNE_INVERT_RXCLK_MASK; 2921 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, 2922 INVERT_RXCLKf, fval & 0x1f); 2923 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG3_ISr(unit, rval)); 2924 } 2925 } 2926 2927 if (!tune_data[0] || !tune_data[1]) { 2928 return SOC_E_NOT_FOUND; 2929 } 2930 return SOC_E_NONE; 2931 } 2932 2933 STATIC int 2934 _soc_triumph_esm_init_set_sram_dac(int unit, int intf_num) 2935 { 2936 soc_reg_t reg; 2937 uint32 addr, rval, fval; 2938 char name_str[20]; 2939 static const struct { 2940 soc_reg_t config_reg3; 2941 } ddr_reg[2] = { 2942 { 2943 ES0_DDR36_CONFIG_REG3_ISr 2944 }, 2945 { 2946 ES1_DDR36_CONFIG_REG3_ISr 2947 } 2948 }; 2949 2950 sal_sprintf(name_str, "sram%d_dac_value", intf_num); 2951 fval = soc_property_get(unit, name_str, 4); 2952 if (fval == -1) { 2953 return SOC_E_NOT_FOUND; 2954 } 2955 2956 reg = ddr_reg[intf_num].config_reg3; 2957 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 2958 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 2959 soc_reg_field_set(unit, reg, &rval, BIASGEN_DAC_ENf, 1); 2960 soc_reg_field_set(unit, reg, &rval, BIASGEN_DAC_CTRLf, fval); 2961 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 2962 2963 return SOC_E_NONE; 2964 } 2965 2966 STATIC int 2967 _soc_triumph_esm_init_set_tcam_dac(int unit) 2968 { 2969 uint32 rval, fval; 2970 2971 fval = soc_property_get(unit, spn_TCAM_PTR_DIST, 2); 2972 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG1_ISr(unit, &rval)); 2973 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 2974 SEL_WRFIFO_PTR_CLKf, fval); 2975 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG1_ISr(unit, rval)); 2976 2977 fval = soc_property_get(unit, spn_TCAM_DAC_VALUE, 4); 2978 if (fval == -1) { 2979 return SOC_E_NOT_FOUND; 2980 } 2981 2982 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG2_ISr(unit, &rval)); 2983 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, BIASGEN_DAC_ENf, 2984 1); 2985 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 2986 BIASGEN_DAC_CTRLf, fval); 2987 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG2_ISr(unit, rval)); 2988 2989 return SOC_E_NONE; 2990 } 2991 2992 STATIC int 2993 _soc_triumph_esm_init_check_sram_tx_status(int unit, int intf_num, 2994 int sram_dac_en) 2995 { 2996 soc_reg_t reg; 2997 uint32 addr, rval; 2998 static const struct { 2999 soc_reg_t status_reg2; 3000 } ddr_reg[2] = { 3001 { 3002 ES0_DDR36_STATUS_REG2_ISr 3003 }, 3004 { 3005 ES1_DDR36_STATUS_REG2_ISr 3006 } 3007 }; 3008 3009 if (sram_dac_en) { 3010 return SOC_E_NONE; 3011 } 3012 3013 reg = ddr_reg[intf_num].status_reg2; 3014 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3015 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3016 if (!soc_reg_field_get(unit, reg, rval, DLL_BIAS_GEN_LOCKEDf)) { 3017 return SOC_E_NOT_FOUND; 3018 } 3019 3020 return SOC_E_NONE; 3021 } 3022 3023 STATIC int 3024 _soc_triumph_esm_init_check_sram_rx_status(int unit, int intf_num) 3025 { 3026 soc_reg_t reg; 3027 uint32 addr, rval; 3028 static const struct { 3029 soc_reg_t status_reg2; 3030 } ddr_reg[2] = { 3031 { 3032 ES0_DDR36_STATUS_REG2_ISr 3033 }, 3034 { 3035 ES1_DDR36_STATUS_REG2_ISr 3036 } 3037 }; 3038 3039 reg = ddr_reg[intf_num].status_reg2; 3040 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3041 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3042 if (!soc_reg_field_get(unit, reg, rval, QK_DLLDSK_LOCKEDf) || 3043 !soc_reg_field_get(unit, reg, rval, QKB_DLLDSKW_LOCKEDf)) { 3044 return SOC_E_NOT_FOUND; 3045 } 3046 3047 return SOC_E_NONE; 3048 } 3049 3050 /* Toggle STOP_DK on SRAM interfaces */ 3051 STATIC int 3052 _soc_triumph_esm_init_stop_dk_old(int unit) 3053 { 3054 soc_reg_t reg; 3055 uint32 addr, rval; 3056 int i; 3057 static const struct { 3058 soc_reg_t config_reg1; 3059 } ddr_reg[2] = { 3060 { 3061 ES0_DDR36_CONFIG_REG1_ISr 3062 }, 3063 { 3064 ES1_DDR36_CONFIG_REG1_ISr 3065 }, 3066 }; 3067 3068 for (i = 0; i < 2; i++) { 3069 reg = ddr_reg[i].config_reg1; 3070 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3071 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3072 soc_reg_field_set(unit, reg, &rval, STOP_DKf, 1); 3073 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3074 } 3075 3076 sal_usleep(1000000); 3077 3078 for (i = 0; i < 2; i++) { 3079 reg = ddr_reg[i].config_reg1; 3080 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3081 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3082 soc_reg_field_set(unit, reg, &rval, STOP_DKf, 0); 3083 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3084 } 3085 3086 sal_usleep(1000000); 3087 3088 return SOC_E_NONE; 3089 } 3090 3091 /* Toggle STOP_DK on SRAM interface */ 3092 STATIC int 3093 _soc_triumph_esm_init_stop_dk(int unit, int intf_num) 3094 { 3095 soc_reg_t reg; 3096 uint32 addr, rval; 3097 static const struct { 3098 soc_reg_t config_reg1; 3099 } ddr_reg[2] = { 3100 { 3101 ES0_DDR36_CONFIG_REG1_ISr 3102 }, 3103 { 3104 ES1_DDR36_CONFIG_REG1_ISr 3105 } 3106 }; 3107 3108 reg = ddr_reg[intf_num].config_reg1; 3109 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3110 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3111 soc_reg_field_set(unit, reg, &rval, STOP_DKf, 1); 3112 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3113 3114 /* No delay is needed */ 3115 3116 soc_reg_field_set(unit, reg, &rval, STOP_DKf, 0); 3117 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3118 3119 /* Wait for the external SRAM to lock within 100us */ 3120 sal_usleep(100); 3121 3122 return SOC_E_NONE; 3123 } 3124 3125 /* Relock DLL on SRAM interface */ 3126 STATIC int 3127 _soc_triumph_esm_init_relock_dll_old(int unit, int intf_num) 3128 { 3129 soc_reg_t reg; 3130 uint32 addr, rval; 3131 static const struct { 3132 soc_reg_t config_reg1; 3133 soc_reg_t config_reg3; 3134 } ddr_reg[2] = { 3135 { 3136 ES0_DDR36_CONFIG_REG1_ISr, 3137 ES0_DDR36_CONFIG_REG3_ISr 3138 }, 3139 { 3140 ES1_DDR36_CONFIG_REG1_ISr, 3141 ES1_DDR36_CONFIG_REG3_ISr 3142 }, 3143 }; 3144 3145 reg = ddr_reg[intf_num].config_reg1; 3146 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3147 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3148 soc_reg_field_set(unit, reg, &rval, RELOCK_DLLf, 1); 3149 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3150 sal_usleep(100); 3151 soc_reg_field_set(unit, reg, &rval, ENABLE_DDRf, 0); 3152 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3153 sal_usleep(2000000); 3154 soc_reg_field_set(unit, reg, &rval, RELOCK_DLLf, 0); 3155 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3156 sal_usleep(100); 3157 soc_reg_field_set(unit, reg, &rval, ENABLE_DDRf, 1); 3158 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3159 sal_usleep(2000000); 3160 3161 reg = ddr_reg[intf_num].config_reg3; 3162 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3163 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3164 soc_reg_field_set(unit, reg, &rval, BIASGEN_RESETf, 1); 3165 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3166 sal_usleep(10000); 3167 soc_reg_field_set(unit, reg, &rval, BIASGEN_RESETf, 0); 3168 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3169 sal_usleep(10000); 3170 3171 return SOC_E_NONE; 3172 } 3173 3174 /* Relock DLL on SRAM interface */ 3175 STATIC int 3176 _soc_triumph_esm_init_relock_dll(int unit, int intf_num, int do_extra_delay) 3177 { 3178 soc_reg_t reg; 3179 uint32 addr, rval; 3180 static const struct { 3181 soc_reg_t config_reg1; 3182 soc_reg_t config_reg3; 3183 } ddr_reg[2] = { 3184 { 3185 ES0_DDR36_CONFIG_REG1_ISr, 3186 ES0_DDR36_CONFIG_REG3_ISr 3187 }, 3188 { 3189 ES1_DDR36_CONFIG_REG1_ISr, 3190 ES1_DDR36_CONFIG_REG3_ISr 3191 } 3192 }; 3193 3194 reg = ddr_reg[intf_num].config_reg1; 3195 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3196 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3197 soc_reg_field_set(unit, reg, &rval, ENABLE_DDRf, 0); 3198 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3199 3200 /* Reset SRAM DLL for 25us */ 3201 sal_usleep(do_extra_delay ? 1000000 : 25); 3202 3203 soc_reg_field_set(unit, reg, &rval, ENABLE_DDRf, 1); 3204 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3205 3206 /* Wait for the external SRAM to lock within 100us */ 3207 sal_usleep(do_extra_delay ? 1000000 : 100); 3208 3209 return SOC_E_NONE; 3210 } 3211 3212 STATIC int 3213 _soc_triumph_esm_init_set_pvt(int unit, int intf_num) 3214 { 3215 soc_reg_t reg; 3216 uint32 pvt_data, addr, rval, fval; 3217 char name_str[20]; 3218 static const struct { 3219 soc_reg_t config_reg2; 3220 } ddr_reg[3] = { 3221 { 3222 ES0_DDR36_CONFIG_REG2_ISr 3223 }, 3224 { 3225 ES1_DDR36_CONFIG_REG2_ISr 3226 }, 3227 { 3228 ETU_DDR72_CONFIG_REG2_ISr 3229 } 3230 }; 3231 3232 if (intf_num < 2) { 3233 sal_sprintf(name_str, "%s%d", spn_EXT_SRAM_PVT, intf_num); 3234 } else { 3235 sal_sprintf(name_str, "%s", spn_EXT_TCAM_PVT); 3236 } 3237 3238 pvt_data = soc_property_get(unit, name_str, 0); 3239 if (!pvt_data) { 3240 return SOC_E_NOT_FOUND; 3241 } 3242 3243 reg = ddr_reg[intf_num].config_reg2; 3244 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3245 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3246 if ((pvt_data >> SOC_TR_MEMTUNE_OVRD_ODTRES_SHIFT) & 3247 SOC_TR_MEMTUNE_OVRD_ODTRES_MASK) { 3248 fval = (pvt_data >> SOC_TR_MEMTUNE_ODTRES_SHIFT) & 3249 SOC_TR_MEMTUNE_ODTRES_MASK; 3250 soc_reg_field_set(unit, reg, &rval, PVT_ODTRES_VALf, fval); 3251 soc_reg_field_set(unit, reg, &rval, OVRD_EN_ODTRES_PVTf, 1); 3252 } 3253 if ((pvt_data >> SOC_TR_MEMTUNE_OVRD_DRIVER_SHIFT) & 3254 SOC_TR_MEMTUNE_OVRD_DRIVER_MASK) { 3255 fval = (pvt_data >> SOC_TR_MEMTUNE_PDRIVE_SHIFT) & 3256 SOC_TR_MEMTUNE_PDRIVE_MASK; 3257 soc_reg_field_set(unit, reg, &rval, PVT_PDRIVE_VALf, fval); 3258 fval = (pvt_data >> SOC_TR_MEMTUNE_NDRIVE_SHIFT) & 3259 SOC_TR_MEMTUNE_NDRIVE_MASK; 3260 soc_reg_field_set(unit, reg, &rval, PVT_NDRIVE_VALf, fval); 3261 soc_reg_field_set(unit, reg, &rval, OVRD_EN_DRIVER_PVTf, 1); 3262 } 3263 if ((pvt_data >> SOC_TR_MEMTUNE_OVRD_SLEW_SHIFT) & 3264 SOC_TR_MEMTUNE_OVRD_SLEW_MASK) { 3265 fval = (pvt_data >> SOC_TR_MEMTUNE_SLEW_SHIFT) & 3266 SOC_TR_MEMTUNE_SLEW_MASK; 3267 soc_reg_field_set(unit, reg, &rval, PVT_SLEW_VALf, fval); 3268 soc_reg_field_set(unit, reg, &rval, OVRD_EN_SLEW_PVTf, 1); 3269 } 3270 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3271 3272 return SOC_E_NONE; 3273 } 3274 3275 int 3276 soc_triumph_esm_init_pvt_comp(int unit, int intf_num) 3277 { 3278 uint16 dev_id; 3279 uint8 rev_id; 3280 soc_reg_t reg, status_reg; 3281 uint32 addr, status_addr, rval; 3282 uint32 odt, slew, pdrive, ndrive; 3283 static const struct { 3284 char *intf_name; 3285 soc_reg_t config_reg2; 3286 soc_reg_t status_reg1; 3287 soc_reg_t status_reg2; 3288 } ddr_reg[3] = { 3289 { 3290 "SRAM0", 3291 ES0_DDR36_CONFIG_REG2_ISr, 3292 ES0_DDR36_STATUS_REG1_ISr, 3293 ES0_DDR36_STATUS_REG2_ISr 3294 }, 3295 { 3296 "SRAM1", 3297 ES1_DDR36_CONFIG_REG2_ISr, 3298 ES1_DDR36_STATUS_REG1_ISr, 3299 ES1_DDR36_STATUS_REG2_ISr 3300 }, 3301 { 3302 "TCAM", 3303 ETU_DDR72_CONFIG_REG2_ISr, 3304 ETU_DDR72_STATUS_REG1_ISr, 3305 ETU_DDR72_STATUS_REG2_ISr 3306 } 3307 }; 3308 3309 soc_cm_get_id(unit, &dev_id, &rev_id); 3310 3311 /* ES0 has its own PVT pads, ES1 and TCAM share the same PVT pads */ 3312 if (intf_num != 0) { 3313 /* Disable "the other" PVT cell */ 3314 reg = ddr_reg[3 - intf_num].config_reg2; 3315 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3316 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3317 soc_reg_field_set(unit, reg, &rval, PVT_COMP_PAD_ENf, 0); 3318 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3319 3320 /* Enable the "target" PVT cell */ 3321 reg = ddr_reg[intf_num].config_reg2; 3322 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3323 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3324 soc_reg_field_set(unit, reg, &rval, PVT_COMP_PAD_ENf, 1); 3325 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3326 } 3327 3328 reg = ddr_reg[intf_num].config_reg2; 3329 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3330 3331 /* Override ODT vaue */ 3332 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3333 soc_reg_field_set(unit, reg, &rval, PVT_ODTRES_VALf, 8); 3334 soc_reg_field_set(unit, reg, &rval, OVRD_EN_ODTRES_PVTf, 1); 3335 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3336 3337 soc_reg_field_set(unit, reg, &rval, OVRD_EN_ODTRES_PVTf, 0); 3338 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3339 3340 /* Override pdrive, ndrive value */ 3341 soc_reg_field_set(unit, reg, &rval, PVT_PDRIVE_VALf, 8); 3342 soc_reg_field_set(unit, reg, &rval, PVT_NDRIVE_VALf, 8); 3343 soc_reg_field_set(unit, reg, &rval, OVRD_EN_DRIVER_PVTf, 1); 3344 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3345 3346 soc_reg_field_set(unit, reg, &rval, OVRD_EN_DRIVER_PVTf, 0); 3347 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3348 3349 sal_usleep(1000); 3350 3351 /* Get PVT status */ 3352 status_reg = ddr_reg[intf_num].status_reg2; 3353 status_addr = soc_reg_addr(unit, status_reg, REG_PORT_ANY, 0); 3354 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, status_addr, &rval)); 3355 odt = soc_reg_field_get(unit, status_reg, rval, PVT_ODT_VALf); 3356 slew = soc_reg_field_get(unit, status_reg, rval, PVT_SLEW_VALf); 3357 ndrive = soc_reg_field_get(unit, status_reg, rval, PVT_NDRIVE_VALf); 3358 pdrive = soc_reg_field_get(unit, status_reg, rval, PVT_PDRIVE_VALf); 3359 3360 status_reg = ddr_reg[intf_num].status_reg1; 3361 status_addr = soc_reg_addr(unit, status_reg, REG_PORT_ANY, 0); 3362 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, status_addr, &rval)); 3363 3364 /* Check ODT PVT status and auto value */ 3365 if (!soc_reg_field_get(unit, status_reg, rval, ODT_PVT_DONEf) && 3366 odt != 0 && odt != 0xf) { 3367 LOG_CLI((BSL_META_U(unit, 3368 "%s ODT PVT compensation fail\n"), 3369 ddr_reg[intf_num].intf_name)); 3370 } 3371 3372 /* Check NDRIVE PVT status and auto value */ 3373 if (!soc_reg_field_get(unit, status_reg, rval, NDRIVER_PVT_DONEf) && 3374 ndrive != 0 && ndrive != 0xf) { 3375 LOG_CLI((BSL_META_U(unit, 3376 "%s NDRIVE PVT compensation fail\n"), 3377 ddr_reg[intf_num].intf_name)); 3378 } 3379 3380 /* Check PDRIVE PVT status and auto value */ 3381 if (!soc_reg_field_get(unit, status_reg, rval, PDRIVER_PVT_DONEf) && 3382 pdrive != 0 && pdrive != 0xf) { 3383 LOG_CLI((BSL_META_U(unit, 3384 "%s PDRIVE PVT compensation fail\n"), 3385 ddr_reg[intf_num].intf_name)); 3386 } 3387 3388 /* Override ODT vaue */ 3389 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3390 soc_reg_field_set(unit, reg, &rval, PVT_ODTRES_VALf, odt); 3391 soc_reg_field_set(unit, reg, &rval, OVRD_EN_ODTRES_PVTf, 1); 3392 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3393 3394 /* Override pdrive, ndrive value */ 3395 soc_reg_field_set(unit, reg, &rval, PVT_PDRIVE_VALf, pdrive); 3396 soc_reg_field_set(unit, reg, &rval, PVT_NDRIVE_VALf, ndrive); 3397 soc_reg_field_set(unit, reg, &rval, OVRD_EN_DRIVER_PVTf, 1); 3398 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3399 3400 /* override slew value */ 3401 if ((SOC_IS_TRIUMPH(unit) && rev_id >= BCM56624_B2_REV_ID) || 3402 (SOC_IS_TRIUMPH2(unit) && rev_id >= BCM56634_B0_REV_ID)) { 3403 if (slew < 4) { 3404 slew = 4; 3405 } 3406 } 3407 soc_reg_field_set(unit, reg, &rval, PVT_SLEW_VALf, slew); 3408 soc_reg_field_set(unit, reg, &rval, OVRD_EN_SLEW_PVTf, 1); 3409 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3410 3411 if (reg != ES0_DDR36_CONFIG_REG2_ISr) { 3412 /* Enable PVT cell */ 3413 SOC_IF_ERROR_RETURN(READ_ES1_DDR36_CONFIG_REG2_ISr(unit, &rval)); 3414 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 3415 PVT_COMP_PAD_ENf, 1); 3416 SOC_IF_ERROR_RETURN(WRITE_ES1_DDR36_CONFIG_REG2_ISr(unit, rval)); 3417 3418 /* Enable TCAM PVT cell */ 3419 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG2_ISr(unit, &rval)); 3420 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 3421 PVT_COMP_PAD_ENf, 1); 3422 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG2_ISr(unit, rval)); 3423 } 3424 3425 return SOC_E_NONE; 3426 } 3427 3428 /* Perform mini-tuning to find latency value */ 3429 STATIC int 3430 _soc_triumph_esm_init_retune_sram(int unit, int intf_num) 3431 { 3432 soc_memtune_data_t mt_data; 3433 soc_reg_t reg; 3434 uint32 tune_data, addr, rval; 3435 char name_str[20]; 3436 static const struct { 3437 soc_reg_t tmode1_reg; 3438 soc_reg_t config_reg1; 3439 } ddr_reg[2] = { 3440 { 3441 ES0_DTU_LTE_TMODE1r, 3442 ES0_DDR36_CONFIG_REG1_ISr 3443 }, 3444 { 3445 ES1_DTU_LTE_TMODE1r, 3446 ES1_DDR36_CONFIG_REG1_ISr 3447 } 3448 }; 3449 3450 if (!soc_feature(unit, soc_feature_esm_rxfifo_resync) || 3451 SOC_WARM_BOOT(unit)) { 3452 /* No need to retune SRAM interface */ 3453 return SOC_E_NONE; 3454 } 3455 3456 sal_sprintf(name_str, "%s%d", spn_EXT_SRAM_TUNING, intf_num); 3457 tune_data = soc_property_get(unit, name_str, 0); 3458 if (!tune_data) { 3459 /* Can not find TX/RX value from tuning result for mini-tuning */ 3460 return SOC_E_NONE; 3461 } 3462 3463 reg = ddr_reg[intf_num].config_reg1; 3464 SOC_IF_ERROR_RETURN 3465 (soc_reg_field32_modify(unit, reg, REG_PORT_ANY, EN_RDFIFOf, 0)); 3466 3467 sal_usleep(1000); 3468 3469 SOC_IF_ERROR_RETURN 3470 (soc_reg_field32_modify(unit, reg, REG_PORT_ANY, EN_RDFIFOf, 1)); 3471 3472 reg = ddr_reg[intf_num].tmode1_reg; 3473 addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 3474 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &rval)); 3475 soc_reg_field_set(unit, reg, &rval, WDOEBFf, 0); 3476 soc_reg_field_set(unit, reg, &rval, WDOEBRf, 0); 3477 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, rval)); 3478 3479 sal_memset(&mt_data, 0, sizeof(mt_data)); 3480 mt_data.interface = SOC_MEM_INTERFACE_SRAM; 3481 mt_data.sub_interface = intf_num; 3482 mt_data.slice_mask = SOC_TR_SRAM_SLICE_MASK; 3483 mt_data.config = TRUE; 3484 mt_data.freq = -1; 3485 mt_data.test_count = 10; 3486 mt_data.do_txrx_first = TRUE; 3487 mt_data.d0r_0 = 0xffffffff; 3488 mt_data.adr0 = -1; 3489 mt_data.adr1 = -1; 3490 mt_data.adr_mode = -1; 3491 mt_data.man_em_latency = -1; 3492 mt_data.man_ddr_latency = -1; 3493 mt_data.man_tx_offset = 3494 (tune_data >> SOC_TR_MEMTUNE_DDR_TX_OFFSET_SHIFT) & 3495 SOC_TR_MEMTUNE_DDR_TX_OFFSET_MASK; 3496 mt_data.man_rx_offset = 3497 (tune_data >> SOC_TR_MEMTUNE_DDR_RX_OFFSET_SHIFT) & 3498 SOC_TR_MEMTUNE_DDR_RX_OFFSET_MASK; 3499 3500 if (SOC_FAILURE(soc_mem_interface_tune(unit, &mt_data))) { 3501 return SOC_E_NONE; /* return OK, expect to have manual re-tune */ 3502 } 3503 3504 return SOC_E_NONE; 3505 } 3506 3507 /* Perform mini-tuning to stabilize TCAM interface */ 3508 STATIC int 3509 _soc_triumph_esm_init_retune_tcam(int unit) 3510 { 3511 soc_memtune_data_t mt_data; 3512 uint32 tune_data; 3513 char name_str[20]; 3514 3515 sal_sprintf(name_str, "%s1", spn_EXT_TCAM_TUNING); 3516 tune_data = soc_property_get(unit, name_str, 0); 3517 if (!tune_data) { 3518 /* Can not find TX/RX value from tuning result for mini-tuning */ 3519 return SOC_E_NONE; 3520 } 3521 3522 sal_memset(&mt_data, 0, sizeof(mt_data)); 3523 mt_data.interface = SOC_MEM_INTERFACE_TCAM; 3524 mt_data.config = TRUE; 3525 mt_data.freq = -1; 3526 mt_data.test_count = 10; 3527 mt_data.mask[0] = 0xffffffff; 3528 mt_data.tcam_loop_count = 100; 3529 mt_data.man_tx_offset = 3530 (tune_data >> SOC_TR_MEMTUNE_TCAM_TX_OFFSET_SHIFT) & 3531 SOC_TR_MEMTUNE_TCAM_TX_OFFSET_MASK; 3532 mt_data.man_rx_offset = 3533 (tune_data >> SOC_TR_MEMTUNE_TCAM_RX_OFFSET_SHIFT) & 3534 SOC_TR_MEMTUNE_TCAM_RX_OFFSET_MASK; 3535 3536 if (SOC_FAILURE(soc_mem_interface_tune(unit, &mt_data))) { 3537 return SOC_E_NONE; /* return OK, expect to have manual re-tune */ 3538 } 3539 /* TCAM tuning may raise interrupt, report and clear it */ 3540 if (SOC_IS_TRIUMPH(unit)) { 3541 _soc_triumph_esm_process_intr_status(unit); 3542 } 3543 #ifdef BCM_TRIUMPH2_SUPPORT 3544 else if (SOC_IS_TRIUMPH2(unit)) { 3545 _soc_triumph2_esm_process_intr_status(unit); 3546 } 3547 #endif /* BCM_TRIUMPH2_SUPPORT */ 3548 3549 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_read_config(unit)); 3550 3551 SOC_IF_ERROR_RETURN(soc_tcam_init(unit)); 3552 3553 return SOC_E_NONE; 3554 } 3555 3556 /* Program tcam index to sram index translation table */ 3557 STATIC int 3558 _soc_triumph_esm_init_set_et_pa_xlate(int unit) 3559 { 3560 soc_tcam_info_t *tcam_info; 3561 soc_tcam_partition_t *partitions; 3562 et_pa_xlat_entry_t xlat_entry; 3563 int sram0_base, sram1_base, counter_base, hbit_base; 3564 int part, index, end, entries_per_block; 3565 int has_counter, has_hbit; 3566 uint32 flags; 3567 3568 tcam_info = SOC_CONTROL(unit)->tcam_info; 3569 if (tcam_info == NULL) { 3570 return SOC_E_INIT; 3571 } 3572 partitions = tcam_info->partitions; 3573 3574 sram0_base = 0; 3575 sram1_base = 0; 3576 counter_base = 0; 3577 hbit_base = 0; 3578 3579 /* upper layer software requires all counters to be continguous */ 3580 for (part = TCAM_PARTITION_RAW + 1; part < TCAM_PARTITION_COUNT; part++) { 3581 if (!partitions[part].num_entries) { 3582 continue; 3583 } 3584 flags = partitions[part].flags; 3585 if (flags & TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM0) { 3586 sram0_base += partitions[part].num_entries_include_pad * 2; 3587 } else if (flags & TCAM_PARTITION_FLAGS_COUNTER_IN_SRAM1) { 3588 sram1_base += partitions[part].num_entries_include_pad * 2; 3589 } 3590 } 3591 3592 index = 0; 3593 for (part = TCAM_PARTITION_RAW + 1; part < TCAM_PARTITION_COUNT; part++) { 3594 if (!partitions[part].num_entries) { 3595 continue; 3596 } 3597 3598 has_hbit = FALSE; 3599 has_counter = FALSE; 3600 flags = partitions[part].flags; 3601 switch (flags & TCAM_PARTITION_FLAGS_TYPE_MASK) { 3602 case TCAM_PARTITION_FLAGS_TYPE_L2: 3603 partitions[part].sram_width_shift = 1; 3604 has_hbit = TRUE; 3605 break; 3606 case TCAM_PARTITION_FLAGS_TYPE_L3: 3607 partitions[part].sram_width_shift = 0; 3608 has_hbit = TRUE; 3609 break; 3610 case TCAM_PARTITION_FLAGS_TYPE_ACL: 3611 if (flags & TCAM_PARTITION_FLAGS_AD_IN_SRAM0 && 3612 flags & TCAM_PARTITION_FLAGS_AD_IN_SRAM1) { 3613 partitions[part].sram_width_shift = 1; 3614 if (sram0_base > sram1_base) { 3615 sram1_base = sram0_base; /* align both, waste some space */ 3616 } else { 3617 sram0_base = sram1_base; /* align both, waste some sapce */ 3618 } 3619 } else { 3620 partitions[part].sram_width_shift = 2; 3621 } 3622 has_counter = TRUE; 3623 break; 3624 default: 3625 continue; 3626 } 3627 3628 partitions[part].sram_base = flags & TCAM_PARTITION_FLAGS_AD_IN_SRAM0 ? 3629 sram0_base : sram1_base; 3630 partitions[part].counter_base = has_counter ? counter_base : -1; 3631 partitions[part].hbit_base = has_hbit ? hbit_base : -1; 3632 3633 sal_memset(&xlat_entry, 0, sizeof(xlat_entry)); 3634 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, ES_WIDTHf, 3635 partitions[part].sram_width_shift); 3636 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, ET_WIDTHf, 3637 partitions[part].tcam_width_shift); 3638 if (has_hbit) { 3639 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, HBIT_ENf, 1); 3640 } 3641 if (part == TCAM_PARTITION_FWD_L2) { 3642 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, PPA_ENf, 1); 3643 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, AGE_ENf, 1); 3644 } 3645 3646 index = partitions[part].tcam_base >> 14; 3647 end = index + (((partitions[part].num_entries - 1) << 3648 partitions[part].tcam_width_shift) >> 14); 3649 for (; index <= end; index++) { 3650 entries_per_block = (1 << 14) >> partitions[part].tcam_width_shift; 3651 if (has_counter) { 3652 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, 3653 ES_CNTR_PA_BASEf, counter_base >> 10); 3654 counter_base += entries_per_block * 2; 3655 } 3656 if (has_hbit) { 3657 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, 3658 HBIT_PA_BASEf, hbit_base >> 11); 3659 hbit_base += entries_per_block; 3660 } 3661 if (flags & TCAM_PARTITION_FLAGS_AD_IN_SRAM0) { 3662 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, 3663 ES_PA_BASEf, sram0_base >> 10); 3664 sram0_base += 3665 entries_per_block << partitions[part].sram_width_shift; 3666 } 3667 if (flags & TCAM_PARTITION_FLAGS_AD_IN_SRAM1) { 3668 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, 3669 ES_PA_BASEf, sram1_base >> 10); 3670 sram1_base += 3671 entries_per_block << partitions[part].sram_width_shift; 3672 } 3673 3674 SOC_IF_ERROR_RETURN(WRITE_ET_PA_XLATm(unit, SOC_BLOCK_ALL, index, 3675 &xlat_entry)); 3676 } 3677 } 3678 sal_memset(&xlat_entry, 0, sizeof(xlat_entry)); 3679 soc_mem_field32_set(unit, ET_PA_XLATm, &xlat_entry, ES_WIDTHf, 3); 3680 end = soc_mem_index_max(unit, ET_PA_XLATm); 3681 for (; index <= end; index++) { 3682 SOC_IF_ERROR_RETURN(WRITE_ET_PA_XLATm(unit, SOC_BLOCK_ALL, index, 3683 &xlat_entry)); 3684 } 3685 3686 return SOC_E_NONE; 3687 } 3688 3689 /* Program software memory state according to table size in user config */ 3690 STATIC int 3691 _soc_triumph_esm_init_adjust_mem_size(int unit) 3692 { 3693 soc_persist_t *sop; 3694 sop_memstate_t *memState; 3695 soc_tcam_info_t *tcam_info; 3696 soc_tcam_partition_t *partitions; 3697 uint16 value = 0; 3698 3699 sop = SOC_PERSIST(unit); 3700 memState = sop->memState; 3701 tcam_info = SOC_CONTROL(unit)->tcam_info; 3702 partitions = tcam_info->partitions; 3703 3704 /* L2 forwarding partition */ 3705 memState[EXT_L2_ENTRYm].index_max = /* TCAM + SRAM */ 3706 memState[EXT_L2_ENTRY_TCAMm].index_max = /* TCAM */ 3707 memState[EXT_L2_ENTRY_DATAm].index_max = /* SRAM */ 3708 partitions[TCAM_PARTITION_FWD_L2].num_entries - 1; 3709 memState[EXT_SRC_HIT_BITS_L2m].index_max = /* SRC hit bit */ 3710 memState[EXT_DST_HIT_BITS_L2m].index_max = /* DST hit bit */ 3711 (partitions[TCAM_PARTITION_FWD_L2].num_entries + 31) / 32 - 1; 3712 3713 /* IP4 forwarding partition */ 3714 memState[EXT_IPV4_DEFIPm].index_max = /* TCAM + SRAM */ 3715 memState[EXT_IPV4_DEFIP_TCAMm].index_max = /* TCAM */ 3716 memState[EXT_DEFIP_DATA_IPV4m].index_max = /* SRAM */ 3717 partitions[TCAM_PARTITION_FWD_IP4].num_entries - 1; 3718 memState[EXT_SRC_HIT_BITS_IPV4m].index_max = /* SRC hit bit */ 3719 memState[EXT_DST_HIT_BITS_IPV4m].index_max = /* DST hit bit */ 3720 (partitions[TCAM_PARTITION_FWD_IP4].num_entries + 31) / 32 - 1; 3721 3722 /* IP6 64-bit prefix forwarding partition */ 3723 memState[EXT_IPV6_64_DEFIPm].index_max = /* TCAM + SRAM */ 3724 memState[EXT_IPV6_64_DEFIP_TCAMm].index_max = /* TCAM */ 3725 memState[EXT_DEFIP_DATA_IPV6_64m].index_max = /* SRAM */ 3726 partitions[TCAM_PARTITION_FWD_IP6U].num_entries - 1; 3727 memState[EXT_SRC_HIT_BITS_IPV6_64m].index_max = /* SRC hit bit */ 3728 memState[EXT_DST_HIT_BITS_IPV6_64m].index_max = /* DST hit bit */ 3729 (partitions[TCAM_PARTITION_FWD_IP6U].num_entries + 31) / 32 - 1; 3730 3731 /* IP6 128-bit prefix forwarding partition */ 3732 memState[EXT_IPV6_128_DEFIPm].index_max = /* TCAM + SRAM */ 3733 memState[EXT_IPV6_128_DEFIP_TCAMm].index_max = /* TCAM */ 3734 memState[EXT_DEFIP_DATA_IPV6_128m].index_max = /* SRAM */ 3735 partitions[TCAM_PARTITION_FWD_IP6].num_entries - 1; 3736 memState[EXT_SRC_HIT_BITS_IPV6_128m].index_max = /* SRC hit bit */ 3737 memState[EXT_DST_HIT_BITS_IPV6_128m].index_max = /* DST hit bit */ 3738 (partitions[TCAM_PARTITION_FWD_IP6].num_entries + 31) / 32 - 1; 3739 3740 /* L2 288-bit ACL partition */ 3741 memState[EXT_ACL288_TCAM_L2m].index_max = /* TCAM */ 3742 memState[EXT_FP_POLICY_ACL288_L2m].index_max = /* SRAM */ 3743 memState[EXT_FP_CNTR_ACL288_L2m].index_max = /* SRAM counter */ 3744 partitions[TCAM_PARTITION_ACL_L2].num_entries - 1; 3745 memState[EXT_FP_CNTR8_ACL288_L2m].index_max = /* SRAM counter */ 3746 (partitions[TCAM_PARTITION_ACL_L2].num_entries + 7) / 8 - 1; 3747 3748 /* IP4 288-bit ACL partition */ 3749 memState[EXT_ACL288_TCAM_IPV4m].index_max = /* TCAM */ 3750 memState[EXT_FP_POLICY_ACL288_IPV4m].index_max = /* SRAM */ 3751 memState[EXT_FP_CNTR_ACL288_IPV4m].index_max = /* SRAM counter */ 3752 partitions[TCAM_PARTITION_ACL_IP4].num_entries - 1; 3753 memState[EXT_FP_CNTR8_ACL288_IPV4m].index_max = /* SRAM counter */ 3754 (partitions[TCAM_PARTITION_ACL_IP4].num_entries + 7) / 8 - 1; 3755 3756 /* IP6 short form 360-bit ACL partition */ 3757 memState[EXT_ACL360_TCAM_DATA_IPV6_SHORTm].index_max = /* TCAM data */ 3758 memState[EXT_FP_POLICY_ACL360_IPV6_SHORTm].index_max = /* SRAM */ 3759 memState[EXT_FP_CNTR_ACL360_IPV6_SHORTm].index_max = /* SRAM counter */ 3760 partitions[TCAM_PARTITION_ACL_IP6S].num_entries - 1; 3761 memState[EXT_FP_CNTR8_ACL360_IPV6_SHORTm].index_max = /* SRAM counter */ 3762 (partitions[TCAM_PARTITION_ACL_IP6S].num_entries + 7) / 8 - 1; 3763 3764 /* IP6 full form 432-bit ACL partition */ 3765 memState[EXT_ACL432_TCAM_DATA_IPV6_LONGm].index_max = /* TCAM data */ 3766 memState[EXT_FP_POLICY_ACL432_IPV6_LONGm].index_max = /* SRAM */ 3767 memState[EXT_FP_CNTR_ACL432_IPV6_LONGm].index_max = /* SRAM counter */ 3768 partitions[TCAM_PARTITION_ACL_IP6F].num_entries - 1; 3769 memState[EXT_FP_CNTR8_ACL432_IPV6_LONGm].index_max = /* SRAM counter */ 3770 (partitions[TCAM_PARTITION_ACL_IP6F].num_entries + 7) / 8 - 1; 3771 3772 /* L2 compact form 144-bit ACL partition */ 3773 memState[EXT_ACL144_TCAM_L2m].index_max = /* TCAM */ 3774 memState[EXT_FP_POLICY_ACL144_L2m].index_max = /* SRAM */ 3775 memState[EXT_FP_CNTR_ACL144_L2m].index_max = /* SRAM counter */ 3776 partitions[TCAM_PARTITION_ACL_L2C].num_entries - 1; 3777 memState[EXT_FP_CNTR8_ACL144_L2m].index_max = /* SRAM counter */ 3778 (partitions[TCAM_PARTITION_ACL_L2C].num_entries + 7) / 8 - 1; 3779 3780 /* IP4 compact form 144-bit ACL partition */ 3781 memState[EXT_ACL144_TCAM_IPV4m].index_max = /* TCAM */ 3782 memState[EXT_FP_POLICY_ACL144_IPV4m].index_max = /* SRAM */ 3783 memState[EXT_FP_CNTR_ACL144_IPV4m].index_max = /* SRAM counter */ 3784 partitions[TCAM_PARTITION_ACL_IP4C].num_entries - 1; 3785 memState[EXT_FP_CNTR8_ACL144_IPV4m].index_max = /* SRAM counter */ 3786 (partitions[TCAM_PARTITION_ACL_IP4C].num_entries + 7) / 8 - 1; 3787 3788 /* IP6 compact form 144-bit ACL partition */ 3789 memState[EXT_ACL144_TCAM_IPV6m].index_max = /* TCAM */ 3790 memState[EXT_FP_POLICY_ACL144_IPV6m].index_max = /* SRAM */ 3791 memState[EXT_FP_CNTR_ACL144_IPV6m].index_max = /* SRAM counter */ 3792 partitions[TCAM_PARTITION_ACL_IP6C].num_entries - 1; 3793 memState[EXT_FP_CNTR8_ACL144_IPV6m].index_max = /* SRAM counter */ 3794 (partitions[TCAM_PARTITION_ACL_IP6C].num_entries + 7) / 8 - 1; 3795 3796 /* L2+IP4 432-bit ACL partition */ 3797 memState[EXT_ACL432_TCAM_DATA_L2_IPV4m].index_max = /* TCAM data */ 3798 memState[EXT_FP_POLICY_ACL432_L2_IPV4m].index_max = /* SRAM */ 3799 memState[EXT_FP_CNTR_ACL432_L2_IPV4m].index_max = /* SRAM counter */ 3800 partitions[TCAM_PARTITION_ACL_L2IP4].num_entries - 1; 3801 memState[EXT_FP_CNTR8_ACL432_L2_IPV4m].index_max = /* SRAM counter */ 3802 (partitions[TCAM_PARTITION_ACL_L2IP4].num_entries + 7) / 8 - 1; 3803 3804 /* L2+IP6 432-bit ACL partition */ 3805 memState[EXT_ACL432_TCAM_DATA_L2_IPV6m].index_max = /* TCAM data */ 3806 memState[EXT_FP_POLICY_ACL432_L2_IPV6m].index_max = /* SRAM */ 3807 memState[EXT_FP_CNTR_ACL432_L2_IPV6m].index_max = /* SRAM counter */ 3808 partitions[TCAM_PARTITION_ACL_L2IP6].num_entries - 1; 3809 memState[EXT_FP_CNTR8_ACL432_L2_IPV6m].index_max = /* SRAM counter */ 3810 (partitions[TCAM_PARTITION_ACL_L2IP6].num_entries + 7) / 8 - 1; 3811 3812 /* All L2+L3 forwarding entries */ 3813 memState[EXT_SRC_HIT_BITSm].index_max = /* SRC hit bit */ 3814 memState[EXT_DST_HIT_BITSm].index_max = /* DST hit bit */ 3815 (partitions[TCAM_PARTITION_FWD_L2].num_entries + 31) / 32 + 3816 (partitions[TCAM_PARTITION_FWD_IP4].num_entries + 31) / 32 + 3817 (partitions[TCAM_PARTITION_FWD_IP6U].num_entries + 31) / 32 + 3818 (partitions[TCAM_PARTITION_FWD_IP6].num_entries + 31) / 32 - 1; 3819 3820 /* All L3 forwarding entries */ 3821 memState[EXT_DEFIP_DATAm].index_max = /* SRAM */ 3822 partitions[TCAM_PARTITION_FWD_IP4].num_entries + 3823 partitions[TCAM_PARTITION_FWD_IP6U].num_entries + 3824 partitions[TCAM_PARTITION_FWD_IP6].num_entries - 1; 3825 3826 /* All 144-bit ACL entries */ 3827 memState[EXT_ACL144_TCAMm].index_max = /* TCAM */ 3828 partitions[TCAM_PARTITION_ACL_L2C].num_entries + 3829 partitions[TCAM_PARTITION_ACL_IP4C].num_entries + 3830 partitions[TCAM_PARTITION_ACL_IP6C].num_entries - 1; 3831 3832 /* All 288-bit ACL entries */ 3833 memState[EXT_ACL288_TCAMm].index_max = /* TCAM */ 3834 partitions[TCAM_PARTITION_ACL_L2].num_entries + 3835 partitions[TCAM_PARTITION_ACL_IP4].num_entries - 1; 3836 3837 /* All 360-bit ACL entries */ 3838 memState[EXT_ACL360_TCAM_DATAm].index_max = /* TCAM data */ 3839 partitions[TCAM_PARTITION_ACL_IP6S].num_entries - 1; 3840 3841 /* All 432-bit ACL entries */ 3842 memState[EXT_ACL432_TCAM_DATAm].index_max = /* TCAM data */ 3843 partitions[TCAM_PARTITION_ACL_IP6F].num_entries + 3844 partitions[TCAM_PARTITION_ACL_L2IP4].num_entries + 3845 partitions[TCAM_PARTITION_ACL_L2IP6].num_entries - 1; 3846 3847 /* All ACL entries */ 3848 memState[EXT_FP_POLICYm].index_max = /* SRAM */ 3849 memState[EXT_FP_CNTRm].index_max = /* SRAM counter */ 3850 partitions[TCAM_PARTITION_ACL_L2].num_entries + 3851 partitions[TCAM_PARTITION_ACL_IP4].num_entries + 3852 partitions[TCAM_PARTITION_ACL_IP6S].num_entries + 3853 partitions[TCAM_PARTITION_ACL_IP6F].num_entries + 3854 partitions[TCAM_PARTITION_ACL_L2C].num_entries + 3855 partitions[TCAM_PARTITION_ACL_IP4C].num_entries + 3856 partitions[TCAM_PARTITION_ACL_IP6C].num_entries + 3857 partitions[TCAM_PARTITION_ACL_L2IP4].num_entries + 3858 partitions[TCAM_PARTITION_ACL_L2IP6].num_entries - 1; 3859 memState[EXT_FP_CNTR8m].index_max = /* SRAM counter */ 3860 (partitions[TCAM_PARTITION_ACL_L2].num_entries + 7) / 8 + 3861 (partitions[TCAM_PARTITION_ACL_IP4].num_entries + 7) / 8 + 3862 (partitions[TCAM_PARTITION_ACL_IP6S].num_entries + 7) / 8 + 3863 (partitions[TCAM_PARTITION_ACL_IP6F].num_entries + 7) / 8 + 3864 (partitions[TCAM_PARTITION_ACL_L2C].num_entries + 7) / 8 + 3865 (partitions[TCAM_PARTITION_ACL_IP4C].num_entries + 7) / 8 + 3866 (partitions[TCAM_PARTITION_ACL_IP6C].num_entries + 7) / 8 + 3867 (partitions[TCAM_PARTITION_ACL_L2IP4].num_entries + 7) / 8 + 3868 (partitions[TCAM_PARTITION_ACL_L2IP6].num_entries + 7) / 8 - 1; 3869 3870 if (SOC_IS_TRIUMPH(unit) || SOC_IS_TRIUMPH2(unit)) { 3871 /* Set maximum supported vrf id for the device. 3872 * For Triumph & Triumph2 devices vrf id needs to be updated 3873 * after max index values are updated */ 3874 SOC_IF_ERROR_RETURN(soc_max_supported_vrf_get(unit, &value)); 3875 SOC_VRF_MAX_SET(unit, value); 3876 } 3877 3878 return SOC_E_NONE; 3879 } 3880 3881 /* Clear all tables to ensure sram tables have valid CRC/ECC */ 3882 STATIC int 3883 _soc_triumph_esm_init_clear_all_entries(int unit) 3884 { 3885 soc_tcam_info_t *tcam_info; 3886 tr_ext_sram_bist_t sram_bist; 3887 soc_timeout_t to; 3888 uint32 rval, to_usec; 3889 3890 tcam_info = SOC_CONTROL(unit)->tcam_info; 3891 3892 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 3893 (10 * MILLISECOND_USEC); 3894 3895 if (!SAL_BOOT_SIMULATION) { 3896 /* Clear SRAM in order to have correct ECC value on each entry */ 3897 sal_memset(&sram_bist, 0, sizeof(sram_bist)); 3898 sram_bist.adr0 = 0; 3899 sram_bist.adr1 = 0x3ffffe; 3900 sram_bist.adr_mode = 2; 3901 sram_bist.em_latency = -1; 3902 sram_bist.w2r_nops = 3; 3903 sram_bist.r2w_nops = 3; 3904 sram_bist.loop_mode = 0; /* WW */ 3905 3906 soc_triumph_ext_sram_enable_set(unit, 0, TRUE, TRUE); 3907 soc_triumph_ext_sram_bist_setup(unit, 0, &sram_bist); 3908 soc_triumph_ext_sram_op(unit, 0, &sram_bist, NULL); 3909 soc_triumph_ext_sram_enable_set(unit, 0, FALSE, TRUE); 3910 3911 soc_triumph_ext_sram_enable_set(unit, 1, TRUE, TRUE); 3912 soc_triumph_ext_sram_bist_setup(unit, 1, &sram_bist); 3913 soc_triumph_ext_sram_op(unit, 1, &sram_bist, NULL); 3914 soc_triumph_ext_sram_enable_set(unit, 1, FALSE, TRUE); 3915 3916 /* Clear hit bit */ 3917 rval = 0; 3918 soc_reg_field_set(unit, ETU_INT_MEM_RSTr, &rval, EXT_DST_HIT_BITSf, 1); 3919 soc_reg_field_set(unit, ETU_INT_MEM_RSTr, &rval, EXT_SRC_HIT_BITSf, 1); 3920 soc_reg_field_set(unit, ETU_INT_MEM_RSTr, &rval, EXT_L2_MOD_FIFOf, 1); 3921 soc_reg_field_set(unit, ETU_INT_MEM_RSTr, &rval, STARTf, 1); 3922 SOC_IF_ERROR_RETURN(WRITE_ETU_INT_MEM_RSTr(unit, rval)); 3923 soc_timeout_init(&to, to_usec, 0); 3924 while (TRUE) { 3925 SOC_IF_ERROR_RETURN(READ_ETU_INT_MEM_RSTr(unit, &rval)); 3926 if (soc_reg_field_get(unit, ETU_INT_MEM_RSTr, rval, COMPLETEf)) { 3927 break; 3928 } 3929 if (soc_timeout_check(&to)) { 3930 return SOC_E_TIMEOUT; 3931 } 3932 } 3933 } 3934 3935 if (tcam_info->partitions[TCAM_PARTITION_FWD_L2].num_entries) { 3936 /* set Free Bit for each TCAM entries */ 3937 SOC_IF_ERROR_RETURN(soc_mem_clear(unit, EXT_L2_ENTRY_TCAMm, 3938 MEM_BLOCK_ALL, TRUE)); 3939 } 3940 3941 if (SOC_CONTROL(unit)->ext_l2_ppa_info != NULL) { 3942 sal_free(SOC_CONTROL(unit)->ext_l2_ppa_info); 3943 SOC_CONTROL(unit)->ext_l2_ppa_info = NULL; 3944 } 3945 if (SOC_CONTROL(unit)->ext_l2_ppa_vlan != NULL) { 3946 sal_free(SOC_CONTROL(unit)->ext_l2_ppa_vlan); 3947 SOC_CONTROL(unit)->ext_l2_ppa_vlan = NULL; 3948 } 3949 3950 return SOC_E_NONE; 3951 } 3952 3953 /* 3954 * Forwarding key value encoding: 3955 * L2 (always 72-bit) 3956 * IP4 (always 72-bit) 3957 * IP6 (0:72-bit, 1:144-bit) 3958 * ACL key value encoding: 3959 * L2 (0:disable, 1:288-bit, 2:144-bit) 3960 * IP4 (0:disable, 1:288-bit, 2:144-bit, 3:L2+IP4, 4:L2) 3961 * IP6 (0:disable, 1:360-bit, 2:432-bit, 3:144-bit, 4:L2+IP6, 5:L2) 3962 */ 3963 STATIC int 3964 _soc_triumph_esm_init_set_esm_mode_per_port(int unit) 3965 { 3966 soc_tcam_info_t *tcam_info; 3967 soc_tcam_partition_t *partitions; 3968 int fwd_ip6_key, acl_l2_key, acl_ip4_key, acl_ip6_key; 3969 uint32 rval; 3970 int port; 3971 3972 tcam_info = SOC_CONTROL(unit)->tcam_info; 3973 partitions = tcam_info->partitions; 3974 3975 fwd_ip6_key = soc_property_get(unit, spn_EXT_IP6_FWD_KEY, -1); 3976 acl_l2_key = soc_property_get(unit, spn_EXT_L2_ACL_KEY, -1); 3977 acl_ip4_key = soc_property_get(unit, spn_EXT_IP4_ACL_KEY, -1); 3978 acl_ip6_key = soc_property_get(unit, spn_EXT_IP6_ACL_KEY, -1); 3979 3980 /* IP6 FWD key is not specified in config, figure it out from table size */ 3981 if (fwd_ip6_key == -1) { 3982 fwd_ip6_key = 0; /* default 72-bit key (prefix length 64) */ 3983 if (!partitions[TCAM_PARTITION_FWD_IP6U].num_entries) { 3984 if (partitions[TCAM_PARTITION_FWD_IP6].num_entries) { 3985 fwd_ip6_key = 1; /* 144-bit key (prefix length 128) */ 3986 } 3987 } 3988 } 3989 3990 /* L2 ACL key is not specified in config, figure it out from table size */ 3991 if (acl_l2_key == -1) { /* L2 ACL key not specified in config */ 3992 acl_l2_key = 0; /* default disable */ 3993 if (partitions[TCAM_PARTITION_ACL_L2].num_entries) { 3994 acl_l2_key = 1; /* 288-bit key */ 3995 } else if (partitions[TCAM_PARTITION_ACL_L2C].num_entries) { 3996 acl_l2_key = 2; /* 144-bit key */ 3997 } 3998 } 3999 4000 /* IP4 ACL key is not specified in config, figure it out from table size */ 4001 if (acl_ip4_key == -1) { /* IP4 ACL key not specified in config */ 4002 acl_ip4_key = 0; /* default disable */ 4003 if (partitions[TCAM_PARTITION_ACL_IP4].num_entries) { 4004 acl_ip4_key = 1; /* 288-bit key */ 4005 } else if (partitions[TCAM_PARTITION_ACL_IP4C].num_entries) { 4006 acl_ip4_key = 2; /* 144-bit key */ 4007 } else if (partitions[TCAM_PARTITION_ACL_L2IP4].num_entries) { 4008 acl_ip4_key = 3; /* 432-bit L2+L3 key */ 4009 } else if (partitions[TCAM_PARTITION_ACL_L2].num_entries) { 4010 acl_ip4_key = 4; /* 288-bit L2 key */ 4011 } 4012 } 4013 4014 /* IP6 ACL key is not specified in config, figure it out from table size */ 4015 if (acl_ip6_key == -1) { /* IP6 ACL key not specified in config */ 4016 acl_ip6_key = 0; /* default disable */ 4017 if (partitions[TCAM_PARTITION_ACL_IP6S].num_entries) { 4018 acl_ip6_key = 1; /* 360-bit key */ 4019 } else if (partitions[TCAM_PARTITION_ACL_IP6F].num_entries) { 4020 acl_ip6_key = 2; /* 432-bit key */ 4021 } else if (partitions[TCAM_PARTITION_ACL_IP6C].num_entries) { 4022 acl_ip6_key = 3; /* 144-bit key */ 4023 } else if (partitions[TCAM_PARTITION_ACL_L2IP6].num_entries) { 4024 acl_ip6_key = 4; /* 432-bit L2+L3 key */ 4025 } else if (partitions[TCAM_PARTITION_ACL_L2].num_entries) { 4026 acl_ip6_key = 5; /* 288-bit L2 key */ 4027 } 4028 } 4029 4030 if (fwd_ip6_key < 0 || fwd_ip6_key > 1 || 4031 acl_l2_key < 0 || acl_l2_key > 2 || 4032 acl_ip4_key < 0 || acl_ip4_key > 4 || 4033 acl_ip6_key < 0 || acl_ip6_key > 5) { 4034 LOG_ERROR(BSL_LS_SOC_COMMON, 4035 (BSL_META_U(unit, 4036 "ESM init: unit %d incorrect key selection\n"), 4037 unit)); 4038 return SOC_E_PARAM; 4039 } 4040 4041 /* 4042 * 350 MHz 6k (subtype 3): 4043 * no L2 (learning) + L3 forward mode 4044 * IP6 ACL only support 144 bit 4045 * 350 MHz 7k (subtype 4): 4046 * L2 (learning) + L3 forward mode only allow 72 bit IP6 4047 * IP6 ACL only support 144 bit 4048 */ 4049 if (tcam_info->mode) { /* 350 MHz */ 4050 if (acl_ip6_key == 1 || acl_ip6_key == 2) { 4051 acl_ip6_key = 3; 4052 } 4053 } 4054 rval = 0; 4055 if (fwd_ip6_key) { 4056 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_128_ENf, 1); 4057 } 4058 if (acl_l2_key) { 4059 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, L2_ACL_ENf, 1); 4060 if (acl_l2_key == 2) { 4061 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, L2_ACL_144_ENf, 4062 1); 4063 } 4064 } 4065 switch (acl_ip4_key) { 4066 case 1: /* ACL_IP4, 288-bit */ 4067 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_ACL_MODEf, 2); 4068 break; 4069 case 2: /* ACL_IP4C, 144-bit */ 4070 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_ACL_MODEf, 2); 4071 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_ACL_144_ENf, 4072 1); 4073 break; 4074 case 3: /* ACL_L2IP4, 432-bit */ 4075 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_ACL_MODEf, 3); 4076 break; 4077 case 4: /* ACL_L2 or ACL_L2C */ 4078 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_ACL_MODEf, 1); 4079 break; 4080 default: 4081 break; 4082 } 4083 switch (acl_ip6_key) { 4084 case 1: /* ACL_IP6S, 360-bit */ 4085 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_MODEf, 2); 4086 break; 4087 case 2: /* ACL_IP6F, 432-bit */ 4088 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_MODEf, 2); 4089 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_FULL_ACLf, 1); 4090 break; 4091 case 3: /* ACL_IP6C, 144-bit */ 4092 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_MODEf, 2); 4093 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_144_ENf, 4094 1); 4095 break; 4096 case 4: /* ACL_L2IP6, 432-bit */ 4097 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_MODEf, 3); 4098 break; 4099 case 5: /* ACL_L2 or ACL_L2C */ 4100 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_ACL_MODEf, 1); 4101 break; 4102 default: 4103 break; 4104 } 4105 4106 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, L2_FWD_ENf, 1); 4107 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV4_FWD_MODEf, 4108 acl_ip4_key == 4 ? 1 : 2); 4109 soc_reg_field_set(unit, ESM_MODE_PER_PORTr, &rval, IPV6_FWD_MODEf, 4110 acl_ip6_key == 5 ? 1 : 2); 4111 4112 PBMP_ALL_ITER(unit, port) { 4113 SOC_IF_ERROR_RETURN(WRITE_ESM_MODE_PER_PORTr(unit, port, rval)); 4114 } 4115 4116 return SOC_E_NONE; 4117 } 4118 4119 int 4120 soc_triumph_esm_init(int unit) 4121 { 4122 uint16 dev_id; 4123 uint8 rev_id; 4124 soc_tcam_info_t *tcam_info; 4125 uint32 rval, to_usec, addr; 4126 uint32 wval = 0; 4127 int rv, sram_mode, ad_mode; 4128 int do_tcam_tuning, do_sram_tuning[2], sram_dac_en[2], always_drive_dbus; 4129 int tx_locked[2], rx_locked[2]; 4130 int intf_num, retry_count; 4131 et_inst_opc_table_entry_t opc_entry; 4132 4133 soc_cm_get_id(unit, &dev_id, &rev_id); 4134 4135 tcam_info = SOC_CONTROL(unit)->tcam_info; 4136 if (tcam_info == NULL) { 4137 return SOC_E_NONE; 4138 } 4139 4140 always_drive_dbus = soc_feature(unit, soc_feature_always_drive_dbus); 4141 4142 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 4143 (10 * MILLISECOND_USEC); 4144 4145 /* De-assert external TCAM reset pin */ 4146 /* coverity[result_independent_of_operands] */ 4147 SOC_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REGr(unit, &rval)); 4148 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, EXT_TCAM_RSTf, 0); 4149 /* coverity[result_independent_of_operands] */ 4150 SOC_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REGr(unit, rval)); 4151 sal_usleep(to_usec); 4152 4153 addr = soc_reg_addr(unit, IESMIF_INTR_CLEARr, REG_PORT_ANY, 0); 4154 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &wval)); 4155 soc_reg_field_set(unit, IESMIF_INTR_STATUSr, &wval, BK2BK_ESM_ELIGIBLEf, 1); 4156 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, wval)); 4157 4158 /* 0: 500MHz 6 cycles, 1: 350MHz 4 cycles, default to 500MHz */ 4159 tcam_info->mode = soc_property_get(unit, spn_EXT_TCAM_MODE, 0); 4160 4161 /* 0: read from device, 3: NL6K, 4: NL7K */ 4162 tcam_info->subtype_override = 4163 soc_property_get(unit, spn_EXT_TCAM_DEV_TYPE, 0); 4164 if (tcam_info->subtype_override && 4165 (tcam_info->subtype_override < 3 || tcam_info->subtype_override > 4)) { 4166 LOG_ERROR(BSL_LS_SOC_COMMON, 4167 (BSL_META_U(unit, 4168 "ESM init: unit %d invalid device type %d\n"), 4169 unit, tcam_info->subtype_override)); 4170 return SOC_E_PARAM; 4171 } 4172 4173 tcam_info->num_tcams_override = 4174 soc_property_get(unit, spn_EXT_TCAM_BANKS, 0); 4175 if (tcam_info->num_tcams_override && 4176 (tcam_info->num_tcams_override < 1 || 4177 tcam_info->num_tcams_override > 2)) { 4178 LOG_ERROR(BSL_LS_SOC_COMMON, 4179 (BSL_META_U(unit, 4180 "ESM init: unit %d does not support %d TCAM banks\n"), 4181 unit, tcam_info->num_tcams_override)); 4182 return SOC_E_PARAM; 4183 } 4184 4185 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_select_ad_mode(unit, &ad_mode)); 4186 4187 /* 4188 * For RX: 4189 * Use MIDL: set MIDL_RX_EN and SEL_RX_CLKDLY_BLK to 1 4190 * Use VCDL: set MIDL_RX_EN and SEL_RX_CLKDLY_BLK to 0 4191 * For TX: 4192 * Use MIDL: set MIDL_TX_EN and SEL_TX_CLKDLY_BLK to 1 4193 * Use VCDL: set MIDL_TX_EN and SEL_TX_CLKDLY_BLK to 0 4194 */ 4195 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG1_ISr(unit, &rval)); 4196 if (SAL_BOOT_QUICKTURN) { 4197 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4198 VCDL_TX_BYPASSf, 1); 4199 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4200 VCDL_RX_BYPASSf, 1); 4201 } 4202 if (soc_property_get(unit, spn_EXT_TCAM_USE_MIDL, 1)) { 4203 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4204 SEL_TX_CLKDLY_BLKf, 1); 4205 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4206 SEL_RX_CLKDLY_BLKf, 1); 4207 } else { 4208 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4209 MIDL_TX_ENf, 0); 4210 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, 4211 MIDL_RX_ENf, 0); 4212 } 4213 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG1_ISr(unit, rval)); 4214 4215 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG2_ISr(unit, &rval)); 4216 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, ODT_CLK500_If, 4217 1); 4218 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG2_ISr(unit, rval)); 4219 4220 4221 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG1_ISr(unit, &rval)); 4222 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, ENABLE_TCAMf, 4223 0); 4224 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG1_ISr(unit, rval)); 4225 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG1_ISr, &rval, ENABLE_TCAMf, 4226 1); 4227 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG1_ISr(unit, rval)); 4228 4229 if (always_drive_dbus) { 4230 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG3_ISr(unit, &rval)); 4231 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &rval, 4232 ALWAYS_DRIVE_DBUSf, 1); 4233 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG3_ISr(unit, rval)); 4234 } 4235 4236 SOC_IF_ERROR_RETURN(READ_ETC_CTLr(unit, &rval)); 4237 soc_reg_field_set(unit, ETC_CTLr, &rval, IN_DBUS_CAPT_DLYf, 63); 4238 soc_reg_field_set(unit, ETC_CTLr, &rval, IN_RDACK11f, 0); 4239 SOC_IF_ERROR_RETURN(WRITE_ETC_CTLr(unit, rval)); 4240 4241 SOC_IF_ERROR_RETURN(READ_ESM_CTLr(unit, &rval)); 4242 soc_reg_field_set(unit, ESM_CTLr, &rval, EXT_TCAM_MODEf, tcam_info->mode); 4243 soc_reg_field_set(unit, ESM_CTLr, &rval, AD_MODEf, ad_mode); 4244 soc_reg_field_set(unit, ESM_CTLr, &rval, SEND_RSP_WORD_DYNAMICf, 1); 4245 if (tcam_info->partitions[TCAM_PARTITION_FWD_IP4].num_entries != 0 || 4246 tcam_info->partitions[TCAM_PARTITION_FWD_IP6U].num_entries != 0 || 4247 tcam_info->partitions[TCAM_PARTITION_FWD_IP6].num_entries != 0) { 4248 soc_reg_field_set(unit, ESM_CTLr, &rval, WDAT36_RMWf, 1); 4249 } 4250 SOC_IF_ERROR_RETURN(WRITE_ESM_CTLr(unit, rval)); 4251 4252 SOC_IF_ERROR_RETURN(READ_ETU_LUREQFIFO_RS_CTLr(unit, &rval)); 4253 soc_reg_field_set(unit, ETU_LUREQFIFO_RS_CTLr, &rval, COUNT_HI_THRf, 5); 4254 soc_reg_field_set(unit, ETU_LUREQFIFO_RS_CTLr, &rval, COUNT_LO_THRf, 1); 4255 SOC_IF_ERROR_RETURN(WRITE_ETU_LUREQFIFO_RS_CTLr(unit, rval)); 4256 4257 /* sram_mode 0: 1.5 clocks latency, 1: 2 clocks latency */ 4258 sram_mode = soc_property_get(unit, spn_EXT_SRAM_MODE, 1); 4259 SOC_IF_ERROR_RETURN(READ_ES0_DDR36_CONFIG_REG1_ISr(unit, &rval)); 4260 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG1_ISr, &rval, SRAM_MODEf, 4261 sram_mode); 4262 SOC_IF_ERROR_RETURN(WRITE_ES0_DDR36_CONFIG_REG1_ISr(unit, rval)); 4263 SOC_IF_ERROR_RETURN(READ_ES1_DDR36_CONFIG_REG1_ISr(unit, &rval)); 4264 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG1_ISr, &rval, SRAM_MODEf, 4265 sram_mode); 4266 SOC_IF_ERROR_RETURN(WRITE_ES1_DDR36_CONFIG_REG1_ISr(unit, rval)); 4267 4268 /* Program SRAM tuning result from config variables */ 4269 for (intf_num = 0; intf_num < 2; intf_num++) { 4270 rv = _soc_triumph_esm_init_set_sram_tuning_result(unit, intf_num); 4271 if (SOC_FAILURE(rv) && rv != SOC_E_NOT_FOUND) { 4272 return rv; 4273 } 4274 do_sram_tuning[intf_num] = 4275 SAL_BOOT_BCMSIM || rv == SOC_E_NOT_FOUND ? FALSE : TRUE; 4276 } 4277 4278 /* Program TCAM tuning result from config variables */ 4279 rv = _soc_triumph_esm_init_set_tcam_tuning_result(unit); 4280 if (SOC_FAILURE(rv) && rv != SOC_E_NOT_FOUND) { 4281 return rv; 4282 } 4283 do_tcam_tuning = SAL_BOOT_BCMSIM || rv == SOC_E_NOT_FOUND ? FALSE : TRUE; 4284 4285 if (SOC_WARM_BOOT(unit)) { 4286 do_tcam_tuning = FALSE; 4287 } 4288 4289 if (SOC_IS_TRIUMPH2(unit)) { 4290 /* Program SRAM DAC value from config variable */ 4291 for (intf_num = 0; intf_num < 2; intf_num++) { 4292 rv = _soc_triumph_esm_init_set_sram_dac(unit, intf_num); 4293 if (SOC_FAILURE(rv) && rv != SOC_E_NOT_FOUND) { 4294 return rv; 4295 } 4296 sram_dac_en[intf_num] = rv == SOC_E_NOT_FOUND ? FALSE : TRUE; 4297 } 4298 4299 /* Program TCAM DAC value from config variable */ 4300 (void)_soc_triumph_esm_init_set_tcam_dac(unit); 4301 4302 /* Bring SRAM and TCAM out of reset */ 4303 /* coverity[result_independent_of_operands] */ 4304 SOC_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REGr(unit, &rval)); 4305 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_DDR0_RST_Lf, 1); 4306 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_DDR1_RST_Lf, 1); 4307 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_TCAM_RST_Lf, 1); 4308 /* coverity[result_independent_of_operands] */ 4309 SOC_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REGr(unit, rval)); 4310 4311 sal_usleep(25); /* reset SRAM DLL for 25us */ 4312 4313 SOC_IF_ERROR_RETURN(READ_ES0_DDR36_CONFIG_REG1_ISr(unit, &rval)); 4314 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG1_ISr, &rval, ENABLE_DDRf, 1); 4315 SOC_IF_ERROR_RETURN(WRITE_ES0_DDR36_CONFIG_REG1_ISr(unit, rval)); 4316 SOC_IF_ERROR_RETURN(READ_ES1_DDR36_CONFIG_REG1_ISr(unit, &rval)); 4317 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG1_ISr, &rval, ENABLE_DDRf, 1); 4318 SOC_IF_ERROR_RETURN(WRITE_ES1_DDR36_CONFIG_REG1_ISr(unit, rval)); 4319 4320 sal_usleep(100); /* wait for SRAM DLLs to lock for 100us */ 4321 4322 /* Check SRAM TX status */ 4323 for (intf_num = 0; intf_num < 2; intf_num++) { 4324 rv = _soc_triumph_esm_init_check_sram_tx_status 4325 (unit, intf_num, sram_dac_en[intf_num]); 4326 if (rv == SOC_E_NOT_FOUND) { 4327 LOG_CLI((BSL_META_U(unit, 4328 "SRAM%d TX DLL not locked\n"), intf_num)); 4329 } else if (SOC_FAILURE(rv)) { 4330 return rv; 4331 } 4332 } 4333 4334 /* Set ES0 PVT */ 4335 rv = _soc_triumph_esm_init_set_pvt(unit, 0); 4336 if (rv == SOC_E_NOT_FOUND) { 4337 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 0)); 4338 /* Set ES0 IO drive strength and slew rate strong */ 4339 if (SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID) { 4340 SOC_IF_ERROR_RETURN(READ_ES0_DDR36_CONFIG_REG2_ISr(unit, &rval)); 4341 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4342 PVT_PDRIVE_VALf, 15); 4343 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4344 PVT_NDRIVE_VALf, 0); 4345 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4346 OVRD_EN_DRIVER_PVTf, 1); 4347 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4348 PVT_SLEW_VALf, 15); 4349 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4350 OVRD_EN_SLEW_PVTf, 1); 4351 SOC_IF_ERROR_RETURN(WRITE_ES0_DDR36_CONFIG_REG2_ISr(unit, rval)); 4352 } 4353 } else if (SOC_FAILURE(rv)) { 4354 return rv; 4355 } 4356 4357 /* Set ES1 PVT */ 4358 rv = _soc_triumph_esm_init_set_pvt(unit, 1); 4359 if (rv == SOC_E_NOT_FOUND) { 4360 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 1)); 4361 /* Set ES1 IO drive strength and slew rate strong */ 4362 if (SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID) { 4363 SOC_IF_ERROR_RETURN(READ_ES1_DDR36_CONFIG_REG2_ISr(unit, &rval)); 4364 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4365 PVT_PDRIVE_VALf, 15); 4366 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4367 PVT_NDRIVE_VALf, 0); 4368 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4369 OVRD_EN_DRIVER_PVTf, 1); 4370 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4371 PVT_SLEW_VALf, 15); 4372 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4373 OVRD_EN_SLEW_PVTf, 1); 4374 SOC_IF_ERROR_RETURN(WRITE_ES1_DDR36_CONFIG_REG2_ISr(unit, rval)); 4375 } 4376 } else if (SOC_FAILURE(rv)) { 4377 return rv; 4378 } 4379 4380 /* Set TCAM PVT */ 4381 rv = _soc_triumph_esm_init_set_pvt(unit, 2); 4382 if (rv == SOC_E_NOT_FOUND) { 4383 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 2)); 4384 /* Set TCAM IO drive strength and slew rate weak */ 4385 if ((SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID)) { 4386 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG2_ISr(unit, &rval)); 4387 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4388 PVT_PDRIVE_VALf, 0); 4389 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4390 PVT_NDRIVE_VALf, 15); 4391 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4392 OVRD_EN_DRIVER_PVTf, 1); 4393 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4394 PVT_SLEW_VALf, 1); 4395 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4396 OVRD_EN_SLEW_PVTf, 1); 4397 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG2_ISr(unit, rval)); 4398 } 4399 } else if (SOC_FAILURE(rv)) { 4400 return rv; 4401 } 4402 4403 tx_locked[0] = tx_locked[1] = FALSE; 4404 rx_locked[0] = rx_locked[1] = FALSE; 4405 for (retry_count = 0; retry_count < 11; retry_count++) { 4406 /* Toggle STOP_DK on SRAM interfaces */ 4407 for (intf_num = 0; intf_num < 2; intf_num++) { 4408 if (tx_locked[intf_num] && rx_locked[intf_num]) { 4409 continue; 4410 } 4411 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_stop_dk(unit, intf_num)); 4412 4413 SOC_IF_ERROR_RETURN 4414 (_soc_triumph_esm_init_relock_dll(unit, intf_num, 4415 retry_count != 0 ? TRUE : FALSE)); 4416 4417 /* Check SRAM TX status */ 4418 rv = _soc_triumph_esm_init_check_sram_tx_status 4419 (unit, intf_num, sram_dac_en[intf_num]); 4420 if (SOC_SUCCESS(rv)) { 4421 tx_locked[intf_num] = TRUE; 4422 } else if (SOC_FAILURE(rv) && rv != SOC_E_NOT_FOUND) { 4423 return rv; 4424 } 4425 4426 /* Check SRAM RX status */ 4427 rv = _soc_triumph_esm_init_check_sram_rx_status(unit, intf_num); 4428 if (SOC_SUCCESS(rv)) { 4429 rx_locked[intf_num] = TRUE; 4430 } else if (SOC_FAILURE(rv) && rv != SOC_E_NOT_FOUND) { 4431 return rv; 4432 } 4433 } 4434 } 4435 4436 for (intf_num = 0; intf_num < 2; intf_num++) { 4437 if (!tx_locked[intf_num]) { 4438 LOG_CLI((BSL_META_U(unit, 4439 "SRAM%d TX DLL not locked\n"), intf_num)); 4440 } 4441 if (!rx_locked[intf_num]) { 4442 LOG_CLI((BSL_META_U(unit, 4443 "SRAM%d RX DLL not locked\n"), intf_num)); 4444 } 4445 } 4446 } else { /* Triumph */ 4447 /* Bring SRAM and TCAM out of reset */ 4448 /* coverity[result_independent_of_operands] */ 4449 SOC_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REGr(unit, &rval)); 4450 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_DDR0_RST_Lf, 1); 4451 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_DDR1_RST_Lf, 1); 4452 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, CMIC_TCAM_RST_Lf, 1); 4453 /* coverity[result_independent_of_operands] */ 4454 SOC_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REGr(unit, rval)); 4455 4456 /* Set ES0 PVT */ 4457 rv = _soc_triumph_esm_init_set_pvt(unit, 0); 4458 if (rv == SOC_E_NOT_FOUND) { 4459 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 0)); 4460 /* Set ES0 IO drive strength and slew rate strong */ 4461 if (SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID) { 4462 SOC_IF_ERROR_RETURN(READ_ES0_DDR36_CONFIG_REG2_ISr(unit, &rval)); 4463 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4464 PVT_PDRIVE_VALf, 15); 4465 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4466 PVT_NDRIVE_VALf, 0); 4467 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4468 OVRD_EN_DRIVER_PVTf, 1); 4469 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4470 PVT_SLEW_VALf, 15); 4471 soc_reg_field_set(unit, ES0_DDR36_CONFIG_REG2_ISr, &rval, 4472 OVRD_EN_SLEW_PVTf, 1); 4473 SOC_IF_ERROR_RETURN(WRITE_ES0_DDR36_CONFIG_REG2_ISr(unit, rval)); 4474 } 4475 } else if (SOC_FAILURE(rv)) { 4476 return rv; 4477 } 4478 4479 /* Set ES1 PVT */ 4480 rv = _soc_triumph_esm_init_set_pvt(unit, 1); 4481 if (rv == SOC_E_NOT_FOUND) { 4482 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 1)); 4483 /* Set ES1 IO drive strength and slew rate strong */ 4484 if (SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID) { 4485 SOC_IF_ERROR_RETURN(READ_ES1_DDR36_CONFIG_REG2_ISr(unit, &rval)); 4486 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4487 PVT_PDRIVE_VALf, 15); 4488 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4489 PVT_NDRIVE_VALf, 0); 4490 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4491 OVRD_EN_DRIVER_PVTf, 1); 4492 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4493 PVT_SLEW_VALf, 15); 4494 soc_reg_field_set(unit, ES1_DDR36_CONFIG_REG2_ISr, &rval, 4495 OVRD_EN_SLEW_PVTf, 1); 4496 SOC_IF_ERROR_RETURN(WRITE_ES1_DDR36_CONFIG_REG2_ISr(unit, rval)); 4497 } 4498 } else if (SOC_FAILURE(rv)) { 4499 return rv; 4500 } 4501 4502 /* Set TCAM PVT */ 4503 rv = _soc_triumph_esm_init_set_pvt(unit, 2); 4504 if (rv == SOC_E_NOT_FOUND) { 4505 SOC_IF_ERROR_RETURN(soc_triumph_esm_init_pvt_comp(unit, 2)); 4506 /* Set TCAM IO drive strength and slew rate weak */ 4507 if ((SOC_IS_TRIUMPH(unit) && rev_id < BCM56624_B2_REV_ID)) { 4508 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG2_ISr(unit, &rval)); 4509 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4510 PVT_PDRIVE_VALf, 0); 4511 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4512 PVT_NDRIVE_VALf, 15); 4513 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4514 OVRD_EN_DRIVER_PVTf, 1); 4515 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4516 PVT_SLEW_VALf, 1); 4517 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG2_ISr, &rval, 4518 OVRD_EN_SLEW_PVTf, 1); 4519 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG2_ISr(unit, rval)); 4520 } 4521 } else if (SOC_FAILURE(rv)) { 4522 return rv; 4523 } 4524 4525 /* Toggle STOP_DK on SRAM interfaces */ 4526 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_stop_dk_old(unit)); 4527 4528 for (intf_num = 0; intf_num < 2; intf_num++) { 4529 /* Relock DLL to stabilize interfaces */ 4530 SOC_IF_ERROR_RETURN 4531 (_soc_triumph_esm_init_relock_dll_old(unit, intf_num)); 4532 (void)_soc_triumph_esm_init_set_sram_dac(unit, intf_num); 4533 } 4534 4535 /* Program TCAM DAC value from config variable */ 4536 (void)_soc_triumph_esm_init_set_tcam_dac(unit); 4537 } /* Triumph */ 4538 4539 /* Perform mini-tuning to find EM_LATENCY for SRAM interface */ 4540 for (intf_num = 0; intf_num < 2; intf_num++) { 4541 if (do_sram_tuning[intf_num]) { 4542 SOC_IF_ERROR_RETURN 4543 (_soc_triumph_esm_init_retune_sram(unit, intf_num)); 4544 } 4545 } 4546 4547 /* Enable memory controller unit */ 4548 if (ad_mode != 2 && ad_mode != 4 && ad_mode != 6 && ad_mode != 8) { 4549 SOC_IF_ERROR_RETURN(READ_ES0_MCU_ENr(unit, &rval)); 4550 soc_reg_field_set(unit, ES0_MCU_ENr, &rval, MCU_ENf, 1); 4551 SOC_IF_ERROR_RETURN(WRITE_ES0_MCU_ENr(unit, rval)); 4552 } 4553 if (ad_mode != 1 && ad_mode != 3 && ad_mode != 5 && ad_mode != 7) { 4554 SOC_IF_ERROR_RETURN(READ_ES1_MCU_ENr(unit, &rval)); 4555 soc_reg_field_set(unit, ES1_MCU_ENr, &rval, MCU_ENf, 1); 4556 SOC_IF_ERROR_RETURN(WRITE_ES1_MCU_ENr(unit, rval)); 4557 } 4558 4559 /* Perform mini-tuning to stabilize TCAM interface */ 4560 if (do_tcam_tuning) { 4561 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_retune_tcam(unit)); 4562 } else { 4563 SOC_IF_ERROR_RETURN(soc_tcam_init(unit)); 4564 } 4565 4566 /* Program tcam index to sram index translation table */ 4567 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_set_et_pa_xlate(unit)); 4568 4569 /* Program software memory state according to table size in user config */ 4570 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_adjust_mem_size(unit)); 4571 4572 if (always_drive_dbus && soc_mem_index_count(unit, EXT_L2_ENTRY_TCAMm)) { 4573 SOC_IF_ERROR_RETURN(soc_mem_cache_set(unit, EXT_L2_ENTRY_TCAMm, 4574 MEM_BLOCK_ALL, TRUE)); 4575 } 4576 4577 /* Clear all tables to ensure sram tables have valid CRC/ECC */ 4578 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_clear_all_entries(unit)); 4579 4580 SOC_IF_ERROR_RETURN(READ_ETU_L2SEARCH72_INSTr(unit, &rval)); 4581 soc_reg_field_set(unit, ETU_L2SEARCH72_INSTr, &rval, OUT_DBUS_CTLf, 0xa0); 4582 SOC_IF_ERROR_RETURN(WRITE_ETU_L2SEARCH72_INSTr(unit, rval)); 4583 4584 SOC_IF_ERROR_RETURN(READ_ESM_L2_AGE_CTLr(unit, &rval)); 4585 soc_reg_field_set(unit, ESM_L2_AGE_CTLr, &rval, EN_RD_TCAMf, 4586 always_drive_dbus ? 0 : 1); 4587 soc_reg_field_set(unit, ESM_L2_AGE_CTLr, &rval, CPU_NOTIFYf, 1); 4588 SOC_IF_ERROR_RETURN(WRITE_ESM_L2_AGE_CTLr(unit, rval)); 4589 4590 SOC_IF_ERROR_RETURN(READ_ESM_PER_PORT_REPL_CONTROLr(unit, &rval)); 4591 soc_reg_field_set(unit, ESM_PER_PORT_REPL_CONTROLr, &rval, EN_RD_TCAMf, 4592 always_drive_dbus ? 0 : 1); 4593 soc_reg_field_set(unit, ESM_PER_PORT_REPL_CONTROLr, &rval, CPU_NOTIFYf, 1); 4594 SOC_IF_ERROR_RETURN(WRITE_ESM_PER_PORT_REPL_CONTROLr(unit, rval)); 4595 4596 SOC_IF_ERROR_RETURN(READ_AUX_ARB_CONTROL_2r(unit, &rval)); 4597 soc_reg_field_set(unit, AUX_ARB_CONTROL_2r, &rval, ESM_AGE_ENABLEf, 1); 4598 soc_reg_field_set(unit, AUX_ARB_CONTROL_2r, &rval, ESM_BP_ENABLEf, 0x0c); 4599 SOC_IF_ERROR_RETURN(WRITE_AUX_ARB_CONTROL_2r(unit, rval)); 4600 4601 if (tcam_info->mode && tcam_info->subtype == 4) { /* 350MHz on 7K */ 4602 SOC_IF_ERROR_RETURN(READ_IESMIF_CONTROL2r(unit, &rval)); 4603 soc_reg_field_set(unit, IESMIF_CONTROL2r, &rval, NL7K_350_MODEf, 1); 4604 SOC_IF_ERROR_RETURN(WRITE_IESMIF_CONTROL2r(unit, rval)); 4605 4606 /* Replace opcode table index 34 from "write to K2 opcode" to 4607 * "compare with LTR 23 opcode (single L2 search with K2)" 4608 * to avoid missing L2 SA lookup for IPv6 L2_ACL + L2_FWD */ 4609 sal_memset(&opc_entry, 0, sizeof(opc_entry)); 4610 soc_mem_field32_set(unit, ET_INST_OPC_TABLEm, &opc_entry, OPCODEf, 4611 0xfa); 4612 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ET_INST_OPC_TABLEm, 4613 MEM_BLOCK_ANY, 34, &opc_entry)); 4614 } 4615 4616 SOC_IF_ERROR_RETURN(READ_ESM_KEYGEN_CTLr(unit, &rval)); 4617 if (tcam_info->subtype == 3) { /* NL6K */ 4618 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, TCAM_TYPEf, 4619 tcam_info->mode ? 0 : 1); 4620 } else if (tcam_info->subtype == 4) { /* NL7K */ 4621 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, TCAM_TYPEf, 4622 tcam_info->mode ? 3 : 2); 4623 } 4624 if (tcam_info->partitions[TCAM_PARTITION_FWD_IP4].num_entries) { 4625 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, IPV4_HIT_BIT_MODEf, 2); 4626 } 4627 if (tcam_info->partitions[TCAM_PARTITION_FWD_IP6U].num_entries || 4628 tcam_info->partitions[TCAM_PARTITION_FWD_IP6].num_entries) { 4629 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, IPV6_HIT_BIT_MODEf, 2); 4630 } 4631 if (tcam_info->partitions[TCAM_PARTITION_FWD_L2].num_entries) { 4632 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, EXT_L2_FWD_ENf, 1); 4633 soc_reg_field_set(unit, ESM_KEYGEN_CTLr, &rval, L2_HIT_BIT_MODEf, 1); 4634 #ifdef BCM_TRIUMPH2_SUPPORT 4635 if (soc_feature(unit, soc_feature_esm_l2_lookup_for_ip6)) { 4636 SOC_IF_ERROR_RETURN(READ_IESMIF_CONTROL2r(unit, &wval)); 4637 soc_reg_field_set(unit, IESMIF_CONTROL2r, &wval, V6_EN_L2FWD_4NONROUTABLEf, 1); 4638 SOC_IF_ERROR_RETURN(WRITE_IESMIF_CONTROL2r(unit, wval)); 4639 } 4640 #endif 4641 } 4642 SOC_IF_ERROR_RETURN(WRITE_ESM_KEYGEN_CTLr(unit, rval)); 4643 4644 SOC_IF_ERROR_RETURN(_soc_triumph_esm_init_set_esm_mode_per_port(unit)); 4645 4646 /* Enable ESM for XGPORT blocks + CPU + SPORT */ 4647 if (SOC_IS_TRIUMPH(unit)) { 4648 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 4649 soc_reg_field_set(unit, IARB_TDM_CONTROLr, &rval, ESM_ENABLEf, 0x3ff); 4650 SOC_IF_ERROR_RETURN(WRITE_IARB_TDM_CONTROLr(unit, rval)); 4651 4652 SOC_IF_ERROR_RETURN(READ_PKTBUF_ESM_OFFSETr(unit, &rval)); 4653 /* set to (4/7) * 92 = 56 for 4 non-ESM eligible slots in tdm cycle */ 4654 soc_reg_field_set(unit, PKTBUF_ESM_OFFSETr, &rval, THRESHOLDf, 56); 4655 SOC_IF_ERROR_RETURN(WRITE_PKTBUF_ESM_OFFSETr(unit, rval)); 4656 } 4657 #ifdef BCM_TRIUMPH2_SUPPORT 4658 if (SOC_IS_TRIUMPH2(unit)) { 4659 int tdm_count, non_esm_count, i; 4660 iarb_tdm_table_entry_t entry; 4661 4662 SOC_IF_ERROR_RETURN(READ_IARB_TDM_CONTROLr(unit, &rval)); 4663 tdm_count = soc_reg_field_get(unit, IARB_TDM_CONTROLr, rval, 4664 TDM_WRAP_PTRf); 4665 non_esm_count = tdm_count; 4666 for (i = 0; i <= tdm_count; i++) { 4667 SOC_IF_ERROR_RETURN(READ_IARB_TDM_TABLEm(unit, MEM_BLOCK_ANY, i, 4668 &entry)); 4669 non_esm_count -= soc_mem_field32_get(unit, IARB_TDM_TABLEm, &entry, 4670 ESM_ELIGIBLEf); 4671 } 4672 4673 SOC_IF_ERROR_RETURN(READ_PKTBUF_ESM_OFFSETr(unit, &rval)); 4674 /* set threshold to roundup(non_esm_count / total_count) * 92 */ 4675 if (tdm_count != 0) { 4676 soc_reg_field_set(unit, PKTBUF_ESM_OFFSETr, &rval, THRESHOLDf, 4677 (92 * non_esm_count + tdm_count - 1) / tdm_count); 4678 } else { 4679 soc_reg_field_set(unit, PKTBUF_ESM_OFFSETr, &rval, THRESHOLDf, 4680 tdm_count); 4681 } 4682 SOC_IF_ERROR_RETURN(WRITE_PKTBUF_ESM_OFFSETr(unit, rval)); 4683 } 4684 #endif /* BCM_TRIUMPH2_SUPPORT */ 4685 4686 addr = soc_reg_addr(unit, IESMIF_INTR_ENABLEr, REG_PORT_ANY, 0); 4687 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, addr, &wval)); 4688 soc_reg_field_set(unit, IESMIF_INTR_STATUSr, &wval, BK2BK_ESM_ELIGIBLEf, 1); 4689 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, addr, wval)); 4690 4691 SOC_IF_ERROR_RETURN(READ_IESMIF_CONTROLr(unit, &rval)); 4692 soc_reg_field_set(unit, IESMIF_CONTROLr, &rval, EN_EXT_SEARCH_REQf, 1); 4693 SOC_IF_ERROR_RETURN(WRITE_IESMIF_CONTROLr(unit, rval)); 4694 4695 return SOC_E_NONE; 4696 } 4697 4698 #define TR_MMU_NUM_PG 8 4699 #define TR_MMU_NUM_COS 8 4700 4701 /* Standard Ethernet MTU, 1536 bytes (1 cell = 128 bytes) */ 4702 #define TR_MMU_ETH_FRAME_CELLS 12 4703 4704 /* Jumbo Frame MTU, 9216 (1 cell = 128 bytes) */ 4705 #define TR_MMU_JUMBO_FRAME_CELLS 72 4706 4707 /* MAX Frame MTU, 16384 (1 cell = 128 bytes) */ 4708 #define TR_MMU_MAX_FRAME_CELLS 128 4709 4710 #define TR_MMU_IN_PORT_MIN_CELLS 72 4711 #define TR_MMU_IN_PORT_MIN_PKTS 1 4712 #define TR_MMU_PG_HDRM_LIMIT_CELLS 36 4713 #define TR_MMU_PG_HDRM_LIMIT_PKTS 36 4714 #define TR_MMU_GLOBAL_HDRM_LIMIT_CELLS 636 4715 #define TR_MMU_PG_RESET_OFFSET_CELLS 24 4716 #define TR_MMU_PG_RESET_OFFSET_PKTS 1 4717 4718 #define TR_MMU_OUT_PORT_MIN_CELLS 12 4719 #define TR_MMU_OUT_PORT_MIN_PKTS 1 4720 #define TR_MMU_OUT_RESET_OFFSET_CELLS 24 4721 #define TR_MMU_OUT_RESET_OFFSET_PKTS 2 4722 #define TR_MMU_SOP_POLICY 0 4723 #define TR_MMU_MOP_POLICY 7 4724 4725 int 4726 soc_triumph_mmu_init(int unit) 4727 { 4728 uint16 dev_id; 4729 uint8 rev_id; 4730 uint64 rval64; 4731 uint32 rval0, rval1, cell_rval, pkt_rval; 4732 int rv = SOC_E_NONE; 4733 int port; 4734 int total_cells, total_pkts; 4735 int in_reserved_cells, in_reserved_pkts; 4736 int out_reserved_cells, out_reserved_pkts; 4737 int out_shared_cells, out_shared_pkts; 4738 int idx, count; 4739 soc_pbmp_t pbmp_8pg; 4740 4741 soc_cm_get_id(unit, &dev_id, &rev_id); 4742 4743 /* Total number of cells */ 4744 if (SOC_IS_VALKYRIE(unit) && dev_id != BCM56620_DEVICE_ID) { 4745 total_cells = 24 * 1024; /* 24K cells */ 4746 } else { 4747 total_cells = 32 * 1024; /* 32K cells */ 4748 } 4749 4750 /* Total number of packet pointers */ 4751 total_pkts = 11 * 1024; /* 11K packet pointers */ 4752 4753 /* Ports with 8PG (1PG for other ports) */ 4754 SOC_PBMP_CLEAR(pbmp_8pg); 4755 SOC_PBMP_WORD_SET(pbmp_8pg, 0, 0xfc004004); /* 2, 14, 26-31 */ 4756 SOC_PBMP_AND(pbmp_8pg, PBMP_ALL(unit)); 4757 4758 /* 4759 * Reserved space calculation: 4760 * Input port: 4761 * per-port minimum 4762 * per-PG minimum (config to 0) 4763 * per-PG headroom 4764 * per-device headroom 4765 * per-port minimum for SC and QM traffic (config to 0) 4766 * Output port: 4767 * per-port per-COS minimum space 4768 * Shared space calculation: 4769 * Input port: total - input port reserved - output port reserved 4770 * Output port: total - output port reserved 4771 */ 4772 in_reserved_cells = NUM_ALL_PORT(unit) * TR_MMU_IN_PORT_MIN_CELLS + 4773 NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_CELLS + 4774 TR_MMU_GLOBAL_HDRM_LIMIT_CELLS; 4775 in_reserved_pkts = NUM_ALL_PORT(unit) * TR_MMU_IN_PORT_MIN_PKTS + 4776 NUM_PORT(unit) * TR_MMU_PG_HDRM_LIMIT_PKTS; 4777 out_reserved_cells = 4778 (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) * 4779 TR_MMU_OUT_PORT_MIN_CELLS; 4780 out_reserved_pkts = 4781 (NUM_PORT(unit) * TR_MMU_NUM_COS + SOC_INFO(unit).num_cpu_cosq) * 4782 TR_MMU_OUT_PORT_MIN_PKTS; 4783 4784 /* 4785 * Input ports threshold 4786 */ 4787 /* Reserved space: Input port per-port minimum */ 4788 cell_rval = 0; 4789 soc_reg_field_set(unit, PORT_MIN_CELLr, &cell_rval, PORT_MINf, 4790 TR_MMU_IN_PORT_MIN_CELLS); 4791 pkt_rval = 0; 4792 soc_reg_field_set(unit, PORT_MIN_PACKETr, &pkt_rval, PORT_MINf, 4793 TR_MMU_IN_PORT_MIN_PKTS); 4794 PBMP_ALL_ITER(unit, port) { 4795 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_CELLr(unit, port, cell_rval)); 4796 SOC_IF_ERROR_RETURN(WRITE_PORT_MIN_PACKETr(unit, port, pkt_rval)); 4797 } 4798 4799 /* Reserved space: Input port per-PG minimum 4800 * Use defalt value 0 4801 * With only one PG in use PORT_MIN should be sufficient */ 4802 4803 /* Reserved space: Input port per-PG headroom 4804 * Use only 1PG (highest priority PG for the port) */ 4805 cell_rval = 0; 4806 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_HDRM_LIMITf, 4807 TR_MMU_PG_HDRM_LIMIT_CELLS); 4808 soc_reg_field_set(unit, PG_HDRM_LIMIT_CELLr, &cell_rval, PG_GEf, 1); 4809 pkt_rval = 0; 4810 soc_reg_field_set(unit, PG_HDRM_LIMIT_PACKETr, &pkt_rval, PG_HDRM_LIMITf, 4811 TR_MMU_PG_HDRM_LIMIT_PKTS); 4812 PBMP_PORT_ITER(unit, port) { 4813 idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0; 4814 SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_CELLr(unit, port, idx, 4815 cell_rval)); 4816 SOC_IF_ERROR_RETURN(WRITE_PG_HDRM_LIMIT_PACKETr(unit, port, idx, 4817 pkt_rval)); 4818 } 4819 4820 /* Reserved space: Input port per-device headroom */ 4821 cell_rval = 0; 4822 soc_reg_field_set(unit, GLOBAL_HDRM_LIMITr, &cell_rval, GLOBAL_HDRM_LIMITf, 4823 TR_MMU_GLOBAL_HDRM_LIMIT_CELLS); 4824 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_HDRM_LIMITr(unit, cell_rval)); 4825 4826 /* Input port shared space */ 4827 cell_rval = 0; 4828 soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_CELLr, &cell_rval, 4829 TOTAL_SHARED_LIMITf, 4830 total_cells - in_reserved_cells - out_reserved_cells); 4831 SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_CELLr(unit, cell_rval)); 4832 pkt_rval = 0; 4833 soc_reg_field_set(unit, TOTAL_SHARED_LIMIT_PACKETr, &pkt_rval, 4834 TOTAL_SHARED_LIMITf, 4835 total_pkts - in_reserved_pkts - out_reserved_pkts); 4836 SOC_IF_ERROR_RETURN(WRITE_TOTAL_SHARED_LIMIT_PACKETr(unit, pkt_rval)); 4837 4838 /* Input port per-port shared space limit - no limit */ 4839 cell_rval = 0; 4840 soc_reg_field_set(unit, PORT_SHARED_LIMIT_CELLr, &cell_rval, 4841 PORT_SHARED_LIMITf, total_cells - 1); 4842 pkt_rval = 0; 4843 soc_reg_field_set(unit, PORT_SHARED_LIMIT_PACKETr, &pkt_rval, 4844 PORT_SHARED_LIMITf, total_pkts - 1); 4845 PBMP_ALL_ITER(unit, port) { 4846 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_CELLr(unit, port, 4847 cell_rval)); 4848 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMIT_PACKETr(unit, port, 4849 pkt_rval)); 4850 } 4851 4852 /* Input port per-PG reset offset 4853 * Use only 1PG (highest priority PG for the port) 4854 * Use default value 0 for CPU */ 4855 cell_rval = 0; 4856 soc_reg_field_set(unit, PG_RESET_OFFSET_CELLr, &cell_rval, 4857 PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_CELLS); 4858 pkt_rval = 0; 4859 soc_reg_field_set(unit, PG_RESET_OFFSET_PACKETr, &pkt_rval, 4860 PG_RESET_OFFSETf, TR_MMU_PG_RESET_OFFSET_PKTS); 4861 PBMP_PORT_ITER(unit, port) { 4862 idx = SOC_PBMP_MEMBER(pbmp_8pg, port) ? TR_MMU_NUM_PG - 1 : 0; 4863 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_CELLr(unit, port, idx, 4864 cell_rval)); 4865 SOC_IF_ERROR_RETURN(WRITE_PG_RESET_OFFSET_PACKETr(unit, port, idx, 4866 pkt_rval)); 4867 } 4868 4869 /* Input port per-PG reset floor (cell). Use default value 0 */ 4870 4871 /* Reserved space: Input port per-port minimum for SC and QM traffic 4872 * Use default value 0 */ 4873 4874 /* Input port priority XON disable */ 4875 4876 /* Input port max packet size in cells */ 4877 rval0 = 0; 4878 soc_reg_field_set(unit, PORT_MAX_PKT_SIZEr, &rval0, PORT_MAX_PKT_SIZEf, 4879 TR_MMU_JUMBO_FRAME_CELLS); 4880 PBMP_ALL_ITER(unit, port) { 4881 SOC_IF_ERROR_RETURN(WRITE_PORT_MAX_PKT_SIZEr(unit, port, rval0)); 4882 } 4883 4884 /* Input port per-PG threshold */ 4885 rval0 = 0; 4886 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG0_THRESH_SELf, 0x8); 4887 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG1_THRESH_SELf, 0x8); 4888 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG2_THRESH_SELf, 0x8); 4889 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG3_THRESH_SELf, 0x8); 4890 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG4_THRESH_SELf, 0x8); 4891 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG5_THRESH_SELf, 0x8); 4892 soc_reg_field_set(unit, PG_THRESH_SELr, &rval0, PG6_THRESH_SELf, 0x8); 4893 PBMP_ITER(pbmp_8pg, port) { 4894 SOC_IF_ERROR_RETURN(WRITE_PG_THRESH_SELr(unit, port, rval0)); 4895 } 4896 4897 idx = TR_MMU_NUM_PG - 1; 4898 rval0 = 0; 4899 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI0_GRPf, idx); 4900 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI1_GRPf, idx); 4901 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI2_GRPf, idx); 4902 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI3_GRPf, idx); 4903 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI4_GRPf, idx); 4904 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI5_GRPf, idx); 4905 soc_reg_field_set(unit, PORT_PRI_GRP0r, &rval0, PRI6_GRPf, idx); 4906 rval1 = 0; 4907 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI7_GRPf, idx); 4908 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI8_GRPf, idx); 4909 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI9_GRPf, idx); 4910 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI10_GRPf, idx); 4911 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI11_GRPf, idx); 4912 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI12_GRPf, idx); 4913 soc_reg_field_set(unit, PORT_PRI_GRP1r, &rval1, PRI13_GRPf, idx); 4914 PBMP_ITER(pbmp_8pg, port) { 4915 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP0r(unit, port, rval0)); 4916 SOC_IF_ERROR_RETURN(WRITE_PORT_PRI_GRP1r(unit, port, rval1)); 4917 } 4918 4919 /* Input port pause enable */ 4920 COMPILER_64_ZERO(rval64); 4921 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE_64r, &rval64, 4922 PORT_PAUSE_ENABLE_LOf, 4923 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0)); 4924 soc_reg64_field32_set(unit, PORT_PAUSE_ENABLE_64r, &rval64, 4925 PORT_PAUSE_ENABLE_HIf, 4926 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 1)); 4927 SOC_IF_ERROR_RETURN(WRITE_PORT_PAUSE_ENABLE_64r(unit, rval64)); 4928 4929 /* 4930 * Output ports threshold 4931 */ 4932 /* Reserved space: Output port per-port per-COS minimum space */ 4933 cell_rval = 0; 4934 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, Q_MIN_CELLf, 4935 TR_MMU_OUT_PORT_MIN_CELLS); 4936 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 4937 Q_LIMIT_ENABLE_CELLf, 0x1); 4938 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 4939 Q_LIMIT_DYNAMIC_CELLf, 0x1); 4940 soc_reg_field_set(unit, OP_QUEUE_CONFIG_CELLr, &cell_rval, 4941 Q_SHARED_LIMIT_CELLf, 2); /* alpha index 2 */ 4942 pkt_rval = 0; 4943 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, Q_MIN_PACKETf, 4944 TR_MMU_OUT_PORT_MIN_PKTS); 4945 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 4946 Q_LIMIT_ENABLE_PACKETf, 0x1); 4947 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 4948 Q_LIMIT_DYNAMIC_PACKETf, 0x1); 4949 soc_reg_field_set(unit, OP_QUEUE_CONFIG_PACKETr, &pkt_rval, 4950 Q_SHARED_LIMIT_PACKETf, 2); /* alpha index 2 */ 4951 PBMP_ALL_ITER(unit, port) { 4952 count = IS_CPU_PORT(unit, port) ? 4953 SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS; 4954 for (idx = 0; idx < count; idx++) { 4955 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_CELLr(unit, port, idx, 4956 cell_rval)); 4957 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIG_PACKETr(unit, port, idx, 4958 pkt_rval)); 4959 } 4960 } 4961 4962 /* Output port per-port per-COS reset offset */ 4963 cell_rval = 0; 4964 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_CELLr, &cell_rval, 4965 Q_RESET_OFFSET_CELLf, TR_MMU_OUT_RESET_OFFSET_CELLS); 4966 pkt_rval = 0; 4967 soc_reg_field_set(unit, OP_QUEUE_RESET_OFFSET_PACKETr, &pkt_rval, 4968 Q_RESET_OFFSET_PACKETf, TR_MMU_OUT_RESET_OFFSET_PKTS); 4969 PBMP_ALL_ITER(unit, port) { 4970 count = IS_CPU_PORT(unit, port) ? 4971 SOC_INFO(unit).num_cpu_cosq : TR_MMU_NUM_COS; 4972 for (idx = 0; idx < count; idx++) { 4973 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_CELLr(unit, port, 4974 idx, 4975 cell_rval)); 4976 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_RESET_OFFSET_PACKETr(unit, port, 4977 idx, 4978 pkt_rval)); 4979 } 4980 } 4981 4982 out_shared_cells = total_cells - out_reserved_cells; 4983 out_shared_pkts = total_pkts - out_reserved_pkts; 4984 4985 /* Output port per-device shared */ 4986 cell_rval = 0; 4987 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_CELLr, &cell_rval, 4988 OP_BUFFER_SHARED_LIMIT_CELLf, out_shared_cells); 4989 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_CELLr(unit, cell_rval)); 4990 pkt_rval = 0; 4991 soc_reg_field_set(unit, OP_BUFFER_SHARED_LIMIT_PACKETr, &pkt_rval, 4992 OP_BUFFER_SHARED_LIMIT_PACKETf, out_shared_pkts); 4993 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_SHARED_LIMIT_PACKETr(unit, pkt_rval)); 4994 4995 /* Output port per-device shared for YELLOW traffic */ 4996 cell_rval = 0; 4997 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_CELLr, &cell_rval, 4998 OP_BUFFER_LIMIT_YELLOW_CELLf, out_shared_cells >> 3); 4999 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_CELLr(unit, cell_rval)); 5000 pkt_rval = 0; 5001 soc_reg_field_set(unit, OP_BUFFER_LIMIT_YELLOW_PACKETr, &pkt_rval, 5002 OP_BUFFER_LIMIT_YELLOW_PACKETf, out_shared_pkts >> 2); 5003 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_YELLOW_PACKETr(unit, pkt_rval)); 5004 5005 /* Output port per-device shared for RED traffic */ 5006 cell_rval = 0; 5007 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_CELLr, &cell_rval, 5008 OP_BUFFER_LIMIT_RED_CELLf, out_shared_cells >> 3); 5009 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_CELLr(unit, cell_rval)); 5010 pkt_rval = 0; 5011 soc_reg_field_set(unit, OP_BUFFER_LIMIT_RED_PACKETr, &pkt_rval, 5012 OP_BUFFER_LIMIT_RED_PACKETf, out_shared_pkts >> 2); 5013 SOC_IF_ERROR_RETURN(WRITE_OP_BUFFER_LIMIT_RED_PACKETr(unit, pkt_rval)); 5014 5015 /* 5016 * Output port per-port shared 5017 * Limit check disabled, however still keep code as reference 5018 * OP_SHARED_LIMIT set to 3/4 of total shared space 5019 * OP_SHARED_RESET_VALUE set to 1/2 of total shared space 5020 */ 5021 cell_rval = 0; 5022 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 5023 OP_SHARED_LIMIT_CELLf, out_shared_cells * 3 / 4); 5024 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 5025 OP_SHARED_RESET_VALUE_CELLf, out_shared_cells / 2); 5026 soc_reg_field_set(unit, OP_PORT_CONFIG_CELLr, &cell_rval, 5027 PORT_LIMIT_ENABLE_CELLf, 0); 5028 pkt_rval = 0; 5029 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 5030 OP_SHARED_LIMIT_PACKETf, out_shared_pkts * 3 / 4); 5031 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 5032 OP_SHARED_RESET_VALUE_PACKETf, out_shared_pkts / 2); 5033 soc_reg_field_set(unit, OP_PORT_CONFIG_PACKETr, &pkt_rval, 5034 PORT_LIMIT_ENABLE_PACKETf, 0); 5035 PBMP_ALL_ITER(unit, port) { 5036 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_CELLr(unit, port, cell_rval)); 5037 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIG_PACKETr(unit, port, 5038 pkt_rval)); 5039 } 5040 5041 /* Output port per-port shared for YELLOW traffic */ 5042 cell_rval = 0; 5043 soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_CELLr, &cell_rval, 5044 OP_PORT_LIMIT_YELLOW_CELLf, 5045 (out_shared_cells * 3 / 4) >> 3); 5046 pkt_rval = 0; 5047 soc_reg_field_set(unit, OP_PORT_LIMIT_YELLOW_PACKETr, &pkt_rval, 5048 OP_PORT_LIMIT_YELLOW_PACKETf, 5049 (out_shared_pkts * 3 / 4) >> 2); 5050 PBMP_ALL_ITER(unit, port) { 5051 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_CELLr(unit, port, 5052 cell_rval)); 5053 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_YELLOW_PACKETr(unit, port, 5054 pkt_rval)); 5055 } 5056 5057 /* Output port per-port shared for RED traffic */ 5058 cell_rval = 0; 5059 soc_reg_field_set(unit, OP_PORT_LIMIT_RED_CELLr, &cell_rval, 5060 OP_PORT_LIMIT_RED_CELLf, 5061 (out_shared_cells * 3 / 4) >> 3); 5062 pkt_rval = 0; 5063 soc_reg_field_set(unit, OP_PORT_LIMIT_RED_PACKETr, &pkt_rval, 5064 OP_PORT_LIMIT_RED_PACKETf, 5065 (out_shared_pkts * 3 / 4) >> 2); 5066 PBMP_ALL_ITER(unit, port) { 5067 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_CELLr(unit, port, 5068 cell_rval)); 5069 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_LIMIT_RED_PACKETr(unit, port, 5070 pkt_rval)); 5071 } 5072 5073 /* Output port configuration */ 5074 rval0 = 0; 5075 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, 5076 MOP_POLICYf, TR_MMU_MOP_POLICY); 5077 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval0, 5078 SOP_POLICYf, TR_MMU_SOP_POLICY); 5079 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval0)); 5080 5081 /* Input port enable */ 5082 COMPILER_64_ZERO(rval64); 5083 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE_64r, &rval64, 5084 INPUT_PORT_RX_ENABLE_LOf, 5085 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0)); 5086 soc_reg64_field32_set(unit, INPUT_PORT_RX_ENABLE_64r, &rval64, 5087 INPUT_PORT_RX_ENABLE_HIf, 5088 SOC_PBMP_WORD_GET(PBMP_ALL(unit), 1)); 5089 SOC_IF_ERROR_RETURN(WRITE_INPUT_PORT_RX_ENABLE_64r(unit, rval64)); 5090 SOC_IF_ERROR_RETURN(WRITE_OUTPUT_PORT_RX_ENABLE_64r(unit, rval64)); 5091 5092 /* init ESM */ 5093 SOC_IF_ERROR_RETURN(READ_IESMIF_CONTROLr(unit, &rval0)); 5094 soc_reg_field_set(unit, IESMIF_CONTROLr, &rval0, EN_EXT_SEARCH_REQf, 0); 5095 SOC_IF_ERROR_RETURN(WRITE_IESMIF_CONTROLr(unit, rval0)); 5096 if (soc_feature(unit, soc_feature_esm_support)) { 5097 /* 5098 * FP_LOCK is taken to synchronize Counter thread counter collection 5099 * where counter thread collects counters in external memory and 5100 * soc_mmu_init() which reintializes counters in external mmeory too. 5101 */ 5102 if (NULL != SOC_CONTROL(unit)->fp_lock) { 5103 sal_mutex_take(SOC_CONTROL(unit)->fp_lock, sal_mutex_FOREVER); 5104 } 5105 /* coverity[stack_use_callee] */ 5106 /* coverity[stack_use_overflow] */ 5107 rv = soc_triumph_esm_init(unit); 5108 5109 if (NULL != SOC_CONTROL(unit)->fp_lock) { 5110 sal_mutex_give(SOC_CONTROL(unit)->fp_lock); 5111 } 5112 5113 SOC_IF_ERROR_RETURN(rv); 5114 } 5115 5116 /* init dual modid */ 5117 if ((NUM_MODID(unit) == 2) && 5118 (SOC_REG_IS_VALID(unit, E2EFC_CONFIGr)) ) { 5119 SOC_IF_ERROR_RETURN(READ_E2EFC_CONFIGr(unit, &rval0)); 5120 soc_reg_field_set(unit, E2EFC_CONFIGr, &rval0, DUAL_MODID_ENf, 1); 5121 SOC_IF_ERROR_RETURN(WRITE_E2EFC_CONFIGr(unit, rval0)); 5122 } 5123 5124 return SOC_E_NONE; 5125 } 5126 5127 int 5128 soc_triumph_age_timer_get(int unit, int *age_seconds, int *enabled) 5129 { 5130 uint32 value; 5131 5132 SOC_IF_ERROR_RETURN(READ_L2_AGE_TIMERr(unit, &value)); 5133 *enabled = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_ENAf); 5134 *age_seconds = soc_reg_field_get(unit, L2_AGE_TIMERr, value, AGE_VALf); 5135 5136 return SOC_E_NONE; 5137 } 5138 5139 int 5140 soc_triumph_age_timer_max_get(int unit, int *max_seconds) 5141 { 5142 *max_seconds = 5143 soc_reg_field_get(unit, L2_AGE_TIMERr, 0xffffffff, AGE_VALf); 5144 5145 return SOC_E_NONE; 5146 } 5147 5148 int 5149 soc_triumph_ext_age_timer_set(int unit, int age_seconds, int enable) 5150 { 5151 uint32 rval; 5152 int num_entries; 5153 5154 num_entries = soc_mem_index_count(unit, EXT_L2_ENTRYm); 5155 if (num_entries > 0) { 5156 /* Disable refresh pulse to ESM */ 5157 SOC_IF_ERROR_RETURN 5158 (soc_reg_field32_modify(unit, AUX_ARB_CONTROL_2r, REG_PORT_ANY, 5159 ESM_AGE_ENABLEf, 0)); 5160 5161 /* 5162 * ESM background process marches through all entries at 5163 * rate of ESM_AGE_CNT.COUNT * 8 ns. The background process 5164 * clears the hit bit of the entry at the first visit and ages 5165 * out entry on second visit. 5166 * age time = 2 * count * 8 ns * number of ext_l2_entry entries */ 5167 rval = 0; 5168 soc_reg_field_set(unit, ESM_AGE_CNTr, &rval, COUNTf, 5169 age_seconds * (1000000000 / 8 / 5170 num_entries)); 5171 SOC_IF_ERROR_RETURN(WRITE_ESM_AGE_CNTr(unit, rval)); 5172 5173 SOC_IF_ERROR_RETURN 5174 (soc_reg_field32_modify(unit, ESM_L2_AGE_CTLr, REG_PORT_ANY, 5175 HW_AGE_MODEf, enable ? 2 : 0)); 5176 5177 /* Re-enable refresh pulse to ESM */ 5178 SOC_IF_ERROR_RETURN 5179 (soc_reg_field32_modify(unit, AUX_ARB_CONTROL_2r, REG_PORT_ANY, 5180 ESM_AGE_ENABLEf, 1)); 5181 } 5182 5183 return SOC_E_NONE; 5184 } 5185 5186 int 5187 soc_triumph_age_timer_set(int unit, int age_seconds, int enable) 5188 { 5189 uint32 rval; 5190 5191 rval = 0; 5192 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_ENAf, enable ? 1 : 0); 5193 soc_reg_field_set(unit, L2_AGE_TIMERr, &rval, AGE_VALf, age_seconds); 5194 SOC_IF_ERROR_RETURN(WRITE_L2_AGE_TIMERr(unit, rval)); 5195 5196 if (soc_feature(unit, soc_feature_esm_support)) { 5197 soc_triumph_ext_age_timer_set(unit, age_seconds, enable); 5198 } 5199 5200 return SOC_E_NONE; 5201 } 5202 5203 int 5204 soc_triumph_tcam_access(int unit, int op_type, int num_inst, int num_pre_nop, 5205 int num_post_nop, uint32 *dbus, int *ibus) 5206 { 5207 uint32 cfg, rval0, rval1, rval2, status; 5208 int rv, i, retry, num_pad_entries; 5209 et_uinst_mem_entry_t uinst_entry; 5210 uint32 always_drive_dbus; 5211 5212 SOC_IF_ERROR_RETURN(WRITE_ETU_ET_INST_REQr(unit, 0)); 5213 5214 always_drive_dbus = FALSE; 5215 num_pad_entries = 0; 5216 if (soc_feature(unit, soc_feature_always_drive_dbus) && 5217 op_type == TCAM_TR_OP_READ) { 5218 always_drive_dbus = TRUE; 5219 5220 /* Add 4 extra NOP in front of any read as workaround */ 5221 num_pad_entries = 2; 5222 sal_memset(&uinst_entry, 0, sizeof(uinst_entry)); 5223 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, DOE0f, 1); 5224 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, DOE1f, 1); 5225 for (i = 0; i < num_pad_entries; i++) { 5226 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ET_UINST_MEMm, 5227 MEM_BLOCK_ANY, i, &uinst_entry)); 5228 } 5229 } 5230 5231 for (i = 0; i < num_inst;) { 5232 sal_memset(&uinst_entry, 0, sizeof(uinst_entry)); 5233 5234 if (i + 1 < num_inst) { 5235 if (ibus[i] <= 0xff) { 5236 soc_mem_field_set(unit, ET_UINST_MEMm, (uint32 *)&uinst_entry, 5237 DBUS0f, &dbus[i * TCAM_TR_WORDS_PER_ENTRY]); 5238 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, DOE0f, 5239 1); 5240 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, IBUS0f, 5241 ibus[i]); 5242 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_VERBOSE)) { 5243 LOG_CLI((BSL_META_U(unit, 5244 "IBUS0: %08x DBUS0: %08x %08x %08x\n"), 5245 ibus[i], 5246 dbus[i * TCAM_TR_WORDS_PER_ENTRY], 5247 dbus[i * TCAM_TR_WORDS_PER_ENTRY + 1], 5248 dbus[i * TCAM_TR_WORDS_PER_ENTRY + 2])); 5249 } 5250 } 5251 i++; 5252 } 5253 5254 if (ibus[i] <= 0xff) { 5255 soc_mem_field_set(unit, ET_UINST_MEMm, (uint32 *)&uinst_entry, 5256 DBUS1f, &dbus[i * TCAM_TR_WORDS_PER_ENTRY]); 5257 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, DOE1f, 1); 5258 soc_mem_field32_set(unit, ET_UINST_MEMm, &uinst_entry, IBUS1f, 5259 ibus[i]); 5260 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_VERBOSE)) { 5261 LOG_CLI((BSL_META_U(unit, 5262 "IBUS1: %08x DBUS1: %08x %08x %08x\n"), 5263 ibus[i], 5264 dbus[i * TCAM_TR_WORDS_PER_ENTRY], 5265 dbus[i * TCAM_TR_WORDS_PER_ENTRY + 1], 5266 dbus[i * TCAM_TR_WORDS_PER_ENTRY + 2])); 5267 } 5268 } 5269 i++; 5270 5271 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_VERBOSE)) { 5272 LOG_CLI((BSL_META_U(unit, 5273 "UINST %d: %08x %08x %08x %08x %08x %08x\n"), 5274 (i - 1)/ 2, 5275 ((uint32 *)&uinst_entry)[0], 5276 ((uint32 *)&uinst_entry)[1], 5277 ((uint32 *)&uinst_entry)[2], 5278 ((uint32 *)&uinst_entry)[3], 5279 ((uint32 *)&uinst_entry)[4], 5280 ((uint32 *)&uinst_entry)[5])); 5281 } 5282 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ET_UINST_MEMm, MEM_BLOCK_ANY, 5283 (i - 1) / 2 + num_pad_entries, 5284 &uinst_entry)); 5285 } 5286 5287 if (always_drive_dbus) { 5288 SOC_IF_ERROR_RETURN(READ_ETU_DDR72_CONFIG_REG3_ISr(unit, &cfg)); 5289 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &cfg, 5290 ALWAYS_DRIVE_DBUSf, 0); 5291 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG3_ISr(unit, cfg)); 5292 } 5293 5294 rval0 = 0; 5295 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval0, STARTf, 1); 5296 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval0, OP_TYPf, op_type); 5297 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval0, NUM_PST_DNOPSf, 5298 num_post_nop); 5299 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval0, NUM_PRE_DNOPSf, 5300 num_pre_nop); 5301 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval0, NUM_INST_DOPSf, 5302 ((num_inst + 1) / 2 + num_pad_entries) & 0x03); 5303 5304 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_VERBOSE)) { 5305 LOG_CLI((BSL_META_U(unit, 5306 "INST_REQ: %08x\n"), rval0)); 5307 } 5308 5309 rv = WRITE_ETU_ET_INST_REQr(unit, rval0); 5310 if (SOC_SUCCESS(rv)) { 5311 for (retry = 10; retry; retry--) { 5312 rv = READ_ETU_ET_INST_STATUSr(unit, &status); 5313 if (SOC_FAILURE(rv)) { 5314 break; 5315 } 5316 if (soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, DONEf)) { 5317 break; 5318 } 5319 5320 sal_usleep(100000); 5321 } 5322 if (!retry) { 5323 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_INFO)) { 5324 LOG_CLI((BSL_META_U(unit, 5325 "soc_triumph_tcam_access: Instruction timeout\n"))); 5326 } 5327 rv = SOC_E_TIMEOUT; 5328 } 5329 } 5330 5331 if (always_drive_dbus) { 5332 soc_reg_field_set(unit, ETU_DDR72_CONFIG_REG3_ISr, &cfg, 5333 ALWAYS_DRIVE_DBUSf, 1); 5334 SOC_IF_ERROR_RETURN(WRITE_ETU_DDR72_CONFIG_REG3_ISr(unit, cfg)); 5335 } 5336 5337 if (SOC_FAILURE(rv)) { 5338 return rv; 5339 } 5340 5341 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_VERBOSE)) { 5342 LOG_CLI((BSL_META_U(unit, 5343 "INST_STAT: %08x\n"), status)); 5344 } 5345 5346 switch (op_type) { 5347 case TCAM_TR_OP_WRITE: 5348 break; 5349 5350 case TCAM_TR_OP_READ: 5351 if (!SOC_WARM_BOOT(unit) && 5352 !soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, RDACKf)) { 5353 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_INFO)) { 5354 LOG_CLI((BSL_META_U(unit, 5355 "soc_triumph_tcam_access: No rdack\n"))); 5356 } 5357 return SOC_E_NOT_FOUND; 5358 } 5359 5360 SOC_IF_ERROR_RETURN(READ_ETU_RSLT_DAT0r(unit, &rval0)); 5361 SOC_IF_ERROR_RETURN(READ_ETU_RSLT_DAT1r(unit, &rval1)); 5362 SOC_IF_ERROR_RETURN(READ_ETU_RSLT_DAT2r(unit, &rval2)); 5363 dbus[0] = rval0; 5364 dbus[1] = rval1; 5365 dbus[2] = rval2 & 0xff; 5366 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_INFO)) { 5367 LOG_CLI((BSL_META_U(unit, 5368 "READ: RSLT_DAT: %08x %08x %08x\n"), 5369 rval0, rval1, rval2)); 5370 } 5371 break; 5372 5373 case TCAM_TR_OP_SINGLE_SEARCH1: 5374 case TCAM_TR_OP_SINGLE_SEARCH0: 5375 case TCAM_TR_OP_PARALLEL_SEARCH: 5376 rval0 = 0xffffffff; 5377 rval1 = 0xffffffff; 5378 if ((op_type == TCAM_TR_OP_SINGLE_SEARCH0 || 5379 op_type == TCAM_TR_OP_PARALLEL_SEARCH) && 5380 soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5381 RBUS0_VALIDf) && 5382 soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5383 RBUS0_HITf) == 3 && 5384 !soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5385 RBUS0_PERRf) && 5386 !soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5387 SEQ_DPEO_ERRf)) { 5388 SOC_IF_ERROR_RETURN(READ_ETU_SEARCH0_RESULTr(unit, &rval0)); 5389 rval0 = soc_reg_field_get(unit, ETU_SEARCH0_RESULTr, rval0, RBUSf); 5390 } 5391 5392 if ((op_type == TCAM_TR_OP_SINGLE_SEARCH1 || 5393 op_type == TCAM_TR_OP_PARALLEL_SEARCH) && 5394 soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5395 RBUS1_VALIDf) && 5396 soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5397 RBUS1_HITf) == 3 && 5398 !soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5399 RBUS1_PERRf) && 5400 !soc_reg_field_get(unit, ETU_ET_INST_STATUSr, status, 5401 SEQ_DPEO_ERRf)) { 5402 SOC_IF_ERROR_RETURN(READ_ETU_SEARCH1_RESULTr(unit, &rval1)); 5403 rval1 = soc_reg_field_get(unit, ETU_SEARCH1_RESULTr, rval1, RBUSf); 5404 } 5405 5406 if (rval0 == 0xffffffff && rval1 == 0xffffffff) { 5407 return SOC_E_NOT_FOUND; 5408 } 5409 5410 dbus[0] = rval0; 5411 dbus[1] = rval1; 5412 if (LOG_CHECK(BSL_LS_SOC_TCAM | BSL_INFO)) { 5413 LOG_CLI((BSL_META_U(unit, 5414 "SEARCH: RESULT_RESULT: %08x %08x\n"), 5415 rval0, rval1)); 5416 } 5417 break; 5418 5419 default: 5420 return SOC_E_PARAM; 5421 } 5422 5423 return SOC_E_NONE; 5424 } 5425 5426 int 5427 soc_triumph_tcam_search_bist(int unit, int part0, int part1, uint32 *data, 5428 int index0, int index1, int loop_count) 5429 { 5430 uint32 rval; 5431 int rv, result0, result1; 5432 5433 rval = 0; 5434 if (part0 != TCAM_PARTITION_RAW) { 5435 soc_reg_field_set(unit, ETU_LTE_BIST_REF_SEARCH0r, &rval, RBUSf, 5436 index0); 5437 soc_reg_field_set(unit, ETU_LTE_BIST_REF_SEARCH0r, &rval, HITf, 3); 5438 } 5439 SOC_IF_ERROR_RETURN(WRITE_ETU_LTE_BIST_REF_SEARCH0r(unit, rval)); 5440 5441 rval = 0; 5442 if (part1 != TCAM_PARTITION_RAW) { 5443 soc_reg_field_set(unit, ETU_LTE_BIST_REF_SEARCH1r, &rval, RBUSf, 5444 index1); 5445 soc_reg_field_set(unit, ETU_LTE_BIST_REF_SEARCH1r, &rval, HITf, 3); 5446 } 5447 SOC_IF_ERROR_RETURN(WRITE_ETU_LTE_BIST_REF_SEARCH1r(unit, rval)); 5448 5449 rval = 0; 5450 soc_reg_field_set(unit, ETU_LTE_BIST_CTLr, &rval, RD_EN_BIST_RSLTSf, 1); 5451 if (loop_count != -1) { 5452 soc_reg_field_set(unit, ETU_LTE_BIST_CTLr, &rval, LOOP_COUNTf, 5453 loop_count); 5454 } 5455 SOC_IF_ERROR_RETURN(WRITE_ETU_LTE_BIST_CTLr(unit, rval)); 5456 5457 rv = soc_tcam_search_entry(unit, part0, part1, data, &result0, &result1); 5458 5459 if (SOC_SUCCESS(rv)) { 5460 rv = READ_ETU_LTE_BIST_STATUSr(unit, &rval); 5461 if (SOC_SUCCESS(rv)) { 5462 rv = rval ? SOC_E_FAIL : SOC_E_NONE; 5463 } 5464 } 5465 5466 /* disable BIST */ 5467 rval = 0; 5468 soc_reg_field_set(unit, ETU_LTE_BIST_CTLr, &rval, RD_EN_BIST_RSLTSf, 0); 5469 soc_reg_field_set(unit, ETU_LTE_BIST_CTLr, &rval, LOOP_COUNTf, 1); 5470 SOC_IF_ERROR_RETURN(WRITE_ETU_LTE_BIST_CTLr(unit, rval)); 5471 5472 return rv; 5473 } 5474 5475 typedef struct tr_sram_bist_regs_s { 5476 soc_reg_t mode; 5477 soc_reg_t lte_d0r_0; 5478 soc_reg_t lte_d0r_1; 5479 soc_reg_t lte_d0f_0; 5480 soc_reg_t lte_d0f_1; 5481 soc_reg_t lte_d1r_0; 5482 soc_reg_t lte_d1r_1; 5483 soc_reg_t lte_d1f_0; 5484 soc_reg_t lte_d1f_1; 5485 soc_reg_t lte_adr0 ; 5486 soc_reg_t lte_adr1 ; 5487 soc_reg_t lte_tmode0; 5488 soc_reg_t lte_tmode1; 5489 soc_reg_t lte_sts_done; 5490 soc_reg_t lte_sts_err_adr; 5491 soc_reg_t lte_sts_err_dr_0; 5492 soc_reg_t lte_sts_err_dr_1; 5493 soc_reg_t lte_sts_err_df_0; 5494 soc_reg_t lte_sts_err_df_1; 5495 } tr_sram_bist_regs_t; 5496 5497 STATIC const tr_sram_bist_regs_t tr_sram_bist_regs[2] = { 5498 { 5499 ES0_DTU_MODEr, 5500 ES0_DTU_LTE_D0R_0r, 5501 ES0_DTU_LTE_D0R_1r, 5502 ES0_DTU_LTE_D0F_0r, 5503 ES0_DTU_LTE_D0F_1r, 5504 ES0_DTU_LTE_D1R_0r, 5505 ES0_DTU_LTE_D1R_1r, 5506 ES0_DTU_LTE_D1F_0r, 5507 ES0_DTU_LTE_D1F_1r, 5508 ES0_DTU_LTE_ADR0r, 5509 ES0_DTU_LTE_ADR1r, 5510 ES0_DTU_LTE_TMODE0r, 5511 ES0_DTU_LTE_TMODE1r, 5512 ES0_DTU_LTE_STS_DONEr, 5513 ES0_DTU_LTE_STS_ERR_ADRr, 5514 ES0_DTU_LTE_STS_ERR_DR_0r, 5515 ES0_DTU_LTE_STS_ERR_DR_1r, 5516 ES0_DTU_LTE_STS_ERR_DF_0r, 5517 ES0_DTU_LTE_STS_ERR_DF_1r, 5518 }, 5519 { 5520 ES1_DTU_MODEr, 5521 ES1_DTU_LTE_D0R_0r, 5522 ES1_DTU_LTE_D0R_1r, 5523 ES1_DTU_LTE_D0F_0r, 5524 ES1_DTU_LTE_D0F_1r, 5525 ES1_DTU_LTE_D1R_0r, 5526 ES1_DTU_LTE_D1R_1r, 5527 ES1_DTU_LTE_D1F_0r, 5528 ES1_DTU_LTE_D1F_1r, 5529 ES1_DTU_LTE_ADR0r, 5530 ES1_DTU_LTE_ADR1r, 5531 ES1_DTU_LTE_TMODE0r, 5532 ES1_DTU_LTE_TMODE1r, 5533 ES1_DTU_LTE_STS_DONEr, 5534 ES1_DTU_LTE_STS_ERR_ADRr, 5535 ES1_DTU_LTE_STS_ERR_DR_0r, 5536 ES1_DTU_LTE_STS_ERR_DR_1r, 5537 ES1_DTU_LTE_STS_ERR_DF_0r, 5538 ES1_DTU_LTE_STS_ERR_DF_1r, 5539 } 5540 }; 5541 5542 int 5543 soc_triumph_ext_sram_enable_set(int unit, int intf_num, int enable, 5544 int clear_status) 5545 { 5546 const tr_sram_bist_regs_t *bist_regs; 5547 soc_reg_t reg; 5548 uint32 reg_addr, orval, rval; 5549 5550 if (intf_num < 0 || intf_num > 1) { 5551 return SOC_E_PARAM; 5552 } 5553 bist_regs = &tr_sram_bist_regs[intf_num]; 5554 5555 /* Enable/disable LTE - lab test engine */ 5556 reg = bist_regs->mode; 5557 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5558 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5559 orval = rval; 5560 soc_reg_field_set(unit, reg, &rval, DTU_ENf, enable ? 1 : 0); 5561 soc_reg_field_set(unit, reg, &rval, SEL_LTEf, enable ? 1 : 0); 5562 if (rval != orval) { 5563 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5564 } 5565 5566 /* Clear status */ 5567 if (clear_status) { 5568 reg = bist_regs->lte_tmode0; 5569 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5570 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5571 soc_reg_field_set(unit, reg, &rval, START_LAB_TESTf, 0); 5572 soc_reg_field_set(unit, reg, &rval, CLR_STATUSf, 1); 5573 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5574 } 5575 5576 return SOC_E_NONE; 5577 } 5578 5579 /* Setup (but not yet start) BIST on specified SRAM module */ 5580 int 5581 soc_triumph_ext_sram_bist_setup(int unit, int intf_num, 5582 tr_ext_sram_bist_t *sram_bist) 5583 { 5584 const tr_sram_bist_regs_t *bist_regs; 5585 soc_reg_t reg; 5586 uint32 reg_addr, orval, rval; 5587 5588 if (intf_num < 0 || intf_num > 1) { 5589 return SOC_E_PARAM; 5590 } 5591 bist_regs = &tr_sram_bist_regs[intf_num]; 5592 5593 /* Program optional data registers */ 5594 if (sram_bist->d0r_0 != 0xffffffff) { 5595 rval = 0; 5596 soc_reg_field_set(unit, bist_regs->lte_d0r_0, &rval, DTU_LTE_D0R_0f, 5597 sram_bist->d0r_0); 5598 reg_addr = soc_reg_addr(unit, bist_regs->lte_d0r_0, REG_PORT_ANY, 0); 5599 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5600 5601 rval = 0; 5602 soc_reg_field_set(unit, bist_regs->lte_d0r_1, &rval, DTU_LTE_D0R_1f, 5603 sram_bist->d0r_1); 5604 reg_addr = soc_reg_addr(unit, bist_regs->lte_d0r_1, REG_PORT_ANY, 0); 5605 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5606 5607 rval = 0; 5608 soc_reg_field_set(unit, bist_regs->lte_d0f_0, &rval, DTU_LTE_D0F_0f, 5609 sram_bist->d0f_0); 5610 reg_addr = soc_reg_addr(unit, bist_regs->lte_d0f_0, REG_PORT_ANY, 0); 5611 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5612 5613 rval = 0; 5614 soc_reg_field_set(unit, bist_regs->lte_d0f_1, &rval, DTU_LTE_D0F_1f, 5615 sram_bist->d0f_1); 5616 reg_addr = soc_reg_addr(unit, bist_regs->lte_d0f_1, REG_PORT_ANY, 0); 5617 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5618 } 5619 if (sram_bist->d1r_0 != 0xffffffff) { 5620 rval = 0; 5621 soc_reg_field_set(unit, bist_regs->lte_d1r_0, &rval, DTU_LTE_D1R_0f, 5622 sram_bist->d1r_0); 5623 reg_addr = soc_reg_addr(unit, bist_regs->lte_d1r_0, REG_PORT_ANY, 0); 5624 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5625 5626 rval = 0; 5627 soc_reg_field_set(unit, bist_regs->lte_d1r_1, &rval, DTU_LTE_D1R_1f, 5628 sram_bist->d1r_1); 5629 reg_addr = soc_reg_addr(unit, bist_regs->lte_d1r_1, REG_PORT_ANY, 0); 5630 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5631 5632 rval = 0; 5633 soc_reg_field_set(unit, bist_regs->lte_d1f_0, &rval, DTU_LTE_D1F_0f, 5634 sram_bist->d1f_0); 5635 reg_addr = soc_reg_addr(unit, bist_regs->lte_d1f_0, REG_PORT_ANY, 0); 5636 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5637 5638 rval = 0; 5639 soc_reg_field_set(unit, bist_regs->lte_d1f_1, &rval, DTU_LTE_D1F_1f, 5640 sram_bist->d1f_1); 5641 reg_addr = soc_reg_addr(unit, bist_regs->lte_d1f_1, REG_PORT_ANY, 0); 5642 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5643 } 5644 5645 /* Program optional address registers */ 5646 if (sram_bist->adr0 != -1) { 5647 rval = 0; 5648 soc_reg_field_set(unit, bist_regs->lte_adr0, &rval, DTU_LTE_ADR0f, 5649 sram_bist->adr0); 5650 reg_addr = soc_reg_addr(unit, bist_regs->lte_adr0, REG_PORT_ANY, 0); 5651 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5652 } 5653 if (sram_bist->adr1 != -1) { 5654 rval = 0; 5655 soc_reg_field_set(unit, bist_regs->lte_adr1, &rval, DTU_LTE_ADR1f, 5656 sram_bist->adr1); 5657 reg_addr = soc_reg_addr(unit, bist_regs->lte_adr1, REG_PORT_ANY, 0); 5658 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5659 } 5660 5661 /* Program optional TMODE1 register */ 5662 if (sram_bist->wdoebr != -1) { 5663 reg = bist_regs->lte_tmode1; 5664 rval = 0; 5665 soc_reg_field_set(unit, reg, &rval, WDOEBRf, sram_bist->wdoebr); 5666 soc_reg_field_set(unit, reg, &rval, WDOEBFf, sram_bist->wdoebf); 5667 soc_reg_field_set(unit, reg, &rval, WDMRf, sram_bist->wdmr); 5668 soc_reg_field_set(unit, reg, &rval, WDMFf, sram_bist->wdmf); 5669 soc_reg_field_set(unit, reg, &rval, RDMRf, sram_bist->rdmr); 5670 soc_reg_field_set(unit, reg, &rval, RDMFf, sram_bist->rdmf); 5671 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5672 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5673 } 5674 5675 /* Program TMODE0 register */ 5676 reg = bist_regs->lte_tmode0; 5677 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5678 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5679 orval = rval; 5680 soc_reg_field_set(unit, reg, &rval, CLR_STATUSf, 0); 5681 soc_reg_field_set(unit, reg, &rval, LOOP_MODEf, sram_bist->loop_mode); 5682 soc_reg_field_set(unit, reg, &rval, ADR_MODEf, sram_bist->adr_mode); 5683 soc_reg_field_set(unit, reg, &rval, CMP_EM_RDAT_FRf, 5684 sram_bist->cmp_em_rdat_fr); 5685 if (sram_bist->em_latency != -1) { 5686 soc_reg_field_set(unit, reg, &rval, EM_LATENCYf, 5687 sram_bist->em_latency & 0x7); 5688 if (soc_reg_field_valid(unit, reg, EM_LATENCY8f)) { 5689 soc_reg_field_set(unit, reg, &rval, EM_LATENCY8f, 5690 sram_bist->em_latency >> 3); 5691 } 5692 } 5693 if (sram_bist->w2r_nops != -1) { 5694 soc_reg_field_set(unit, reg, &rval, W2R_NOPSf, sram_bist->w2r_nops); 5695 } 5696 if (sram_bist->r2w_nops != -1) { 5697 soc_reg_field_set(unit, reg, &rval, R2W_NOPSf, sram_bist->r2w_nops); 5698 } 5699 if (rval != orval) { 5700 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5701 } 5702 5703 return SOC_E_NONE; 5704 } 5705 5706 int 5707 soc_triumph_ext_sram_op(int unit, int intf_num, tr_ext_sram_bist_t *sram_bist, 5708 tr_ext_sram_bist_t *opt_sram_bist) 5709 { 5710 soc_tcam_info_t *tcam_info; 5711 const tr_sram_bist_regs_t *bist_regs[2]; 5712 tr_ext_sram_bist_t *bist_ptr; 5713 soc_timeout_t to; 5714 int to_usec; 5715 soc_reg_t reg; 5716 uint32 reg_addr, rval; 5717 int rv, rv1, i; 5718 5719 tcam_info = SOC_CONTROL(unit)->tcam_info; 5720 5721 if (intf_num < 0 || intf_num > 1) { 5722 return SOC_E_PARAM; 5723 } 5724 bist_regs[0] = &tr_sram_bist_regs[intf_num]; 5725 if (opt_sram_bist != NULL) { 5726 bist_regs[1] = &tr_sram_bist_regs[intf_num ^ 1]; 5727 } 5728 5729 if (SAL_BOOT_QUICKTURN) { 5730 to_usec = 60000000; 5731 } else { 5732 to_usec = 50000; 5733 } 5734 5735 if (opt_sram_bist != NULL) { 5736 /* Kick off the optional BIST on the other SRAM interface */ 5737 reg = bist_regs[1]->lte_tmode0; 5738 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5739 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5740 soc_reg_field_set(unit, reg, &rval, START_LAB_TESTf, 1); 5741 soc_reg_field_set(unit, reg, &rval, FOREVERf, 1); 5742 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5743 } 5744 5745 /* Kick off the BIST on the target SRAM interface */ 5746 reg = bist_regs[0]->lte_tmode0; 5747 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5748 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5749 soc_reg_field_set(unit, reg, &rval, START_LAB_TESTf, 1); 5750 if (sram_bist->bg_tcam_loop_count > 1) { 5751 soc_reg_field_set(unit, reg, &rval, FOREVERf, 1); 5752 } 5753 SOC_IF_ERROR_RETURN(soc_reg32_write(unit, reg_addr, rval)); 5754 5755 rv = SOC_E_NONE; 5756 if (sram_bist->bg_tcam_loop_count > 1) { 5757 /* Kick off the optional BIST on TCAM interface */ 5758 rval = 0; 5759 soc_reg_field_set(unit, ETU_ET_INST_REQr, &rval, STARTf, 1); 5760 SOC_IF_ERROR_RETURN(WRITE_ETU_ET_INST_REQr(unit, rval)); 5761 5762 /* BIST should have already finished if loop count is small */ 5763 if (sram_bist->bg_tcam_loop_count > 200) { 5764 /* loop_count * 8 instrction / freq */ 5765 sal_udelay(sram_bist->bg_tcam_loop_count * 8 / 5766 tcam_info->tcam_freq); 5767 } 5768 5769 /* Wait until TCAM interface BIST done */ 5770 soc_timeout_init(&to, to_usec, 0); 5771 while (1) { 5772 rv = READ_ETU_ET_INST_STATUSr(unit, &rval); 5773 if (SOC_FAILURE(rv)) { 5774 break; 5775 } 5776 if (soc_reg_field_get(unit, ETU_ET_INST_STATUSr, rval, DONEf)) { 5777 break; 5778 } 5779 if (soc_timeout_check(&to)) { 5780 rv = SOC_E_TIMEOUT; 5781 break; 5782 } 5783 } 5784 5785 /* Remove the target SRAM interface from forever mode */ 5786 rv1 = soc_reg32_read(unit, reg_addr, &rval); 5787 if (SOC_SUCCESS(rv1)) { 5788 soc_reg_field_set(unit, reg, &rval, FOREVERf, 0); 5789 } else { 5790 rval = 0; 5791 } 5792 rv1 = soc_reg32_write(unit, reg_addr, rval); 5793 } 5794 5795 if (opt_sram_bist != NULL) { 5796 /* Remove the other SRAM interface from forever mode */ 5797 reg = bist_regs[1]->lte_tmode0; 5798 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5799 rv1 = soc_reg32_read(unit, reg_addr, &rval); 5800 if (SOC_SUCCESS(rv1)) { 5801 soc_reg_field_set(unit, reg, &rval, FOREVERf, 0); 5802 } else { 5803 rval = 0; 5804 } 5805 rv1 = soc_reg32_write(unit, reg_addr, rval); 5806 } 5807 5808 if (SOC_FAILURE(rv)) { 5809 return rv; 5810 } 5811 5812 for (i = 0; i < (opt_sram_bist != NULL ? 2 : 1); i++) { 5813 bist_ptr = i == 0 ? sram_bist : opt_sram_bist; 5814 5815 /* Wait until BIST done on SRAM interface */ 5816 soc_timeout_init(&to, to_usec, 0); 5817 reg = bist_regs[i]->lte_sts_done; 5818 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5819 while (1) { 5820 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5821 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 5822 break; 5823 } 5824 if (soc_timeout_check(&to)) { 5825 return SOC_E_TIMEOUT; 5826 } 5827 } 5828 bist_ptr->err_cnt = soc_reg_field_get(unit, reg, rval, ERR_CNTf); 5829 bist_ptr->err_bitmap = soc_reg_field_get(unit, reg, rval, ERR_BITMAPf); 5830 5831 if (bist_ptr->err_cnt || bist_ptr->err_bitmap) { 5832 reg = bist_regs[i]->lte_sts_err_adr; 5833 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5834 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5835 bist_ptr->err_adr = soc_reg_field_get(unit, reg, rval, ERR_ADRf); 5836 5837 reg = bist_regs[i]->lte_sts_err_dr_0; 5838 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5839 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5840 bist_ptr->err_dr_0 = soc_reg_field_get(unit, reg, rval, ERR_DR_0f); 5841 5842 reg = bist_regs[i]->lte_sts_err_dr_1; 5843 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5844 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5845 bist_ptr->err_dr_1 = soc_reg_field_get(unit, reg, rval, ERR_DR_1f); 5846 5847 reg = bist_regs[i]->lte_sts_err_df_0; 5848 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5849 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5850 bist_ptr->err_df_0 = soc_reg_field_get(unit, reg, rval, ERR_DF_0f); 5851 5852 reg = bist_regs[i]->lte_sts_err_df_1; 5853 reg_addr = soc_reg_addr(unit, reg, REG_PORT_ANY, 0); 5854 SOC_IF_ERROR_RETURN(soc_reg32_read(unit, reg_addr, &rval)); 5855 bist_ptr->err_df_1 = soc_reg_field_get(unit, reg, rval, ERR_DF_1f); 5856 } 5857 } 5858 5859 return SOC_E_NONE; 5860 } 5861 5862 int 5863 soc_triumph_l2x_to_ext_l2(int unit, l2x_entry_t *l2x_entry, 5864 ext_l2_entry_entry_t *ext_l2_entry) 5865 { 5866 sal_mac_addr_t mac; 5867 uint32 fval; 5868 5869 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, VLAN_IDf); 5870 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, VLAN_IDf, fval); 5871 5872 soc_mem_mac_addr_get(unit, L2Xm, l2x_entry, MAC_ADDRf, mac); 5873 soc_mem_mac_addr_set(unit, EXT_L2_ENTRYm, ext_l2_entry, MAC_ADDRf, mac); 5874 5875 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, KEY_TYPEf); 5876 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, KEY_TYPE_VFIf, 5877 fval == 3 ? 1 : 0); 5878 5879 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, DESTINATIONf); 5880 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, DESTINATIONf, fval); 5881 5882 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, DEST_TYPEf); 5883 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, DEST_TYPEf, fval); 5884 5885 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, CLASS_IDf); 5886 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, CLASS_IDf, fval); 5887 5888 5889 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, RPEf); 5890 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, RPEf, fval); 5891 5892 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, MIRRORf); 5893 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, MIRRORf, fval); 5894 5895 if (SOC_MEM_FIELD_VALID(unit, L2Xm, MIRROR1f)) { 5896 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, MIRROR1f); 5897 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, MIRROR1f, fval); 5898 } 5899 5900 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, PRIf); 5901 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, PRIf, fval); 5902 5903 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, CPUf); 5904 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, CPUf, fval); 5905 5906 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, DST_DISCARDf); 5907 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, DST_DISCARDf, fval); 5908 5909 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, SRC_DISCARDf); 5910 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, SRC_DISCARDf, fval); 5911 5912 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, SCPf); 5913 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, SCPf, fval); 5914 5915 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, STATIC_BITf); 5916 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, STATIC_BITf, fval); 5917 5918 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, VALIDf); 5919 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, VALIDf, fval); 5920 5921 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, HITDAf); 5922 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, DST_HITf, fval); 5923 5924 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, HITSAf); 5925 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, SRC_HITf, fval); 5926 5927 fval = soc_mem_field32_get(unit, L2Xm, l2x_entry, LIMIT_COUNTEDf); 5928 soc_mem_field32_set(unit, EXT_L2_ENTRYm, ext_l2_entry, LIMIT_COUNTEDf, fval); 5929 5930 return SOC_E_NONE; 5931 } 5932 5933 int 5934 soc_triumph_ext_l2_to_l2x(int unit, ext_l2_entry_entry_t *ext_l2_entry, 5935 l2x_entry_t *l2x_entry) 5936 { 5937 sal_mac_addr_t mac; 5938 uint32 fval; 5939 5940 sal_memset(l2x_entry, 0, sizeof(l2x_entry_t)); 5941 5942 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, VLAN_IDf); 5943 soc_mem_field32_set(unit, L2Xm, l2x_entry, VLAN_IDf, fval); 5944 5945 soc_mem_mac_addr_get(unit, EXT_L2_ENTRYm, ext_l2_entry, MAC_ADDRf, mac); 5946 soc_mem_mac_addr_set(unit, L2Xm, l2x_entry, MAC_ADDRf, mac); 5947 5948 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 5949 KEY_TYPE_VFIf); 5950 soc_mem_field32_set(unit, L2Xm, l2x_entry, KEY_TYPEf, fval ? 3 : 0); 5951 5952 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 5953 DESTINATIONf); 5954 soc_mem_field32_set(unit, L2Xm, l2x_entry, DESTINATIONf, fval); 5955 5956 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, DEST_TYPEf); 5957 soc_mem_field32_set(unit, L2Xm, l2x_entry, DEST_TYPEf, fval); 5958 5959 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, CLASS_IDf); 5960 soc_mem_field32_set(unit, L2Xm, l2x_entry, CLASS_IDf, fval); 5961 5962 5963 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, RPEf); 5964 soc_mem_field32_set(unit, L2Xm, l2x_entry, RPEf, fval); 5965 5966 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, MIRRORf); 5967 soc_mem_field32_set(unit, L2Xm, l2x_entry, MIRRORf, fval); 5968 5969 if (SOC_MEM_FIELD_VALID(unit, L2Xm, MIRROR1f)) { 5970 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, MIRROR1f); 5971 soc_mem_field32_set(unit, L2Xm, l2x_entry, MIRROR1f, fval); 5972 } 5973 5974 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, PRIf); 5975 soc_mem_field32_set(unit, L2Xm, l2x_entry, PRIf, fval); 5976 5977 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, CPUf); 5978 soc_mem_field32_set(unit, L2Xm, l2x_entry, CPUf, fval); 5979 5980 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 5981 DST_DISCARDf); 5982 soc_mem_field32_set(unit, L2Xm, l2x_entry, DST_DISCARDf, fval); 5983 5984 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 5985 SRC_DISCARDf); 5986 soc_mem_field32_set(unit, L2Xm, l2x_entry, SRC_DISCARDf, fval); 5987 5988 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, SCPf); 5989 soc_mem_field32_set(unit, L2Xm, l2x_entry, SCPf, fval); 5990 5991 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, STATIC_BITf); 5992 soc_mem_field32_set(unit, L2Xm, l2x_entry, STATIC_BITf, fval); 5993 5994 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, VALIDf); 5995 soc_mem_field32_set(unit, L2Xm, l2x_entry, VALIDf, fval); 5996 5997 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, DST_HITf); 5998 soc_mem_field32_set(unit, L2Xm, l2x_entry, HITDAf, fval); 5999 6000 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, SRC_HITf); 6001 soc_mem_field32_set(unit, L2Xm, l2x_entry, HITSAf, fval); 6002 6003 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6004 LIMIT_COUNTEDf); 6005 soc_mem_field32_set(unit, L2Xm, l2x_entry, LIMIT_COUNTEDf, fval); 6006 6007 return SOC_E_NONE; 6008 } 6009 6010 /* 6011 * External L2 Bulk Delete/Replace Acceleration 6012 * 6013 * Hardware scanning of the external L2 table for bulk delete and 6014 * bulk replace can be a little slow with large L2 tables. This 6015 * code caches enough information on each entry in order to do a 6016 * quick software walk of the table looking for matches. 6017 * 6018 * There are per-vlan min and max indices that are kept so that for 6019 * per-vlan or per-vlan/port scans we only need to look at a subset of 6020 * the entries. 6021 * 6022 * Times to scan a 256K L2 table that is empty or near empty drop from 6023 * 56 msec to 0.8 msec. If all entries still need to be looked at 6024 * (because the vlan min/max is the whole table, the scna time is about 6025 * 6 msec. 6026 * 6027 * Memory use is 12 bytes per L2 entry (data word plus mac address) 6028 * which is 3MBytes for a 256K L2 table. The per-vlan limits are 6029 * 32KBytes. 6030 */ 6031 int 6032 _soc_tr_l2e_ppa_init(int unit) 6033 { 6034 _soc_tr_l2e_ppa_info_t *einfo; 6035 _soc_tr_l2e_ppa_vlan_t *evlan; 6036 int vlan, esize; 6037 6038 if (SOC_CONTROL(unit)->ext_l2_ppa_info != NULL) { 6039 sal_free(SOC_CONTROL(unit)->ext_l2_ppa_info); 6040 SOC_CONTROL(unit)->ext_l2_ppa_info = NULL; 6041 } 6042 if (SOC_CONTROL(unit)->ext_l2_ppa_vlan != NULL) { 6043 sal_free(SOC_CONTROL(unit)->ext_l2_ppa_vlan); 6044 SOC_CONTROL(unit)->ext_l2_ppa_vlan = NULL; 6045 } 6046 6047 esize = soc_mem_index_count(unit, EXT_L2_ENTRYm) * 6048 sizeof(_soc_tr_l2e_ppa_info_t); 6049 einfo = sal_alloc(esize, "_soc_tr_l2e_ppa_info"); 6050 if (einfo == NULL) { 6051 return SOC_E_MEMORY; 6052 } 6053 6054 evlan = sal_alloc(sizeof(_soc_tr_l2e_ppa_vlan_t), 6055 "_soc_tr_l2e_ppa_vlan"); 6056 if (evlan == NULL) { 6057 sal_free(einfo); 6058 return SOC_E_MEMORY; 6059 } 6060 sal_memset(einfo, 0, esize); 6061 for (vlan = 0; vlan <= VLAN_ID_MAX; vlan++) { 6062 evlan->vlan_min[vlan] = -1; 6063 evlan->vlan_max[vlan] = -1; 6064 } 6065 SOC_CONTROL(unit)->ext_l2_ppa_info = einfo; 6066 SOC_CONTROL(unit)->ext_l2_ppa_vlan = evlan; 6067 return SOC_E_NONE; 6068 } 6069 6070 STATIC int 6071 _soc_tr_l2e_ppa_update(int unit, int index, ext_l2_entry_entry_t *entry) 6072 { 6073 _soc_tr_l2e_ppa_info_t *ppa_info; 6074 _soc_tr_l2e_ppa_vlan_t *ppa_vlan; 6075 uint32 entvalue; 6076 uint32 l2data; 6077 sal_mac_addr_t l2mac; 6078 soc_mem_t mem; 6079 vlan_id_t vlan, oldvlan; 6080 int vlan_min, vlan_max; 6081 uint32 vdata, vmask; 6082 6083 mem = EXT_L2_ENTRYm; 6084 if (SOC_CONTROL(unit)->ext_l2_ppa_info == NULL) { 6085 if (!soc_mem_is_valid(unit, mem) || 6086 soc_mem_index_count(unit, mem) <= 0) { 6087 return SOC_E_NONE; 6088 } 6089 SOC_IF_ERROR_RETURN(_soc_tr_l2e_ppa_init(unit)); 6090 } 6091 6092 ppa_info = SOC_CONTROL(unit)->ext_l2_ppa_info; 6093 ppa_vlan = SOC_CONTROL(unit)->ext_l2_ppa_vlan; 6094 6095 vlan = 0; 6096 entvalue = 0; 6097 if (entry != NULL) { 6098 l2data = soc_mem_field32_get(unit, mem, entry, LIMIT_COUNTEDf); 6099 if (l2data != 0) { 6100 entvalue |= _SOC_TR_L2E_LIMIT_COUNTED; 6101 } 6102 l2data = soc_mem_field32_get(unit, mem, entry, VALIDf); 6103 if (l2data != 0) { 6104 entvalue |= _SOC_TR_L2E_VALID; 6105 } 6106 l2data = soc_mem_field32_get(unit, mem, entry, STATIC_BITf); 6107 if (l2data != 0) { 6108 entvalue |= _SOC_TR_L2E_STATIC; 6109 } 6110 l2data = soc_mem_field32_get(unit, mem, entry, VLAN_IDf); 6111 vlan = l2data; 6112 entvalue |= (l2data & _SOC_TR_L2E_VLAN_MASK) << _SOC_TR_L2E_VLAN_SHIFT; 6113 l2data = soc_mem_field32_get(unit, mem, entry, Tf); 6114 if (l2data) { 6115 l2data = soc_mem_field32_get(unit, mem, entry, TGIDf); 6116 entvalue |= _SOC_TR_L2E_T | 6117 ((l2data & _SOC_TR_L2E_TRUNK_MASK) << _SOC_TR_L2E_TRUNK_SHIFT); 6118 } else { 6119 l2data = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 6120 entvalue |= 6121 (l2data & _SOC_TR_L2E_MOD_MASK) << _SOC_TR_L2E_MOD_SHIFT; 6122 l2data = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 6123 entvalue |= 6124 (l2data & _SOC_TR_L2E_PORT_MASK) << _SOC_TR_L2E_PORT_SHIFT; 6125 } 6126 soc_mem_mac_addr_get(unit, mem, entry, MAC_ADDRf, l2mac); 6127 } else { 6128 sal_memset(l2mac, 0, sizeof(l2mac)); 6129 } 6130 oldvlan = (ppa_info[index].data >> 16) & 0xfff; 6131 ppa_info[index].data = entvalue; 6132 sal_memcpy(ppa_info[index].mac, l2mac, sizeof(sal_mac_addr_t)); 6133 6134 if (vlan != oldvlan) { /* update vlan_min/max indices */ 6135 if (oldvlan != 0) { 6136 vlan_min = ppa_vlan->vlan_min[oldvlan]; 6137 vlan_max = ppa_vlan->vlan_max[oldvlan]; 6138 vdata = oldvlan << _SOC_TR_L2E_VLAN_SHIFT; 6139 vmask = _SOC_TR_L2E_VLAN_MASK << _SOC_TR_L2E_VLAN_SHIFT; 6140 6141 /* deleted last one? */ 6142 if (index == vlan_min && index == vlan_max) { 6143 ppa_vlan->vlan_min[oldvlan] = -1; 6144 ppa_vlan->vlan_max[oldvlan] = -1; 6145 } else if (index == vlan_min) { 6146 for (; vlan_min <= vlan_max; vlan_min++) { 6147 entvalue = ppa_info[vlan_min].data; 6148 if ((entvalue & vmask) == vdata) { 6149 break; 6150 } 6151 } 6152 ppa_vlan->vlan_min[oldvlan] = vlan_min; 6153 } else if (index == vlan_max) { 6154 for (; vlan_min <= vlan_max; vlan_max--) { 6155 entvalue = ppa_info[vlan_max].data; 6156 if ((entvalue & vmask) == vdata) { 6157 break; 6158 } 6159 } 6160 ppa_vlan->vlan_max[oldvlan] = vlan_max; 6161 } 6162 6163 } 6164 if (vlan != 0) { 6165 vlan_min = ppa_vlan->vlan_min[vlan]; 6166 vlan_max = ppa_vlan->vlan_max[vlan]; 6167 if (vlan_min < 0 || index < vlan_min) { 6168 ppa_vlan->vlan_min[vlan] = index; 6169 } 6170 if (vlan_max < 0 || index > vlan_max) { 6171 ppa_vlan->vlan_max[vlan] = index; 6172 } 6173 } 6174 } 6175 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6176 (BSL_META_U(unit, 6177 "tr_l2e_ppa: index=%d oldvlan=%d min:max %d:%d\n"), 6178 index, oldvlan, 6179 ppa_vlan->vlan_min[oldvlan], 6180 ppa_vlan->vlan_max[oldvlan])); 6181 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6182 (BSL_META_U(unit, 6183 "tr_l2e_ppa: ent=0x%x mac=%x:%x:%x:%x:%x:%x vlan=%d min:max %d:%d\n"), 6184 ppa_info[index].data, 6185 l2mac[0], l2mac[1], l2mac[2], l2mac[3], l2mac[4], l2mac[5], 6186 vlan, 6187 ppa_vlan->vlan_min[vlan], 6188 ppa_vlan->vlan_max[vlan])); 6189 return SOC_E_NONE; 6190 } 6191 6192 int 6193 soc_triumph_ext_l2_entry_update(int unit, int index, void *entry) 6194 { 6195 ext_l2_entry_tcam_entry_t tcam_entry; 6196 void *tcam_entry_ptr; 6197 uint32 fval, *cache; 6198 sal_mac_addr_t mac; 6199 int copyno, tcam_entry_dw; 6200 6201 copyno = SOC_MEM_BLOCK_ANY(unit, EXT_L2_ENTRY_TCAMm); 6202 cache = SOC_MEM_STATE(unit, EXT_L2_ENTRY_TCAMm).cache[copyno]; 6203 if (cache != NULL) { 6204 if (entry != NULL) { 6205 sal_memset(&tcam_entry, 0, sizeof(tcam_entry)); 6206 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, entry, VLAN_IDf); 6207 soc_mem_field32_set(unit, EXT_L2_ENTRY_TCAMm, &tcam_entry, 6208 VLAN_IDf, fval); 6209 soc_mem_mac_addr_get(unit, EXT_L2_ENTRYm, entry, MAC_ADDRf, mac); 6210 soc_mem_mac_addr_set(unit, EXT_L2_ENTRY_TCAMm, &tcam_entry, 6211 MAC_ADDRf, mac); 6212 fval = soc_mem_field32_get(unit, EXT_L2_ENTRYm, entry, 6213 KEY_TYPE_VFIf); 6214 soc_mem_field32_set(unit, EXT_L2_ENTRY_TCAMm, &tcam_entry, 6215 KEY_TYPE_VFIf, fval); 6216 soc_mem_field32_set(unit, EXT_L2_ENTRY_TCAMm, &tcam_entry, FREEf, 6217 0); 6218 soc_mem_field32_set(unit, EXT_L2_ENTRY_TCAMm, &tcam_entry, 6219 MASK_RESERVEDf, 0x3ff); 6220 tcam_entry_ptr = &tcam_entry; 6221 } else { 6222 tcam_entry_ptr = soc_mem_entry_null(unit, EXT_L2_ENTRY_TCAMm); 6223 } 6224 tcam_entry_dw = soc_mem_entry_words(unit, EXT_L2_ENTRY_TCAMm); 6225 sal_memcpy(cache + index * tcam_entry_dw, tcam_entry_ptr, 6226 tcam_entry_dw * 4); 6227 } 6228 6229 _soc_tr_l2e_ppa_update(unit, index, entry); 6230 6231 return SOC_E_NONE; 6232 } 6233 6234 /* 6235 * Function: 6236 * soc_triumph_learn_count_update 6237 * Description: 6238 * Check MAC learn limit and update MAC learn counter if it won't go over 6239 * the limit 6240 * Parameters: 6241 * unit device number 6242 * ext_l2_entry entry to be add or delete 6243 * incl_sys_vlan update system and vlan table or not 6244 * diff number to be add to MAC counter 6245 * use negative to subtract MAC counter 6246 * Return: 6247 * SOC_E_XXX 6248 */ 6249 int 6250 soc_triumph_learn_count_update(int unit, ext_l2_entry_entry_t *ext_l2_entry, 6251 int incl_sys_vlan, int diff) 6252 { 6253 uint32 entry[SOC_MAX_MEM_WORDS], rval; 6254 vlan_or_vfi_mac_count_entry_t v_entry; 6255 port_or_trunk_mac_count_entry_t p_entry; 6256 int v_index, p_index, s_limit, v_limit, p_limit, s_count, v_count, p_count; 6257 int rv; 6258 6259 p_index = -1; 6260 v_index = -1; 6261 switch (soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6262 DEST_TYPEf)) { 6263 case 0: /* mod port */ 6264 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 0, 6265 &entry)); 6266 if (soc_mem_field32_get(unit, PORT_TABm, &entry, MY_MODIDf) == 6267 soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6268 MODULE_IDf)) { 6269 p_index = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6270 PORT_NUMf) + 128; 6271 } 6272 break; 6273 case 1: /* trunk */ 6274 p_index = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6275 TGIDf); 6276 break; 6277 default: 6278 return SOC_E_NONE; 6279 } 6280 if (incl_sys_vlan) { 6281 v_index = soc_mem_field32_get(unit, EXT_L2_ENTRYm, ext_l2_entry, 6282 VLAN_IDf); 6283 } 6284 6285 /* read limit setting */ 6286 s_limit = v_limit = p_limit = -1; 6287 if (diff > 0) { 6288 SOC_IF_ERROR_RETURN(READ_SYS_MAC_LIMIT_CONTROLr(unit, &rval)); 6289 if (soc_reg_field_get(unit, SYS_MAC_LIMIT_CONTROLr, rval, ENABLEf)) { 6290 if (v_index >= 0) { 6291 s_limit = soc_reg_field_get(unit, SYS_MAC_LIMIT_CONTROLr, rval, 6292 SYS_LIMITf); 6293 SOC_IF_ERROR_RETURN(soc_mem_read(unit, VLAN_OR_VFI_MAC_LIMITm, 6294 MEM_BLOCK_ANY, v_index, 6295 &entry)); 6296 v_limit = soc_mem_field32_get(unit, VLAN_OR_VFI_MAC_LIMITm, 6297 &entry, LIMITf); 6298 } 6299 if (p_index >= 0) { 6300 SOC_IF_ERROR_RETURN(soc_mem_read(unit, 6301 PORT_OR_TRUNK_MAC_LIMITm, 6302 MEM_BLOCK_ANY, p_index, 6303 &entry)); 6304 p_limit = soc_mem_field32_get(unit, PORT_OR_TRUNK_MAC_LIMITm, 6305 &entry, LIMITf); 6306 } 6307 } else { 6308 /* If MAC Learn limit count is not enable -> do nothing */ 6309 return SOC_E_NONE; 6310 } 6311 } 6312 6313 SOC_IF_ERROR_RETURN(_soc_l2x_frozen_cml_save(unit)); 6314 6315 /* read current count */ 6316 rv = SOC_E_NONE; 6317 s_count = v_count = 0; 6318 if (v_index >= 0) { 6319 rv = READ_SYS_MAC_COUNTr(unit, &rval); 6320 if (SOC_SUCCESS(rv)) { 6321 s_count = soc_reg_field_get(unit, SYS_MAC_COUNTr, rval, COUNTf); 6322 6323 rv = soc_mem_read(unit, VLAN_OR_VFI_MAC_COUNTm, MEM_BLOCK_ANY, 6324 v_index, &v_entry); 6325 if (SOC_SUCCESS(rv)) { 6326 v_count = soc_mem_field32_get(unit, VLAN_OR_VFI_MAC_COUNTm, 6327 &v_entry, COUNTf); 6328 } 6329 } 6330 } 6331 6332 p_count = 0; 6333 if (SOC_SUCCESS(rv) && p_index >= 0) { 6334 rv = soc_mem_read(unit, PORT_OR_TRUNK_MAC_COUNTm, MEM_BLOCK_ANY, 6335 p_index, &p_entry); 6336 if (SOC_SUCCESS(rv)) { 6337 p_count = soc_mem_field32_get(unit, PORT_OR_TRUNK_MAC_COUNTm, 6338 &p_entry, COUNTf); 6339 } 6340 } 6341 6342 if (SOC_FAILURE(rv)) { 6343 SOC_IF_ERROR_RETURN(_soc_l2x_frozen_cml_restore(unit)); 6344 return rv; 6345 } 6346 6347 if (v_index >= 0) { 6348 s_count += diff; 6349 v_count += diff; 6350 } 6351 if (p_index >= 0) { 6352 p_count += diff; 6353 } 6354 6355 if (diff > 0) { 6356 if ((s_limit >= 0 && s_count > s_limit) || 6357 (v_limit >= 0 && v_count > v_limit) || 6358 (p_limit >= 0 && p_count > p_limit)) { 6359 SOC_IF_ERROR_RETURN(_soc_l2x_frozen_cml_restore(unit)); 6360 return SOC_E_RESOURCE; 6361 } 6362 } else { 6363 if (s_count < 0) { 6364 s_count = 0; 6365 } 6366 if (v_count < 0) { 6367 v_count = 0; 6368 } 6369 if (p_count < 0) { 6370 p_count = 0; 6371 } 6372 } 6373 6374 if (v_index >= 0) { 6375 soc_reg_field_set(unit, SYS_MAC_COUNTr, &rval, COUNTf, s_count); 6376 rv = WRITE_SYS_MAC_COUNTr(unit, rval); 6377 6378 if (SOC_SUCCESS(rv)) { 6379 soc_mem_field32_set(unit, VLAN_OR_VFI_MAC_COUNTm, &v_entry, COUNTf, 6380 v_count); 6381 rv = WRITE_VLAN_OR_VFI_MAC_COUNTm(unit, MEM_BLOCK_ANY, v_index, 6382 &v_entry); 6383 } 6384 } 6385 6386 if (SOC_SUCCESS(rv) && p_index >= 0) { 6387 soc_mem_field32_set(unit, PORT_OR_TRUNK_MAC_COUNTm, &p_entry, COUNTf, 6388 p_count); 6389 rv = WRITE_PORT_OR_TRUNK_MAC_COUNTm(unit, MEM_BLOCK_ANY, p_index, 6390 &p_entry); 6391 } 6392 6393 SOC_IF_ERROR_RETURN(_soc_l2x_frozen_cml_restore(unit)); 6394 6395 return rv; 6396 } 6397 6398 STATIC int 6399 _soc_triumph_tx(int unit, int port, int pkt_len) 6400 { 6401 static dcb14_t *dcb[SOC_MAX_NUM_DEVICES] = {NULL}; 6402 soc_pbsmh_v3_hdr_t pbsmh; 6403 int rc, i, done; 6404 static sdc_t *dch[SOC_MAX_NUM_DEVICES] = {NULL}; 6405 static dma_chan_t tx_ch[SOC_MAX_NUM_DEVICES] = {-1}; 6406 static uint8 tx_flags[SOC_MAX_NUM_DEVICES] = {0}; 6407 6408 if (pkt_len != 192 && pkt_len != 64) { 6409 return SOC_E_PARAM; 6410 } 6411 6412 if (dcb[unit] == NULL) { 6413 dch[unit] = SOC_CONTROL(unit)->soc_dma_default_tx; 6414 tx_ch[unit] = dch[unit]->sc_channel; 6415 tx_flags[unit] = dch[unit]->sc_flags; 6416 rc = soc_dma_rom_init(unit, 256, TRUE, FALSE); 6417 if (SOC_FAILURE(rc)) { 6418 goto _restore; 6419 } 6420 dcb[unit] = soc_dma_rom_dcb_alloc(unit, 192); 6421 if (dcb[unit] == NULL) { 6422 rc = SOC_E_MEMORY; 6423 goto _restore; 6424 } 6425 } else { 6426 SOC_IF_ERROR_RETURN 6427 (soc_dma_chan_config(unit, SOC_DMA_ROM_TX_CHANNEL, DV_TX, 6428 SOC_DMA_F_MBM | SOC_DMA_F_POLL | SOC_DMA_F_DEFAULT)); 6429 } 6430 6431 PBS_MH_W0_START_SET(&pbsmh); 6432 PBS_MH_W1_RSVD_SET(&pbsmh); 6433 PBS_MH_V3_W2_SMOD_DPORT_COS_SET(&pbsmh, 0, port, 0, 0, 0); 6434 6435 SOC_DCB_STAT_SET(unit, dcb[unit], 1); 6436 SOC_DCB_HG_SET(unit, dcb[unit], 1); 6437 SOC_DCB_REQCOUNT_SET(unit, dcb[unit], pkt_len); 6438 dcb[unit]->mh0 = soc_ntohl(((uint32 *)&pbsmh)[0]); 6439 dcb[unit]->mh1 = soc_ntohl(((uint32 *)&pbsmh)[1]); 6440 dcb[unit]->mh2 = soc_ntohl(((uint32 *)&pbsmh)[2]); 6441 dcb[unit]->mh3 = 0; 6442 6443 rc = soc_dma_rom_tx_start(unit, dcb[unit]); 6444 if (SOC_FAILURE(rc)) { 6445 goto _restore; 6446 } 6447 for (i =0; i < 100000; i++) { 6448 soc_dma_rom_tx_poll(unit, &done); 6449 if (done) { 6450 break; 6451 } 6452 } 6453 6454 _restore: 6455 if (dch[unit]) { 6456 SOC_IF_ERROR_RETURN 6457 (soc_dma_chan_config(unit, tx_ch[unit], DV_TX, tx_flags[unit])); 6458 } 6459 return rc; 6460 } 6461 6462 int 6463 soc_triumph_xgport_mode_change(int unit, soc_port_t port, soc_mac_mode_t mode) 6464 { 6465 mac_driver_t *macd; 6466 soc_field_t rst_field = INVALIDf; 6467 uint32 rval, to_usec, old_bits, bits; 6468 uint64 val64; 6469 soc_pbmp_t ctr_pbmp; 6470 int rv; 6471 int autoneg, autoneg_done, speed, duplex; 6472 int pause_tx, pause_rx, loopback, enable; 6473 soc_port_ability_t ability; 6474 6475 sal_memset(&ability, 0, sizeof(soc_port_ability_t)); 6476 6477 if (!SOC_PORT_VALID(unit, port)) { 6478 return SOC_E_PORT; 6479 } 6480 switch (port) { 6481 case 2: 6482 rst_field = CMIC_XGP0_RST_Lf; 6483 break; 6484 case 14: 6485 rst_field = CMIC_XGP1_RST_Lf; 6486 break; 6487 case 26: 6488 rst_field = CMIC_XGP2_RST_Lf; 6489 break; 6490 case 27: 6491 rst_field = CMIC_XGP3_RST_Lf; 6492 break; 6493 default: 6494 return SOC_E_PORT; 6495 } 6496 6497 SOC_IF_ERROR_RETURN(READ_XGPORT_MODE_REGr(unit, port, &rval)); 6498 old_bits = soc_reg_field_get(unit, XGPORT_MODE_REGr, rval, 6499 XGPORT_MODE_BITSf); 6500 bits = mode == SOC_MAC_MODE_10000 ? 2 : 1; 6501 if (bits == old_bits) { 6502 return SOC_E_NONE; 6503 } 6504 6505 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 6506 (10 * MILLISECOND_USEC); 6507 6508 /* get current PHY setting */ 6509 SOC_IF_ERROR_RETURN(soc_phyctrl_auto_negotiate_get(unit, port, &autoneg, 6510 &autoneg_done)); 6511 SOC_IF_ERROR_RETURN(soc_phyctrl_ability_advert_get(unit, port, &ability)); 6512 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_get(unit, port, &speed)); 6513 SOC_IF_ERROR_RETURN(soc_phyctrl_duplex_get(unit, port, &duplex)); 6514 6515 /* get current MAC setting */ 6516 SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd)); 6517 SOC_IF_ERROR_RETURN(MAC_ENABLE_GET(macd, unit, port, &enable)); 6518 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_GET(macd, unit, port, &loopback)); 6519 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &pause_tx, &pause_rx)); 6520 6521 /* 1, Disable MAC TX and RX */ 6522 SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, FALSE)); 6523 6524 /* 2. Set port mode to disabled */ 6525 SOC_IF_ERROR_RETURN(READ_XGPORT_MODE_REGr(unit, port, &rval)); 6526 soc_reg_field_set(unit, XGPORT_MODE_REGr, &rval, XGPORT_MODE_BITSf, 0); 6527 SOC_IF_ERROR_RETURN(WRITE_XGPORT_MODE_REGr(unit, port, rval)); 6528 6529 /* 3. Send packet */ 6530 if (old_bits == 2) { /* it was xport-mode */ 6531 SOC_IF_ERROR_RETURN(_soc_triumph_tx(unit, port, 192)); 6532 } else if (old_bits == 1) { /* it was gport-mode */ 6533 SOC_IF_ERROR_RETURN(_soc_triumph_tx(unit, port, 64)); 6534 } 6535 6536 /* 4. Wait for (more than) 500 core clks */ 6537 sal_usleep(100000); 6538 6539 /* 5. Block linkscan and sbus access */ 6540 soc_linkscan_pause(unit); 6541 SCHAN_LOCK(unit); 6542 6543 /* 6. Assert XGPORT block */ 6544 rv = READ_CMIC_SOFT_RESET_REGr(unit, &rval); 6545 if (SOC_SUCCESS(rv)) { 6546 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, rst_field, 0); 6547 rv = WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 6548 } 6549 6550 /* 7. De-assert XGPORT block */ 6551 if (SOC_SUCCESS(rv)) { 6552 sal_usleep(to_usec); 6553 soc_reg_field_set(unit, CMIC_SOFT_RESET_REGr, &rval, rst_field, 1); 6554 rv = WRITE_CMIC_SOFT_RESET_REGr(unit, rval); 6555 } 6556 6557 /* 8. Resume sbus access and linkscan */ 6558 SCHAN_UNLOCK(unit); 6559 soc_linkscan_continue(unit); 6560 sal_usleep(to_usec); 6561 6562 /* 9. Change the XGPORT block mode */ 6563 SOC_IF_ERROR_RETURN(READ_XGPORT_MODE_REGr(unit, port, &rval)); 6564 soc_reg_field_set(unit, XGPORT_MODE_REGr, &rval, XGPORT_MODE_BITSf, bits); 6565 SOC_IF_ERROR_RETURN(WRITE_XGPORT_MODE_REGr(unit, port, rval)); 6566 6567 /* reset xgxs */ 6568 soc_xgxs_reset(unit, port); 6569 rval = 0; 6570 soc_reg_field_set(unit, XGPORT_XGXS_NEWCTL_REGr, &rval, TXD1G_FIFO_RSTBf, 6571 mode == SOC_MAC_MODE_10000 ? 0xf : 0x1); 6572 SOC_IF_ERROR_RETURN(WRITE_XGPORT_XGXS_NEWCTL_REGr(unit, port, rval)); 6573 6574 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 6575 SOC_IF_ERROR_RETURN(soc_phyctrl_probe(unit, port)); 6576 SOC_IF_ERROR_RETURN(soc_phyctrl_init(unit, port)); 6577 6578 /* restore PHY setting */ 6579 SOC_IF_ERROR_RETURN(soc_phyctrl_auto_negotiate_set(unit, port, autoneg)); 6580 SOC_IF_ERROR_RETURN(soc_phyctrl_ability_advert_set(unit, port, &ability)); 6581 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, speed)); 6582 SOC_IF_ERROR_RETURN(soc_phyctrl_duplex_set(unit, port, duplex)); 6583 6584 SOC_IF_ERROR_RETURN(MAC_INIT(macd, unit, port)); 6585 6586 /* restore MAC setting */ 6587 SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, pause_tx, pause_rx)); 6588 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(macd, unit, port, loopback)); 6589 SOC_IF_ERROR_RETURN(MAC_ENABLE_SET(macd, unit, port, enable)); 6590 6591 /* Reset and Refresh counters */ 6592 SOC_PBMP_CLEAR(ctr_pbmp); 6593 SOC_PBMP_PORT_SET(ctr_pbmp, port); 6594 COMPILER_64_SET(val64, 0, 0); 6595 SOC_IF_ERROR_RETURN(soc_counter_set_by_port(unit, ctr_pbmp, val64)); 6596 soc_counter_sync(unit); 6597 6598 return SOC_E_NONE; 6599 } 6600 6601 /************************************************** 6602 * @function soc_triumph_l2_entry_limit_count_update 6603 * 6604 * 6605 * @purpose Read L2 table from hardware, calculate 6606 * and restore port/trunk and vlan/vfi 6607 * mac counts. 6608 * 6609 * @param unit @b{(input)} unit number 6610 * 6611 * @returns BCM_E_NONE 6612 * @returns BCM_E_FAIL 6613 * 6614 * @comments This rountine gets called for an 6615 * L2 table SER event, if any of the 6616 * mac limits(system, port, vlan) are 6617 * enabled on the device. 6618 * 6619 * @end 6620 */ 6621 6622 int 6623 soc_triumph_l2_entry_limit_count_update(int unit) 6624 { 6625 uint32 entry[SOC_MAX_MEM_WORDS], rval; 6626 uint32 *v_entry; /* vlan or vfi count entry */ 6627 uint32 *p_entry; /* port or trunk count entry */ 6628 uint32 *l2; /* l2 entry */ 6629 int32 v_index = -1; /* vlan index */ 6630 int32 p_index = -1; /* port index */ 6631 uint32 s_count = 0; /* system mac count */ 6632 uint32 p_count = 0; /* port or trunk mac count */ 6633 uint32 v_count = 0; /* vlan or vfi mac count */ 6634 6635 /* l2 table */ 6636 int index_min, index_max; 6637 int entry_dw, entry_sz; 6638 int chnk_idx, chnk_idx_max, table_chnk_sz, idx; 6639 int chunk_size = 1024; 6640 6641 /* port or trunk mac count table */ 6642 int ptm_index_min, ptm_index_max; 6643 int ptm_table_sz, ptm_entry_dw, ptm_entry_sz; 6644 6645 /* vlan or vfi mac count table */ 6646 int vvm_index_min, vvm_index_max; 6647 int vvm_table_sz, vvm_entry_dw, vvm_entry_sz; 6648 6649 uint32 *buf = NULL; 6650 uint32 *ptm_buf = NULL; 6651 uint32 *vvm_buf = NULL; 6652 6653 uint32 dest_type, key_type; 6654 uint32 is_valid, is_limit_counted = 0; 6655 uint32 is_free; 6656 soc_mem_t mem; 6657 int rv; 6658 6659 p_index = -1; 6660 v_index = -1; 6661 6662 6663 /* If MAC learn limit not enabled do nothing */ 6664 SOC_IF_ERROR_RETURN(READ_SYS_MAC_LIMIT_CONTROLr(unit, &rval)); 6665 if (!soc_reg_field_get(unit, SYS_MAC_LIMIT_CONTROLr, 6666 rval, ENABLEf)) { 6667 return SOC_E_NONE; 6668 } 6669 6670 6671 /* 6672 * Mac limits are enabled. 6673 * 1. Read (DMA) L2 table to recalculate mac count 6674 * 2. Iterate through all the entries. 6675 * 3. if the entry is limit_counted 6676 * Check if KEY_TYPE is BRIDGE, VLAN or VFI 6677 * based on DEST_TYPE determine if Trunk or ModPort 6678 * Get port index into port_or_trunk_mac_count table 6679 * Get vlan/vfi index into vlan_or_vfi_mac_count table 6680 * update the port, vlan/vfi, system mac count. 6681 * Write(slam) port_or_trunk_mac count and 6682 * vlan_or_vfi_mac_count tables. 6683 */ 6684 6685 mem = L2Xm; 6686 soc_mem_lock(unit, mem); 6687 6688 /* 6689 * Allocate memory for port/trunk mac count table to store 6690 * the updated count. 6691 */ 6692 ptm_entry_dw = soc_mem_entry_words(unit, PORT_OR_TRUNK_MAC_COUNTm); 6693 ptm_entry_sz = ptm_entry_dw * sizeof(uint32); 6694 ptm_index_min = soc_mem_index_min(unit, PORT_OR_TRUNK_MAC_COUNTm); 6695 ptm_index_max = soc_mem_index_max(unit,PORT_OR_TRUNK_MAC_COUNTm); 6696 ptm_table_sz = (ptm_index_max - ptm_index_min + 1) * ptm_entry_sz; 6697 6698 ptm_buf = soc_cm_salloc(unit, ptm_table_sz, "ptm_tmp"); 6699 6700 if (ptm_buf == NULL) { 6701 soc_mem_unlock(unit, mem); 6702 return SOC_E_MEMORY; 6703 } 6704 6705 sal_memset(ptm_buf, 0, ptm_table_sz); 6706 6707 /* 6708 * Allocate memory for vlan/vfi mac count table to store 6709 * the updated count. 6710 */ 6711 vvm_entry_dw = soc_mem_entry_words(unit, VLAN_OR_VFI_MAC_COUNTm); 6712 vvm_entry_sz = vvm_entry_dw * sizeof(uint32); 6713 vvm_index_min = soc_mem_index_min(unit, VLAN_OR_VFI_MAC_COUNTm); 6714 vvm_index_max = soc_mem_index_max(unit,VLAN_OR_VFI_MAC_COUNTm); 6715 vvm_table_sz = (vvm_index_max - vvm_index_min + 1) * vvm_entry_sz; 6716 6717 vvm_buf = soc_cm_salloc(unit, vvm_table_sz, "vvm_tmp"); 6718 6719 if (vvm_buf == NULL) { 6720 soc_cm_sfree(unit, ptm_buf); 6721 soc_mem_unlock(unit, mem); 6722 return SOC_E_MEMORY; 6723 } 6724 6725 sal_memset(vvm_buf, 0, vvm_table_sz); 6726 6727 /* Create a copy L2_ENTRY_1m table for calculating mac count */ 6728 entry_dw = soc_mem_entry_words(unit, mem); 6729 entry_sz = entry_dw * sizeof(uint32); 6730 index_min = soc_mem_index_min(unit, mem); 6731 index_max = soc_mem_index_max(unit, mem); 6732 table_chnk_sz = chunk_size * entry_sz; 6733 6734 buf = soc_cm_salloc(unit, table_chnk_sz, "l2x_tmp"); 6735 6736 if (buf == NULL) { 6737 soc_cm_sfree(unit, ptm_buf); 6738 soc_cm_sfree(unit, vvm_buf); 6739 soc_mem_unlock(unit, mem); 6740 return SOC_E_MEMORY; 6741 } 6742 6743 for (chnk_idx = index_min; chnk_idx <= index_max; chnk_idx += chunk_size) { 6744 6745 sal_memset(buf, 0, table_chnk_sz); 6746 6747 chnk_idx_max = ((chnk_idx + chunk_size) <= index_max) ? 6748 (chnk_idx + chunk_size - 1) : index_max; 6749 6750 /* DMA L2 Table */ 6751 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, chnk_idx, 6752 chnk_idx_max, buf); 6753 if (rv < 0) { 6754 soc_cm_sfree(unit, buf); 6755 soc_cm_sfree(unit, ptm_buf); 6756 soc_cm_sfree(unit, vvm_buf); 6757 soc_mem_unlock(unit, mem); 6758 return SOC_E_FAIL; 6759 } 6760 6761 /* Iter through all l2 entries in the chunk */ 6762 for (idx = 0; idx <= (chnk_idx_max - chnk_idx); idx++) { 6763 l2 = (buf + (idx * entry_dw)); 6764 6765 /* check if entry is valid */ 6766 is_valid = soc_mem_field32_get(unit, mem, l2, VALIDf); 6767 if (!is_valid) { 6768 /* not valid entry skip it */ 6769 continue; 6770 } 6771 6772 /* check if entry is limit counted */ 6773 if (soc_mem_field_valid(unit, mem, LIMIT_COUNTEDf)) { 6774 is_limit_counted = soc_mem_field32_get(unit,mem, l2, 6775 LIMIT_COUNTEDf); 6776 if (!is_limit_counted) { 6777 /* entry not limit counted skip it */ 6778 continue; 6779 } 6780 } 6781 6782 /* 6783 * Get the key type of the entries 6784 * Process entries with only key_types 6785 * 1. SOC_MEM_KEY_L2_ENTRY_1_L2_BRIDGE 6786 * 2. SOC_MEM_KEY_L2_ENTRY_1_L2_VFI 6787 */ 6788 key_type = soc_mem_field32_get(unit, mem, l2, KEY_TYPEf); 6789 6790 if ((key_type != TR_L2_HASH_KEY_TYPE_BRIDGE) && 6791 (key_type != TR_L2_HASH_KEY_TYPE_VFI)) { 6792 continue; 6793 } 6794 6795 dest_type = soc_mem_field32_get(unit, mem, l2, DEST_TYPEf); 6796 6797 switch (dest_type) { 6798 case 0: /* mod port */ 6799 rv = soc_mem_read(unit, PORT_TABm, 6800 MEM_BLOCK_ANY, 0, 6801 &entry); 6802 if (SOC_FAILURE(rv)) { 6803 soc_cm_sfree(unit, buf); 6804 soc_cm_sfree(unit, ptm_buf); 6805 soc_cm_sfree(unit, vvm_buf); 6806 soc_mem_unlock(unit, mem); 6807 return rv; 6808 } 6809 if (soc_mem_field32_get(unit, PORT_TABm, 6810 &entry, MY_MODIDf) == 6811 soc_mem_field32_get(unit, mem, l2, L2__MODULE_IDf)) { 6812 p_index = soc_mem_field32_get(unit, mem, 6813 l2, PORT_NUMf) + 6814 soc_mem_index_count(unit, TRUNK_GROUPm) ; 6815 } 6816 break; 6817 case 1: /* trunk */ 6818 p_index = soc_mem_field32_get(unit, mem, l2, L2__TGIDf); 6819 break; 6820 default: 6821 /* if VFI based key then break else continue? */ 6822 break; 6823 } 6824 6825 /* 6826 * based on key_type get vlan or vfi 6827 * to index into VLAN_OR_VFI_MAC_COUNTm 6828 */ 6829 if (key_type == TR_L2_HASH_KEY_TYPE_BRIDGE) { 6830 v_index = soc_mem_field32_get(unit, mem, l2, VLAN_IDf); 6831 } else { 6832 v_index = soc_mem_field32_get(unit, mem, l2, VFIf) + 6833 soc_mem_index_count(unit, VLAN_TABm); 6834 } 6835 6836 6837 /* 6838 * read and update vlan or vfi mac count 6839 * in buffer also update the sys mac count. 6840 */ 6841 v_count = 0; 6842 if (v_index >= 0) { 6843 v_entry = (vvm_buf + (v_index * vvm_entry_dw)); 6844 v_count = soc_mem_field32_get(unit, VLAN_OR_VFI_MAC_COUNTm, 6845 v_entry, COUNTf); 6846 s_count++; 6847 v_count++; 6848 soc_mem_field32_set(unit, VLAN_OR_VFI_MAC_COUNTm, 6849 v_entry, COUNTf, v_count); 6850 } 6851 6852 /* 6853 * read and update port or trunk mac count 6854 * in buffer. 6855 */ 6856 p_count = 0; 6857 if (p_index >= 0) { 6858 p_entry = ptm_buf + (p_index * ptm_entry_dw); 6859 p_count = soc_mem_field32_get(unit, PORT_OR_TRUNK_MAC_COUNTm, 6860 p_entry, COUNTf); 6861 p_count++; 6862 soc_mem_field32_set(unit, PORT_OR_TRUNK_MAC_COUNTm, 6863 p_entry, COUNTf, p_count); 6864 } 6865 6866 } /* End for index */ 6867 } /* End for chnk_idx */ 6868 6869 /* Free memory */ 6870 soc_cm_sfree(unit, buf); 6871 6872 /* Work on EXT_L2_TABLE */ 6873 if (soc_feature(unit, soc_feature_esm_support)) { 6874 soc_mem_unlock(unit, mem); 6875 /* Create a copy EXT_L2_ENTRYm table for calculating mac count */ 6876 mem = EXT_L2_ENTRYm; 6877 soc_mem_lock(unit, mem); 6878 entry_dw = soc_mem_entry_words(unit, mem); 6879 entry_sz = entry_dw * sizeof(uint32); 6880 index_min = soc_mem_index_min(unit, mem); 6881 index_max = soc_mem_index_max(unit, mem); 6882 table_chnk_sz = chunk_size * entry_sz; 6883 6884 buf = soc_cm_salloc(unit, table_chnk_sz, "l2x_tmp"); 6885 6886 if (buf == NULL) { 6887 soc_cm_sfree(unit, ptm_buf); 6888 soc_cm_sfree(unit, vvm_buf); 6889 soc_mem_unlock(unit, mem); 6890 return SOC_E_MEMORY; 6891 } 6892 6893 for (chnk_idx = index_min; chnk_idx <= index_max; 6894 chnk_idx += chunk_size) { 6895 6896 sal_memset(buf, 0, table_chnk_sz); 6897 6898 chnk_idx_max = ((chnk_idx + chunk_size) <= index_max) ? 6899 (chnk_idx + chunk_size - 1) : index_max; 6900 6901 /* DMA L2 Table */ 6902 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, chnk_idx, 6903 chnk_idx_max, buf); 6904 if (rv < 0) { 6905 soc_cm_sfree(unit, buf); 6906 soc_cm_sfree(unit, ptm_buf); 6907 soc_cm_sfree(unit, vvm_buf); 6908 soc_mem_unlock(unit, mem); 6909 return SOC_E_FAIL; 6910 } 6911 6912 /* Iter through all l2 entries in the chunk */ 6913 for (idx = 0; idx <= (chnk_idx_max - chnk_idx); idx++) { 6914 l2 = (buf + (idx * entry_dw)); 6915 6916 /* check if entry is valid */ 6917 is_free = soc_mem_field32_get(unit, mem, l2, FREEf); 6918 if (is_free) { 6919 /* not valid entry skip it */ 6920 continue; 6921 } 6922 6923 /* check if entry is limit counted */ 6924 if (soc_mem_field_valid(unit, mem, LIMIT_COUNTEDf)) { 6925 is_limit_counted = soc_mem_field32_get(unit,mem, l2, 6926 LIMIT_COUNTEDf); 6927 if (!is_limit_counted) { 6928 /* entry not limit counted skip it */ 6929 continue; 6930 } 6931 } 6932 6933 /* 6934 * Get the key type(KEY_TYPE_VFIf) of the entries 6935 * 0 - VLAN_ID 6936 * 0 - VFI 6937 */ 6938 key_type = soc_mem_field32_get(unit, mem, l2, KEY_TYPE_VFIf); 6939 6940 /* 6941 * based on key_type get vlan or vfi 6942 * to index into VLAN_OR_VFI_MAC_COUNTm 6943 */ 6944 if (key_type == 0) { 6945 v_index = soc_mem_field32_get(unit, mem, l2, VLAN_IDf); 6946 } else { 6947 v_index = soc_mem_field32_get(unit, mem, l2, VFIf) + 6948 soc_mem_index_count(unit, VLAN_TABm); 6949 } 6950 6951 dest_type = soc_mem_field32_get(unit, mem, l2, DEST_TYPEf); 6952 6953 switch (dest_type) { 6954 case 0: /* mod port */ 6955 rv = soc_mem_read(unit, PORT_TABm, 6956 MEM_BLOCK_ANY, 0, 6957 &entry); 6958 if (SOC_FAILURE(rv)) { 6959 soc_cm_sfree(unit, buf); 6960 soc_cm_sfree(unit, ptm_buf); 6961 soc_cm_sfree(unit, vvm_buf); 6962 soc_mem_unlock(unit, mem); 6963 return rv; 6964 } 6965 if (soc_mem_field32_get(unit, PORT_TABm, 6966 &entry, MY_MODIDf) == 6967 soc_mem_field32_get(unit, mem, l2, MODULE_IDf)) { 6968 p_index = soc_mem_field32_get(unit, mem, 6969 l2, PORT_NUMf) + 6970 soc_mem_index_count(unit, TRUNK_GROUPm) ; 6971 } 6972 break; 6973 case 1: /* trunk */ 6974 p_index = soc_mem_field32_get(unit, mem, 6975 l2, TGIDf); 6976 break; 6977 default: 6978 break; 6979 } 6980 6981 6982 /* 6983 * read and update vlan or vfi mac count 6984 * in buffer also update the sys mac count. 6985 */ 6986 v_count = 0; 6987 if (v_index >= 0) { 6988 v_entry = (vvm_buf + (v_index * vvm_entry_dw)); 6989 v_count = soc_mem_field32_get(unit, VLAN_OR_VFI_MAC_COUNTm, 6990 v_entry, COUNTf); 6991 s_count++; 6992 v_count++; 6993 soc_mem_field32_set(unit, VLAN_OR_VFI_MAC_COUNTm, 6994 v_entry, COUNTf, v_count); 6995 } 6996 6997 /* 6998 * read and update port or trunk mac count 6999 * in buffer. 7000 */ 7001 p_count = 0; 7002 if (p_index >= 0) { 7003 p_entry = ptm_buf + (p_index * ptm_entry_dw); 7004 p_count = soc_mem_field32_get(unit, 7005 PORT_OR_TRUNK_MAC_COUNTm, 7006 p_entry, COUNTf); 7007 p_count++; 7008 soc_mem_field32_set(unit, PORT_OR_TRUNK_MAC_COUNTm, 7009 p_entry, COUNTf, p_count); 7010 } 7011 7012 } /* End for index */ 7013 } /* End for chnk_idx */ 7014 7015 /* Free memory */ 7016 soc_cm_sfree(unit, buf); 7017 7018 } /* End if soc_feature_esm_support */ 7019 7020 /* Write the tables to hardware */ 7021 rv = soc_mem_write_range(unit, PORT_OR_TRUNK_MAC_COUNTm, MEM_BLOCK_ANY, 7022 ptm_index_min, ptm_index_max, (void *)ptm_buf); 7023 7024 if (rv < 0) { 7025 soc_cm_sfree(unit, ptm_buf); 7026 soc_cm_sfree(unit, vvm_buf); 7027 soc_mem_unlock(unit, mem); 7028 return SOC_E_FAIL; 7029 } 7030 7031 rv = soc_mem_write_range(unit, VLAN_OR_VFI_MAC_COUNTm, MEM_BLOCK_ANY, 7032 vvm_index_min, vvm_index_max, (void *)vvm_buf); 7033 7034 if (rv < 0) { 7035 soc_cm_sfree(unit, ptm_buf); 7036 soc_cm_sfree(unit, vvm_buf); 7037 soc_mem_unlock(unit, mem); 7038 return SOC_E_FAIL; 7039 } 7040 7041 /* Update system count */ 7042 soc_reg_field_set(unit, SYS_MAC_COUNTr, &rval, COUNTf, s_count); 7043 rv = WRITE_SYS_MAC_COUNTr(unit, rval); 7044 7045 /* Free memory */ 7046 soc_cm_sfree(unit, ptm_buf); 7047 soc_cm_sfree(unit, vvm_buf); 7048 7049 soc_mem_unlock(unit, mem); 7050 return rv; 7051 } 7052 7053 #endif /* BCM_TRIUMPH_SUPPORT */