tsn_stat.c (95989B)
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 * Purpose: 8 * Manage common functionality for TSN Statistics counter implementation. 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/drv.h> 13 #include <soc/scache.h> 14 #include <bcm/port.h> 15 #include <bcm/error.h> 16 #include <bcm/types.h> 17 #include <bcm/tsn.h> 18 #include <bcm_int/esw/tsn.h> 19 #include <bcm_int/esw/tsn_stat.h> 20 #include <bcm_int/esw_dispatch.h> 21 #if defined(BCM_GREYHOUND2_SUPPORT) 22 #include <bcm_int/esw/greyhound2.h> 23 #endif /* BCM_GREYHOUND2_SUPPORT */ 24 #include <bcm_int/esw/switch.h> 25 26 #if defined(BCM_TSN_SUPPORT) 27 /* 28 * TSN stat type feature mapping 29 */ 30 STATIC const soc_feature_t tsn_stat_type_feature[bcmTsnStatCount] = 31 { 32 soc_feature_tsn_sr, /* bcmTsnStatIngressSrTaggedPackets */ 33 soc_feature_tsn_sr, /* bcmTsnStatIngressNonLinkLocalPackets */ 34 soc_feature_tsn_sr, /* bcmTsnStatIngressSrWrongLanPackets */ 35 soc_feature_tsn_sr, /* bcmTsnStatIngressSrRxErrorPackets */ 36 soc_feature_tsn_sr, /* bcmTsnStatIngressSrTagErrorPackets */ 37 soc_feature_tsn_sr, /* bcmTsnStatIngressSrDuplicatePackets */ 38 soc_feature_tsn_sr, /* bcmTsnStatIngressSrOutOfOrderSrPackets */ 39 soc_feature_tsn_sr, /* bcmTsnStatIngressSrOwnRxPackets */ 40 soc_feature_tsn_sr, /* bcmTsnStatIngressSrUnexpectedPackets */ 41 soc_feature_tsn_mtu_stu, /* bcmTsnStatIngressMtuErrorPackets */ 42 soc_feature_tsn_mtu_stu, /* bcmTsnStatIngressStuErrorPackets */ 43 soc_feature_tsn_sr, /* bcmTsnStatIngressSrAcceptedSrPackets */ 44 soc_feature_tsn_sr, /* bcmTsnStatIngressSrSaSrcFilteredPackets */ 45 soc_feature_tsn_taf, /* bcmTsnStatIngressTafMeterDrop */ 46 soc_feature_tsn_taf, /* bcmTsnStatIngressTafGatePass */ 47 soc_feature_tsn_taf, /* bcmTsnStatIngressTafGateCloseDrop */ 48 soc_feature_tsn_taf, /* bcmTsnStatIngressTafGateNoByteDrop */ 49 soc_feature_tsn_taf, /* bcmTsnStatIngressTafMtuPass */ 50 soc_feature_tsn_sr, /* bcmTsnStatEgressSrTaggedPackets */ 51 soc_feature_tsn_sr, /* bcmTsnStatEgressNonLinkLocalPackets */ 52 soc_feature_tsn_mtu_stu, /* bcmTsnStatEgressMtuErrorPackets */ 53 soc_feature_tsn_mtu_stu /* bcmTsnStatEgressStuErrorPackets */ 54 }; 55 56 /* 57 * TSN stat portcnt member list data structure 58 */ 59 typedef struct bcmi_tsn_stat_portcnt_member_s { 60 soc_mem_t mem; 61 soc_field_t field; 62 uint64 *port_counter_hw; 63 uint64 *port_counter_sw; 64 } bcmi_tsn_stat_portcnt_member_t; 65 66 /* 67 * TSN stat portcnt table entry data structure for temporary access 68 */ 69 typedef struct bcmi_tsn_stat_portcnt_table_entry_s { 70 uint32 entry_data[SOC_MAX_MEM_WORDS]; 71 } bcmi_tsn_stat_portcnt_table_entry_t; 72 73 /* 74 * Software book keeping for TSN stat portcnt related information: 75 * - enabled matrix for extra counter callback(thread) 76 */ 77 typedef struct bcmi_tsn_stat_portcnt_bk_info_s { 78 SHR_BITDCL *stat_bitmap; /* TSN Portcnt Stat bitmap [stats] */ 79 SHR_BITDCL *stat_port_bitmap; /* TSN Portcnt Port bitmap [stats * ports] */ 80 int num_port; 81 } bcmi_tsn_stat_portcnt_bk_info_t; 82 83 /* 84 * TSN stat portcnt control data structure 85 */ 86 typedef struct bcmi_tsn_stat_portcnt_control_s { 87 sal_mutex_t portcnt_mutex; 88 bcmi_tsn_stat_portcnt_member_t *stats; 89 bcmi_tsn_stat_portcnt_table_entry_t *portcnt_entry_temp; 90 bcmi_tsn_stat_portcnt_bk_info_t *portcnt_bk_info; 91 } bcmi_tsn_stat_portcnt_control_t; 92 93 /* 94 * TSN stat flowcnt control data structure 95 */ 96 typedef struct bcmi_tsn_stat_flowcnt_control_s { 97 sal_mutex_t flowcnt_mutex; 98 } bcmi_tsn_stat_flowcnt_control_t; 99 100 /* 101 * TSN stat control data structure 102 */ 103 typedef struct bcmi_tsn_stat_control_s { 104 /* TSN stat related control structures defined below */ 105 bcmi_tsn_stat_portcnt_control_t *portcnt_control; 106 bcmi_tsn_stat_flowcnt_control_t *flowcnt_control; 107 /* TSN stat device info for chip specific */ 108 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 109 } bcmi_tsn_stat_control_t; 110 111 /* TSN stat control */ 112 STATIC bcmi_tsn_stat_control_t *tsn_stat_control[BCM_MAX_NUM_UNITS]; 113 114 /* Global initialized parameter for TSN stat */ 115 STATIC uint8 tsn_stat_initialized = 0; 116 117 static soc_ser_tsn_stat_functions_t ser_tsn_stat_functions; 118 119 /* 120 * Macro: 121 * TSN_STAT_PORTCNT_IS_INIT (internal) 122 * Purpose: 123 * Check that the unit is valid and confirm that 124 * the TSN Port Stat functions are initialized. 125 * Parameters: 126 * unit - BCM device number 127 * Notes: 128 * Results in return (BCM_E_UNIT), return (BCM_E_UNAVAIL), or 129 * return (BCM_E_INIT) if fails. 130 */ 131 #define TSN_STAT_PORTCNT_IS_INIT(_unit_) \ 132 do { \ 133 if (!soc_feature(_unit_, soc_feature_tsn)) { \ 134 return BCM_E_UNAVAIL; \ 135 } \ 136 if (NULL == tsn_stat_control[_unit_]) { \ 137 LOG_ERROR(BSL_LS_BCM_TSN, \ 138 (BSL_META_U(_unit_, \ 139 "TSN stat control Error: " \ 140 "not initialized\n"))); \ 141 return BCM_E_INIT; \ 142 } \ 143 if (NULL == tsn_stat_control[_unit_]->portcnt_control) { \ 144 LOG_ERROR(BSL_LS_BCM_TSN, \ 145 (BSL_META_U(_unit_, \ 146 "TSN portcnt control Error: " \ 147 "not initialized\n"))); \ 148 return BCM_E_INIT; \ 149 } \ 150 } while (0) 151 152 /* 153 * Macro: 154 * TSN_STAT_PORTCNT_IS_INIT (internal) 155 * Purpose: 156 * Check that the unit is valid and confirm that 157 * the TSN Port Stat functions are initialized. 158 * Parameters: 159 * unit - BCM device number 160 * Notes: 161 * Results in return (BCM_E_UNIT), return (BCM_E_UNAVAIL), or 162 * return (BCM_E_INIT) if fails. 163 */ 164 #define TSN_STAT_FLOWCNT_IS_INIT(_unit_) \ 165 do { \ 166 if (!soc_feature(_unit_, soc_feature_tsn)) { \ 167 return BCM_E_UNAVAIL; \ 168 } \ 169 if (NULL == tsn_stat_control[_unit_]) { \ 170 LOG_ERROR(BSL_LS_BCM_TSN, \ 171 (BSL_META_U(_unit_, \ 172 "TSN stat control Error: " \ 173 "not initialized\n"))); \ 174 return BCM_E_INIT; \ 175 } \ 176 if (NULL == tsn_stat_control[_unit_]->flowcnt_control) { \ 177 LOG_ERROR(BSL_LS_BCM_TSN, \ 178 (BSL_META_U(_unit_, \ 179 "TSN flowcnt control Error: " \ 180 "not initialized\n"))); \ 181 return BCM_E_INIT; \ 182 } \ 183 } while (0) 184 185 186 /* TSN stat mutex lock and unlock */ 187 #define TSN_STAT_PORTCNT_LOCK(pc) \ 188 sal_mutex_take((pc)->portcnt_mutex, sal_mutex_FOREVER) 189 #define TSN_STAT_PORTCNT_UNLOCK(pc) \ 190 sal_mutex_give((pc)->portcnt_mutex) 191 #define TSN_STAT_FLOWCNT_LOCK(fc) \ 192 sal_mutex_take((fc)->flowcnt_mutex, sal_mutex_FOREVER) 193 #define TSN_STAT_FLOWCNT_UNLOCK(fc) \ 194 sal_mutex_give((fc)->flowcnt_mutex) 195 196 /* 197 * Enabled matrix for TSN Portcnt Stat usage bitmap operations 198 * - if any port is enabled 199 */ 200 #define TSN_STAT_PORTCNT_USED_GET(portcnt_bk_info, stat) \ 201 (((portcnt_bk_info)->stat_bitmap) ? \ 202 SHR_BITGET((portcnt_bk_info)->stat_bitmap, (stat)) : 0) 203 #define TSN_STAT_PORTCNT_USED_SET(portcnt_bk_info, stat) \ 204 SHR_BITSET((portcnt_bk_info)->stat_bitmap, (stat)) 205 #define TSN_STAT_PORTCNT_USED_CLR(portcnt_bk_info, stat) \ 206 SHR_BITCLR((portcnt_bk_info)->stat_bitmap, (stat)) 207 208 /* 209 * Enabled matrix for TSN Portcnt Port usage bitmap operations 210 * with specified TSN stat 211 */ 212 #define TSN_STAT_PORTCNT_PORT_USED_GET(portcnt_bk_info, stat, port) \ 213 (((portcnt_bk_info)->stat_port_bitmap) ? \ 214 SHR_BITGET((portcnt_bk_info)->stat_port_bitmap, \ 215 ((stat * (portcnt_bk_info)->num_port) + port)) : 0) 216 #define TSN_STAT_PORTCNT_PORT_USED_SET(portcnt_bk_info, stat, port) \ 217 SHR_BITSET((portcnt_bk_info)->stat_port_bitmap, \ 218 ((stat * (portcnt_bk_info)->num_port) + port)) 219 #define TSN_STAT_PORTCNT_PORT_USED_CLR(portcnt_bk_info, stat, port) \ 220 SHR_BITCLR((portcnt_bk_info)->stat_port_bitmap, \ 221 ((stat * (portcnt_bk_info)->num_port) + port)) 222 223 /* TSN stat type validation */ 224 #define TSN_STAT_IS_VALID(unit, type) \ 225 ((type >= bcmTsnStatIngressSrTaggedPackets) && \ 226 (type < bcmTsnStatCount)) 227 228 /* helper macro to execute dispatched specific device function */ 229 #define TSN_STAT_FLOWCNT_FUNC(_name_, _args_) \ 230 ((NULL == tsn_stat_control[unit]->tsn_stat_dev_info-> \ 231 tsn_stat_flowcnt_dev_info->tsn_stat_flowcnt_##_name_) ? BCM_E_INIT :\ 232 (tsn_stat_control[unit]->tsn_stat_dev_info-> \ 233 tsn_stat_flowcnt_dev_info->tsn_stat_flowcnt_##_name_)_args_) 234 235 236 /* 237 * Function: 238 * tsn_stat_control_instance_get 239 * Description: 240 * Helper function to retrieve TSN stat control pointer 241 * Parameters: 242 * unit - (IN) BCM device number 243 * tc - (OUT) TSN stat control data structure 244 * Returns: 245 * BCM_E_XXX 246 */ 247 STATIC int 248 tsn_stat_control_instance_get( 249 int unit, 250 bcmi_tsn_stat_control_t **tc) 251 { 252 /* Input parameter check. */ 253 if (NULL == tc) { 254 return BCM_E_PARAM; 255 } 256 257 /* Check if TSN feature supported and initialized for TSN stat */ 258 if (!soc_feature(unit, soc_feature_tsn)) { 259 return BCM_E_UNAVAIL; 260 } 261 if (NULL == tsn_stat_control[unit]) { 262 LOG_ERROR(BSL_LS_BCM_TSN, 263 (BSL_META_U(unit, 264 "TSN stat control Error: " 265 "not initialized\n"))); 266 return BCM_E_INIT; 267 } 268 if (NULL == tsn_stat_control[unit]->tsn_stat_dev_info) { 269 LOG_ERROR(BSL_LS_BCM_TSN, 270 (BSL_META_U(unit, 271 "TSN stat dev info Error: " 272 "not initialized\n"))); 273 return BCM_E_INIT; 274 } 275 276 /* Fill info structure. */ 277 *tc = tsn_stat_control[unit]; 278 279 return BCM_E_NONE; 280 } 281 282 /* 283 * Function: 284 * tsn_stat_portcnt_control_instance_get 285 * Description: 286 * Helper function to retrieve TSN stat portcnt control pointer 287 * Parameters: 288 * unit - (IN) BCM device number 289 * pc - (OUT) TSN port stat control data structure 290 * Returns: 291 * BCM_E_XXX 292 */ 293 STATIC int 294 tsn_stat_portcnt_control_instance_get( 295 int unit, 296 bcmi_tsn_stat_portcnt_control_t **pc) 297 { 298 /* Input parameter check. */ 299 if (NULL == pc) { 300 return BCM_E_PARAM; 301 } 302 303 /* Check if TSN feature supported and initialized for TSN portcnt */ 304 TSN_STAT_PORTCNT_IS_INIT(unit); 305 306 /* Fill info structure. */ 307 *pc = tsn_stat_control[unit]->portcnt_control; 308 309 return BCM_E_NONE; 310 } 311 312 /* 313 * Function: 314 * tsn_stat_flowcnt_control_instance_get 315 * Description: 316 * Helper function to retrieve TSN stat flowcnt control pointer 317 * Parameters: 318 * unit - (IN) BCM device number 319 * fc - (OUT) TSN flow stat control data structure 320 * Returns: 321 * BCM_E_XXX 322 */ 323 STATIC int 324 tsn_stat_flowcnt_control_instance_get( 325 int unit, 326 bcmi_tsn_stat_flowcnt_control_t **fc) 327 { 328 /* Input parameter check. */ 329 if (NULL == fc) { 330 return BCM_E_PARAM; 331 } 332 333 /* Check if TSN feature supported and initialized for TSN portcnt */ 334 TSN_STAT_FLOWCNT_IS_INIT(unit); 335 336 /* Fill info structure. */ 337 *fc = tsn_stat_control[unit]->flowcnt_control; 338 339 return BCM_E_NONE; 340 } 341 342 /* 343 * Function: 344 * bcmi_esw_tsn_stat_gport_validate 345 * Description: 346 * Helper function to validate port/gport parameter 347 * Parameters: 348 * unit - (IN) BCM device number 349 * port_in - (IN) Port / Gport to validate 350 * port_out - (OUT) Port number if valid. 351 * Returns: 352 * BCM_E_NONE - Port OK 353 * BCM_E_INIT - Not initialized 354 * BCM_E_PORT - Port Invalid 355 */ 356 STATIC int 357 bcmi_esw_tsn_stat_gport_validate( 358 int unit, 359 bcm_port_t port_in, 360 bcm_port_t *port_out) 361 { 362 /* Input parameter check. */ 363 if (NULL == port_out) { 364 return BCM_E_PARAM; 365 } 366 367 if (BCM_GPORT_IS_SET(port_in)) { 368 BCM_IF_ERROR_RETURN( 369 bcm_esw_port_local_get(unit, port_in, port_out)); 370 } else if (SOC_PORT_VALID(unit, port_in) && 371 SOC_PBMP_MEMBER(PBMP_ALL(unit), port_in)) { 372 *port_out = port_in; 373 } else { 374 return BCM_E_PORT; 375 } 376 377 return BCM_E_NONE; 378 } 379 380 #ifdef BCM_WARM_BOOT_SUPPORT 381 /* 382 * Function: 383 * bcmi_esw_tsn_stat_portcnt_sync 384 * Purpose: 385 * Synchronize the TSN Portcnt Stat/Port sw bitmap into scache 386 * Parameters: 387 * unit - (IN) Unit number 388 * Returns: 389 * BCM_E_xxx 390 */ 391 int 392 bcmi_esw_tsn_stat_portcnt_sync(int unit) 393 { 394 bcmi_tsn_stat_control_t *tc; 395 bcmi_tsn_stat_portcnt_control_t *pc; 396 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 397 bcmi_tsn_stat_portcnt_bk_info_t *portcnt_bk_info; 398 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 399 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 400 int num_stat; 401 int num_stat_port; 402 soc_scache_handle_t scache_handle; 403 uint8 *portcnt_scache_ptr; 404 uint32 portcnt_scache_size; 405 int i, p, num_port; 406 407 /* Get TSN stat control */ 408 BCM_IF_ERROR_RETURN( 409 tsn_stat_control_instance_get(unit, &tc)); 410 411 /* Get portcnt control */ 412 BCM_IF_ERROR_RETURN( 413 tsn_stat_portcnt_control_instance_get(unit, &pc)); 414 415 /* Get chip specific info for TSN stat portcnt */ 416 tsn_stat_dev_info = tc->tsn_stat_dev_info; 417 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 418 portcnt_bk_info = pc->portcnt_bk_info; 419 420 /* Get num_stat */ 421 num_stat = portcnt_dev_info->num_stats; 422 /* Get num_stat_port */ 423 num_stat_port = (num_stat * portcnt_bk_info->num_port); 424 425 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 426 BCM_TSN_WB_SCACHE_PART_TSN_STAT_PORTCNT); 427 /* allocate the scache pointer size */ 428 /* TSN portcnt stat_bitmap and stat_port_bitmap */ 429 portcnt_scache_size = SHR_BITALLOCSIZE(num_stat) + 430 SHR_BITALLOCSIZE(num_stat_port); 431 432 /* TSN Port Stat counter port_counter_hw and port_counter_sw */ 433 portcnt_member = &pc->stats[0]; 434 num_port = soc_mem_index_count(unit, portcnt_member->mem); 435 portcnt_scache_size += (num_stat * (num_port * sizeof(uint64)) * 2); 436 437 BCM_IF_ERROR_RETURN( 438 _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 439 portcnt_scache_size, &portcnt_scache_ptr, 440 BCM_TSN_WB_DEFAULT_VERSION, NULL)); 441 if (NULL == portcnt_scache_ptr) { 442 LOG_VERBOSE(BSL_LS_BCM_TSN, 443 (BSL_META_U(unit, 444 "SCACHE Memory not available \n"))); 445 return BCM_E_MEMORY; 446 } 447 448 TSN_STAT_PORTCNT_LOCK(pc); 449 450 /* TSN portcnt stat_bitmap */ 451 SHR_BITCOPY_RANGE((SHR_BITDCL *)(portcnt_scache_ptr), 0, 452 portcnt_bk_info->stat_bitmap, 0, num_stat); 453 portcnt_scache_ptr += SHR_BITALLOCSIZE(num_stat); 454 455 /* TSN portcnt stat_port_bitmap */ 456 SHR_BITCOPY_RANGE((SHR_BITDCL *)(portcnt_scache_ptr), 0, 457 portcnt_bk_info->stat_port_bitmap, 0, num_stat_port); 458 portcnt_scache_ptr += SHR_BITALLOCSIZE(num_stat_port); 459 460 /* TSN Port Stat counter for port_counter_hw and port_counter_sw */ 461 for (i = 0; i < num_stat; i++) { 462 portcnt_member = &pc->stats[i]; 463 num_port = soc_mem_index_count(unit, portcnt_member->mem); 464 465 for (p = 0; p < num_port; p++) { 466 /* TSN Port Stat counter port_counter_hw */ 467 sal_memcpy(portcnt_scache_ptr, 468 &(portcnt_member->port_counter_hw[p]), sizeof(uint64)); 469 portcnt_scache_ptr += sizeof(uint64); 470 /* TSN Port Stat counter port_counter_sw */ 471 sal_memcpy(portcnt_scache_ptr, 472 &(portcnt_member->port_counter_sw[p]), sizeof(uint64)); 473 portcnt_scache_ptr += sizeof(uint64); 474 } 475 } 476 477 TSN_STAT_PORTCNT_UNLOCK(pc); 478 479 return BCM_E_NONE; 480 } 481 482 /* 483 * Function: 484 * bcmi_esw_tsn_stat_portcnt_reload 485 * Purpose: 486 * Reload the scache data into TSN Portcnt Stat/Port sw bitmap 487 * Parameters: 488 * unit - (IN) Unit number 489 * Returns: 490 * BCM_E_xxx 491 */ 492 int 493 bcmi_esw_tsn_stat_portcnt_reload(int unit) 494 { 495 int rv = BCM_E_NONE; 496 bcmi_tsn_stat_control_t *tc; 497 bcmi_tsn_stat_portcnt_control_t *pc; 498 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 499 bcmi_tsn_stat_portcnt_bk_info_t *portcnt_bk_info; 500 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 501 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 502 int num_stat; 503 int num_stat_port; 504 soc_scache_handle_t scache_handle; 505 uint8 *portcnt_scache_ptr; 506 int i, p, num_port; 507 508 LOG_DEBUG(BSL_LS_BCM_TSN, 509 (BSL_META_U(unit, 510 "bcmi_esw_tsn_stat_portcnt_reload\n"))); 511 512 /* Get TSN stat control */ 513 BCM_IF_ERROR_RETURN( 514 tsn_stat_control_instance_get(unit, &tc)); 515 516 /* Get portcnt control */ 517 BCM_IF_ERROR_RETURN( 518 tsn_stat_portcnt_control_instance_get(unit, &pc)); 519 520 /* Get chip specific info for TSN stat portcnt */ 521 tsn_stat_dev_info = tc->tsn_stat_dev_info; 522 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 523 portcnt_bk_info = pc->portcnt_bk_info; 524 525 /* Get num_stat */ 526 num_stat = portcnt_dev_info->num_stats; 527 /* Get num_stat_port */ 528 num_stat_port = (num_stat * portcnt_bk_info->num_port); 529 530 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 531 BCM_TSN_WB_SCACHE_PART_TSN_STAT_PORTCNT); 532 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 533 0, &portcnt_scache_ptr, 534 BCM_TSN_WB_DEFAULT_VERSION, NULL); 535 536 if (rv == BCM_E_NOT_FOUND) { 537 portcnt_scache_ptr = NULL; 538 rv = BCM_E_NONE; 539 } else if (BCM_FAILURE(rv)) { 540 return rv; 541 } 542 543 if (portcnt_scache_ptr != NULL) { 544 /* TSN portcnt stat_bitmap */ 545 SHR_BITCOPY_RANGE(portcnt_bk_info->stat_bitmap, 0, 546 (SHR_BITDCL *)(portcnt_scache_ptr), 0, 547 num_stat); 548 portcnt_scache_ptr += SHR_BITALLOCSIZE(num_stat); 549 550 /* TSN portcnt stat_port_bitmap */ 551 SHR_BITCOPY_RANGE(portcnt_bk_info->stat_port_bitmap, 0, 552 (SHR_BITDCL *)(portcnt_scache_ptr), 0, 553 num_stat_port); 554 portcnt_scache_ptr += SHR_BITALLOCSIZE(num_stat_port); 555 556 /* TSN Port Stat counter for port_counter_hw and port_counter_sw */ 557 for (i = 0; i < num_stat; i++) { 558 portcnt_member = &pc->stats[i]; 559 num_port = soc_mem_index_count(unit, portcnt_member->mem); 560 561 for (p = 0; p < num_port; p++) { 562 /* TSN Port Stat counter port_counter_hw */ 563 sal_memcpy(&(portcnt_member->port_counter_hw[p]), 564 portcnt_scache_ptr, sizeof(uint64)); 565 portcnt_scache_ptr += sizeof(uint64); 566 /* TSN Port Stat counter port_counter_sw */ 567 sal_memcpy(&(portcnt_member->port_counter_sw[p]), 568 portcnt_scache_ptr, sizeof(uint64)); 569 portcnt_scache_ptr += sizeof(uint64); 570 } 571 } 572 } 573 574 return rv; 575 } 576 577 /* 578 * Function: 579 * bcmi_esw_tsn_stat_flowcnt_sync 580 * Purpose: 581 * Synchronize the TSN Flowcnt Stat into scache 582 * Parameters: 583 * unit - (IN) Unit number 584 * Returns: 585 * BCM_E_xxx 586 */ 587 int 588 bcmi_esw_tsn_stat_flowcnt_sync(int unit) 589 { 590 int rv = BCM_E_NONE; 591 bcmi_tsn_stat_flowcnt_control_t *fc; 592 soc_scache_handle_t scache_handle; 593 uint8 *scache_ptr; 594 int scache_size; 595 596 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 597 BCM_TSN_WB_SCACHE_PART_TSN_STAT_FLOWCNT); 598 599 BCM_IF_ERROR_RETURN( 600 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 601 602 TSN_STAT_FLOWCNT_LOCK(fc); 603 rv = TSN_STAT_FLOWCNT_FUNC(get_scache_size, (unit, &scache_size)); 604 605 if (BCM_SUCCESS(rv)) { 606 rv = _bcm_esw_scache_ptr_get( 607 unit, scache_handle, TRUE, 608 scache_size, 609 &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL); 610 } 611 612 if (BCM_SUCCESS(rv)) { 613 rv = TSN_STAT_FLOWCNT_FUNC(sync, (unit, scache_ptr)); 614 } 615 TSN_STAT_FLOWCNT_UNLOCK(fc); 616 617 return rv; 618 } 619 620 /* 621 * Function: 622 * bcmi_esw_tsn_stat_flowcnt_reload 623 * Purpose: 624 * Reload the scache data into TSN Flowcnt Stat 625 * Parameters: 626 * unit - (IN) Unit number 627 * Returns: 628 * BCM_E_xxx 629 */ 630 int 631 bcmi_esw_tsn_stat_flowcnt_reload(int unit) 632 { 633 int rv = BCM_E_NONE; 634 bcmi_tsn_stat_flowcnt_control_t *fc; 635 soc_scache_handle_t scache_handle; 636 uint8 *scache_ptr; 637 int scache_size; 638 639 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_TSN, 640 BCM_TSN_WB_SCACHE_PART_TSN_STAT_FLOWCNT); 641 642 BCM_IF_ERROR_RETURN( 643 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 644 645 TSN_STAT_FLOWCNT_LOCK(fc); 646 rv = TSN_STAT_FLOWCNT_FUNC(get_scache_size, (unit, &scache_size)); 647 648 if (BCM_SUCCESS(rv)) { 649 rv = _bcm_esw_scache_ptr_get( 650 unit, scache_handle, FALSE, 651 scache_size, 652 &scache_ptr, BCM_TSN_WB_DEFAULT_VERSION, NULL); 653 } 654 655 if (BCM_E_NOT_FOUND == rv) { 656 /* proceed with Level 1 Warm Boot */ 657 rv = TSN_STAT_FLOWCNT_FUNC(reload_l1, (unit)); 658 } else if (BCM_E_NONE == rv) { 659 if (NULL == scache_ptr) { 660 rv = BCM_E_INTERNAL; 661 } else { 662 rv = TSN_STAT_FLOWCNT_FUNC(reload_l2, (unit, scache_ptr)); 663 } 664 } 665 TSN_STAT_FLOWCNT_UNLOCK(fc); 666 667 return rv; 668 } 669 #endif /* BCM_WARM_BOOT_SUPPORT */ 670 671 /* 672 * Function: 673 * bcmi_esw_tsn_stat_portcnt_collect 674 * Description: 675 * TSN Port Counter accumulation routine called periodically 676 * to sync s/w copy with h/w copy. 677 * Parameters: 678 * unit - (IN) Unit number 679 * mem - (IN) TSN port stat counter memory (if -1 for all memories) 680 * counter_idx - (IN) counter index (port index). 681 * if -1 accumulate for all counters (for ports) 682 * else retrieve a specific counter (one port). 683 * Returns: 684 * None 685 * Notes: 686 */ 687 STATIC void 688 bcmi_esw_tsn_stat_portcnt_collect( 689 int unit, 690 soc_mem_t mem, 691 int counter_idx) 692 { 693 uint32 mem_index_min; 694 int mem_index_max; 695 uint32 packet_count_hw[2]; 696 uint64 new_packet_count; 697 uint64 prev_packet_count; 698 uint64 max_packet_size; 699 soc_memacc_t memacc_pkt; 700 soc_mem_t l_mem; 701 soc_field_t l_field; 702 int i, index, width; 703 bcmi_tsn_stat_control_t *tc; 704 bcmi_tsn_stat_portcnt_control_t *pc; 705 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 706 bcmi_tsn_stat_portcnt_table_entry_t *portcnt_entry_temp; 707 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 708 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 709 uint32 *portcnt_entry_temp_ptr_start, *portcnt_entry_temp_ptr; 710 int entry_words; 711 712 /* Get TSN stat control */ 713 (void)tsn_stat_control_instance_get(unit, &tc); 714 if (NULL == tc) { 715 return; 716 } 717 718 /* Get chip specific info for TSN stat */ 719 tsn_stat_dev_info = tc->tsn_stat_dev_info; 720 if (NULL == tsn_stat_dev_info) { 721 return; 722 } 723 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 724 if (NULL == portcnt_dev_info) { 725 return; 726 } 727 728 /* Get portcnt control */ 729 (void)tsn_stat_portcnt_control_instance_get(unit, &pc); 730 if (NULL == pc) { 731 return; 732 } 733 734 COMPILER_64_ZERO(new_packet_count); 735 COMPILER_64_ZERO(prev_packet_count); 736 COMPILER_64_ZERO(max_packet_size); 737 738 l_mem = pc->stats[0].mem; 739 l_field = pc->stats[0].field; 740 /* Get the packet count field width for this device */ 741 width = soc_mem_field_length(unit, l_mem, l_field); 742 743 /* Hardware support maximum packet size */ 744 COMPILER_64_SET(max_packet_size, 0, 1); 745 COMPILER_64_SHL(max_packet_size, width); 746 747 portcnt_entry_temp = pc->portcnt_entry_temp; 748 portcnt_entry_temp_ptr_start = &(portcnt_entry_temp[0].entry_data[0]); 749 for (i = 0; i < portcnt_dev_info->num_stats; i++) { 750 /* Check if the matrix of (stats) is enabled for portcnt callback */ 751 if (!TSN_STAT_PORTCNT_USED_GET(pc->portcnt_bk_info, i)) { 752 continue; 753 } 754 755 l_mem = pc->stats[i].mem; 756 l_field = pc->stats[i].field; 757 758 /* Get entry_words for each memory */ 759 entry_words = soc_mem_entry_words(unit, l_mem); 760 if ((mem == -1) || (l_mem == mem)) { 761 portcnt_member = &pc->stats[i]; 762 763 mem_index_min = soc_mem_index_min(unit, l_mem); 764 mem_index_max = soc_mem_index_max(unit, l_mem); 765 766 /* 767 * If counter_idx != -1, retrieve specific 768 * counter index from the flex counter memory pool. 769 */ 770 if (counter_idx != -1) { 771 if ((counter_idx < mem_index_min) || 772 (counter_idx > mem_index_max)) { 773 return; 774 } 775 mem_index_min = mem_index_max = counter_idx; 776 } 777 778 /* Read all the counters or a specific counter from memory */ 779 if (counter_idx == -1) { 780 if (soc_mem_read_range(unit, l_mem, MEM_BLOCK_ANY, 781 mem_index_min, mem_index_max, 782 portcnt_entry_temp_ptr_start) != 783 BCM_E_NONE) { 784 LOG_ERROR(BSL_LS_BCM_TSN, 785 (BSL_META_U(unit, 786 "Unable to read a range of mem: " 787 "%s\n"), 788 SOC_MEM_UFNAME(unit, l_mem))); 789 return; 790 } 791 } else { 792 portcnt_entry_temp_ptr = 793 (portcnt_entry_temp_ptr_start + (entry_words * counter_idx)); 794 if (soc_mem_read(unit, l_mem, MEM_BLOCK_ANY, 795 counter_idx, 796 portcnt_entry_temp_ptr) != BCM_E_NONE) { 797 LOG_ERROR(BSL_LS_BCM_TSN, 798 (BSL_META_U(unit, 799 "Unable to read mem: %s\n"), 800 SOC_MEM_UFNAME(unit, l_mem))); 801 return; 802 } 803 } 804 805 /* Get a (memory, field) access information structure */ 806 if (soc_memacc_init(unit, l_mem, l_field, &memacc_pkt)) { 807 LOG_ERROR(BSL_LS_BCM_TSN, 808 (BSL_META_U(unit, 809 "Invalid mem: %s or field: %s\n"), 810 SOC_MEM_UFNAME(unit, l_mem), 811 SOC_FIELD_NAME(unit, l_field))); 812 return; 813 } 814 815 for (index = mem_index_min; index <= mem_index_max; index++) { 816 /* 817 * Check if the matrix of (stat, port) is enabled 818 * for portcnt callback 819 */ 820 if (!TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 821 i, index)) { 822 continue; 823 } 824 825 portcnt_entry_temp_ptr = 826 (portcnt_entry_temp_ptr_start + (entry_words * index)); 827 soc_memacc_field_get(&memacc_pkt, 828 portcnt_entry_temp_ptr, 829 packet_count_hw); 830 831 /* Set current hw counter into 64-bit new_packet_count */ 832 if (width > 32) { 833 /* 64-bit field */ 834 COMPILER_64_SET(new_packet_count, 835 packet_count_hw[1], 836 packet_count_hw[0]); 837 } else { 838 /* 32-bit field */ 839 COMPILER_64_SET(new_packet_count, 840 0, 841 packet_count_hw[0]); 842 } 843 844 /* Set previous hw counter into prev_packet_count */ 845 COMPILER_64_COPY(prev_packet_count, 846 portcnt_member->port_counter_hw[index]); 847 848 /* Compare old and new hardware counter */ 849 if (!COMPILER_64_EQ(prev_packet_count, new_packet_count)) { 850 LOG_VERBOSE(BSL_LS_BCM_TSN, 851 (BSL_META_U(unit, 852 "Port %d: TSN stat(%d)==>" 853 "Old Packet Count Value %x:%x\t" 854 "New Packet Count Value %x:%x\n"), 855 index, i, 856 COMPILER_64_HI(prev_packet_count), 857 COMPILER_64_LO(prev_packet_count), 858 COMPILER_64_HI(new_packet_count), 859 COMPILER_64_LO(new_packet_count))); 860 /* Update Soft Copy for current HW counter */ 861 COMPILER_64_COPY(portcnt_member->port_counter_hw[index], 862 new_packet_count); 863 } 864 865 /* 866 * Calculate the differences between new and previous 867 * packet counters 868 */ 869 if (COMPILER_64_GT(prev_packet_count, new_packet_count)) { 870 /* Roll over case */ 871 LOG_VERBOSE(BSL_LS_BCM_TSN, 872 (BSL_META_U(unit, 873 "Roll over happend!\n"))); 874 LOG_VERBOSE(BSL_LS_BCM_TSN, 875 (BSL_META_U(unit, 876 "... Read Packet HW Count :" 877 " %x:%x\n"), 878 COMPILER_64_HI(new_packet_count), 879 COMPILER_64_LO(new_packet_count))); 880 881 COMPILER_64_ADD_64(new_packet_count, max_packet_size); 882 COMPILER_64_SUB_64(new_packet_count, prev_packet_count); 883 LOG_VERBOSE(BSL_LS_BCM_TSN, 884 (BSL_META_U(unit, 885 "... Diffed Packet HW Count :" 886 " %x:%x\n"), 887 COMPILER_64_HI(new_packet_count), 888 COMPILER_64_LO(new_packet_count))); 889 } else { 890 /* Normal case */ 891 COMPILER_64_SUB_64(new_packet_count, prev_packet_count); 892 } 893 894 /* Add difference (if it is) */ 895 if (!COMPILER_64_IS_ZERO(new_packet_count)) { 896 LOG_VERBOSE(BSL_LS_BCM_TSN, 897 (BSL_META_U(unit, 898 "Port %d: TSN stat(%d)==>" 899 "Old Packet Count SW Value: " 900 "%x:%x\t"), 901 index, i, 902 COMPILER_64_HI( 903 portcnt_member->port_counter_sw[index]), 904 COMPILER_64_LO( 905 portcnt_member->port_counter_sw[index]))); 906 COMPILER_64_ADD_64( 907 portcnt_member->port_counter_sw[index], 908 new_packet_count); 909 LOG_VERBOSE(BSL_LS_BCM_TSN, 910 (BSL_META_U(unit, 911 "New Packet Count SW Value: " 912 "%x:%x\n"), 913 COMPILER_64_HI( 914 portcnt_member->port_counter_sw[index]), 915 COMPILER_64_LO( 916 portcnt_member->port_counter_sw[index]))); 917 } 918 } 919 } 920 } 921 922 return; 923 } 924 925 /* 926 * Function: 927 * bcmi_esw_tsn_stat_portcnt_map 928 * Description: 929 * Get the counter table index information based on 930 * the giving TSN statistic type 931 * Parameters: 932 * unit - (IN) Unit number 933 * port - (IN) port number 934 * stat - (IN) TSN statistics type (see tsn.h) 935 * stat_index - (OUT) TSN stat table index 936 * offset_index - (OUT) offset index (port) in the counter table 937 * (specified TSN stat) 938 * Returns: 939 * BCM_E_XXX 940 * Notes: 941 */ 942 STATIC int 943 bcmi_esw_tsn_stat_portcnt_map( 944 int unit, 945 bcm_gport_t port, 946 bcm_tsn_stat_t stat, 947 int *stat_index, 948 int *offset_index) 949 { 950 int i, rv = BCM_E_NONE; 951 bcmi_tsn_stat_control_t *tc; 952 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 953 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 954 const tsn_stat_portcnt_table_info_t *portcnt_table; 955 bcm_port_t port_out; 956 957 /* Input parameter check. */ 958 if (NULL == stat_index) { 959 return BCM_E_PARAM; 960 } 961 if (!TSN_STAT_IS_VALID(unit, stat)) { 962 return BCM_E_PARAM; 963 } 964 965 /* The port will be ignored if offset_index == NULL */ 966 if (offset_index != NULL) { 967 /* Get offset_index based on the giving gport */ 968 rv = bcmi_esw_tsn_stat_gport_validate(unit, port, &port_out); 969 if (BCM_FAILURE(rv)) { 970 return rv; 971 } 972 *offset_index = port_out; 973 } 974 975 /* Get TSN stat control */ 976 BCM_IF_ERROR_RETURN( 977 tsn_stat_control_instance_get(unit, &tc)); 978 979 /* Get chip specific info for TSN stat */ 980 tsn_stat_dev_info = tc->tsn_stat_dev_info; 981 if (NULL == tsn_stat_dev_info) { 982 return BCM_E_UNAVAIL; 983 } 984 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 985 if (NULL == portcnt_dev_info) { 986 return BCM_E_UNAVAIL; 987 } 988 989 /* Get stat_index based on the giving TSN statistic type = stat */ 990 portcnt_table = portcnt_dev_info->portcnt_table_info; 991 if (NULL == portcnt_table) { 992 return BCM_E_UNAVAIL; 993 } 994 995 *stat_index = -1; 996 for (i = 0; i < portcnt_dev_info->num_stats; i++) { 997 bcm_tsn_stat_t stat_itr = portcnt_table[i].portcnt_stat; 998 999 assert((stat_itr >= 0) && (stat_itr < bcmTsnStatCount)); 1000 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 1001 continue; 1002 } 1003 if (stat == stat_itr) { 1004 *stat_index = i; 1005 break; 1006 } 1007 } 1008 1009 if (*stat_index == -1) { 1010 /* Cannot find specified TSN statistic type for this device */ 1011 return BCM_E_UNAVAIL; 1012 } 1013 1014 return rv; 1015 } 1016 1017 /* 1018 * Function: 1019 * bcmi_esw_tsn_stat_portcnt_cleanup 1020 * Description: 1021 * Clean and free all allocated TSN port counter resources 1022 * Parameters: 1023 * unit - (IN) Unit number 1024 * Returns: 1025 * BCM_E_XXX 1026 */ 1027 STATIC int 1028 bcmi_esw_tsn_stat_portcnt_cleanup(int unit) 1029 { 1030 bcmi_tsn_stat_portcnt_control_t *pc; 1031 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1032 bcmi_tsn_stat_portcnt_bk_info_t *portcnt_bk_info; 1033 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 1034 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 1035 int i; 1036 1037 LOG_DEBUG(BSL_LS_BCM_TSN, 1038 (BSL_META_U(unit, 1039 "bcmi_esw_tsn_stat_portcnt_cleanup\n"))); 1040 1041 pc = tsn_stat_control[unit]->portcnt_control; 1042 1043 if (pc->stats != NULL) { 1044 tsn_stat_dev_info = tsn_stat_control[unit]->tsn_stat_dev_info; 1045 if (tsn_stat_dev_info != NULL) { 1046 portcnt_dev_info = 1047 tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 1048 if (portcnt_dev_info != NULL) { 1049 for (i = 0; i < portcnt_dev_info->num_stats; i++) { 1050 portcnt_member = &pc->stats[i]; 1051 if (portcnt_member->port_counter_sw != NULL) { 1052 sal_free(portcnt_member->port_counter_sw); 1053 portcnt_member->port_counter_sw = NULL; 1054 } 1055 if (portcnt_member->port_counter_hw != NULL) { 1056 sal_free(portcnt_member->port_counter_hw); 1057 portcnt_member->port_counter_hw = NULL; 1058 } 1059 } 1060 } 1061 } 1062 sal_free(pc->stats); 1063 pc->stats = NULL; 1064 } 1065 1066 if (pc->portcnt_entry_temp != NULL) { 1067 soc_cm_sfree(unit, pc->portcnt_entry_temp); 1068 pc->portcnt_entry_temp = NULL; 1069 } 1070 1071 if (pc->portcnt_bk_info != NULL) { 1072 portcnt_bk_info = pc->portcnt_bk_info; 1073 if (portcnt_bk_info->stat_bitmap != NULL) { 1074 sal_free(portcnt_bk_info->stat_bitmap); 1075 portcnt_bk_info->stat_bitmap = NULL; 1076 } 1077 if (portcnt_bk_info->stat_port_bitmap != NULL) { 1078 sal_free(portcnt_bk_info->stat_port_bitmap); 1079 portcnt_bk_info->stat_port_bitmap = NULL; 1080 } 1081 sal_free(pc->portcnt_bk_info); 1082 pc->portcnt_bk_info = NULL; 1083 } 1084 1085 if (pc->portcnt_mutex != NULL) { 1086 sal_mutex_destroy(pc->portcnt_mutex); 1087 pc->portcnt_mutex = NULL; 1088 } 1089 1090 return BCM_E_NONE; 1091 } 1092 1093 /* 1094 * Function: 1095 * bcmi_esw_tsn_stat_portcnt_init 1096 * Description: 1097 * Initialize and allocate all required resources for TSN port counters 1098 * Parameters: 1099 * unit - (IN) Unit number 1100 * Returns: 1101 * BCM_E_XXX 1102 */ 1103 STATIC int 1104 bcmi_esw_tsn_stat_portcnt_init(int unit) 1105 { 1106 int rv = BCM_E_NONE; 1107 bcmi_tsn_stat_control_t *tc; 1108 bcmi_tsn_stat_portcnt_control_t *pc; 1109 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1110 bcmi_tsn_stat_portcnt_bk_info_t *portcnt_bk_info; 1111 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 1112 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 1113 const tsn_stat_portcnt_table_info_t *portcnt_table; 1114 int i, num_port = 0; 1115 1116 /* Get TSN stat control */ 1117 BCM_IF_ERROR_RETURN( 1118 tsn_stat_control_instance_get(unit, &tc)); 1119 1120 pc = tc->portcnt_control; 1121 if (NULL == pc) { 1122 return BCM_E_INIT; 1123 } 1124 sal_memset(pc, 0, sizeof(bcmi_tsn_stat_portcnt_control_t)); 1125 1126 /* Create portcnt protection mutex. */ 1127 pc->portcnt_mutex = sal_mutex_create("tsn portcnt control mutex"); 1128 if (NULL == pc->portcnt_mutex) { 1129 return BCM_E_RESOURCE; 1130 } 1131 1132 /* Get chip specific info for TSN stat portcnt */ 1133 tsn_stat_dev_info = tc->tsn_stat_dev_info; 1134 if (NULL == tsn_stat_dev_info) { 1135 return BCM_E_UNAVAIL; 1136 } 1137 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 1138 if (NULL == portcnt_dev_info) { 1139 return BCM_E_UNAVAIL; 1140 } 1141 1142 /* Allocate the TSN portcnt stats member resource */ 1143 pc->stats = 1144 sal_alloc((portcnt_dev_info->num_stats * 1145 sizeof(bcmi_tsn_stat_portcnt_member_t)), 1146 "TSN portcnt stats"); 1147 if (NULL == pc->stats) { 1148 return BCM_E_MEMORY; 1149 } 1150 sal_memset(pc->stats, 0, 1151 (portcnt_dev_info->num_stats * 1152 sizeof(bcmi_tsn_stat_portcnt_member_t))); 1153 1154 /* 1155 * For each TSN Port Stat counter: 1156 * allocate *port_counter_sw and *port_counter_hw for all ports 1157 */ 1158 portcnt_table = portcnt_dev_info->portcnt_table_info; 1159 for (i = 0; i < portcnt_dev_info->num_stats; i++) { 1160 portcnt_member = &pc->stats[i]; 1161 portcnt_member->mem = portcnt_table[i].portcnt_mem; 1162 portcnt_member->field = portcnt_table[i].portcnt_field; 1163 num_port = soc_mem_index_count(unit, portcnt_member->mem); 1164 1165 /* Allocate port_counter_sw */ 1166 portcnt_member->port_counter_sw = 1167 sal_alloc((num_port * sizeof(uint64)), "TSN port counter sw"); 1168 if (NULL == portcnt_member->port_counter_sw) { 1169 return BCM_E_MEMORY; 1170 } 1171 sal_memset(portcnt_member->port_counter_sw, 0, 1172 (num_port * sizeof(uint64))); 1173 1174 /* Allocate port_counter_hw */ 1175 portcnt_member->port_counter_hw = 1176 sal_alloc((num_port * sizeof(uint64)), "TSN port counter hw"); 1177 if (NULL == portcnt_member->port_counter_hw) { 1178 return BCM_E_MEMORY; 1179 } 1180 sal_memset(portcnt_member->port_counter_hw, 0, 1181 (num_port * sizeof(uint64))); 1182 } 1183 1184 /* Allocate the TSN portcnt temporary counter resource for DMA */ 1185 num_port = soc_mem_index_count(unit, portcnt_table[0].portcnt_mem); 1186 pc->portcnt_entry_temp = 1187 soc_cm_salloc(unit, 1188 (num_port * sizeof(bcmi_tsn_stat_portcnt_table_entry_t)), 1189 "TSN portcnt temporary counter"); 1190 if (NULL == pc->portcnt_entry_temp) { 1191 return BCM_E_MEMORY; 1192 } 1193 sal_memset(pc->portcnt_entry_temp, 0, 1194 (num_port * sizeof(bcmi_tsn_stat_portcnt_table_entry_t))); 1195 1196 /* Allocate the TSN portcnt book keeping info resource */ 1197 pc->portcnt_bk_info = 1198 sal_alloc(sizeof(bcmi_tsn_stat_portcnt_bk_info_t), 1199 "TSN portcnt book keeping"); 1200 if (NULL == pc->portcnt_bk_info) { 1201 return BCM_E_MEMORY; 1202 } 1203 sal_memset(pc->portcnt_bk_info, 0, 1204 sizeof(bcmi_tsn_stat_portcnt_bk_info_t)); 1205 1206 portcnt_bk_info = pc->portcnt_bk_info; 1207 portcnt_bk_info->stat_bitmap = 1208 sal_alloc(SHR_BITALLOCSIZE(portcnt_dev_info->num_stats), 1209 "TSN portcnt stat_bitmap"); 1210 if (NULL == portcnt_bk_info->stat_bitmap) { 1211 return BCM_E_MEMORY; 1212 } 1213 sal_memset(portcnt_bk_info->stat_bitmap, 0, 1214 SHR_BITALLOCSIZE(portcnt_dev_info->num_stats)); 1215 1216 portcnt_bk_info->stat_port_bitmap = 1217 sal_alloc(SHR_BITALLOCSIZE(portcnt_dev_info->num_stats * num_port), 1218 "TSN portcnt stat_port_bitmap"); 1219 if (NULL == portcnt_bk_info->stat_port_bitmap) { 1220 return BCM_E_MEMORY; 1221 } 1222 sal_memset(portcnt_bk_info->stat_port_bitmap, 0, 1223 SHR_BITALLOCSIZE(portcnt_dev_info->num_stats * num_port)); 1224 1225 portcnt_bk_info->num_port = num_port; 1226 1227 1228 /* WARMBOOT related */ 1229 1230 return rv; 1231 } 1232 1233 /* 1234 * Function: 1235 * bcmi_esw_tsn_stat_portcnt_set 1236 * Description: 1237 * Set 64-bit counter value for specified TSN statistic type. 1238 * Parameters: 1239 * unit - (IN) Unit number 1240 * port - (IN) port number 1241 * stat - (IN) TSN statistics type (see tsn.h) 1242 * val - (IN) 64-bit counter value. 1243 * Returns: 1244 * BCM_E_XXX. 1245 * Notes: 1246 */ 1247 int 1248 bcmi_esw_tsn_stat_portcnt_set( 1249 int unit, 1250 bcm_gport_t port, 1251 bcm_tsn_stat_t stat, 1252 uint64 val) 1253 { 1254 int rv = BCM_E_NONE; 1255 bcmi_tsn_stat_portcnt_control_t *pc; 1256 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1257 int stat_index, offset_index, total_entries; 1258 uint32 entry[SOC_MAX_MEM_WORDS]; 1259 soc_mem_t counter_mem; 1260 soc_field_t counter_field; 1261 uint32 max_packet_value[2]; 1262 int width; 1263 1264 BCM_IF_ERROR_RETURN( 1265 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1266 1267 rv = bcmi_esw_tsn_stat_portcnt_map(unit, port, stat, 1268 &stat_index, &offset_index); 1269 if (BCM_FAILURE(rv)) { 1270 return rv; 1271 } 1272 1273 TSN_STAT_PORTCNT_LOCK(pc); 1274 portcnt_member = &pc->stats[stat_index]; 1275 counter_mem = portcnt_member->mem; 1276 counter_field = portcnt_member->field; 1277 total_entries = soc_mem_index_count(unit, counter_mem); 1278 1279 if (offset_index >= total_entries) { 1280 LOG_ERROR(BSL_LS_BCM_TSN, 1281 (BSL_META_U(unit, 1282 "Wrong OFFSET_INDEX(Port). " 1283 "Must be < Total Entries %d \n"), 1284 total_entries)); 1285 TSN_STAT_PORTCNT_UNLOCK(pc); 1286 assert(0); 1287 } 1288 1289 /* Memory read from hardware */ 1290 sal_memset(entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1291 if (soc_mem_read(unit, counter_mem, MEM_BLOCK_ANY, 1292 offset_index, &entry) != BCM_E_NONE) { 1293 TSN_STAT_PORTCNT_UNLOCK(pc); 1294 return BCM_E_INTERNAL; 1295 } 1296 1297 width = soc_mem_field_length(unit, counter_mem, counter_field); 1298 if (width > 32) { 1299 /* 64-bit field */ 1300 max_packet_value[0] = COMPILER_64_LO(val); 1301 max_packet_value[1] = COMPILER_64_HI(val); 1302 } else { 1303 /* 32-bit field */ 1304 max_packet_value[0] = COMPILER_64_LO(val); 1305 max_packet_value[1] = 0; 1306 } 1307 soc_mem_field_set(unit, counter_mem, (uint32 *)entry, 1308 counter_field, max_packet_value); 1309 1310 LOG_DEBUG(BSL_LS_BCM_TSN, 1311 (BSL_META_U(unit, 1312 "Packet Count HW Value\t:TABLE:" 1313 "%s INDEX(port):%d : %x:%x \n"), 1314 SOC_MEM_UFNAME(unit, counter_mem), 1315 offset_index, 1316 max_packet_value[1], 1317 max_packet_value[0])); 1318 1319 /* Memory write into hardware */ 1320 if (soc_mem_write(unit, counter_mem, MEM_BLOCK_ALL, 1321 offset_index, &entry) != BCM_E_NONE) { 1322 TSN_STAT_PORTCNT_UNLOCK(pc); 1323 return BCM_E_INTERNAL; 1324 } 1325 1326 /* Update Soft Copy for HW counter */ 1327 COMPILER_64_SET(portcnt_member->port_counter_hw[offset_index], 1328 max_packet_value[1], 1329 max_packet_value[0]); 1330 1331 /* Update Soft Copy for SW counter */ 1332 COMPILER_64_SET(portcnt_member->port_counter_sw[offset_index], 1333 COMPILER_64_HI(val), 1334 COMPILER_64_LO(val)); 1335 1336 /* Set to enable the portcnt callback for matrix of (stat, port) */ 1337 if (!TSN_STAT_PORTCNT_USED_GET(pc->portcnt_bk_info, stat_index)) { 1338 TSN_STAT_PORTCNT_USED_SET(pc->portcnt_bk_info, stat_index); 1339 } 1340 if (!TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 1341 stat_index, offset_index)) { 1342 TSN_STAT_PORTCNT_PORT_USED_SET(pc->portcnt_bk_info, 1343 stat_index, offset_index); 1344 } 1345 1346 TSN_STAT_PORTCNT_UNLOCK(pc); 1347 1348 return BCM_E_NONE; 1349 } 1350 1351 /* 1352 * Function: 1353 * bcmi_esw_tsn_stat_portcnt_get 1354 * Description: 1355 * Get 64-bit counter value for specified TSN statistic type. 1356 * Parameters: 1357 * unit - (IN) Unit number 1358 * port - (IN) port number 1359 * sync_mode - (IN) if 1 read hw counter else sw accumulated counter 1360 * stat - (IN) TSN statistics type (see tsn.h) 1361 * val - (OUT) 64-bit counter value. 1362 * Returns: 1363 * BCM_E_XXX. 1364 * Notes: 1365 */ 1366 int 1367 bcmi_esw_tsn_stat_portcnt_get( 1368 int unit, 1369 bcm_gport_t port, 1370 int sync_mode, 1371 bcm_tsn_stat_t stat, 1372 uint64 *val) 1373 { 1374 int rv = BCM_E_NONE; 1375 bcmi_tsn_stat_portcnt_control_t *pc; 1376 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1377 int stat_index, offset_index, total_entries; 1378 soc_mem_t counter_mem; 1379 1380 /* Input parameter check. */ 1381 if (NULL == val) { 1382 return BCM_E_PARAM; 1383 } 1384 1385 BCM_IF_ERROR_RETURN( 1386 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1387 1388 rv = bcmi_esw_tsn_stat_portcnt_map(unit, port, stat, 1389 &stat_index, &offset_index); 1390 if (BCM_FAILURE(rv)) { 1391 return rv; 1392 } 1393 1394 portcnt_member = &pc->stats[stat_index]; 1395 counter_mem = portcnt_member->mem; 1396 total_entries = soc_mem_index_count(unit, counter_mem); 1397 1398 if (offset_index >= total_entries) { 1399 LOG_ERROR(BSL_LS_BCM_TSN, 1400 (BSL_META_U(unit, 1401 "Wrong OFFSET_INDEX(Port). " 1402 "Must be < Total Entries %d \n"), 1403 total_entries)); 1404 return BCM_E_PARAM; 1405 } 1406 1407 TSN_STAT_PORTCNT_LOCK(pc); 1408 1409 /* Set to enable the portcnt callback for matrix of (stat, port) */ 1410 if (!TSN_STAT_PORTCNT_USED_GET(pc->portcnt_bk_info, stat_index)) { 1411 TSN_STAT_PORTCNT_USED_SET(pc->portcnt_bk_info, stat_index); 1412 } 1413 if (!TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 1414 stat_index, offset_index)) { 1415 TSN_STAT_PORTCNT_PORT_USED_SET(pc->portcnt_bk_info, 1416 stat_index, offset_index); 1417 /* Force sync_mode = 1 for the first time touch */ 1418 sync_mode = 1; 1419 } 1420 1421 /* sync the software counter with hardware counter */ 1422 if (sync_mode == 1) { 1423 bcmi_esw_tsn_stat_portcnt_collect(unit, counter_mem, offset_index); 1424 } 1425 1426 /* Packet Count HW Value */ 1427 LOG_DEBUG(BSL_LS_BCM_TSN, 1428 (BSL_META_U(unit, 1429 "Packet Count HW Value\t:TABLE:" 1430 "%s INDEX(port):%d : %x:%x \n"), 1431 SOC_MEM_UFNAME(unit, counter_mem), 1432 offset_index, 1433 COMPILER_64_HI(portcnt_member->port_counter_hw[offset_index]), 1434 COMPILER_64_LO(portcnt_member->port_counter_hw[offset_index]))); 1435 1436 /* Return Packet Count SW Value */ 1437 COMPILER_64_COPY(*val, 1438 portcnt_member->port_counter_sw[offset_index]); 1439 LOG_DEBUG(BSL_LS_BCM_TSN, 1440 (BSL_META_U(unit, 1441 "Packet Count SW Value\t:TABLE:" 1442 "%s INDEX(port):%d : %x:%x \n"), 1443 SOC_MEM_UFNAME(unit, counter_mem), 1444 offset_index, 1445 COMPILER_64_HI(*val), 1446 COMPILER_64_LO(*val))); 1447 1448 TSN_STAT_PORTCNT_UNLOCK(pc); 1449 1450 return BCM_E_NONE; 1451 } 1452 1453 /* 1454 * Function: 1455 * bcmi_esw_tsn_stat_portcnt_used_update 1456 * Description: 1457 * Helper function to update TSN stat portcnt usage bitmap. 1458 * Parameters: 1459 * unit - (IN) Unit number 1460 * port - (IN) port number 1461 * stat - (IN) TSN statistics type (see tsn.h) 1462 * op - (IN) TSN stat portcnt usage bitmap operation modes. 1463 * Returns: 1464 * BCM_E_XXX. 1465 * Notes: 1466 */ 1467 int 1468 bcmi_esw_tsn_stat_portcnt_used_update( 1469 int unit, 1470 bcm_gport_t port, 1471 bcm_tsn_stat_t stat, 1472 bcmi_tsn_stat_portcnt_used_operation_t op) 1473 { 1474 int rv = BCM_E_NONE; 1475 bcmi_tsn_stat_portcnt_control_t *pc; 1476 int stat_index, offset_index; 1477 bcm_port_t port_out = 0, p; 1478 bcm_pbmp_t pbmp; 1479 int empty; 1480 1481 BCM_PBMP_CLEAR(pbmp); 1482 if (port == -1) { 1483 BCM_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 1484 BCM_PBMP_ITER(pbmp, p) { 1485 port_out = p; 1486 break; 1487 } 1488 } else { 1489 rv = bcmi_esw_tsn_stat_gport_validate(unit, port, &port_out); 1490 if (BCM_FAILURE(rv)) { 1491 return rv; 1492 } 1493 BCM_PBMP_PORT_SET(pbmp, port_out); 1494 } 1495 1496 BCM_IF_ERROR_RETURN( 1497 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1498 1499 rv = bcmi_esw_tsn_stat_portcnt_map(unit, port_out, stat, 1500 &stat_index, &offset_index); 1501 if (BCM_FAILURE(rv)) { 1502 return rv; 1503 } 1504 1505 switch (op) { 1506 case BCM_TSN_STAT_PORTCNT_USED_SET: 1507 if (!TSN_STAT_PORTCNT_USED_GET(pc->portcnt_bk_info, stat_index)) { 1508 TSN_STAT_PORTCNT_USED_SET(pc->portcnt_bk_info, stat_index); 1509 } 1510 1511 BCM_PBMP_ITER(pbmp, p) { 1512 if (!TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 1513 stat_index, p)) { 1514 TSN_STAT_PORTCNT_PORT_USED_SET(pc->portcnt_bk_info, 1515 stat_index, p); 1516 } 1517 } 1518 1519 break; 1520 case BCM_TSN_STAT_PORTCNT_USED_CLEAR: 1521 if (TSN_STAT_PORTCNT_USED_GET(pc->portcnt_bk_info, stat_index)) { 1522 BCM_PBMP_ITER(pbmp, p) { 1523 if (TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 1524 stat_index, p)) { 1525 TSN_STAT_PORTCNT_PORT_USED_CLR(pc->portcnt_bk_info, 1526 stat_index, p); 1527 } 1528 } 1529 1530 empty = 1; 1531 PBMP_ALL_ITER(unit, p) { 1532 if (TSN_STAT_PORTCNT_PORT_USED_GET(pc->portcnt_bk_info, 1533 stat_index, p)) { 1534 empty = 0; /* Not empty */ 1535 break; 1536 } 1537 } 1538 1539 if (empty) { 1540 TSN_STAT_PORTCNT_USED_CLR(pc->portcnt_bk_info, stat_index); 1541 } 1542 } 1543 1544 break; 1545 default: 1546 return BCM_E_PARAM; 1547 } 1548 1549 return rv; 1550 } 1551 1552 /* 1553 * Function: 1554 * bcmi_esw_tsn_stat_portcnt_stat_sync 1555 * Description: 1556 * Helper function to sync HW/SW TSN stat portcnt per specified stat type. 1557 * Parameters: 1558 * unit - (IN) Unit number 1559 * stat - (IN) TSN statistics type (see tsn.h) 1560 * Returns: 1561 * BCM_E_XXX. 1562 * Notes: 1563 */ 1564 int 1565 bcmi_esw_tsn_stat_portcnt_stat_sync(int unit, bcm_tsn_stat_t stat) 1566 { 1567 bcmi_tsn_stat_portcnt_control_t *pc; 1568 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1569 int stat_index; 1570 soc_mem_t counter_mem; 1571 1572 BCM_IF_ERROR_RETURN( 1573 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1574 1575 BCM_IF_ERROR_RETURN( 1576 bcmi_esw_tsn_stat_portcnt_map(unit, -1, stat, 1577 &stat_index, NULL)); 1578 1579 portcnt_member = &(pc->stats[stat_index]); 1580 counter_mem = portcnt_member->mem; 1581 1582 /* Sync the software counter with hardware counter (per stat type) */ 1583 TSN_STAT_PORTCNT_LOCK(pc); 1584 bcmi_esw_tsn_stat_portcnt_collect(unit, counter_mem, -1); 1585 TSN_STAT_PORTCNT_UNLOCK(pc); 1586 1587 return BCM_E_NONE; 1588 } 1589 1590 /* 1591 * Function: 1592 * bcmi_esw_tsn_stat_portcnt_hw_sw_get 1593 * Description: 1594 * Helper function to get both HW and SW TSN stat portcnt 1595 * per specified stat type and port. 1596 * Parameters: 1597 * unit - (IN) Unit number 1598 * stat - (IN) TSN statistics type (see tsn.h) 1599 * port - (IN) port number 1600 * hw_value - (OUT) 64-bit HW counter value. 1601 * sw_value - (OUT) 64-bit SW counter value. 1602 * Returns: 1603 * BCM_E_XXX. 1604 * Notes: 1605 */ 1606 int 1607 bcmi_esw_tsn_stat_portcnt_hw_sw_get( 1608 int unit, 1609 bcm_tsn_stat_t stat, 1610 bcm_gport_t port, 1611 uint64 *hw_value, 1612 uint64 *sw_value) 1613 { 1614 bcmi_tsn_stat_portcnt_control_t *pc; 1615 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1616 int stat_index, offset_index, total_entries; 1617 soc_mem_t counter_mem; 1618 1619 /* Input parameter check. */ 1620 if ((NULL == hw_value) || (NULL == sw_value)) { 1621 return BCM_E_PARAM; 1622 } 1623 1624 BCM_IF_ERROR_RETURN( 1625 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1626 1627 BCM_IF_ERROR_RETURN( 1628 bcmi_esw_tsn_stat_portcnt_map(unit, port, stat, 1629 &stat_index, &offset_index)); 1630 1631 portcnt_member = &(pc->stats[stat_index]); 1632 counter_mem = portcnt_member->mem; 1633 total_entries = soc_mem_index_count(unit, counter_mem); 1634 1635 if (offset_index >= total_entries) { 1636 LOG_ERROR(BSL_LS_BCM_TSN, 1637 (BSL_META_U(unit, 1638 "Wrong OFFSET_INDEX(Port). " 1639 "Must be < Total Entries %d \n"), 1640 total_entries)); 1641 return BCM_E_PARAM; 1642 } 1643 1644 TSN_STAT_PORTCNT_LOCK(pc); 1645 1646 /* Return Packet Count HW Value */ 1647 COMPILER_64_COPY(*hw_value, 1648 portcnt_member->port_counter_hw[offset_index]); 1649 /* Return Packet Count SW Value */ 1650 COMPILER_64_COPY(*sw_value, 1651 portcnt_member->port_counter_sw[offset_index]); 1652 1653 LOG_DEBUG(BSL_LS_BCM_TSN, 1654 (BSL_META_U(unit, 1655 "Packet Count HW Value\t:TABLE:" 1656 "%s INDEX(port):%d : %x:%x \n"), 1657 SOC_MEM_UFNAME(unit, counter_mem), 1658 offset_index, 1659 COMPILER_64_HI(*hw_value), 1660 COMPILER_64_LO(*hw_value))); 1661 LOG_DEBUG(BSL_LS_BCM_TSN, 1662 (BSL_META_U(unit, 1663 "Packet Count SW Value\t:TABLE:" 1664 "%s INDEX(port):%d : %x:%x \n"), 1665 SOC_MEM_UFNAME(unit, counter_mem), 1666 offset_index, 1667 COMPILER_64_HI(*sw_value), 1668 COMPILER_64_LO(*sw_value))); 1669 1670 TSN_STAT_PORTCNT_UNLOCK(pc); 1671 1672 return BCM_E_NONE; 1673 } 1674 1675 /* 1676 * Function: 1677 * bcmi_esw_tsn_stat_portcnt_hw_set 1678 * Description: 1679 * Helper function to set HW only TSN stat portcnt 1680 * per specified stat type and port. 1681 * Parameters: 1682 * unit - (IN) Unit number 1683 * stat - (IN) TSN statistics type (see tsn.h) 1684 * port - (IN) port number 1685 * hw_value - (OUT) 64-bit HW counter value. 1686 * Returns: 1687 * BCM_E_XXX. 1688 * Notes: 1689 */ 1690 int 1691 bcmi_esw_tsn_stat_portcnt_hw_set( 1692 int unit, 1693 bcm_tsn_stat_t stat, 1694 bcm_gport_t port, 1695 uint64 hw_value) 1696 { 1697 bcmi_tsn_stat_portcnt_control_t *pc; 1698 bcmi_tsn_stat_portcnt_member_t *portcnt_member; 1699 int stat_index, offset_index, total_entries; 1700 uint32 entry[SOC_MAX_MEM_WORDS]; 1701 soc_mem_t counter_mem; 1702 soc_field_t counter_field; 1703 uint32 packet_count_hw[2]; 1704 uint64 old_packet_count; 1705 int width; 1706 1707 BCM_IF_ERROR_RETURN( 1708 tsn_stat_portcnt_control_instance_get(unit, &pc)); 1709 1710 BCM_IF_ERROR_RETURN( 1711 bcmi_esw_tsn_stat_portcnt_map(unit, port, stat, 1712 &stat_index, &offset_index)); 1713 1714 TSN_STAT_PORTCNT_LOCK(pc); 1715 portcnt_member = &(pc->stats[stat_index]); 1716 counter_mem = portcnt_member->mem; 1717 counter_field = portcnt_member->field; 1718 total_entries = soc_mem_index_count(unit, counter_mem); 1719 1720 if (offset_index >= total_entries) { 1721 LOG_ERROR(BSL_LS_BCM_TSN, 1722 (BSL_META_U(unit, 1723 "Wrong OFFSET_INDEX(Port). " 1724 "Must be < Total Entries %d \n"), 1725 total_entries)); 1726 TSN_STAT_PORTCNT_UNLOCK(pc); 1727 assert(0); 1728 } 1729 1730 /* Memory read from hardware */ 1731 sal_memset(entry, 0, sizeof(uint32) * SOC_MAX_MEM_WORDS); 1732 if (soc_mem_read(unit, counter_mem, MEM_BLOCK_ANY, 1733 offset_index, &entry) != BCM_E_NONE) { 1734 TSN_STAT_PORTCNT_UNLOCK(pc); 1735 return BCM_E_INTERNAL; 1736 } 1737 1738 width = soc_mem_field_length(unit, counter_mem, counter_field); 1739 1740 /* Get current HW value */ 1741 sal_memset(packet_count_hw, 0, sizeof(uint32) * 2); 1742 soc_mem_field_get(unit, counter_mem, (uint32 *)entry, 1743 counter_field, packet_count_hw); 1744 if (width > 32) { 1745 /* 64-bit field */ 1746 COMPILER_64_SET(old_packet_count, 1747 packet_count_hw[1], 1748 packet_count_hw[0]); 1749 } else { 1750 /* 32-bit field */ 1751 COMPILER_64_SET(old_packet_count, 1752 0, 1753 packet_count_hw[0]); 1754 } 1755 1756 /* Compare old and new hardware counter */ 1757 if (!COMPILER_64_EQ(old_packet_count, hw_value)) { 1758 LOG_VERBOSE(BSL_LS_BCM_TSN, 1759 (BSL_META_U(unit, 1760 "Port %d: TSN stat(%d)==>" 1761 "Old HW Packet Count Value %x:%x\t" 1762 "New HW Packet Count Value %x:%x\n"), 1763 offset_index, stat_index, 1764 COMPILER_64_HI(old_packet_count), 1765 COMPILER_64_LO(old_packet_count), 1766 COMPILER_64_HI(hw_value), 1767 COMPILER_64_LO(hw_value))); 1768 1769 if (width > 32) { 1770 /* 64-bit field */ 1771 packet_count_hw[0] = COMPILER_64_LO(hw_value); 1772 packet_count_hw[1] = COMPILER_64_HI(hw_value); 1773 } else { 1774 /* 32-bit field */ 1775 packet_count_hw[0] = COMPILER_64_LO(hw_value); 1776 packet_count_hw[1] = 0; 1777 } 1778 1779 soc_mem_field_set(unit, counter_mem, (uint32 *)entry, 1780 counter_field, packet_count_hw); 1781 1782 /* Memory write into hardware */ 1783 if (soc_mem_write(unit, counter_mem, MEM_BLOCK_ALL, 1784 offset_index, &entry) != BCM_E_NONE) { 1785 TSN_STAT_PORTCNT_UNLOCK(pc); 1786 return BCM_E_INTERNAL; 1787 } 1788 } 1789 1790 /* Update Soft Copy for current HW counter */ 1791 COMPILER_64_COPY(portcnt_member->port_counter_hw[offset_index], 1792 hw_value); 1793 1794 LOG_DEBUG(BSL_LS_BCM_TSN, 1795 (BSL_META_U(unit, 1796 "Packet Count HW Value\t:TABLE:" 1797 "%s INDEX(port):%d : %x:%x \n"), 1798 SOC_MEM_UFNAME(unit, counter_mem), 1799 offset_index, 1800 COMPILER_64_HI(portcnt_member->port_counter_hw[offset_index]), 1801 COMPILER_64_LO(portcnt_member->port_counter_hw[offset_index]))); 1802 1803 TSN_STAT_PORTCNT_UNLOCK(pc); 1804 1805 return BCM_E_NONE; 1806 } 1807 1808 /* 1809 * Function: 1810 * bcmi_esw_tsn_stat_portcnt_update 1811 * Description: 1812 * For SER module to update the SW & HW counter 1813 * with given memory and memory index 1814 * Parameters: 1815 * unit - (IN) Unit number 1816 * mem - (IN) TSN stat counter memory 1817 * mem_idx - (IN) memory index 1818 * new_count - (IN) new counter value 1819 * Returns: 1820 * BCM_E_XXX 1821 */ 1822 int 1823 bcmi_esw_tsn_stat_portcnt_update( 1824 int unit, 1825 soc_mem_t mem, 1826 int mem_idx, 1827 uint64 new_count) 1828 { 1829 bcmi_tsn_stat_control_t *tc; 1830 const bcmi_esw_tsn_stat_dev_info_t *tsn_stat_dev_info; 1831 const tsn_stat_portcnt_dev_info_t *portcnt_dev_info; 1832 const tsn_stat_portcnt_table_info_t *portcnt_table; 1833 int total_entries, i; 1834 bcm_gport_t port; 1835 bcm_tsn_stat_t stat_itr = 0; 1836 1837 /* Input parameter check. */ 1838 if (!SOC_MEM_IS_VALID(unit, mem)) { 1839 return BCM_E_PARAM; 1840 } 1841 1842 total_entries = soc_mem_index_count(unit, mem); 1843 if (mem_idx >= total_entries) { 1844 LOG_ERROR(BSL_LS_BCM_TSN, 1845 (BSL_META_U(unit, 1846 "Wrong OFFSET_INDEX(Port). " 1847 "Must be < Total Entries %d \n"), 1848 total_entries)); 1849 assert(0); 1850 } 1851 1852 /* Get TSN stat control */ 1853 BCM_IF_ERROR_RETURN( 1854 tsn_stat_control_instance_get(unit, &tc)); 1855 1856 /* Get chip specific info for TSN stat */ 1857 tsn_stat_dev_info = tc->tsn_stat_dev_info; 1858 if (NULL == tsn_stat_dev_info) { 1859 return BCM_E_UNAVAIL; 1860 } 1861 portcnt_dev_info = tsn_stat_dev_info->tsn_stat_portcnt_dev_info; 1862 if (NULL == portcnt_dev_info) { 1863 return BCM_E_UNAVAIL; 1864 } 1865 1866 /* Get stat_index based on the giving TSN statistic type = stat */ 1867 portcnt_table = portcnt_dev_info->portcnt_table_info; 1868 if (NULL == portcnt_table) { 1869 return BCM_E_UNAVAIL; 1870 } 1871 1872 for (i = 0; i < portcnt_dev_info->num_stats; i++) { 1873 stat_itr = portcnt_table[i].portcnt_stat; 1874 1875 assert((stat_itr >= 0) && (stat_itr < bcmTsnStatCount)); 1876 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 1877 continue; 1878 } 1879 if (mem == portcnt_table[i].portcnt_mem) { 1880 break; 1881 } 1882 } 1883 1884 if (i == portcnt_dev_info->num_stats) { 1885 return BCM_E_NOT_FOUND; 1886 } 1887 1888 port = mem_idx; 1889 BCM_IF_ERROR_RETURN( 1890 bcmi_esw_tsn_stat_portcnt_set(unit, port, stat_itr, new_count)); 1891 1892 return BCM_E_NONE; 1893 } 1894 1895 /* 1896 * Function: 1897 * bcmi_esw_tsn_stat_flowcnt_group_create 1898 * Description: 1899 * Create a TSN stat group by picking stat types (in an array) to be 1900 * included for counting 1901 * Parameters: 1902 * unit - (IN) unit number 1903 * group_type - (IN) TSN statistic group type 1904 * count - (IN) the number of elements in stat_arr 1905 * stat_arr - (IN) array for tsn stat types 1906 * stat_id - (OUT) tsn statistic group id 1907 * 1908 * Return Value: 1909 * BCM_E_XXX 1910 * Notes: 1911 */ 1912 int 1913 bcmi_esw_tsn_stat_flowcnt_group_create( 1914 int unit, 1915 bcm_tsn_stat_group_type_t group_type, 1916 int count, 1917 bcm_tsn_stat_t *stat_arr, 1918 bcm_tsn_stat_group_t *stat_id) 1919 { 1920 int i, rv = BCM_E_NONE; 1921 uint32 enable_values; 1922 uint32 group_id; 1923 bcmi_tsn_stat_flowcnt_control_t *fc; 1924 1925 BCM_IF_ERROR_RETURN( 1926 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 1927 1928 /* check feature support or not */ 1929 for (i = 0; i < count; i++) { 1930 bcm_tsn_stat_t stat_itr = stat_arr[i]; 1931 1932 if (stat_itr < 0 || stat_itr >= bcmTsnStatCount) { 1933 return BCM_E_PARAM; 1934 } 1935 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 1936 return BCM_E_UNAVAIL; 1937 } 1938 } 1939 1940 BCM_IF_ERROR_RETURN( 1941 TSN_STAT_FLOWCNT_FUNC(group_enable_value_encode, 1942 (unit, group_type, stat_arr, count, &enable_values))); 1943 1944 TSN_STAT_FLOWCNT_LOCK(fc); 1945 rv = TSN_STAT_FLOWCNT_FUNC(group_enable_value_insert, 1946 (unit, group_type, enable_values, &group_id)); 1947 TSN_STAT_FLOWCNT_UNLOCK(fc); 1948 1949 BCM_IF_ERROR_RETURN(rv); 1950 BCM_IF_ERROR_RETURN( 1951 TSN_STAT_FLOWCNT_FUNC(group_id_encode, 1952 (unit, group_type, group_id, stat_id))); 1953 return BCM_E_NONE; 1954 } 1955 1956 /* 1957 * Function: 1958 * bcmi_esw_tsn_stat_flowcnt_group_set 1959 * Description: 1960 * Set configuration of the TSN stat group 1961 * Parameters: 1962 * unit - (IN) unit number 1963 * stat_id - (IN) TSN statistic group id 1964 * count - (IN) the number of elements in stat_arr 1965 * stat_arr - (IN) array for TSN stat types 1966 * 1967 * Return Value: 1968 * BCM_E_XXX 1969 * Notes: 1970 */ 1971 int 1972 bcmi_esw_tsn_stat_flowcnt_group_set( 1973 int unit, 1974 bcm_tsn_stat_group_t stat_id, 1975 int count, 1976 bcm_tsn_stat_t *stat_arr) 1977 { 1978 int i, rv = BCM_E_NONE; 1979 bcm_tsn_stat_group_type_t group_type; 1980 uint32 group_id; 1981 int group_refcnt; 1982 uint32 new_enable_values; 1983 bcmi_tsn_stat_flowcnt_control_t *fc; 1984 1985 BCM_IF_ERROR_RETURN( 1986 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 1987 1988 /* check feature support or not */ 1989 for (i = 0; i < count; i++) { 1990 bcm_tsn_stat_t stat_itr = stat_arr[i]; 1991 1992 if (stat_itr < 0 || stat_itr >= bcmTsnStatCount) { 1993 return BCM_E_PARAM; 1994 } 1995 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 1996 return BCM_E_UNAVAIL; 1997 } 1998 } 1999 2000 /* decode */ 2001 BCM_IF_ERROR_RETURN( 2002 TSN_STAT_FLOWCNT_FUNC(group_id_decode, 2003 (unit, stat_id, &group_type, &group_id))); 2004 BCM_IF_ERROR_RETURN( 2005 TSN_STAT_FLOWCNT_FUNC(group_enable_value_encode, 2006 (unit, group_type, stat_arr, count, &new_enable_values))); 2007 2008 TSN_STAT_FLOWCNT_LOCK(fc); 2009 /* check group id has been just created and 2010 * not attached on any flow yet 2011 */ 2012 rv = TSN_STAT_FLOWCNT_FUNC(group_refcnt_get, 2013 (unit, group_type, group_id, &group_refcnt)); 2014 if (BCM_SUCCESS(rv)) { 2015 if (0 == group_refcnt) { 2016 rv = BCM_E_PARAM; 2017 } else if (1 != group_refcnt) { 2018 rv = BCM_E_BUSY; 2019 } 2020 } 2021 2022 /* check the new setting has already existed or not */ 2023 if (BCM_SUCCESS(rv)) { 2024 rv = TSN_STAT_FLOWCNT_FUNC(group_enable_value_exist_check, 2025 (unit, group_type, new_enable_values)); 2026 } 2027 2028 /* write new value */ 2029 if (BCM_SUCCESS(rv)) { 2030 rv = TSN_STAT_FLOWCNT_FUNC(group_enable_value_set, 2031 (unit, group_type, group_id, new_enable_values)); 2032 } 2033 TSN_STAT_FLOWCNT_UNLOCK(fc); 2034 2035 return rv; 2036 } 2037 2038 /* 2039 * Function: 2040 * bcmi_esw_tsn_stat_flowcnt_group_get 2041 * Description: 2042 * Get configuration of the TSN stat group 2043 * Parameters: 2044 * unit - (IN) unit number 2045 * stat_id - (IN) TSN statistic group id 2046 * group_type - (IN) TSN statistic group type 2047 * max - (OUT) the size of stat_arr 2048 * stat_arr - (OUT) array for returned TSN stat types 2049 * count - (OUT) actual number of TSN stat types 2050 * 2051 * Return Value: 2052 * BCM_E_XXX 2053 * Notes: 2054 */ 2055 int 2056 bcmi_esw_tsn_stat_flowcnt_group_get( 2057 int unit, 2058 bcm_tsn_stat_group_t stat_id, 2059 bcm_tsn_stat_group_type_t *ret_group_type, 2060 int max, 2061 bcm_tsn_stat_t *stat_arr, 2062 int *count) 2063 { 2064 int rv = BCM_E_NONE; 2065 bcm_tsn_stat_group_type_t group_type; 2066 uint32 group_id; 2067 int group_refcnt; 2068 uint32 enable_values; 2069 bcmi_tsn_stat_flowcnt_control_t *fc; 2070 2071 BCM_IF_ERROR_RETURN( 2072 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2073 2074 if (NULL == ret_group_type) { 2075 return BCM_E_PARAM; 2076 } 2077 2078 /* decode stat_id to group_type, group_id */ 2079 BCM_IF_ERROR_RETURN( 2080 TSN_STAT_FLOWCNT_FUNC(group_id_decode, 2081 (unit, stat_id, &group_type, &group_id))); 2082 2083 TSN_STAT_FLOWCNT_LOCK(fc); 2084 /* and check group id has been created or not */ 2085 rv = TSN_STAT_FLOWCNT_FUNC(group_refcnt_get, 2086 (unit, group_type, group_id, &group_refcnt)); 2087 if (BCM_SUCCESS(rv)) { 2088 if (0 == group_refcnt) { 2089 rv = BCM_E_PARAM; 2090 } 2091 } 2092 /* get value */ 2093 if (BCM_SUCCESS(rv)) { 2094 rv = TSN_STAT_FLOWCNT_FUNC(group_enable_value_get, 2095 (unit, group_type, group_id, &enable_values)); 2096 } 2097 TSN_STAT_FLOWCNT_UNLOCK(fc); 2098 2099 BCM_IF_ERROR_RETURN(rv); 2100 BCM_IF_ERROR_RETURN( 2101 TSN_STAT_FLOWCNT_FUNC(group_enable_value_decode, 2102 (unit, group_type, enable_values, stat_arr, max, count))); 2103 *ret_group_type = group_type; 2104 2105 return BCM_E_NONE; 2106 } 2107 2108 /* 2109 * Function: 2110 * bcmi_esw_tsn_stat_flowcnt_group_destroy 2111 * Description: 2112 * Destroy a TSN stat group 2113 * Parameters: 2114 * unit - (IN) unit number 2115 * stat_id - (IN) TSN statistic group id 2116 * 2117 * Return Value: 2118 * BCM_E_XXX 2119 * Notes: 2120 */ 2121 int 2122 bcmi_esw_tsn_stat_flowcnt_group_destroy( 2123 int unit, 2124 bcm_tsn_stat_group_t stat_id) 2125 { 2126 int rv = BCM_E_NONE; 2127 bcm_tsn_stat_group_type_t group_type; 2128 uint32 group_id; 2129 int group_refcnt; 2130 bcmi_tsn_stat_flowcnt_control_t *fc; 2131 2132 BCM_IF_ERROR_RETURN( 2133 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2134 2135 2136 /* decode */ 2137 BCM_IF_ERROR_RETURN( 2138 TSN_STAT_FLOWCNT_FUNC(group_id_decode, 2139 (unit, stat_id, &group_type, &group_id))); 2140 2141 TSN_STAT_FLOWCNT_LOCK(fc); 2142 /* check group id has been created and not attached on any flow */ 2143 rv = TSN_STAT_FLOWCNT_FUNC(group_refcnt_get, 2144 (unit, group_type, group_id, &group_refcnt)); 2145 if (BCM_SUCCESS(rv)) { 2146 if (0 == group_refcnt) { 2147 rv = BCM_E_PARAM; 2148 } else if (1 != group_refcnt) { 2149 rv = BCM_E_BUSY; 2150 } 2151 } 2152 if (BCM_SUCCESS(rv)) { 2153 rv = TSN_STAT_FLOWCNT_FUNC(group_enable_value_delete, 2154 (unit, group_type, group_id)); 2155 } 2156 TSN_STAT_FLOWCNT_UNLOCK(fc); 2157 2158 return rv; 2159 } 2160 2161 /* 2162 * Function: 2163 * bcmi_esw_tsn_stat_flowcnt_group_traverse 2164 * Description: 2165 * Traverse TSN stat groups 2166 * Parameters: 2167 * unit - (IN) unit number 2168 * cb - (IN) User provided call back function 2169 * user_data - (IN) User provided data 2170 * 2171 * Return Value: 2172 * BCM_E_XXX 2173 * Notes: 2174 */ 2175 int 2176 bcmi_esw_tsn_stat_flowcnt_group_traverse( 2177 int unit, 2178 bcm_tsn_stat_group_traverse_cb cb, 2179 void *user_data) 2180 { 2181 int rv = BCM_E_NONE; 2182 bcmi_tsn_stat_flowcnt_control_t *fc; 2183 2184 BCM_IF_ERROR_RETURN( 2185 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2186 2187 TSN_STAT_FLOWCNT_LOCK(fc); 2188 rv = TSN_STAT_FLOWCNT_FUNC(group_traverse, (unit, cb, user_data)); 2189 TSN_STAT_FLOWCNT_UNLOCK(fc); 2190 2191 return rv; 2192 } 2193 2194 /* 2195 * Function: 2196 * bcmi_esw_tsn_stat_flowcnt_flow_get 2197 * Description: 2198 * Get the stat group for this flow with specified group type 2199 * Parameters: 2200 * unit - (IN) unit number 2201 * flow - (IN) SR flow 2202 * group_type - (IN) TSN statistic group type 2203 * stat_group - (OUT)TSN statistic group 2204 * 2205 * Return Value: 2206 * BCM_E_XXX 2207 * Notes: 2208 */ 2209 int 2210 bcmi_esw_tsn_stat_flowcnt_flow_get( 2211 int unit, 2212 bcm_tsn_sr_flow_t flow_id, 2213 bcm_tsn_stat_group_type_t group_type, 2214 bcm_tsn_stat_group_t *stat_id) 2215 { 2216 uint32 group_id; 2217 int rv = BCM_E_NONE; 2218 bcmi_tsn_stat_flowcnt_control_t *fc; 2219 2220 BCM_IF_ERROR_RETURN( 2221 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2222 2223 if (NULL == stat_id) { 2224 return BCM_E_PARAM; 2225 } 2226 2227 TSN_STAT_FLOWCNT_LOCK(fc); 2228 rv = TSN_STAT_FLOWCNT_FUNC(flow_get, 2229 (unit, flow_id, group_type, &group_id)); 2230 TSN_STAT_FLOWCNT_UNLOCK(fc); 2231 BCM_IF_ERROR_RETURN(rv); 2232 2233 if (BCMI_TSN_FLOWCNT_GROUP_ID_RESERVED == group_id) { 2234 *stat_id = BCM_TSN_STAT_GROUP_INVALID; 2235 } else { 2236 BCM_IF_ERROR_RETURN( 2237 TSN_STAT_FLOWCNT_FUNC(group_id_encode, 2238 (unit, group_type, group_id, stat_id))); 2239 } 2240 return BCM_E_NONE; 2241 } 2242 2243 /* 2244 * Function: 2245 * bcmi_esw_tsn_stat_flowcnt_flow_set 2246 * Description: 2247 * Attach ingress/egress stat group to this flow and enable counting for 2248 * the stat group. To disable counting for a specific group type, set 2249 * BCM_TSN_STAT_GROUP_INVALID as stat_group 2250 * Parameters: 2251 * unit - (IN) unit number 2252 * flow - (IN) SR flow 2253 * group_type - (IN) TSN statistic group type 2254 * stat_group - (IN) TSN statistic group 2255 * 2256 * Return Value: 2257 * BCM_E_XXX 2258 * Notes: 2259 */ 2260 int 2261 bcmi_esw_tsn_stat_flowcnt_flow_set( 2262 int unit, 2263 bcm_tsn_sr_flow_t flow_id, 2264 bcm_tsn_stat_group_type_t group_type, 2265 bcm_tsn_stat_group_t new_stat_id) 2266 { 2267 int rv = BCM_E_NONE; 2268 uint32 new_group_id; 2269 int new_group_refcnt; 2270 bcmi_tsn_stat_flowcnt_control_t *fc; 2271 2272 BCM_IF_ERROR_RETURN( 2273 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2274 2275 /* parameter check if the user want to switch to the new group id */ 2276 if (BCM_TSN_STAT_GROUP_INVALID != new_stat_id) { 2277 bcm_tsn_stat_group_type_t new_group_type; 2278 2279 /* new group id should have the right group type */ 2280 BCM_IF_ERROR_RETURN( 2281 TSN_STAT_FLOWCNT_FUNC(group_id_decode, 2282 (unit, new_stat_id, &new_group_type, &new_group_id))); 2283 2284 if (new_group_type != group_type) { 2285 BCM_IF_ERROR_RETURN(BCM_E_PARAM); 2286 } 2287 } else { 2288 new_group_id = BCMI_TSN_FLOWCNT_GROUP_ID_RESERVED; 2289 } 2290 2291 TSN_STAT_FLOWCNT_LOCK(fc); 2292 /* check new group id has been created or not */ 2293 if (BCM_TSN_STAT_GROUP_INVALID != new_stat_id) { 2294 rv = TSN_STAT_FLOWCNT_FUNC(group_refcnt_get, 2295 (unit, group_type, new_group_id, &new_group_refcnt)); 2296 if (BCM_SUCCESS(rv)) { 2297 if (0 == new_group_refcnt) { 2298 rv = BCM_E_PARAM; 2299 } 2300 } 2301 } 2302 if (BCM_SUCCESS(rv)) { 2303 rv = TSN_STAT_FLOWCNT_FUNC(flow_set, 2304 (unit, flow_id, group_type, new_group_id)); 2305 } 2306 TSN_STAT_FLOWCNT_UNLOCK(fc); 2307 2308 return rv; 2309 } 2310 2311 /* 2312 * Function: 2313 * bcmi_esw_tsn_stat_flowcnt_set 2314 * Description: 2315 * Helper function for flow counter set 2316 * Parameters: 2317 * unit - (IN) unit number 2318 * flow_id - (IN) SR flow 2319 * arr_cnt - (IN) size of stat_arr and value_arr 2320 * stat_type_arr - (IN) TSN stat types 2321 * stat_value_arr - (IN) TSN stat values 2322 * 2323 * Return Value: 2324 * BCM_E_XXX 2325 * Notes: 2326 */ 2327 int 2328 bcmi_esw_tsn_stat_flowcnt_set( 2329 int unit, 2330 bcm_tsn_sr_flow_t flow_id, 2331 uint32 arr_cnt, 2332 bcm_tsn_stat_t *stat_type_arr, 2333 uint64 *stat_value_arr) 2334 { 2335 int i, rv = BCM_E_NONE; 2336 bcmi_tsn_stat_flowcnt_control_t *fc; 2337 2338 BCM_IF_ERROR_RETURN( 2339 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2340 2341 /* check feature support or not */ 2342 for (i = 0; i < arr_cnt; i++) { 2343 bcm_tsn_stat_t stat_itr = stat_type_arr[i]; 2344 2345 if (stat_itr < 0 || stat_itr >= bcmTsnStatCount) { 2346 return BCM_E_PARAM; 2347 } 2348 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 2349 return BCM_E_UNAVAIL; 2350 } 2351 } 2352 2353 TSN_STAT_FLOWCNT_LOCK(fc); 2354 /* for write, write both sw and hw value */ 2355 rv = TSN_STAT_FLOWCNT_FUNC(counter_access, 2356 (unit, flow_id, bcmiTsnStatCounterActionWrite, 2357 arr_cnt, stat_type_arr, 2358 stat_value_arr, stat_value_arr)); 2359 TSN_STAT_FLOWCNT_UNLOCK(fc); 2360 return rv; 2361 } 2362 2363 /* 2364 * Function: 2365 * bcmi_esw_tsn_stat_flowcnt_get 2366 * Description: 2367 * Helper function for flow counter get 2368 * Parameters: 2369 * unit - (IN) unit number 2370 * flow_id - (IN) SR flow 2371 * sync_mode - (IN) if 1 read hw counter else sw accumulated counter 2372 * arr_cnt - (IN) size of stat_arr and value_arr 2373 * stat_type_arr - (IN) TSN stat types 2374 * stat_value_arr - (IN) TSN stat values 2375 * 2376 * Return Value: 2377 * BCM_E_XXX 2378 * Notes: 2379 */ 2380 int 2381 bcmi_esw_tsn_stat_flowcnt_get( 2382 int unit, 2383 bcm_tsn_sr_flow_t flow_id, 2384 int sync_mode, 2385 uint32 arr_cnt, 2386 bcm_tsn_stat_t *stat_type_arr, 2387 uint64 *stat_value_arr) 2388 { 2389 int i, rv = BCM_E_NONE; 2390 bcmi_tsn_stat_flowcnt_control_t *fc; 2391 2392 BCM_IF_ERROR_RETURN( 2393 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2394 2395 /* check feature support or not */ 2396 for (i = 0; i < arr_cnt; i++) { 2397 bcm_tsn_stat_t stat_itr = stat_type_arr[i]; 2398 2399 if (stat_itr < 0 || stat_itr >= bcmTsnStatCount) { 2400 return BCM_E_PARAM; 2401 } 2402 if (!soc_feature(unit, tsn_stat_type_feature[stat_itr])) { 2403 return BCM_E_UNAVAIL; 2404 } 2405 } 2406 2407 TSN_STAT_FLOWCNT_LOCK(fc); 2408 /* for read, just need to read value from sw database 2409 * (maybe need to sync at first) 2410 */ 2411 rv = TSN_STAT_FLOWCNT_FUNC(counter_access, 2412 (unit, flow_id, 2413 (sync_mode ? 2414 bcmiTsnStatCounterActionReadSync : 2415 bcmiTsnStatCounterActionRead), 2416 arr_cnt, stat_type_arr, stat_value_arr, NULL)); 2417 TSN_STAT_FLOWCNT_UNLOCK(fc); 2418 return rv; 2419 } 2420 2421 /* 2422 * Function: 2423 * bcmi_esw_tsn_stat_flowcnt_fbmp_get 2424 * Description: 2425 * given a stat type, return all hw flow_id(s) been attached on it 2426 * Parameters: 2427 * unit - (IN) unit number 2428 * stat - (IN) TSN stat type 2429 * fbmp - (OUT)bitmap for return hw flow_id(s) 2430 * fbmp_size - (IN) size of fbmp 2431 * 2432 * Return Value: 2433 * BCM_E_XXX 2434 * Notes: 2435 */ 2436 int 2437 bcmi_esw_tsn_stat_flowcnt_fbmp_get( 2438 int unit, 2439 bcm_tsn_stat_t stat, 2440 SHR_BITDCL *fbmp, 2441 uint32 fbmp_size) 2442 { 2443 int rv = BCM_E_NONE; 2444 bcmi_tsn_stat_flowcnt_control_t *fc; 2445 2446 BCM_IF_ERROR_RETURN( 2447 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2448 2449 if (stat < 0 || stat >= bcmTsnStatCount) { 2450 return BCM_E_PARAM; 2451 } 2452 2453 if (!soc_feature(unit, tsn_stat_type_feature[stat])) { 2454 return BCM_E_UNAVAIL; 2455 } 2456 2457 TSN_STAT_FLOWCNT_LOCK(fc); 2458 rv = TSN_STAT_FLOWCNT_FUNC(flow_get_fbmp, (unit, stat, fbmp, fbmp_size)); 2459 TSN_STAT_FLOWCNT_UNLOCK(fc); 2460 2461 return rv; 2462 } 2463 2464 2465 /* 2466 * Function: 2467 * bcmi_esw_tsn_stat_flowcnt_hw_sw_get 2468 * Description: 2469 * Helper function for flow counter get both sw/hw value 2470 * Parameters: 2471 * unit - (IN) unit number 2472 * stat - (IN) TSN stat type 2473 * flow_id - (IN) SR flow 2474 * hw_value - (OUT) hw value 2475 * sw_value - (OUT) sw value 2476 * 2477 * Return Value: 2478 * BCM_E_XXX 2479 * Notes: 2480 */ 2481 int 2482 bcmi_esw_tsn_stat_flowcnt_hw_sw_get( 2483 int unit, 2484 bcm_tsn_stat_t stat, 2485 bcm_tsn_sr_flow_t flow_id, 2486 uint64 *hw_value, 2487 uint64 *sw_value) 2488 { 2489 int rv = BCM_E_NONE; 2490 bcmi_tsn_stat_flowcnt_control_t *fc; 2491 2492 BCM_IF_ERROR_RETURN( 2493 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2494 2495 if (stat < 0 || stat >= bcmTsnStatCount) { 2496 return BCM_E_PARAM; 2497 } 2498 if (!soc_feature(unit, tsn_stat_type_feature[stat])) { 2499 return BCM_E_UNAVAIL; 2500 } 2501 2502 TSN_STAT_FLOWCNT_LOCK(fc); 2503 rv = TSN_STAT_FLOWCNT_FUNC(counter_access, 2504 (unit, flow_id, bcmiTsnStatCounterActionReadSync, 2505 1, &stat, sw_value, hw_value)); 2506 TSN_STAT_FLOWCNT_UNLOCK(fc); 2507 return rv; 2508 } 2509 2510 /* 2511 * Function: 2512 * bcmi_esw_tsn_stat_flowcnt_hw_set 2513 * Description: 2514 * Helper function for flow counter set hw value 2515 * Parameters: 2516 * unit - (IN) unit number 2517 * stat - (IN) TSN stat type 2518 * flow_id - (IN) SR flow 2519 * hw_value - (IN) hw value 2520 * 2521 * Return Value: 2522 * BCM_E_XXX 2523 * Notes: 2524 */ 2525 int 2526 bcmi_esw_tsn_stat_flowcnt_hw_set( 2527 int unit, 2528 bcm_tsn_stat_t stat, 2529 bcm_tsn_sr_flow_t flow_id, 2530 uint64 hw_value) 2531 { 2532 int rv = BCM_E_NONE; 2533 bcmi_tsn_stat_flowcnt_control_t *fc; 2534 2535 BCM_IF_ERROR_RETURN( 2536 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2537 2538 if (stat < 0 || stat >= bcmTsnStatCount) { 2539 return BCM_E_PARAM; 2540 } 2541 if (!soc_feature(unit, tsn_stat_type_feature[stat])) { 2542 return BCM_E_UNAVAIL; 2543 } 2544 2545 TSN_STAT_FLOWCNT_LOCK(fc); 2546 rv = TSN_STAT_FLOWCNT_FUNC(counter_access, 2547 (unit, flow_id, bcmiTsnStatCounterActionWrite, 2548 1, &stat, NULL, &hw_value)); 2549 TSN_STAT_FLOWCNT_UNLOCK(fc); 2550 return rv; 2551 } 2552 2553 /* 2554 * Function: 2555 * bcmi_esw_tsn_stat_flowcnt_stat_sync 2556 * Description: 2557 * Helper function to sync HW/SW TSN stat flowcnt per specified stat type. 2558 * Parameters: 2559 * unit - (IN) Unit number 2560 * stat - (IN) TSN statistics type (see tsn.h) 2561 * Returns: 2562 * BCM_E_XXX. 2563 * Notes: 2564 */ 2565 int bcmi_esw_tsn_stat_flowcnt_stat_sync(int unit, bcm_tsn_stat_t stat) 2566 { 2567 int rv = BCM_E_NONE; 2568 bcmi_tsn_stat_flowcnt_control_t *fc; 2569 2570 BCM_IF_ERROR_RETURN( 2571 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2572 2573 if (stat < 0 || stat >= bcmTsnStatCount) { 2574 return BCM_E_PARAM; 2575 } 2576 2577 if (!soc_feature(unit, tsn_stat_type_feature[stat])) { 2578 return BCM_E_UNAVAIL; 2579 } 2580 2581 TSN_STAT_FLOWCNT_LOCK(fc); 2582 rv = TSN_STAT_FLOWCNT_FUNC(counter_sync_stat, (unit, stat)); 2583 TSN_STAT_FLOWCNT_UNLOCK(fc); 2584 2585 return rv; 2586 } 2587 2588 /* 2589 * Function: 2590 * bcmi_esw_tsn_stat_flowcnt_cleanup 2591 * Description: 2592 * Clean and free all allocated TSN flow counter resources 2593 * Parameters: 2594 * unit - (IN) Unit number 2595 * Returns: 2596 * BCM_E_XXX 2597 */ 2598 STATIC int 2599 bcmi_esw_tsn_stat_flowcnt_cleanup(int unit) 2600 { 2601 bcmi_tsn_stat_flowcnt_control_t *fc; 2602 2603 LOG_DEBUG(BSL_LS_BCM_TSN, 2604 (BSL_META_U(unit, 2605 "bcmi_esw_tsn_stat_flowcnt_cleanup\n"))); 2606 2607 fc = tsn_stat_control[unit]->flowcnt_control; 2608 if (NULL != fc->flowcnt_mutex) { 2609 sal_mutex_destroy(fc->flowcnt_mutex); 2610 fc->flowcnt_mutex = NULL; 2611 } 2612 2613 return BCM_E_NONE; 2614 } 2615 2616 2617 /* 2618 * Function: 2619 * bcmi_esw_tsn_stat_flowcnt_init 2620 * Description: 2621 * Initialize and allocate all required resources for TSN flow counters 2622 * Parameters: 2623 * unit - (IN) Unit number 2624 * Returns: 2625 * BCM_E_XXX 2626 */ 2627 STATIC int 2628 bcmi_esw_tsn_stat_flowcnt_init(int unit) 2629 { 2630 bcmi_tsn_stat_control_t *tc; 2631 bcmi_tsn_stat_flowcnt_control_t *fc; 2632 2633 /* Get TSN stat control */ 2634 BCM_IF_ERROR_RETURN( 2635 tsn_stat_control_instance_get(unit, &tc)); 2636 2637 /* Set up the unit flowcnt control structure. */ 2638 fc = tc->flowcnt_control; 2639 if (NULL == fc) { 2640 return BCM_E_INIT; 2641 } 2642 sal_memset(fc, 0, sizeof(bcmi_tsn_stat_flowcnt_control_t)); 2643 2644 /* Create flowcnt protection mutex. */ 2645 fc->flowcnt_mutex = sal_mutex_create("tsn flowcnt control mutex"); 2646 if (NULL == fc->flowcnt_mutex) { 2647 return BCM_E_RESOURCE; 2648 } 2649 2650 return BCM_E_NONE; 2651 } 2652 2653 /* 2654 * Function: 2655 * bcmi_esw_tsn_stat_flowcnt_update 2656 * Description: 2657 * For SER module to update the SW & HW counter 2658 * with given memory and memory index 2659 * Parameters: 2660 * unit - (IN) Unit number 2661 * mem - (IN) TSN stat counter memory 2662 * mem_idx - (IN) memory index 2663 * new_count - (IN) new counter value 2664 * Returns: 2665 * BCM_E_XXX 2666 */ 2667 int 2668 bcmi_esw_tsn_stat_flowcnt_update( 2669 int unit, 2670 soc_mem_t mem, 2671 int mem_idx, 2672 uint64 new_count) 2673 { 2674 bcm_error_t rv = BCM_E_NOT_FOUND; 2675 bcmi_tsn_stat_flowcnt_control_t *fc; 2676 int total_entries; 2677 2678 /* Input parameter check. */ 2679 if (!SOC_MEM_IS_VALID(unit, mem)) { 2680 return BCM_E_PARAM; 2681 } 2682 2683 total_entries = soc_mem_index_count(unit, mem); 2684 if (mem_idx >= total_entries) { 2685 LOG_ERROR(BSL_LS_BCM_TSN, 2686 (BSL_META_U(unit, 2687 "Wrong OFFSET_INDEX(Flow). " 2688 "Must be < Total Entries %d \n"), 2689 total_entries)); 2690 assert(0); 2691 } 2692 BCM_IF_ERROR_RETURN( 2693 tsn_stat_flowcnt_control_instance_get(unit, &fc)); 2694 2695 TSN_STAT_FLOWCNT_LOCK(fc); 2696 /* for write, write both sw and hw value */ 2697 rv = TSN_STAT_FLOWCNT_FUNC(counter_update, 2698 (unit, mem, mem_idx, new_count)); 2699 TSN_STAT_FLOWCNT_UNLOCK(fc); 2700 return rv; 2701 } 2702 2703 /* 2704 * Function: 2705 * bcmi_esw_tsn_stat_counter_update 2706 * Description: 2707 * For SER module to update the SW & HW counter 2708 * with given memory and memory index 2709 * Parameters: 2710 * unit - (IN) Unit number 2711 * mem - (IN) TSN stat counter memory 2712 * mem_idx - (IN) memory index 2713 * new_count - (IN) new counter value 2714 * Returns: 2715 * BCM_E_XXX 2716 */ 2717 int 2718 bcmi_esw_tsn_stat_counter_update( 2719 int unit, 2720 soc_mem_t mem, 2721 int mem_idx, 2722 uint64 new_count) 2723 { 2724 bcm_error_t rv1 = BCM_E_NOT_FOUND, rv2 = BCM_E_NOT_FOUND; 2725 2726 /* Check if it's sr flow memory, update flow cnt if it is */ 2727 rv1 = bcmi_esw_tsn_stat_flowcnt_update( 2728 unit, mem, mem_idx, new_count); 2729 if (BCM_SUCCESS(rv1)) { 2730 return rv1; 2731 } 2732 2733 /* Check if it's sr port memory, update port cnt if it is */ 2734 rv2 = bcmi_esw_tsn_stat_portcnt_update( 2735 unit, mem, mem_idx, new_count); 2736 if (BCM_SUCCESS(rv2)) { 2737 return rv2; 2738 } 2739 2740 return BCM_E_NOT_FOUND; 2741 } 2742 2743 /* 2744 * Function: 2745 * bcmi_esw_tsn_stat_counter_cb 2746 * Description: 2747 * Callback function for counter collection 2748 * Parameters: 2749 * unit - (IN) Unit number 2750 * Returns: 2751 * BCM_E_XXX 2752 */ 2753 STATIC void 2754 bcmi_esw_tsn_stat_counter_cb(int unit) 2755 { 2756 bcmi_tsn_stat_portcnt_control_t *pc; 2757 bcmi_tsn_stat_flowcnt_control_t *fc; 2758 2759 (void)tsn_stat_portcnt_control_instance_get(unit, &pc); 2760 (void)tsn_stat_flowcnt_control_instance_get(unit, &fc); 2761 if (NULL == pc || NULL == fc) { 2762 return; 2763 } 2764 2765 /* TSN stat portcnt callback */ 2766 TSN_STAT_PORTCNT_LOCK(pc); 2767 bcmi_esw_tsn_stat_portcnt_collect(unit, -1, -1); 2768 TSN_STAT_PORTCNT_UNLOCK(pc); 2769 /* TSN stat flowcnt callback */ 2770 TSN_STAT_FLOWCNT_LOCK(fc); 2771 (void)TSN_STAT_FLOWCNT_FUNC(counter_sync_all, (unit)); 2772 TSN_STAT_FLOWCNT_UNLOCK(fc); 2773 } 2774 2775 /* 2776 * Function: 2777 * bcmi_esw_tsn_stat_threshold_init 2778 * Description: 2779 * Initialize for TSN stat counter threshold 2780 * Parameters: 2781 * unit - (IN) Unit number 2782 * Returns: 2783 * BCM_E_XXX 2784 */ 2785 STATIC int 2786 bcmi_esw_tsn_stat_threshold_init(int unit) 2787 { 2788 bcmi_tsn_stat_control_t *tc; 2789 const bcmi_esw_tsn_stat_dev_info_t *stat_dev_info; 2790 const tsn_stat_threshold_ctrl_info_t *threshold_ctrl_info; 2791 2792 BCM_IF_ERROR_RETURN( 2793 tsn_stat_control_instance_get(unit, &tc)); 2794 stat_dev_info = tc->tsn_stat_dev_info; 2795 2796 threshold_ctrl_info = stat_dev_info->tsn_stat_threshold_ctrl_info; 2797 if ((threshold_ctrl_info != NULL) && 2798 (threshold_ctrl_info->tsn_stat_threshold_ctrl_init != NULL)) { 2799 return threshold_ctrl_info->tsn_stat_threshold_ctrl_init(unit); 2800 } 2801 2802 return BCM_E_UNAVAIL; 2803 } 2804 2805 /* 2806 * Function: 2807 * bcmi_esw_tsn_stat_cleanup 2808 * Description: 2809 * Clean and free all allocated TSN stat counter resources 2810 * Parameters: 2811 * unit - (IN) Unit number 2812 * Returns: 2813 * BCM_E_XXX 2814 */ 2815 int 2816 bcmi_esw_tsn_stat_cleanup(int unit) 2817 { 2818 LOG_VERBOSE(BSL_LS_BCM_TSN, 2819 (BSL_META_U(unit, 2820 "bcmi_esw_tsn_stat_cleanup\n"))); 2821 2822 2823 soc_counter_extra_unregister(unit, bcmi_esw_tsn_stat_counter_cb); 2824 2825 if (tsn_stat_control[unit] != NULL) { 2826 if (tsn_stat_control[unit]->portcnt_control != NULL) { 2827 bcmi_esw_tsn_stat_portcnt_cleanup(unit); 2828 sal_free(tsn_stat_control[unit]->portcnt_control); 2829 tsn_stat_control[unit]->portcnt_control = NULL; 2830 } 2831 if (tsn_stat_control[unit]->flowcnt_control != NULL) { 2832 bcmi_esw_tsn_stat_flowcnt_cleanup(unit); 2833 sal_free(tsn_stat_control[unit]->flowcnt_control); 2834 tsn_stat_control[unit]->flowcnt_control = NULL; 2835 } 2836 if (tsn_stat_control[unit]->tsn_stat_dev_info != NULL) { 2837 TSN_STAT_FLOWCNT_FUNC(cleanup, (unit)); 2838 } 2839 sal_free(tsn_stat_control[unit]); 2840 tsn_stat_control[unit] = NULL; 2841 } 2842 2843 ser_tsn_stat_functions._soc_tsn_stat_counter_update_f = NULL; 2844 soc_ser_tsn_stat_function_register(unit, &ser_tsn_stat_functions); 2845 2846 return BCM_E_NONE; 2847 } 2848 2849 /* 2850 * Function: 2851 * bcmi_esw_tsn_stat_init 2852 * Description: 2853 * Initialize and allocate all required resources for TSN stat counters 2854 * Parameters: 2855 * unit - (IN) Unit number 2856 * Returns: 2857 * BCM_E_XXX 2858 */ 2859 int 2860 bcmi_esw_tsn_stat_init(int unit) 2861 { 2862 int rv = BCM_E_NONE; 2863 int i; 2864 bcmi_tsn_stat_control_t *tc; 2865 2866 LOG_VERBOSE(BSL_LS_BCM_TSN, 2867 (BSL_META_U(unit, 2868 "bcmi_esw_tsn_stat_init\n"))); 2869 2870 /* Global initialization flag setup */ 2871 if (tsn_stat_initialized == 0) { 2872 for (i = 0; i < BCM_MAX_NUM_UNITS; i++) { 2873 tsn_stat_control[i] = NULL; 2874 } 2875 tsn_stat_initialized = 1; 2876 } 2877 2878 /* Clean up the TSN stat control related resources */ 2879 if (tsn_stat_control[unit] != NULL) { 2880 bcmi_esw_tsn_stat_cleanup(unit); 2881 } 2882 2883 /* Allocate TSN stat control resource for this unit. */ 2884 tsn_stat_control[unit] = sal_alloc(sizeof(bcmi_tsn_stat_control_t), 2885 "tsn stat control"); 2886 tc = tsn_stat_control[unit]; 2887 if (NULL == tc) { 2888 return BCM_E_MEMORY; 2889 } 2890 sal_memset(tc, 0, sizeof(bcmi_tsn_stat_control_t)); 2891 2892 2893 /* Get the chip tsn_stat_dev_info structure. */ 2894 #if defined(BCM_GREYHOUND2_SUPPORT) 2895 if (SOC_IS_GREYHOUND2(unit)) { 2896 rv = bcmi_gh2_tsn_stat_info_init(unit, &tc->tsn_stat_dev_info); 2897 if (BCM_SUCCESS(rv) && NULL == tc->tsn_stat_dev_info) { 2898 rv = BCM_E_INIT; 2899 } 2900 } else 2901 #endif /* BCM_GREYHOUND2_SUPPORT */ 2902 { 2903 rv = BCM_E_UNAVAIL; 2904 } 2905 2906 /* Release resource if any error occurred. */ 2907 if (BCM_FAILURE(rv)) { 2908 bcmi_esw_tsn_stat_cleanup(unit); 2909 return rv; 2910 } 2911 /* Check if tsn_stat_dev_info is NULL */ 2912 if (NULL == tc->tsn_stat_dev_info) { 2913 bcmi_esw_tsn_stat_cleanup(unit); 2914 return BCM_E_UNAVAIL; 2915 } 2916 2917 /* Initialize TSN Stat portcnt */ 2918 tsn_stat_control[unit]->portcnt_control 2919 = sal_alloc(sizeof(bcmi_tsn_stat_portcnt_control_t), 2920 "tsn portcnt control"); 2921 if (NULL == tsn_stat_control[unit]->portcnt_control) { 2922 bcmi_esw_tsn_stat_cleanup(unit); 2923 return BCM_E_MEMORY; 2924 } 2925 rv = bcmi_esw_tsn_stat_portcnt_init(unit); 2926 if (BCM_FAILURE(rv)) { 2927 bcmi_esw_tsn_stat_cleanup(unit); 2928 return rv; 2929 } 2930 2931 /* Initialize TSN Stat flowtcnt */ 2932 tsn_stat_control[unit]->flowcnt_control 2933 = sal_alloc(sizeof(bcmi_tsn_stat_flowcnt_control_t), 2934 "tsn flowcnt control"); 2935 if (NULL == tsn_stat_control[unit]->flowcnt_control) { 2936 bcmi_esw_tsn_stat_cleanup(unit); 2937 return BCM_E_MEMORY; 2938 } 2939 rv = bcmi_esw_tsn_stat_flowcnt_init(unit); 2940 if (BCM_FAILURE(rv)) { 2941 bcmi_esw_tsn_stat_cleanup(unit); 2942 return rv; 2943 } 2944 2945 /* Initialize chip-specific data */ 2946 rv = TSN_STAT_FLOWCNT_FUNC(init, (unit)); 2947 if (BCM_FAILURE(rv)) { 2948 bcmi_esw_tsn_stat_cleanup(unit); 2949 return rv; 2950 } 2951 2952 /* Register callback function for TSN stat counter */ 2953 rv = soc_counter_extra_register(unit, bcmi_esw_tsn_stat_counter_cb); 2954 if (BCM_FAILURE(rv)) { 2955 bcmi_esw_tsn_stat_cleanup(unit); 2956 return rv; 2957 } 2958 2959 /* Register callback function for SER TSN stat counter */ 2960 ser_tsn_stat_functions._soc_tsn_stat_counter_update_f = 2961 &bcmi_esw_tsn_stat_counter_update; 2962 rv = soc_ser_tsn_stat_function_register(unit, &ser_tsn_stat_functions); 2963 if (BCM_FAILURE(rv)) { 2964 bcmi_esw_tsn_stat_cleanup(unit); 2965 return rv; 2966 } 2967 2968 /* Initialize TSN Stat counter threshold */ 2969 rv = bcmi_esw_tsn_stat_threshold_init(unit); 2970 /* Release resource if any error occurred. */ 2971 if (BCM_FAILURE(rv)) { 2972 bcmi_esw_tsn_stat_cleanup(unit); 2973 return rv; 2974 } 2975 2976 return BCM_E_NONE; 2977 } 2978 2979 /* 2980 * Function: 2981 * bcmi_esw_tsn_stat_threshold_set 2982 * Purpose: 2983 * Configure threshold for a specific stat type on 2984 * a specific source 2985 * Parameters: 2986 * unit - (IN) Unit number 2987 * source - (IN) Stat source for TSN stat threshold check 2988 * stat - (IN) TSN statistics type (see tsn.h) 2989 * config - (IN) TSN stat threshold configuration structure 2990 * Returns: 2991 * BCM_E_XXX 2992 */ 2993 int 2994 bcmi_esw_tsn_stat_threshold_set( 2995 int unit, 2996 bcm_tsn_stat_threshold_source_t source, 2997 bcm_tsn_stat_t stat, 2998 bcm_tsn_stat_threshold_config_t *config) 2999 { 3000 bcmi_tsn_stat_control_t *tc; 3001 const bcmi_esw_tsn_stat_dev_info_t *stat_dev_info; 3002 const tsn_stat_threshold_ctrl_info_t *threshold_ctrl_info; 3003 3004 BCM_IF_ERROR_RETURN( 3005 tsn_stat_control_instance_get(unit, &tc)); 3006 stat_dev_info = tc->tsn_stat_dev_info; 3007 3008 threshold_ctrl_info = stat_dev_info->tsn_stat_threshold_ctrl_info; 3009 if ((threshold_ctrl_info != NULL) && 3010 (threshold_ctrl_info->tsn_stat_threshold_ctrl_set != NULL)) { 3011 BCM_IF_ERROR_RETURN( 3012 threshold_ctrl_info->tsn_stat_threshold_ctrl_set(unit, 3013 source, 3014 stat, 3015 config)); 3016 3017 /* Enable stat matrix (all ports) for syncing the counter */ 3018 return bcmi_esw_tsn_stat_portcnt_used_update 3019 (unit, -1, stat, BCM_TSN_STAT_PORTCNT_USED_SET); 3020 } 3021 3022 return BCM_E_UNAVAIL; 3023 } 3024 3025 /* 3026 * Function: 3027 * bcmi_esw_tsn_stat_threshold_get 3028 * Purpose: 3029 * Get the threshold configuration for a specific stat type on 3030 * a specific source 3031 * Parameters: 3032 * unit - (IN) Unit number 3033 * source - (IN) Stat source for TSN stat threshold check 3034 * stat - (IN) TSN statistics type (see tsn.h) 3035 * config - (OUT) TSN stat threshold configuration structure 3036 * Returns: 3037 * BCM_E_XXX 3038 */ 3039 int 3040 bcmi_esw_tsn_stat_threshold_get( 3041 int unit, 3042 bcm_tsn_stat_threshold_source_t source, 3043 bcm_tsn_stat_t stat, 3044 bcm_tsn_stat_threshold_config_t *config) 3045 { 3046 bcmi_tsn_stat_control_t *tc; 3047 const bcmi_esw_tsn_stat_dev_info_t *stat_dev_info; 3048 const tsn_stat_threshold_ctrl_info_t *threshold_ctrl_info; 3049 3050 BCM_IF_ERROR_RETURN( 3051 tsn_stat_control_instance_get(unit, &tc)); 3052 stat_dev_info = tc->tsn_stat_dev_info; 3053 3054 threshold_ctrl_info = stat_dev_info->tsn_stat_threshold_ctrl_info; 3055 if ((threshold_ctrl_info != NULL) && 3056 (threshold_ctrl_info->tsn_stat_threshold_ctrl_get != NULL)) { 3057 return threshold_ctrl_info->tsn_stat_threshold_ctrl_get(unit, 3058 source, 3059 stat, 3060 config); 3061 } 3062 3063 return BCM_E_UNAVAIL; 3064 } 3065 3066 #endif /* BCM_TSN_SUPPORT */ 3067