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