ser_in_house.c (53300B)
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 * This test is intended to be used for in house SER testing. The test writes 8 * all SW accessible memories on chip and reads them back to check for flips. 9 * The assumption is that this test will be run at regular intervals in a loop 10 * that is part of a master soc script as per test requirements. The test 11 * provides information on the total memory tested, total number of flips and 12 * the logical coordinate of each flip. However it does not provide information 13 * about the physical coordinate of each flip. 14 * 15 * Configuration parameters passed from CLI: 16 * TestPat: Test Pattern used to fill the memories 17 * 0: All 0s 18 * 1: All 1s 19 * 2: Logical checker board 20 * 3: Logical inverse checker board 21 * RdWrMode: Whether the test writes or reads the memories 22 * 1: Test only writes all the memories under test 23 * 2: Test only reads back all memories under test and counts flips 24 */ 25 26 #include <appl/diag/system.h> 27 #include <shared/alloc.h> 28 #include <sal/core/alloc.h> 29 #include <shared/bsl.h> 30 #include<soc/mcm/intenum.h> 31 32 #include <soc/cm.h> 33 #include <soc/dma.h> 34 #include <soc/drv.h> 35 #include <soc/dcb.h> 36 #include <soc/cmicm.h> 37 #include <soc/cmic.h> 38 39 #include <sal/types.h> 40 #include <appl/diag/parse.h> 41 #include <appl/diag/system.h> 42 #include <bcm/port.h> 43 #include <bcm/vlan.h> 44 #include <bcm/link.h> 45 46 #include "testlist.h" 47 48 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 49 50 51 #define MEM_WORD 32 52 #define BYTE 8 53 #define CHB_FIRST_WORD 0x55555555 54 #define ICHB_FIRST_WORD 0xaaaaaaaa 55 56 #define MAX_FAIL_COUNT 10000 57 #define TEST_PATTERN_ALL0 0 58 #define TEST_PATTERN_ALL1 1 59 #define TEST_PATTERN_CHB 2 60 #define TEST_PATTERN_ICHB 3 61 62 #define WRITE_ONLY 1 63 #define READ_ONLY 2 64 65 #define TEST_PATTERN_PARAM_DEFAULT 2 66 #define RD_WR_MODE_PARAM_DEFAULT 1 67 #define QUIET_MODE_PARAM_DEFAULT 0 68 69 #define TH_ACC_TYPE_DUPLICATE 9 70 #define TH_ACC_TYPE_DATA_SPLIT 14 71 #define TH_ACC_TYPE_UNIQUE_PIPE0 0 72 #define TH_ACC_TYPE_UNIQUE_PIPE1 1 73 #define TH_ACC_TYPE_UNIQUE_PIPE2 2 74 #define TH_ACC_TYPE_UNIQUE_PIPE3 3 75 #define TH_ACC_TYPE_SINGLE 20 76 #define TH_ACC_TYPE_ADDR_SPLIT_DIST 10 77 #define TH_ACC_TYPE_ADDR_SPLIT_SPLIT 12 78 #define TH_NUM_UNIQUE_ACC_TYPES 4 79 #define TH_NUM_VALID_ACC_TYPES 9 80 #define TH_BASE_TYPE_IPORT 0 81 #define TH_BASE_TYPE_EPORT 1 82 #define TH_BASE_TYPE_IPIPE 2 83 #define TH_BASE_TYPE_EPIPE 3 84 #define TH_BASE_TYPE_CHIP 4 85 #define TH_BASE_TYPE_XPE 5 86 #define TH_BASE_TYPE_SLICE 6 87 #define TH_BASE_TYPE_LAYER 7 88 #define TH_NUM_VALID_BASE_TYPES 8 89 #define SBUS_V4_MMU_MEMIDX_MASK 0x0003ffff 90 #define TH_NUM_BASE_TYPE_BLOCKS 3 91 #define TH_MMU_ACC_TYPE_BOUNDARY 32768 92 #define INVALID_ACC_TYPE 999 93 94 typedef void (*get_valid_unique_acc_types_t) (int, soc_mem_t, uint32*); 95 96 typedef struct ser_ih_s { 97 uint32 test_pattern_param; 98 uint32 rd_wr_mode_param; 99 uint32 quiet_mode_param; 100 uint32 total_memories_written; 101 uint32 total_memories_read; 102 uint32 total_bits_tested; 103 uint32 bad_input; 104 uint32 total_flips; 105 uint32 test_fail; 106 uint32 num_acc_types; 107 uint32 num_unique_acc_types; 108 uint32 acc_type_duplicate; 109 uint32 acc_type_data_split; 110 uint32 acc_type_single; 111 uint32 acc_type_addr_split_dist; 112 uint32 acc_type_addr_split_split; 113 uint32 *acc_type_unique; 114 uint32 sbus_v4; 115 uint32 num_base_type_blocks; 116 get_valid_unique_acc_types_t get_valid_unique_acc_types; 117 uint32 memidx_mask; 118 uint32 **mask_array; 119 } ser_ih_t; 120 121 static ser_ih_t *ser_ih_parray[SOC_MAX_NUM_DEVICES]; 122 /* The do_not_test_list array contains a list of memories not to be tested. This 123 includes memories that are updated continuously by hardware even this test is 124 ran immediately after "init soc". The 'rc.soc" is not executed as it starts 125 more software threads and keeps writing to more memories. The list also 126 includes overlays and aggregates that are missed in the soc_mem_info_t. */ 127 #ifdef BCM_TOMAHAWK2_SUPPORT 128 static soc_mem_t th2_do_not_test_list[] = { 129 DLB_ECMP_GROUP_CONTROLm, 130 DLB_ECMP_PORT_INST_QUALITY_MEASUREm, 131 DLB_ECMP_PORT_INST_QUALITY_MEASURE_PIPE0m, 132 DLB_ECMP_PORT_INST_QUALITY_MEASURE_PIPE1m, 133 DLB_ECMP_PORT_INST_QUALITY_MEASURE_PIPE2m, 134 DLB_ECMP_PORT_INST_QUALITY_MEASURE_PIPE3m, 135 DLB_HGT_LAG_GROUP_CONTROLm, 136 DLB_HGT_LAG_PORT_INST_QUALITY_MEASUREm, 137 DLB_HGT_LAG_PORT_INST_QUALITY_MEASURE_PIPE0m, 138 DLB_HGT_LAG_PORT_INST_QUALITY_MEASURE_PIPE1m, 139 DLB_HGT_LAG_PORT_INST_QUALITY_MEASURE_PIPE2m, 140 DLB_HGT_LAG_PORT_INST_QUALITY_MEASURE_PIPE3m, 141 EFP_COUNTER_TABLEm, 142 EFP_COUNTER_TABLE_PIPE0m, 143 EFP_COUNTER_TABLE_PIPE1m, 144 EFP_COUNTER_TABLE_PIPE2m, 145 EFP_COUNTER_TABLE_PIPE3m, 146 EFP_METER_TABLEm, 147 EFP_METER_TABLE_PIPE0m, 148 EFP_METER_TABLE_PIPE1m, 149 EFP_METER_TABLE_PIPE2m, 150 EFP_METER_TABLE_PIPE3m, 151 EGR_PERQ_XMT_COUNTERSm, 152 EGR_PERQ_XMT_COUNTERS_PIPE0m, 153 EGR_PERQ_XMT_COUNTERS_PIPE1m, 154 EGR_PERQ_XMT_COUNTERS_PIPE2m, 155 EGR_PERQ_XMT_COUNTERS_PIPE3m, 156 EXACT_MATCH_4m, 157 EXACT_MATCH_2_ENTRY_ONLYm, 158 EXACT_MATCH_2_ENTRY_ONLY_PIPE0m, 159 EXACT_MATCH_2_ENTRY_ONLY_PIPE1m, 160 EXACT_MATCH_2_ENTRY_ONLY_PIPE2m, 161 EXACT_MATCH_2_ENTRY_ONLY_PIPE3m, 162 EXACT_MATCH_2_PIPE0m, 163 EXACT_MATCH_2_PIPE1m, 164 EXACT_MATCH_2_PIPE2m, 165 EXACT_MATCH_2_PIPE3m, 166 EXACT_MATCH_4_ENTRY_ONLYm, 167 EXACT_MATCH_4_ENTRY_ONLY_PIPE0m, 168 EXACT_MATCH_4_ENTRY_ONLY_PIPE1m, 169 EXACT_MATCH_4_ENTRY_ONLY_PIPE2m, 170 EXACT_MATCH_4_ENTRY_ONLY_PIPE3m, 171 EXACT_MATCH_4_PIPE0m, 172 EXACT_MATCH_4_PIPE1m, 173 EXACT_MATCH_4_PIPE2m, 174 EXACT_MATCH_4_PIPE3m, 175 EXACT_MATCH_HIT_ONLYm, 176 FPEM_ECCm, 177 FPEM_ECC_PIPE0m, 178 FPEM_ECC_PIPE1m, 179 FPEM_ECC_PIPE2m, 180 FPEM_ECC_PIPE3m, 181 IFP_METER_TABLEm, 182 IFP_METER_TABLE_PIPE0m, 183 IFP_METER_TABLE_PIPE1m, 184 IFP_METER_TABLE_PIPE2m, 185 IFP_METER_TABLE_PIPE3m, 186 IFP_STORM_CONTROL_METERSm, 187 L3_ENTRY_ONLYm, 188 MMU_MTRO_BUCKET_L0_MEMm, 189 MMU_MTRO_BUCKET_L0_MEM_0m, 190 MMU_MTRO_BUCKET_L0_MEM_1m, 191 MMU_MTRO_BUCKET_L0_MEM_PIPE0m, 192 MMU_MTRO_BUCKET_L0_MEM_PIPE1m, 193 MMU_MTRO_BUCKET_L0_MEM_PIPE2m, 194 MMU_MTRO_BUCKET_L0_MEM_PIPE3m, 195 MMU_MTRO_BUCKET_L1_MEMm, 196 MMU_MTRO_BUCKET_L1_MEM_0m, 197 MMU_MTRO_BUCKET_L1_MEM_1m, 198 MMU_MTRO_BUCKET_L1_MEM_PIPE0m, 199 MMU_MTRO_BUCKET_L1_MEM_PIPE1m, 200 MMU_MTRO_BUCKET_L1_MEM_PIPE2m, 201 MMU_MTRO_BUCKET_L1_MEM_PIPE3m, 202 MMU_MTRO_BUCKET_L2_MEMm, 203 MMU_MTRO_BUCKET_L2_MEM_0m, 204 MMU_MTRO_BUCKET_L2_MEM_1m, 205 MMU_MTRO_BUCKET_L2_MEM_2m, 206 MMU_MTRO_BUCKET_L2_MEM_3m, 207 MMU_MTRO_BUCKET_L2_MEM_4m, 208 MMU_MTRO_BUCKET_L2_MEM_5m, 209 MMU_MTRO_BUCKET_L2_MEM_6m, 210 MMU_MTRO_BUCKET_L2_MEM_7m, 211 MMU_MTRO_BUCKET_S1_MEM_0m, 212 MMU_MTRO_EGRMETERINGBUCKET_MEMm, 213 MMU_MTRO_EGRMETERINGBUCKET_MEM_0m, 214 MMU_MTRO_EGRMETERINGBUCKET_MEM_1m, 215 MMU_MTRO_EGRMETERINGBUCKET_MEM_PIPE0m, 216 MMU_MTRO_EGRMETERINGBUCKET_MEM_PIPE1m, 217 MMU_MTRO_EGRMETERINGBUCKET_MEM_PIPE2m, 218 MMU_MTRO_EGRMETERINGBUCKET_MEM_PIPE3m, 219 MMU_SEDCFG_MEM_FAIL_ADDR_64m, 220 MMU_SEDCFG_MEM_FAIL_ADDR_64_SC0m, 221 MMU_SEDCFG_MEM_FAIL_ADDR_64_SC1m, 222 MMU_THDU_UCQ_STATS_TABLEm, 223 MMU_THDU_UCQ_STATS_TABLE_XPE0_PIPE0m, 224 MMU_THDU_UCQ_STATS_TABLE_XPE0_PIPE1m, 225 MMU_THDU_UCQ_STATS_TABLE_XPE1_PIPE2m, 226 MMU_THDU_UCQ_STATS_TABLE_XPE1_PIPE3m, 227 MMU_THDU_UCQ_STATS_TABLE_XPE2_PIPE0m, 228 MMU_THDU_UCQ_STATS_TABLE_XPE2_PIPE1m, 229 MMU_THDU_UCQ_STATS_TABLE_XPE3_PIPE2m, 230 MMU_THDU_UCQ_STATS_TABLE_XPE3_PIPE3m, 231 MMU_WRED_AVG_QSIZE_XPE0_PIPE0m, 232 MMU_WRED_AVG_QSIZE_XPE0_PIPE1m, 233 MMU_WRED_AVG_QSIZE_XPE1_PIPE2m, 234 MMU_WRED_AVG_QSIZE_XPE1_PIPE3m, 235 MMU_WRED_AVG_QSIZE_XPE2_PIPE0m, 236 MMU_WRED_AVG_QSIZE_XPE2_PIPE1m, 237 MMU_WRED_AVG_QSIZE_XPE3_PIPE2m, 238 MMU_WRED_AVG_QSIZE_XPE3_PIPE3m, 239 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE0_PIPE0m, 240 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE0_PIPE1m, 241 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE1_PIPE2m, 242 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE1_PIPE3m, 243 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE2_PIPE0m, 244 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE2_PIPE1m, 245 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE3_PIPE2m, 246 MMU_WRED_PORT_SP_DROP_THD_MARK_XPE3_PIPE3m, 247 MMU_WRED_PORT_SP_DROP_THD_XPE0_PIPE0m, 248 MMU_WRED_PORT_SP_DROP_THD_XPE0_PIPE1m, 249 MMU_WRED_PORT_SP_DROP_THD_XPE1_PIPE2m, 250 MMU_WRED_PORT_SP_DROP_THD_XPE1_PIPE3m, 251 MMU_WRED_PORT_SP_DROP_THD_XPE2_PIPE0m, 252 MMU_WRED_PORT_SP_DROP_THD_XPE2_PIPE1m, 253 MMU_WRED_PORT_SP_DROP_THD_XPE3_PIPE2m, 254 MMU_WRED_PORT_SP_DROP_THD_XPE3_PIPE3m, 255 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE0_PIPE0m, 256 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE0_PIPE1m, 257 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE1_PIPE2m, 258 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE1_PIPE3m, 259 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE2_PIPE0m, 260 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE2_PIPE1m, 261 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE3_PIPE2m, 262 MMU_WRED_UC_QUEUE_DROP_THD_0_XPE3_PIPE3m, 263 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE0_PIPE0m, 264 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE0_PIPE1m, 265 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE1_PIPE2m, 266 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE1_PIPE3m, 267 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE2_PIPE0m, 268 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE2_PIPE1m, 269 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE3_PIPE2m, 270 MMU_WRED_UC_QUEUE_DROP_THD_1_XPE3_PIPE3m, 271 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE0_PIPE0m, 272 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE0_PIPE1m, 273 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE1_PIPE2m, 274 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE1_PIPE3m, 275 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE2_PIPE0m, 276 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE2_PIPE1m, 277 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE3_PIPE2m, 278 MMU_WRED_UC_QUEUE_DROP_THD_MARK_XPE3_PIPE3m 279 }; 280 #else 281 static soc_mem_t th2_do_not_test_list[1]; 282 #endif 283 #ifdef BCM_TOMAHAWK_SUPPORT 284 static soc_mem_t th_do_not_test_list[] = { 285 EGR_SER_FIFOm, 286 EGR_SER_FIFO_PIPE0m, 287 EGR_SER_FIFO_PIPE1m, 288 EGR_SER_FIFO_PIPE2m, 289 EGR_SER_FIFO_PIPE3m, 290 ING_SER_FIFOm, 291 ING_SER_FIFO_PIPE0m, 292 ING_SER_FIFO_PIPE1m, 293 ING_SER_FIFO_PIPE2m, 294 ING_SER_FIFO_PIPE3m, 295 L2_MGMT_SER_FIFOm, 296 SER_ACC_TYPE_MAPm, 297 SER_MEMORYm, 298 SER_RESULT_0m, 299 SER_RESULT_1m, 300 SER_RESULT_DATA_0m, 301 SER_RESULT_DATA_1m, 302 SER_RESULT_EXPECTED_0m, 303 SER_RESULT_EXPECTED_1m, 304 CENTRAL_CTR_EVICTION_FIFOm, 305 CLPORT_WC_UCMEM_DATAm, 306 XLPORT_WC_UCMEM_DATAm, 307 L2Xm, 308 L2_BULKm, 309 L2_ENTRY_ISS_LPm, 310 L2_ENTRY_ONLY_TILEm, 311 L3_DEFIP_AUX_HITBIT_UPDATEm, 312 L3_DEFIP_PAIR_128_DATA_ONLYm, 313 L3_DEFIP_PAIR_128_HIT_ONLYm, 314 L3_DEFIP_DATA_ONLYm, 315 L3_ENTRY_HIT_ONLYm, 316 L3_ENTRY_IPV4_MULTICASTm, 317 L3_ENTRY_IPV4_UNICASTm, 318 L3_ENTRY_IPV6_MULTICASTm, 319 L3_ENTRY_IPV6_UNICASTm, 320 L3_ENTRY_LPm, 321 MMU_GCFG_MEM_FAIL_ADDR_64m, 322 MMU_SCFG_MEM_FAIL_ADDR_64_SC0m, 323 MMU_XCFG_MEM_FAIL_ADDR_64_XPE0m, 324 MMU_XCFG_MEM_FAIL_ADDR_64_XPE1m, 325 MMU_XCFG_MEM_FAIL_ADDR_64_XPE2m, 326 MMU_XCFG_MEM_FAIL_ADDR_64_XPE3m, 327 MMU_SCFG_MEM_FAIL_ADDR_64_SC1m, 328 EGR_IP_TUNNEL_IPV6m, 329 EGR_IP_TUNNEL_MPLSm, 330 EDB_1DBG_Bm, 331 MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE0m, 332 MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE1m, 333 MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE2m, 334 MMU_MTRO_EGRMETERINGCONFIG_MEM_A_PIPE3m, 335 MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE0m, 336 MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE1m, 337 MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE2m, 338 MMU_MTRO_EGRMETERINGCONFIG_MEM_B_PIPE3m, 339 MMU_REPL_GROUP_INITIAL_COPY_COUNT_SC0m, 340 MMU_REPL_GROUP_INITIAL_COPY_COUNT_SC1m, 341 THDI_PORT_SP_CONFIG_PIPE0m, 342 THDI_PORT_SP_CONFIG_PIPE1m, 343 THDI_PORT_SP_CONFIG_PIPE2m, 344 THDI_PORT_SP_CONFIG_PIPE3m, 345 MMU_THDM_DB_QUEUE_CONFIG_PIPE0m, 346 MMU_THDM_DB_QUEUE_CONFIG_PIPE1m, 347 MMU_THDM_DB_QUEUE_CONFIG_PIPE2m, 348 MMU_THDM_DB_QUEUE_CONFIG_PIPE3m, 349 MMU_THDM_DB_QUEUE_OFFSET_PIPE0m, 350 MMU_THDM_DB_QUEUE_OFFSET_PIPE1m, 351 MMU_THDM_DB_QUEUE_OFFSET_PIPE2m, 352 MMU_THDM_DB_QUEUE_OFFSET_PIPE3m, 353 MMU_THDM_DB_PORTSP_CONFIG_PIPE0m, 354 MMU_THDM_DB_PORTSP_CONFIG_PIPE1m, 355 MMU_THDM_DB_PORTSP_CONFIG_PIPE2m, 356 MMU_THDM_DB_PORTSP_CONFIG_PIPE3m, 357 MMU_THDM_MCQE_QUEUE_CONFIG_PIPE0m, 358 MMU_THDM_MCQE_QUEUE_CONFIG_PIPE1m, 359 MMU_THDM_MCQE_QUEUE_CONFIG_PIPE2m, 360 MMU_THDM_MCQE_QUEUE_CONFIG_PIPE3m, 361 MMU_THDM_MCQE_QUEUE_OFFSET_PIPE0m, 362 MMU_THDM_MCQE_QUEUE_OFFSET_PIPE1m, 363 MMU_THDM_MCQE_QUEUE_OFFSET_PIPE2m, 364 MMU_THDM_MCQE_QUEUE_OFFSET_PIPE3m, 365 MMU_THDM_MCQE_PORTSP_CONFIG_PIPE0m, 366 MMU_THDM_MCQE_PORTSP_CONFIG_PIPE1m, 367 MMU_THDM_MCQE_PORTSP_CONFIG_PIPE2m, 368 MMU_THDM_MCQE_PORTSP_CONFIG_PIPE3m, 369 MMU_THDU_Q_TO_QGRP_MAP_PIPE0m, 370 MMU_THDU_Q_TO_QGRP_MAP_PIPE1m, 371 MMU_THDU_Q_TO_QGRP_MAP_PIPE2m, 372 MMU_THDU_Q_TO_QGRP_MAP_PIPE3m, 373 MMU_THDU_CONFIG_QUEUE_PIPE0m, 374 MMU_THDU_CONFIG_QUEUE_PIPE1m, 375 MMU_THDU_CONFIG_QUEUE_PIPE2m, 376 MMU_THDU_CONFIG_QUEUE_PIPE3m, 377 MMU_THDU_OFFSET_QUEUE_PIPE0m, 378 MMU_THDU_OFFSET_QUEUE_PIPE1m, 379 MMU_THDU_OFFSET_QUEUE_PIPE2m, 380 MMU_THDU_OFFSET_QUEUE_PIPE3m, 381 MMU_THDU_CONFIG_QGROUP_PIPE0m, 382 MMU_THDU_CONFIG_QGROUP_PIPE1m, 383 MMU_THDU_CONFIG_QGROUP_PIPE2m, 384 MMU_THDU_CONFIG_QGROUP_PIPE3m, 385 MMU_THDU_OFFSET_QGROUP_PIPE0m, 386 MMU_THDU_OFFSET_QGROUP_PIPE1m, 387 MMU_THDU_OFFSET_QGROUP_PIPE2m, 388 MMU_THDU_OFFSET_QGROUP_PIPE3m, 389 MMU_THDU_CONFIG_PORT_PIPE0m, 390 MMU_THDU_CONFIG_PORT_PIPE1m, 391 MMU_THDU_CONFIG_PORT_PIPE2m, 392 MMU_THDU_CONFIG_PORT_PIPE3m, 393 MMU_THDU_RESUME_PORT_PIPE0m, 394 MMU_THDU_RESUME_PORT_PIPE1m, 395 MMU_THDU_RESUME_PORT_PIPE2m, 396 MMU_THDU_RESUME_PORT_PIPE3m, 397 MMU_WRED_DROP_CURVE_PROFILE_0m, 398 MMU_WRED_DROP_CURVE_PROFILE_1m, 399 MMU_WRED_DROP_CURVE_PROFILE_2m, 400 MMU_WRED_DROP_CURVE_PROFILE_3m, 401 MMU_WRED_DROP_CURVE_PROFILE_4m, 402 MMU_WRED_DROP_CURVE_PROFILE_5m, 403 MMU_WRED_DROP_CURVE_PROFILE_6m, 404 MMU_WRED_DROP_CURVE_PROFILE_7m, 405 MMU_CFAP_BANK0_XPE0m, 406 MMU_CFAP_BANK0_XPE1m, 407 MMU_CFAP_BANK0_XPE2m, 408 MMU_CFAP_BANK0_XPE3m, 409 MMU_CFAP_BANK1_XPE0m, 410 MMU_CFAP_BANK1_XPE1m, 411 MMU_CFAP_BANK1_XPE2m, 412 MMU_CFAP_BANK1_XPE3m, 413 MMU_CFAP_BANK2_XPE0m, 414 MMU_CFAP_BANK2_XPE1m, 415 MMU_CFAP_BANK2_XPE2m, 416 MMU_CFAP_BANK2_XPE3m, 417 MMU_CFAP_BANK3_XPE0m, 418 MMU_CFAP_BANK3_XPE1m, 419 MMU_CFAP_BANK3_XPE2m, 420 MMU_CFAP_BANK3_XPE3m, 421 MMU_CFAP_BANK4_XPE0m, 422 MMU_CFAP_BANK4_XPE1m, 423 MMU_CFAP_BANK4_XPE2m, 424 MMU_CFAP_BANK4_XPE3m, 425 MMU_CFAP_BANK5_XPE0m, 426 MMU_CFAP_BANK5_XPE1m, 427 MMU_CFAP_BANK5_XPE2m, 428 MMU_CFAP_BANK5_XPE3m, 429 MMU_CFAP_BANK6_XPE0m, 430 MMU_CFAP_BANK6_XPE1m, 431 MMU_CFAP_BANK6_XPE2m, 432 MMU_CFAP_BANK6_XPE3m, 433 MMU_CFAP_BANK7_XPE0m, 434 MMU_CFAP_BANK7_XPE1m, 435 MMU_CFAP_BANK7_XPE2m, 436 MMU_CFAP_BANK7_XPE3m, 437 MMU_CFAP_BANK8_XPE0m, 438 MMU_CFAP_BANK8_XPE1m, 439 MMU_CFAP_BANK8_XPE2m, 440 MMU_CFAP_BANK8_XPE3m, 441 MMU_CFAP_BANK9_XPE0m, 442 MMU_CFAP_BANK9_XPE1m, 443 MMU_CFAP_BANK9_XPE2m, 444 MMU_CFAP_BANK9_XPE3m, 445 MMU_CFAP_BANK10_XPE0m, 446 MMU_CFAP_BANK10_XPE1m, 447 MMU_CFAP_BANK10_XPE2m, 448 MMU_CFAP_BANK10_XPE3m, 449 MMU_CFAP_BANK11_XPE0m, 450 MMU_CFAP_BANK11_XPE1m, 451 MMU_CFAP_BANK11_XPE2m, 452 MMU_CFAP_BANK11_XPE3m, 453 MMU_CFAP_BANK12_XPE0m, 454 MMU_CFAP_BANK12_XPE1m, 455 MMU_CFAP_BANK12_XPE2m, 456 MMU_CFAP_BANK12_XPE3m, 457 MMU_CFAP_BANK13_XPE0m, 458 MMU_CFAP_BANK13_XPE1m, 459 MMU_CFAP_BANK13_XPE2m, 460 MMU_CFAP_BANK13_XPE3m, 461 MMU_CFAP_BANK14_XPE0m, 462 MMU_CFAP_BANK14_XPE1m, 463 MMU_CFAP_BANK14_XPE2m, 464 MMU_CFAP_BANK14_XPE3m 465 }; 466 #else 467 /* Dummy array to get through preco error for unsupported chips */ 468 static soc_mem_t th_do_not_test_list[1]; 469 #endif /* BCM_TOMAHAWK_SUPPORT */ 470 471 #ifdef BCM_TRIDENT2_SUPPORT 472 static soc_mem_t td2p_do_not_test_list[] = { 473 DLB_HGT_FLOWSETm, 474 DLB_HGT_FLOWSET_Xm, 475 DLB_HGT_FLOWSET_Ym, 476 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_Xm, 477 DLB_HGT_FLOWSET_TIMESTAMP_PAGE_Ym, 478 DLB_HGT_GROUP_STATS_Xm, 479 DLB_HGT_GROUP_STATS_Ym, 480 DLB_HGT_OPTIMAL_CANDIDATE_Xm, 481 DLB_HGT_OPTIMAL_CANDIDATE_Ym, 482 EFP_COUNTER_TABLE_Xm, 483 EFP_COUNTER_TABLE_Ym, 484 EFP_METER_TABLE_Xm, 485 EFP_METER_TABLE_Ym, 486 EGR_FLEX_CTR_COUNTER_TABLE_0_Xm, 487 EGR_FLEX_CTR_COUNTER_TABLE_0_Ym, 488 EGR_FLEX_CTR_COUNTER_TABLE_1_Xm, 489 EGR_FLEX_CTR_COUNTER_TABLE_1_Ym, 490 EGR_FLEX_CTR_COUNTER_TABLE_2_Xm, 491 EGR_FLEX_CTR_COUNTER_TABLE_2_Ym, 492 EGR_FLEX_CTR_COUNTER_TABLE_3_Xm, 493 EGR_FLEX_CTR_COUNTER_TABLE_3_Ym, 494 EGR_FRAGMENT_ID_TABLE_Xm, 495 EGR_FRAGMENT_ID_TABLE_Ym, 496 EGR_IP_TUNNEL_IPV6m, 497 EGR_MMU_CREDIT_LIMIT_Xm, 498 EGR_MMU_CREDIT_LIMIT_Ym, 499 EGR_PERQ_XMT_COUNTERS_Xm, 500 EGR_PERQ_XMT_COUNTERS_Ym, 501 EGR_PW_INIT_COUNTERS_Xm, 502 EGR_PW_INIT_COUNTERS_Ym, 503 EGR_SER_FIFOm, 504 FP_COUNTER_TABLE_Xm, 505 FP_COUNTER_TABLE_Ym, 506 FP_GLOBAL_MASK_TCAMm, 507 FP_STORM_CONTROL_METERS_Xm, 508 FP_STORM_CONTROL_METERS_Ym, 509 IARB_MAIN_TDM_Xm, 510 IARB_MAIN_TDM_Ym, 511 ING_FLEX_CTR_COUNTER_TABLE_0_Xm, 512 ING_FLEX_CTR_COUNTER_TABLE_0_Ym, 513 ING_FLEX_CTR_COUNTER_TABLE_1_Xm, 514 ING_FLEX_CTR_COUNTER_TABLE_1_Ym, 515 ING_FLEX_CTR_COUNTER_TABLE_2_Xm, 516 ING_FLEX_CTR_COUNTER_TABLE_2_Ym, 517 ING_FLEX_CTR_COUNTER_TABLE_3_Xm, 518 ING_FLEX_CTR_COUNTER_TABLE_3_Ym, 519 ING_FLEX_CTR_COUNTER_TABLE_4_Xm, 520 ING_FLEX_CTR_COUNTER_TABLE_4_Ym, 521 ING_FLEX_CTR_COUNTER_TABLE_5_Xm, 522 ING_FLEX_CTR_COUNTER_TABLE_5_Ym, 523 ING_FLEX_CTR_COUNTER_TABLE_6_Xm, 524 ING_FLEX_CTR_COUNTER_TABLE_6_Ym, 525 ING_FLEX_CTR_COUNTER_TABLE_7_Xm, 526 ING_FLEX_CTR_COUNTER_TABLE_7_Ym, 527 ING_PW_TERM_SEQ_NUM_Xm, 528 ING_PW_TERM_SEQ_NUM_Ym, 529 ING_SERVICE_PRI_MAPm, 530 ING_SER_FIFOm, 531 ING_SNAT_HIT_ONLY_Xm, 532 ING_SNAT_HIT_ONLY_Ym, 533 L2_HITDA_ONLY_Xm, 534 L2_HITDA_ONLY_Ym, 535 L2_HITSA_ONLY_Xm, 536 L2_HITSA_ONLY_Ym, 537 L2_ENTRY_LPm, 538 L3_DEFIP_HIT_ONLY_Xm, 539 L3_DEFIP_HIT_ONLY_Ym, 540 L3_DEFIP_PAIR_128_HIT_ONLY_Xm, 541 L3_DEFIP_PAIR_128_HIT_ONLY_Ym, 542 L3_ENTRY_HIT_ONLYm, 543 L3_ENTRY_HIT_ONLY_Xm, 544 L3_ENTRY_HIT_ONLY_Ym, 545 L3_ENTRY_IPV4_MULTICASTm, 546 L3_ENTRY_IPV4_UNICASTm, 547 L3_ENTRY_IPV6_MULTICASTm, 548 L3_ENTRY_IPV6_UNICASTm, 549 L3_ENTRY_LPm, 550 LMEPm, 551 LMEP_DAm, 552 MAID_REDUCTIONm, 553 MA_INDEXm, 554 MA_STATEm, 555 MMU_CFAP_BANK0m, 556 MMU_CFAP_BANK1m, 557 MMU_CFAP_BANK2m, 558 MMU_CFAP_BANK3m, 559 MMU_CFAP_BANK4m, 560 MMU_CFAP_BANK5m, 561 MMU_CFAP_BANK6m, 562 MMU_CFAP_BANK7m, 563 MMU_CFAP_BANK8m, 564 MMU_CFAP_BANK9m, 565 MMU_CFAP_BANK10m, 566 MMU_CFAP_BANK11m, 567 MMU_CFAP_BANK12m, 568 MMU_CFAP_BANK13m, 569 MMU_CFAP_BANK14m, 570 MMU_CFAP_BANK15m, 571 MMU_CFAP_BANK16m, 572 MMU_CFAP_BANK17m, 573 MMU_CFAP_BANK18m, 574 MMU_CFAP_BANK19m, 575 MMU_CFAP_BANK20m, 576 MMU_INTFI_PFC_ST_TBLm, 577 OAM_LM_COUNTERSm, 578 RH_HGT_DROPS_Xm, 579 RH_HGT_DROPS_Ym, 580 RMEPm, 581 SER_MEMORYm, 582 XLPORT_WC_UCMEM_DATAm 583 }; 584 #else 585 /* Dummy array to get through preco error for unsupported chips */ 586 static soc_mem_t td2p_do_not_test_list[1]; 587 #endif /* BCM_TRIDENT2_SUPPORT */ 588 589 /* List of TCAMs to be covered. This list is maintained separately because a lot 590 of memories marked as CAMs are actually aggregates having both an SRAM and a 591 CAM. This list is generated by searching for names with --A flags from the 592 listmem command, duplicates like _[X|Y] and _PIPE[0-3] */ 593 #ifdef BCM_TOMAHAWK_SUPPORT 594 static soc_mem_t th_tcam_test_list[] = { 595 L3_TUNNEL_ONLYm, 596 FP_UDF_TCAMm, 597 VLAN_SUBNET_ONLYm, 598 VFP_TCAMm, 599 MY_STATION_TCAM_ENTRY_ONLYm, 600 IP_MULTICAST_TCAMm, 601 L2_USER_ENTRY_ONLYm, 602 L3_DEFIP_ONLYm, 603 EXACT_MATCH_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 604 DST_COMPRESSION_TCAM_ONLYm, 605 SRC_COMPRESSION_TCAM_ONLYm, 606 IFP_LOGICAL_TABLE_SELECT_TCAM_ONLYm, 607 IFP_TCAMm, 608 ING_SNAT_ONLYm, 609 CPU_COS_MAP_ONLYm, 610 EFP_TCAMm 611 }; 612 #else 613 /* Dummy array to get through preco error for unsupported chips */ 614 static soc_mem_t th_tcam_test_list[1]; 615 #endif /* BCM_TOMAHAWK_SUPPORT */ 616 617 #ifdef BCM_TRIDENT2_SUPPORT 618 static soc_mem_t td2p_tcam_test_list[] = { 619 CPU_COS_MAP_ONLYm, 620 EFP_TCAMm, 621 FP_GM_FIELDSm, 622 FP_TCAMm, 623 FP_UDF_TCAMm, 624 ING_SNAT_ONLYm, 625 IP_MULTICAST_TCAMm, 626 L2_USER_ENTRY_ONLYm, 627 L3_DEFIP_ONLYm, 628 L3_TUNNEL_ONLYm, 629 MY_STATION_TCAM_ENTRY_ONLYm, 630 MY_STATION_TCAM_2_ENTRY_ONLYm, 631 SUBPORT_TAG_SGPP_MAP_ONLYm, 632 UDF_CONDITIONAL_CHECK_TABLE_CAMm, 633 VFP_TCAMm, 634 VLAN_SUBNET_ONLYm 635 }; 636 #else 637 /* Dummy array to get through preco error for unsupported chips */ 638 static soc_mem_t td2p_tcam_test_list[1]; 639 #endif /* BCM_TRIDENT2_SUPPORT */ 640 641 static void 642 th_get_valid_unique_acc_types(int unit, soc_mem_t mem, 643 uint32 *unique_acc_types) 644 { 645 int block; 646 int base_type; 647 uint32 memidx; 648 soc_mem_info_t *meminfo = &SOC_MEM_INFO(unit, mem); 649 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 650 651 memidx = meminfo->base & ser_ih_p->memidx_mask; 652 653 unique_acc_types[0] = ser_ih_p->acc_type_unique[0]; 654 unique_acc_types[1] = ser_ih_p->acc_type_unique[1]; 655 unique_acc_types[2] = ser_ih_p->acc_type_unique[2]; 656 unique_acc_types[3] = ser_ih_p->acc_type_unique[3]; 657 658 base_type = SOC_MEM_BASE_TYPE(unit, mem); 659 660 SOC_MEM_BLOCK_ITER(unit, mem, block) { 661 if (block == MMU_XPE_BLOCK(unit)) { 662 switch (base_type) { 663 case TH_BASE_TYPE_IPIPE : 664 if ((memidx / 32768 == 0) 665 || (memidx / 32768 == 3)) { 666 unique_acc_types[2] = INVALID_ACC_TYPE; 667 unique_acc_types[3] = INVALID_ACC_TYPE; 668 } else { 669 unique_acc_types[0] = INVALID_ACC_TYPE; 670 unique_acc_types[1] = INVALID_ACC_TYPE; 671 } 672 break; 673 case TH_BASE_TYPE_EPIPE : 674 if ((memidx / 32768 == 0) 675 || (memidx / 32768 == 1)) { 676 unique_acc_types[1] = INVALID_ACC_TYPE; 677 unique_acc_types[3] = INVALID_ACC_TYPE; 678 } else { 679 unique_acc_types[0] = INVALID_ACC_TYPE; 680 unique_acc_types[2] = INVALID_ACC_TYPE; 681 } 682 break; 683 case TH_BASE_TYPE_SLICE : 684 if (memidx / 32768 == 0) { 685 unique_acc_types[1] = INVALID_ACC_TYPE; 686 unique_acc_types[3] = INVALID_ACC_TYPE; 687 } else { 688 unique_acc_types[0] = INVALID_ACC_TYPE; 689 unique_acc_types[2] = INVALID_ACC_TYPE; 690 } 691 break; 692 case TH_BASE_TYPE_LAYER : 693 if (memidx / 32768 == 0) { 694 unique_acc_types[2] = INVALID_ACC_TYPE; 695 unique_acc_types[3] = INVALID_ACC_TYPE; 696 } else { 697 unique_acc_types[0] = INVALID_ACC_TYPE; 698 unique_acc_types[1] = INVALID_ACC_TYPE; 699 } 700 break; 701 default : 702 unique_acc_types[0] = INVALID_ACC_TYPE; 703 unique_acc_types[1] = INVALID_ACC_TYPE; 704 unique_acc_types[2] = INVALID_ACC_TYPE; 705 unique_acc_types[3] = INVALID_ACC_TYPE; 706 break; 707 } 708 } else if (block == MMU_SC_BLOCK(unit)) { 709 switch (base_type) { 710 case TH_BASE_TYPE_IPIPE : 711 case TH_BASE_TYPE_LAYER: 712 unique_acc_types[2] = INVALID_ACC_TYPE; 713 unique_acc_types[3] = INVALID_ACC_TYPE; 714 break; 715 default: 716 unique_acc_types[0] = INVALID_ACC_TYPE; 717 unique_acc_types[1] = INVALID_ACC_TYPE; 718 unique_acc_types[2] = INVALID_ACC_TYPE; 719 unique_acc_types[3] = INVALID_ACC_TYPE; 720 break; 721 } 722 } 723 } 724 } 725 726 static void 727 get_chip_specific_data(int unit) 728 { 729 uint16 dev_id; 730 uint8 rev_id; 731 732 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 733 734 soc_cm_get_id (unit, &dev_id, &rev_id); 735 736 cli_out("\nDevice ID = 0x%04x, Rev ID = %0d", dev_id, rev_id); 737 738 if (dev_id == BCM56960_DEVICE_ID || dev_id == BCM56860_DEVICE_ID || 739 dev_id == BCM56970_DEVICE_ID) { 740 ser_ih_p->sbus_v4 = 1; 741 ser_ih_p->memidx_mask = SBUS_V4_MMU_MEMIDX_MASK; 742 ser_ih_p->num_unique_acc_types = TH_NUM_UNIQUE_ACC_TYPES; 743 ser_ih_p->num_acc_types = TH_NUM_VALID_ACC_TYPES; 744 ser_ih_p->acc_type_duplicate = TH_ACC_TYPE_DUPLICATE; 745 ser_ih_p->acc_type_single = TH_ACC_TYPE_SINGLE; 746 ser_ih_p->acc_type_data_split = TH_ACC_TYPE_DATA_SPLIT; 747 ser_ih_p->acc_type_addr_split_dist = TH_ACC_TYPE_ADDR_SPLIT_DIST; 748 ser_ih_p->acc_type_addr_split_split = TH_ACC_TYPE_ADDR_SPLIT_SPLIT; 749 750 ser_ih_p->acc_type_unique = (uint32*) 751 sal_alloc(ser_ih_p->num_unique_acc_types * 752 sizeof(uint32), 753 "acc_type_unique"); 754 ser_ih_p->acc_type_unique[0] = TH_ACC_TYPE_UNIQUE_PIPE0; 755 ser_ih_p->acc_type_unique[1] = TH_ACC_TYPE_UNIQUE_PIPE1; 756 ser_ih_p->acc_type_unique[2] = TH_ACC_TYPE_UNIQUE_PIPE2; 757 ser_ih_p->acc_type_unique[3] = TH_ACC_TYPE_UNIQUE_PIPE3; 758 759 ser_ih_p->memidx_mask = SBUS_V4_MMU_MEMIDX_MASK; 760 ser_ih_p->get_valid_unique_acc_types = &th_get_valid_unique_acc_types; 761 762 } else { 763 cli_out("\nUnsupported chip"); 764 ser_ih_p->bad_input = 1; 765 } 766 } 767 768 static int 769 is_acc_type_unique(int unit, soc_mem_t mem) 770 { 771 int rv = 0; 772 int i; 773 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 774 775 for (i = 0; i < ser_ih_p->num_unique_acc_types; i++) { 776 if (SOC_MEM_ACC_TYPE(unit, mem) == ser_ih_p->acc_type_unique[i]) { 777 rv = 1; 778 } 779 } 780 781 return rv; 782 } 783 784 785 static int 786 do_not_test(int unit, soc_mem_t mem) 787 { 788 int i; 789 int rv = 0; 790 int num_do_not_test = 0; 791 soc_mem_t dummy_list[] = {0}; 792 soc_mem_t *do_not_test_list; 793 794 if (SOC_IS_TOMAHAWKX(unit)) { 795 num_do_not_test = sizeof(th_do_not_test_list) / 796 sizeof(th_do_not_test_list[0]); 797 do_not_test_list = th_do_not_test_list; 798 } else if (SOC_IS_TRIDENT2PLUS(unit)) { 799 num_do_not_test = sizeof(td2p_do_not_test_list) / 800 sizeof(td2p_do_not_test_list[0]); 801 do_not_test_list = td2p_do_not_test_list; 802 } else { 803 do_not_test_list = dummy_list; 804 } 805 for (i = 0; i < num_do_not_test; i++) { 806 if (mem == do_not_test_list[i]) { 807 rv = 1; 808 return rv; 809 } 810 } 811 812 if (SOC_IS_TOMAHAWK2(unit)) { 813 num_do_not_test = sizeof(th2_do_not_test_list) / 814 sizeof(th2_do_not_test_list[0]); 815 do_not_test_list = th2_do_not_test_list; 816 817 for (i = 0; i < num_do_not_test; i++) { 818 if (mem == do_not_test_list[i]) { 819 rv = 1; 820 return rv; 821 } 822 } 823 } 824 825 return rv; 826 } 827 828 static int 829 test_tcam(int unit, soc_mem_t mem) { 830 int i; 831 int rv = 0; 832 int num_tcam_test = 0; 833 soc_mem_t dummy_list[] = {0}; 834 soc_mem_t *tcam_test_list; 835 836 if (SOC_IS_TOMAHAWKX(unit)) { 837 num_tcam_test = sizeof(th_tcam_test_list) / 838 sizeof(th_tcam_test_list[0]); 839 tcam_test_list = th_tcam_test_list; 840 } else if (SOC_IS_TRIDENT2PLUS(unit)) { 841 num_tcam_test = sizeof(td2p_tcam_test_list) / 842 sizeof(td2p_tcam_test_list[0]); 843 tcam_test_list = td2p_tcam_test_list; 844 } else { 845 tcam_test_list = dummy_list; 846 } 847 for (i = 0; i < num_tcam_test; i++) { 848 if (mem == tcam_test_list[i]) { 849 rv = 1; 850 } 851 } 852 return rv; 853 } 854 855 static int 856 test_mem(int unit, soc_mem_t mem) 857 { 858 int rv = 0; 859 uint32 num_entries; 860 uint32 flags = 0; 861 862 if (SOC_MEM_IS_VALID(unit, mem)) { 863 num_entries = soc_mem_index_max(unit, mem) 864 - soc_mem_index_min(unit, mem) + 1; 865 flags = SOC_MEM_INFO(unit, mem).flags; 866 if ((!((flags & SOC_MEM_FLAG_AGGR) || (flags & SOC_MEM_FLAG_READONLY))) 867 && (num_entries >= 2) && (do_not_test(unit, mem) == 0)) { 868 if (flags & SOC_MEM_FLAG_CAM) { 869 if (test_tcam(unit, mem) == 1) { 870 rv = 1; 871 } 872 } else { 873 rv = 1; 874 } 875 } 876 } 877 return rv; 878 } 879 880 static int 881 duplicate_mem(int unit, soc_mem_t mem) { 882 int i; 883 int rv = 0; 884 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 885 soc_mem_info_t *meminfo = &SOC_MEM_INFO(unit, mem); 886 887 if ((test_mem(unit, mem) == 1) 888 && (is_acc_type_unique(unit, mem) == 1)) { 889 for (i = 0; i < NUM_SOC_MEM; i++) { 890 if (test_mem(unit, i) == 1) { 891 if (meminfo->base == SOC_MEM_INFO(unit, i).base) { 892 if ((SOC_MEM_ACC_TYPE(unit, i) 893 == ser_ih_p->acc_type_duplicate) 894 || (SOC_MEM_ACC_TYPE(unit, i) 895 == ser_ih_p->acc_type_data_split) 896 ) { 897 rv = 1; 898 } 899 } 900 } 901 } 902 } 903 return rv; 904 } 905 906 907 908 static int 909 do_unique_access(int unit, soc_mem_t mem) 910 { 911 int rv = 0; 912 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 913 914 if (SOC_MEM_ACC_TYPE(unit, mem) == ser_ih_p->acc_type_duplicate) { 915 rv = 1; 916 } 917 918 return rv; 919 } 920 921 static void 922 ser_ih_parse_test_params(int unit, args_t *a) 923 { 924 parse_table_t parse_table; 925 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 926 927 const char tr901_test_usage[] = 928 #ifdef COMPILER_STRING_CONST_LIMIT 929 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 930 #else 931 "This test is intended to be used for in house SER testing. The test can be\n" 932 "to write all SW accessible memories on chip and read them back to check for\n" 933 "flips. The assumption is that this test will be run at regular intervals in a\n" 934 "loop that is part of a master soc script as per test requirements. The test\n" 935 "provides information on the total memory tested, total number of flips and\n" 936 "the logical coordinate of each flip. However it does not provide information\n" 937 "about the physical coordinate of each flip.\n" 938 "\n" 939 "Configuration parameters passed from CLI:\n" 940 "TestPat: Test Pattern used to fill the memories\n" 941 " 0: All 0s\n" 942 " 1: All 1s\n" 943 " 2: Logical checker board\n" 944 " 3: Logical inverse checker board\n" 945 "RdWrMode: Whether the test writes or reads the memories\n" 946 " 1: Test only writes all the memories under test\n" 947 " 2: Test only reads back all memories under test and counts flips\n"; 948 #endif 949 950 ser_ih_p->bad_input = 0; 951 952 ser_ih_p->test_pattern_param = TEST_PATTERN_PARAM_DEFAULT; 953 ser_ih_p->rd_wr_mode_param = RD_WR_MODE_PARAM_DEFAULT; 954 ser_ih_p->quiet_mode_param = QUIET_MODE_PARAM_DEFAULT; 955 /*Parse CLI opts */ 956 957 parse_table_init(unit, &parse_table); 958 parse_table_add(&parse_table, "TestPat", PQ_INT | PQ_DFL, 959 0, &(ser_ih_p->test_pattern_param), NULL); 960 parse_table_add(&parse_table, "RdWrMode", PQ_INT | PQ_DFL, 961 0, &(ser_ih_p->rd_wr_mode_param), NULL); 962 parse_table_add(&parse_table, "QuietMode", PQ_INT | PQ_DFL, 963 0, &(ser_ih_p->quiet_mode_param), NULL); 964 965 966 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 967 test_msg("%s", tr901_test_usage); 968 test_error(unit, 969 "%s: Invalid option: %s\n", 970 ARG_CMD(a), 971 ARG_CUR(a) ? ARG_CUR(a) : "*"); 972 ser_ih_p->bad_input = 1; 973 parse_arg_eq_done(&parse_table); 974 } else { 975 cli_out("\n-----------------"); 976 cli_out("\n TEST PARAMETERS "); 977 cli_out("\n-----------------"); 978 cli_out("\ntest_pattern = %0d", ser_ih_p->test_pattern_param); 979 cli_out("\nrd_wr_mode = %0d", ser_ih_p->rd_wr_mode_param); 980 cli_out("\nquiet_mode = %0d", ser_ih_p->quiet_mode_param); 981 cli_out("\n-----------------"); 982 } 983 } 984 985 static int 986 num_bits_mask(int unit, soc_mem_t mem) 987 { 988 int i, j; 989 uint32 entry_words; 990 uint32 num_bits = 0; 991 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 992 993 entry_words = soc_mem_entry_words(unit, mem); 994 995 for (i = 0; i < entry_words; i++) { 996 for (j = 0; j < MEM_WORD; j++) { 997 if (((0x00000001 << j) & ser_ih_p->mask_array[mem][i]) != 0x0) { 998 num_bits++; 999 } 1000 } 1001 } 1002 1003 return num_bits; 1004 } 1005 1006 static void 1007 write_mem(int unit, soc_mem_t mem, uint32 test_pattern) 1008 { 1009 uint32 i, j; 1010 uint32 *wr_data; 1011 uint32 base_word; 1012 uint32 wr_word; 1013 uint32 entry_words; 1014 uint32 flags = SOC_MEM_DONT_USE_CACHE | SOC_MEM_DONT_CONVERT_XY2DM; 1015 uint32 meminfo_flags; 1016 soc_mem_info_t *meminfo = &SOC_MEM_INFO(unit, mem); 1017 1018 meminfo_flags = meminfo->flags; 1019 meminfo->flags &= (~SOC_MEM_FLAG_CAM); 1020 1021 switch (test_pattern) { 1022 case TEST_PATTERN_ALL0 : 1023 base_word = 0x00000000; 1024 break; 1025 case TEST_PATTERN_ALL1 : 1026 base_word = 0xffffffff; 1027 break; 1028 case TEST_PATTERN_CHB : 1029 base_word = CHB_FIRST_WORD; 1030 break; 1031 case TEST_PATTERN_ICHB : 1032 base_word = ICHB_FIRST_WORD; 1033 break; 1034 default: 1035 base_word = 0x00000000; 1036 break; 1037 } 1038 1039 for (i = soc_mem_index_min(unit, mem); 1040 i < (soc_mem_index_max(unit, mem) + 1); 1041 i++) { 1042 1043 wr_word = base_word; 1044 entry_words = soc_mem_entry_words(unit, mem); 1045 wr_data = (uint32*)sal_alloc(entry_words * sizeof(uint32), "wr_data"); 1046 1047 for (j = 0; j < entry_words; j++) { 1048 wr_data[j] = wr_word; 1049 } 1050 1051 (void)soc_mem_write_extended(unit, flags, mem, COPYNO_ALL, i, wr_data); 1052 1053 if (test_pattern == TEST_PATTERN_CHB 1054 || test_pattern == TEST_PATTERN_ICHB) { 1055 base_word = ~base_word; 1056 } 1057 1058 sal_free(wr_data); 1059 } 1060 1061 meminfo->flags = meminfo_flags; 1062 } 1063 1064 static void 1065 write_all_mems(int unit) 1066 { 1067 int i; 1068 soc_mem_t mem; 1069 uint32 acc_type; 1070 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1071 1072 if (ser_ih_p->quiet_mode_param) { 1073 cli_out("\nWriting all memories..."); 1074 } 1075 for (i = 0; i < NUM_SOC_MEM; i++) { 1076 mem = (soc_mem_t)(i); 1077 1078 if (test_mem(unit, mem) == 1 && duplicate_mem(unit, mem) == 0) { 1079 acc_type = SOC_MEM_ACC_TYPE(unit, mem); 1080 if (!ser_ih_p->quiet_mode_param) { 1081 cli_out("\nWriting %s, acc_type = %0d, base = 0x%08x", 1082 SOC_MEM_NAME(unit, mem), acc_type, 1083 SOC_MEM_INFO(unit, mem).base); 1084 } 1085 write_mem(unit, mem, ser_ih_p->test_pattern_param); 1086 ser_ih_p->total_memories_written++; 1087 } 1088 } 1089 } 1090 1091 static void 1092 read_and_check_mem(int unit, soc_mem_t mem, uint32 test_pattern) 1093 { 1094 uint32 i, j, k; 1095 uint32 mem_word_bit; 1096 uint32 *rd_data; 1097 uint32 base_word; 1098 uint32 exp_word; 1099 uint32 entry_words; 1100 uint32 flags = SOC_MEM_DONT_USE_CACHE | SOC_MEM_DONT_CONVERT_XY2DM; 1101 uint32 use_unique_access_types = 0; 1102 uint32 mask; 1103 uint32 fail_row; 1104 uint32 fail_col; 1105 uint32 fail_cnt; 1106 uint32 num_entries; 1107 uint32 meminfo_flags; 1108 uint32 comp_mask; 1109 uint32 *valid_acc_types; 1110 soc_mem_info_t *meminfo = &SOC_MEM_INFO(unit, mem); 1111 1112 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1113 1114 meminfo_flags = meminfo->flags; 1115 1116 meminfo_flags = meminfo->flags; 1117 meminfo->flags &= (~SOC_MEM_FLAG_CAM); 1118 1119 use_unique_access_types = do_unique_access(unit, mem); 1120 entry_words = soc_mem_entry_words(unit, mem); 1121 num_entries = soc_mem_index_max(unit, mem) 1122 - soc_mem_index_min(unit, mem) + 1; 1123 1124 valid_acc_types = (uint32*) sal_alloc(ser_ih_p->num_unique_acc_types * 1125 sizeof(uint32), "acc_type_unique"); 1126 1127 ser_ih_p->get_valid_unique_acc_types(unit, mem, valid_acc_types); 1128 1129 for (i = 0; i < ser_ih_p->num_unique_acc_types; i++) { 1130 1131 switch (test_pattern) { 1132 case TEST_PATTERN_ALL0 : 1133 base_word = 0x00000000; 1134 break; 1135 case TEST_PATTERN_ALL1 : 1136 base_word = 0xffffffff; 1137 break; 1138 case TEST_PATTERN_CHB : 1139 base_word = CHB_FIRST_WORD; 1140 break; 1141 case TEST_PATTERN_ICHB : 1142 base_word = ICHB_FIRST_WORD; 1143 break; 1144 default: 1145 base_word = 0x00000000; 1146 break; 1147 } 1148 if (use_unique_access_types == 0 && i > 0) { 1149 break; 1150 } else if (use_unique_access_types == 0 && i == 0) { 1151 if (!ser_ih_p->quiet_mode_param) { 1152 cli_out("\nReading and Checking %s", SOC_MEM_NAME(unit, mem)); 1153 } 1154 ser_ih_p->total_memories_read++; 1155 ser_ih_p->total_bits_tested 1156 += num_entries * num_bits_mask(unit, mem); 1157 } else { 1158 if (valid_acc_types[i] != INVALID_ACC_TYPE) { 1159 if (!ser_ih_p->quiet_mode_param) { 1160 cli_out("\nReading and Checking %s for acc_type %0d", 1161 SOC_MEM_NAME(unit, mem), valid_acc_types[i]); 1162 } 1163 ser_ih_p->total_memories_read++; 1164 ser_ih_p->total_bits_tested 1165 += num_entries * num_bits_mask(unit, mem); 1166 } else { 1167 continue; 1168 } 1169 } 1170 1171 fail_cnt = 0; 1172 for (j = soc_mem_index_min(unit, mem); 1173 j < (soc_mem_index_max(unit, mem) + 1); 1174 j++) { 1175 exp_word = base_word; 1176 rd_data = (uint32*)sal_alloc(entry_words * sizeof(uint32), 1177 "rd_data"); 1178 if (use_unique_access_types == 0) { 1179 soc_mem_read_extended(unit, flags, mem, 0, 1180 COPYNO_ALL, j, rd_data); 1181 } else { 1182 soc_mem_pipe_select_read(unit, flags, mem, COPYNO_ALL, 1183 valid_acc_types[i], j, rd_data); 1184 } 1185 1186 for (k = 0; k < entry_words; k++) { 1187 mask = ser_ih_p->mask_array[mem][k]; 1188 1189 if (rd_data[k] != 1190 ((exp_word & mask) | (rd_data[k] & (~mask)))) { 1191 if (!ser_ih_p->quiet_mode_param) { 1192 cli_out("\nexp_word = 0x%08x, rd_data = 0x%08x", 1193 exp_word, rd_data[k]); 1194 } 1195 for (mem_word_bit = 0; 1196 mem_word_bit < MEM_WORD; 1197 mem_word_bit++) { 1198 comp_mask = (0x00000001 << mem_word_bit) & mask; 1199 if ((rd_data[k] & comp_mask) 1200 != (exp_word & comp_mask)) { 1201 if (!ser_ih_p->quiet_mode_param) { 1202 cli_out("\nmask = 0x%08x", mask); 1203 } 1204 fail_row = j; 1205 fail_col = (k * MEM_WORD) + mem_word_bit; 1206 fail_cnt++; 1207 if (!ser_ih_p->quiet_mode_param) { 1208 cli_out("\nFlip: Row = %0d, Col = %0d", 1209 fail_row, fail_col); 1210 } 1211 if (fail_cnt >= MAX_FAIL_COUNT) { 1212 test_error(unit,"\n*ERROR: Max flip count of %0d " 1213 "exceeded for %s acc_type %0d", 1214 MAX_FAIL_COUNT, 1215 SOC_MEM_NAME(unit, mem), 1216 valid_acc_types[i]); 1217 ser_ih_p->test_fail = 1; 1218 break; 1219 } 1220 } 1221 } 1222 } 1223 } 1224 1225 if (test_pattern == TEST_PATTERN_CHB 1226 || test_pattern == TEST_PATTERN_ICHB) { 1227 base_word = ~base_word; 1228 } 1229 1230 sal_free(rd_data); 1231 } 1232 if (ser_ih_p->quiet_mode_param && fail_cnt > 0) { 1233 cli_out("\n*ERROR: %s acc_type %0d had %0d bit flipped", 1234 SOC_MEM_NAME(unit, mem), valid_acc_types[i], fail_cnt); 1235 } 1236 ser_ih_p->total_flips += fail_cnt; 1237 } 1238 1239 sal_free(valid_acc_types); 1240 meminfo->flags = meminfo_flags; 1241 } 1242 1243 static void 1244 read_and_check_all_mems(int unit) 1245 { 1246 int i; 1247 soc_mem_t mem; 1248 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1249 1250 if (ser_ih_p->quiet_mode_param) { 1251 cli_out("\nReading and Checking all memories..."); 1252 } 1253 for (i = 0; i < NUM_SOC_MEM; i++) { 1254 mem = (soc_mem_t)(i); 1255 1256 if (test_mem(unit, mem) == 1 && duplicate_mem(unit, mem) == 0) { 1257 read_and_check_mem(unit, mem, ser_ih_p->test_pattern_param); 1258 } 1259 } 1260 } 1261 1262 int 1263 ser_ih_test_init(int unit, args_t *a, void **pa) 1264 { 1265 int i, j; 1266 soc_mem_t mem; 1267 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1268 1269 SOC_MEM_FORCE_READ_THROUGH_SET(unit, 1); 1270 1271 ser_ih_p = sal_alloc(sizeof(ser_ih_t), "ser_ih_test"); 1272 sal_memset(ser_ih_p, 0, sizeof(ser_ih_t)); 1273 ser_ih_parray[unit] = ser_ih_p; 1274 1275 ser_ih_parse_test_params(unit, a); 1276 1277 ser_ih_p->mask_array = (uint32**)sal_alloc(NUM_SOC_MEM * sizeof(uint32*), 1278 "mask_array*"); 1279 1280 for (i = 0; i < NUM_SOC_MEM; i++) { 1281 ser_ih_p->mask_array[i] = (uint32*)sal_alloc(SOC_MAX_MEM_WORDS * 1282 sizeof(uint32), 1283 "mask_array"); 1284 } 1285 1286 for (i = 0; i < NUM_SOC_MEM; i++) { 1287 for (j = 0; j < SOC_MAX_MEM_WORDS; j++) { 1288 ser_ih_p->mask_array[i][j] = 0xffffffff; 1289 } 1290 } 1291 1292 for (i = 0; i < NUM_SOC_MEM; i++) { 1293 mem = (soc_mem_t)(i); 1294 1295 if (SOC_MEM_IS_VALID(unit, mem)) { 1296 soc_mem_datamask_get(unit, mem, ser_ih_p->mask_array[i]); 1297 } 1298 } 1299 1300 ser_ih_p->total_memories_written = 0; 1301 ser_ih_p->total_memories_read = 0; 1302 ser_ih_p->total_flips = 0; 1303 ser_ih_p->total_bits_tested = 0; 1304 1305 get_chip_specific_data(unit); 1306 1307 if (ser_ih_p->bad_input == 1) { 1308 return BCM_E_FAIL; 1309 } else { 1310 return BCM_E_NONE; 1311 } 1312 } 1313 1314 int 1315 ser_ih_test(int unit, args_t *a, void *pa) 1316 { 1317 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1318 1319 if (ser_ih_p->rd_wr_mode_param == WRITE_ONLY) { 1320 write_all_mems(unit); 1321 } else if (ser_ih_p->rd_wr_mode_param == READ_ONLY) { 1322 read_and_check_all_mems(unit); 1323 } 1324 return 0; 1325 } 1326 1327 int 1328 ser_ih_test_cleanup(int unit, void *pa) 1329 { 1330 int i; 1331 ser_ih_t *ser_ih_p = ser_ih_parray[unit]; 1332 1333 cli_out("\n-----------------"); 1334 cli_out("\n TEST RESULT "); 1335 cli_out("\n-----------------"); 1336 if (ser_ih_p->rd_wr_mode_param == WRITE_ONLY) { 1337 cli_out("\nTotal memories written = %0d", ser_ih_p->total_memories_written); 1338 } else if (ser_ih_p->rd_wr_mode_param == READ_ONLY) { 1339 cli_out("\nTotal memories read = %0d", ser_ih_p->total_memories_read); 1340 cli_out("\nTotal Flips = %0d", ser_ih_p->total_flips); 1341 cli_out("\nTotal bits tested = %0d kb", ser_ih_p->total_bits_tested / 1024); 1342 } 1343 cli_out("\n-----------------"); 1344 1345 for (i = 0; i < NUM_SOC_MEM; i++) { 1346 sal_free(ser_ih_p->mask_array[i]); 1347 } 1348 1349 sal_free(ser_ih_p->mask_array); 1350 1351 sal_free(ser_ih_p->acc_type_unique); 1352 sal_free(ser_ih_p); 1353 cli_out("\n"); 1354 return 0; 1355 } 1356 1357 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT2_SUPPORT */ 1358 1359