bst.c (99132B)
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 * BST - Buffer Statistics Tracking 8 * Purpose: API to set and manage various BST resources for TH 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/defs.h> 13 #include <sal/core/libc.h> 14 #include <shared/alloc.h> 15 #include <sal/core/spl.h> 16 #include <sal/core/boot.h> 17 18 #include <soc/drv.h> 19 #include <soc/error.h> 20 #include <soc/ll.h> 21 #include <soc/debug.h> 22 #include <soc/mem.h> 23 #include <soc/profile_mem.h> 24 #include <soc/trident3.h> 25 26 #include <bcm/switch.h> 27 #include <bcm/types.h> 28 #include <bcm/cosq.h> 29 #include <bcm_int/bst.h> 30 #include <bcm_int/esw/port.h> 31 32 #if defined(BCM_HELIX5_SUPPORT) 33 #define SOC_HX5_DOWNLINK_PORTQ_BASE 416 34 #define _HX5_MMU_PORTS_PER_PIPE 72 35 #endif 36 #if defined(BCM_TRIDENT3_SUPPORT) 37 extern int _bcm_bst_td3_trigger_report(int unit, bcm_bst_stat_id_t bid, 38 int xpe, int pipe, int index); 39 extern int _bcm_bst_td3_sync_report(int unit, bcm_bst_stat_id_t bid, 40 int port, int index, int chk_report); 41 extern int _bcm_bst_td3_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid, 42 int port, int index); 43 extern int _bcm_bst_td3_hw_stat_clear(int unit, 44 _bcm_bst_resource_info_t *resInfo, 45 bcm_bst_stat_id_t bid, int port, 46 int index); 47 48 int 49 _bcm_bst_td3_byte_to_cell(int unit, uint32 bytes) 50 { 51 return (bytes + (_TD3_MMU_BYTES_PER_CELL - 1))/_TD3_MMU_BYTES_PER_CELL; 52 } 53 54 int 55 _bcm_bst_td3_cell_to_byte(int unit, uint32 cells) 56 { 57 return cells * _TD3_MMU_BYTES_PER_CELL; 58 } 59 60 int 61 _bcm_td3_bst_control_set(int unit, bcm_switch_control_t type, int arg, 62 _bcm_bst_thread_oper_t operation) 63 { 64 uint32 rval, rval_en, rval_action, i, fval, enable = 0; 65 uint32 hdrm_en = 0; 66 _bcm_bst_cmn_unit_info_t *bst_info; 67 _bcm_bst_resource_info_t *pres = NULL; 68 soc_reg_t stat_reg = INVALIDr; 69 soc_field_t stat_field = INVALIDf; 70 soc_field_t snap_en[] = {BST_HW_SNAPSHOT_EN_THDOf, 71 BST_HW_SNAPSHOT_EN_THDIf, 72 BST_HW_SNAPSHOT_EN_CFAPf 73 }; 74 soc_field_t snap_action[] = {ACTION_EN_THDOf, 75 ACTION_EN_THDIf, 76 ACTION_EN_CFAPf 77 }; 78 79 bst_info = _BCM_UNIT_BST_INFO(unit); 80 81 if (!bst_info) { 82 return BCM_E_INIT; 83 } 84 85 switch (type) { 86 case bcmSwitchBstEnable: 87 BCM_IF_ERROR_RETURN(READ_MMU_GCFG_BST_TRACKING_ENABLEr(unit, &rval)); 88 89 fval = arg ? 0x1 : 0; 90 91 soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval, 92 BST_TRACK_EN_THDOf, fval); 93 soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval, 94 BST_TRACK_EN_THDIf, fval); 95 soc_reg_field_set(unit, MMU_GCFG_BST_TRACKING_ENABLEr, &rval, 96 BST_TRACK_EN_CFAPf, fval); 97 98 BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_BST_TRACKING_ENABLEr(unit, rval)); 99 100 /* Globally Enable/Disable Headroom Pool Monitoring for all 101 headroom pools */ 102 hdrm_en = arg ? 0xf : 0; 103 for (i = 0; i < NUM_LAYER(unit); i++) { 104 BCM_IF_ERROR_RETURN 105 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, i, 0, hdrm_en)); 106 } 107 108 if (operation == _bcmBstThreadOperExternal) { 109 if (fval) { 110 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit)); 111 } else { 112 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit)); 113 } 114 } else { 115 /* Set Enable Flag to True/False, to Run/Pause the Thread 116 * respectively. Wont Kill the thread. 117 */ 118 _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE); 119 } 120 121 break; 122 case bcmSwitchBstTrackingMode: 123 BCM_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 124 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, BST_TRACKING_MODEf, arg); 125 BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 126 bst_info->track_mode = arg ? 1 : 0; 127 /* 128 * As Headroom Pool has two different stats resource 129 * for tracking current usage count and peak usage count 130 * we set up the respective resource accordingly based on 131 * BST Tracking Mode 132 */ 133 if (bst_info->track_mode) { 134 /* Peak Mode */ 135 stat_reg = THDI_HDRM_POOL_PEAK_COUNT_HPr; 136 stat_field = PEAK_BUFFER_COUNTf; 137 } else { 138 /* Current Mode */ 139 stat_reg = THDI_HDRM_POOL_COUNT_HPr; 140 stat_field = TOTAL_BUFFER_COUNTf; 141 } 142 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 143 if (pres != NULL) { 144 _BCM_BST_STAT_INFO(pres, pres->stat_mem[0], stat_reg, 145 stat_field); 146 } 147 break; 148 case bcmSwitchBstSnapshotEnable: 149 rval_en = 0; 150 rval_action = 0; 151 if (arg != 0) { 152 BCM_IF_ERROR_RETURN( 153 READ_MMU_GCFG_BST_HW_SNAPSHOT_ENr(unit, &rval_en)); 154 BCM_IF_ERROR_RETURN( 155 READ_MMU_GCFG_BST_SNAPSHOT_ACTION_ENr(unit, &rval_action)); 156 157 for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) { 158 enable = 0; 159 if (arg & (0x1 << i)) { 160 enable = 0x1; 161 } else { 162 enable = 0; 163 } 164 165 soc_reg_field_set(unit, MMU_GCFG_BST_HW_SNAPSHOT_ENr, &rval_en, 166 snap_en[i], enable); 167 168 soc_reg_field_set(unit, MMU_GCFG_BST_SNAPSHOT_ACTION_ENr, 169 &rval_action, snap_action[i], ((enable) ? 1 : 0)); 170 } 171 } 172 BCM_IF_ERROR_RETURN( 173 WRITE_MMU_GCFG_BST_HW_SNAPSHOT_ENr(unit, rval_en)); 174 BCM_IF_ERROR_RETURN( 175 WRITE_MMU_GCFG_BST_SNAPSHOT_ACTION_ENr(unit, rval_action)); 176 bst_info->snapshot_mode = arg; 177 178 break; 179 180 default: 181 return BCM_E_UNAVAIL; 182 } 183 return BCM_E_NONE; 184 } 185 186 int 187 _bcm_td3_bst_control_get(int unit, bcm_switch_control_t type, int *arg) 188 { 189 uint32 rval; 190 _bcm_bst_cmn_unit_info_t *bst_info; 191 int hdrm_en, cfap_en; 192 193 bst_info = _BCM_UNIT_BST_INFO(unit); 194 195 if (!bst_info) { 196 return BCM_E_INIT; 197 } 198 199 switch (type) { 200 case bcmSwitchBstEnable: 201 BCM_IF_ERROR_RETURN(READ_MMU_GCFG_BST_TRACKING_ENABLEr(unit, &rval)); 202 cfap_en = soc_reg_field_get(unit, MMU_GCFG_BST_TRACKING_ENABLEr, rval, 203 BST_TRACK_EN_CFAPf); 204 BCM_IF_ERROR_RETURN 205 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, 0, 0, &rval)); 206 hdrm_en = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval, 207 PEAK_COUNT_UPDATE_EN_HPf); 208 209 if ((cfap_en == 0x1) && 210 (hdrm_en == 0xf)) { 211 /* Only when both cfap and 212 headroom tracking is enabled */ 213 *arg = 1; 214 } else { 215 *arg = 0; 216 } 217 break; 218 case bcmSwitchBstTrackingMode: 219 *arg = bst_info->track_mode; 220 break; 221 case bcmSwitchBstSnapshotEnable: 222 *arg = bst_info->snapshot_mode; 223 break; 224 default: 225 return BCM_E_UNAVAIL; 226 } 227 return BCM_E_NONE; 228 } 229 230 int 231 _bcm_bst_td3_intr_enable_set(int unit, int enable) 232 { 233 uint32 rval; 234 if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) { 235 if (SOC_REG_IS_VALID(unit, MMU_XCFG_XPE_CPU_INT_ENr)) { 236 BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_ENr(unit, &rval)); 237 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval, 238 BST_THDO_INT_ENf, enable); 239 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval, 240 BST_THDI_INT_ENf, enable); 241 BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_ENr(unit, rval)); 242 } 243 244 if (SOC_REG_IS_VALID(unit, MMU_SEDCFG_SED_CPU_INT_ENr)) { 245 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_SED_CPU_INT_ENr(unit, &rval)); 246 soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_ENr, &rval, 247 BST_CFAP_INT_ENf, enable); 248 BCM_IF_ERROR_RETURN(WRITE_MMU_SEDCFG_SED_CPU_INT_ENr(unit, rval)); 249 } 250 } 251 return BCM_E_NONE; 252 } 253 254 STATIC int 255 soc_td3_set_hw_intr_cb(int unit) 256 { 257 BCM_IF_ERROR_RETURN(soc_td3_set_bst_callback(unit, &_bcm_bst_hw_event_cb)); 258 return BCM_E_NONE; 259 } 260 261 STATIC int 262 _bst_td3_intr_status_reset(int unit) 263 { 264 uint32 rval; 265 266 BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, &rval)); 267 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval, 268 BST_THDO_INT_CLRf, 0); 269 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval, 270 BST_THDI_INT_CLRf, 0); 271 BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, rval)); 272 273 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_SED_CPU_INT_CLEARr(unit, &rval)); 274 soc_reg_field_set(unit, MMU_SEDCFG_SED_CPU_INT_CLEARr, &rval, 275 BST_CFAP_INT_CLRf, 0); 276 BCM_IF_ERROR_RETURN(WRITE_MMU_SEDCFG_SED_CPU_INT_CLEARr(unit, rval)); 277 return BCM_E_NONE; 278 } 279 280 /* Use this flag to indicate a triggered MC CPU queue index. */ 281 #define _TD3_BST_MCAST_CPU_FLAG (1U << 30) 282 /* Max 1 XPEs and 2 PIPEs */ 283 #define _TD3X_MAX_XPEPIPE 2 284 int bst_td3_cfap_trigger_status[SOC_MAX_NUM_DEVICES] = {0}; 285 286 int 287 _bcm_bst_td3_intr_to_resources(int unit, uint32 *flags) 288 { 289 uint32 flags_tr = 0; 290 uint32 fval = 0; 291 uint32 rval_dev, rval32_type, rval32_status; 292 uint64 rval_uc, rval_db, rval_rqe; 293 int index[_bcmResourceMaxCount * _TD3X_MAX_XPEPIPE] = {-1}, i; 294 int ins_xpe[_bcmResourceMaxCount * _TD3X_MAX_XPEPIPE] = {-1}; 295 int ins_pipe[_bcmResourceMaxCount * _TD3X_MAX_XPEPIPE] = {-1}; 296 int res[_bcmResourceMaxCount * _TD3X_MAX_XPEPIPE] = {-1}, res_ct = 0; 297 soc_field_t fld = INVALIDf; 298 soc_reg_t reg_type = INVALIDr, reg_status = INVALIDr; 299 int xpe = 0; 300 uint32 inst, pipe, ipipe_map; 301 soc_info_t *si; 302 303 si = &SOC_INFO(unit); 304 _bcm_bst_td3_intr_enable_set(unit, 0); 305 _bst_td3_intr_status_reset(unit); 306 307 LOG_VERBOSE(BSL_LS_BCM_COSQ, 308 (BSL_META_U(unit, 309 "BST interrupt handler: unit=%d flags=0x%x\n"), 310 unit, *flags)); 311 312 /* _bcmResourceDevice */ 313 BCM_IF_ERROR_RETURN(READ_CFAPBSTTHRSr(unit, &rval_dev)); 314 if (soc_reg_field_get(unit, CFAPBSTTHRSr, rval_dev, BST_THRESHOLDf)) { 315 if (SOC_REG_IS_VALID(unit, MMU_SEDCFG_SED_CPU_INT_STATr)) { 316 /* For CFAP, it use MMU_SEDCFG_SED_CPU_INT_STATr to indicate the bst 317 * interruptbut not use a trigger status register. 318 * Interrupt status was stored in bst_td3_cfap_trigger_status. */ 319 if (bst_td3_cfap_trigger_status[unit]) { 320 index[res_ct] = 0; 321 ins_xpe[res_ct] = -1; 322 ins_pipe[res_ct] = -1; 323 res[res_ct++] = _bcmResourceDevice; 324 bst_td3_cfap_trigger_status[unit] = 0; 325 } 326 } 327 } 328 329 /* THDI Status/Triggers */ 330 reg_type = SOC_REG_UNIQUE_ACC(unit, THDI_BST_TRIGGER_STATUS_TYPEr)[xpe]; 331 reg_status = SOC_REG_UNIQUE_ACC(unit, THDI_BST_TRIGGER_STATUS_32r)[xpe]; 332 ipipe_map = si->xpe_ipipe_map[xpe]; 333 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 334 if(!(ipipe_map & (1 << pipe))) { 335 continue; 336 } 337 inst = pipe; 338 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg_type, inst, 0, &rval32_type)); 339 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg_status, inst, 0, &rval32_status)); 340 341 /* _bcmResourceIngPool */ 342 fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type, 343 POOL_SHARED_TRIGGERf); 344 if (fval) { 345 fld = POOL_SHARED_TRIGGER_STATUSf; 346 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld); 347 ins_xpe[res_ct] = 0; 348 ins_pipe[res_ct] = inst; 349 res[res_ct++] = _bcmResourceIngPool; 350 } 351 352 /* _bcmResourcePortPool */ 353 fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type, 354 SP_SHARED_TRIGGERf); 355 if (fval) { 356 fld = SP_SHARED_TRIGGER_STATUSf; 357 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld); 358 ins_xpe[res_ct] = 0; 359 ins_pipe[res_ct] = inst; 360 res[res_ct++] = _bcmResourcePortPool; 361 } 362 363 /* _bcmResourcePriGroupShared */ 364 fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type, 365 PG_SHARED_TRIGGERf); 366 if (fval) { 367 fld = PG_SHARED_TRIGGER_STATUSf; 368 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld); 369 ins_xpe[res_ct] = 0; 370 ins_pipe[res_ct] = inst; 371 res[res_ct++] = _bcmResourcePriGroupShared; 372 } 373 374 /* _bcmResourcePriGroupHeadroom */ 375 fval = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPEr, rval32_type, 376 PG_HDRM_TRIGGERf); 377 378 if (fval) { 379 fld = PG_HDRM_TRIGGER_STATUSf; 380 index[res_ct] = soc_reg_field_get(unit, reg_status, rval32_status, fld); 381 ins_xpe[res_ct] = 0; 382 ins_pipe[res_ct] = inst; 383 res[res_ct++] = _bcmResourcePriGroupHeadroom; 384 } 385 386 rval32_type = 0; 387 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg_type, inst, 0, rval32_type)); 388 rval32_status = 0; 389 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg_status, inst, 0, rval32_status)); 390 } 391 392 393 /* THDM DB Status/Triggers */ 394 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 395 BCM_IF_ERROR_RETURN 396 (soc_reg_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, xpe, 0, &rval_db)); 397 reg_status = MMU_THDM_DB_DEVICE_BST_STATr; 398 399 /* _bcmResourceEgrPool */ 400 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db, 401 MCUC_SP_BST_STAT_TRIGGEREDf); 402 403 if (fval) { 404 fld = MCUC_SP_BST_STAT_IDf; 405 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld); 406 ins_xpe[res_ct] = xpe; 407 ins_pipe[res_ct] = 0; 408 res[res_ct++] = _bcmResourceEgrPool; 409 } 410 411 /* _bcmResourceEgrMCastPool */ 412 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db, 413 MC_SP_BST_STAT_TRIGGEREDf); 414 if (fval) { 415 fld = MC_SP_BST_STAT_IDf; 416 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld); 417 ins_xpe[res_ct] = xpe; 418 ins_pipe[res_ct] = 0; 419 res[res_ct++] = _bcmResourceEgrMCastPool; 420 } 421 422 /* _bcmResourceMcast */ 423 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db, 424 MC_Q_BST_STAT_TRIGGEREDf); 425 426 if (fval) { 427 fld = MC_Q_BST_STAT_IDf; 428 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld); 429 ins_xpe[res_ct] = xpe; 430 ins_pipe[res_ct] = (index[res_ct] >> 10) & 1U; 431 res[res_ct++] = _bcmResourceMcast; 432 } 433 434 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db, 435 MC_CPU_Q_BST_STAT_TRIGGEREDf); 436 437 if (fval) { 438 fld = MC_CPU_Q_BST_STAT_IDf; 439 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld); 440 index[res_ct] |= _TD3_BST_MCAST_CPU_FLAG; 441 ins_xpe[res_ct] = xpe; 442 ins_pipe[res_ct] = 0; 443 res[res_ct++] = _bcmResourceMcast; 444 } 445 446 /* _bcmResourceEgrPortPoolSharedMcast*/ 447 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, rval_db, 448 MC_PORTSP_BST_STAT_TRIGGEREDf); 449 450 if (fval) { 451 fld = MC_PORTSP_BST_STAT_IDf; 452 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_db, fld); 453 ins_xpe[res_ct] = xpe; 454 ins_pipe[res_ct] = 0; 455 res[res_ct++] = _bcmResourceEgrPortPoolSharedMcast; 456 } 457 458 COMPILER_64_ZERO(rval_db); 459 BCM_IF_ERROR_RETURN 460 (soc_reg_set(unit, MMU_THDM_DB_DEVICE_BST_STATr, xpe, 0, rval_db)); 461 } 462 463 /* THDU Status/Triggers */ 464 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 465 BCM_IF_ERROR_RETURN 466 (soc_reg_get(unit, THDU_BST_STATr, xpe, 0, &rval_uc)); 467 reg_status = THDU_BST_STATr; 468 469 /* _bcmResourceUcast */ 470 fval = soc_reg64_field32_get(unit, reg_status, rval_uc, 471 UC_Q_BST_STAT_TRIGGEREDf); 472 if (fval) { 473 fld = UC_Q_BST_STAT_IDf; 474 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld); 475 ins_xpe[res_ct] = xpe; 476 ins_pipe[res_ct] = (index[res_ct] >> 10) & 1U; 477 res[res_ct++] = _bcmResourceUcast; 478 } 479 480 /* _bcmResourceEgrPortPoolSharedUcast*/ 481 fval = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, 482 UC_PORT_SP_BST_STAT_TRIGGEREDf); 483 if (fval) { 484 fld = UC_PORT_SP_BST_STAT_IDf; 485 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld); 486 ins_xpe[res_ct] = xpe; 487 ins_pipe[res_ct] = (index[res_ct] >> 9) & 1U; 488 res[res_ct++] = _bcmResourceEgrPortPoolSharedUcast; 489 } 490 491 /* _bcmResourceUCQueueGroup*/ 492 fval = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, 493 UC_QGROUP_BST_STAT_TRIGGEREDf); 494 if (fval) { 495 fld = UC_QGROUP_BST_STAT_IDf; 496 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_uc, fld); 497 ins_xpe[res_ct] = xpe; 498 ins_pipe[res_ct] = (index[res_ct] >> 7) & 1U; 499 res[res_ct++] = _bcmResourceUCQueueGroup; 500 } 501 502 COMPILER_64_ZERO(rval_uc); 503 BCM_IF_ERROR_RETURN 504 (soc_reg_set(unit, THDU_BST_STATr, xpe, 0, rval_uc)); 505 } 506 507 /* THDR Status/Triggers */ 508 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 509 reg_status = MMU_THDR_DB_BST_STATr; 510 BCM_IF_ERROR_RETURN 511 (soc_reg_get(unit, reg_status, xpe, 0, &rval_rqe)); 512 513 /* _bcmResourceRQEQueue */ 514 fval = soc_reg64_field32_get(unit, reg_status, rval_rqe, 515 PRIQ_TRIGGEREDf); 516 if (fval) { 517 fld = PRIQ_IDf; 518 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_rqe, fld); 519 ins_xpe[res_ct] = xpe; 520 ins_pipe[res_ct] = 0; 521 res[res_ct++] = _bcmResourceRQEQueue; 522 } 523 524 /* _bcmResourceRQEPool*/ 525 fval = soc_reg64_field32_get(unit, reg_status, rval_rqe, 526 SP_TRIGGEREDf); 527 if (fval) { 528 fld = SP_IDf; 529 index[res_ct] = soc_reg64_field32_get(unit, reg_status, rval_rqe, fld); 530 ins_xpe[res_ct] = xpe; 531 ins_pipe[res_ct] = 0; 532 res[res_ct++] = _bcmResourceRQEPool; 533 } 534 535 COMPILER_64_ZERO(rval_rqe); 536 BCM_IF_ERROR_RETURN 537 (soc_reg_set(unit, reg_status, xpe, 0, rval_rqe)); 538 } 539 540 if (res_ct == 0) { 541 _bcm_bst_td3_intr_enable_set(unit, 1); 542 /* No resource to fetch */ 543 return BCM_E_NONE; 544 } 545 546 for (i = 0; i < res_ct; i++) { 547 BCM_IF_ERROR_RETURN( 548 _bcm_bst_td3_sync_report(unit, res[i], -1, index[i], 0)); 549 BCM_IF_ERROR_RETURN( 550 _bcm_bst_td3_trigger_report(unit, res[i], ins_xpe[i], 551 ins_pipe[i], index[i])); 552 } 553 554 *flags = flags_tr; 555 _bcm_bst_td3_intr_enable_set(unit, 1); 556 return BCM_E_NONE; 557 } 558 559 int 560 _bcm_bst_td3_hw_stat_clear(int unit, _bcm_bst_resource_info_t *resInfo, 561 bcm_bst_stat_id_t bid, int port, int index) 562 { 563 _bcm_bst_cmn_unit_info_t *bst_info; 564 int rv, pipe; 565 uint32 rval; 566 soc_mem_t base_mem = INVALIDm, mem = INVALIDm; 567 soc_reg_t reg; 568 int min_hw_idx, max_hw_idx, idx; 569 int pipe_factor = 1, pipe_offset = 0, inst, stats_per_inst; 570 int num_entries, mem_wsz; 571 void *pentry; 572 char *dmabuf; 573 int enable = 0; 574 int p_idx; 575 int sync_val = 0; 576 577 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 578 return BCM_E_PARAM; 579 } 580 581 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 582 return BCM_E_INIT; 583 } 584 585 if (bst_info->pre_sync) { 586 bst_info->pre_sync(unit, bid, &sync_val); 587 } 588 589 /* sync all the stats */ 590 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 591 pipe_factor = NUM_PIPE(unit); 592 } 593 if (index == -1) { 594 min_hw_idx = resInfo->index_min; 595 if (resInfo->num_instance > 1) { 596 max_hw_idx = ((resInfo->index_max + 1) / pipe_factor / 597 resInfo->num_instance) - 1; 598 } else { 599 max_hw_idx = ((resInfo->index_max + 1) / pipe_factor) - 1; 600 } 601 } else { 602 min_hw_idx = max_hw_idx = index; 603 if (bid == bcmBstStatIdDevice) { 604 min_hw_idx = resInfo->index_min; 605 max_hw_idx = resInfo->index_max; 606 } 607 } 608 609 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 610 if ((base_mem = resInfo->stat_mem[0]) != INVALIDm) { 611 int xpe = 0; 612 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 613 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe); 614 if (mem == INVALIDm) { 615 continue; 616 } 617 618 if (index < 0) { 619 num_entries = soc_mem_index_count(unit, mem); 620 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 621 622 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 623 if (dmabuf == NULL) { 624 return BCM_E_MEMORY; 625 } 626 627 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 628 soc_mem_index_min(unit, mem), 629 soc_mem_index_max(unit, mem), 630 dmabuf)) { 631 soc_cm_sfree(unit, dmabuf); 632 return BCM_E_INTERNAL; 633 } 634 635 /* Clear stat counter if requested */ 636 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 637 p_idx = idx; 638 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 639 /* 640 * Reorder sw stat index 641 * HW stat: index 0 - port 0 pool 0 642 * index 1 - port 1 pool 0 643 * index 2 - port 2 pool 0 644 * ... 645 * index n - port n%34 pool n/34 646 * SW stat: index 0 - port 0 pool 0 647 * index 1 - port 0 pool 1 648 * index 2 - port 0 pool 2 649 * ... 650 * index n - port n/4 pool n%4 651 */ 652 /* coverity[parameter_hidden: FALSE] */ 653 int port, pool; 654 port = idx / _TD3_MMU_NUM_POOL; 655 pool = idx % _TD3_MMU_NUM_POOL; 656 #ifdef BCM_HELIX5_SUPPORT 657 if (SOC_IS_HELIX5(unit)) { 658 p_idx = pool * _HX5_MMU_PORTS_PER_PIPE + port; 659 } else 660 #endif 661 { 662 p_idx = pool * _TD3_MMU_PORTS_PER_PIPE + port; 663 } 664 } 665 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 666 dmabuf, p_idx); 667 soc_mem_field32_set(unit, mem, pentry, resInfo->stat_field, 0); 668 } 669 670 if (soc_mem_write_range(unit, mem, MEM_BLOCK_ALL, 671 soc_mem_index_min(unit, mem), 672 soc_mem_index_max(unit, mem), 673 dmabuf)) { 674 soc_cm_sfree(unit, dmabuf); 675 return BCM_E_INTERNAL; 676 } 677 soc_cm_sfree(unit, dmabuf); 678 } else { 679 /* Clear a specific index */ 680 uint32 entry[SOC_MAX_MEM_WORDS]; 681 p_idx = index; 682 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 683 /* 684 * Reorder sw stat index 685 * HW stat: index 0 - port 0 pool 0 686 * index 1 - port 1 pool 0 687 * index 2 - port 2 pool 0 688 * ... 689 * index n - port n%34 pool n/34 690 * SW stat: index 0 - port 0 pool 0 691 * index 1 - port 0 pool 1 692 * index 2 - port 0 pool 2 693 * ... 694 * index n - port n/4 pool n%4 695 */ 696 int port, pool; 697 port = index / _TD3_MMU_NUM_POOL; 698 pool = index % _TD3_MMU_NUM_POOL; 699 p_idx = pool * _TD3_MMU_PORTS_PER_PIPE + port; 700 } 701 702 SOC_IF_ERROR_RETURN( 703 soc_mem_read(unit, mem, MEM_BLOCK_ALL, p_idx, entry)); 704 soc_mem_field32_set(unit, mem, entry, 705 resInfo->stat_field, 0); 706 SOC_IF_ERROR_RETURN( 707 soc_mem_write(unit, mem, MEM_BLOCK_ALL, p_idx, entry)); 708 } 709 } 710 } else if (resInfo->profile_r[0]) { 711 pipe_offset += max_hw_idx; 712 } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) { 713 int stat_idx = 0; 714 stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance; 715 716 /* Clear stat counters */ 717 if (bst_info->control_get) { 718 bst_info->control_get(unit, bcmSwitchBstEnable, &enable); 719 } 720 if (enable && bst_info->control_set) { 721 bst_info->control_set(unit, bcmSwitchBstEnable, 0, TRUE); 722 } 723 724 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 725 rval = 0; 726 if (stats_per_inst) { 727 inst = idx / stats_per_inst; 728 stat_idx = idx % stats_per_inst; 729 } else { 730 inst = REG_PORT_ANY; 731 stat_idx = idx; 732 } 733 rv = soc_reg32_get(unit, reg, inst, stat_idx, &rval); 734 if (rv) { 735 return BCM_E_INTERNAL; 736 } 737 soc_reg_field_set(unit, reg, &rval, resInfo->stat_field, 0); 738 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, stat_idx, rval)); 739 } 740 741 if (enable && bst_info->control_set) { 742 bst_info->control_set(unit, bcmSwitchBstEnable, enable, TRUE); 743 } 744 745 } /* if valid reg */ 746 } /* for each pipe */ 747 748 if (bst_info->post_sync) { 749 bst_info->post_sync(unit, bid, sync_val); 750 } 751 752 return BCM_E_NONE; 753 } 754 755 /* 756 * This function resolves latched BST index and 757 * reports events indicated by BST triggers. 758 */ 759 int 760 _bcm_bst_td3_trigger_report(int unit, bcm_bst_stat_id_t bid, 761 int xpe, int pipe, int index) 762 { 763 soc_info_t *si = &SOC_INFO(unit); 764 _bcm_bst_resource_info_t *pres; 765 int mmu_port_base = 0; 766 int phy_port = 0; 767 int mmu_port = 0; 768 bcm_gport_t gport = 0; 769 bcm_cos_queue_t cosq = 0; 770 771 pres = _BCM_BST_RESOURCE(unit, bid); 772 if (pres == NULL) { 773 return BCM_E_PARAM; 774 } 775 776 if (pres->flags & _BCM_BST_CMN_RES_F_PIPED) { 777 mmu_port_base = SOC_TD3_MMU_PORT_PER_PIPE * pipe; 778 } 779 780 switch (bid) { 781 case _bcmResourceDevice: 782 gport = -1; 783 cosq = BCM_COS_INVALID; 784 break; 785 786 case _bcmResourceIngPool: 787 case _bcmResourceEgrPool: 788 case _bcmResourceEgrMCastPool: 789 gport = -1; 790 cosq = index % _TD3_MMU_NUM_POOL; 791 break; 792 793 case _bcmResourcePortPool: 794 mmu_port= index/_TD3_MMU_NUM_POOL; 795 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 796 gport = si->port_p2l_mapping[phy_port]; 797 cosq = index % _TD3_MMU_NUM_POOL; 798 break; 799 800 case _bcmResourcePriGroupHeadroom: 801 case _bcmResourcePriGroupShared: 802 mmu_port = index/_TD3_MMU_NUM_PG; 803 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 804 gport = si->port_p2l_mapping[phy_port]; 805 cosq = index % _TD3_MMU_NUM_PG; 806 break; 807 808 case _bcmResourceUcast: 809 index = index & ((1U << 10) - 1); 810 #ifdef BCM_HELIX5_SUPPORT 811 if (SOC_IS_HELIX5(unit)) { 812 if (index > SOC_HX5_DOWNLINK_PORTQ_BASE - 1) { 813 index = index - SOC_HX5_DOWNLINK_PORTQ_BASE; 814 mmu_port = index / 16 + 16; 815 } else { 816 mmu_port = index / 26; 817 } 818 phy_port = si->port_m2p_mapping[mmu_port]; 819 gport = si->port_p2l_mapping[phy_port]; 820 cosq = index - si->port_uc_cosq_base[gport]; 821 822 } else 823 #endif 824 { 825 mmu_port = index/10; 826 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 827 gport = si->port_p2l_mapping[phy_port]; 828 cosq = index % 10; 829 } 830 break; 831 832 case _bcmResourceMcast: 833 if (index & _TD3_BST_MCAST_CPU_FLAG) { 834 index = index & ~_TD3_BST_MCAST_CPU_FLAG; 835 gport = CMIC_PORT(unit); 836 cosq = index; 837 } else { 838 index = index & ((1U << 10) - 1); 839 #ifdef BCM_HELIX5_SUPPORT 840 if (SOC_IS_HELIX5(unit)) { 841 if (index > SOC_HX5_DOWNLINK_PORTQ_BASE - 1) { 842 index = index - SOC_HX5_DOWNLINK_PORTQ_BASE; 843 mmu_port = index / 16 + 16; 844 } else { 845 mmu_port = index / 26; 846 } 847 phy_port = si->port_m2p_mapping[mmu_port]; 848 gport = si->port_p2l_mapping[phy_port]; 849 cosq = index - si->port_cosq_base[gport]; 850 } else 851 #endif 852 { 853 mmu_port = index/10; 854 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 855 gport = si->port_p2l_mapping[phy_port]; 856 cosq = index % 10; 857 } 858 } 859 break; 860 861 case _bcmResourceEgrPortPoolSharedUcast: 862 index = index & ((1U << 9) - 1); 863 mmu_port = index/_TD3_MMU_NUM_POOL; 864 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 865 gport = si->port_p2l_mapping[phy_port]; 866 cosq = index % _TD3_MMU_NUM_POOL; 867 break; 868 869 case _bcmResourceEgrPortPoolSharedMcast: 870 mmu_port = index & 0xff; 871 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 872 gport = si->port_p2l_mapping[phy_port]; 873 cosq = (index >> 8) & 0x3; 874 break; 875 default: 876 break; 877 } 878 879 /* Generate SOC EVENT */ 880 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 881 bid, gport, cosq); 882 883 return BCM_E_NONE; 884 } 885 886 /* 887 * This function syncs BST snapshot and can report event 888 * when stat is above threshold. 889 * chk_report: 0 - sync only, no report. 890 * 1 - sync, and report based on threshold check. 891 */ 892 int 893 _bcm_bst_td3_sync_report(int unit, bcm_bst_stat_id_t bid, 894 int port, int index, int chk_report) 895 { 896 _bcm_bst_cmn_unit_info_t *bst_info; 897 _bcm_bst_resource_info_t *resInfo; 898 int num_entries, mem_wsz, sync_val = 0; 899 int idx, idx_offset, thd_idx; 900 int inst, xpe, xpe_offset, pipe, pipe_offset = 0; 901 int stats_per_inst = 0; /* stats per mem instance(xpe) */ 902 void *pentry; 903 char *dmabuf; 904 uint32 rval, temp_val; 905 soc_mem_t mem, base_mem; 906 soc_reg_t reg; 907 bcm_gport_t gport; 908 bcm_cos_queue_t cosq; 909 910 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 911 return BCM_E_INIT; 912 } 913 914 if (bst_info->pre_sync) { 915 bst_info->pre_sync(unit, bid, &sync_val); 916 } 917 918 /* sync all the stats */ 919 resInfo = _BCM_BST_RESOURCE(unit, bid); 920 if (resInfo == NULL) { 921 return BCM_E_PARAM; 922 } 923 924 base_mem = resInfo->stat_mem[0]; 925 reg = resInfo->stat_reg[0]; 926 927 if (reg != INVALIDr) { 928 int stat_idx = 0; 929 stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance; 930 pipe_offset = 0; 931 932 for (idx = 0; idx < resInfo->num_stat_pp; idx++) { 933 rval = 0; 934 if (stats_per_inst) { 935 inst = idx / stats_per_inst; 936 stat_idx = idx % stats_per_inst; 937 } else { 938 inst = REG_PORT_ANY; 939 stat_idx = idx; 940 stats_per_inst = 1; 941 } 942 943 idx_offset = idx + pipe_offset; 944 SOC_IF_ERROR_RETURN 945 (soc_reg32_get(unit, reg, inst, stat_idx, &rval)); 946 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field); 947 if (bst_info->track_mode) { 948 /* BST tracking is in Peak mode. 949 * Hence store the watermark value only. 950 */ 951 if (resInfo->p_stat[idx_offset] < temp_val) { 952 resInfo->p_stat[idx_offset] = temp_val; 953 } 954 } else { 955 resInfo->p_stat[idx_offset] = temp_val; 956 } 957 if (chk_report) { 958 /* Check if there exists threshold for a resource 959 * continue if we don't have one */ 960 if (resInfo->p_threshold == NULL) { 961 continue; 962 } 963 964 /* In TH, stat count and thd count need not be same as in previous 965 * chips(check init). This is due to different AccType for Stat and 966 * Threshold. 967 * Stats - usually NON-DUP Acc Type 968 * Threshold - usually DUP Acc Type 969 * Hence threshold index might only exist for 1 instance and 970 * applicable to all. 971 */ 972 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 973 /* For CFAP res, threshold exists per instance(xpe) */ 974 thd_idx = idx_offset; 975 } else { 976 thd_idx = idx_offset % stats_per_inst; 977 } 978 979 /* coverity[copy_paste_error : FALSE] */ 980 if (resInfo->p_threshold[thd_idx] && 981 (resInfo->p_stat[idx_offset] >= 982 (resInfo->p_threshold[thd_idx] * resInfo->threshold_gran) 983 )) { 984 /* Generate SOC EVENT */ 985 if (bst_info->handlers.reverse_resolve_index) { 986 /* reverse map the inedx to port/cos pair */ 987 bst_info->handlers.reverse_resolve_index(unit, bid, 988 port, idx_offset, 989 &gport, &cosq); 990 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 991 bid, gport, cosq); 992 993 } 994 } 995 } 996 } 997 } else if (base_mem != INVALIDm) { 998 int min_idx = 0, max_idx = 0; 999 int stats_per_pipe = 0; /* stats per pipe per mem-instance(xpe) */ 1000 1001 /* Get the mem attributes(Max idx) from the first child, 1002 * which could be used for other instances. 1003 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 1004 */ 1005 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0); 1006 1007 if (mem == INVALIDm) { 1008 return BCM_E_PARAM; 1009 } 1010 stats_per_inst = (resInfo->index_max + 1) / resInfo->num_instance; 1011 stats_per_pipe = stats_per_inst / NUM_PIPE(unit); 1012 1013 num_entries = soc_mem_index_max(unit, mem) + 1; 1014 min_idx = soc_mem_index_min(unit, mem); 1015 max_idx = soc_mem_index_max(unit, mem); 1016 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 1017 1018 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 1019 if (dmabuf == NULL) { 1020 return BCM_E_MEMORY; 1021 } 1022 1023 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 1024 xpe_offset = 0; 1025 gport = BCM_GPORT_INVALID; 1026 cosq = -1; 1027 1028 if (xpe) { 1029 xpe_offset = stats_per_inst * xpe; 1030 } 1031 1032 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1033 pipe_offset = 0; 1034 if (pipe) { 1035 pipe_offset = stats_per_pipe * pipe; 1036 } 1037 1038 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe); 1039 if (mem == INVALIDm) { 1040 continue; 1041 } 1042 1043 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 1044 min_idx, max_idx, dmabuf)) { 1045 soc_cm_sfree(unit, dmabuf); 1046 return BCM_E_INTERNAL; 1047 } 1048 1049 for (idx = 0; idx < max_idx; idx++) { 1050 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 1051 /* 1052 * Reorder sw stat index 1053 * HW stat: index 0 - port 0 pool 0 1054 * index 1 - port 1 pool 0 1055 * index 2 - port 2 pool 0 1056 * ... 1057 * index n - port n%34 pool n/34 1058 * SW stat: index 0 - port 0 pool 0 1059 * index 1 - port 0 pool 1 1060 * index 2 - port 0 pool 2 1061 * ... 1062 * index n - port n/4 pool n%4 1063 */ 1064 /* coverity[parameter_hidden: FALSE] */ 1065 int port, pool; 1066 #ifdef BCM_HELIX5_SUPPORT 1067 if (SOC_IS_HELIX5(unit)) { 1068 port = idx % _HX5_MMU_PORTS_PER_PIPE; 1069 pool = idx / _HX5_MMU_PORTS_PER_PIPE; 1070 } else 1071 #endif 1072 { 1073 port = idx % _TD3_MMU_PORTS_PER_PIPE; 1074 pool = idx / _TD3_MMU_PORTS_PER_PIPE; 1075 } 1076 idx_offset = port * _TD3_MMU_NUM_POOL + pool + 1077 pipe_offset + xpe_offset; 1078 } else { 1079 idx_offset = idx + pipe_offset + xpe_offset; 1080 } 1081 if (idx_offset >= resInfo->num_stat_pp) { 1082 continue; 1083 } 1084 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 1085 dmabuf, idx); 1086 temp_val = soc_mem_field32_get(unit, mem, pentry, 1087 resInfo->stat_field); 1088 if (bst_info->track_mode) { 1089 /* BST tracking is in Peak mode. 1090 * Hence store the watermark value only. 1091 */ 1092 if (resInfo->p_stat[idx_offset] < temp_val) { 1093 resInfo->p_stat[idx_offset] = temp_val; 1094 } 1095 } else { 1096 resInfo->p_stat[idx_offset] = temp_val; 1097 } 1098 1099 if (chk_report) { 1100 /* In TH, stat count and thd count need not be same as in 1101 * previous chips(check init). This is due to different 1102 * AccType for Stat and Threshold. 1103 * Stats - usually NON-DUP Acc Type 1104 * Threshold - usually DUP Acc Type 1105 * Hence threshold index might only exist for 1 instance 1106 * and applicable to all. 1107 */ 1108 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 1109 /* For CFAP res, threshold exists per instance(xpe) */ 1110 thd_idx = idx_offset; 1111 } else { 1112 /* For rest, considering thd of 1st instance(xpe) */ 1113 thd_idx = idx_offset % stats_per_inst; 1114 } 1115 if (resInfo->p_threshold[thd_idx] && 1116 (resInfo->p_stat[idx_offset] >= 1117 (resInfo->p_threshold[thd_idx]) * resInfo->threshold_gran)) { 1118 /* Generate SOC EVENT */ 1119 if (bst_info->handlers.reverse_resolve_index) { 1120 /* reverse map the inedx to port/cos pair */ 1121 bst_info->handlers.reverse_resolve_index(unit, bid, 1122 port, idx_offset, 1123 &gport, &cosq); 1124 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 1125 bid, gport, cosq); 1126 1127 } 1128 } 1129 } 1130 } 1131 } 1132 } 1133 soc_cm_sfree(unit, dmabuf); 1134 } 1135 1136 if (bst_info->post_sync) { 1137 bst_info->post_sync(unit, bid, sync_val); 1138 } 1139 1140 return BCM_E_NONE; 1141 } 1142 1143 int 1144 _bcm_bst_td3_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid, 1145 int port, int index) 1146 { 1147 return _bcm_bst_td3_sync_report(unit, bid, port, index, 1); 1148 } 1149 1150 /* 1151 * This function is used to enable and disable headroom 1152 * pool monitoring for given headroom pool index and pipe. 1153 */ 1154 STATIC int 1155 _bcm_td3_bst_hdrm_monitor_set(int unit, int hdrm_idx, 1156 int pipe, int enable) 1157 { 1158 int idx, idx_min, idx_max; 1159 uint32 rval, hdrm_pool_cfg; 1160 1161 if (pipe == -1) { 1162 /* Both Layer 0 and Layer 1 */ 1163 idx_min = 0; 1164 idx_max = NUM_LAYER(unit); 1165 } else if ((pipe == 0) || (pipe == 3)) { 1166 /* Layer 0 */ 1167 idx_min = 0; 1168 idx_max = 1; 1169 } else if ((pipe == 1) || (pipe == 2)) { 1170 /* Layer 1 */ 1171 idx_min = 1; 1172 idx_max = 2; 1173 } else { 1174 return BCM_E_PARAM; 1175 } 1176 1177 for (idx = idx_min; idx < idx_max; idx++) { 1178 BCM_IF_ERROR_RETURN 1179 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, idx, 0, &rval)); 1180 hdrm_pool_cfg = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval, 1181 PEAK_COUNT_UPDATE_EN_HPf); 1182 if (enable == 0x1) { 1183 hdrm_pool_cfg = hdrm_pool_cfg | (0x1 << hdrm_idx); 1184 } else { 1185 hdrm_pool_cfg = hdrm_pool_cfg & (~(0x1 << hdrm_idx)); 1186 } 1187 soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval, 1188 PEAK_COUNT_UPDATE_EN_HPf, hdrm_pool_cfg); 1189 BCM_IF_ERROR_RETURN 1190 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, idx, 0, rval)); 1191 } 1192 1193 return BCM_E_NONE; 1194 } 1195 1196 /* 1197 * This function is used to clear the hardware stat for 1198 * the headroom pool usage count for given [Port, Prio]. 1199 */ 1200 STATIC int 1201 _bcm_td3_bst_hdrm_hw_stat_clear(int unit, 1202 bcm_gport_t gport, 1203 bcm_cos_t cosq) 1204 { 1205 int i, j; 1206 uint32 rval, hdrm_pool_cfg[2]; 1207 _bcm_bst_cmn_unit_info_t *bst_info; 1208 _bcm_bst_resource_info_t *resInfo; 1209 int enable = 0x0; 1210 uint32 xpe_map = 0; 1211 int start_hw_index = 0, end_hw_index = 0, pipe = -1; 1212 soc_info_t *si = NULL; 1213 int bcm_rv; 1214 1215 resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 1216 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 1217 return BCM_E_PARAM; 1218 } 1219 1220 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1221 return BCM_E_INIT; 1222 } 1223 1224 if (gport == -1) { 1225 if (cosq == BCM_COS_INVALID) { 1226 pipe = -1; 1227 /* 4 Headroom Pool Ids */ 1228 start_hw_index = 0; 1229 end_hw_index = 3; 1230 xpe_map = 0xf; 1231 } else { 1232 return BCM_E_PARAM; 1233 } 1234 } else { 1235 if (bst_info->handlers.resolve_index == NULL) { 1236 return BCM_E_UNAVAIL; 1237 } 1238 1239 bst_info->handlers.resolve_index(unit, gport, cosq, 1240 bcmBstStatIdHeadroomPool, &pipe, 1241 &start_hw_index, &end_hw_index, 1242 NULL, NULL, &bcm_rv); 1243 if (bcm_rv) { 1244 return bcm_rv; 1245 } 1246 si = &SOC_INFO(unit); 1247 xpe_map = si->ipipe_xpe_map[pipe]; 1248 } 1249 1250 for (j = 0; j < NUM_LAYER(unit); j++) { 1251 rval = 0x0; 1252 BCM_IF_ERROR_RETURN 1253 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, j, 0, &rval)); 1254 hdrm_pool_cfg[j] = soc_reg_field_get(unit, THDI_HDRM_POOL_CFGr, rval, 1255 PEAK_COUNT_UPDATE_EN_HPf); 1256 } 1257 1258 for (i = start_hw_index; i <= end_hw_index; i++) { 1259 /* Disable hardware tracking the headroom pool */ 1260 enable = 0x0; 1261 BCM_IF_ERROR_RETURN 1262 (_bcm_td3_bst_hdrm_monitor_set(unit, i, pipe, enable)); 1263 1264 /* Reset Headroom Pool Peak Use-Count */ 1265 for (j = 0; j < NUM_XPE(unit); j++) { 1266 if (xpe_map & (1 << j)) { 1267 BCM_IF_ERROR_RETURN 1268 (soc_reg32_get(unit, resInfo->stat_reg[0], 1269 j, i, &rval)); 1270 soc_reg_field_set(unit, resInfo->stat_reg[0], &rval, 1271 resInfo->stat_field, 0x0); 1272 1273 BCM_IF_ERROR_RETURN 1274 (soc_reg32_set(unit, THDI_HDRM_POOL_PEAK_COUNT_HPr, 1275 j, i, rval)); 1276 } 1277 } 1278 1279 /* Enable hardware tracking the headroom pool */ 1280 enable = 0x1; 1281 BCM_IF_ERROR_RETURN 1282 (_bcm_td3_bst_hdrm_monitor_set(unit, i, pipe, enable)); 1283 } 1284 1285 for (j = 0; j < NUM_LAYER(unit); j++) { 1286 rval = 0x0; 1287 soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval, 1288 PEAK_COUNT_UPDATE_EN_HPf, hdrm_pool_cfg[j]); 1289 BCM_IF_ERROR_RETURN 1290 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, j, 0, rval)); 1291 } 1292 1293 return BCM_E_NONE; 1294 } 1295 1296 /* 1297 * This function is used to clear the software stat for 1298 * the headroom pool usage count for given [Port, Prio]. 1299 */ 1300 STATIC int 1301 _bcm_td3_bst_hdrm_sw_stat_clear(int unit, 1302 bcm_gport_t gport, 1303 bcm_cos_t cosq) 1304 { 1305 int i = 0, j = 0; 1306 _bcm_bst_resource_info_t *resInfo; 1307 _bcm_bst_cmn_unit_info_t *bst_info; 1308 uint32 xpe_map = 0; 1309 int start_hw_index = 0, end_hw_index = 0, pipe = -1; 1310 soc_info_t *si = NULL; 1311 int bcm_rv; 1312 1313 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1314 return BCM_E_INIT; 1315 } 1316 1317 resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 1318 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 1319 return BCM_E_PARAM; 1320 } 1321 1322 if (gport == -1) { 1323 if (cosq == BCM_COS_INVALID) { 1324 /* 4 Headroom Pool Ids */ 1325 start_hw_index = 0; 1326 end_hw_index = 3; 1327 xpe_map = 0xf; 1328 } else { 1329 return BCM_E_PARAM; 1330 } 1331 } else { 1332 if (bst_info->handlers.resolve_index == NULL) { 1333 return BCM_E_UNAVAIL; 1334 } 1335 1336 bst_info->handlers.resolve_index(unit, gport, cosq, 1337 bcmBstStatIdHeadroomPool, &pipe, 1338 &start_hw_index, &end_hw_index, 1339 NULL, NULL, &bcm_rv); 1340 if (bcm_rv) { 1341 return bcm_rv; 1342 } 1343 si = &SOC_INFO(unit); 1344 xpe_map = si->ipipe_xpe_map[pipe]; 1345 } 1346 1347 for (i = start_hw_index; i <= end_hw_index; i++) { 1348 for (j = 0; j < NUM_XPE(unit); j++) { 1349 if (xpe_map & (1 << j)) { 1350 resInfo->p_stat[i + j * NUM_XPE(unit)] = 0x0; 1351 } 1352 } 1353 } 1354 1355 return BCM_E_NONE; 1356 } 1357 1358 /* 1359 * This function is used to clear the software/hardware 1360 * stat for the headroom pool usage count for given [Port, Prio]. 1361 */ 1362 int 1363 _bcm_td3_bst_hdrm_stat_clear(int unit, 1364 bcm_gport_t gport, 1365 bcm_cos_queue_t cosq) 1366 { 1367 _bcm_bst_cmn_unit_info_t *bst_info; 1368 _bcm_bst_resource_info_t *resInfo; 1369 int bcm_rv = BCM_E_NONE; 1370 1371 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1372 return BCM_E_INIT; 1373 } 1374 1375 /* sync all the stats */ 1376 resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 1377 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 1378 return BCM_E_PARAM; 1379 } 1380 1381 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 1382 bcm_rv = _bcm_td3_bst_hdrm_sw_stat_clear(unit, gport, cosq); 1383 sal_mutex_give(bst_info->bst_reslock); 1384 if (BCM_FAILURE(bcm_rv)) { 1385 return bcm_rv; 1386 } 1387 1388 if (bst_info->track_mode) { 1389 /* BST tracking is in peak mode */ 1390 BCM_IF_ERROR_RETURN 1391 (_bcm_td3_bst_hdrm_hw_stat_clear(unit, gport, cosq)); 1392 } 1393 1394 return BCM_E_NONE; 1395 } 1396 1397 /* 1398 * This function is used to get the BST stat for 1399 * the headroom pool usage count from software cache. 1400 */ 1401 STATIC int 1402 _bcm_td3_cosq_bst_hdrm_stat_sw_get(int unit, 1403 bcm_gport_t gport, 1404 bcm_cos_t cosq, 1405 uint32 *max_hdrm_stat) 1406 { 1407 _bcm_bst_resource_info_t *resInfo; 1408 _bcm_bst_cmn_unit_info_t *bst_info; 1409 uint32 temp_stat = 0; 1410 int i = 0, j = 0; 1411 int start_hw_index = 0, end_hw_index = 0, pipe = -1; 1412 uint32 xpe_map = 0; 1413 soc_info_t *si = NULL; 1414 int bcm_rv; 1415 1416 resInfo = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 1417 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 1418 return BCM_E_PARAM; 1419 } 1420 1421 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1422 return BCM_E_INIT; 1423 } 1424 1425 if (gport == -1) { 1426 if (cosq == BCM_COS_INVALID) { 1427 xpe_map = 0xf; 1428 start_hw_index = 0; 1429 end_hw_index = 3; 1430 } else { 1431 return BCM_E_PARAM; 1432 } 1433 } else { 1434 if (bst_info->handlers.resolve_index == NULL) { 1435 return BCM_E_UNAVAIL; 1436 } 1437 1438 bst_info->handlers.resolve_index(unit, gport, cosq, 1439 bcmBstStatIdHeadroomPool, &pipe, 1440 &start_hw_index, &end_hw_index, 1441 NULL, NULL, &bcm_rv); 1442 if (bcm_rv) { 1443 return bcm_rv; 1444 } 1445 si = &SOC_INFO(unit); 1446 xpe_map = si->ipipe_xpe_map[pipe]; 1447 } 1448 1449 for (i = start_hw_index; i <= end_hw_index; i++) { 1450 for (j = 0; j < NUM_XPE(unit); j++) { 1451 if (xpe_map & (1 << j)) { 1452 temp_stat = resInfo->p_stat[i + (j * NUM_XPE(unit))]; 1453 if (temp_stat > *max_hdrm_stat) { 1454 *max_hdrm_stat = temp_stat; 1455 } 1456 } 1457 } 1458 } 1459 1460 return BCM_E_NONE; 1461 } 1462 1463 /* 1464 * This function is used to get the BST stat for 1465 * the headroom pool usage count for given [Port, Prio]. 1466 * Note: Regardless of tracking mode this function 1467 * returns max value of headroom pools. 1468 */ 1469 int 1470 _bcm_td3_cosq_bst_hdrm_stat_get(int unit, 1471 bcm_gport_t gport, 1472 bcm_cos_queue_t cosq, 1473 uint32 options, 1474 uint64 *pvalue) 1475 { 1476 uint32 max_hdrm_stat = 0; 1477 1478 if (pvalue == NULL) { 1479 return BCM_E_PARAM; 1480 } 1481 1482 COMPILER_64_ZERO(*pvalue); 1483 1484 BCM_IF_ERROR_RETURN 1485 (_bcm_td3_cosq_bst_hdrm_stat_sw_get(unit, gport, cosq, 1486 &max_hdrm_stat)); 1487 1488 /* Cell Size = 208 bytes */ 1489 COMPILER_64_ADD_32(*pvalue, 1490 (max_hdrm_stat * _TD3_MMU_BYTES_PER_CELL)); 1491 1492 if (options & BCM_COSQ_STAT_CLEAR) { 1493 BCM_IF_ERROR_RETURN 1494 (_bcm_td3_bst_hdrm_stat_clear(unit, gport, cosq)); 1495 } 1496 return BCM_E_NONE; 1497 } 1498 1499 /* Function to return the corresponding XPE instance for a given gport. 1500 * Direction(Ingress/Egress) is derived from bid type 1501 */ 1502 int _bst_td3_port_to_mmu_inst_map_get(int unit, bcm_bst_stat_id_t bid, 1503 bcm_gport_t gport, uint32 *mmu_inst_map) 1504 { 1505 soc_info_t *si = &SOC_INFO(unit); 1506 _bcm_bst_resource_info_t *resInfo; 1507 bcm_port_t local_port; 1508 bcm_module_t module; 1509 bcm_trunk_t trunk; 1510 int id, pipe; 1511 1512 resInfo = _BCM_BST_RESOURCE(unit, bid); 1513 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 1514 return BCM_E_PARAM; 1515 } 1516 1517 if (!BCM_GPORT_IS_SET(gport)) { 1518 if (!SOC_PORT_VALID(unit, gport)) { 1519 return BCM_E_PORT; 1520 } 1521 local_port = gport; 1522 } else { 1523 BCM_IF_ERROR_RETURN 1524 (_bcm_esw_gport_resolve(unit, gport, &module, 1525 &local_port, &trunk, &id)); 1526 } 1527 1528 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 1529 1530 if ((bid == bcmBstStatIdEgrPool) || (bid == bcmBstStatIdEgrMCastPool) || 1531 (bid == bcmBstStatIdUcast) || (bid == bcmBstStatIdMcast) || 1532 (bid == bcmBstStatIdRQEQueue) || (bid == bcmBstStatIdRQEPool) || 1533 (bid == bcmBstStatIdUCQueueGroup)) { 1534 /* For Egress Res, 1535 * Pipe 0,1 has XPE 0,2 1536 * Pipe 2,3 has XPE 1,3 1537 */ 1538 *mmu_inst_map = si->epipe_xpe_map[pipe]; 1539 } else if ((bid == bcmBstStatIdIngPool) || (bid == bcmBstStatIdPortPool) || 1540 (bid == bcmBstStatIdPriGroupShared) || 1541 (bid == bcmBstStatIdPriGroupHeadroom)) { 1542 /* For Ingress Res, 1543 * Pipe 0,3 has XPE 0,1 1544 * Pipe 1,2 has XPE 2,3 1545 */ 1546 *mmu_inst_map = si->ipipe_xpe_map[pipe]; 1547 } else { 1548 /* For Global res, return all instance */ 1549 *mmu_inst_map = (1 << NUM_XPE(unit)) - 1; 1550 } 1551 1552 return BCM_E_NONE; 1553 } 1554 1555 int _bst_td3_thd_reg_index_get(int unit, bcm_bst_stat_id_t bid, int pipe, 1556 int hw_index, int *inst, int *index) 1557 { 1558 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 1559 int phy_port, mmu_port, mmu_port_base; 1560 soc_info_t *si = &SOC_INFO(unit); 1561 1562 mmu_port_base = SOC_TD3_MMU_PORT_PER_PIPE * pipe; 1563 mmu_port = hw_index / _TD3_MMU_NUM_POOL; 1564 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 1565 *inst = si->port_p2l_mapping[phy_port]; 1566 *index = hw_index % _TD3_MMU_NUM_POOL; 1567 } 1568 1569 return BCM_E_NONE; 1570 } 1571 1572 int _bst_td3_cmn_io_op(int unit, int op, int pipe, int hw_index, 1573 bcm_bst_stat_id_t bid, soc_mem_t mem, soc_reg_t reg, 1574 soc_field_t field, uint32 *resval) 1575 { 1576 uint32 entry[SOC_MAX_MEM_WORDS], rval; 1577 int port = REG_PORT_ANY, reg_index = hw_index; 1578 _bcm_bst_resource_info_t *resInfo; 1579 1580 resInfo = _BCM_BST_RESOURCE(unit, bid); 1581 if ((resInfo->flags & _BCM_BST_CMN_RES_F_PORTED) && 1582 (op & BST_OP_THD)) { 1583 BCM_IF_ERROR_RETURN( 1584 _bst_td3_thd_reg_index_get(unit, bid, pipe, hw_index, 1585 &port, ®_index)); 1586 } 1587 1588 if (mem != INVALIDm) { 1589 SOC_IF_ERROR_RETURN( 1590 soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, entry)); 1591 if (op & BST_OP_GET) { 1592 *resval = soc_mem_field32_get(unit, mem, entry, field); 1593 } else if (op & BST_OP_SET) { 1594 soc_mem_field32_set(unit, mem, entry, field, *resval); 1595 SOC_IF_ERROR_RETURN( 1596 soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, entry)); 1597 } 1598 } else if (reg != INVALIDr) { 1599 SOC_IF_ERROR_RETURN( 1600 soc_reg32_get(unit, reg, port, reg_index, &rval)); 1601 if (op & BST_OP_GET) { 1602 *resval = soc_reg_field_get(unit, reg, rval, field); 1603 } else if (op & BST_OP_SET) { 1604 if (*resval >= (1 << soc_reg_field_length(unit, reg, field))) { 1605 return BCM_E_PARAM; 1606 } 1607 soc_reg_field_set(unit, reg, &rval, field, *resval); 1608 SOC_IF_ERROR_RETURN( 1609 soc_reg32_set(unit, reg, port, reg_index, rval)); 1610 } 1611 } 1612 1613 return BCM_E_NONE; 1614 } 1615 1616 int 1617 _bst_td3_sbusdma_desc_setup(int unit) 1618 { 1619 _bcm_bst_cmn_unit_info_t *bst_info; 1620 _bcm_bst_resource_info_t *resInfo; 1621 _bcm_bst_tbl_ctrl_t *tbl_ctrl; 1622 int blk, bid, pipe, mi, pipe_factor; 1623 uint8 acc_type; 1624 soc_mem_t mem, base_mem; 1625 soc_reg_t reg; 1626 uint32 size; 1627 uint8 *buff = NULL; 1628 _bcm_bst_tbl_desc_t *desc = NULL; 1629 int stats_per_inst = 0; 1630 int idx_count = 0; 1631 int xpe = 0; 1632 int stat_idx = 0; 1633 int inst = 0; 1634 1635 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1636 return BCM_E_INIT; 1637 } 1638 buff = bst_info->bst_tbl_buf; 1639 bst_tbl_ctrl[unit] = sal_alloc(bcmBstStatIdMaxCount * 1640 sizeof(_bcm_bst_tbl_ctrl_t *), 1641 "bst_tbl_ctrl_p"); 1642 if (bst_tbl_ctrl[unit] == NULL) { 1643 return BCM_E_MEMORY; 1644 } 1645 1646 bst_info->bst_tbl_desc = sal_alloc(bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t), 1647 "bst_tbl_desc_p"); 1648 if (bst_info->bst_tbl_desc == NULL) { 1649 return BCM_E_MEMORY; 1650 } 1651 sal_memset(bst_info->bst_tbl_desc, 0, bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t)); 1652 desc = bst_info->bst_tbl_desc; 1653 1654 mi = 0; 1655 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 1656 resInfo = _BCM_BST_RESOURCE(unit, bid); 1657 if (resInfo == NULL) { 1658 return BCM_E_PARAM; 1659 } 1660 1661 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 1662 continue; 1663 } 1664 1665 tbl_ctrl = sal_alloc(sizeof(_bcm_bst_tbl_ctrl_t), "bst_tbl_ctrl"); 1666 if (tbl_ctrl == NULL) { 1667 return BCM_E_MEMORY; 1668 } 1669 pipe_factor = 1; 1670 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 1671 pipe_factor = NUM_PIPE(unit)/2; 1672 } 1673 size = 0; 1674 tbl_ctrl->tindex = bid; 1675 tbl_ctrl->entries = resInfo->num_instance * pipe_factor; 1676 tbl_ctrl->buff = buff; 1677 tbl_ctrl->size = 0; 1678 bst_tbl_ctrl[unit][bid] = tbl_ctrl; 1679 1680 base_mem = resInfo->stat_mem[0]; 1681 reg = resInfo->stat_reg[0]; 1682 if (reg != INVALIDr) { 1683 stats_per_inst = resInfo->num_stat_pp / resInfo->num_instance; 1684 for (xpe = 0; xpe < resInfo->num_instance; xpe++) { 1685 if (stats_per_inst) { 1686 inst = xpe ; 1687 stat_idx = 0; 1688 } else { 1689 inst = REG_PORT_ANY; 1690 stat_idx = xpe; 1691 stats_per_inst = 1; 1692 } 1693 desc[mi].reg = reg; 1694 desc[mi].addr = soc_reg_addr_get(unit, reg, inst, stat_idx, 1695 SOC_REG_ADDR_OPTION_NONE, &blk, 1696 &acc_type); 1697 desc[mi].flags = 0; 1698 desc[mi].acc_type = acc_type; 1699 desc[mi].blk = blk; 1700 desc[mi].width = BYTES2WORDS(soc_reg_bytes(unit, reg)); 1701 desc[mi].entries= stats_per_inst; 1702 desc[mi].shift = 8; 1703 size += desc[mi].entries * desc[mi].width * 4; 1704 tbl_ctrl->blk = desc[mi].blk; 1705 mi++; 1706 } 1707 } else if (base_mem != INVALIDm) { 1708 idx_count = 0; 1709 1710 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0); 1711 if (mem == INVALIDm) { 1712 return BCM_E_PARAM; 1713 } 1714 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 1715 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1716 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe); 1717 if (mem == INVALIDm) { 1718 continue; 1719 } 1720 idx_count = soc_mem_index_max(unit, mem) + 1; 1721 desc[mi].mem = mem; 1722 desc[mi].flags = SOC_SBUSDMA_CFG_COUNTER_IS_MEM | SOC_SBUSDMA_CFG_USE_FLAGS; 1723 desc[mi].blk = SOC_MEM_BLOCK_ANY(unit, mem); 1724 desc[mi].addr = soc_mem_addr_get(unit, mem, 1725 0, desc[mi].blk, 0, &acc_type); 1726 desc[mi].acc_type = acc_type; 1727 desc[mi].blk = SOC_BLOCK2SCH(unit, desc[mi].blk); 1728 desc[mi].width = soc_mem_entry_words(unit, mem); 1729 desc[mi].entries = idx_count; 1730 desc[mi].shift = 0; 1731 size += desc[mi].entries * desc[mi].width * 4; 1732 tbl_ctrl->blk = desc[mi].blk; 1733 mi++; 1734 } 1735 } 1736 } 1737 buff += size; 1738 tbl_ctrl->size += size; 1739 } 1740 1741 return BCM_E_NONE; 1742 } 1743 1744 int 1745 _bcm_bst_td3_sbusdma_desc_init(int unit) 1746 { 1747 _bcm_bst_cmn_unit_info_t *bst_info; 1748 _bcm_bst_resource_info_t *resInfo; 1749 int pipe, bid, mi; 1750 soc_mem_t mem, base_mem; 1751 soc_reg_t reg; 1752 uint32 entries, width, size = 0; 1753 int xpe = 0; 1754 int rv = BCM_E_INIT; 1755 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1756 return BCM_E_INIT; 1757 } 1758 mi = 0; 1759 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 1760 resInfo = _BCM_BST_RESOURCE(unit, bid); 1761 if (resInfo == NULL) { 1762 return BCM_E_PARAM; 1763 } 1764 1765 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 1766 continue; 1767 } 1768 1769 base_mem = resInfo->stat_mem[0]; 1770 reg = resInfo->stat_reg[0]; 1771 if (reg != INVALIDr) { 1772 for (xpe = 0; xpe < resInfo->num_instance; xpe++) { 1773 entries = resInfo->num_stat_pp / resInfo->num_instance; 1774 width = BYTES2WORDS(soc_reg_bytes(unit, reg)); 1775 size += entries * width * 4; 1776 mi++; 1777 } 1778 } else if (base_mem != INVALIDm) { 1779 int idx_count = 0; 1780 1781 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0); 1782 if (mem == INVALIDm) { 1783 return BCM_E_PARAM; 1784 } 1785 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 1786 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1787 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe); 1788 if (mem == INVALIDm) { 1789 continue; 1790 } 1791 idx_count = soc_mem_index_max(unit, mem) + 1; 1792 entries = idx_count; 1793 width = soc_mem_entry_words(unit, mem); 1794 size += entries * width * 4; 1795 mi++; 1796 } 1797 } 1798 } 1799 } 1800 bst_info->bst_tbl_size = size; 1801 bst_info->bst_tbl_num = mi; 1802 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1803 (BSL_META_U(unit, 1804 "Total bst tbls: %d, Total size: %d\n"), 1805 bcmBstStatIdMaxCount, size)); 1806 bst_tbl_handles[unit] = 0; 1807 if (bst_info->bst_tbl_buf == NULL) { 1808 bst_info->bst_tbl_buf = soc_cm_salloc(unit, size, "bst_tbl_buf"); 1809 if (bst_info->bst_tbl_buf == NULL) { 1810 goto error; 1811 } 1812 } 1813 sal_memset(bst_info->bst_tbl_buf, 0, size); 1814 rv =_bst_td3_sbusdma_desc_setup(unit); 1815 if (rv != SOC_E_NONE) { 1816 goto error; 1817 } 1818 1819 rv = soc_bst_sbusdma_desc_setup(unit); 1820 if (rv != SOC_E_NONE) { 1821 goto error; 1822 } 1823 return BCM_E_NONE; 1824 error: 1825 if (bst_info->bst_tbl_buf) { 1826 soc_cm_sfree(unit, bst_info->bst_tbl_buf); 1827 bst_info->bst_tbl_buf = NULL; 1828 } 1829 if (bst_info->bst_tbl_desc) { 1830 sal_free(bst_info->bst_tbl_desc); 1831 bst_info->bst_tbl_desc = NULL; 1832 } 1833 rv = soc_bst_sbusdma_desc_free(unit); 1834 return rv; 1835 } 1836 1837 1838 int 1839 _bcm_bst_td3_sbusdma_desc_deinit(int unit) 1840 { 1841 _bcm_bst_cmn_unit_info_t *bst_info; 1842 int rv = BCM_E_INIT; 1843 1844 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1845 return BCM_E_INIT; 1846 } 1847 1848 if (bst_info->bst_tbl_buf) { 1849 soc_cm_sfree(unit, bst_info->bst_tbl_buf); 1850 bst_info->bst_tbl_buf = NULL; 1851 } 1852 if (bst_info->bst_tbl_desc) { 1853 sal_free(bst_info->bst_tbl_desc); 1854 bst_info->bst_tbl_desc = NULL; 1855 } 1856 1857 rv = soc_bst_sbusdma_desc_free(unit); 1858 if (rv != BCM_E_NONE) { 1859 return rv; 1860 } 1861 1862 return BCM_E_NONE; 1863 } 1864 1865 int 1866 _bst_td3_sw_sbusdma_desc_sync(int unit, int bid) 1867 { 1868 _bcm_bst_cmn_unit_info_t *bst_info; 1869 _bcm_bst_resource_info_t *resInfo; 1870 _bcm_bst_tbl_ctrl_t *tbl_ctrl; 1871 int idx, idx_offset, xpe, xpe_offset, pipe, pipe_offset = 0; 1872 void *pentry; 1873 uint32 rval, temp_val; 1874 uint8 *buff = NULL; 1875 soc_mem_t mem, base_mem; 1876 soc_reg_t reg; 1877 uint32 width = 0; 1878 bcm_gport_t gport = -1; 1879 bcm_cos_t cosq = -1; 1880 int port = -1; 1881 1882 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1883 sal_mutex_give(bst_info->bst_reslock); 1884 return BCM_E_INIT; 1885 } 1886 if (!bst_tbl_ctrl[unit][bid]) { 1887 sal_mutex_give(bst_info->bst_reslock); 1888 return BCM_E_INIT; 1889 } 1890 tbl_ctrl = bst_tbl_ctrl[unit][bid]; 1891 buff = tbl_ctrl->buff; 1892 resInfo = _BCM_BST_RESOURCE(unit, bid); 1893 if (resInfo == NULL) { 1894 sal_mutex_give(bst_info->bst_reslock); 1895 return BCM_E_PARAM; 1896 } 1897 1898 base_mem = resInfo->stat_mem[0]; 1899 reg = resInfo->stat_reg[0]; 1900 if (reg != INVALIDr) { 1901 pipe_offset = 0; 1902 for (idx = 0; idx < resInfo->num_stat_pp; idx++) { 1903 rval = 0; 1904 width = BYTES2WORDS(soc_reg_bytes(unit, reg)); 1905 idx_offset = idx + pipe_offset; 1906 sal_memcpy(&rval, buff, width * 4); 1907 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field); 1908 if (bst_info->track_mode) { 1909 /* BST tracking is in Peak mode. 1910 * Hence store the watermark value only. 1911 */ 1912 if (resInfo->p_stat[idx_offset] < temp_val) { 1913 resInfo->p_stat[idx_offset] = temp_val; 1914 } 1915 } else { 1916 resInfo->p_stat[idx_offset] = temp_val; 1917 } 1918 buff = buff + width * 4; 1919 1920 /* Check if there exists threshold for a resource 1921 * continue if we don't have one */ 1922 if (resInfo->p_threshold == NULL) { 1923 continue; 1924 } 1925 1926 /* coverity[copy_paste_error : FALSE] */ 1927 if (resInfo->p_threshold[idx_offset] && 1928 (resInfo->p_stat[idx_offset] >= 1929 (resInfo->p_threshold[idx_offset] * resInfo->threshold_gran) 1930 )) { 1931 /* Generate SOC EVENT */ 1932 if (bst_info->handlers.reverse_resolve_index) { 1933 /* reverse map the inedx to port/cos pair */ 1934 bst_info->handlers.reverse_resolve_index(unit, bid, 1935 port, idx_offset, 1936 &gport, &cosq); 1937 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 1938 bid, gport, cosq); 1939 } 1940 } 1941 1942 } 1943 } else if (base_mem != INVALIDm) { 1944 int max_idx = 0; 1945 int stats_per_pipe = 0; /* stats per pipe per mem-instance(xpe) */ 1946 int stats_per_inst = 0; 1947 1948 /* Get the mem attributes(Max idx) from the first child, 1949 * which could be used for other instances. 1950 * Note: In TD3, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 1951 */ 1952 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, 0, 0); 1953 1954 if (mem == INVALIDm) { 1955 sal_mutex_give(bst_info->bst_reslock); 1956 return BCM_E_PARAM; 1957 } 1958 stats_per_inst = (resInfo->index_max + 1) / resInfo->num_instance; 1959 stats_per_pipe = stats_per_inst / NUM_PIPE(unit); 1960 max_idx = soc_mem_index_max(unit, mem); 1961 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 1962 xpe_offset = 0; 1963 gport = BCM_GPORT_INVALID; 1964 cosq = -1; 1965 if (xpe) { 1966 xpe_offset = stats_per_inst * xpe; 1967 } 1968 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1969 pipe_offset = 0; 1970 if (pipe) { 1971 pipe_offset = stats_per_pipe * pipe; 1972 } 1973 mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, base_mem, xpe, pipe); 1974 if (mem == INVALIDm) { 1975 continue; 1976 } 1977 1978 for (idx = 0; idx < max_idx; idx++) { 1979 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 1980 /* 1981 * Reorder sw stat index 1982 * HW stat: index 0 - port 0 pool 0 1983 * index 1 - port 1 pool 0 1984 * index 2 - port 2 pool 0 1985 * ... 1986 * index n - port n%34 pool n/34 1987 * SW stat: index 0 - port 0 pool 0 1988 * index 1 - port 0 pool 1 1989 * index 2 - port 0 pool 2 1990 * ... 1991 * index n - port n/4 pool n%4 1992 */ 1993 /* coverity[parameter_hidden: FALSE] */ 1994 int port, pool; 1995 port = idx % _TD3_MMU_PORTS_PER_PIPE; 1996 pool = idx / _TD3_MMU_PORTS_PER_PIPE; 1997 idx_offset = port * _TD3_MMU_NUM_POOL + pool + 1998 pipe_offset + xpe_offset; 1999 } else { 2000 idx_offset = idx + pipe_offset + xpe_offset; 2001 } 2002 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 2003 buff, idx); 2004 temp_val = soc_mem_field32_get(unit, mem, pentry, 2005 resInfo->stat_field); 2006 if (bst_info->track_mode) { 2007 /* BST tracking is in Peak mode. 2008 * Hence store the watermark value only. 2009 */ 2010 if (resInfo->p_stat[idx_offset] < temp_val) { 2011 resInfo->p_stat[idx_offset] = temp_val; 2012 } 2013 } else { 2014 resInfo->p_stat[idx_offset] = temp_val; 2015 } 2016 2017 if (resInfo->p_threshold[idx_offset] && 2018 (resInfo->p_stat[idx_offset] >= 2019 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 2020 /* Generate SOC EVENT */ 2021 if (bst_info->handlers.reverse_resolve_index) { 2022 /* reverse map the inedx to port/cos pair */ 2023 bst_info->handlers.reverse_resolve_index(unit, bid, 2024 port, idx_offset, 2025 &gport, &cosq); 2026 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 2027 bid, gport, cosq); 2028 2029 } 2030 } 2031 } 2032 buff += tbl_ctrl->size / tbl_ctrl->entries; 2033 } 2034 } 2035 } 2036 2037 return BCM_E_NONE; 2038 } 2039 2040 2041 int 2042 _bcm_bst_td3_sbusdma_desc_sync(int unit) 2043 { 2044 _bcm_bst_cmn_unit_info_t *bst_info; 2045 _bcm_bst_resource_info_t *resInfo; 2046 bcm_bst_stat_id_t bid; 2047 int enable = 0; 2048 2049 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2050 return BCM_E_INIT; 2051 } 2052 2053 if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) { 2054 return BCM_E_NONE; 2055 } 2056 2057 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 2058 2059 if (bst_info->control_get) { 2060 bst_info->control_get(unit, bcmSwitchBstEnable, &enable); 2061 } 2062 2063 if (enable && bst_info->control_set) { 2064 bst_info->control_set(unit, bcmSwitchBstEnable, 0, 2065 _bcmBstThreadOperInternal); 2066 } 2067 2068 BCM_IF_ERROR_RETURN(soc_bst_hw_sbusdma_desc_sync(unit)); 2069 2070 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 2071 resInfo = _BCM_BST_RESOURCE(unit, bid); 2072 if (resInfo == NULL) { 2073 return BCM_E_PARAM; 2074 } 2075 2076 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 2077 continue; 2078 } 2079 2080 BCM_IF_ERROR_RETURN(_bst_td3_sw_sbusdma_desc_sync(unit, bid)); 2081 } 2082 2083 if (enable && bst_info->control_set) { 2084 bst_info->control_set(unit, bcmSwitchBstEnable, enable, 2085 _bcmBstThreadOperInternal); 2086 } 2087 2088 sal_mutex_give(bst_info->bst_reslock); 2089 return BCM_E_NONE; 2090 } 2091 2092 2093 2094 int 2095 bcm_bst_td3_init(int unit) 2096 { 2097 _bcm_bst_cmn_unit_info_t *bst_info; 2098 _bcm_bst_resource_info_t *pres; 2099 int idx_count, i; 2100 /* stat count and thd count need not be same. 2101 * stat_count - Acc Type of stat are Non Dup, hence stat is for all ACC type 2102 * thd_count - Acc Type of Thd are Dup(except CFAP), hence 1 copy. 2103 */ 2104 int total_stat_count, total_thd_count; 2105 soc_mem_t stat_mem = INVALIDm, child_mem = INVALIDm, thd_mem = INVALIDm; 2106 soc_reg_t stat_reg = INVALIDr, thd_reg = INVALIDr, prof_reg = INVALIDr; 2107 soc_field_t stat_field = INVALIDf, thd_field = INVALIDf, prof_field = INVALIDf; 2108 int layer = 0, granularity = 1; 2109 uint32 rval; 2110 2111 bst_info = _BCM_UNIT_BST_INFO(unit); 2112 if (!bst_info) { 2113 return BCM_E_MEMORY; 2114 } 2115 2116 bst_info->max_bytes = 0x500000; 2117 bst_info->to_cell = _bcm_bst_td3_byte_to_cell; 2118 bst_info->to_byte = _bcm_bst_td3_cell_to_byte; 2119 bst_info->control_set = _bcm_td3_bst_control_set; 2120 bst_info->control_get = _bcm_td3_bst_control_get; 2121 bst_info->intr_to_resources = _bcm_bst_td3_intr_to_resources; 2122 bst_info->hw_stat_snapshot = _bcm_bst_td3_sync_hw_snapshot; 2123 bst_info->hw_stat_clear = _bcm_bst_td3_hw_stat_clear; 2124 bst_info->intr_enable_set = _bcm_bst_td3_intr_enable_set; 2125 bst_info->pre_sync = NULL; 2126 bst_info->post_sync = NULL; 2127 bst_info->hw_intr_cb = soc_td3_set_hw_intr_cb; 2128 bst_info->port_to_mmu_inst_map = _bst_td3_port_to_mmu_inst_map_get; 2129 bst_info->bst_cmn_io_op = _bst_td3_cmn_io_op; 2130 bst_info->hw_sbusdma_desc_init = _bcm_bst_td3_sbusdma_desc_init; 2131 bst_info->hw_sbusdma_desc_deinit = _bcm_bst_td3_sbusdma_desc_deinit; 2132 bst_info->hw_sbusdma_desc_sync = _bcm_bst_td3_sbusdma_desc_sync; 2133 if(soc_property_get(unit, spn_PROFILE_PG_1HDRM_8SHARED, 1)) { 2134 bst_info->mode = 1; 2135 } else { 2136 bst_info->mode = 0; 2137 } 2138 2139 /* DEVICE - Resources begin */ 2140 /* bcmBstStatIdDevice */ 2141 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice); 2142 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2143 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV); 2144 pres->num_instance = NUM_XPE(unit); 2145 idx_count = 1; 2146 stat_mem = INVALIDm; 2147 stat_reg = CFAPBSTSTATr; 2148 stat_field = BST_STATf; 2149 2150 /* Threshold info count and Resource allocation */ 2151 granularity = 1; 2152 total_thd_count = NUM_XPE(unit) * idx_count; 2153 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf, 2154 granularity); 2155 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst cfap"); 2156 /* Stat info count and Resource allocation */ 2157 total_stat_count = total_thd_count; /* No per pipe copy */ 2158 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2159 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst cfap"); 2160 pres->index_min = 0; 2161 pres->index_max = total_stat_count - 1; 2162 /* DEVICE - Resources end */ 2163 2164 /* INGRESS - Resources begin */ 2165 /* bcmBstStatIdHeadroomPool */ 2166 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdHeadroomPool); 2167 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2168 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING); 2169 pres->num_instance = NUM_XPE(unit); 2170 /* There are 4 HDRM POOL per XPE */ 2171 idx_count = _TD3_MMU_NUM_POOL; 2172 stat_mem = INVALIDm; 2173 BCM_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 2174 bst_info->track_mode = soc_reg_field_get(unit, MMU_GCFG_MISCCONFIGr, 2175 rval, BST_TRACKING_MODEf); 2176 /* 2177 * As Headroom Pool has two different stats resource 2178 * for tracking current usage count and peak usage count 2179 * we set up the respective resource accordingly based on 2180 * BST Tracking Mode 2181 */ 2182 if (bst_info->track_mode) { 2183 /* Peak Mode */ 2184 stat_reg = THDI_HDRM_POOL_PEAK_COUNT_HPr; 2185 stat_field = PEAK_BUFFER_COUNTf; 2186 } else { 2187 /* Current Mode */ 2188 stat_reg = THDI_HDRM_POOL_COUNT_HPr; 2189 stat_field = TOTAL_BUFFER_COUNTf; 2190 } 2191 2192 /* Disabling the headroom Pool monitoring during init */ 2193 for (layer = 0; layer < NUM_LAYER(unit); layer++) { 2194 BCM_IF_ERROR_RETURN 2195 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, layer, 0, 0x0)); 2196 } 2197 2198 /* Stat info count and Resource allocation */ 2199 total_stat_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */ 2200 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2201 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ing headroom pool"); 2202 pres->index_min = 0; 2203 pres->index_max = total_stat_count - 1; 2204 2205 2206 /* bcmBstStatIdIngPool */ 2207 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool); 2208 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2209 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING); 2210 pres->num_instance = NUM_XPE(unit); 2211 idx_count = 4; 2212 stat_mem = INVALIDm; 2213 stat_reg = THDI_BST_SP_GLOBAL_SHARED_CNTr; 2214 stat_field = SP_GLOBAL_SHARED_CNTf; 2215 2216 /* Threshold info count and Resource allocation */ 2217 granularity = 1; 2218 total_thd_count = idx_count; /* Acc type is Duplicate, hence 1 copy */ 2219 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 2220 THDI_BST_SP_GLOBAL_SHARED_PROFILEr, 2221 SP_GLOBAL_SHARED_PROFILEf, granularity); 2222 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst ing pool"); 2223 /* Stat info count and Resource allocation */ 2224 total_stat_count = NUM_XPE(unit) * total_thd_count; /* No per pipe copy */ 2225 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2226 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ing pool"); 2227 pres->index_min = 0; 2228 pres->index_max = total_stat_count - 1; 2229 2230 /* bcmBstStatIdPortPool */ 2231 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool); 2232 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2233 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2234 _BCM_BST_CMN_RES_F_PIPED | 2235 _BCM_BST_CMN_RES_F_RES_ING); 2236 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 2237 pres->num_instance = NUM_XPE(unit); 2238 stat_mem = THDI_PORT_SP_BSTm; 2239 stat_reg = INVALIDr; 2240 stat_field = SP_BST_STAT_PORT_COUNTf; 2241 2242 /* Get the mem attributes(Max idx) from the first child, 2243 * which could be used for other instances. 2244 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2245 */ 2246 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2247 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2248 2249 /* Threshold info count and Resource allocation */ 2250 granularity = 1; 2251 total_thd_count = NUM_PIPE(unit) * idx_count; 2252 thd_mem = THDI_PORT_SP_CONFIGm; 2253 thd_field = SP_BST_PROFILE_SHAREDf; 2254 for (i = 0; i < NUM_PIPE(unit); i++) { 2255 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2256 INVALIDr, thd_field, granularity, i); 2257 } 2258 _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_SP_SHARED_PROFILEr, 2259 BST_SP_SHARED_THRESHf); 2260 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst port pool"); 2261 /* Stat info count and Resource allocation */ 2262 total_stat_count = NUM_XPE(unit) * total_thd_count; 2263 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, stat_reg, stat_reg, stat_field); 2264 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst port pool"); 2265 pres->index_min = 0; 2266 pres->index_max = total_stat_count - 1; 2267 2268 /* bcmBstStatIdPriGroupShared */ 2269 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared); 2270 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2271 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2272 _BCM_BST_CMN_RES_F_PIPED | 2273 _BCM_BST_CMN_RES_F_RES_ING); 2274 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 2275 pres->num_instance = NUM_XPE(unit); 2276 stat_mem = THDI_PORT_PG_BSTm; 2277 stat_reg = INVALIDr; 2278 stat_field = PG_BST_STAT_SHAREDf; 2279 idx_count = NUM_PORT(unit) * 8; 2280 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2281 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2282 2283 /* Threshold info count and Resource allocation */ 2284 granularity = 1; 2285 total_thd_count = idx_count * NUM_PIPE(unit); 2286 thd_mem = THDI_PORT_PG_CONFIGm; 2287 thd_field = PG_BST_PROFILE_SHAREDf; 2288 for (i = 0; i < NUM_PIPE(unit); i++) { 2289 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2290 INVALIDr, thd_field, granularity, i); 2291 } 2292 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 2293 THDI_BST_PG_SHARED_PROFILEr, BST_PG_SHARED_THRESHf); 2294 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst pg"); 2295 /* Stat info count and Resource allocation */ 2296 /* Stat res - THDI_PORT_PG_BST : (Num Ports (32/pipe) * 4 pipes) * 8(PGs) */ 2297 total_stat_count = NUM_XPE(unit) * total_thd_count; 2298 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2299 stat_reg, stat_reg, stat_field); 2300 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst pg"); 2301 pres->index_min = 0; 2302 pres->index_max = total_stat_count - 1; 2303 2304 /* bcmBstStatIdPriGroupHeadroom */ 2305 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom); 2306 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2307 pres->num_instance = NUM_XPE(unit); 2308 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2309 _BCM_BST_CMN_RES_F_PIPED | 2310 _BCM_BST_CMN_RES_F_RES_ING); 2311 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 2312 stat_mem = THDI_PORT_PG_BSTm; 2313 stat_reg = INVALIDr; 2314 stat_field = PG_BST_STAT_HDRMf; 2315 idx_count = NUM_PORT(unit) * 8; 2316 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2317 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2318 2319 /* Threshold info count and Resource allocation */ 2320 granularity = 1; 2321 total_thd_count = idx_count * NUM_PIPE(unit); 2322 thd_mem = THDI_PORT_PG_CONFIGm; 2323 thd_field = PG_BST_PROFILE_HDRMf; 2324 for (i = 0; i < NUM_PIPE(unit); i++) { 2325 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2326 INVALIDr, thd_field, granularity, i); 2327 } 2328 _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_PG_HDRM_PROFILEr, 2329 BST_PG_HDRM_THRESHf); 2330 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst pg hdrm"); 2331 /* Stat info count and Resource allocation */ 2332 /* Stat res - THDI_PORT_PG_BST : (Num Ports (32/pipe) * 4 pipes) * 8(PGs) */ 2333 total_stat_count = NUM_XPE(unit) * total_thd_count; 2334 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2335 stat_reg, stat_reg, stat_field); 2336 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst pg hdrm"); 2337 pres->index_min = 0; 2338 pres->index_max = total_stat_count - 1; 2339 /* INGRESS - Resources end */ 2340 2341 /* EGRESS - Resources begin */ 2342 /* bcmBstStatIdEgrPool */ 2343 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool); 2344 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2345 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 2346 pres->num_instance = NUM_XPE(unit); 2347 idx_count = 4; 2348 pres->threshold_adj = -1; 2349 stat_mem = INVALIDm; 2350 stat_reg = MMU_THDM_DB_POOL_MCUC_BST_STATr; 2351 stat_field = BST_STATf; 2352 2353 /* Threshold info count and Resource allocation */ 2354 granularity = 1; 2355 total_thd_count = idx_count; /* No per pipe copy */ 2356 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 2357 MMU_THDM_DB_POOL_MCUC_BST_THRESHOLDr, BST_STATf, 2358 granularity); 2359 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst egrpool"); 2360 /* Stat info count and Resource allocation */ 2361 total_stat_count = NUM_XPE(unit) * total_thd_count; /* No per pipe copy */ 2362 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2363 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst egrpool"); 2364 pres->index_min = 0; 2365 pres->index_max = total_stat_count - 1; 2366 2367 /* bcmBstStatIdEgrMCastPool */ 2368 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool); 2369 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2370 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 2371 pres->num_instance = NUM_XPE(unit); 2372 idx_count = 4; 2373 pres->threshold_adj = -1; 2374 stat_mem = INVALIDm; 2375 stat_reg = MMU_THDM_DB_POOL_MC_BST_STATr; 2376 stat_field = BST_STATf; 2377 2378 /* Threshold info count and Resource allocation */ 2379 granularity = 1; 2380 total_thd_count = idx_count; /* No per pipe copy */ 2381 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 2382 MMU_THDM_DB_POOL_MC_BST_THRESHOLDr, BST_STATf, 2383 granularity); 2384 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst egr mcpool"); 2385 /* Stat info count and Resource allocation */ 2386 total_stat_count = NUM_XPE(unit) * total_thd_count; /* No per pipe copy */ 2387 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2388 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst egr mcpool"); 2389 pres->index_min = 0; 2390 pres->index_max = total_stat_count - 1; 2391 2392 /* bcmBstStatIdMcast */ 2393 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast); 2394 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2395 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2396 _BCM_BST_CMN_RES_F_PIPED | 2397 _BCM_BST_CMN_RES_F_RES_EGR); 2398 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit)); 2399 pres->num_instance = NUM_XPE(unit); 2400 stat_mem = MMU_THDM_DB_QUEUE_BSTm; 2401 stat_reg = INVALIDr; 2402 stat_field = Q_COUNTf; 2403 2404 /* Get the mem attributes(Max idx) from the first child, 2405 * which could be used for other instances. 2406 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2407 */ 2408 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2409 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2410 2411 /* Threshold info count and Resource allocation */ 2412 granularity = 1; 2413 total_thd_count = NUM_PIPE(unit) * idx_count; 2414 thd_mem = MMU_THDM_DB_QUEUE_CONFIGm; 2415 thd_field = BST_THRESHOLD_PROFILEf; 2416 for (i = 0; i < NUM_PIPE(unit); i++) { 2417 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2418 INVALIDr, thd_field, granularity, i); 2419 } 2420 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 2421 MMU_THDM_DB_QUEUE_MC_BST_THRESHOLD_PROFILEr, BST_STATf); 2422 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst mcast"); 2423 /* Stat info count and Resource allocation */ 2424 total_stat_count = NUM_XPE(unit) * total_thd_count; 2425 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2426 stat_reg, stat_reg, stat_field); 2427 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst mcast"); 2428 pres->index_min = 0; 2429 pres->index_max = total_stat_count - 1; 2430 2431 /* bcmBstStatIdEgrPortPoolSharedMcast */ 2432 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedMcast); 2433 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2434 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2435 _BCM_BST_CMN_RES_F_PIPED | 2436 _BCM_BST_CMN_RES_F_RES_EGR | 2437 _BCM_BST_CMN_RES_F_PORTED); 2438 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 2439 pres->num_instance = NUM_XPE(unit); 2440 stat_mem = MMU_THDM_DB_PORTSP_BSTm; 2441 stat_reg = INVALIDr; 2442 stat_field = P_COUNTf; 2443 2444 /* Get the mem attributes(Max idx) from the first child, 2445 * which could be used for other instances. 2446 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2447 */ 2448 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2449 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2450 2451 /* Threshold info count and Resource allocation */ 2452 granularity = 1; 2453 total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count; 2454 thd_reg = MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr; 2455 thd_field = BST_THRESHOLD_PROFILEf; 2456 for (i = 0; i < 8; i++) { 2457 _BCM_BST_THRESHOLD_INFO_N(pres, INVALIDm, 2458 thd_reg, thd_field, granularity, i); 2459 } 2460 2461 prof_reg = MMU_THDM_DB_PORTSP_BST_THRESHOLDr; 2462 prof_field = BST_STATf; 2463 for (i = 0; i < NUM_XPE(unit); i++) { 2464 _BCM_BST_PROFILE_INFO_N(pres, INVALIDm, 2465 prof_reg, prof_field, i); 2466 } 2467 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, 2468 "bst egr port pool shared mcast"); 2469 /* Stat info count and Resource allocation */ 2470 total_stat_count = total_thd_count; 2471 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2472 stat_reg, stat_reg, stat_field); 2473 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, 2474 "bst egr port pool shared mcast"); 2475 pres->index_min = 0; 2476 pres->index_max = total_stat_count - 1; 2477 2478 /* bcmBstStatIdUcast */ 2479 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast); 2480 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2481 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2482 _BCM_BST_CMN_RES_F_PIPED | 2483 _BCM_BST_CMN_RES_F_RES_EGR); 2484 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 2485 pres->num_instance = NUM_XPE(unit); 2486 stat_mem = MMU_THDU_BST_QUEUEm; 2487 stat_reg = INVALIDr; 2488 stat_field = Q_COUNTf; 2489 2490 /* Get the mem attributes(Max idx) from the first child, 2491 * which could be used for other instances. 2492 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2493 */ 2494 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2495 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2496 2497 /* Threshold info count and Resource allocation */ 2498 granularity = 8; /* UC Queue Thd is 8 cell granularity */ 2499 total_thd_count = NUM_PIPE(unit) * idx_count; 2500 thd_mem = MMU_THDU_CONFIG_QUEUEm; 2501 thd_field = Q_WM_MAX_THRESHOLDf; 2502 for (i = 0; i < NUM_PIPE(unit); i++) { 2503 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2504 INVALIDr, thd_field, granularity, i); 2505 } 2506 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, BST_STATf); 2507 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst ucast"); 2508 /* Stat info count and Resource allocation */ 2509 total_stat_count = NUM_XPE(unit) * total_thd_count; 2510 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2511 stat_reg, stat_reg, stat_field); 2512 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst ucast"); 2513 pres->index_min = 0; 2514 pres->index_max = total_stat_count - 1; 2515 2516 /* bcmBstStatIdEgrPortPoolSharedUcast */ 2517 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedUcast); 2518 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2519 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2520 _BCM_BST_CMN_RES_F_PIPED | 2521 _BCM_BST_CMN_RES_F_RES_EGR); 2522 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 2523 pres->num_instance = NUM_XPE(unit); 2524 stat_mem = MMU_THDU_BST_PORTm; 2525 stat_reg = INVALIDr; 2526 stat_field = Q_COUNTf; 2527 2528 /* Get the mem attributes(Max idx) from the first child, 2529 * which could be used for other instances. 2530 * Note: In TD3, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2531 */ 2532 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, stat_mem, 0, 0); 2533 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2534 2535 /* Threshold info count and Resource allocation */ 2536 granularity = 8; /* UC Port Shared Thd is 8 cell granularity */ 2537 total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count; 2538 thd_mem = MMU_THDU_CONFIG_PORTm; 2539 thd_field = WM_MAX_THRESHOLDf; 2540 for (i = 0; i < NUM_PIPE(unit); i++) { 2541 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2542 INVALIDr, thd_field, granularity, i); 2543 } 2544 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_PORT_BST_THRESHOLDr, BST_STATf); 2545 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, 2546 "bst egr port pool shared ucast"); 2547 /* Stat info count and Resource allocation */ 2548 total_stat_count = total_thd_count; 2549 _BCM_BST_STAT_INFO2(pres, stat_mem, stat_mem, 2550 stat_reg, stat_reg, stat_field); 2551 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, 2552 "bst egr port pool shared ucast"); 2553 pres->index_min = 0; 2554 pres->index_max = total_stat_count - 1; 2555 2556 /* bcmBstStatIdRQEQueue */ 2557 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEQueue); 2558 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2559 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 2560 pres->num_instance = NUM_XPE(unit); 2561 idx_count = 11; 2562 pres->threshold_adj = -1; 2563 stat_mem = INVALIDm; 2564 stat_reg = MMU_THDR_DB_BST_STAT_PRIQr; 2565 stat_field = BST_STATf; 2566 2567 /* Threshold info count and Resource allocation */ 2568 granularity = 1; 2569 total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */ 2570 thd_reg = MMU_THDR_DB_BST_THRESHOLD_PRIQr; 2571 thd_field = BST_THRf; 2572 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, thd_reg, thd_field, granularity); 2573 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst RQE queue"); 2574 /* Stat info count and Resource allocation */ 2575 total_stat_count = total_thd_count; /* No per pipe copy */ 2576 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2577 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst RQE queue"); 2578 pres->index_min = 0; 2579 pres->index_max = total_stat_count - 1; 2580 2581 /* bcmBstStatIdRQEPool */ 2582 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEPool); 2583 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2584 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 2585 pres->num_instance = NUM_XPE(unit); 2586 idx_count = 4; 2587 pres->threshold_adj = -1; 2588 stat_mem = INVALIDm; 2589 stat_reg = MMU_THDR_DB_BST_STAT_SPr; 2590 stat_field = BST_STATf; 2591 2592 /* Threshold info count and Resource allocation */ 2593 granularity = 1; 2594 total_thd_count = NUM_XPE(unit) * idx_count; /* No per pipe copy */ 2595 thd_reg = MMU_THDR_DB_BST_THRESHOLD_SPr; 2596 thd_field = BST_THRf; 2597 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, thd_reg, thd_field, granularity); 2598 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, "bst RQE pool"); 2599 /* Stat info count and Resource allocation */ 2600 total_stat_count = total_thd_count; /* No per pipe copy */ 2601 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2602 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, "bst RQE pool"); 2603 pres->index_min = 0; 2604 pres->index_max = total_stat_count - 1; 2605 2606 /* bcmBstStatIdUCQueueGroup */ 2607 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUCQueueGroup); 2608 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 2609 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 2610 _BCM_BST_CMN_RES_F_PIPED | 2611 _BCM_BST_CMN_RES_F_RES_EGR | 2612 _BCM_BST_CMN_RES_F_PORTED); 2613 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 2614 pres->num_instance = NUM_XPE(unit); 2615 stat_mem = MMU_THDU_BST_QGROUPm; 2616 stat_reg = INVALIDr; 2617 stat_field = Q_COUNTf; 2618 thd_mem = MMU_THDU_CONFIG_QGROUPm; 2619 thd_field = Q_WM_MAX_THRESHOLDf; 2620 2621 /* Get the mem attributes(Max idx) from the first child, 2622 * which could be used for other instances. 2623 * Note: In TH, XPE 0/Pipe 0 instance valid for all memories(Ing/Egr). 2624 */ 2625 child_mem = SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, thd_mem, 0, 0); 2626 idx_count = soc_mem_index_max(unit, child_mem) + 1; 2627 2628 /* Threshold info count and Resource allocation */ 2629 granularity = 8; /* UC queue group Thd is 8 cell granularity */ 2630 total_thd_count = NUM_XPE(unit) * NUM_PIPE(unit) * idx_count; 2631 for (i = 0; i < NUM_PIPE(unit); i++) { 2632 _BCM_BST_THRESHOLD_INFO_N(pres, SOC_MEM_UNIQUE_ACC(unit, thd_mem)[i], 2633 INVALIDr, thd_field, granularity, i); 2634 } 2635 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QGROUP_BST_THRESHOLDr, 2636 BST_STATf); 2637 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, total_thd_count, 2638 "bst unicast queue group"); 2639 /* Stat info count and Resource allocation */ 2640 total_stat_count = total_thd_count; 2641 _BCM_BST_STAT_INFO(pres, stat_mem, stat_reg, stat_field); 2642 _BCM_BST_RESOURCE_STAT_INIT(pres, total_stat_count, 2643 "bst unicast queue group"); 2644 pres->index_min = 0; 2645 pres->index_max = total_stat_count - 1; 2646 /* EGRESS - Resources end */ 2647 2648 return BCM_E_NONE; 2649 } 2650 #endif /* BCM_TRIDENT3_SUPPORT */ 2651