counter.c (794809B)
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 * Packet Statistics Counter Management 8 * 9 * Firebolt 1024 bytes per port (128 * uint64) 10 * Helix 1024 bytes per port (128 * uint64) 11 * Felix 1024 bytes per port (128 * uint64) 12 * Raptor 1024 bytes per port (128 * uint64) 13 * Hercules: 1024 bytes per port (128 * uint64) 14 * HUMV: 2048 bytes per port (256 * uint64) 15 * Bradley: 2048 bytes per port (256 * uint64) 16 * Goldwing: 2048 bytes per port (256 * uint64) 17 * Triumph: 4096 bytes per port (512 * uint64) 18 * 19 * BCM5670 Endian: on Hercules, the well-intentioned ES_BIG_ENDIAN_OTHER 20 * causes counter DMA to write the most significant word first in the 21 * DMA buffer. This is wrong because not all big-endian hosts have the 22 * same setting for ES_BIG_ENDIAN_OTHER (e.g. mousse and idtrp334). 23 * This problem makes it necessary to check the endian select to 24 * determine whether to swap words. 25 */ 26 27 #include <shared/bsl.h> 28 29 #include <sal/core/libc.h> 30 #include <shared/alloc.h> 31 #include <sal/core/spl.h> 32 #include <sal/core/sync.h> 33 #include <sal/core/time.h> 34 35 #include <soc/drv.h> 36 #include <soc/counter.h> 37 #include <soc/ll.h> 38 #include <soc/debug.h> 39 #include <soc/mem.h> 40 #include <soc/register.h> 41 #ifdef BCM_ESW_SUPPORT 42 #include <soc/format.h> 43 #endif 44 #ifdef BCM_TRIDENT_SUPPORT 45 #include <soc/trident.h> 46 #endif 47 #if defined(BCM_PETRA_SUPPORT) 48 #include <soc/dpp/drv.h> 49 #include <bcm_int/dpp/error.h> 50 #include <bcm_int/dpp/utils.h> 51 #endif 52 #if defined(BCM_DFE_SUPPORT) 53 #include <soc/dfe/cmn/dfe_drv.h> 54 #endif 55 #if defined(BCM_PETRA_SUPPORT) 56 #include <soc/dpp/ARAD/arad_stat.h> 57 #endif 58 #if defined(BCM_JERICHO_SUPPORT) 59 #include <soc/dpp/JER/jer_stat.h> 60 #endif 61 #if defined(BCM_88750_SUPPORT) 62 #include <soc/dfe/fe1600/fe1600_stat.h> 63 #endif 64 #if defined(BCM_PETRA_SUPPORT) 65 #include <soc/dpp/mbcm.h> 66 #endif 67 #if defined(BCM_DNX_SUPPORT) 68 #include <soc/dnx/dnx_data/auto_generated/dnx_data_port.h> 69 #include <soc/dnx/dnx_data/auto_generated/dnx_data_fabric.h> 70 #include <soc/dnx/stat/jer2_stat.h> 71 #include <soc/dnx/dnx_err_recovery_manager_utils.h> 72 #endif 73 #ifdef BCM_CMICM_SUPPORT 74 #include <soc/cmicm.h> 75 #endif 76 #if defined(BCM_TRIDENT2_SUPPORT) 77 #include <soc/trident2.h> 78 #include <bcm_int/esw_dispatch.h> 79 #endif 80 #if defined(BCM_MONTEREY_SUPPORT) 81 #include <soc/monterey.h> 82 #endif 83 #if defined(BCM_APACHE_SUPPORT) 84 #include <soc/apache.h> 85 #endif 86 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 87 #include <soc/td2_td2p.h> 88 #endif 89 #if defined(BCM_KATANA2_SUPPORT) 90 #include <soc/katana2.h> 91 #endif 92 #if defined(BCM_KATANA2_SUPPORT) 93 #include <soc/saber2.h> 94 #endif 95 96 #if defined(BCM_TOMAHAWK_SUPPORT) 97 #include <soc/tomahawk.h> 98 #include <soc/tomahawk2.h> 99 #endif 100 #if defined(BCM_TOMAHAWK3_SUPPORT) 101 #include <soc/tomahawk3.h> 102 #endif 103 #if defined(BCM_TRIDENT3_SUPPORT) 104 #include <soc/trident3.h> 105 #endif 106 #if defined(BCM_HELIX5_SUPPORT) 107 #include <soc/helix5.h> 108 #endif 109 110 #if defined(BCM_GREYHOUND2_SUPPORT) 111 #include <soc/greyhound2.h> 112 #endif 113 114 #ifdef CRASH_RECOVERY_SUPPORT 115 #include <soc/hwstate/hw_log.h> 116 #endif /* CRASH_RECOVERY_SUPPORT */ 117 118 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT) 119 #include <soc/dnxc/dnxc_ha.h> 120 #endif 121 122 #include <soc/dnxc/multithread_analyzer.h> 123 124 #if defined(INCLUDE_PHY_8806X) 125 extern int phy_mt2_update_led_speed_activity(int unit, soc_port_t port); 126 #endif 127 128 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) 129 130 #define COUNTER_IDX_PORTBASE(unit, port) \ 131 ((port) * SOC_CONTROL(unit)->counter_perport) 132 133 #define COUNTER_IDX_GET(unit, ctr_ref, port) \ 134 (COUNTER_IDX_PORTBASE(unit, port) + \ 135 SOC_REG_CTR_IDX(unit, (ctr_ref)->reg) + (ctr_ref)->index) 136 137 #define COUNTER_IDX_OFFSET(unit) 0 138 139 #define COUNTER_MIN_IDX_GET(unit, port) \ 140 (COUNTER_IDX_PORTBASE(unit, port) + COUNTER_IDX_OFFSET(unit)) 141 142 soc_counter_control_t *soc_counter_control[SOC_MAX_NUM_DEVICES]; 143 144 static soc_counter_extra_f soc_counter_extra[SOC_MAX_NUM_DEVICES] 145 [SOC_COUNTER_EXTRA_CB_MAX]; 146 /* Number of cosq per unit per port */ 147 static int num_cosq[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PORTS] = {{ 0 }}; 148 149 #ifdef BCM_SBUSDMA_SUPPORT 150 volatile uint32 _soc_counter_pending[SOC_MAX_NUM_DEVICES] = { 0 }; 151 #endif 152 153 #ifdef BCM_TOMAHAWK_SUPPORT 154 static uint32 *buff_max[SOC_MAX_NUM_DEVICES] = { NULL }; 155 static void *host_entry[SOC_MAX_NUM_DEVICES] = { NULL }; 156 static void *host_buff[SOC_MAX_NUM_DEVICES] = { NULL }; 157 #endif 158 159 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) 160 STATIC int 161 soc_counter_collect64(int unit, int discard, soc_port_t tmp_port, soc_reg_t hw_ctr_reg); 162 #endif /* defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) */ 163 164 165 STATIC void 166 soc_counter_collect_non_dma_entries(int unit, 167 int tmp_port, 168 int port_idx, 169 int ar_idx, 170 soc_reg_t ctr_reg); 171 STATIC int 172 _soc_counter_non_dma_is_invalid(int unit, soc_reg_t reg, soc_port_t port); 173 174 #ifdef BCM_TOMAHAWK_SUPPORT 175 STATIC void 176 soc_counter_collect_th_non_dma_entries(int unit, 177 int tmp_port, 178 int port_idx, 179 int ar_idx, 180 soc_reg_t ctr_reg); 181 #endif /* BCM_TOMAHAWK_SUPPORT */ 182 STATIC void soc_counter_generic_collect_non_dma_entries(int unit, 183 soc_ctr_control_info_t 184 ctrl_info, 185 int base_idx, 186 int ar_idx, 187 soc_reg_t ctr_reg); 188 /* 189 * Turn on COUNTER_BENCH and "debug +verbose" to benchmark the CPU time 190 * spent on counter activity. NOTE: most useful on platforms where 191 * sal_time_usecs() has usec precision instead of clock tick precision. 192 */ 193 194 #undef COUNTER_BENCH 195 196 /* Per port mapping to counter map structures */ 197 #define PORT_CTR_REG(unit, port, idx) \ 198 (&SOC_CONTROL(unit)->counter_map[port]->cmap_base[idx]) 199 #define PORT_CTR_NUM(unit, port) \ 200 (SOC_CONTROL(unit)->counter_map[port]->cmap_size) 201 202 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 203 204 static uint64 *soc_counter_tbuf[SOC_MAX_NUM_DEVICES]; 205 #define SOC_COUNTER_TBUF_SIZE(unit) \ 206 (SOC_CONTROL(unit)->counter_perport * sizeof(uint64)) 207 208 #ifdef BCM_TRIUMPH2_SUPPORT 209 #define COUNTER_TIMESTAMP_FIFO_SIZE 4 210 #define DIRECT_TIMESTAMP_DMA_COUNTER_NUM 100 211 #define XMAC_DMA_COUNTER_BASE 42 212 #endif /* BCM_TRIUMPH2_SUPPORT */ 213 214 #ifdef BCM_KATANA_SUPPORT 215 typedef struct _kt_cosq_counter_mem_map_s { 216 soc_mem_t mem; 217 soc_counter_non_dma_id_t non_dma_id; 218 }_kt_cosq_counter_mem_map_t; 219 220 /* 221 * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded 222 * CTR_FLEX_COUNT_4/5/6/7 = Red packet ENQ discarded 223 * CTR_FLEX_COUNT_8/9/10/11 = Total DEQ 224 */ 225 _kt_cosq_counter_mem_map_t _kt_cosq_mem_map[] = 226 { 227 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 228 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 229 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 230 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 231 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 232 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 233 { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 234 { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 235 { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }, 236 { CTR_FLEX_COUNT_9m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }, 237 { CTR_FLEX_COUNT_10m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }, 238 { CTR_FLEX_COUNT_11m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT } 239 }; 240 241 /* 242 * CTR_FLEX_COUNT_0 = Total ENQ discarded 243 * CTR_FLEX_COUNT_1 = Total ENQ Accepted 244 * CTR_FLEX_COUNT_2 = Green ENQ discarded 245 * CTR_FLEX_COUNT_3 = Yellow ENQ discarded 246 * CTR_FLEX_COUNT_4 = Red packet ENQ discarded 247 * CTR_FLEX_COUNT_5 = Green ENQ Accepted 248 * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted 249 * CTR_FLEX_COUNT_7 = Red ENQ Accepted 250 * CTR_FLEX_COUNT_8 = Total DEQ 251 */ 252 _kt_cosq_counter_mem_map_t _kt_cosq_gport_mem_map[] = 253 { 254 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 255 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT }, 256 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN }, 257 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW }, 258 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 259 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN }, 260 { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW }, 261 { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED }, 262 { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT } 263 }; 264 #endif 265 #ifdef BCM_KATANA2_SUPPORT 266 /* 267 * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded 268 * CTR_FLEX_COUNT_4/5/6/7 = Red packet ENQ discarded 269 * CTR_FLEX_COUNT_8/9/10/11 = Total DEQ 270 */ 271 _sb2_cosq_counter_mem_map_t _kt2_cosq_mem_map[] = 272 { 273 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 274 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 275 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 276 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 277 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 278 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 279 { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 280 { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 281 { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"}, 282 { CTR_FLEX_COUNT_9m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" }, 283 { CTR_FLEX_COUNT_10m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"}, 284 { CTR_FLEX_COUNT_11m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" }, 285 }; 286 287 /* 288 * CTR_FLEX_COUNT_0 = Total ENQ discarded 289 * CTR_FLEX_COUNT_1 = Total ENQ Accepted 290 * CTR_FLEX_COUNT_2 = Green ENQ discarded 291 * CTR_FLEX_COUNT_3 = Yellow ENQ discarded 292 * CTR_FLEX_COUNT_4 = Red packet ENQ discarded 293 * CTR_FLEX_COUNT_5 = Green ENQ Accepted 294 * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted 295 * CTR_FLEX_COUNT_7 = Red ENQ Accepted 296 * CTR_FLEX_COUNT_8 = Total DEQ 297 */ 298 _sb2_cosq_counter_mem_map_t _kt2_cosq_gport_mem_map[] = 299 { 300 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 301 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT }, 302 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN }, 303 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW }, 304 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 305 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_GREEN }, 306 { CTR_FLEX_COUNT_6m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_YELLOW }, 307 { CTR_FLEX_COUNT_7m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT_RED }, 308 { CTR_FLEX_COUNT_8m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT } 309 }; 310 311 /* 312 * CTR_FLEX_COUNT_0/1 = Total ENQ discarded 313 * CTR_FLEX_COUNT_2/3 = Red packet ENQ discarded 314 * CTR_FLEX_COUNT_4/5 = Total DEQ 315 */ 316 _sb2_cosq_counter_mem_map_t _sb2_cosq_mem_map[] = 317 { 318 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 319 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 320 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 321 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 322 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"}, 323 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" }, 324 }; 325 326 /* 327 * CTR_FLEX_COUNT_0 = Total ENQ discarded 328 * CTR_FLEX_COUNT_1 = Red packet ENQ discarded 329 * CTR_FLEX_COUNT_2 = Total DEQ 330 */ 331 _sb2_cosq_counter_mem_map_t _dg2_cosq_mem_map[] = 332 { 333 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 334 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 335 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE"}, 336 }; 337 338 /* 339 * CTR_FLEX_COUNT_0 = Total ENQ discarded 340 * CTR_FLEX_COUNT_1 = Total ENQ Accepted 341 * CTR_FLEX_COUNT_2 = Green ENQ discarded 342 * CTR_FLEX_COUNT_3 = Yellow ENQ discarded 343 * CTR_FLEX_COUNT_4 = Red packet ENQ discarded 344 * CTR_FLEX_COUNT_5 = Total DEQ 345 */ 346 _sb2_cosq_counter_mem_map_t _sb2_cosq_gport_mem_map[] = 347 { 348 { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT }, 349 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT }, 350 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_GREEN }, 351 { CTR_FLEX_COUNT_3m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_YELLOW }, 352 { CTR_FLEX_COUNT_4m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED }, 353 { CTR_FLEX_COUNT_5m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT }, 354 }; 355 356 #if defined (BCM_METROLITE_SUPPORT) 357 /* 358 * CTR_FLEX_COUNT_0 = Total ENQ discarded 359 * CTR_FLEX_COUNT_1 = Red packet ENQ discarded 360 * CTR_FLEX_COUNT_2 = Total DEQ 361 */ 362 _sb2_cosq_counter_mem_map_t _ml_cosq_mem_map[] = 363 { { CTR_FLEX_COUNT_0m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT,"DROP_PKT","DROP_BYTE"}, 364 { CTR_FLEX_COUNT_1m, SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED,"DROP_PKT_R","DROP_BYTE_R" }, 365 { CTR_FLEX_COUNT_2m, SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT,"PERQ_PKT","PERQ_BYTE" }, 366 }; 367 #endif 368 #endif 369 #ifdef BCM_KATANA2_SUPPORT 370 void 371 soc_sb2_cosq_counter_mem_map_get(int unit, int *num_elem, 372 _sb2_cosq_counter_mem_map_t **mem_map) 373 { 374 uint16 dev_id; 375 uint8 rev_id; 376 soc_cm_get_id(unit, &dev_id, &rev_id); 377 #if defined (BCM_METROLITE_SUPPORT) 378 if (SOC_IS_METROLITE(0)) { 379 *mem_map = _ml_cosq_mem_map; 380 *num_elem = sizeof(_ml_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t); 381 } else 382 #endif 383 if (dev_id == BCM56233_DEVICE_ID) { 384 *mem_map = _dg2_cosq_mem_map; 385 *num_elem = sizeof(_dg2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t); 386 } else if (SOC_IS_SABER2(unit)) { 387 *mem_map = _sb2_cosq_mem_map; 388 *num_elem = sizeof(_sb2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t); 389 } else { 390 *mem_map = _kt2_cosq_mem_map; 391 *num_elem = sizeof(_kt2_cosq_mem_map)/sizeof(_sb2_cosq_counter_mem_map_t); 392 } 393 394 } 395 #endif 396 397 int 398 is_xaui_rx_counter(soc_reg_t ctr_reg) 399 { 400 switch (ctr_reg) { 401 case IR64r: 402 case IR127r: 403 case IR255r: 404 case IR511r: 405 case IR1023r: 406 case IR1518r: 407 case IR2047r: 408 case IR4095r: 409 case IR9216r: 410 case IR16383r: 411 case IRBCAr: 412 case IRBYTr: 413 case IRERBYTr: 414 case IRERPKTr: 415 case IRFCSr: 416 case IRFLRr: 417 case IRFRGr: 418 case IRJBRr: 419 case IRJUNKr: 420 case IRMAXr: 421 case IRMCAr: 422 case IRMEBr: 423 case IRMEGr: 424 case IROVRr: 425 case IRPKTr: 426 case IRUNDr: 427 case IRXCFr: 428 case IRXPFr: 429 case IRXUOr: 430 #ifdef BCM_TRX_SUPPORT 431 case IRUCr: 432 #ifdef BCM_ENDURO_SUPPORT 433 case IRUCAr: 434 #endif /* BCM_ENDURO_SUPPORT */ 435 case IRPOKr: 436 case MAC_RXLLFCMSGCNTr: 437 #endif 438 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 439 case IRXPPr: 440 #endif 441 return 1; 442 default: 443 break; 444 } 445 return 0; 446 } 447 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 448 449 #ifdef BCM_TRIDENT_SUPPORT 450 STATIC int 451 _soc_counter_trident_get_info(int unit, soc_port_t port, soc_reg_t id, 452 int *base_index, int *num_entries) 453 { 454 soc_control_t *soc; 455 soc_info_t *si; 456 soc_counter_non_dma_t *non_dma; 457 soc_port_t phy_port, mmu_port; 458 soc_port_t mmu_cmic_port, mmu_lb_port; 459 460 soc = SOC_CONTROL(unit); 461 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 462 463 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 464 return SOC_E_UNAVAIL; 465 } 466 467 if (port < 0) { 468 return SOC_E_PARAM; 469 } 470 471 si = &SOC_INFO(unit); 472 if (si->port_l2p_mapping[port] == -1) { 473 *base_index = 0; 474 *num_entries = 0; 475 return SOC_E_NONE; 476 } 477 478 mmu_cmic_port = si->port_p2m_mapping[si->port_l2p_mapping[si->cmic_port]]; 479 mmu_lb_port = si->port_p2m_mapping[si->port_l2p_mapping[si->lb_port]]; 480 481 phy_port = si->port_l2p_mapping[port]; 482 mmu_port = si->port_p2m_mapping[phy_port]; 483 484 switch (id) { 485 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 486 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 487 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */ 488 *base_index = si->port_cosq_base[port]; 489 } else { /* in Y pipe */ 490 *base_index = si->port_cosq_base[port] + 491 non_dma->dma_index_max[0] + 1; 492 } 493 *num_entries = si->port_num_cosq[port]; 494 break; 495 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC: 496 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC: 497 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */ 498 *base_index = si->port_uc_cosq_base[port]; 499 } else { /* in Y pipe */ 500 *base_index = si->port_uc_cosq_base[port] + 501 non_dma->dma_index_max[0] + 1; 502 } 503 *num_entries = si->port_num_uc_cosq[port]; 504 break; 505 case SOC_COUNTER_NON_DMA_MMU_QCN_CNM: 506 if((mmu_port == mmu_lb_port) || (mmu_port == mmu_cmic_port)){ 507 *num_entries = 0; 508 *base_index = 0; 509 }else{ 510 *num_entries = 2;/* 2 QCN queue per port */ 511 *base_index = port * (*num_entries); 512 } 513 break; 514 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT: 515 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT: 516 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */ 517 *base_index = si->port_ext_cosq_base[port]; 518 } else { /* in Y pipe */ 519 *base_index = si->port_ext_cosq_base[port] + 520 non_dma->dma_index_max[0] + 1; 521 } 522 *num_entries = si->port_num_ext_cosq[port]; 523 break; 524 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT: 525 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE: 526 if (mmu_port == mmu_cmic_port) { 527 *base_index = 0; 528 *num_entries = 48; 529 } else { 530 *base_index = 48 + (mmu_port - mmu_cmic_port - 1) * 5; 531 *num_entries = 5; 532 } 533 break; 534 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC: 535 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC: 536 if (mmu_port < mmu_lb_port) { /* in X pipe */ 537 if (mmu_port == mmu_cmic_port) { 538 *base_index = 0; 539 *num_entries = 0; 540 } else if (mmu_port <= mmu_cmic_port + 4) { 541 *base_index = (mmu_port - mmu_cmic_port - 1) * 74; 542 *num_entries = 74; /* 10 ucast + 64 ext ucast */ 543 } else { 544 *base_index = 74 * 4 + (mmu_port - mmu_cmic_port - 5) * 10; 545 *num_entries = 10; 546 } 547 } else { /* in Y pipe */ 548 if (mmu_port == mmu_lb_port) { 549 *base_index = 0; 550 *num_entries = 0; 551 } else if (mmu_port <= mmu_lb_port + 4) { 552 *base_index = 576 + (mmu_port - mmu_lb_port - 1) * 74; 553 *num_entries = 74; /* 10 ucast + 64 ext ucast */ 554 } else { 555 *base_index = 576 + 74 * 4 + (mmu_port - mmu_lb_port - 5) * 10; 556 *num_entries = 10; 557 } 558 } 559 break; 560 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING: 561 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING: 562 *num_entries = 1; 563 *base_index = port; 564 break; 565 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW: 566 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED: 567 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN: 568 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW: 569 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED: 570 *num_entries = 1; 571 *base_index = mmu_port; 572 break; 573 case SOC_COUNTER_NON_DMA_PG_MIN_PEAK: 574 case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT: 575 case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK: 576 case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT: 577 case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK: 578 case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT: 579 *num_entries = 8; 580 *base_index = port * (*num_entries); 581 break; 582 case SOC_COUNTER_NON_DMA_QUEUE_PEAK: 583 case SOC_COUNTER_NON_DMA_QUEUE_CURRENT: 584 *num_entries = 5; 585 *base_index = port * (*num_entries); 586 break; 587 case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK: 588 case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT: 589 *num_entries = 10; 590 *base_index = port * (*num_entries); 591 break; 592 case SOC_COUNTER_NON_DMA_EXT_QUEUE_PEAK: 593 case SOC_COUNTER_NON_DMA_EXT_QUEUE_CURRENT: 594 *num_entries = 64; 595 *base_index = port * (*num_entries); 596 break; 597 case SOC_COUNTER_NON_DMA_POOL_PEAK: 598 case SOC_COUNTER_NON_DMA_POOL_CURRENT: 599 *base_index = 0; 600 *num_entries = non_dma->num_entries; 601 break; 602 default: 603 return SOC_E_INTERNAL; 604 } 605 *base_index += non_dma->base_index; 606 607 return SOC_E_NONE; 608 } 609 #endif /* BCM_TRIDENT_SUPPORT */ 610 611 #if defined ( BCM_APACHE_SUPPORT ) 612 #define _AP_PBLKS_PER_PIPE 9 613 #define _APACHE_XLPS_PER_PGW 9 614 #define _APACHE_PORTS_PER_XLP 4 615 616 #define _MONTEREY_XLPS_PER_PGW 8 617 #define _MN_PBLKS_PER_PIPE 8 618 619 STATIC int 620 _soc_counter_apache_get_child_dma_by_idx(int unit, soc_counter_non_dma_t *parent, 621 int idx, soc_counter_non_dma_t **child) 622 { 623 int rv = SOC_E_NONE; 624 625 if ((parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 626 if (idx >= parent->extra_ctr_ct) { 627 return SOC_E_PARAM; 628 } 629 *child = &parent->extra_ctrs[idx << 1]; 630 } else { 631 *child = parent; 632 } 633 return rv; 634 } 635 636 /* For a given logical port, return the OBM id and the lane number */ 637 int 638 soc_apache_port_obm_info_get(int unit, soc_port_t port, 639 int *obm_id, int *lane) 640 { 641 soc_info_t *si; 642 soc_port_t phy_port; 643 int obm, pgw; 644 645 si = &SOC_INFO(unit); 646 phy_port = si->port_l2p_mapping[port]; 647 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port) || 648 IS_RDB_PORT(unit, port)) { 649 /* nothing to do for non-idb ports */ 650 return SOC_E_NONE; 651 } 652 653 /* OBM group (num groups = num tsc's) belongs to PGW0/PGW1 */ 654 obm = si->port_serdes[port]; 655 if (SOC_IS_MONTEREY(unit)) { 656 obm %= _MONTEREY_XLPS_PER_PGW; 657 } else { 658 obm %= _APACHE_XLPS_PER_PGW; 659 } 660 661 pgw = si->port_group[port]; 662 if (lane) { 663 *lane = (phy_port - 1) % _APACHE_PORTS_PER_XLP; 664 *lane += (pgw) ? 4 : 0; 665 } 666 if (obm_id) { 667 *obm_id = obm; 668 } 669 670 return SOC_E_NONE; 671 } 672 673 STATIC int 674 _soc_counter_apache_get_pgw_inst(int unit, soc_port_t port, 675 int *pgw_inst, int *lane) 676 { 677 soc_info_t *si; 678 soc_port_t phy_port; 679 int pgw; 680 681 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || IS_MACSEC_PORT(unit, port) || 682 IS_RDB_PORT(unit, port)) { 683 /* nothing to do for non-idb ports */ 684 return SOC_E_NONE; 685 } 686 687 si = &SOC_INFO(unit); 688 phy_port = si->port_l2p_mapping[port]; 689 pgw = si->port_group[port]; 690 if (lane) { 691 *lane = (phy_port - 1) % _APACHE_PORTS_PER_XLP; 692 } 693 if (pgw_inst) { 694 *pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 695 } 696 return SOC_E_NONE; 697 } 698 699 STATIC int 700 _soc_counter_apache_get_info(int unit, soc_port_t port, soc_reg_t id, 701 int *base_index, int *num_entries) 702 { 703 soc_info_t *si; 704 soc_control_t *soc; 705 soc_counter_non_dma_t *non_dma; 706 soc_port_t phy_port = 0, mmu_port = 0; 707 int obm_id, lane; 708 int maxports = 75; 709 soc = SOC_CONTROL(unit); 710 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 711 712 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 713 return SOC_E_UNAVAIL; 714 } 715 716 si = &SOC_INFO(unit); 717 if (port >= 0 && port < maxports) { 718 if (si->port_l2p_mapping[port] == -1) { 719 *base_index = 0; 720 *num_entries = 0; 721 return SOC_E_NONE; 722 } 723 724 phy_port = si->port_l2p_mapping[port]; 725 mmu_port = si->port_p2m_mapping[phy_port]; 726 } else { 727 728 mmu_port =-1 ; 729 730 } 731 732 switch (id) { 733 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 734 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 735 if (mmu_port >= 0) { 736 #ifdef BCM_MONTEREY_SUPPORT 737 if (SOC_IS_MONTEREY(unit)) { 738 *base_index = 739 soc_monterey_logical_qnum_hw_qnum(unit, port, 740 si->port_cosq_base[port], 0); 741 } else 742 #endif 743 { 744 *base_index = 745 soc_apache_logical_qnum_hw_qnum(unit, port, 746 si->port_cosq_base[port], 0); 747 } 748 *num_entries = si->port_num_cosq[port]; 749 } else { 750 *base_index = port; 751 *num_entries = non_dma->num_entries; 752 } 753 break; 754 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC: 755 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC: 756 if (mmu_port >= 0) { 757 #ifdef BCM_MONTEREY_SUPPORT 758 if (SOC_IS_MONTEREY(unit)) { 759 *base_index = 760 soc_monterey_logical_qnum_hw_qnum(unit, port, 761 si->port_uc_cosq_base[port], 1); 762 } else 763 #endif 764 { 765 *base_index = 766 soc_apache_logical_qnum_hw_qnum(unit, port, 767 si->port_uc_cosq_base[port], 1); 768 } 769 *num_entries = si->port_num_uc_cosq[port]; 770 } else { 771 *base_index = 0; 772 *num_entries = non_dma->num_entries; 773 } 774 break; 775 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT: 776 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE: 777 case SOC_COUNTER_NON_DMA_QUEUE_PEAK: 778 case SOC_COUNTER_NON_DMA_QUEUE_CURRENT: 779 if (mmu_port >= 0) { 780 *base_index = si->port_cosq_base[port]; 781 *num_entries = si->port_num_cosq[port]; 782 } else { 783 *base_index = port; 784 *num_entries = non_dma->num_entries; 785 } 786 break; 787 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC: 788 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC: 789 case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK: 790 case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT: 791 if (mmu_port >= 0) { 792 *base_index = si->port_uc_cosq_base[port]; 793 *num_entries = si->port_num_uc_cosq[port]; 794 } else { 795 *base_index = 0; 796 *num_entries = non_dma->num_entries; 797 } 798 break; 799 case SOC_COUNTER_NON_DMA_MMU_QCN_CNM: 800 if (mmu_port >= 0) { 801 *base_index = si->port_uc_cosq_base[port]; 802 *num_entries = si->port_num_uc_cosq[port]; 803 } else { 804 *base_index = 0; 805 *num_entries = non_dma->num_entries; 806 } 807 break; 808 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI: 809 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI: 810 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI: 811 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI: 812 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI: 813 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI: 814 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI: 815 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI: 816 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI: 817 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI: 818 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI: 819 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI: 820 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI: 821 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI: 822 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI: 823 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI: 824 *base_index = (phy_port - 1) / 16 * 4; 825 *num_entries = 4; 826 break; 827 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT: 828 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT: 829 if (mmu_port >= 0) { 830 *base_index = non_dma->dma_index_min[0]; 831 *num_entries = non_dma->dma_index_max[0] + 1; 832 } else { 833 *base_index = 0; 834 *num_entries = non_dma->num_entries; 835 } 836 break; 837 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING: 838 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING: 839 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER: 840 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER: 841 if (mmu_port >= 0) { 842 *num_entries = non_dma->entries_per_port; 843 *base_index = mmu_port; 844 } else { 845 return SOC_E_INTERNAL; 846 } 847 break; 848 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW: 849 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED: 850 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN: 851 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW: 852 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED: 853 if ((mmu_port >= 0) && (mmu_port < 74)) { 854 *base_index = (mmu_port & 0x7f) * non_dma->entries_per_port; 855 *num_entries = non_dma->entries_per_port; 856 } else { 857 return SOC_E_INTERNAL; 858 } 859 break; 860 case SOC_COUNTER_NON_DMA_PG_MIN_PEAK: 861 case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT: 862 case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK: 863 case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT: 864 case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK: 865 case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT: 866 if (mmu_port >= 0) { 867 *base_index = (mmu_port & 0x7f) * non_dma->entries_per_port; 868 *num_entries = non_dma->entries_per_port; 869 } else { 870 return SOC_E_INTERNAL; 871 } 872 break; 873 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT: 874 case SOC_COUNTER_NON_DMA_DROP_RQ_BYTE: 875 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW: 876 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED: 877 case SOC_COUNTER_NON_DMA_POOL_PEAK: 878 case SOC_COUNTER_NON_DMA_POOL_CURRENT: 879 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK: 880 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT: 881 case SOC_COUNTER_NON_DMA_E2E_DROP_COUNT: 882 *base_index = 0; 883 *num_entries = non_dma->num_entries; 884 break; 885 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 886 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 887 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 888 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 889 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 890 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 891 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 892 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 893 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS: 894 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS: 895 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO: 896 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO: 897 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI: 898 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI: 899 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0: 900 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0: 901 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1: 902 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1: 903 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS: 904 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS: 905 *base_index = 0; 906 *num_entries = 1; 907 lane = 0; 908 /* find obm from the port number */ 909 SOC_IF_ERROR_RETURN 910 (soc_apache_port_obm_info_get(unit, port, &obm_id, &lane)); 911 if (obm_id >= _AP_PBLKS_PER_PIPE) { 912 return SOC_E_PARAM; 913 } 914 _soc_counter_apache_get_child_dma_by_idx(unit, non_dma, obm_id, &non_dma); 915 *base_index += lane; 916 break; 917 default: 918 return SOC_E_INTERNAL; 919 } 920 *base_index += non_dma->base_index; 921 922 return SOC_E_NONE; 923 } 924 #endif /* BCM_APACHE_SUPPORT */ 925 926 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT) 927 STATIC int 928 _soc_counter_monterey_cpri_get_info(int unit, soc_port_t port, soc_reg_t id, 929 int *base_index, int *num_entries) 930 { 931 soc_control_t *soc; 932 soc_counter_non_dma_t *non_dma; 933 934 soc = SOC_CONTROL(unit); 935 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 936 937 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 938 return SOC_E_UNAVAIL; 939 } 940 941 if ((id >= SOC_COUNTER_NON_DMA_CPRI_START) && 942 (id <= SOC_COUNTER_NON_DMA_CPRI_END)) { 943 *base_index = port; 944 *num_entries = non_dma->entries_per_port; 945 *base_index += non_dma->base_index; 946 } 947 948 return SOC_E_NONE; 949 } 950 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */ 951 952 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT ) 953 STATIC int 954 _soc_counter_trident2_get_info(int unit, soc_port_t port, soc_reg_t id, 955 int *base_index, int *num_entries) 956 { 957 soc_info_t *si; 958 soc_control_t *soc; 959 soc_counter_non_dma_t *non_dma; 960 soc_port_t phy_port, mmu_port; 961 int pipe; 962 963 soc = SOC_CONTROL(unit); 964 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 965 966 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 967 return SOC_E_UNAVAIL; 968 } 969 970 if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) { 971 return SOC_E_UNAVAIL; 972 } 973 974 si = &SOC_INFO(unit); 975 if (port >= 0) { 976 if (si->port_l2p_mapping[port] == -1) { 977 *base_index = 0; 978 *num_entries = 0; 979 return SOC_E_NONE; 980 } 981 982 phy_port = si->port_l2p_mapping[port]; 983 mmu_port = si->port_p2m_mapping[phy_port]; 984 pipe = (mmu_port >= 64) ? 1 : 0; 985 } else { 986 phy_port = mmu_port = -1; 987 pipe = -1; 988 } 989 COMPILER_REFERENCE(pipe); 990 991 switch (id) { 992 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 993 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 994 if (mmu_port >= 0) { 995 *base_index = 996 soc_td2_logical_qnum_hw_qnum(unit, port, 997 si->port_cosq_base[port], 0); 998 *num_entries = si->port_num_cosq[port]; 999 } else { 1000 *base_index = 0; 1001 *num_entries = non_dma->num_entries; 1002 } 1003 break; 1004 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC: 1005 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC: 1006 if (mmu_port >= 0) { 1007 *base_index = 1008 soc_td2_logical_qnum_hw_qnum(unit, port, 1009 si->port_uc_cosq_base[port], 1); 1010 *num_entries = si->port_num_uc_cosq[port]; 1011 } else { 1012 *base_index = 0; 1013 *num_entries = non_dma->num_entries; 1014 } 1015 break; 1016 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT: 1017 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE: 1018 case SOC_COUNTER_NON_DMA_QUEUE_PEAK: 1019 case SOC_COUNTER_NON_DMA_QUEUE_CURRENT: 1020 if (mmu_port >= 0) { 1021 *base_index = si->port_cosq_base[port]; 1022 *num_entries = si->port_num_cosq[port]; 1023 } else { 1024 *base_index = 0; 1025 *num_entries = non_dma->num_entries; 1026 } 1027 break; 1028 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC: 1029 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC: 1030 case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK: 1031 case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT: 1032 if (mmu_port >= 0) { 1033 *base_index = si->port_uc_cosq_base[port]; 1034 *num_entries = si->port_num_uc_cosq[port]; 1035 } else { 1036 *base_index = 0; 1037 *num_entries = non_dma->num_entries; 1038 } 1039 break; 1040 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_EXT: 1041 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_EXT: 1042 if (mmu_port >= 0) { 1043 if (pipe > 0) { 1044 /* 1045 * Y-PIPE entries in DMA buffer is begging with 1480. 1046 */ 1047 *base_index = 1480; 1048 *num_entries = non_dma->dma_index_max[1] 1049 - non_dma->dma_index_min[1] + 1; 1050 } else { 1051 *base_index = 0; 1052 *num_entries = non_dma->dma_index_max[0] + 1; 1053 } 1054 } else { 1055 *base_index = 0; 1056 *num_entries = non_dma->num_entries; 1057 } 1058 break; 1059 case SOC_COUNTER_NON_DMA_MMU_QCN_CNM: 1060 if (mmu_port >= 0) { 1061 *base_index = si->port_uc_cosq_base[port]; 1062 *num_entries = si->port_num_uc_cosq[port]; 1063 } else { 1064 *base_index = 0; 1065 *num_entries = non_dma->num_entries; 1066 } 1067 break; 1068 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI: 1069 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI: 1070 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI: 1071 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI: 1072 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI: 1073 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI: 1074 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI: 1075 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI: 1076 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI: 1077 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI: 1078 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI: 1079 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI: 1080 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI: 1081 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI: 1082 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI: 1083 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI: 1084 *base_index = SOC_INFO(unit).port_group[port] * 4; 1085 *num_entries = 4; 1086 break; 1087 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT: 1088 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT: 1089 if (mmu_port >= 0) { 1090 *base_index = non_dma->dma_index_min[0]; 1091 *num_entries = non_dma->dma_index_max[0] + 1; 1092 if (pipe > 0) { 1093 *base_index = non_dma->dma_index_max[0] + 1; 1094 } 1095 } else { 1096 *base_index = 0; 1097 *num_entries = non_dma->num_entries; 1098 } 1099 break; 1100 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING: 1101 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING: 1102 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER: 1103 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER: 1104 if (mmu_port >= 0) { 1105 *num_entries = non_dma->entries_per_port; 1106 *base_index = mmu_port; 1107 } else { 1108 return SOC_E_INTERNAL; 1109 } 1110 break; 1111 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW: 1112 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED: 1113 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN: 1114 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW: 1115 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED: 1116 if (mmu_port >= 0) { 1117 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */ 1118 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port; 1119 } else { /* in Y pipe */ 1120 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port + 1121 (non_dma->num_entries / 2); 1122 } 1123 *num_entries = non_dma->entries_per_port; 1124 } else { 1125 return SOC_E_INTERNAL; 1126 } 1127 break; 1128 case SOC_COUNTER_NON_DMA_PG_MIN_PEAK: 1129 case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT: 1130 case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK: 1131 case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT: 1132 case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK: 1133 case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT: 1134 if (mmu_port >= 0) { 1135 if (SOC_PBMP_MEMBER(si->xpipe_pbm, port)) { /* in X pipe */ 1136 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port; 1137 } else { /* in Y pipe */ 1138 *base_index = (mmu_port & 0x3f) * non_dma->entries_per_port + 1139 non_dma->dma_index_max[0] + 1; 1140 } 1141 *num_entries = non_dma->entries_per_port; 1142 } else { 1143 return SOC_E_INTERNAL; 1144 } 1145 break; 1146 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT: 1147 case SOC_COUNTER_NON_DMA_DROP_RQ_BYTE: 1148 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW: 1149 case SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED: 1150 case SOC_COUNTER_NON_DMA_POOL_PEAK: 1151 case SOC_COUNTER_NON_DMA_POOL_CURRENT: 1152 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK: 1153 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT: 1154 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_PEAK: 1155 case SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_CURRENT: 1156 *base_index = 0; 1157 *num_entries = non_dma->num_entries; 1158 break; 1159 default: 1160 return SOC_E_INTERNAL; 1161 } 1162 *base_index += non_dma->base_index; 1163 1164 return SOC_E_NONE; 1165 } 1166 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */ 1167 1168 #ifdef BCM_TRIUMPH3_SUPPORT 1169 STATIC int 1170 _soc_counter_triumph3_get_info(int unit, soc_port_t port, soc_reg_t id, 1171 int *base_index, int *num_entries) 1172 { 1173 soc_info_t *si; 1174 soc_control_t *soc; 1175 soc_counter_non_dma_t *non_dma; 1176 soc_port_t phy_port, mmu_port; 1177 1178 soc = SOC_CONTROL(unit); 1179 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1180 1181 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1182 return SOC_E_UNAVAIL; 1183 } 1184 1185 si = &SOC_INFO(unit); 1186 if (port >= 0) { 1187 phy_port = si->port_l2p_mapping[port]; 1188 mmu_port = si->port_p2m_mapping[phy_port]; 1189 } else { 1190 phy_port = mmu_port = -1; 1191 } 1192 1193 switch (id) { 1194 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT: 1195 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE: 1196 if (mmu_port >= 0) { 1197 if (mmu_port <= 39) { 1198 *base_index = mmu_port * 8; 1199 *num_entries = 8; 1200 } else if (mmu_port <= 55) { 1201 *base_index = 320 + (mmu_port - 40) * 10; 1202 *num_entries = 10; 1203 } else if (mmu_port == 56) { 1204 *base_index = 0x1e0; 1205 *num_entries = 8; 1206 } else if (mmu_port == 57) { 1207 *num_entries = 0; 1208 } else if (mmu_port == 58) { 1209 *base_index = 0x1e8; 1210 *num_entries = 8; 1211 } else if (mmu_port == 59) { 1212 *base_index = 0x200; 1213 *num_entries = 48; 1214 } else if (mmu_port == 60) { 1215 *base_index = 0x1f0; 1216 *num_entries = 8; 1217 } else if (mmu_port == 61) { 1218 *base_index = 0x1f8; 1219 *num_entries = 1; 1220 } else { 1221 return SOC_E_PARAM; 1222 } 1223 } else { 1224 *base_index = 0; 1225 *num_entries = 560; 1226 } 1227 break; 1228 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 1229 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 1230 if (mmu_port >= 0) { 1231 *base_index = si->port_cosq_base[port] + 1024; 1232 *num_entries = si->port_num_cosq[port]; 1233 } else { 1234 *base_index = 0; 1235 *num_entries = 1592; 1236 } 1237 break; 1238 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC: 1239 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC: 1240 if (mmu_port >= 0) { 1241 *base_index = si->port_uc_cosq_base[port]; 1242 *num_entries = si->port_num_uc_cosq[port]; 1243 } else { 1244 *base_index = 0; 1245 *num_entries = 1592; 1246 } 1247 break; 1248 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC: 1249 case SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC: 1250 case SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK: 1251 case SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT: 1252 if (mmu_port >= 0) { 1253 *base_index = si->port_uc_cosq_base[port]; 1254 *num_entries = si->port_num_uc_cosq[port]; 1255 } else { 1256 *base_index = 0; 1257 *num_entries = 1024; 1258 } 1259 break; 1260 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING: 1261 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING: 1262 *num_entries = 1; 1263 *base_index = port; 1264 break; 1265 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW: 1266 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED: 1267 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN: 1268 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW: 1269 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED: 1270 if (mmu_port >= 0) { 1271 *num_entries = 1; 1272 *base_index = mmu_port; 1273 } else { 1274 return SOC_E_INTERNAL; 1275 } 1276 break; 1277 case SOC_COUNTER_NON_DMA_PG_MIN_PEAK: 1278 case SOC_COUNTER_NON_DMA_PG_MIN_CURRENT: 1279 case SOC_COUNTER_NON_DMA_PG_SHARED_PEAK: 1280 case SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT: 1281 case SOC_COUNTER_NON_DMA_PG_HDRM_PEAK: 1282 case SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT: 1283 if (mmu_port >= 0) { 1284 *num_entries = 8; 1285 *base_index = mmu_port * (*num_entries); 1286 } else { 1287 *base_index = 0; 1288 *num_entries = 504; 1289 } 1290 break; 1291 case SOC_COUNTER_NON_DMA_QUEUE_PEAK: 1292 case SOC_COUNTER_NON_DMA_QUEUE_CURRENT: 1293 *num_entries = 48; 1294 *base_index = port * (*num_entries); 1295 break; 1296 case SOC_COUNTER_NON_DMA_POOL_PEAK: 1297 case SOC_COUNTER_NON_DMA_POOL_CURRENT: 1298 *base_index = 0; 1299 *num_entries = non_dma->num_entries; 1300 break; 1301 default: 1302 return SOC_E_INTERNAL; 1303 } 1304 *base_index += non_dma->base_index; 1305 1306 return SOC_E_NONE; 1307 } 1308 #endif /* BCM_TRIUMPH3_SUPPORT */ 1309 1310 #ifdef BCM_KATANA_SUPPORT 1311 STATIC int 1312 _soc_counter_katana_get_info(int unit, soc_port_t port, soc_reg_t id, 1313 int *base_index, int *num_entries) 1314 { 1315 soc_control_t *soc; 1316 soc_counter_non_dma_t *non_dma; 1317 int max_ports = 0; 1318 #if defined (BCM_SABER2_SUPPORT) 1319 soc_info_t *si = &SOC_INFO(unit); 1320 #endif 1321 soc = SOC_CONTROL(unit); 1322 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1323 1324 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1325 return SOC_E_UNAVAIL; 1326 } 1327 1328 max_ports = (SOC_IS_KATANA(unit)) ? SOC_MAX_NUM_PORTS : 1329 SOC_MAX_NUM_PP_PORTS; 1330 #if defined (BCM_SABER2_SUPPORT) 1331 if (SOC_IS_SABER2(unit)) { 1332 max_ports = si->cpu_hg_pp_port_index; 1333 } 1334 #endif 1335 if (port >= 0 ) { 1336 if (port < max_ports) { 1337 if (SOC_IS_KATANA2(unit)) { 1338 *base_index = SOC_INFO(unit).port_uc_cosq_base[port]; 1339 } 1340 else if (SOC_IS_KATANAX(unit)) { 1341 *base_index = SOC_INFO(unit).port_cosq_base[port]; 1342 } 1343 *num_entries = SOC_INFO(unit).port_num_uc_cosq[port]; 1344 *base_index += non_dma->base_index; 1345 } else { 1346 /* extended queues */ 1347 *base_index = port; 1348 *num_entries = non_dma->num_entries; 1349 *base_index += non_dma->base_index; 1350 } 1351 } 1352 1353 return SOC_E_NONE; 1354 } 1355 #endif /* BCM_KATANA_SUPPORT */ 1356 #ifdef BCM_KATANA2_SUPPORT 1357 int 1358 _soc_counter_katana2_get_mcindex(int unit, soc_port_t port, soc_reg_t id, 1359 int *base_index, int *num_entries) 1360 { 1361 soc_control_t *soc; 1362 soc_counter_non_dma_t *non_dma; 1363 int max_ports = 0; 1364 soc = SOC_CONTROL(unit); 1365 if (id < NUM_SOC_REG) { 1366 return SOC_E_PARAM; 1367 } 1368 if (id >= SOC_COUNTER_NON_DMA_END) { 1369 return SOC_E_PARAM; 1370 } 1371 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1372 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1373 return SOC_E_UNAVAIL; 1374 } 1375 max_ports = SOC_MAX_NUM_PP_PORTS; 1376 1377 if (port >= 0 ) { 1378 if (port < max_ports) { 1379 *base_index = SOC_INFO(unit).port_cosq_base[port]; 1380 *num_entries = SOC_INFO(unit).port_num_uc_cosq[port]; 1381 *base_index += non_dma->base_index; 1382 } else { 1383 *base_index = -1; 1384 } 1385 } 1386 1387 return SOC_E_NONE; 1388 } 1389 #endif 1390 1391 #ifdef BCM_GREYHOUND2_SUPPORT 1392 STATIC int 1393 _soc_counter_gh2_get_info(int unit, soc_port_t port, soc_reg_t id, 1394 int *base_index, int *num_entries) 1395 { 1396 soc_control_t *soc; 1397 soc_counter_non_dma_t *non_dma; 1398 soc_port_t phy_port, mmu_port; 1399 int i; 1400 1401 if ((NULL == base_index) || (NULL == num_entries)) { 1402 return SOC_E_PARAM; 1403 } 1404 1405 soc = SOC_CONTROL(unit); 1406 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1407 1408 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1409 return SOC_E_UNAVAIL; 1410 } 1411 1412 if (port >= 0) { 1413 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1414 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 1415 } else { 1416 phy_port = mmu_port = -1; 1417 } 1418 1419 if (non_dma->entries_per_port == 1) { 1420 /* This non-dma counter is per port */ 1421 *base_index = non_dma->base_index + port; 1422 *num_entries = 1; 1423 } else { 1424 switch (id) { 1425 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 1426 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 1427 if (mmu_port >= 0) { 1428 if (mmu_port >= SOC_GH2_64Q_MMU_PORT_IDX_MIN) { 1429 /* Port with 64 COSQ */ 1430 *num_entries = SOC_GH2_2LEVEL_QUEUE_NUM; 1431 *base_index = 1432 (SOC_GH2_64Q_MMU_PORT_IDX_MIN * 1433 SOC_GH2_LEGACY_QUEUE_NUM) + 1434 ((mmu_port - SOC_GH2_64Q_MMU_PORT_IDX_MIN) * 1435 (*num_entries)); 1436 } else { 1437 /* Port with 8 COSQ */ 1438 *num_entries = SOC_GH2_LEGACY_QUEUE_NUM; 1439 *base_index = mmu_port * (*num_entries); 1440 } 1441 } else { 1442 *base_index = 0; 1443 *num_entries = 1444 (SOC_GH2_64Q_MMU_PORT_IDX_MIN * 1445 SOC_GH2_LEGACY_QUEUE_NUM) + 1446 ((SOC_GH2_64Q_MMU_PORT_IDX_MAX - 1447 SOC_GH2_64Q_MMU_PORT_IDX_MIN + 1) * 1448 SOC_GH2_2LEVEL_QUEUE_NUM); 1449 } 1450 *base_index += non_dma->base_index; 1451 break; 1452 case SOC_COUNTER_NON_DMA_COSQ_DROP_PKT: 1453 *base_index = non_dma->base_index; 1454 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 1455 if (i == port) { 1456 break; 1457 } 1458 *base_index += SOC_GH2_2LEVEL_QUEUE_NUM; 1459 } 1460 *num_entries = SOC_GH2_2LEVEL_QUEUE_NUM; 1461 break; 1462 default: 1463 *base_index = non_dma->base_index; 1464 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 1465 if (i == port) { 1466 break; 1467 } 1468 *base_index += num_cosq[unit][i]; 1469 } 1470 *num_entries = num_cosq[unit][port]; 1471 return SOC_E_NONE; 1472 } 1473 } 1474 1475 return SOC_E_NONE; 1476 } 1477 #endif /* BCM_GREYHOUND2_SUPPORT */ 1478 1479 #ifdef BCM_FIREBOLT_SUPPORT 1480 STATIC int 1481 _soc_counter_fb_get_info(int unit, soc_port_t port, soc_reg_t id, 1482 int *base_index, int *num_entries) 1483 { 1484 soc_control_t *soc; 1485 soc_counter_non_dma_t *non_dma; 1486 int i; 1487 1488 soc = SOC_CONTROL(unit); 1489 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1490 1491 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1492 return SOC_E_UNAVAIL; 1493 } 1494 1495 if (non_dma->entries_per_port == 1) { 1496 /* This non-dma counter is per port */ 1497 *base_index = non_dma->base_index + port; 1498 *num_entries = 1; 1499 } else { 1500 if (SOC_IS_SC_CQ(unit)) { 1501 /* This non-dma counter is per cosq */ 1502 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) { 1503 *base_index = non_dma->base_index; 1504 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 1505 if (i == port) { 1506 break; 1507 } 1508 *base_index += num_cosq[unit][i]; 1509 } 1510 *num_entries = num_cosq[unit][port]; 1511 } else { 1512 /* This non-dma counter is per uc/mc q */ 1513 *base_index = non_dma->base_index + 1514 (non_dma->entries_per_port * port); 1515 *num_entries = non_dma->entries_per_port; 1516 } 1517 } else { 1518 *base_index = non_dma->base_index; 1519 for (i = 0; i < SOC_MAX_NUM_PORTS; i++) { 1520 if (i == port) { 1521 break; 1522 } 1523 *base_index += num_cosq[unit][i]; 1524 } 1525 *num_entries = num_cosq[unit][port]; 1526 } 1527 } 1528 1529 return SOC_E_NONE; 1530 } 1531 #endif /* BCM_FIREBOLT_SUPPORT */ 1532 1533 #ifdef BCM_SHADOW_SUPPORT 1534 STATIC int 1535 _soc_counter_shadow_get_info(int unit, soc_port_t port, soc_reg_t id, 1536 int *base_index, int *num_entries) 1537 { 1538 soc_control_t *soc; 1539 soc_counter_non_dma_t *non_dma; 1540 1541 soc = SOC_CONTROL(unit); 1542 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 1543 1544 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 1545 return SOC_E_UNAVAIL; 1546 } 1547 1548 *base_index = non_dma->base_index; 1549 *num_entries = 1; 1550 1551 return SOC_E_NONE; 1552 } 1553 #endif /* BCM_SHADOW_SUPPORT */ 1554 1555 int 1556 _soc_controlled_counter_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg, 1557 int *base_index, int *num_entries, char **cname) 1558 { 1559 soc_control_t *soc = SOC_CONTROL(unit); 1560 1561 if (ctr_reg < 0) { 1562 return SOC_E_PARAM; 1563 } 1564 1565 if (soc->controlled_counters == NULL) { 1566 return SOC_E_UNAVAIL; 1567 } 1568 1569 if(!COUNTER_IS_COLLECTED(soc->controlled_counters[ctr_reg])) { 1570 return SOC_E_PARAM; 1571 } 1572 1573 { 1574 *base_index = COUNTER_IDX_PORTBASE(unit, port) + soc->controlled_counters[ctr_reg].counter_idx; 1575 *num_entries = 1; /* MAC counters are non-array */ 1576 } 1577 1578 if (NULL != cname) { 1579 *cname = soc->controlled_counters[ctr_reg].cname; 1580 } 1581 1582 return SOC_E_NONE; 1583 } 1584 1585 #ifdef BCM_PETRA_SUPPORT 1586 STATIC int 1587 _soc_counter_arad_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg, 1588 int *base_index, int *num_entries, char **cname) 1589 { 1590 int rv = SOC_E_NONE; 1591 1592 if (_SOC_CONTROLLED_COUNTER_USE(unit, port)) { 1593 rv = _soc_controlled_counter_get_info(unit, port, ctr_reg, base_index, 1594 num_entries, cname); 1595 1596 } else if (ctr_reg >= NUM_SOC_REG) { 1597 if (ctr_reg >= SOC_COUNTER_NON_DMA_END) { 1598 return SOC_E_PARAM; 1599 } else { 1600 /*non dma counters*/ 1601 return SOC_E_UNAVAIL; 1602 } 1603 } else { 1604 *base_index = COUNTER_IDX_PORTBASE(unit, port) + 1605 SOC_REG_CTR_IDX(unit, ctr_reg) + _SOC_CONTROLLED_COUNTER_NOF(unit)/*added shift for tbe controlled registers*/; 1606 1607 *num_entries = SOC_REG_NUMELS(unit, ctr_reg); 1608 if (cname) { 1609 *cname = SOC_REG_NAME(unit, ctr_reg); 1610 } 1611 } 1612 return rv; 1613 1614 } 1615 #endif /* BCM_PETRA_SUPPORT */ 1616 1617 #ifdef SOC_COUNTER_TABLE_SUPPORT 1618 STATIC int 1619 _soc_counter_tbl_get_info(int unit, soc_port_t port, int ctr_reg, 1620 soc_ctr_tbl_entry_t **entry) { 1621 int i; 1622 int ctr_fld; 1623 soc_ctr_tbl_info_t *ctr_tbl_info = SOC_CTR_TBL_INFO(unit); 1624 soc_ctr_tbl_entry_t *ctr_tbl_entry = NULL; 1625 int entry_num = 0; 1626 1627 if ((entry == NULL) || (ctr_reg < SOC_COUNTER_TABLE_FIELD_START)) { 1628 return SOC_E_PARAM; 1629 } 1630 1631 ctr_tbl_entry = ctr_tbl_info->tables; 1632 entry_num = ctr_tbl_info->num; 1633 1634 ctr_fld = ctr_reg - SOC_COUNTER_TABLE_FIELD_START; 1635 1636 for(i=0; i < entry_num; i++) { 1637 if(ctr_fld == ctr_tbl_entry->ctr_field) { 1638 *entry = ctr_tbl_entry; 1639 return SOC_E_NONE; 1640 } 1641 ctr_tbl_entry++; 1642 } 1643 1644 return SOC_E_NOT_FOUND; 1645 } 1646 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 1647 1648 STATIC int 1649 _soc_counter_get_info(int unit, soc_port_t port, soc_reg_t ctr_reg, 1650 int *base_index, int *num_entries, char **cname) 1651 { 1652 int rv; 1653 #ifdef BCM_TOMAHAWK_SUPPORT 1654 soc_reg_t ctr_reg_offset = ctr_reg; 1655 #endif /* BCM_TOMAHAWK_SUPPORT */ 1656 #ifdef SOC_COUNTER_TABLE_SUPPORT 1657 soc_ctr_tbl_entry_t *ctr_tbl_entry = NULL; 1658 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 1659 1660 if ((!(SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit) || 1661 SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))) && (port < 0)) { 1662 return SOC_E_PARAM; 1663 } 1664 1665 #ifdef BCM_PETRA_SUPPORT 1666 if (SOC_IS_ARAD(unit)) { 1667 rv = _soc_counter_arad_get_info(unit, port, ctr_reg, base_index, 1668 num_entries, cname); 1669 return rv; 1670 } 1671 #endif /* BCM_PETRA_SUPPORT */ 1672 1673 if (soc_feature(unit, soc_feature_controlled_counters)) { 1674 rv = _soc_controlled_counter_get_info(unit, port, ctr_reg, base_index, 1675 num_entries, cname); 1676 return rv; 1677 } 1678 1679 if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) && 1680 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 1681 #ifdef BCM_TOMAHAWK_SUPPORT 1682 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1683 /* TH has encodings for ctr_reg */ 1684 ctr_reg &= 0x80ffffff; 1685 } 1686 #endif /* BCM_TOMAHAWK_SUPPORT */ 1687 1688 if (ctr_reg >= SOC_COUNTER_NON_DMA_END) { 1689 return SOC_E_PARAM; 1690 } 1691 1692 #ifdef BCM_TOMAHAWK_SUPPORT 1693 if (SOC_IS_TOMAHAWKX(unit)) { 1694 rv = soc_counter_tomahawk_get_info(unit, port, ctr_reg_offset, 1695 base_index, num_entries); 1696 } else 1697 #endif /* BCM_TOMAHAWK_SUPPORT */ 1698 #ifdef BCM_TRIDENT3_SUPPORT 1699 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 1700 rv = soc_counter_trident3_get_info(unit, port, ctr_reg_offset, 1701 base_index, num_entries); 1702 } else 1703 #endif /* BCM_TRIDENT3_SUPPORT */ 1704 1705 #if defined (BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT) 1706 /* 1707 * This will be used only for CPRI counters. 1708 * For all the other counters info, Monterey uses Apache 1709 * counter get info. 1710 */ 1711 if ((SOC_IS_MONTEREY(unit)) && 1712 ((ctr_reg >= SOC_COUNTER_NON_DMA_CPRI_START) && 1713 (ctr_reg <= SOC_COUNTER_NON_DMA_CPRI_END))) { 1714 rv = _soc_counter_monterey_cpri_get_info(unit, port, ctr_reg, 1715 base_index, num_entries); 1716 } else 1717 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */ 1718 1719 #ifdef BCM_HELIX5_SUPPORT 1720 if (SOC_IS_HELIX5(unit)) { 1721 rv = soc_counter_helix5_get_info(unit, port, ctr_reg_offset, 1722 base_index, num_entries); 1723 } else 1724 #endif /* BCM_HELIX5_SUPPORT */ 1725 #ifdef BCM_APACHE_SUPPORT 1726 if (SOC_IS_APACHE(unit)) { 1727 rv = _soc_counter_apache_get_info(unit, port, ctr_reg, 1728 base_index, num_entries); 1729 } else 1730 #endif /* BCM_APACHE_SUPPORT */ 1731 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT ) 1732 if (SOC_IS_TD2_TT2(unit)) { 1733 rv = _soc_counter_trident2_get_info(unit, port, ctr_reg, base_index, 1734 num_entries); 1735 } else 1736 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */ 1737 #ifdef BCM_TRIDENT_SUPPORT 1738 if (SOC_IS_TD_TT(unit)) { 1739 rv = _soc_counter_trident_get_info(unit, port, ctr_reg, base_index, 1740 num_entries); 1741 } else 1742 #endif /* BCM_TRIDENT_SUPPORT */ 1743 #ifdef BCM_TRIUMPH3_SUPPORT 1744 if (SOC_IS_TRIUMPH3(unit)) { 1745 rv = _soc_counter_triumph3_get_info(unit, port, ctr_reg, base_index, 1746 num_entries); 1747 } else 1748 #endif /* BCM_TRIUMPH3_SUPPORT */ 1749 #ifdef BCM_KATANA_SUPPORT 1750 if (SOC_IS_KATANAX(unit)) { 1751 rv = _soc_counter_katana_get_info(unit, port, ctr_reg, base_index, 1752 num_entries); 1753 } else 1754 #endif /* BCM_KATANA_SUPPORT */ 1755 #ifdef BCM_GREYHOUND2_SUPPORT 1756 if (SOC_IS_GREYHOUND2(unit)) { 1757 rv = _soc_counter_gh2_get_info(unit, port, ctr_reg, base_index, 1758 num_entries); 1759 } else 1760 #endif /* BCM_GREYHOUND2_SUPPORT */ 1761 #ifdef BCM_FIREBOLT_SUPPORT 1762 if (SOC_IS_FBX(unit) && !(SOC_IS_SHADOW(unit))) { 1763 rv = _soc_counter_fb_get_info(unit, port, ctr_reg, base_index, 1764 num_entries); 1765 } else 1766 #endif /* BCM_FIREBOLT_SUPPORT */ 1767 #ifdef BCM_SHADOW_SUPPORT 1768 if (SOC_IS_SHADOW(unit)) { 1769 rv = _soc_counter_shadow_get_info(unit, port, ctr_reg, base_index, 1770 num_entries); 1771 } else 1772 #endif /* BCM_SHADOW_SUPPORT */ 1773 { 1774 rv = SOC_E_UNAVAIL; 1775 } 1776 1777 if (rv < 0) { 1778 return rv; 1779 } 1780 if (cname) { 1781 *cname = SOC_CONTROL(unit)-> 1782 counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].cname; 1783 } 1784 1785 } else { 1786 if ((ctr_reg < SOC_COUNTER_NON_DMA_START) && 1787 !SOC_REG_IS_ENABLED(unit, ctr_reg)) { 1788 return SOC_E_PARAM; 1789 } 1790 #ifdef BCM_SHADOW_SUPPORT 1791 if (SOC_IS_SHADOW(unit) && IS_IL_PORT(unit, port)) { 1792 return SOC_E_PORT; 1793 } 1794 #endif /* BCM_SHADOW_SUPPORT */ 1795 1796 #ifdef SOC_COUNTER_TABLE_SUPPORT 1797 if (SOC_IS_TOMAHAWK3(unit)) { 1798 if(ctr_reg >= SOC_COUNTER_TABLE_FIELD_START) { 1799 SOC_IF_ERROR_RETURN( 1800 _soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_entry)); 1801 *num_entries = 1; 1802 *base_index = COUNTER_IDX_PORTBASE(unit, port) + ctr_tbl_entry->ctr_idx; 1803 if (cname) { 1804 *cname = SOC_FIELD_NAME(unit, (ctr_tbl_entry->ctr_field - SOC_COUNTER_TABLE_FIELD_START)); 1805 } 1806 return SOC_E_NONE; 1807 } 1808 } 1809 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 1810 1811 if(!SOC_REG_IS_VALID(unit, ctr_reg)) { 1812 return SOC_E_PARAM; 1813 } 1814 1815 *base_index = COUNTER_IDX_PORTBASE(unit, port) + 1816 SOC_REG_CTR_IDX(unit, ctr_reg); 1817 if (SOC_IS_TRIUMPH3(unit)) { 1818 *base_index -= 0x20; 1819 } 1820 #ifdef BCM_HURRICANE2_SUPPORT 1821 if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || \ 1822 SOC_IS_GREYHOUND(unit)) { 1823 *base_index -= 0x37; 1824 } 1825 #endif /* BCM_HURRICANE2_SUPPORT */ 1826 #ifdef BCM_GREYHOUND2_SUPPORT 1827 if (SOC_IS_GREYHOUND2(unit)) { 1828 *base_index -= 0x6f; 1829 } 1830 #endif /* BCM_GREYHOUND2_SUPPORT */ 1831 *num_entries = SOC_REG_NUMELS(unit, ctr_reg); 1832 if (cname) { 1833 *cname = SOC_REG_NAME(unit, ctr_reg); 1834 } 1835 } 1836 1837 return SOC_E_NONE; 1838 } 1839 1840 #ifdef SOC_COUNTER_TABLE_SUPPORT 1841 STATIC int 1842 _soc_ctr_tbl_field_get(int unit, soc_reg_t ctr_reg, int port, 1843 soc_ctr_tbl_entry_t *ctr_tbl_info_entry, 1844 uint64 *ctr_val) { 1845 soc_mem_t mem; 1846 soc_field_t ctr_fld; 1847 soc_format_t format; 1848 int copyno, index; 1849 uint32 row_ent[16]; 1850 uint32 fval[2]; 1851 int phy_port; 1852 1853 if(ctr_reg < SOC_COUNTER_TABLE_FIELD_START) { 1854 return SOC_E_PARAM; 1855 } 1856 1857 if(ctr_tbl_info_entry == NULL || ctr_val == NULL) { 1858 return SOC_E_PARAM; 1859 } 1860 1861 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1862 phy_port -= SOC_COUNTER_TABLE_BASE_PORT; 1863 ctr_fld = ctr_tbl_info_entry->ctr_field; 1864 mem = ctr_tbl_info_entry->mem; 1865 format = ctr_tbl_info_entry->format; 1866 index = (phy_port % NUM_PORTS_PER_CDMIB_MEM) * NUM_CDMIB_MEM_ROWS_PER_PORT 1867 + ctr_tbl_info_entry->row_offset; 1868 copyno = SOC_MEM_BLOCK_MIN(unit, mem) + 1869 (phy_port / NUM_PORTS_PER_CDMIB_MEM); 1870 1871 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, copyno, index, row_ent)); 1872 soc_format_field_get(unit, format, row_ent, ctr_fld, fval); 1873 COMPILER_64_SET(*ctr_val, fval[1], fval[0]); 1874 1875 return SOC_E_NONE; 1876 } 1877 1878 STATIC int 1879 _soc_ctr_tbl_field_set(int unit, soc_reg_t ctr_reg, int port, 1880 soc_ctr_tbl_entry_t *ctr_tbl_info_entry, 1881 uint64 *ctr_val) { 1882 soc_mem_t mem; 1883 soc_field_t ctr_fld; 1884 soc_format_t format; 1885 int copyno, index; 1886 uint32 row_ent[16]; 1887 uint32 fval[2]; 1888 int phy_port; 1889 1890 if(ctr_reg < SOC_COUNTER_TABLE_FIELD_START) { 1891 return SOC_E_PARAM; 1892 } 1893 1894 if(ctr_tbl_info_entry == NULL || ctr_val == NULL) { 1895 return SOC_E_PARAM; 1896 } 1897 1898 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1899 phy_port -= SOC_COUNTER_TABLE_BASE_PORT; 1900 ctr_fld = ctr_tbl_info_entry->ctr_field; 1901 mem = ctr_tbl_info_entry->mem; 1902 format = ctr_tbl_info_entry->format; 1903 index = (phy_port % NUM_PORTS_PER_CDMIB_MEM) * NUM_CDMIB_MEM_ROWS_PER_PORT 1904 + ctr_tbl_info_entry->row_offset; 1905 copyno = SOC_MEM_BLOCK_MIN(unit, mem) + 1906 (phy_port / NUM_PORTS_PER_CDMIB_MEM); 1907 1908 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, copyno, index, row_ent)); 1909 COMPILER_64_TO_32_HI(fval[1], *ctr_val); 1910 COMPILER_64_TO_32_LO(fval[0], *ctr_val); 1911 soc_format_field_set(unit, format, row_ent, ctr_fld, fval); 1912 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, copyno, index, row_ent)); 1913 1914 return SOC_E_NONE; 1915 } 1916 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 1917 1918 /* 1919 * Function: 1920 * soc_counter_idx_get 1921 * Purpose: 1922 * Get the index of a counter given the counter and port 1923 * Parameters: 1924 * unit - The SOC unit number 1925 * reg - The register number 1926 * port - The port for which index is being calculated 1927 * Returns: 1928 * SOC_E_XXX, no it is not 1929 * Notes: 1930 */ 1931 1932 int 1933 soc_counter_idx_get(int unit, soc_reg_t reg, int ar_idx, int port) 1934 { 1935 int base_index, num_entries; 1936 if (_soc_counter_get_info(unit, port, reg, &base_index, &num_entries, 1937 NULL) < 0) { 1938 return -1; 1939 } 1940 1941 if (ar_idx < 0) { 1942 return base_index; 1943 } else if (ar_idx < num_entries) { 1944 return base_index + ar_idx; 1945 } else { 1946 return -1; 1947 } 1948 } 1949 1950 /* 1951 * Function: 1952 * _soc_counter_num_cosq_init 1953 * Purpose: 1954 * Initialize the number of COSQ per port. 1955 * Parameters: 1956 * unit - The SOC unit number 1957 * nports - Number of ports the unit has. 1958 * Returns: 1959 * None. 1960 */ 1961 STATIC void 1962 _soc_counter_num_cosq_init(int unit, int nports) 1963 { 1964 /* Some compiler may generate false warning in partial build dead code */ 1965 if (nports > SOC_MAX_NUM_PORTS) { 1966 return; 1967 } 1968 1969 #ifdef BCM_TRIUMPH_SUPPORT 1970 #ifdef BCM_TRIDENT_SUPPORT 1971 if (SOC_IS_TD_TT(unit)) { 1972 return; 1973 } 1974 #endif /* BCM_TRIDENT_SUPPORT */ 1975 #ifdef BCM_SHADOW_SUPPORT 1976 if (SOC_IS_SHADOW(unit)) { 1977 return; 1978 } 1979 #endif /* BCM_SHADOW_SUPPORT */ 1980 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 1981 if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || \ 1982 SOC_IS_GREYHOUND2(unit)) { 1983 int port; 1984 1985 /* all ports 8Q, including G, HG, CMIC and the reserved port 1 */ 1986 for (port = 0; port < nports; port++) { 1987 num_cosq[unit][port] = 8; 1988 } 1989 1990 } else 1991 #endif /* BCM_HURRICANE_SUPPORT || BCM_GREYHOUND_SUPPORT*/ 1992 #ifdef BCM_TRIUMPH2_SUPPORT 1993 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)){ 1994 const int port_24q[] = {26, 27, 28, 29, 30, 31, 34, 38, 39, 42, 43, 46, 50, 51}; 1995 const int port_16q = 54; 1996 int port, i; 1997 1998 for (port = 0; port < nports; port++) { 1999 if (IS_CPU_PORT(unit, port)) { 2000 num_cosq[unit][port] = NUM_CPU_COSQ(unit); 2001 } else { 2002 num_cosq[unit][port] = 8; 2003 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) { 2004 if (port == port_24q[i]) { 2005 num_cosq[unit][port] = 24; 2006 break; 2007 } 2008 } 2009 if ((port == port_16q) && (port < SOC_MAX_NUM_PORTS)) { 2010 num_cosq[unit][port] = 16; 2011 } 2012 } 2013 } 2014 2015 } else 2016 #endif /* BCM_TRIUMPH2_SUPPORT */ 2017 #ifdef BCM_ENDURO_SUPPORT 2018 if (SOC_IS_ENDURO(unit)){ 2019 const int port_24q[] = {26, 27, 28, 29}; 2020 int port, i; 2021 2022 for (port = 0; port < nports; port++) { 2023 if (IS_CPU_PORT(unit, port)) { 2024 num_cosq[unit][port] = NUM_CPU_COSQ(unit); 2025 } else { 2026 num_cosq[unit][port] = 8; 2027 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) { 2028 if (port == port_24q[i]) { 2029 num_cosq[unit][port] = 24; 2030 break; 2031 } 2032 } 2033 } 2034 } 2035 2036 } else 2037 #endif /* BCM_ENDURO_SUPPORT */ 2038 #ifdef BCM_KATANA_SUPPORT 2039 if (SOC_IS_KATANA(unit)) { 2040 int port; 2041 2042 for (port = 0; port < nports; port++) { 2043 if (IS_CPU_PORT(unit, port)) { 2044 num_cosq[unit][port] = NUM_CPU_COSQ(unit); 2045 /* coverity[overrun-local] */ 2046 } else if (IS_HG_PORT(unit, port)) { 2047 num_cosq[unit][port] = 24; 2048 } else { 2049 num_cosq[unit][port] = 8; 2050 } 2051 } 2052 } else 2053 #endif /* BCM_KATANA_SUPPORT */ 2054 if (SOC_IS_TR_VL(unit)) { 2055 const int port_24q[] = {2, 3, 14, 15, 26, 27, 28, 29, 30, 31, 32, 43}; 2056 int port, i; 2057 2058 for (port = 0; port < nports; port++) { 2059 if (IS_CPU_PORT(unit, port)) { 2060 num_cosq[unit][port] = NUM_CPU_COSQ(unit); 2061 } else { 2062 num_cosq[unit][port] = 8; 2063 for (i = 0; i < sizeof(port_24q) / sizeof(port_24q[1]); i++) { 2064 if (port == port_24q[i]) { 2065 num_cosq[unit][port] = 24; 2066 break; 2067 } 2068 } 2069 } 2070 } 2071 } else 2072 #endif /* BCM_TRIUMPH_SUPPORT */ 2073 #ifdef BCM_FIREBOLT_SUPPORT 2074 if (SOC_IS_SC_CQ(unit) || SOC_IS_HB_GW(unit) || SOC_IS_FB_FX_HX(unit)) { 2075 int port; 2076 2077 for (port = 0; port < nports; port++) { 2078 if (IS_CPU_PORT(unit, port)) { 2079 num_cosq[unit][port] = NUM_CPU_COSQ(unit); 2080 } else { 2081 num_cosq[unit][port] = 8; 2082 } 2083 } 2084 } else 2085 #endif /* BCM_FIREBOLT_SUPPORT */ 2086 { 2087 return; 2088 } 2089 2090 return; 2091 } 2092 2093 #ifdef BCM_TRIUMPH3_SUPPORT 2094 STATIC int 2095 _soc_counter_triumph3_non_dma_init(int unit, int nports, 2096 int non_dma_start_index, 2097 int *non_dma_entries) 2098 { 2099 soc_control_t *soc; 2100 soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2; 2101 int num_entries, alloc_size; 2102 uint32 *buf; 2103 2104 soc = SOC_CONTROL(unit); 2105 *non_dma_entries = 0; 2106 2107 /* EGR_PERQ_XMT_COUNTERS size depends on user's portmap config */ 2108 num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm); 2109 alloc_size = num_entries * sizeof(uint32) * 2110 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm); 2111 2112 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 2113 if (buf == NULL) { 2114 return SOC_E_MEMORY; 2115 } 2116 sal_memset(buf, 0, alloc_size); 2117 2118 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 2119 SOC_COUNTER_NON_DMA_START]; 2120 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2121 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 2122 non_dma0->pbmp = PBMP_ALL(unit); 2123 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2124 non_dma0->entries_per_port = 48; 2125 non_dma0->num_entries = num_entries; 2126 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 2127 non_dma0->reg = INVALIDr; 2128 non_dma0->field = PACKET_COUNTERf; 2129 non_dma0->cname = "MC_PERQ_PKT"; 2130 non_dma0->dma_buf[0] = buf; 2131 non_dma0->dma_index_max[0] = num_entries - 1; 2132 non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERSm; 2133 *non_dma_entries += non_dma0->num_entries; 2134 2135 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 2136 SOC_COUNTER_NON_DMA_START]; 2137 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2138 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2139 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2140 non_dma1->field = BYTE_COUNTERf; 2141 non_dma1->cname = "MC_PERQ_BYTE"; 2142 *non_dma_entries += non_dma1->num_entries; 2143 2144 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC - 2145 SOC_COUNTER_NON_DMA_START]; 2146 sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t)); 2147 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 2148 non_dma2->pbmp = PBMP_ALL(unit); 2149 non_dma2->entries_per_port = 10; 2150 non_dma2->num_entries = 0; 2151 non_dma2->cname = "UC_PERQ_PKT"; 2152 2153 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC - 2154 SOC_COUNTER_NON_DMA_START]; 2155 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2156 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 2157 non_dma2->pbmp = PBMP_ALL(unit); 2158 non_dma2->entries_per_port = 10; 2159 non_dma2->num_entries = 0; 2160 non_dma2->cname = "UC_PERQ_BYTE"; 2161 2162 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 2163 SOC_COUNTER_NON_DMA_START]; 2164 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2165 _SOC_COUNTER_NON_DMA_DO_DMA; 2166 non_dma0->pbmp = PBMP_ALL(unit); 2167 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2168 non_dma0->entries_per_port = 48; /* 48 for cpu port */ 2169 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEMm); 2170 non_dma0->mem = MMU_CTR_MC_DROP_MEMm; 2171 non_dma0->reg = INVALIDr; 2172 non_dma0->field = PKT_CNTf; 2173 non_dma0->cname = "MCQ_DROP_PKT"; 2174 non_dma0->dma_buf[0] = buf; 2175 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2176 non_dma0->dma_mem[0] = non_dma0->mem; 2177 *non_dma_entries += non_dma0->num_entries; 2178 2179 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 2180 SOC_COUNTER_NON_DMA_START]; 2181 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2182 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2183 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2184 non_dma1->field = BYTE_COUNTf; 2185 non_dma1->cname = "MCQ_DROP_BYTE"; 2186 *non_dma_entries += non_dma1->num_entries; 2187 2188 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC - 2189 SOC_COUNTER_NON_DMA_START]; 2190 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 2191 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2192 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2193 non_dma0->entries_per_port = 8; 2194 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm); 2195 non_dma0->mem = MMU_CTR_UC_DROP_MEMm; 2196 non_dma0->reg = INVALIDr; 2197 non_dma0->field = PKT_CNTf; 2198 non_dma0->cname = "UCQ_DROP_PKT"; 2199 non_dma0->dma_buf[0] = buf; 2200 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2201 non_dma0->dma_mem[0] = non_dma0->mem; 2202 *non_dma_entries += non_dma0->num_entries; 2203 2204 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC - 2205 SOC_COUNTER_NON_DMA_START]; 2206 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2207 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2208 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2209 non_dma1->field = BYTE_COUNTf; 2210 non_dma1->cname = "UCQ_DROP_BYTE"; 2211 *non_dma_entries += non_dma1->num_entries; 2212 2213 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 2214 SOC_COUNTER_NON_DMA_START]; 2215 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 2216 non_dma0->pbmp = PBMP_ALL(unit); 2217 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2218 non_dma0->entries_per_port = 1; 2219 non_dma0->num_entries = nports; 2220 non_dma0->mem = INVALIDm; 2221 non_dma0->reg = DROP_PKT_CNT_INGr; 2222 non_dma0->field = COUNTf; 2223 non_dma0->cname = "DROP_PKT_ING"; 2224 *non_dma_entries += non_dma0->num_entries; 2225 2226 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 2227 SOC_COUNTER_NON_DMA_START]; 2228 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2229 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2230 non_dma1->reg = DROP_BYTE_CNT_ING_64r; 2231 non_dma1->cname = "DROP_BYTE_ING"; 2232 *non_dma_entries += non_dma1->num_entries; 2233 2234 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 2235 SOC_COUNTER_NON_DMA_START]; 2236 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2237 _SOC_COUNTER_NON_DMA_DO_DMA; 2238 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2239 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2240 non_dma0->entries_per_port = 1; 2241 non_dma0->num_entries = 63; /* one per port */ 2242 non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm; 2243 non_dma0->reg = INVALIDr; 2244 non_dma0->field = PKT_CNTf; 2245 non_dma0->cname = "DROP_PKT_YEL"; 2246 non_dma0->dma_buf[0] = buf; 2247 non_dma0->dma_index_min[0] = 63 * 4; 2248 non_dma0->dma_index_max[0] = 63 * 4 + 62; 2249 non_dma0->dma_mem[0] = non_dma0->mem; 2250 *non_dma_entries += non_dma0->num_entries; 2251 2252 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 2253 SOC_COUNTER_NON_DMA_START]; 2254 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2255 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2256 non_dma1->cname = "DROP_PKT_RED"; 2257 non_dma1->dma_index_min[0] = 63 * 3; 2258 non_dma1->dma_index_max[0] = 63 * 3 + 62; 2259 *non_dma_entries += non_dma1->num_entries; 2260 2261 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN - 2262 SOC_COUNTER_NON_DMA_START]; 2263 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2264 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2265 non_dma1->cname = "WRED_PKT_GRE"; 2266 non_dma1->dma_index_min[0] = 63 * 2; 2267 non_dma1->dma_index_max[0] = 63 * 2 + 62; 2268 *non_dma_entries += non_dma1->num_entries; 2269 2270 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW - 2271 SOC_COUNTER_NON_DMA_START]; 2272 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2273 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2274 non_dma1->cname = "WRED_PKT_YEL"; 2275 non_dma1->dma_index_min[0] = 63 * 1; 2276 non_dma1->dma_index_max[0] = 66 * 1 + 62; 2277 *non_dma_entries += non_dma1->num_entries; 2278 2279 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED - 2280 SOC_COUNTER_NON_DMA_START]; 2281 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2282 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2283 non_dma1->cname = "WRED_PKT_RED"; 2284 non_dma1->dma_index_min[0] = 0; 2285 non_dma1->dma_index_max[0] = 62; 2286 *non_dma_entries += non_dma1->num_entries; 2287 2288 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK - 2289 SOC_COUNTER_NON_DMA_START]; 2290 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2291 _SOC_COUNTER_NON_DMA_PEAK; 2292 SOC_PBMP_CLEAR(non_dma0->pbmp); 2293 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2294 non_dma0->entries_per_port = 0; 2295 non_dma0->num_entries = 4; 2296 non_dma0->mem = INVALIDm; 2297 non_dma0->reg = TOTAL_BUFFER_COUNT_CELL_SPr; 2298 non_dma0->field = TOTAL_BUFFER_COUNTf; 2299 non_dma0->cname = "POOL_PEAK"; 2300 non_dma0->dma_buf[0] = buf; 2301 *non_dma_entries += non_dma0->num_entries; 2302 2303 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT - 2304 SOC_COUNTER_NON_DMA_START]; 2305 sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t)); 2306 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2307 _SOC_COUNTER_NON_DMA_CURRENT; 2308 non_dma2->cname = "POOL_CUR"; 2309 2310 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK - 2311 SOC_COUNTER_NON_DMA_START]; 2312 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2313 _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA; 2314 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2315 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2316 non_dma0->entries_per_port = 8; 2317 non_dma0->num_entries = nports * non_dma0->entries_per_port; 2318 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2319 non_dma0->mem = THDI_PORT_PG_CNTRSm; 2320 non_dma0->reg = INVALIDr; 2321 non_dma0->field = PG_MIN_COUNTf; 2322 non_dma0->dma_buf[0] = buf; 2323 non_dma0->dma_mem[0] = non_dma0->mem; 2324 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2325 non_dma0->cname = "PG_MIN_PEAK"; 2326 *non_dma_entries += non_dma0->num_entries; 2327 2328 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT - 2329 SOC_COUNTER_NON_DMA_START]; 2330 sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t)); 2331 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2332 _SOC_COUNTER_NON_DMA_CURRENT; 2333 non_dma2->cname = "PG_MIN_CUR"; 2334 2335 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK - 2336 SOC_COUNTER_NON_DMA_START]; 2337 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2338 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2339 non_dma1->field = PG_SHARED_COUNTf; 2340 non_dma1->cname = "PG_SHARED_PEAK"; 2341 *non_dma_entries += non_dma1->num_entries; 2342 2343 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT - 2344 SOC_COUNTER_NON_DMA_START]; 2345 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2346 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT; 2347 non_dma2->cname = "PG_SHARED_CUR"; 2348 2349 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK - 2350 SOC_COUNTER_NON_DMA_START]; 2351 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2352 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2353 non_dma1->field = PG_HDRM_COUNTf; 2354 non_dma1->cname = "PG_HDRM_PEAK"; 2355 *non_dma_entries += non_dma1->num_entries; 2356 2357 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT - 2358 SOC_COUNTER_NON_DMA_START]; 2359 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2360 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT; 2361 non_dma2->cname = "PG_HDRM_CUR"; 2362 2363 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK - 2364 SOC_COUNTER_NON_DMA_START]; 2365 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 2366 _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA; 2367 non_dma1->pbmp = PBMP_PORT_ALL(unit); 2368 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2369 non_dma1->entries_per_port = 48; 2370 non_dma1->num_entries = nports * non_dma1->entries_per_port; 2371 non_dma1->reg = OP_QUEUE_TOTAL_COUNT_CELLr; 2372 non_dma1->mem = INVALIDm; 2373 non_dma1->field = Q_TOTAL_COUNT_CELLf; 2374 non_dma1->cname = "MC_QUEUE_PEAK"; 2375 *non_dma_entries += non_dma1->num_entries; 2376 2377 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT - 2378 SOC_COUNTER_NON_DMA_START]; 2379 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2380 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_CURRENT; 2381 non_dma2->cname = "MC_QUEUE_CUR"; 2382 2383 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK - 2384 SOC_COUNTER_NON_DMA_START]; 2385 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 2386 _SOC_COUNTER_NON_DMA_PEAK | _SOC_COUNTER_NON_DMA_DO_DMA; 2387 non_dma1->pbmp = PBMP_PORT_ALL(unit); 2388 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2389 non_dma1->entries_per_port = 10; 2390 non_dma1->num_entries = soc_mem_index_count(unit, MMU_THDO_COUNTER_QUEUEm); 2391 non_dma1->reg = INVALIDr; 2392 non_dma1->mem = MMU_THDO_COUNTER_QUEUEm; 2393 non_dma1->field = SHARED_COUNTf; 2394 non_dma1->dma_buf[0] = buf; 2395 non_dma1->cname = "UC_QUEUE_PEAK"; 2396 non_dma1->dma_mem[0] = non_dma1->mem; 2397 non_dma1->dma_index_max[0] = non_dma1->num_entries - 1; 2398 *non_dma_entries += non_dma1->num_entries; 2399 2400 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT - 2401 SOC_COUNTER_NON_DMA_START]; 2402 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2403 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2404 _SOC_COUNTER_NON_DMA_CURRENT; 2405 non_dma2->cname = "UC_QUEUE_CUR"; 2406 return SOC_E_NONE; 2407 } 2408 #endif 2409 2410 2411 #ifdef BCM_TRIDENT_SUPPORT 2412 /* 2413 * Function: 2414 * _soc_counter_trident_non_dma_init 2415 * Purpose: 2416 * Initialize Trident's non-DMA counters. 2417 * Parameters: 2418 * unit - The SOC unit number 2419 * nports - Number of ports. 2420 * non_dma_start_index - The starting index of non-DMA counter entries. 2421 * non_dma_entries - (OUT) The number of non-DMA counter entries. 2422 * Returns: 2423 * SOC_E_NONE 2424 * SOC_E_MEMORY 2425 */ 2426 STATIC int 2427 _soc_counter_trident_non_dma_init(int unit, int nports, int non_dma_start_index, 2428 int *non_dma_entries) 2429 { 2430 soc_control_t *soc; 2431 soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2; 2432 int entry_words, num_entries[2], alloc_size, table_size; 2433 uint32 *buf; 2434 2435 soc = SOC_CONTROL(unit); 2436 *non_dma_entries = 0; 2437 2438 soc_trident_get_egr_perq_xmt_counters_size(unit, &num_entries[0], 2439 &num_entries[1]); 2440 entry_words = soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm); 2441 2442 /* EGR_PERQ_XMT_COUNTERS size depends on user's portmap config */ 2443 alloc_size = (num_entries[0] + num_entries[1]) * entry_words * sizeof(uint32); 2444 2445 /* MMU_CTR_UC_DROP_MEM is the largest among MMU_CTR_*_DROP_MEM tables */ 2446 table_size = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) * 2447 soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm) * sizeof(uint32); 2448 if (alloc_size < table_size) { 2449 alloc_size = table_size; 2450 } 2451 2452 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 2453 if (buf == NULL) { 2454 return SOC_E_MEMORY; 2455 } 2456 sal_memset(buf, 0, alloc_size); 2457 2458 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 2459 SOC_COUNTER_NON_DMA_START]; 2460 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2461 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 2462 non_dma0->pbmp = PBMP_ALL(unit); 2463 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2464 non_dma0->entries_per_port = 48; /* cpu port has max number of queues */ 2465 non_dma0->num_entries = num_entries[0] + num_entries[1]; 2466 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 2467 non_dma0->reg = INVALIDr; 2468 non_dma0->field = PACKET_COUNTERf; 2469 non_dma0->cname = "MC_PERQ_PKT"; 2470 non_dma0->dma_buf[0] = buf; 2471 non_dma0->dma_index_max[0] = num_entries[0] - 1; 2472 non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERS_Xm; 2473 #if (SOC_MAX_NUM_PIPES > 1) 2474 non_dma0->dma_buf[1] = &buf[num_entries[0] * entry_words]; 2475 non_dma0->dma_index_max[1] = num_entries[1] - 1; 2476 non_dma0->dma_mem[1] = EGR_PERQ_XMT_COUNTERS_Ym; 2477 #endif 2478 *non_dma_entries += non_dma0->num_entries; 2479 2480 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 2481 SOC_COUNTER_NON_DMA_START]; 2482 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2483 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2484 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2485 non_dma1->field = BYTE_COUNTERf; 2486 non_dma1->cname = "MC_PERQ_BYTE"; 2487 *non_dma_entries += non_dma1->num_entries; 2488 2489 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC - 2490 SOC_COUNTER_NON_DMA_START]; 2491 *non_dma2 = *non_dma0; 2492 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 2493 non_dma2->pbmp = PBMP_PORT_ALL(unit); 2494 non_dma2->entries_per_port = 10; 2495 non_dma2->num_entries = 0; 2496 non_dma2->cname = "UC_PERQ_PKT"; 2497 2498 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC - 2499 SOC_COUNTER_NON_DMA_START]; 2500 *non_dma2 = *non_dma1; 2501 non_dma2->pbmp = PBMP_PORT_ALL(unit); 2502 non_dma2->entries_per_port = 10; 2503 non_dma2->num_entries = 0; 2504 non_dma2->cname = "UC_PERQ_BYTE"; 2505 2506 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT - 2507 SOC_COUNTER_NON_DMA_START]; 2508 *non_dma2 = *non_dma0; 2509 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 2510 non_dma2->pbmp = PBMP_PORT_ALL(unit); 2511 non_dma2->entries_per_port = 64; 2512 non_dma2->num_entries = 0; 2513 non_dma2->cname = "EXT_PERQ_PKT"; 2514 2515 non_dma2 = 2516 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT - 2517 SOC_COUNTER_NON_DMA_START]; 2518 *non_dma2 = *non_dma1; 2519 non_dma2->pbmp = PBMP_PORT_ALL(unit); 2520 non_dma2->entries_per_port = 64; 2521 non_dma2->num_entries = 0; 2522 non_dma2->cname = "EXT_PERQ_BYTE"; 2523 2524 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 2525 SOC_COUNTER_NON_DMA_START]; 2526 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2527 _SOC_COUNTER_NON_DMA_DO_DMA; 2528 non_dma0->pbmp = PBMP_ALL(unit); 2529 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2530 non_dma0->entries_per_port = 48; /* 48 for cpu port */ 2531 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEMm); 2532 non_dma0->mem = MMU_CTR_MC_DROP_MEMm; 2533 non_dma0->reg = INVALIDr; 2534 non_dma0->field = PKT_CNTf; 2535 non_dma0->cname = "MCQ_DROP_PKT"; 2536 non_dma0->dma_buf[0] = buf; 2537 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2538 non_dma0->dma_mem[0] = non_dma0->mem; 2539 *non_dma_entries += non_dma0->num_entries; 2540 2541 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 2542 SOC_COUNTER_NON_DMA_START]; 2543 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2544 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2545 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2546 non_dma1->field = BYTE_COUNTf; 2547 non_dma1->cname = "MCQ_DROP_BYTE"; 2548 *non_dma_entries += non_dma1->num_entries; 2549 2550 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC - 2551 SOC_COUNTER_NON_DMA_START]; 2552 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2553 _SOC_COUNTER_NON_DMA_DO_DMA; 2554 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2555 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2556 non_dma0->entries_per_port = 74; /* 10 ucast + 64 ext ucast */ 2557 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm); 2558 non_dma0->mem = MMU_CTR_UC_DROP_MEMm; 2559 non_dma0->reg = INVALIDr; 2560 non_dma0->field = PKT_CNTf; 2561 non_dma0->cname = "UCQ_DROP_PKT"; 2562 non_dma0->dma_buf[0] = buf; 2563 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 2564 non_dma0->dma_mem[0] = non_dma0->mem; 2565 *non_dma_entries += non_dma0->num_entries; 2566 2567 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC - 2568 SOC_COUNTER_NON_DMA_START]; 2569 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2570 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 2571 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2572 non_dma1->field = BYTE_COUNTf; 2573 non_dma1->cname = "UCQ_DROP_BYTE"; 2574 *non_dma_entries += non_dma1->num_entries; 2575 2576 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 2577 SOC_COUNTER_NON_DMA_START]; 2578 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 2579 non_dma0->pbmp = PBMP_ALL(unit); 2580 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2581 non_dma0->entries_per_port = 1; 2582 non_dma0->num_entries = nports; 2583 non_dma0->mem = INVALIDm; 2584 non_dma0->reg = DROP_PKT_CNT_INGr; 2585 non_dma0->field = COUNTf; 2586 non_dma0->cname = "DROP_PKT_ING"; 2587 *non_dma_entries += non_dma0->num_entries; 2588 2589 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 2590 SOC_COUNTER_NON_DMA_START]; 2591 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2592 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2593 non_dma1->reg = DROP_BYTE_CNT_ING_64r; 2594 non_dma1->cname = "DROP_BYTE_ING"; 2595 *non_dma_entries += non_dma1->num_entries; 2596 2597 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 2598 SOC_COUNTER_NON_DMA_START]; 2599 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2600 _SOC_COUNTER_NON_DMA_DO_DMA; 2601 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2602 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2603 non_dma0->entries_per_port = 1; 2604 non_dma0->num_entries = 66; /* one per port */ 2605 non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm; 2606 non_dma0->reg = INVALIDr; 2607 non_dma0->field = PKT_CNTf; 2608 non_dma0->cname = "DROP_PKT_YEL"; 2609 non_dma0->dma_buf[0] = buf; 2610 non_dma0->dma_index_min[0] = 66 * 4; 2611 non_dma0->dma_index_max[0] = 66 * 4 + 65; 2612 non_dma0->dma_mem[0] = non_dma0->mem; 2613 *non_dma_entries += non_dma0->num_entries; 2614 2615 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 2616 SOC_COUNTER_NON_DMA_START]; 2617 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2618 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2619 non_dma1->cname = "DROP_PKT_RED"; 2620 non_dma1->dma_index_min[0] = 66 * 3; 2621 non_dma1->dma_index_max[0] = 66 * 3 + 65; 2622 *non_dma_entries += non_dma1->num_entries; 2623 2624 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN - 2625 SOC_COUNTER_NON_DMA_START]; 2626 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2627 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2628 non_dma1->cname = "WRED_PKT_GRE"; 2629 non_dma1->dma_index_min[0] = 66 * 2; 2630 non_dma1->dma_index_max[0] = 66 * 2 + 65; 2631 *non_dma_entries += non_dma1->num_entries; 2632 2633 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW - 2634 SOC_COUNTER_NON_DMA_START]; 2635 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2636 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2637 non_dma1->cname = "WRED_PKT_YEL"; 2638 non_dma1->dma_index_min[0] = 66 * 1; 2639 non_dma1->dma_index_max[0] = 66 * 1 + 65; 2640 *non_dma_entries += non_dma1->num_entries; 2641 2642 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED - 2643 SOC_COUNTER_NON_DMA_START]; 2644 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2645 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2646 non_dma1->cname = "WRED_PKT_RED"; 2647 non_dma1->dma_index_min[0] = 0; 2648 non_dma1->dma_index_max[0] = 65; 2649 *non_dma_entries += non_dma1->num_entries; 2650 2651 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK - 2652 SOC_COUNTER_NON_DMA_START]; 2653 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2654 _SOC_COUNTER_NON_DMA_PEAK; 2655 SOC_PBMP_CLEAR(non_dma0->pbmp); 2656 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2657 non_dma0->entries_per_port = 0; 2658 non_dma0->num_entries = 4; 2659 non_dma0->mem = INVALIDm; 2660 non_dma0->reg = TOTAL_BUFFER_COUNT_CELL_SPr; 2661 non_dma0->field = TOTAL_BUFFER_COUNTf; 2662 non_dma0->cname = "POOL_PEAK"; 2663 *non_dma_entries += non_dma0->num_entries; 2664 2665 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT - 2666 SOC_COUNTER_NON_DMA_START]; 2667 sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t)); 2668 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2669 _SOC_COUNTER_NON_DMA_CURRENT; 2670 non_dma2->cname = "POOL_CUR"; 2671 2672 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK - 2673 SOC_COUNTER_NON_DMA_START]; 2674 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2675 _SOC_COUNTER_NON_DMA_PEAK; 2676 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2677 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2678 non_dma0->entries_per_port = 8; 2679 non_dma0->num_entries = nports * non_dma0->entries_per_port; 2680 non_dma0->mem = INVALIDm; 2681 non_dma0->reg = PG_MIN_COUNT_CELLr; 2682 non_dma0->field = PG_MIN_COUNTf; 2683 non_dma0->cname = "PG_MIN_PEAK"; 2684 *non_dma_entries += non_dma0->num_entries; 2685 2686 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT - 2687 SOC_COUNTER_NON_DMA_START]; 2688 sal_memcpy(non_dma2, non_dma0, sizeof(soc_counter_non_dma_t)); 2689 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2690 _SOC_COUNTER_NON_DMA_CURRENT; 2691 non_dma2->cname = "PG_MIN_CUR"; 2692 2693 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK - 2694 SOC_COUNTER_NON_DMA_START]; 2695 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2696 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2697 non_dma1->reg = PG_SHARED_COUNT_CELLr; 2698 non_dma1->field = PG_SHARED_COUNTf; 2699 non_dma1->cname = "PG_SHARED_PEAK"; 2700 *non_dma_entries += non_dma1->num_entries; 2701 2702 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT - 2703 SOC_COUNTER_NON_DMA_START]; 2704 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2705 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2706 _SOC_COUNTER_NON_DMA_CURRENT; 2707 non_dma2->cname = "PG_SHARED_CUR"; 2708 2709 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK - 2710 SOC_COUNTER_NON_DMA_START]; 2711 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2712 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2713 non_dma1->reg = PG_HDRM_COUNT_CELLr; 2714 non_dma1->field = PG_HDRM_COUNTf; 2715 non_dma1->cname = "PG_HDRM_PEAK"; 2716 *non_dma_entries += non_dma1->num_entries; 2717 2718 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT - 2719 SOC_COUNTER_NON_DMA_START]; 2720 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2721 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2722 _SOC_COUNTER_NON_DMA_CURRENT; 2723 non_dma2->cname = "PG_HDRM_CUR"; 2724 2725 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK - 2726 SOC_COUNTER_NON_DMA_START]; 2727 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2728 non_dma1->pbmp = PBMP_ALL(unit); 2729 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2730 non_dma1->entries_per_port = 5; 2731 non_dma1->num_entries = nports * non_dma0->entries_per_port; 2732 non_dma1->reg = OP_QUEUE_TOTAL_COUNT_CELLr; 2733 non_dma1->field = Q_TOTAL_COUNT_CELLf; 2734 non_dma1->cname = "MC_QUEUE_PEAK"; 2735 *non_dma_entries += non_dma1->num_entries; 2736 2737 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT - 2738 SOC_COUNTER_NON_DMA_START]; 2739 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2740 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2741 _SOC_COUNTER_NON_DMA_CURRENT; 2742 non_dma2->cname = "MC_QUEUE_CUR"; 2743 2744 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK - 2745 SOC_COUNTER_NON_DMA_START]; 2746 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2747 non_dma1->pbmp = PBMP_PORT_ALL(unit); 2748 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2749 non_dma1->entries_per_port = 10; 2750 non_dma1->num_entries = nports * non_dma1->entries_per_port; 2751 non_dma1->reg = OP_UC_QUEUE_TOTAL_COUNT_CELLr; 2752 non_dma1->field = Q_TOTAL_COUNT_CELLf; 2753 non_dma1->cname = "UC_QUEUE_PEAK"; 2754 *non_dma_entries += non_dma1->num_entries; 2755 2756 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT - 2757 SOC_COUNTER_NON_DMA_START]; 2758 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2759 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2760 _SOC_COUNTER_NON_DMA_CURRENT; 2761 non_dma2->cname = "UC_QUEUE_CUR"; 2762 2763 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EXT_QUEUE_PEAK - 2764 SOC_COUNTER_NON_DMA_START]; 2765 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 2766 non_dma1->pbmp = PBMP_EQ(unit); 2767 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 2768 non_dma1->entries_per_port = 64; 2769 non_dma1->num_entries = nports * non_dma1->entries_per_port; 2770 non_dma1->reg = OP_EX_QUEUE_TOTAL_COUNT_CELLr; 2771 non_dma1->cname = "EXT_QUEUE_PEAK"; 2772 non_dma1->field = Q_TOTAL_COUNT_CELLf; 2773 *non_dma_entries += non_dma1->num_entries; 2774 2775 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EXT_QUEUE_CURRENT - 2776 SOC_COUNTER_NON_DMA_START]; 2777 sal_memcpy(non_dma2, non_dma1, sizeof(soc_counter_non_dma_t)); 2778 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 2779 _SOC_COUNTER_NON_DMA_CURRENT; 2780 non_dma2->cname = "EXT_QUEUE_CUR"; 2781 2782 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM - 2783 SOC_COUNTER_NON_DMA_START]; 2784 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 2785 _SOC_COUNTER_NON_DMA_DO_DMA; 2786 non_dma0->pbmp = PBMP_PORT_ALL(unit); 2787 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 2788 non_dma0->entries_per_port = 2; 2789 non_dma0->num_entries = soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm); 2790 non_dma0->mem = MMU_QCN_CNM_COUNTERm; 2791 non_dma0->reg = INVALIDr; 2792 non_dma0->field = CNM_CNTf; 2793 non_dma0->cname = "QCN_CNM_COUNTER"; 2794 non_dma0->dma_buf[0] = buf; 2795 non_dma0->dma_mem[0] = non_dma0->mem; 2796 non_dma0->dma_index_min[0] = 0; 2797 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 2798 *non_dma_entries += non_dma0->num_entries; 2799 2800 return SOC_E_NONE; 2801 } 2802 #endif /* BCM_TRIDENT_SUPPORT */ 2803 2804 #if defined (BCM_MONTEREY_SUPPORT) 2805 /* Function to initialize extra counters for monterey*/ 2806 STATIC int 2807 soc_counter_monterey_extra_obm_ctrs_init(int unit, 2808 soc_counter_non_dma_t *non_dma_parent, 2809 soc_counter_non_dma_t *non_dma_extra, 2810 uint32 extra_ctr_ct, 2811 int *total_entries) 2812 { 2813 #define LOSSY_LO 0 2814 #define LOSSY_HI 1 2815 #define LOSSLESS0 2 2816 #define LOSSLESS1 3 2817 #define EXPRESS 4 2818 2819 #define COUNTER_TYPE_DROP 0 2820 #define COUNTER_TYPE_ENQUEUE 1 2821 char obm_type_str[][12] = {"LOSSY_LO", "LOSSY_HI", 2822 "LOSSLESS0", "LOSSLESS1", "EXPRESS"}; 2823 char obm_ctr_type_str[][10] = {"DROP", "ENQUEUE"}; 2824 int i, byte_flag = 0, obm_type = LOSSY_LO, parent_base_index = 0; 2825 int counter_type = COUNTER_TYPE_DROP; 2826 uint32 count = 0; 2827 2828 soc_reg_t obm_drop_pkt_regs[][2][5] = { 2829 { 2830 {IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr, 2831 IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr, 2832 IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr, 2833 IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr, 2834 IDB_OBM0_EXPRESS_PKT_DROP_COUNTr}, 2835 2836 {IDB_OBM0_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2837 IDB_OBM0_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2838 IDB_OBM0_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2839 IDB_OBM0_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2840 IDB_OBM0_EXPRESS_ARRIVAL_PKT_COUNTr} 2841 }, 2842 { 2843 {IDB_OBM1_LOSSY_LO_PKT_DROP_COUNTr, 2844 IDB_OBM1_LOSSY_HI_PKT_DROP_COUNTr, 2845 IDB_OBM1_LOSSLESS0_PKT_DROP_COUNTr, 2846 IDB_OBM1_LOSSLESS1_PKT_DROP_COUNTr, 2847 IDB_OBM1_EXPRESS_PKT_DROP_COUNTr}, 2848 2849 {IDB_OBM1_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2850 IDB_OBM1_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2851 IDB_OBM1_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2852 IDB_OBM1_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2853 IDB_OBM1_EXPRESS_ARRIVAL_PKT_COUNTr} 2854 }, 2855 { 2856 {IDB_OBM2_LOSSY_LO_PKT_DROP_COUNTr, 2857 IDB_OBM2_LOSSY_HI_PKT_DROP_COUNTr, 2858 IDB_OBM2_LOSSLESS0_PKT_DROP_COUNTr, 2859 IDB_OBM2_LOSSLESS1_PKT_DROP_COUNTr, 2860 IDB_OBM2_EXPRESS_PKT_DROP_COUNTr}, 2861 2862 {IDB_OBM2_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2863 IDB_OBM2_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2864 IDB_OBM2_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2865 IDB_OBM2_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2866 IDB_OBM2_EXPRESS_ARRIVAL_PKT_COUNTr} 2867 }, 2868 { 2869 {IDB_OBM3_LOSSY_LO_PKT_DROP_COUNTr, 2870 IDB_OBM3_LOSSY_HI_PKT_DROP_COUNTr, 2871 IDB_OBM3_LOSSLESS0_PKT_DROP_COUNTr, 2872 IDB_OBM3_LOSSLESS1_PKT_DROP_COUNTr, 2873 IDB_OBM3_EXPRESS_PKT_DROP_COUNTr}, 2874 2875 {IDB_OBM3_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2876 IDB_OBM3_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2877 IDB_OBM3_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2878 IDB_OBM3_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2879 IDB_OBM3_EXPRESS_ARRIVAL_PKT_COUNTr} 2880 }, 2881 { 2882 {IDB_OBM4_LOSSY_LO_PKT_DROP_COUNTr, 2883 IDB_OBM4_LOSSY_HI_PKT_DROP_COUNTr, 2884 IDB_OBM4_LOSSLESS0_PKT_DROP_COUNTr, 2885 IDB_OBM4_LOSSLESS1_PKT_DROP_COUNTr, 2886 IDB_OBM4_EXPRESS_PKT_DROP_COUNTr}, 2887 2888 {IDB_OBM4_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2889 IDB_OBM4_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2890 IDB_OBM4_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2891 IDB_OBM4_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2892 IDB_OBM4_EXPRESS_ARRIVAL_PKT_COUNTr} 2893 }, 2894 { 2895 {IDB_OBM5_LOSSY_LO_PKT_DROP_COUNTr, 2896 IDB_OBM5_LOSSY_HI_PKT_DROP_COUNTr, 2897 IDB_OBM5_LOSSLESS0_PKT_DROP_COUNTr, 2898 IDB_OBM5_LOSSLESS1_PKT_DROP_COUNTr, 2899 IDB_OBM5_EXPRESS_PKT_DROP_COUNTr}, 2900 2901 {IDB_OBM5_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2902 IDB_OBM5_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2903 IDB_OBM5_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2904 IDB_OBM5_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2905 IDB_OBM5_EXPRESS_ARRIVAL_PKT_COUNTr} 2906 }, 2907 { 2908 {IDB_OBM6_LOSSY_LO_PKT_DROP_COUNTr, 2909 IDB_OBM6_LOSSY_HI_PKT_DROP_COUNTr, 2910 IDB_OBM6_LOSSLESS0_PKT_DROP_COUNTr, 2911 IDB_OBM6_LOSSLESS1_PKT_DROP_COUNTr, 2912 IDB_OBM6_EXPRESS_PKT_DROP_COUNTr}, 2913 2914 {IDB_OBM6_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2915 IDB_OBM6_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2916 IDB_OBM6_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2917 IDB_OBM6_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2918 IDB_OBM6_EXPRESS_ARRIVAL_PKT_COUNTr} 2919 }, 2920 { 2921 {IDB_OBM7_LOSSY_LO_PKT_DROP_COUNTr, 2922 IDB_OBM7_LOSSY_HI_PKT_DROP_COUNTr, 2923 IDB_OBM7_LOSSLESS0_PKT_DROP_COUNTr, 2924 IDB_OBM7_LOSSLESS1_PKT_DROP_COUNTr, 2925 IDB_OBM7_EXPRESS_PKT_DROP_COUNTr}, 2926 2927 {IDB_OBM7_LOSSY_LO_ARRIVAL_PKT_COUNTr, 2928 IDB_OBM7_LOSSY_HI_ARRIVAL_PKT_COUNTr, 2929 IDB_OBM7_LOSSLESS0_ARRIVAL_PKT_COUNTr, 2930 IDB_OBM7_LOSSLESS1_ARRIVAL_PKT_COUNTr, 2931 IDB_OBM7_EXPRESS_ARRIVAL_PKT_COUNTr} 2932 } 2933 }; 2934 soc_reg_t obm_drop_byte_regs[][2][5] = { 2935 { 2936 {IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr, 2937 IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr, 2938 IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr, 2939 IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr, 2940 IDB_OBM0_EXPRESS_BYTE_DROP_COUNTr}, 2941 2942 {IDB_OBM0_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 2943 IDB_OBM0_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 2944 IDB_OBM0_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 2945 IDB_OBM0_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 2946 IDB_OBM0_EXPRESS_ARRIVAL_BYTE_COUNTr} 2947 }, 2948 { 2949 {IDB_OBM1_LOSSY_LO_BYTE_DROP_COUNTr, 2950 IDB_OBM1_LOSSY_HI_BYTE_DROP_COUNTr, 2951 IDB_OBM1_LOSSLESS0_BYTE_DROP_COUNTr, 2952 IDB_OBM1_LOSSLESS1_BYTE_DROP_COUNTr, 2953 IDB_OBM1_EXPRESS_BYTE_DROP_COUNTr}, 2954 2955 {IDB_OBM1_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 2956 IDB_OBM1_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 2957 IDB_OBM1_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 2958 IDB_OBM1_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 2959 IDB_OBM1_EXPRESS_ARRIVAL_BYTE_COUNTr} 2960 }, 2961 { 2962 {IDB_OBM2_LOSSY_LO_BYTE_DROP_COUNTr, 2963 IDB_OBM2_LOSSY_HI_BYTE_DROP_COUNTr, 2964 IDB_OBM2_LOSSLESS0_BYTE_DROP_COUNTr, 2965 IDB_OBM2_LOSSLESS1_BYTE_DROP_COUNTr, 2966 IDB_OBM2_EXPRESS_BYTE_DROP_COUNTr}, 2967 2968 {IDB_OBM2_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 2969 IDB_OBM2_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 2970 IDB_OBM2_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 2971 IDB_OBM2_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 2972 IDB_OBM2_EXPRESS_ARRIVAL_BYTE_COUNTr} 2973 }, 2974 { 2975 {IDB_OBM3_LOSSY_LO_BYTE_DROP_COUNTr, 2976 IDB_OBM3_LOSSY_HI_BYTE_DROP_COUNTr, 2977 IDB_OBM3_LOSSLESS0_BYTE_DROP_COUNTr, 2978 IDB_OBM3_LOSSLESS1_BYTE_DROP_COUNTr, 2979 IDB_OBM3_EXPRESS_BYTE_DROP_COUNTr}, 2980 2981 {IDB_OBM3_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 2982 IDB_OBM3_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 2983 IDB_OBM3_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 2984 IDB_OBM3_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 2985 IDB_OBM3_EXPRESS_ARRIVAL_BYTE_COUNTr} 2986 }, 2987 { 2988 {IDB_OBM4_LOSSY_LO_BYTE_DROP_COUNTr, 2989 IDB_OBM4_LOSSY_HI_BYTE_DROP_COUNTr, 2990 IDB_OBM4_LOSSLESS0_BYTE_DROP_COUNTr, 2991 IDB_OBM4_LOSSLESS1_BYTE_DROP_COUNTr, 2992 IDB_OBM4_EXPRESS_BYTE_DROP_COUNTr}, 2993 2994 {IDB_OBM4_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 2995 IDB_OBM4_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 2996 IDB_OBM4_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 2997 IDB_OBM4_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 2998 IDB_OBM4_EXPRESS_ARRIVAL_BYTE_COUNTr} 2999 }, 3000 { 3001 {IDB_OBM5_LOSSY_LO_BYTE_DROP_COUNTr, 3002 IDB_OBM5_LOSSY_HI_BYTE_DROP_COUNTr, 3003 IDB_OBM5_LOSSLESS0_BYTE_DROP_COUNTr, 3004 IDB_OBM5_LOSSLESS1_BYTE_DROP_COUNTr, 3005 IDB_OBM5_EXPRESS_BYTE_DROP_COUNTr}, 3006 3007 {IDB_OBM5_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 3008 IDB_OBM5_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 3009 IDB_OBM5_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 3010 IDB_OBM5_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 3011 IDB_OBM5_EXPRESS_ARRIVAL_BYTE_COUNTr} 3012 }, 3013 { 3014 {IDB_OBM6_LOSSY_LO_BYTE_DROP_COUNTr, 3015 IDB_OBM6_LOSSY_HI_BYTE_DROP_COUNTr, 3016 IDB_OBM6_LOSSLESS0_BYTE_DROP_COUNTr, 3017 IDB_OBM6_LOSSLESS1_BYTE_DROP_COUNTr, 3018 IDB_OBM6_EXPRESS_BYTE_DROP_COUNTr}, 3019 3020 {IDB_OBM6_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 3021 IDB_OBM6_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 3022 IDB_OBM6_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 3023 IDB_OBM6_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 3024 IDB_OBM6_EXPRESS_ARRIVAL_BYTE_COUNTr} 3025 }, 3026 { 3027 {IDB_OBM7_LOSSY_LO_BYTE_DROP_COUNTr, 3028 IDB_OBM7_LOSSY_HI_BYTE_DROP_COUNTr, 3029 IDB_OBM7_LOSSLESS0_BYTE_DROP_COUNTr, 3030 IDB_OBM7_LOSSLESS1_BYTE_DROP_COUNTr, 3031 IDB_OBM7_EXPRESS_BYTE_DROP_COUNTr}, 3032 3033 {IDB_OBM7_LOSSY_LO_ARRIVAL_BYTE_COUNTr, 3034 IDB_OBM7_LOSSY_HI_ARRIVAL_BYTE_COUNTr, 3035 IDB_OBM7_LOSSLESS0_ARRIVAL_BYTE_COUNTr, 3036 IDB_OBM7_LOSSLESS1_ARRIVAL_BYTE_COUNTr, 3037 IDB_OBM7_EXPRESS_ARRIVAL_BYTE_COUNTr} 3038 } 3039 }; 3040 count = COUNTOF(obm_drop_byte_regs); 3041 if (count > extra_ctr_ct) { 3042 return SOC_E_PARAM; 3043 } 3044 3045 /* Do sanity check for input params */ 3046 if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 3047 return SOC_E_PARAM; 3048 } 3049 switch (non_dma_parent->id) { 3050 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 3051 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 3052 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 3053 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 3054 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS: 3055 byte_flag = 0; 3056 counter_type = COUNTER_TYPE_DROP; 3057 break; 3058 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0: 3059 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1: 3060 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO: 3061 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI: 3062 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS: 3063 byte_flag = 0; 3064 counter_type = COUNTER_TYPE_ENQUEUE; 3065 break; 3066 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 3067 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 3068 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 3069 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 3070 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS: 3071 byte_flag = 1; 3072 counter_type = COUNTER_TYPE_DROP; 3073 break; 3074 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0: 3075 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1: 3076 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO: 3077 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI: 3078 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS: 3079 byte_flag = 1; 3080 counter_type = COUNTER_TYPE_ENQUEUE; 3081 break; 3082 default: 3083 return SOC_E_PARAM; 3084 } 3085 3086 switch (non_dma_parent->id) { 3087 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 3088 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 3089 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO: 3090 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO: 3091 obm_type = LOSSY_LO; 3092 break; 3093 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 3094 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 3095 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI: 3096 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI: 3097 obm_type = LOSSY_HI; 3098 break; 3099 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 3100 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 3101 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0: 3102 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0: 3103 obm_type = LOSSLESS0; 3104 break; 3105 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 3106 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 3107 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1: 3108 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1: 3109 obm_type = LOSSLESS1; 3110 break; 3111 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS: 3112 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS: 3113 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS: 3114 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS: 3115 obm_type = EXPRESS; 3116 break; 3117 } 3118 3119 parent_base_index = non_dma_parent->base_index; 3120 *total_entries = 0; 3121 3122 for (i = 0; i < extra_ctr_ct; i++) { 3123 *non_dma_extra = *non_dma_parent; 3124 if (byte_flag == 0) { 3125 non_dma_extra->reg = obm_drop_pkt_regs[i][counter_type][obm_type]; 3126 } else { 3127 non_dma_extra->reg = obm_drop_byte_regs[i][counter_type][obm_type]; 3128 } 3129 non_dma_extra->extra_ctrs = NULL; 3130 non_dma_extra->extra_ctr_ct = 0; 3131 non_dma_extra->base_index = parent_base_index + *total_entries; 3132 non_dma_extra->flags = (non_dma_parent->flags & 3133 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) | 3134 _SOC_COUNTER_NON_DMA_SUBSET_CHILD; 3135 3136 non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9, 3137 "Extra ctrs cname"); 3138 3139 if (non_dma_extra->cname == NULL) { 3140 return SOC_E_MEMORY; 3141 } 3142 3143 sal_sprintf(non_dma_extra->cname, "*OBM%d_%s_%s_%s", 3144 i, obm_type_str[obm_type], 3145 obm_ctr_type_str[counter_type], 3146 byte_flag ? "BYTE":"PKT"); 3147 3148 non_dma_extra->num_entries = non_dma_extra->entries_per_port; 3149 *total_entries += non_dma_extra->num_entries; 3150 3151 non_dma_extra += 2; 3152 } 3153 return SOC_E_NONE; 3154 } 3155 #endif /* BCM_MONTEREY_SUPPORT */ 3156 3157 #if defined (BCM_APACHE_SUPPORT) 3158 /* Function to initialize extra counters */ 3159 STATIC int 3160 soc_counter_apache_extra_obm_ctrs_init(int unit, 3161 soc_counter_non_dma_t *non_dma_parent, 3162 soc_counter_non_dma_t *non_dma_extra, 3163 uint32 extra_ctr_ct, 3164 int *total_entries) 3165 { 3166 #define LOSSY_LO 0 3167 #define LOSSY_HI 1 3168 #define LOSSLESS0 2 3169 #define LOSSLESS1 3 3170 char obm_type_str[][12] = {"LOSSY_LO", "LOSSY_HI", 3171 "LOSSLESS0", "LOSSLESS1"}; /* For CNAME */ 3172 int i, byte_flag = 0, obm_type = 0, parent_base_index = 0; 3173 uint32 count = 0; 3174 3175 soc_reg_t obm_drop_pkt_regs[][4] = { 3176 {IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr, 3177 IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr 3178 }, 3179 {IDB_OBM1_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM1_LOSSY_HI_PKT_DROP_COUNTr, 3180 IDB_OBM1_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM1_LOSSLESS1_PKT_DROP_COUNTr 3181 }, 3182 {IDB_OBM2_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM2_LOSSY_HI_PKT_DROP_COUNTr, 3183 IDB_OBM2_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM2_LOSSLESS1_PKT_DROP_COUNTr 3184 }, 3185 {IDB_OBM3_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM3_LOSSY_HI_PKT_DROP_COUNTr, 3186 IDB_OBM3_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM3_LOSSLESS1_PKT_DROP_COUNTr 3187 }, 3188 {IDB_OBM4_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM4_LOSSY_HI_PKT_DROP_COUNTr, 3189 IDB_OBM4_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM4_LOSSLESS1_PKT_DROP_COUNTr 3190 }, 3191 {IDB_OBM5_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM5_LOSSY_HI_PKT_DROP_COUNTr, 3192 IDB_OBM5_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM5_LOSSLESS1_PKT_DROP_COUNTr 3193 }, 3194 {IDB_OBM6_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM6_LOSSY_HI_PKT_DROP_COUNTr, 3195 IDB_OBM6_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM6_LOSSLESS1_PKT_DROP_COUNTr 3196 }, 3197 {IDB_OBM7_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM7_LOSSY_HI_PKT_DROP_COUNTr, 3198 IDB_OBM7_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM7_LOSSLESS1_PKT_DROP_COUNTr 3199 }, 3200 {IDB_OBM8_LOSSY_LO_PKT_DROP_COUNTr, IDB_OBM8_LOSSY_HI_PKT_DROP_COUNTr, 3201 IDB_OBM8_LOSSLESS0_PKT_DROP_COUNTr, IDB_OBM8_LOSSLESS1_PKT_DROP_COUNTr 3202 }, 3203 }; 3204 soc_reg_t obm_drop_byte_regs[][4] = { 3205 {IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr, 3206 IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr 3207 }, 3208 {IDB_OBM1_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM1_LOSSY_HI_BYTE_DROP_COUNTr, 3209 IDB_OBM1_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM1_LOSSLESS1_BYTE_DROP_COUNTr 3210 }, 3211 {IDB_OBM2_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM2_LOSSY_HI_BYTE_DROP_COUNTr, 3212 IDB_OBM2_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM2_LOSSLESS1_BYTE_DROP_COUNTr 3213 }, 3214 {IDB_OBM3_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM3_LOSSY_HI_BYTE_DROP_COUNTr, 3215 IDB_OBM3_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM3_LOSSLESS1_BYTE_DROP_COUNTr 3216 }, 3217 {IDB_OBM4_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM4_LOSSY_HI_BYTE_DROP_COUNTr, 3218 IDB_OBM4_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM4_LOSSLESS1_BYTE_DROP_COUNTr 3219 }, 3220 {IDB_OBM5_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM5_LOSSY_HI_BYTE_DROP_COUNTr, 3221 IDB_OBM5_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM5_LOSSLESS1_BYTE_DROP_COUNTr 3222 }, 3223 {IDB_OBM6_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM6_LOSSY_HI_BYTE_DROP_COUNTr, 3224 IDB_OBM6_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM6_LOSSLESS1_BYTE_DROP_COUNTr 3225 }, 3226 {IDB_OBM7_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM7_LOSSY_HI_BYTE_DROP_COUNTr, 3227 IDB_OBM7_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM7_LOSSLESS1_BYTE_DROP_COUNTr 3228 }, 3229 {IDB_OBM8_LOSSY_LO_BYTE_DROP_COUNTr, IDB_OBM8_LOSSY_HI_BYTE_DROP_COUNTr, 3230 IDB_OBM8_LOSSLESS0_BYTE_DROP_COUNTr, IDB_OBM8_LOSSLESS1_BYTE_DROP_COUNTr 3231 }, 3232 }; 3233 3234 count = COUNTOF(obm_drop_byte_regs); 3235 if (count > extra_ctr_ct) { 3236 return SOC_E_PARAM; 3237 } 3238 3239 /* Do sanity check for input params */ 3240 if (!(non_dma_parent->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 3241 /* Only for Extra counters */ 3242 return SOC_E_PARAM; 3243 } 3244 switch (non_dma_parent->id) { 3245 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 3246 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 3247 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 3248 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 3249 byte_flag = 0; 3250 break; 3251 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 3252 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 3253 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 3254 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 3255 byte_flag = 1; 3256 break; 3257 default: 3258 return SOC_E_PARAM; 3259 } 3260 3261 switch (non_dma_parent->id) { 3262 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 3263 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 3264 obm_type = LOSSY_LO; 3265 break; 3266 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 3267 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 3268 obm_type = LOSSY_HI; 3269 break; 3270 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 3271 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 3272 obm_type = LOSSLESS0; 3273 break; 3274 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 3275 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 3276 obm_type = LOSSLESS1; 3277 break; 3278 } 3279 3280 parent_base_index = non_dma_parent->base_index; 3281 *total_entries = 0; 3282 3283 for (i = 0; i < extra_ctr_ct; i++) { 3284 *non_dma_extra = *non_dma_parent; 3285 if (byte_flag == 0) { 3286 non_dma_extra->reg = obm_drop_pkt_regs[i][obm_type]; 3287 } else { 3288 non_dma_extra->reg = obm_drop_byte_regs[i][obm_type]; 3289 } 3290 non_dma_extra->extra_ctrs = NULL; 3291 non_dma_extra->extra_ctr_ct = 0; 3292 non_dma_extra->base_index = parent_base_index + *total_entries; 3293 non_dma_extra->flags = (non_dma_parent->flags & 3294 ~_SOC_COUNTER_NON_DMA_SUBSET_PARENT) | 3295 _SOC_COUNTER_NON_DMA_SUBSET_CHILD; 3296 3297 non_dma_extra->cname = sal_alloc(sal_strlen(non_dma_parent->cname) + 9, 3298 "Extra ctrs cname"); 3299 3300 if (non_dma_extra->cname == NULL) { 3301 return SOC_E_MEMORY; 3302 } 3303 3304 sal_sprintf(non_dma_extra->cname, "*OBM%d_%s_DRP_%s", 3305 i, obm_type_str[obm_type], byte_flag ? "BYTE":"PKT"); 3306 3307 non_dma_extra->num_entries = non_dma_extra->entries_per_port; 3308 *total_entries += non_dma_extra->num_entries; 3309 3310 /* Allocation of Child Control blocks. 3311 * [0],..<even indices> - PKT_CTR non_dma ctrl block 3312 * [1],..<odd indices> - BYTE_CTR non_dma ctrl block 3313 * Hence in below code, jump by 2, so all similar control blocks are 3314 * initilized at the same time. 3315 */ 3316 non_dma_extra += 2; 3317 /* coverity[check_after_deref] */ 3318 if (!non_dma_extra) { 3319 /* ERR: Cannot be NULL, until 'i reaches 'extra_ctr_ct' */ 3320 /* This condition may not hit but intentional for defensive check */ 3321 /* coverity[dead_error_line] */ 3322 return SOC_E_INTERNAL; 3323 } 3324 } 3325 return SOC_E_NONE; 3326 } 3327 3328 STATIC int 3329 soc_counter_common_extra_obm_ctrs_init(int unit, 3330 soc_counter_non_dma_t *non_dma_parent, 3331 soc_counter_non_dma_t *non_dma_extra, 3332 uint32 extra_ctr_ct, 3333 int *total_entries) 3334 { 3335 #if defined(BCM_MONTEREY_SUPPORT) 3336 if (SOC_IS_MONTEREY(unit)) { 3337 return soc_counter_monterey_extra_obm_ctrs_init(unit, 3338 non_dma_parent, 3339 non_dma_extra, 3340 extra_ctr_ct, 3341 total_entries); 3342 } 3343 #endif 3344 return soc_counter_apache_extra_obm_ctrs_init(unit, 3345 non_dma_parent, 3346 non_dma_extra, 3347 extra_ctr_ct, 3348 total_entries); 3349 } 3350 3351 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT) 3352 STATIC int 3353 _soc_counter_monterey_non_dma_cpri_init(int unit, int nports, 3354 int non_dma_start_index, 3355 int *non_dma_entries) 3356 { 3357 soc_control_t *soc; 3358 soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2; 3359 *non_dma_entries = 0; 3360 3361 soc = SOC_CONTROL(unit); 3362 3363 /* 3364 * Adding CPRI counter information to the non dma info 3365 * Although CPRI counters are DMA'able, it is inefficient 3366 * because for DMA'ing the counters should be seperated by 3367 * the same offset, else descriptors need to be created 3368 * for each set of counters. There are only a few CPRI 3369 * so not using dma. 3370 * All the CPRI counters are 3371 * 1. Read Only 3372 * 2. Clear on Read 3373 * 3. Saturate on Overflow 3374 */ 3375 3376 3377 /* 3378 * symbol error counter that increments upon detecting symbol 3379 * error (due to invalid symbol or disparity error) 3380 */ 3381 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_SYMBOL_ERR - 3382 SOC_COUNTER_NON_DMA_START]; 3383 3384 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 3385 _SOC_COUNTER_NON_DMA_READ_ONLY | 3386 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ | 3387 _SOC_COUNTER_NON_DMA_SATURATE_ON_OVERFLOW; 3388 3389 SOC_PBMP_CLEAR(non_dma0->pbmp); 3390 non_dma0->pbmp = PBMP_CPRI_ALL(unit); 3391 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3392 non_dma0->entries_per_port = 1; 3393 non_dma0->num_entries = nports; 3394 non_dma0->mem = INVALIDm; 3395 non_dma0->reg = CPRI_RXPCS_0_CNTR_STATUSr; 3396 non_dma0->field = RXPCS_BER_COUNTf; 3397 non_dma0->cname = "CPRI_RX_SYMBOL_ERR"; 3398 *non_dma_entries += non_dma0->num_entries; 3399 3400 /* 3401 * Counts the number of seed vector mismatches. It increments 3402 * if the seed vector of the current hyperframe does not match 3403 * the sts_rxpcs_seed_vector value. 3404 */ 3405 non_dma1 = 3406 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_SEED_VECTOR_MISMATCH - 3407 SOC_COUNTER_NON_DMA_START]; 3408 3409 *non_dma1 = *non_dma0; 3410 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3411 non_dma1->reg = CPRI_RXPCS_1_CNTR_STATUSr; 3412 non_dma1->field = RXPCS_SEED_MISMATCH_CNTf; 3413 non_dma1->cname = "CPRI_RX_SEED_MISMATCH"; 3414 *non_dma_entries += non_dma1->num_entries; 3415 3416 3417 /* Count number of state transitions into the error state */ 3418 non_dma1 = 3419 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_CPRI_RX_STATE_TRANSITION_ERR - 3420 SOC_COUNTER_NON_DMA_START]; 3421 3422 *non_dma1 = *non_dma0; 3423 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3424 non_dma1->reg = CPRI_RXPCS_2_CNTR_STATUSr; 3425 non_dma1->field = RXPCS_64B66B_ERR_HF_CNTf; 3426 non_dma1->cname = "CPRI_RX_STATE_TRANSITION_ERR"; 3427 *non_dma_entries += non_dma1->num_entries; 3428 3429 /* 3430 * VSD Control Packet 3431 * Packet count with Flow-Id out of range(0-127) 3432 */ 3433 non_dma1 = &soc->counter_non_dma[ 3434 SOC_COUNTER_NON_DMA_CPRI_TX_VSD_CTRL_PKT_FLOW_ID_ERR - 3435 SOC_COUNTER_NON_DMA_START]; 3436 3437 *non_dma1 = *non_dma0; 3438 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3439 non_dma1->reg = CPRI_TXFRM_CWA_VSD_CTRL_PACKET_SIZE_ERR_STATUSr; 3440 non_dma1->field = TX_CWA_VSD_CTRL_PACKET_FLOW_ID_ERR_CNTf; 3441 non_dma1->cname = "CPRI_TX_VSD_CTRL_FLOW_ID_ERR"; 3442 *non_dma_entries += non_dma1->num_entries; 3443 3444 /* 3445 * VSD Control Packet 3446 * Counts the number of packets with packet size error. 3447 * Packet is longer than 16 bytes (1 decap data word). 3448 */ 3449 non_dma2 = &soc->counter_non_dma[ 3450 SOC_COUNTER_NON_DMA_CPRI_TX_VSD_CTRL_PKT_SIZE_ERR - 3451 SOC_COUNTER_NON_DMA_START]; 3452 3453 *non_dma2 = *non_dma1; 3454 non_dma2->base_index = non_dma_start_index + *non_dma_entries; 3455 non_dma2->field = TX_CWA_VSD_CTRL_PACKET_SIZE_ERR_CNTf; 3456 non_dma2->cname = "CPRI_TX_VSD_CTRL_PKT_SIZE_ERR"; 3457 *non_dma_entries += non_dma2->num_entries; 3458 3459 /* 3460 * VSD Raw Packet 3461 * Counts the number of packets with packet size error. 3462 * Either packet is too short and ended before HF end, or 3463 * packet is too long and extends past HF end. 3464 */ 3465 non_dma1 = &soc->counter_non_dma[ 3466 SOC_COUNTER_NON_DMA_CPRI_TX_VSD_RAW_PKT_SIZE_ERR - 3467 SOC_COUNTER_NON_DMA_START]; 3468 3469 *non_dma1 = *non_dma0; 3470 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3471 non_dma1->reg = CPRI_TXFRM_CWA_VSD_RAW_PACKET_SIZE_ERR_STATUSr; 3472 non_dma1->field = TX_CWA_VSD_RAW_PACKET_SIZE_ERR_CNTf; 3473 non_dma1->cname = "CPRI_TX_VSD_RAW_PKT_SIZE_ERR"; 3474 *non_dma_entries += non_dma1->num_entries; 3475 3476 /* 3477 * Counts the number of packets dropped by RSVD5 due to CRC error. 3478 */ 3479 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_RSVD5_TX_DROP_CRC_ERR - 3480 SOC_COUNTER_NON_DMA_START]; 3481 3482 *non_dma1 = *non_dma0; 3483 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3484 non_dma1->reg = BRCM_RESERVED_CPM_1r; 3485 non_dma1->field = BRCM_RESERVED_CPM_1_1f; 3486 non_dma1->cname = "CPRI_TX_RSVD5_DROP_CRC_ERR"; 3487 *non_dma_entries += non_dma1->num_entries; 3488 3489 /* 3490 * Counts the number of single message control streams 3491 * dropped due to bad CRC. 3492 */ 3493 non_dma1 = &soc->counter_non_dma[ 3494 SOC_COUNTER_NON_DMA_RSVD4_RX_SINGLE_MSG_DROP_CRC_ERR - 3495 SOC_COUNTER_NON_DMA_START]; 3496 3497 *non_dma1 = *non_dma0; 3498 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3499 non_dma1->reg = BRCM_RESERVED_CPM_323r; 3500 non_dma1->field = BRCM_RESERVED_CPM_323_0f; 3501 non_dma1->cname = "RSVD4_RX_SINGLE_MSG_DROP"; 3502 *non_dma_entries += non_dma1->num_entries; 3503 3504 /* 3505 * RSVD4 control message processing status counter. 3506 * Counts the number of cases when the tag was not found during lookup. 3507 */ 3508 non_dma1 = &soc->counter_non_dma[ 3509 SOC_COUNTER_NON_DMA_RSVD4_RX_TAG_LKUP_FAIL - 3510 SOC_COUNTER_NON_DMA_START]; 3511 3512 *non_dma1 = *non_dma0; 3513 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3514 non_dma1->reg = BRCM_RESERVED_CPM_324r; 3515 non_dma1->field = BRCM_RESERVED_CPM_324_0f; 3516 non_dma1->cname = "RSVD4_RX_TAG_LKUP_FAIL"; 3517 *non_dma_entries += non_dma1->num_entries; 3518 3519 /* single message control streams including the error messages */ 3520 non_dma1 = &soc->counter_non_dma[ 3521 SOC_COUNTER_NON_DMA_RSVD4_RX_SINGLE_MSG_CTRL_STREAMS - 3522 SOC_COUNTER_NON_DMA_START]; 3523 3524 *non_dma1 = *non_dma0; 3525 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3526 non_dma1->reg = BRCM_RESERVED_CPM_325r; 3527 non_dma1->field = BRCM_RESERVED_CPM_325_0f; 3528 non_dma1->cname = "RSVD4_RX_SINGLE_MSG_CTRL_STREAMS"; 3529 *non_dma_entries += non_dma1->num_entries; 3530 3531 /* 3532 * Counts the number of multiple message control 3533 * streams including the error messages. 3534 */ 3535 non_dma1 = &soc->counter_non_dma[ 3536 SOC_COUNTER_NON_DMA_RSVD4_RX_MULPILE_MSG_CTRL_STREAMS - 3537 SOC_COUNTER_NON_DMA_START]; 3538 3539 *non_dma1 = *non_dma0; 3540 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3541 non_dma1->reg = BRCM_RESERVED_CPM_327r; 3542 non_dma1->field = BRCM_RESERVED_CPM_327_0f; 3543 non_dma1->cname = "RSVD4_RX_MULTIPLE_MSG_CTRL_STREAMS"; 3544 *non_dma_entries += non_dma1->num_entries; 3545 3546 /* 3547 * Counts the number of incorrect timestamp sequences. 3548 * Increments once per incorrect timestamp sequence. 3549 */ 3550 non_dma1 = &soc->counter_non_dma[ 3551 SOC_COUNTER_NON_DMA_RSVD4_RX_INCORRECT_TIME_STAMP_SEQ - 3552 SOC_COUNTER_NON_DMA_START]; 3553 3554 *non_dma1 = *non_dma0; 3555 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3556 non_dma1->reg = BRCM_RESERVED_CPM_326r; 3557 non_dma1->field = BRCM_RESERVED_CPM_326_0f; 3558 non_dma1->cname = "RSVD4_RX_INCORRECT_TS_SEQ"; 3559 *non_dma_entries += non_dma1->num_entries; 3560 3561 /* Counts the number of data bytes in error. */ 3562 non_dma1 = &soc->counter_non_dma[ 3563 SOC_COUNTER_NON_DMA_CPRI_RX_DATA_BYTES_ERR - 3564 SOC_COUNTER_NON_DMA_START]; 3565 3566 *non_dma1 = *non_dma0; 3567 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3568 non_dma1->reg = CPRI_RX_STATS_CNTR_0_STATUSr; 3569 non_dma1->field = RX_ERR_BYTE_CNTRf; 3570 non_dma1->cname = "CPRI_RX_DATA_BYTE_ERR"; 3571 *non_dma_entries += non_dma1->num_entries; 3572 3573 /* Counts the number of messages dropped due to header errors. */ 3574 non_dma1 = &soc->counter_non_dma[ 3575 SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_HDR_MSG_ERR - 3576 SOC_COUNTER_NON_DMA_START]; 3577 3578 *non_dma1 = *non_dma0; 3579 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3580 non_dma1->reg = CPRI_RX_STATS_CNTR_1_STATUSr; 3581 non_dma1->field = BRCM_RESERVED_CPM_328_0f; 3582 non_dma1->cname = "RSVD4_RX_HDR_ERR"; 3583 *non_dma_entries += non_dma1->num_entries; 3584 3585 /* 3586 * Counts the number of RSVD4 messages whose headers did not 3587 * match any of the options in the look up table. 3588 */ 3589 non_dma1 = &soc->counter_non_dma[ 3590 SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_MSG_HDR_LKUP_FAIL - 3591 SOC_COUNTER_NON_DMA_START]; 3592 3593 *non_dma1 = *non_dma0; 3594 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3595 non_dma1->reg = CPRI_RX_STATS_CNTR_2_STATUSr; 3596 non_dma1->field = BRCM_RESERVED_CPM_329_0f; 3597 non_dma1->cname = "RSVD4_RX_HDR_LKUP_FAIL"; 3598 *non_dma_entries += non_dma1->num_entries; 3599 3600 /* 3601 * Counts the total number of RSVD4 messages including 3602 * the error and dropped messages. 3603 */ 3604 non_dma1 = &soc->counter_non_dma[ 3605 SOC_COUNTER_NON_DMA_CPRI_RX_RSVD4_TOTAL_MSG_COUNT - 3606 SOC_COUNTER_NON_DMA_START]; 3607 3608 *non_dma1 = *non_dma0; 3609 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3610 non_dma1->reg = CPRI_RX_STATS_CNTR_3_STATUSr; 3611 non_dma1->field = BRCM_RESERVED_CPM_330_0f; 3612 non_dma1->cname = "RSVD4_RX_TOTAL_MSG_COUNT"; 3613 *non_dma_entries += non_dma1->num_entries; 3614 3615 /* Counts the number of incorect HFN extracted */ 3616 non_dma1 = &soc->counter_non_dma[ 3617 SOC_COUNTER_NON_DMA_CPRI_RX_INCORRECT_HFN_EXTRACT - 3618 SOC_COUNTER_NON_DMA_START]; 3619 3620 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 3621 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3622 non_dma1->reg = CPRI_RX_STATS_CNTR_4_STATUSr; 3623 non_dma1->field = RXFRM_HFN_ERR_CNTRf; 3624 non_dma1->cname = "CPRI_RX_INCORRECT_HFN"; 3625 *non_dma_entries += non_dma1->num_entries; 3626 3627 /* Counts the number of incorect BFN extracted */ 3628 non_dma1 = &soc->counter_non_dma[ 3629 SOC_COUNTER_NON_DMA_CPRI_RX_INCORRECT_BFN_EXTRACT - 3630 SOC_COUNTER_NON_DMA_START]; 3631 3632 *non_dma1 = *non_dma0; 3633 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3634 non_dma1->reg = CPRI_RX_STATS_CNTR_5_STATUSr; 3635 non_dma1->field = RXFRM_BFN_ERR_CNTRf; 3636 non_dma1->cname = "CPRI_RX_INCORRECT_BFN"; 3637 *non_dma_entries += non_dma1->num_entries; 3638 3639 /* Count of bytes in control words with error indication */ 3640 non_dma1 = &soc->counter_non_dma[ 3641 SOC_COUNTER_NON_DMA_CPRI_RX_CTRL_WORD_ERR - 3642 SOC_COUNTER_NON_DMA_START]; 3643 3644 *non_dma1 = *non_dma0; 3645 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3646 non_dma1->reg = CPRI_RX_STATS_CNTR_6_STATUSr; 3647 non_dma1->field = RX_CW_ERR_CNTf; 3648 non_dma1->cname = "CPRI_RX_CW_ERR"; 3649 *non_dma_entries += non_dma1->num_entries; 3650 3651 /* count of Generic Control Word words dropped due to byte errors */ 3652 non_dma1 = &soc->counter_non_dma[ 3653 SOC_COUNTER_NON_DMA_CPRI_RX_GENERIC_CTRL_WORD_ERR - 3654 SOC_COUNTER_NON_DMA_START]; 3655 3656 *non_dma1 = *non_dma0; 3657 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3658 non_dma1->reg = CPRI_RX_GCW_ERR_CNTR_STATUSr; 3659 non_dma1->field = RX_GCW_ERR_CNTf; 3660 non_dma1->cname = "CPRI_RX_GCW_ERR"; 3661 *non_dma_entries += non_dma1->num_entries; 3662 3663 /* VSD raw packets dropped due to byte errors */ 3664 non_dma1 = &soc->counter_non_dma[ 3665 SOC_COUNTER_NON_DMA_CPRI_RX_VSD_RAW_PKT_DROP - 3666 SOC_COUNTER_NON_DMA_START]; 3667 3668 *non_dma1 = *non_dma0; 3669 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3670 non_dma1->reg = CPRI_VSDRAW_ERR_CNTR_STATUSr; 3671 non_dma1->field = RX_VSD_RAW_ERR_CNTf; 3672 non_dma1->cname = "CPRI_RX_VSD_RAW_ERR"; 3673 *non_dma_entries += non_dma1->num_entries; 3674 3675 /* Count of VSD control packets dropped due to byte error */ 3676 non_dma1 = &soc->counter_non_dma[ 3677 SOC_COUNTER_NON_DMA_CPRI_RX_VSD_CTRL_PKT_DROP - 3678 SOC_COUNTER_NON_DMA_START]; 3679 3680 *non_dma1 = *non_dma0; 3681 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3682 non_dma1->reg = CPRI_VSD_CTRL_ERR_CNTR_STATUSr; 3683 non_dma1->field = RX_VSD_CTRL_ERR_CNTf; 3684 non_dma1->cname = "CPRI_RX_VSD_CTRL_ERR"; 3685 *non_dma_entries += non_dma1->num_entries; 3686 3687 /* Counts the number of RSVD4 data slots used as data messages. */ 3688 non_dma1 = &soc->counter_non_dma[ 3689 SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_DATA_SLOT_DATA_MSG - 3690 SOC_COUNTER_NON_DMA_START]; 3691 3692 *non_dma1 = *non_dma0; 3693 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3694 non_dma1->reg = BRCM_RESERVED_CPM_6r; 3695 non_dma1->field = BRCM_RESERVED_CPM_6_0f; 3696 non_dma1->cname = "RSVD4_DATA_SLOT_DATA_MSG_CNT"; 3697 *non_dma_entries += non_dma1->num_entries; 3698 3699 /* Counts the number of RSVD4 data slots used as empty messages */ 3700 non_dma1 = &soc->counter_non_dma[ 3701 SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_DATA_SLOT_EMPTY_MSG - 3702 SOC_COUNTER_NON_DMA_START]; 3703 3704 *non_dma1 = *non_dma0; 3705 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3706 non_dma1->reg = BRCM_RESERVED_CPM_7r; 3707 non_dma1->field = BRCM_RESERVED_CPM_7_0f; 3708 non_dma1->cname = "RSVD4_DATA_SLOT_EMPTY_MSG_CNT"; 3709 *non_dma_entries += non_dma1->num_entries; 3710 3711 /* Counts the number of RSVD4 control slots used as control messages */ 3712 non_dma1 = &soc->counter_non_dma[ 3713 SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_CTRL_SLOT_CTRL_MSG - 3714 SOC_COUNTER_NON_DMA_START]; 3715 3716 *non_dma1 = *non_dma0; 3717 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3718 non_dma1->reg = BRCM_RESERVED_CPM_8r; 3719 non_dma1->field = BRCM_RESERVED_CPM_8_0f; 3720 non_dma1->cname = "RSVD4_CTRL_SLOT_CTRL_MSG_CNT"; 3721 *non_dma_entries += non_dma1->num_entries; 3722 3723 /* Counts the number of RSVD4 control slots used as empty messages */ 3724 non_dma1 = &soc->counter_non_dma[ 3725 SOC_COUNTER_NON_DMA_CPRI_TX_RSVD4_CTRL_SLOT_EMPTY_MSG - 3726 SOC_COUNTER_NON_DMA_START]; 3727 3728 *non_dma1 = *non_dma0; 3729 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3730 non_dma1->reg = BRCM_RESERVED_CPM_9r; 3731 non_dma1->field = BRCM_RESERVED_CPM_9_0f; 3732 non_dma1->cname = "RSVD4_CTRL_SLOT_EMPTY_MSG_CNT"; 3733 *non_dma_entries += non_dma1->num_entries; 3734 3735 /* Count of RSVD5 messages with incorrect parity. */ 3736 non_dma1 = &soc->counter_non_dma[ 3737 SOC_COUNTER_NON_DMA_RSVD5_RX_MSG_PARITY_ERR - 3738 SOC_COUNTER_NON_DMA_START]; 3739 3740 *non_dma1 = *non_dma0; 3741 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3742 non_dma1->reg = BRCM_RESERVED_CPM_316r; 3743 non_dma1->field = BRCM_RESERVED_CPM_316_0f; 3744 non_dma1->cname = "RSVD5_MSG_PARITY_ERR"; 3745 *non_dma_entries += non_dma1->num_entries; 3746 3747 /* 3748 * HDLC error frame counter. Increments if the HDLC frame 3749 * contains errors, abort sequence or FCS errors. Counts runt 3750 * frames too that are dropped. 3751 */ 3752 non_dma1 = &soc->counter_non_dma[ 3753 SOC_COUNTER_NON_DMA_CPRI_RX_HDLC_FRAME_ERR - 3754 SOC_COUNTER_NON_DMA_START]; 3755 3756 *non_dma1 = *non_dma0; 3757 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3758 non_dma1->reg = CPRI_HDLC_ERR_CNTR_STATUSr; 3759 non_dma1->field = RX_HDLC_ERROR_FRAME_CNTf; 3760 non_dma1->cname = "CPRI_RX_HDLC_FRM_ERR"; 3761 *non_dma_entries += non_dma1->num_entries; 3762 3763 /* HDLC good frame counter. */ 3764 non_dma1 = &soc->counter_non_dma[ 3765 SOC_COUNTER_NON_DMA_CPRI_RX_HDLC_FRAME_OK - 3766 SOC_COUNTER_NON_DMA_START]; 3767 3768 *non_dma1 = *non_dma0; 3769 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3770 non_dma1->reg = CPRI_HDLC_CNTR_STATUSr; 3771 non_dma1->field = RX_HDLC_GOOD_FRAME_CNTf; 3772 non_dma1->cname = "CPRI_RX_HDLC_FRM_CNT"; 3773 *non_dma_entries += non_dma1->num_entries; 3774 3775 /* Counts the error packets dropped in the MAC */ 3776 non_dma1 = &soc->counter_non_dma[ 3777 SOC_COUNTER_NON_DMA_CPRI_RX_FAST_ETH_PKT_MAC_DROP - 3778 SOC_COUNTER_NON_DMA_START]; 3779 3780 *non_dma1 = *non_dma0; 3781 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3782 non_dma1->reg = CPRI_FAST_ETH_ERR_CNTR_STATUSr; 3783 non_dma1->field = RX_FAST_ETH_MAC_ERR_PKT_CNTf; 3784 non_dma1->cname = "CPRI_RX_FAST_ETH_PKT_DROP_CNT"; 3785 *non_dma_entries += non_dma1->num_entries; 3786 3787 /* Counts the number of valid packets forwarded to the encap block */ 3788 non_dma1 = &soc->counter_non_dma[ 3789 SOC_COUNTER_NON_DMA_CPRI_RX_FAST_ETH_PKT_MAC_OK - 3790 SOC_COUNTER_NON_DMA_START]; 3791 3792 *non_dma1 = *non_dma0; 3793 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3794 non_dma1->reg = CPRI_FAST_ETH_CNTR_STATUSr; 3795 non_dma1->field = RX_FAST_ETH_MAC_PKT_CNTf; 3796 non_dma1->cname = "CPRI_RX_FAST_ETH_PKT_CNT"; 3797 *non_dma_entries += non_dma1->num_entries; 3798 3799 return SOC_E_NONE; 3800 } 3801 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */ 3802 3803 STATIC int 3804 _soc_counter_apache_non_dma_init(int unit, int nports, 3805 int non_dma_start_index, 3806 int *non_dma_entries) 3807 { 3808 soc_control_t *soc; 3809 soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2, *temp; 3810 int alloc_size; 3811 uint32 *buf; 3812 uint32 dma_num_entries=0,dma_num_index=0, dma_index_max = 0; 3813 int full_chip = 1, rv, num_extra_ctr_entries; 3814 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 3815 3816 soc = SOC_CONTROL(unit); 3817 *non_dma_entries = 0; 3818 3819 /* MMU_CTR_UC_DROP_MEM is the largest table to be DMA'ed */ 3820 if (SOC_IS_MONTEREY(unit)) { 3821 alloc_size = 2 * soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) * 3822 sizeof(uint32) * soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm); 3823 dma_num_entries=67; 3824 dma_num_index=66; 3825 dma_index_max = 639; 3826 } else { 3827 alloc_size = 2 * soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) * 3828 sizeof(uint32) * soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm); 3829 dma_num_entries=74; 3830 dma_num_index=74; 3831 dma_index_max = 16383; 3832 } 3833 3834 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 3835 if (buf == NULL) { 3836 return SOC_E_MEMORY; 3837 } 3838 sal_memset(buf, 0, alloc_size); 3839 3840 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 3841 SOC_COUNTER_NON_DMA_START]; 3842 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 3843 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 3844 non_dma0->pbmp = PBMP_ALL(unit); 3845 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3846 non_dma0->entries_per_port = 48; /* cpu port has max number of queues */ 3847 non_dma0->num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) / ((full_chip)? 1 : 2); 3848 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 3849 non_dma0->reg = INVALIDr; 3850 non_dma0->field = PACKET_COUNTERf; 3851 non_dma0->cname = "MC_PERQ_PKT"; 3852 non_dma0->dma_buf[0] = buf; 3853 non_dma0->dma_index_max[0] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm) - 1; 3854 non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERSm; 3855 *non_dma_entries += non_dma0->num_entries; 3856 3857 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 3858 SOC_COUNTER_NON_DMA_START]; 3859 *non_dma1 = *non_dma0; 3860 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 3861 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3862 non_dma1->field = BYTE_COUNTERf; 3863 non_dma1->cname = "MC_PERQ_BYTE"; 3864 *non_dma_entries += non_dma1->num_entries; 3865 3866 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC - 3867 SOC_COUNTER_NON_DMA_START]; 3868 *non_dma2 = *non_dma0; 3869 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 3870 non_dma2->pbmp = PBMP_PORT_ALL(unit); 3871 non_dma2->entries_per_port = 10; 3872 non_dma2->num_entries = 0; 3873 non_dma2->cname = "UC_PERQ_PKT"; 3874 3875 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC - 3876 SOC_COUNTER_NON_DMA_START]; 3877 *non_dma2 = *non_dma1; 3878 non_dma2->pbmp = PBMP_PORT_ALL(unit); 3879 non_dma2->entries_per_port = 10; 3880 non_dma2->num_entries = 0; 3881 non_dma2->cname = "UC_PERQ_BYTE"; 3882 3883 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT - 3884 SOC_COUNTER_NON_DMA_START]; 3885 *non_dma2 = *non_dma0; 3886 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 3887 3888 non_dma2->entries_per_port = 0; 3889 non_dma2->num_entries = 0; 3890 SOC_PBMP_CLEAR(non_dma2->pbmp); 3891 3892 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT - 3893 SOC_COUNTER_NON_DMA_START]; 3894 *non_dma2 = *non_dma1; 3895 non_dma2->entries_per_port = 0; 3896 non_dma2->num_entries = 0; 3897 SOC_PBMP_CLEAR(non_dma2->pbmp); 3898 3899 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 3900 SOC_COUNTER_NON_DMA_START]; 3901 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 3902 _SOC_COUNTER_NON_DMA_DO_DMA; 3903 non_dma0->pbmp = PBMP_ALL(unit); 3904 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3905 non_dma0->entries_per_port = 48; /* APACHE 48 for cpu port */ 3906 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM0m); 3907 non_dma0->mem = MMU_CTR_MC_DROP_MEM0m; 3908 non_dma0->reg = INVALIDr; 3909 non_dma0->field = PKTCNTf; 3910 non_dma0->cname = "MCQ_DROP_PKT"; 3911 non_dma0->dma_mem[0] = MMU_CTR_MC_DROP_MEM0m; 3912 non_dma0->dma_buf[0] = buf; 3913 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 3914 *non_dma_entries += non_dma0->num_entries; 3915 3916 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 3917 SOC_COUNTER_NON_DMA_START]; 3918 *non_dma1 = *non_dma0; 3919 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 3920 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3921 non_dma1->field = BYTECNTf; 3922 non_dma1->cname = "MCQ_DROP_BYTE"; 3923 *non_dma_entries += non_dma1->num_entries; 3924 3925 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC - 3926 SOC_COUNTER_NON_DMA_START]; 3927 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 3928 non_dma0->pbmp = PBMP_PORT_ALL(unit); 3929 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3930 non_dma0->entries_per_port = 10; 3931 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm); 3932 non_dma0->mem = MMU_CTR_UC_DROP_MEMm; 3933 non_dma0->reg = INVALIDr; 3934 non_dma0->field = PKTCNTf; 3935 non_dma0->cname = "UCQ_DROP_PKT"; 3936 non_dma0->dma_buf[0] = buf; 3937 non_dma0->dma_index_max[0] = dma_index_max; 3938 non_dma0->dma_mem[0] = non_dma0->mem; 3939 *non_dma_entries += non_dma0->num_entries; 3940 3941 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC - 3942 SOC_COUNTER_NON_DMA_START]; 3943 *non_dma1 = *non_dma0; 3944 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 3945 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3946 non_dma1->field = BYTECNTf; 3947 non_dma1->cname = "UCQ_DROP_BYTE"; 3948 *non_dma_entries += non_dma1->num_entries; 3949 3950 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 3951 SOC_COUNTER_NON_DMA_START]; 3952 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 3953 non_dma0->pbmp = PBMP_ALL(unit); 3954 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3955 non_dma0->entries_per_port = 1; 3956 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm); 3957 non_dma0->mem = MMU_CTR_ING_DROP_MEMm; 3958 non_dma0->reg = INVALIDr; 3959 non_dma0->field = PKTCNTf; 3960 non_dma0->cname = "DROP_PKT_ING"; 3961 non_dma0->dma_buf[0] = buf; 3962 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem); 3963 non_dma0->dma_mem[0] = non_dma0->mem; 3964 *non_dma_entries += non_dma0->num_entries; 3965 3966 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 3967 SOC_COUNTER_NON_DMA_START]; 3968 *non_dma1 = *non_dma0; 3969 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 3970 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3971 non_dma1->field = BYTECNTf; 3972 non_dma1->cname = "DROP_BYTE_ING"; 3973 *non_dma_entries += non_dma1->num_entries; 3974 3975 non_dma0 = 3976 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER - 3977 SOC_COUNTER_NON_DMA_START]; 3978 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 3979 non_dma0->pbmp = PBMP_ALL(unit); 3980 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 3981 non_dma0->entries_per_port = 1; 3982 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm); 3983 non_dma0->mem = MMU_CTR_MTRI_DROP_MEMm; 3984 non_dma0->reg = INVALIDr; 3985 non_dma0->field = PKTCNTf; 3986 non_dma0->cname = "DROP_PKT_IMTR"; 3987 non_dma0->dma_buf[0] = buf; 3988 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem); 3989 non_dma0->dma_mem[0] = non_dma0->mem; 3990 *non_dma_entries += non_dma0->num_entries; 3991 3992 non_dma1 = 3993 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER - 3994 SOC_COUNTER_NON_DMA_START]; 3995 *non_dma1 = *non_dma0; 3996 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 3997 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 3998 non_dma1->field = BYTECNTf; 3999 non_dma1->cname = "DROP_BYTE_IMTR"; 4000 *non_dma_entries += non_dma1->num_entries; 4001 4002 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 4003 SOC_COUNTER_NON_DMA_START]; 4004 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4005 _SOC_COUNTER_NON_DMA_DO_DMA; 4006 non_dma0->pbmp = PBMP_PORT_ALL(unit); 4007 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4008 non_dma0->entries_per_port = 1; 4009 /* TO DO: APACHE For this ver of regs file num of entries changed */ 4010 non_dma0->num_entries = dma_num_entries; /* one per port */ 4011 non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm; 4012 non_dma0->reg = INVALIDr; 4013 non_dma0->field = PKTCNTf; 4014 non_dma0->cname = "DROP_PKT_YEL"; 4015 non_dma0->dma_buf[0] = buf; 4016 non_dma0->dma_index_min[0] = dma_num_index * 4; 4017 non_dma0->dma_index_max[0] = (dma_num_index * 4) + (dma_num_index -1); 4018 non_dma0->dma_mem[0] = non_dma0->mem; 4019 *non_dma_entries += non_dma0->num_entries; 4020 4021 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 4022 SOC_COUNTER_NON_DMA_START]; 4023 *non_dma1 = *non_dma0; 4024 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4025 non_dma1->cname = "DROP_PKT_RED"; 4026 /* TO DO: APACHE For this ver of regs file num of entries changed */ 4027 non_dma1->dma_index_min[0] = dma_num_index * 3; 4028 non_dma1->dma_index_max[0] = (dma_num_index * 3) + (dma_num_index - 1); 4029 *non_dma_entries += non_dma1->num_entries; 4030 4031 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN - 4032 SOC_COUNTER_NON_DMA_START]; 4033 *non_dma1 = *non_dma0; 4034 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4035 non_dma1->cname = "WRED_PKT_GRE"; 4036 /* TO DO: APACHE For this ver of regs file num of entries changed */ 4037 non_dma1->dma_index_min[0] = dma_num_index * 2; 4038 non_dma1->dma_index_max[0] = (dma_num_index * 2) + (dma_num_index - 1); 4039 *non_dma_entries += non_dma1->num_entries; 4040 4041 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW - 4042 SOC_COUNTER_NON_DMA_START]; 4043 *non_dma1 = *non_dma0; 4044 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4045 non_dma1->cname = "WRED_PKT_YEL"; 4046 /* TO DO: APACHE For this ver of regs file num of entries changed */ 4047 non_dma1->dma_index_min[0] = dma_num_index * 1; 4048 non_dma1->dma_index_max[0] = (dma_num_index * 1) + (dma_num_index - 1); 4049 *non_dma_entries += non_dma1->num_entries; 4050 4051 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED - 4052 SOC_COUNTER_NON_DMA_START]; 4053 *non_dma1 = *non_dma0; 4054 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4055 non_dma1->cname = "WRED_PKT_RED"; 4056 non_dma1->dma_index_min[0] = 0; 4057 non_dma1->dma_index_max[0] = 65; 4058 *non_dma_entries += non_dma1->num_entries; 4059 4060 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT - 4061 SOC_COUNTER_NON_DMA_START]; 4062 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4063 _SOC_COUNTER_NON_DMA_DO_DMA; 4064 SOC_PBMP_CLEAR(non_dma0->pbmp); 4065 non_dma0->pbmp = PBMP_ALL(unit); 4066 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4067 non_dma0->entries_per_port = 0; 4068 non_dma0->num_entries = 11; 4069 non_dma0->mem = INVALIDm; 4070 non_dma0->reg = DROP_PKT_CNT_RQE_PKTr; 4071 non_dma0->field = PKTCNTf; 4072 non_dma0->cname = "RQ_DROP_PKT"; 4073 non_dma0->dma_buf[0] = buf; 4074 *non_dma_entries += non_dma0->num_entries; 4075 4076 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_BYTE - 4077 SOC_COUNTER_NON_DMA_START]; 4078 *non_dma1 = *non_dma0; 4079 non_dma1->pbmp = PBMP_ALL(unit); 4080 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4081 non_dma1->reg = DROP_PKT_CNT_RQE_BYTE_64r; 4082 non_dma1->field = BYTECNTf; 4083 non_dma1->cname = "RQ_DROP_BYTE"; 4084 *non_dma_entries += non_dma1->num_entries; 4085 4086 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW - 4087 SOC_COUNTER_NON_DMA_START]; 4088 *non_dma1 = *non_dma0; 4089 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4090 non_dma1->reg = DROP_PKT_CNT_RQE_YELr; 4091 non_dma1->field = PKTCNTf; 4092 non_dma1->cname = "RQ_DROP_PKT_YEL"; 4093 *non_dma_entries += non_dma1->num_entries; 4094 4095 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED - 4096 SOC_COUNTER_NON_DMA_START]; 4097 *non_dma1 = *non_dma0; 4098 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4099 non_dma1->reg = DROP_PKT_CNT_RQE_REDr; 4100 non_dma1->field = PKTCNTf; 4101 non_dma1->cname = "RQ_DROP_PKT_RED"; 4102 *non_dma_entries += non_dma1->num_entries; 4103 4104 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK - 4105 SOC_COUNTER_NON_DMA_START]; 4106 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4107 _SOC_COUNTER_NON_DMA_PEAK; 4108 SOC_PBMP_CLEAR(non_dma0->pbmp); 4109 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4110 non_dma0->entries_per_port = 0; 4111 non_dma0->num_entries = 4; 4112 non_dma0->mem = INVALIDm; 4113 non_dma0->reg = THDI_POOL_SHARED_COUNT_SPr; 4114 non_dma0->field = TOTAL_BUFFER_COUNTf; 4115 non_dma0->cname = "POOL_PEAK"; 4116 non_dma0->dma_buf[0] = buf; 4117 *non_dma_entries += non_dma0->num_entries; 4118 4119 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT - 4120 SOC_COUNTER_NON_DMA_START]; 4121 *non_dma2 = *non_dma0; 4122 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4123 _SOC_COUNTER_NON_DMA_CURRENT; 4124 non_dma2->cname = "POOL_CUR"; 4125 4126 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK - 4127 SOC_COUNTER_NON_DMA_START]; 4128 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4129 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 4130 non_dma0->pbmp = PBMP_ALL(unit); 4131 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4132 non_dma0->entries_per_port = 8; 4133 non_dma0->num_entries = nports * non_dma0->entries_per_port; 4134 non_dma0->mem = THDI_PORT_PG_CNTRS_RT1_Xm; 4135 non_dma0->reg = INVALIDr; 4136 non_dma0->field = PG_MIN_COUNTf; 4137 non_dma0->cname = "PG_MIN_PEAK"; 4138 non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT1_Xm; 4139 non_dma0->dma_buf[0] = buf; 4140 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 4141 *non_dma_entries += non_dma0->num_entries; 4142 4143 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT - 4144 SOC_COUNTER_NON_DMA_START]; 4145 *non_dma2 = *non_dma0; 4146 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4147 _SOC_COUNTER_NON_DMA_CURRENT; 4148 non_dma2->cname = "PG_MIN_CUR"; 4149 4150 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK - 4151 SOC_COUNTER_NON_DMA_START]; 4152 *non_dma1 = *non_dma0; 4153 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 4154 _SOC_COUNTER_NON_DMA_PEAK; 4155 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4156 non_dma1->field = PG_SHARED_COUNTf; 4157 non_dma1->cname = "PG_SHARED_PEAK"; 4158 *non_dma_entries += non_dma1->num_entries; 4159 4160 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT - 4161 SOC_COUNTER_NON_DMA_START]; 4162 *non_dma2 = *non_dma1; 4163 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4164 _SOC_COUNTER_NON_DMA_CURRENT; 4165 non_dma2->cname = "PG_SHARED_CUR"; 4166 4167 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK - 4168 SOC_COUNTER_NON_DMA_START]; 4169 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4170 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 4171 non_dma0->pbmp = PBMP_ALL(unit); 4172 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4173 non_dma0->entries_per_port = 8; 4174 non_dma0->num_entries = nports * non_dma0->entries_per_port; 4175 non_dma0->mem = THDI_PORT_PG_CNTRS_RT2_Xm; 4176 non_dma0->reg = INVALIDr; 4177 non_dma0->field = PG_HDRM_COUNTf; 4178 non_dma0->cname = "PG_HDRM_PEAK"; 4179 non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT2_Xm; 4180 non_dma0->dma_buf[0] = buf; 4181 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 4182 *non_dma_entries += non_dma0->num_entries; 4183 4184 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT - 4185 SOC_COUNTER_NON_DMA_START]; 4186 *non_dma2 = *non_dma0; 4187 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4188 _SOC_COUNTER_NON_DMA_CURRENT; 4189 non_dma2->cname = "PG_HDRM_CUR"; 4190 4191 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK - 4192 SOC_COUNTER_NON_DMA_START]; 4193 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4194 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 4195 non_dma0->pbmp = PBMP_ALL(unit); 4196 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4197 non_dma0->entries_per_port = 48; /* 48 for cpu port */ 4198 non_dma0->num_entries = soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_0m); 4199 non_dma0->mem = MMU_THDM_DB_QUEUE_COUNT_0m; 4200 non_dma0->reg = INVALIDr; 4201 non_dma0->field = SHARED_COUNTf; 4202 non_dma0->cname = "QUEUE_PEAK"; 4203 non_dma0->dma_mem[0] = MMU_THDM_DB_QUEUE_COUNT_0m; 4204 non_dma0->dma_buf[0] = buf; 4205 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 4206 *non_dma_entries += non_dma0->num_entries; 4207 4208 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT - 4209 SOC_COUNTER_NON_DMA_START]; 4210 *non_dma2 = *non_dma0; 4211 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4212 _SOC_COUNTER_NON_DMA_CURRENT; 4213 non_dma2->cname = "QUEUE_CUR"; 4214 4215 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK - 4216 SOC_COUNTER_NON_DMA_START]; 4217 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4218 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 4219 non_dma0->pbmp = PBMP_PORT_ALL(unit); 4220 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4221 non_dma0->entries_per_port = 10; 4222 non_dma0->num_entries = 4223 soc_mem_index_count(unit, MMU_THDU_XPIPE_COUNTER_QUEUEm); 4224 non_dma0->mem = MMU_THDU_XPIPE_COUNTER_QUEUEm; 4225 non_dma0->reg = INVALIDr; 4226 non_dma0->field = SHARED_COUNTf; 4227 non_dma0->cname = "UC_QUEUE_PEAK"; 4228 non_dma0->dma_mem[0] = MMU_THDU_XPIPE_COUNTER_QUEUEm; 4229 non_dma0->dma_buf[0] = buf; 4230 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]) - 1; 4231 *non_dma_entries += non_dma0->num_entries; 4232 4233 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT - 4234 SOC_COUNTER_NON_DMA_START]; 4235 *non_dma2 = *non_dma0; 4236 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4237 _SOC_COUNTER_NON_DMA_CURRENT; 4238 non_dma2->cname = "UC_QUEUE_CUR"; 4239 if (!SOC_IS_MONTEREY(unit)) { 4240 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM - 4241 SOC_COUNTER_NON_DMA_START]; 4242 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4243 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_FLEX_MAPPING; 4244 non_dma0->pbmp = PBMP_PORT_ALL(unit); 4245 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4246 non_dma0->entries_per_port = 10; 4247 non_dma0->num_entries = 1 * soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm); 4248 4249 non_dma0->mem = MMU_QCN_CNM_COUNTERm; 4250 non_dma0->reg = INVALIDr; 4251 non_dma0->field = CNM_CNTf; 4252 non_dma0->cname = "QCN_CNM_COUNTER"; 4253 non_dma0->dma_buf[0] = buf; 4254 non_dma0->dma_mem[0] = non_dma0->mem; 4255 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 4256 non_dma0->soc_counter_hw_idx_get = soc_apache_qcn_counter_hw_index_get; 4257 *non_dma_entries += non_dma0->num_entries; 4258 } 4259 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK - 4260 SOC_COUNTER_NON_DMA_START]; 4261 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4262 _SOC_COUNTER_NON_DMA_PEAK; 4263 SOC_PBMP_CLEAR(non_dma0->pbmp); 4264 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4265 non_dma0->entries_per_port = 0; 4266 non_dma0->num_entries = 1; 4267 non_dma0->mem = INVALIDm; 4268 non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEXr; 4269 non_dma0->field = GLOBAL_HDRM_COUNTf; 4270 4271 non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK"; 4272 non_dma0->dma_buf[0] = buf; 4273 *non_dma_entries += non_dma0->num_entries; 4274 4275 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT - 4276 SOC_COUNTER_NON_DMA_START]; 4277 *non_dma2 = *non_dma0; 4278 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 4279 _SOC_COUNTER_NON_DMA_CURRENT; 4280 non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR"; 4281 4282 non_dma0 = 4283 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_E2E_DROP_COUNT - 4284 SOC_COUNTER_NON_DMA_START]; 4285 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 4286 SOC_PBMP_CLEAR(non_dma0->pbmp); 4287 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4288 non_dma0->reg = E2E_DROP_COUNTr; 4289 non_dma0->mem = INVALIDm; 4290 non_dma0->entries_per_port = 0; 4291 non_dma0->num_entries = 1; 4292 non_dma0->field = COUNTf; 4293 non_dma0->cname = "E2E_DROP_COUNT"; 4294 *non_dma_entries += non_dma1->num_entries; 4295 4296 4297 4298 soc_ctr_ctrl->port_obm_info_get = soc_apache_port_obm_info_get; 4299 /* Control block for IDB OBM counters */ 4300 /* Lossy LO drop counters - Pkt Counters */ 4301 non_dma0 = 4302 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO - 4303 SOC_COUNTER_NON_DMA_START]; 4304 non_dma0->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO; 4305 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4306 non_dma0->reg = IDB_OBM0_LOSSY_LO_PKT_DROP_COUNTr; 4307 non_dma0->cname = "OBM_LOSSY_LO_DRP_PKT"; 4308 4309 /* Common across all OBM structures */ 4310 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4311 _SOC_COUNTER_NON_DMA_OBM; 4312 /* Use Parent-Child model to cover all 8 OBMs */ 4313 non_dma0->flags |= _SOC_COUNTER_NON_DMA_SUBSET_PARENT; 4314 non_dma0->pbmp = PBMP_PORT_ALL(unit); 4315 non_dma0->entries_per_port = 8; 4316 non_dma0->num_entries = 1; 4317 non_dma0->mem = INVALIDm; 4318 non_dma0->field = COUNTERf; 4319 non_dma0->dma_buf[0] = buf; 4320 non_dma0->pbmp = PBMP_ALL(unit); 4321 /* Remove CPU port as OBM counters not applicable to CPU port*/ 4322 SOC_PBMP_PORT_REMOVE(non_dma0->pbmp, 0); 4323 4324 /* 4325 * Below represents how Extra cntrs are arranged 4326 * for OBM 0-8 Drop Counters. 4327 * n = NUM_OBMs (9) 4328 * 4329 * [0] [2] [2n-2] 4330 * ------ ------ ------ 4331 * | || |...| | 4332 * | PKT || PKT |...| PKT | 4333 * | [0] || [1] |...| [n-1]| 4334 * ------ ------ ... ------ 4335 * | || |...| | 4336 * | BYTE || BYTE |...| BYTE | 4337 * | [0] || [1] |...| [n-1]| 4338 * ------ ------ ------ 4339 * [1] [3] [2n-1] 4340 */ 4341 non_dma0->extra_ctr_ct = SOC_IS_MONTEREY(unit) ? _MN_PBLKS_PER_PIPE :_AP_PBLKS_PER_PIPE; /* 9 OBMs per Pipe */ 4342 alloc_size = (non_dma0->extra_ctr_ct << 1) * sizeof(soc_counter_non_dma_t); 4343 temp = non_dma0->extra_ctrs = sal_alloc(alloc_size, 4344 "non_dma_ctrs_obm_lossy_lo"); 4345 if (non_dma0->extra_ctrs == NULL) { 4346 non_dma0->extra_ctr_ct = 0; 4347 non_dma0->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4348 return SOC_E_MEMORY; 4349 } else { 4350 sal_memset(non_dma0->extra_ctrs, 0, alloc_size); 4351 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4352 non_dma0, 4353 non_dma0->extra_ctrs, 4354 non_dma0->extra_ctr_ct, 4355 &num_extra_ctr_entries); 4356 if (rv != SOC_E_NONE) { 4357 LOG_CLI((BSL_META_U(unit, 4358 "ERR: Extra ctrs Init FAILED for id %d\n"), 4359 non_dma0->id - SOC_COUNTER_NON_DMA_START)); 4360 } 4361 non_dma0->num_entries = num_extra_ctr_entries; 4362 } 4363 *non_dma_entries += non_dma0->num_entries; 4364 4365 /* Lossy LO drop counters - Byte Counters */ 4366 non_dma1 = 4367 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO - 4368 SOC_COUNTER_NON_DMA_START]; 4369 *non_dma1 = *non_dma0; 4370 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO; 4371 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4372 non_dma1->reg = IDB_OBM0_LOSSY_LO_BYTE_DROP_COUNTr; 4373 non_dma1->field = COUNTERf; 4374 non_dma1->cname = "OBM_LOSSY_LO_DRP_BYTE"; 4375 4376 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4377 non_dma1->extra_ctrs = temp + 1; 4378 if (non_dma1->extra_ctrs) { 4379 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4380 non_dma1, 4381 non_dma1->extra_ctrs, 4382 non_dma1->extra_ctr_ct, 4383 &num_extra_ctr_entries); 4384 if (rv != SOC_E_NONE) { 4385 LOG_CLI((BSL_META_U(unit, 4386 "ERR: Extra ctrs Init FAILED for id %d\n"), 4387 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4388 } 4389 } 4390 *non_dma_entries += non_dma1->num_entries; 4391 4392 /* Lossy HI drop counters - Packet Counters */ 4393 non_dma1 = 4394 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI - 4395 SOC_COUNTER_NON_DMA_START]; 4396 *non_dma1 = *non_dma0; 4397 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI; 4398 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4399 non_dma1->reg = IDB_OBM0_LOSSY_HI_PKT_DROP_COUNTr; 4400 non_dma1->cname = "OBM_LOSSY_HI_DRP_PKT"; 4401 4402 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4403 "non_dma_ctrs_obm_lossy_hi"); 4404 4405 if (non_dma1->extra_ctrs == NULL) { 4406 non_dma1->extra_ctr_ct = 0; 4407 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4408 return SOC_E_MEMORY; 4409 } else { 4410 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4411 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4412 non_dma1, 4413 non_dma1->extra_ctrs, 4414 non_dma1->extra_ctr_ct, 4415 &num_extra_ctr_entries); 4416 if (rv != SOC_E_NONE) { 4417 LOG_CLI((BSL_META_U(unit, 4418 "ERR: Extra ctrs Init FAILED for id %d\n"), 4419 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4420 } 4421 non_dma1->num_entries = num_extra_ctr_entries; 4422 } 4423 *non_dma_entries += non_dma1->num_entries; 4424 4425 /* Lossy HI drop counters - Byte Counters */ 4426 non_dma1 = 4427 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI - 4428 SOC_COUNTER_NON_DMA_START]; 4429 *non_dma1 = *non_dma0; 4430 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI; 4431 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4432 non_dma1->reg = IDB_OBM0_LOSSY_HI_BYTE_DROP_COUNTr; 4433 non_dma1->field = COUNTERf; 4434 non_dma1->cname = "OBM_LOSSY_HI_DRP_BYTE"; 4435 4436 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4437 non_dma1->extra_ctrs = temp + 1; 4438 if (non_dma1->extra_ctrs) { 4439 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4440 non_dma1, 4441 non_dma1->extra_ctrs, 4442 non_dma1->extra_ctr_ct, 4443 &num_extra_ctr_entries); 4444 if (rv != SOC_E_NONE) { 4445 LOG_CLI((BSL_META_U(unit, 4446 "ERR: Extra ctrs Init FAILED for id %d\n"), 4447 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4448 } 4449 } 4450 *non_dma_entries += non_dma1->num_entries; 4451 4452 /* Lossless0 drop counters - Packet Counters */ 4453 non_dma1 = 4454 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0 - 4455 SOC_COUNTER_NON_DMA_START]; 4456 *non_dma1 = *non_dma0; 4457 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0; 4458 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4459 non_dma1->reg = IDB_OBM0_LOSSLESS0_PKT_DROP_COUNTr; 4460 non_dma1->cname = "OBM_LOSSLESS0_DRP_PKT"; 4461 4462 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4463 "non_dma_ctrs_obm_lossless0"); 4464 4465 if (non_dma1->extra_ctrs == NULL) { 4466 non_dma1->extra_ctr_ct = 0; 4467 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4468 return SOC_E_MEMORY; 4469 } else { 4470 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4471 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4472 non_dma1, 4473 non_dma1->extra_ctrs, 4474 non_dma1->extra_ctr_ct, 4475 &num_extra_ctr_entries); 4476 if (rv != SOC_E_NONE) { 4477 LOG_CLI((BSL_META_U(unit, 4478 "ERR: Extra ctrs Init FAILED for id %d\n"), 4479 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4480 } 4481 non_dma1->num_entries = num_extra_ctr_entries; 4482 } 4483 *non_dma_entries += non_dma1->num_entries; 4484 4485 /* Lossless0 drop counters - Byte Counters */ 4486 non_dma1 = 4487 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0 - 4488 SOC_COUNTER_NON_DMA_START]; 4489 *non_dma1 = *non_dma0; 4490 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0; 4491 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4492 non_dma1->reg = IDB_OBM0_LOSSLESS0_BYTE_DROP_COUNTr; 4493 non_dma1->field = COUNTERf; 4494 non_dma1->cname = "OBM_LOSSLESS0_DRP_BYTE"; 4495 4496 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4497 non_dma1->extra_ctrs = temp + 1; 4498 if (non_dma1->extra_ctrs) { 4499 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4500 non_dma1, 4501 non_dma1->extra_ctrs, 4502 non_dma1->extra_ctr_ct, 4503 &num_extra_ctr_entries); 4504 if (rv != SOC_E_NONE) { 4505 LOG_CLI((BSL_META_U(unit, 4506 "ERR: Extra ctrs Init FAILED for id %d\n"), 4507 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4508 } 4509 } 4510 *non_dma_entries += non_dma1->num_entries; 4511 4512 /* Lossless1 drop counters - Packet counters */ 4513 non_dma1 = 4514 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1 - 4515 SOC_COUNTER_NON_DMA_START]; 4516 *non_dma1 = *non_dma0; 4517 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1; 4518 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4519 non_dma1->reg = IDB_OBM0_LOSSLESS1_PKT_DROP_COUNTr; 4520 non_dma1->cname = "OBM_LOSSLESS1_DRP_PKT"; 4521 4522 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4523 "non_dma_ctrs_obm_lossless1"); 4524 4525 if (non_dma1->extra_ctrs == NULL) { 4526 non_dma1->extra_ctr_ct = 0; 4527 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4528 return SOC_E_MEMORY; 4529 } else { 4530 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4531 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4532 non_dma1, 4533 non_dma1->extra_ctrs, 4534 non_dma1->extra_ctr_ct, 4535 &num_extra_ctr_entries); 4536 if (rv != SOC_E_NONE) { 4537 LOG_CLI((BSL_META_U(unit, 4538 "ERR: Extra ctrs Init FAILED for id %d\n"), 4539 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4540 } 4541 non_dma1->num_entries = num_extra_ctr_entries; 4542 } 4543 *non_dma_entries += non_dma1->num_entries; 4544 4545 /* Lossless1 drop counters - Byte Counters */ 4546 non_dma1 = 4547 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1 - 4548 SOC_COUNTER_NON_DMA_START]; 4549 *non_dma1 = *non_dma0; 4550 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1; 4551 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4552 non_dma1->reg = IDB_OBM0_LOSSLESS1_BYTE_DROP_COUNTr; 4553 non_dma1->field = COUNTERf; 4554 non_dma1->cname = "OBM_LOSSLESS1_DRP_BYTE"; 4555 4556 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4557 non_dma1->extra_ctrs = temp + 1; 4558 if (non_dma1->extra_ctrs) { 4559 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4560 non_dma1, 4561 non_dma1->extra_ctrs, 4562 non_dma1->extra_ctr_ct, 4563 &num_extra_ctr_entries); 4564 if (rv != SOC_E_NONE) { 4565 LOG_CLI((BSL_META_U(unit, 4566 "ERR: Extra ctrs Init FAILED for id %d\n"), 4567 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4568 } 4569 } 4570 *non_dma_entries += non_dma1->num_entries; 4571 4572 /* Following counters are Monterey specific */ 4573 if (SOC_IS_MONTEREY(unit)) { 4574 /* Express drop counters - Packet counters */ 4575 non_dma1 = 4576 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS - 4577 SOC_COUNTER_NON_DMA_START]; 4578 *non_dma1 = *non_dma0; 4579 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS; 4580 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4581 non_dma1->reg = IDB_OBM0_EXPRESS_PKT_DROP_COUNTr; 4582 non_dma1->cname = "OBM_EXPRESS_DRP_PKT"; 4583 4584 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4585 "non_dma_ctrs_obm_express_drop"); 4586 4587 if (non_dma1->extra_ctrs == NULL) { 4588 non_dma1->extra_ctr_ct = 0; 4589 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4590 return SOC_E_MEMORY; 4591 } else { 4592 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4593 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4594 non_dma1, 4595 non_dma1->extra_ctrs, 4596 non_dma1->extra_ctr_ct, 4597 &num_extra_ctr_entries); 4598 if (rv != SOC_E_NONE) { 4599 LOG_CLI((BSL_META_U(unit, 4600 "ERR: Extra ctrs Init FAILED for id %d\n"), 4601 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4602 } 4603 non_dma1->num_entries = num_extra_ctr_entries; 4604 } 4605 *non_dma_entries += non_dma1->num_entries; 4606 4607 /* Express drop counters - Byte Counters */ 4608 non_dma1 = 4609 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS - 4610 SOC_COUNTER_NON_DMA_START]; 4611 *non_dma1 = *non_dma0; 4612 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS; 4613 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4614 non_dma1->reg = IDB_OBM0_EXPRESS_BYTE_DROP_COUNTr; 4615 non_dma1->field = COUNTERf; 4616 non_dma1->cname = "OBM_EXPRESS_DRP_BYTE"; 4617 4618 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4619 non_dma1->extra_ctrs = temp + 1; 4620 if (non_dma1->extra_ctrs) { 4621 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4622 non_dma1, 4623 non_dma1->extra_ctrs, 4624 non_dma1->extra_ctr_ct, 4625 &num_extra_ctr_entries); 4626 if (rv != SOC_E_NONE) { 4627 LOG_CLI((BSL_META_U(unit, 4628 "ERR: Extra ctrs Init FAILED for id %d\n"), 4629 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4630 } 4631 } 4632 *non_dma_entries += non_dma1->num_entries; 4633 4634 /* Lossy_lo enqueue counters - Packet counters */ 4635 non_dma1 = 4636 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO - 4637 SOC_COUNTER_NON_DMA_START]; 4638 *non_dma1 = *non_dma0; 4639 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO; 4640 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4641 non_dma1->reg = IDB_OBM0_LOSSY_LO_ARRIVAL_PKT_COUNTr; 4642 non_dma1->cname = "OBM_LOSSY_LO_ENQ_PKT"; 4643 4644 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4645 "non_dma_ctrs_obm_lossy_lo_drop"); 4646 4647 if (non_dma1->extra_ctrs == NULL) { 4648 non_dma1->extra_ctr_ct = 0; 4649 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4650 return SOC_E_MEMORY; 4651 } else { 4652 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4653 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4654 non_dma1, 4655 non_dma1->extra_ctrs, 4656 non_dma1->extra_ctr_ct, 4657 &num_extra_ctr_entries); 4658 if (rv != SOC_E_NONE) { 4659 LOG_CLI((BSL_META_U(unit, 4660 "ERR: Extra ctrs Init FAILED for id %d\n"), 4661 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4662 } 4663 non_dma1->num_entries = num_extra_ctr_entries; 4664 } 4665 *non_dma_entries += non_dma1->num_entries; 4666 4667 /* Lossy_lo enqueue counters - Byte Counters */ 4668 non_dma1 = 4669 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO - 4670 SOC_COUNTER_NON_DMA_START]; 4671 *non_dma1 = *non_dma0; 4672 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO; 4673 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4674 non_dma1->reg = IDB_OBM0_LOSSY_LO_ARRIVAL_BYTE_COUNTr; 4675 non_dma1->field = COUNTERf; 4676 non_dma1->cname = "OBM_LOSSY_LO_ENQ_BYTE"; 4677 4678 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4679 non_dma1->extra_ctrs = temp + 1; 4680 if (non_dma1->extra_ctrs) { 4681 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4682 non_dma1, 4683 non_dma1->extra_ctrs, 4684 non_dma1->extra_ctr_ct, 4685 &num_extra_ctr_entries); 4686 if (rv != SOC_E_NONE) { 4687 LOG_CLI((BSL_META_U(unit, 4688 "ERR: Extra ctrs Init FAILED for id %d\n"), 4689 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4690 } 4691 } 4692 *non_dma_entries += non_dma1->num_entries; 4693 4694 /* Lossy_hi enqueue counters - Packet counters */ 4695 non_dma1 = 4696 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI - 4697 SOC_COUNTER_NON_DMA_START]; 4698 *non_dma1 = *non_dma0; 4699 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI; 4700 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4701 non_dma1->reg = IDB_OBM0_LOSSY_HI_ARRIVAL_PKT_COUNTr; 4702 non_dma1->cname = "OBM_LOSSY_HI_ENQ_PKT"; 4703 4704 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4705 "non_dma_ctrs_obm_lossy_hi_drop"); 4706 4707 if (non_dma1->extra_ctrs == NULL) { 4708 non_dma1->extra_ctr_ct = 0; 4709 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4710 return SOC_E_MEMORY; 4711 } else { 4712 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4713 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4714 non_dma1, 4715 non_dma1->extra_ctrs, 4716 non_dma1->extra_ctr_ct, 4717 &num_extra_ctr_entries); 4718 if (rv != SOC_E_NONE) { 4719 LOG_CLI((BSL_META_U(unit, 4720 "ERR: Extra ctrs Init FAILED for id %d\n"), 4721 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4722 } 4723 non_dma1->num_entries = num_extra_ctr_entries; 4724 } 4725 *non_dma_entries += non_dma1->num_entries; 4726 4727 /* Lossy_hi enqueue counters - Byte Counters */ 4728 non_dma1 = 4729 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI - 4730 SOC_COUNTER_NON_DMA_START]; 4731 *non_dma1 = *non_dma0; 4732 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI; 4733 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4734 non_dma1->reg = IDB_OBM0_LOSSY_HI_ARRIVAL_BYTE_COUNTr; 4735 non_dma1->field = COUNTERf; 4736 non_dma1->cname = "OBM_LOSSY_HI_ENQ_BYTE"; 4737 4738 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4739 non_dma1->extra_ctrs = temp + 1; 4740 if (non_dma1->extra_ctrs) { 4741 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4742 non_dma1, 4743 non_dma1->extra_ctrs, 4744 non_dma1->extra_ctr_ct, 4745 &num_extra_ctr_entries); 4746 if (rv != SOC_E_NONE) { 4747 LOG_CLI((BSL_META_U(unit, 4748 "ERR: Extra ctrs Init FAILED for id %d\n"), 4749 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4750 } 4751 } 4752 *non_dma_entries += non_dma1->num_entries; 4753 4754 /* Lossless0 enqueue counters - Packet counters */ 4755 non_dma1 = 4756 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0 - 4757 SOC_COUNTER_NON_DMA_START]; 4758 *non_dma1 = *non_dma0; 4759 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0; 4760 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4761 non_dma1->reg = IDB_OBM0_LOSSLESS0_ARRIVAL_PKT_COUNTr; 4762 non_dma1->cname = "OBM_LOSSLESS0_ENQ_PKT"; 4763 4764 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4765 "non_dma_ctrs_obm_lossless0_enqueue"); 4766 4767 if (non_dma1->extra_ctrs == NULL) { 4768 non_dma1->extra_ctr_ct = 0; 4769 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4770 return SOC_E_MEMORY; 4771 } else { 4772 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4773 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4774 non_dma1, 4775 non_dma1->extra_ctrs, 4776 non_dma1->extra_ctr_ct, 4777 &num_extra_ctr_entries); 4778 if (rv != SOC_E_NONE) { 4779 LOG_CLI((BSL_META_U(unit, 4780 "ERR: Extra ctrs Init FAILED for id %d\n"), 4781 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4782 } 4783 non_dma1->num_entries = num_extra_ctr_entries; 4784 } 4785 *non_dma_entries += non_dma1->num_entries; 4786 4787 /* Lossless0 enqueue counters - Byte Counters */ 4788 non_dma1 = 4789 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0 - 4790 SOC_COUNTER_NON_DMA_START]; 4791 *non_dma1 = *non_dma0; 4792 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0; 4793 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4794 non_dma1->reg = IDB_OBM0_LOSSLESS0_ARRIVAL_BYTE_COUNTr; 4795 non_dma1->field = COUNTERf; 4796 non_dma1->cname = "OBM_LOSSLESS0_ENQ_BYTE"; 4797 4798 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4799 non_dma1->extra_ctrs = temp + 1; 4800 if (non_dma1->extra_ctrs) { 4801 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4802 non_dma1, 4803 non_dma1->extra_ctrs, 4804 non_dma1->extra_ctr_ct, 4805 &num_extra_ctr_entries); 4806 if (rv != SOC_E_NONE) { 4807 LOG_CLI((BSL_META_U(unit, 4808 "ERR: Extra ctrs Init FAILED for id %d\n"), 4809 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4810 } 4811 } 4812 *non_dma_entries += non_dma1->num_entries; 4813 4814 /* Lossless1 enqueue counters - Packet counters */ 4815 non_dma1 = 4816 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1 - 4817 SOC_COUNTER_NON_DMA_START]; 4818 *non_dma1 = *non_dma0; 4819 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1; 4820 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4821 non_dma1->reg = IDB_OBM0_LOSSLESS1_ARRIVAL_PKT_COUNTr; 4822 non_dma1->cname = "OBM_LOSSLESS1_ENQ_PKT"; 4823 4824 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4825 "non_dma_ctrs_obm_lossless1_enqueue"); 4826 4827 if (non_dma1->extra_ctrs == NULL) { 4828 non_dma1->extra_ctr_ct = 0; 4829 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4830 return SOC_E_MEMORY; 4831 } else { 4832 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4833 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4834 non_dma1, 4835 non_dma1->extra_ctrs, 4836 non_dma1->extra_ctr_ct, 4837 &num_extra_ctr_entries); 4838 if (rv != SOC_E_NONE) { 4839 LOG_CLI((BSL_META_U(unit, 4840 "ERR: Extra ctrs Init FAILED for id %d\n"), 4841 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4842 } 4843 non_dma1->num_entries = num_extra_ctr_entries; 4844 } 4845 *non_dma_entries += non_dma1->num_entries; 4846 4847 /* Lossless1 enqueue counters - Byte Counters */ 4848 non_dma1 = 4849 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1 - 4850 SOC_COUNTER_NON_DMA_START]; 4851 *non_dma1 = *non_dma0; 4852 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1; 4853 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4854 non_dma1->reg = IDB_OBM0_LOSSLESS1_ARRIVAL_BYTE_COUNTr; 4855 non_dma1->field = COUNTERf; 4856 non_dma1->cname = "OBM_LOSSLESS1_ENQ_BYTE"; 4857 4858 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4859 non_dma1->extra_ctrs = temp + 1; 4860 if (non_dma1->extra_ctrs) { 4861 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4862 non_dma1, 4863 non_dma1->extra_ctrs, 4864 non_dma1->extra_ctr_ct, 4865 &num_extra_ctr_entries); 4866 if (rv != SOC_E_NONE) { 4867 LOG_CLI((BSL_META_U(unit, 4868 "ERR: Extra ctrs Init FAILED for id %d\n"), 4869 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4870 } 4871 } 4872 *non_dma_entries += non_dma1->num_entries; 4873 4874 /* Express enqueue counters - Packet counters */ 4875 non_dma1 = 4876 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS - 4877 SOC_COUNTER_NON_DMA_START]; 4878 *non_dma1 = *non_dma0; 4879 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS; 4880 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4881 non_dma1->reg = IDB_OBM0_EXPRESS_ARRIVAL_PKT_COUNTr; 4882 non_dma1->cname = "OBM_EXPRESS_ENQ_PKT"; 4883 4884 temp = non_dma1->extra_ctrs = sal_alloc(alloc_size, 4885 "non_dma_ctrs_obm_express_enqueue"); 4886 4887 if (non_dma1->extra_ctrs == NULL) { 4888 non_dma1->extra_ctr_ct = 0; 4889 non_dma1->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 4890 return SOC_E_MEMORY; 4891 } else { 4892 sal_memset(non_dma1->extra_ctrs, 0, alloc_size); 4893 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4894 non_dma1, 4895 non_dma1->extra_ctrs, 4896 non_dma1->extra_ctr_ct, 4897 &num_extra_ctr_entries); 4898 if (rv != SOC_E_NONE) { 4899 LOG_CLI((BSL_META_U(unit, 4900 "ERR: Extra ctrs Init FAILED for id %d\n"), 4901 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4902 } 4903 non_dma1->num_entries = num_extra_ctr_entries; 4904 } 4905 *non_dma_entries += non_dma1->num_entries; 4906 4907 /* Express enqueue counters - Byte Counters */ 4908 non_dma1 = 4909 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS - 4910 SOC_COUNTER_NON_DMA_START]; 4911 *non_dma1 = *non_dma0; 4912 non_dma1->id = SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS; 4913 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 4914 non_dma1->reg = IDB_OBM0_EXPRESS_ARRIVAL_BYTE_COUNTr; 4915 non_dma1->field = COUNTERf; 4916 non_dma1->cname = "OBM_EXPRESS_ENQ_BYTE"; 4917 4918 /* Memory for extra ctrs for BYTE_CTRS are done along with PACKET_CTR */ 4919 non_dma1->extra_ctrs = temp + 1; 4920 if (non_dma1->extra_ctrs) { 4921 rv = soc_counter_common_extra_obm_ctrs_init(unit, 4922 non_dma1, 4923 non_dma1->extra_ctrs, 4924 non_dma1->extra_ctr_ct, 4925 &num_extra_ctr_entries); 4926 if (rv != SOC_E_NONE) { 4927 LOG_CLI((BSL_META_U(unit, 4928 "ERR: Extra ctrs Init FAILED for id %d\n"), 4929 non_dma1->id - SOC_COUNTER_NON_DMA_START)); 4930 } 4931 } 4932 *non_dma_entries += non_dma1->num_entries; 4933 } 4934 /* End of Control block for IDB OBM counters */ 4935 4936 return SOC_E_NONE; 4937 } 4938 #endif /* BCM_APACHE_SUPPORT */ 4939 4940 4941 4942 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT ) 4943 STATIC int 4944 _soc_counter_trident2_non_dma_init(int unit, int nports, 4945 int non_dma_start_index, 4946 int *non_dma_entries) 4947 { 4948 soc_control_t *soc; 4949 soc_counter_non_dma_t *non_dma0, *non_dma1, *non_dma2; 4950 int alloc_size; 4951 uint32 *buf; 4952 int full_chip = 1; 4953 4954 soc = SOC_CONTROL(unit); 4955 *non_dma_entries = 0; 4956 4957 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4958 if (SAL_BOOT_QUICKTURN) { 4959 if ( !soc_td2p_if_full_chip(unit)) { 4960 /* testing with half chip */ 4961 full_chip = 0; 4962 } 4963 } 4964 #endif 4965 4966 /* MMU_CTR_UC_DROP_MEM is the largest table to be DMA'ed */ 4967 4968 alloc_size = 2 * soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm) * 4969 sizeof(uint32) * soc_mem_entry_words(unit, MMU_CTR_UC_DROP_MEMm); 4970 4971 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 4972 if (buf == NULL) { 4973 return SOC_E_MEMORY; 4974 } 4975 sal_memset(buf, 0, alloc_size); 4976 4977 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 4978 SOC_COUNTER_NON_DMA_START]; 4979 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 4980 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 4981 non_dma0->pbmp = PBMP_ALL(unit); 4982 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 4983 non_dma0->entries_per_port = 48; /* cpu port has max number of queues */ 4984 non_dma0->num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) * ((full_chip)? 2 : 1); 4985 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 4986 non_dma0->reg = INVALIDr; 4987 non_dma0->field = PACKET_COUNTERf; 4988 non_dma0->cname = "MC_PERQ_PKT"; 4989 non_dma0->dma_buf[0] = buf; 4990 non_dma0->dma_buf[1] = (full_chip)? 4991 &buf[soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) * 4992 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERS_Xm)] : NULL; 4993 non_dma0->dma_index_max[0] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) - 1; 4994 non_dma0->dma_index_max[1] = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERS_Xm) - 1; 4995 non_dma0->dma_mem[0] = EGR_PERQ_XMT_COUNTERS_Xm; 4996 non_dma0->dma_mem[1] = EGR_PERQ_XMT_COUNTERS_Ym; 4997 *non_dma_entries += non_dma0->num_entries; 4998 4999 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 5000 SOC_COUNTER_NON_DMA_START]; 5001 *non_dma1 = *non_dma0; 5002 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5003 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5004 non_dma1->field = BYTE_COUNTERf; 5005 non_dma1->cname = "MC_PERQ_BYTE"; 5006 *non_dma_entries += non_dma1->num_entries; 5007 5008 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC - 5009 SOC_COUNTER_NON_DMA_START]; 5010 *non_dma2 = *non_dma0; 5011 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 5012 non_dma2->pbmp = PBMP_PORT_ALL(unit); 5013 non_dma2->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */ 5014 non_dma2->num_entries = 0; 5015 non_dma2->cname = "UC_PERQ_PKT"; 5016 5017 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC - 5018 SOC_COUNTER_NON_DMA_START]; 5019 *non_dma2 = *non_dma1; 5020 non_dma2->pbmp = PBMP_PORT_ALL(unit); 5021 non_dma2->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */ 5022 non_dma2->num_entries = 0; 5023 non_dma2->cname = "UC_PERQ_BYTE"; 5024 5025 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT - 5026 SOC_COUNTER_NON_DMA_START]; 5027 *non_dma2 = *non_dma0; 5028 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 5029 non_dma2->entries_per_port = 0; 5030 non_dma2->num_entries = 0; 5031 SOC_PBMP_CLEAR(non_dma2->pbmp); 5032 5033 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT - 5034 SOC_COUNTER_NON_DMA_START]; 5035 *non_dma2 = *non_dma1; 5036 non_dma2->entries_per_port = 0; 5037 non_dma2->num_entries = 0; 5038 SOC_PBMP_CLEAR(non_dma2->pbmp); 5039 5040 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 5041 SOC_COUNTER_NON_DMA_START]; 5042 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5043 _SOC_COUNTER_NON_DMA_DO_DMA; 5044 non_dma0->pbmp = PBMP_ALL(unit); 5045 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5046 non_dma0->entries_per_port = 48; /* 48 for cpu port */ 5047 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM0m) + 5048 soc_mem_index_count(unit, MMU_CTR_MC_DROP_MEM1m); 5049 non_dma0->mem = MMU_CTR_MC_DROP_MEM0m; 5050 non_dma0->reg = INVALIDr; 5051 non_dma0->field = PKTCNTf; 5052 non_dma0->cname = "MCQ_DROP_PKT"; 5053 non_dma0->dma_mem[0] = MMU_CTR_MC_DROP_MEM0m; 5054 non_dma0->dma_mem[1] = MMU_CTR_MC_DROP_MEM1m; 5055 non_dma0->dma_buf[0] = buf; 5056 non_dma0->dma_buf[1] = 5057 &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) * 5058 soc_mem_entry_words(unit, non_dma0->dma_mem[0])]; 5059 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 5060 non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]); 5061 *non_dma_entries += non_dma0->num_entries; 5062 5063 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 5064 SOC_COUNTER_NON_DMA_START]; 5065 *non_dma1 = *non_dma0; 5066 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5067 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5068 non_dma1->field = BYTECNTf; 5069 non_dma1->cname = "MCQ_DROP_BYTE"; 5070 *non_dma_entries += non_dma1->num_entries; 5071 5072 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC - 5073 SOC_COUNTER_NON_DMA_START]; 5074 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 5075 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5076 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5077 non_dma0->entries_per_port = 16; /* front pannel port has max 16 L2 UC queues */ 5078 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_UC_DROP_MEMm); 5079 non_dma0->mem = MMU_CTR_UC_DROP_MEMm; 5080 non_dma0->reg = INVALIDr; 5081 non_dma0->field = PKTCNTf; 5082 non_dma0->cname = "UCQ_DROP_PKT"; 5083 non_dma0->dma_buf[0] = buf; 5084 non_dma0->dma_buf[1] = 5085 &buf[1480 * soc_mem_entry_words(unit, non_dma0->mem)]; 5086 non_dma0->dma_index_max[0] = 1479; 5087 non_dma0->dma_index_min[1] = 1536; 5088 non_dma0->dma_index_max[1] = 3015; 5089 non_dma0->dma_mem[0] = non_dma0->mem; 5090 non_dma0->dma_mem[1] = non_dma0->mem; 5091 *non_dma_entries += non_dma0->num_entries; 5092 5093 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC - 5094 SOC_COUNTER_NON_DMA_START]; 5095 *non_dma1 = *non_dma0; 5096 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5097 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5098 non_dma1->field = BYTECNTf; 5099 non_dma1->cname = "UCQ_DROP_BYTE"; 5100 *non_dma_entries += non_dma1->num_entries; 5101 5102 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_EXT - 5103 SOC_COUNTER_NON_DMA_START]; 5104 *non_dma2 = *non_dma0; 5105 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID; 5106 non_dma2->entries_per_port = 0; 5107 non_dma2->num_entries = 0; 5108 SOC_PBMP_CLEAR(non_dma2->pbmp); 5109 5110 non_dma2 = 5111 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_EXT - 5112 SOC_COUNTER_NON_DMA_START]; 5113 *non_dma2 = *non_dma1; 5114 non_dma2->entries_per_port = 0; 5115 non_dma2->num_entries = 0; 5116 SOC_PBMP_CLEAR(non_dma2->pbmp); 5117 5118 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 5119 SOC_COUNTER_NON_DMA_START]; 5120 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 5121 non_dma0->pbmp = PBMP_ALL(unit); 5122 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5123 non_dma0->entries_per_port = 1; 5124 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm); 5125 non_dma0->mem = MMU_CTR_ING_DROP_MEMm; 5126 non_dma0->reg = INVALIDr; 5127 non_dma0->field = PKTCNTf; 5128 non_dma0->cname = "DROP_PKT_ING"; 5129 non_dma0->dma_buf[0] = buf; 5130 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem); 5131 non_dma0->dma_mem[0] = non_dma0->mem; 5132 *non_dma_entries += non_dma0->num_entries; 5133 5134 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 5135 SOC_COUNTER_NON_DMA_START]; 5136 *non_dma1 = *non_dma0; 5137 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5138 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5139 non_dma1->field = BYTECNTf; 5140 non_dma1->cname = "DROP_BYTE_ING"; 5141 *non_dma_entries += non_dma1->num_entries; 5142 5143 non_dma0 = 5144 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER - 5145 SOC_COUNTER_NON_DMA_START]; 5146 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | _SOC_COUNTER_NON_DMA_DO_DMA; 5147 non_dma0->pbmp = PBMP_ALL(unit); 5148 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5149 non_dma0->entries_per_port = 1; 5150 non_dma0->num_entries = soc_mem_index_count(unit, MMU_CTR_ING_DROP_MEMm); 5151 non_dma0->mem = MMU_CTR_MTRI_DROP_MEMm; 5152 non_dma0->reg = INVALIDr; 5153 non_dma0->field = PKTCNTf; 5154 non_dma0->cname = "DROP_PKT_IMTR"; 5155 non_dma0->dma_buf[0] = buf; 5156 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->mem); 5157 non_dma0->dma_mem[0] = non_dma0->mem; 5158 *non_dma_entries += non_dma0->num_entries; 5159 5160 non_dma1 = 5161 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER - 5162 SOC_COUNTER_NON_DMA_START]; 5163 *non_dma1 = *non_dma0; 5164 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5165 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5166 non_dma1->field = BYTECNTf; 5167 non_dma1->cname = "DROP_BYTE_IMTR"; 5168 *non_dma_entries += non_dma1->num_entries; 5169 5170 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 5171 SOC_COUNTER_NON_DMA_START]; 5172 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5173 _SOC_COUNTER_NON_DMA_DO_DMA; 5174 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5175 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5176 non_dma0->entries_per_port = 1; 5177 non_dma0->num_entries = 106; /* one per port */ 5178 non_dma0->mem = MMU_CTR_COLOR_DROP_MEMm; 5179 non_dma0->reg = INVALIDr; 5180 non_dma0->field = PKTCNTf; 5181 non_dma0->cname = "DROP_PKT_YEL"; 5182 non_dma0->dma_buf[0] = buf; 5183 non_dma0->dma_index_min[0] = 106 * 4; 5184 non_dma0->dma_index_max[0] = (106 * 4) + 105; 5185 non_dma0->dma_mem[0] = non_dma0->mem; 5186 *non_dma_entries += non_dma0->num_entries; 5187 5188 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 5189 SOC_COUNTER_NON_DMA_START]; 5190 *non_dma1 = *non_dma0; 5191 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5192 non_dma1->cname = "DROP_PKT_RED"; 5193 non_dma1->dma_index_min[0] = 106 * 3; 5194 non_dma1->dma_index_max[0] = (106 * 3) + 105; 5195 *non_dma_entries += non_dma1->num_entries; 5196 5197 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN - 5198 SOC_COUNTER_NON_DMA_START]; 5199 *non_dma1 = *non_dma0; 5200 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5201 non_dma1->cname = "WRED_PKT_GRE"; 5202 non_dma1->dma_index_min[0] = 106 * 2; 5203 non_dma1->dma_index_max[0] = (106 * 2) + 105; 5204 *non_dma_entries += non_dma1->num_entries; 5205 5206 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW - 5207 SOC_COUNTER_NON_DMA_START]; 5208 *non_dma1 = *non_dma0; 5209 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5210 non_dma1->cname = "WRED_PKT_YEL"; 5211 non_dma1->dma_index_min[0] = 106 * 1; 5212 non_dma1->dma_index_max[0] = (106 * 1) + 105; 5213 *non_dma_entries += non_dma1->num_entries; 5214 5215 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED - 5216 SOC_COUNTER_NON_DMA_START]; 5217 *non_dma1 = *non_dma0; 5218 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5219 non_dma1->cname = "WRED_PKT_RED"; 5220 non_dma1->dma_index_min[0] = 0; 5221 non_dma1->dma_index_max[0] = 105; 5222 *non_dma_entries += non_dma1->num_entries; 5223 5224 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT - 5225 SOC_COUNTER_NON_DMA_START]; 5226 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5227 _SOC_COUNTER_NON_DMA_DO_DMA; 5228 /* SDK-67053 : Setting the port bitmap so that this counter can 5229 be cleared by the "clear c" command */ 5230 non_dma0->pbmp = PBMP_ALL(unit); 5231 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5232 non_dma0->entries_per_port = 0; 5233 non_dma0->num_entries = 11; 5234 non_dma0->mem = INVALIDm; 5235 non_dma0->reg = DROP_PKT_CNT_RQE_PKTr; 5236 non_dma0->field = PKTCNTf; 5237 non_dma0->cname = "RQ_DROP_PKT"; 5238 non_dma0->dma_buf[0] = buf; 5239 *non_dma_entries += non_dma0->num_entries; 5240 5241 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_BYTE - 5242 SOC_COUNTER_NON_DMA_START]; 5243 *non_dma1 = *non_dma0; 5244 /* SDK-67053 : Setting the port bitmap so that this counter can 5245 be cleared by the "clear c" command */ 5246 non_dma1->pbmp = PBMP_ALL(unit); 5247 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5248 non_dma1->reg = DROP_PKT_CNT_RQE_BYTE_64r; 5249 non_dma1->field = BYTECNTf; 5250 non_dma1->cname = "RQ_DROP_BYTE"; 5251 *non_dma_entries += non_dma1->num_entries; 5252 5253 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW - 5254 SOC_COUNTER_NON_DMA_START]; 5255 *non_dma1 = *non_dma0; 5256 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5257 non_dma1->reg = DROP_PKT_CNT_RQE_YELr; 5258 non_dma1->field = PKTCNTf; 5259 non_dma1->cname = "RQ_DROP_PKT_YEL"; 5260 *non_dma_entries += non_dma1->num_entries; 5261 5262 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED - 5263 SOC_COUNTER_NON_DMA_START]; 5264 *non_dma1 = *non_dma0; 5265 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5266 non_dma1->reg = DROP_PKT_CNT_RQE_REDr; 5267 non_dma1->field = PKTCNTf; 5268 non_dma1->cname = "RQ_DROP_PKT_RED"; 5269 *non_dma_entries += non_dma1->num_entries; 5270 5271 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_PEAK - 5272 SOC_COUNTER_NON_DMA_START]; 5273 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5274 _SOC_COUNTER_NON_DMA_PEAK; 5275 SOC_PBMP_CLEAR(non_dma0->pbmp); 5276 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5277 non_dma0->entries_per_port = 0; 5278 non_dma0->num_entries = 4; 5279 non_dma0->mem = INVALIDm; 5280 non_dma0->reg = THDI_POOL_SHARED_COUNT_SPr; 5281 non_dma0->field = TOTAL_BUFFER_COUNTf; 5282 non_dma0->cname = "POOL_PEAK"; 5283 non_dma0->dma_buf[0] = buf; 5284 *non_dma_entries += non_dma0->num_entries; 5285 5286 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_POOL_CURRENT - 5287 SOC_COUNTER_NON_DMA_START]; 5288 *non_dma2 = *non_dma0; 5289 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5290 _SOC_COUNTER_NON_DMA_CURRENT; 5291 non_dma2->cname = "POOL_CUR"; 5292 5293 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_PEAK - 5294 SOC_COUNTER_NON_DMA_START]; 5295 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5296 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 5297 non_dma0->pbmp = PBMP_ALL(unit); 5298 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5299 non_dma0->entries_per_port = 8; 5300 non_dma0->num_entries = nports * non_dma0->entries_per_port; 5301 non_dma0->mem = THDI_PORT_PG_CNTRS_RT1_Xm; 5302 non_dma0->reg = INVALIDr; 5303 non_dma0->field = PG_MIN_COUNTf; 5304 non_dma0->cname = "PG_MIN_PEAK"; 5305 non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT1_Xm; 5306 non_dma0->dma_mem[1] = THDI_PORT_PG_CNTRS_RT1_Ym; 5307 non_dma0->dma_buf[0] = buf; 5308 non_dma0->dma_buf[1] = (full_chip)? 5309 &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) * 5310 soc_mem_entry_words(unit, non_dma0->dma_mem[0])] : NULL; 5311 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 5312 non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]); 5313 *non_dma_entries += non_dma0->num_entries; 5314 5315 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_MIN_CURRENT - 5316 SOC_COUNTER_NON_DMA_START]; 5317 *non_dma2 = *non_dma0; 5318 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5319 _SOC_COUNTER_NON_DMA_CURRENT; 5320 non_dma2->cname = "PG_MIN_CUR"; 5321 5322 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_PEAK - 5323 SOC_COUNTER_NON_DMA_START]; 5324 *non_dma1 = *non_dma0; 5325 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 5326 _SOC_COUNTER_NON_DMA_PEAK; 5327 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5328 non_dma1->field = PG_SHARED_COUNTf; 5329 non_dma1->cname = "PG_SHARED_PEAK"; 5330 *non_dma_entries += non_dma1->num_entries; 5331 5332 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT - 5333 SOC_COUNTER_NON_DMA_START]; 5334 *non_dma2 = *non_dma1; 5335 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5336 _SOC_COUNTER_NON_DMA_CURRENT; 5337 non_dma2->cname = "PG_SHARED_CUR"; 5338 5339 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_PEAK - 5340 SOC_COUNTER_NON_DMA_START]; 5341 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5342 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 5343 non_dma0->pbmp = PBMP_ALL(unit); 5344 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5345 non_dma0->entries_per_port = 8; 5346 non_dma0->num_entries = nports * non_dma0->entries_per_port; 5347 non_dma0->mem = THDI_PORT_PG_CNTRS_RT2_Xm; 5348 non_dma0->reg = INVALIDr; 5349 non_dma0->field = PG_HDRM_COUNTf; 5350 non_dma0->cname = "PG_HDRM_PEAK"; 5351 non_dma0->dma_mem[0] = THDI_PORT_PG_CNTRS_RT2_Xm; 5352 non_dma0->dma_mem[1] = THDI_PORT_PG_CNTRS_RT2_Ym; 5353 non_dma0->dma_buf[0] = buf; 5354 non_dma0->dma_buf[1] = (full_chip)? 5355 &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) * 5356 soc_mem_entry_words(unit, non_dma0->dma_mem[0])] : NULL; 5357 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 5358 non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]); 5359 *non_dma_entries += non_dma0->num_entries; 5360 5361 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT - 5362 SOC_COUNTER_NON_DMA_START]; 5363 *non_dma2 = *non_dma0; 5364 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5365 _SOC_COUNTER_NON_DMA_CURRENT; 5366 non_dma2->cname = "PG_HDRM_CUR"; 5367 5368 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_PEAK - 5369 SOC_COUNTER_NON_DMA_START]; 5370 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5371 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 5372 non_dma0->pbmp = PBMP_ALL(unit); 5373 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5374 non_dma0->entries_per_port = 48; /* 48 for cpu port */ 5375 non_dma0->num_entries = 5376 soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_0m) + 5377 soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_COUNT_1m); 5378 non_dma0->mem = MMU_THDM_DB_QUEUE_COUNT_0m; 5379 non_dma0->reg = INVALIDr; 5380 non_dma0->field = SHARED_COUNTf; 5381 non_dma0->cname = "QUEUE_PEAK"; 5382 non_dma0->dma_mem[0] = MMU_THDM_DB_QUEUE_COUNT_0m; 5383 non_dma0->dma_mem[1] = MMU_THDM_DB_QUEUE_COUNT_1m; 5384 non_dma0->dma_buf[0] = buf; 5385 non_dma0->dma_buf[1] = 5386 &buf[soc_mem_index_count(unit, non_dma0->dma_mem[0]) * 5387 soc_mem_entry_words(unit, non_dma0->dma_mem[0])]; 5388 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 5389 non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]); 5390 *non_dma_entries += non_dma0->num_entries; 5391 5392 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_QUEUE_CURRENT - 5393 SOC_COUNTER_NON_DMA_START]; 5394 *non_dma2 = *non_dma0; 5395 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5396 _SOC_COUNTER_NON_DMA_CURRENT; 5397 non_dma2->cname = "QUEUE_CUR"; 5398 5399 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK - 5400 SOC_COUNTER_NON_DMA_START]; 5401 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5402 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_PEAK; 5403 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5404 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5405 non_dma0->entries_per_port = 10; 5406 non_dma0->num_entries = 5407 soc_mem_index_count(unit, MMU_THDU_XPIPE_COUNTER_QUEUEm) + 5408 soc_mem_index_count(unit, MMU_THDU_YPIPE_COUNTER_QUEUEm); 5409 non_dma0->mem = MMU_THDU_XPIPE_COUNTER_QUEUEm; 5410 non_dma0->reg = INVALIDr; 5411 non_dma0->field = SHARED_COUNTf; 5412 non_dma0->cname = "UC_QUEUE_PEAK"; 5413 non_dma0->dma_mem[0] = MMU_THDU_XPIPE_COUNTER_QUEUEm; 5414 non_dma0->dma_mem[1] = MMU_THDU_YPIPE_COUNTER_QUEUEm; 5415 non_dma0->dma_buf[0] = buf; 5416 non_dma0->dma_buf[1] = 5417 &buf[((soc_mem_index_count(unit, non_dma0->dma_mem[0])) - 1) * 5418 soc_mem_entry_words(unit, non_dma0->dma_mem[0])]; 5419 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]) - 1; 5420 non_dma0->dma_index_max[1] = soc_mem_index_max(unit, non_dma0->dma_mem[1]); 5421 *non_dma_entries += non_dma0->num_entries; 5422 5423 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT - 5424 SOC_COUNTER_NON_DMA_START]; 5425 *non_dma2 = *non_dma0; 5426 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5427 _SOC_COUNTER_NON_DMA_CURRENT; 5428 non_dma2->cname = "UC_QUEUE_CUR"; 5429 5430 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_MMU_QCN_CNM - 5431 SOC_COUNTER_NON_DMA_START]; 5432 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5433 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_FLEX_MAPPING; 5434 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5435 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5436 non_dma0->entries_per_port = 10; 5437 non_dma0->num_entries = 2 * soc_mem_index_count(unit, MMU_QCN_CNM_COUNTERm); 5438 #ifdef BCM_TRIDENT2PLUS_SUPPORT 5439 if (SAL_BOOT_QUICKTURN && SOC_IS_TD2P_TT2P(unit)) { 5440 non_dma0->num_entries = 1; 5441 } 5442 #endif 5443 5444 non_dma0->mem = MMU_QCN_CNM_COUNTERm; 5445 non_dma0->reg = INVALIDr; 5446 non_dma0->field = CNM_CNTf; 5447 non_dma0->cname = "QCN_CNM_COUNTER"; 5448 non_dma0->dma_buf[0] = buf; 5449 non_dma0->dma_mem[0] = non_dma0->mem; 5450 non_dma0->dma_index_max[0] = soc_mem_index_max(unit, non_dma0->dma_mem[0]); 5451 non_dma0->soc_counter_hw_idx_get = soc_td2_qcn_counter_hw_index_get; 5452 *non_dma_entries += non_dma0->num_entries; 5453 5454 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI - 5455 SOC_COUNTER_NON_DMA_START]; 5456 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5457 _SOC_COUNTER_NON_DMA_OBM; 5458 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5459 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5460 non_dma0->entries_per_port = 4; 5461 non_dma0->num_entries = 32; 5462 non_dma0->mem = INVALIDm; 5463 non_dma0->reg = PGW_OBM0_HIGH_PRI_PKT_DROPr; 5464 non_dma0->field = COUNTERf; 5465 non_dma0->cname = "OBM0_HIGH_PRI_DROP_PKT"; 5466 non_dma0->dma_buf[0] = buf; 5467 *non_dma_entries += non_dma0->num_entries; 5468 5469 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI - 5470 SOC_COUNTER_NON_DMA_START]; 5471 *non_dma1 = *non_dma0; 5472 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5473 non_dma1->reg = PGW_OBM0_LOW_PRI_PKT_DROPr; 5474 non_dma1->field = COUNTERf; 5475 non_dma1->cname = "OBM0_LOW_PRI_DROP_PKT"; 5476 *non_dma_entries += non_dma1->num_entries; 5477 5478 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI - 5479 SOC_COUNTER_NON_DMA_START]; 5480 *non_dma1 = *non_dma0; 5481 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5482 non_dma1->reg = PGW_OBM0_HIGH_PRI_BYTE_DROPr; 5483 non_dma1->field = COUNTERf; 5484 non_dma1->cname = "OBM0_HIGH_PRI_DROP_BYTE"; 5485 *non_dma_entries += non_dma1->num_entries; 5486 5487 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI - 5488 SOC_COUNTER_NON_DMA_START]; 5489 *non_dma1 = *non_dma0; 5490 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5491 non_dma1->reg = PGW_OBM0_LOW_PRI_BYTE_DROPr; 5492 non_dma1->field = COUNTERf; 5493 non_dma1->cname = "OBM0_LOW_PRI_DROP_BYTE"; 5494 *non_dma_entries += non_dma1->num_entries; 5495 5496 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI - 5497 SOC_COUNTER_NON_DMA_START]; 5498 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5499 _SOC_COUNTER_NON_DMA_OBM; 5500 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5501 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5502 non_dma0->entries_per_port = 4; 5503 non_dma0->num_entries = 32; 5504 non_dma0->mem = INVALIDm; 5505 non_dma0->reg = PGW_OBM1_HIGH_PRI_PKT_DROPr; 5506 non_dma0->field = COUNTERf; 5507 non_dma0->cname = "OBM1_HIGH_PRI_DROP_PKT"; 5508 non_dma0->dma_buf[0] = buf; 5509 *non_dma_entries += non_dma0->num_entries; 5510 5511 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI - 5512 SOC_COUNTER_NON_DMA_START]; 5513 *non_dma1 = *non_dma0; 5514 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5515 non_dma1->reg = PGW_OBM1_LOW_PRI_PKT_DROPr; 5516 non_dma1->field = COUNTERf; 5517 non_dma1->cname = "OBM1_LOW_PRI_DROP_PKT"; 5518 *non_dma_entries += non_dma1->num_entries; 5519 5520 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI - 5521 SOC_COUNTER_NON_DMA_START]; 5522 *non_dma1 = *non_dma0; 5523 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5524 non_dma1->reg = PGW_OBM1_HIGH_PRI_BYTE_DROPr; 5525 non_dma1->field = COUNTERf; 5526 non_dma1->cname = "OBM1_HIGH_PRI_DROP_BYTE"; 5527 *non_dma_entries += non_dma1->num_entries; 5528 5529 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI - 5530 SOC_COUNTER_NON_DMA_START]; 5531 *non_dma1 = *non_dma0; 5532 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5533 non_dma1->reg = PGW_OBM1_LOW_PRI_BYTE_DROPr; 5534 non_dma1->field = COUNTERf; 5535 non_dma1->cname = "OBM1_LOW_PRI_DROP_BYTE"; 5536 *non_dma_entries += non_dma1->num_entries; 5537 5538 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI - 5539 SOC_COUNTER_NON_DMA_START]; 5540 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5541 _SOC_COUNTER_NON_DMA_OBM; 5542 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5543 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5544 non_dma0->entries_per_port = 4; 5545 non_dma0->num_entries = 32; 5546 non_dma0->mem = INVALIDm; 5547 non_dma0->reg = PGW_OBM2_HIGH_PRI_PKT_DROPr; 5548 non_dma0->field = COUNTERf; 5549 non_dma0->cname = "OBM2_HIGH_PRI_DROP_PKT"; 5550 non_dma0->dma_buf[0] = buf; 5551 *non_dma_entries += non_dma0->num_entries; 5552 5553 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI - 5554 SOC_COUNTER_NON_DMA_START]; 5555 *non_dma1 = *non_dma0; 5556 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5557 non_dma1->reg = PGW_OBM2_LOW_PRI_PKT_DROPr; 5558 non_dma1->field = COUNTERf; 5559 non_dma1->cname = "OBM2_LOW_PRI_DROP_PKT"; 5560 *non_dma_entries += non_dma1->num_entries; 5561 5562 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI - 5563 SOC_COUNTER_NON_DMA_START]; 5564 *non_dma1 = *non_dma0; 5565 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5566 non_dma1->reg = PGW_OBM2_HIGH_PRI_BYTE_DROPr; 5567 non_dma1->field = COUNTERf; 5568 non_dma1->cname = "OBM2_HIGH_PRI_DROP_BYTE"; 5569 *non_dma_entries += non_dma1->num_entries; 5570 5571 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI - 5572 SOC_COUNTER_NON_DMA_START]; 5573 *non_dma1 = *non_dma0; 5574 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5575 non_dma1->reg = PGW_OBM2_LOW_PRI_BYTE_DROPr; 5576 non_dma1->field = COUNTERf; 5577 non_dma1->cname = "OBM2_LOW_PRI_DROP_BYTE"; 5578 *non_dma_entries += non_dma1->num_entries; 5579 5580 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI - 5581 SOC_COUNTER_NON_DMA_START]; 5582 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5583 _SOC_COUNTER_NON_DMA_OBM; 5584 non_dma0->pbmp = PBMP_PORT_ALL(unit); 5585 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5586 non_dma0->entries_per_port = 4; 5587 non_dma0->num_entries = 32; 5588 non_dma0->mem = INVALIDm; 5589 non_dma0->reg = PGW_OBM3_HIGH_PRI_PKT_DROPr; 5590 non_dma0->field = COUNTERf; 5591 non_dma0->cname = "OBM3_HIGH_PRI_DROP_PKT"; 5592 non_dma0->dma_buf[0] = buf; 5593 *non_dma_entries += non_dma0->num_entries; 5594 5595 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI - 5596 SOC_COUNTER_NON_DMA_START]; 5597 *non_dma1 = *non_dma0; 5598 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5599 non_dma1->reg = PGW_OBM3_LOW_PRI_PKT_DROPr; 5600 non_dma1->field = COUNTERf; 5601 non_dma1->cname = "OBM3_LOW_PRI_DROP_PKT"; 5602 *non_dma_entries += non_dma1->num_entries; 5603 5604 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI - 5605 SOC_COUNTER_NON_DMA_START]; 5606 *non_dma1 = *non_dma0; 5607 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5608 non_dma1->reg = PGW_OBM3_HIGH_PRI_BYTE_DROPr; 5609 non_dma1->field = COUNTERf; 5610 non_dma1->cname = "OBM3_HIGH_PRI_DROP_BYTE"; 5611 *non_dma_entries += non_dma1->num_entries; 5612 5613 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI - 5614 SOC_COUNTER_NON_DMA_START]; 5615 *non_dma1 = *non_dma0; 5616 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5617 non_dma1->reg = PGW_OBM3_LOW_PRI_BYTE_DROPr; 5618 non_dma1->field = COUNTERf; 5619 non_dma1->cname = "OBM3_LOW_PRI_DROP_BYTE"; 5620 *non_dma_entries += non_dma1->num_entries; 5621 5622 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_PEAK - 5623 SOC_COUNTER_NON_DMA_START]; 5624 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5625 _SOC_COUNTER_NON_DMA_PEAK; 5626 SOC_PBMP_CLEAR(non_dma0->pbmp); 5627 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5628 non_dma0->entries_per_port = 0; 5629 non_dma0->num_entries = 1; 5630 non_dma0->mem = INVALIDm; 5631 non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEXr; 5632 non_dma0->field = GLOBAL_HDRM_COUNTf; 5633 5634 non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK"; 5635 non_dma0->dma_buf[0] = buf; 5636 *non_dma_entries += non_dma0->num_entries; 5637 5638 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_X_CURRENT - 5639 SOC_COUNTER_NON_DMA_START]; 5640 *non_dma2 = *non_dma0; 5641 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5642 _SOC_COUNTER_NON_DMA_CURRENT; 5643 non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR"; 5644 5645 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_PEAK - 5646 SOC_COUNTER_NON_DMA_START]; 5647 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5648 _SOC_COUNTER_NON_DMA_PEAK; 5649 SOC_PBMP_CLEAR(non_dma0->pbmp); 5650 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5651 non_dma0->entries_per_port = 0; 5652 non_dma0->num_entries = 1; 5653 non_dma0->mem = INVALIDm; 5654 non_dma0->reg = THDI_GLOBAL_HDRM_COUNT_PIPEYr; 5655 non_dma0->field = GLOBAL_HDRM_COUNTf; 5656 non_dma0->cname = "GLOBAL_HDRM_COUNT_PEAK"; 5657 non_dma0->dma_buf[0] = buf; 5658 *non_dma_entries += non_dma0->num_entries; 5659 5660 non_dma2 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_GLOBAL_HDR_COUNT_Y_CURRENT - 5661 SOC_COUNTER_NON_DMA_START]; 5662 *non_dma2 = *non_dma0; 5663 non_dma2->flags = _SOC_COUNTER_NON_DMA_VALID | 5664 _SOC_COUNTER_NON_DMA_CURRENT; 5665 non_dma2->cname = "GLOBAL_HDRM_COUNT_CURR"; 5666 5667 5668 5669 5670 return SOC_E_NONE; 5671 5672 } 5673 #endif /* BCM_TRIDENT2_SUPPORT || BCM_TRIDENT2PLUS_SUPPORT */ 5674 5675 #ifdef BCM_HURRICANE_SUPPORT 5676 /* 5677 * Function: 5678 * _soc_counter_hu_non_dma_init 5679 * Purpose: 5680 * Initialize Hurricane's non-DMA counters. 5681 * Parameters: 5682 * unit - The SOC unit number 5683 * nports - Number of ports. 5684 * non_dma_start_index - The starting index of non-DMA counter entries. 5685 * non_dma_entries - (OUT) The number of non-DMA counter entries. 5686 * Returns: 5687 * SOC_E_NONE 5688 * SOC_E_MEMORY 5689 */ 5690 STATIC int 5691 _soc_counter_hu_non_dma_init(int unit, int nports, int non_dma_start_index, 5692 int *non_dma_entries) 5693 { 5694 soc_control_t *soc; 5695 soc_counter_non_dma_t *non_dma0, *non_dma1; 5696 int max_cosq_per_port, total_num_cosq, port; 5697 int num_entries, alloc_size; 5698 uint32 *buf; 5699 5700 soc = SOC_CONTROL(unit); 5701 *non_dma_entries = 0; 5702 5703 max_cosq_per_port = 0; 5704 total_num_cosq = 0; 5705 for (port = 0; port < nports; port++) { 5706 if (num_cosq[unit][port] > max_cosq_per_port) { 5707 max_cosq_per_port = num_cosq[unit][port]; 5708 } 5709 total_num_cosq += num_cosq[unit][port]; 5710 } 5711 5712 num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm); 5713 alloc_size = num_entries * 5714 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32); 5715 5716 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 5717 if (buf == NULL) { 5718 return SOC_E_MEMORY; 5719 } 5720 sal_memset(buf, 0, alloc_size); 5721 5722 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 5723 SOC_COUNTER_NON_DMA_START]; 5724 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5725 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 5726 non_dma0->pbmp = PBMP_ALL(unit); 5727 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5728 non_dma0->entries_per_port = max_cosq_per_port; 5729 non_dma0->num_entries = num_entries; 5730 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 5731 non_dma0->reg = INVALIDr; 5732 non_dma0->field = PACKET_COUNTERf; 5733 non_dma0->cname = "PERQ_PKT"; 5734 non_dma0->dma_buf[0] = buf; 5735 non_dma0->dma_index_max[0] = num_entries - 1; 5736 non_dma0->dma_mem[0] = non_dma0->mem; 5737 *non_dma_entries += non_dma0->num_entries; 5738 5739 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 5740 SOC_COUNTER_NON_DMA_START]; 5741 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 5742 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5743 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5744 non_dma1->field = BYTE_COUNTERf; 5745 non_dma1->cname = "PERQ_BYTE"; 5746 *non_dma_entries += non_dma1->num_entries; 5747 5748 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 5749 SOC_COUNTER_NON_DMA_START]; 5750 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5751 non_dma0->pbmp = PBMP_ALL(unit); 5752 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5753 non_dma0->entries_per_port = 1; 5754 non_dma0->num_entries = nports; 5755 non_dma0->mem = INVALIDm; 5756 non_dma0->reg = CNGDROPCOUNT1r; 5757 non_dma0->field = DROPPKTCOUNTf; 5758 non_dma0->cname = "DROP_PKT_YEL"; 5759 *non_dma_entries += non_dma0->num_entries; 5760 5761 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 5762 SOC_COUNTER_NON_DMA_START]; 5763 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5764 non_dma0->pbmp = PBMP_ALL(unit); 5765 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5766 non_dma0->entries_per_port = 1; 5767 non_dma0->num_entries = nports; 5768 non_dma0->mem = INVALIDm; 5769 non_dma0->reg = CNGDROPCOUNT0r; 5770 non_dma0->field = DROPPKTCOUNTf; 5771 non_dma0->cname = "DROP_PKT_RED"; 5772 *non_dma_entries += non_dma0->num_entries; 5773 5774 if (SOC_IS_HURRICANE2(unit)) { 5775 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 5776 SOC_COUNTER_NON_DMA_START]; 5777 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5778 non_dma0->pbmp = PBMP_ALL(unit); 5779 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5780 non_dma0->entries_per_port = max_cosq_per_port; 5781 non_dma0->num_entries = total_num_cosq; 5782 non_dma0->mem = INVALIDm; 5783 non_dma0->reg = EGRDROPPKTCOUNT_COSr; 5784 non_dma0->field = DROPPEDPKTCOUNTf; 5785 non_dma0->cname = "PERQ_DROP_PKT_EGR"; 5786 *non_dma_entries += non_dma0->num_entries; 5787 } 5788 5789 return SOC_E_NONE; 5790 } 5791 #endif /* BCM_HURRICANE_SUPPORT */ 5792 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 5793 /* 5794 * Function: 5795 * _soc_counter_gh_non_dma_init 5796 * Purpose: 5797 * Initialize Greyhound's non-DMA counters. 5798 * Parameters: 5799 * unit - The SOC unit number 5800 * nports - Number of ports. 5801 * non_dma_start_index - The starting index of non-DMA counter entries. 5802 * non_dma_entries - (OUT) The number of non-DMA counter entries. 5803 * Returns: 5804 * SOC_E_NONE 5805 * SOC_E_MEMORY 5806 */ 5807 STATIC int 5808 _soc_counter_gh_non_dma_init(int unit, int nports, 5809 int non_dma_start_index, int *non_dma_entries) 5810 { 5811 soc_control_t *soc; 5812 soc_counter_non_dma_t *non_dma0, *non_dma1; 5813 int max_cosq_per_port, total_num_cosq, port; 5814 int num_entries, alloc_size; 5815 uint32 *buf; 5816 5817 soc = SOC_CONTROL(unit); 5818 *non_dma_entries = 0; 5819 5820 max_cosq_per_port = 0; 5821 total_num_cosq = 0; 5822 for (port = 0; port < nports; port++) { 5823 if (num_cosq[unit][port] > max_cosq_per_port) { 5824 max_cosq_per_port = num_cosq[unit][port]; 5825 } 5826 total_num_cosq += num_cosq[unit][port]; 5827 } 5828 5829 num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm); 5830 alloc_size = num_entries * 5831 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32); 5832 5833 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 5834 if (buf == NULL) { 5835 return SOC_E_MEMORY; 5836 } 5837 sal_memset(buf, 0, alloc_size); 5838 5839 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 5840 SOC_COUNTER_NON_DMA_START]; 5841 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5842 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 5843 non_dma0->pbmp = PBMP_ALL(unit); 5844 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5845 non_dma0->entries_per_port = max_cosq_per_port; 5846 non_dma0->num_entries = num_entries; 5847 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 5848 non_dma0->reg = INVALIDr; 5849 non_dma0->field = PACKET_COUNTERf; 5850 non_dma0->cname = "PERQ_PKT"; 5851 non_dma0->dma_buf[0] = buf; 5852 non_dma0->dma_index_max[0] = num_entries - 1; 5853 non_dma0->dma_mem[0] = non_dma0->mem; 5854 *non_dma_entries += non_dma0->num_entries; 5855 5856 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 5857 SOC_COUNTER_NON_DMA_START]; 5858 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 5859 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 5860 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 5861 non_dma1->field = BYTE_COUNTERf; 5862 non_dma1->cname = "PERQ_BYTE"; 5863 *non_dma_entries += non_dma1->num_entries; 5864 5865 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 5866 SOC_COUNTER_NON_DMA_START]; 5867 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5868 non_dma0->pbmp = PBMP_ALL(unit); 5869 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5870 non_dma0->entries_per_port = 1; 5871 non_dma0->num_entries = nports; 5872 non_dma0->mem = INVALIDm; 5873 non_dma0->reg = CNGDROPCOUNT1r; 5874 non_dma0->field = DROPPKTCOUNTf; 5875 non_dma0->cname = "DROP_PKT_YEL"; 5876 *non_dma_entries += non_dma0->num_entries; 5877 5878 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 5879 SOC_COUNTER_NON_DMA_START]; 5880 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5881 non_dma0->pbmp = PBMP_ALL(unit); 5882 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5883 non_dma0->entries_per_port = 1; 5884 non_dma0->num_entries = nports; 5885 non_dma0->mem = INVALIDm; 5886 non_dma0->reg = CNGDROPCOUNT0r; 5887 non_dma0->field = DROPPKTCOUNTf; 5888 non_dma0->cname = "DROP_PKT_RED"; 5889 *non_dma_entries += non_dma0->num_entries; 5890 5891 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 5892 SOC_COUNTER_NON_DMA_START]; 5893 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5894 non_dma0->pbmp = PBMP_ALL(unit); 5895 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5896 non_dma0->entries_per_port = 1; 5897 non_dma0->num_entries = nports; 5898 non_dma0->mem = INVALIDm; 5899 non_dma0->reg = ING_DROPPKT_CNTr; 5900 non_dma0->field = FC_DROP_COUNTERf; 5901 non_dma0->cname = "DROP_PKT_ING"; 5902 *non_dma_entries += non_dma0->num_entries; 5903 5904 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 5905 SOC_COUNTER_NON_DMA_START]; 5906 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5907 non_dma0->pbmp = PBMP_ALL(unit); 5908 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5909 non_dma0->entries_per_port = max_cosq_per_port; 5910 non_dma0->num_entries = total_num_cosq; 5911 non_dma0->mem = INVALIDm; 5912 non_dma0->reg = EGRDROPPKTCOUNT_COSr; 5913 non_dma0->field = DROPPEDPKTCOUNTf; 5914 non_dma0->cname = "PERQ_DROP_PKT_EGR"; 5915 *non_dma_entries += non_dma0->num_entries; 5916 5917 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_DROP_PKT - 5918 SOC_COUNTER_NON_DMA_START]; 5919 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 5920 non_dma0->pbmp = PBMP_ALL(unit); 5921 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5922 non_dma0->entries_per_port = 1; 5923 non_dma0->num_entries = nports; 5924 non_dma0->mem = INVALIDm; 5925 non_dma0->reg = WRED_DROP_COUNTERr; 5926 non_dma0->field = COUNTERf; 5927 non_dma0->cname = "WRED_DROP_CNT"; 5928 *non_dma_entries += non_dma0->num_entries; 5929 5930 num_entries = soc_mem_index_count(unit, EGR_PER_Q_ECN_MARKEDm); 5931 alloc_size = num_entries * 5932 soc_mem_entry_words(unit, EGR_PER_Q_ECN_MARKEDm) * sizeof(uint32); 5933 5934 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 5935 if (buf == NULL) { 5936 return SOC_E_MEMORY; 5937 } 5938 sal_memset(buf, 0, alloc_size); 5939 5940 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_ECN_MARKED - 5941 SOC_COUNTER_NON_DMA_START]; 5942 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 5943 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 5944 non_dma0->pbmp = PBMP_ALL(unit); 5945 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 5946 non_dma0->entries_per_port = max_cosq_per_port; 5947 non_dma0->num_entries = num_entries; 5948 non_dma0->mem = EGR_PER_Q_ECN_MARKEDm; 5949 non_dma0->reg = INVALIDr; 5950 non_dma0->field = PACKET_COUNTERf; 5951 non_dma0->cname = "PERQ_ECN_MARKED"; 5952 non_dma0->dma_buf[0] = buf; 5953 non_dma0->dma_index_max[0] = num_entries - 1; 5954 non_dma0->dma_mem[0] = non_dma0->mem; 5955 *non_dma_entries += non_dma0->num_entries; 5956 5957 return SOC_E_NONE; 5958 } 5959 #endif /* BCM_GREYHOUND_SUPPORT || BCM_HURRICANE3_SUPPORT */ 5960 5961 #if defined(BCM_GREYHOUND2_SUPPORT) 5962 /* 5963 * Function: 5964 * _soc_counter_gh2_non_dma_init 5965 * Purpose: 5966 * Initialize Greyhound2's non-DMA counters. 5967 * Parameters: 5968 * unit - The SOC unit number 5969 * nports - Number of ports. 5970 * non_dma_start_index - The starting index of non-DMA counter entries. 5971 * non_dma_entries - (OUT) The number of non-DMA counter entries. 5972 * Returns: 5973 * SOC_E_NONE 5974 * SOC_E_MEMORY 5975 */ 5976 STATIC int 5977 _soc_counter_gh2_non_dma_init(int unit, int nports, 5978 int non_dma_start_index, int *non_dma_entries) 5979 { 5980 soc_control_t *soc; 5981 soc_counter_non_dma_t *non_dma0, *non_dma1; 5982 int max_cosq_per_port, total_num_cosq, port; 5983 int num_entries, alloc_size; 5984 uint32 *buf; 5985 5986 soc = SOC_CONTROL(unit); 5987 *non_dma_entries = 0; 5988 5989 max_cosq_per_port = 0; 5990 total_num_cosq = 0; 5991 for (port = 0; port < nports; port++) { 5992 if (num_cosq[unit][port] > max_cosq_per_port) { 5993 max_cosq_per_port = num_cosq[unit][port]; 5994 } 5995 total_num_cosq += num_cosq[unit][port]; 5996 } 5997 5998 num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm); 5999 alloc_size = num_entries * 6000 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32); 6001 6002 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6003 if (buf == NULL) { 6004 return SOC_E_MEMORY; 6005 } 6006 sal_memset(buf, 0, alloc_size); 6007 6008 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 6009 SOC_COUNTER_NON_DMA_START]; 6010 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6011 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6012 non_dma0->pbmp = PBMP_ALL(unit); 6013 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6014 non_dma0->entries_per_port = 64; 6015 non_dma0->num_entries = num_entries; 6016 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 6017 non_dma0->reg = INVALIDr; 6018 non_dma0->field = PACKET_COUNTERf; 6019 non_dma0->cname = "PERQ_PKT"; 6020 non_dma0->dma_buf[0] = buf; 6021 non_dma0->dma_index_max[0] = num_entries - 1; 6022 non_dma0->dma_mem[0] = non_dma0->mem; 6023 *non_dma_entries += non_dma0->num_entries; 6024 6025 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 6026 SOC_COUNTER_NON_DMA_START]; 6027 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6028 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 6029 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6030 non_dma1->field = BYTE_COUNTERf; 6031 non_dma1->cname = "PERQ_BYTE"; 6032 *non_dma_entries += non_dma1->num_entries; 6033 6034 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 6035 SOC_COUNTER_NON_DMA_START]; 6036 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6037 non_dma0->pbmp = PBMP_ALL(unit); 6038 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6039 non_dma0->entries_per_port = 1; 6040 non_dma0->num_entries = nports; 6041 non_dma0->mem = INVALIDm; 6042 non_dma0->reg = CNGDROPCOUNT1r; 6043 non_dma0->field = DROPPKTCOUNTf; 6044 non_dma0->cname = "DROP_PKT_YEL"; 6045 *non_dma_entries += non_dma0->num_entries; 6046 6047 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 6048 SOC_COUNTER_NON_DMA_START]; 6049 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6050 non_dma0->pbmp = PBMP_ALL(unit); 6051 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6052 non_dma0->entries_per_port = 1; 6053 non_dma0->num_entries = nports; 6054 non_dma0->mem = INVALIDm; 6055 non_dma0->reg = CNGDROPCOUNT0r; 6056 non_dma0->field = DROPPKTCOUNTf; 6057 non_dma0->cname = "DROP_PKT_RED"; 6058 *non_dma_entries += non_dma0->num_entries; 6059 6060 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 6061 SOC_COUNTER_NON_DMA_START]; 6062 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6063 non_dma0->pbmp = PBMP_ALL(unit); 6064 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6065 non_dma0->entries_per_port = 1; 6066 non_dma0->num_entries = nports; 6067 non_dma0->mem = INVALIDm; 6068 non_dma0->reg = ING_DROPPKT_CNTr; 6069 non_dma0->field = FC_DROP_COUNTERf; 6070 non_dma0->cname = "DROP_PKT_ING"; 6071 *non_dma_entries += non_dma0->num_entries; 6072 6073 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 6074 SOC_COUNTER_NON_DMA_START]; 6075 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6076 non_dma0->pbmp = PBMP_ALL(unit); 6077 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6078 non_dma0->entries_per_port = 64; 6079 non_dma0->num_entries = nports * non_dma0->entries_per_port; 6080 non_dma0->mem = INVALIDm; 6081 non_dma0->reg = EGRDROPPKTCOUNT_COSr; 6082 non_dma0->field = DROPPEDPKTCOUNTf; 6083 non_dma0->cname = "PERQ_DROP_PKT_EGR"; 6084 *non_dma_entries += non_dma0->num_entries; 6085 6086 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_WRED_DROP_PKT - 6087 SOC_COUNTER_NON_DMA_START]; 6088 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6089 non_dma0->pbmp = PBMP_ALL(unit); 6090 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6091 non_dma0->entries_per_port = 1; 6092 non_dma0->num_entries = nports; 6093 non_dma0->mem = INVALIDm; 6094 non_dma0->reg = WRED_DROP_COUNTERr; 6095 non_dma0->field = COUNTERf; 6096 non_dma0->cname = "WRED_DROP_CNT"; 6097 *non_dma_entries += non_dma0->num_entries; 6098 6099 num_entries = soc_mem_index_count(unit, EGR_PER_Q_ECN_MARKEDm); 6100 alloc_size = num_entries * 6101 soc_mem_entry_words(unit, EGR_PER_Q_ECN_MARKEDm) * sizeof(uint32); 6102 6103 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6104 if (buf == NULL) { 6105 return SOC_E_MEMORY; 6106 } 6107 sal_memset(buf, 0, alloc_size); 6108 6109 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_ECN_MARKED - 6110 SOC_COUNTER_NON_DMA_START]; 6111 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6112 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6113 non_dma0->pbmp = PBMP_ALL(unit); 6114 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6115 non_dma0->entries_per_port = max_cosq_per_port; 6116 non_dma0->num_entries = num_entries; 6117 non_dma0->mem = EGR_PER_Q_ECN_MARKEDm; 6118 non_dma0->reg = INVALIDr; 6119 non_dma0->field = PACKET_COUNTERf; 6120 non_dma0->cname = "PERQ_ECN_MARKED"; 6121 non_dma0->dma_buf[0] = buf; 6122 non_dma0->dma_index_max[0] = num_entries - 1; 6123 non_dma0->dma_mem[0] = non_dma0->mem; 6124 *non_dma_entries += non_dma0->num_entries; 6125 6126 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS- 6127 SOC_COUNTER_NON_DMA_START]; 6128 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6129 non_dma0->pbmp = PBMP_PORT_ALL(unit); 6130 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6131 non_dma0->entries_per_port = 1; 6132 non_dma0->num_entries = nports; 6133 non_dma0->mem = INVALIDm; 6134 non_dma0->reg = TAS_OVERRUN_PKT_CNT_EXPRESSr; 6135 non_dma0->field = CNTf; 6136 non_dma0->cname = "TAS_TXOVERRUN_EXPRESS"; 6137 *non_dma_entries += non_dma0->num_entries; 6138 6139 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT- 6140 SOC_COUNTER_NON_DMA_START]; 6141 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6142 non_dma0->pbmp = PBMP_PORT_ALL(unit); 6143 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6144 non_dma0->entries_per_port = 1; 6145 non_dma0->num_entries = nports; 6146 non_dma0->mem = INVALIDm; 6147 non_dma0->reg = TAS_OVERRUN_PKT_CNT_PREEMPTr; 6148 non_dma0->field = CNTf; 6149 non_dma0->cname = "TAS_TXOVERRUN_PREEMPT"; 6150 *non_dma_entries += non_dma0->num_entries; 6151 6152 non_dma0 = 6153 &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PREEMPT_MAC_MERGE_HOLD_CNT- 6154 SOC_COUNTER_NON_DMA_START]; 6155 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6156 non_dma0->pbmp = PBMP_ALL(unit); 6157 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6158 non_dma0->entries_per_port = 1; 6159 non_dma0->num_entries = nports; 6160 non_dma0->mem = INVALIDm; 6161 non_dma0->reg = MACMERGERHOLDCOUNTr; 6162 non_dma0->field = CNTf; 6163 non_dma0->cname = "PREEMPT_MACMERGE_HOLD_CNT"; 6164 *non_dma_entries += non_dma0->num_entries; 6165 6166 num_entries = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1; 6167 alloc_size = num_entries * 6168 soc_mem_entry_words(unit, ING_RX_COUNTERm) * sizeof(uint32); 6169 6170 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6171 if (buf == NULL) { 6172 return SOC_E_MEMORY; 6173 } 6174 sal_memset(buf, 0, alloc_size); 6175 6176 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_RX_COUNTER_NON_PREEMPTABLE_CNT - 6177 SOC_COUNTER_NON_DMA_START]; 6178 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6179 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6180 non_dma0->pbmp = PBMP_ALL(unit); 6181 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6182 non_dma0->entries_per_port = 1; 6183 non_dma0->num_entries = num_entries; 6184 non_dma0->mem = ING_RX_COUNTERm; 6185 non_dma0->reg = INVALIDr; 6186 non_dma0->field = COUNTf; 6187 non_dma0->cname = "ING_RX_NON_PREEMPTABLE_CNT"; 6188 non_dma0->dma_buf[0] = buf; 6189 non_dma0->dma_index_min[0] = 0; 6190 non_dma0->dma_index_max[0] = num_entries - 1; 6191 non_dma0->dma_mem[0] = non_dma0->mem; 6192 *non_dma_entries += non_dma0->num_entries; 6193 6194 num_entries = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1; 6195 alloc_size = num_entries * 6196 soc_mem_entry_words(unit, ING_RX_COUNTERm) * sizeof(uint32); 6197 6198 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6199 if (buf == NULL) { 6200 return SOC_E_MEMORY; 6201 } 6202 sal_memset(buf, 0, alloc_size); 6203 6204 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_ING_RX_COUNTER_PREEMPTABLE_CNT - 6205 SOC_COUNTER_NON_DMA_START]; 6206 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6207 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6208 non_dma0->pbmp = PBMP_ALL(unit); 6209 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6210 non_dma0->entries_per_port = 1; 6211 non_dma0->num_entries = num_entries; 6212 non_dma0->mem = ING_RX_COUNTERm; 6213 non_dma0->reg = INVALIDr; 6214 non_dma0->field = COUNTf; 6215 non_dma0->cname = "ING_RX_PREEMPTABLE_CNT"; 6216 non_dma0->dma_buf[0] = buf; 6217 non_dma0->dma_index_min[0] = soc_mem_index_count(unit, ING_RX_COUNTERm) >> 1; 6218 non_dma0->dma_index_max[0] = soc_mem_index_count(unit, ING_RX_COUNTERm) - 1; 6219 non_dma0->dma_mem[0] = non_dma0->mem; 6220 *non_dma_entries += non_dma0->num_entries; 6221 6222 num_entries = soc_mem_index_count(unit, EGR_MFRAME_COUNTERm); 6223 alloc_size = num_entries * 6224 soc_mem_entry_words(unit, EGR_MFRAME_COUNTERm) * sizeof(uint32); 6225 6226 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6227 if (buf == NULL) { 6228 return SOC_E_MEMORY; 6229 } 6230 sal_memset(buf, 0, alloc_size); 6231 6232 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_TX_COUNTER_PREEMPTABLE_CNT - 6233 SOC_COUNTER_NON_DMA_START]; 6234 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6235 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6236 non_dma0->pbmp = PBMP_ALL(unit); 6237 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6238 non_dma0->entries_per_port = 1; 6239 non_dma0->num_entries = num_entries; 6240 non_dma0->mem = EGR_MFRAME_COUNTERm; 6241 non_dma0->reg = INVALIDr; 6242 non_dma0->field = COUNTf; 6243 non_dma0->cname = "EGR_TX_PREEMPTABLE_CNT"; 6244 non_dma0->dma_buf[0] = buf; 6245 non_dma0->dma_index_min[0] = 0; 6246 non_dma0->dma_index_max[0] = num_entries - 1; 6247 non_dma0->dma_mem[0] = non_dma0->mem; 6248 *non_dma_entries += non_dma0->num_entries; 6249 6250 return SOC_E_NONE; 6251 } 6252 #endif /* BCM_GREYHOUND2_SUPPORT */ 6253 6254 #ifdef BCM_KATANA_SUPPORT 6255 6256 STATIC int 6257 _soc_counter_kt_cosq_gport_non_dma_init(int unit, int nports, 6258 int non_dma_start_index, 6259 int *non_dma_entries) 6260 { 6261 soc_control_t *soc; 6262 #ifdef BCM_KATANA2_SUPPORT 6263 soc_port_t my_port; 6264 #endif 6265 soc_counter_non_dma_t *non_dma0, *non_dma1; 6266 _kt_cosq_counter_mem_map_t *mem_map; 6267 int table_size, id; 6268 uint32 *buf; 6269 char *cname_pkt[] = { "DROP_PKT", "ACCEPT_PKT", 6270 "DROP_PKT_G", "DROP_PKT_Y", 6271 "DROP_PKT_R", "ACCEPT_PKT_G", 6272 "ACCEPT_PKT_Y", "ACCEPT_PKT_R", 6273 "PERQ_PKT" }; 6274 char *cname_byte[] = { "DROP_BYTE", "ACCEPT_BYTE", 6275 "DROP_BYTE_G", "DROP_BYTE_Y", 6276 "DROP_BYTE_R", "ACCEPT_BYTE_G", 6277 "ACCEPT_BYTE_Y", "ACCEPT_BYTE_R", 6278 "PERQ_BYTE" }; 6279 6280 soc = SOC_CONTROL(unit); 6281 *non_dma_entries = 0; 6282 6283 table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * 6284 soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m) * sizeof(uint32); 6285 6286 buf = soc_cm_salloc(unit, table_size, "non_dma_counter"); 6287 if (buf == NULL) { 6288 return SOC_E_MEMORY; 6289 } 6290 sal_memset(buf, 0, table_size); 6291 6292 mem_map = _kt_cosq_gport_mem_map; 6293 6294 /* 6295 * CTR_FLEX_COUNT_0 = Total ENQ discarded 6296 * CTR_FLEX_COUNT_1 = Total ENQ Accepted 6297 * CTR_FLEX_COUNT_2 = Green ENQ discarded 6298 * CTR_FLEX_COUNT_3 = Yellow ENQ discarded 6299 * CTR_FLEX_COUNT_4 = Red packet ENQ discarded 6300 * CTR_FLEX_COUNT_5 = Green ENQ Accepted 6301 * CTR_FLEX_COUNT_6 = Yellow ENQ Accepted 6302 * CTR_FLEX_COUNT_7 = Red ENQ Accepted 6303 * CTR_FLEX_COUNT_8 = Total DEQ 6304 */ 6305 for (id = 0; id < 9; id++) { 6306 if (soc_feature(unit, soc_feature_counter_toggled_read) && 6307 (mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT || 6308 mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_ACCEPT_PKT)) { 6309 continue; 6310 } 6311 non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6312 SOC_COUNTER_NON_DMA_START]; 6313 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6314 _SOC_COUNTER_NON_DMA_DO_DMA | 6315 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6316 if (id == 0) { 6317 non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC; 6318 } 6319 if (!soc_feature(unit, soc_feature_counter_toggled_read)) { 6320 /* adjust the extra count 1 in s/w counters */ 6321 if (!SOC_IS_KATANA2(unit)) { 6322 non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT; 6323 } 6324 } 6325 non_dma0->pbmp = PBMP_ALL(unit); 6326 #ifdef BCM_KATANA2_SUPPORT 6327 if (SOC_IS_KATANA2(unit)) { 6328 SOC_PBMP_CLEAR(non_dma0->pbmp); 6329 for (my_port = SOC_INFO(unit).cmic_port; 6330 my_port <= SOC_INFO(unit).lb_port; 6331 my_port++) { 6332 if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) { 6333 SOC_PBMP_PORT_ADD(non_dma0->pbmp, my_port); 6334 } 6335 } 6336 } 6337 #endif 6338 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6339 non_dma0->entries_per_port = 8; 6340 non_dma0->num_entries = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m); 6341 non_dma0->mem = mem_map[id].mem; 6342 non_dma0->reg = INVALIDr; 6343 non_dma0->field = COUNTf; 6344 non_dma0->cname = cname_pkt[id]; 6345 non_dma0->dma_buf[0] = buf; 6346 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 6347 non_dma0->dma_mem[0] = non_dma0->mem; 6348 *non_dma_entries += non_dma0->num_entries; 6349 6350 non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6351 SOC_COUNTER_NON_DMA_START + 1]; 6352 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6353 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 6354 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6355 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6356 non_dma1->field = BYTE_COUNTf; 6357 non_dma1->cname = cname_byte[id]; 6358 *non_dma_entries += non_dma1->num_entries; 6359 } 6360 6361 return SOC_E_NONE; 6362 } 6363 6364 /* 6365 * Function: 6366 * _soc_counter_katana_non_dma_init 6367 * Purpose: 6368 * Initialize Katana's non-DMA counters. 6369 * Parameters: 6370 * unit - The SOC unit number 6371 * nports - Number of ports. 6372 * non_dma_start_index - The starting index of non-DMA counter entries. 6373 * non_dma_entries - (OUT) The number of non-DMA counter entries. 6374 * Returns: 6375 * SOC_E_NONE 6376 * SOC_E_MEMORY 6377 */ 6378 STATIC int 6379 _soc_counter_katana_non_dma_init(int unit, int nports, int non_dma_start_index, 6380 int *non_dma_entries) 6381 { 6382 soc_control_t *soc; 6383 #ifdef BCM_KATANA2_SUPPORT 6384 soc_port_t my_port; 6385 #endif 6386 soc_counter_non_dma_t *non_dma0, *non_dma1; 6387 _kt_cosq_counter_mem_map_t *mem_map; 6388 int table_size; 6389 uint32 *buf; 6390 int i, id; 6391 int entry_words, buf_base; 6392 char *cname_pkt[] = { "DROP_PKT", "DROP_PKT_R", 6393 "PERQ_PKT" }; 6394 char *cname_byte[] = { "DROP_BYTE", "DROP_BYTE_R", 6395 "PERQ_BYTE" }; 6396 6397 if (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) { 6398 SOC_IF_ERROR_RETURN 6399 (_soc_counter_kt_cosq_gport_non_dma_init(unit, nports, 6400 non_dma_start_index, non_dma_entries)); 6401 return SOC_E_NONE; 6402 } 6403 mem_map = _kt_cosq_mem_map; 6404 soc = SOC_CONTROL(unit); 6405 *non_dma_entries = 0; 6406 6407 entry_words = soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m); 6408 table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * 4 * 6409 entry_words * sizeof(uint32); 6410 buf = soc_cm_salloc(unit, table_size, "non_dma_counter"); 6411 if (buf == NULL) { 6412 return SOC_E_MEMORY; 6413 } 6414 sal_memset(buf, 0, table_size); 6415 6416 /* 6417 * CTR_FLEX_COUNT_0/1/2/3 = Total ENQ discarded 6418 * CTR_FLEX_COUNT_4/5/6/7 = Red packet ENQ discarded 6419 * CTR_FLEX_COUNT_8/9/10/11 = Total DEQ 6420 */ 6421 for (id = 0; id < 12; id = id + 4) { 6422 if (soc_feature(unit, soc_feature_counter_toggled_read) && 6423 mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED) { 6424 continue; 6425 } 6426 non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6427 SOC_COUNTER_NON_DMA_START]; 6428 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6429 _SOC_COUNTER_NON_DMA_DO_DMA | 6430 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6431 if (id == 0) { 6432 non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC; 6433 } 6434 if (!soc_feature(unit, soc_feature_counter_toggled_read)) { 6435 /* adjust the extra count 1 in s/w counters */ 6436 if (!SOC_IS_KATANA2(unit)) { 6437 non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT; 6438 } 6439 } 6440 non_dma0->pbmp = PBMP_ALL(unit); 6441 #ifdef BCM_KATANA2_SUPPORT 6442 if (SOC_IS_KATANA2(unit)) { 6443 SOC_PBMP_CLEAR(non_dma0->pbmp); 6444 for (my_port = SOC_INFO(unit).cmic_port; 6445 my_port <= SOC_INFO(unit).lb_port; 6446 my_port++) { 6447 if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) { 6448 SOC_PBMP_PORT_ADD(non_dma0->pbmp,my_port); 6449 } 6450 } 6451 } 6452 #endif 6453 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6454 non_dma0->entries_per_port = 8; 6455 non_dma0->mem = mem_map[id].mem; 6456 if (soc_feature(unit, soc_feature_counter_toggled_read) && 6457 (id == 8)) { 6458 non_dma0->mem = mem_map[id].mem - 4; 6459 } 6460 non_dma0->num_entries = 4 * soc_mem_index_count(unit, non_dma0->mem); 6461 non_dma0->reg = INVALIDr; 6462 non_dma0->field = COUNTf; 6463 non_dma0->cname = cname_pkt[id / 4]; 6464 6465 entry_words = soc_mem_entry_words(unit, non_dma0->mem); 6466 for (i = 0; i < 4; i++) { 6467 buf_base = i * entry_words * soc_mem_index_count(unit, non_dma0->mem); 6468 non_dma0->dma_buf[i] = &buf[buf_base]; 6469 non_dma0->dma_index_min[i] = 0; 6470 non_dma0->dma_index_max[i] = soc_mem_index_count(unit, non_dma0->mem) - 1; 6471 non_dma0->dma_mem[i] = mem_map[id + i].mem; 6472 if (soc_feature(unit, soc_feature_counter_toggled_read) && 6473 (id == 8)) { 6474 non_dma0->dma_mem[i] = mem_map[id + i].mem - 4; 6475 } 6476 } 6477 *non_dma_entries += non_dma0->num_entries; 6478 6479 non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6480 SOC_COUNTER_NON_DMA_START + 1]; 6481 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6482 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 6483 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6484 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6485 non_dma1->field = BYTE_COUNTf; 6486 non_dma1->cname = cname_byte[id / 4]; 6487 *non_dma_entries += non_dma1->num_entries; 6488 } 6489 6490 return SOC_E_NONE; 6491 } 6492 #endif /* BCM_KATANA_SUPPORT */ 6493 6494 #ifdef BCM_KATANA2_SUPPORT 6495 STATIC int 6496 _soc_counter_sb2_cosq_gport_non_dma_init(int unit, int nports, 6497 int non_dma_start_index, 6498 int *non_dma_entries) 6499 { 6500 soc_control_t *soc; 6501 soc_counter_non_dma_t *non_dma0, *non_dma1; 6502 _sb2_cosq_counter_mem_map_t *mem_map; 6503 int table_size, id, max_id = 9; 6504 uint32 *buf; 6505 char *cname_pkt[] = { "DROP_PKT", "ACCEPT_PKT", 6506 "DROP_PKT_G", "DROP_PKT_Y", 6507 "DROP_PKT_R", "ACCEPT_PKT_G", 6508 "ACCEPT_PKT_Y", "ACCEPT_PKT_R", 6509 "MC_PERQ_PKT" }; 6510 char *cname_byte[] = { "DROP_BYTE", "ACCEPT_BYTE", 6511 "DROP_BYTE_G", "DROP_BYTE_Y", 6512 "DROP_BYTE_R", "ACCEPT_BYTE_G", 6513 "ACCEPT_BYTE_Y", "ACCEPT_BYTE_R", 6514 "MC_PERQ_BYTE" }; 6515 6516 soc = SOC_CONTROL(unit); 6517 *non_dma_entries = 0; 6518 6519 table_size = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * 6520 soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m) * sizeof(uint32); 6521 6522 buf = soc_cm_salloc(unit, table_size, "non_dma_counter"); 6523 if (buf == NULL) { 6524 return SOC_E_MEMORY; 6525 } 6526 sal_memset(buf, 0, table_size); 6527 6528 if (SOC_IS_SABER2(unit)) { 6529 mem_map = _sb2_cosq_gport_mem_map; 6530 max_id = 6; 6531 } else { 6532 mem_map = _kt2_cosq_gport_mem_map; 6533 } 6534 6535 /* 6536 * CTR_FLEX_COUNT_0 = Total ENQ discarded 6537 * CTR_FLEX_COUNT_1 = Total ENQ Accepted 6538 * CTR_FLEX_COUNT_2 = Green ENQ discarded 6539 * CTR_FLEX_COUNT_3 = Yellow ENQ discarded 6540 * CTR_FLEX_COUNT_4 = Red packet ENQ discarded 6541 * CTR_FLEX_COUNT_5 = Total DEQ 6542 */ 6543 for (id = 0; id < max_id; id++) { 6544 non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6545 SOC_COUNTER_NON_DMA_START]; 6546 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6547 _SOC_COUNTER_NON_DMA_DO_DMA | 6548 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6549 if (id == 0) { 6550 non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC; 6551 } 6552 if (!soc_feature(unit, soc_feature_counter_toggled_read)) { 6553 /* adjust the extra count 1 in s/w counters */ 6554 non_dma0->flags |= _SOC_COUNTER_NON_DMA_EXTRA_COUNT; 6555 } 6556 non_dma0->pbmp = PBMP_ALL(unit); 6557 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6558 non_dma0->entries_per_port = 8; 6559 non_dma0->num_entries = soc_mem_index_count(unit, CTR_FLEX_COUNT_0m); 6560 non_dma0->mem = mem_map[id].mem; 6561 non_dma0->reg = INVALIDr; 6562 non_dma0->field = COUNTf; 6563 non_dma0->cname = cname_pkt[id]; 6564 non_dma0->dma_buf[0] = buf; 6565 non_dma0->dma_index_max[0] = non_dma0->num_entries - 1; 6566 non_dma0->dma_mem[0] = non_dma0->mem; 6567 *non_dma_entries += non_dma0->num_entries; 6568 6569 non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6570 SOC_COUNTER_NON_DMA_START + 1]; 6571 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6572 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 6573 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6574 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6575 non_dma1->field = BYTE_COUNTf; 6576 non_dma1->cname = cname_byte[id]; 6577 *non_dma_entries += non_dma1->num_entries; 6578 } 6579 return SOC_E_NONE; 6580 } 6581 6582 /* 6583 * Function: 6584 * _soc_counter_saber2_non_dma_init 6585 * Purpose: 6586 * Initialize Saber2's non-DMA counters. 6587 * Parameters: 6588 * unit - The SOC unit number 6589 * nports - Number of ports. 6590 * non_dma_start_index - The starting index of non-DMA counter entries. 6591 * non_dma_entries - (OUT) The number of non-DMA counter entries. 6592 * Returns: 6593 * SOC_E_NONE 6594 * SOC_E_MEMORY 6595 */ 6596 STATIC int 6597 _soc_counter_saber2_non_dma_init(int unit, int nports, int non_dma_start_index, 6598 int *non_dma_entries) 6599 { 6600 soc_control_t *soc; 6601 soc_counter_non_dma_t *non_dma0, *non_dma1; 6602 _sb2_cosq_counter_mem_map_t *mem_map; 6603 soc_port_t my_port; 6604 int table_size; 6605 uint32 *buf ; 6606 int i, id, max_id = 6, increment = 2; 6607 int entry_words, buf_base; 6608 uint16 dev_id; 6609 uint8 rev_id; 6610 6611 if (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) { 6612 SOC_IF_ERROR_RETURN 6613 (_soc_counter_sb2_cosq_gport_non_dma_init(unit, nports, 6614 non_dma_start_index, non_dma_entries)); 6615 return SOC_E_NONE; 6616 } 6617 #if defined (BCM_KATANA2_SUPPORT) 6618 if (SOC_IS_SABER2(unit)) { 6619 mem_map = _sb2_cosq_mem_map; 6620 } else { 6621 mem_map = _kt2_cosq_mem_map; 6622 increment = 4; 6623 max_id = 12; 6624 } 6625 #endif 6626 #if defined (BCM_METROLITE_SUPPORT) 6627 if (SOC_IS_METROLITE(unit)) { 6628 mem_map = _ml_cosq_mem_map; 6629 increment = 1; 6630 max_id = 3; 6631 } 6632 #endif 6633 soc_cm_get_id(unit, &dev_id, &rev_id); 6634 if (dev_id == BCM56233_DEVICE_ID) { 6635 /* 6636 * CTR_FLEX_COUNT_0 = Total ENQ discarded 6637 * CTR_FLEX_COUNT_1 = Red packet ENQ discarded 6638 * CTR_FLEX_COUNT_2 = Total DEQ 6639 */ 6640 mem_map = _dg2_cosq_mem_map; 6641 max_id = 3; 6642 increment = 1; 6643 } 6644 soc = SOC_CONTROL(unit); 6645 *non_dma_entries = 0; 6646 6647 entry_words = soc_mem_entry_words(unit, CTR_FLEX_COUNT_0m); 6648 table_size = (soc_mem_index_count(unit, CTR_FLEX_COUNT_0m) * increment * 6649 entry_words * sizeof(uint32)); 6650 6651 buf = soc_cm_salloc(unit, table_size, "non_dma_counter"); 6652 if (buf == NULL) { 6653 return SOC_E_MEMORY; 6654 } 6655 sal_memset(buf, 0, table_size); 6656 6657 /* 6658 * CTR_FLEX_COUNT_0/1 = Total ENQ discarded 6659 * CTR_FLEX_COUNT_2/3 = Red packet ENQ discarded 6660 * CTR_FLEX_COUNT_4/5 = Total DEQ 6661 */ 6662 for (id = 0; id < max_id; id = id + increment) { 6663 if (soc_feature(unit, soc_feature_counter_toggled_read) && 6664 mem_map[id].non_dma_id == SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_RED) { 6665 continue; 6666 } 6667 non_dma0 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6668 SOC_COUNTER_NON_DMA_START]; 6669 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6670 _SOC_COUNTER_NON_DMA_DO_DMA | 6671 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6672 if (id == 0) { 6673 non_dma0->flags |= _SOC_COUNTER_NON_DMA_ALLOC; 6674 } 6675 SOC_PBMP_CLEAR(non_dma0->pbmp); 6676 for (my_port = SOC_INFO(unit).cmic_port; 6677 my_port <= SOC_INFO(unit).lb_port; 6678 my_port++) { 6679 if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) { 6680 SOC_PBMP_PORT_ADD(non_dma0->pbmp, my_port); 6681 } 6682 } 6683 6684 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6685 non_dma0->entries_per_port = 48; /* Need 48 entries to display CPU queues */ 6686 non_dma0->mem = mem_map[id].mem; 6687 non_dma0->num_entries = increment * soc_mem_index_count(unit, non_dma0->mem); 6688 non_dma0->reg = INVALIDr; 6689 non_dma0->field = COUNTf; 6690 non_dma0->cname = mem_map[id].cname_pkt; 6691 6692 entry_words = soc_mem_entry_words(unit, non_dma0->mem); 6693 for (i = 0; i < increment; i++) { 6694 buf_base = i * entry_words * soc_mem_index_count(unit, non_dma0->mem); 6695 non_dma0->dma_buf[i] = &buf[buf_base]; 6696 non_dma0->dma_index_min[i] = 0; 6697 non_dma0->dma_index_max[i] = soc_mem_index_count(unit, non_dma0->mem) - 1; 6698 non_dma0->dma_mem[i] = mem_map[id + i].mem; 6699 } 6700 *non_dma_entries += non_dma0->num_entries; 6701 6702 non_dma1 = &soc->counter_non_dma[mem_map[id].non_dma_id - 6703 SOC_COUNTER_NON_DMA_START + 1]; 6704 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6705 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 6706 _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 6707 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6708 non_dma1->field = BYTE_COUNTf; 6709 non_dma1->cname = mem_map[id].cname_byte; 6710 *non_dma_entries += non_dma1->num_entries; 6711 } 6712 return SOC_E_NONE; 6713 } 6714 #endif /* BCM_SABER2_SUPPORT */ 6715 6716 #ifdef BCM_TRIUMPH_SUPPORT 6717 /* 6718 * Function: 6719 * _soc_counter_tr_non_dma_init 6720 * Purpose: 6721 * Initialize Triumph's non-DMA counters. 6722 * Parameters: 6723 * unit - The SOC unit number 6724 * nports - Number of ports. 6725 * non_dma_start_index - The starting index of non-DMA counter entries. 6726 * non_dma_entries - (OUT) The number of non-DMA counter entries. 6727 * Returns: 6728 * SOC_E_NONE 6729 * SOC_E_MEMORY 6730 */ 6731 STATIC int 6732 _soc_counter_tr_non_dma_init(int unit, int nports, int non_dma_start_index, 6733 int *non_dma_entries) 6734 { 6735 soc_control_t *soc; 6736 soc_counter_non_dma_t *non_dma0, *non_dma1; 6737 int max_cosq_per_port, total_num_cosq, port; 6738 int num_entries, alloc_size; 6739 uint32 *buf; 6740 6741 soc = SOC_CONTROL(unit); 6742 *non_dma_entries = 0; 6743 6744 max_cosq_per_port = 0; 6745 total_num_cosq = 0; 6746 for (port = 0; port < nports; port++) { 6747 if (num_cosq[unit][port] > max_cosq_per_port) { 6748 max_cosq_per_port = num_cosq[unit][port]; 6749 } 6750 total_num_cosq += num_cosq[unit][port]; 6751 } 6752 6753 num_entries = soc_mem_index_count(unit, EGR_PERQ_XMT_COUNTERSm); 6754 alloc_size = num_entries * 6755 soc_mem_entry_words(unit, EGR_PERQ_XMT_COUNTERSm) * sizeof(uint32); 6756 6757 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 6758 if (buf == NULL) { 6759 return SOC_E_MEMORY; 6760 } 6761 sal_memset(buf, 0, alloc_size); 6762 6763 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 6764 SOC_COUNTER_NON_DMA_START]; 6765 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6766 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 6767 non_dma0->pbmp = PBMP_ALL(unit); 6768 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6769 non_dma0->entries_per_port = max_cosq_per_port; 6770 non_dma0->num_entries = num_entries; 6771 non_dma0->mem = EGR_PERQ_XMT_COUNTERSm; 6772 non_dma0->reg = INVALIDr; 6773 non_dma0->field = PACKET_COUNTERf; 6774 non_dma0->cname = "PERQ_PKT"; 6775 non_dma0->dma_buf[0] = buf; 6776 non_dma0->dma_index_max[0] = num_entries - 1; 6777 non_dma0->dma_mem[0] = non_dma0->mem; 6778 *non_dma_entries += non_dma0->num_entries; 6779 6780 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 6781 SOC_COUNTER_NON_DMA_START]; 6782 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6783 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 6784 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6785 non_dma1->field = BYTE_COUNTERf; 6786 non_dma1->cname = "PERQ_BYTE"; 6787 *non_dma_entries += non_dma1->num_entries; 6788 6789 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 6790 SOC_COUNTER_NON_DMA_START]; 6791 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6792 _SOC_COUNTER_NON_DMA_PERQ_REG; 6793 non_dma0->pbmp = PBMP_ALL(unit); 6794 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6795 non_dma0->entries_per_port = max_cosq_per_port; 6796 non_dma0->num_entries = total_num_cosq; 6797 non_dma0->mem = INVALIDm; 6798 non_dma0->reg = DROP_PKT_CNTr; 6799 non_dma0->field = COUNTf; 6800 non_dma0->cname = "PERQ_DROP_PKT"; 6801 *non_dma_entries += non_dma0->num_entries; 6802 6803 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 6804 SOC_COUNTER_NON_DMA_START]; 6805 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6806 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6807 non_dma1->reg = DROP_BYTE_CNTr; 6808 non_dma1->cname = "PERQ_DROP_BYTE"; 6809 *non_dma_entries += non_dma1->num_entries; 6810 6811 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 6812 SOC_COUNTER_NON_DMA_START]; 6813 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6814 non_dma0->pbmp = PBMP_ALL(unit); 6815 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6816 non_dma0->entries_per_port = 1; 6817 non_dma0->num_entries = nports; 6818 non_dma0->mem = INVALIDm; 6819 non_dma0->reg = DROP_PKT_CNT_INGr; 6820 non_dma0->field = COUNTf; 6821 non_dma0->cname = "DROP_PKT_ING"; 6822 *non_dma_entries += non_dma0->num_entries; 6823 6824 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 6825 SOC_COUNTER_NON_DMA_START]; 6826 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6827 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6828 non_dma1->reg = DROP_BYTE_CNT_INGr; 6829 non_dma1->cname = "DROP_BYTE_ING"; 6830 *non_dma_entries += non_dma1->num_entries; 6831 6832 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 6833 SOC_COUNTER_NON_DMA_START]; 6834 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6835 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6836 non_dma1->reg = DROP_PKT_CNT_YELr; 6837 non_dma1->cname = "DROP_PKT_YEL"; 6838 *non_dma_entries += non_dma1->num_entries; 6839 6840 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 6841 SOC_COUNTER_NON_DMA_START]; 6842 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6843 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6844 non_dma1->reg = DROP_PKT_CNT_REDr; 6845 non_dma1->cname = "DROP_PKT_RED"; 6846 *non_dma_entries += non_dma1->num_entries; 6847 6848 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TX_LLFC_MSG_CNT - 6849 SOC_COUNTER_NON_DMA_START]; 6850 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6851 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 6852 non_dma1->pbmp = PBMP_ALL(unit); 6853 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6854 non_dma1->mem = INVALIDm; 6855 non_dma1->reg = TXLLFCMSGCNTr; 6856 non_dma1->field = TXLLFCMSGCNT_STATSf; 6857 non_dma1->cname = "MAC_TXLLFCMSG"; 6858 non_dma1->entries_per_port = 1; 6859 non_dma1->num_entries = nports; 6860 *non_dma_entries += non_dma1->num_entries; 6861 return SOC_E_NONE; 6862 } 6863 #endif /* BCM_TRIUMPH_SUPPORT */ 6864 6865 #ifdef BCM_SCORPION_SUPPORT 6866 /* 6867 * Function: 6868 * _soc_counter_sc_non_dma_init 6869 * Purpose: 6870 * Initialize Scorpion's non-DMA counters. 6871 * Parameters: 6872 * unit - The SOC unit number 6873 * nports - Number of ports 6874 * non_dma_start_index - The starting index of non-DMA counter entries. 6875 * non_dma_entries - (OUT) The number of non-DMA counter entries. 6876 * Returns: 6877 * SOC_E_NONE 6878 */ 6879 STATIC int 6880 _soc_counter_sc_non_dma_init(int unit, int nports, int non_dma_start_index, 6881 int *non_dma_entries) 6882 { 6883 soc_control_t *soc; 6884 soc_counter_non_dma_t *non_dma0, *non_dma1; 6885 int max_cosq_per_port, total_num_cosq, port; 6886 6887 soc = SOC_CONTROL(unit); 6888 *non_dma_entries = 0; 6889 6890 max_cosq_per_port = 0; 6891 total_num_cosq = 0; 6892 for (port = 0; port < nports; port++) { 6893 if (num_cosq[unit][port] > max_cosq_per_port) { 6894 max_cosq_per_port = num_cosq[unit][port]; 6895 } 6896 total_num_cosq += num_cosq[unit][port]; 6897 } 6898 6899 /* EGR_PERQ_XMT_COUNTERS register support in scorpion */ 6900 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 6901 SOC_COUNTER_NON_DMA_START]; 6902 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6903 non_dma0->pbmp = PBMP_PORT_ALL(unit); 6904 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6905 non_dma0->entries_per_port = SOC_REG_NUMELS(unit, EGR_PERQ_XMT_COUNTERSr); 6906 non_dma0->num_entries = nports * non_dma0->entries_per_port; 6907 non_dma0->mem = INVALIDm; 6908 non_dma0->reg = EGR_PERQ_XMT_COUNTERSr; 6909 non_dma0->field = PACKET_COUNTERf; 6910 non_dma0->cname = "PERQ_PKT"; 6911 *non_dma_entries += non_dma0->num_entries; 6912 6913 6914 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 6915 SOC_COUNTER_NON_DMA_START]; 6916 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 6917 _SOC_COUNTER_NON_DMA_PERQ_REG; 6918 non_dma0->pbmp = PBMP_ALL(unit); 6919 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6920 non_dma0->entries_per_port = max_cosq_per_port; 6921 non_dma0->num_entries = total_num_cosq; 6922 non_dma0->mem = INVALIDm; 6923 non_dma0->reg = HOLDROP_PKT_CNTr; 6924 non_dma0->field = COUNTf; 6925 non_dma0->cname = "PERQ_DROP_PKT"; 6926 *non_dma_entries += non_dma0->num_entries; 6927 6928 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP - 6929 SOC_COUNTER_NON_DMA_START]; 6930 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 6931 non_dma0->pbmp = PBMP_ALL(unit); 6932 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 6933 non_dma0->entries_per_port = 1; 6934 non_dma0->num_entries = nports; 6935 non_dma0->mem = INVALIDm; 6936 non_dma0->reg = IBP_DROP_PKT_CNTr; 6937 non_dma0->field = COUNTf; 6938 non_dma0->cname = "DROP_PKT_IBP"; 6939 *non_dma_entries += non_dma0->num_entries; 6940 6941 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP - 6942 SOC_COUNTER_NON_DMA_START]; 6943 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6944 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6945 non_dma1->reg = CFAP_DROP_PKT_CNTr; 6946 non_dma1->cname = "DROP_PKT_CFAP"; 6947 *non_dma_entries += non_dma1->num_entries; 6948 6949 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 6950 SOC_COUNTER_NON_DMA_START]; 6951 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6952 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6953 non_dma1->reg = YELLOW_CNG_DROP_CNTr; 6954 non_dma1->cname = "DROP_PKT_YEL"; 6955 *non_dma_entries += non_dma1->num_entries; 6956 6957 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 6958 SOC_COUNTER_NON_DMA_START]; 6959 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6960 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6961 non_dma1->reg = RED_CNG_DROP_CNTr; 6962 non_dma1->cname = "DROP_PKT_RED"; 6963 *non_dma_entries += non_dma1->num_entries; 6964 6965 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_TX_LLFC_MSG_CNT - 6966 SOC_COUNTER_NON_DMA_START]; 6967 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 6968 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 6969 non_dma1->pbmp = PBMP_ALL(unit); 6970 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 6971 non_dma1->mem = INVALIDm; 6972 non_dma1->reg = TXLLFCMSGCNTr; 6973 non_dma1->field = TXLLFCMSGCNT_STATSf; 6974 non_dma1->cname = "MAC_TXLLFCMSG"; 6975 non_dma1->entries_per_port = 1; 6976 non_dma1->num_entries = nports; 6977 *non_dma_entries += non_dma1->num_entries; 6978 6979 return SOC_E_NONE; 6980 } 6981 #endif /* BCM_SCORPION_SUPPORT */ 6982 6983 #ifdef BCM_SHADOW_SUPPORT 6984 /* 6985 * Function: 6986 * _soc_counter_shadow_non_dma_init 6987 * Purpose: 6988 * Initialize Shadow's non-DMA counters. 6989 * Parameters: 6990 * unit - The SOC unit number 6991 * nports - Number of ports. 6992 * non_dma_start_index - The starting index of non-DMA counter entries. 6993 * non_dma_entries - (OUT) The number of non-DMA counter entries. 6994 * Returns: 6995 * SOC_E_NONE 6996 * SOC_E_MEMORY 6997 */ 6998 STATIC int 6999 _soc_counter_shadow_non_dma_init(int unit, int nports, int non_dma_start_index, 7000 int *non_dma_entries) 7001 { 7002 soc_control_t *soc; 7003 soc_counter_non_dma_t *non_dma0,*non_dma1; 7004 int num_entries,alloc_size; 7005 uint32 *buf; 7006 7007 soc = SOC_CONTROL(unit); 7008 *non_dma_entries = 0; 7009 7010 /* Reusing non_dma id for interlaken counters */ 7011 7012 /* IL_STAT_MEM_0 Entries */ 7013 num_entries = soc_mem_index_count(unit, IL_STAT_MEM_0m); 7014 alloc_size = num_entries * 7015 soc_mem_entry_words(unit, IL_STAT_MEM_0m) * sizeof(uint32); 7016 7017 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 7018 if (buf == NULL) { 7019 return SOC_E_MEMORY; 7020 } 7021 sal_memset(buf, 0, alloc_size); 7022 7023 7024 /* IL_STAT_MEM_0: RX_STAT_PKT_COUNTf */ 7025 /* Overload SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT */ 7026 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT - 7027 SOC_COUNTER_NON_DMA_START]; 7028 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 7029 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 7030 non_dma0->pbmp = PBMP_IL_ALL(unit); 7031 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 7032 non_dma0->entries_per_port = 1; 7033 non_dma0->num_entries = 1; 7034 non_dma0->mem = IL_STAT_MEM_0m; 7035 non_dma0->reg = INVALIDr; 7036 non_dma0->field = RX_STAT_PKT_COUNTf; 7037 non_dma0->cname = "IL_RX_PKTCNT"; 7038 non_dma0->dma_buf[0] = buf; 7039 non_dma0->dma_index_min[0] = 0; 7040 non_dma0->dma_index_max[0] = num_entries - 1; 7041 non_dma0->dma_mem[0] = non_dma0->mem; 7042 *non_dma_entries += non_dma0->num_entries; 7043 7044 /* IL_STAT_MEM_0: RX_STAT_BYTE_COUNTf */ 7045 /* Overload SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE */ 7046 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE - 7047 SOC_COUNTER_NON_DMA_START]; 7048 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7049 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7050 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7051 non_dma1->field = RX_STAT_BYTE_COUNTf; 7052 non_dma1->cname = "IL_RX_BYTECNT"; 7053 *non_dma_entries += non_dma1->num_entries; 7054 7055 /* IL_STAT_MEM_0: RX_STAT_BAD_PKT_ILERR_COUNTf */ 7056 /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT */ 7057 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT - 7058 SOC_COUNTER_NON_DMA_START]; 7059 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7060 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7061 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7062 non_dma1->field = RX_STAT_BAD_PKT_ILERR_COUNTf; 7063 non_dma1->cname = "IL_RX_ERRCNT"; 7064 *non_dma_entries += non_dma1->num_entries; 7065 7066 7067 /* IL_STAT_MEM_1 Entries */ 7068 num_entries = soc_mem_index_count(unit, IL_STAT_MEM_1m); 7069 alloc_size = num_entries * 7070 soc_mem_entry_words(unit, IL_STAT_MEM_1m) * sizeof(uint32); 7071 7072 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 7073 if (buf == NULL) { 7074 return SOC_E_MEMORY; 7075 } 7076 sal_memset(buf, 0, alloc_size); 7077 7078 7079 /* IL_STAT_MEM_1: RX_STAT_GTMTU_PKT_COUNTf Greater that MTU size*/ 7080 /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE */ 7081 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE - 7082 SOC_COUNTER_NON_DMA_START]; 7083 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 7084 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 7085 non_dma0->pbmp = PBMP_IL_ALL(unit); 7086 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 7087 non_dma0->entries_per_port = 1; 7088 non_dma0->num_entries = 1; 7089 non_dma0->mem = IL_STAT_MEM_1m; 7090 non_dma0->reg = INVALIDr; 7091 non_dma0->field = RX_STAT_GTMTU_PKT_COUNTf; 7092 non_dma0->cname = "IL_RX_GTMTUCNT"; 7093 non_dma0->dma_buf[0] = buf; 7094 non_dma0->dma_index_min[0] = 0; 7095 non_dma0->dma_index_max[0] = num_entries - 1; 7096 non_dma0->dma_mem[0] = non_dma0->mem; 7097 *non_dma_entries += non_dma0->num_entries; 7098 7099 /* IL_STAT_MEM_1: RX_STAT_EQMTU_PKT_COUNTf - equal to MTU Size*/ 7100 /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC */ 7101 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC - 7102 SOC_COUNTER_NON_DMA_START]; 7103 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7104 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7105 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7106 non_dma1->field = RX_STAT_EQMTU_PKT_COUNTf; 7107 non_dma1->cname = "IL_RX_EQMTUCNT"; 7108 *non_dma_entries += non_dma1->num_entries; 7109 7110 7111 /* IL_STAT_MEM_1: RX_STAT_IEEE_CRCERR_PKT_COUNTf - IEEE CRC err count*/ 7112 /* Overload SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC */ 7113 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC - 7114 SOC_COUNTER_NON_DMA_START]; 7115 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7116 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7117 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7118 non_dma1->field = RX_STAT_IEEE_CRCERR_PKT_COUNTf; 7119 non_dma1->cname = "IL_RX_CRCERRCNT"; 7120 *non_dma_entries += non_dma1->num_entries; 7121 7122 /* IL_STAT_MEM_2 Entries */ 7123 num_entries = soc_mem_index_count(unit, IL_STAT_MEM_2m); 7124 alloc_size = num_entries * 7125 soc_mem_entry_words(unit, IL_STAT_MEM_2m) * sizeof(uint32); 7126 7127 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 7128 if (buf == NULL) { 7129 return SOC_E_MEMORY; 7130 } 7131 sal_memset(buf, 0, alloc_size); 7132 7133 /* IL_STAT_MEM_2: RX_STAT_PKT_COUNTf Rx stat packet count*/ 7134 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING */ 7135 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING - 7136 SOC_COUNTER_NON_DMA_START]; 7137 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 7138 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 7139 non_dma0->pbmp = PBMP_IL_ALL(unit); 7140 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 7141 non_dma0->entries_per_port = 1; 7142 non_dma0->num_entries = 1; 7143 non_dma0->mem = IL_STAT_MEM_2m; 7144 non_dma0->reg = INVALIDr; 7145 non_dma0->field = RX_STAT_PKT_COUNTf; 7146 non_dma0->cname = "IL_RX_STATCNT"; 7147 non_dma0->dma_buf[0] = buf; 7148 non_dma0->dma_index_min[0] = 0; 7149 non_dma0->dma_index_max[0] = num_entries - 1; 7150 non_dma0->dma_mem[0] = non_dma0->mem; 7151 *non_dma_entries += non_dma0->num_entries; 7152 7153 /* IL_STAT_MEM_3 Entries */ 7154 num_entries = soc_mem_index_count(unit, IL_STAT_MEM_3m); 7155 alloc_size = num_entries * 7156 soc_mem_entry_words(unit, IL_STAT_MEM_3m) * sizeof(uint32); 7157 7158 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 7159 if (buf == NULL) { 7160 return SOC_E_MEMORY; 7161 } 7162 sal_memset(buf, 0, alloc_size); 7163 7164 /* IL_STAT_MEM_3: TX_STAT_PKT_COUNT */ 7165 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING */ 7166 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING - 7167 SOC_COUNTER_NON_DMA_START]; 7168 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID | 7169 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 7170 non_dma0->pbmp = PBMP_IL_ALL(unit); 7171 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 7172 non_dma0->entries_per_port = 1; 7173 non_dma0->num_entries = 1; 7174 non_dma0->mem = IL_STAT_MEM_3m; 7175 non_dma0->reg = INVALIDr; 7176 non_dma0->field = TX_STAT_PKT_COUNTf; 7177 non_dma0->cname = "IL_TX_PKTCNT"; 7178 non_dma0->dma_buf[0] = buf; 7179 non_dma0->dma_index_min[0] = 0; 7180 non_dma0->dma_index_max[0] = 1; 7181 non_dma0->dma_mem[0] = non_dma0->mem; 7182 *non_dma_entries += non_dma0->num_entries; 7183 7184 /* IL_STAT_MEM_3: TX_STAT_BYTE_COUNTf */ 7185 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP */ 7186 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_IBP - 7187 SOC_COUNTER_NON_DMA_START]; 7188 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7189 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7190 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7191 non_dma1->field = TX_STAT_BYTE_COUNTf; 7192 non_dma1->cname = "IL_TX_BYTECNT"; 7193 *non_dma_entries += non_dma1->num_entries; 7194 7195 /* IL_STAT_MEM_3: TX_STAT_BAD_PKT_PERR_COUNTf */ 7196 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP */ 7197 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_CFAP - 7198 SOC_COUNTER_NON_DMA_START]; 7199 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7200 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7201 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7202 non_dma1->field = TX_STAT_BAD_PKT_PERR_COUNTf; 7203 non_dma1->cname = "IL_TX_ERRCNT"; 7204 *non_dma_entries += non_dma1->num_entries; 7205 7206 /* IL_STAT_MEM_3: TX_STAT_GTMTU_PKT_COUNTf */ 7207 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT */ 7208 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT - 7209 SOC_COUNTER_NON_DMA_START]; 7210 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7211 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7212 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7213 non_dma1->field = TX_STAT_GTMTU_PKT_COUNTf; 7214 non_dma1->cname = "IL_TX_GTMTUCNT"; 7215 *non_dma_entries += non_dma1->num_entries; 7216 7217 /* IL_STAT_MEM_3: TX_STAT_EQMTU_PKT_COUNT - Greater than mtu size */ 7218 /* Overload SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW */ 7219 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 7220 SOC_COUNTER_NON_DMA_START]; 7221 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7222 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID; 7223 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7224 non_dma1->field = TX_STAT_EQMTU_PKT_COUNTf; 7225 non_dma1->cname = "IL_TX_EQMTUCNT"; 7226 *non_dma_entries += non_dma1->num_entries; 7227 7228 /* IL_STAT_MEM_4 Entries */ 7229 /* IL_STAT_MEM_4 overloaded on SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT */ 7230 num_entries = soc_mem_index_count(unit, IL_STAT_MEM_4m); 7231 alloc_size = num_entries * 7232 soc_mem_entry_words(unit, IL_STAT_MEM_4m) * sizeof(uint32); 7233 7234 buf = soc_cm_salloc(unit, alloc_size, "non_dma_counter"); 7235 if (buf == NULL) { 7236 return SOC_E_MEMORY; 7237 } 7238 sal_memset(buf, 0, alloc_size); 7239 7240 /* TX_STAT_PKT_COUNT */ 7241 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 7242 SOC_COUNTER_NON_DMA_START]; 7243 non_dma1->flags = _SOC_COUNTER_NON_DMA_VALID | 7244 _SOC_COUNTER_NON_DMA_DO_DMA | _SOC_COUNTER_NON_DMA_ALLOC; 7245 non_dma1->pbmp = PBMP_IL_ALL(unit); 7246 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7247 non_dma1->entries_per_port = 1; 7248 non_dma1->num_entries = 1; 7249 non_dma1->mem = IL_STAT_MEM_4m; 7250 non_dma1->reg = INVALIDr; 7251 non_dma1->field = TX_STAT_PKT_COUNTf; 7252 non_dma1->cname = "IL_TX_STATCNT"; 7253 non_dma1->dma_buf[0] = buf; 7254 non_dma1->dma_index_min[0] = 0; 7255 non_dma1->dma_index_max[0] = num_entries - 1; 7256 non_dma1->dma_mem[0] = non_dma1->mem; 7257 *non_dma_entries += non_dma1->num_entries; 7258 7259 return SOC_E_NONE; 7260 } 7261 #endif /* BCM_SHADOW_SUPPORT */ 7262 7263 #ifdef BCM_BRADLEY_SUPPORT 7264 /* 7265 * Function: 7266 * _soc_counter_hb_non_dma_init 7267 * Purpose: 7268 * Initialize Bradley's non-DMA counters. 7269 * Parameters: 7270 * unit - The SOC unit number 7271 * nports - Number of ports 7272 * non_dma_start_index - The starting index of non-DMA counter entries. 7273 * non_dma_entries - (OUT) The number of non-DMA counter entries. 7274 * Returns: 7275 * SOC_E_NONE 7276 */ 7277 STATIC int 7278 _soc_counter_hb_non_dma_init(int unit, int nports, int non_dma_start_index, 7279 int *non_dma_entries) 7280 { 7281 soc_control_t *soc; 7282 soc_counter_non_dma_t *non_dma; 7283 7284 soc = SOC_CONTROL(unit); 7285 *non_dma_entries = 0; 7286 7287 non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT - 7288 SOC_COUNTER_NON_DMA_START]; 7289 non_dma->flags = _SOC_COUNTER_NON_DMA_VALID; 7290 non_dma->pbmp = PBMP_ALL(unit); 7291 non_dma->base_index = non_dma_start_index + *non_dma_entries; 7292 non_dma->entries_per_port = 1; 7293 non_dma->num_entries = nports; 7294 non_dma->mem = INVALIDm; 7295 non_dma->reg = DROP_PKT_CNTr; 7296 non_dma->field = COUNTf; 7297 non_dma->cname = "DROP_PKT_MMU"; 7298 *non_dma_entries += non_dma->num_entries; 7299 7300 return SOC_E_NONE; 7301 } 7302 #endif /* BCM_BRADLEY_SUPPORT */ 7303 7304 #ifdef BCM_FIREBOLT_SUPPORT 7305 /* 7306 * Function: 7307 * _soc_counter_fb_non_dma_init 7308 * Purpose: 7309 * Initialize Firebolt's non-DMA counters. 7310 * Parameters: 7311 * unit - The SOC unit number 7312 * nports - Number of ports 7313 * non_dma_start_index - The starting index of non-DMA counter entries. 7314 * non_dma_entries - (OUT) The number of non-DMA counter entries. 7315 * Returns: 7316 * SOC_E_NONE 7317 */ 7318 STATIC int 7319 _soc_counter_fb_non_dma_init(int unit, int nports, int non_dma_start_index, 7320 int *non_dma_entries) 7321 { 7322 soc_control_t *soc; 7323 soc_counter_non_dma_t *non_dma0, *non_dma1; 7324 7325 soc = SOC_CONTROL(unit); 7326 *non_dma_entries = 0; 7327 7328 non_dma0 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW - 7329 SOC_COUNTER_NON_DMA_START]; 7330 non_dma0->flags = _SOC_COUNTER_NON_DMA_VALID; 7331 non_dma0->pbmp = PBMP_ALL(unit); 7332 non_dma0->base_index = non_dma_start_index + *non_dma_entries; 7333 non_dma0->entries_per_port = 1; 7334 non_dma0->num_entries = nports; 7335 non_dma0->mem = INVALIDm; 7336 non_dma0->reg = CNGDROPCOUNT1r; 7337 non_dma0->field = DROPPKTCOUNTf; 7338 non_dma0->cname = "DROP_PKT_YEL"; 7339 *non_dma_entries += non_dma0->num_entries; 7340 7341 non_dma1 = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED - 7342 SOC_COUNTER_NON_DMA_START]; 7343 sal_memcpy(non_dma1, non_dma0, sizeof(soc_counter_non_dma_t)); 7344 non_dma1->base_index = non_dma_start_index + *non_dma_entries; 7345 non_dma1->reg = CNGDROPCOUNT0r; 7346 non_dma1->cname = "DROP_PKT_RED"; 7347 *non_dma_entries += non_dma1->num_entries; 7348 7349 return SOC_E_NONE; 7350 } 7351 #endif /* BCM_FIREBOLT_SUPPORT */ 7352 7353 #ifdef BCM_SBUSDMA_SUPPORT 7354 static sbusdma_desc_handle_t *_soc_blk_counter_handles[SOC_MAX_NUM_DEVICES] = {NULL}; 7355 static soc_blk_ctr_process_t **_blk_ctr_process[SOC_MAX_NUM_DEVICES] = {NULL}; 7356 void _soc_sbusdma_blk_ctr_cb(int unit, int status, sbusdma_desc_handle_t handle, 7357 void *data) 7358 { 7359 uint16 i, j, arr, bufidx, hwidx; 7360 uint64 ctr_new, ctr_prev, ctr_diff; 7361 int wide, width, f; 7362 volatile uint64 *vptr; 7363 uint32 *hwptr; 7364 soc_control_t *soc = SOC_CONTROL(unit); 7365 soc_reg_t ctr_reg; 7366 soc_blk_ctr_process_t *ctr_process = _blk_ctr_process[unit][PTR_TO_INT(data)]; 7367 LOG_DEBUG(BSL_LS_SOC_COUNTER, 7368 (BSL_META_U(unit, 7369 "In blk counter cb [%d]\n"), handle)); 7370 if (status == SOC_E_NONE) { 7371 LOG_DEBUG(BSL_LS_SOC_COUNTER, 7372 (BSL_META_U(unit, 7373 "Complete: blk:%d, index: %d, entries: %d.\n"), 7374 ctr_process->blk, ctr_process->bindex, ctr_process->entries)); 7375 /* Process data (need bindex, count) */ 7376 hwptr = (uint32*)ctr_process->buff; 7377 for (i=0, bufidx = 0, hwidx = 0; i<ctr_process->entries; i++) { 7378 arr = soc->blk_ctr_desc[ctr_process->bindex].desc[i].entries; 7379 ctr_reg = soc->blk_ctr_desc[ctr_process->bindex].desc[i].reg; 7380 wide = (soc->blk_ctr_desc[ctr_process->bindex].desc[i].width > 1) ? 1 : 0; 7381 for (j=0; j<arr; j++, bufidx++, hwidx++) { 7382 uint32 *ptr = &hwptr[hwidx]; 7383 if (wide) { 7384 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 7385 COMPILER_64_SET(ctr_new, ptr[0], ptr[1]); 7386 } else { 7387 COMPILER_64_SET(ctr_new, ptr[1], ptr[0]); 7388 } 7389 hwidx++; 7390 } else { 7391 COMPILER_64_SET(ctr_new, 0, ptr[0]); 7392 } 7393 if (!COMPILER_64_IS_ZERO(ctr_new)) { 7394 LOG_DEBUG(BSL_LS_SOC_COUNTER, 7395 (BSL_META_U(unit, 7396 "idx: %d, bufidx: %d, :val: %x_%x\n"), 7397 i, bufidx, COMPILER_64_HI(ctr_new), 7398 COMPILER_64_LO(ctr_new))); 7399 } 7400 ctr_prev = ctr_process->hwval[bufidx]; 7401 vptr = &ctr_process->swval[bufidx]; 7402 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 7403 /* clear delta. (not maintaining delta for now) */ 7404 } else { 7405 ctr_diff = ctr_new; 7406 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { /* handle rollover */ 7407 uint64 wrap_amt; 7408 f = 0; 7409 width = SOC_REG_INFO(unit, ctr_reg).fields[f].len; 7410 while((SOC_REG_INFO(unit, ctr_reg).fields + f) != NULL) { 7411 if (SOC_REG_INFO(unit, ctr_reg).fields[f].field == 7412 COUNTf) { 7413 width = SOC_REG_INFO(unit, ctr_reg).fields[f].len; 7414 break; 7415 } 7416 f++; 7417 } 7418 if (width < 32) { 7419 COMPILER_64_SET(wrap_amt, 0, 1UL << width); 7420 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 7421 } else if (width < 64) { 7422 COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0); 7423 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 7424 } 7425 } 7426 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 7427 ctr_process->hwval[bufidx] = ctr_new; 7428 COMPILER_64_ADD_64(*vptr, ctr_diff); 7429 } 7430 } 7431 } 7432 } else { 7433 LOG_ERROR(BSL_LS_SOC_COMMON, 7434 (BSL_META_U(unit, 7435 "Counter SBUSDMA failed: blk:%d, index: %d, entries: %d.\n"), 7436 ctr_process->blk, ctr_process->bindex, ctr_process->entries)); 7437 if (status == SOC_E_TIMEOUT) { 7438 /* delete this handles desc */ 7439 (void)soc_sbusdma_desc_delete(unit, handle); 7440 _soc_blk_counter_handles[unit][ctr_process->bindex] = 0; 7441 } 7442 } 7443 } 7444 #endif 7445 7446 /* Function to Set all Sw maintained counter values to 0 */ 7447 void 7448 soc_counter_ctr_reset_to_zero(int unit) 7449 { 7450 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 7451 soc_control_t *soc = SOC_CONTROL(unit); 7452 7453 if (soc->counter_sw_val != NULL) { 7454 sal_memset(soc->counter_sw_val, 0, 7455 soc_ctr_ctrl->total_dma_entries * sizeof(uint64)); 7456 } 7457 if (soc->counter_hw_val != NULL) { 7458 sal_memset(soc->counter_hw_val, 0, 7459 soc_ctr_ctrl->total_dma_entries * sizeof(uint64)); 7460 } 7461 if (soc->counter_delta != NULL) { 7462 sal_memset(soc->counter_delta, 0, 7463 soc_ctr_ctrl->total_dma_entries * sizeof(uint64)); 7464 } 7465 return; 7466 } 7467 7468 /* 7469 * Function: 7470 * soc_counter_attach 7471 * Purpose: 7472 * Initialize counter module. 7473 * Notes: 7474 * Allocates counter collection buffers. 7475 * We need to work with the true data for the chip, not the current 7476 * pbmp_valid settings. They may be changed after attach, but the 7477 * memory won't be reallocated at that time. 7478 */ 7479 7480 int 7481 soc_counter_attach(int unit) 7482 { 7483 soc_control_t *soc; 7484 int n_entries, n_bytes; 7485 int non_dma_entries = 0; 7486 int portsize, nports, ports64; 7487 int blk, bindex, port, phy_port; 7488 int blktype, ctype, idx; 7489 uint32 array_idx; 7490 char *counter_level; 7491 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 7492 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) 7493 int ct; 7494 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_APACHE_SUPPORT*/ 7495 #if defined(BCM_TOMAHAWK2_SUPPORT) 7496 soc_info_t *si = &SOC_INFO(unit); 7497 #endif 7498 #if defined(BCM_PETRA_SUPPORT) 7499 int nof_entries_to_alloacte; 7500 #endif /* BCM_PETRA_SUPPORT */ 7501 7502 assert(SOC_UNIT_VALID(unit)); 7503 7504 soc = SOC_CONTROL(unit); 7505 soc->ctr_evict_pid = SAL_THREAD_ERROR; 7506 soc->ctr_evict_interval = 0; 7507 soc->counter_pid = SAL_THREAD_ERROR; 7508 soc->counter_interval = 0; 7509 SOC_PBMP_CLEAR(soc->counter_pbmp); 7510 soc->counter_trigger = NULL; 7511 soc->counter_intr = NULL; 7512 /* Note that flags will be reinitialized in soc_counter_start */ 7513 if (soc_feature(unit, soc_feature_stat_dma) && !SOC_IS_RCPU_ONLY(unit)) { 7514 soc->counter_flags = SOC_COUNTER_F_DMA; 7515 } else { 7516 soc->counter_flags = 0; 7517 } 7518 soc->counter_coll_prev = soc->counter_coll_cur = sal_time_usecs(); 7519 7520 /*For soc_feature_controlled_counters feture (use only the relevant)*/ 7521 if (soc_feature(unit, soc_feature_controlled_counters)) { 7522 /*For not soc_feature_ignore_controlled_counter_priority feture (use only the relevant)*/ 7523 if (!soc_feature(unit, soc_feature_ignore_controlled_counter_priority)) { 7524 counter_level = soc_property_get_str(unit, spn_SOC_COUNTER_CONTROL_LEVEL); 7525 if(NULL == counter_level) { 7526 soc->soc_controlled_counter_flags |= _SOC_CONTROLLED_COUNTER_FLAG_HIGH; 7527 } else if (sal_strcmp(counter_level, "HIGH_LEVEL")) { 7528 soc->soc_controlled_counter_flags |= _SOC_CONTROLLED_COUNTER_FLAG_HIGH; 7529 } else if (sal_strcmp(counter_level, "MEDIUM_LEVEL")) { 7530 soc->soc_controlled_counter_flags |= (_SOC_CONTROLLED_COUNTER_FLAG_HIGH | _SOC_CONTROLLED_COUNTER_FLAG_MEDIUM); 7531 } else if (sal_strcmp(counter_level, "LOW_LEVEL")) { 7532 soc->soc_controlled_counter_flags |= (_SOC_CONTROLLED_COUNTER_FLAG_HIGH | _SOC_CONTROLLED_COUNTER_FLAG_MEDIUM | _SOC_CONTROLLED_COUNTER_FLAG_LOW); 7533 } else { /*default*/ 7534 LOG_ERROR(BSL_LS_SOC_COMMON, 7535 (BSL_META_U(unit, 7536 "soc_counter_attach: unit %d:illegal counter level \n"), unit)); 7537 return SOC_E_FAIL; 7538 } 7539 } 7540 /*count the relevant counters (according to level)*/ 7541 soc->soc_controlled_counter_num = 0; 7542 soc->soc_controlled_counter_all_num = 0; 7543 if (soc->controlled_counters) { 7544 for (array_idx = 0; soc->controlled_counters[array_idx].controlled_counter_f != NULL; array_idx++) { 7545 7546 #ifdef BCM_PETRA_SUPPORT 7547 if (SOC_IS_ARAD(unit)) { 7548 /*do not collect NIF counters - the register are not cleared on read*/ 7549 if ( (soc->controlled_counters[array_idx].flags & _SOC_CONTROLLED_COUNTER_FLAG_NIF) || (soc->controlled_counters[array_idx].flags & _SOC_CONTROLLED_COUNTER_FLAG_ILKN) ) { 7550 continue; 7551 } 7552 } 7553 #endif 7554 (soc->soc_controlled_counter_all_num)++; 7555 if (soc_feature(unit, soc_feature_ignore_controlled_counter_priority)) { 7556 (soc->soc_controlled_counter_num)++; 7557 soc->controlled_counters[array_idx].counter_idx = soc->soc_controlled_counter_all_num - 1; 7558 LOG_DEBUG(BSL_LS_SOC_COMMON, 7559 (BSL_META_U(unit, 7560 "counter_idx, %d. counter_id,%d.\n"), 7561 soc->controlled_counters[array_idx].counter_idx, 7562 soc->controlled_counters[array_idx].counter_id)); 7563 } else { 7564 if (soc->controlled_counters[array_idx].flags & soc->soc_controlled_counter_flags) { 7565 (soc->soc_controlled_counter_num)++; 7566 soc->controlled_counters[array_idx].counter_idx = soc->soc_controlled_counter_all_num - 1; 7567 } 7568 } 7569 } 7570 } 7571 } 7572 portsize = 0; 7573 port = 0; 7574 /* We can't use pbmp_valid calculations, so we must do this manually. */ 7575 for (phy_port = 0; ; phy_port++) { 7576 blk = SOC_PORT_BLOCK(unit, phy_port); 7577 #if defined(BCM_MONTEREY_SUPPORT) 7578 if (SOC_IS_MONTEREY(unit) ) { 7579 if ((((phy_port > 0) && (phy_port < 13)) || 7580 ((phy_port > 52) && (phy_port < 65))) 7581 && !(IS_CPRI_PORT(unit, port))) { 7582 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1); 7583 } 7584 } 7585 #endif 7586 bindex = SOC_PORT_BINDEX(unit, phy_port); 7587 if (blk < 0 && bindex < 0) { /* end of list */ 7588 break; 7589 } 7590 if (soc_feature(unit, soc_feature_logical_port_num)) { 7591 if (port < SOC_INFO(unit).port_p2l_mapping[phy_port]) { 7592 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 7593 } 7594 } else { 7595 port = phy_port; 7596 } 7597 } 7598 7599 port++; 7600 7601 #if defined(BCM_TOMAHAWK2_SUPPORT) 7602 /* for flex port, should reserve enough counter resources */ 7603 if (SOC_IS_TOMAHAWK2(unit)) { 7604 if (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, _TH2_PBLKS_PER_DEV)) { 7605 int num_pipe = soc_property_get(unit, "num_pipe", 4); 7606 port = num_pipe * _TH2_DEV_PORTS_PER_PIPE; 7607 } 7608 } 7609 #endif 7610 7611 /* Don't count last port if CMIC */ 7612 if (CMIC_PORT(unit) == (port - 1)) { 7613 /* 7614 * On XGS3 switch CMIC port stats are DMAable. Allocate space 7615 * in case these stats need to be DMAed as well. 7616 */ 7617 if (!soc_feature(unit, soc_feature_cpuport_stat_dma)) { 7618 port--; 7619 } 7620 } 7621 7622 nports = port; /* 0..max_port_num */ 7623 ports64 = 0; 7624 7625 if (SOC_IS_HB_GW(unit)) { 7626 portsize = 2048; 7627 ports64 = nports; 7628 } else if (SOC_IS_APACHE(unit)) { 7629 portsize = 17 * 1024; 7630 ports64 = nports; 7631 } else if (SOC_IS_TRX(unit)) { 7632 portsize = 4096; 7633 ports64 = nports; 7634 } else if (SOC_IS_HERCULES(unit) || SOC_IS_XGS3_SWITCH(unit)) { 7635 portsize = 1024; 7636 ports64 = nports; 7637 #if defined(BCM_PETRA_SUPPORT) 7638 } else if (SOC_IS_ARAD(unit)) { 7639 nof_entries_to_alloacte = FABRIC_LOGICAL_PORT_BASE(unit) + SOC_DPP_DEFS_GET(unit, first_fabric_link_id) + SOC_DPP_DEFS_GET(unit, nof_fabric_links); 7640 if (nof_entries_to_alloacte < nports){ 7641 LOG_ERROR(BSL_LS_SOC_COMMON, 7642 (BSL_META_U(unit, 7643 "Number of counters (%d) is larger than counters allowed in database (%d)!\n"), 7644 nports, nof_entries_to_alloacte)); 7645 } 7646 nports = nof_entries_to_alloacte; 7647 ports64 = nports; 7648 portsize = sizeof(uint64) * (soc->soc_controlled_counter_all_num + 160 /*nof non controlled counters*/); 7649 #endif 7650 #if defined(BCM_DNX_SUPPORT) 7651 } else if (SOC_IS_DNX(unit)) { 7652 nports = dnx_data_port.general.fabric_port_base_get(unit) + dnx_data_fabric.links.nof_links_get(unit); 7653 ports64 = nports; 7654 portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num); 7655 #endif 7656 #if defined(BCM_DFE_SUPPORT) 7657 } else if (SOC_IS_DFE(unit)) { 7658 ports64 = nports; 7659 portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num); 7660 #endif 7661 #if defined(BCM_DNXF_SUPPORT) 7662 } else if (SOC_IS_DNXF(unit)) { 7663 ports64 = nports; 7664 portsize = sizeof(uint64)*(soc->soc_controlled_counter_all_num); 7665 #endif 7666 } else { 7667 LOG_ERROR(BSL_LS_SOC_COMMON, 7668 (BSL_META_U(unit, 7669 "soc_counter_attach: unit %d: unexpected chip type\n"), 7670 unit)); 7671 return SOC_E_FAIL; 7672 } 7673 7674 soc->counter_perport = portsize / sizeof(uint64); 7675 soc->counter_n32 = 0; 7676 soc->counter_n64 = (portsize / sizeof(uint64)) * ports64; 7677 soc->counter_ports32 = 0; 7678 if(soc->counter_flags & SOC_COUNTER_F_DMA) { 7679 soc->counter_ports64 = ports64; 7680 } 7681 n_bytes = portsize * nports; 7682 7683 n_entries = soc->counter_n32 + soc->counter_n64; 7684 soc->counter_portsize = portsize; 7685 soc->counter_bufsize = n_bytes; 7686 7687 LOG_DEBUG(BSL_LS_SOC_COMMON, 7688 (BSL_META_U(unit, 7689 "soc_counter_attach: %d bytes/port, %d ports, %d ctrs/port, " 7690 "%d ports with %d ctrs\n"), 7691 portsize, nports, soc->counter_perport, 7692 ports64, soc->counter_n64)); 7693 7694 /* Initialize SOC Counter Control Structure */ 7695 if (SOC_CTR_CTRL(unit) != NULL) { 7696 sal_free(soc_ctr_ctrl); 7697 SOC_CTR_CTRL(unit) = NULL; 7698 } 7699 7700 if (SOC_CTR_CTRL(unit) == NULL) { 7701 soc_ctr_ctrl = sal_alloc(sizeof(soc_counter_control_t), 7702 "cntr_ctrl_s"); 7703 if (!soc_ctr_ctrl) { 7704 return SOC_E_MEMORY; 7705 } 7706 } 7707 sal_memset(soc_ctr_ctrl, 0, sizeof(soc_counter_control_t)); 7708 SOC_CTR_CTRL(unit) = soc_ctr_ctrl; 7709 7710 #ifdef BCM_TOMAHAWK_SUPPORT 7711 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 7712 soc_ctr_ctrl->collect_non_stat_dma = soc_counter_collect_th_non_dma_entries; 7713 } else 7714 #endif /* BCM_TOMAHAWK_SUPPORT */ 7715 { 7716 soc_ctr_ctrl->collect_non_stat_dma = soc_counter_collect_non_dma_entries; 7717 } 7718 7719 /* Initialize Non-DMA counters */ 7720 7721 if (soc->counter_non_dma == NULL) { 7722 soc->counter_non_dma = sal_alloc((SOC_COUNTER_NON_DMA_END - 7723 SOC_COUNTER_NON_DMA_START) * 7724 sizeof(soc_counter_non_dma_t), 7725 "cntr_non_dma"); 7726 if (soc->counter_non_dma == NULL) { 7727 goto error; 7728 } 7729 } else { 7730 for (idx = 0; idx < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START; 7731 idx++) { 7732 if (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_ALLOC) { 7733 soc_cm_sfree(unit, soc->counter_non_dma[idx].dma_buf[0]); 7734 } 7735 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) 7736 if((soc->counter_non_dma[idx].extra_ctrs != NULL) && 7737 ((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_DO_DMA) || 7738 (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM))){ 7739 uint32 ct2, ctr_offset; 7740 uint32 fld_ct = 2; /* TH/TH2 has default fld_ct = 2 */ 7741 #ifdef BCM_TOMAHAWK3_SUPPORT 7742 if(SOC_IS_TOMAHAWK3(unit)) { 7743 fld_ct = soc->counter_non_dma[idx].extra_ctr_fld_ct; 7744 } 7745 #endif /* BCM_TOMAHAWK3_SUPPORT */ 7746 for(ct = 0; ct < soc->counter_non_dma[idx].extra_ctr_ct; ct++) { 7747 for(ct2 = 0; ct2 < fld_ct; ct2++) { 7748 ctr_offset = ct * fld_ct + ct2; 7749 if((soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname != NULL) && 7750 (soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname[0] == '*')){ 7751 sal_free(soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname); 7752 soc->counter_non_dma[idx].extra_ctrs[ctr_offset].cname = NULL; 7753 } 7754 } 7755 } 7756 7757 sal_free(soc->counter_non_dma[idx].extra_ctrs); 7758 soc->counter_non_dma[idx].extra_ctrs = NULL; 7759 if((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM) && 7760 (soc->counter_non_dma[idx].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) { 7761 soc->counter_non_dma[idx+1].extra_ctrs = NULL; 7762 } 7763 } 7764 #endif /* BCM_TOMAHAWK_SUPPORT */ 7765 } 7766 } 7767 sal_memset(soc->counter_non_dma, 0, 7768 (SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START) * 7769 sizeof(soc_counter_non_dma_t)); 7770 7771 /* Controlled counters */ 7772 if (!soc_feature(unit, soc_feature_controlled_counters)) { 7773 soc->controlled_counters = NULL; 7774 } 7775 7776 /* Initialize the number of cosq counters per port */ 7777 _soc_counter_num_cosq_init(unit, nports); 7778 7779 #ifdef BCM_TRIUMPH_SUPPORT 7780 #ifdef BCM_TRIUMPH3_SUPPORT 7781 if (SOC_IS_TRIUMPH3(unit)) { 7782 if (SOC_FAILURE(_soc_counter_triumph3_non_dma_init(unit, 7783 nports, n_entries, &non_dma_entries))) { 7784 goto error; 7785 } 7786 } else 7787 #endif /* BCM_TRIUMPH3_SUPPORT */ 7788 #ifdef BCM_TOMAHAWK_SUPPORT 7789 if (SOC_IS_TOMAHAWKX(unit)) { 7790 #ifdef BCM_TOMAHAWK3_SUPPORT 7791 if (SOC_IS_TOMAHAWK3(unit)) { 7792 if (SOC_FAILURE(soc_counter_tomahawk3_non_dma_init 7793 (unit, nports, n_entries, &non_dma_entries))) { 7794 goto error; 7795 } 7796 } else 7797 #endif 7798 if (SOC_FAILURE(soc_counter_tomahawk_non_dma_init 7799 (unit, nports, n_entries, &non_dma_entries))) { 7800 goto error; 7801 } 7802 } else 7803 #endif /* BCM_TOMAHAWK_SUPPORT */ 7804 #ifdef BCM_TRIDENT3_SUPPORT 7805 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 7806 if (SOC_FAILURE(soc_counter_trident3_non_dma_init 7807 (unit, nports, n_entries, &non_dma_entries))) { 7808 goto error; 7809 } 7810 } else 7811 #endif /* BCM_TOMAHAWK_SUPPORT */ 7812 #ifdef BCM_HELIX5_SUPPORT 7813 if (SOC_IS_HELIX5(unit)) { 7814 if (SOC_FAILURE(soc_counter_helix5_non_dma_init 7815 (unit, nports, n_entries, &non_dma_entries))) { 7816 goto error; 7817 } 7818 } else 7819 #endif /* BCM_HELIX5_SUPPORT */ 7820 #ifdef BCM_APACHE_SUPPORT 7821 if (SOC_IS_APACHE(unit)) { 7822 if (SOC_FAILURE(_soc_counter_apache_non_dma_init(unit, 7823 nports, n_entries, &non_dma_entries))) { 7824 goto error; 7825 } 7826 #if defined(BCM_MONTEREY_SUPPORT) && defined (CPRIMOD_SUPPORT) 7827 /* Add CPRI counters if supported */ 7828 if (SOC_IS_MONTEREY(unit)) { 7829 int cpri_non_dma_entries = 0; 7830 if (SOC_FAILURE(_soc_counter_monterey_non_dma_cpri_init(unit, 7831 nports, n_entries + non_dma_entries, 7832 &cpri_non_dma_entries))) { 7833 goto error; 7834 } 7835 non_dma_entries += cpri_non_dma_entries; 7836 } 7837 #endif /* BCM_MONTEREY_SUPPORT && CPRIMOD_SUPPORT */ 7838 } else 7839 #endif /* BCM_APACHE_SUPPORT */ 7840 #if defined ( BCM_TRIDENT2_SUPPORT ) || defined ( BCM_TRIDENT2PLUS_SUPPORT ) 7841 if (SOC_IS_TD2_TT2(unit)) { 7842 if (SOC_FAILURE(_soc_counter_trident2_non_dma_init(unit, 7843 nports, n_entries, &non_dma_entries))) { 7844 goto error; 7845 } 7846 } else 7847 #endif /* BCM_TRIDENT2_SUPPORT */ 7848 #ifdef BCM_TRIDENT_SUPPORT 7849 if (SOC_IS_TD_TT(unit)) { 7850 if (SOC_FAILURE(_soc_counter_trident_non_dma_init(unit, nports, n_entries, 7851 &non_dma_entries))) { 7852 goto error; 7853 } 7854 } else 7855 #endif /* BCM_TRIDENT_SUPPORT */ 7856 #ifdef BCM_HURRICANE_SUPPORT 7857 if (SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) { 7858 if (SOC_FAILURE(_soc_counter_hu_non_dma_init(unit, nports, n_entries, 7859 &non_dma_entries))) { 7860 goto error; 7861 } 7862 } else 7863 #endif /* BCM_HURRICANE_SUPPORT */ 7864 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 7865 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 7866 if (SOC_FAILURE(_soc_counter_gh_non_dma_init(unit, nports, n_entries, 7867 &non_dma_entries))) { 7868 goto error; 7869 } 7870 } else 7871 #endif /* BCM_GREYHOUND_SUPPORT || BCM_HURRICANE3_SUPPORT */ 7872 #if defined(BCM_GREYHOUND2_SUPPORT) 7873 if (SOC_IS_GREYHOUND2(unit)) { 7874 if (SOC_FAILURE(_soc_counter_gh2_non_dma_init(unit, nports, n_entries, 7875 &non_dma_entries))) { 7876 goto error; 7877 } 7878 } else 7879 #endif /* BCM_GREYHOUND2_SUPPORT */ 7880 #ifdef BCM_KATANA2_SUPPORT 7881 /*we may not need separate saber2_non_dma() function */ 7882 if (SOC_IS_KATANA2(unit)) { 7883 if (SOC_FAILURE(_soc_counter_saber2_non_dma_init(unit, nports, n_entries, 7884 &non_dma_entries))) { 7885 goto error; 7886 } 7887 } else 7888 #endif /* BCM_SABER2_SUPPORT */ 7889 #ifdef BCM_KATANA_SUPPORT 7890 if (SOC_IS_KATANAX(unit)) { 7891 if (SOC_FAILURE(_soc_counter_katana_non_dma_init(unit, nports, n_entries, 7892 &non_dma_entries))) { 7893 goto error; 7894 } 7895 } else 7896 #endif /* BCM_KATANA_SUPPORT */ 7897 if (SOC_IS_TR_VL(unit)) { 7898 if (SOC_FAILURE(_soc_counter_tr_non_dma_init(unit, nports, n_entries, 7899 &non_dma_entries))) { 7900 goto error; 7901 } 7902 } else 7903 #endif /* BCM_TRIUMPH_SUPPORT */ 7904 #ifdef BCM_SCORPION_SUPPORT 7905 if (SOC_IS_SC_CQ(unit) && (!(SOC_IS_SHADOW(unit)))) { 7906 if (SOC_FAILURE(_soc_counter_sc_non_dma_init(unit, nports, n_entries, 7907 &non_dma_entries))) { 7908 goto error; 7909 } 7910 } else 7911 #endif /* BCM_SCORPION_SUPPORT */ 7912 #ifdef BCM_SHADOW_SUPPORT 7913 if (SOC_IS_SHADOW(unit)) { 7914 if (!SOC_PBMP_IS_NULL(PBMP_IL_ALL(unit))) { 7915 if (SOC_FAILURE(_soc_counter_shadow_non_dma_init(unit, nports, 7916 n_entries, &non_dma_entries))) { 7917 goto error; 7918 } 7919 } 7920 } else 7921 #endif /* BCM_SHADOW_SUPPORT */ 7922 #ifdef BCM_BRADLEY_SUPPORT 7923 if (SOC_IS_HB_GW(unit)) { 7924 if (SOC_FAILURE(_soc_counter_hb_non_dma_init(unit, nports, n_entries, 7925 &non_dma_entries))) { 7926 goto error; 7927 } 7928 } else 7929 #endif /* BCM_BRADLEY_SUPPORT */ 7930 #ifdef BCM_FIREBOLT_SUPPORT 7931 if (SOC_IS_FB_FX_HX(unit)) { 7932 if (SOC_FAILURE(_soc_counter_fb_non_dma_init(unit, nports, n_entries, 7933 &non_dma_entries))) { 7934 goto error; 7935 } 7936 } else 7937 #endif /* BCM_FIREBOLT_SUPPORT */ 7938 { 7939 non_dma_entries = 0; 7940 } 7941 7942 soc->counter_n64_non_dma = non_dma_entries; 7943 7944 /* 7945 * Counter DMA buffer allocation (32 and 64 bit allocated together) 7946 */ 7947 7948 assert(n_bytes > 0); 7949 7950 /* Hardware DMA buf */ 7951 if(soc->counter_flags & SOC_COUNTER_F_DMA) { 7952 if (soc->counter_buf32 == NULL) { 7953 soc->counter_buf32 = soc_cm_salloc(unit, n_bytes, "cntr_dma_buf"); 7954 if (soc->counter_buf32 == NULL) { 7955 goto error; 7956 } 7957 soc->counter_buf64 = (uint64 *)&soc->counter_buf32[soc->counter_n32]; 7958 } 7959 sal_memset(soc->counter_buf32, 0, n_bytes); 7960 } 7961 7962 n_entries += non_dma_entries; 7963 7964 /* Hardware value buf */ 7965 if (soc->counter_hw_val != NULL) { 7966 sal_free(soc->counter_hw_val); 7967 soc->counter_hw_val = NULL; 7968 } 7969 if (soc->counter_hw_val == NULL) { 7970 soc->counter_hw_val = sal_alloc(n_entries * sizeof(uint64), 7971 "cntr_hw_val"); 7972 if (soc->counter_hw_val == NULL) { 7973 goto error; 7974 } 7975 } 7976 sal_memset(soc->counter_hw_val, 0, n_entries * sizeof(uint64)); 7977 7978 /* Software value buf */ 7979 if (soc->counter_sw_val != NULL) { 7980 sal_free(soc->counter_sw_val); 7981 soc->counter_sw_val = NULL; 7982 } 7983 if (soc->counter_sw_val == NULL) { 7984 soc->counter_sw_val = sal_alloc(n_entries * sizeof(uint64), 7985 "cntr_sw_val"); 7986 if (soc->counter_sw_val == NULL) { 7987 goto error; 7988 } 7989 } 7990 sal_memset(soc->counter_sw_val, 0, n_entries * sizeof(uint64)); 7991 7992 /* Delta buf */ 7993 if (soc->counter_delta != NULL) { 7994 sal_free(soc->counter_delta); 7995 soc->counter_delta = NULL; 7996 } 7997 if (soc->counter_delta == NULL) { 7998 soc->counter_delta = sal_alloc(n_entries * sizeof(uint64), 7999 "cntr_delta"); 8000 if (soc->counter_delta == NULL) { 8001 goto error; 8002 } 8003 } 8004 sal_memset(soc->counter_delta, 0, n_entries * sizeof(uint64)); 8005 soc_ctr_ctrl->total_dma_entries = n_entries; 8006 8007 #ifdef BCM_SBUSDMA_SUPPORT 8008 _soc_counter_pending[unit] = 0; 8009 #endif 8010 8011 /* Set up and install counter maps */ 8012 8013 /* We can't use pbmp_valid calculations, so we must do this manually. */ 8014 for (phy_port = 0; ; phy_port++) { 8015 #if defined(BCM_DNX_SUPPORT) 8016 if (SOC_IS_DNX(unit)) { 8017 break; /*skip due to dnx using controlled counter */ 8018 } 8019 #endif 8020 blk = SOC_PORT_BLOCK(unit, phy_port); 8021 bindex = SOC_PORT_BINDEX(unit, phy_port); 8022 if (blk < 0 && bindex < 0) { /* end of list */ 8023 break; 8024 } 8025 if (blk < 0) { /* empty slot */ 8026 continue; 8027 } 8028 if (soc_feature(unit, soc_feature_logical_port_num)) { 8029 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 8030 if (port < 0) { 8031 continue; 8032 } 8033 } else { 8034 port = phy_port; 8035 if (port >= nports) { 8036 continue; 8037 } 8038 } 8039 #if defined(BCM_MONTEREY_SUPPORT) 8040 if (!(IS_CPRI_PORT(unit, port)) && SOC_IS_MONTEREY(unit)) { 8041 if (((phy_port > 0) && (phy_port < 13)) || 8042 ((phy_port > 52) && (phy_port < 65))) { 8043 blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1); 8044 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1); 8045 if (blk < 0 && bindex < 0) { /* end of list */ 8046 break; 8047 } 8048 if (blk < 0) { /* empty slot */ 8049 continue; 8050 } 8051 } 8052 } 8053 #endif 8054 blktype = SOC_BLOCK_INFO(unit, blk).type; 8055 switch (blktype) { 8056 case SOC_BLK_EPIC: 8057 ctype = SOC_CTR_TYPE_FE; 8058 break; 8059 case SOC_BLK_GPIC: 8060 case SOC_BLK_GPORT: 8061 case SOC_BLK_QGPORT: 8062 case SOC_BLK_SPORT: 8063 ctype = SOC_CTR_TYPE_GE; 8064 break; 8065 case SOC_BLK_XQPORT: 8066 case SOC_BLK_XGPORT: 8067 if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) { 8068 ctype = SOC_CTR_TYPE_XE; 8069 } else { 8070 ctype = SOC_CTR_TYPE_GE; 8071 } 8072 break; 8073 case SOC_BLK_IPIC: 8074 case SOC_BLK_HPIC: 8075 ctype = SOC_CTR_TYPE_HG; 8076 break; 8077 case SOC_BLK_XPIC: 8078 case SOC_BLK_XPORT: 8079 case SOC_BLK_GXPORT: 8080 case SOC_BLK_XLPORT: 8081 case SOC_BLK_XLPORTB0: 8082 case SOC_BLK_XTPORT: 8083 case SOC_BLK_CLPORT: 8084 case SOC_BLK_MXQPORT: 8085 case SOC_BLK_XWPORT: 8086 case SOC_BLK_CDPORT: 8087 if (SOC_IS_GREYHOUND(unit) && blktype == SOC_BLK_GXPORT){ 8088 if (SOC_BLOCK_PORT(unit, blk) < 0){ 8089 ctype = SOC_CTR_TYPE_XE; 8090 } else { 8091 /* Greyhound GE port with SOC_BLK_GXPORT case*/ 8092 ctype = SOC_CTR_TYPE_GE; 8093 } 8094 } else { 8095 ctype = SOC_CTR_TYPE_XE; 8096 } 8097 8098 #ifdef BCM_SABER2_SUPPORT 8099 if (SOC_IS_SABER2(unit)) { 8100 if (blktype == SOC_BLK_MXQPORT) { 8101 ctype = SOC_CTR_TYPE_GE; 8102 break; 8103 } 8104 if (blktype == SOC_BLK_XLPORT) { 8105 ctype = SOC_CTR_TYPE_XE; 8106 break; 8107 } 8108 LOG_WARN(BSL_LS_SOC_COMMON, 8109 (BSL_META_U(unit, " UNKNOWN TYPE \n"))); 8110 } 8111 if (SOC_IS_GREYHOUND2(unit) && blktype == SOC_BLK_CLPORT) { 8112 ctype = SOC_CTR_TYPE_CE; 8113 } 8114 #endif /* BCM_SABER2_SUPPORT */ 8115 #ifdef BCM_HELIX5_SUPPORT 8116 if (SOC_IS_HELIX5(unit)) { 8117 if (IS_QSGMII_PORT(unit, port)) { 8118 ctype = SOC_CTR_TYPE_GE; 8119 } else { 8120 ctype = SOC_CTR_TYPE_XE; 8121 } 8122 if (blktype == SOC_BLK_CLPORT) { 8123 ctype = SOC_CTR_TYPE_CE; 8124 } 8125 break; 8126 } 8127 #endif 8128 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT) || defined (BCM_TOMAHAWK2_SUPPORT) || defined (BCM_TOMAHAWK3_SUPPORT) 8129 if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKPLUS(unit)) || 8130 (SOC_IS_TOMAHAWK2(unit)) || (SOC_IS_TOMAHAWK3(unit))) { 8131 if (blktype == SOC_BLK_CLPORT) { 8132 ctype = SOC_CTR_TYPE_CE; 8133 break; 8134 } 8135 if (blktype == SOC_BLK_CDPORT) { 8136 ctype = SOC_CTR_TYPE_CD; 8137 break; 8138 } 8139 if (blktype == SOC_BLK_XLPORT) { 8140 ctype = SOC_CTR_TYPE_XE; 8141 break; 8142 } 8143 LOG_WARN(BSL_LS_SOC_COMMON, 8144 (BSL_META_U(unit, " UNKNOWN TYPE \n"))); 8145 } 8146 #endif 8147 break; 8148 case SOC_BLK_CLG2PORT: 8149 ctype = SOC_CTR_TYPE_CE; 8150 break; 8151 case SOC_BLK_CLP: 8152 case SOC_BLK_XLP: 8153 if (IS_IL_PORT(unit, port)) { 8154 continue; 8155 } else if (IS_CE_PORT(unit, port)) { 8156 ctype = SOC_CTR_TYPE_CE; 8157 } else if (IS_QSGMII_PORT(unit,port)) { 8158 ctype = SOC_CTR_TYPE_GE; 8159 } else { 8160 ctype = SOC_CTR_TYPE_XE; 8161 } 8162 break; 8163 case SOC_BLK_MXQ: 8164 ctype = SOC_CTR_TYPE_GE; 8165 break; 8166 case SOC_BLK_CMIC: 8167 #if defined(BCM_MONTEREY_SUPPORT) 8168 case SOC_BLK_CPRI: 8169 #endif 8170 if (soc_feature(unit, soc_feature_cpuport_stat_dma)) { 8171 ctype = SOC_CTR_TYPE_CPU; 8172 break; 8173 } 8174 case SOC_BLK_CPIC: 8175 default: 8176 continue; 8177 } 8178 8179 if (!SOC_CONTROL(unit)->counter_map[port]) { 8180 SOC_CONTROL(unit)->counter_map[port] = 8181 &SOC_CTR_DMA_MAP(unit, ctype); 8182 assert(SOC_CONTROL(unit)->counter_map[port]); 8183 } 8184 8185 #ifdef BCM_WARM_BOOT_SUPPORT 8186 /* Flexport operation can change port mappings. 8187 * counter_map should be reassigned based on recovered port info 8188 * from scache, especially for devices using multiple counter maps of 8189 * different sizes 8190 */ 8191 if (SOC_WARM_BOOT(unit)) { 8192 SOC_CONTROL(unit)->counter_map[port] = 8193 &SOC_CTR_DMA_MAP(unit, ctype); 8194 assert(SOC_CONTROL(unit)->counter_map[port]); 8195 } 8196 #endif 8197 assert(SOC_CONTROL(unit)->counter_map[port]->cmap_base); 8198 8199 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 8200 /* We need this done in a port loop like this one, so we're 8201 * piggybacking on it. */ 8202 8203 if (soc_feature(unit, soc_feature_timestamp_counter) && 8204 SOC_CONTROL(unit)->sw_timestamp_fifo_enable) { 8205 /* A HW register implemented as a FIFO-pop on read is in the 8206 * counter collection space. We must copy the DMA'd values 8207 * into a SW FIFO and make them available to the application 8208 * on request. 8209 */ 8210 if (soc->counter_timestamp_fifo[port] == NULL) { 8211 soc->counter_timestamp_fifo[port] = 8212 sal_alloc(sizeof(shr_fifo_t), "Timestamp counter FIFO"); 8213 if (soc->counter_timestamp_fifo[port] == NULL) { 8214 goto error; 8215 } 8216 } else { 8217 SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]); 8218 } 8219 sal_memset(soc->counter_timestamp_fifo[port], 0, 8220 sizeof(shr_fifo_t)); 8221 SHR_FIFO_ALLOC(soc->counter_timestamp_fifo[port], 8222 COUNTER_TIMESTAMP_FIFO_SIZE, sizeof(uint32), 8223 SHR_FIFO_FLAG_DO_NOT_PUSH_DUPLICATE); 8224 } 8225 #endif /* BCM_TRIUMPH2_SUPPORT */ 8226 } 8227 #ifdef BCM_SBUSDMA_SUPPORT 8228 /* Init blk counters */ 8229 if (soc->blk_ctr_desc_count) { 8230 uint16 ctr; 8231 /* Calc size */ 8232 n_entries = 0; 8233 for (idx = 0; idx < soc->blk_ctr_desc_count; idx++) { 8234 ctr = 0; 8235 while (soc->blk_ctr_desc[idx].desc[ctr].reg != INVALIDr) { 8236 n_entries += soc->blk_ctr_desc[idx].desc[ctr].entries; 8237 ctr++; 8238 } 8239 } 8240 soc->blk_ctr_count = n_entries; 8241 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 8242 (BSL_META_U(unit, 8243 "Total ctr blks: %d, Total entries: %d\n"), 8244 soc->blk_ctr_desc_count, n_entries)); 8245 if (_soc_blk_counter_handles[unit] == NULL) { 8246 _soc_blk_counter_handles[unit] = sal_alloc(n_entries * sizeof(sbusdma_desc_handle_t), 8247 "blk_ctr_desc_handles"); 8248 if (_soc_blk_counter_handles[unit] == NULL) { 8249 goto error; 8250 } 8251 } 8252 sal_memset(_soc_blk_counter_handles[unit], 0, n_entries * sizeof(sbusdma_desc_handle_t)); 8253 8254 if (soc->blk_ctr_buf == NULL) { 8255 soc->blk_ctr_buf = soc_cm_salloc(unit, n_entries * sizeof(uint64), 8256 "blk_ctr_hw_buff"); 8257 if (soc->blk_ctr_buf == NULL) { 8258 goto error; 8259 } 8260 } 8261 sal_memset(soc->blk_ctr_buf, 0, n_entries * sizeof(uint64)); 8262 8263 if (soc->blk_counter_hw_val == NULL) { 8264 soc->blk_counter_hw_val = sal_alloc(n_entries * sizeof(uint64), 8265 "blk_ctr_hw_vals"); 8266 if (soc->blk_counter_hw_val == NULL) { 8267 goto error; 8268 } 8269 } 8270 sal_memset(soc->blk_counter_hw_val, 0, n_entries * sizeof(uint64)); 8271 8272 if (soc->blk_counter_sw_val == NULL) { 8273 soc->blk_counter_sw_val = sal_alloc(n_entries * sizeof(uint64), 8274 "blk_ctr_sw_vals"); 8275 if (soc->blk_counter_sw_val == NULL) { 8276 goto error; 8277 } 8278 } 8279 sal_memset(soc->blk_counter_sw_val, 0, n_entries * sizeof(uint64)); 8280 } 8281 #endif 8282 return SOC_E_NONE; 8283 8284 error: 8285 8286 #ifdef BCM_SBUSDMA_SUPPORT 8287 if (soc->blk_counter_sw_val != NULL) { 8288 sal_free(soc->blk_counter_sw_val); 8289 soc->blk_counter_sw_val = NULL; 8290 } 8291 8292 if (soc->blk_counter_hw_val != NULL) { 8293 sal_free(soc->blk_counter_hw_val); 8294 soc->blk_counter_hw_val = NULL; 8295 } 8296 8297 if (soc->blk_ctr_buf != NULL) { 8298 soc_cm_sfree(unit, soc->blk_ctr_buf); 8299 soc->blk_ctr_buf = NULL; 8300 } 8301 8302 if (_soc_blk_counter_handles[unit] != NULL) { 8303 sal_free(_soc_blk_counter_handles[unit]); 8304 _soc_blk_counter_handles[unit] = NULL; 8305 } 8306 #endif 8307 8308 #ifdef BCM_TRIUMPH2_SUPPORT 8309 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 8310 if (soc->counter_timestamp_fifo[port] != NULL) { 8311 SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]); 8312 sal_free(soc->counter_timestamp_fifo[port]); 8313 soc->counter_timestamp_fifo[port] = NULL; 8314 } 8315 } 8316 #endif /* BCM_TRIUMPH2_SUPPORT */ 8317 8318 if (soc->counter_evict != NULL) { 8319 sal_free(soc->counter_evict); 8320 soc->counter_evict = NULL; 8321 } 8322 8323 if (soc->counter_non_dma != NULL) { 8324 for (idx = 0; 8325 idx < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START; 8326 idx++) { 8327 if (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_ALLOC) { 8328 soc_cm_sfree(unit, soc->counter_non_dma[idx].dma_buf[0]); 8329 } 8330 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) 8331 if((soc->counter_non_dma[idx].extra_ctrs != NULL) && 8332 ((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_DO_DMA) || 8333 (soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM))){ 8334 for(ct = 0; ct < soc->counter_non_dma[idx].extra_ctr_ct; ct++) { 8335 if((soc->counter_non_dma[idx].extra_ctrs[ct*2].cname != NULL) && 8336 (soc->counter_non_dma[idx].extra_ctrs[ct*2].cname[0] == '*')){ 8337 sal_free(soc->counter_non_dma[idx].extra_ctrs[ct*2].cname); 8338 soc->counter_non_dma[idx].extra_ctrs[ct*2].cname = NULL; 8339 } 8340 8341 if((soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname != NULL) && 8342 (soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname[0] == '*')){ 8343 sal_free(soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname); 8344 soc->counter_non_dma[idx].extra_ctrs[ct*2+1].cname = NULL; 8345 } 8346 } 8347 8348 sal_free(soc->counter_non_dma[idx].extra_ctrs); 8349 soc->counter_non_dma[idx].extra_ctrs = NULL; 8350 if((soc->counter_non_dma[idx].flags & _SOC_COUNTER_NON_DMA_OBM) && 8351 (soc->counter_non_dma[idx].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) { 8352 soc->counter_non_dma[idx+1].extra_ctrs = NULL; 8353 } 8354 } 8355 #endif /* BCM_TOMAHAWK_SUPPORT */ 8356 } 8357 sal_free(soc->counter_non_dma); 8358 soc->counter_non_dma = NULL; 8359 } 8360 8361 if (soc->counter_buf32 != NULL) { 8362 soc_cm_sfree(unit, soc->counter_buf32); 8363 soc->counter_buf32 = NULL; 8364 soc->counter_buf64 = NULL; 8365 } 8366 8367 if (soc->counter_hw_val != NULL) { 8368 sal_free(soc->counter_hw_val); 8369 soc->counter_hw_val = NULL; 8370 } 8371 8372 if (soc->counter_sw_val != NULL) { 8373 sal_free(soc->counter_sw_val); 8374 soc->counter_sw_val = NULL; 8375 } 8376 8377 if (soc->counter_delta != NULL) { 8378 sal_free(soc->counter_delta); 8379 soc->counter_delta = NULL; 8380 } 8381 8382 return SOC_E_MEMORY; 8383 } 8384 8385 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 8386 int 8387 _soc_counter_trident2p_non_dma_pbmp_update(int unit) 8388 { 8389 int id, i; 8390 soc_control_t *soc = SOC_CONTROL(unit); 8391 soc_counter_non_dma_t *non_dma; 8392 int soc_counter_non_dma1[] = { 8393 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT, /* MC_PERQ_PKT */ 8394 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE, /* MC_PERQ_BYTE */ 8395 SOC_COUNTER_NON_DMA_COSQ_DROP_PKT, /* MCQ_DROP_PKT */ 8396 SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE, /* MCQ_DROP_BYTE */ 8397 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING, /* DROP_PKT_ING */ 8398 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING, /* DROP_BYTE_ING */ 8399 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER, /* DROP_PKT_IMTR */ 8400 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER, /* DROP_BYTE_IMTR */ 8401 SOC_COUNTER_NON_DMA_DROP_RQ_PKT, /* RQ_DROP_PKT */ 8402 SOC_COUNTER_NON_DMA_DROP_RQ_BYTE, /* RQ_DROP_BYTE */ 8403 SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW, /* RQ_DROP_PKT_YEL */ 8404 SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED, /* RQ_DROP_PKT_RED */ 8405 SOC_COUNTER_NON_DMA_PG_MIN_PEAK, /* PG_MIN_PEAK */ 8406 SOC_COUNTER_NON_DMA_PG_MIN_CURRENT, /* PG_MIN_CUR */ 8407 SOC_COUNTER_NON_DMA_PG_SHARED_PEAK, /* PG_SHARED_PEAK */ 8408 SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT, /* PG_SHARED_CUR */ 8409 SOC_COUNTER_NON_DMA_PG_HDRM_PEAK, /* PG_HDRM_PEAK */ 8410 SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT, /* PG_HDRM_CUR */ 8411 SOC_COUNTER_NON_DMA_QUEUE_PEAK, /* QUEUE_PEAK */ 8412 SOC_COUNTER_NON_DMA_QUEUE_CURRENT /* QUEUE_CUR */ 8413 }; 8414 8415 int soc_counter_non_dma2[] = { 8416 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC, /* UC_PERQ_PKT */ 8417 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC, /* UC_PERQ_BYTE */ 8418 SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC, /* UCQ_DROP_PKT */ 8419 SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC, /* UCQ_DROP_BYTE */ 8420 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW, /* DROP_PKT_YEL */ 8421 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED, /* DROP_PKT_RED */ 8422 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN, /* WRED_PKT_GRE */ 8423 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW, /* WRED_PKT_YEL */ 8424 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED, /* WRED_PKT_RED */ 8425 SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK, /* UC_QUEUE_PEAK */ 8426 SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT, /* UC_QUEUE_CUR */ 8427 SOC_COUNTER_NON_DMA_MMU_QCN_CNM, /* QCN_CNM_COUNTER */ 8428 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_HIGH_PRI, /* OBM0_HIGH_PRI_DROP_PKT */ 8429 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM0_LOW_PRI, /* OBM0_LOW_PRI_DROP_PKT */ 8430 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_HIGH_PRI, /* OBM0_HIGH_PRI_DROP_BYTE */ 8431 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM0_LOW_PRI, /* OBM0_LOW_PRI_DROP_BYTE */ 8432 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_HIGH_PRI, /* OBM1_HIGH_PRI_DROP_PKT */ 8433 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM1_LOW_PRI, /* OBM1_LOW_PRI_DROP_PKT */ 8434 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_HIGH_PRI, /* OBM1_HIGH_PRI_DROP_BYTE */ 8435 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM1_LOW_PRI, /* OBM1_LOW_PRI_DROP_BYTE */ 8436 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_HIGH_PRI, /* OBM2_HIGH_PRI_DROP_PKT */ 8437 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM2_LOW_PRI, /* OBM2_LOW_PRI_DROP_PKT */ 8438 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_HIGH_PRI, /* OBM2_HIGH_PRI_DROP_BYTE */ 8439 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM2_LOW_PRI, /* OBM2_LOW_PRI_DROP_BYTE */ 8440 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_HIGH_PRI, /* OBM3_HIGH_PRI_DROP_PKT */ 8441 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM3_LOW_PRI, /* OBM3_LOW_PRI_DROP_PKT */ 8442 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_HIGH_PRI, /* OBM3_HIGH_PRI_DROP_BYTE */ 8443 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM3_LOW_PRI /* OBM3_LOW_PRI_DROP_BYTE */ 8444 }; 8445 8446 for (i = 0; i < sizeof(soc_counter_non_dma1)/sizeof(int); ++i) { 8447 id = soc_counter_non_dma1[i]; 8448 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 8449 non_dma->pbmp = PBMP_ALL(unit); 8450 } 8451 8452 for (i = 0; i < sizeof(soc_counter_non_dma2)/sizeof(int); ++i) { 8453 id = soc_counter_non_dma2[i]; 8454 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 8455 non_dma->pbmp = PBMP_PORT_ALL(unit); 8456 } 8457 8458 return SOC_E_NONE; 8459 } 8460 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) */ 8461 8462 #if defined (BCM_APACHE_SUPPORT) 8463 int 8464 _soc_counter_apache_non_dma_pbmp_update(int unit) 8465 { 8466 int id, i; 8467 soc_control_t *soc = SOC_CONTROL(unit); 8468 soc_counter_non_dma_t *non_dma; 8469 int soc_counter_non_dma1[] = { 8470 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT, /* MC_PERQ_PKT */ 8471 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE, /* MC_PERQ_BYTE */ 8472 SOC_COUNTER_NON_DMA_COSQ_DROP_PKT, /* MCQ_DROP_PKT */ 8473 SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE, /* MCQ_DROP_BYTE */ 8474 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING, /* DROP_PKT_ING */ 8475 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING, /* DROP_BYTE_ING */ 8476 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_ING_METER, /* DROP_PKT_IMTR */ 8477 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_ING_METER, /* DROP_BYTE_IMTR */ 8478 SOC_COUNTER_NON_DMA_PG_MIN_PEAK, /* PG_MIN_PEAK */ 8479 SOC_COUNTER_NON_DMA_PG_MIN_CURRENT, /* PG_MIN_CUR */ 8480 SOC_COUNTER_NON_DMA_PG_SHARED_PEAK, /* PG_SHARED_PEAK */ 8481 SOC_COUNTER_NON_DMA_PG_SHARED_CURRENT, /* PG_SHARED_CUR */ 8482 SOC_COUNTER_NON_DMA_PG_HDRM_PEAK, /* PG_HDRM_PEAK */ 8483 SOC_COUNTER_NON_DMA_PG_HDRM_CURRENT, /* PG_HDRM_CUR */ 8484 SOC_COUNTER_NON_DMA_QUEUE_PEAK, /* QUEUE_PEAK */ 8485 SOC_COUNTER_NON_DMA_QUEUE_CURRENT /* QUEUE_CUR */ 8486 }; 8487 8488 int soc_counter_non_dma2[] = { 8489 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC, /* UC_PERQ_PKT */ 8490 SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC, /* UC_PERQ_BYTE */ 8491 SOC_COUNTER_NON_DMA_COSQ_DROP_PKT_UC, /* UCQ_DROP_PKT */ 8492 SOC_COUNTER_NON_DMA_COSQ_DROP_BYTE_UC, /* UCQ_DROP_BYTE */ 8493 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW, /* DROP_PKT_YEL */ 8494 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED, /* DROP_PKT_RED */ 8495 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN, /* WRED_PKT_GRE */ 8496 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW, /* WRED_PKT_YEL */ 8497 SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED, /* WRED_PKT_RED */ 8498 SOC_COUNTER_NON_DMA_UC_QUEUE_PEAK, /* UC_QUEUE_PEAK */ 8499 SOC_COUNTER_NON_DMA_UC_QUEUE_CURRENT, /* UC_QUEUE_CUR */ 8500 SOC_COUNTER_NON_DMA_MMU_QCN_CNM, /* QCN_CNM_COUNTER */ 8501 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO, /* OBM_LOSSY_LO_DRP_PKT */ 8502 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO, /* OBM_LOSSY_LO_DRP_BYTE */ 8503 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI, /* OBM_LOSSY_HI_DRP_PKT */ 8504 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI, /* OBM_LOSSY_HI_DRP_BYTE */ 8505 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0, /* OBM_LOSSLESS0_DRP_PKT */ 8506 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0, /* OBM_LOSSLESS0_DRP_BYTE */ 8507 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1, /* OBM_LOSSLESS1_DRP_PKT */ 8508 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1, /* OBM_LOSSLESS1_DRP_BYTE */ 8509 SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS, /* OBM_EXPRESS_DRP_PKT */ 8510 SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS, /* OBM_EXPRESS_DRP_BYTE */ 8511 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO, /* OBM_LOSSY_LO_ENQ_PKT */ 8512 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO, /* OBM_LOSSY_LO_ENQ_BYTE */ 8513 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI, /* OBM_LOSSY_HI_ENQ_PKT */ 8514 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI, /* OBM_LOSSY_HI_ENQ_BYTE */ 8515 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0, /* OBM_LOSSLESS0_ENQ_PKT */ 8516 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0, /* OBM_LOSSLESS0_ENQ_BYTE */ 8517 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1, /* OBM_LOSSLESS1_ENQ_PKT */ 8518 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1, /* OBM_LOSSLESS0_ENQ_BYTE */ 8519 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS, /* OBM_EXPRESS_ENQ_PKT */ 8520 SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS /* OBM_EXPRESS_ENQ_BYTE */ 8521 }; 8522 8523 for (i = 0; i < sizeof(soc_counter_non_dma1)/sizeof(int); ++i) { 8524 id = soc_counter_non_dma1[i]; 8525 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 8526 non_dma->pbmp = PBMP_ALL(unit); 8527 } 8528 8529 for (i = 0; i < sizeof(soc_counter_non_dma2)/sizeof(int); ++i) { 8530 id = soc_counter_non_dma2[i]; 8531 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 8532 non_dma->pbmp = PBMP_PORT_ALL(unit); 8533 } 8534 8535 return SOC_E_NONE; 8536 } 8537 #endif /* BCM_APACHE_SUPPORT */ 8538 8539 /* 8540 * Function: 8541 * soc_counter_non_dma_pbmp_update 8542 * Purpose: 8543 * Update non_dma->pbmp 8544 * Notes: 8545 */ 8546 int 8547 soc_counter_non_dma_pbmp_update(int unit) 8548 { 8549 #ifdef BCM_APACHE_SUPPORT 8550 if (SOC_IS_APACHE(unit)) { 8551 SOC_IF_ERROR_RETURN(_soc_counter_apache_non_dma_pbmp_update(unit)); 8552 } 8553 #endif /* BCM_APACHE_SUPPORT */ 8554 #if defined ( BCM_TRIDENT2PLUS_SUPPORT ) 8555 if (SOC_IS_TD2P_TT2P(unit)) { 8556 SOC_IF_ERROR_RETURN(_soc_counter_trident2p_non_dma_pbmp_update(unit)); 8557 } 8558 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 8559 8560 return SOC_E_NONE; 8561 } 8562 8563 /* 8564 * Function: 8565 * soc_port_cmap_get/set 8566 * Purpose: 8567 * Access the counter map structure per port 8568 */ 8569 8570 soc_cmap_t * 8571 soc_port_cmap_get(int unit, soc_port_t port) 8572 { 8573 if (!SOC_UNIT_VALID(unit)) { 8574 return NULL; 8575 } 8576 if (!SOC_IS_KATANA2(unit)) { 8577 if (!SOC_PORT_VALID(unit, port) || 8578 (!IS_PORT(unit, port) && 8579 (!soc_feature(unit, soc_feature_cpuport_stat_dma)))) { 8580 return NULL; 8581 } 8582 } 8583 return SOC_CONTROL(unit)->counter_map[port]; 8584 } 8585 8586 int 8587 soc_port_cmap_set(int unit, soc_port_t port, soc_ctr_type_t ctype) 8588 { 8589 if (!SOC_UNIT_VALID(unit)) { 8590 return SOC_E_UNIT; 8591 } 8592 if (!SOC_IS_KATANA2(unit)) { 8593 if (!SOC_PORT_VALID(unit, port) || 8594 (!IS_PORT(unit, port) && 8595 (!soc_feature(unit, soc_feature_cpuport_stat_dma)))) { 8596 return SOC_E_PARAM; 8597 } 8598 } 8599 SOC_CONTROL(unit)->counter_map[port] = &SOC_CTR_DMA_MAP(unit, ctype); 8600 return SOC_E_NONE; 8601 } 8602 8603 /* 8604 * Function: 8605 * soc_counter_detach 8606 * Purpose: 8607 * Finalize counter module. 8608 * Notes: 8609 * Stops counter task if running. 8610 * Deallocates counter collection buffers. 8611 */ 8612 8613 int 8614 soc_counter_detach(int unit) 8615 { 8616 soc_control_t *soc; 8617 int i; 8618 #ifdef BCM_TRIUMPH2_SUPPORT 8619 soc_port_t port; 8620 #endif /* BCM_TRIUMPH2_SUPPORT */ 8621 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) 8622 int ct; 8623 #endif /* BCM_TOMAHAWK_SUPPORT */ 8624 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 8625 8626 assert(SOC_UNIT_VALID(unit)); 8627 8628 /* 8629 * COVERITY 8630 * 8631 * assert validates the input 8632 */ 8633 /* coverity[overrun-local : FALSE] */ 8634 soc = SOC_CONTROL(unit); 8635 8636 /* 8637 * COVERITY 8638 * 8639 * assert validates the input 8640 */ 8641 /* coverity[overrun-local : FALSE] */ 8642 SOC_IF_ERROR_RETURN(soc_counter_stop(unit)); 8643 8644 #ifdef BCM_TRIUMPH2_SUPPORT 8645 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 8646 if (soc->counter_timestamp_fifo[port] != NULL) { 8647 SHR_FIFO_FREE(soc->counter_timestamp_fifo[port]); 8648 sal_free(soc->counter_timestamp_fifo[port]); 8649 soc->counter_timestamp_fifo[port] = NULL; 8650 } 8651 } 8652 #endif /* BCM_TRIUMPH2_SUPPORT */ 8653 8654 if (soc->counter_evict != NULL) { 8655 sal_free(soc->counter_evict); 8656 soc->counter_evict = NULL; 8657 } 8658 8659 if (soc_ctr_ctrl != NULL) { 8660 sal_free(soc_ctr_ctrl); 8661 SOC_CTR_CTRL(unit) = NULL; 8662 } 8663 8664 if (soc->counter_non_dma != NULL) { 8665 for (i = 0; i < SOC_COUNTER_NON_DMA_END - SOC_COUNTER_NON_DMA_START; 8666 i++) { 8667 if (soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_ALLOC) { 8668 soc_cm_sfree(unit, soc->counter_non_dma[i].dma_buf[0]); 8669 } 8670 8671 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_APACHE_SUPPORT) 8672 if((soc->counter_non_dma[i].extra_ctrs != NULL) && 8673 ((soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_DO_DMA) || 8674 (soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_OBM))){ 8675 for(ct = 0; ct < soc->counter_non_dma[i].extra_ctr_ct; ct++) { 8676 if((soc->counter_non_dma[i].extra_ctrs[ct*2].cname != NULL) && 8677 (soc->counter_non_dma[i].extra_ctrs[ct*2].cname[0] == '*')){ 8678 sal_free(soc->counter_non_dma[i].extra_ctrs[ct*2].cname); 8679 soc->counter_non_dma[i].extra_ctrs[ct*2].cname = NULL; 8680 } 8681 8682 if((soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname != NULL) && 8683 (soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname[0] == '*')){ 8684 sal_free(soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname); 8685 soc->counter_non_dma[i].extra_ctrs[ct*2+1].cname = NULL; 8686 } 8687 } 8688 8689 sal_free(soc->counter_non_dma[i].extra_ctrs); 8690 soc->counter_non_dma[i].extra_ctrs = NULL; 8691 if((soc->counter_non_dma[i].flags & _SOC_COUNTER_NON_DMA_OBM) && 8692 (soc->counter_non_dma[i].id != SOC_COUNTER_NON_DMA_PORT_OBM_FC_EVENTS)) { 8693 soc->counter_non_dma[i+1].extra_ctrs = NULL; 8694 } 8695 } 8696 #endif /* BCM_TOMAHAWK_SUPPORT */ 8697 } 8698 sal_free(soc->counter_non_dma); 8699 soc->counter_non_dma = NULL; 8700 } 8701 8702 if (soc->counter_buf32 != NULL) { 8703 soc_cm_sfree(unit, soc->counter_buf32); 8704 soc->counter_buf32 = NULL; 8705 soc->counter_buf64 = NULL; 8706 } 8707 8708 if (soc->counter_hw_val != NULL) { 8709 sal_free(soc->counter_hw_val); 8710 soc->counter_hw_val = NULL; 8711 } 8712 8713 if (soc->counter_sw_val != NULL) { 8714 sal_free(soc->counter_sw_val); 8715 soc->counter_sw_val = NULL; 8716 } 8717 8718 if (soc->counter_delta != NULL) { 8719 sal_free(soc->counter_delta); 8720 soc->counter_delta = NULL; 8721 } 8722 8723 #ifdef BCM_SBUSDMA_SUPPORT 8724 if (_soc_blk_counter_handles[unit] != NULL) { 8725 sal_free(_soc_blk_counter_handles[unit]); 8726 _soc_blk_counter_handles[unit] = NULL; 8727 } 8728 8729 if (soc->blk_ctr_buf != NULL) { 8730 soc_cm_sfree(unit, soc->blk_ctr_buf); 8731 soc->blk_ctr_buf = NULL; 8732 } 8733 8734 if (soc->blk_counter_hw_val != NULL) { 8735 sal_free(soc->blk_counter_hw_val); 8736 soc->blk_counter_hw_val = NULL; 8737 } 8738 8739 if (soc->blk_counter_sw_val != NULL) { 8740 sal_free(soc->blk_counter_sw_val); 8741 soc->blk_counter_sw_val = NULL; 8742 } 8743 8744 _soc_counter_pending[unit] = 0; 8745 #endif 8746 return SOC_E_NONE; 8747 } 8748 8749 /* 8750 * StrataSwitch counter register map 8751 * 8752 * NOTE: soc_attach verifies this map is correct and prints warnings if 8753 * not. The map should contain only registers with a single field named 8754 * COUNT, and all such registers should be in the map. 8755 * 8756 * The soc_counter_map[] array is a list of counter registers in the 8757 * order found in the internal address map and counter DMA buffer. 8758 * soc_counter_map[0] corresponds to S-Channel address 8759 * COUNTER_OFF_MIN, and contains SOC_CTR_MAP_SIZE(unit) entries. 8760 * 8761 * This map structure, contents, and size are exposed only to provide a 8762 * convenient way to loop through all available counters. 8763 * 8764 * Accumulated counters are stored as 64-bit values and may be written 8765 * and read by multiple tasks on a 32-bit processor. This requires 8766 * atomic operation to get correct values. Also, to fetch-and-clear a 8767 * counter requires atomic operation. 8768 * 8769 * These atomic operations are very brief, so rather than using an 8770 * inefficient mutex we use splhi to lock out interrupts and task 8771 * switches. In theory, splhi is only a few instructions on most 8772 * processors. 8773 */ 8774 8775 #define COUNTER_ATOMIC_DEF soc_control_t * 8776 #define COUNTER_ATOMIC_BEGIN(_soc) \ 8777 do { \ 8778 if ((_soc) && (_soc)->counter_lock) { \ 8779 sal_spinlock_lock((_soc)->counter_lock); \ 8780 } \ 8781 } while (0) 8782 #define COUNTER_ATOMIC_END(_soc) \ 8783 do { \ 8784 if ((_soc) && (_soc)->counter_lock) { \ 8785 sal_spinlock_unlock((_soc)->counter_lock); \ 8786 } \ 8787 } while (0) 8788 8789 #ifdef BROADCOM_DEBUG 8790 8791 char *soc_ctr_type_names[] = SOC_CTR_TYPE_NAMES_INITIALIZER; 8792 8793 /* 8794 * Function: 8795 * _soc_counter_verify (internal) 8796 * Purpose: 8797 * Verify contents of soc_counter_map[] array 8798 */ 8799 void 8800 _soc_counter_verify(int unit) 8801 { 8802 int i, errors, num_ctrs, found; 8803 soc_ctr_type_t ctype; 8804 soc_reg_t reg; 8805 int ar_idx; 8806 uint32 skip_offset = 0; 8807 8808 LOG_DEBUG(BSL_LS_SOC_COMMON, 8809 (BSL_META_U(unit, 8810 "soc_counter_verify: unit %d begins\n"), unit)); 8811 errors = 0; 8812 if (SOC_IS_TRIUMPH3(unit)) { 8813 skip_offset = 32; 8814 } 8815 #if defined(BCM_HURRICANE2_SUPPORT) 8816 if (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || \ 8817 SOC_IS_GREYHOUND(unit)) { 8818 skip_offset = 55; 8819 } 8820 #endif 8821 8822 #ifdef BCM_GREYHOUND2_SUPPORT 8823 if (SOC_IS_GREYHOUND2(unit)) { 8824 skip_offset = 111; 8825 } 8826 #endif /* BCM_GREYHOUND2_SUPPORT */ 8827 8828 for (ctype = SOC_CTR_TYPE_FE; ctype < SOC_CTR_NUM_TYPES; ctype++) { 8829 if (SOC_HAS_CTR_TYPE(unit, ctype)) { 8830 num_ctrs = SOC_CTR_MAP_SIZE(unit, ctype); 8831 for (i = 0; i < num_ctrs; i++) { 8832 reg = SOC_CTR_TO_REG(unit, ctype, i); 8833 ar_idx = SOC_CTR_TO_REG_IDX(unit, ctype, i); 8834 if (SOC_COUNTER_INVALID(unit, reg)) { 8835 continue; 8836 } 8837 if (reg >= SOC_COUNTER_TABLE_FIELD_START) { 8838 continue; 8839 }; 8840 if (!SOC_REG_IS_COUNTER(unit, reg)) { 8841 LOG_DEBUG(BSL_LS_SOC_COMMON, 8842 (BSL_META_U(unit, 8843 "soc_counter_verify: " 8844 "%s cntr %s (%d) index %d " 8845 "is not a counter\n"), 8846 soc_ctr_type_names[ctype], 8847 SOC_REG_NAME(unit, reg), reg, i)); 8848 errors = 1; 8849 } 8850 if (((SOC_REG_CTR_IDX(unit, reg) + ar_idx) - 8851 COUNTER_IDX_OFFSET(unit) - skip_offset) 8852 != i) { 8853 LOG_DEBUG(BSL_LS_SOC_COMMON, 8854 (BSL_META_U(unit, 8855 "soc_counter_verify: " 8856 "%s cntr %s (%d) index mismatch.\n" 8857 " (ctr_idx %d + ar_idx %d) - offset %d != " 8858 "index in ctr array %d\n"), 8859 soc_ctr_type_names[ctype], 8860 SOC_REG_NAME(unit, reg), reg, 8861 SOC_REG_CTR_IDX(unit, reg), 8862 ar_idx, 8863 COUNTER_IDX_OFFSET(unit), 8864 i)); 8865 errors = 1; 8866 } 8867 } 8868 } 8869 } 8870 8871 for (reg = 0; reg < NUM_SOC_REG; reg++) { 8872 if (SOC_REG_IS_VALID(unit, reg) && SOC_REG_IS_COUNTER(unit, reg)) { 8873 found = FALSE; 8874 i = -1; 8875 for (ctype = SOC_CTR_TYPE_FE; ctype < SOC_CTR_NUM_TYPES; ctype++) { 8876 if (SOC_HAS_CTR_TYPE(unit, ctype)) { 8877 num_ctrs = SOC_CTR_MAP_SIZE(unit, ctype); 8878 for (i = 0; i < num_ctrs; i++) { 8879 if (SOC_CTR_TO_REG(unit, ctype, i) == reg) { 8880 if ((SOC_REG_CTR_IDX(unit, reg) - 8881 COUNTER_IDX_OFFSET(unit) - skip_offset) != i) { 8882 LOG_DEBUG(BSL_LS_SOC_COMMON, 8883 (BSL_META_U(unit, 8884 "soc_counter_verify: " 8885 "%s cntr %s (%d) index mismatch.\n" 8886 " (ctr_idx %d - offset %d) != " 8887 "index in ctr array %d\n"), 8888 soc_ctr_type_names[ctype], 8889 SOC_REG_NAME(unit, reg), reg, 8890 SOC_REG_CTR_IDX(unit, reg), 8891 COUNTER_IDX_OFFSET(unit), 8892 i)); 8893 errors = 1; 8894 } 8895 found = TRUE; 8896 break; 8897 } 8898 } 8899 } 8900 if (found) { 8901 break; 8902 } 8903 } 8904 8905 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 8906 if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit) || 8907 SOC_IS_HURRICANE2(unit) || SOC_IS_KATANAX(unit)) { 8908 /* OAM_SEC_NS_COUNTER_64 is a general purpose counter 8909 which counts time for entire chip */ 8910 if ((!found) && (OAM_SEC_NS_COUNTER_64r == reg)) { 8911 found = TRUE; 8912 } 8913 } 8914 #endif 8915 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 8916 if(SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || \ 8917 SOC_IS_GREYHOUND2(unit)) { 8918 if( (!found) && ( 8919 (HOLD_COS0r == reg) || 8920 (HOLD_COS1r == reg) || 8921 (HOLD_COS2r == reg) || 8922 (HOLD_COS3r == reg) || 8923 (HOLD_COS4r == reg) || 8924 (HOLD_COS5r == reg) || 8925 (HOLD_COS6r == reg) || 8926 (HOLD_COS7r == reg) ) ) { 8927 found = TRUE; 8928 } 8929 } 8930 #endif 8931 #ifdef BCM_KATANA2_SUPPORT 8932 if (SOC_IS_KATANA2(unit)) { 8933 if ((!found) && (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_RXLP))) { 8934 found = TRUE; 8935 } 8936 } 8937 #endif 8938 /* Few RTS registers are marked as counters.. (ISCOUNTER => 1) */ 8939 if (SOC_IS_APACHE(unit)) { 8940 if ((!found) && 8941 (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_IPROC))) { 8942 found = TRUE; 8943 } 8944 } 8945 8946 #ifdef BCM_MONTEREY_SUPPORT 8947 if (SOC_IS_MONTEREY(unit)) { 8948 if ((!found) && 8949 (SOC_BLOCK_IS(SOC_REG_INFO(unit, reg).block, SOC_BLK_CPRI))) { 8950 found = TRUE; 8951 } 8952 } 8953 #endif 8954 8955 /* Workaround for SDK-130624. Remove this block after ARCHTH3-423 8956 is resolved and integrated */ 8957 #ifdef BCM_TOMAHAWK3_SUPPORT 8958 if (SOC_IS_TOMAHAWK3(unit)) { 8959 if (!found) { 8960 switch (reg) { 8961 case CPU_MASQUERADE_COUNTER_DEST_TYPEr: 8962 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE0r: 8963 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE1r: 8964 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE2r: 8965 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE3r: 8966 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE4r: 8967 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE5r: 8968 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE6r: 8969 case CPU_MASQUERADE_COUNTER_DEST_TYPE_PIPE7r: 8970 case IS_PKSCH_PKT_CREDITS_PER_PIPEr: 8971 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE0r: 8972 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE1r: 8973 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE2r: 8974 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE3r: 8975 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE4r: 8976 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE5r: 8977 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE6r: 8978 case IS_PKSCH_PKT_CREDITS_PER_PIPE_PIPE7r: 8979 case MMU_CRB_CREDIT_DROP_PKT_COUNTr: 8980 case MMU_CRB_INVALID_DESTINATION_PKT_COUNTr: 8981 case MMU_CRB_PKT_DROP_CNTR_STATr: 8982 case MMU_EBCFG_ECC_SINGLE_BIT_ERRORSr: 8983 case MMU_EBCFG_MEM_FAIL_INT_CTRr: 8984 case MMU_EBCTM_BURST_CTRL_STSr: 8985 case MMU_EBCTM_CT_FSM_STSr: 8986 case MMU_EBPTS_EDB_CREDIT_COUNTERr: 8987 case MMU_EBPTS_PKSCH_PKT_CREDITS_PER_PIPEr: 8988 case MMU_GLBCFG_ECC_SINGLE_BIT_ERRORSr: 8989 case MMU_GLBCFG_MEM_FAIL_INT_CTRr: 8990 case MMU_INTFO_OOBFC_MSG_TX_CNTr: 8991 case MMU_ITMCFG_ECC_SINGLE_BIT_ERRORSr: 8992 case MMU_ITMCFG_MEM_FAIL_INT_CTRr: 8993 case MMU_PTSCH_EB_CREDIT_CONFIGr: 8994 case MMU_RL_DEBUG_PKT_CNTr: 8995 found = TRUE; 8996 break; 8997 default: 8998 break; 8999 } 9000 9001 } 9002 } 9003 #endif /* BCM_TOMAHAWK3_SUPPORT */ 9004 9005 if (!found) { 9006 LOG_DEBUG(BSL_LS_SOC_COMMON, 9007 (BSL_META_U(unit, 9008 "soc_counter_verify: " 9009 "counter %d %s is missing (i=%d, 0x%x)\n"), 9010 (int)reg, SOC_REG_NAME(unit, reg), i, i)); 9011 errors = 1; 9012 } 9013 } 9014 } 9015 9016 if (errors) { 9017 LOG_CLI((BSL_META_U(unit, 9018 "\nERRORS found during counter initialization. " 9019 "Set debug verbose for more info.\n\n"))); 9020 } 9021 9022 LOG_DEBUG(BSL_LS_SOC_COMMON, 9023 (BSL_META_U(unit, 9024 "soc_counter_verify: unit %d ends\n"), unit)); 9025 } 9026 9027 /* 9028 * Function: 9029 * _soc_counter_illegal 9030 * Purpose: 9031 * Routine to display info about bad counter and halt. 9032 */ 9033 9034 void 9035 _soc_counter_illegal(int unit, soc_reg_t ctr_reg) 9036 { 9037 LOG_CLI((BSL_META_U(unit, 9038 "soc_counter_get: unit %d: " 9039 "ctr_reg %d (%s) is not a counter\n"), 9040 unit, ctr_reg, SOC_REG_NAME(unit, ctr_reg))); 9041 /* assert(0); */ 9042 } 9043 9044 #endif /* BROADCOM_DEBUG */ 9045 9046 #ifdef BCM_TOMAHAWK_SUPPORT 9047 extern uint32 soc_mem_fifo_delay_value; 9048 9049 9050 STATIC void 9051 _soc_counter_fifo_process(int unit, central_ctr_eviction_fifo_entry_t *entry) 9052 { 9053 soc_control_t *soc; 9054 soc_counter_non_dma_t *pkt_ctr_dma, *byte_ctr_dma; 9055 soc_counter_evict_t *evict; 9056 soc_mem_t mem; 9057 int index, mem_id, pipe; 9058 uint32 fval[2]; 9059 int pkt_ctr_id, byte_ctr_id, offset, base_index; 9060 uint64 ctr_diff; 9061 9062 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 9063 9064 soc = SOC_CONTROL(unit); 9065 9066 mem = CENTRAL_CTR_EVICTION_FIFOm; 9067 if (SOC_IS_TRIDENT3X(unit)) { 9068 index = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, INDEXf); 9069 mem_id = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, POOL_NUMf); 9070 pipe = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, entry, PIPE_NUMf); 9071 } else { 9072 if(SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) { 9073 index = soc_mem_field32_get(unit, mem, entry, INDEXf); 9074 } else { 9075 index = soc_mem_field32_get(unit, mem, entry, CEV_INDEXf); 9076 } 9077 mem_id = soc_mem_field32_get(unit, mem, entry, POOL_NUMf); 9078 pipe = soc_mem_field32_get(unit, mem, entry, PIPE_NUMf); 9079 } 9080 /* Check if pool number is within the range */ 9081 if ((mem_id < 1) || (mem_id > soc->counter_evict_max_mem_id)) { 9082 soc->counter_evict_inval_poolid_count++; 9083 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 9084 (BSL_META_U(unit, 9085 "Invalid eviction pool# = %d\n"), mem_id)); 9086 return; 9087 } 9088 9089 evict = &soc->counter_evict[mem_id]; 9090 pkt_ctr_id = evict->pkt_counter_id; 9091 byte_ctr_id = evict->byte_counter_id; 9092 offset = evict->offset[pipe]; 9093 9094 pkt_ctr_dma = &soc->counter_non_dma[pkt_ctr_id - SOC_COUNTER_NON_DMA_START]; 9095 9096 if (SOC_IS_TRIDENT3X(unit)) { 9097 fval[0] = soc_format_field32_get(unit, CTR_EVICTION_MESSAGEfmt, 9098 entry, PKT_CNTf); 9099 } else { 9100 fval[0] = soc_mem_field32_get(unit, mem, entry, PKT_CNTf); 9101 } 9102 9103 COMPILER_64_SET(ctr_diff, 0, fval[0]); 9104 base_index = pkt_ctr_dma->base_index + offset; 9105 9106 COUNTER_ATOMIC_BEGIN(s); 9107 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + index], ctr_diff); 9108 soc->counter_delta[base_index + index] = ctr_diff; 9109 COUNTER_ATOMIC_END(s); 9110 9111 byte_ctr_dma = &soc->counter_non_dma[byte_ctr_id - SOC_COUNTER_NON_DMA_START]; 9112 if (SOC_IS_TRIDENT3X(unit)) { 9113 soc_format_field_get(unit, CTR_EVICTION_MESSAGEfmt, entry->entry_data, 9114 BYTE_CNTf, fval); 9115 } else { 9116 soc_mem_field_get(unit, mem, entry->entry_data, BYTE_CNTf, fval); 9117 } 9118 COMPILER_64_SET(ctr_diff, fval[1], fval[0]); 9119 base_index = byte_ctr_dma->base_index + offset; 9120 9121 COUNTER_ATOMIC_BEGIN(s); 9122 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + index], ctr_diff); 9123 soc->counter_delta[base_index + index] = ctr_diff; 9124 COUNTER_ATOMIC_END(s); 9125 9126 } 9127 9128 void 9129 _soc_ctr_evict_fifo_dma_thread(void *unit_vp) 9130 { 9131 int unit = PTR_TO_INT(unit_vp); 9132 soc_control_t *soc = SOC_CONTROL(unit); 9133 int cmc = SOC_PCI_CMC(unit); 9134 soc_mem_t mem; 9135 int i, count, adv_threshold; 9136 uint32 rval, stat_fail_mask; 9137 uint32 hostmem_timeout, done, error; 9138 int rv, interval, non_empty, fail; 9139 uint8 chan; 9140 int entries_per_buf, entry_words, yield_entries, yield_num; 9141 uint32 stat_fail_ovrflw_mask; 9142 9143 #if defined(BCM_TOMAHAWK3_SUPPORT) 9144 if (SOC_IS_TOMAHAWK3(unit)) { 9145 chan = SOC_MEM_FIFO_DMA_CHANNEL_0; 9146 }else 9147 #endif 9148 { 9149 chan = SOC_MEM_FIFO_DMA_CHANNEL_1; 9150 } 9151 9152 /* Maximum possible counter evictions per second is 2700. Hostbuf size is 9153 * set to double the value to account for load conditions */ 9154 entries_per_buf = soc_property_get(unit, "spn_COUNTER_EVICT_HOSTBUF_SIZE", 9155 _SOC_CTR_EVICT_HOSTBUF_SIZE); 9156 adv_threshold = entries_per_buf / 2; 9157 yield_entries = soc_property_get(unit, "spn_COUNTER_EVICT_ENTRIES_MAX", 9158 _SOC_CTR_EVICT_ENTRIES_MAX); 9159 yield_num = yield_entries; 9160 9161 mem = CENTRAL_CTR_EVICTION_FIFOm; 9162 entry_words = soc_mem_entry_words(unit, mem); 9163 host_buff[unit] = soc_cm_salloc(unit, entries_per_buf * entry_words * 9164 sizeof(uint32), "Counter Eviction DMA Buffer"); 9165 if (host_buff[unit] == NULL) { 9166 soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR, 9167 SOC_SWITCH_EVENT_THREAD_CTR_EVICT_DMA, __LINE__, 9168 SOC_E_MEMORY); 9169 goto cleanup_exit; 9170 } 9171 9172 rv = soc_fifodma_masks_get(unit, &hostmem_timeout, &stat_fail_ovrflw_mask, &error, &done); 9173 9174 rv = soc_fifodma_start(unit, chan, TRUE, mem, 0, MEM_BLOCK_ANY, 0, 9175 entries_per_buf, host_buff[unit]); 9176 if (SOC_FAILURE(rv)) { 9177 soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR, 9178 SOC_SWITCH_EVENT_THREAD_CTR_EVICT_DMA, __LINE__, 9179 rv); 9180 goto cleanup_exit; 9181 } 9182 9183 host_entry[unit] = host_buff[unit]; 9184 buff_max[unit] = (uint32 *)(host_entry[unit]) + (entries_per_buf * entry_words); 9185 9186 stat_fail_mask = hostmem_timeout | stat_fail_ovrflw_mask; 9187 soc->counter_evict_inval_poolid_count = 0; 9188 while ((interval = soc->ctr_evict_interval)) { 9189 fail = FALSE; 9190 /* Interrupt */ 9191 if (soc->ctrEvictDmaIntrEnb) { 9192 soc_fifodma_intr_enable(unit, chan); 9193 if (sal_sem_take(soc->ctrEvictIntr, interval) < 0) { 9194 LOG_DEBUG(BSL_LS_SOC_EVICT, 9195 (BSL_META_U(unit, 9196 "%s polling timeout " 9197 "soc_mem_fifo_delay_value=%d\n"), 9198 soc->ctr_evict_name, soc_mem_fifo_delay_value)); 9199 } else { 9200 LOG_DEBUG(BSL_LS_SOC_EVICT, 9201 (BSL_META_U(unit, 9202 "%s woken up soc_mem_fifo_delay_value=%d\n"), 9203 soc->ctr_evict_name, soc_mem_fifo_delay_value)); 9204 /* check for timeout or overflow and either process or continue */ 9205 soc_fifodma_status_get(unit, chan, &rval); 9206 if (rval & stat_fail_mask) { 9207 fail = TRUE; 9208 } 9209 } 9210 /* Polling */ 9211 } else { 9212 /* Sleep for counter eviction interval */ 9213 sal_usleep(interval); 9214 } 9215 9216 EVICT_LOCK(unit); 9217 do { 9218 non_empty = FALSE; 9219 9220 /* get entry count, process if nonzero else continue */ 9221 rv = soc_fifodma_num_entries_get(unit, chan, &count); 9222 if (SOC_SUCCESS(rv)) { 9223 non_empty = TRUE; 9224 if (count > adv_threshold) { 9225 count = adv_threshold; 9226 } 9227 9228 for (i = 0; i < count; i++, yield_num--) { 9229 if(!soc->counter_interval) { 9230 EVICT_UNLOCK(unit); 9231 goto cleanup_exit; 9232 } 9233 /* Yield if value set in counter_evict_entries_max config variable is 9234 * not default value and if number specified in config variable has been 9235 * reached 9236 */ 9237 if (yield_entries) { 9238 if (yield_num == 0) { 9239 yield_num = yield_entries; 9240 sal_thread_yield(); 9241 } 9242 } 9243 9244 _soc_counter_fifo_process(unit, host_entry[unit]); 9245 host_entry[unit] = (uint32 *)(host_entry[unit]) + entry_words; 9246 /* handle roll over */ 9247 if ((uint32 *)(host_entry[unit]) >= buff_max[unit]) { 9248 host_entry[unit] = host_buff[unit]; 9249 } 9250 } 9251 soc_fifodma_set_entries_read(unit, chan, i); 9252 } 9253 9254 /* check and clear error */ 9255 soc_fifodma_status_get(unit, chan, &rval); 9256 if (rval & done) { 9257 LOG_ERROR(BSL_LS_SOC_COMMON, 9258 (BSL_META_U(unit, 9259 "FIFO DMA engine terminated for " 9260 "cmc[%d]:chan[%d]\n"), 9261 cmc, chan)); 9262 if (rval & error) { 9263 LOG_ERROR(BSL_LS_SOC_COMMON, 9264 (BSL_META_U(unit, 9265 "FIFO DMA engine encountered error: " 9266 "[0x%x]\n"), 9267 rval)); 9268 } 9269 EVICT_UNLOCK(unit); 9270 goto cleanup_exit; 9271 } 9272 } while (non_empty); 9273 EVICT_UNLOCK(unit); 9274 9275 /* Clearing of the FIFO_CH_DMA_INT interrupt by resetting 9276 overflow & timeout status in FIFO_CHy_RD_DMA_STAT_CLR reg */ 9277 if (fail) { 9278 soc_fifodma_status_clear(unit, chan); 9279 } 9280 } 9281 9282 cleanup_exit: 9283 soc_fifodma_stop(unit, chan); 9284 9285 if (host_buff[unit] != NULL) { 9286 soc_cm_sfree(unit, host_buff[unit]); 9287 host_buff[unit] = NULL; 9288 host_entry[unit] = NULL; 9289 } 9290 soc->ctr_evict_pid = SAL_THREAD_ERROR; 9291 sal_thread_exit(0); 9292 } 9293 9294 int 9295 soc_ctr_evict_stop(int unit) 9296 { 9297 soc_control_t *soc; 9298 int rv = SOC_E_NONE; 9299 soc_timeout_t to; 9300 int chan; 9301 9302 if (!soc_feature(unit, soc_feature_counter_eviction)) { 9303 return SOC_E_UNAVAIL; 9304 } 9305 9306 soc = SOC_CONTROL(unit); 9307 9308 SOC_IF_ERROR_RETURN(soc_counter_tomahawk_eviction_enable(unit, FALSE)); 9309 9310 if (!soc_feature(unit, soc_feature_fifo_dma) || SOC_IS_HELIX5(unit)) { 9311 chan = SOC_MEM_FIFO_DMA_CHANNEL_1; 9312 soc_fifodma_intr_disable(unit, chan); 9313 } 9314 9315 soc->ctr_evict_interval = 0; /* Request exit */ 9316 if (soc->ctr_evict_pid && (soc->ctr_evict_pid != SAL_THREAD_ERROR)) { 9317 /* Wake up thread so it will check the exit flag */ 9318 if (soc->ctrEvictIntr != NULL) { 9319 sal_sem_give(soc->ctrEvictIntr); 9320 } 9321 /* Give thread a few seconds to wake up and exit */ 9322 if (SAL_BOOT_SIMULATION) { 9323 soc_timeout_init(&to, 300 * 1000000, 0); 9324 } else { 9325 soc_timeout_init(&to, 60 * 1000000, 0); 9326 } 9327 while (soc->ctr_evict_pid != SAL_THREAD_ERROR) { 9328 if (soc_timeout_check(&to)) { 9329 LOG_ERROR(BSL_LS_SOC_COMMON, 9330 (BSL_META_U(unit, 9331 "thread will not exit\n"))); 9332 rv = SOC_E_INTERNAL; 9333 break; 9334 } 9335 } 9336 } 9337 return rv; 9338 } 9339 9340 int 9341 soc_ctr_evict_start(int unit, uint32 flags, sal_usecs_t interval) 9342 { 9343 soc_control_t *soc; 9344 uint32 flag = _SOC_COUNTER_NON_DMA_CLEAR_ON_READ; 9345 int pri, chan; 9346 9347 if (!soc_feature(unit, soc_feature_counter_eviction)) { 9348 return SOC_E_UNAVAIL; 9349 } 9350 9351 if (!soc_property_get(unit, "ctr_evict_enable", 1)) { 9352 LOG_CLI((BSL_META_U(unit, 9353 "*** skip counter eviction start for now\n"))); 9354 soc_counter_tomahawk_eviction_flags_update(unit, flag, 0); 9355 return SOC_E_NONE; 9356 } 9357 9358 soc = SOC_CONTROL(unit); 9359 9360 if (soc->ctr_evict_interval != 0) { 9361 SOC_IF_ERROR_RETURN(soc_ctr_evict_stop(unit)); 9362 } 9363 9364 sal_snprintf(soc->ctr_evict_name, sizeof(soc->ctr_evict_name), 9365 "CtrEvict.%d", unit); 9366 soc->ctr_evict_flags = flags; 9367 soc->ctr_evict_interval = interval; 9368 9369 if (interval == 0) { 9370 return SOC_E_NONE; 9371 } 9372 9373 9374 if (soc->ctr_evict_pid == SAL_THREAD_ERROR) { 9375 pri = soc_property_get(unit, "spn_COUNTER_EVICT_THREAD_PRI", 9376 _SOC_CTR_EVICT_THREAD_PRI); 9377 9378 soc->ctr_evict_pid = 9379 sal_thread_create(soc->ctr_evict_name, SAL_THREAD_STKSZ, pri, 9380 _soc_ctr_evict_fifo_dma_thread, 9381 INT_TO_PTR(unit)); 9382 if (soc->ctr_evict_pid == SAL_THREAD_ERROR) { 9383 LOG_ERROR(BSL_LS_SOC_COMMON, 9384 (BSL_META_U(unit, 9385 "soc_ctr_evict_start: Could not start thread\n"))); 9386 return SOC_E_MEMORY; 9387 } 9388 } 9389 9390 if (!soc_feature(unit, soc_feature_fifo_dma)) { 9391 chan = SOC_MEM_FIFO_DMA_CHANNEL_1; 9392 soc_fifodma_intr_enable(unit, chan); 9393 } 9394 9395 /* coverity[dead_error_line] */ 9396 SOC_IF_ERROR_RETURN(soc_counter_tomahawk_eviction_enable(unit, TRUE)); 9397 9398 return SOC_E_NONE; 9399 } 9400 9401 /* 9402 * Function: 9403 * soc_counter_eviction_sync 9404 * Purpose: 9405 * Sync values stored in Eviction Fifo to the SW val 9406 * Parameters: 9407 * unit - StrataSwitch unit #. 9408 * Returns: 9409 * SOC_E_XXX 9410 * Notes: 9411 * This is to ensure counter values in Transit(in Eviction FIFO) to be 9412 * synced when stat sync is issue. 9413 * Ensures that ALL counter activity that occurred before the sync 9414 * is reflected in the results of any soc_counter_get()-type 9415 * routine that is called after the sync. 9416 */ 9417 int 9418 soc_counter_eviction_sync(int unit) 9419 { 9420 soc_control_t *soc = SOC_CONTROL(unit); 9421 uint8 chan = SOC_MEM_FIFO_DMA_CHANNEL_1; 9422 9423 /* disable interrupt before releasing semaphore, which causes eviction 9424 * thread to sync stat from Eviction fifo to Sw_val 9425 */ 9426 soc_fifodma_intr_disable(unit, chan); 9427 9428 if (soc->ctrEvictIntr != NULL) { 9429 sal_sem_give(soc->ctrEvictIntr); 9430 } 9431 9432 return SOC_E_NONE; 9433 } 9434 9435 #endif /* BCM_TOMAHAWK_SUPPORT */ 9436 9437 /* 9438 * Function: 9439 * soc_counter_autoz 9440 * Purpose: 9441 * Set or clear AUTOZ mode for all MAC counter registers (all ports) 9442 * Parameters: 9443 * unit - StrataSwitch unit #. 9444 * enable - if TRUE, enable, otherwise disable AUTOZ mode 9445 * Returns: 9446 * SOC_E_XXX. 9447 * Notes: 9448 * This module requires AUTOZ is off to accumulate counters properly. 9449 * On 5665, this also turns on/off the MMU counters AUTOZ mode. 9450 */ 9451 9452 int 9453 soc_counter_autoz(int unit, int enable) 9454 { 9455 soc_port_t port; 9456 9457 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 9458 (BSL_META_U(unit, 9459 "soc_counter_autoz: unit=%d enable=%d\n"), unit, enable)); 9460 9461 PBMP_PORT_ITER(unit, port) { 9462 #if defined(BCM_ESW_SUPPORT) 9463 SOC_IF_ERROR_RETURN(soc_autoz_set(unit, port, enable)); 9464 #endif 9465 } 9466 9467 return (SOC_E_NONE); 9468 } 9469 9470 /* 9471 * Function: 9472 * _soc_counter_get 9473 * Purpose: 9474 * Given a counter register number and port number, fetch the 9475 * 64-bit software-accumulated counter value or read from device counter 9476 * register. The software-accumulated counter value is zeroed if requested. 9477 * Parameters: 9478 * unit - StrataSwitch unit #. 9479 * port - StrataSwitch port #. 9480 * ctr_reg - counter register 9481 * zero - if TRUE, current counter is zeroed after reading. 9482 * sync_mode - if TRUE, read from device else software accumulated value 9483 * val - (OUT) 64-bit counter value. 9484 * Returns: 9485 * SOC_E_XXX. 9486 * Notes: 9487 * Returns 0 if ctr_reg is INVALIDr or not enabled. 9488 */ 9489 9490 STATIC INLINE int 9491 _soc_counter_get(int unit, soc_port_t port, soc_reg_t ctr_reg, int ar_idx, 9492 int zero, int sync_mode, uint64 *val) 9493 { 9494 soc_control_t *soc = SOC_CONTROL(unit); 9495 int port_index, num_entries; 9496 char *cname; 9497 uint64 *vptr; 9498 uint64 value; 9499 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 9500 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 9501 9502 #ifdef BCM_TOMAHAWK_SUPPORT 9503 if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) && 9504 (ctr_reg >= SOC_COUNTER_NON_DMA_START) && 9505 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 9506 soc_counter_non_dma_t *non_dma = 9507 &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 9508 soc_ctr_control_info_t ctrl_info; 9509 if (soc_tomahawk_mem_is_xpe(unit, non_dma->mem)) { 9510 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE; 9511 } 9512 #ifdef BCM_FLOWTRACKER_SUPPORT 9513 else if ((ctr_reg >= 9514 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT) && 9515 (ctr_reg <= SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT)) { 9516 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_FT_GROUP; 9517 sync_mode = 1; 9518 } 9519 #endif 9520 #ifdef BCM_TOMAHAWK3_SUPPORT 9521 else if (soc_tomahawk3_mem_is_itm(unit, non_dma->mem) || 9522 soc_tomahawk3_reg_is_itm(unit, non_dma->reg)) { 9523 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM; 9524 9525 /* some exceptions here */ 9526 if(SOC_MEM_IS_VALID(unit, non_dma->mem)) { 9527 switch(non_dma->mem) { 9528 case MMU_THDO_SRC_PORT_DROP_COUNTm: 9529 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 9530 break; 9531 default: 9532 break; 9533 } 9534 } 9535 } 9536 #endif /* BCM_TOMAHAWK3_SUPPORT */ 9537 else { 9538 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 9539 } 9540 ctrl_info.instance = port; 9541 return soc_counter_generic_get(unit, ctr_reg, ctrl_info, 9542 sync_mode ? SOC_COUNTER_SYNC_ENABLE : 0, 9543 ar_idx, val); 9544 } 9545 #endif /* BCM_TOMAHAWK_SUPPORT */ 9546 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 9547 /*when port is invalid, rely on ar_idx to get ind*/ 9548 if ((port == SOC_PORT_INVALID) && SOC_IS_TRIDENT2PLUS(unit) && 9549 (ctr_reg >= SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC && 9550 ctr_reg <= SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC )) { 9551 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, SOC_PORT_MIN(unit,all), 9552 ctr_reg, &port_index, &num_entries, &cname)); 9553 port_index += ar_idx; 9554 } else 9555 #endif 9556 { 9557 /* coverity[negative_returns] */ 9558 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg, 9559 &port_index, &num_entries, 9560 &cname)); 9561 if (ar_idx >= num_entries) { 9562 return SOC_E_PARAM; 9563 } 9564 9565 if (sync_mode == TRUE) { 9566 COUNTER_LOCK(unit); 9567 9568 /* sync the software counter with hardware counter */ 9569 if (!SOC_COUNTER_INVALID(unit, ctr_reg)) { 9570 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) 9571 soc_counter_collect64(unit, FALSE, port, ctr_reg); 9572 #endif 9573 } else if (ctr_reg >= SOC_COUNTER_NON_DMA_START && 9574 ctr_reg < SOC_COUNTER_NON_DMA_END) { 9575 if(soc_ctr_ctrl->collect_non_stat_dma) { 9576 soc_ctr_ctrl->collect_non_stat_dma(unit, port, port_index, 9577 ar_idx, ctr_reg); 9578 } 9579 #ifdef BCM_TOMAHAWK_SUPPORT 9580 if (soc_feature(unit, soc_feature_counter_eviction)) { 9581 SOC_IF_ERROR_RETURN(soc_counter_eviction_sync(unit)); 9582 } 9583 #endif 9584 9585 LOG_DEBUG(BSL_LS_SOC_COUNTER, 9586 (BSL_META_U(unit, 9587 "port[%d], ctr_reg[%d]," 9588 "port_index[%d], ar_idx[%d]" 9589 "num_entries[%d], cname[%s] "), 9590 port, ctr_reg, port_index, ar_idx, 9591 num_entries, cname)); 9592 } 9593 COUNTER_UNLOCK(unit); 9594 } 9595 9596 if (ar_idx > 0 && ar_idx < num_entries) { 9597 port_index += ar_idx; 9598 } 9599 } 9600 9601 /* Try to minimize the atomic section as much as possible */ 9602 if (ctr_reg >= SOC_COUNTER_NON_DMA_START && 9603 ctr_reg < SOC_COUNTER_NON_DMA_END && 9604 (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags & 9605 _SOC_COUNTER_NON_DMA_CURRENT)) { 9606 vptr = &soc->counter_hw_val[port_index]; 9607 } else { 9608 vptr = &soc->counter_sw_val[port_index]; 9609 } 9610 if (zero) { 9611 COUNTER_ATOMIC_BEGIN(s); 9612 value = *vptr; 9613 COMPILER_64_ZERO(*vptr); 9614 COUNTER_ATOMIC_END(s); 9615 } else { 9616 COUNTER_ATOMIC_BEGIN(s); 9617 value = *vptr; 9618 COUNTER_ATOMIC_END(s); 9619 } 9620 9621 LOG_DEBUG(BSL_LS_SOC_COUNTER, 9622 (BSL_META_U(unit, 9623 "cntr get %s port=%d " 9624 "port_index=%d vptr=%p val=0x%08x_%08x\n"), 9625 cname, 9626 port, 9627 port_index, 9628 (void *)vptr, COMPILER_64_HI(value), COMPILER_64_LO(value))); 9629 9630 *val = value; 9631 9632 return SOC_E_NONE; 9633 } 9634 9635 /* 9636 * Function: 9637 * _soc_counter_instance_encode 9638 * Purpose: 9639 * Given an input array of heterogeneous soc_ctr_control_info_t 9640 * data structures, encode them into one single output 9641 * soc_ctr_control_info_t data structure. 9642 * Parameters: 9643 * input_ctrl_info - (IN) Input array of ctrl_info variables to be 9644 * encoded. 9645 * count - (IN) Number of ctrl_info variables to be encoded. 9646 * output_ctrl_info - (OUT) Encoded output ctrl_info data structure. 9647 * Returns: 9648 * SOC_E_XXX. 9649 * Notes: 9650 * Encoding support currently exists for SOC_CTR_INSTANCE_TYPE_POOL_PIPE 9651 * and SOC_CTR_INSTANCE_TYPE_XPE_PORT 9652 * Decoding is done inside soc_tomahawk_counter_generic_get_info function. 9653 * Encoding scheme 9654 * Bits 0-3 PIPE 9655 * 4-9 POOL 9656 * 10-13 XPE 9657 * 14-23 PORT 9658 * 24-25 ITM 9659 */ 9660 int 9661 soc_counter_instance_encode(soc_ctr_control_info_t *input_ctrl_info, int count, 9662 soc_ctr_control_info_t *output_ctrl_info) 9663 { 9664 switch (count) { 9665 case 1: 9666 *output_ctrl_info = input_ctrl_info[0]; 9667 return SOC_E_NONE; 9668 break; 9669 9670 case 2: 9671 if ((input_ctrl_info[0].instance_type == SOC_CTR_INSTANCE_TYPE_POOL) 9672 && (input_ctrl_info[1].instance_type == 9673 SOC_CTR_INSTANCE_TYPE_PIPE)) { 9674 if (input_ctrl_info[1].instance == -1) { 9675 *output_ctrl_info = input_ctrl_info[1]; 9676 } else { 9677 output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_POOL_PIPE; 9678 /* First 4 bits allocated to Pipe and next 6 allocated to 9679 * Pool */ 9680 output_ctrl_info->instance = ((input_ctrl_info[0].instance << 4) 9681 | (input_ctrl_info[1].instance)); 9682 } 9683 return SOC_E_NONE; 9684 } else if ((input_ctrl_info[0].instance_type == 9685 SOC_CTR_INSTANCE_TYPE_PIPE) 9686 && (input_ctrl_info[1].instance_type == 9687 SOC_CTR_INSTANCE_TYPE_POOL)) { 9688 if (input_ctrl_info[0].instance == -1) { 9689 *output_ctrl_info = input_ctrl_info[0]; 9690 } else { 9691 output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_POOL_PIPE; 9692 output_ctrl_info->instance = ((input_ctrl_info[1].instance << 4) 9693 | (input_ctrl_info[0].instance)); 9694 } 9695 return SOC_E_NONE; 9696 } else if ((input_ctrl_info[0].instance_type == 9697 SOC_CTR_INSTANCE_TYPE_XPE) 9698 && (input_ctrl_info[1].instance_type == 9699 SOC_CTR_INSTANCE_TYPE_PORT)) { 9700 output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_XPE_PORT; 9701 /*Bits 10-13 allocated to XPE and next 10 allocated to 9702 * Port */ 9703 output_ctrl_info->instance = ((input_ctrl_info[0].instance << 10) 9704 |(input_ctrl_info[1].instance << 14)); 9705 return SOC_E_NONE; 9706 } else if ((input_ctrl_info[0].instance_type == 9707 SOC_CTR_INSTANCE_TYPE_PORT) 9708 && (input_ctrl_info[1].instance_type == 9709 SOC_CTR_INSTANCE_TYPE_XPE)) { 9710 output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_XPE_PORT; 9711 /*Bits 10-13 allocated to XPE and next 10 allocated to 9712 * Port */ 9713 output_ctrl_info->instance = ((input_ctrl_info[0].instance << 14) 9714 |(input_ctrl_info[1].instance << 10)); 9715 return SOC_E_NONE; 9716 } else if ((input_ctrl_info[0].instance_type == 9717 SOC_CTR_INSTANCE_TYPE_ITM) 9718 && (input_ctrl_info[1].instance_type == 9719 SOC_CTR_INSTANCE_TYPE_PORT)) { 9720 output_ctrl_info->instance_type = SOC_CTR_INSTANCE_TYPE_ITM_PORT; 9721 output_ctrl_info->instance = 9722 ((input_ctrl_info[0].instance << CTR_INSTANCE_BIT_SHIFT_ITM) | 9723 (input_ctrl_info[1].instance << CTR_INSTANCE_BIT_SHIFT_PORT)); 9724 return SOC_E_NONE; 9725 } else { 9726 return SOC_E_PARAM; 9727 } 9728 break; 9729 9730 default: 9731 return SOC_E_PARAM; 9732 9733 } 9734 } 9735 9736 static INLINE int 9737 _soc_counter_generic_get(int unit, soc_ctr_control_info_t ctrl_info, soc_reg_t ctr_reg, 9738 int ar_idx, int zero, int sync_mode, uint64 *val) 9739 { 9740 soc_control_t *soc = SOC_CONTROL(unit); 9741 int base_index, num_entries,i, pipe_max_idx = 0; 9742 uint64 *vptr; 9743 uint64 value; 9744 #ifdef BCM_TOMAHAWK3_SUPPORT 9745 soc_info_t * si = &SOC_INFO(unit); 9746 #endif 9747 9748 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 9749 COMPILER_64_SET(*val, 0, 0); 9750 SOC_IF_ERROR_RETURN(soc_counter_generic_get_info(unit, ctrl_info,ctr_reg, 9751 &base_index,&num_entries)); 9752 if (ar_idx >= num_entries) { 9753 return SOC_E_PARAM; 9754 } 9755 /* Retrieve ar_idx across all pipes */ 9756 if (((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) && 9757 (ctrl_info.instance == -1)) || (ctrl_info.instance_type == 9758 SOC_CTR_INSTANCE_TYPE_POOL)) { 9759 pipe_max_idx = base_index + (NUM_PIPE(unit) * num_entries); 9760 } 9761 9762 if (sync_mode == TRUE) { 9763 COUNTER_LOCK(unit); 9764 9765 /* sync the software counter with hardware counter */ 9766 if (!SOC_COUNTER_INVALID(unit, ctr_reg)) { 9767 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) 9768 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) { 9769 soc_counter_collect64(unit, FALSE, ctrl_info.instance, ctr_reg); 9770 } 9771 #endif 9772 } else if (ctr_reg >= SOC_COUNTER_NON_DMA_START && 9773 ctr_reg < SOC_COUNTER_NON_DMA_END) { 9774 if (pipe_max_idx == 0) { 9775 soc_counter_generic_collect_non_dma_entries(unit, ctrl_info, 9776 base_index, 9777 ar_idx, ctr_reg); 9778 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) { 9779 for (i = 0; i < NUM_PIPE(unit); i++) { 9780 #ifdef BCM_TOMAHAWK3_SUPPORT 9781 if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) { 9782 continue; 9783 } 9784 #endif 9785 ctrl_info.instance = i; 9786 soc_counter_generic_collect_non_dma_entries(unit, 9787 ctrl_info, 9788 base_index + i * num_entries, 9789 ar_idx, 9790 ctr_reg); 9791 } 9792 } 9793 else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL || 9794 ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE) { 9795 int pipe_start = 0, pipe_end = 0, i = 0; 9796 soc_ctr_control_info_t ctrl_info_in[2], ctrl_info_out; 9797 9798 ctrl_info_in[0].instance_type = SOC_CTR_INSTANCE_TYPE_POOL; 9799 ctrl_info_in[0].instance = 0; 9800 ctrl_info_in[1].instance_type = SOC_CTR_INSTANCE_TYPE_PIPE; 9801 ctrl_info_in[1].instance = 0; 9802 9803 if (ctrl_info.instance_type 9804 == SOC_CTR_INSTANCE_TYPE_POOL) { 9805 pipe_start = 0; 9806 pipe_end = NUM_PIPE(unit) - 1; 9807 ctrl_info_in[0].instance = ctrl_info.instance; 9808 } else { 9809 if (ctrl_info.instance != -1) { 9810 pipe_start = pipe_end = (ctrl_info.instance & 0xF); 9811 ctrl_info_in[0].instance = (ctrl_info.instance >> 4) & 0x3F; 9812 } else { 9813 pipe_start = 0; 9814 pipe_end = NUM_PIPE(unit) - 1; 9815 } 9816 } 9817 9818 for(i = pipe_start; i <= pipe_end; i++) { 9819 #ifdef BCM_TOMAHAWK3_SUPPORT 9820 if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) { 9821 continue; 9822 } 9823 #endif 9824 ctrl_info_in[1].instance = i; 9825 soc_counter_instance_encode(ctrl_info_in, 2, &ctrl_info_out); 9826 soc_counter_generic_collect_non_dma_entries(unit, 9827 ctrl_info_out, 9828 base_index, 9829 ar_idx, 9830 ctr_reg); 9831 } 9832 } 9833 } 9834 9835 COUNTER_UNLOCK(unit); 9836 9837 #ifdef BCM_TOMAHAWK_SUPPORT 9838 if (soc_feature(unit, soc_feature_counter_eviction)) { 9839 int i = 0; 9840 int rv = 0; 9841 int count = 0; 9842 uint8 chan = SOC_MEM_FIFO_DMA_CHANNEL_1; 9843 soc_mem_t mem = CENTRAL_CTR_EVICTION_FIFOm; 9844 int entry_words = soc_mem_entry_words(unit, mem); 9845 9846 #if defined(BCM_TOMAHAWK3_SUPPORT) 9847 if (SOC_IS_TOMAHAWK3(unit)) { 9848 chan = SOC_MEM_FIFO_DMA_CHANNEL_0; 9849 } 9850 #endif 9851 EVICT_LOCK(unit); 9852 if (host_entry[unit]) { 9853 rv = soc_fifodma_num_entries_get(unit, chan, &count); 9854 if (SOC_SUCCESS(rv)) { 9855 for (i = 0; i < count; i++) { 9856 if (!soc->counter_interval) { 9857 break; 9858 } 9859 _soc_counter_fifo_process(unit, host_entry[unit]); 9860 host_entry[unit] = (uint32*)(host_entry[unit]) + entry_words; 9861 if ((uint32*)(host_entry[unit]) >= buff_max[unit]) { 9862 host_entry[unit] = host_buff[unit]; 9863 } 9864 } 9865 soc_fifodma_set_entries_read(unit, chan, i); 9866 } 9867 } 9868 EVICT_UNLOCK(unit); 9869 } 9870 #endif 9871 } 9872 9873 if (ar_idx > 0 && ar_idx < num_entries) { 9874 base_index += ar_idx; 9875 } 9876 9877 do { 9878 /* Try to minimize the atomic section as much as possible */ 9879 if ((ctr_reg >= NUM_SOC_REG) && 9880 (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags & 9881 _SOC_COUNTER_NON_DMA_CURRENT)) { 9882 vptr = &soc->counter_hw_val[base_index]; 9883 } else { 9884 vptr = &soc->counter_sw_val[base_index]; 9885 } 9886 if (zero) { 9887 COUNTER_ATOMIC_BEGIN(s); 9888 value = *vptr; 9889 COMPILER_64_ZERO(*vptr); 9890 COUNTER_ATOMIC_END(s); 9891 } else { 9892 COUNTER_ATOMIC_BEGIN(s); 9893 value = *vptr; 9894 COUNTER_ATOMIC_END(s); 9895 } 9896 base_index += num_entries; 9897 COMPILER_64_ADD_64(*val, value); 9898 } while (base_index < pipe_max_idx); 9899 9900 return SOC_E_NONE; 9901 } 9902 9903 int soc_counter_sync_mode_get(int unit) 9904 { 9905 #ifdef BCM_PETRA_SUPPORT 9906 #ifdef CRASH_RECOVERY_SUPPORT 9907 if (SOC_IS_ARAD(unit)) 9908 { 9909 /* In case crash recovery is enabled - read the values from HW instead of SW */ 9910 if (SOC_CR_ENABALED(unit)) 9911 { 9912 return TRUE; /* read hw accumulated */ 9913 } 9914 return FALSE; /* read sw accumulated */ 9915 } 9916 else 9917 #endif /* CRASH_RECOVERY_SUPPORT */ 9918 #endif 9919 { 9920 return FALSE; /* read sw accumulated */ 9921 } 9922 } 9923 9924 /* 9925 * Function: 9926 * soc_counter_generic_get 9927 * Purpose: 9928 * Given a counter register number, instance type, instance and a counter 9929 * value, get both the software-accumulated value from the counter. 9930 * Parameters: 9931 * unit - StrataSwitch unit #. 9932 * ctr_reg - counter register to retrieve. 9933 * ctrl_info - Counter Control Info Structure 9934 * Contains Instance type and instance. 9935 * val(OUT) - 64-bit counter value. 9936 * Returns: 9937 * SOC_E_XXX 9938 * Notes: 9939 * * Currently supported instance types are 9940 * 1. SOC_CTR_INSTANCE_TYPE_PORT 9941 * 2. SOC_CTR_INSTANCE_TYPE_POOL 9942 * 3. SOC_CTR_INSTANCE_TYPE_PIPE 9943 * 4. SOC_CTR_INSTANCE_TYPE_POOL_PIPE 9944 * 5. SOC_CTR_INSTANCE_TYPE_XPE 9945 * 6. SOC_CTR_INSTANCE_TYPE_XPE_PORT 9946 */ 9947 int 9948 soc_counter_generic_get(int unit, soc_reg_t ctr_reg, 9949 soc_ctr_control_info_t ctrl_info, uint32 flags, 9950 int ar_idx, uint64 *val) 9951 { 9952 int sync_mode = soc_counter_sync_mode_get(unit); 9953 int rv = SOC_E_NONE; 9954 soc_control_t *soc = SOC_CONTROL(unit); 9955 soc_info_t *si = &SOC_INFO(unit); 9956 int pipe, xpe, port; 9957 #ifdef BCM_TOMAHAWK3_SUPPORT 9958 uint16 dev_id; 9959 uint8 rev_id; 9960 #endif 9961 uint64 value; 9962 COMPILER_64_ZERO(*val); 9963 if (ctr_reg < SOC_COUNTER_NON_DMA_START || 9964 ctr_reg >= SOC_COUNTER_NON_DMA_END) { 9965 return SOC_E_PARAM; 9966 } 9967 9968 if (soc->counter_non_dma == NULL) { 9969 return SOC_E_RESOURCE; 9970 } 9971 9972 if (!(soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags)) { 9973 return SOC_E_UNAVAIL; 9974 } 9975 9976 if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) && 9977 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 9978 soc_counter_non_dma_t *non_dma = 9979 &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 9980 soc_mem_t mem = non_dma->mem; 9981 soc_reg_t reg = non_dma->reg; 9982 soc_ctr_control_info_t input_ctrl_info [2], output_ctrl_info; 9983 if (flags & SOC_COUNTER_SYNC_ENABLE) { 9984 sync_mode = TRUE; 9985 } 9986 #ifdef BCM_TOMAHAWK3_SUPPORT 9987 soc_cm_get_id(unit, &dev_id, &rev_id); 9988 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) { 9989 int itm; 9990 port = ctrl_info.instance; 9991 pipe = si->port_pipe[port]; 9992 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 9993 input_ctrl_info[1].instance = ctrl_info.instance; 9994 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 9995 if (mem != INVALIDm) { 9996 for (itm = 0; itm < NUM_ITM(unit) ; itm++) { 9997 if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) { 9998 continue; 9999 } 10000 input_ctrl_info[0].instance = itm; 10001 10002 if (SOC_MEM_UNIQUE_ACC_ITM(unit,mem,itm) == INVALIDm) { 10003 continue; 10004 } 10005 10006 if(itm > 0 && 10007 !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 10008 /* skip if ITM memories that has non-ITM base type */ 10009 continue; 10010 } 10011 10012 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 10013 rv = _soc_counter_generic_get(unit, output_ctrl_info, 10014 ctr_reg, ar_idx, FALSE, 10015 sync_mode, &value); 10016 if (rv != SOC_E_NONE) { 10017 return rv; 10018 } 10019 /* Sum values from all valid itm-port combinations */ 10020 COMPILER_64_ADD_64(*val, value); 10021 } 10022 } else if (reg != INVALIDr) { 10023 10024 for (itm = 0; itm < NUM_ITM(unit) ; itm++) { 10025 if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) { 10026 continue; 10027 } 10028 input_ctrl_info[0].instance = itm; 10029 10030 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 10031 rv = _soc_counter_generic_get(unit, output_ctrl_info, 10032 ctr_reg, ar_idx, FALSE, 10033 sync_mode, &value); 10034 10035 if (rv != SOC_E_NONE) { 10036 return rv; 10037 } 10038 /* Sum values from all valid itm-port combinations */ 10039 COMPILER_64_ADD_64(*val, value); 10040 } 10041 } 10042 } else 10043 #endif /* BCM_TOMAHAWK3_SUPPORT */ 10044 10045 /* Each XPE maps to a pair of IPIPE or EPIPE based on memory type. 10046 * Hence loop through all applicable XPEs for a given pipe and return 10047 * accumulated value*/ 10048 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) { 10049 port = ctrl_info.instance; 10050 pipe = si->port_pipe[port]; 10051 if (mem != INVALIDm) { 10052 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 10053 input_ctrl_info[1].instance = ctrl_info.instance; 10054 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10055 10056 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) { 10057 input_ctrl_info[0].instance = xpe; 10058 if ((mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) { 10059 /* Get valid XPE/Pipe Combination */ 10060 if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) { 10061 continue; 10062 } 10063 } else { 10064 if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) { 10065 /* Invalid XPE/Pipe Combination */ 10066 continue; 10067 } 10068 } 10069 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 10070 rv = _soc_counter_generic_get(unit, output_ctrl_info, 10071 ctr_reg, ar_idx, FALSE, 10072 sync_mode, &value); 10073 if (rv != SOC_E_NONE) { 10074 return rv; 10075 } 10076 /* Sum values from all valid xpe-port combinations */ 10077 COMPILER_64_ADD_64(*val, value); 10078 10079 } 10080 } else if (reg != INVALIDr) { 10081 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 10082 10083 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) { 10084 input_ctrl_info[0].instance = xpe; 10085 if (reg == THDI_POOL_SHARED_COUNT_SPr) { 10086 /* Get valid XPE/Pipe Combination */ 10087 if(!((si->ipipe_xpe_map[pipe] >> xpe) & 1)) { 10088 continue; 10089 } 10090 } 10091 rv = _soc_counter_generic_get(unit, input_ctrl_info[0], 10092 ctr_reg, ar_idx, FALSE, 10093 sync_mode, &value); 10094 if (rv != SOC_E_NONE) { 10095 return rv; 10096 } 10097 /* Sum values from all valid xpe-port combinations */ 10098 COMPILER_64_ADD_64(*val, value); 10099 } 10100 } 10101 } else { 10102 rv = _soc_counter_generic_get(unit, ctrl_info, ctr_reg, ar_idx, 10103 FALSE, sync_mode, val); 10104 } 10105 } 10106 10107 return rv; 10108 } 10109 10110 #ifdef BCM_APACHE_SUPPORT 10111 int 10112 soc_counter_apache_generic_get_info(int unit,soc_ctr_control_info_t ctrl_info, 10113 soc_reg_t id, int *base_index, 10114 int *num_entries) 10115 { 10116 soc_info_t *si = &SOC_INFO(unit); 10117 soc_control_t *soc = SOC_CONTROL(unit); 10118 soc_counter_non_dma_t *non_dma; 10119 soc_port_t port; 10120 10121 if ((id < NUM_SOC_REG) || (id >= SOC_COUNTER_NON_DMA_END)) { 10122 return SOC_E_PARAM; 10123 } 10124 10125 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 10126 10127 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && 10128 !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 10129 /* For Parent-Child model, return E_UNAVAIL if child non_dma is INVALID. 10130 */ 10131 return SOC_E_UNAVAIL; 10132 } 10133 10134 *base_index = 0; 10135 switch (ctrl_info.instance_type) { 10136 case SOC_CTR_INSTANCE_TYPE_PORT: 10137 port = ctrl_info.instance; 10138 if (si->port_l2p_mapping[port] == -1) { 10139 *base_index = 0; 10140 *num_entries = 0; 10141 return SOC_E_PARAM; 10142 } 10143 10144 switch (id) { 10145 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO: 10146 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_LO: 10147 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_HI: 10148 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSY_HI: 10149 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS0: 10150 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS0: 10151 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSLESS1: 10152 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1: 10153 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_EXPRESS: 10154 case SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_EXPRESS: 10155 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_LO: 10156 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_LO: 10157 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSY_HI: 10158 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSY_HI: 10159 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS0: 10160 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS0: 10161 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_LOSSLESS1: 10162 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_LOSSLESS1: 10163 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_PKT_OBM_EXPRESS: 10164 case SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS: 10165 if (IS_RDB_PORT(unit, port) || 10166 IS_LB_PORT(unit, port)) { 10167 return SOC_E_PARAM; 10168 } 10169 return _soc_counter_apache_get_info(unit, port, id, 10170 base_index, 10171 num_entries); 10172 break; 10173 default: 10174 return SOC_E_PARAM; 10175 } 10176 break; 10177 10178 default: 10179 return SOC_E_PARAM; 10180 } 10181 return SOC_E_NONE; 10182 } 10183 #endif 10184 10185 int 10186 soc_counter_generic_get_info(int unit, soc_ctr_control_info_t ctrl_info, 10187 soc_reg_t id, int *base_index, int *num_entries) 10188 { 10189 int rv = SOC_E_UNAVAIL; 10190 #ifdef BCM_TOMAHAWK_SUPPORT 10191 if (SOC_IS_TOMAHAWKX(unit)) { 10192 rv = soc_counter_tomahawk_generic_get_info(unit, ctrl_info, id, 10193 base_index, num_entries); 10194 } 10195 #endif 10196 #ifdef BCM_TRIDENT3_SUPPORT 10197 if (SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 10198 rv = soc_counter_trident3_generic_get_info(unit, ctrl_info, id, 10199 base_index, num_entries); 10200 } 10201 #endif 10202 #ifdef BCM_HELIX5_SUPPORT 10203 if (SOC_IS_HELIX5(unit)) { 10204 rv = soc_counter_helix5_generic_get_info(unit, ctrl_info, id, 10205 base_index, num_entries); 10206 } 10207 #endif 10208 #ifdef BCM_APACHE_SUPPORT 10209 if (SOC_IS_APACHE(unit)) { 10210 rv = soc_counter_apache_generic_get_info(unit, ctrl_info, id, 10211 base_index, num_entries); 10212 } 10213 #endif 10214 return rv; 10215 } 10216 10217 /* 10218 * Function: 10219 * soc_counter_get, soc_counter_get32 10220 * soc_counter_get_zero, soc_counter_get32_zero 10221 * Purpose: 10222 * Given a counter register number and port number, fetch the 10223 * 64-bit software-accumulated counter value (normal versions) 10224 * or the 64-bit software-accumulated counter value truncated to 10225 * 32 bits (32-bit versions). The software-accumulated counter 10226 * value is zeroed if requested. 10227 * Parameters: 10228 * unit - StrataSwitch unit #. 10229 * port - StrataSwitch port #. 10230 * ctr_reg - counter register to retrieve. 10231 * val - (OUT) 64/32-bit counter value. 10232 * Returns: 10233 * SOC_E_XXX. 10234 * Notes: 10235 * The 32-bit version returns only the lower 32 bits of the 64-bit 10236 * counter value. 10237 */ 10238 10239 10240 int 10241 soc_counter_get(int unit, soc_port_t port, soc_reg_t ctr_reg, 10242 int ar_idx, uint64 *val) 10243 { 10244 int sync_mode = soc_counter_sync_mode_get(unit); 10245 return _soc_counter_get(unit, port, ctr_reg, ar_idx, 10246 FALSE, sync_mode, val); 10247 } 10248 10249 int 10250 soc_counter_get32(int unit, soc_port_t port, soc_reg_t ctr_reg, 10251 int ar_idx, uint32 *val) 10252 { 10253 uint64 val64; 10254 int rv; 10255 int sync_mode = soc_counter_sync_mode_get(unit); 10256 10257 rv = _soc_counter_get(unit, port, ctr_reg, ar_idx, 10258 FALSE, sync_mode, &val64); 10259 10260 if (rv >= 0) { 10261 COMPILER_64_TO_32_LO(*val, val64); 10262 } 10263 10264 return rv; 10265 } 10266 10267 int 10268 soc_counter_get_zero(int unit, soc_port_t port, 10269 soc_reg_t ctr_reg, int ar_idx, uint64 *val) 10270 { 10271 int sync_mode = soc_counter_sync_mode_get(unit); 10272 return _soc_counter_get(unit, port, ctr_reg, ar_idx, 10273 TRUE, sync_mode, val); 10274 } 10275 10276 int 10277 soc_counter_get32_zero(int unit, soc_port_t port, 10278 soc_reg_t ctr_reg, int ar_idx, uint32 *val) 10279 { 10280 uint64 val64; 10281 int rv; 10282 int sync_mode = soc_counter_sync_mode_get(unit); 10283 10284 rv = _soc_counter_get(unit, port, ctr_reg, ar_idx, 10285 TRUE, sync_mode, &val64); 10286 10287 if (rv >= 0) { 10288 COMPILER_64_TO_32_LO(*val, val64); 10289 } 10290 10291 return rv; 10292 } 10293 10294 /* 10295 * Function: 10296 * soc_counter_sync_get, soc_counter_sync_get32 10297 * Purpose: 10298 * Given a counter register and port number, sync the 10299 * counter value from the device register to the sw accumulated 10300 * value. 10301 * Parameters: 10302 * unit - StrataSwitch unit #. 10303 * port - StrataSwitch port #. 10304 * ctr_reg - counter register to retrieve. 10305 * val - (OUT) 64/32-bit counter value. 10306 * Returns: 10307 * SOC_E_XXX. 10308 */ 10309 10310 int 10311 soc_counter_sync_get(int unit, soc_port_t port, soc_reg_t ctr_reg, 10312 int ar_idx, uint64 *val) 10313 { 10314 int sync_mode = TRUE; /* read register */ 10315 return _soc_counter_get(unit, port, ctr_reg, ar_idx, 10316 FALSE, sync_mode, val); 10317 } 10318 10319 int 10320 soc_counter_sync_get32(int unit, soc_port_t port, soc_reg_t ctr_reg, 10321 int ar_idx, uint32 *val) 10322 { 10323 uint64 val64; 10324 int rv; 10325 int sync_mode = TRUE; /* read register */ 10326 10327 rv = _soc_counter_get(unit, port, ctr_reg, ar_idx, 10328 FALSE, sync_mode, &val64); 10329 10330 if (rv >= 0) { 10331 COMPILER_64_TO_32_LO(*val, val64); 10332 } 10333 10334 return rv; 10335 } 10336 10337 int 10338 soc_counter_direct_get(int unit, soc_port_t port, soc_reg_t ctr_reg, 10339 int ar_idx, uint64 *val) 10340 { 10341 int port_index, num_entries; 10342 int port_base, index; 10343 char *cname; 10344 uint64 value = COMPILER_64_INIT(0, 0); 10345 10346 port_base = COUNTER_MIN_IDX_GET(unit, port); 10347 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg, 10348 &port_index, &num_entries, 10349 &cname)); 10350 if (ar_idx >= num_entries) { 10351 return SOC_E_PARAM; 10352 } 10353 index = port_index - port_base; 10354 ctr_reg = PORT_CTR_REG(unit, port, index)->reg; 10355 ar_idx = PORT_CTR_REG(unit, port, index)->index; 10356 if (!SOC_COUNTER_INVALID(unit, ctr_reg)) { 10357 #ifdef SOC_COUNTER_TABLE_SUPPORT 10358 #if defined (BCM_TOMAHAWK3_SUPPORT) 10359 if (SOC_IS_TOMAHAWK3(unit) && 10360 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 10361 soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL; 10362 SOC_IF_ERROR_RETURN 10363 (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry)); 10364 SOC_IF_ERROR_RETURN 10365 (_soc_ctr_tbl_field_get(unit, ctr_reg, port, ctr_tbl_info_entry, &value)); 10366 } else 10367 #endif /* BCM_TOMAHAWK3_SUPPORT */ 10368 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 10369 { 10370 SOC_IF_ERROR_RETURN(soc_reg_get(unit, ctr_reg, port, ar_idx, 10371 &value)); 10372 } 10373 } 10374 10375 *val = value; 10376 10377 return SOC_E_NONE; 10378 } 10379 10380 #ifdef BCM_TOMAHAWK_SUPPORT 10381 STATIC int 10382 _soc_counter_generic_get_delta(int unit, soc_ctr_control_info_t ctrl_info, 10383 soc_reg_t ctr_reg, int ar_idx, uint64 *value) 10384 { 10385 int base_index, num_entries; 10386 soc_control_t *soc = SOC_CONTROL(unit); 10387 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 10388 int pipe_max_idx = 0; 10389 uint64 *vptr; 10390 uint64 val; 10391 10392 COMPILER_64_ZERO(*value); 10393 10394 SOC_IF_ERROR_RETURN 10395 (soc_counter_generic_get_info(unit, ctrl_info, ctr_reg, 10396 &base_index, &num_entries)); 10397 10398 if (ar_idx >= num_entries) { 10399 return SOC_E_PARAM; 10400 } 10401 10402 if (((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) && 10403 (ctrl_info.instance == -1)) || (ctrl_info.instance_type == 10404 SOC_CTR_INSTANCE_TYPE_POOL)) { 10405 pipe_max_idx = base_index + (NUM_PIPE(unit) * num_entries); 10406 } 10407 10408 if (ar_idx > 0 && ar_idx < num_entries) { 10409 base_index += ar_idx; 10410 } 10411 10412 if (soc->counter_interval == 0) { 10413 COMPILER_64_ZERO(*value); 10414 } else { 10415 do { 10416 if ((ctr_reg >= NUM_SOC_REG) && 10417 (soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags & 10418 _SOC_COUNTER_NON_DMA_CURRENT)) { 10419 return SOC_E_PARAM; 10420 } else { 10421 vptr = &soc->counter_delta[base_index]; 10422 } 10423 COUNTER_ATOMIC_BEGIN(s); 10424 val = *vptr; 10425 COUNTER_ATOMIC_END(s); 10426 base_index += num_entries; 10427 COMPILER_64_ADD_64(*value, val); 10428 } while (base_index < pipe_max_idx); 10429 } 10430 return SOC_E_NONE; 10431 10432 } 10433 10434 STATIC int 10435 soc_counter_generic_get_delta(int unit, soc_ctr_control_info_t ctrl_info, 10436 soc_reg_t ctr_reg, int ar_idx, uint64 *value) 10437 { 10438 soc_control_t *soc = SOC_CONTROL(unit); 10439 int rv = SOC_E_NONE; 10440 soc_info_t *si = &SOC_INFO(unit); 10441 uint64 val; 10442 int pipe, xpe, port; 10443 10444 COMPILER_64_ZERO(*value); 10445 COMPILER_64_ZERO(val); 10446 10447 if (ctr_reg >= SOC_COUNTER_NON_DMA_END) { 10448 return SOC_E_PARAM; 10449 } 10450 10451 if (!(soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].flags)) { 10452 return SOC_E_UNAVAIL; 10453 } 10454 10455 if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) && 10456 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 10457 soc_mem_t mem = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].mem; 10458 soc_reg_t reg = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].reg; 10459 soc_ctr_control_info_t input_ctrl_info[2], output_ctrl_info; 10460 /* Each XPE maps to a pair of IPIPE or EPIPE based on memory type. 10461 * Hence loop through all applicable XPEs for a given pipe and return 10462 * accumulated value*/ 10463 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) { 10464 port = ctrl_info.instance; 10465 pipe = si->port_pipe[port]; 10466 if (mem != INVALIDm) { 10467 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 10468 input_ctrl_info[1].instance = ctrl_info.instance; 10469 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10470 10471 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) { 10472 input_ctrl_info[0].instance = xpe; 10473 if (mem == MMU_CTR_COLOR_DROP_MEMm) { 10474 /* Get valid XPE/Pipe Combination */ 10475 if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) { 10476 continue; 10477 } 10478 } else { 10479 if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) { 10480 /* Invalid XPE/Pipe Combination */ 10481 continue; 10482 } 10483 } 10484 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 10485 rv = _soc_counter_generic_get_delta(unit, output_ctrl_info, 10486 ctr_reg, ar_idx, 10487 &val); 10488 if (rv != SOC_E_NONE) { 10489 return rv; 10490 } 10491 /* Sum values from all valid xpe-port combinations */ 10492 COMPILER_64_ADD_64(*value, val); 10493 } 10494 } else if (reg != INVALIDr) { 10495 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 10496 10497 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) { 10498 input_ctrl_info[0].instance = xpe; 10499 if (reg == THDI_POOL_SHARED_COUNT_SPr) { 10500 /* Get valid XPE/Pipe Combination */ 10501 if(!((si->ipipe_xpe_map[pipe] >> xpe) & 1)) { 10502 continue; 10503 } 10504 } 10505 rv = _soc_counter_generic_get_delta(unit, input_ctrl_info[0], 10506 ctr_reg, ar_idx, 10507 &val); 10508 if (rv != SOC_E_NONE) { 10509 return rv; 10510 } 10511 /* Sum values from all valid xpe-port combinations */ 10512 COMPILER_64_ADD_64(*value, val); 10513 } 10514 } 10515 #ifdef BCM_TOMAHAWK3_SUPPORT 10516 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) { 10517 uint16 itm; 10518 port = ctrl_info.instance; 10519 pipe = si->port_pipe[port]; 10520 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 10521 input_ctrl_info[1].instance = ctrl_info.instance; 10522 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10523 for (itm = 0; itm < NUM_ITM(unit) ; itm++) { 10524 input_ctrl_info[0].instance = itm; 10525 10526 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 10527 rv = _soc_counter_generic_get_delta(unit, output_ctrl_info, 10528 ctr_reg, ar_idx, 10529 &val); 10530 if (rv != SOC_E_NONE) { 10531 return rv; 10532 } 10533 /* Sum values for a counter from all ITMs */ 10534 COMPILER_64_ADD_64(*value, val); 10535 } 10536 #endif 10537 } else { 10538 rv = _soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx, 10539 value); 10540 } 10541 } else { 10542 rv = _soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx, 10543 value); 10544 } 10545 10546 return rv; 10547 } 10548 10549 STATIC int 10550 soc_counter_generic_get_rate(int unit, soc_ctr_control_info_t ctrl_info, 10551 soc_reg_t ctr_reg, int ar_idx, uint64 *rate) 10552 { 10553 soc_control_t *soc = SOC_CONTROL(unit); 10554 uint64 value; 10555 10556 COMPILER_64_ZERO(value); 10557 COMPILER_64_ZERO(*rate); 10558 10559 SOC_IF_ERROR_RETURN 10560 (soc_counter_generic_get_delta(unit, ctrl_info, ctr_reg, ar_idx, 10561 &value)); 10562 10563 if (soc->counter_interval == 0) { 10564 COMPILER_64_ZERO(*rate); 10565 } else { 10566 #ifdef COMPILER_HAS_DOUBLE 10567 /* 10568 * This uses floating point right now because uint64 multiply/divide 10569 * support is missing from many compiler libraries. 10570 */ 10571 10572 #define UINT32_MAX_VALUE (4294967296.0) 10573 uint32 ratedblHI, ratedblLO; 10574 double interval, delta, ratedbl; 10575 10576 delta = COMPILER_64_HI(value) * UINT32_MAX_VALUE + 10577 COMPILER_64_LO(value); 10578 10579 interval = SAL_USECS_SUB(soc->counter_coll_cur, 10580 soc->counter_coll_prev) / 1000000.0; 10581 10582 if (interval < 0.0001) { 10583 COMPILER_64_SET(*rate, 0, 0); 10584 } else { 10585 ratedbl = (delta / interval + 0.5); 10586 ratedblHI = (uint32)(ratedbl / UINT32_MAX_VALUE); 10587 ratedblLO = (uint32)(ratedbl - ratedblHI * UINT32_MAX_VALUE); 10588 10589 COMPILER_64_SET(*rate, ratedblHI, ratedblLO); 10590 } 10591 10592 #else /* !COMPILER_HAS_DOUBLE */ 10593 uint32 delta32, rate32; 10594 int interval; 10595 10596 COMPILER_64_TO_32_LO(delta32, value); 10597 10598 interval = SAL_USECS_SUB(soc->counter_coll_cur, soc->counter_coll_prev); 10599 10600 if (interval < 100) { 10601 rate32 = 0; 10602 } else { 10603 rate32 = _shr_div_exp10(delta32, interval, 6); 10604 } 10605 10606 COMPILER_64_SET(*rate, 0, rate32); 10607 #endif /* !COMPILER_HAS_DOUBLE */ 10608 } 10609 return SOC_E_NONE; 10610 } 10611 #endif /* BCM_TOMAHAWK_SUPPORT */ 10612 10613 /* 10614 * Function: 10615 * soc_counter_get_rate 10616 * Purpose: 10617 * Returns the counter incrementing rate in units of 1/sec. 10618 * Parameters: 10619 * unit - StrataSwitch unit #. 10620 * port - StrataSwitch port #. 10621 * ctr_reg - counter register to retrieve. 10622 * rate - (OUT) 64-bit rate value. 10623 * Returns: 10624 * SOC_E_XXX. 10625 */ 10626 10627 int 10628 soc_counter_get_rate(int unit, soc_port_t port, 10629 soc_reg_t ctr_reg, int ar_idx, uint64 *rate) 10630 { 10631 soc_control_t *soc = SOC_CONTROL(unit); 10632 int port_index, num_entries; 10633 10634 #ifdef BCM_TOMAHAWK_SUPPORT 10635 if (SOC_IS_TOMAHAWKX(unit) && 10636 (ctr_reg >= SOC_COUNTER_NON_DMA_START) && 10637 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 10638 soc_ctr_control_info_t ctrl_info; 10639 int mem = soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START].mem; 10640 10641 if (soc_tomahawk_mem_is_xpe(unit, mem)) { 10642 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE; 10643 } 10644 #ifdef BCM_TOMAHAWK3_SUPPORT 10645 else if (soc_tomahawk3_mem_is_itm(unit, mem)) { 10646 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM; 10647 10648 /* some exceptions here */ 10649 if(SOC_MEM_IS_VALID(unit, mem)) { 10650 switch(mem) { 10651 case MMU_THDO_SRC_PORT_DROP_COUNTm: 10652 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10653 break; 10654 default: 10655 break; 10656 } 10657 } 10658 } 10659 #endif /* BCM_TOMAHAWK3_SUPPORT */ 10660 else { 10661 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10662 } 10663 ctrl_info.instance = port; 10664 return soc_counter_generic_get_rate(unit, ctrl_info, ctr_reg, 10665 ar_idx, rate); 10666 } 10667 #endif 10668 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg, 10669 &port_index, &num_entries, 10670 NULL)); 10671 if (ar_idx >= num_entries) { 10672 return SOC_E_PARAM; 10673 } 10674 10675 if (ar_idx > 0 && ar_idx < num_entries) { 10676 port_index += ar_idx; 10677 } 10678 10679 if (soc->counter_interval == 0) { 10680 COMPILER_64_ZERO(*rate); 10681 } else { 10682 #ifdef COMPILER_HAS_DOUBLE 10683 /* 10684 * This uses floating point right now because uint64 multiply/divide 10685 * support is missing from many compiler libraries. 10686 */ 10687 10688 #define UINT32_MAX_VALUE (4294967296.0) 10689 uint32 ratedblHI, ratedblLO; 10690 double interval, delta, ratedbl; 10691 10692 delta = COMPILER_64_HI(soc->counter_delta[port_index]) * UINT32_MAX_VALUE + 10693 COMPILER_64_LO(soc->counter_delta[port_index]); 10694 10695 interval = SAL_USECS_SUB(soc->counter_coll_cur, 10696 soc->counter_coll_prev) / 1000000.0; 10697 10698 if (interval < 0.0001) { 10699 COMPILER_64_SET(*rate, 0, 0); 10700 } else { 10701 ratedbl = (delta / interval + 0.5); 10702 ratedblHI = (uint32)(ratedbl / UINT32_MAX_VALUE); 10703 ratedblLO = (uint32)(ratedbl - ratedblHI * UINT32_MAX_VALUE); 10704 10705 COMPILER_64_SET(*rate, ratedblHI, ratedblLO); 10706 } 10707 10708 #else /* !COMPILER_HAS_DOUBLE */ 10709 uint32 delta32, rate32; 10710 int interval; 10711 10712 COMPILER_64_TO_32_LO(delta32, soc->counter_delta[port_index]); 10713 10714 interval = SAL_USECS_SUB(soc->counter_coll_cur, soc->counter_coll_prev); 10715 10716 if (interval < 100) { 10717 rate32 = 0; 10718 } else { 10719 rate32 = _shr_div_exp10(delta32, interval, 6); 10720 } 10721 10722 COMPILER_64_SET(*rate, 0, rate32); 10723 #endif /* !COMPILER_HAS_DOUBLE */ 10724 } 10725 10726 return SOC_E_NONE; 10727 } 10728 10729 /* 10730 * Function: 10731 * soc_counter_get32_rate 10732 * Purpose: 10733 * Returns the counter incrementing rate in units of 1/sec. 10734 * Parameters: 10735 * unit - StrataSwitch unit #. 10736 * port - StrataSwitch port #. 10737 * ctr_reg - counter register to retrieve. 10738 * rate - (OUT) 32-bit delta value. 10739 * Returns: 10740 * SOC_E_XXX. 10741 */ 10742 10743 int 10744 soc_counter_get32_rate(int unit, soc_port_t port, 10745 soc_reg_t ctr_reg, int ar_idx, uint32 *rate) 10746 { 10747 uint64 rate64; 10748 10749 SOC_IF_ERROR_RETURN(soc_counter_get_rate(unit, port, ctr_reg, 10750 ar_idx, &rate64)); 10751 10752 COMPILER_64_TO_32_LO(*rate, rate64); 10753 10754 return SOC_E_NONE; 10755 } 10756 10757 /* Function: 10758 * soc_counter_generic_multi_get 10759 * Purpose: 10760 * Given a counter register number, count, instance type and instance, 10761 * fetch multiple 64-bit software-accumulated counter values from 10762 * ar_idx to ar_idx + count. 10763 * Parameter: 10764 * unit - StrataSwitch Unit #. 10765 * ctr_reg - Counter Register to retrieve. 10766 * ctrl_info - Counter Control Info Structure 10767 * Contains the instance type and instance. 10768 * flags - not yet implemented. 10769 * ar_idx - Base index of counter to be retrieved. 10770 * count - Number of entries to retrieve. 10771 * val - (OUT) Base address of array holding the 64-bit counter values. 10772 *Returns: 10773 * SOC_E_XXX 10774 *Notes: 10775 * If count is set to 0, nothing is retrieved 10776 */ 10777 int 10778 soc_counter_generic_multi_get(int unit, soc_reg_t ctr_reg, 10779 soc_ctr_control_info_t ctrl_info, 10780 uint32 flags, int ar_idx, int count, 10781 uint64 *val) 10782 { 10783 int sync_mode = soc_counter_sync_mode_get(unit); 10784 int rv = SOC_E_NONE; 10785 int i = 0; /* return value and iterator */ 10786 soc_control_t *soc = SOC_CONTROL(unit); 10787 uint64 counter_val; /* value holder for each _soc_counter_generic_get call */ 10788 COMPILER_64_ZERO(counter_val); 10789 10790 if (flags & SOC_COUNTER_SYNC_ENABLE) { 10791 sync_mode = TRUE; 10792 } 10793 if (count < 0) { 10794 return SOC_E_PARAM; 10795 } 10796 10797 if (soc->counter_non_dma == NULL) { 10798 return SOC_E_RESOURCE; 10799 } 10800 10801 for (i = 0; i < count; i++) { 10802 rv = _soc_counter_generic_get(unit, ctrl_info, ctr_reg, (ar_idx+i), 10803 FALSE, sync_mode, &counter_val); 10804 val[i] = counter_val; 10805 if (rv!= SOC_E_NONE) { 10806 return rv; 10807 } 10808 } 10809 return rv; 10810 10811 } 10812 10813 STATIC int 10814 _soc_distribute_u64(uint64 value, uint64 *l, uint64 *r) 10815 { 10816 uint64 tmp, tmp1; 10817 tmp = value; 10818 COMPILER_64_SHR(tmp, 1); 10819 *l = tmp; 10820 COMPILER_64_SET(tmp1, 0, 1); 10821 COMPILER_64_AND(tmp1, value); 10822 COMPILER_64_ADD_64(tmp1, tmp); 10823 *r = tmp1; 10824 return 0; 10825 } 10826 10827 /* 10828 * Function: 10829 * soc_counter_set, soc_counter_set32 10830 * Purpose: 10831 * Given a counter register number, port number, and a counter 10832 * value, set both the hardware and software-accumulated counters 10833 * to the value. 10834 * Parameters: 10835 * unit - StrataSwitch unit #. 10836 * port - StrataSwitch port #. 10837 * ctr_reg - counter register to retrieve. 10838 * val - 64/32-bit counter value. 10839 * Returns: 10840 * SOC_E_XXX 10841 * Notes: 10842 * The 32-bit version sets the upper 32-bits of the 64-bit 10843 * software counter to zero. The specified value is truncated 10844 * to the width of the hardware register when storing to hardware. 10845 * Use the value 0 to clear counters. 10846 */ 10847 10848 STATIC int 10849 _soc_counter_set(int unit, soc_port_t port, soc_reg_t ctr_reg, 10850 int ar_idx, uint64 val64) 10851 { 10852 soc_control_t *soc = SOC_CONTROL(unit); 10853 int port_index, num_entries; 10854 int index_min, index_max, index; 10855 soc_counter_non_dma_t *non_dma; 10856 uint32 entry[SOC_MAX_MEM_FIELD_WORDS], fval[2]; 10857 int dma_base_index; 10858 soc_mem_t dma_mem; 10859 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 10860 int rv = SOC_E_NONE; 10861 int prime_ctr_write, i; 10862 uint32 val32; 10863 int numpipe = 0; 10864 int ctr_is_readonly = 0; 10865 #ifdef BCM_KATANA_SUPPORT 10866 uint32 pkt_count = 0; 10867 #endif /* BCM_KATANA_SUPPORT */ 10868 int qindex = -1; 10869 #ifdef BCM_KATANA2_SUPPORT 10870 int j=0; 10871 #endif 10872 #if defined(BCM_SABER2_SUPPORT) || defined(BCM_KATANA_SUPPORT) 10873 uint16 dev_id; 10874 uint8 rev_id; 10875 #endif 10876 #ifdef BCM_TRIUMPH3_SUPPORT 10877 int skip_hw_set = 0; 10878 #endif 10879 10880 #ifdef BCM_TOMAHAWK_SUPPORT 10881 if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit))&& 10882 (ctr_reg >= SOC_COUNTER_NON_DMA_START) && 10883 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 10884 soc_ctr_control_info_t ctrl_info; 10885 if (IS_LB_PORT(unit, port)) { 10886 /* Do nothing for LB port */ 10887 return SOC_E_NONE; 10888 } 10889 non_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 10890 if (soc_tomahawk_mem_is_xpe(unit, non_dma->mem)) { 10891 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_XPE; 10892 } 10893 #ifdef BCM_FLOWTRACKER_SUPPORT 10894 else if ((ctr_reg >= 10895 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT) && 10896 (ctr_reg <= SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT)) { 10897 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_FT_GROUP; 10898 } 10899 #endif 10900 #ifdef BCM_TOMAHAWK3_SUPPORT 10901 else if (soc_tomahawk3_mem_is_itm(unit, non_dma->mem) || 10902 soc_tomahawk3_reg_is_itm(unit, non_dma->reg)) { 10903 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_ITM; 10904 10905 /* some exceptions here */ 10906 if(SOC_MEM_IS_VALID(unit, non_dma->mem)) { 10907 switch(non_dma->mem) { 10908 case MMU_THDO_SRC_PORT_DROP_COUNTm: 10909 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10910 break; 10911 default: 10912 break; 10913 } 10914 } 10915 } 10916 #endif /* BCM_TOMAHAWK3_SUPPORT */ 10917 else { 10918 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10919 } 10920 ctrl_info.instance = port; 10921 10922 if (ctr_reg == SOC_COUNTER_NON_DMA_SFLOW_ING_PKT || 10923 ctr_reg == SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT) 10924 { 10925 if (ar_idx == -1) { 10926 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_SFLOW; 10927 ctrl_info.instance = -1; 10928 ar_idx = port; 10929 } 10930 } 10931 return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0, 10932 ar_idx, val64); 10933 } 10934 #endif /* BCM_TOMAHAWK_SUPPORT */ 10935 #ifdef BCM_MONTEREY_SUPPORT 10936 if (SOC_IS_MONTEREY(unit) && 10937 (ctr_reg >= SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO) && 10938 (ctr_reg <= SOC_COUNTER_NON_DMA_PORT_ENQUEUE_BYTE_OBM_EXPRESS)) { 10939 soc_ctr_control_info_t ctrl_info; 10940 if (IS_LB_PORT(unit, port) || 10941 IS_RDB_PORT(unit, port) || 10942 IS_MACSEC_PORT(unit, port) || 10943 IS_CPU_PORT(unit, port)) { 10944 /* Do nothing for LB port */ 10945 return SOC_E_NONE; 10946 } 10947 ctrl_info.instance = port; 10948 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10949 return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0, 10950 ar_idx, val64); 10951 } 10952 #endif 10953 #ifdef BCM_APACHE_SUPPORT 10954 if (SOC_IS_APACHE(unit) && 10955 (ctr_reg >= SOC_COUNTER_NON_DMA_PORT_DROP_PKT_OBM_LOSSY_LO) && 10956 (ctr_reg <= SOC_COUNTER_NON_DMA_PORT_DROP_BYTE_OBM_LOSSLESS1)) { 10957 soc_ctr_control_info_t ctrl_info; 10958 if (IS_LB_PORT(unit, port) || 10959 IS_CPU_PORT(unit, port)) { 10960 /* Do nothing for LB port */ 10961 return SOC_E_NONE; 10962 } 10963 ctrl_info.instance = port; 10964 ctrl_info.instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 10965 return soc_counter_generic_set(unit, ctr_reg, ctrl_info, 0, 10966 ar_idx, val64); 10967 } 10968 #endif 10969 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg, 10970 &port_index, &num_entries, 10971 NULL)); 10972 if (ar_idx >= num_entries) { 10973 return SOC_E_PARAM; 10974 } 10975 10976 if (ar_idx < 0) { 10977 index_min = 0; 10978 index_max = num_entries - 1; 10979 } else { 10980 index_min = index_max = ar_idx; 10981 } 10982 10983 /* 10984 * Wait for dma counter processing completion 10985 */ 10986 #ifdef BCM_SBUSDMA_SUPPORT 10987 while (_soc_counter_pending[unit] && soc->counter_interval) { 10988 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100); 10989 } 10990 #endif 10991 10992 COUNTER_LOCK(unit); 10993 #ifdef BCM_KATANA2_SUPPORT 10994 /* 10995 * We are looping twice to set the mc stats in case of packing mode 10996 */ 10997 for (j=0; j<2; j++) { 10998 if( j == 1) { 10999 if( SOC_IS_KATANA2(unit) && soc_feature(unit, 11000 soc_feature_mmu_packing) ) { 11001 rv = _soc_counter_katana2_get_mcindex(unit, port, ctr_reg, 11002 &port_index, &num_entries); 11003 if (SOC_FAILURE(rv)) { 11004 goto counter_set_done; 11005 } 11006 if(port_index == -1) { 11007 continue; 11008 } 11009 } 11010 else { 11011 continue; 11012 } 11013 } 11014 #else 11015 { 11016 #endif 11017 11018 for (index = index_min; index <= index_max; index++) { 11019 ctr_is_readonly = 0; 11020 #ifdef BCM_TRIUMPH3_SUPPORT 11021 skip_hw_set = 0; 11022 #endif 11023 #if defined(BCM_PETRA_SUPPORT) 11024 if (!_SOC_CONTROLLED_COUNTER_USE(unit, port)) { 11025 #endif 11026 if ((ctr_reg >= SOC_COUNTER_NON_DMA_START) && 11027 (ctr_reg < SOC_COUNTER_NON_DMA_END)) { 11028 non_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 11029 if (non_dma->flags & (_SOC_COUNTER_NON_DMA_PEAK | 11030 _SOC_COUNTER_NON_DMA_CURRENT)) { 11031 continue; 11032 } 11033 11034 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 11035 goto counter_set_done; 11036 } else if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) && 11037 (non_dma->extra_ctrs != NULL)) { 11038 goto counter_set_done; 11039 } 11040 11041 if (non_dma->mem != INVALIDm) { 11042 dma_mem = non_dma->dma_mem[0]; 11043 dma_base_index = port_index - non_dma->base_index + 11044 non_dma->dma_index_min[0]; 11045 #if defined (BCM_METROLITE_SUPPORT) 11046 if (SOC_IS_METROLITE(unit)) { 11047 numpipe = 1; 11048 } else 11049 #endif 11050 #ifdef BCM_SABER2_SUPPORT 11051 if ( SOC_IS_SABER2(unit) ) { 11052 soc_cm_get_id(unit, &dev_id, &rev_id); 11053 if (dev_id == BCM56233_DEVICE_ID) { 11054 numpipe = 1; 11055 } else { 11056 numpipe = 2; 11057 } 11058 } else 11059 #endif 11060 11061 #if defined (BCM_KATANA2_SUPPORT) 11062 if ( SOC_IS_KATANA2(unit) ) { 11063 numpipe = 4; 11064 } else 11065 #endif 11066 #if defined (BCM_KATANA_SUPPORT) 11067 if ( SOC_IS_KATANA(unit)) { 11068 numpipe = 4; 11069 soc_cm_get_id(unit, &dev_id, &rev_id); 11070 if ((dev_id == BCM56445_DEVICE_ID)|| (dev_id == BCM56446_DEVICE_ID)|| 11071 (dev_id == BCM56447_DEVICE_ID)|| (dev_id == BCM56448_DEVICE_ID)|| 11072 (dev_id == BCM55441_DEVICE_ID)) { 11073 numpipe = 1; 11074 } 11075 } else 11076 #endif 11077 { 11078 numpipe = SOC_INFO(unit).num_pipe; 11079 } 11080 for (i = 1; i < numpipe; i++) { 11081 if (non_dma->dma_mem[i] != INVALIDm && 11082 dma_base_index > non_dma->dma_index_max[i - 1]) { 11083 dma_mem = non_dma->dma_mem[i]; 11084 dma_base_index -= non_dma->dma_index_max[i - 1] + 1; 11085 dma_base_index += non_dma->dma_index_min[i]; 11086 } 11087 } 11088 11089 /* Need to retrieve the table index 11090 * for flexible mapping Non-DMA counter*/ 11091 if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) { 11092 if (non_dma->soc_counter_hw_idx_get == NULL) { 11093 continue; 11094 } 11095 rv = non_dma->soc_counter_hw_idx_get(unit, port, 11096 dma_base_index + index, &qindex); 11097 if (SOC_FAILURE(rv)) { 11098 goto counter_set_done; 11099 } 11100 if (-1 == qindex) { 11101 continue; 11102 } 11103 } else { 11104 qindex = dma_base_index + index; 11105 } 11106 11107 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, qindex, entry); 11108 if (SOC_FAILURE(rv)) { 11109 goto counter_set_done; 11110 } 11111 #ifdef BCM_KATANA_SUPPORT 11112 if ((SOC_IS_KATANA(unit)) && 11113 (!soc_feature(unit, soc_feature_counter_toggled_read))) { 11114 soc_mem_field_get(unit, dma_mem, entry, COUNTf, &pkt_count); 11115 if (!SAL_BOOT_BCMSIM) { 11116 if (pkt_count) { 11117 pkt_count -= 1; 11118 } 11119 } 11120 soc_mem_field_set(unit, dma_mem, entry, 11121 COUNTf, &pkt_count); 11122 11123 } 11124 #endif 11125 fval[0] = COMPILER_64_LO(val64); 11126 fval[1] = COMPILER_64_HI(val64); 11127 soc_mem_field_set(unit, dma_mem, entry, 11128 non_dma->field, fval); 11129 11130 /* 11131 * If parity is not enabled on the device 11132 * set the parity bit in the MMU_CTR_UC_DROP_MEMm 11133 * during counter set as suggested by DE. 11134 */ 11135 if (SOC_IS_TRIDENT(unit) || SOC_IS_TRIUMPH3(unit)) { 11136 uint32 rval = 0; 11137 if (dma_mem == MMU_CTR_UC_DROP_MEMm) { 11138 rv = READ_MISCCONFIGr(unit, &rval); 11139 if (SOC_SUCCESS(rv)) { 11140 if (!soc_reg_field_get(unit, MISCCONFIGr, 11141 rval, PARITY_GEN_ENf)) { 11142 soc_mem_field32_set(unit, dma_mem, entry, 11143 PARITYf, 0); 11144 if (COMPILER_64_IS_ZERO(val64)) { 11145 sal_memset(entry, 0, sizeof(entry)); 11146 } 11147 } 11148 } 11149 } 11150 } 11151 11152 rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL, qindex, entry); 11153 if (SOC_FAILURE(rv)) { 11154 goto counter_set_done; 11155 } 11156 11157 /* Check non-DMA counters (memory) is read-only or not */ 11158 if (soc_mem_flags(unit, dma_mem) & SOC_MEM_FLAG_READONLY) { 11159 ctr_is_readonly = 1; 11160 } 11161 } else if (non_dma->reg != INVALIDr) { 11162 if (port < 0) { 11163 rv = SOC_E_PARAM; 11164 goto counter_set_done; 11165 } 11166 11167 /* Check non-DMA counters (register) is read-only or not */ 11168 if (SOC_REG_INFO(unit, non_dma->reg).flags & SOC_REG_FLAG_RO) { 11169 ctr_is_readonly = 1; 11170 } 11171 11172 /* For Per port -> PBMP_MEMBER(non_dma->pbmp, port) is valid 11173 * and for system level counters it is invalid 11174 * For system level counters -> SOC_PBMP_IS_NULL is valid 11175 * and invalid for per port cases. 11176 */ 11177 if (PBMP_MEMBER(non_dma->pbmp, port) || 11178 (SOC_PBMP_IS_NULL(non_dma->pbmp) && 11179 (non_dma->num_entries == 1))) { 11180 uint64 regval64; 11181 uint32 regval32; 11182 int base_index = 0; 11183 11184 if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) { 11185 if (non_dma->reg == TXLLFCMSGCNTr) { 11186 if (!IS_HG_PORT( unit, port)) { 11187 continue; 11188 } 11189 } 11190 } 11191 11192 if (!ctr_is_readonly) { /* non-DMA counters (register) is not readonly */ 11193 rv = soc_reg_get(unit, non_dma->reg, 11194 port, index, ®val64); 11195 if (SOC_FAILURE(rv)) { 11196 goto counter_set_done; 11197 } 11198 11199 if (SOC_REG_IS_64(unit, non_dma->reg)) { 11200 soc_reg64_field_set(unit, non_dma->reg, ®val64, 11201 non_dma->field, val64); 11202 } else { 11203 regval32 = COMPILER_64_LO(regval64); 11204 soc_reg_field_set(unit, non_dma->reg, ®val32, 11205 non_dma->field, COMPILER_64_LO(val64)); 11206 COMPILER_64_SET(regval64, 0, regval32); 11207 } 11208 11209 rv = soc_reg_set(unit, non_dma->reg, 11210 port, index, regval64); 11211 if (SOC_FAILURE(rv)) { 11212 goto counter_set_done; 11213 } 11214 } else { /* non-DMA counters (register) is readonly */ 11215 if (soc_feature(unit, soc_feature_tas)) { 11216 if (ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS || 11217 ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT) { 11218 /* read-only register, only take value=0 to clear it */ 11219 if (!COMPILER_64_IS_ZERO(val64)) { 11220 rv = SOC_E_UNAVAIL; 11221 goto counter_set_done; 11222 } 11223 11224 /* 11225 * Both TAS_OVERRUN_PKT_CNT_EXPRESS/PREEMPT will be clear to 0 11226 * by set 1 to TAS_OVERRUN_CNT_CLRf. 11227 */ 11228 rv = soc_reg32_get(unit, TAS_GATE_PURGE_ENABLEr, 11229 port, index, ®val32); 11230 if (SOC_FAILURE(rv)) { 11231 goto counter_set_done; 11232 } 11233 11234 soc_reg_field_set(unit, TAS_GATE_PURGE_ENABLEr, ®val32, 11235 TAS_OVERRUN_CNT_CLRf, TRUE); 11236 11237 rv = soc_reg32_set(unit, TAS_GATE_PURGE_ENABLEr, 11238 port, index, regval32); 11239 if (SOC_FAILURE(rv)) { 11240 goto counter_set_done; 11241 } 11242 11243 if (ctr_reg == SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS) { 11244 /* 11245 * Also need to clear software based counter value bufs 11246 * sw_val/hw_val/delta for PREEMPT 11247 */ 11248 rv = _soc_counter_get_info( 11249 unit, port, 11250 SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_PREEMPT, 11251 &base_index, &num_entries, NULL); 11252 } else { 11253 /* 11254 * Also need to clear software based counter value bufs 11255 * sw_val/hw_val/delta for EXPRESS 11256 */ 11257 rv = _soc_counter_get_info( 11258 unit, port, 11259 SOC_COUNTER_NON_DMA_TAS_TXOVERRUN_EXPRESS, 11260 &base_index, &num_entries, NULL); 11261 } 11262 11263 if (SOC_FAILURE(rv)) { 11264 goto counter_set_done; 11265 } 11266 11267 /* The following section updates 64-bit values and must be atomic */ 11268 COUNTER_ATOMIC_BEGIN(s); 11269 soc->counter_sw_val[base_index + index] = val64; 11270 soc->counter_hw_val[base_index + index] = val64; 11271 COMPILER_64_SET(soc->counter_delta[base_index + index], 0, 0); 11272 COUNTER_ATOMIC_END(s); 11273 11274 /* need to clear soc->counter_hw_val to match the hardware value */ 11275 ctr_is_readonly = 0; 11276 } 11277 } 11278 } 11279 } 11280 } 11281 } else if (ctr_reg != INVALIDr) { 11282 if (port < 0) { 11283 rv = SOC_E_PARAM; 11284 goto counter_set_done; 11285 } 11286 11287 #ifdef BCM_TRIUMPH3_SUPPORT 11288 if (SOC_IS_TRIUMPH3(unit) && (IS_HG_PORT(unit, port)) 11289 && ((ctr_reg == RRPKTr) || (ctr_reg == RRBYTr)) ) { 11290 skip_hw_set = 1; 11291 ctr_is_readonly = 1; 11292 } 11293 #endif 11294 11295 #ifdef SOC_COUNTER_TABLE_SUPPORT 11296 if (SOC_REG_IS_COUNTER_TABLE (unit, ctr_reg)) { 11297 if (SOC_IS_TOMAHAWK3(unit)) { 11298 soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL; 11299 SOC_IF_ERROR_RETURN 11300 (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry)); 11301 SOC_IF_ERROR_RETURN 11302 (_soc_ctr_tbl_field_set(unit, ctr_reg, port, ctr_tbl_info_entry, &val64)); 11303 } else { 11304 return SOC_E_PARAM; 11305 } 11306 } 11307 else 11308 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 11309 if (!(SOC_REG_INFO(unit, ctr_reg).flags & SOC_REG_FLAG_64_BITS) && 11310 !SOC_IS_XGS3_SWITCH(unit)) { 11311 val32 = COMPILER_64_LO(val64); 11312 rv = soc_reg32_set(unit, ctr_reg, port, index, val32); 11313 if (SOC_FAILURE(rv)) { 11314 goto counter_set_done; 11315 } 11316 } else { 11317 if (soc_feature(unit, soc_feature_prime_ctr_writes) && 11318 /*SOC_REG_INFO(unit, ctr_reg).block == SOC_BLK_EGR) {*/ 11319 SOC_BLOCK_IS(SOC_REG_INFO(unit, ctr_reg).block, SOC_BLK_EGR)) { 11320 prime_ctr_write = TRUE; 11321 } else { 11322 prime_ctr_write = FALSE; 11323 } 11324 11325 if (prime_ctr_write) { 11326 rv = soc_reg32_get(unit, ctr_reg, port, index, &val32); 11327 if (SOC_FAILURE(rv)) { 11328 goto counter_set_done; 11329 } 11330 } 11331 #ifdef BCM_TRIUMPH3_SUPPORT 11332 if (!skip_hw_set) { 11333 #else 11334 { 11335 #endif 11336 rv = soc_reg_set(unit, ctr_reg, port, index, val64); 11337 if (SOC_FAILURE(rv)) { 11338 goto counter_set_done; 11339 } 11340 } 11341 if (prime_ctr_write) { 11342 rv = soc_reg32_get(unit, ctr_reg, port, index, &val32); 11343 if (SOC_FAILURE(rv)) { 11344 goto counter_set_done; 11345 } 11346 } 11347 } 11348 11349 /* Check DMA counters (register) is read-only or not */ 11350 if (SOC_REG_IS_VALID(unit, ctr_reg) && 11351 SOC_REG_INFO(unit, ctr_reg).flags & SOC_REG_FLAG_RO) { 11352 ctr_is_readonly = 1; 11353 } 11354 } 11355 #if defined(BCM_PETRA_SUPPORT) 11356 } 11357 #endif 11358 /* The following section updates 64-bit values and must be atomic */ 11359 COUNTER_ATOMIC_BEGIN(s); 11360 soc->counter_sw_val[port_index + index] = val64; 11361 /* 11362 * It checks if the counter is read-only. If so, only the soc->counter_sw_val is set and 11363 * soc->counter_hw_val is left untouched to match the hardware value. 11364 */ 11365 if (!ctr_is_readonly) { 11366 soc->counter_hw_val[port_index + index] = val64; 11367 } 11368 COMPILER_64_SET(soc->counter_delta[port_index + index], 0, 0); 11369 COUNTER_ATOMIC_END(s); 11370 /* 11371 * For counter sync operation update the dma buffer 11372 * for the port index with the value read from hardware 11373 * counter register. 11374 */ 11375 if ((ctr_reg != INVALIDr) && 11376 (!SOC_COUNTER_INVALID(unit, ctr_reg)) && 11377 (soc->counter_flags & SOC_COUNTER_F_DMA)) { 11378 int ctr_idx; 11379 uint32 *ptr; 11380 int port_base_dma, port_base; 11381 int port_index, num_entries; 11382 char *cname; 11383 11384 /* get index of counter register */ 11385 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, ctr_reg, 11386 &port_index, 11387 &num_entries, 11388 &cname)); 11389 port_base = COUNTER_MIN_IDX_GET(unit, port); 11390 port_base_dma = COUNTER_MIN_IDX_GET(unit, 11391 port - soc->counter_ports32); 11392 ctr_idx = port_index - port_base; 11393 #ifdef BCM_SBUSDMA_SUPPORT 11394 if (soc_feature(unit, soc_feature_sbusdma) && 11395 (ctr_reg < NUM_SOC_REG) && 11396 !SOC_REG_IS_64(unit, ctr_reg)) { 11397 uint32 *buf32 ; 11398 if (SOC_IS_TOMAHAWKX(unit)) { 11399 if (ctr_idx < soc->counter_egr_first) { 11400 buf32 = (uint32 *)&soc->counter_buf64[ 11401 port_base_dma + 11402 soc->counter_ing_first]; 11403 ptr = &buf32[ctr_idx - soc->counter_ing_first]; 11404 } else { 11405 buf32 = (uint32 *)&soc->counter_buf64[ 11406 port_base_dma + 11407 soc->counter_egr_first]; 11408 ptr = &buf32[ctr_idx - soc->counter_egr_first]; 11409 } 11410 } else { 11411 if (ctr_idx < soc->counter_egr_first) { 11412 buf32 = (uint32 *)&soc->counter_buf64[ 11413 port_base_dma + 11414 soc->counter_ing_first]; 11415 ptr = &buf32[ctr_idx - soc->counter_ing_first]; 11416 } else if (ctr_idx < soc->counter_mac_first) { 11417 buf32 = (uint32 *)&soc->counter_buf64[ 11418 port_base_dma + 11419 soc->counter_egr_first]; 11420 ptr = &buf32[ctr_idx - soc->counter_egr_first]; 11421 } else { 11422 buf32 = (uint32 *)&soc->counter_buf64[ 11423 port_base_dma + 11424 soc->counter_mac_first]; 11425 ptr = &buf32[ctr_idx - soc->counter_mac_first]; 11426 } 11427 } 11428 COUNTER_ATOMIC_BEGIN(s); 11429 if (soc_reg_field_length( 11430 unit, ctr_reg, COUNTf) == 32) { 11431 COMPILER_64_TO_32_LO(ptr[0], val64); 11432 } else { 11433 ptr[0] = COMPILER_64_LO(val64) & 11434 ((1 << soc_reg_field_length 11435 (unit, ctr_reg, COUNTf)) - 1); 11436 } 11437 COUNTER_ATOMIC_END(s); 11438 } else 11439 #endif /* BCM_SBUSDMA_SUPPORT */ 11440 { 11441 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + ctr_idx]; 11442 if (SOC_IS_TOMAHAWK3(unit) && 11443 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg) && 11444 soc->counter_mib_tbl_first > 0) { 11445 /* For counter tables, dma_offset is obtained from SOC_CTR_TBL_INFO */ 11446 int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[ctr_idx - soc->counter_mib_tbl_first].dma_offset; 11447 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset]; 11448 } 11449 COUNTER_ATOMIC_BEGIN(s); 11450 /* Update the DMA location */ 11451 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 11452 COMPILER_64_TO_32_HI(ptr[0], val64); 11453 COMPILER_64_TO_32_LO(ptr[1], val64); 11454 } else { 11455 COMPILER_64_TO_32_LO(ptr[0], val64); 11456 COMPILER_64_TO_32_HI(ptr[1], val64); 11457 } 11458 COUNTER_ATOMIC_END(s); 11459 } 11460 }/* ctr_reg != INVALIDr */ 11461 } 11462 } 11463 counter_set_done: 11464 COUNTER_UNLOCK(unit); 11465 return rv; 11466 } 11467 11468 int 11469 soc_counter_set(int unit, soc_port_t port, soc_reg_t ctr_reg, 11470 int ar_idx, uint64 val) 11471 { 11472 return _soc_counter_set(unit, port, ctr_reg, ar_idx, val); 11473 } 11474 11475 int 11476 soc_counter_set32(int unit, soc_port_t port, soc_reg_t ctr_reg, 11477 int ar_idx, uint32 val) 11478 { 11479 uint64 val64; 11480 11481 COMPILER_64_SET(val64, 0, val); 11482 11483 return _soc_counter_set(unit, port, ctr_reg, ar_idx, val64); 11484 } 11485 11486 STATIC int 11487 _soc_counter_generic_set(int unit, soc_ctr_control_info_t ctrl_info, soc_reg_t id, 11488 int ar_idx, uint64 val) 11489 { 11490 soc_control_t *soc = SOC_CONTROL(unit); 11491 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 11492 int base_index, base_index_temp, num_entries, 11493 entries_per_pipe = 0; 11494 int index_min, index_max, index; 11495 soc_counter_non_dma_t *non_dma; 11496 uint32 entry[SOC_MAX_MEM_FIELD_WORDS], fval[2]; 11497 int dma_base_index = 0; 11498 soc_mem_t dma_mem; 11499 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 11500 int rv = SOC_E_NONE; 11501 int prime_ctr_write, i; 11502 uint32 val32; 11503 soc_port_t port = -1 ; 11504 int subset_ct = 0, pipe = 0, pipe_start = 0, pipe_end = 0, all_pipe = 0; 11505 uint8 clear_on_read = 0; 11506 int field_len = 0; 11507 uint64 masked_val; 11508 #ifdef BCM_TOMAHAWK3_SUPPORT 11509 uint16 dev_id; 11510 uint8 rev_id; 11511 11512 soc_cm_get_id(unit, &dev_id, &rev_id); 11513 #endif 11514 COMPILER_64_ZERO(masked_val); 11515 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) { 11516 port = ctrl_info.instance; 11517 #ifdef BCM_TOMAHAWK3_SUPPORT 11518 if (SOC_IS_TOMAHAWK3(unit) && 11519 SOC_CONTROL(unit)->em_halfchip == 1) { 11520 pipe = SOC_INFO(unit).port_pipe[port]; 11521 if (pipe == 2 || pipe == 3 || pipe == 4 || pipe == 5) { 11522 return SOC_E_PARAM; 11523 } 11524 } 11525 #endif 11526 } 11527 11528 SOC_IF_ERROR_RETURN 11529 (soc_counter_generic_get_info(unit, ctrl_info, id, 11530 &base_index, &num_entries)); 11531 base_index_temp = base_index; 11532 11533 if ((ar_idx >= num_entries) || (ar_idx < -1)) { 11534 return SOC_E_PARAM; 11535 } 11536 11537 if (ar_idx == -1) { 11538 index_min = 0; 11539 index_max = num_entries - 1; 11540 } else { 11541 index_min = index_max = ar_idx; 11542 } 11543 11544 COUNTER_LOCK(unit); 11545 for (index = index_min; index <= index_max; index++) { 11546 if (id >= NUM_SOC_REG) { 11547 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 11548 if (non_dma->flags & (_SOC_COUNTER_NON_DMA_PEAK | 11549 _SOC_COUNTER_NON_DMA_CURRENT)) { 11550 continue; 11551 } 11552 11553 /* To iterate across pipes */ 11554 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE) { 11555 pipe = ctrl_info.instance & 0xF; 11556 if (pipe == -1) { 11557 all_pipe = 1; 11558 } else if (pipe >= NUM_PIPE(unit)) { 11559 return SOC_E_PARAM; 11560 } 11561 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) { 11562 all_pipe = 1; 11563 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) { 11564 pipe = ctrl_info.instance; 11565 if (pipe == -1) { 11566 all_pipe = 1; 11567 } else if (pipe >= NUM_PIPE(unit)) { 11568 return SOC_E_PARAM; 11569 } 11570 11571 entries_per_pipe = num_entries; 11572 } 11573 11574 if (all_pipe == 1) { 11575 pipe_start = 0; 11576 pipe_end = NUM_PIPE(unit) - 1; 11577 } else { 11578 pipe_start = pipe_end = pipe; 11579 } 11580 11581 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && 11582 !(non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT)) { 11583 goto counter_set_done; 11584 } else if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) && 11585 (non_dma->extra_ctrs != NULL)) { 11586 /* If there is subset of counters, use subset info for DMA */ 11587 non_dma = non_dma->extra_ctrs; 11588 11589 if ((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) || 11590 (ctrl_info.instance_type == 11591 SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) { 11592 /* Decoding for POOL_PIPE and multiply by 2 for 11593 * parent-child model */ 11594 entries_per_pipe = num_entries; 11595 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_POOL) { 11596 subset_ct = ctrl_info.instance << 1; 11597 } else { 11598 subset_ct = (ctrl_info.instance & 0x3F0) >> 3; 11599 } 11600 } else if (ctrl_info.instance_type == 11601 SOC_CTR_INSTANCE_TYPE_ITM_PORT) { 11602 subset_ct = 11603 (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >> 11604 CTR_INSTANCE_BIT_SHIFT_ITM; 11605 entries_per_pipe = non_dma->num_entries; 11606 } else if (ctrl_info.instance_type == 11607 SOC_CTR_INSTANCE_TYPE_XPE_PORT) { 11608 /* Decoding for XPE_PORT and multiply by 2 for parent-child 11609 * model */ 11610 subset_ct = (ctrl_info.instance & 0x3C00) >> 9; 11611 if ((non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) { 11612 if (SOC_IS_TRIDENT3(unit)) { 11613 entries_per_pipe = non_dma->num_entries / 2; 11614 } else { 11615 entries_per_pipe = non_dma->num_entries; 11616 } 11617 } else { 11618 if (SOC_IS_HELIX5(unit) || SOC_IS_MAVERICK2(unit)) { 11619 entries_per_pipe = non_dma->num_entries; 11620 } else { 11621 entries_per_pipe = non_dma->num_entries / 2; 11622 } 11623 } 11624 } else if (ctrl_info.instance_type == 11625 SOC_CTR_INSTANCE_TYPE_SFLOW) { 11626 subset_ct = ctrl_info.instance << 1; 11627 entries_per_pipe = non_dma->num_entries; 11628 } else if (ctrl_info.instance_type == 11629 SOC_CTR_INSTANCE_TYPE_FT_GROUP) { 11630 subset_ct = ctrl_info.instance << 1; 11631 entries_per_pipe = non_dma->num_entries; 11632 11633 } else 11634 #ifdef BCM_APACHE_SUPPORT 11635 if (SOC_IS_APACHE(unit) && 11636 (ctrl_info.instance_type == 11637 SOC_CTR_INSTANCE_TYPE_PORT)) { 11638 int obm_id, lane; 11639 SOC_IF_ERROR_RETURN 11640 (soc_apache_port_obm_info_get(unit, port, 11641 &obm_id, &lane)); 11642 entries_per_pipe = non_dma->num_entries; 11643 subset_ct = (obm_id << 1); 11644 } else 11645 #endif 11646 { 11647 entries_per_pipe = non_dma->num_entries; 11648 if (non_dma->mem != INVALIDm) { 11649 entries_per_pipe = 11650 soc_mem_index_count(unit, non_dma->dma_mem[0]); 11651 } 11652 } 11653 non_dma = non_dma + subset_ct; 11654 11655 if (!non_dma || 11656 !(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 11657 goto counter_set_done; 11658 } 11659 } else { 11660 if (non_dma->mem != INVALIDm) { 11661 if ((non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) && 11662 SOC_IS_TRIDENT3X(unit)) { 11663 entries_per_pipe = (non_dma->num_entries)/2; 11664 } else { 11665 entries_per_pipe = 11666 soc_mem_index_count(unit, non_dma->dma_mem[0]); 11667 } 11668 } else { 11669 entries_per_pipe = non_dma->num_entries; 11670 } 11671 } 11672 11673 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ) { 11674 clear_on_read = 1; 11675 } 11676 if (non_dma->mem != INVALIDm) { 11677 /* If CLR_ON_READ is enabled for the Counter, perform only 11678 * Software updation. 11679 */ 11680 /* Iterate across pipes for POOL and PIPE = -1 case */ 11681 11682 field_len = soc_mem_field_length(unit, non_dma->mem, 11683 non_dma->field); 11684 if (field_len < 32) { 11685 COMPILER_64_SET(masked_val, 0, ((1 << field_len) - 1)); 11686 COMPILER_64_AND(masked_val, val); 11687 } else { 11688 COMPILER_64_SET(masked_val, ((1 << (field_len - 32)) - 1), 11689 0xffffffff); 11690 COMPILER_64_AND(masked_val, val); 11691 } 11692 if (all_pipe) { 11693 dma_base_index = base_index; 11694 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 11695 /* Skip if no enabled ports in pipe */ 11696 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 11697 continue; 11698 } 11699 dma_mem = non_dma->dma_mem[pipe]; 11700 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 11701 index, entry); 11702 if (SOC_FAILURE(rv)) { 11703 goto counter_set_done; 11704 } 11705 11706 if (clear_on_read) { 11707 /* Intent is to set All pipe value to 0. 11708 * Since Clear on read is true, reading clears the 11709 * values in Hardware. 11710 * Optimization - to not set the value to zero again. 11711 */ 11712 continue; 11713 } 11714 if (pipe == 0) { 11715 fval[0] = COMPILER_64_LO(masked_val); 11716 fval[1] = COMPILER_64_HI(masked_val); 11717 } else { 11718 fval[0] = 0; 11719 fval[1] = 0; 11720 } 11721 soc_mem_field_set(unit, dma_mem, entry, 11722 non_dma->field, fval); 11723 11724 rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL, 11725 index, entry); 11726 if (SOC_FAILURE(rv)) { 11727 goto counter_set_done; 11728 } 11729 11730 if(non_dma->dma_num_entries[pipe] != 0) { 11731 base_index += non_dma->dma_num_entries[pipe]; 11732 } else { 11733 base_index += entries_per_pipe; 11734 } 11735 } 11736 base_index = base_index_temp; 11737 } else { 11738 int pipe_offset = 0; 11739 dma_mem = non_dma->dma_mem[0]; 11740 base_index = base_index_temp; 11741 11742 for (i = 0; i < NUM_PIPE(unit); i++) { 11743 if (non_dma->dma_mem[i] != INVALIDm) { 11744 dma_mem = non_dma->dma_mem[i]; 11745 dma_base_index = base_index - non_dma->base_index; 11746 pipe_offset = dma_base_index / entries_per_pipe; 11747 11748 if (non_dma->dma_index_min[i]) { 11749 dma_base_index += non_dma->dma_index_min[i]; 11750 } 11751 break; 11752 } 11753 } 11754 if (pipe_offset) { 11755 for (; i < NUM_PIPE(unit); i++) { 11756 if (non_dma->dma_mem[i] != INVALIDm) { 11757 /* Choose the appropriate index where pipes are 11758 * applicable. In XPE case, each XPE is valid 11759 * for only pair of pipes(and can have holes in 11760 * between. 11761 */ 11762 if (pipe_offset) { 11763 pipe_offset--; 11764 continue; 11765 } else { 11766 break; 11767 } 11768 } 11769 } 11770 i %= NUM_PIPE(unit); 11771 dma_mem = non_dma->dma_mem[i]; 11772 dma_base_index = (dma_base_index % entries_per_pipe) + 11773 non_dma->dma_index_min[i]; 11774 } 11775 11776 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 11777 dma_base_index + index, entry); 11778 if (SOC_FAILURE(rv)) { 11779 goto counter_set_done; 11780 } 11781 11782 if (!clear_on_read) { 11783 /* Set Hardware only when Clear On Read is False. 11784 * Else Hardware will be cleared by Read operation 11785 * above. 11786 */ 11787 fval[0] = COMPILER_64_LO(masked_val); 11788 fval[1] = COMPILER_64_HI(masked_val); 11789 soc_mem_field_set(unit, dma_mem, entry, 11790 non_dma->field, fval); 11791 11792 /* 11793 * If parity is not enabled on the device 11794 * set the parity bit in the MMU_CTR_UC_DROP_MEMm 11795 * during counter set as suggested by DE. 11796 */ 11797 11798 rv = soc_mem_write(unit, dma_mem, MEM_BLOCK_ALL, 11799 dma_base_index + index, entry); 11800 if (SOC_FAILURE(rv)) { 11801 goto counter_set_done; 11802 } 11803 } 11804 } 11805 } else if (non_dma->reg != INVALIDr) { 11806 if (ctrl_info.instance_type == 11807 SOC_CTR_INSTANCE_TYPE_ITM_PORT) { 11808 port = 11809 (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >> 11810 CTR_INSTANCE_BIT_SHIFT_ITM; 11811 /* port means ITM instance# but not used here, where 11812 base_index already reflect the ITM# offset */ 11813 entries_per_pipe = 0; 11814 pipe_start = 0; 11815 pipe_end = 0; 11816 base_index = base_index_temp; 11817 } 11818 if (port < 0) { 11819 rv = SOC_E_PARAM; 11820 goto counter_set_done; 11821 } 11822 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_OBM) && 11823 (soc_ctr_ctrl->port_obm_info_get)) { 11824 /* Set for OBM based counters. 11825 * Lossy_Lo, Lossy_Hi, Lossless0, Lossless1 11826 */ 11827 uint64 regval64; 11828 uint32 regval32; 11829 int obm_id = 0, lane = 0; 11830 soc_reg_t reg = INVALIDr; 11831 soc_info_t *si = &SOC_INFO(unit);; 11832 11833 rv = soc_ctr_ctrl->port_obm_info_get(unit, port, 11834 &obm_id, &lane); 11835 if (SOC_FAILURE(rv)) { 11836 goto counter_set_done; 11837 } 11838 #ifdef BCM_APACHE_SUPPORT 11839 if (SOC_IS_APACHE(unit)) { 11840 int pgw_inst = 0; 11841 11842 _soc_counter_apache_get_pgw_inst(unit, port, &pgw_inst, &lane); 11843 rv = soc_reg_get(unit, non_dma->reg, 11844 pgw_inst, lane, ®val64); 11845 if (SOC_FAILURE(rv)) { 11846 goto counter_set_done; 11847 } 11848 if (SOC_REG_IS_64(unit, non_dma->reg)) { 11849 soc_reg64_field_set(unit, non_dma->reg, ®val64, 11850 non_dma->field, val); 11851 } else { 11852 regval32 = COMPILER_64_LO(regval64); 11853 soc_reg_field_set(unit, non_dma->reg, ®val32, 11854 non_dma->field, COMPILER_64_LO(val)); 11855 COMPILER_64_SET(regval64, 0, regval32); 11856 } 11857 rv = soc_reg_set(unit, non_dma->reg, 11858 pgw_inst, lane, regval64); 11859 11860 } else 11861 #endif 11862 { 11863 pipe = si->port_pipe[port]; 11864 if (obm_id) { 11865 subset_ct = obm_id << 1; 11866 non_dma = non_dma + subset_ct; 11867 } 11868 11869 reg = SOC_REG_UNIQUE_ACC(unit, non_dma->reg)[pipe]; 11870 rv = soc_reg_get(unit, reg, pipe, lane, ®val64); 11871 if (SOC_FAILURE(rv)) { 11872 goto counter_set_done; 11873 } 11874 11875 if (SOC_REG_IS_64(unit, non_dma->reg)) { 11876 soc_reg64_field_set(unit, non_dma->reg, ®val64, 11877 non_dma->field, val); 11878 } else { 11879 regval32 = COMPILER_64_LO(regval64); 11880 soc_reg_field_set(unit, non_dma->reg, ®val32, 11881 non_dma->field, COMPILER_64_LO(val)); 11882 COMPILER_64_SET(regval64, 0, regval32); 11883 } 11884 11885 rv = soc_reg_set(unit, reg, pipe, lane, regval64); 11886 if (SOC_FAILURE(rv)) { 11887 goto counter_set_done; 11888 } 11889 } 11890 } else { 11891 if (PBMP_MEMBER(non_dma->pbmp, port)) { 11892 uint64 regval64; 11893 uint32 regval32; 11894 11895 rv = soc_reg_get(unit, non_dma->reg, 11896 port, index, ®val64); 11897 if (SOC_FAILURE(rv)) { 11898 goto counter_set_done; 11899 } 11900 if (SOC_REG_IS_64(unit, non_dma->reg)) { 11901 soc_reg64_field_set(unit, non_dma->reg, ®val64, 11902 non_dma->field, val); 11903 } else { 11904 regval32 = COMPILER_64_LO(regval64); 11905 soc_reg_field_set(unit, non_dma->reg, ®val32, 11906 non_dma->field, COMPILER_64_LO(val)); 11907 COMPILER_64_SET(regval64, 0, regval32); 11908 } 11909 rv = soc_reg_set(unit, non_dma->reg, 11910 port, index, regval64); 11911 if (SOC_FAILURE(rv)) { 11912 goto counter_set_done; 11913 } 11914 } 11915 } 11916 } 11917 } else { 11918 if (port < 0) { 11919 rv = SOC_E_PARAM; 11920 goto counter_set_done; 11921 } 11922 11923 if (!(SOC_REG_INFO(unit, id).flags & SOC_REG_FLAG_64_BITS) && 11924 !SOC_IS_XGS3_SWITCH(unit)) { 11925 val32 = COMPILER_64_LO(val); 11926 rv = soc_reg32_set(unit, id, port, index, val32); 11927 if (SOC_FAILURE(rv)) { 11928 goto counter_set_done; 11929 } 11930 } else { 11931 if (soc_feature(unit, soc_feature_prime_ctr_writes) && 11932 /*SOC_REG_INFO(unit, id).block == SOC_BLK_EGR) */ 11933 SOC_BLOCK_IS(SOC_REG_INFO(unit, id).block, SOC_BLK_EGR)) { 11934 prime_ctr_write = TRUE; 11935 } else { 11936 prime_ctr_write = FALSE; 11937 } 11938 11939 if (prime_ctr_write) { 11940 rv = soc_reg32_get(unit, id, port, index, &val32); 11941 if (SOC_FAILURE(rv)) { 11942 goto counter_set_done; 11943 } 11944 } 11945 rv = soc_reg_set(unit, id, port, index, val); 11946 if (SOC_FAILURE(rv)) { 11947 goto counter_set_done; 11948 } 11949 if (prime_ctr_write) { 11950 rv = soc_reg32_get(unit, id, port, index, &val32); 11951 if (SOC_FAILURE(rv)) { 11952 goto counter_set_done; 11953 } 11954 } 11955 } 11956 } 11957 11958 for (pipe = pipe_start; pipe <= pipe_end; pipe++) { 11959 /* The following section updates 64-bit values and must be atomic */ 11960 COUNTER_ATOMIC_BEGIN(s); 11961 soc->counter_sw_val[base_index + index] = val; 11962 soc->counter_hw_val[base_index + index] = val; 11963 COMPILER_64_SET(soc->counter_delta[base_index + index], 0, 0); 11964 COUNTER_ATOMIC_END(s); 11965 base_index += entries_per_pipe; 11966 11967 /* When Set is called with value with Pipe = -1 11968 * Set given value for Pipe 0 and set other pipe values to 0 11969 */ 11970 if (all_pipe) { 11971 COMPILER_64_SET(val, 0, 0); 11972 } 11973 } 11974 } 11975 11976 counter_set_done: 11977 COUNTER_UNLOCK(unit); 11978 return rv; 11979 11980 } 11981 11982 /* 11983 * Function: 11984 * soc_counter_generic_set 11985 * Purpose: 11986 * Given a counter register number, instance type, instance and a counter 11987 * value, set both the hardware and software-accumulated counters to the 11988 * value. 11989 * Parameters: 11990 * unit - StrataSwitch unit #. 11991 * ctrl_info - Counter Control Info Structure. 11992 * Contains the instance type and instance. 11993 * id - counter register id to set. 11994 * val - 64 bit counter value. 11995 * Returns: 11996 * SOC_E_XXX 11997 * Notes: 11998 * Currently supported instance types are 11999 * 1. SOC_CTR_INSTANCE_TYPE_PORT 12000 * 2. SOC_CTR_INSTANCE_TYPE_POOL 12001 * 3. SOC_CTR_INSTANCE_TYPE_PIPE 12002 */ 12003 int 12004 soc_counter_generic_set(int unit, soc_reg_t id, 12005 soc_ctr_control_info_t ctrl_info, uint32 flags, 12006 int ar_idx, uint64 val) 12007 { 12008 int xpe,i,port,pipe,rv=0; 12009 soc_ctr_control_info_t input_ctrl_info[2], output_ctrl_info; 12010 soc_info_t *si = &SOC_INFO(unit); 12011 soc_control_t *soc = SOC_CONTROL(unit); 12012 soc_mem_t mem = INVALIDm; 12013 #ifdef BCM_TOMAHAWK3_SUPPORT 12014 uint16 dev_id; 12015 uint8 rev_id; 12016 #endif 12017 if (id < SOC_COUNTER_NON_DMA_START || 12018 id >= SOC_COUNTER_NON_DMA_END) { 12019 return SOC_E_PARAM; 12020 } 12021 12022 if (soc->counter_non_dma == NULL) { 12023 return SOC_E_RESOURCE; 12024 } 12025 12026 if (!(soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START].flags)) { 12027 return SOC_E_UNAVAIL; 12028 } 12029 mem = soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START].mem; 12030 if ((ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) && 12031 (ctrl_info.instance == -1)) { 12032 for (i = 0; i < NUM_PIPE(unit) ; i++) { 12033 #ifdef BCM_TOMAHAWK3_SUPPORT 12034 if (SOC_PBMP_IS_NULL(si->pipe_pbm[i])) { 12035 continue; 12036 } 12037 #endif 12038 ctrl_info.instance = i; 12039 rv = _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val); 12040 if (rv < 0) { 12041 return rv; 12042 } 12043 } 12044 } 12045 12046 #ifdef BCM_TOMAHAWK3_SUPPORT 12047 soc_cm_get_id(unit, &dev_id, &rev_id); 12048 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM) { 12049 uint64 setval[2]; 12050 int setval_iterate = 0, itm; 12051 port = ctrl_info.instance; 12052 pipe = si->port_pipe[port]; 12053 12054 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 12055 input_ctrl_info[1].instance = ctrl_info.instance; 12056 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 12057 12058 if ((NUM_ITM(unit) == 1) || (dev_id == BCM56983_DEVICE_ID)) { 12059 COMPILER_64_COPY(setval[0], val); 12060 } else { 12061 _soc_distribute_u64(val, &setval[0], &setval[1]); 12062 } 12063 12064 for (itm = 0; itm < NUM_ITM(unit) ; itm++) { 12065 if (itm == 1 && (dev_id == BCM56983_DEVICE_ID)) { 12066 continue; 12067 } 12068 input_ctrl_info[0].instance = itm; 12069 12070 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 12071 rv = _soc_counter_generic_set(unit, output_ctrl_info, id, 12072 ar_idx, setval[setval_iterate]); 12073 setval_iterate++; 12074 if (rv != SOC_E_NONE) { 12075 break; 12076 } 12077 } 12078 12079 return rv; 12080 } 12081 #endif /* BCM_TOMAHAWK3_SUPPORT */ 12082 12083 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE) { 12084 uint64 setval[2]; 12085 int setval_iterate = 0; 12086 port = ctrl_info.instance; 12087 pipe = si->port_pipe[port]; 12088 input_ctrl_info[0].instance_type = ctrl_info.instance_type; 12089 input_ctrl_info[1].instance = ctrl_info.instance; 12090 input_ctrl_info[1].instance_type = SOC_CTR_INSTANCE_TYPE_PORT; 12091 if (NUM_XPE(unit) == 1) { 12092 COMPILER_64_COPY(setval[0], val); 12093 } else { 12094 _soc_distribute_u64(val, &setval[0], &setval[1]); 12095 } 12096 12097 for (xpe = 0; xpe < NUM_XPE(unit) ; xpe++) { 12098 input_ctrl_info[0].instance = xpe; 12099 if ((mem == MMU_CTR_COLOR_DROP_MEMm) && !SOC_IS_TOMAHAWK2(unit)) { 12100 if(!((si->epipe_xpe_map[pipe] >> xpe) & 1)) { 12101 continue; 12102 } 12103 12104 } else { 12105 if (SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit,mem,xpe,pipe) == INVALIDm) { 12106 /* Invalid XPE/Pipe Combination */ 12107 continue; 12108 } 12109 } 12110 soc_counter_instance_encode(input_ctrl_info,2,&output_ctrl_info); 12111 rv = _soc_counter_generic_set(unit, output_ctrl_info, id, 12112 ar_idx, setval[setval_iterate] ); 12113 setval_iterate++; 12114 if (rv < 0) { 12115 return rv; 12116 } 12117 } 12118 return rv; 12119 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_SFLOW && 12120 ctrl_info.instance == -1) { 12121 for (i = 0; i < SOC_SFLOW_CTR_TYPE_COUNT ; i++) { 12122 ctrl_info.instance = i; 12123 rv = _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val); 12124 if (rv < 0) { 12125 return rv; 12126 } 12127 } 12128 return rv; 12129 } else { 12130 return _soc_counter_generic_set(unit, ctrl_info, id, ar_idx, val); 12131 } 12132 } 12133 12134 /* Function: 12135 * soc_counter_generic_multi_set 12136 * Purpose: 12137 * Given a counter register number, count, instance type, instance and 12138 * array of values, set multiple hardware and software-accumulated counter 12139 * values to values specified in input val array. 12140 * Parameter: 12141 * unit - StrataSwitch Unit #. 12142 * ctr_reg - Counter Register to retrieve. 12143 * ctrl_info - Counter Control Info Structure 12144 * Contains the instance type and instance. 12145 * flags - not yet implemented. 12146 * ar_idx - Base index of counter to be set. 12147 * count - Number of consecutive entries to be set. 12148 * val - Base address of array holding the values to be set in 12149 * counters. 12150 *Returns: 12151 * SOC_E_XXX 12152 *Notes: 12153 * If count is set to 0, nothing is set. 12154 */ 12155 int 12156 soc_counter_generic_multi_set(int unit, soc_reg_t ctr_reg, 12157 soc_ctr_control_info_t ctrl_info, 12158 uint32 flags, int ar_idx, int count, 12159 uint64 *val) 12160 { 12161 int i; 12162 int rv = SOC_E_NONE; 12163 soc_control_t *soc = SOC_CONTROL(unit); 12164 12165 if (count < 0) { 12166 return SOC_E_PARAM; 12167 } 12168 12169 if (soc->counter_non_dma == NULL) { 12170 return SOC_E_RESOURCE; 12171 } 12172 12173 for (i = 0; i<count; i++) { 12174 rv = _soc_counter_generic_set(unit, ctrl_info, ctr_reg, (ar_idx+i), 12175 val[i]); 12176 if (rv!=SOC_E_NONE) { 12177 return rv; 12178 } 12179 } 12180 return rv; 12181 } 12182 12183 STATIC int 12184 _soc_counter_non_dma_is_invalid(int unit, soc_reg_t reg, soc_port_t port) 12185 { 12186 int pgw_index = -1, xlp = 0, xlp_index, blk; 12187 12188 switch (reg) { 12189 case PGW_OBM0_HIGH_PRI_PKT_DROPr: 12190 case PGW_OBM0_LOW_PRI_PKT_DROPr: 12191 case PGW_OBM0_HIGH_PRI_BYTE_DROPr: 12192 case PGW_OBM0_LOW_PRI_BYTE_DROPr: 12193 xlp = 0; 12194 break; 12195 case PGW_OBM1_HIGH_PRI_PKT_DROPr: 12196 case PGW_OBM1_LOW_PRI_PKT_DROPr: 12197 case PGW_OBM1_HIGH_PRI_BYTE_DROPr: 12198 case PGW_OBM1_LOW_PRI_BYTE_DROPr: 12199 xlp = 1; 12200 break; 12201 case PGW_OBM2_HIGH_PRI_PKT_DROPr: 12202 case PGW_OBM2_LOW_PRI_PKT_DROPr: 12203 case PGW_OBM2_HIGH_PRI_BYTE_DROPr: 12204 case PGW_OBM2_LOW_PRI_BYTE_DROPr: 12205 xlp = 2; 12206 break; 12207 case PGW_OBM3_HIGH_PRI_PKT_DROPr: 12208 case PGW_OBM3_LOW_PRI_PKT_DROPr: 12209 case PGW_OBM3_HIGH_PRI_BYTE_DROPr: 12210 case PGW_OBM3_LOW_PRI_BYTE_DROPr: 12211 xlp = 3; 12212 break; 12213 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_YELLOW: 12214 case SOC_COUNTER_NON_DMA_PORT_DROP_PKT_RED: 12215 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_GREEN: 12216 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_YELLOW: 12217 case SOC_COUNTER_NON_DMA_PORT_WRED_PKT_RED: 12218 if (IS_RDB_PORT(unit, port) || IS_MACSEC_PORT(unit,port)) { 12219 return TRUE; 12220 } 12221 break; 12222 default: 12223 return FALSE; 12224 } 12225 12226 pgw_index = SOC_INFO(unit).port_group[port]; 12227 if (pgw_index == -1) { 12228 return FALSE; 12229 } 12230 xlp_index = pgw_index * 4 + xlp; 12231 for (blk = 0; SOC_BLOCK_TYPE(unit, blk) >= 0; blk++) { 12232 if (SOC_BLOCK_TYPE(unit, blk) != SOC_BLK_XLPORT) { 12233 continue; 12234 } 12235 if (SOC_BLOCK_NUMBER(unit, blk) == xlp_index) { 12236 if (!SOC_INFO(unit).block_valid[blk]) { 12237 return TRUE; 12238 } 12239 } 12240 } 12241 12242 return FALSE; 12243 } 12244 12245 /* 12246 * Function: 12247 * _soc_counter_set_by_port 12248 * Purpose: 12249 * Given a port bit map, set all counters for the specified ports to 12250 * the requested value. Useful mainly to clear all the counters. 12251 * Parameters: 12252 * unit - StrataSwitch unit #. 12253 * pbmp - Bit map of all ports to set counters on. 12254 * ctr_reg - if !INVALIDr set only a specified counter 12255 * else all the counters for a port 12256 * val - 64/32-bit counter value. 12257 * Returns: 12258 * SOC_E_XXX 12259 */ 12260 12261 int 12262 _soc_counter_set_by_port(int unit, pbmp_t pbmp, soc_reg_t ctr_reg, 12263 int ar_idx, uint64 val) 12264 { 12265 int i, rv = 0; 12266 soc_port_t port; 12267 soc_ctr_ref_t *ctr_ref; 12268 soc_control_t *soc = SOC_CONTROL(unit); 12269 soc_counter_non_dma_t *non_dma = NULL; 12270 int min_index = 0; 12271 int max_ctr = 0; 12272 int num_idx = 0; 12273 int dma_id = 0; 12274 int non_dma_counter_end = 0; 12275 int port_base; 12276 int port_index, num_entries; 12277 char *cname; 12278 int dma_counters = 1; 12279 int non_dma_counters = 1; 12280 12281 PBMP_ITER(pbmp, port) { 12282 /* 12283 * Flexing operations on certain devices can create new ports, 12284 * or delete existing ports. This can happen when the counter 12285 * thread is not running. So we make a check here before proceeding 12286 * with further processing. We ignore processing for ports which no 12287 * longer exist. 12288 */ 12289 if (!SOC_CONTROL(unit)->counter_map[port]) { 12290 continue; 12291 } 12292 12293 if (IS_MACSEC_PORT(unit, port)) { 12294 continue; 12295 } 12296 if (!SOC_PORT_VALID(unit, port)) { 12297 continue; 12298 } 12299 12300 /* 12301 * If ctr_reg != INVALIDr the request is for 12302 * setting a specific counter register for 12303 * a port. 12304 */ 12305 if (ctr_reg != INVALIDr) { 12306 if ((ctr_reg < NUM_SOC_REG) || 12307 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 12308 /* No DMA counters for the loopback port */ 12309 if (IS_LB_PORT(unit, port) 12310 #if defined(BCM_SHADOW_SUPPORT) 12311 || IS_IL_PORT(unit, port) 12312 #endif 12313 ) { 12314 continue; 12315 } 12316 SOC_IF_ERROR_RETURN( 12317 _soc_counter_get_info(unit, port, ctr_reg, 12318 &port_index, &num_entries, 12319 &cname)); 12320 12321 port_base = COUNTER_IDX_PORTBASE(unit, port); 12322 min_index = port_index - port_base; 12323 max_ctr = min_index + 1; 12324 non_dma_counters = 0; 12325 12326 dma_id = 0; 12327 non_dma_counter_end = 0; 12328 } else { 12329 /* 12330 * if ctr_reg >= NUM_SOC_REG, set stats for a 12331 * specific port and queue in the hardware 12332 * and the sw copy of the same. 12333 */ 12334 min_index = 0; 12335 max_ctr = 0; 12336 dma_counters = 0; 12337 12338 dma_id = ctr_reg - SOC_COUNTER_NON_DMA_START; 12339 non_dma_counter_end = dma_id + 1; 12340 12341 } 12342 } else { 12343 /* 12344 * The request is for setting all the 12345 * counter registers for a port. 12346 */ 12347 dma_id = 0; 12348 non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 12349 SOC_COUNTER_NON_DMA_START; 12350 12351 /* No DMA counters for the loopback port */ 12352 if (IS_LB_PORT(unit, port) || 12353 IS_RDB_PORT(unit, port) || 12354 IS_MACSEC_PORT(unit, port) 12355 #if defined(BCM_SHADOW_SUPPORT) 12356 || IS_IL_PORT(unit, port) 12357 #endif 12358 ) { 12359 min_index = 0; 12360 max_ctr = 0; 12361 } else { 12362 min_index = 0; 12363 max_ctr = PORT_CTR_NUM(unit, port); 12364 } 12365 } 12366 12367 12368 if (!IS_LB_PORT(unit, port) 12369 && !IS_RDB_PORT(unit, port) 12370 && !IS_MACSEC_PORT(unit,port) 12371 #if defined(BCM_SHADOW_SUPPORT) 12372 && !IS_IL_PORT(unit, port) 12373 #endif 12374 ) 12375 { 12376 12377 if (dma_counters ) { 12378 /* No DMA counters for the loopback port */ 12379 for (i = min_index; i < max_ctr; i++) { 12380 ctr_ref = PORT_CTR_REG(unit, port, i); 12381 num_idx = (ctr_reg == INVALIDr)? ctr_ref->index: ar_idx; 12382 if (!SOC_COUNTER_INVALID(unit, ctr_ref->reg)) { 12383 if (!SOC_REG_IS_COUNTER_TABLE(unit,ctr_ref->reg) && 12384 !SOC_REG_PORT_VALID(unit,ctr_ref->reg, port)) { 12385 continue; 12386 } 12387 rv = _soc_counter_set(unit, port, ctr_ref->reg, 12388 num_idx, val); 12389 12390 if (rv == SOC_E_FAIL) { 12391 LOG_ERROR(BSL_LS_SOC_COMMON, 12392 (BSL_META_U(unit, 12393 "Error %d calling " 12394 "soc_counter_set for" 12395 "port: %d, reg: %d, " 12396 "index: %d\n"), rv, 12397 port, ctr_ref->reg, ctr_ref->index)); 12398 } 12399 } 12400 } 12401 }/* dma_counters */ 12402 } 12403 12404 if (non_dma_counters) { 12405 for (i = dma_id; i < non_dma_counter_end ; i++) { 12406 non_dma = &soc->counter_non_dma[i]; 12407 /* Clear counters should not clear Non Port based counters (like 12408 * Flex and Field counters) - they are to be cleared by the 12409 * corresponding module */ 12410 if (SOC_PBMP_IS_NULL(non_dma->pbmp)) { 12411 continue; 12412 } 12413 12414 if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) { 12415 continue; 12416 } 12417 12418 if (!IS_MACSEC_PORT(unit, port)) { 12419 #if defined (BCM_APACHE_SUPPORT) 12420 if (SOC_IS_APACHE(unit)) { 12421 if (((SOC_COUNTER_NON_DMA_START + i) == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_EXT) 12422 || ((SOC_COUNTER_NON_DMA_START + i) == SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_EXT) ) { 12423 continue; 12424 } 12425 } 12426 #endif 12427 rv = _soc_counter_set(unit, port, 12428 SOC_COUNTER_NON_DMA_START + i, -1, 12429 val); 12430 } 12431 if (rv == SOC_E_FAIL) { 12432 LOG_ERROR(BSL_LS_SOC_COMMON, 12433 (BSL_META_U(unit, 12434 "Error %d calling soc_counter_set " 12435 "for port: %d, " 12436 "non-DMA index: %d\n"), 12437 rv, port, i)); 12438 } 12439 } 12440 } 12441 #ifdef BCM_BRADLEY_SUPPORT 12442 /* 12443 * The HOLD register is not supported by DMA on HUMV/Bradley, 12444 * so we cannot use the standard counter_set function. 12445 */ 12446 if (SOC_IS_HBX(unit)) { 12447 if (SOC_REG_IS_VALID(unit, HOLD_Xr) && 12448 SOC_REG_IS_VALID(unit, HOLD_Yr)) { 12449 SOC_IF_ERROR_RETURN 12450 (WRITE_HOLD_Xr(unit, port, COMPILER_64_LO(val) / 2)); 12451 SOC_IF_ERROR_RETURN 12452 (WRITE_HOLD_Yr(unit, port, COMPILER_64_LO(val) / 2)); 12453 } 12454 } 12455 #endif 12456 } 12457 12458 return SOC_E_NONE; 12459 } 12460 12461 /* 12462 * Function: 12463 * soc_counter_clear_by_port_reg 12464 * Purpose: 12465 * Given a port,counter register. clear counters for the specified ports 12466 * Useful mainly to clear individual snmp counters. 12467 * Parameters: 12468 * unit - StrataSwitch unit #. 12469 * port - Bit map of all ports to set counters on. 12470 * ctr_reg - counter register to clear. 12471 * val - 64bit counter value(set to 0). 12472 * Returns: 12473 * SOC_E_XXX 12474 */ 12475 12476 int 12477 soc_counter_clear_by_port_reg(int unit, soc_port_t port, soc_reg_t ctr_reg, 12478 int ar_idx, uint64 val) 12479 { 12480 pbmp_t pbmp; 12481 12482 SOC_PBMP_CLEAR(pbmp); 12483 SOC_PBMP_PORT_SET(pbmp, port); 12484 COMPILER_64_ZERO(val); 12485 return _soc_counter_set_by_port(unit, pbmp, ctr_reg, ar_idx, val); 12486 } 12487 12488 12489 /* 12490 * Function: 12491 * soc_counter_set_by_port, soc_counter_set32_by_port 12492 * Purpose: 12493 * Given a port bit map, set all counters for the specified ports to 12494 * the requested value. Useful mainly to clear all the counters. 12495 * Parameters: 12496 * unit - StrataSwitch unit #. 12497 * pbm - Bit map of all ports to set counters on. 12498 * val - 64/32-bit counter value. 12499 * Returns: 12500 * SOC_E_XXX 12501 * Notes: 12502 * The 32-bit version sets the upper 32-bits of the 64-bit 12503 * software counters to zero. The specified value is truncated 12504 * to the size of the hardware register when storing to hardware. 12505 */ 12506 12507 int 12508 soc_counter_set_by_port(int unit, pbmp_t pbmp, uint64 val) 12509 { 12510 return _soc_counter_set_by_port(unit, pbmp, INVALIDr, 0, val); 12511 } 12512 12513 int 12514 soc_counter_set32_by_port(int unit, pbmp_t pbmp, uint32 val) 12515 { 12516 uint64 val64; 12517 12518 COMPILER_64_SET(val64, 0, val); 12519 12520 return soc_counter_set_by_port(unit, pbmp, val64); 12521 } 12522 12523 int 12524 soc_controlled_counter_clear(int unit, soc_port_t port) 12525 { 12526 soc_control_t *soc = SOC_CONTROL(unit); 12527 uint64 ctr_new; 12528 int index, port_base; 12529 soc_controlled_counter_t* ctr; 12530 12531 LOG_DEBUG(BSL_LS_SOC_COUNTER, 12532 (BSL_META_U(unit, 12533 "soc_controlled_counter_clear: unit=%d " 12534 "port=%d\n"), unit, port)); 12535 12536 if ((!soc_feature(unit, soc_feature_controlled_counters)) || 12537 (!soc->controlled_counters)) { 12538 return SOC_E_NONE; 12539 } 12540 12541 port_base = COUNTER_IDX_PORTBASE(unit, port); 12542 12543 COUNTER_LOCK(unit); 12544 12545 #ifdef BCM_PETRA_SUPPORT 12546 if (SOC_IS_ARAD(unit) && !SOC_IS_JERICHO(unit)) { 12547 SOC_IF_ERROR_RETURN(soc_arad_stat_clear_on_read_set(unit , 1)); 12548 } 12549 #endif 12550 #ifdef BCM_JERICHO_SUPPORT 12551 /*Jericho collected counters are not cleared on read*/ 12552 if (SOC_IS_JERICHO(unit)) { 12553 SOC_IF_ERROR_RETURN(soc_jer_nif_controlled_counter_clear(unit, port)); 12554 } 12555 #endif 12556 for (index = 0; soc->controlled_counters[index].controlled_counter_f != NULL; index++) { 12557 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 12558 uint32 clear_on_read; 12559 12560 ctr = &soc->controlled_counters[index]; 12561 if (ctr->controlled_counter_clear_f != NULL) { 12562 ctr->controlled_counter_clear_f(unit, ctr->counter_id, port); 12563 } else { 12564 /* assume clear on read */ 12565 ctr->controlled_counter_f(unit, ctr->counter_id, port, &ctr_new, &clear_on_read); 12566 if(!clear_on_read) { 12567 LOG_WARN(BSL_LS_SOC_COMMON, 12568 (BSL_META_U(unit, 12569 "Counter Id(%d) is not cleared!\n"), ctr->counter_id)); 12570 } 12571 } 12572 /*check if counter is relevant*/ 12573 if(!COUNTER_IS_COLLECTED(soc->controlled_counters[index])) { 12574 continue; 12575 } 12576 /* The following section updates 64-bit values and must be atomic */ 12577 COUNTER_ATOMIC_BEGIN(s); 12578 COMPILER_64_SET(soc->counter_sw_val[port_base + ctr->counter_idx], 0, 0); 12579 COMPILER_64_SET(soc->counter_hw_val[port_base + ctr->counter_idx], 0, 0); 12580 COMPILER_64_SET(soc->counter_delta[port_base + ctr->counter_idx], 0, 0); 12581 COUNTER_ATOMIC_END(s); 12582 12583 } 12584 12585 #ifdef BCM_PETRA_SUPPORT 12586 if (SOC_IS_ARAD(unit) && !SOC_IS_JERICHO(unit)) { 12587 SOC_IF_ERROR_RETURN(soc_arad_stat_clear_on_read_set(unit , 0)); 12588 } 12589 #endif 12590 12591 COUNTER_UNLOCK(unit); 12592 12593 return SOC_E_NONE; 12594 } 12595 12596 /* 12597 * Function: 12598 * soc_counter_set_by_reg, soc_counter_set32_by_reg 12599 * Purpose: 12600 * Given a counter register number and a counter value, set both 12601 * the hardware and software-accumulated counters to the value 12602 * for all ports. 12603 * Parameters: 12604 * unit - StrataSwitch unit #. 12605 * ctr_reg - counter register to set. 12606 * val - 64/32-bit counter value. 12607 * Returns: 12608 * SOC_E_XXX 12609 * Notes: 12610 * The 32-bit version sets the upper 32-bits of the 64-bit 12611 * software counters to zero. The specified value is truncated 12612 * to the size of the hardware register when storing to hardware. 12613 */ 12614 12615 int 12616 soc_counter_set_by_reg(int unit, soc_reg_t ctr_reg, int ar_idx, uint64 val) 12617 { 12618 soc_port_t port; 12619 12620 if (SOC_COUNTER_INVALID(unit, ctr_reg)) { 12621 return SOC_E_NONE; 12622 } 12623 12624 #ifdef BROADCOM_DEBUG 12625 if (!SOC_REG_IS_COUNTER(unit, ctr_reg)) { 12626 _soc_counter_illegal(unit, ctr_reg); 12627 return SOC_E_NONE; 12628 } 12629 #endif /* BROADCOM_DEBUG */ 12630 12631 12632 PBMP_PORT_ITER(unit, port) { 12633 SOC_IF_ERROR_RETURN(_soc_counter_set(unit, port, ctr_reg, 12634 ar_idx, val)); 12635 } 12636 12637 return SOC_E_NONE; 12638 } 12639 12640 int 12641 soc_counter_set32_by_reg(int unit, soc_reg_t ctr_reg, int ar_idx, uint32 val) 12642 { 12643 uint64 val64; 12644 12645 COMPILER_64_SET(val64, 0, val); 12646 12647 return soc_counter_set_by_reg(unit, ctr_reg, ar_idx, val64); 12648 } 12649 12650 /* Function: 12651 * soc_counter_config_multi_get 12652 * Purpose: 12653 * Given a counter register number, count, instance type, instance... 12654 * Parameter: 12655 * unit - StrataSwitch Unit #. 12656 * ctr_reg - Counter Register to retrieve. 12657 * count - Number of consecutive entries to be set. 12658 * ctrl_info - Counter Control Info Structure 12659 * Contains the instance type and instance. 12660 * ctrl_config - Counter Control config structure to Get Dma attributes. 12661 * Refer soc_ctr_ctrl_config_s. 12662 *Returns: 12663 * SOC_E_XXX 12664 *Notes: 12665 * If count is set to 0, nothing is retrieved. 12666 */ 12667 int 12668 soc_counter_config_multi_get(int unit, soc_reg_t ctr_reg, int count, 12669 soc_ctr_control_info_t *ctrl_info, 12670 soc_ctr_ctrl_config_t *ctrl_config) 12671 { 12672 int i; 12673 soc_control_t *soc = SOC_CONTROL(unit); 12674 soc_counter_non_dma_t *non_dma = NULL; 12675 soc_counter_non_dma_t *parent_dma = NULL; 12676 int value = -1, config_type = 0; 12677 int instance_type = -1, in_pipe = -1; 12678 int c_offset, rv = SOC_E_NONE; 12679 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 12680 12681 if (soc_ctr_ctrl == NULL) { 12682 return SOC_E_INIT; 12683 } 12684 12685 if ((count < 0) || (!ctrl_config) || (!ctrl_info)) { 12686 return SOC_E_PARAM; 12687 } 12688 12689 if (soc->counter_non_dma == NULL) { 12690 return SOC_E_RESOURCE; 12691 } 12692 12693 if ((ctr_reg < SOC_COUNTER_NON_DMA_START) || 12694 (ctr_reg >= SOC_COUNTER_NON_DMA_END)) { 12695 return SOC_E_PARAM; 12696 } 12697 12698 for (i = 0; i < count; i++) { 12699 /* Check sanity of Ctrl_info */ 12700 instance_type = ctrl_info[i].instance_type; 12701 12702 if (!((instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) || 12703 (instance_type == SOC_CTR_INSTANCE_TYPE_POOL) || 12704 (instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE))) { 12705 return SOC_E_PARAM; 12706 } 12707 12708 parent_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 12709 non_dma = parent_dma; 12710 12711 if (soc_ctr_ctrl->get_child_dma) { 12712 rv = soc_ctr_ctrl->get_child_dma(unit, ctr_reg, 12713 ctrl_info[i], &non_dma); 12714 if (rv != SOC_E_NONE) { 12715 return rv; 12716 } 12717 } 12718 12719 switch (instance_type) { 12720 case SOC_CTR_INSTANCE_TYPE_PIPE: 12721 in_pipe = ctrl_info[i].instance; 12722 if ((in_pipe >= NUM_PIPE(unit)) || (in_pipe < -1)) { 12723 return SOC_E_PARAM; 12724 } 12725 break; 12726 case SOC_CTR_INSTANCE_TYPE_POOL: 12727 c_offset = ctrl_info[i].instance; 12728 if ((c_offset < 0) || (c_offset >= parent_dma->extra_ctr_ct)) { 12729 return SOC_E_PARAM; 12730 } 12731 in_pipe = -1; 12732 break; 12733 case SOC_CTR_INSTANCE_TYPE_POOL_PIPE: 12734 return SOC_E_UNAVAIL; 12735 /* coverity[dead_error_begin] */ 12736 default: 12737 return SOC_E_PARAM; 12738 } 12739 12740 config_type = ctrl_config[i].config_type; 12741 value = -1; 12742 switch (config_type) { 12743 case SOC_CTR_CTRL_CONFIG_DMA_ENABLE: 12744 value = (non_dma->flags & _SOC_COUNTER_NON_DMA_VALID); 12745 break; 12746 case SOC_CTR_CTRL_CONFIG_DMA_MINIDX: 12747 if (in_pipe == -1) { 12748 in_pipe = 0; 12749 } 12750 value = non_dma->dma_index_min[in_pipe]; 12751 break; 12752 case SOC_CTR_CTRL_CONFIG_DMA_MAXIDX: 12753 if (in_pipe == -1) { 12754 in_pipe = 0; 12755 } 12756 value = non_dma->dma_index_max[in_pipe]; 12757 break; 12758 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL: 12759 if (non_dma->dma_rate_profile == _SOC_COUNTER_DMA_RATE_PROFILE_MASK) { 12760 value = 1; 12761 } else { 12762 value = 0; 12763 } 12764 break; 12765 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_AUTO: 12766 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_WFS: 12767 return SOC_E_UNAVAIL; 12768 break; 12769 default: 12770 return SOC_E_PARAM; 12771 } 12772 ctrl_config[i].config_val = value; 12773 } 12774 return rv; 12775 } 12776 12777 /* Function: 12778 * soc_counter_config_multi_set 12779 * Purpose: 12780 * Given a counter register number, count, instance type, instance... 12781 * Parameter: 12782 * unit - StrataSwitch Unit #. 12783 * ctr_reg - Counter Register to retrieve. 12784 * count - Number of consecutive entries to be set. 12785 * ctrl_info - Counter Control Info Structure 12786 * Contains the instance type and instance. 12787 * ctrl_config - Counter Control config structure to set Dma attributes. 12788 * Refer soc_ctr_ctrl_config_s. 12789 *Returns: 12790 * SOC_E_XXX 12791 *Notes: 12792 * If count is set to 0, nothing is set. 12793 */ 12794 int 12795 soc_counter_config_multi_set(int unit, soc_reg_t ctr_reg, int count, 12796 soc_ctr_control_info_t *ctrl_info, 12797 soc_ctr_ctrl_config_t *ctrl_config) 12798 { 12799 int i, max_idx = 0; 12800 soc_control_t *soc = SOC_CONTROL(unit); 12801 soc_counter_non_dma_t *non_dma = NULL; 12802 soc_counter_non_dma_t *parent_dma = NULL; 12803 int value = -1, config_type = 0; 12804 int instance_type = -1, in_pipe = -1, pipe = -1; 12805 int c_offset, rv = SOC_E_NONE; 12806 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 12807 12808 if (soc_ctr_ctrl == NULL) { 12809 return SOC_E_INIT; 12810 } 12811 12812 if ((count < 0) || (!ctrl_config) || (!ctrl_info)) { 12813 return SOC_E_PARAM; 12814 } 12815 12816 if ((ctr_reg < SOC_COUNTER_NON_DMA_START) || 12817 (ctr_reg >= SOC_COUNTER_NON_DMA_END)) { 12818 return SOC_E_PARAM; 12819 } 12820 12821 if (soc->counter_non_dma == NULL) { 12822 return SOC_E_RESOURCE; 12823 } 12824 12825 for (i = 0; i < count; i++) { 12826 /* Check sanity of Ctrl_info */ 12827 instance_type = ctrl_info[i].instance_type; 12828 12829 if (!((instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) || 12830 (instance_type == SOC_CTR_INSTANCE_TYPE_POOL) || 12831 (instance_type == SOC_CTR_INSTANCE_TYPE_POOL_PIPE))) { 12832 return SOC_E_PARAM; 12833 } 12834 12835 parent_dma = &soc->counter_non_dma[ctr_reg - SOC_COUNTER_NON_DMA_START]; 12836 non_dma = parent_dma; 12837 /* Get child dma if this falls under Parent-child model. */ 12838 if (soc_ctr_ctrl->get_child_dma) { 12839 rv = soc_ctr_ctrl->get_child_dma(unit, ctr_reg, 12840 ctrl_info[i], &non_dma); 12841 } 12842 max_idx = non_dma->num_entries / NUM_PIPE(unit); 12843 12844 switch (instance_type) { 12845 case SOC_CTR_INSTANCE_TYPE_PIPE: 12846 in_pipe = ctrl_info[i].instance; 12847 if ((in_pipe >= NUM_PIPE(unit)) || (in_pipe < -1)) { 12848 return SOC_E_PARAM; 12849 } 12850 break; 12851 case SOC_CTR_INSTANCE_TYPE_POOL: 12852 c_offset = ctrl_info[i].instance; 12853 if ((c_offset < 0) || (c_offset >= parent_dma->extra_ctr_ct)) { 12854 return SOC_E_PARAM; 12855 } 12856 in_pipe = -1; 12857 break; 12858 case SOC_CTR_INSTANCE_TYPE_POOL_PIPE: 12859 return SOC_E_UNAVAIL; 12860 /* coverity[dead_error_begin] */ 12861 default: 12862 return SOC_E_PARAM; 12863 } 12864 12865 value = ctrl_config[i].config_val; 12866 config_type = ctrl_config[i].config_type; 12867 12868 switch (config_type) { 12869 case SOC_CTR_CTRL_CONFIG_DMA_ENABLE: 12870 if (value) { 12871 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 12872 if ((parent_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) && 12873 (!(parent_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) && 12874 (ctr_reg != SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE) && 12875 (ctr_reg != SOC_COUNTER_NON_DMA_ING_FLEX_BYTE)) { 12876 parent_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 12877 } 12878 } else { 12879 non_dma->flags &= ~_SOC_COUNTER_NON_DMA_VALID; 12880 } 12881 break; 12882 case SOC_CTR_CTRL_CONFIG_DMA_MINIDX: 12883 if ((value < 0) || (value > max_idx)) { 12884 return SOC_E_PARAM; 12885 } 12886 if (in_pipe == -1) { 12887 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 12888 non_dma->dma_index_min[pipe] = value; 12889 } 12890 } else { 12891 non_dma->dma_index_min[in_pipe] = value; 12892 } 12893 break; 12894 case SOC_CTR_CTRL_CONFIG_DMA_MAXIDX: 12895 if ((value < 0) || (value > max_idx)) { 12896 return SOC_E_PARAM; 12897 } 12898 if (in_pipe == -1) { 12899 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 12900 non_dma->dma_index_max[pipe] = value; 12901 } 12902 } else { 12903 non_dma->dma_index_max[in_pipe] = value; 12904 } 12905 break; 12906 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_ALL: 12907 if (soc_ctr_ctrl->dma_config_update) { 12908 rv = soc_ctr_ctrl->dma_config_update(unit, non_dma, 12909 config_type, value); 12910 } 12911 break; 12912 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_AUTO: 12913 case SOC_CTR_CTRL_CONFIG_DMA_RATE_PROFILE_WFS: 12914 return SOC_E_UNAVAIL; 12915 break; 12916 default: 12917 return SOC_E_PARAM; 12918 } 12919 } 12920 return rv; 12921 } 12922 12923 /* 12924 * Function: 12925 * soc_counter_collect32 12926 * Purpose: 12927 * This routine gets called each time the counter transfer has 12928 * completed a cycle. It collects the 32-bit counters. 12929 * Parameters: 12930 * unit - StrataSwitch unit #. 12931 * discard - If TRUE, the software counters are not updated; this 12932 * results in only synchronizing the previous hardware 12933 * count buffer. 12934 * Returns: 12935 * SOC_E_XXX 12936 * Notes: 12937 * Computes the deltas in the hardware counters from the last 12938 * time it was called and adds them to the high resolution (64-bit) 12939 * software counters in counter_sw_val[]. It takes wrapping into 12940 * account for counters that are less than 32 bits wide. 12941 * It also computes counter_delta[]. 12942 */ 12943 12944 STATIC int 12945 soc_counter_collect32(int unit, int discard) 12946 { 12947 soc_control_t *soc = SOC_CONTROL(unit); 12948 soc_port_t port; 12949 soc_reg_t ctr_reg; 12950 soc_ctr_ref_t *ctr_ref; 12951 uint32 ctr_new, ctr_prev, ctr_diff; 12952 int index; 12953 int port_index; 12954 int dma; 12955 int recheck_cntrs; 12956 int ar_idx; 12957 12958 LOG_DEBUG(BSL_LS_SOC_COUNTER, 12959 (BSL_META_U(unit, 12960 "soc_counter_collect32: unit=%d discard=%d\n"), 12961 unit, discard)); 12962 12963 dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) && 12964 !discard); 12965 12966 recheck_cntrs = soc_feature(unit, soc_feature_recheck_cntrs); 12967 12968 PBMP_ITER(soc->counter_pbmp, port) { 12969 /* 12970 * Flexing operations on certain devices can create new ports, 12971 * or delete existing ports. This can happen when the counter 12972 * thread is not running. So we make a check here before proceeding 12973 * with further processing. We ignore processing for ports which no 12974 * longer exist. 12975 */ 12976 if (!SOC_CONTROL(unit)->counter_map[port]) { 12977 continue; 12978 } 12979 12980 if ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) && 12981 (!SOC_IS_XGS3_SWITCH(unit))) { 12982 continue; 12983 } 12984 #if defined(BCM_SHADOW_SUPPORT) 12985 if (SOC_IS_SHADOW(unit) && IS_IL_PORT(unit, port)) { 12986 continue; 12987 } 12988 #endif /* BCM_SHADOW_SUPPORT */ 12989 12990 12991 port_index = COUNTER_MIN_IDX_GET(unit, port); 12992 12993 for (index = 0; index < PORT_CTR_NUM(unit, port); 12994 index++, port_index++) { 12995 volatile uint64 *vptr; 12996 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 12997 12998 ctr_ref = PORT_CTR_REG(unit, port, index); 12999 ctr_reg = ctr_ref->reg; 13000 ar_idx = ctr_ref->index; 13001 13002 if (SOC_COUNTER_INVALID(unit, ctr_reg)) { 13003 continue; 13004 } 13005 if (!SOC_REG_PORT_VALID(unit,ctr_reg, port)) { 13006 continue; 13007 } 13008 13009 ctr_prev = COMPILER_64_LO(soc->counter_hw_val[port_index]); 13010 13011 if (dma) { 13012 ctr_new = soc->counter_buf32[port_index]; 13013 } else { /* Not DMA. Just read register */ 13014 SOC_IF_ERROR_RETURN 13015 (soc_reg32_get(unit, ctr_reg, port, ar_idx, 13016 &ctr_new)); 13017 } 13018 13019 if ( (recheck_cntrs == TRUE) && (ctr_new != ctr_prev) ) { 13020 /* Seeds of doubt, double-check */ 13021 uint32 ctr_new2; 13022 int suspicious = 0; 13023 SOC_IF_ERROR_RETURN 13024 (soc_reg32_get(unit, ctr_reg, port, 0, &ctr_new2)); 13025 13026 /* Check for partial ordering, with wrap */ 13027 if (ctr_new < ctr_prev) { 13028 if ((ctr_new2 < ctr_new) || (ctr_new2 > ctr_prev)) { 13029 /* prev < new2 < new, bad data */ 13030 /* Try again next time */ 13031 ctr_new = ctr_prev; 13032 suspicious = 1; 13033 } 13034 } else { 13035 if ((ctr_new2 < ctr_new) && (ctr_new2 > ctr_prev)) { 13036 /* prev < new2 < new, bad data */ 13037 /* Try again next time */ 13038 ctr_new = ctr_prev; 13039 suspicious = 1; 13040 } 13041 } 13042 /* Otherwise believe ctr_new */ 13043 13044 if (suspicious) { 13045 #if !defined(SOC_NO_NAMES) 13046 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 13047 (BSL_META_U(unit, 13048 "soc_counter_collect32: " 13049 "unit %d, port%d: suspicious %s " 13050 "counter read (%s)\n"), 13051 unit, port, 13052 dma?"DMA":"manual", 13053 SOC_REG_NAME(unit, ctr_reg))); 13054 #else 13055 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 13056 (BSL_META_U(unit, 13057 "soc_counter_collect32: " 13058 "unit %d, port%d: suspicious %s " 13059 "counter read (Counter%d)\n"), 13060 unit, port, 13061 dma?"DMA":"manual", 13062 ctr_reg)); 13063 #endif /* SOC_NO_NAMES */ 13064 } /* Suspicious counter change */ 13065 } /* recheck_cntrs == TRUE */ 13066 13067 if (ctr_new == ctr_prev) { 13068 COUNTER_ATOMIC_BEGIN(s); 13069 COMPILER_64_SET(soc->counter_delta[port_index], 0, 0); 13070 COUNTER_ATOMIC_END(s); 13071 continue; 13072 } 13073 13074 if (discard) { 13075 COUNTER_ATOMIC_BEGIN(s); 13076 /* Update the DMA location */ 13077 soc->counter_buf32[port_index] = ctr_new; 13078 /* Update the previous value buffer */ 13079 COMPILER_64_SET(soc->counter_hw_val[port_index], 0, ctr_new); 13080 COMPILER_64_SET(soc->counter_delta[port_index], 0, 0); 13081 COUNTER_ATOMIC_END(s); 13082 continue; 13083 } 13084 13085 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 13086 (BSL_META_U(unit, 13087 "soc_counter_collect32: ctr %d => %u\n"), 13088 port_index, ctr_new)); 13089 13090 vptr = &soc->counter_sw_val[port_index]; 13091 13092 ctr_diff = ctr_new; 13093 13094 if (ctr_diff < ctr_prev) { 13095 int width, i = 0; 13096 13097 /* 13098 * Counter must have wrapped around. Add the proper 13099 * wrap-around amount. Full 32-bit wide counters do not 13100 * need anything added. 13101 */ 13102 width = SOC_REG_INFO(unit, ctr_reg).fields[0].len; 13103 if (soc_feature(unit, soc_feature_counter_parity) 13104 #ifdef BCM_HURRICANE2_SUPPORT 13105 || soc_reg_field_valid(unit, ctr_reg, PARITYf) 13106 #endif 13107 ) 13108 { 13109 while((SOC_REG_INFO(unit, ctr_reg).fields + i) != NULL) { 13110 if (SOC_REG_INFO(unit, ctr_reg).fields[i].field == 13111 COUNTf) { 13112 width = SOC_REG_INFO(unit, ctr_reg).fields[i].len; 13113 break; 13114 } 13115 i++; 13116 } 13117 } 13118 if (width < 32) { 13119 ctr_diff += (1UL << width); 13120 } 13121 } 13122 13123 ctr_diff -= ctr_prev; 13124 13125 COUNTER_ATOMIC_BEGIN(s); 13126 COMPILER_64_ADD_32(*vptr, ctr_diff); 13127 COMPILER_64_SET(soc->counter_delta[port_index], 0, ctr_diff); 13128 COMPILER_64_SET(soc->counter_hw_val[port_index], 0, ctr_new); 13129 COUNTER_ATOMIC_END(s); 13130 13131 } 13132 13133 /* If signaled to exit then return */ 13134 if (!soc->counter_interval) { 13135 return SOC_E_NONE; 13136 } 13137 13138 /* 13139 * Allow other tasks to run between processing each port. 13140 */ 13141 13142 sal_thread_yield(); 13143 } 13144 13145 return SOC_E_NONE; 13146 } 13147 13148 #ifdef BCM_SBUSDMA_SUPPORT 13149 13150 #ifdef SOC_COUNTER_TABLE_SUPPORT 13151 #define COUNTER_SBUSDMA_DESC_SIZE 5 13152 #elif defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 13153 #define COUNTER_SBUSDMA_DESC_SIZE 4 13154 #else 13155 #define COUNTER_SBUSDMA_DESC_SIZE 3 13156 #endif 13157 13158 #if defined(BCM_ESW_SUPPORT) && (SOC_MAX_NUM_PP_PORTS > SOC_MAX_NUM_PORTS) 13159 STATIC sbusdma_desc_handle_t 13160 _soc_port_counter_handles[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PP_PORTS][COUNTER_SBUSDMA_DESC_SIZE]; 13161 #else 13162 STATIC sbusdma_desc_handle_t 13163 _soc_port_counter_handles[SOC_MAX_NUM_DEVICES][SOC_MAX_NUM_PORTS][COUNTER_SBUSDMA_DESC_SIZE]; 13164 #endif 13165 13166 #endif /* BCM_SBUSDMA_SUPPORT */ 13167 13168 int soc_controlled_counter_update_by_port(int unit, soc_port_t dst_port, soc_port_t src_port) 13169 { 13170 soc_control_t *soc = SOC_CONTROL(unit); 13171 int dst_port_base, src_port_base; 13172 int number_of_port_counters; 13173 13174 COUNTER_LOCK(unit); 13175 13176 dst_port_base = COUNTER_IDX_PORTBASE(unit, dst_port); 13177 src_port_base = COUNTER_IDX_PORTBASE(unit, src_port); 13178 /* 13179 * get number of counters per port 13180 */ 13181 number_of_port_counters = SOC_CONTROL(unit)->counter_perport; 13182 /*Copy SW counter data from src port to dst port*/ 13183 sal_memcpy(&soc->counter_delta[dst_port_base], &soc->counter_delta[src_port_base], 13184 sizeof(uint64) * number_of_port_counters); 13185 sal_memcpy(&soc->counter_hw_val[dst_port_base], &soc->counter_hw_val[src_port_base], 13186 sizeof(uint64) * number_of_port_counters); 13187 sal_memcpy(&soc->counter_sw_val[dst_port_base], &soc->counter_sw_val[src_port_base], 13188 sizeof(uint64) * number_of_port_counters); 13189 /*Clear SW counter data on src port*/ 13190 sal_memset(&soc->counter_delta[src_port_base], 0x0, sizeof(uint64) * number_of_port_counters); 13191 sal_memset(&soc->counter_hw_val[src_port_base], 0x0, sizeof(uint64) * number_of_port_counters); 13192 sal_memset(&soc->counter_sw_val[src_port_base], 0x0, sizeof(uint64) * number_of_port_counters); 13193 13194 COUNTER_UNLOCK(unit); 13195 13196 return SOC_E_NONE; 13197 } 13198 13199 int soc_controlled_counter_length_get(int unit, soc_controlled_counter_t* ctr, int *length) 13200 { 13201 if (ctr && ctr->controlled_counter_length_f != NULL) { 13202 ctr->controlled_counter_length_f(unit, ctr->counter_id, length); 13203 } else { 13204 13205 LOG_ERROR(BSL_LS_SOC_COMMON, 13206 (BSL_META_U(unit, 13207 "soc_controlled_counter_length_get: unit %d:" 13208 "please define controlled_counter_length_get() function.\n"), 13209 unit)); 13210 return SOC_E_FAIL; 13211 } 13212 13213 return SOC_E_NONE; 13214 } 13215 /* 13216 * Function: 13217 * soc_controlled_counters_collect64 13218 * Purpose: 13219 * This routine gets called each time the counter transfer has 13220 * completed a cycle. It collects the 64-bit controlled counters. 13221 */ 13222 int 13223 soc_controlled_counters_collect64(int unit, int discard) 13224 { 13225 soc_control_t *soc = SOC_CONTROL(unit); 13226 soc_port_t port; 13227 uint64 ctr_new; 13228 uint64 ctr_diff,ctr_prev; 13229 uint64 ctr_delta; 13230 int index, port_base; 13231 soc_controlled_counter_t* ctr; 13232 uint32 clear_on_read; 13233 13234 LOG_DEBUG(BSL_LS_SOC_COUNTER, 13235 (BSL_META_U(unit, 13236 "soc_controlled_counters_collect64: unit=%d " 13237 "discard=%d\n"), unit, discard)); 13238 13239 if (!soc_feature(unit, soc_feature_controlled_counters)) { 13240 return SOC_E_NONE; 13241 } 13242 13243 PBMP_ITER(soc->counter_pbmp, port) { 13244 if (!soc->controlled_counters) { 13245 break; 13246 } 13247 for (index = 0; soc->controlled_counters[index].controlled_counter_f != NULL; index++) { 13248 volatile uint64 *vptr; 13249 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 13250 13251 ctr = &soc->controlled_counters[index]; 13252 13253 if(!COUNTER_IS_COLLECTED(soc->controlled_counters[index])) { 13254 continue; 13255 } 13256 13257 ctr->controlled_counter_f(unit, ctr->counter_id, port, &ctr_new, &clear_on_read); 13258 13259 if(clear_on_read) { 13260 /* Counters are Clear-on-Read. Add ctr_new to 13261 * previously stored sw value if discard is not set 13262 */ 13263 13264 port_base = COUNTER_IDX_PORTBASE(unit, port); 13265 /* In order to improve access efficiency. Here we didn't take atomic lock first, 13266 * and get the delta value directly. In case the delta value was messed up, it 13267 * doesn't matter. Because the delta vaule was not used to update SOC DB. 13268 */ 13269 ctr_delta = soc->counter_delta[port_base + ctr->counter_idx]; 13270 13271 if (COMPILER_64_IS_ZERO(ctr_new) && COMPILER_64_IS_ZERO(ctr_delta)) { 13272 continue; 13273 } 13274 13275 if (discard) { 13276 /* Update the previous value buffer */ 13277 COUNTER_ATOMIC_BEGIN(s); 13278 soc->counter_hw_val[port_base + ctr->counter_idx] = ctr_new; 13279 COMPILER_64_ZERO(soc->counter_delta[port_base + ctr->counter_idx]); 13280 COUNTER_ATOMIC_END(s); 13281 continue; 13282 } 13283 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 13284 (BSL_META_U(unit, 13285 "soc_controlled_counters_collect64: ctr %d => " 13286 "0x%08x_%08x\n"), port_base + ctr->counter_idx, 13287 COMPILER_64_HI(ctr_new), COMPILER_64_LO(ctr_new))); 13288 13289 vptr = &soc->counter_sw_val[port_base + ctr->counter_idx]; 13290 COUNTER_ATOMIC_BEGIN(s); 13291 COMPILER_64_ADD_64(*vptr, ctr_new); 13292 soc->counter_delta[port_base + ctr->counter_idx] = ctr_new; 13293 soc->counter_hw_val[port_base + ctr->counter_idx] = ctr_new; 13294 COUNTER_ATOMIC_END(s); 13295 } else { 13296 /* Counters are NOT Clear-on-Read. Add ctr_new to 13297 * previously stored sw value if discard is not set. 13298 * Should consider the HW reg roll back. 13299 */ 13300 port_base = COUNTER_IDX_PORTBASE(unit, port); 13301 /* Atomic because soc_counter_set may update 64-bit value */ 13302 COUNTER_ATOMIC_BEGIN(s); 13303 ctr_prev = soc->counter_hw_val[port_base + ctr->counter_idx]; 13304 COUNTER_ATOMIC_END(s); 13305 13306 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 13307 COUNTER_ATOMIC_BEGIN(s); 13308 COMPILER_64_ZERO(soc->counter_delta[port_base + ctr->counter_idx]); 13309 COUNTER_ATOMIC_END(s); 13310 continue; 13311 } 13312 13313 vptr = &soc->counter_sw_val[port_base + ctr->counter_idx]; 13314 ctr_diff = ctr_new; 13315 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 13316 int width; 13317 uint64 wrap_amt; 13318 /* 13319 * Counter must have wrapped around. 13320 * Add the proper wrap-around amount. 13321 */ 13322 SOC_IF_ERROR_RETURN(soc_controlled_counter_length_get(unit, ctr, &width)); 13323 13324 if (width < 32) { 13325 COMPILER_64_SET(wrap_amt, 0, 1UL << width); 13326 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 13327 } else if (width < 64) { 13328 COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0); 13329 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 13330 } 13331 } 13332 13333 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 13334 13335 COUNTER_ATOMIC_BEGIN(s); 13336 COMPILER_64_ADD_64(*vptr, ctr_diff); 13337 soc->counter_delta[port_base + ctr->counter_idx ] = ctr_diff; 13338 soc->counter_hw_val[port_base + ctr->counter_idx ] = ctr_new; 13339 COUNTER_ATOMIC_END(s); 13340 } 13341 13342 } 13343 13344 /* If signaled to exit then return */ 13345 if (!soc->counter_interval) { 13346 return SOC_E_NONE; 13347 } 13348 13349 /* Allow other tasks to run between processing each port */ 13350 COUNTER_UNLOCK(unit); 13351 sal_thread_yield(); 13352 COUNTER_LOCK(unit); 13353 } 13354 13355 return SOC_E_NONE; 13356 } 13357 13358 #ifdef BCM_XGS_SUPPORT 13359 13360 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 13361 /* 13362 * Function: 13363 * _soc_xgs3_update_link_activity 13364 * Purpose: 13365 * Report the link activities to LED processor. 13366 * Parameters: 13367 * unit - switch unit 13368 * port - port number 13369 * tx_byte - transmitted byte during counter DMA interval 13370 * rx_byte - received byte during counter DMA interval 13371 * 13372 * Returns: 13373 * SOC_E_* 13374 */ 13375 static int 13376 _soc_xgs3_update_link_activity(int unit, soc_port_t port, 13377 uint32 tx_byte, uint32 rx_byte) 13378 { 13379 soc_control_t *soc = SOC_CONTROL(unit); 13380 int port_speed, interval, byte; 13381 uint32 portdata, act_byte; 13382 soc_info_t *si = &SOC_INFO(unit); 13383 13384 if (si->port_speed_max[port] >= 100000) { 13385 port_speed = si->port_speed_max[port]; 13386 } else { 13387 SOC_IF_ERROR_RETURN(soc_mac_speed_get(unit, port, &port_speed)); 13388 } 13389 13390 portdata = 0; 13391 interval = soc->counter_interval; 13392 13393 if (tx_byte < rx_byte) { 13394 act_byte = rx_byte; 13395 } else { 13396 act_byte = tx_byte; 13397 } 13398 13399 if (act_byte > (uint32)(((port_speed / 8) * interval) / 2)) { 13400 /* transmitting or receiving more than 50% */ 13401 portdata |= 0x2; 13402 } else if (act_byte > (uint32)(((port_speed / 8) * interval) / 4)) { 13403 /* transmitting or receiving more than 25% */ 13404 portdata |= 0x4; 13405 } else if (act_byte > 0) { 13406 /* some transmitting or receiving activity on the link */ 13407 portdata |= 0x8; 13408 } 13409 13410 if (tx_byte) { 13411 /* Indicate TX activity */ 13412 portdata |= 0x10; 13413 } 13414 if (rx_byte) { 13415 /* Indicate RX activity */ 13416 portdata |= 0x20; 13417 } 13418 13419 #ifdef BCM_TRIDENT_SUPPORT 13420 #define MONTEREY_LEDUP_PORT_MAX 64 13421 #define APACHE_LEDUP_PORT_MAX 36 13422 #define TRIDENT_LEDUP0_PORT_MAX 36 13423 #define TRIDENT2_LEDUP0_PORT_MAX 64 13424 13425 if (SOC_IS_TD_TT(unit)) { 13426 soc_info_t *si; 13427 int phy_port; /* physical port number */ 13428 uint32 dram_base; 13429 uint32 prev_data; 13430 13431 si = &SOC_INFO(unit); 13432 phy_port = si->port_l2p_mapping[port]; 13433 13434 /* trident first 36 ports in ledproc0, the other 36 ports in ledproc1*/ 13435 if (phy_port > TRIDENT_LEDUP0_PORT_MAX) { 13436 phy_port -= TRIDENT_LEDUP0_PORT_MAX; 13437 dram_base = CMICE_LEDUP1_DATA_RAM_BASE; 13438 } else { 13439 dram_base = CMICE_LEDUP0_DATA_RAM_BASE; 13440 } 13441 #ifdef BCM_CMICM_SUPPORT 13442 if (soc_feature(unit, soc_feature_cmicm)) { 13443 if (SOC_IS_TRIDENT2X(unit) && !SOC_IS_APACHE(unit)) { 13444 int i, skip_count = 0; 13445 int led_ix = (phy_port > TRIDENT2_LEDUP0_PORT_MAX)? 1:0; 13446 for (i=1; i<phy_port; i++) { 13447 skip_count += ((si->port_p2l_mapping[i+(led_ix*TRIDENT2_LEDUP0_PORT_MAX)] == -1) ? 1: 0); 13448 } 13449 if (phy_port > TRIDENT2_LEDUP0_PORT_MAX) { 13450 phy_port -= TRIDENT2_LEDUP0_PORT_MAX; 13451 dram_base = CMIC_LEDUP1_DATA_RAM_OFFSET; 13452 } else { 13453 dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET; 13454 } 13455 phy_port -= skip_count; 13456 } else if (SOC_IS_MONTEREY(unit) ) { 13457 phy_port = si->port_l2p_mapping[port]; 13458 dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET; 13459 } else if (SOC_IS_APACHE(unit) ) { 13460 phy_port = si->port_l2p_mapping[port]; 13461 /* Apache first 36 ports in ledproc0, the other 36 ports in ledproc1*/ 13462 if (phy_port > APACHE_LEDUP_PORT_MAX) { 13463 phy_port -= APACHE_LEDUP_PORT_MAX; 13464 dram_base = CMIC_LEDUP1_DATA_RAM_OFFSET; 13465 } else { 13466 dram_base = CMIC_LEDUP0_DATA_RAM_OFFSET; 13467 } 13468 } 13469 } 13470 #endif /* BCM_CMICM_SUPPORT */ 13471 if (soc_feature(unit, soc_feature_led_data_offset_a0)) { 13472 byte = LS_LED_DATA_OFFSET_A0 + phy_port; 13473 if (SOC_IS_APACHE(unit)) { 13474 byte -= 1; /* Start from A0 offset */ 13475 } 13476 } else { 13477 byte = LS_LED_DATA_OFFSET + phy_port; 13478 } 13479 13480 prev_data = soc_pci_read(unit, dram_base + CMIC_LED_REG_SIZE * byte); 13481 prev_data &= ~0x3e; 13482 portdata |= prev_data; 13483 soc_pci_write(unit, dram_base + CMIC_LED_REG_SIZE * byte, portdata); 13484 13485 } else 13486 #ifdef BCM_SABER2_SUPPORT 13487 if (SOC_IS_SABER2(unit)) { 13488 uint32 lastdata = 0; 13489 byte = LS_LED_DATA_OFFSET_A0 + port; 13490 lastdata = soc_pci_read(unit, CMIC_LEDUP0_DATA_RAM_OFFSET + CMIC_LED_REG_SIZE * byte); 13491 lastdata &= ~0x30; 13492 portdata |= lastdata; 13493 soc_pci_write(unit, CMIC_LEDUP0_DATA_RAM_OFFSET + CMIC_LED_REG_SIZE * byte, portdata); 13494 } else 13495 #endif 13496 #endif 13497 { 13498 /* 20 bytes from LS_LED_DATA_OFFSET is used by linkscan callback */ 13499 byte = LS_LED_DATA_OFFSET + 20 + port; 13500 soc_pci_write(unit, CMIC_LED_DATA_RAM(byte), portdata); 13501 } 13502 return SOC_E_NONE; 13503 } 13504 #endif 13505 #endif /* BCM_XGS_SUPPORT */ 13506 13507 #if defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT) 13508 /* 13509 * Function: 13510 * soc_counter_collect64 13511 * Purpose: 13512 * This routine gets called each time the counter transfer has 13513 * completed a cycle. It collects the 64-bit counters. 13514 * Parameters: 13515 * unit - StrataSwitch unit #. 13516 * discard - If true, the software counters are not updated; this 13517 * results in only synchronizing the previous hardware 13518 * count buffer. 13519 * tmp_port - if -1 sw accumulation of all the counters done. 13520 * port valid when hw_ctr_reg is valid 13521 * hw_ctr_reg - if -1 sw accumulation of all the counters done. 13522 * else hw register value of the tmp_port synced 13523 * to sw counter. 13524 * Returns: 13525 * SOC_E_XXX 13526 * Notes: 13527 * It computes the deltas in the hardware counters from the last 13528 * time it was called and adds them to the high resolution (64-bit) 13529 * software counters in counter_sw_val[]. It takes wrapping into 13530 * account for counters that are less than 64 bits wide. 13531 * It also computes counter_delta[]. 13532 */ 13533 13534 STATIC int 13535 soc_counter_collect64(int unit, int discard, soc_port_t tmp_port, soc_reg_t hw_ctr_reg) 13536 { 13537 soc_control_t *soc = SOC_CONTROL(unit); 13538 soc_port_t port; 13539 soc_reg_t ctr_reg; 13540 uint64 ctr_new, ctr_prev, ctr_diff; 13541 int index, max_index; 13542 int port_base, port_base_dma; 13543 int dma = 0; 13544 int recheck_cntrs; 13545 int ar_idx; 13546 pbmp_t counter_pbmp; 13547 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 13548 int pio_hold, pio_hold_enable; 13549 uint64 *counter_tmp = NULL; 13550 uint32 tx_byt_to_led = 0; 13551 uint32 rx_byt_to_led = 0; 13552 int rxcnt_xaui = 0; 13553 int skip_xaui_rx_counters; 13554 soc_reg_t reg_1a = INVALIDr; 13555 soc_reg_t reg_1b = INVALIDr; 13556 soc_reg_t reg_2a = INVALIDr; 13557 soc_reg_t reg_2b = INVALIDr; 13558 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 13559 13560 LOG_DEBUG(BSL_LS_SOC_COUNTER, 13561 (BSL_META_U(unit, 13562 "soc_counter_collect64: unit=%d discard=%d\n"), 13563 unit, discard)); 13564 13565 COMPILER_64_ZERO(ctr_new); 13566 COMPILER_64_ZERO(ctr_prev); 13567 COMPILER_64_ZERO(ctr_diff); 13568 13569 /* hw_ctr_reg is INVALIDr for normal sw counter accumulation */ 13570 if (hw_ctr_reg == INVALIDr) { 13571 dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) && (discard != TRUE)); 13572 } 13573 recheck_cntrs = soc_feature(unit, soc_feature_recheck_cntrs); 13574 13575 #ifdef BCM_BRADLEY_SUPPORT 13576 pio_hold = SOC_IS_HBX(unit); 13577 pio_hold_enable = (soc->counter_flags & SOC_COUNTER_F_HOLD); 13578 13579 if (SOC_IS_HBX(unit) && soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) { 13580 13581 rxcnt_xaui = 1; 13582 reg_1a = MAC_TXPSETHRr; 13583 reg_1b = IRFCSr; 13584 reg_2a = MAC_TXMAXSZr; 13585 reg_2b = IROVRr; 13586 if (dma) { 13587 counter_tmp = soc_counter_tbuf[unit]; 13588 } 13589 } 13590 #endif /* BCM_BRADLEY_SUPPORT */ 13591 13592 #ifdef BCM_TRX_SUPPORT 13593 if (SOC_IS_TRX(unit) && soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) { 13594 13595 rxcnt_xaui = 1; 13596 reg_1a = MAC_TXPSETHRr; 13597 #ifdef BCM_ENDURO_SUPPORT 13598 if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) { 13599 reg_1b = IRUCAr; 13600 } else 13601 #endif /* BCM_ENDURO_SUPPORT */ 13602 { 13603 reg_1b = IRUCr; 13604 } 13605 reg_2a = MAC_TXMAXSZr; 13606 reg_2b = IRFCSr; 13607 if (dma) { 13608 counter_tmp = soc_counter_tbuf[unit]; 13609 } 13610 } 13611 #endif /* BCM_TRX_SUPPORT */ 13612 13613 if (hw_ctr_reg == INVALIDr) { 13614 /* accumulate sw counters for all ports */ 13615 SOC_PBMP_CLEAR(counter_pbmp); 13616 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp); 13617 } else { 13618 /* sync and accumulate sw counter for specified register of port */ 13619 SOC_PBMP_CLEAR(counter_pbmp); 13620 port = tmp_port; 13621 SOC_PBMP_PORT_ADD(counter_pbmp, port); 13622 } 13623 13624 PBMP_ITER(counter_pbmp, port) { 13625 /* 13626 * Flexing operations on certain devices can create new ports, 13627 * or delete existing ports. This can happen when the counter 13628 * thread is not running. So we make a check here before proceeding 13629 * with further processing. We ignore processing for ports which no 13630 * longer exist. 13631 */ 13632 if (!SOC_CONTROL(unit)->counter_map[port]) { 13633 continue; 13634 } 13635 13636 if (!SOC_IS_XGS3_SWITCH(unit) && !SOC_IS_ARAD(unit) && 13637 !IS_HG_PORT(unit, port) && !IS_XE_PORT(unit, port)) { 13638 continue; 13639 } 13640 13641 port_base = COUNTER_MIN_IDX_GET(unit, port); 13642 port_base_dma = COUNTER_MIN_IDX_GET(unit, port - soc->counter_ports32); 13643 13644 #ifdef BCM_PETRA_SUPPORT 13645 if (SOC_IS_ARAD(unit)) { 13646 if (_SOC_CONTROLLED_COUNTER_USE(unit, port)) { 13647 continue; 13648 } 13649 port_base += _SOC_CONTROLLED_COUNTER_NOF(unit); 13650 } 13651 #endif /*BCM_PETRA_SUPPORT*/ 13652 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 13653 /* 13654 * Handle XAUI Rx counter bug. 13655 * 13656 * If the IRFCS counter returns the contents of the 13657 * MAC_TXPSETHR register, and the IROVR counter returns the 13658 * contents of the MAC_TXMAXSZ register, we assume that the 13659 * counters are bogus. 13660 * 13661 * By using two counters we significantly reduce the chance of 13662 * getting stuck if the real counter value matches the bogus 13663 * reference. 13664 * 13665 * To protect ourselves from the error condition happening 13666 * while the counter DMA is in progress, we manually check the 13667 * counters before and after we copy the DMA buffer contents. 13668 */ 13669 skip_xaui_rx_counters = 1; 13670 if (rxcnt_xaui && 13671 (IS_GX_PORT(unit, port) || 13672 (IS_XG_PORT(unit, port) && 13673 (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))))) { 13674 uint64 val_1a, val_1b, val_2a, val_2b; 13675 uint32 *p1, *p2; 13676 int rxcnt_appear_valid = 0; 13677 13678 /* Read reference values and counter values */ 13679 if (soc_reg_get(unit, reg_1a, port, 0, &val_1a) == 0 && 13680 soc_reg_get(unit, reg_1b, port, 0, &val_1b) == 0 && 13681 soc_reg_get(unit, reg_2a, port, 0, &val_2a) == 0 && 13682 soc_reg_get(unit, reg_2b, port, 0, &val_2b) == 0) { 13683 13684 /* Check for bogus values */ 13685 if (COMPILER_64_NE(val_1a, val_1b) || 13686 COMPILER_64_NE(val_2a, val_2b)) { 13687 rxcnt_appear_valid = 1; 13688 } 13689 if (rxcnt_appear_valid && counter_tmp) { 13690 /* Copy DMA buffer */ 13691 sal_memcpy(counter_tmp, &soc->counter_buf64[port_base_dma], 13692 SOC_COUNTER_TBUF_SIZE(unit)); 13693 p1 = (uint32 *)&counter_tmp[SOC_REG_CTR_IDX(unit, reg_1b)]; 13694 p2 = (uint32 *)&counter_tmp[SOC_REG_CTR_IDX(unit, reg_2b)]; 13695 /* Read counter values again */ 13696 if (soc_reg_get(unit, reg_1b, port, 0, &val_1b) == 0 && 13697 soc_reg_get(unit, reg_2b, port, 0, &val_2b) == 0) { 13698 /* Check for bogus value again, including DMA buffer */ 13699 if ((COMPILER_64_NE(val_1a, val_1b) || 13700 COMPILER_64_NE(val_2a, val_2b)) && 13701 (p1[0] != COMPILER_64_LO(val_1a) || 13702 p2[0] != COMPILER_64_LO(val_2a))) { 13703 /* Counters appears to be valid */ 13704 skip_xaui_rx_counters = 0; 13705 } 13706 } 13707 } else if (rxcnt_appear_valid && !dma) { 13708 /* If not DMA we take the chance and read the counters */ 13709 skip_xaui_rx_counters = 0; 13710 } 13711 } 13712 } 13713 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 13714 13715 if (hw_ctr_reg == INVALIDr) { 13716 index = 0; 13717 max_index = PORT_CTR_NUM(unit, port); 13718 } else { 13719 int port_index1, num_entries1; 13720 char *cname; 13721 13722 /* get index of counter register */ 13723 SOC_IF_ERROR_RETURN(_soc_counter_get_info(unit, port, hw_ctr_reg, 13724 &port_index1, &num_entries1, 13725 &cname)); 13726 13727 index = port_index1 - port_base; 13728 max_index = index + 1; 13729 } 13730 13731 for ( ; index < max_index; index++) { 13732 volatile uint64 *vptr; 13733 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 13734 13735 ctr_reg = PORT_CTR_REG(unit, port, index)->reg; 13736 ar_idx = PORT_CTR_REG(unit, port, index)->index; 13737 13738 if (SOC_COUNTER_INVALID(unit, ctr_reg)) { 13739 continue; 13740 } 13741 if ((ctr_reg < NUM_SOC_REG) && !SOC_REG_PORT_IDX_VALID(unit,ctr_reg, port, ar_idx)) { 13742 continue; 13743 } 13744 13745 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 13746 /* Trap for BigMAC TX Timestamp FIFO reads 13747 * 13748 * MAC_TXTIMESTAMPFIFOREADr is immediately after 13749 * MAC_RXLLFCMSGCNTr. It is a single register exposing 13750 * a HW FIFO which pops on read. And it is in the counter 13751 * DMA range. So we detect MAC_RXLLFCMSGCNTr and record 13752 * the value of the next piece of data in a SW FIFO for 13753 * use by the API. 13754 */ 13755 if (soc_feature(unit, soc_feature_timestamp_counter) && 13756 dma && (ctr_reg == MAC_RXLLFCMSGCNTr) && 13757 (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) && 13758 (soc->counter_timestamp_fifo[port] != NULL) && 13759 !SHR_FIFO_IS_FULL(soc->counter_timestamp_fifo[port])) { 13760 uint32 *ptr = 13761 (uint32 *)&soc->counter_buf64[port_base_dma + index + 1]; 13762 13763 if (ptr[0] != 0) { /* Else, HW FIFO empty */ 13764 SHR_FIFO_PUSH(soc->counter_timestamp_fifo[port], &(ptr[0])); 13765 } 13766 } 13767 /*If spn_SW_TIMESTAMP_FIFO_ENABLE is 0, the counter DMA will not 13768 *read register MAC_TXTIMESTAMPFIFOREAD. 13769 */ 13770 if (!SOC_CONTROL(unit)->sw_timestamp_fifo_enable && 13771 IS_XE_PORT(unit, port) && 13772 (index >= (DIRECT_TIMESTAMP_DMA_COUNTER_NUM + 13773 XMAC_DMA_COUNTER_BASE))) { 13774 dma = FALSE; 13775 } 13776 13777 #endif /* BCM_TRIUMPH2_SUPPORT */ 13778 13779 /* Atomic because soc_counter_set may update 64-bit value */ 13780 COUNTER_ATOMIC_BEGIN(s); 13781 ctr_prev = soc->counter_hw_val[port_base + index]; 13782 COUNTER_ATOMIC_END(s); 13783 13784 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 13785 if (pio_hold && ctr_reg == HOLDr) { 13786 if (pio_hold_enable) { 13787 uint64 ctr_prev_x, ctr_prev_y; 13788 uint32 ctr_x, ctr_y; 13789 int idx_x, idx_y; 13790 /* 13791 * We need to account for the two values of HOLD 13792 * separately to get correct rollover behavior. 13793 * Use holes in counter space to store HOLD_X/Y values 13794 * HOLD_X at RDBGC4r, hole, IUNHGIr 13795 * HOLD_Y at IUNKOPCr, hole, RDBGC5r 13796 */ 13797 13798 idx_x = SOC_REG_CTR_IDX(unit, RDBGC4r) + 1; 13799 idx_y = SOC_REG_CTR_IDX(unit, IUNKOPCr) + 1; 13800 13801 COUNTER_ATOMIC_BEGIN(s); 13802 ctr_prev_x = soc->counter_hw_val[port_base + idx_x]; 13803 ctr_prev_y = soc->counter_hw_val[port_base + idx_y]; 13804 COUNTER_ATOMIC_END(s); 13805 13806 SOC_IF_ERROR_RETURN 13807 (soc_reg32_get(unit, HOLD_Xr, port, ar_idx, 13808 &ctr_x)); 13809 SOC_IF_ERROR_RETURN 13810 (soc_reg32_get(unit, HOLD_Yr, port, ar_idx, 13811 &ctr_y)); 13812 13813 if (discard) { 13814 /* Just save the new sum to be used below */ 13815 COMPILER_64_SET(ctr_new, 0, ctr_x + ctr_y); 13816 } else { 13817 int width = 0; 13818 uint64 wrap_amt; 13819 13820 COMPILER_64_SET(ctr_diff, 0, ctr_x); 13821 /* We know the width of HOLDr is < 32 */ 13822 if (COMPILER_64_LT(ctr_diff, ctr_prev_x)) { 13823 width = 13824 SOC_REG_INFO(unit, ctr_reg).fields[0].len; 13825 COMPILER_64_SET(wrap_amt, 0, 1UL << width); 13826 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 13827 } 13828 /* Calculate HOLD_X diff from previous */ 13829 COMPILER_64_SUB_64(ctr_diff, ctr_prev_x); 13830 ctr_new = ctr_diff; 13831 13832 COMPILER_64_SET(ctr_diff, 0, ctr_y); 13833 if (COMPILER_64_LT(ctr_diff, ctr_prev_y)) { 13834 width = 13835 SOC_REG_INFO(unit, ctr_reg).fields[0].len; 13836 COMPILER_64_SET(wrap_amt, 0, 1UL << width); 13837 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 13838 } 13839 /* Calculate HOLD_Y diff from previous */ 13840 COMPILER_64_SUB_64(ctr_diff, ctr_prev_y); 13841 13842 /* Combine diffs */ 13843 COMPILER_64_ADD_64(ctr_new, ctr_diff); 13844 /* Add previous value so logic below handles 13845 * all of the other updates */ 13846 COMPILER_64_ADD_64(ctr_new, ctr_prev); 13847 } 13848 13849 /* Update previous values with new values. 13850 * Since these are INVALID registers, the other 13851 * counter logic will not touch them. */ 13852 COMPILER_64_SET(soc->counter_hw_val[port_base + idx_x], 0, ctr_x); 13853 COMPILER_64_SET(soc->counter_hw_val[port_base + idx_y], 0, ctr_y); 13854 } else { 13855 /* 13856 * The counter collected by DMA is not reliable 13857 * due to incorrect access type, so force zero. 13858 */ 13859 COMPILER_64_ZERO(ctr_new); 13860 } 13861 } else if (IS_HYPLITE_PORT(unit, port) && is_xaui_rx_counter(ctr_reg)) { 13862 SOC_IF_ERROR_RETURN 13863 (soc_reg_read(unit, ctr_reg, 13864 soc_reg_addr(unit, ctr_reg, port, ar_idx), 13865 &ctr_new)); 13866 } else if (rxcnt_xaui && is_xaui_rx_counter(ctr_reg)) { 13867 if (skip_xaui_rx_counters) { 13868 ctr_new = ctr_prev; 13869 } else if (counter_tmp) { 13870 uint32 *ptr = (uint32 *)&counter_tmp[index]; 13871 /* No need to check for SWAP64 flag */ 13872 COMPILER_64_SET(ctr_new, ptr[1], ptr[0]); 13873 } else { 13874 SOC_IF_ERROR_RETURN 13875 (soc_reg_get(unit, ctr_reg, port, ar_idx, 13876 &ctr_new)); 13877 } 13878 } else 13879 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 13880 if (dma) { 13881 #ifdef BCM_SBUSDMA_SUPPORT 13882 #ifdef SOC_COUNTER_TABLE_SUPPORT 13883 if (SOC_IS_TOMAHAWK3(unit) && 13884 soc_feature(unit, soc_feature_sbusdma) && 13885 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 13886 uint32 *ptr; 13887 int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[index - soc->counter_mib_tbl_first].dma_offset; 13888 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset]; 13889 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 13890 COMPILER_64_SET(ctr_new, ptr[0], ptr[1]); 13891 } else { 13892 COMPILER_64_SET(ctr_new, ptr[1], ptr[0]); 13893 } 13894 } else 13895 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 13896 if (soc_feature(unit, soc_feature_sbusdma) && 13897 (ctr_reg < NUM_SOC_REG) && 13898 !SOC_REG_IS_64(unit, ctr_reg)) { 13899 uint32 *buf32, *ptr, temp = 0; 13900 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) { 13901 if (index < soc->counter_egr_first) { 13902 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 13903 soc->counter_ing_first]; 13904 ptr = &buf32[index - soc->counter_ing_first]; 13905 } else { 13906 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 13907 soc->counter_egr_first]; 13908 ptr = &buf32[index - soc->counter_egr_first]; 13909 } 13910 temp = *ptr & ((1 << soc_reg_field_length 13911 (unit, ctr_reg, COUNTf)) - 1); 13912 } else { 13913 if (index < soc->counter_egr_first) { 13914 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 13915 soc->counter_ing_first]; 13916 ptr = &buf32[index - soc->counter_ing_first]; 13917 } else if (index < soc->counter_mac_first) { 13918 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 13919 soc->counter_egr_first]; 13920 ptr = &buf32[index - soc->counter_egr_first]; 13921 } else { 13922 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 13923 soc->counter_mac_first]; 13924 ptr = &buf32[index - soc->counter_mac_first]; 13925 } 13926 13927 if (soc_reg_field_length(unit, ctr_reg, COUNTf) == 32) { 13928 temp = *ptr & 0xffffffff; 13929 } else { 13930 temp = *ptr & ((1 << soc_reg_field_length 13931 (unit, ctr_reg, COUNTf)) - 1); 13932 } 13933 } 13934 COMPILER_64_SET(ctr_new, 0, temp); 13935 } else 13936 #endif /* BCM_SBUSDMA_SUPPORT */ 13937 { 13938 uint32 *ptr = 13939 (uint32 *)&soc->counter_buf64[port_base_dma + index]; 13940 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 13941 COMPILER_64_SET(ctr_new, ptr[0], ptr[1]); 13942 } else { 13943 COMPILER_64_SET(ctr_new, ptr[1], ptr[0]); 13944 } 13945 } 13946 } else { 13947 if(ctr_reg < NUM_SOC_REG) { 13948 SOC_IF_ERROR_RETURN 13949 (soc_reg_get(unit, ctr_reg, port, ar_idx, 13950 &ctr_new)); 13951 } 13952 #ifdef SOC_COUNTER_TABLE_SUPPORT 13953 else if (SOC_IS_TOMAHAWK3(unit) && 13954 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 13955 soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL; 13956 SOC_IF_ERROR_RETURN 13957 (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry)); 13958 SOC_IF_ERROR_RETURN 13959 (_soc_ctr_tbl_field_get(unit, ctr_reg, port, ctr_tbl_info_entry, &ctr_new)); 13960 } 13961 #endif /* SOC_COUNTER_TABLE_SUPPORT */ 13962 } 13963 13964 /* 13965 * For counter sync operation update the dma buffer 13966 * for the port index with the value read from hardware 13967 * counter register. 13968 */ 13969 if ((hw_ctr_reg != INVALIDr) && 13970 (soc->counter_flags & SOC_COUNTER_F_DMA)) { 13971 uint32 *ptr; 13972 #ifdef BCM_SBUSDMA_SUPPORT 13973 if (soc_feature(unit, soc_feature_sbusdma) && 13974 (ctr_reg < NUM_SOC_REG) && 13975 !SOC_REG_IS_64(unit, ctr_reg)) { 13976 uint32 *buf32; 13977 if (SOC_IS_TOMAHAWKX(unit)) { 13978 if (index < soc->counter_egr_first) { 13979 buf32 = (uint32 *)&soc->counter_buf64[ 13980 port_base_dma + 13981 soc->counter_ing_first]; 13982 ptr = &buf32[index - soc->counter_ing_first]; 13983 } else { 13984 buf32 = (uint32 *)&soc->counter_buf64[ 13985 port_base_dma + 13986 soc->counter_egr_first]; 13987 ptr = &buf32[index - soc->counter_egr_first]; 13988 } 13989 } else { 13990 if (index < soc->counter_egr_first) { 13991 buf32 = (uint32 *)&soc->counter_buf64[ 13992 port_base_dma + 13993 soc->counter_ing_first]; 13994 ptr = &buf32[index - soc->counter_ing_first]; 13995 } else if (index < soc->counter_mac_first) { 13996 buf32 = (uint32 *)&soc->counter_buf64[ 13997 port_base_dma + 13998 soc->counter_egr_first]; 13999 ptr = &buf32[index - soc->counter_egr_first]; 14000 } else { 14001 buf32 = (uint32 *)&soc->counter_buf64[ 14002 port_base_dma + 14003 soc->counter_mac_first]; 14004 ptr = &buf32[index - soc->counter_mac_first]; 14005 } 14006 } 14007 COUNTER_ATOMIC_BEGIN(s); 14008 if (soc_reg_field_length( 14009 unit, ctr_reg, COUNTf) == 32) { 14010 COMPILER_64_TO_32_LO(ptr[0], ctr_new); 14011 } else { 14012 ptr[0] = COMPILER_64_LO(ctr_new) & 14013 ((1 << soc_reg_field_length 14014 (unit, ctr_reg, COUNTf)) - 1); 14015 } 14016 COUNTER_ATOMIC_END(s); 14017 14018 } else 14019 #endif /* BCM_SBUSDMA_SUPPORT */ 14020 { 14021 #ifdef BCM_TOMAHAWK3_SUPPORT 14022 if (SOC_IS_TOMAHAWK3(unit) && 14023 soc_feature(unit, soc_feature_sbusdma) && 14024 SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 14025 int dma_offset = SOC_CTR_TBL_INFO(unit)->tables[index - soc->counter_mib_tbl_first].dma_offset; 14026 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + soc->counter_mib_tbl_first + dma_offset]; 14027 } else 14028 #endif 14029 { 14030 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + index]; 14031 } 14032 COUNTER_ATOMIC_BEGIN(s); 14033 /* Update the DMA location */ 14034 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 14035 COMPILER_64_TO_32_HI(ptr[0], ctr_new); 14036 COMPILER_64_TO_32_LO(ptr[1], ctr_new); 14037 } else { 14038 COMPILER_64_TO_32_LO(ptr[0], ctr_new); 14039 COMPILER_64_TO_32_HI(ptr[1], ctr_new); 14040 } 14041 COUNTER_ATOMIC_END(s); 14042 } 14043 }/* hw_ctr_reg != INVALIDr */ 14044 14045 if (soc_feature(unit, soc_feature_counter_parity) 14046 #ifdef BCM_HURRICANE2_SUPPORT 14047 || soc_reg_field_valid(unit, ctr_reg, PARITYf) 14048 #endif 14049 ) 14050 { 14051 uint32 temp; 14052 uint32 temp_len; 14053 if (soc_reg_field_valid(unit, ctr_reg, EVEN_PARITYf) || 14054 soc_reg_field_valid(unit, ctr_reg, PARITYf)) { 14055 temp_len = soc_reg_field_length(unit, ctr_reg, COUNTf); 14056 if (temp_len < 32) { 14057 temp = COMPILER_64_LO(ctr_new) & ((1 << temp_len) - 1); 14058 COMPILER_64_SET(ctr_new, 0, temp); 14059 } else { 14060 temp = COMPILER_64_HI(ctr_new) & 14061 ((1 << (temp_len - 32)) - 1); 14062 COMPILER_64_SET(ctr_new, temp, COMPILER_64_LO(ctr_new)); 14063 } 14064 } 14065 } 14066 14067 if ( (recheck_cntrs == TRUE) && 14068 COMPILER_64_NE(ctr_new, ctr_prev) ) { 14069 /* Seeds of doubt, double-check */ 14070 uint64 ctr_new2; 14071 int suspicious = 0; 14072 SOC_IF_ERROR_RETURN 14073 (soc_reg_get(unit, ctr_reg, port, 0, 14074 &ctr_new2)); 14075 14076 /* Check for partial ordering, with wrap */ 14077 if (COMPILER_64_LT(ctr_new, ctr_prev)) { 14078 if (COMPILER_64_LT(ctr_new2, ctr_new) || 14079 COMPILER_64_GE(ctr_new2, ctr_prev)) { 14080 /* prev < new2 < new, bad data */ 14081 /* Try again next time */ 14082 ctr_new = ctr_prev; 14083 suspicious = 1; 14084 } 14085 } else { 14086 if (COMPILER_64_LT(ctr_new2, ctr_new) && 14087 COMPILER_64_GE(ctr_new2, ctr_prev)) { 14088 /* prev < new2 < new, bad data */ 14089 /* Try again next time */ 14090 ctr_new = ctr_prev; 14091 suspicious = 1; 14092 } 14093 } 14094 /* Otherwise believe ctr_new */ 14095 14096 if (suspicious) { 14097 #if !defined(SOC_NO_NAMES) 14098 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 14099 (BSL_META_U(unit, 14100 "soc_counter_collect64: " 14101 "unit %d, port%d: suspicious %s " 14102 "counter read (%s)\n"), 14103 unit, port, 14104 dma?"DMA":"manual", 14105 SOC_REG_NAME(unit, ctr_reg))); 14106 #else 14107 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 14108 (BSL_META_U(unit, 14109 "soc_counter_collect64: " 14110 "unit %d, port%d: suspicious %s " 14111 "counter read (Counter%d)\n"), 14112 unit, port, 14113 dma?"DMA":"manual", 14114 ctr_reg)); 14115 #endif /* SOC_NO_NAMES */ 14116 } /* Suspicious counter change */ 14117 } /* recheck_cntrs == TRUE */ 14118 14119 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 14120 COUNTER_ATOMIC_BEGIN(s); 14121 COMPILER_64_ZERO(soc->counter_delta[port_base + index]); 14122 COUNTER_ATOMIC_END(s); 14123 continue; 14124 } 14125 14126 if (discard) { 14127 if (dma) { 14128 uint32 *ptr; 14129 #ifdef BCM_SBUSDMA_SUPPORT 14130 if (soc_feature(unit, soc_feature_sbusdma) && 14131 (ctr_reg < NUM_SOC_REG) && 14132 !SOC_REG_IS_64(unit, ctr_reg)) { 14133 uint32 *buf32; 14134 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) { 14135 if (index < soc->counter_egr_first) { 14136 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 14137 soc->counter_ing_first]; 14138 ptr = &buf32[index - soc->counter_ing_first]; 14139 } else { 14140 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 14141 soc->counter_egr_first]; 14142 ptr = &buf32[index - soc->counter_egr_first]; 14143 } 14144 } else { 14145 if (index < soc->counter_egr_first) { 14146 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 14147 soc->counter_ing_first]; 14148 ptr = &buf32[index - soc->counter_ing_first]; 14149 } else if (index < soc->counter_mac_first) { 14150 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 14151 soc->counter_egr_first]; 14152 ptr = &buf32[index - soc->counter_egr_first]; 14153 } else { 14154 buf32 = (uint32 *)&soc->counter_buf64[port_base_dma + 14155 soc->counter_mac_first]; 14156 ptr = &buf32[index - soc->counter_mac_first]; 14157 } 14158 } 14159 } else 14160 #endif 14161 { 14162 ptr = (uint32 *)&soc->counter_buf64[port_base_dma + index]; 14163 } 14164 COUNTER_ATOMIC_BEGIN(s); 14165 /* Update the DMA location */ 14166 if (soc->counter_flags & SOC_COUNTER_F_SWAP64) { 14167 COMPILER_64_TO_32_HI(ptr[0], ctr_new); 14168 COMPILER_64_TO_32_LO(ptr[1], ctr_new); 14169 } else { 14170 COMPILER_64_TO_32_LO(ptr[0], ctr_new); 14171 COMPILER_64_TO_32_HI(ptr[1], ctr_new); 14172 } 14173 } else { 14174 COUNTER_ATOMIC_BEGIN(s); 14175 } 14176 /* Update the previous value buffer */ 14177 soc->counter_hw_val[port_base + index] = ctr_new; 14178 COMPILER_64_ZERO(soc->counter_delta[port_base + index]); 14179 COUNTER_ATOMIC_END(s); 14180 continue; 14181 } 14182 14183 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 14184 (BSL_META_U(unit, 14185 "soc_counter_collect64: ctr %d => 0x%08x_%08x\n"), 14186 port_base + index, 14187 COMPILER_64_HI(ctr_new), COMPILER_64_LO(ctr_new))); 14188 14189 vptr = &soc->counter_sw_val[port_base + index]; 14190 14191 ctr_diff = ctr_new; 14192 14193 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 14194 int width, i = 0; 14195 uint64 wrap_amt; 14196 14197 /* 14198 * Counter must have wrapped around. 14199 * Add the proper wrap-around amount. 14200 */ 14201 #ifdef SOC_COUNTER_TABLE_SUPPORT 14202 if(SOC_REG_IS_COUNTER_TABLE(unit, ctr_reg)) { 14203 soc_ctr_tbl_entry_t *ctr_tbl_info_entry = NULL; 14204 14205 SOC_IF_ERROR_RETURN 14206 (_soc_counter_tbl_get_info(unit, port, ctr_reg, &ctr_tbl_info_entry)); 14207 width = soc_format_field_length(unit, 14208 ctr_tbl_info_entry->format, 14209 ctr_tbl_info_entry->ctr_field); 14210 } else 14211 #endif 14212 { 14213 width = SOC_REG_INFO(unit, ctr_reg).fields[0].len; 14214 if (soc_feature(unit, soc_feature_counter_parity) 14215 #ifdef BCM_HURRICANE2_SUPPORT 14216 || soc_reg_field_valid(unit, ctr_reg, PARITYf) 14217 #endif 14218 ) 14219 { 14220 while((SOC_REG_INFO(unit, ctr_reg).fields + i) != NULL) { 14221 if (SOC_REG_INFO(unit, ctr_reg).fields[i].field == 14222 COUNTf) { 14223 width = SOC_REG_INFO(unit, ctr_reg).fields[i].len; 14224 break; 14225 } 14226 i++; 14227 } 14228 } 14229 } 14230 if (width < 32) { 14231 COMPILER_64_SET(wrap_amt, 0, 1UL << width); 14232 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 14233 } else if (width < 64) { 14234 COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0); 14235 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 14236 } 14237 } 14238 14239 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 14240 14241 COUNTER_ATOMIC_BEGIN(s); 14242 COMPILER_64_ADD_64(*vptr, ctr_diff); 14243 soc->counter_delta[port_base + index] = ctr_diff; 14244 soc->counter_hw_val[port_base + index] = ctr_new; 14245 COUNTER_ATOMIC_END(s); 14246 14247 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14248 if (soc_feature(unit, soc_feature_ctr_xaui_activity)) { 14249 #ifdef BCM_TRIDENT_SUPPORT 14250 if (SOC_IS_TD_TT(unit)) { 14251 if (ctr_reg == RPKTr) { 14252 COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff); 14253 } else if (ctr_reg == TPKTr) { 14254 COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff); 14255 } 14256 } else 14257 #ifdef BCM_SABER2_SUPPORT 14258 if (SOC_IS_SABER2(unit)) { 14259 if (IS_MXQ_PORT(unit, port)) { 14260 if (ctr_reg == MXQ_RPKTr) { 14261 COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff); 14262 } else if (ctr_reg == MXQ_TPKTr) { 14263 COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff); 14264 } 14265 } else { 14266 if (ctr_reg == RPKTr) { 14267 COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff); 14268 } else if (ctr_reg == TPKTr) { 14269 COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff); 14270 } 14271 } 14272 14273 } else 14274 #endif 14275 #endif 14276 { 14277 #ifdef BCM_BRADLEY_SUPPORT 14278 if (ctr_reg == IRBYTr) { 14279 COMPILER_64_TO_32_LO(rx_byt_to_led, ctr_diff); 14280 } else if (ctr_reg == ITBYTr) { 14281 COMPILER_64_TO_32_LO(tx_byt_to_led, ctr_diff); 14282 } 14283 #endif 14284 } 14285 } 14286 #endif 14287 } 14288 14289 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 14290 if (soc_feature(unit, soc_feature_ctr_xaui_activity)) { 14291 _soc_xgs3_update_link_activity(unit, port, tx_byt_to_led, 14292 rx_byt_to_led); 14293 tx_byt_to_led = 0; 14294 rx_byt_to_led = 0; 14295 } 14296 #endif 14297 14298 #if defined(INCLUDE_PHY_8806X) 14299 phy_mt2_update_led_speed_activity(unit, port); 14300 #endif 14301 14302 /* If signaled to exit then return */ 14303 if (!soc->counter_interval) { 14304 return SOC_E_NONE; 14305 } 14306 14307 /* 14308 * Allow other tasks to run between processing each port. 14309 */ 14310 14311 if (hw_ctr_reg == INVALIDr) { 14312 COUNTER_UNLOCK(unit); 14313 sal_thread_yield(); 14314 COUNTER_LOCK(unit); 14315 } 14316 14317 if (!soc->counter_interval) { 14318 return SOC_E_NONE; 14319 } 14320 } 14321 14322 return SOC_E_NONE; 14323 } 14324 #endif /*defined(BCM_XGS_SUPPORT) || defined(BCM_PETRA_SUPPORT)*/ 14325 14326 #ifdef BCM_KATANA_SUPPORT 14327 STATIC int 14328 _soc_counter_katana_a0_non_dma_entries(int unit, int dma_id, int port_idx, 14329 int idx, soc_reg_t ctr_reg) 14330 14331 { 14332 soc_control_t *soc; 14333 soc_counter_non_dma_t *non_dma, *non_dma1; 14334 int base_index, id, width, i, index; 14335 int rv, entry_words; 14336 uint32 fval[2]; 14337 uint64 ctr_new; 14338 int buffer_seg, seg_addr; 14339 soc_mem_t buffer_mem, dma_mem; 14340 uint32 rval = 0; 14341 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 14342 int field_count; 14343 soc_field_t field; 14344 int dma_base_index; 14345 int num_non_dma_entries = 0; 14346 LOG_DEBUG(BSL_LS_SOC_COUNTER, 14347 (BSL_META_U(unit, 14348 "_soc_counter_katana_a0_non_dma_entries: unit=%d id=%d\n"), 14349 unit, dma_id)); 14350 14351 soc = SOC_CONTROL(unit); 14352 14353 if (soc->counter_non_dma == NULL) { 14354 return SOC_E_RESOURCE; 14355 } 14356 14357 non_dma = &soc->counter_non_dma[dma_id]; 14358 14359 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 14360 non_dma1 = &soc->counter_non_dma[dma_id + 1]; 14361 } else { 14362 return SOC_E_NONE; 14363 } 14364 14365 entry_words = soc_mem_entry_words(unit, non_dma->mem); 14366 if (non_dma->field != INVALIDf) { 14367 width = soc_mem_field_length(unit, non_dma->mem, 14368 non_dma->field); 14369 } else { 14370 width = 32; 14371 } 14372 14373 buffer_seg = (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) ? 14374 (11 * 1024) : (8 * 1024); 14375 buffer_mem = (soc_feature(unit, soc_feature_cosq_gport_stat_ability)) ? 14376 CTR_FLEX_COUNT_11m : CTR_FLEX_COUNT_8m; 14377 14378 for (id = 0; id < 2; id++) { 14379 index = non_dma->mem - CTR_FLEX_COUNT_0m; 14380 seg_addr = (id == 0) ? buffer_seg : (index * 1024); 14381 soc_reg_field_set(unit, CTR_SEGMENT_STARTr, &rval, SEG_STARTf, 14382 seg_addr); 14383 SOC_IF_ERROR_RETURN 14384 (soc_reg32_set(unit,CTR_SEGMENT_STARTr, REG_PORT_ANY,index, rval)); 14385 LOG_DEBUG(BSL_LS_SOC_COUNTER, 14386 (BSL_META_U(unit, 14387 "id=%d index=%d seg_addr=%d \n"), 14388 id, index, seg_addr)); 14389 if (ctr_reg == INVALIDr) { 14390 for (i = 0; i < 4; i++) { 14391 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 14392 if (non_dma->dma_buf[i] == NULL) { 14393 continue; 14394 } 14395 14396 dma_mem = (id == 0) ? non_dma->dma_mem[i] : (buffer_mem + i); 14397 rv = soc_mem_read_range(unit, dma_mem, 14398 MEM_BLOCK_ANY, 14399 non_dma->dma_index_min[i], 14400 non_dma->dma_index_max[i], 14401 non_dma->dma_buf[i]); 14402 if (SOC_FAILURE(rv)) { 14403 return rv; 14404 } 14405 } 14406 } 14407 dma_mem = non_dma->mem; 14408 base_index = non_dma->base_index; 14409 num_non_dma_entries = non_dma->num_entries; 14410 } 14411 else { 14412 /* Collect counter values for a specific port */ 14413 dma_mem = non_dma->dma_mem[0]; 14414 dma_base_index = port_idx - non_dma->base_index + 14415 non_dma->dma_index_min[0]; 14416 14417 for (i = 1; i < 4; i++) { 14418 if (non_dma->dma_buf[i] == NULL) { 14419 continue; 14420 } 14421 if (dma_base_index > non_dma->dma_index_max[i - 1]) { 14422 dma_mem = non_dma->dma_mem[i]; 14423 dma_base_index -= non_dma->dma_index_max[i - 1] + 1; 14424 dma_base_index += non_dma->dma_index_min[i]; 14425 14426 } 14427 } 14428 14429 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 14430 dma_base_index + idx, 14431 non_dma->dma_buf[0]); 14432 14433 14434 if (SOC_FAILURE(rv)) { 14435 return rv; 14436 } 14437 14438 base_index = port_idx + idx; 14439 num_non_dma_entries = 1; 14440 14441 } 14442 for (field_count = 0; field_count < 2; field_count++) { 14443 base_index = (field_count == 0) ? base_index : 14444 non_dma1->base_index; 14445 field = (field_count == 0) ? non_dma->field : 14446 non_dma1->field; 14447 for (i = 0; i < num_non_dma_entries; i++) { 14448 soc_mem_field_get(unit, dma_mem, 14449 &non_dma->dma_buf[0][entry_words * i], 14450 field, fval); 14451 if (width <= 32) { 14452 COMPILER_64_SET(ctr_new, 0, fval[0]); 14453 } else { 14454 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 14455 } 14456 14457 COUNTER_ATOMIC_BEGIN(s); 14458 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 14459 ctr_new); 14460 soc->counter_hw_val[base_index + i] = ctr_new; 14461 soc->counter_delta[base_index + i] = ctr_new; 14462 COUNTER_ATOMIC_END(s); 14463 } 14464 } 14465 } 14466 return SOC_E_NONE; 14467 } 14468 #endif /* BCM_KATANA_SUPPORT */ 14469 14470 STATIC int 14471 soc_counter_non_dma_ready(int unit, soc_counter_non_dma_t *non_dma, int *ctr_dma_ct) 14472 { 14473 soc_control_t *soc; 14474 int max_profile, curr_profile_pick, given_profiles; 14475 14476 soc = SOC_CONTROL(unit); 14477 14478 if (soc->counter_sync_req) { 14479 /* Return True for all Counters when sync is in Progress */ 14480 return 1; 14481 } 14482 14483 if ((!(non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT)) || 14484 (soc->ctr_evict_interval == 0)) { 14485 /* Traditional DMA. Hence return true. 14486 */ 14487 return 1; 14488 } 14489 14490 if (non_dma->dma_rate_profile & _SOC_COUNTER_DMA_RATE_PROFILE_ALL) { 14491 /* Enabled for All profiles */ 14492 return 1; 14493 } 14494 14495 14496 /* get max profile value */ 14497 max_profile = _SOC_COUNTER_DMA_RATE_PROFILE_MAX; 14498 14499 *ctr_dma_ct = *ctr_dma_ct % max_profile; 14500 curr_profile_pick = 1 << *ctr_dma_ct; 14501 14502 given_profiles = 14503 (non_dma->dma_rate_profile & _SOC_COUNTER_DMA_RATE_PROFILE_MASK) >> 14504 _SOC_COUNTER_DMA_RATE_PROFILE_OFFSET; 14505 14506 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 14507 (BSL_META_U(unit, 14508 "dma_prof 0x%x, pick_prof 0x%x, ctr_dma_ct %d\n"), 14509 given_profiles, curr_profile_pick, *ctr_dma_ct)); 14510 if (given_profiles & curr_profile_pick) { 14511 return 1; 14512 } 14513 14514 return 0; 14515 } 14516 14517 /* 14518 * Function: 14519 * soc_counter_collect_non_dma_entries 14520 * Purpose: 14521 * This routine collects and accumulates all the non-dmaable counters. 14522 * Gets invoked from the counter thread and _soc_counter_get. 14523 * Based on arg the ctr_reg 14524 * Parameters: 14525 * unit - StrataSwitch unit #. 14526 * tmp_port - StrataSwitch port #. 14527 * port_idx - port index 14528 * ar_idx - index 14529 * ctr_reg - if INVALIDr, collects and accumulates counter values for all 14530 * else collects and accumulates for a specified port. 14531 * Returns: 14532 * NONE 14533 * Notes: 14534 */ 14535 14536 STATIC void 14537 soc_counter_collect_non_dma_entries(int unit, 14538 int tmp_port, 14539 int port_idx, 14540 int ar_idx, 14541 soc_reg_t ctr_reg) 14542 { 14543 soc_control_t *soc; 14544 soc_counter_non_dma_t *non_dma; 14545 int base_index, width, i; 14546 int id = 0; 14547 int idx = 0; 14548 int port; 14549 uint32 fval[2]; 14550 uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt; 14551 int rv, count, entry_words; 14552 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 14553 int dma_base_index; 14554 int num_non_dma_entries = 0; 14555 soc_mem_t dma_mem; 14556 int non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 14557 SOC_COUNTER_NON_DMA_START; 14558 14559 int index_max = 0; 14560 int j, subset_ct; /* For Parent-Child Model */ 14561 14562 int qindex; 14563 int port_index, num_entries; 14564 char *cname; 14565 soc_reg_t ctr_tmp_reg; 14566 14567 soc = SOC_CONTROL(unit); 14568 14569 if (soc->counter_non_dma == NULL) { 14570 return; 14571 } 14572 14573 /* 14574 * if ctr_reg != -1, retrieve stats for a 14575 * specific port and queue from the hardware 14576 * update the sw copy of the same. 14577 */ 14578 if (ctr_reg >= NUM_SOC_REG) { 14579 id = ctr_reg - SOC_COUNTER_NON_DMA_START; 14580 non_dma_counter_end = id + 1; 14581 idx = (ar_idx < 0)? 0: ar_idx; 14582 } 14583 14584 for (; id < non_dma_counter_end; id++) { 14585 non_dma = &soc->counter_non_dma[id]; 14586 14587 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 14588 continue; 14589 } 14590 14591 /* If signaled to exit then return */ 14592 if (!soc->counter_interval) { 14593 return; 14594 } 14595 14596 width = entry_words = 0; 14597 14598 if (non_dma->mem != INVALIDm) { 14599 14600 #ifdef BCM_KATANA_SUPPORT 14601 if ((SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit)) && 14602 (soc_feature(unit, soc_feature_counter_toggled_read))) { 14603 14604 rv = _soc_counter_katana_a0_non_dma_entries(unit, id, port_idx, 14605 idx, ctr_reg); 14606 14607 if (SOC_FAILURE(rv)) { 14608 return; 14609 } else { 14610 continue; 14611 } 14612 } 14613 #endif 14614 14615 14616 entry_words = soc_mem_entry_words(unit, non_dma->mem); 14617 if (non_dma->field != INVALIDf) { 14618 width = soc_mem_field_length(unit, non_dma->mem, 14619 non_dma->field); 14620 } else { 14621 width = 32; 14622 } 14623 14624 if (ctr_reg == INVALIDr) { 14625 #ifdef BCM_KATANA2_SUPPORT 14626 for (i = 0; i < (SOC_IS_SABER2(unit) ? 2 : 4); i++) 14627 #else 14628 for (i = 0; i < NUM_PIPE(unit); i++) 14629 #endif 14630 { 14631 /* Do only if the Pipe mem is VALID. */ 14632 if (non_dma->dma_mem[i] == INVALIDm) { 14633 continue; 14634 } 14635 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 14636 14637 if (non_dma->dma_buf[i] == NULL) { 14638 continue; 14639 } 14640 14641 rv = soc_mem_read_range(unit, non_dma->dma_mem[i], 14642 MEM_BLOCK_ANY, 14643 non_dma->dma_index_min[i], 14644 non_dma->dma_index_max[i], 14645 non_dma->dma_buf[i]); 14646 14647 if (SOC_FAILURE(rv)) { 14648 return; 14649 } 14650 } 14651 } 14652 dma_mem = non_dma->mem; 14653 base_index = non_dma->base_index; 14654 index_max = non_dma->num_entries; 14655 14656 num_non_dma_entries = index_max; 14657 14658 } else { 14659 14660 /* Collect counter values for a specific port */ 14661 dma_mem = non_dma->dma_mem[0]; 14662 dma_base_index = port_idx - non_dma->base_index + 14663 non_dma->dma_index_min[0]; 14664 14665 for (i = 1; i < NUM_PIPE(unit); i++) { 14666 if (non_dma->dma_buf[i] == NULL) { 14667 continue; 14668 } 14669 14670 if (dma_base_index > non_dma->dma_index_max[i - 1]) { 14671 dma_mem = non_dma->dma_mem[i]; 14672 dma_base_index -= non_dma->dma_index_max[i - 1] + 1; 14673 dma_base_index += non_dma->dma_index_min[i]; 14674 } 14675 } 14676 14677 /* Need to retrieve the table index 14678 * for flexible mapping Non-DMA counter*/ 14679 if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) { 14680 if (non_dma->soc_counter_hw_idx_get == NULL) { 14681 continue; 14682 } 14683 rv = non_dma->soc_counter_hw_idx_get(unit, tmp_port, 14684 dma_base_index + idx, 14685 &qindex); 14686 if (SOC_FAILURE(rv)) { 14687 return; 14688 } 14689 if (-1 == qindex) { 14690 continue; 14691 } 14692 } else { 14693 qindex = dma_base_index + idx; 14694 } 14695 14696 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 14697 qindex, non_dma->dma_buf[0]); 14698 14699 14700 if (SOC_FAILURE(rv)) { 14701 return; 14702 } 14703 14704 base_index = port_idx + idx; 14705 num_non_dma_entries = 1; 14706 14707 } 14708 14709 /* For flexible mapping Non-DMA counter, need to assign the counter 14710 * value to SW structure based the table index retrieved 14711 * when the routine is to collect all the values 14712 * for all Non-DMA counters*/ 14713 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) 14714 && (ctr_reg == INVALIDr)) { 14715 ctr_tmp_reg = SOC_COUNTER_NON_DMA_START + id; 14716 PBMP_ITER(soc->counter_pbmp, port) { 14717 rv = _soc_counter_get_info(unit, port, ctr_tmp_reg, 14718 &port_index, &num_entries, 14719 &cname); 14720 if (SOC_FAILURE(rv)) { 14721 return; 14722 } 14723 dma_base_index = port_index - non_dma->base_index + 14724 non_dma->dma_index_min[0]; 14725 for (i = 0; i < num_entries; i++) { 14726 if (non_dma->soc_counter_hw_idx_get == NULL) { 14727 continue; 14728 } 14729 rv = non_dma->soc_counter_hw_idx_get(unit, port, 14730 dma_base_index + i, &qindex); 14731 if (SOC_FAILURE(rv)) { 14732 return; 14733 } 14734 if (-1 == qindex) { 14735 continue; 14736 } 14737 14738 soc_mem_field_get(unit, dma_mem, 14739 &non_dma->dma_buf[0][entry_words * qindex], 14740 non_dma->field, fval); 14741 if (width <= 32) { 14742 COMPILER_64_SET(ctr_new, 0, fval[0]); 14743 } else { 14744 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 14745 } 14746 if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) { 14747 COMPILER_64_SUB_32(ctr_new, 1); 14748 } 14749 14750 COUNTER_ATOMIC_BEGIN(s); 14751 ctr_prev = soc->counter_hw_val[port_index + i]; 14752 COUNTER_ATOMIC_END(s); 14753 14754 if (!(non_dma->flags 14755 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 14756 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 14757 COUNTER_ATOMIC_BEGIN(s); 14758 COMPILER_64_ZERO 14759 (soc->counter_delta[port_index + i]); 14760 COUNTER_ATOMIC_END(s); 14761 continue; 14762 } 14763 } 14764 14765 ctr_diff = ctr_new; 14766 14767 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 14768 COUNTER_ATOMIC_BEGIN(s); 14769 if (COMPILER_64_GT(ctr_new, 14770 soc->counter_sw_val[port_index + i])) { 14771 soc->counter_sw_val[port_index + i] = ctr_new; 14772 } 14773 soc->counter_hw_val[port_index + i] = ctr_new; 14774 COMPILER_64_ZERO 14775 (soc->counter_delta[port_index + i]); 14776 COUNTER_ATOMIC_END(s); 14777 continue; 14778 } 14779 14780 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 14781 COUNTER_ATOMIC_BEGIN(s); 14782 soc->counter_sw_val[port_index + i] = ctr_new; 14783 soc->counter_hw_val[port_index + i] = ctr_new; 14784 COMPILER_64_ZERO(soc->counter_delta[port_index + i]); 14785 COUNTER_ATOMIC_END(s); 14786 continue; 14787 } 14788 14789 if (!(non_dma->flags 14790 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 14791 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 14792 if (width < 32) { 14793 COMPILER_64_ADD_32(ctr_diff, 1U << width); 14794 } else if (width < 64) { 14795 COMPILER_64_SET( 14796 wrap_amt, 1U << (width - 32), 0); 14797 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 14798 } 14799 } 14800 14801 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 14802 } 14803 14804 COUNTER_ATOMIC_BEGIN(s); 14805 COMPILER_64_ADD_64(soc->counter_sw_val[port_index + i], 14806 ctr_diff); 14807 soc->counter_hw_val[port_index + i] = ctr_new; 14808 soc->counter_delta[port_index + i] = ctr_diff; 14809 COUNTER_ATOMIC_END(s); 14810 } 14811 } 14812 } else { 14813 for (i = 0; i < num_non_dma_entries; i++) { 14814 soc_mem_field_get(unit, non_dma->mem, 14815 &non_dma->dma_buf[0][entry_words * 14816 i], 14817 non_dma->field, fval); 14818 if (width <= 32) { 14819 COMPILER_64_SET(ctr_new, 0, fval[0]); 14820 } else { 14821 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 14822 } 14823 if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) { 14824 COMPILER_64_SUB_32(ctr_new, 1); 14825 } 14826 14827 COUNTER_ATOMIC_BEGIN(s); 14828 ctr_prev = soc->counter_hw_val[base_index + i]; 14829 COUNTER_ATOMIC_END(s); 14830 14831 if (!(non_dma->flags 14832 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 14833 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 14834 COUNTER_ATOMIC_BEGIN(s); 14835 COMPILER_64_ZERO 14836 (soc->counter_delta[base_index + i]); 14837 COUNTER_ATOMIC_END(s); 14838 continue; 14839 } 14840 } 14841 14842 ctr_diff = ctr_new; 14843 14844 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 14845 COUNTER_ATOMIC_BEGIN(s); 14846 if (COMPILER_64_GT 14847 (ctr_new, 14848 soc->counter_sw_val[base_index + i])) { 14849 soc->counter_sw_val[base_index + i] = ctr_new; 14850 } 14851 soc->counter_hw_val[base_index + i] = ctr_new; 14852 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 14853 COUNTER_ATOMIC_END(s); 14854 continue; 14855 } 14856 14857 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 14858 COUNTER_ATOMIC_BEGIN(s); 14859 soc->counter_sw_val[base_index + i] = ctr_new; 14860 soc->counter_hw_val[base_index + i] = ctr_new; 14861 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 14862 COUNTER_ATOMIC_END(s); 14863 continue; 14864 } 14865 14866 if (!(non_dma->flags 14867 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 14868 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 14869 if (width < 32) { 14870 COMPILER_64_ADD_32(ctr_diff, 1U << width); 14871 } else if (width < 64) { 14872 COMPILER_64_SET 14873 (wrap_amt, 1U << (width - 32), 0); 14874 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 14875 } 14876 } 14877 14878 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 14879 } 14880 14881 COUNTER_ATOMIC_BEGIN(s); 14882 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 14883 ctr_diff); 14884 soc->counter_hw_val[base_index + i] = ctr_new; 14885 soc->counter_delta[base_index + i] = ctr_diff; 14886 COUNTER_ATOMIC_END(s); 14887 } 14888 } 14889 } else if (non_dma->reg != INVALIDr) { 14890 pbmp_t counter_pbmp; 14891 14892 count = 0; 14893 if (non_dma->field != INVALIDf) { 14894 width = soc_reg_field_length(unit, non_dma->reg, 14895 non_dma->field); 14896 } else { 14897 width = 32; 14898 } 14899 14900 /* 14901 * If stats retrieval is for a specific 14902 * port, set the pbmp for counter collection. 14903 */ 14904 if (ctr_reg >= NUM_SOC_REG) { 14905 SOC_PBMP_CLEAR(counter_pbmp); 14906 port = tmp_port; 14907 SOC_PBMP_PORT_ADD(counter_pbmp, port); 14908 } else { 14909 SOC_PBMP_CLEAR(counter_pbmp); 14910 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp); 14911 } 14912 14913 PBMP_ITER(counter_pbmp, port) { 14914 /* 14915 * stats retrieval for a specific port. 14916 */ 14917 if (_soc_counter_non_dma_is_invalid(unit, non_dma->reg, port)) { 14918 continue; 14919 } 14920 j = 0; 14921 subset_ct = 0; 14922 14923 if (ctr_reg >= NUM_SOC_REG) { 14924 if (!SOC_PBMP_MEMBER(counter_pbmp, port)) { 14925 continue; 14926 } 14927 14928 if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) { 14929 if (non_dma->reg == TXLLFCMSGCNTr) { 14930 if (!IS_HG_PORT( unit, port)) { 14931 continue; 14932 } 14933 } 14934 } 14935 14936 i = idx; 14937 count = i + 1; 14938 base_index = port_idx; 14939 } else { 14940 if (non_dma->entries_per_port == 0) { 14941 /* 14942 * OK to over-write port variable as loop 14943 * breaks after 1 iter. Check below for 14944 * the same codition. 14945 */ 14946 port = REG_PORT_ANY; 14947 count = non_dma->num_entries; 14948 base_index = non_dma->base_index; 14949 } else { 14950 if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) { 14951 continue; 14952 } 14953 14954 if (SOC_IS_TR_VL(unit) || SOC_IS_SC_CQ(unit)) { 14955 if (non_dma->reg == TXLLFCMSGCNTr) { 14956 if (!IS_HG_PORT( unit, port)) { 14957 continue; 14958 } 14959 } 14960 } 14961 14962 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) { 14963 count = num_cosq[unit][port]; 14964 base_index = non_dma->base_index; 14965 for (i = 0; i < port; i++) { 14966 base_index += num_cosq[unit][i]; 14967 } 14968 #ifdef BCM_APACHE_SUPPORT 14969 } else if (SOC_IS_APACHE(unit) && 14970 (non_dma->flags & 14971 _SOC_COUNTER_NON_DMA_OBM)) { 14972 count = non_dma->entries_per_port; 14973 base_index = non_dma->base_index; 14974 subset_ct = non_dma->extra_ctr_ct; 14975 if (non_dma->extra_ctrs) { 14976 non_dma = non_dma->extra_ctrs; 14977 } 14978 #endif 14979 } else if (non_dma->flags & 14980 _SOC_COUNTER_NON_DMA_OBM) { 14981 count = non_dma->entries_per_port; 14982 base_index = non_dma->base_index + 14983 SOC_INFO(unit).port_group[port] * count; 14984 } else { 14985 count = non_dma->entries_per_port; 14986 base_index = non_dma->base_index + port * count; 14987 } 14988 } 14989 } 14990 14991 do { 14992 for (i = 0; i < count; i++) { 14993 #ifdef BCM_APACHE_SUPPORT 14994 if (SOC_IS_APACHE(unit) && 14995 (non_dma->flags & _SOC_COUNTER_NON_DMA_OBM)) { 14996 soc_reg_t reg = non_dma->reg; 14997 int pgw_inst = (i / _APACHE_PORTS_PER_XLP); 14998 pgw_inst = (pgw_inst | SOC_REG_ADDR_INSTANCE_MASK); 14999 base_index = non_dma->base_index; 15000 rv = soc_reg_get(unit, reg, pgw_inst, 15001 (i % _APACHE_PORTS_PER_XLP), &ctr_new); 15002 } else 15003 #endif 15004 { 15005 /* coverity[negative_returns : FALSE] */ 15006 rv = soc_reg_get(unit, non_dma->reg, port, i, &ctr_new); 15007 } 15008 if (SOC_FAILURE(rv)) { 15009 return; 15010 } 15011 COUNTER_ATOMIC_BEGIN(s); 15012 ctr_prev = soc->counter_hw_val[base_index + i]; 15013 COUNTER_ATOMIC_END(s); 15014 15015 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 15016 COUNTER_ATOMIC_BEGIN(s); 15017 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15018 COUNTER_ATOMIC_END(s); 15019 continue; 15020 } 15021 15022 ctr_diff = ctr_new; 15023 15024 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 15025 COUNTER_ATOMIC_BEGIN(s); 15026 if (COMPILER_64_GT(ctr_new, ctr_prev)) { 15027 soc->counter_sw_val[base_index + i] = ctr_new; 15028 } 15029 soc->counter_hw_val[base_index + i] = ctr_new; 15030 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15031 COUNTER_ATOMIC_END(s); 15032 continue; 15033 } 15034 15035 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 15036 COUNTER_ATOMIC_BEGIN(s); 15037 soc->counter_sw_val[base_index + i] = ctr_new; 15038 soc->counter_hw_val[base_index + i] = ctr_new; 15039 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15040 COUNTER_ATOMIC_END(s); 15041 continue; 15042 } 15043 15044 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 15045 if (width < 32) { 15046 COMPILER_64_ADD_32(ctr_diff, 1U << width); 15047 } else if (width < 64) { 15048 COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0); 15049 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 15050 } 15051 } 15052 15053 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 15054 15055 COUNTER_ATOMIC_BEGIN(s); 15056 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 15057 ctr_diff); 15058 soc->counter_hw_val[base_index + i] = ctr_new; 15059 soc->counter_delta[base_index + i] = ctr_diff; 15060 COUNTER_ATOMIC_END(s); 15061 } 15062 j++; 15063 if ((subset_ct > 1) && (j < subset_ct)) { 15064 non_dma += 2; 15065 } 15066 } while ((j < subset_ct) && non_dma); 15067 if ((non_dma->entries_per_port == 0) || 15068 (subset_ct != 0)) { 15069 break; 15070 } 15071 } 15072 } else { 15073 continue; 15074 } 15075 } 15076 } 15077 15078 #ifdef BCM_TOMAHAWK_SUPPORT 15079 STATIC void 15080 soc_counter_collect_th_non_dma_entries(int unit, 15081 int tmp_port, 15082 int port_idx, 15083 int ar_idx, 15084 soc_reg_t ctr_reg) 15085 { 15086 soc_control_t *soc; 15087 soc_counter_non_dma_t *non_dma; 15088 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 15089 soc_mem_t dma_mem; 15090 int base_index, width, i, j, id = 0, idx = 0, obm_flag = 0, port; 15091 uint32 fval[2], efp_ctr_rval; 15092 uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt; 15093 int rv, count, entry_words; 15094 int dma_base_index, num_non_dma_entries = 0; 15095 int non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 15096 SOC_COUNTER_NON_DMA_START; 15097 static int ctr_dma_ct = 0; 15098 int index_max = 0, max_pipe, pipe, default_entries_per_pipe = 0; 15099 uint32 subset_ct = 0; /* For Parent-Child Model */ 15100 int qindex, port_index, num_entries; 15101 char *cname; 15102 soc_reg_t ctr_tmp_reg; 15103 uint8 error_return = 0; 15104 15105 soc = SOC_CONTROL(unit); 15106 15107 if (soc->counter_non_dma == NULL) { 15108 return; 15109 } 15110 15111 max_pipe = SOC_CONTROL(unit)->max_num_pipe; /* store locally */ 15112 15113 if (soc_feature(unit, soc_feature_th_a0_sw_war) && 15114 soc->ctr_evict_interval) { 15115 soc_reg_t reg = EGR_EFP_CNTR_UPDATE_CONTROLr; 15116 efp_ctr_rval = 0; 15117 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &efp_ctr_rval); 15118 if (SOC_FAILURE(rv)) { 15119 return; 15120 } 15121 soc_reg_field_set(unit, reg, &efp_ctr_rval, CLR_ON_READf, 1); 15122 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, efp_ctr_rval); 15123 if (SOC_FAILURE(rv)) { 15124 return; 15125 } 15126 } 15127 15128 /* 15129 * if ctr_reg != -1, retrieve stats for a 15130 * specific port and queue from the hardware 15131 * update the sw copy of the same. 15132 */ 15133 if (ctr_reg >= NUM_SOC_REG) { 15134 id = ctr_reg - SOC_COUNTER_NON_DMA_START; 15135 non_dma_counter_end = id + 1; 15136 idx = (ar_idx < 0)? 0: ar_idx; 15137 } 15138 15139 for (; id < non_dma_counter_end; id++) { 15140 default_entries_per_pipe = 0; 15141 non_dma = &soc->counter_non_dma[id]; 15142 15143 if(non_dma == NULL) { 15144 continue; 15145 } 15146 15147 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 15148 continue; 15149 } 15150 15151 /* If signaled to exit then return */ 15152 if (!soc->counter_interval) { 15153 error_return = 1; 15154 goto done; 15155 } 15156 15157 width = entry_words = 0; 15158 15159 if (non_dma->mem != INVALIDm) { 15160 count = 0; 15161 /* If there is subset of counters, use subset info for DMA */ 15162 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) && 15163 (non_dma->extra_ctrs != NULL)) { 15164 #ifdef BCM_TOMAHAWK3_SUPPORT 15165 if(SOC_IS_TOMAHAWK3(unit) && (non_dma->extra_ctr_fld_ct != 0)) { 15166 subset_ct = non_dma->extra_ctr_ct; 15167 } else 15168 #endif 15169 { 15170 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 15171 subset_ct = non_dma->extra_ctr_ct << 1; 15172 } 15173 non_dma = non_dma->extra_ctrs; 15174 } else { 15175 subset_ct = 1; 15176 } 15177 15178 do { 15179 /* If signaled to exit then return */ 15180 if (!soc->counter_interval) { 15181 error_return = 1; 15182 goto done; 15183 } 15184 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 15185 count++; 15186 non_dma++; 15187 continue; 15188 } 15189 15190 /* Check if this Counter is up for DMA. 15191 * During Slow-DMA, not all counters are up for DMA at the same 15192 * time/frequency. 15193 */ 15194 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) && 15195 (!soc_counter_non_dma_ready(unit, non_dma, &ctr_dma_ct))) { 15196 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 15197 (BSL_META_U(unit, 15198 "id %d(%d): NOT pickd for DMA(pipes %d). Ct %d,mem %d/%d/%d\n"), 15199 id, SOC_COUNTER_NON_DMA_START, count, 15200 max_pipe, non_dma->mem, 15201 non_dma->dma_mem[0], non_dma->dma_mem[1])); 15202 count++; 15203 non_dma++; 15204 continue; 15205 } 15206 #ifdef BCM_TOMAHAWK3_SUPPORT 15207 if (SOC_IS_TOMAHAWK3(unit)) { 15208 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) && 15209 count == 0) { 15210 COUNTER_UNLOCK(unit); 15211 sal_thread_yield(); 15212 COUNTER_LOCK(unit); 15213 } 15214 } else 15215 #endif 15216 { 15217 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 15218 COUNTER_UNLOCK(unit); 15219 sal_thread_yield(); 15220 COUNTER_LOCK(unit); 15221 } 15222 } 15223 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 15224 (BSL_META_U(unit, 15225 "id %d(%d): picked for DMA(Pipes %d). mem %d/%d/%d\n"), 15226 id, SOC_COUNTER_NON_DMA_START, max_pipe, 15227 non_dma->mem, non_dma->dma_mem[0], 15228 non_dma->dma_mem[1])); 15229 15230 entry_words = soc_mem_entry_words(unit, non_dma->mem); 15231 if (non_dma->field != INVALIDf) { 15232 width = soc_mem_field_length(unit, non_dma->mem, 15233 non_dma->field); 15234 } else { 15235 width = 32; 15236 } 15237 15238 if (non_dma->dma_mem[0] != INVALIDm) { 15239 default_entries_per_pipe = 15240 soc_mem_index_count(unit, non_dma->dma_mem[0]); 15241 } 15242 15243 15244 if (ctr_reg == INVALIDr) { 15245 for (i = 0; i < max_pipe; i++) { 15246 /* Do only if the Pipe mem is VALID. */ 15247 if (non_dma->dma_mem[i] == INVALIDm) { 15248 continue; 15249 } 15250 /* Skip if no enabled ports in pipe */ 15251 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, i))) { 15252 continue; 15253 } 15254 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 15255 15256 if (non_dma->dma_buf[i] == NULL) { 15257 continue; 15258 } 15259 15260 rv = soc_mem_read_range(unit, non_dma->dma_mem[i], 15261 MEM_BLOCK_ANY, 15262 non_dma->dma_index_min[i], 15263 non_dma->dma_index_max[i], 15264 non_dma->dma_buf[i]); 15265 15266 if (SOC_FAILURE(rv)) { 15267 error_return = 1; 15268 goto done; 15269 } 15270 } 15271 } 15272 dma_mem = non_dma->mem; 15273 base_index = non_dma->base_index; 15274 index_max = non_dma->num_entries; 15275 num_non_dma_entries = index_max; 15276 15277 /* Set range over which field values from h/w are to be 15278 * extracted for color drop counters*/ 15279 if (non_dma->mem == MMU_CTR_COLOR_DROP_MEMm) { 15280 if(SOC_IS_TRIDENT3(unit) || SOC_IS_MAVERICK2(unit)) { 15281 default_entries_per_pipe = 66; 15282 } else if (SOC_IS_TOMAHAWK2(unit)) { 15283 default_entries_per_pipe = 34; 15284 } else if (SOC_IS_HELIX5(unit)) { 15285 default_entries_per_pipe = 68; 15286 } else { 15287 default_entries_per_pipe = 68; 15288 } 15289 num_non_dma_entries = default_entries_per_pipe; 15290 } 15291 15292 } else { 15293 15294 /* Collect counter values for a specific port */ 15295 dma_mem = non_dma->dma_mem[0]; 15296 dma_base_index = port_idx - non_dma->base_index + 15297 non_dma->dma_index_min[0]; 15298 15299 for (i = 1; i < NUM_PIPE(unit); i++) { 15300 if (non_dma->dma_buf[i] == NULL) { 15301 continue; 15302 } 15303 15304 if (dma_base_index > non_dma->dma_index_max[i - 1]) { 15305 dma_mem = non_dma->dma_mem[i]; 15306 dma_base_index -= non_dma->dma_index_max[i - 1] + 1; 15307 dma_base_index += non_dma->dma_index_min[i]; 15308 } 15309 } 15310 15311 /* Need to retrieve the table index 15312 * for flexible mapping Non-DMA counter*/ 15313 if (non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) { 15314 if (non_dma->soc_counter_hw_idx_get == NULL) { 15315 continue; 15316 } 15317 rv = non_dma->soc_counter_hw_idx_get(unit, tmp_port, 15318 dma_base_index + idx, 15319 &qindex); 15320 if (SOC_FAILURE(rv)) { 15321 error_return = 1; 15322 goto done; 15323 } 15324 if (-1 == qindex) { 15325 continue; 15326 } 15327 } else { 15328 qindex = dma_base_index + idx; 15329 } 15330 15331 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 15332 qindex, non_dma->dma_buf[0]); 15333 15334 15335 if (SOC_FAILURE(rv)) { 15336 error_return = 1; 15337 goto done; 15338 } 15339 15340 /* coverity[UNUSED_VALUE: FALSE] */ 15341 base_index = port_idx + idx; 15342 num_non_dma_entries = 1; 15343 } 15344 15345 /* For flexible mapping Non-DMA counter, need to assign the counter 15346 * value to SW structure based the table index retrieved 15347 * when the routine is to collect all the values 15348 * for all Non-DMA counters*/ 15349 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_FLEX_MAPPING) 15350 && (ctr_reg == INVALIDr)) { 15351 ctr_tmp_reg = SOC_COUNTER_NON_DMA_START + id; 15352 PBMP_ITER(soc->counter_pbmp, port) { 15353 rv = _soc_counter_get_info(unit, port, ctr_tmp_reg, 15354 &port_index, &num_entries, 15355 &cname); 15356 if (SOC_FAILURE(rv)) { 15357 error_return = 1; 15358 goto done; 15359 } 15360 dma_base_index = port_index - non_dma->base_index + 15361 non_dma->dma_index_min[0]; 15362 for (i = 0; i < num_entries; i++) { 15363 if (non_dma->soc_counter_hw_idx_get == NULL) { 15364 continue; 15365 } 15366 rv = non_dma->soc_counter_hw_idx_get(unit, port, 15367 dma_base_index + i, &qindex); 15368 if (SOC_FAILURE(rv)) { 15369 error_return = 1; 15370 goto done; 15371 } 15372 if (-1 == qindex) { 15373 continue; 15374 } 15375 15376 soc_mem_field_get(unit, dma_mem, 15377 &non_dma->dma_buf[0][entry_words * qindex], 15378 non_dma->field, fval); 15379 if (width <= 32) { 15380 COMPILER_64_SET(ctr_new, 0, fval[0]); 15381 } else { 15382 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 15383 } 15384 if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) { 15385 COMPILER_64_SUB_32(ctr_new, 1); 15386 } 15387 15388 COUNTER_ATOMIC_BEGIN(s); 15389 ctr_prev = soc->counter_hw_val[port_index + i]; 15390 COUNTER_ATOMIC_END(s); 15391 15392 if (!(non_dma->flags 15393 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 15394 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 15395 COUNTER_ATOMIC_BEGIN(s); 15396 COMPILER_64_ZERO 15397 (soc->counter_delta[port_index + i]); 15398 COUNTER_ATOMIC_END(s); 15399 continue; 15400 } 15401 } 15402 15403 ctr_diff = ctr_new; 15404 15405 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 15406 COUNTER_ATOMIC_BEGIN(s); 15407 if (COMPILER_64_GT(ctr_new, 15408 soc->counter_sw_val[port_index + i])) { 15409 soc->counter_sw_val[port_index + i] = ctr_new; 15410 } 15411 soc->counter_hw_val[port_index + i] = ctr_new; 15412 COMPILER_64_ZERO 15413 (soc->counter_delta[port_index + i]); 15414 COUNTER_ATOMIC_END(s); 15415 continue; 15416 } 15417 15418 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 15419 COUNTER_ATOMIC_BEGIN(s); 15420 soc->counter_sw_val[port_index + i] = ctr_new; 15421 soc->counter_hw_val[port_index + i] = ctr_new; 15422 COMPILER_64_ZERO(soc->counter_delta[port_index + i]); 15423 COUNTER_ATOMIC_END(s); 15424 continue; 15425 } 15426 15427 if (!(non_dma->flags 15428 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 15429 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 15430 if (width < 32) { 15431 COMPILER_64_ADD_32(ctr_diff, 1U << width); 15432 } else if (width < 64) { 15433 COMPILER_64_SET( 15434 wrap_amt, 1U << (width - 32), 0); 15435 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 15436 } 15437 } 15438 15439 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 15440 } 15441 15442 COUNTER_ATOMIC_BEGIN(s); 15443 COMPILER_64_ADD_64(soc->counter_sw_val[port_index + i], 15444 ctr_diff); 15445 soc->counter_hw_val[port_index + i] = ctr_new; 15446 soc->counter_delta[port_index + i] = ctr_diff; 15447 COUNTER_ATOMIC_END(s); 15448 } 15449 } 15450 } else { 15451 int invalid_pipe_ct = 0; 15452 int entries_per_pipe[SOC_MAX_NUM_PIPES]; 15453 for (pipe = 0; pipe < max_pipe; pipe++) { 15454 if (!num_non_dma_entries) { 15455 break; 15456 } 15457 if (!non_dma->dma_buf[pipe]) { 15458 /* Skip the pipe indices if dma_buf for given pipe 15459 * is NULL. 15460 */ 15461 invalid_pipe_ct++; 15462 continue; 15463 } 15464 15465 entries_per_pipe[pipe] = default_entries_per_pipe; 15466 base_index = non_dma->base_index + 15467 (pipe - invalid_pipe_ct) * default_entries_per_pipe; 15468 15469 #ifdef BCM_TOMAHAWK3_SUPPORT 15470 if (SOC_IS_TOMAHAWK3(unit)) { 15471 int pipe2 = 0; 15472 if (SOC_CONTROL(unit)->em_halfchip == 1 && 15473 non_dma->dma_mem[pipe] == INVALIDm) { 15474 continue; 15475 } 15476 entries_per_pipe[pipe] = non_dma->dma_num_entries[pipe]; 15477 base_index = non_dma->base_index; 15478 for(pipe2 = 1; pipe2 <= pipe; pipe2++) { 15479 base_index += non_dma->dma_num_entries[pipe2 - 1]; 15480 } 15481 } 15482 #endif 15483 /* Skip if no enabled ports in pipe */ 15484 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 15485 continue; 15486 } 15487 15488 for (i = 0 ; i < entries_per_pipe[pipe]; i++) { 15489 soc_mem_field_get(unit, non_dma->mem, 15490 &non_dma->dma_buf[pipe][entry_words * i], 15491 non_dma->field, fval); 15492 if (width <= 32) { 15493 COMPILER_64_SET(ctr_new, 0, fval[0]); 15494 } else { 15495 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 15496 } 15497 if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) { 15498 COMPILER_64_SUB_32(ctr_new, 1); 15499 } 15500 15501 COUNTER_ATOMIC_BEGIN(s); 15502 ctr_prev = soc->counter_hw_val[base_index + i]; 15503 COUNTER_ATOMIC_END(s); 15504 15505 if (!(non_dma->flags 15506 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 15507 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 15508 COUNTER_ATOMIC_BEGIN(s); 15509 COMPILER_64_ZERO 15510 (soc->counter_delta[base_index + i]); 15511 COUNTER_ATOMIC_END(s); 15512 continue; 15513 } 15514 } 15515 15516 ctr_diff = ctr_new; 15517 15518 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 15519 COUNTER_ATOMIC_BEGIN(s); 15520 if (COMPILER_64_GT 15521 (ctr_new, 15522 soc->counter_sw_val[base_index + i])) { 15523 soc->counter_sw_val[base_index + i] = ctr_new; 15524 } 15525 soc->counter_hw_val[base_index + i] = ctr_new; 15526 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15527 COUNTER_ATOMIC_END(s); 15528 continue; 15529 } 15530 15531 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 15532 COUNTER_ATOMIC_BEGIN(s); 15533 soc->counter_sw_val[base_index + i] = ctr_new; 15534 soc->counter_hw_val[base_index + i] = ctr_new; 15535 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15536 COUNTER_ATOMIC_END(s); 15537 continue; 15538 } 15539 15540 if (!(non_dma->flags 15541 & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 15542 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 15543 if (width < 32) { 15544 COMPILER_64_ADD_32(ctr_diff, 1U << width); 15545 } else if (width < 64) { 15546 COMPILER_64_SET 15547 (wrap_amt, 1U << (width - 32), 0); 15548 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 15549 } 15550 } 15551 15552 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 15553 } 15554 15555 COUNTER_ATOMIC_BEGIN(s); 15556 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 15557 ctr_diff); 15558 soc->counter_hw_val[base_index + i] = ctr_new; 15559 soc->counter_delta[base_index + i] = ctr_diff; 15560 COUNTER_ATOMIC_END(s); 15561 } 15562 } 15563 } 15564 count++; 15565 non_dma++; 15566 } while ((count < subset_ct) && non_dma); 15567 } else if (non_dma->reg != INVALIDr) { 15568 int mmu_xpe_ctr = 0; 15569 int mmu_itm_ctr = 0; 15570 pbmp_t counter_pbmp; 15571 soc_counter_non_dma_t *non_dma_tmp = non_dma; 15572 15573 count = 0; 15574 if (non_dma->field != INVALIDf) { 15575 width = soc_reg_field_length(unit, non_dma->reg, 15576 non_dma->field); 15577 } else { 15578 width = 32; 15579 } 15580 15581 /* 15582 * If stats retrieval is for a specific 15583 * port, set the pbmp for counter collection. 15584 */ 15585 if (ctr_reg >= NUM_SOC_REG) { 15586 SOC_PBMP_CLEAR(counter_pbmp); 15587 port = tmp_port; 15588 SOC_PBMP_PORT_ADD(counter_pbmp, port); 15589 } else { 15590 SOC_PBMP_CLEAR(counter_pbmp); 15591 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp); 15592 } 15593 15594 obm_flag = 0; 15595 PBMP_ITER(counter_pbmp, port) { 15596 subset_ct = 1; 15597 /* 15598 * stats retrieval for a specific port. 15599 */ 15600 15601 j = 0; 15602 if (ctr_reg >= NUM_SOC_REG) { 15603 if (!SOC_PBMP_MEMBER(counter_pbmp, port)) { 15604 continue; 15605 } 15606 15607 i = idx; 15608 count = i + 1; 15609 base_index = port_idx; 15610 } else { 15611 if (non_dma->entries_per_port == 0) { 15612 /* 15613 * OK to over-write port variable as loop 15614 * breaks after 1 iter. Check below for 15615 * the same codition. 15616 */ 15617 port = REG_PORT_ANY; 15618 count = non_dma->num_entries; 15619 base_index = non_dma->base_index; 15620 if ((non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT) || 15621 (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_BYTE) || 15622 (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT_YELLOW) || 15623 (non_dma->id == SOC_COUNTER_NON_DMA_DROP_RQ_PKT_RED) || 15624 (non_dma->id == SOC_COUNTER_NON_DMA_POOL_PEAK) || 15625 (non_dma->id == SOC_COUNTER_NON_DMA_POOL_CURRENT)) { 15626 mmu_xpe_ctr = 1; 15627 } else if ((non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT) || 15628 (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_BYTE) || 15629 (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_YELLOW) || 15630 (non_dma->id == SOC_COUNTER_NON_DMA_PRIQ_DROP_PKT_RED) || 15631 (non_dma->id == SOC_COUNTER_NON_DMA_HDRM_POOL_DROP_PKT)) { 15632 mmu_itm_ctr = 1; 15633 } 15634 } else { 15635 if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) { 15636 continue; 15637 } 15638 15639 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) { 15640 count = num_cosq[unit][port]; 15641 base_index = non_dma->base_index; 15642 for (i = 0; i < port; i++) { 15643 base_index += num_cosq[unit][i]; 15644 } 15645 } else if (non_dma->flags & 15646 _SOC_COUNTER_NON_DMA_OBM) { 15647 if (obm_flag == 0) { 15648 count = non_dma->entries_per_port * max_pipe; 15649 base_index = non_dma->base_index; 15650 obm_flag = 1; /* covers all ports for the 15651 * current obm */ 15652 subset_ct = non_dma->extra_ctr_ct; 15653 if (non_dma->extra_ctrs) { 15654 non_dma_tmp = non_dma->extra_ctrs; 15655 } 15656 } else { 15657 break; 15658 } 15659 } else { 15660 count = non_dma->entries_per_port; 15661 base_index = non_dma->base_index + port * count; 15662 } 15663 } 15664 } 15665 15666 do { 15667 for (i = 0; i < count; i++) { 15668 if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_OBM) { 15669 soc_reg_t reg = non_dma_tmp->reg; 15670 #ifdef BCM_TOMAHAWK3_SUPPORT 15671 int phy_port, obm_port, is_active; 15672 #endif 15673 /* coverity[divide_by_zero : FALSE] */ 15674 pipe = i / non_dma->entries_per_port; 15675 /* Skip if no enabled ports in pipe */ 15676 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 15677 continue; 15678 } 15679 reg = SOC_REG_UNIQUE_ACC(unit, non_dma_tmp->reg)[pipe]; 15680 base_index = non_dma_tmp->base_index; 15681 #ifdef BCM_TOMAHAWK3_SUPPORT 15682 if (SOC_IS_TOMAHAWK3(unit)) { 15683 obm_port = i % non_dma->entries_per_port; 15684 phy_port = 15685 soc_counter_tomahawk3_obm_drop_to_phy_port(unit, pipe, reg, obm_port); 15686 if (phy_port < 0 || 15687 SOC_INFO(unit).port_p2l_mapping[phy_port] == -1) { 15688 continue; 15689 } 15690 15691 rv = soc_th3_portctrl_pm_is_active(unit, phy_port, &is_active); 15692 if (SOC_FAILURE(rv)) { 15693 error_return = 1; 15694 goto done; 15695 } 15696 15697 /* Skip counters for this PM if it's not initialized */ 15698 if (!is_active) { 15699 continue; 15700 } 15701 15702 rv = soc_reg_get(unit, reg, pipe, obm_port, &ctr_new); 15703 } else 15704 #endif 15705 { 15706 rv = soc_reg_get(unit, reg, pipe, 15707 i % non_dma->entries_per_port, &ctr_new); 15708 } 15709 } else { 15710 /* coverity[negative_returns : FALSE] */ 15711 if (mmu_xpe_ctr == 1) { 15712 rv = soc_reg_get(unit, non_dma_tmp->reg, 15713 (i / (count / NUM_XPE(unit))), 15714 (i % (count / NUM_XPE(unit))), &ctr_new); 15715 } else if (mmu_itm_ctr == 1) { 15716 /* Skip if inactive ITM */ 15717 if(((1 << (i / (count / NUM_ITM(unit)))) & 15718 soc->info.itm_map) == 0) { 15719 continue; 15720 } 15721 15722 rv = soc_reg_get(unit, non_dma_tmp->reg, 15723 (i / (count / NUM_ITM(unit))), 15724 (i % (count / NUM_ITM(unit))), &ctr_new); 15725 } else { 15726 rv = soc_reg_get(unit, non_dma_tmp->reg, port, i, &ctr_new); 15727 } 15728 } 15729 if (SOC_FAILURE(rv)) { 15730 error_return = 1; 15731 goto done; 15732 } 15733 COUNTER_ATOMIC_BEGIN(s); 15734 ctr_prev = soc->counter_hw_val[base_index + i]; 15735 COUNTER_ATOMIC_END(s); 15736 15737 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 15738 COUNTER_ATOMIC_BEGIN(s); 15739 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15740 COUNTER_ATOMIC_END(s); 15741 continue; 15742 } 15743 15744 ctr_diff = ctr_new; 15745 15746 if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_PEAK) { 15747 COUNTER_ATOMIC_BEGIN(s); 15748 if (COMPILER_64_GT(ctr_new, 15749 soc->counter_sw_val[base_index + i])) { 15750 soc->counter_sw_val[base_index + i] = ctr_new; 15751 } 15752 soc->counter_hw_val[base_index + i] = ctr_new; 15753 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15754 COUNTER_ATOMIC_END(s); 15755 continue; 15756 } 15757 15758 if (non_dma_tmp->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 15759 COUNTER_ATOMIC_BEGIN(s); 15760 soc->counter_sw_val[base_index + i] = ctr_new; 15761 soc->counter_hw_val[base_index + i] = ctr_new; 15762 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 15763 COUNTER_ATOMIC_END(s); 15764 continue; 15765 } 15766 15767 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 15768 if (width < 32) { 15769 COMPILER_64_ADD_32(ctr_diff, 1U << width); 15770 } else if (width < 64) { 15771 COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0); 15772 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 15773 } 15774 } 15775 15776 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 15777 15778 COUNTER_ATOMIC_BEGIN(s); 15779 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 15780 ctr_diff); 15781 soc->counter_hw_val[base_index + i] = ctr_new; 15782 soc->counter_delta[base_index + i] = ctr_diff; 15783 COUNTER_ATOMIC_END(s); 15784 } 15785 j++; 15786 if (subset_ct > 1) { 15787 non_dma_tmp += 2; 15788 } 15789 } while ((j < subset_ct) && non_dma_tmp); 15790 15791 if (non_dma->entries_per_port == 0) { 15792 break; 15793 } 15794 } 15795 COUNTER_UNLOCK(unit); 15796 sal_thread_yield(); 15797 COUNTER_LOCK(unit); 15798 } 15799 } 15800 15801 done: 15802 if (soc_feature(unit, soc_feature_th_a0_sw_war) && 15803 soc->ctr_evict_interval) { 15804 soc_reg_t reg = EGR_EFP_CNTR_UPDATE_CONTROLr; 15805 efp_ctr_rval = 0; 15806 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &efp_ctr_rval); 15807 if (SOC_FAILURE(rv)) { 15808 return; 15809 } 15810 15811 soc_reg_field_set(unit, reg, &efp_ctr_rval, CLR_ON_READf, 0); 15812 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, efp_ctr_rval); 15813 if (SOC_FAILURE(rv)) { 15814 return; 15815 } 15816 } 15817 15818 if (error_return) { 15819 return; 15820 } 15821 ctr_dma_ct++; 15822 } 15823 #endif /* BCM_TOMAHAWK_SUPPORT */ 15824 15825 #ifdef BCM_XGS3_SWITCH_SUPPORT 15826 /* 15827 * Function: 15828 * _soc_xgs3_counter_dma_setup 15829 * Purpose: 15830 * Configure hardware registers for counter collection. Used during 15831 * soc_counter_thread initialization. 15832 * Parameters: 15833 * unit - switch unit 15834 * Returns: 15835 * SOC_E_* 15836 */ 15837 STATIC int 15838 _soc_xgs3_counter_dma_setup(int unit) 15839 { 15840 soc_control_t *soc; 15841 int csize; 15842 pbmp_t pbmp; 15843 soc_reg_t reg; 15844 soc_ctr_type_t ctype; 15845 uint32 val; 15846 uint32 ing_blk, ing_blkoff, ing_pstage, ing_c_cnt; 15847 uint32 egr_blk, egr_blkoff, egr_pstage, egr_c_cnt; 15848 #ifdef BCM_SHADOW_SUPPORT 15849 uint32 inv_c_cnt = 0; 15850 #endif 15851 uint32 gmac_c_cnt, xmac_c_cnt; 15852 int blk, bindex, blk_num, port, phy_port; 15853 soc_reg_t blknum_reg, portnum_reg; 15854 int num_blknum, num_portnum, blknum_offset, portnum_offset; 15855 uint32 blknum_mask, portnum_mask; 15856 uint32 blknum_map[20]; 15857 uint32 portnum_map[24]; 15858 #ifdef BCM_CMICM_SUPPORT 15859 int cmc = SOC_PCI_CMC(unit); 15860 #endif 15861 ing_blk = ing_blkoff = ing_pstage = 0; 15862 egr_blk = egr_blkoff = egr_pstage = 0; 15863 15864 #ifdef BCM_FIREBOLT_SUPPORT 15865 if (SOC_IS_FBX(unit)) { 15866 ing_blk = SOC_BLK_IPIPE; 15867 egr_blk = SOC_BLK_EPIPE; 15868 ing_blkoff = SOC_BLOCK2OFFSET(unit, IPIPE_BLOCK(unit)); 15869 egr_blkoff = SOC_BLOCK2OFFSET(unit, EPIPE_BLOCK(unit)); 15870 } 15871 #endif 15872 15873 soc = SOC_CONTROL(unit); 15874 SOC_PBMP_ASSIGN(pbmp, soc->counter_pbmp); 15875 /* 15876 * Calculate the number of counters from each block 15877 */ 15878 ing_c_cnt = egr_c_cnt = gmac_c_cnt = xmac_c_cnt = 0; 15879 #ifdef BCM_SHADOW_SUPPORT 15880 if (SOC_IS_SHADOW(unit)) { 15881 inv_c_cnt = ing_c_cnt; 15882 } 15883 #endif 15884 for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) { 15885 if (!SOC_HAS_CTR_TYPE(unit, ctype)) { 15886 continue; 15887 } 15888 for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize > 0; csize--) { 15889 reg = SOC_CTR_TO_REG(unit, ctype, csize); 15890 if (SOC_COUNTER_INVALID(unit, reg)) { 15891 continue; /* skip trailing invalids */ 15892 } 15893 if (SOC_REG_BLOCK_IS(unit, reg, ing_blk) && 15894 (ing_c_cnt == 0)) { 15895 ing_c_cnt = csize + 1; 15896 if (soc_feature(unit, soc_feature_new_sbus_format)) { 15897 ing_pstage = (SOC_REG_INFO(unit, reg).offset >> 26) & 0x3F; 15898 } else { 15899 ing_pstage = (SOC_REG_INFO(unit, reg).offset >> 24) & 0xFF; 15900 } 15901 } 15902 if (SOC_REG_BLOCK_IS(unit, reg, egr_blk) && 15903 (egr_c_cnt == 0)) { 15904 egr_c_cnt = csize + 1; 15905 if (soc_feature(unit, soc_feature_new_sbus_format)) { 15906 egr_pstage = (SOC_REG_INFO(unit, reg).offset >> 26) & 0x3F; 15907 } else { 15908 egr_pstage = (SOC_REG_INFO(unit, reg).offset >> 24) & 0xFF; 15909 } 15910 } 15911 if ((SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT) || 15912 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_QGPORT) || 15913 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_SPORT) || 15914 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XGPORT) || 15915 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XQPORT) || 15916 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT) || 15917 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) || 15918 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) || 15919 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) || 15920 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) || 15921 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) || 15922 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) && 15923 (gmac_c_cnt == 0)) { 15924 gmac_c_cnt = csize + 1; 15925 } 15926 if ((SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XPORT) || 15927 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XGPORT) || 15928 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XQPORT) || 15929 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT) || 15930 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) || 15931 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) || 15932 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) || 15933 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) || 15934 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) || 15935 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) || 15936 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) && 15937 (xmac_c_cnt == 0)) { 15938 xmac_c_cnt = csize + 1; 15939 } 15940 } 15941 } 15942 #ifdef BCM_SHADOW_SUPPORT 15943 if (SOC_IS_SHADOW(unit)) { 15944 /* Remove leading invalids (Shadow) */ 15945 for (csize = 0; csize < SOC_CTR_MAP_SIZE(unit, SOC_CTR_TYPE_XE); csize++) { 15946 reg = SOC_CTR_TO_REG(unit, SOC_CTR_TYPE_XE, csize); 15947 if (SOC_COUNTER_INVALID(unit, reg)) { 15948 inv_c_cnt++; 15949 } else { 15950 break; 15951 } 15952 } 15953 } 15954 #endif /* BCM_SHADOW_SUPPORT */ 15955 15956 egr_c_cnt = (egr_c_cnt) ? (egr_c_cnt - ing_c_cnt) : 0; 15957 gmac_c_cnt = (gmac_c_cnt) ? (gmac_c_cnt - egr_c_cnt - ing_c_cnt) : 0; 15958 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 15959 if (!SOC_CONTROL(unit)->sw_timestamp_fifo_enable) { 15960 xmac_c_cnt = DIRECT_TIMESTAMP_DMA_COUNTER_NUM; 15961 } else 15962 #endif 15963 { 15964 xmac_c_cnt = (xmac_c_cnt) ? (xmac_c_cnt - egr_c_cnt - ing_c_cnt) : 0; 15965 } 15966 #ifdef BCM_SHADOW_SUPPORT 15967 if (SOC_IS_SHADOW(unit)) { 15968 ing_c_cnt -= inv_c_cnt; 15969 } 15970 #endif 15971 15972 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 15973 (BSL_META_U(unit, 15974 "ing_c_cnt = %d egr_c_cnt = %d " 15975 "gmac_c_cnt = %d xmac_c_cnt = %d\n" 15976 "ing_pstage = %d egr_pstage = %d " 15977 "ing_blkoff = %d egr_blkoff = %d\n"), 15978 ing_c_cnt, egr_c_cnt, gmac_c_cnt, xmac_c_cnt, 15979 ing_pstage, egr_pstage, ing_blkoff, egr_blkoff)); 15980 15981 /* Prepare for CMIC_STAT_DMA_PORTNUM_MAP and BLKNUM_MAP */ 15982 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_3_0r)) { 15983 portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_3_0r; 15984 num_portnum = 4; 15985 portnum_offset = 8; 15986 #if defined(BCM_HB_GW_SUPPORT) 15987 } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_5_0r)) { 15988 portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_5_0r; 15989 num_portnum = 6; 15990 portnum_offset = 5; 15991 #endif 15992 } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_7_0r)) { 15993 portnum_reg = CMIC_STAT_DMA_PORTNUM_MAP_7_0r; 15994 num_portnum = 8; 15995 portnum_offset = 4; 15996 } else { 15997 return SOC_E_INTERNAL; 15998 } 15999 portnum_mask = 16000 (1 << soc_reg_field_length(unit, portnum_reg, SBUS_PORTNUM_0f)) - 1; 16001 16002 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_4_0r)) { 16003 blknum_reg = CMIC_STAT_DMA_BLKNUM_MAP_4_0r; 16004 num_blknum = 5; 16005 blknum_offset = 6; 16006 } else if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_7_0r)) { 16007 blknum_reg = CMIC_STAT_DMA_BLKNUM_MAP_7_0r; 16008 num_blknum = 8; 16009 blknum_offset = 4; 16010 } else { 16011 return SOC_E_INTERNAL; 16012 } 16013 blknum_mask = 16014 (1 << soc_reg_field_length(unit, blknum_reg, SBUS_BLKNUM_0f)) - 1; 16015 16016 sal_memset(portnum_map, 0, sizeof(portnum_map)); 16017 sal_memset(blknum_map, 0, sizeof(blknum_map)); 16018 PBMP_ITER(pbmp, port) { 16019 /* Check port value to avoid out of bound array access */ 16020 if ((port / num_blknum) >= 20) { 16021 return SOC_E_INTERNAL; 16022 } 16023 if ((port / num_portnum) >= 24) { 16024 return SOC_E_INTERNAL; 16025 } 16026 if (soc_feature(unit, soc_feature_logical_port_num)) { 16027 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 16028 } else { 16029 phy_port = port; 16030 } 16031 blk = SOC_PORT_BLOCK(unit, phy_port); 16032 bindex = SOC_PORT_BINDEX(unit, phy_port); 16033 blk_num = SOC_BLOCK2OFFSET(unit, blk); 16034 /* coverity[overrun-local] */ 16035 blknum_map[port / num_blknum] |= 16036 (blk_num & blknum_mask) << (blknum_offset * (port % num_blknum)); 16037 /* coverity[overrun-local] */ 16038 portnum_map[port / num_portnum] |= 16039 (bindex & portnum_mask) << (portnum_offset * (port % num_portnum)); 16040 } 16041 16042 switch (portnum_reg) { 16043 case CMIC_STAT_DMA_PORTNUM_MAP_3_0r: 16044 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_3_0r(unit, portnum_map[0]); 16045 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_7_4r(unit, portnum_map[1]); 16046 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_11_8r(unit, portnum_map[2]); 16047 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_15_12r(unit, portnum_map[3]); 16048 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_19_16r(unit, portnum_map[4]); 16049 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_20r(unit, portnum_map[5]); 16050 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_27_24r(unit, portnum_map[6]); 16051 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_31_28r(unit, portnum_map[7]); 16052 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_35_32r(unit, portnum_map[8]); 16053 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_39_36r(unit, portnum_map[9]); 16054 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_43_40r(unit, portnum_map[10]); 16055 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_47_44r(unit, portnum_map[11]); 16056 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_51_48r(unit, portnum_map[12]); 16057 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_55_52r(unit, portnum_map[13]); 16058 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_59_56r(unit, portnum_map[14]); 16059 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_63_60r(unit, portnum_map[15]); 16060 if (!SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTNUM_MAP_67_64r)) { 16061 break; 16062 } 16063 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_67_64r(unit, portnum_map[16]); 16064 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_71_68r(unit, portnum_map[17]); 16065 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_75_72r(unit, portnum_map[18]); 16066 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_79_76r(unit, portnum_map[19]); 16067 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_83_80r(unit, portnum_map[20]); 16068 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_87_84r(unit, portnum_map[21]); 16069 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_91_88r(unit, portnum_map[22]); 16070 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_95_92r(unit, portnum_map[23]); 16071 break; 16072 #if defined(BCM_HB_GW_SUPPORT) 16073 case CMIC_STAT_DMA_PORTNUM_MAP_5_0r: 16074 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_5_0r(unit, portnum_map[0]); 16075 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_11_6r(unit, portnum_map[1]); 16076 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_17_12r(unit, portnum_map[2]); 16077 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_18r(unit, portnum_map[3]); 16078 break; 16079 #endif 16080 case CMIC_STAT_DMA_PORTNUM_MAP_7_0r: 16081 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_7_0r(unit, portnum_map[0]); 16082 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_15_8r(unit, portnum_map[1]); 16083 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_23_16r(unit, portnum_map[2]); 16084 WRITE_CMIC_STAT_DMA_PORTNUM_MAP_31_24r(unit, portnum_map[3]); 16085 break; 16086 } 16087 16088 switch (blknum_reg) { 16089 case CMIC_STAT_DMA_BLKNUM_MAP_4_0r: 16090 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_4_0r(unit, blknum_map[0]); 16091 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_9_5r(unit, blknum_map[1]); 16092 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_14_10r(unit, blknum_map[2]); 16093 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_19_15r(unit, blknum_map[3]); 16094 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_24_20r(unit, blknum_map[4]); 16095 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_29_25r(unit, blknum_map[5]); 16096 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_34_30r(unit, blknum_map[6]); 16097 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_39_35r(unit, blknum_map[7]); 16098 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_44_40r(unit, blknum_map[8]); 16099 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_49_45r(unit, blknum_map[9]); 16100 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_54_50r(unit, blknum_map[10]); 16101 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_59_55r(unit, blknum_map[11]); 16102 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_63_60r)) { 16103 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_63_60r(unit, blknum_map[12]); 16104 break; 16105 } 16106 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_64_60r(unit, blknum_map[12]); 16107 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_69_65r(unit, blknum_map[13]); 16108 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_74_70r(unit, blknum_map[14]); 16109 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_79_75r(unit, blknum_map[15]); 16110 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_84_80r(unit, blknum_map[16]); 16111 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_89_85r(unit, blknum_map[17]); 16112 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_94_90r(unit, blknum_map[18]); 16113 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_95r(unit, blknum_map[19]); 16114 break; 16115 case CMIC_STAT_DMA_BLKNUM_MAP_7_0r: 16116 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_7_0r(unit, blknum_map[0]); 16117 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_15_8r(unit, blknum_map[1]); 16118 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_23_16r(unit, blknum_map[2]); 16119 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_31_24r(unit, blknum_map[3]); 16120 if (!SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_BLKNUM_MAP_39_32r)) { 16121 break; 16122 } 16123 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_39_32r(unit, blknum_map[4]); 16124 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_47_40r(unit, blknum_map[5]); 16125 WRITE_CMIC_STAT_DMA_BLKNUM_MAP_55_48r(unit, blknum_map[6]); 16126 16127 break; 16128 } 16129 16130 /* 16131 * Reset value in CMIC_STAT_DMA_SETUP register is good. No 16132 * additional setup necessary for FB/ER 16133 */ 16134 #ifdef BCM_CMICM_SUPPORT 16135 if(soc_feature(unit, soc_feature_cmicm)) { 16136 soc_pci_write(unit,CMIC_CMCx_STAT_DMA_ADDR_OFFSET(cmc),soc_cm_l2p(unit, soc->counter_buf64)); 16137 soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_0_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 0)); 16138 if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_1r)) { 16139 soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_1_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 1)); 16140 } 16141 if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_2r)) { 16142 soc_pci_write(unit,CMIC_CMCx_STAT_DMA_PORTS_2_OFFSET(cmc),SOC_PBMP_WORD_GET(pbmp, 2)); 16143 } 16144 SOC_PBMP_ASSIGN(pbmp, PBMP_HG_ALL(unit)); 16145 SOC_PBMP_OR(pbmp, PBMP_XE_ALL(unit)); 16146 SOC_PBMP_AND(pbmp, soc->counter_pbmp); 16147 16148 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_0r(unit, SOC_PBMP_WORD_GET(pbmp, 0)); 16149 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_1r)) { 16150 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_1r 16151 (unit, SOC_PBMP_WORD_GET(pbmp, 1)); 16152 } 16153 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_2r)) { 16154 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_2r 16155 (unit, SOC_PBMP_WORD_GET(pbmp, 2)); 16156 } 16157 } else 16158 #endif /* CMICM Support */ 16159 { 16160 WRITE_CMIC_STAT_DMA_ADDRr(unit, soc_cm_l2p(unit, soc->counter_buf64)); 16161 16162 WRITE_CMIC_STAT_DMA_PORTSr(unit, SOC_PBMP_WORD_GET(pbmp, 0)); 16163 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTS_HIr)) { 16164 WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, SOC_PBMP_WORD_GET(pbmp, 1)); 16165 } 16166 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORTS_HI_2r)) { 16167 WRITE_CMIC_STAT_DMA_PORTS_HI_2r(unit, SOC_PBMP_WORD_GET(pbmp, 2)); 16168 } 16169 16170 if (SOC_IS_HB_GW(unit)) { 16171 SOC_PBMP_ASSIGN(pbmp, PBMP_PORT_ALL(unit)); 16172 } else { 16173 SOC_PBMP_ASSIGN(pbmp, PBMP_HG_ALL(unit)); 16174 SOC_PBMP_OR(pbmp, PBMP_XE_ALL(unit)); 16175 } 16176 SOC_PBMP_AND(pbmp, soc->counter_pbmp); 16177 16178 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAPr(unit, SOC_PBMP_WORD_GET(pbmp, 0)); 16179 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_HIr)) { 16180 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_HIr 16181 (unit, SOC_PBMP_WORD_GET(pbmp, 1)); 16182 } 16183 if (SOC_REG_IS_VALID(unit, CMIC_STAT_DMA_PORT_TYPE_MAP_HI_2r)) { 16184 WRITE_CMIC_STAT_DMA_PORT_TYPE_MAP_HI_2r 16185 (unit, SOC_PBMP_WORD_GET(pbmp, 2)); 16186 } 16187 } 16188 val = 0; 16189 soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr, 16190 &val, ING_ETH_BLK_NUMf, ing_blkoff); 16191 soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr, 16192 &val, ING_STAT_COUNTERS_NUMf, ing_c_cnt); 16193 soc_reg_field_set(unit, CMIC_STAT_DMA_ING_STATS_CFGr, 16194 &val, ING_STATS_PIPELINE_STAGE_NUMf, ing_pstage); 16195 WRITE_CMIC_STAT_DMA_ING_STATS_CFGr(unit, val); 16196 16197 val = 0; 16198 soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr, 16199 &val, EGR_ETH_BLK_NUMf, egr_blkoff); 16200 soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr, 16201 &val, EGR_STAT_COUNTERS_NUMf, egr_c_cnt); 16202 soc_reg_field_set(unit, CMIC_STAT_DMA_EGR_STATS_CFGr, 16203 &val, EGR_STATS_PIPELINE_STAGE_NUMf, egr_pstage); 16204 WRITE_CMIC_STAT_DMA_EGR_STATS_CFGr(unit, val); 16205 16206 val = 0; 16207 soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr, 16208 &val, MAC_G_STAT_COUNTERS_NUMf, gmac_c_cnt); 16209 soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr, 16210 &val, MAC_X_STAT_COUNTERS_NUMf, xmac_c_cnt); 16211 soc_reg_field_set(unit, CMIC_STAT_DMA_MAC_STATS_CFGr, 16212 &val, CPU_STATS_PORT_NUMf, CMIC_PORT(unit)); 16213 WRITE_CMIC_STAT_DMA_MAC_STATS_CFGr(unit, val); 16214 16215 #ifdef BCM_CMICM_SUPPORT 16216 if(soc_feature(unit, soc_feature_cmicm)) { 16217 val = soc_pci_read(unit,CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc)); 16218 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, 16219 ST_DMA_ITER_DONE_CLRf, 1); 16220 if (soc_feature(unit, soc_feature_new_sbus_format)) { 16221 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, 16222 EN_TR3_SBUS_STYLEf, 1); 16223 } 16224 soc_pci_write(unit,CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc),val); 16225 soc_cmicm_intr0_enable(unit, IRQ_CMCx_STAT_ITER_DONE); 16226 } else 16227 #endif 16228 { 16229 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ITER_DONE_CLR); 16230 soc_intr_enable(unit, IRQ_STAT_ITER_DONE); 16231 } 16232 return SOC_E_NONE; 16233 } 16234 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 16235 16236 #ifdef BCM_SBUSDMA_SUPPORT 16237 void _soc_sbusdma_port_ctr_cb(int unit, int status, sbusdma_desc_handle_t handle, 16238 void *data) 16239 { 16240 int phy_port; 16241 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 16242 16243 if (soc_feature(unit, soc_feature_logical_port_num)) { 16244 phy_port = SOC_INFO(unit).port_p2l_mapping[PTR_TO_INT(data)]; 16245 } else { 16246 phy_port = PTR_TO_INT(data); 16247 } 16248 16249 LOG_DEBUG(BSL_LS_SOC_COUNTER, 16250 (BSL_META_U(unit, 16251 "In port counter cb [%d]\n"), handle)); 16252 if (status == SOC_E_NONE) { 16253 LOG_DEBUG(BSL_LS_SOC_COUNTER, 16254 (BSL_META_U(unit, 16255 "Complete: port:%d.\n"),phy_port)); 16256 } else { 16257 uint8 i; 16258 int blk; 16259 LOG_ERROR(BSL_LS_SOC_COMMON, 16260 (BSL_META_U(unit, 16261 "Counter SBUSDMA failed: Handle:%d port:%d.\n"), handle,phy_port)); 16262 if (status == SOC_E_TIMEOUT) { 16263 (void)soc_sbusdma_desc_delete(unit, handle); 16264 for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) { 16265 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16266 if ((i == 3) && (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit)))) { 16267 break; 16268 } 16269 #endif 16270 if (_soc_port_counter_handles[unit][PTR_TO_INT(data)][i] == handle) { 16271 _soc_port_counter_handles[unit][PTR_TO_INT(data)][i] = 0; 16272 break; 16273 } 16274 blk = SOC_PORT_BLOCK(unit, PTR_TO_INT(data)); 16275 if ((i == 2) && 16276 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) && 16277 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) && 16278 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) && 16279 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) && 16280 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) && 16281 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) && 16282 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) && 16283 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) && 16284 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) { 16285 break; 16286 } 16287 } 16288 } 16289 } 16290 COUNTER_ATOMIC_BEGIN(s); 16291 _soc_counter_pending[unit]--; 16292 COUNTER_ATOMIC_END(s); 16293 } 16294 16295 int 16296 _soc_counter_sbusdma_setup(int unit) 16297 { 16298 soc_control_t *soc; 16299 int csize; 16300 soc_ctr_type_t ctype; 16301 soc_reg_t reg, ing_reg, egr_reg, mac_reg, gmac_reg; 16302 int ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt; 16303 int ing_first, egr_first, mac_first, gmac_first; 16304 int ing_last, egr_last, mac_last, gmac_last; 16305 uint32 ing_addr, egr_addr, mac_addr; 16306 int ing_blkoff, egr_blkoff, mac_blkoff; 16307 uint8 ing_acc_type, egr_acc_type, mac_acc_type; 16308 int blk, port, phy_port, i; 16309 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16310 soc_reg_t mac_xlpmib_reg; 16311 int mac_xlpmib_c_cnt, mac_xlpmib_first, mac_xlpmib_last; 16312 #endif /* BCM_GREYHOUND2_SUPPORT */ 16313 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) 16314 soc_reg_t mac_clmib_reg; 16315 int mac_clmib_c_cnt, mac_clmib_first, mac_clmib_last; 16316 #endif /* BCM_GREYHOUND2_SUPPORT */ 16317 #ifdef BCM_KATANA2_SUPPORT 16318 soc_port_t my_port; 16319 #endif 16320 int port_num_blktype; 16321 soc_pbmp_t all_pbmp; 16322 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 16323 int use_gmac, gmac_c_width; 16324 #endif 16325 #ifdef SOC_COUNTER_TABLE_SUPPORT 16326 int mib_tbl_first = 10000; /* a huge number */ 16327 int mib_tbl_last = -1; 16328 int mib_tbl_c_cnt = 0; 16329 uint32 mib_tbl_addr = 0; 16330 uint8 mib_tbl_acc_type = 0; 16331 #endif 16332 16333 soc = SOC_CONTROL(unit); 16334 port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ? 16335 SOC_DRIVER(unit)->port_num_blktype : 1; 16336 16337 sal_memset(_soc_port_counter_handles[unit], 0, sizeof(_soc_port_counter_handles[unit])); 16338 ing_reg = INVALIDr; 16339 egr_reg = INVALIDr; 16340 mac_reg = INVALIDr; 16341 gmac_reg = INVALIDr; 16342 ing_first = 10000; /* a huge number */ 16343 egr_first = 10000; 16344 mac_first = 10000; 16345 gmac_first = 10000; 16346 ing_last = -1; 16347 egr_last = -1; 16348 mac_last = -1; 16349 gmac_last = -1; 16350 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16351 mac_xlpmib_reg = INVALIDr; 16352 mac_xlpmib_first = 10000; 16353 mac_xlpmib_last = -1; 16354 #endif /* BCM_GREYHOUND2_SUPPORT */ 16355 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) 16356 mac_clmib_reg = INVALIDr; 16357 mac_clmib_first = 10000; 16358 mac_clmib_last = -1; 16359 #endif /* BCM_GREYHOUND2_SUPPORT */ 16360 ing_reg = INVALIDr; 16361 egr_reg = INVALIDr; 16362 mac_reg = INVALIDr; 16363 gmac_reg = INVALIDr; 16364 for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) { 16365 if (!SOC_HAS_CTR_TYPE(unit, ctype)) { 16366 continue; 16367 } 16368 for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize >= 0; csize--) { 16369 reg = SOC_CTR_TO_REG(unit, ctype, csize); 16370 if (SOC_COUNTER_INVALID(unit, reg)) { 16371 continue; /* skip trailing invalids */ 16372 } 16373 #ifdef SOC_COUNTER_TABLE_SUPPORT 16374 if (SOC_IS_TOMAHAWK3(unit) && 16375 SOC_REG_IS_COUNTER_TABLE(unit, reg)) { 16376 if (mib_tbl_first > csize) { 16377 mib_tbl_first = csize; 16378 } 16379 if (mib_tbl_last < csize) { 16380 mib_tbl_last = csize; 16381 } 16382 continue; 16383 } 16384 #endif 16385 if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_IPIPE)) { 16386 if (ing_first > csize) { 16387 ing_first = csize; 16388 ing_reg = reg; 16389 } 16390 if (ing_last < csize) { 16391 ing_last = csize; 16392 } 16393 } 16394 if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_EPIPE)) { 16395 if (egr_first > csize) { 16396 egr_first = csize; 16397 egr_reg = reg; 16398 } 16399 if (egr_last < csize) { 16400 egr_last = csize; 16401 } 16402 } 16403 16404 #ifdef BCM_SABER2_SUPPORT 16405 if (SOC_IS_SABER2(unit)) { 16406 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT)) { 16407 if (mac_first > csize) { 16408 mac_first = csize; 16409 mac_reg = reg; 16410 } 16411 if (mac_last < csize) { 16412 mac_last = csize; 16413 } 16414 mac_reg = reg; 16415 continue; 16416 } 16417 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 16418 if (gmac_first > csize) { 16419 gmac_first = csize; 16420 gmac_reg = reg; 16421 } 16422 if (gmac_last < csize) { 16423 gmac_last = csize; 16424 } 16425 continue; 16426 } 16427 } 16428 #endif /* BCM_SABER2_SUPPORT */ 16429 #ifdef BCM_HELIX5_SUPPORT 16430 if (SOC_IS_HELIX5(unit)) { 16431 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 16432 if (mac_first > csize) { 16433 mac_first = csize; 16434 } 16435 if (mac_last < csize) { 16436 mac_last = csize; 16437 } 16438 mac_reg = reg; 16439 continue; 16440 } 16441 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) { 16442 if (gmac_first > csize) { 16443 gmac_first = csize; 16444 } 16445 if (gmac_last < csize) { 16446 gmac_last = csize; 16447 } 16448 gmac_reg = reg; 16449 continue; 16450 } 16451 16452 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) { 16453 if (mac_clmib_first > csize) { 16454 mac_clmib_first = csize; 16455 } 16456 if (mac_clmib_last < csize) { 16457 mac_clmib_last = csize; 16458 } 16459 mac_clmib_reg = reg; 16460 continue; 16461 } 16462 } 16463 #endif /* BCM_HELIX5_SUPPORT */ 16464 #if defined(BCM_TOMAHAWKPLUS_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) 16465 if (SOC_IS_TOMAHAWKPLUS(unit) || SOC_IS_TRIDENT3X(unit) || 16466 SOC_IS_TOMAHAWK2(unit)) { 16467 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) { 16468 if (mac_first > csize) { 16469 mac_first = csize; 16470 mac_reg = reg; 16471 } 16472 if (mac_last < csize) { 16473 mac_last = csize; 16474 } 16475 mac_reg = reg; 16476 continue; 16477 } 16478 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 16479 if (gmac_first > csize) { 16480 gmac_first = csize; 16481 gmac_reg = reg; 16482 } 16483 if (gmac_last < csize) { 16484 gmac_last = csize; 16485 } 16486 continue; 16487 } 16488 } 16489 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWKPLUS_SUPPORT || BCM_TOMAHAWK2_SUPPORT */ 16490 16491 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16492 if (SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit)) { 16493 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 16494 /* The first XLPMIB_XXXr offset = 0x10000 (XLPMIB_R64r) */ 16495 if (SOC_REG_INFO(unit, reg).offset & 0x10000) { 16496 if (mac_xlpmib_first > csize) { 16497 mac_xlpmib_first = csize; 16498 mac_xlpmib_reg = reg; 16499 } 16500 if (mac_xlpmib_last < csize) { 16501 mac_xlpmib_last = csize; 16502 } 16503 mac_xlpmib_reg = reg; 16504 } else { 16505 if (mac_first > csize) { 16506 mac_first = csize; 16507 mac_reg = reg; 16508 } 16509 if (mac_last < csize) { 16510 mac_last = csize; 16511 } 16512 mac_reg = reg; 16513 } 16514 continue; 16515 } 16516 } 16517 16518 #endif /* BCM_GREYHOUND2_SUPPORT */ 16519 #if defined(BCM_GREYHOUND2_SUPPORT) 16520 if (SOC_IS_GREYHOUND2(unit)) { 16521 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) { 16522 if (mac_clmib_first > csize) { 16523 mac_clmib_first = csize; 16524 mac_clmib_reg = reg; 16525 } 16526 if (mac_clmib_last < csize) { 16527 mac_clmib_last = csize; 16528 } 16529 mac_clmib_reg = reg; 16530 continue; 16531 } 16532 } 16533 #endif /* BCM_GREYHOUND2_SUPPORT */ 16534 16535 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) || 16536 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) || 16537 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) || 16538 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) || 16539 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) || 16540 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) || 16541 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_PGW_CL)) { 16542 if (mac_first > csize) { 16543 mac_first = csize; 16544 mac_reg = reg; 16545 } 16546 if (mac_last < csize) { 16547 mac_last = csize; 16548 } 16549 mac_reg = reg; 16550 } else if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT)|| 16551 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) { 16552 if (gmac_first > csize) { 16553 gmac_first = csize; 16554 gmac_reg = reg; 16555 } 16556 if (gmac_last < csize) { 16557 gmac_last = csize; 16558 } 16559 } 16560 /* CLG2 MIB have some new unique registers which are added 16561 * in seperate counter map. So we use gmac for CLG2. 16562 */ 16563 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) { 16564 if (gmac_first > csize) { 16565 gmac_first = csize; 16566 gmac_reg = reg; 16567 } 16568 if (gmac_last < csize) { 16569 gmac_last = csize; 16570 } 16571 } 16572 } 16573 } 16574 16575 ing_c_cnt = ing_last != -1 ? ing_last - ing_first + 1 : 0; 16576 egr_c_cnt = egr_last != -1 ? egr_last - egr_first + 1 : 0; 16577 mac_c_cnt = mac_last != -1 ? mac_last - mac_first + 1 : 0; 16578 gmac_c_cnt = gmac_last != -1 ? gmac_last - gmac_first + 1 : 0; 16579 soc->counter_ing_first = ing_first; 16580 soc->counter_egr_first = egr_first; 16581 soc->counter_mac_first = mac_last != -1 ? mac_first : gmac_first; 16582 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16583 mac_xlpmib_c_cnt = mac_xlpmib_first != -1 ? mac_xlpmib_last - mac_xlpmib_first + 1 : 0; 16584 #endif 16585 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) 16586 mac_clmib_c_cnt = mac_clmib_first != -1 ? mac_clmib_last - mac_clmib_first + 1 : 0; 16587 #endif /* BCM_GREYHOUND2_SUPPORT */ 16588 16589 assert(SOC_REG_IS_VALID(unit, ing_reg)); 16590 assert(SOC_REG_IS_VALID(unit, egr_reg)); 16591 ing_addr = soc_reg_addr_get(unit, ing_reg, REG_PORT_ANY, 0, 16592 SOC_REG_ADDR_OPTION_NONE, &ing_blkoff, 16593 &ing_acc_type); 16594 egr_addr = soc_reg_addr_get(unit, egr_reg, REG_PORT_ANY, 0, 16595 SOC_REG_ADDR_OPTION_NONE, &egr_blkoff, 16596 &egr_acc_type); 16597 16598 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16599 (BSL_META_U(unit, 16600 "ing_c_cnt = %d egr_c_cnt = %d mac_c_cnt = %d gmac_c_cnt = %d\n" 16601 "ing_blkoff = %d ing_acc_type = %d ing_addr = %08x \n" 16602 "egr_blkoff = %d egr_acc_type = %d egr_addr = %08x \n"), 16603 ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt, 16604 ing_blkoff, ing_acc_type, ing_addr, 16605 egr_blkoff, egr_acc_type, egr_addr)); 16606 #if defined(BCM_MONTEREY_SUPPORT) 16607 if (SOC_IS_MONTEREY(unit)) { 16608 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16609 (BSL_META_U(unit, 16610 "mac_xlpmib_c_cnt = %d "), 16611 mac_xlpmib_c_cnt)); 16612 } 16613 #endif 16614 #if defined(BCM_GREYHOUND2_SUPPORT) 16615 if (SOC_IS_GREYHOUND2(unit)) { 16616 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16617 (BSL_META_U(unit, 16618 "mac_xlpmib_c_cnt = %d mac_clmib_c_cnt = %d\n"), 16619 mac_xlpmib_c_cnt, mac_clmib_c_cnt)); 16620 } 16621 #endif /* BCM_GREYHOUND2_SUPPORT */ 16622 16623 #ifdef SOC_COUNTER_TABLE_SUPPORT 16624 if (SOC_IS_TOMAHAWK3(unit)) { 16625 mib_tbl_c_cnt = mib_tbl_first != -1 ? mib_tbl_last - mib_tbl_first + 1 : 0; 16626 mib_tbl_addr = soc_mem_addr_get(unit, CDMIB_MEMm, 0, 0, 0, &mib_tbl_acc_type); 16627 soc->counter_mib_tbl_first = mib_tbl_first; 16628 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16629 (BSL_META_U(unit, "mib_tbl_c_cnt = %d\n"), mib_tbl_c_cnt)); 16630 } 16631 #endif 16632 16633 SOC_PBMP_CLEAR(all_pbmp); 16634 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 16635 #ifdef BCM_KATANA2_SUPPORT 16636 if (SOC_IS_KATANA2(unit)) { 16637 SOC_PBMP_CLEAR(all_pbmp); 16638 for (my_port = SOC_INFO(unit).cmic_port; 16639 my_port <= SOC_INFO(unit).lb_port; 16640 my_port++) { 16641 if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) { 16642 SOC_PBMP_PORT_ADD(all_pbmp,my_port); 16643 } 16644 } 16645 } 16646 #endif 16647 16648 #if defined(BCM_KATANA2_SUPPORT) 16649 if (!(soc_feature(unit, soc_feature_discontinuous_pp_port))) { 16650 if (soc_feature(unit, soc_feature_linkphy_coe) && 16651 SOC_INFO(unit).linkphy_enabled) { 16652 SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).linkphy_pp_port_pbm); 16653 } 16654 if (soc_feature(unit, soc_feature_subtag_coe) && 16655 SOC_INFO(unit).subtag_enabled) { 16656 SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).subtag_pp_port_pbm); 16657 } 16658 } 16659 #endif 16660 PBMP_ITER(all_pbmp, port) { 16661 16662 soc_sbusdma_desc_ctrl_t ctrl = {0}; 16663 soc_sbusdma_desc_cfg_t cfg; 16664 uint64 *buff; 16665 16666 if (soc_feature(unit, soc_feature_logical_port_num)) { 16667 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 16668 } else { 16669 phy_port = port; 16670 } 16671 buff = &soc->counter_buf64[port * soc->counter_perport]; 16672 16673 /* IPIPE */ 16674 ctrl.flags = 0; 16675 ctrl.cfg_count = 1; 16676 ctrl.buff = &buff[ing_first]; 16677 ctrl.cb = _soc_sbusdma_port_ctr_cb; 16678 ctrl.data = INT_TO_PTR(phy_port); 16679 #define _IP_COUNTERS "IP COUNTERS" 16680 sal_strncpy(ctrl.name, _IP_COUNTERS, sizeof(_IP_COUNTERS)); 16681 cfg.acc_type = ing_acc_type; 16682 cfg.blk = ing_blkoff; 16683 cfg.addr = ing_addr + port; 16684 cfg.width = SOC_REG_IS_64(unit, ing_reg) ? 2 : 1; 16685 cfg.count = ing_c_cnt; 16686 cfg.addr_shift = 8; 16687 SOC_IF_ERROR_RETURN 16688 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 16689 &_soc_port_counter_handles[unit][phy_port][0])); 16690 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16691 (BSL_META_U(unit, 16692 "port %d phy_port %d handle ip: %d\n"), 16693 port, phy_port, _soc_port_counter_handles[unit][phy_port][0])); 16694 16695 /* EPIPE */ 16696 ctrl.buff = &buff[egr_first]; 16697 #define _EP_COUNTERS "EP COUNTERS" 16698 sal_strncpy(ctrl.name, _EP_COUNTERS, sizeof(_EP_COUNTERS)); 16699 cfg.acc_type = egr_acc_type; 16700 cfg.blk = egr_blkoff; 16701 cfg.addr = egr_addr + port; 16702 cfg.width = SOC_REG_IS_64(unit, egr_reg) ? 2 : 1; 16703 cfg.count = egr_c_cnt; 16704 cfg.addr_shift = 8; 16705 SOC_IF_ERROR_RETURN 16706 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 16707 &_soc_port_counter_handles[unit][phy_port][1])); 16708 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16709 (BSL_META_U(unit, 16710 "port %d phy_port %d handle ep: %d\n"), 16711 port, phy_port, _soc_port_counter_handles[unit][phy_port][1])); 16712 16713 #ifdef SOC_COUNTER_TABLE_SUPPORT 16714 /* MIB_TABLE */ 16715 if (SOC_IS_TOMAHAWK3(unit) && 16716 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CDPORT) && 16717 PBMP_MEMBER(soc->counter_pbmp, port)) { 16718 ctrl.flags = SOC_SBUSDMA_MEMORY_CMD_MSG; 16719 ctrl.cfg_count = 1; 16720 ctrl.buff = &buff[mib_tbl_first]; 16721 ctrl.cb = _soc_sbusdma_port_ctr_cb; 16722 ctrl.data = INT_TO_PTR(phy_port); 16723 #define _MIB_TABLE_COUNTERS "MIB TBL CTRS" 16724 sal_strncpy(ctrl.name, _MIB_TABLE_COUNTERS, sizeof(_MIB_TABLE_COUNTERS)); 16725 cfg.acc_type = mib_tbl_acc_type; 16726 cfg.blk = SOC_PORT_BLOCK(unit, phy_port); 16727 cfg.blk = SOC_BLOCK2SCH(unit, cfg.blk); 16728 cfg.addr = mib_tbl_addr + SOC_PORT_BINDEX(unit, phy_port) * NUM_CDMIB_MEM_ROWS_PER_PORT; 16729 cfg.width = 16; /* treat one row (8 counters) as one here */ 16730 cfg.count = mib_tbl_c_cnt / 8; /* 8 counters per row in table */ 16731 cfg.addr_shift = 0; 16732 SOC_IF_ERROR_RETURN 16733 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 16734 &_soc_port_counter_handles[unit][phy_port][4])); 16735 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16736 (BSL_META_U(unit, 16737 "port %d phy_port %d handle mib_table: %d\n"), 16738 port, phy_port, _soc_port_counter_handles[unit][phy_port][4])); 16739 } 16740 #endif 16741 16742 /* MAC */ 16743 for (i = 0; i < port_num_blktype; i++) { 16744 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 16745 if (blk < 0) { 16746 continue; 16747 } 16748 assert(SOC_REG_IS_VALID(unit, mac_reg) || 16749 SOC_REG_IS_VALID(unit, gmac_reg)); 16750 16751 if (SOC_REG_IS_VALID(unit, mac_reg)) { 16752 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_reg).block, 16753 SOC_BLOCK_TYPE(unit, blk))) { 16754 if (SOC_BLOCK_PORT(unit, blk) < 0) { 16755 /* Greyhound phy_port 2-5 have both GXPORT and 16756 XLPORT block attribute. Need to check block_port 16757 to identify the valid attribute */ 16758 continue; 16759 } 16760 break; 16761 } 16762 } 16763 if (SOC_REG_IS_VALID(unit, gmac_reg)) { 16764 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, gmac_reg).block, 16765 SOC_BLOCK_TYPE(unit, blk))) { 16766 if (SOC_BLOCK_PORT(unit, blk) < 0) { 16767 /* Greyhound phy_port 2-5 have both GXPORT and 16768 XLPORT block attribute. Need to check block_port 16769 to identify the valid attribute */ 16770 continue; 16771 } 16772 break; 16773 } 16774 } 16775 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_HELIX5_SUPPORT) 16776 if (SOC_REG_IS_VALID(unit, mac_clmib_reg)) { 16777 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_clmib_reg).block, 16778 SOC_BLOCK_TYPE(unit, blk))) { 16779 if (SOC_BLOCK_PORT(unit, blk) < 0) { 16780 continue; 16781 } 16782 break; 16783 } 16784 } 16785 #endif /* BCM_GREYHOUND2_SUPPORT */ 16786 } 16787 if (i == port_num_blktype) { 16788 continue; 16789 } 16790 16791 mac_blkoff = 0; 16792 mac_addr = 0; 16793 mac_acc_type = 0; 16794 #if defined (BCM_METROLITE_SUPPORT) 16795 if (SOC_IS_METROLITE(unit)) { 16796 if(SOC_PORT_VALID(unit, port)) { 16797 if (phy_port == 0) { 16798 continue; 16799 } 16800 if (phy_port >= 1 && phy_port <= 4) { 16801 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE, 16802 &mac_blkoff, &mac_acc_type); 16803 cfg.count = mac_c_cnt; 16804 } else { 16805 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE, 16806 &mac_blkoff, &mac_acc_type); 16807 cfg.count = gmac_c_cnt; 16808 } 16809 cfg.width = 2; 16810 } 16811 } else 16812 #endif 16813 16814 #if defined (BCM_SABER2_SUPPORT) 16815 if (SOC_IS_SABER2(unit)) { 16816 if(SOC_PORT_VALID(unit, port)) { 16817 if (phy_port == 0) { 16818 continue; 16819 } 16820 if (phy_port >= 1 && phy_port <= 24) { 16821 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, 16822 SOC_REG_ADDR_OPTION_NONE, 16823 &mac_blkoff, &mac_acc_type); 16824 cfg.count = mac_c_cnt; 16825 } else { 16826 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 16827 SOC_REG_ADDR_OPTION_NONE, 16828 &mac_blkoff, &mac_acc_type); 16829 cfg.count = gmac_c_cnt; 16830 } 16831 cfg.width = 2; 16832 } 16833 } else 16834 #endif 16835 #if defined(BCM_HELIX5_SUPPORT) 16836 if (SOC_IS_HELIX5(unit)) { 16837 use_gmac = IS_QSGMII_PORT(unit, port) ? 1 : 0; 16838 cfg.width = 2; 16839 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) { 16840 mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0, FALSE, 16841 &mac_blkoff, &mac_acc_type); 16842 cfg.count = mac_clmib_c_cnt; 16843 } else if (use_gmac) { 16844 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE, 16845 &mac_blkoff, &mac_acc_type); 16846 cfg.count = gmac_c_cnt; 16847 cfg.width = 1; 16848 } else { 16849 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE, 16850 &mac_blkoff, &mac_acc_type); 16851 cfg.count = mac_c_cnt; 16852 } 16853 } else 16854 #endif /* HELIX5 */ 16855 #if defined(BCM_TRIDENT3_SUPPORT) 16856 if (SOC_IS_TRIDENT3X(unit)) { 16857 use_gmac = 16858 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), 16859 SOC_BLK_XLPORT) ? TRUE : FALSE; 16860 gmac_c_width = 2; 16861 if (use_gmac) { 16862 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE, 16863 &mac_blkoff, &mac_acc_type); 16864 cfg.count = gmac_c_cnt; 16865 cfg.width = gmac_c_width; 16866 } else { 16867 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE, 16868 &mac_blkoff, &mac_acc_type); 16869 cfg.count = mac_c_cnt; 16870 cfg.width = 2; 16871 } 16872 } else 16873 #endif /* TRIDENT3 */ 16874 #if defined BCM_TOMAHAWKPLUS_SUPPORT 16875 if (SOC_IS_TOMAHAWKPLUS(unit) && 16876 (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT))) { 16877 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 16878 SOC_REG_ADDR_OPTION_NONE, 16879 &mac_blkoff, &mac_acc_type); 16880 cfg.count = gmac_c_cnt; 16881 cfg.width = 2; 16882 } else 16883 #endif /* BCM_TOMAHAWKPLUS_SUPPORT */ 16884 #if defined BCM_TOMAHAWK2_SUPPORT 16885 if (SOC_IS_TOMAHAWK2(unit)) { 16886 use_gmac = SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT) ? TRUE : FALSE; 16887 gmac_c_width = 2; 16888 16889 if (use_gmac) { 16890 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 16891 SOC_REG_ADDR_OPTION_NONE, 16892 &mac_blkoff, &mac_acc_type); 16893 cfg.count = gmac_c_cnt; 16894 cfg.width = gmac_c_width; 16895 } else { 16896 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, 16897 SOC_REG_ADDR_OPTION_NONE, 16898 &mac_blkoff, &mac_acc_type); 16899 cfg.count = mac_c_cnt; 16900 cfg.width = 2; 16901 } 16902 } else 16903 #endif /* BCM_TOMAHAWK2_SUPPORT */ 16904 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLG2PORT)) { 16905 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 16906 SOC_REG_ADDR_OPTION_NONE, 16907 &mac_blkoff, &mac_acc_type); 16908 cfg.count = gmac_c_cnt; 16909 cfg.width = 2; 16910 } else if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_GPORT)|| 16911 SOC_BLOCK_IS_CMP(unit, SOC_PORT_IDX_BLOCK(unit, phy_port,i), 16912 SOC_BLK_GXPORT)) { 16913 16914 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 16915 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 16916 &mac_acc_type); 16917 cfg.count = gmac_c_cnt; 16918 cfg.width = 1; 16919 } else { 16920 #ifdef BCM_GREYHOUND2_SUPPORT 16921 if ((SOC_IS_GREYHOUND2(unit)) && 16922 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) { 16923 mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0, 16924 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 16925 &mac_acc_type); 16926 cfg.count = mac_clmib_c_cnt; 16927 cfg.width = 2; 16928 } else 16929 #endif /* BCM_GREYHOUND2_SUPPORT */ 16930 { 16931 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, 16932 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 16933 &mac_acc_type); 16934 cfg.count = mac_c_cnt; 16935 cfg.width = 2; 16936 } 16937 } 16938 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16939 (BSL_META_U(unit, 16940 "port %d mac_blkoff = %d, mac_addr = %08x\n"), 16941 port, mac_blkoff, mac_addr)); 16942 16943 /* MAC or port group */ 16944 ctrl.buff = &buff[soc->counter_mac_first]; 16945 #define _MIBS "MIBS" 16946 sal_strncpy(ctrl.name, _MIBS, sizeof(_MIBS)); 16947 cfg.acc_type = mac_acc_type; 16948 cfg.blk = mac_blkoff; 16949 cfg.addr = mac_addr; 16950 cfg.addr_shift = 8; 16951 SOC_IF_ERROR_RETURN 16952 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 16953 &_soc_port_counter_handles[unit][phy_port][2])); 16954 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16955 (BSL_META_U(unit, 16956 "port %d phy_port %d handle mib: %d\n"), 16957 port, phy_port, _soc_port_counter_handles[unit][phy_port][2])); 16958 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 16959 /* MAC for XLPMIB */ 16960 if ((SOC_IS_GREYHOUND2(unit) && 16961 (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT))) || 16962 (SOC_IS_MONTEREY(unit))){ 16963 mac_addr = soc_reg_addr_get(unit, mac_xlpmib_reg, port, 0, 16964 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 16965 &mac_acc_type); 16966 cfg.count = mac_xlpmib_c_cnt; 16967 cfg.width = 2; 16968 16969 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16970 (BSL_META_U(unit, 16971 "port %d mac_xlpmib_c_cnt = %d\n" 16972 "mac_blkoff = %d, mac_addr = %08x\n"), 16973 port, mac_xlpmib_c_cnt, mac_blkoff, mac_addr)); 16974 16975 ctrl.buff = &buff[mac_xlpmib_first]; 16976 #define _XLPMIBS "XLPMIBS" 16977 sal_strncpy(ctrl.name, _XLPMIBS, sizeof(_XLPMIBS)); 16978 cfg.acc_type = mac_acc_type; 16979 cfg.blk = mac_blkoff; 16980 cfg.addr = mac_addr; 16981 cfg.addr_shift = 8; 16982 SOC_IF_ERROR_RETURN 16983 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 16984 &_soc_port_counter_handles[unit][phy_port][3])); 16985 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 16986 (BSL_META_U(unit, 16987 "port %d phy_port %d handle xlpmib: %d\n"), 16988 port, phy_port, _soc_port_counter_handles[unit][phy_port][3])); 16989 } 16990 #endif /* BCM_GREYHOUND2_SUPPORT */ 16991 } 16992 16993 16994 16995 if (soc->blk_ctr_desc_count) { 16996 int rc; 16997 uint16 cnt, bindex; 16998 soc_sbusdma_desc_ctrl_t ctrl = {0}; 16999 soc_sbusdma_desc_cfg_t *cfg; 17000 uint64 *buff, *hwval, *swval; 17001 sal_memset(_soc_blk_counter_handles[unit], 0, 17002 soc->blk_ctr_desc_count * sizeof(sbusdma_desc_handle_t)); 17003 _blk_ctr_process[unit] = sal_alloc(soc->blk_ctr_desc_count * 17004 sizeof(soc_blk_ctr_process_t*), 17005 "blk_ctr_process_ptr"); 17006 buff = soc->blk_ctr_buf; 17007 hwval = soc->blk_counter_hw_val; 17008 swval = soc->blk_counter_sw_val; 17009 for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) { 17010 cnt = 0; 17011 while (soc->blk_ctr_desc[bindex].desc[cnt].reg != INVALIDr) { 17012 cnt++; 17013 } 17014 if (cnt) { 17015 uint8 at; 17016 uint16 i; 17017 int ctr_blk; 17018 soc_blk_ctr_process_t *ctr_process; 17019 cfg = sal_alloc(cnt * sizeof(soc_sbusdma_desc_cfg_t), 17020 "sbusdma_desc_cfg"); 17021 if (cfg == NULL) { 17022 return SOC_E_MEMORY; 17023 } 17024 ctrl.flags = 0; 17025 ctrl.cfg_count = cnt; 17026 ctrl.buff = buff; 17027 ctrl.cb = _soc_sbusdma_blk_ctr_cb; 17028 #define _BLK_CTRS "BLK CTRS" 17029 sal_strncpy(ctrl.name, _BLK_CTRS, sizeof(_BLK_CTRS)); 17030 ctr_process = sal_alloc(sizeof(soc_blk_ctr_process_t), "blk_ctr_process"); 17031 if (cfg == NULL) { 17032 sal_free(cfg); 17033 return SOC_E_MEMORY; 17034 } 17035 ctr_process->blk = soc->blk_ctr_desc[bindex].blk; 17036 ctr_process->bindex = bindex; 17037 ctr_process->entries = cnt; 17038 ctr_process->buff = buff; 17039 ctr_process->hwval = hwval; 17040 ctr_process->swval = swval; 17041 ctrl.data = INT_TO_PTR((uint32)bindex); 17042 _blk_ctr_process[unit][bindex] = ctr_process; 17043 for (i=0; i<cnt; i++) { 17044 cfg[i].addr = soc_reg_addr_get(unit, 17045 soc->blk_ctr_desc[bindex].desc[i].reg, 17046 REG_PORT_ANY, 0, 17047 SOC_REG_ADDR_OPTION_NONE, 17048 &ctr_blk, &at); 17049 cfg[i].blk = ctr_blk; 17050 cfg[i].width = soc->blk_ctr_desc[bindex].desc[i].width; 17051 cfg[i].count = soc->blk_ctr_desc[bindex].desc[i].entries; 17052 cfg[i].addr_shift = soc->blk_ctr_desc[bindex].desc[i].shift; 17053 } 17054 rc = soc_sbusdma_desc_create(unit, &ctrl, cfg, 17055 &_soc_blk_counter_handles[unit][bindex]); 17056 sal_free(cfg); 17057 if (rc != SOC_E_NONE) { 17058 LOG_ERROR(BSL_LS_SOC_COMMON, 17059 (BSL_META_U(unit, 17060 "Desc creation error for handle blk: %d\n"), 17061 _soc_blk_counter_handles[unit][bindex])); 17062 return rc; 17063 } 17064 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17065 (BSL_META_U(unit, 17066 "handle blk: %d\n"), 17067 _soc_blk_counter_handles[unit][bindex])); 17068 } 17069 buff += cnt; hwval += cnt; swval += cnt; 17070 } 17071 } 17072 return SOC_E_NONE; 17073 } 17074 17075 #if defined(BCM_XGS5_SWITCH_PORT_SUPPORT) 17076 /* 17077 * Function: 17078 * soc_counter_port_sbusdma_desc_alloc 17079 * Purpose: 17080 * Allocate the Sbus DMA descriptors for the port. 17081 * . 17082 * Parameters: 17083 * unit - (IN) Unit number. 17084 * port - (IN) Logical port. 17085 * Returns: 17086 * SOC_E_NONE Success 17087 * SOC_E_* 17088 */ 17089 int 17090 soc_counter_port_sbusdma_desc_alloc(int unit, soc_port_t port) 17091 { 17092 soc_control_t *soc; 17093 int csize; 17094 soc_ctr_type_t ctype; 17095 soc_reg_t reg, ing_reg, egr_reg, mac_reg, gmac_reg; 17096 int ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt; 17097 int ing_first, egr_first, mac_first, gmac_first; 17098 int ing_last, egr_last, mac_last, gmac_last; 17099 uint32 ing_addr, egr_addr, mac_addr; 17100 int ing_blkoff, egr_blkoff, mac_blkoff; 17101 uint8 ing_acc_type, egr_acc_type, mac_acc_type; 17102 int blk, phy_port, i; 17103 int port_num_blktype; 17104 soc_sbusdma_desc_ctrl_t ctrl = {0}; 17105 soc_sbusdma_desc_cfg_t cfg; 17106 uint64 *buff; 17107 #if defined(BCM_TOMAHAWK2_SUPPORT) 17108 int use_gmac, gmac_c_width; 17109 #endif 17110 #ifdef SOC_COUNTER_TABLE_SUPPORT 17111 int mib_tbl_first = 10000; /* a huge number */ 17112 int mib_tbl_last = -1; 17113 int mib_tbl_c_cnt = 0; 17114 uint32 mib_tbl_addr = 0; 17115 uint8 mib_tbl_acc_type = 0; 17116 #endif 17117 #if defined(BCM_MONTEREY_SUPPORT) 17118 soc_reg_t mac_xlpmib_reg; 17119 int mac_xlpmib_c_cnt, mac_xlpmib_first, mac_xlpmib_last; 17120 #endif 17121 #if defined(BCM_HELIX5_SUPPORT) 17122 soc_reg_t mac_clmib_reg; 17123 int mac_clmib_c_cnt, mac_clmib_first, mac_clmib_last; 17124 #endif 17125 soc = SOC_CONTROL(unit); 17126 17127 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 17128 if (phy_port == -1) { 17129 return SOC_E_INTERNAL; 17130 } 17131 17132 port_num_blktype = SOC_DRIVER(unit)->port_num_blktype > 1 ? 17133 SOC_DRIVER(unit)->port_num_blktype : 1; 17134 17135 ing_reg = INVALIDr; 17136 egr_reg = INVALIDr; 17137 mac_reg = INVALIDr; 17138 gmac_reg = INVALIDr; 17139 ing_first = 10000; /* a huge number */ 17140 egr_first = 10000; 17141 mac_first = 10000; 17142 gmac_first = 10000; 17143 ing_last = -1; 17144 egr_last = -1; 17145 mac_last = -1; 17146 gmac_last = -1; 17147 ing_reg = INVALIDr; 17148 egr_reg = INVALIDr; 17149 mac_reg = INVALIDr; 17150 gmac_reg = INVALIDr; 17151 #if defined(BCM_MONTEREY_SUPPORT) 17152 mac_xlpmib_reg = INVALIDr; 17153 mac_xlpmib_first = 10000; 17154 mac_xlpmib_last = -1; 17155 #endif 17156 #if defined(BCM_HELIX5_SUPPORT) 17157 mac_clmib_reg = INVALIDr; 17158 mac_clmib_first = 10000; 17159 mac_clmib_last = -1; 17160 #endif 17161 for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) { 17162 if (!SOC_HAS_CTR_TYPE(unit, ctype)) { 17163 continue; 17164 } 17165 for (csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; csize >= 0; csize--) { 17166 reg = SOC_CTR_TO_REG(unit, ctype, csize); 17167 if (SOC_COUNTER_INVALID(unit, reg)) { 17168 continue; /* skip trailing invalids */ 17169 } 17170 #ifdef SOC_COUNTER_TABLE_SUPPORT 17171 if (SOC_IS_TOMAHAWK3(unit) && 17172 SOC_REG_IS_COUNTER_TABLE(unit, reg)) { 17173 if (mib_tbl_first > csize) { 17174 mib_tbl_first = csize; 17175 } 17176 if (mib_tbl_last < csize) { 17177 mib_tbl_last = csize; 17178 } 17179 continue; 17180 } 17181 #endif 17182 if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_IPIPE)) { 17183 if (ing_first > csize) { 17184 ing_first = csize; 17185 ing_reg = reg; 17186 } 17187 if (ing_last < csize) { 17188 ing_last = csize; 17189 } 17190 } 17191 if (SOC_REG_BLOCK_IS(unit, reg, SOC_BLK_EPIPE)) { 17192 if (egr_first > csize) { 17193 egr_first = csize; 17194 egr_reg = reg; 17195 } 17196 if (egr_last < csize) { 17197 egr_last = csize; 17198 } 17199 } 17200 #if defined(BCM_TOMAHAWK2_SUPPORT) 17201 if (SOC_IS_TOMAHAWK2(unit)) { 17202 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) { 17203 if (mac_first > csize) { 17204 mac_first = csize; 17205 mac_reg = reg; 17206 } 17207 if (mac_last < csize) { 17208 mac_last = csize; 17209 } 17210 mac_reg = reg; 17211 continue; 17212 } 17213 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 17214 if (gmac_first > csize) { 17215 gmac_first = csize; 17216 gmac_reg = reg; 17217 } 17218 if (gmac_last < csize) { 17219 gmac_last = csize; 17220 } 17221 continue; 17222 } 17223 } 17224 #endif /* BCM_TOMAHAWK2_SUPPORT */ 17225 #if defined(BCM_MONTEREY_SUPPORT) 17226 if (SOC_IS_MONTEREY(unit)) { 17227 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 17228 /* The first XLPMIB_XXXr offset = 0x10000 (XLPMIB_R64r) */ 17229 if (SOC_REG_INFO(unit, reg).offset & 0x10000) { 17230 if (mac_xlpmib_first > csize) { 17231 mac_xlpmib_first = csize; 17232 mac_xlpmib_reg = reg; 17233 } 17234 if (mac_xlpmib_last < csize) { 17235 mac_xlpmib_last = csize; 17236 } 17237 mac_xlpmib_reg = reg; 17238 17239 } else { 17240 if (mac_first > csize) { 17241 mac_first = csize; 17242 mac_reg = reg; 17243 } 17244 if (mac_last < csize) { 17245 mac_last = csize; 17246 } 17247 mac_reg = reg; 17248 } 17249 continue; 17250 } 17251 } 17252 #endif 17253 #ifdef BCM_HELIX5_SUPPORT 17254 if (SOC_IS_HELIX5(unit)) { 17255 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT)) { 17256 if (mac_first > csize) { 17257 mac_first = csize; 17258 } 17259 if (mac_last < csize) { 17260 mac_last = csize; 17261 } 17262 mac_reg = reg; 17263 continue; 17264 } 17265 17266 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) { 17267 if (gmac_first > csize) { 17268 gmac_first = csize; 17269 } 17270 if (gmac_last < csize) { 17271 gmac_last = csize; 17272 } 17273 gmac_reg = reg; 17274 continue; 17275 } 17276 17277 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT)) { 17278 if (mac_clmib_first > csize) { 17279 mac_clmib_first = csize; 17280 } 17281 if (mac_clmib_last < csize) { 17282 mac_clmib_last = csize; 17283 } 17284 mac_clmib_reg = reg; 17285 continue; 17286 } 17287 } 17288 #endif /* BCM_HELIX5_SUPPORT */ 17289 17290 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORT) || 17291 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XLPORTB0) || 17292 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XTPORT) || 17293 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_XWPORT) || 17294 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLPORT) || 17295 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_MXQPORT) || 17296 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_PGW_CL)) { 17297 if (mac_first > csize) { 17298 mac_first = csize; 17299 mac_reg = reg; 17300 } 17301 if (mac_last < csize) { 17302 mac_last = csize; 17303 } 17304 mac_reg = reg; 17305 } else if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GPORT)|| 17306 SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_GXPORT)) { 17307 if (gmac_first > csize) { 17308 gmac_first = csize; 17309 gmac_reg = reg; 17310 } 17311 if (gmac_last < csize) { 17312 gmac_last = csize; 17313 } 17314 } 17315 /* CLG2 MIB have some new unique registers which are added 17316 * in seperate counter map. So we use gmac for CLG2. 17317 */ 17318 if (SOC_REG_BLOCK_IN_LIST(unit, reg, SOC_BLK_CLG2PORT)) { 17319 if (gmac_first > csize) { 17320 gmac_first = csize; 17321 gmac_reg = reg; 17322 } 17323 if (gmac_last < csize) { 17324 gmac_last = csize; 17325 } 17326 } 17327 } 17328 } 17329 17330 ing_c_cnt = ing_first != -1 ? ing_last - ing_first + 1 : 0; 17331 egr_c_cnt = egr_first != -1 ? egr_last - egr_first + 1 : 0; 17332 mac_c_cnt = mac_first != -1 ? mac_last - mac_first + 1 : 0; 17333 gmac_c_cnt = gmac_first != -1 ? gmac_last - gmac_first + 1 : 0; 17334 #if defined(BCM_HELIX5_SUPPORT) 17335 mac_clmib_c_cnt = mac_clmib_first != -1 ? mac_clmib_last - mac_clmib_first + 1 : 0; 17336 #endif /* BCM_MONTEREY_SUPPORT */ 17337 soc->counter_ing_first = ing_first; 17338 soc->counter_egr_first = egr_first; 17339 soc->counter_mac_first = mac_first; 17340 #if defined(BCM_MONTEREY_SUPPORT) 17341 mac_xlpmib_c_cnt = mac_xlpmib_first != -1 ? mac_xlpmib_last - mac_xlpmib_first + 1 : 0; 17342 #endif /* BCM_MONTEREY_SUPPORT */ 17343 assert(SOC_REG_IS_VALID(unit, ing_reg)); 17344 assert(SOC_REG_IS_VALID(unit, egr_reg)); 17345 ing_addr = soc_reg_addr_get(unit, ing_reg, REG_PORT_ANY, 0, 17346 SOC_REG_ADDR_OPTION_NONE, &ing_blkoff, 17347 &ing_acc_type); 17348 egr_addr = soc_reg_addr_get(unit, egr_reg, REG_PORT_ANY, 0, 17349 SOC_REG_ADDR_OPTION_NONE, &egr_blkoff, 17350 &egr_acc_type); 17351 17352 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17353 (BSL_META_U(unit, 17354 "ing_c_cnt = %d egr_c_cnt = %d mac_c_cnt = %d gmac_c_cnt = %d\n" 17355 "ing_blkoff = %d ing_acc_type = %d ing_addr = %08x \n" 17356 "egr_blkoff = %d egr_acc_type = %d egr_addr = %08x \n"), 17357 ing_c_cnt, egr_c_cnt, mac_c_cnt, gmac_c_cnt, 17358 ing_blkoff, ing_acc_type, ing_addr, 17359 egr_blkoff, egr_acc_type, egr_addr)); 17360 #if defined(BCM_MONTEREY_SUPPORT) 17361 if ( SOC_IS_MONTEREY(unit)) { 17362 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17363 (BSL_META_U(unit, 17364 "mac_xlpmib_c_cnt = %d \n"), 17365 mac_xlpmib_c_cnt )); 17366 } 17367 #endif /* BCM_MONTEREY_SUPPORT */ 17368 #ifdef SOC_COUNTER_TABLE_SUPPORT 17369 if (SOC_IS_TOMAHAWK3(unit)) { 17370 mib_tbl_c_cnt = mib_tbl_first != -1 ? mib_tbl_last - mib_tbl_first + 1 : 0; 17371 mib_tbl_addr = soc_mem_addr_get(unit, CDMIB_MEMm, 0, 0, 0, &mib_tbl_acc_type); 17372 soc->counter_mib_tbl_first = mib_tbl_first; 17373 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17374 (BSL_META_U(unit, "mib_tbl_c_cnt = %d\n"), mib_tbl_c_cnt)); 17375 } 17376 #endif 17377 buff = &soc->counter_buf64[port * soc->counter_perport]; 17378 17379 /* IPIPE */ 17380 ctrl.flags = 0; 17381 ctrl.cfg_count = 1; 17382 ctrl.buff = &buff[ing_first]; 17383 ctrl.cb = _soc_sbusdma_port_ctr_cb; 17384 ctrl.data = INT_TO_PTR(phy_port); 17385 ctrl.pc = 0; 17386 ctrl.pc_data = 0; 17387 #define _IP_COUNTERS "IP COUNTERS" 17388 sal_strncpy(ctrl.name, _IP_COUNTERS, sizeof(_IP_COUNTERS)); 17389 cfg.acc_type = ing_acc_type; 17390 cfg.blk = ing_blkoff; 17391 cfg.addr = ing_addr + port; 17392 cfg.width = SOC_REG_IS_64(unit, ing_reg) ? 2 : 1; 17393 cfg.count = ing_c_cnt; 17394 cfg.addr_shift = 8; 17395 SOC_IF_ERROR_RETURN 17396 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 17397 &_soc_port_counter_handles[unit][phy_port][0])); 17398 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17399 (BSL_META_U(unit, 17400 "port %d phy_port %d handle ip: %d\n"), 17401 port, phy_port, _soc_port_counter_handles[unit][phy_port][0])); 17402 17403 /* EPIPE */ 17404 ctrl.buff = &buff[egr_first]; 17405 #define _EP_COUNTERS "EP COUNTERS" 17406 sal_strncpy(ctrl.name, _EP_COUNTERS, sizeof(_EP_COUNTERS)); 17407 cfg.acc_type = egr_acc_type; 17408 cfg.blk = egr_blkoff; 17409 cfg.addr = egr_addr + port; 17410 cfg.width = SOC_REG_IS_64(unit, egr_reg) ? 2 : 1; 17411 cfg.count = egr_c_cnt; 17412 cfg.addr_shift = 8; 17413 SOC_IF_ERROR_RETURN 17414 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 17415 &_soc_port_counter_handles[unit][phy_port][1])); 17416 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17417 (BSL_META_U(unit, 17418 "port %d phy_port %d handle ep: %d\n"), 17419 port, phy_port, _soc_port_counter_handles[unit][phy_port][1])); 17420 17421 #ifdef SOC_COUNTER_TABLE_SUPPORT 17422 /* MIB_TABLE */ 17423 if (SOC_IS_TOMAHAWK3(unit) && 17424 SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CDPORT)) { 17425 ctrl.flags = SOC_SBUSDMA_MEMORY_CMD_MSG; 17426 ctrl.cfg_count = 1; 17427 ctrl.buff = &buff[mib_tbl_first]; 17428 ctrl.cb = _soc_sbusdma_port_ctr_cb; 17429 ctrl.data = INT_TO_PTR(phy_port); 17430 #define _MIB_TABLE_COUNTERS "MIB TBL CTRS" 17431 sal_strncpy(ctrl.name, _MIB_TABLE_COUNTERS, sizeof(_MIB_TABLE_COUNTERS)); 17432 cfg.acc_type = mib_tbl_acc_type; 17433 cfg.blk = SOC_PORT_BLOCK(unit, phy_port); 17434 cfg.blk = SOC_BLOCK2SCH(unit, cfg.blk); 17435 cfg.addr = mib_tbl_addr + SOC_PORT_BINDEX(unit, phy_port) * NUM_CDMIB_MEM_ROWS_PER_PORT; 17436 cfg.width = 16; /* treat one row (8 counters) as one here */ 17437 cfg.count = mib_tbl_c_cnt / 8; /* 8 counters per row in table */ 17438 cfg.addr_shift = 0; 17439 SOC_IF_ERROR_RETURN 17440 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 17441 &_soc_port_counter_handles[unit][phy_port][4])); 17442 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17443 (BSL_META_U(unit, 17444 "port %d phy_port %d handle mib_table: %d\n"), 17445 port, phy_port, _soc_port_counter_handles[unit][phy_port][4])); 17446 } 17447 #endif 17448 17449 /* MAC */ 17450 for (i = 0; i < port_num_blktype; i++) { 17451 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 17452 if (blk < 0) { 17453 continue; 17454 } 17455 assert(SOC_REG_IS_VALID(unit, mac_reg) || 17456 SOC_REG_IS_VALID(unit, gmac_reg)); 17457 17458 if (SOC_REG_IS_VALID(unit, mac_reg)) { 17459 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_reg).block, 17460 SOC_BLOCK_TYPE(unit, blk))) { 17461 if (SOC_BLOCK_PORT(unit, blk) < 0) { 17462 /* Greyhound phy_port 2-5 have both GXPORT and 17463 XLPORT block attribute. Need to check block_port 17464 to identify the valid attribute */ 17465 continue; 17466 } 17467 break; 17468 } 17469 } 17470 if (SOC_REG_IS_VALID(unit, gmac_reg)) { 17471 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, gmac_reg).block, 17472 SOC_BLOCK_TYPE(unit, blk))) { 17473 if (SOC_BLOCK_PORT(unit, blk) < 0) { 17474 /* Greyhound phy_port 2-5 have both GXPORT and 17475 XLPORT block attribute. Need to check block_port 17476 to identify the valid attribute */ 17477 continue; 17478 } 17479 break; 17480 } 17481 } 17482 17483 #if defined(BCM_HELIX5_SUPPORT) 17484 if (SOC_REG_IS_VALID(unit, mac_clmib_reg)) { 17485 if (SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, mac_clmib_reg).block, 17486 SOC_BLOCK_TYPE(unit, blk))) { 17487 if (SOC_BLOCK_PORT(unit, blk) < 0) { 17488 continue; 17489 } 17490 break; 17491 } 17492 } 17493 #endif /* BCM_HELIX5_SUPPORT */ 17494 17495 } 17496 if (i == port_num_blktype) { 17497 return SOC_E_NONE; 17498 } 17499 17500 mac_blkoff = 0; 17501 mac_addr = 0; 17502 mac_acc_type = 0; 17503 17504 #if defined(BCM_TOMAHAWK2_SUPPORT) 17505 if (SOC_IS_TOMAHAWK2(unit)) { 17506 use_gmac = SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_XLPORT) ? TRUE : FALSE; 17507 gmac_c_width = 2; 17508 17509 if (use_gmac) { 17510 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 17511 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 17512 &mac_acc_type); 17513 cfg.count = gmac_c_cnt; 17514 cfg.width = gmac_c_width; 17515 } else { 17516 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, 17517 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 17518 &mac_acc_type); 17519 cfg.count = mac_c_cnt; 17520 cfg.width = 2; 17521 } 17522 } else 17523 #endif /* BCM_TOMAHAWK2_SUPPORT */ 17524 #if defined(BCM_HELIX5_SUPPORT) 17525 if (SOC_IS_HELIX5(unit)) { 17526 cfg.width = 2; 17527 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLPORT)) { 17528 mac_addr = soc_reg_addr_get(unit, mac_clmib_reg, port, 0, FALSE, 17529 &mac_blkoff, &mac_acc_type); 17530 cfg.count = mac_clmib_c_cnt; 17531 } else if (IS_QSGMII_PORT(unit, port)) { 17532 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, FALSE, 17533 &mac_blkoff, &mac_acc_type); 17534 cfg.count = gmac_c_cnt; 17535 cfg.width = 1; 17536 } else { 17537 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, FALSE, 17538 &mac_blkoff, &mac_acc_type); 17539 cfg.count = mac_c_cnt; 17540 } 17541 } else 17542 #endif /* BCM_HELIX5_SUPPORT */ 17543 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_CLG2PORT)) { 17544 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 17545 SOC_REG_ADDR_OPTION_NONE, 17546 &mac_blkoff, &mac_acc_type); 17547 cfg.count = gmac_c_cnt; 17548 cfg.width = 2; 17549 } else if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), SOC_BLK_GPORT)|| 17550 SOC_BLOCK_IS_CMP(unit, SOC_PORT_IDX_BLOCK(unit, phy_port,i), 17551 SOC_BLK_GXPORT)) { 17552 mac_addr = soc_reg_addr_get(unit, gmac_reg, port, 0, 17553 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 17554 &mac_acc_type); 17555 cfg.count = gmac_c_cnt; 17556 cfg.width = 1; 17557 } else { 17558 17559 mac_addr = soc_reg_addr_get(unit, mac_reg, port, 0, 17560 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 17561 &mac_acc_type); 17562 cfg.count = mac_c_cnt; 17563 cfg.width = 2; 17564 17565 } 17566 17567 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17568 (BSL_META_U(unit, 17569 "port %d mac_blkoff = %d, mac_addr = %08x\n"), 17570 port, mac_blkoff, mac_addr)); 17571 ctrl.buff = &buff[mac_first]; 17572 #define _MIBS "MIBS" 17573 sal_strncpy(ctrl.name, _MIBS, sizeof(_MIBS)); 17574 cfg.acc_type = mac_acc_type; 17575 cfg.blk = mac_blkoff; 17576 cfg.addr = mac_addr; 17577 cfg.addr_shift = 8; 17578 SOC_IF_ERROR_RETURN 17579 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 17580 &_soc_port_counter_handles[unit][phy_port][2])); 17581 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17582 (BSL_META_U(unit, 17583 "port %d phy_port %d handle mib: %d\n"), 17584 port, phy_port, _soc_port_counter_handles[unit][phy_port][2])); 17585 17586 #if defined(BCM_MONTEREY_SUPPORT) 17587 /* MAC for XLPMIB */ 17588 if (SOC_IS_MONTEREY(unit)) 17589 { 17590 mac_addr = soc_reg_addr_get(unit, mac_xlpmib_reg, port, 0, 17591 SOC_REG_ADDR_OPTION_NONE, &mac_blkoff, 17592 &mac_acc_type); 17593 cfg.count = mac_xlpmib_c_cnt; 17594 cfg.width = 2; 17595 17596 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17597 (BSL_META_U(unit, 17598 "port %d mac_xlpmib_c_cnt = %d\n" 17599 "mac_blkoff = %d, mac_addr = %08x\n"), 17600 port, mac_xlpmib_c_cnt, mac_blkoff, mac_addr)); 17601 17602 ctrl.buff = &buff[mac_xlpmib_first]; 17603 #define _XLPMIBS "XLPMIBS" 17604 sal_strncpy(ctrl.name, _XLPMIBS, sizeof(_XLPMIBS)); 17605 cfg.acc_type = mac_acc_type; 17606 cfg.blk = mac_blkoff; 17607 cfg.addr = mac_addr; 17608 cfg.addr_shift = 8; 17609 SOC_IF_ERROR_RETURN 17610 (soc_sbusdma_desc_create(unit, &ctrl, &cfg, 17611 &_soc_port_counter_handles[unit][phy_port][3])); 17612 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17613 (BSL_META_U(unit, 17614 "port %d phy_port %d handle xlpmib: %d\n"), 17615 port, phy_port, _soc_port_counter_handles[unit][phy_port][3])); 17616 } 17617 #endif /* BCM_MONTEREY_SUPPORT*/ 17618 return SOC_E_NONE; 17619 } 17620 17621 /* 17622 * Function: 17623 * soc_counter_port_sbusdma_desc_free 17624 * Purpose: 17625 * Deallocte or free the Sbus DMA descriptors 17626 * associated with the port. 17627 * 17628 * Parameters: 17629 * unit - (IN) Unit number. 17630 * port - (IN) Logical port. 17631 * Returns: 17632 * SOC_E_NONE Success 17633 * SOC_E_* 17634 */ 17635 int 17636 soc_counter_port_sbusdma_desc_free(int unit, soc_port_t port) 17637 { 17638 soc_control_t *soc = SOC_CONTROL(unit); 17639 uint8 i, state = 0; 17640 int ret, err = 0; 17641 int blk, bindex, phy_port; 17642 17643 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 17644 if (phy_port == -1 ) { 17645 return SOC_E_INTERNAL; 17646 } 17647 17648 blk = SOC_PORT_BLOCK(unit, phy_port); 17649 bindex = SOC_PORT_BINDEX(unit, phy_port); 17650 if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) { 17651 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17652 (BSL_META_U(unit, 17653 "port: %d blk: %d, bindex: %d\n"), 17654 port, blk, bindex)); 17655 } 17656 for (i = 0; i <= (COUNTER_SBUSDMA_DESC_SIZE-1); i++) { 17657 if ((i == 2) && 17658 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) && 17659 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) && 17660 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) && 17661 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) && 17662 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) && 17663 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) && 17664 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) && 17665 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) && 17666 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) && 17667 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) { 17668 continue; 17669 } 17670 #if defined(BCM_MONTEREY_SUPPORT) 17671 if (i == 3) { 17672 if (!SOC_IS_MONTEREY(unit)) { 17673 continue; 17674 } 17675 } 17676 #endif 17677 if (_soc_port_counter_handles[unit][phy_port][i]) { 17678 do { 17679 (void)soc_sbusdma_desc_get_state(unit, _soc_port_counter_handles[unit][phy_port][i], 17680 &state); 17681 if (state) { 17682 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 17683 } 17684 } while (state); 17685 17686 ret = soc_sbusdma_desc_delete(unit, _soc_port_counter_handles[unit][phy_port][i]); 17687 if (ret) { 17688 err++; 17689 } 17690 _soc_port_counter_handles[unit][phy_port][i] = 0; 17691 } 17692 } 17693 17694 return err; 17695 } 17696 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT*/ 17697 17698 int 17699 _soc_counter_sbudma_desc_free_all(int unit) 17700 { 17701 soc_control_t *soc = SOC_CONTROL(unit); 17702 uint8 i, state = 0; 17703 int ret, err = 0; 17704 soc_port_t port; 17705 int blk, bindex, phy_port; 17706 soc_pbmp_t all_pbmp; 17707 #ifdef BCM_KATANA2_SUPPORT 17708 soc_port_t my_port; 17709 #endif 17710 17711 SOC_PBMP_CLEAR(all_pbmp); 17712 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 17713 #ifdef BCM_KATANA2_SUPPORT 17714 if (SOC_IS_KATANA2(unit)) { 17715 SOC_PBMP_CLEAR(all_pbmp); 17716 for (my_port = SOC_INFO(unit).cmic_port; 17717 my_port <= SOC_INFO(unit).lb_port; 17718 my_port++) { 17719 if (SOC_INFO(unit).block_valid[SOC_PORT_BLOCK(unit,my_port)]) { 17720 SOC_PBMP_PORT_ADD(all_pbmp,my_port); 17721 } 17722 } 17723 } 17724 #endif 17725 #if defined(BCM_KATANA2_SUPPORT) 17726 if (!(soc_feature(unit, soc_feature_discontinuous_pp_port))) { 17727 if (soc_feature(unit, soc_feature_linkphy_coe) && 17728 SOC_INFO(unit).linkphy_enabled) { 17729 SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).linkphy_pp_port_pbm); 17730 } 17731 if (soc_feature(unit, soc_feature_subtag_coe) && 17732 SOC_INFO(unit).subtag_enabled) { 17733 SOC_PBMP_REMOVE(all_pbmp, SOC_INFO(unit).subtag_pp_port_pbm); 17734 } 17735 } 17736 #endif 17737 PBMP_ITER(all_pbmp, port) { 17738 if (soc_feature(unit, soc_feature_logical_port_num)) { 17739 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 17740 } else { 17741 phy_port = port; 17742 } 17743 17744 blk = SOC_PORT_BLOCK(unit, phy_port); 17745 #if defined(BCM_MONTEREY_SUPPORT) 17746 if (SOC_IS_MONTEREY(unit) ) { 17747 if ((((phy_port > 0) && (phy_port < 13)) || 17748 ((phy_port > 52) && (phy_port < 65))) 17749 && !(IS_CPRI_PORT(unit, port))) { 17750 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,1); 17751 } else { 17752 blk = SOC_PORT_IDX_BLOCK(unit, phy_port ,0); 17753 } 17754 } 17755 #endif 17756 bindex = SOC_PORT_BINDEX(unit, phy_port); 17757 if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) { 17758 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 17759 (BSL_META_U(unit, 17760 "port: %d blk: %d, bindex: %d\n"), 17761 port, blk, bindex)); 17762 } 17763 for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) { 17764 if ((i == 2) && 17765 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) && 17766 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) && 17767 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) && 17768 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) && 17769 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) && 17770 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) && 17771 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) && 17772 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) && 17773 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CPRI) && 17774 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT && 17775 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT)))) { 17776 continue; 17777 } 17778 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 17779 if (i == 3) { 17780 if (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit))) { 17781 continue; 17782 } 17783 if (SOC_IS_GREYHOUND2(unit) && 17784 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT))) { 17785 continue; 17786 } 17787 } 17788 #endif 17789 if (_soc_port_counter_handles[unit][phy_port][i]) { 17790 do { 17791 (void)soc_sbusdma_desc_get_state(unit, _soc_port_counter_handles[unit][phy_port][i], 17792 &state); 17793 if (state) { 17794 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 17795 } 17796 } while (state); 17797 17798 ret = soc_sbusdma_desc_delete(unit, _soc_port_counter_handles[unit][phy_port][i]); 17799 if (ret) { 17800 err++; 17801 } 17802 _soc_port_counter_handles[unit][phy_port][i] = 0; 17803 } 17804 } 17805 } 17806 if (soc->blk_ctr_desc_count && _soc_blk_counter_handles[unit]) { 17807 uint16 bindex; 17808 for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) { 17809 if (_soc_blk_counter_handles[unit][bindex]) { 17810 do { 17811 (void)soc_sbusdma_desc_get_state(unit, _soc_blk_counter_handles[unit][bindex], 17812 &state); 17813 if (state) { 17814 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 17815 } 17816 } while (state); 17817 ret = soc_sbusdma_desc_delete(unit, _soc_blk_counter_handles[unit][bindex]); 17818 if (ret) { 17819 err++; 17820 } 17821 _soc_blk_counter_handles[unit][bindex] = 0; 17822 if (_blk_ctr_process[unit][bindex]) { 17823 sal_free(_blk_ctr_process[unit][bindex]); 17824 _blk_ctr_process[unit][bindex] = NULL; 17825 } 17826 } 17827 } 17828 if (_blk_ctr_process[unit]) { 17829 sal_free(_blk_ctr_process[unit]); 17830 _blk_ctr_process[unit] = NULL; 17831 } 17832 } 17833 return err; 17834 } 17835 17836 int 17837 soc_blk_counter_get(int unit, soc_block_t blk, soc_reg_t ctr_reg, int ar_idx, 17838 uint64 *val) 17839 { 17840 uint16 bindex, rindex; 17841 soc_blk_ctr_process_t *ctr_process; 17842 soc_ctr_reg_desc_t *reg_desc; 17843 soc_control_t *soc = SOC_CONTROL(unit); 17844 17845 if (soc->blk_ctr_desc_count && _blk_ctr_process[unit]) { 17846 for (bindex = 0; bindex < soc->blk_ctr_desc_count; bindex++) { 17847 if (_blk_ctr_process[unit][bindex]) { 17848 ctr_process = _blk_ctr_process[unit][bindex]; 17849 if (ctr_process->blk == blk) { 17850 reg_desc = soc->blk_ctr_desc[ctr_process->bindex].desc; 17851 for (rindex = 0; reg_desc[rindex].reg != INVALIDr; 17852 rindex++) { 17853 if (reg_desc[rindex].reg == ctr_reg) { 17854 if (ar_idx < reg_desc[rindex].entries) { 17855 *val = ctr_process->swval[ar_idx]; 17856 return SOC_E_NONE; 17857 } else { 17858 return SOC_E_PARAM; 17859 } 17860 } 17861 } 17862 return SOC_E_PARAM; 17863 } 17864 } 17865 } 17866 return SOC_E_PARAM; 17867 } 17868 return SOC_E_INIT; 17869 } 17870 17871 #endif /* BCM_SBUSDMA_SUPPORT */ 17872 17873 #ifdef BCM_XGS_SUPPORT 17874 /* 17875 * Function: 17876 * _soc_counter_dma_setup 17877 * Purpose: 17878 * Configure hardware registers for counter collection. Used during 17879 * soc_counter_thread initialization. 17880 * Parameters: 17881 * unit - switch unit 17882 * Returns: 17883 * SOC_E_* 17884 */ 17885 17886 static int 17887 _soc_counter_dma_setup(int unit) 17888 { 17889 soc_control_t *soc; 17890 uint32 creg_first, creg_last, cireg_first, cireg_last; 17891 int csize; 17892 pbmp_t pbmp; 17893 soc_reg_t reg; 17894 soc_ctr_type_t ctype; 17895 uint32 offset; 17896 #ifdef BCM_HERCULES_SUPPORT 17897 uint32 val; 17898 #endif 17899 #ifdef BCM_XGS3_SWITCH_SUPPORT 17900 if (SOC_IS_XGS3_SWITCH(unit)) { 17901 #ifdef BCM_SBUSDMA_SUPPORT 17902 if (soc_feature(unit, soc_feature_sbusdma)) { 17903 int rv = _soc_counter_sbusdma_setup(unit); 17904 if (rv) { 17905 (void)_soc_counter_sbudma_desc_free_all(unit); 17906 } 17907 return rv; 17908 } else 17909 #endif 17910 { 17911 return(_soc_xgs3_counter_dma_setup(unit)); 17912 } 17913 } 17914 #endif 17915 17916 soc = SOC_CONTROL(unit); 17917 SOC_PBMP_ASSIGN(pbmp, soc->counter_pbmp); 17918 17919 WRITE_CMIC_STAT_DMA_ADDRr(unit, soc_cm_l2p(unit, soc->counter_buf32)); 17920 WRITE_CMIC_STAT_DMA_PORTSr(unit, SOC_PBMP_WORD_GET(pbmp, 0)); 17921 17922 /* 17923 * Calculate the first and last register offsets for collection 17924 * Higig offsets are kept separately 17925 */ 17926 creg_first = creg_last = cireg_first = cireg_last = 0; 17927 for (ctype = 0; ctype < SOC_CTR_NUM_TYPES; ctype++) { 17928 if (!SOC_HAS_CTR_TYPE(unit, ctype)) { 17929 continue; 17930 } 17931 if (ctype == SOC_CTR_TYPE_GFE) { /* offsets screwed up */ 17932 continue; 17933 } 17934 reg = SOC_CTR_TO_REG(unit, ctype, 0); 17935 if (!SOC_COUNTER_INVALID(unit, reg)) { 17936 if (ctype == SOC_CTR_TYPE_HG) { 17937 cireg_first = SOC_REG_INFO(unit, reg).offset; 17938 } else { 17939 creg_first = SOC_REG_INFO(unit, reg).offset; 17940 if (cireg_first == 0) { 17941 cireg_first = creg_first; 17942 } 17943 } 17944 } 17945 csize = SOC_CTR_MAP_SIZE(unit, ctype) - 1; 17946 for (; csize > 0; csize--) { 17947 reg = SOC_CTR_TO_REG(unit, ctype, csize); 17948 if (SOC_COUNTER_INVALID(unit, reg)) { 17949 continue; /* skip trailing invalids */ 17950 } 17951 offset = SOC_REG_INFO(unit, reg).offset; 17952 csize = SOC_REG_IS_64(unit, reg) ? 17953 sizeof(uint64) : sizeof(uint32); 17954 csize = (soc->counter_portsize / csize) - 1; 17955 if (ctype == SOC_CTR_TYPE_HG) { 17956 if (offset > cireg_last) { 17957 cireg_last = offset; 17958 if (cireg_last > cireg_first + csize) { 17959 cireg_last = cireg_first + csize; 17960 } 17961 } 17962 } else { 17963 if (offset > creg_last) { 17964 creg_last = offset; 17965 if (creg_last > creg_first + csize) { 17966 creg_last = creg_first + csize; 17967 } 17968 } 17969 } 17970 break; 17971 } 17972 } 17973 17974 /* 17975 * Set the various configuration registers 17976 */ 17977 #ifdef BCM_HERCULES_SUPPORT 17978 if (SOC_IS_HERCULES15(unit)) { 17979 val = 0; 17980 creg_first = cireg_first; 17981 creg_last = cireg_last; 17982 soc_reg_field_set(unit, CMIC_64BIT_STATS_CFGr, &val, 17983 L_STAT_REGf, creg_last); 17984 soc_reg_field_set(unit, CMIC_64BIT_STATS_CFGr, &val, 17985 F_STAT_REGf, creg_first); 17986 WRITE_CMIC_64BIT_STATS_CFGr(unit, val); 17987 } else { 17988 val = 0; 17989 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, 17990 L_STAT_REGf, creg_last); 17991 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, 17992 F_STAT_REGf, creg_first); 17993 WRITE_CMIC_STAT_DMA_SETUPr(unit, val); 17994 } 17995 #endif 17996 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ITER_DONE_CLR); 17997 17998 17999 #ifdef BCM_CMICM_SUPPORT 18000 if(soc_feature(unit, soc_feature_cmicm)) { 18001 soc_cmicm_intr0_enable(unit, IRQ_CMCx_STAT_ITER_DONE); 18002 } else 18003 #endif 18004 { 18005 soc_intr_enable(unit, IRQ_STAT_ITER_DONE); 18006 } 18007 18008 return SOC_E_NONE; 18009 } 18010 #endif /*BCM_XGS_SUPPORT*/ 18011 /* 18012 * Function: 18013 * soc_counter_thread 18014 * Purpose: 18015 * Master counter collection and accumulation thread. 18016 * Parameters: 18017 * unit_vp - StrataSwitch unit # (as a void *). 18018 * Returns: 18019 * Nothing, does not return. 18020 */ 18021 18022 void 18023 soc_counter_thread(void *unit_vp) 18024 { 18025 int unit = PTR_TO_INT(unit_vp); 18026 soc_control_t *soc = SOC_CONTROL(unit); 18027 int rv = SOC_E_NONE; 18028 int interval; 18029 #if defined(WRITE_CMIC_DMA_STATr) || (defined(BCM_CMICM_SUPPORT) && defined(BCM_ESW_SUPPORT)) 18030 uint32 val; 18031 #endif 18032 int dma; 18033 sal_usecs_t cdma_timeout, now; 18034 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 18035 int sync_gnt = FALSE; 18036 int i; 18037 soc_counter_control_t *soc_ctr_ctrl = SOC_CTR_CTRL(unit); 18038 #if defined(BCM_ESW_SUPPORT) 18039 #ifdef BCM_CMICM_SUPPORT 18040 int cmc = SOC_PCI_CMC(unit); 18041 #endif 18042 #endif 18043 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_ESW_SUPPORT) 18044 static int _stat_err[SOC_MAX_NUM_DEVICES] = {0}; 18045 #endif 18046 #ifdef BCM_SBUSDMA_SUPPORT 18047 soc_timeout_t to; 18048 int timer_started = 0; 18049 #endif 18050 #ifdef BCM_TRIDENT2_SUPPORT 18051 int age_sync = FALSE; 18052 #endif 18053 18054 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18055 (BSL_META_U(unit, 18056 "soc_counter_thread: unit=%d\n"), unit)); 18057 18058 DNXC_MTA(dnxc_multithread_analyzer_declare_api_in_play(unit, __FUNCTION__, MTA_FLAG_THREAD_MAIN_FUNC, TRUE)); 18059 18060 /* 18061 * Create a semaphore used to time the trigger scans, and if DMA is 18062 * used, monitor for the Stats DMA Iteration Done interrupt. 18063 */ 18064 cdma_timeout = soc_property_get(unit, spn_CDMA_TIMEOUT_USEC, 1000000); 18065 18066 dma = ((soc->counter_flags & SOC_COUNTER_F_DMA) != 0); 18067 18068 #ifdef BCM_DNX_SUPPORT 18069 while(SOC_WARM_BOOT(unit) && SOC_IS_DNX(unit)) 18070 { 18071 /** Busy wait */ 18072 sal_usleep(10000); 18073 } 18074 18075 if(SOC_IS_DNX(unit)) 18076 { 18077 DNX_ERR_RECOVERY_UTILS_EXCLUDED_THREAD_ADD(unit); 18078 } 18079 #endif /*BCM_DNX_SUPPORT*/ 18080 18081 if (dma) { 18082 #ifdef BCM_XGS_SUPPORT 18083 rv = _soc_counter_dma_setup(unit); 18084 #endif /* BCM_XGS_SUPPORT */ 18085 if (rv < 0) { 18086 goto done; 18087 } 18088 } 18089 18090 /* 18091 * The hardware timer can only be used for intervals up to about 18092 * 1.048 seconds. This implementation uses a software timer (via 18093 * semaphore timeout) instead of the hardware timer. 18094 */ 18095 18096 while ((interval = soc->counter_interval) != 0) { 18097 #ifdef COUNTER_BENCH 18098 sal_usecs_t start_time; 18099 #endif 18100 int err = 0; 18101 18102 /* 18103 * Use a semaphore timeout instead of a sleep to achieve the 18104 * desired delay between scans. This allows this thread to exit 18105 * immediately when soc_counter_stop wants it to. 18106 */ 18107 18108 LOG_DEBUG(BSL_LS_SOC_COUNTER, 18109 (BSL_META_U(unit, 18110 "soc_counter_thread: sleep %d\n"), interval)); 18111 18112 (void)sal_sem_take(soc->counter_trigger, interval); 18113 18114 if (soc->counter_interval == 0) { /* Exit signaled */ 18115 break; 18116 } 18117 18118 #ifdef BCM_TRIDENT2_SUPPORT 18119 if (soc->l2x_sw_aging && soc->l2x_age_sync != NULL) { 18120 sal_sem_take(soc->l2x_age_sync, sal_sem_FOREVER); 18121 age_sync = TRUE; 18122 } 18123 #endif 18124 18125 if (soc->counter_sync_req) { 18126 sync_gnt = TRUE; 18127 } 18128 18129 #ifdef COUNTER_BENCH 18130 start_time = sal_time_usecs(); 18131 #endif 18132 18133 18134 /* 18135 * If in DMA mode, use DMA to transfer the counters into 18136 * memory. Start a DMA pass by enabling DMA and clearing 18137 * STAT_DMA_DONE bit. Wait for the pass to finish. 18138 */ 18139 COUNTER_LOCK(unit); 18140 18141 #ifdef BCM_SBUSDMA_SUPPORT 18142 if (dma && soc_feature(unit, soc_feature_sbusdma)) { 18143 uint8 i; 18144 int ret; 18145 soc_port_t port; 18146 int blk, bindex, phy_port; 18147 18148 PBMP_ITER(soc->counter_pbmp, port) { 18149 if (soc_feature(unit, soc_feature_logical_port_num)) { 18150 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 18151 } else { 18152 phy_port = port; 18153 } 18154 #ifdef BCM_KATANA2_SUPPORT 18155 if (SOC_IS_KATANA2(unit)) { 18156 if (!SOC_PORT_VALID(unit, phy_port)) { 18157 continue; 18158 } 18159 } 18160 #endif 18161 blk = SOC_PORT_BLOCK(unit, phy_port); 18162 bindex = SOC_PORT_BINDEX(unit, phy_port); 18163 if (SOC_IS_MONTEREY(unit)) { 18164 if ( ((phy_port > 0) && (phy_port < 13)) || 18165 ((phy_port > 52) && (phy_port < 65))) { 18166 blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1); 18167 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1); 18168 } 18169 } 18170 if (_soc_port_counter_handles[unit][phy_port][0] && soc->counter_interval) { 18171 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18172 (BSL_META_U(unit, 18173 "port: %d blk: %d, bindex: %d\n"), 18174 port, blk, bindex)); 18175 } 18176 for (i=0; i<=(COUNTER_SBUSDMA_DESC_SIZE-1); i++) { 18177 if ((i == 2) && 18178 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT) && 18179 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORTB0) && 18180 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XTPORT) && 18181 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XWPORT) && 18182 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_MXQPORT) && 18183 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GPORT) && 18184 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_GXPORT) && 18185 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLPORT) && 18186 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CLG2PORT) && 18187 !SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_CDPORT))) { 18188 break; 18189 } 18190 #if defined(BCM_GREYHOUND2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 18191 if (i == 3) { 18192 if (!(SOC_IS_GREYHOUND2(unit) || SOC_IS_MONTEREY(unit))) { 18193 continue; 18194 } 18195 if (SOC_IS_GREYHOUND2(unit) && 18196 (!SOC_BLOCK_IS_CMP(unit, blk, SOC_BLK_XLPORT))) { 18197 continue; 18198 } 18199 } 18200 #endif 18201 if (_soc_port_counter_handles[unit][phy_port][i] && soc->counter_interval) { 18202 do { 18203 ret = soc_sbusdma_desc_run(unit, _soc_port_counter_handles[unit][phy_port][i]); 18204 if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) { 18205 if (ret == SOC_E_INIT) { 18206 /* sbus dma thread not running!! */ 18207 break; 18208 } 18209 18210 /* 18211 * timeout if sbus dma has been busy 18212 * for too long. 18213 */ 18214 if (!timer_started) { 18215 soc_timeout_init(&to, 2 * cdma_timeout, 0); 18216 timer_started = 1; 18217 } 18218 18219 if (soc_timeout_check(&to)) { 18220 LOG_WARN(BSL_LS_SOC_COMMON, 18221 (BSL_META_U(unit, 18222 "Counters read operation timedout\n"))); 18223 break; 18224 } 18225 COUNTER_UNLOCK(unit); 18226 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100); 18227 COUNTER_LOCK(unit); 18228 } else { 18229 COUNTER_ATOMIC_BEGIN(s); 18230 _soc_counter_pending[unit]++; 18231 COUNTER_ATOMIC_END(s); 18232 } 18233 } while(((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) && 18234 _soc_port_counter_handles[unit][phy_port][i] && 18235 soc->counter_interval); 18236 18237 if (timer_started) { 18238 timer_started = 0; 18239 } 18240 } else { 18241 if (soc->counter_interval == 0) { /* Exit signaled */ 18242 break; 18243 } 18244 } 18245 } 18246 } 18247 18248 if (soc->blk_ctr_desc_count && soc->counter_interval) { 18249 for (i=0; i<soc->blk_ctr_desc_count; i++) { 18250 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18251 (BSL_META_U(unit, 18252 "blk ctr %d\n"), i)); 18253 if (_soc_blk_counter_handles[unit][i] && soc->counter_interval) { 18254 do { 18255 ret = soc_sbusdma_desc_run(unit, _soc_blk_counter_handles[unit][i]); 18256 if ((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) { 18257 COUNTER_UNLOCK(unit); 18258 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 18259 COUNTER_LOCK(unit); 18260 } 18261 } while(((ret == SOC_E_BUSY) || (ret == SOC_E_INIT)) && soc->counter_interval); 18262 } else { 18263 if (soc->counter_interval == 0) { /* Exit signaled */ 18264 break; 18265 } 18266 } 18267 } 18268 } 18269 if (soc->counter_interval == 0) { /* Exit signaled */ 18270 COUNTER_UNLOCK(unit); 18271 break; 18272 } 18273 } 18274 #endif 18275 if (dma && !soc_feature(unit, soc_feature_sbusdma)) { 18276 LOG_DEBUG(BSL_LS_SOC_COUNTER, 18277 (BSL_META_U(unit, 18278 "soc_counter_thread: trigger DMA\n"))); 18279 18280 #ifdef BCM_CMICM_SUPPORT 18281 #if defined(BCM_ESW_SUPPORT) 18282 18283 if(soc_feature(unit, soc_feature_cmicm)) { 18284 /* Clear Status */ 18285 val = soc_pci_read(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc)); 18286 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, 18287 ENf, 0); 18288 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, 18289 ST_DMA_ITER_DONE_CLRf, 0); 18290 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val); 18291 /* start DMA */ 18292 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, 18293 ENf, 1); 18294 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val); 18295 } else 18296 #endif 18297 #endif 18298 { 18299 /* Clear Status and start DMA */ 18300 #ifdef WRITE_CMIC_DMA_STATr 18301 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_DONE_CLR); 18302 READ_CMIC_STAT_DMA_SETUPr(unit, &val); 18303 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, 18304 ENf, 1); 18305 WRITE_CMIC_STAT_DMA_SETUPr(unit, val); 18306 #endif 18307 } 18308 /* Wait for ISR to wake semaphore */ 18309 #ifdef BCM_CMICM_SUPPORT 18310 if(soc_feature(unit, soc_feature_cmicm)) { 18311 if (sal_sem_take(soc->counter_intr, cdma_timeout) >= 0) { 18312 soc_cm_sinval(unit, 18313 (void *)soc->counter_buf32, 18314 soc->counter_bufsize); 18315 18316 LOG_DEBUG(BSL_LS_SOC_COUNTER, 18317 (BSL_META_U(unit, 18318 "soc_counter_thread: " 18319 "DMA iter done\n"))); 18320 18321 #ifdef COUNTER_BENCH 18322 LOG_DEBUG(BSL_LS_SOC_COMMON, 18323 (BSL_META_U(unit, 18324 "Time taken for dma: %d usec\n"), 18325 SAL_USECS_SUB(sal_time_usecs(), start_time))); 18326 #endif 18327 } else { 18328 LOG_ERROR(BSL_LS_SOC_COMMON, 18329 (BSL_META_U(unit, 18330 "soc_counter_thread: " 18331 "DMA did not finish buf32=%p\n"), 18332 (void *)soc->counter_buf32)); 18333 err = 1; 18334 } 18335 #if defined(BCM_ESW_SUPPORT) 18336 18337 if (soc_pci_read(unit, CMIC_CMCx_STAT_DMA_STAT_OFFSET(cmc)) & ST_CMCx_DMA_ERR) { 18338 LOG_ERROR(BSL_LS_SOC_COMMON, 18339 (BSL_META_U(unit, 18340 "soc_counter_thread: unit = %d DMA Error\n"), 18341 unit)); 18342 if (soc_ser_stat_error(unit, -1) != SOC_E_NONE) { 18343 _stat_err[unit]++; 18344 /* Error is reported atleast one more time after correction. 18345 So try few times and abort if correction really fails */ 18346 if (_stat_err[unit] > 10) { 18347 err = 1; 18348 } 18349 } else { 18350 _stat_err[unit] = 0; 18351 } 18352 } 18353 #endif 18354 } else 18355 #endif /* CMICm Support */ 18356 { 18357 if (sal_sem_take(soc->counter_intr, cdma_timeout) >= 0) { 18358 soc_cm_sinval(unit, 18359 (void *)soc->counter_buf32, 18360 soc->counter_bufsize); 18361 18362 LOG_DEBUG(BSL_LS_SOC_COUNTER, 18363 (BSL_META_U(unit, 18364 "soc_counter_thread: " 18365 "DMA iter done\n"))); 18366 18367 #ifdef COUNTER_BENCH 18368 LOG_DEBUG(BSL_LS_SOC_COMMON, 18369 (BSL_META_U(unit, 18370 "Time taken for dma: %d usec\n"), 18371 SAL_USECS_SUB(sal_time_usecs(), start_time))); 18372 #endif 18373 } else { 18374 LOG_ERROR(BSL_LS_SOC_COMMON, 18375 (BSL_META_U(unit, 18376 "soc_counter_thread: " 18377 "DMA did not finish buf32=%p\n"), 18378 (void *)soc->counter_buf32)); 18379 err = 1; 18380 } 18381 #ifdef BCM_XGS3_SWITCH_SUPPORT 18382 if (SOC_IS_XGS3_SWITCH(unit)) { 18383 if (soc_pci_read(unit, CMIC_DMA_STAT) & DS_STAT_DMA_ERROR) { 18384 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_DONE_CLR); 18385 if (soc_feature(unit, soc_feature_stat_dma_error_ack)) { 18386 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ERROR_CLR - 1); 18387 } else { 18388 WRITE_CMIC_DMA_STATr(unit, DS_STAT_DMA_ERROR_CLR); 18389 } 18390 LOG_ERROR(BSL_LS_SOC_COMMON, 18391 (BSL_META_U(unit, 18392 "soc_counter_thread: unit = %d DMA Error\n"), 18393 unit)); 18394 if (soc_ser_stat_error(unit, -1) != SOC_E_NONE) { 18395 _stat_err[unit]++; 18396 /* Error is reported atleast one more time after correction. 18397 So try few times and abort if correction really fails */ 18398 if (_stat_err[unit] > 10) { 18399 err = 1; 18400 _stat_err[unit] = 0; 18401 } 18402 } else { 18403 _stat_err[unit] = 0; 18404 } 18405 } 18406 } 18407 #endif 18408 } 18409 if (soc->counter_interval == 0) { /* Exit signaled */ 18410 COUNTER_UNLOCK(unit); 18411 break; 18412 } 18413 } 18414 18415 /* 18416 * Add up changes to counter values. 18417 */ 18418 18419 #ifdef BCM_SBUSDMA_SUPPORT 18420 while (_soc_counter_pending[unit] && soc->counter_interval) { 18421 COUNTER_UNLOCK(unit); 18422 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 100); 18423 COUNTER_LOCK(unit); 18424 } 18425 #endif 18426 18427 now = sal_time_usecs(); 18428 COUNTER_ATOMIC_BEGIN(s); 18429 soc->counter_coll_prev = soc->counter_coll_cur; 18430 soc->counter_coll_cur = now; 18431 COUNTER_ATOMIC_END(s); 18432 18433 if ( (!err) && (soc->counter_n32 > 0) && (soc->counter_interval) ) { 18434 rv = soc_counter_collect32(unit, FALSE); 18435 if (rv < 0) { 18436 LOG_ERROR(BSL_LS_SOC_COMMON, 18437 (BSL_META_U(unit, 18438 "soc_counter_thread: collect32 failed: %s\n"), 18439 soc_errmsg(rv))); 18440 err = 1; 18441 } 18442 } 18443 18444 if ((!err) && (soc->counter_n64 > 0) && (soc->counter_interval) ) { 18445 if(SOC_IS_SAND(unit)) { 18446 if (SOC_IS_ARAD(unit)) { 18447 #ifdef BCM_PETRA_SUPPORT 18448 rv = soc_counter_collect64(unit, FALSE, -1, INVALIDr); 18449 #endif 18450 } else { 18451 rv = SOC_E_NONE; 18452 } 18453 } else { 18454 #ifdef BCM_XGS_SUPPORT 18455 rv = soc_counter_collect64(unit, FALSE, -1, INVALIDr); 18456 #endif 18457 } 18458 18459 if (rv < 0) { 18460 LOG_ERROR(BSL_LS_SOC_COMMON, 18461 (BSL_META_U(unit, 18462 "soc_counter_thread: collect64 failed: " 18463 "%s\n"), soc_errmsg(rv))); 18464 err = 1; 18465 } 18466 } 18467 18468 /* soc_counter_collect64 could trigger thread schedule */ 18469 if (!(soc->counter_interval)) { 18470 COUNTER_UNLOCK(unit); 18471 break; 18472 } 18473 18474 if ((soc->counter_interval)) { 18475 soc_controlled_counters_collect64(unit, FALSE); 18476 if (rv < 0) { 18477 LOG_ERROR(BSL_LS_SOC_COMMON, 18478 (BSL_META_U(unit, 18479 "soc_counter_thread: soc_controlled_counters_collect64 failed: " 18480 "%s\n"), soc_errmsg(rv))); 18481 err = 1; 18482 } 18483 } 18484 18485 /* soc_controlled_counters_collect64 could trigger thread schedule */ 18486 if (!(soc->counter_interval)) { 18487 COUNTER_UNLOCK(unit); 18488 break; 18489 } 18490 18491 /* 18492 * Check optional non CMIC counter DMA support entries 18493 * These counters are included in "show counter" output 18494 */ 18495 if ((soc->counter_interval)) { 18496 if(soc_ctr_ctrl->collect_non_stat_dma) { 18497 soc_ctr_ctrl->collect_non_stat_dma(unit, -1, -1, -1, -1); 18498 } 18499 } 18500 18501 COUNTER_UNLOCK(unit); 18502 18503 /* soc_counter_collect_non_dma_entries could trigger thread schedule */ 18504 if (!(soc->counter_interval)) { 18505 break; 18506 } 18507 18508 /* 18509 * Callback for additional work 18510 * These counters are not included in "show counter" output 18511 */ 18512 for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) { 18513 if (soc_counter_extra[unit][i] != NULL) { 18514 soc_counter_extra[unit][i](unit); 18515 } 18516 18517 /* soc_counter_extra could trigger thread schedule */ 18518 if (!(soc->counter_interval)) { 18519 if (err) { 18520 rv = SOC_E_INTERNAL; 18521 } 18522 goto done; 18523 } 18524 } 18525 18526 #ifdef BCM_TRIDENT2_SUPPORT 18527 if (age_sync) { 18528 sal_sem_give(soc->l2x_age_sync); 18529 age_sync = FALSE; 18530 } 18531 #endif 18532 18533 /* 18534 * Forgive spurious errors 18535 */ 18536 18537 if (err) { 18538 LOG_ERROR(BSL_LS_SOC_COMMON, 18539 (BSL_META_U(unit, 18540 "AbnormalThreadExit:" 18541 "soc_counter_thread: Too many errors\n"))); 18542 rv = SOC_E_INTERNAL; 18543 goto done; 18544 } 18545 18546 #ifdef COUNTER_BENCH 18547 LOG_DEBUG(BSL_LS_SOC_COMMON, 18548 (BSL_META_U(unit, 18549 "Iteration time: %d usec\n"), 18550 SAL_USECS_SUB(sal_time_usecs(), start_time))); 18551 #endif 18552 18553 if (sync_gnt) { 18554 soc->counter_sync_req = 0; 18555 sync_gnt = 0; 18556 } 18557 } 18558 18559 rv = SOC_E_NONE; 18560 18561 done: 18562 #ifdef BCM_TRIDENT2_SUPPORT 18563 if (age_sync) { 18564 sal_sem_give(soc->l2x_age_sync); 18565 } 18566 #endif 18567 18568 if (rv < 0) { 18569 LOG_ERROR(BSL_LS_SOC_COMMON, 18570 (BSL_META_U(unit, 18571 "soc_counter_thread: Operation failed - exiting\n"))); 18572 soc_event_generate(unit, SOC_SWITCH_EVENT_THREAD_ERROR, 18573 SOC_SWITCH_EVENT_THREAD_COUNTER, __LINE__, rv); 18574 } 18575 18576 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18577 (BSL_META_U(unit, 18578 "soc_counter_thread: exiting\n"))); 18579 18580 soc->counter_pid = SAL_THREAD_ERROR; 18581 soc->counter_interval = 0; 18582 18583 DNXC_MTA(dnxc_multithread_analyzer_declare_api_in_play(unit, __FUNCTION__, MTA_FLAG_THREAD_MAIN_FUNC, FALSE)); 18584 18585 #ifdef BCM_DNX_SUPPORT 18586 if(SOC_IS_DNX(unit)) 18587 { 18588 DNX_ERR_RECOVERY_UTILS_EXCLUDED_THREAD_REMOVE(unit); 18589 } 18590 #endif 18591 18592 sal_thread_exit(0); 18593 } 18594 18595 /* 18596 * Function: 18597 * soc_counter_start 18598 * Purpose: 18599 * Start the counter collection, S/W accumulation process. 18600 * Parameters: 18601 * unit - StrataSwitch unit #. 18602 * flags - SOC_COUNTER_F_xxx flags. 18603 * interval - collection period in micro-seconds. 18604 * Using 0 is the same as calling soc_counter_stop(). 18605 * pbmp - bit map of ports to collact counters on. 18606 * Returns: 18607 * SOC_E_XXX 18608 */ 18609 int 18610 soc_counter_start(int unit, uint32 flags, int interval, pbmp_t pbmp) 18611 { 18612 soc_control_t *soc = SOC_CONTROL(unit); 18613 char pfmt[SOC_PBMP_FMT_LEN]; 18614 int rv = SOC_E_NONE; 18615 soc_port_t p; 18616 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18617 (BSL_META_U(unit, 18618 "soc_counter_start: unit=%d flags=0x%x " 18619 "interval=%d pbmp=%s\n"), 18620 unit, flags, interval, SOC_PBMP_FMT(pbmp, pfmt))); 18621 18622 /* Stop if already running */ 18623 #ifdef ADAPTER_SERVER_MODE 18624 #ifndef BCM_DNX_SUPPORT 18625 return SOC_E_NONE; 18626 #endif 18627 #endif /* ADAPTER_SERVER_MODE */ 18628 if (soc->counter_interval != 0) { 18629 SOC_IF_ERROR_RETURN(soc_counter_stop(unit)); 18630 } 18631 18632 if (interval == 0) { 18633 return SOC_E_NONE; 18634 } 18635 18636 /* 18637 * Create fresh semaphores 18638 * Semaphore already existing means other thread still holds it. 18639 * Unexpected results could happen if we mandatorily destroy it here. 18640 * So we need to retry soc_counter_stop(). If fail, then warn and return. 18641 */ 18642 18643 if ((soc->counter_trigger != NULL || soc->counter_intr != NULL) && 18644 (rv = soc_counter_stop(unit)) != SOC_E_NONE) { 18645 LOG_ERROR(BSL_LS_SOC_COMMON, 18646 (BSL_META_U(unit, 18647 "soc_counter_start: sem unexpectedly survives\n"))); 18648 return SOC_E_INTERNAL; 18649 } 18650 18651 soc->counter_trigger = 18652 sal_sem_create("counter_trigger", sal_sem_BINARY, 0); 18653 18654 soc->counter_intr = 18655 sal_sem_create("counter_intr", sal_sem_BINARY, 0); 18656 18657 if (soc->counter_trigger == NULL || soc->counter_intr == NULL) { 18658 LOG_ERROR(BSL_LS_SOC_COMMON, 18659 (BSL_META_U(unit, 18660 "soc_counter_start: sem create failed\n"))); 18661 return SOC_E_INTERNAL; 18662 } 18663 18664 /* Create fresh lock */ 18665 if (soc->counter_lock != NULL) { 18666 sal_spinlock_destroy(soc->counter_lock); 18667 soc->counter_lock = NULL; 18668 } 18669 18670 soc->counter_lock = sal_spinlock_create("counter spinlock"); 18671 18672 if (soc->counter_lock == NULL) { 18673 LOG_ERROR(BSL_LS_SOC_COMMON, 18674 (BSL_META_U(unit, 18675 "soc_counter_start: lock create failed\n"))); 18676 return SOC_E_INTERNAL; 18677 } 18678 18679 sal_snprintf(soc->counter_name, 18680 sizeof(soc->counter_name), 18681 "bcmCNTR.%d", unit); 18682 18683 SOC_PBMP_ASSIGN(soc->counter_pbmp, pbmp); 18684 PBMP_ITER(soc->counter_pbmp, p) { 18685 if ((SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), p))) { 18686 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, p); 18687 } 18688 if (IS_LB_PORT(unit, p)) { 18689 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, p); 18690 } 18691 } 18692 soc->counter_flags = flags; 18693 18694 soc->counter_flags &= ~SOC_COUNTER_F_SWAP64; /* HW takes care of this */ 18695 18696 if (!soc_feature(unit, soc_feature_stat_dma) || SOC_IS_RCPU_ONLY(unit)) { 18697 soc->counter_flags &= ~SOC_COUNTER_F_DMA; 18698 } 18699 18700 /* 18701 * The HOLD register is not supported by DMA on HUMV/Bradley, 18702 * but in order to allow certain test scripts to pass, we 18703 * optionally collect this register manually. 18704 */ 18705 18706 #ifdef BCM_BRADLEY_SUPPORT 18707 soc->counter_flags &= ~SOC_COUNTER_F_HOLD; 18708 18709 if (SOC_IS_HBX(unit)) { 18710 if (soc_property_get(unit, spn_CDMA_PIO_HOLD_ENABLE, 1)) { 18711 soc->counter_flags |= SOC_COUNTER_F_HOLD; 18712 } 18713 } 18714 #endif /* BCM_BRADLEY_SUPPORT */ 18715 18716 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 18717 if (soc_feature(unit, soc_feature_bigmac_rxcnt_bug)) { 18718 /* Allocate buffer for DMA counter validation */ 18719 soc_counter_tbuf[unit] = sal_alloc(SOC_COUNTER_TBUF_SIZE(unit), 18720 "counter_tbuf"); 18721 if (soc_counter_tbuf[unit] == NULL) { 18722 LOG_ERROR(BSL_LS_SOC_COMMON, 18723 (BSL_META_U(unit, 18724 "soc_counter_thread: unit %d: " 18725 "failed to allocate temp counter buffer\n"), 18726 unit)); 18727 } 18728 } 18729 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 18730 18731 SOC_IF_ERROR_RETURN(soc_counter_autoz(unit, 0)); 18732 18733 /* Synchronize counter 'prev' values with current hardware counters */ 18734 18735 soc->counter_coll_prev = soc->counter_coll_cur = sal_time_usecs(); 18736 18737 if (soc->counter_n32 > 0) { 18738 COUNTER_LOCK(unit); 18739 rv = soc_counter_collect32(unit, TRUE); 18740 COUNTER_UNLOCK(unit); 18741 SOC_IF_ERROR_RETURN(rv); 18742 } 18743 18744 if (soc->counter_n64 > 0) { 18745 COUNTER_LOCK(unit); 18746 if(SOC_IS_SAND(unit)) { 18747 rv = SOC_E_NONE; 18748 } else { 18749 #if defined(BCM_XGS_SUPPORT) 18750 rv = soc_counter_collect64(unit,FALSE, -1, INVALIDr); 18751 #endif 18752 } 18753 COUNTER_UNLOCK(unit); 18754 SOC_IF_ERROR_RETURN(rv); 18755 } 18756 18757 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT) 18758 /* 18759 * Temporarily allow DBAL writes for current thread even if it's generally disabled. 18760 */ 18761 if (SOC_IS_DNX(unit) || SOC_IS_DNXF(unit)) 18762 { 18763 rv = dnxc_ha_tmp_allow_access_enable(unit, DNXC_HA_ALLOW_DBAL); 18764 SOC_IF_ERROR_RETURN(rv); 18765 } 18766 #endif /*BCM_DNX_SUPPORT*/ 18767 18768 soc_controlled_counters_collect64(unit, TRUE); 18769 18770 #if defined (BCM_DNX_SUPPORT) || defined (BCM_DNXF_SUPPORT) 18771 /* 18772 * revert dnxc_allow_hw_write_enable. 18773 */ 18774 if (SOC_IS_DNX(unit) || SOC_IS_DNXF(unit)) 18775 { 18776 rv = dnxc_ha_tmp_allow_access_disable(unit, DNXC_HA_ALLOW_DBAL); 18777 } 18778 #endif /*BCM_DNX_SUPPORT*/ 18779 18780 /* Start the thread */ 18781 18782 if (interval != 0) { 18783 soc->counter_interval = interval; 18784 18785 soc->counter_pid = 18786 sal_thread_create(soc->counter_name, 18787 SAL_THREAD_STKSZ, 18788 soc_property_get(unit, 18789 spn_COUNTER_THREAD_PRI, 18790 _SOC_CTR_THREAD_PRI), 18791 soc_counter_thread, INT_TO_PTR(unit)); 18792 18793 if (soc->counter_pid == SAL_THREAD_ERROR) { 18794 soc->counter_interval = 0; 18795 LOG_ERROR(BSL_LS_SOC_COMMON, 18796 (BSL_META_U(unit, 18797 "soc_counter_start: thread create failed\n"))); 18798 return (SOC_E_INTERNAL); 18799 } 18800 18801 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18802 (BSL_META_U(unit, 18803 "soc_counter_start: complete\n"))); 18804 } 18805 #ifdef BCM_TOMAHAWK_SUPPORT 18806 if ((soc_feature(unit, soc_feature_counter_eviction)) && 18807 (!SOC_WARM_BOOT(unit))) { 18808 /* During WB, eviction will be enabled post WB init */ 18809 SOC_IF_ERROR_RETURN(soc_ctr_evict_start(unit, 0, interval)); 18810 } 18811 #endif /* BCM_TOMAHAWK_SUPPORT */ 18812 18813 18814 return (SOC_E_NONE); 18815 } 18816 18817 18818 18819 /* 18820 * Function: 18821 * soc_counter_port_collect_enable_set 18822 * Purpose: 18823 * Enable/disable the gathering of MIB statistics on this port. 18824 * Parameters: 18825 * unit - StrataSwitch unit #. 18826 * port - Port number #. 18827 * enable: enable/disable the port's mib gathering. 18828 * Returns: 18829 * SOC_E_XXX 18830 */ 18831 int 18832 soc_counter_port_collect_enable_set(int unit, int port, int enable) 18833 { 18834 soc_control_t *soc = SOC_CONTROL(unit); 18835 18836 if (IS_LB_PORT(unit, port)) { 18837 return SOC_E_NONE; 18838 } 18839 18840 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 18841 return SOC_E_NONE; 18842 } 18843 18844 COUNTER_LOCK(unit); 18845 18846 if (enable) { 18847 SOC_PBMP_PORT_ADD(soc->counter_pbmp,port); 18848 } else { 18849 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp,port); 18850 } 18851 18852 COUNTER_UNLOCK(unit); 18853 18854 return (SOC_E_NONE); 18855 } 18856 18857 /* 18858 * Function: 18859 * soc_counter_status 18860 * Purpose: 18861 * Get the status of counter collection, S/W accumulation process. 18862 * Parameters: 18863 * unit - StrataSwitch unit #. 18864 * flags - SOC_COUNTER_F_xxx flags. 18865 * interval - collection period in micro-seconds. 18866 * pbmp - bit map of ports to collact counters on. 18867 * Returns: 18868 * SOC_E_XXX 18869 */ 18870 18871 int 18872 soc_counter_status(int unit, uint32 *flags, int *interval, pbmp_t *pbmp) 18873 { 18874 soc_control_t *soc = SOC_CONTROL(unit); 18875 18876 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18877 (BSL_META_U(unit, 18878 "soc_counter_status: unit=%d\n"), unit)); 18879 18880 *interval = soc->counter_interval; 18881 *flags = soc->counter_flags; 18882 SOC_PBMP_ASSIGN(*pbmp, soc->counter_pbmp); 18883 18884 return (SOC_E_NONE); 18885 } 18886 18887 /* 18888 * Function: 18889 * soc_counter_sync 18890 * Purpose: 18891 * Force an immediate counter update 18892 * Parameters: 18893 * unit - StrataSwitch unit #. 18894 * Returns: 18895 * SOC_E_XXX 18896 * Notes: 18897 * Ensures that ALL counter activity that occurred before the sync 18898 * is reflected in the results of any soc_counter_get()-type 18899 * routine that is called after the sync. 18900 */ 18901 18902 int 18903 soc_counter_sync(int unit) 18904 { 18905 soc_control_t *soc = SOC_CONTROL(unit); 18906 soc_timeout_t to; 18907 uint32 stat_sync_timeout; 18908 18909 if (soc->counter_interval == 0) { 18910 return SOC_E_DISABLED; 18911 } 18912 18913 /* Trigger a collection */ 18914 18915 soc->counter_sync_req = TRUE; 18916 18917 sal_sem_give(soc->counter_trigger); 18918 18919 #ifdef BCM_TOMAHAWK_SUPPORT 18920 if (soc_feature(unit, soc_feature_counter_eviction)) { 18921 SOC_IF_ERROR_RETURN(soc_counter_eviction_sync(unit)); 18922 } 18923 #endif /* BCM_TOMAHAWK_SUPPORT */ 18924 18925 if (SAL_BOOT_QUICKTURN) { 18926 stat_sync_timeout = STAT_SYNC_TIMEOUT_QT; 18927 } else if (SAL_BOOT_BCMSIM) { 18928 stat_sync_timeout = STAT_SYNC_TIMEOUT_BCMSIM; 18929 } else if (SOC_IS_RCPU_ONLY(unit)) { 18930 stat_sync_timeout = STAT_SYNC_TIMEOUT*4; 18931 } else { 18932 stat_sync_timeout = STAT_SYNC_TIMEOUT; 18933 } 18934 stat_sync_timeout = soc_property_get(unit, 18935 spn_BCM_STAT_SYNC_TIMEOUT, 18936 stat_sync_timeout); 18937 soc_timeout_init(&to, stat_sync_timeout, 0); 18938 while (soc->counter_sync_req) { 18939 if (soc_timeout_check(&to)) { 18940 if (soc->counter_sync_req) { 18941 LOG_ERROR(BSL_LS_SOC_COMMON, 18942 (BSL_META_U(unit, 18943 "soc_counter_sync: counter thread not responding\n"))); 18944 soc->counter_sync_req = FALSE; 18945 return SOC_E_TIMEOUT; 18946 } 18947 } 18948 18949 sal_usleep(10000); 18950 } 18951 18952 return SOC_E_NONE; 18953 } 18954 18955 /* 18956 * Function: 18957 * soc_counter_stop 18958 * Purpose: 18959 * Terminate the counter collection, S/W accumulation process. 18960 * Parameters: 18961 * unit - StrataSwitch unit #. 18962 * Returns: 18963 * SOC_E_XXX 18964 */ 18965 18966 int 18967 soc_counter_stop(int unit) 18968 { 18969 soc_control_t *soc = SOC_CONTROL(unit); 18970 int rv = SOC_E_NONE; 18971 soc_timeout_t to; 18972 sal_usecs_t cdma_timeout; 18973 #ifdef BCM_XGS_SUPPORT 18974 #ifdef BCM_CMICM_SUPPORT 18975 int cmc = SOC_PCI_CMC(unit); 18976 #endif 18977 #endif 18978 18979 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 18980 (BSL_META_U(unit, 18981 "soc_counter_stop: unit=%d\n"), unit)); 18982 18983 if (SAL_BOOT_QUICKTURN) { 18984 cdma_timeout = CDMA_TIMEOUT_QT; 18985 } else if (SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM) { 18986 cdma_timeout = CDMA_TIMEOUT_BCMSIM; 18987 } else if (SOC_IS_RCPU_ONLY(unit)) { 18988 cdma_timeout = CDMA_TIMEOUT*10; 18989 } else { 18990 cdma_timeout = CDMA_TIMEOUT*5; 18991 } 18992 cdma_timeout = soc_property_get(unit, spn_CDMA_TIMEOUT_USEC, cdma_timeout); 18993 18994 /* Stop thread if present. */ 18995 18996 if (soc->counter_interval != 0) { 18997 sal_thread_t sample_pid; 18998 18999 /* 19000 * Signal by setting interval to 0, and wake up thread to speed 19001 * its exit. It may also be waiting for the hardware interrupt 19002 * semaphore. Wait a limited amount of time for it to exit. 19003 */ 19004 19005 soc->counter_interval = 0; 19006 19007 sal_sem_give(soc->counter_intr); 19008 sal_sem_give(soc->counter_trigger); 19009 19010 soc_timeout_init(&to, cdma_timeout, 0); 19011 19012 while ((sample_pid = soc->counter_pid) != SAL_THREAD_ERROR) { 19013 if (soc_timeout_check(&to)) { 19014 LOG_ERROR(BSL_LS_SOC_COMMON, 19015 (BSL_META_U(unit, 19016 "soc_counter_stop: thread did not exit\n"))); 19017 soc->counter_pid = SAL_THREAD_ERROR; 19018 rv = SOC_E_TIMEOUT; 19019 break; 19020 } 19021 19022 sal_usleep(10000); 19023 } 19024 } 19025 19026 #ifdef BCM_XGS_SUPPORT 19027 if ((soc->counter_flags & SOC_COUNTER_F_DMA) && 19028 !soc_feature(unit, soc_feature_sbusdma)) { 19029 uint32 val; 19030 19031 /* 19032 * Disable hardware counter scanning. 19033 * Turn off all ports to speed up final scan cycle. 19034 * 19035 * This cleanup is done here instead of at the end of the 19036 * counter thread so counter DMA will turn off even if the 19037 * thread is non responsive. 19038 */ 19039 19040 #ifdef BCM_CMICM_SUPPORT 19041 if(soc_feature(unit, soc_feature_cmicm)) { 19042 19043 soc_cmicm_intr0_disable(unit, IRQ_CMCx_STAT_ITER_DONE); 19044 19045 val = soc_pci_read(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc)); 19046 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, ENf, 0); 19047 soc_reg_field_set(unit, CMIC_CMC0_STAT_DMA_CFGr, &val, E_Tf, 0); 19048 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_CFG_OFFSET(cmc), val); 19049 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_0_OFFSET(cmc), 0); 19050 if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_1r)) { 19051 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_1_OFFSET(cmc), 0); 19052 } 19053 if (SOC_REG_IS_VALID(unit, CMIC_CMC0_STAT_DMA_PORTS_2r)) { 19054 soc_pci_write(unit, CMIC_CMCx_STAT_DMA_PORTS_2_OFFSET(cmc), 0); 19055 } 19056 } else 19057 #endif 19058 { 19059 19060 soc_intr_disable(unit, IRQ_STAT_ITER_DONE); 19061 19062 READ_CMIC_STAT_DMA_SETUPr(unit, &val); 19063 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, ENf, 0); 19064 soc_reg_field_set(unit, CMIC_STAT_DMA_SETUPr, &val, E_Tf, 0); 19065 WRITE_CMIC_STAT_DMA_SETUPr(unit, val); 19066 WRITE_CMIC_STAT_DMA_PORTSr(unit, 0); 19067 #if defined(BCM_RAPTOR_SUPPORT) 19068 if (soc_feature(unit, soc_feature_register_hi)) { 19069 WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, 0); 19070 } 19071 #endif /* BCM_RAPTOR_SUPPORT */ 19072 #if defined(BCM_TRIUMPH_SUPPORT) 19073 if (SOC_IS_TR_VL(unit)) { 19074 WRITE_CMIC_STAT_DMA_PORTS_HIr(unit, 0); 19075 } 19076 #endif /* BCM_TRIUMPH_SUPPORT */ 19077 } 19078 19079 /* 19080 * Wait for STAT_DMA_ACTIVE to go away, with a timeout in case 19081 * it never does. 19082 */ 19083 19084 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19085 (BSL_META_U(unit, 19086 "soc_counter_stop: waiting for idle\n"))); 19087 19088 soc_timeout_init(&to, cdma_timeout, 0); 19089 #ifdef BCM_CMICM_SUPPORT 19090 if(soc_feature(unit, soc_feature_cmicm)) { 19091 while (soc_pci_read(unit, CMIC_CMCx_STAT_DMA_STAT_OFFSET(cmc)) & ST_CMCx_DMA_ACTIVE) { 19092 if (soc_timeout_check(&to)) { 19093 rv = SOC_E_INTERNAL; 19094 break; 19095 } 19096 } 19097 } else 19098 #endif 19099 { 19100 while (soc_pci_read(unit, CMIC_DMA_STAT) & DS_STAT_DMA_ACTIVE) { 19101 if (soc_timeout_check(&to)) { 19102 rv = SOC_E_TIMEOUT; 19103 break; 19104 } 19105 } 19106 } 19107 } 19108 19109 #ifdef BCM_XGS3_SWITCH_SUPPORT 19110 #ifdef BCM_SBUSDMA_SUPPORT 19111 if ((soc->counter_flags & SOC_COUNTER_F_DMA) && 19112 soc_feature(unit, soc_feature_sbusdma)) { 19113 int err; 19114 if ((err = _soc_counter_sbudma_desc_free_all(unit)) != 0) { 19115 LOG_ERROR(BSL_LS_SOC_COMMON, 19116 (BSL_META_U(unit, 19117 "soc_counter_stop: [%d] Desc free error(s)\n"), 19118 err)); 19119 } 19120 } 19121 #endif 19122 #endif 19123 19124 #ifdef BCM_BRADLEY_SUPPORT 19125 if (soc_counter_tbuf[unit]) { 19126 sal_free(soc_counter_tbuf[unit]); 19127 soc_counter_tbuf[unit] = NULL; 19128 } 19129 #endif /* BCM_BRADLEY_SUPPORT */ 19130 #endif /* BCM_XGS_SUPPORT */ 19131 19132 if (rv != SOC_E_TIMEOUT) { 19133 if (NULL != soc->counter_intr) { 19134 sal_sem_destroy(soc->counter_intr); 19135 soc->counter_intr = NULL; 19136 } 19137 if (NULL != soc->counter_trigger) { 19138 sal_sem_destroy(soc->counter_trigger); 19139 soc->counter_trigger = NULL; 19140 } 19141 } 19142 19143 if (soc->counter_lock != NULL) { 19144 sal_spinlock_destroy(soc->counter_lock); 19145 soc->counter_lock = NULL; 19146 } 19147 19148 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19149 (BSL_META_U(unit, 19150 "soc_counter_stop: stopped\n"))); 19151 19152 #ifdef BCM_TOMAHAWK_SUPPORT 19153 if (soc_feature(unit, soc_feature_counter_eviction)) { 19154 SOC_IF_ERROR_RETURN(soc_ctr_evict_stop(unit)); 19155 } 19156 #endif /* BCM_TOMAHAWK_SUPPORT */ 19157 19158 return (rv); 19159 } 19160 19161 /* 19162 * Function: 19163 * soc_counter_extra_register 19164 * Purpose: 19165 * Register callback for additional counter collection. 19166 * Parameters: 19167 * unit - The SOC unit number 19168 * fn - Callback function. 19169 * Returns: 19170 * SOC_E_XXX 19171 * Notes: 19172 */ 19173 int 19174 soc_counter_extra_register(int unit, soc_counter_extra_f fn) 19175 { 19176 int i; 19177 19178 if (fn == NULL) { 19179 return SOC_E_PARAM; 19180 } 19181 19182 for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) { 19183 if (soc_counter_extra[unit][i] == fn) { 19184 return SOC_E_NONE; 19185 } 19186 } 19187 19188 for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) { 19189 if (soc_counter_extra[unit][i] == NULL) { 19190 soc_counter_extra[unit][i] = fn; 19191 return SOC_E_NONE; 19192 } 19193 } 19194 19195 return SOC_E_FULL; 19196 } 19197 19198 /* 19199 * Function: 19200 * soc_counter_extra_unregister 19201 * Purpose: 19202 * Unregister callback for additional counter collection. 19203 * Parameters: 19204 * unit - The SOC unit number 19205 * fn - Callback function. 19206 * Returns: 19207 * SOC_E_XXX 19208 * Notes: 19209 */ 19210 int 19211 soc_counter_extra_unregister(int unit, soc_counter_extra_f fn) 19212 { 19213 int i; 19214 19215 if (fn == NULL) { 19216 return SOC_E_PARAM; 19217 } 19218 19219 for (i = 0; i < SOC_COUNTER_EXTRA_CB_MAX; i++) { 19220 if (soc_counter_extra[unit][i] == fn) { 19221 soc_counter_extra[unit][i] = NULL; 19222 return SOC_E_NONE; 19223 } 19224 } 19225 19226 return SOC_E_NOT_FOUND; 19227 } 19228 19229 int 19230 soc_counter_timestamp_get(int unit, soc_port_t port, 19231 uint32 *timestamp) 19232 { 19233 soc_control_t *soc = SOC_CONTROL(unit); 19234 int rv = SOC_E_NOT_FOUND; 19235 19236 if (!soc_feature(unit, soc_feature_timestamp_counter)) { 19237 return rv; 19238 } 19239 19240 if (soc->counter_timestamp_fifo[port] == NULL) { 19241 return rv; 19242 } 19243 19244 COUNTER_LOCK(unit); 19245 if (!SHR_FIFO_IS_EMPTY(soc->counter_timestamp_fifo[port])) { 19246 SHR_FIFO_POP(soc->counter_timestamp_fifo[port], timestamp); 19247 rv = SOC_E_NONE; 19248 } 19249 COUNTER_UNLOCK(unit); 19250 return rv; 19251 } 19252 19253 /* Function to return associated dma for a given dma structure. 19254 * Example, Associated DMA for ING_FLEX_PKT is ING_FLEX_BYTE and vice versa. 19255 */ 19256 STATIC 19257 void soc_counter_get_associated_dma(int unit, soc_reg_t id, 19258 soc_counter_non_dma_t *non_dma, 19259 soc_counter_non_dma_t **non_dma_temp) 19260 { 19261 if (non_dma_temp == NULL) { 19262 return; 19263 } 19264 19265 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 19266 /* If CLR_ON_READ is NOT set, Return NULL */ 19267 *non_dma_temp = NULL; 19268 return; 19269 } 19270 switch (id) { 19271 case SOC_COUNTER_NON_DMA_ING_FLEX_PKT: 19272 case SOC_COUNTER_NON_DMA_EGR_FLEX_PKT: 19273 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT: 19274 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_PKT_UC: 19275 case SOC_COUNTER_NON_DMA_EFP_PKT: 19276 *non_dma_temp = non_dma + 1; 19277 break; 19278 case SOC_COUNTER_NON_DMA_ING_FLEX_BYTE: 19279 case SOC_COUNTER_NON_DMA_EGR_FLEX_BYTE: 19280 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE: 19281 case SOC_COUNTER_NON_DMA_EGR_PERQ_XMT_BYTE_UC: 19282 case SOC_COUNTER_NON_DMA_EFP_BYTE: 19283 *non_dma_temp = non_dma - 1; 19284 break; 19285 default: 19286 *non_dma_temp = NULL; 19287 break; /* all other cases not handled yet */ 19288 } 19289 19290 } 19291 19292 /* 19293 * Function: 19294 * soc_counter_generic_collect_non_dma_entries 19295 * Purpose: 19296 * This routine is similar to the soc_counter_collect_non_dma_entries 19297 * routine. The difference is that soc_counter_collect_non_dma_entries can 19298 * handle only SOC_CTR_INSTANCE_TYPE_PORT while this routine can handle the 19299 * types defined in soc_ctr_instance_type_e. 19300 * Parameters: 19301 * unit - StrataSwitch unit #. 19302 * ctrl_info - StrataSwitch port #. 19303 * base_idx - base index returned by generic_get_info. 19304 * ar_idx - index. 19305 * ctr_reg - if INVALIDr, collects and accumulates counter values for all 19306 * else collects and accumulates for a specified port. 19307 * Currently, this functionality is not being used. 19308 * Returns: 19309 * NONE 19310 * Notes: 19311 */ 19312 19313 STATIC void 19314 soc_counter_generic_collect_non_dma_entries(int unit, 19315 soc_ctr_control_info_t ctrl_info, 19316 int base_idx, 19317 int ar_idx, 19318 soc_reg_t ctr_reg) 19319 { 19320 soc_control_t *soc; 19321 soc_counter_non_dma_t *non_dma, *non_dma_temp; 19322 int base_index = 0, width, i, j; 19323 int id = 0; 19324 int idx = 0; 19325 int port=0; 19326 uint32 fval[2]; 19327 uint64 ctr_new, ctr_prev, ctr_diff, wrap_amt; 19328 int rv = 0, count, entry_words; 19329 COUNTER_ATOMIC_DEF s = SOC_CONTROL(unit); 19330 int dma_base_index = 0; 19331 int num_non_dma_entries = 0; 19332 soc_mem_t dma_mem; 19333 int non_dma_counter_end = SOC_COUNTER_NON_DMA_END - 19334 SOC_COUNTER_NON_DMA_START; 19335 static int ctr_dma_ct = 0; 19336 int index_max = 0, pipe = 0, entries_per_pipe = 0, inst_pipe = -1; 19337 int pipe_start = 0, pool_id; 19338 uint32 subset_ct = 0; /* For Parent-Child Model */ 19339 uint32 fld_ct = 2; 19340 soc_info_t *si = NULL; 19341 19342 si = &SOC_INFO(unit); 19343 19344 soc = SOC_CONTROL(unit); 19345 19346 if (soc->counter_non_dma == NULL) { 19347 return; 19348 } 19349 19350 /* 19351 * if ctr_reg != -1, retrieve stats for a 19352 * specific port and queue from the hardware 19353 * update the sw copy of the same. 19354 */ 19355 if (ctr_reg >= NUM_SOC_REG) { 19356 id = ctr_reg - SOC_COUNTER_NON_DMA_START; 19357 non_dma_counter_end = id + 1; 19358 idx = (ar_idx < 0)? 0: ar_idx; 19359 } 19360 19361 for (; id < non_dma_counter_end; id++) { 19362 non_dma = &soc->counter_non_dma[id]; 19363 19364 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && ctr_reg == INVALIDr) { 19365 continue; 19366 } 19367 19368 /* If signaled to exit then return */ 19369 if (!soc->counter_interval) { 19370 return; 19371 } 19372 19373 width = entry_words = 0; 19374 19375 if (non_dma->mem != INVALIDm) { 19376 count = 0; 19377 19378 /* If there is subset of counters, use subset info for DMA */ 19379 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_SUBSET_PARENT) && 19380 (non_dma->extra_ctrs != NULL)) { 19381 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 19382 subset_ct = non_dma->extra_ctr_ct << 1; 19383 #ifdef BCM_TOMAHAWK3_SUPPORT 19384 if(SOC_IS_TOMAHAWK3(unit) && (non_dma->extra_ctr_fld_ct != 0)) { 19385 subset_ct = non_dma->extra_ctr_ct; 19386 fld_ct = non_dma->extra_ctr_fld_ct; 19387 } 19388 #endif 19389 non_dma = non_dma->extra_ctrs; 19390 } else { 19391 subset_ct = 1; 19392 } 19393 19394 do { 19395 /* If signaled to exit then return */ 19396 if (!soc->counter_interval) { 19397 return; 19398 } 19399 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID) && ctr_reg == INVALIDr) { 19400 break; 19401 } 19402 19403 /* Check if this Counter is up for DMA. 19404 * During Slow-DMA, not all counters are up for DMA at the same 19405 * time/frequency. 19406 */ 19407 if ((non_dma->flags & _SOC_COUNTER_NON_DMA_CTR_EVICT) && 19408 (!soc_counter_non_dma_ready(unit, non_dma, &ctr_dma_ct))) { 19409 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19410 (BSL_META_U(unit, 19411 "id %d(%d): NOT pickd for DMA(pipes %d). Ct %d, mem:\n\t%d\n"), 19412 id, SOC_COUNTER_NON_DMA_START, count, 19413 NUM_PIPE(unit), non_dma->mem)); 19414 for (i = 0; i < NUM_PIPE(unit); i++) { 19415 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19416 (BSL_META_U(unit, "\t%d\n"), non_dma->dma_mem[i])); 19417 } 19418 count++; 19419 non_dma++; 19420 continue; 19421 } 19422 19423 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19424 (BSL_META_U(unit, 19425 "id %d(%d): picked for DMA(Pipes %d). mem:\n\t%d\n"), 19426 id, SOC_COUNTER_NON_DMA_START, NUM_PIPE(unit), 19427 non_dma->mem)); 19428 for (i = 0; i < NUM_PIPE(unit); i++) { 19429 LOG_VERBOSE(BSL_LS_SOC_COUNTER, 19430 (BSL_META_U(unit, "\t%d\n"), non_dma->dma_mem[i])); 19431 } 19432 entry_words = soc_mem_entry_words(unit, non_dma->mem); 19433 19434 /* Non-DMA can have either register based or memory based 19435 * counters. INVALIDr signifies memory based */ 19436 if (ctr_reg == INVALIDr) { 19437 for (i = 0; i < NUM_PIPE(unit); i++) { 19438 /* Do only if the Pipe mem is VALID. */ 19439 if (non_dma->dma_mem[i] == INVALIDm) { 19440 continue; 19441 } 19442 /* Skip if no enabled ports in pipe */ 19443 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, i))) { 19444 continue; 19445 } 19446 if (non_dma->flags & _SOC_COUNTER_NON_DMA_DO_DMA) { 19447 19448 if (non_dma->dma_buf[i] == NULL) { 19449 continue; 19450 } 19451 19452 rv = soc_mem_read_range(unit, 19453 non_dma->dma_mem[i], 19454 MEM_BLOCK_ANY, 19455 non_dma->dma_index_min[i], 19456 non_dma->dma_index_max[i], 19457 &non_dma->dma_buf[i]); 19458 19459 if (SOC_FAILURE(rv)) { 19460 return; 19461 } 19462 } 19463 } 19464 19465 base_index = non_dma->base_index; 19466 index_max = non_dma->num_entries; 19467 entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit); 19468 num_non_dma_entries = index_max; 19469 19470 } else { 19471 subset_ct = 1; /* Only for given instance type */ 19472 /* Collect counter values for a specific instance */ 19473 19474 base_index = base_idx + ar_idx; 19475 num_non_dma_entries = 1; 19476 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_XPE_PORT) { 19477 int xpe_inst = (ctrl_info.instance >> 10) & 0xf; 19478 int port = ctrl_info.instance >> 14; 19479 soc_counter_non_dma_t *parent_dma; 19480 19481 parent_dma = &soc->counter_non_dma[id]; 19482 inst_pipe = si->port_pipe[port]; 19483 19484 if ((xpe_inst >= 0) && (xpe_inst < NUM_XPE(unit)) && 19485 (parent_dma->extra_ctrs)) { 19486 non_dma = &parent_dma->extra_ctrs[xpe_inst << 1]; 19487 /* Each XPE has 2 pipe entries */ 19488 if ( 1 == NUM_PIPE(unit)) { 19489 entries_per_pipe = non_dma->num_entries; 19490 } else { 19491 entries_per_pipe = non_dma->num_entries / 2; 19492 } 19493 dma_mem = non_dma->dma_mem[inst_pipe]; 19494 if (dma_mem == INVALIDm) { 19495 break; 19496 } 19497 19498 dma_base_index = (base_idx - non_dma->base_index) % 19499 entries_per_pipe + 19500 non_dma->dma_index_min[inst_pipe]; 19501 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 19502 dma_base_index + idx, 19503 non_dma->dma_buf[inst_pipe]); 19504 if (SOC_FAILURE(rv)) { 19505 return; 19506 } 19507 } 19508 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM_PORT) { 19509 /* Decode ITM instance and port for TYPE_ITM_PORT */ 19510 int itm_inst = 19511 (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >> 19512 CTR_INSTANCE_BIT_SHIFT_ITM; 19513 int port = 19514 (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_PORT) >> 19515 CTR_INSTANCE_BIT_SHIFT_PORT; 19516 soc_counter_non_dma_t *parent_dma; 19517 19518 parent_dma = &soc->counter_non_dma[id]; 19519 inst_pipe = si->port_pipe[port]; 19520 19521 if ((itm_inst >= 0) && (itm_inst < NUM_ITM(unit)) && 19522 (parent_dma->extra_ctrs)) { 19523 non_dma = &parent_dma->extra_ctrs[itm_inst]; 19524 entries_per_pipe = non_dma->num_entries; 19525 dma_mem = non_dma->dma_mem[inst_pipe]; 19526 #ifdef BCM_TOMAHAWK3_SUPPORT 19527 /* In normal case, only dma_mem[0] is filled */ 19528 if (SOC_IS_TOMAHAWK3(unit) && 19529 (SOC_CONTROL(unit)->em_halfchip == 0)) { 19530 dma_mem = non_dma->dma_mem[0]; 19531 } 19532 #endif 19533 if (dma_mem == INVALIDm) { 19534 break; 19535 } 19536 19537 /* Retrieve table index by substract the base_index */ 19538 dma_base_index = (base_idx - non_dma->base_index); 19539 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 19540 dma_base_index + idx, 19541 non_dma->dma_buf[inst_pipe]); 19542 if (SOC_FAILURE(rv)) { 19543 return; 19544 } 19545 } 19546 } else if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PORT) { 19547 dma_mem = non_dma->dma_mem[0]; 19548 dma_base_index = base_idx - non_dma->base_index + 19549 non_dma->dma_index_min[0]; 19550 inst_pipe = 0; 19551 19552 for (i = 1; i < NUM_PIPE(unit); i++) { 19553 if (non_dma->dma_buf[i] == NULL) { 19554 continue; 19555 } 19556 19557 if (dma_base_index > non_dma->dma_index_max[i - 1]) { 19558 inst_pipe = i; 19559 dma_mem = non_dma->dma_mem[i]; 19560 dma_base_index -= non_dma->dma_index_max[i - 1] + 1; 19561 dma_base_index += non_dma->dma_index_min[i]; 19562 } 19563 } 19564 rv = soc_mem_read(unit, dma_mem, MEM_BLOCK_ANY, 19565 dma_base_index + idx, 19566 non_dma->dma_buf[inst_pipe]); 19567 if (SOC_FAILURE(rv)) { 19568 return; 19569 } 19570 } else if (ctrl_info.instance_type == 19571 SOC_CTR_INSTANCE_TYPE_PIPE) { 19572 inst_pipe = ctrl_info.instance; 19573 entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit); 19574 rv = soc_mem_read(unit, 19575 non_dma->dma_mem[inst_pipe], 19576 MEM_BLOCK_ANY, ar_idx, 19577 non_dma->dma_buf[inst_pipe]); 19578 if (SOC_FAILURE(rv)) { 19579 return; 19580 } 19581 } 19582 else if ((ctrl_info.instance_type 19583 == SOC_CTR_INSTANCE_TYPE_POOL) || 19584 (ctrl_info.instance_type 19585 == SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) { 19586 /* Only POOL_PIPE is possible. Type POOL was translated to 19587 type POOL_PIPE in _soc_counter_generic_get */ 19588 pipe_start = (ctrl_info.instance & 0xF); 19589 pool_id = (ctrl_info.instance >> 4) & 0x3F; 19590 19591 non_dma = &(non_dma[pool_id << 1]); 19592 19593 rv = soc_mem_read(unit, non_dma->dma_mem[pipe_start], 19594 MEM_BLOCK_ANY, idx, 19595 non_dma->dma_buf[pipe_start]); 19596 if (SOC_FAILURE(rv)) { 19597 return; 19598 } 19599 entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit); 19600 } 19601 else if ((ctrl_info.instance_type 19602 == SOC_CTR_INSTANCE_TYPE_FT_GROUP)) { 19603 19604 /* non_dma = &(non_dma[pool_id << 1]);*/ 19605 19606 rv = soc_mem_read(unit, non_dma->dma_mem[0], 19607 MEM_BLOCK_ANY, idx, 19608 non_dma->dma_buf[0]); 19609 if (SOC_FAILURE(rv)) { 19610 return; 19611 } 19612 entries_per_pipe = non_dma->num_entries / NUM_PIPE(unit); 19613 } 19614 19615 } 19616 19617 pipe = 0; 19618 non_dma_temp = non_dma; 19619 for (j = 0; j < fld_ct; j++) { /* for packet and byte */ 19620 for (i = 0; i < num_non_dma_entries; i++) { 19621 if (ctr_reg == INVALIDr) { 19622 pipe = i / entries_per_pipe; 19623 /* buffer is NULL. Can happen if memory has holes */ 19624 if (!non_dma->dma_buf[pipe]) { 19625 /* Skip the pipe indices if dma_buf for given pipe 19626 * is NULL. 19627 * Also -1 because for-loop increases index by 1 19628 * after continue (-1). 19629 */ 19630 i += entries_per_pipe - 1; 19631 continue; 19632 } 19633 soc_mem_field_get(unit, non_dma->mem, 19634 &non_dma->dma_buf[pipe][entry_words * 19635 (i % entries_per_pipe)], 19636 non_dma_temp->field, fval); 19637 } else { 19638 /* Only for given instance type */ 19639 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_PIPE) { 19640 /* Recalculate the base_index when converting from 19641 pkt to byte or byte to pkt */ 19642 if (j > 0) { 19643 base_index += non_dma_temp->base_index - 19644 non_dma->base_index; 19645 } 19646 soc_mem_field_get(unit, non_dma->mem, 19647 &non_dma->dma_buf[inst_pipe] 19648 [entry_words *(i % entries_per_pipe)] 19649 , non_dma_temp->field, fval); 19650 } else if ((ctrl_info.instance_type == 19651 SOC_CTR_INSTANCE_TYPE_XPE_PORT) || 19652 (ctrl_info.instance_type == 19653 SOC_CTR_INSTANCE_TYPE_PORT)) { 19654 /* Recalculate the base_index when converting from 19655 pkt to byte or byte to pkt */ 19656 if (j > 0) { 19657 base_index += non_dma_temp->base_index - 19658 non_dma->base_index; 19659 } 19660 if (inst_pipe != -1) { 19661 soc_mem_field_get(unit, 19662 non_dma->dma_mem[inst_pipe], 19663 &non_dma->dma_buf[inst_pipe][0], 19664 non_dma_temp->field, fval); 19665 } else { 19666 break; 19667 } 19668 } 19669 else if ((ctrl_info.instance_type == 19670 SOC_CTR_INSTANCE_TYPE_POOL) || 19671 (ctrl_info.instance_type == 19672 SOC_CTR_INSTANCE_TYPE_POOL_PIPE)) { 19673 /* num_non_dma_entries is always 1 because only 19674 POOL_PIPE is possible */ 19675 pipe = pipe_start; 19676 i = pipe_start * entries_per_pipe; 19677 19678 if (!non_dma->dma_buf[pipe]) { 19679 continue; 19680 } 19681 soc_mem_field_get(unit, non_dma->mem, 19682 non_dma->dma_buf[pipe], 19683 non_dma_temp->field, fval); 19684 /* recalculate base_index for pkt or byte */ 19685 base_index = (non_dma_temp->base_index) + idx; 19686 } else if ((ctrl_info.instance_type == 19687 SOC_CTR_INSTANCE_TYPE_ITM_PORT)) { 19688 if (inst_pipe != -1) { 19689 soc_mem_field_get(unit, 19690 non_dma->dma_mem[0], 19691 &non_dma->dma_buf[inst_pipe][0], 19692 non_dma_temp->field, fval); 19693 } else { 19694 break; 19695 } 19696 } 19697 else if ((ctrl_info.instance_type == 19698 SOC_CTR_INSTANCE_TYPE_FT_GROUP)) { 19699 /* num_non_dma_entries is always 1 because only 19700 POOL_PIPE is possible */ 19701 if (!non_dma->dma_buf[0]) { 19702 continue; 19703 } 19704 soc_mem_field_get(unit, non_dma->mem, 19705 non_dma->dma_buf[0], 19706 non_dma_temp->field, fval); 19707 /* recalculate base_index for pkt or byte */ 19708 base_index = (non_dma_temp->base_index) + idx; 19709 } 19710 } 19711 if (non_dma_temp->field != INVALIDf) { 19712 width = soc_mem_field_length(unit, non_dma_temp->mem, 19713 non_dma_temp->field); 19714 } else { 19715 width = 32; 19716 } 19717 if (width <= 32) { 19718 /* 19719 * COVERITY 19720 * faval is passed as output parameter to function 19721 * soc_mem_field_get to get initialized 19722 */ 19723 /* coverity[uninit_use : FALSE] */ 19724 COMPILER_64_SET(ctr_new, 0, fval[0]); 19725 } else { 19726 /* coverity[uninit_use : FALSE] */ 19727 COMPILER_64_SET(ctr_new, fval[1], fval[0]); 19728 } 19729 if (non_dma->flags & _SOC_COUNTER_NON_DMA_EXTRA_COUNT) { 19730 COMPILER_64_SUB_32(ctr_new, 1); 19731 } 19732 COUNTER_ATOMIC_BEGIN(s); 19733 ctr_prev = soc->counter_hw_val[base_index + i]; 19734 COUNTER_ATOMIC_END(s); 19735 19736 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 19737 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 19738 COUNTER_ATOMIC_BEGIN(s); 19739 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19740 COUNTER_ATOMIC_END(s); 19741 continue; 19742 } 19743 } 19744 19745 ctr_diff = ctr_new; 19746 19747 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 19748 COUNTER_ATOMIC_BEGIN(s); 19749 if (COMPILER_64_GT(ctr_new, soc->counter_sw_val[base_index + i])) { 19750 soc->counter_sw_val[base_index + i] = ctr_new; 19751 } 19752 soc->counter_hw_val[base_index + i] = ctr_new; 19753 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19754 COUNTER_ATOMIC_END(s); 19755 continue; 19756 } 19757 19758 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 19759 COUNTER_ATOMIC_BEGIN(s); 19760 soc->counter_sw_val[base_index + i] = ctr_new; 19761 soc->counter_hw_val[base_index + i] = ctr_new; 19762 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19763 COUNTER_ATOMIC_END(s); 19764 continue; 19765 } 19766 19767 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_CLEAR_ON_READ)) { 19768 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 19769 if (width < 32) { 19770 COMPILER_64_ADD_32(ctr_diff, 1U << width); 19771 } else if (width < 64) { 19772 COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0); 19773 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 19774 } 19775 } 19776 19777 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 19778 } 19779 19780 COUNTER_ATOMIC_BEGIN(s); 19781 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 19782 ctr_diff); 19783 soc->counter_hw_val[base_index + i] = ctr_new; 19784 soc->counter_delta[base_index + i] = ctr_diff; 19785 COUNTER_ATOMIC_END(s); 19786 } 19787 /* Get the associated dma. Get the byte from the pkt, or pkt from the byte */ 19788 non_dma_temp = NULL; 19789 /* do this check for CLEAR_ON_READ CASE ONLY * 19790 */ 19791 if ((ctr_reg != INVALIDr)) { 19792 soc_counter_get_associated_dma(unit, ctr_reg, non_dma, 19793 &non_dma_temp); 19794 } 19795 if (non_dma_temp == NULL) { 19796 /* Don't loop for the second time if the associated dma is NULL 19797 or when doing a global sync */ 19798 break; 19799 } 19800 } 19801 count++; 19802 non_dma++; 19803 } while ((count < subset_ct) && non_dma); 19804 } else if (non_dma->reg != INVALIDr) { 19805 pbmp_t counter_pbmp; 19806 19807 count = 0; 19808 if (non_dma->field != INVALIDf) { 19809 width = soc_reg_field_length(unit, non_dma->reg, 19810 non_dma->field); 19811 } else { 19812 width = 32; 19813 } 19814 19815 /* 19816 * If stats retrieval is for a specific 19817 * port, set the pbmp for counter collection. 19818 */ 19819 if (ctr_reg >= NUM_SOC_REG) { 19820 SOC_PBMP_CLEAR(counter_pbmp); 19821 if (ctrl_info.instance_type == SOC_CTR_INSTANCE_TYPE_ITM_PORT) { 19822 /* For ITM counter register, port is used as ITM instance */ 19823 port = 19824 (ctrl_info.instance & CTR_INSTANCE_BIT_MASK_ITM) >> 19825 CTR_INSTANCE_BIT_SHIFT_ITM; 19826 } else { 19827 port = ctrl_info.instance; 19828 } 19829 SOC_PBMP_PORT_ADD(counter_pbmp, port); 19830 } else { 19831 SOC_PBMP_CLEAR(counter_pbmp); 19832 SOC_PBMP_ASSIGN(counter_pbmp, soc->counter_pbmp); 19833 } 19834 19835 PBMP_ITER(counter_pbmp, port) { 19836 /* 19837 * stats retrieval for a specific port. 19838 */ 19839 19840 if (ctr_reg >= NUM_SOC_REG) { 19841 if (!SOC_PBMP_MEMBER(counter_pbmp, port)) { 19842 continue; 19843 } 19844 19845 i = idx; 19846 count = i + 1; 19847 base_index = base_idx; 19848 } else { 19849 if (non_dma->entries_per_port == 0) { 19850 /* 19851 * OK to over-write port variable as loop 19852 * breaks after 1 iter. Check below for 19853 * the same codition. 19854 */ 19855 port = REG_PORT_ANY; 19856 count = non_dma->num_entries; 19857 base_index = non_dma->base_index; 19858 } else { 19859 if (!SOC_PBMP_MEMBER(non_dma->pbmp, port)) { 19860 continue; 19861 } 19862 19863 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PERQ_REG) { 19864 count = num_cosq[unit][port]; 19865 base_index = non_dma->base_index; 19866 for (i = 0; i < port; i++) { 19867 base_index += num_cosq[unit][i]; 19868 } 19869 } else { 19870 count = non_dma->entries_per_port; 19871 base_index = non_dma->base_index + port * count; 19872 } 19873 } 19874 } 19875 19876 for (i = 0; i < count; i++) { 19877 /* coverity[negative_returns : FALSE] */ 19878 rv = soc_reg_get(unit, non_dma->reg, port, i, &ctr_new); 19879 if (SOC_FAILURE(rv)) { 19880 return; 19881 } 19882 COUNTER_ATOMIC_BEGIN(s); 19883 ctr_prev = soc->counter_hw_val[base_index + i]; 19884 COUNTER_ATOMIC_END(s); 19885 19886 if (COMPILER_64_EQ(ctr_new, ctr_prev)) { 19887 COUNTER_ATOMIC_BEGIN(s); 19888 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19889 COUNTER_ATOMIC_END(s); 19890 continue; 19891 } 19892 19893 ctr_diff = ctr_new; 19894 19895 if (non_dma->flags & _SOC_COUNTER_NON_DMA_PEAK) { 19896 COUNTER_ATOMIC_BEGIN(s); 19897 if (COMPILER_64_GT(ctr_new, 19898 soc->counter_sw_val[base_index + i])) { 19899 soc->counter_sw_val[base_index + i] = ctr_new; 19900 } 19901 soc->counter_hw_val[base_index + i] = ctr_new; 19902 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19903 COUNTER_ATOMIC_END(s); 19904 continue; 19905 } 19906 19907 if (non_dma->flags & _SOC_COUNTER_NON_DMA_CURRENT) { 19908 COUNTER_ATOMIC_BEGIN(s); 19909 soc->counter_sw_val[base_index + i] = ctr_new; 19910 soc->counter_hw_val[base_index + i] = ctr_new; 19911 COMPILER_64_ZERO(soc->counter_delta[base_index + i]); 19912 COUNTER_ATOMIC_END(s); 19913 continue; 19914 } 19915 19916 if (COMPILER_64_LT(ctr_diff, ctr_prev)) { 19917 if (width < 32) { 19918 COMPILER_64_ADD_32(ctr_diff, 1U << width); 19919 } else if (width < 64) { 19920 COMPILER_64_SET(wrap_amt, 1U << (width - 32), 0); 19921 COMPILER_64_ADD_64(ctr_diff, wrap_amt); 19922 } 19923 } 19924 19925 COMPILER_64_SUB_64(ctr_diff, ctr_prev); 19926 19927 COUNTER_ATOMIC_BEGIN(s); 19928 COMPILER_64_ADD_64(soc->counter_sw_val[base_index + i], 19929 ctr_diff); 19930 soc->counter_hw_val[base_index + i] = ctr_new; 19931 soc->counter_delta[base_index + i] = ctr_diff; 19932 COUNTER_ATOMIC_END(s); 19933 } 19934 if (non_dma->entries_per_port == 0) { 19935 break; 19936 } 19937 } 19938 } else { 19939 continue; 19940 } 19941 } 19942 ctr_dma_ct++; 19943 } 19944 19945 /* 19946 * Function: 19947 * _soc_counter_port_pbmp_add(int unit, int port) 19948 * Purpose: 19949 * add port to counter_pbmp 19950 * 19951 * Parameters: 19952 * unit - StrataSwitch unit #. 19953 * port - Port number #. 19954 * 19955 * Returns: 19956 * SOC_E_XXX 19957 */ 19958 STATIC int 19959 _soc_counter_port_pbmp_add(int unit, int port) 19960 { 19961 soc_control_t *soc = SOC_CONTROL(unit); 19962 int phy_port; 19963 int blk; 19964 int bindex; 19965 int blktype; 19966 int port_idx; 19967 soc_ctr_type_t ctype; 19968 19969 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 19970 if (phy_port < 0) { 19971 return SOC_E_INTERNAL; 19972 } 19973 19974 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 19975 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, 0); 19976 #if defined(BCM_MONTEREY_SUPPORT) 19977 if (!(IS_CPRI_PORT(unit, port)) && SOC_IS_MONTEREY(unit)) { 19978 if ( ((phy_port > 0) && (phy_port < 13)) || 19979 ((phy_port > 48) && (phy_port < 65))) { 19980 blk = SOC_PORT_IDX_BLOCK(unit, phy_port,1); 19981 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port,1); 19982 } 19983 } 19984 #endif 19985 if (blk < 0 && bindex < 0) { /* End of regsfile port list */ 19986 return SOC_E_NONE; 19987 } 19988 19989 for (port_idx = 0; port_idx < SOC_DRIVER(unit)->port_num_blktype; 19990 port_idx++) { 19991 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, port_idx); 19992 if (blk < 0) { /* End of block list of each port */ 19993 break; 19994 } 19995 19996 blktype = SOC_BLOCK_INFO(unit, blk).type; 19997 switch (blktype) { 19998 case SOC_BLK_CPORT: 19999 case SOC_BLK_XLPORT: 20000 case SOC_BLK_XLPORTB0: 20001 case SOC_BLK_CLPORT: 20002 case SOC_BLK_CLG2PORT: 20003 case SOC_BLK_CDPORT: 20004 case SOC_BLK_GXPORT: 20005 ctype = SOC_CTR_TYPE_XE; 20006 20007 #ifdef BCM_GREYHOUND_SUPPORT 20008 if (SOC_IS_GREYHOUND(unit) && blktype == SOC_BLK_GXPORT){ 20009 if (SOC_BLOCK_PORT(unit, blk) < 0){ 20010 ctype = SOC_CTR_TYPE_XE; 20011 } else { 20012 /* Greyhound GE port with SOC_BLK_GXPORT case*/ 20013 ctype = SOC_CTR_TYPE_GE; 20014 } 20015 } 20016 #endif /* BCM_GREYHOUND_SUPPORT */ 20017 #ifdef BCM_GREYHOUND2_SUPPORT 20018 if (SOC_IS_GREYHOUND2(unit) && blktype == SOC_BLK_CLPORT) { 20019 ctype = SOC_CTR_TYPE_CE; 20020 } 20021 #endif /* BCM_GREYHOUND2_SUPPORT */ 20022 #ifdef BCM_HELIX5_SUPPORT 20023 if (SOC_IS_HELIX5(unit)) { 20024 if (IS_QSGMII_PORT(unit, port)) { 20025 ctype = SOC_CTR_TYPE_GE; 20026 } else { 20027 ctype = SOC_CTR_TYPE_XE; 20028 } 20029 if (blktype == SOC_BLK_CLPORT) { 20030 ctype = SOC_CTR_TYPE_CE; 20031 } 20032 break; 20033 } 20034 #endif 20035 #if defined(BCM_TRIDENT3_SUPPORT) || defined BCM_TOMAHAWKPLUS_SUPPORT || \ 20036 defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 20037 if (SOC_IS_TRIDENT3X(unit) || SOC_IS_TOMAHAWKPLUS(unit) || 20038 SOC_IS_TOMAHAWK2(unit) || SOC_IS_TOMAHAWK3(unit)) { 20039 if (blktype == SOC_BLK_CLPORT) { 20040 ctype = SOC_CTR_TYPE_CE; 20041 break; 20042 } 20043 if (blktype == SOC_BLK_CDPORT) { 20044 ctype = SOC_CTR_TYPE_CD; 20045 break; 20046 } 20047 if (blktype == SOC_BLK_XLPORT) { 20048 ctype = SOC_CTR_TYPE_XE; 20049 break; 20050 } 20051 LOG_WARN(BSL_LS_SOC_COMMON, 20052 (BSL_META_U(unit, " UNKNOWN TYPE \n"))); 20053 } 20054 #endif /* BCM_TOMAHAWKPLUS_SUPPORT */ 20055 if (blktype == SOC_BLK_CLG2PORT) { 20056 ctype = SOC_CTR_TYPE_CE; 20057 } 20058 if (SOC_BLOCK_PORT(unit, blk) < 0) { 20059 ctype = -1; 20060 } 20061 break; 20062 #if defined(BCM_MONTEREY_SUPPORT) 20063 case SOC_BLK_CPRI: 20064 if(IS_CPRI_PORT(unit, port) && 20065 SOC_IS_MONTEREY(unit) ) { 20066 ctype = SOC_CTR_TYPE_CPU; 20067 } else 20068 { 20069 ctype = -1; 20070 } 20071 break; 20072 #endif 20073 default: 20074 ctype = -1; 20075 break; 20076 } 20077 20078 if (ctype != -1) { 20079 SOC_IF_ERROR_RETURN(soc_port_cmap_set(unit, port, ctype)); 20080 SOC_PBMP_PORT_ADD(soc->counter_pbmp,port); 20081 break; 20082 } 20083 } /* For each block in the given port */ 20084 20085 return SOC_E_NONE; 20086 } 20087 20088 int 20089 soc_counter_port_pbmp_add(int unit, int port) 20090 { 20091 int rv; 20092 20093 COUNTER_LOCK(unit); 20094 rv = _soc_counter_port_pbmp_add(unit, port); 20095 COUNTER_UNLOCK(unit); 20096 return rv; 20097 } 20098 20099 int 20100 soc_counter_port_pbmp_remove(int unit, int port) 20101 { 20102 soc_control_t *soc = SOC_CONTROL(unit); 20103 20104 COUNTER_LOCK(unit); 20105 soc->counter_map[port] = 0; 20106 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp,port); 20107 COUNTER_UNLOCK(unit); 20108 return SOC_E_NONE; 20109 } 20110 20111 20112 /* 20113 * Function: 20114 * soc_ser_update_counter 20115 * 20116 * Purpose: 20117 * Update both sw and corresponding hw counter 20118 * (to keep SW and HW counters coherent) 20119 * 20120 * Parameters: 20121 * unit - SOC unit number 20122 * 20123 * is_reg - nonZero => counter is declared as REG in regsfile 20124 * - Zero => counter is declared as MEM in regsfile 20125 * 20126 * restore_reg - register view that needs to be written 20127 * (for REG based counters) 20128 * 20129 * restore_mem - mem view (hw) that needs to be written 20130 * (for MEM based counters) 20131 * 20132 * index - index for MEM based counter tables 20133 * - element_number for REG based counter 20134 * 20135 * copyno - copyno for use with soc_mem_write 20136 * - port for use with soc_reg_set 20137 * 20138 * base_reg - base reg view (for REG based counters) 20139 * 20140 * base_mem - base mem view (for MEM based counters) 20141 * 20142 * inst_num - Instance number 20143 * - Pool number in case of flex counters 20144 * - XPE number in case of mmu counters 20145 * - obm queue number in case of obm counters 20146 * - 0 otherwise 20147 * 20148 * pipe - Will be invalid (-1) for MMU_CTR_COLOR_DROP_MEM_XPE0-3 20149 * - Will be >= 0 and < NUM_PIPE(unit) otherwise 20150 * 20151 * restore_last - nonZero => write last sw recorded value to hw counter 20152 * - Zero => clear both sw and hw counter 20153 * 20154 * Returns: 20155 * SOC_E_??? 20156 * 20157 * Notes: 20158 */ 20159 int 20160 soc_ser_update_counter(int unit, int is_reg, soc_reg_t restore_reg, 20161 soc_mem_t restore_mem, int index, int copyno, 20162 soc_reg_t base_reg, soc_mem_t base_mem, 20163 int inst_num, int pipe, int restore_last) 20164 { 20165 void *null_entry = NULL; 20166 20167 LOG_VERBOSE(BSL_LS_SOC_SER, (BSL_META_U(unit, 20168 "restore_%s %s, index=%0d, copyno=%0d, " 20169 "base_%s=%s, inst_num=%0d, pipe=%0d, restore_last=%0d \n"), 20170 is_reg? "reg" : "mem", 20171 is_reg? SOC_REG_NAME(unit, restore_reg) 20172 : SOC_MEM_NAME(unit, restore_mem), 20173 index, copyno, 20174 is_reg? "reg" : "mem", 20175 is_reg? SOC_REG_NAME(unit, base_reg) 20176 : SOC_MEM_NAME(unit, base_mem), 20177 inst_num, pipe, restore_last)); 20178 20179 if (is_reg && 20180 SOC_REG_IS_VALID(unit, restore_reg) && 20181 SOC_REG_IS_VALID(unit, base_reg)) { 20182 int reg_set_port = copyno; 20183 20184 /* clear hw reg */ 20185 if (SOC_REG_IS_64(unit, restore_reg)) { 20186 uint64 tmp64; 20187 COMPILER_64_ZERO(tmp64); 20188 LOG_WARN(BSL_LS_SOC_SER, 20189 (BSL_META_U(unit, 20190 "Clearing restore_reg %s, 64b, pipe=%0d, numels=%0d\n"), 20191 SOC_REG_NAME(unit, restore_reg), pipe, index)); 20192 SOC_IF_ERROR_RETURN( 20193 soc_reg_set(unit, restore_reg, reg_set_port, index, tmp64)); 20194 } else { 20195 LOG_WARN(BSL_LS_SOC_SER, 20196 (BSL_META_U(unit, 20197 "Clearing restore_reg %s, 32b, pipe=%0d, numels=%0d\n"), 20198 SOC_REG_NAME(unit, restore_reg), pipe, index)); 20199 SOC_IF_ERROR_RETURN( 20200 soc_reg32_set(unit, restore_reg, reg_set_port, index, 0)); 20201 } 20202 return SOC_E_NONE; 20203 } else if (!is_reg && 20204 SOC_MEM_IS_VALID(unit, restore_mem) && 20205 SOC_MEM_IS_VALID(unit, base_mem)) { 20206 20207 /* clear hw mem */ 20208 null_entry = soc_mem_entry_null(unit, restore_mem); 20209 return(soc_mem_write(unit, restore_mem, copyno, index, null_entry)); 20210 } 20211 20212 return SOC_E_FAIL; 20213 } 20214 20215 #endif /* defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT) */