bst.c (153804B)
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 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 25 #include <bcm/cosq.h> 26 #include <bcm/switch.h> 27 #include <bcm_int/bst.h> 28 29 #if defined(BCM_TRIUMPH3_SUPPORT) 30 #include <soc/triumph3.h> 31 #endif 32 33 #if defined(BCM_APACHE_SUPPORT) 34 #include <soc/apache.h> 35 #endif 36 #if defined(BCM_MONTEREY_SUPPORT) 37 #include <soc/monterey.h> 38 #endif 39 40 #if defined(BCM_TRIDENT2_SUPPORT) 41 #include <soc/trident2.h> 42 #endif 43 44 _bcm_bst_cmn_unit_info_t *_bcm_bst_unit_info[BCM_MAX_NUM_UNITS]; 45 sbusdma_desc_handle_t bst_tbl_handles[BCM_MAX_NUM_UNITS] = {0}; 46 _bcm_bst_tbl_ctrl_t **bst_tbl_ctrl[BCM_MAX_NUM_UNITS] = {NULL}; 47 48 #define _BCM_AP_BST_MIN_THRESHOLD_CELLS 18 49 50 #if defined(BCM_TRIUMPH3_SUPPORT) 51 STATIC int _bcm_bst_hw_stat_sync(int unit, _bcm_bst_resource_info_t *resInfo, 52 bcm_bst_stat_id_t bid, int port, int index); 53 #endif 54 55 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 56 STATIC int _bcm_bst_td2_sbusdma_desc_sync(int unit); 57 STATIC int _bcm_bst_td2_sbusdma_desc_init(int unit); 58 STATIC int _bcm_bst_td2_sbusdma_desc_deinit(int unit); 59 #endif 60 61 #if defined(BCM_TRIUMPH3_SUPPORT) 62 STATIC int _bcm_bst_sw_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 63 bcm_bst_stat_id_t bid); 64 #endif 65 STATIC int _bcm_bst_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index, 66 bcm_bst_stat_id_t bid, 67 bcm_cosq_bst_profile_t *profile, 68 uint32 *p_profile); 69 STATIC int _bcm_bst_cmn_io_op(int unit, int op, int pipe, int hw_index, 70 bcm_bst_stat_id_t bid, soc_mem_t mem, 71 soc_reg_t reg, soc_field_t field, uint32 *resval); 72 73 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 74 defined(BCM_APACHE_SUPPORT) 75 STATIC int 76 _bcm_bst_check_intr_status(int unit, bcm_bst_stat_id_t bid); 77 #endif 78 79 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 80 defined(BCM_APACHE_SUPPORT) 81 STATIC int 82 _bcm_bst_tr3_byte_to_cell(int unit, uint32 bytes) 83 { 84 return (bytes + (208 - 1))/208; 85 } 86 87 STATIC int 88 _bcm_bst_tr3_cell_to_byte(int unit, uint32 cells) 89 { 90 return cells * 208; 91 } 92 #endif 93 94 #if defined(BCM_TRIUMPH3_SUPPORT) 95 STATIC int 96 _bcm_tr3_bst_control_set(int unit, bcm_switch_control_t type, int arg, 97 _bcm_bst_thread_oper_t operation) 98 { 99 uint32 rval,fval=0, i; 100 _bcm_bst_cmn_unit_info_t *bst_info; 101 uint32 sval[3] = {0}; 102 soc_field_t fld[3] = {BST_HW_SNAPSHOT_EN_THDOf, 103 BST_HW_SNAPSHOT_EN_THDIf, 104 BST_HW_SNAPSHOT_EN_CFAPf}; 105 106 bst_info = _BCM_UNIT_BST_INFO(unit); 107 108 switch (type) { 109 case bcmSwitchBstEnable: 110 111 fval = arg; 112 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 113 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 114 BST_TRACK_EN_THDOf, fval); 115 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 116 BST_TRACK_EN_THDIf, fval); 117 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 118 BST_TRACK_EN_CFAPf, fval); 119 BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval)); 120 121 122 BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 123 soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, 1); 124 BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 125 126 if (operation == _bcmBstThreadOperExternal) { 127 if (fval) { 128 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit)); 129 } else { 130 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit)); 131 } 132 } else { 133 _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE); 134 } 135 break; 136 case bcmSwitchBstTrackingMode: 137 BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 138 soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, (arg ? 1 : 0)); 139 BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 140 bst_info->track_mode = arg ? 1 : 0; 141 break; 142 143 case bcmSwitchBstSnapshotEnable: 144 for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) { 145 if (arg & (0x1 << i)) { 146 sval[i] = 1; 147 } else { 148 sval[i] = 0; 149 } 150 151 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_CONFIGr(unit, &rval)); 152 soc_reg_field_set(unit, BST_TRACKING_CONFIGr, &rval, fld[i], sval[i]); 153 BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_CONFIGr(unit, rval)); 154 } 155 bst_info->snapshot_mode = arg; 156 157 break; 158 default: 159 return BCM_E_UNAVAIL; 160 } 161 162 return BCM_E_NONE; 163 } 164 165 STATIC int 166 _bcm_tr3_bst_control_get(int unit, bcm_switch_control_t type, int *arg) 167 { 168 uint32 rval; 169 _bcm_bst_cmn_unit_info_t *bst_info; 170 bst_info = _BCM_UNIT_BST_INFO(unit); 171 172 173 switch (type) { 174 case bcmSwitchBstEnable: 175 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 176 *arg = soc_reg_field_get(unit,BST_TRACKING_ENABLEr, rval, 177 BST_TRACK_EN_THDOf); 178 break; 179 case bcmSwitchBstTrackingMode: 180 BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 181 *arg = soc_reg_field_get(unit, MISCCONFIGr, rval, BST_TRACKING_MODEf); 182 break; 183 184 case bcmSwitchBstSnapshotEnable: 185 *arg = bst_info->snapshot_mode; 186 break; 187 188 default: 189 return BCM_E_UNAVAIL; 190 } 191 return BCM_E_NONE; 192 } 193 194 STATIC int 195 _bcm_bst_triumph3_intr_to_resources(int unit, uint32 *flags) 196 { 197 uint32 flags_tr = 0, fval, rval; 198 uint64 rval64; 199 int index = -1; 200 bcm_bst_stat_id_t bid = bcmBstStatIdMaxCount; 201 soc_field_t fld; 202 203 fld = INVALIDf; 204 205 BCM_IF_ERROR_RETURN(READ_THDO_BST_STATr(unit, &rval64)); 206 if ((fval = soc_reg64_field32_get(unit, THDO_BST_STATr, 207 rval64, BST_STAT_TRIGGERED_TYPEf))) { 208 209 if (fval & 0x1) { 210 bid = bcmBstStatIdUcast; 211 fld = UC_Q_BST_STAT_IDf; 212 } else if (fval & 0x8) { 213 bid = bcmBstStatIdEgrPool; 214 fld = SP_MC_BST_STAT_IDf; 215 } 216 217 index = soc_reg64_field32_get(unit, THDO_BST_STATr, rval64, fld); 218 } 219 220 BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUSr(unit, &rval64)); 221 222 if (soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, 223 rval64, TRIGGER_TYPEf)) { 224 225 index = soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, 226 rval64, PG_SHARED_TRIGGER_IDf); 227 228 fval = soc_reg64_field32_get(unit, THDI_BST_TRIGGER_STATUSr, rval64, 229 TRIGGER_TYPEf); 230 if (fval & 0x1) { 231 bid = bcmBstStatIdPriGroupShared; 232 } 233 234 if (fval & 0x2) { 235 bid = bcmBstStatIdPriGroupHeadroom; 236 } 237 238 if (fval & 0x4) { 239 bid = bcmBstStatIdPortPool; 240 } 241 242 if (fval & 0x8) { 243 bid = bcmBstStatIdIngPool; 244 } 245 } 246 247 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 248 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64)); 249 (void)soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r, 250 rval64, BST_CFAP_INT_ENf); 251 index = 0; 252 bid = bcmBstStatIdDevice; 253 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 254 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 255 (void)soc_reg_field_get(unit, MEM_FAIL_INT_ENr, rval, 256 BST_CFAP_INT_ENf); 257 index = 0; 258 bid = bcmBstStatIdDevice; 259 } 260 261 if (bid == bcmBstStatIdMaxCount) { 262 return BCM_E_NONE; 263 } 264 265 BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 266 if (soc_reg_field_get(unit, MISCCONFIGr, rval, BST_TRACKING_MODEf)) { 267 _bcm_bst_sync_hw_trigger(unit, bid, -1, index); 268 } else { 269 _bcm_bst_sync_hw_snapshot(unit, bid, -1, index); 270 } 271 272 *flags = flags_tr; 273 274 return BCM_E_NONE; 275 } 276 277 STATIC int 278 soc_tr3_set_hw_intr_cb(int unit) 279 { 280 BCM_IF_ERROR_RETURN(soc_tr3_set_bst_callback(unit, &_bcm_bst_hw_event_cb)); 281 return SOC_E_NONE; 282 } 283 284 STATIC int 285 _bcm_bst_triumph3_init(int unit) 286 { 287 _bcm_bst_cmn_unit_info_t *bst_info; 288 _bcm_bst_resource_info_t *pres; 289 290 bst_info = _BCM_UNIT_BST_INFO(unit); 291 292 bst_info->max_bytes = 0x500000; 293 bst_info->to_cell = _bcm_bst_tr3_byte_to_cell; 294 bst_info->to_byte = _bcm_bst_tr3_cell_to_byte; 295 bst_info->control_set = _bcm_tr3_bst_control_set; 296 bst_info->control_get = _bcm_tr3_bst_control_get; 297 bst_info->intr_to_resources = _bcm_bst_triumph3_intr_to_resources; 298 bst_info->hw_trigger_set = NULL; 299 bst_info->hw_trigger_reset = NULL; 300 bst_info->hw_intr_cb = soc_tr3_set_hw_intr_cb; 301 bst_info->intr_enable_set = _bst_intr_enable_set; 302 bst_info->hw_stat_snapshot = _bcm_bst_sync_hw_snapshot; 303 bst_info->hw_stat_clear = _bcm_bst_hw_stat_clear; 304 bst_info->pre_sync = NULL; 305 bst_info->post_sync = NULL; 306 307 /* bcmBstStatIdDevice */ 308 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice); 309 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 310 pres->index_min = pres->index_max = 0; 311 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV); 312 _BCM_BST_STAT_INFO(pres, INVALIDm, CFAPBSTSTATr, BST_STATf); 313 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf, 1); 314 _BCM_BST_RESOURCE_STAT_INIT(pres, 1, "bst cfap"); 315 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 1, "bst cfap"); 316 317 /* bcmBstStatIdEgrPool */ 318 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool); 319 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 320 pres->index_min = 0; 321 pres->index_max = 3; 322 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 323 _BCM_BST_STAT_INFO(pres, INVALIDm, OP_MCUC_SP_BST_STATr, BST_STATf); 324 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 325 OP_MCUC_SP_BST_THRESHOLDr, BST_THRESHOLDf, 1); 326 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egrpool"); 327 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egrpool"); 328 329 /* bcmBstStatIdEgrMCastPool */ 330 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool); 331 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 332 pres->index_min = 0; 333 pres->index_max = 3; 334 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 335 _BCM_BST_STAT_INFO(pres, INVALIDm, OP_MC_SP_BST_STATr, BST_STATf); 336 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 337 OP_MC_SP_BST_THRESHOLDr, BST_THRESHOLDf, 1); 338 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egr mcpool"); 339 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egr mcpool"); 340 341 /* bcmBstStatIdIngPool */ 342 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool); 343 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 344 pres->index_min = 0; 345 pres->index_max = 3; 346 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING); 347 _BCM_BST_STAT_INFO(pres, INVALIDm, THDI_BST_SHADOW_SPr, BST_STATf); 348 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 349 THDI_BST_PROFILE_THRESH_SPr, BST_THRESHOLDf, 1); 350 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst ing pool"); 351 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst ing pool"); 352 353 /* bcmBstStatIdPortPool */ 354 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool); 355 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 356 pres->index_min = 0; 357 pres->index_max = soc_mem_index_max(unit, THDI_PORT_SP_BSTm); 358 359 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 360 _BCM_BST_CMN_RES_F_RES_ING); 361 362 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 363 364 _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_SP_CONFIGm, 365 INVALIDr, BST_THRESHOLD_PROFILEf, 1); 366 367 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 368 THDI_BST_PROFILE_THRESH_PORT_SHAREDr, BST_THRESHOLDf); 369 370 _BCM_BST_STAT_INFO(pres, THDI_PORT_SP_BSTm, INVALIDr, BST_STATf); 371 372 _BCM_BST_RESOURCE_STAT_INIT(pres, 373 soc_mem_index_count(unit, THDI_PORT_SP_BSTm), "bst port pool"); 374 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 375 soc_mem_index_count(unit, THDI_PORT_SP_BSTm), "bst port pool"); 376 377 /* bcmBstStatIdPriGroupShared */ 378 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared); 379 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 380 pres->index_min = 0; 381 pres->index_max = (63 * 8) - 1; 382 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 383 _BCM_BST_CMN_RES_F_RES_ING); 384 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 385 _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_PG_CONFIGm, INVALIDr, 386 PG_BST_PROFILE_SHAREDf, 1); 387 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 388 THDI_BST_PROFILE_THRESH_PG_SHAREDr, 389 BST_THRESHOLD_SHAREDf); 390 _BCM_BST_STAT_INFO(pres, THDI_PORT_PG_BSTm, INVALIDr, PG_BST_STAT_SHAREDf); 391 _BCM_BST_RESOURCE_STAT_INIT(pres, 63 * 8, "bst pg"); 392 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 63 * 8, "bst pg"); 393 394 /* bcmBstStatIdPriGroupHeadroom */ 395 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom); 396 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 397 pres->index_min = 0; 398 pres->index_max = (63 * 8) - 1; 399 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 400 _BCM_BST_CMN_RES_F_RES_ING); 401 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 402 _BCM_BST_THRESHOLD_INFO(pres, THDI_PORT_PG_CONFIGm, INVALIDr, 403 PG_BST_PROFILE_HDRMf, 1); 404 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 405 THDI_BST_PROFILE_THRESH_PG_HDRMr, 406 BST_THRESHOLD_HDRMf); 407 _BCM_BST_STAT_INFO(pres, THDI_PORT_PG_BSTm, INVALIDr, BST_STAT_HDRMf); 408 _BCM_BST_RESOURCE_STAT_INIT(pres, 63 * 8, "bst pg hdrm"); 409 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 63 * 8, "bst pg"); 410 411 /* bcmBstStatIdMcast */ 412 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast); 413 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 414 pres->index_min = 0; 415 pres->index_max = 47; 416 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 417 _BCM_BST_CMN_RES_F_RES_EGR); 418 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit)); 419 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 420 OP_CPU_QUEUE_BST_THRESHOLDr, BST_PROFILEf, 1); 421 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_CPU_QUEUE_BST_THRESHOLD_PROFILEr, 422 THRESHOLDf); 423 _BCM_BST_STAT_INFO(pres, INVALIDm, OP_CPU_QUEUE_BST_STATr, BST_STATf); 424 _BCM_BST_RESOURCE_STAT_INIT(pres, 48, "bst mcast"); 425 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 48, "bst mcast"); 426 427 /* bcmBstStatIdUcast */ 428 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast); 429 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 430 pres->index_min = 0; 431 pres->index_max = soc_mem_index_max(unit, MMU_THDO_BST_QUEUEm); 432 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 433 _BCM_BST_CMN_RES_F_RES_EGR); 434 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 435 _BCM_BST_THRESHOLD_INFO(pres, MMU_THDO_CONFIG_QUEUEm, INVALIDr, 436 BST_THRESHOLD_PROFILEf, 8); 437 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, 438 BST_THRESHOLDf); 439 _BCM_BST_STAT_INFO(pres, MMU_THDO_BST_QUEUEm, INVALIDr, BST_STATf); 440 _BCM_BST_RESOURCE_STAT_INIT(pres, 441 soc_mem_index_count(unit, MMU_THDO_BST_QUEUEm), "bst ucast"); 442 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 443 soc_mem_index_count(unit, MMU_THDO_BST_QUEUEm), "bst ucast"); 444 445 return BCM_E_NONE; 446 } 447 448 #endif /* BCM_TRIUMPH3_SUPPORT */ 449 450 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 451 452 STATIC int _bcm_td2_bst_sync_thread_restore(int unit) 453 { 454 _bcm_bst_cmn_unit_info_t *bst_info; 455 int enable; 456 457 bst_info = _BCM_UNIT_BST_INFO(unit); 458 if (bst_info->control_get) { 459 bst_info->control_get(unit, bcmSwitchBstEnable, &enable); 460 if (enable) { 461 return TRUE; 462 } 463 } 464 465 return FALSE; 466 } 467 468 STATIC int _bcm_td2_bst_info_restore(int unit) 469 { 470 _bcm_bst_cmn_unit_info_t *bst_info; 471 uint32 rval; 472 473 bst_info = _BCM_UNIT_BST_INFO(unit); 474 475 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 476 bst_info->track_mode = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, 477 BST_TRACK_EN_THDOf); 478 479 BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval)); 480 bst_info->snapshot_mode = soc_reg_field_get(unit, BST_HW_SNAPSHOT_ENr, rval, 481 BST_HW_SNAPSHOT_EN_THDOf); 482 483 return BCM_E_NONE; 484 } 485 486 STATIC int _bcm_td2_bst_resource_threshold_restore(int unit) 487 { 488 _bcm_bst_resource_info_t *resInfo; 489 int hw_index, pipe, ipipe, index_max = 0; 490 bcm_bst_stat_id_t bid; 491 uint32 cells; 492 uint32 profile_index; 493 int pipe_offset; 494 int pipe_factor = 1; 495 496 pipe_factor = NUM_PIPE(unit); 497 498 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 499 resInfo = _BCM_BST_RESOURCE(unit, bid); 500 501 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 502 index_max = resInfo->index_max / NUM_PIPE(unit); 503 } 504 else { 505 index_max = resInfo->index_max; 506 } 507 508 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 509 pipe_offset = 0; 510 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 511 if (pipe) { 512 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor); 513 } 514 ipipe = pipe; 515 } else { 516 if (pipe) { 517 continue; 518 } 519 ipipe = pipe; 520 } 521 522 for (hw_index = resInfo->index_min; hw_index < index_max; hw_index++) { 523 if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) { 524 SOC_IF_ERROR_RETURN( 525 _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 526 ipipe, hw_index, bid, 527 resInfo->threshold_mem[ipipe], 528 resInfo->threshold_reg[ipipe], 529 resInfo->threshold_field, 530 &profile_index)); 531 532 SOC_IF_ERROR_RETURN( 533 _bcm_bst_cmn_io_op(unit, BST_OP_GET, 534 ipipe, profile_index, bid, 535 resInfo->profile_mem, 536 resInfo->profile_reg[0], 537 resInfo->profile_field, 538 &cells)); 539 } else { 540 SOC_IF_ERROR_RETURN( 541 _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 542 ipipe, hw_index, bid, 543 resInfo->threshold_mem[ipipe], 544 resInfo->threshold_reg[ipipe], 545 resInfo->threshold_field, 546 &cells)); 547 } 548 549 resInfo->p_threshold[hw_index + pipe_offset] = cells; 550 } 551 } 552 } 553 554 return BCM_E_NONE; 555 } 556 557 STATIC int 558 _bcm_td2_bst_threshold_maximum_set(int unit, _bcm_bst_cmn_unit_info_t *bst_info, 559 uint32 enable) 560 { 561 int hw_index, pipe, cells; 562 uint32 bid_index, index_max; 563 _bcm_bst_resource_info_t *resInfo; 564 bcm_cosq_bst_profile_t profile; 565 int pipe_offset; 566 int pipe_factor = 1; 567 uint32 threshold_max = BST_THRESHOLD_MAX_HIGH; 568 569 /* Need to set bst threshold to max high when bst_trac_en is disabled. 570 Only add bst id if relative bst id is set. 571 Registers listed below are exposed to add with related BST ID in the future 572 MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILE 573 MMU_THDM_DB_PORTSP_BST_THRESHOLD 574 MMU_THDM_MCQE_CPUQUEUE_BST_THRESHOLD_PROFILE 575 MMU_THDM_MCQE_POOL_MC_BST_THRESHOLD 576 MMU_THDM_MCQE_QUEUE_MC_BST_THRESHOLD_PROFILE 577 MMU_THDM_MCQE_PORTSP_BST_THRESHOLD 578 */ 579 bcm_bst_stat_id_t bst_threshold_id[] = {bcmBstStatIdEgrPool, 580 bcmBstStatIdEgrMCastPool, 581 bcmBstStatIdMcast}; 582 583 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) { 584 for (bid_index = 0; 585 bid_index < (sizeof(bst_threshold_id)/sizeof(bcm_bst_stat_id_t)); 586 bid_index++) { 587 sal_memset(&profile, 0, sizeof(bcm_cosq_bst_profile_t)); 588 resInfo = _BCM_BST_RESOURCE(unit, bst_threshold_id[bid_index]); 589 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 590 continue; 591 } 592 593 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 594 index_max = resInfo->index_max / NUM_PIPE(unit) - 1; 595 } 596 else { 597 index_max = resInfo->index_max; 598 } 599 600 for (hw_index = resInfo->index_min; hw_index <= index_max ; hw_index++) { 601 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 602 pipe_offset = 0; 603 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 604 pipe_factor = NUM_PIPE(unit); 605 if (pipe) { 606 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor); 607 } 608 } 609 610 if(resInfo->p_threshold[hw_index + pipe_offset] != threshold_max) { 611 if(enable == 1) { 612 cells = resInfo->p_threshold[hw_index + pipe_offset]; 613 if(cells != 0) { 614 /* Taking granularity into count */ 615 if(resInfo->threshold_gran != 0) { 616 cells = cells * resInfo->threshold_gran - resInfo->threshold_adj; 617 } else { 618 cells -= resInfo->threshold_adj; 619 } 620 621 profile.byte = bst_info->to_byte(unit, cells); 622 623 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw 624 (unit, pipe, BCM_BST_DUP_XPE, hw_index, 625 bst_threshold_id[bid_index], &profile, NULL)); 626 } 627 } else { 628 profile.byte = BST_THRESHOLD_INVALID; 629 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw 630 (unit, pipe, BCM_BST_DUP_XPE, hw_index, 631 bst_threshold_id[bid_index], &profile, NULL)); 632 633 } 634 } 635 } 636 } 637 } 638 } 639 640 return BCM_E_NONE; 641 } 642 643 STATIC int 644 _bcm_td2_bst_control_set(int unit, bcm_switch_control_t type, int arg, 645 _bcm_bst_thread_oper_t operation) 646 { 647 uint32 i, rval, fval; 648 uint32 sval[3] = {0}; 649 _bcm_bst_cmn_unit_info_t *bst_info; 650 soc_field_t fld[6] = {BST_HW_SNAPSHOT_EN_THDOf, 651 ACTION_EN_THDOf, 652 BST_HW_SNAPSHOT_EN_THDIf, 653 ACTION_EN_THDIf, 654 BST_HW_SNAPSHOT_EN_CFAPf, 655 ACTION_CFAPf}; 656 657 bst_info = _BCM_UNIT_BST_INFO(unit); 658 659 switch (type) { 660 case bcmSwitchBstEnable: 661 662 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 663 664 fval = !!arg; 665 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 666 BST_TRACK_EN_THDOf, fval); 667 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 668 BST_TRACK_EN_THDIf, fval); 669 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, 670 BST_TRACK_EN_CFAPf, fval); 671 672 BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval)); 673 674 if (operation == _bcmBstThreadOperExternal) { 675 BCM_IF_ERROR_RETURN(_bcm_td2_bst_threshold_maximum_set(unit, bst_info, fval)); 676 677 if (fval) { 678 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit)); 679 } else { 680 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit)); 681 } 682 } else { 683 _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, fval ? TRUE : FALSE); 684 } 685 686 break; 687 case bcmSwitchBstTrackingMode: 688 BCM_IF_ERROR_RETURN(READ_MISCCONFIGr(unit, &rval)); 689 soc_reg_field_set(unit, MISCCONFIGr, &rval, BST_TRACKING_MODEf, arg); 690 BCM_IF_ERROR_RETURN(WRITE_MISCCONFIGr(unit, rval)); 691 bst_info->track_mode = arg ? 1 : 0; 692 break; 693 case bcmSwitchBstSnapshotEnable: 694 for (i = _BCM_BST_SNAPSHOT_THDO; i < _BCM_BST_SNAPSHOT_COUNT; i++) { 695 if (arg & (0x1 << i)) { 696 sval[i] = 1; 697 } else { 698 sval[i] = 0; 699 } 700 701 BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval)); 702 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[i*2], sval[i]); 703 BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval)); 704 705 BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval)); 706 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[i*2+1], sval[i]); 707 BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval)); 708 } 709 bst_info->snapshot_mode = arg; 710 711 break; 712 default: 713 return BCM_E_UNAVAIL; 714 } 715 return BCM_E_NONE; 716 } 717 718 STATIC int 719 _bcm_td2_bst_control_get(int unit, bcm_switch_control_t type, int *arg) 720 { 721 uint32 rval; 722 _bcm_bst_cmn_unit_info_t *bst_info; 723 bst_info = _BCM_UNIT_BST_INFO(unit); 724 725 switch (type) { 726 case bcmSwitchBstEnable: 727 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 728 *arg = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, 729 BST_TRACK_EN_THDOf); 730 break; 731 case bcmSwitchBstTrackingMode: 732 *arg = bst_info->track_mode; 733 break; 734 case bcmSwitchBstSnapshotEnable: 735 *arg = bst_info->snapshot_mode; 736 break; 737 default: 738 return BCM_E_UNAVAIL; 739 } 740 return BCM_E_NONE; 741 } 742 743 STATIC int 744 _bcm_bst_td2_intr_to_resources(int unit, uint32 *flags) 745 { 746 uint32 flags_tr = 0; 747 uint32 fval, fval_pipe[SOC_MAX_NUM_PIPES]; 748 uint32 rval, rval_dev, rval_pipe[SOC_MAX_NUM_PIPES], rval_status; 749 uint32 rval_rqe; 750 uint64 rval_uc, rval_db, rval_mcqe, rval64, rval64_zero; 751 int index[_bcmResourceMaxCount][SOC_MAX_NUM_PIPES], res_ct = 0; 752 bcm_bst_stat_id_t bid[_bcmResourceMaxCount] = {-1}; 753 int pipe = 0, pos = 0; 754 int bid_mcast = 0; 755 soc_field_t fld[SOC_MAX_NUM_PIPES]; 756 soc_reg_t reg[SOC_MAX_NUM_PIPES]; 757 _bcm_bst_cmn_unit_info_t *bst_info; 758 bst_info = _BCM_UNIT_BST_INFO(unit); 759 760 for (pipe = 0; pipe < NUM_PIPE(unit) ; pipe++) { 761 fval_pipe[pipe] = 0; 762 rval_pipe[pipe] = 0; 763 fld[pipe] = INVALIDf; 764 reg[pipe] = INVALIDr; 765 for (pos = 0; pos < _bcmResourceMaxCount; pos++) { 766 index[pos][pipe] = -1; 767 } 768 } 769 770 if (bst_info->intr_enable_set) { 771 bst_info->intr_enable_set(unit, 0); 772 } 773 774 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 775 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64)); 776 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 777 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval_status)); 778 } 779 780 _bst_intr_status_reset(unit); 781 782 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 783 BCM_IF_ERROR_RETURN(READ_THDU_BST_STATr(unit, &rval_uc)); 784 BCM_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_BST_STATr(unit, &rval_db)); 785 BCM_IF_ERROR_RETURN(READ_MMU_THDM_MCQE_DEVICE_BST_STATr(unit, &rval_mcqe)); 786 BCM_IF_ERROR_RETURN(READ_MMU_THDR_DB_BST_STATr(unit, &rval_rqe)); 787 788 /* bcmBstStatIdEgrPool */ 789 fval = soc_reg64_field32_get(unit, MMU_THDM_DB_DEVICE_BST_STATr, 790 rval_db, BST_STAT_TRIGGERED_TYPEf); 791 if (fval) { 792 reg[0] = MMU_THDM_DB_DEVICE_BST_STATr; 793 /* Check all triggered types. */ 794 for (pos = 0; pos < 5; pos++) { 795 if (!(fval & (1U << pos))) { 796 continue; 797 } 798 switch (fval & (1U << pos)) { 799 case 0x1: 800 bid[res_ct] = bcmBstStatIdEgrPool; 801 fld[0] = MCUC_SP_BST_STAT_IDf; 802 break; 803 case 0x2: 804 bid[res_ct] = bcmBstStatIdEgrMCastPool; 805 fld[0] = MC_SP_BST_STAT_IDf; 806 break; 807 case 0x4: 808 bid[res_ct] = bcmBstStatIdMcast; 809 fld[0] = MC_Q_BST_STAT_IDf; 810 bid_mcast = 1; 811 break; 812 case 0x8: 813 if (!bid_mcast) { 814 bid[res_ct] = bcmBstStatIdMcast; 815 fld[0] = MC_CPU_Q_BST_STAT_IDf; 816 } else { 817 fld[0] = INVALIDf; 818 } 819 break; 820 case 0x10: 821 bid[res_ct] = bcmBstStatIdEgrPortPoolSharedMcast; 822 fld[0] = MC_PORTSP_BST_STAT_IDf; 823 break; 824 default: 825 fld[0] = INVALIDf; 826 } 827 if (fld[0] != INVALIDf) { 828 index[res_ct++][0] = soc_reg64_field32_get(unit, reg[0], rval_db, fld[0]); 829 } 830 } 831 COMPILER_64_ZERO(rval64_zero); 832 BCM_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_BST_STATr(unit, rval64_zero)); 833 } 834 835 #if defined(BCM_APACHE_SUPPORT) 836 if (SOC_IS_APACHE(unit)) { 837 /* bcmBstStatIdDevice */ 838 BCM_IF_ERROR_RETURN(READ_CFAP_BST_THRSr(unit, &rval_dev)); 839 if (soc_reg_field_get(unit, CFAP_BST_THRSr, rval_dev, BST_THRESHOLDf)) { 840 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 841 if (soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r, 842 rval64, BST_CFAP_INT_ENf)) { 843 index[res_ct][0] = 0; 844 bid[res_ct++] = bcmBstStatIdDevice; 845 } 846 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 847 /* CFAP : Device resource. 848 * Check Intr Status reg if Stats > Thd. 849 */ 850 reg[0] = MEM_FAIL_INT_STATr; 851 if (soc_reg_field_get(unit, reg[0], rval_status, BST_CFAP_INTf)) { 852 index[res_ct][0] = 0; 853 bid[res_ct++] = bcmBstStatIdDevice; 854 } 855 } 856 } 857 } else 858 #endif 859 { 860 /* bcmBstStatIdDevice */ 861 BCM_IF_ERROR_RETURN(READ_CFAPBSTTHRSr(unit, &rval_dev)); 862 if (soc_reg_field_get(unit, CFAPBSTTHRSr, rval_dev, BST_THRESHOLDf)) { 863 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 864 if (soc_reg64_field32_get(unit, MEM_FAIL_INT_EN_64r, 865 rval64, BST_CFAP_INT_ENf)) { 866 index[res_ct][0] = 0; 867 bid[res_ct++] = bcmBstStatIdDevice; 868 } 869 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 870 /* CFAP : Device resource. 871 * Check Intr Status reg if Stats > Thd. 872 */ 873 reg[0] = MEM_FAIL_INT_STATr; 874 if (soc_reg_field_get(unit, reg[0], rval_status, BST_CFAP_INTf)) { 875 index[res_ct][0] = 0; 876 bid[res_ct++] = bcmBstStatIdDevice; 877 } 878 } 879 } 880 } 881 882 #if defined(BCM_APACHE_SUPPORT) 883 if (SOC_IS_APACHE(unit)) { 884 /* Ingress based Status/Triggers */ 885 BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, &rval_pipe[0])); 886 reg[0] = THDI_BST_TRIGGER_STATUS_PIPEXr; 887 888 /* bcmBstStatIdIngPool */ 889 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 890 rval_pipe[0], POOL_SHARED_TRIGGERf); 891 if (fval_pipe[0]) { 892 fld[0] = POOL_SHARED_TRIGGER_STATUSf; 893 894 if (!fval) { 895 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 896 if (!fval_pipe[pipe]) { 897 continue; 898 } 899 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[0]); 900 } 901 } 902 bid[res_ct++] = bcmBstStatIdIngPool; 903 } 904 905 /* bcmBstStatIdPortPool */ 906 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 907 rval_pipe[0], SP_SHARED_TRIGGER_PIPEXf); 908 if (fval_pipe[0]) { 909 fld[0] = SP_SHARED_TRIGGER_STATUS_PIPEXf; 910 911 if (!fval) { 912 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 913 if (!fval_pipe[pipe]) { 914 continue; 915 } 916 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 917 } 918 } 919 bid[res_ct++] = bcmBstStatIdPortPool; 920 } 921 922 /* bcmBstStatIdPriGroupShared */ 923 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 924 rval_pipe[0], PG_SHARED_TRIGGER_PIPEXf); 925 if (fval_pipe[0]) { 926 fld[0] = PG_SHARED_TRIGGER_STATUS_PIPEXf; 927 928 if (!fval) { 929 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 930 if (!fval_pipe[pipe]) { 931 continue; 932 } 933 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 934 } 935 } 936 bid[res_ct++] = bcmBstStatIdPriGroupShared; 937 } 938 939 /* bcmBstStatIdPriGroupHeadroom */ 940 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 941 rval_pipe[0], PG_HDRM_TRIGGER_PIPEXf); 942 if (fval_pipe[0]) { 943 fld[0] = PG_HDRM_TRIGGER_STATUS_PIPEXf; 944 945 if (!fval) { 946 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 947 if (!fval_pipe[pipe]) { 948 continue; 949 } 950 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 951 } 952 } 953 bid[res_ct++] = bcmBstStatIdPriGroupHeadroom; 954 } 955 BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, 0)); 956 } else 957 #endif 958 { 959 /* Ingress based Status/Triggers */ 960 BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, &rval_pipe[0])); 961 BCM_IF_ERROR_RETURN(READ_THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr(unit, &rval_pipe[1])); 962 reg[0] = THDI_BST_TRIGGER_STATUS_PIPEXr; 963 reg[1] = THDI_BST_TRIGGER_STATUS_PIPEYr; 964 965 /* bcmBstStatIdIngPool */ 966 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 967 rval_pipe[0], POOL_SHARED_TRIGGERf); 968 fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 969 rval_pipe[1], POOL_SHARED_TRIGGERf); 970 if (fval_pipe[0] || fval_pipe[1]) { 971 fld[0] = POOL_SHARED_TRIGGER_STATUSf; 972 973 if (!fval) { 974 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 975 if (!fval_pipe[pipe]) { 976 continue; 977 } 978 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[0]); 979 } 980 } 981 bid[res_ct++] = bcmBstStatIdIngPool; 982 } 983 984 /* bcmBstStatIdPortPool */ 985 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 986 rval_pipe[0], SP_SHARED_TRIGGER_PIPEXf); 987 fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 988 rval_pipe[1], SP_SHARED_TRIGGER_PIPEYf); 989 if (fval_pipe[0] || fval_pipe[1]) { 990 fld[0] = SP_SHARED_TRIGGER_STATUS_PIPEXf; 991 fld[1] = SP_SHARED_TRIGGER_STATUS_PIPEYf; 992 993 if (!fval) { 994 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 995 if (!fval_pipe[pipe]) { 996 continue; 997 } 998 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 999 } 1000 } 1001 bid[res_ct++] = bcmBstStatIdPortPool; 1002 } 1003 1004 /* bcmBstStatIdPriGroupShared */ 1005 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 1006 rval_pipe[0], PG_SHARED_TRIGGER_PIPEXf); 1007 fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 1008 rval_pipe[1], PG_SHARED_TRIGGER_PIPEYf); 1009 if (fval_pipe[0] || fval_pipe[1]) { 1010 fld[0] = PG_SHARED_TRIGGER_STATUS_PIPEXf; 1011 fld[1] = PG_SHARED_TRIGGER_STATUS_PIPEYf; 1012 1013 if (!fval) { 1014 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1015 if (!fval_pipe[pipe]) { 1016 continue; 1017 } 1018 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 1019 } 1020 } 1021 bid[res_ct++] = bcmBstStatIdPriGroupShared; 1022 } 1023 1024 /* bcmBstStatIdPriGroupHeadroom */ 1025 fval_pipe[0] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr, 1026 rval_pipe[0], PG_HDRM_TRIGGER_PIPEXf); 1027 fval_pipe[1] = soc_reg_field_get(unit, THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr, 1028 rval_pipe[1], PG_HDRM_TRIGGER_PIPEYf); 1029 if (fval_pipe[0] || fval_pipe[1]) { 1030 fld[0] = PG_HDRM_TRIGGER_STATUS_PIPEXf; 1031 fld[1] = PG_HDRM_TRIGGER_STATUS_PIPEYf; 1032 1033 if (!fval) { 1034 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1035 if (!fval_pipe[pipe]) { 1036 continue; 1037 } 1038 index[res_ct][pipe] = soc_reg_field_get(unit, reg[pipe], rval_pipe[pipe], fld[pipe]); 1039 } 1040 } 1041 bid[res_ct++] = bcmBstStatIdPriGroupHeadroom; 1042 } 1043 BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEXr(unit, 0)); 1044 BCM_IF_ERROR_RETURN(WRITE_THDI_BST_TRIGGER_STATUS_TYPE_PIPEYr(unit, 0)); 1045 } 1046 1047 /* bcmBstStatIdUcast */ 1048 if ((fval = soc_reg64_field32_get(unit, THDU_BST_STATr, 1049 rval_uc, BST_STAT_TRIGGERED_TYPEf))) { 1050 if (fval & 0x1) { 1051 fld[0] = UC_Q_BST_STAT_IDf; 1052 index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, fld[0]); 1053 if (index[res_ct][0] >= 2048) { 1054 index[res_ct][1] = index[res_ct][0] - 2048 + 1480; 1055 index[res_ct][0] = -1; 1056 } 1057 bid[res_ct++] = bcmBstStatIdUcast; 1058 } 1059 if (fval & 0x2) { 1060 fld[0] = UC_QGROUP_BST_STAT_IDf; 1061 index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, 1062 fld[0]); 1063 if (NUM_PIPE(unit) > 1) { 1064 if (index[res_ct][0] >= 128) { 1065 index[res_ct][1] = index[res_ct][0] - 128; 1066 index[res_ct][0] = -1; 1067 } 1068 } 1069 bid[res_ct++] = bcmBstStatIdUCQueueGroup; 1070 } 1071 if (fval & 0x4) { 1072 fld[0] = UC_PORT_SP_BST_STAT_IDf; 1073 index[res_ct][0] = soc_reg64_field32_get(unit, THDU_BST_STATr, rval_uc, 1074 fld[0]); 1075 if (NUM_PIPE(unit) > 1) { 1076 if (index[res_ct][0] >= 256) { 1077 index[res_ct][1] = index[res_ct][0] - 256; 1078 index[res_ct][0] = -1; 1079 } 1080 } 1081 bid[res_ct++] = bcmBstStatIdEgrPortPoolSharedUcast; 1082 } 1083 1084 COMPILER_64_ZERO(rval64_zero); 1085 BCM_IF_ERROR_RETURN(WRITE_THDU_BST_STATr(unit, rval64_zero)); 1086 } 1087 1088 /* THDR Status/Triggers */ 1089 reg[0] = MMU_THDR_DB_BST_STATr; 1090 fval = soc_reg_field_get(unit, reg[0], rval_rqe, 1091 PRIQ_TRIGGEREDf); 1092 if (fval & 0x1) { 1093 fld[0] = PRIQ_IDf; 1094 index[res_ct][0] = soc_reg_field_get(unit, reg[0], rval_rqe, 1095 fld[0]); 1096 bid[res_ct++] = bcmBstStatIdRQEQueue; 1097 } 1098 1099 fval = soc_reg_field_get(unit, reg[0], rval_rqe, 1100 SP_TRIGGEREDf); 1101 if (fval & 0x1) { 1102 fld[0] = SP_IDf; 1103 index[res_ct][0] = soc_reg_field_get(unit, reg[0], rval_rqe, 1104 fld[0]); 1105 bid[res_ct++] = bcmBstStatIdRQEPool; 1106 } 1107 1108 COMPILER_64_ZERO(rval64_zero); 1109 /*BCM_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_BST_STATr(unit, rval64_zero));*/ 1110 BCM_IF_ERROR_RETURN(soc_reg_set(unit, MMU_THDR_DB_BST_STATr, REG_PORT_ANY, 1111 0, rval64_zero)); 1112 1113 if (res_ct == 0) { 1114 /* No resource to fetch */ 1115 if (bst_info->intr_enable_set) { 1116 bst_info->intr_enable_set(unit, 1); 1117 } 1118 return BCM_E_NONE; 1119 } 1120 1121 for (pos = 0; pos < res_ct; pos++) { 1122 if (index[pos][0] != -1) { 1123 _bcm_bst_sync_hw_snapshot(unit, bid[pos], -1, index[pos][0]); 1124 } else { 1125 _bcm_bst_sync_hw_snapshot(unit, bid[pos], -2, index[pos][1]); 1126 } 1127 } 1128 1129 *flags = flags_tr; 1130 if (bst_info->intr_enable_set) { 1131 bst_info->intr_enable_set(unit, 1); 1132 } 1133 return BCM_E_NONE; 1134 } 1135 1136 STATIC int 1137 _bcm_bst_td2_hw_trigger_set(int unit, bcm_bst_stat_id_t bid) 1138 { 1139 uint32 rval; 1140 _bcm_bst_resource_info_t *resInfo; 1141 soc_field_t fld[2] = { INVALIDf, INVALIDf }; 1142 1143 resInfo = _BCM_BST_RESOURCE(unit, bid); 1144 if (resInfo == NULL) { 1145 return BCM_E_PARAM; 1146 } 1147 1148 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 1149 fld[0] = BST_HW_SNAPSHOT_EN_CFAPf; 1150 fld[1] = ACTION_CFAPf; 1151 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) { 1152 fld[0] = BST_HW_SNAPSHOT_EN_THDIf; 1153 fld[1] = ACTION_EN_THDIf; 1154 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) { 1155 fld[0] = BST_HW_SNAPSHOT_EN_THDOf; 1156 fld[1] = ACTION_EN_THDOf; 1157 } else { 1158 return BCM_E_PARAM; 1159 } 1160 1161 BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval)); 1162 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[0], 1); 1163 BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval)); 1164 1165 BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval)); 1166 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[1], 1); 1167 BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval)); 1168 return BCM_E_NONE; 1169 } 1170 1171 STATIC int 1172 _bcm_bst_td2_hw_trigger_reset(int unit, bcm_bst_stat_id_t bid) 1173 { 1174 uint32 rval; 1175 _bcm_bst_resource_info_t *resInfo; 1176 soc_field_t fld[2] = { INVALIDf, INVALIDf }; 1177 1178 if (bid != -1) { 1179 resInfo = _BCM_BST_RESOURCE(unit, bid); 1180 if (resInfo == NULL) { 1181 return BCM_E_PARAM; 1182 } 1183 1184 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 1185 fld[0] = BST_HW_SNAPSHOT_EN_CFAPf; 1186 fld[1] = ACTION_CFAPf; 1187 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) { 1188 fld[0] = BST_HW_SNAPSHOT_EN_THDIf; 1189 fld[1] = ACTION_EN_THDIf; 1190 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) { 1191 fld[0] = BST_HW_SNAPSHOT_EN_THDOf; 1192 fld[1] = ACTION_EN_THDOf; 1193 } else { 1194 return BCM_E_PARAM; 1195 } 1196 1197 BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval)); 1198 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, fld[0], 0); 1199 BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval)); 1200 1201 BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval)); 1202 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, fld[1], 0); 1203 BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval)); 1204 } else { 1205 /* Reset for all Resources */ 1206 BCM_IF_ERROR_RETURN(READ_BST_HW_SNAPSHOT_ENr(unit, &rval)); 1207 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_CFAPf, 0); 1208 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_THDIf, 0); 1209 soc_reg_field_set(unit, BST_HW_SNAPSHOT_ENr, &rval, BST_HW_SNAPSHOT_EN_THDOf, 0); 1210 BCM_IF_ERROR_RETURN(WRITE_BST_HW_SNAPSHOT_ENr(unit, rval)); 1211 1212 BCM_IF_ERROR_RETURN(READ_BST_SNAPSHOT_ACTION_ENr(unit, &rval)); 1213 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_CFAPf, 0); 1214 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_EN_THDIf, 0); 1215 soc_reg_field_set(unit, BST_SNAPSHOT_ACTION_ENr, &rval, ACTION_EN_THDOf, 0); 1216 BCM_IF_ERROR_RETURN(WRITE_BST_SNAPSHOT_ACTION_ENr(unit, rval)); 1217 } 1218 return BCM_E_NONE; 1219 } 1220 1221 STATIC int 1222 soc_td2_set_hw_intr_cb(int unit) 1223 { 1224 #if defined(BCM_MONTEREY_SUPPORT) 1225 if (SOC_IS_MONTEREY(unit)) { 1226 BCM_IF_ERROR_RETURN(soc_monterey_set_bst_callback(unit, &_bcm_bst_hw_event_cb)); 1227 return SOC_E_NONE; 1228 } 1229 #endif 1230 #if defined(BCM_APACHE_SUPPORT) 1231 if (SOC_IS_APACHE(unit)) { 1232 BCM_IF_ERROR_RETURN(soc_apache_set_bst_callback(unit, &_bcm_bst_hw_event_cb)); 1233 return SOC_E_NONE; 1234 } 1235 #endif 1236 BCM_IF_ERROR_RETURN(soc_td2_set_bst_callback(unit, &_bcm_bst_hw_event_cb)); 1237 return SOC_E_NONE; 1238 } 1239 1240 int 1241 _bcm_bst_td2_intr_check(int unit) 1242 { 1243 _bcm_bst_cmn_unit_info_t *bst_info; 1244 _bcm_bst_resource_info_t *resInfo; 1245 int num_entries, mem_wsz, port; 1246 int idx, idx_offset, rv, pipe, pipe_offset = 0; 1247 void *pentry; 1248 char *dmabuf; 1249 uint32 rval, temp_val; 1250 soc_mem_t mem; 1251 soc_reg_t reg; 1252 bcm_bst_stat_id_t bid = bcmBstStatIdMaxCount; 1253 1254 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 1255 return BCM_E_INIT; 1256 } 1257 1258 /* bcmBstStatIdHeadroomPool is used for Tomahawk*/ 1259 for(bid = _BCM_BST_RESOURCE_MIN; bid < bcmBstStatIdMaxCount; bid++) 1260 { 1261 /* bcmBstStatIdHeadroomPool is not supported for TD2/TD2+...*/ 1262 if (bid == bcmBstStatIdHeadroomPool) { 1263 continue; 1264 } 1265 1266 /* sync all the stats */ 1267 resInfo = _BCM_BST_RESOURCE(unit, bid); 1268 if (resInfo == NULL) { 1269 return BCM_E_PARAM; 1270 } 1271 1272 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 1273 bcm_gport_t gport = -1; 1274 bcm_cos_t cosq = -1; 1275 mem = resInfo->stat_mem[pipe]; 1276 reg = resInfo->stat_reg[pipe]; 1277 pipe_offset = 0; 1278 1279 if (pipe) { 1280 pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe; 1281 } 1282 1283 if (pipe == 1) { 1284 port = -2; 1285 } else { 1286 port = -1; 1287 } 1288 1289 if (mem != INVALIDm) { 1290 num_entries = soc_mem_index_count(unit, mem); 1291 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 1292 1293 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 1294 if (dmabuf == NULL) { 1295 return BCM_E_MEMORY; 1296 } 1297 1298 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 1299 soc_mem_index_min(unit, mem), 1300 soc_mem_index_max(unit, mem), 1301 dmabuf)) { 1302 soc_cm_sfree(unit, dmabuf); 1303 return BCM_E_INTERNAL; 1304 } 1305 1306 for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) { 1307 idx_offset = idx + pipe_offset; 1308 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 1309 dmabuf, idx); 1310 temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field); 1311 if (bst_info->track_mode) { 1312 if (resInfo->p_stat[idx_offset] < temp_val) { 1313 resInfo->p_stat[idx_offset] = temp_val; 1314 } 1315 } else { 1316 resInfo->p_stat[idx_offset] = temp_val; 1317 } 1318 1319 if (resInfo->p_threshold[idx_offset] && 1320 (resInfo->p_stat[idx_offset] >= 1321 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 1322 LOG_WARN(BSL_LS_SOC_COMMON, 1323 (BSL_META_U(unit, 1324 "unit %d %s %d mem %s bid %d port %d idx %d threshold %d stat %d!!\n"), 1325 unit, __FUNCTION__, __LINE__, SOC_MEM_NAME(unit, mem), bid, port, idx_offset, 1326 resInfo->p_threshold[idx_offset], resInfo->p_stat[idx_offset])); 1327 /* Generate SOC EVENT */ 1328 if (bst_info->handlers.reverse_resolve_index) { 1329 /* reverse map the inedx to port/cos pair */ 1330 bst_info->handlers.reverse_resolve_index(unit, bid, 1331 port, idx_offset, 1332 &gport, &cosq); 1333 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 1334 bid, gport, cosq); 1335 1336 } 1337 } 1338 } 1339 soc_cm_sfree(unit, dmabuf); 1340 } else if (reg != INVALIDr) { 1341 for (idx = 0; idx < resInfo->num_stat_pp; idx++) { 1342 idx_offset = idx + pipe_offset; 1343 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval); 1344 if (rv) { 1345 return BCM_E_INTERNAL; 1346 } 1347 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field); 1348 if (bst_info->track_mode) { 1349 if (resInfo->p_stat[idx_offset] < temp_val) { 1350 resInfo->p_stat[idx_offset] = temp_val; 1351 } 1352 } else { 1353 resInfo->p_stat[idx_offset] = temp_val; 1354 } 1355 1356 if (resInfo->p_threshold[idx_offset] && 1357 (resInfo->p_stat[idx_offset] >= 1358 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 1359 LOG_WARN(BSL_LS_SOC_COMMON, 1360 (BSL_META_U(unit, 1361 "unit %d %s %d reg %s bid %d port %d pipe %d idx %d threshold %d stat %d!!\n"), 1362 unit, __FUNCTION__, __LINE__, SOC_REG_NAME(unit, reg), bid, port, pipe, idx_offset, 1363 resInfo->p_threshold[idx_offset], resInfo->p_stat[idx_offset])); 1364 /* Generate SOC EVENT */ 1365 if (bst_info->handlers.reverse_resolve_index) { 1366 /* reverse map the inedx to port/cos pair */ 1367 bst_info->handlers.reverse_resolve_index(unit, bid, 1368 port, idx_offset, 1369 &gport, &cosq); 1370 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 1371 bid, gport, cosq); 1372 } 1373 } 1374 } 1375 } 1376 } 1377 } 1378 return BCM_E_NONE; 1379 } 1380 1381 STATIC int 1382 soc_td2_intr_check_cb_register(int unit) 1383 { 1384 BCM_IF_ERROR_RETURN(soc_td2_set_bst_intr_check_callback(unit, &_bcm_bst_td2_intr_check)); 1385 return SOC_E_NONE; 1386 } 1387 1388 STATIC int 1389 _bcm_td2_pre_sync(int unit, bcm_bst_stat_id_t bid, int *sync_val) 1390 { 1391 soc_field_t field = INVALIDf; 1392 _bcm_bst_resource_info_t *resInfo; 1393 uint32 rval; 1394 1395 if ((bid < 0) || (bid >= bcmBstStatIdMaxCount)) { 1396 return BCM_E_INTERNAL; 1397 } 1398 resInfo = _BCM_BST_RESOURCE(unit, bid); 1399 1400 if (resInfo == NULL) { 1401 return BCM_E_INTERNAL; 1402 } 1403 1404 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 1405 field = BST_TRACK_EN_CFAPf; 1406 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) { 1407 field = BST_TRACK_EN_THDIf; 1408 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) { 1409 field = BST_TRACK_EN_THDOf; 1410 } else { 1411 return BCM_E_PARAM; 1412 } 1413 1414 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 1415 *sync_val = soc_reg_field_get(unit, BST_TRACKING_ENABLEr, rval, 1416 field); 1417 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, field, 0); 1418 BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval)); 1419 1420 return SOC_E_NONE; 1421 } 1422 1423 STATIC int 1424 _bcm_td2_post_sync(int unit, bcm_bst_stat_id_t bid, int sync_val) 1425 { 1426 soc_field_t field = INVALIDf; 1427 _bcm_bst_resource_info_t *resInfo; 1428 uint32 rval; 1429 1430 if ((bid < 0) || (bid >= bcmBstStatIdMaxCount)) { 1431 return BCM_E_INTERNAL; 1432 } 1433 resInfo = _BCM_BST_RESOURCE(unit, bid); 1434 1435 if (resInfo == NULL) { 1436 return BCM_E_INTERNAL; 1437 } 1438 1439 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 1440 field = BST_TRACK_EN_CFAPf; 1441 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) { 1442 field = BST_TRACK_EN_THDIf; 1443 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) { 1444 field = BST_TRACK_EN_THDOf; 1445 } else { 1446 return BCM_E_PARAM; 1447 } 1448 1449 BCM_IF_ERROR_RETURN(READ_BST_TRACKING_ENABLEr(unit, &rval)); 1450 soc_reg_field_set(unit, BST_TRACKING_ENABLEr, &rval, field, sync_val); 1451 BCM_IF_ERROR_RETURN(WRITE_BST_TRACKING_ENABLEr(unit, rval)); 1452 1453 return SOC_E_NONE; 1454 } 1455 1456 STATIC int 1457 _bcm_bst_td2_init(int unit) 1458 { 1459 _bcm_bst_cmn_unit_info_t *bst_info; 1460 _bcm_bst_resource_info_t *pres; 1461 int td2_3320 = 0; 1462 int idx_count = 0; 1463 1464 td2_3320 = soc_feature(unit, soc_feature_min_resume_limit_1); 1465 1466 bst_info = _BCM_UNIT_BST_INFO(unit); 1467 1468 bst_info->to_cell = _bcm_bst_tr3_byte_to_cell; 1469 bst_info->to_byte = _bcm_bst_tr3_cell_to_byte; 1470 bst_info->control_set = _bcm_td2_bst_control_set; 1471 bst_info->control_get = _bcm_td2_bst_control_get; 1472 bst_info->intr_to_resources = _bcm_bst_td2_intr_to_resources; 1473 bst_info->hw_trigger_set = _bcm_bst_td2_hw_trigger_set; 1474 bst_info->hw_trigger_reset = _bcm_bst_td2_hw_trigger_reset; 1475 bst_info->hw_intr_cb = soc_td2_set_hw_intr_cb; 1476 bst_info->intr_enable_set = _bst_intr_enable_set; 1477 bst_info->pre_sync = _bcm_td2_pre_sync; 1478 bst_info->post_sync = _bcm_td2_post_sync; 1479 bst_info->hw_stat_snapshot = _bcm_bst_sync_hw_snapshot; 1480 bst_info->hw_stat_clear = _bcm_bst_hw_stat_clear; 1481 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 1482 bst_info->hw_sbusdma_desc_init = _bcm_bst_td2_sbusdma_desc_init; 1483 bst_info->hw_sbusdma_desc_deinit = _bcm_bst_td2_sbusdma_desc_deinit; 1484 bst_info->hw_sbusdma_desc_sync = _bcm_bst_td2_sbusdma_desc_sync; 1485 } 1486 if(soc_property_get(unit, spn_PROFILE_PG_1HDRM_8SHARED, 1)) { 1487 bst_info->mode = 1 ; 1488 } else { 1489 bst_info->mode = 0; 1490 } 1491 bst_info->max_bytes = bst_info->to_byte(unit, BST_THRESHOLD_MAX_HIGH); 1492 1493 /* Register a callback for soc to do bst interrupt check during mmu ser processing*/ 1494 soc_td2_intr_check_cb_register(unit); 1495 1496 /* bcmBstStatIdDevice */ 1497 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdDevice); 1498 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1499 pres->index_min = 0; 1500 pres->index_max = 0; 1501 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_DEV); 1502 #if defined(BCM_APACHE_SUPPORT) 1503 if (SOC_IS_APACHE(unit)) { 1504 _BCM_BST_STAT_INFO(pres, INVALIDm, CFAP_BST_STATr, BST_STATf); 1505 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAP_BST_THRSr, BST_THRESHOLDf, 1); 1506 } else 1507 #endif 1508 { 1509 _BCM_BST_STAT_INFO(pres, INVALIDm, CFAPBSTSTATr, BST_STATf); 1510 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, CFAPBSTTHRSr, BST_THRESHOLDf, 1); 1511 } 1512 _BCM_BST_RESOURCE_STAT_INIT(pres, 1, "bst cfap"); 1513 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 1, "bst cfap"); 1514 1515 /* bcmBstStatIdEgrPool */ 1516 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPool); 1517 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1518 pres->index_min = 0; 1519 pres->index_max = 3; 1520 pres->threshold_adj = td2_3320 ? -1 : 0; 1521 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 1522 _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDM_DB_POOL_MCUC_BST_STATr, BST_STATf); 1523 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 1524 MMU_THDM_DB_POOL_MCUC_BST_THRESHOLDr, BST_STATf, 1); 1525 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egrpool"); 1526 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egrpool"); 1527 1528 /* bcmBstStatIdEgrMCastPool */ 1529 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrMCastPool); 1530 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1531 pres->index_min = 0; 1532 pres->index_max = 3; 1533 pres->threshold_adj = td2_3320 ? -1 : 0; 1534 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 1535 _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDM_DB_POOL_MC_BST_STATr, BST_STATf); 1536 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 1537 MMU_THDM_DB_POOL_MC_BST_THRESHOLDr, BST_STATf, 1); 1538 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst egr mcpool"); 1539 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst egr mcpool"); 1540 1541 /* bcmBstStatIdIngPool */ 1542 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdIngPool); 1543 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1544 pres->index_min = 0; 1545 pres->index_max = 3; 1546 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_ING); 1547 _BCM_BST_STAT_INFO(pres, INVALIDm, THDI_BST_SP_GLOBAL_SHARED_CNTr, 1548 SP_GLOBAL_SHARED_CNTf); 1549 1550 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 1551 THDI_BST_SP_GLOBAL_SHARED_PROFILEr, SP_GLOBAL_SHARED_PROFILEf, 1); 1552 1553 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst ing pool"); 1554 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst ing pool"); 1555 1556 /* bcmBstStatIdPortPool */ 1557 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPortPool); 1558 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1559 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1560 _BCM_BST_CMN_RES_F_PIPED | 1561 _BCM_BST_CMN_RES_F_RES_ING); 1562 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 1563 1564 _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_SP_CONFIG_Xm, 1565 THDI_PORT_SP_CONFIG_Ym, INVALIDr, INVALIDr, SP_BST_PROFILE_SHAREDf, 1); 1566 1567 _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_SP_SHARED_PROFILEr, 1568 BST_SP_SHARED_THRESHf); 1569 1570 _BCM_BST_STAT_INFO2(pres, THDI_PORT_SP_BST_Xm, THDI_PORT_SP_BST_Ym, 1571 INVALIDr, INVALIDr, SP_BST_STAT_PORT_COUNTf); 1572 1573 _BCM_BST_RESOURCE_STAT_INIT(pres, 1574 soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) * NUM_PIPE(unit), 1575 "bst port pool"); 1576 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 1577 soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) * NUM_PIPE(unit), 1578 "bst port pool"); 1579 pres->index_min = 0; 1580 pres->index_max = soc_mem_index_count(unit, THDI_PORT_SP_BST_Xm) * 1581 NUM_PIPE(unit); 1582 1583 /* bcmBstStatIdPriGroupShared */ 1584 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupShared); 1585 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1586 1587 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1588 _BCM_BST_CMN_RES_F_PIPED | 1589 _BCM_BST_CMN_RES_F_RES_ING); 1590 1591 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 1592 1593 _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_PG_CONFIG_Xm, 1594 THDI_PORT_PG_CONFIG_Ym, INVALIDr, INVALIDr, PG_BST_PROFILE_SHAREDf, 1); 1595 1596 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 1597 THDI_BST_PG_SHARED_PROFILEr, BST_PG_SHARED_THRESHf); 1598 1599 _BCM_BST_STAT_INFO2(pres, THDI_PORT_PG_BST_Xm, THDI_PORT_PG_BST_Ym, 1600 INVALIDr, INVALIDr, PG_BST_STAT_SHAREDf); 1601 1602 #if defined(BCM_APACHE_SUPPORT) 1603 #if defined(BCM_MONTEREY_SUPPORT) 1604 if (SOC_IS_MONTEREY(unit)) { 1605 /* Stat res -THDI_PORT_PG_BST_X : 68 (ports) * 8 (PGs) */ 1606 _BCM_BST_RESOURCE_STAT_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg"); 1607 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg"); 1608 pres->index_min = 0; 1609 pres->index_max = (68 * 8) * NUM_PIPE(unit); 1610 } else 1611 #endif 1612 if (SOC_IS_APACHE(unit)) { 1613 /* Stat res - THDI_PORT_PG_BST_X/_Y : 75(Ports) * 8(PGs) * 1(pipes) */ 1614 _BCM_BST_RESOURCE_STAT_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg"); 1615 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg"); 1616 pres->index_min = 0; 1617 pres->index_max = (75 * 8) * NUM_PIPE(unit); 1618 } else 1619 #endif 1620 { 1621 /* Stat res - THDI_PORT_PG_BST_X/_Y : 53(Ports) * 8(PGs) * 2(pipes) */ 1622 _BCM_BST_RESOURCE_STAT_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg"); 1623 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg"); 1624 pres->index_min = 0; 1625 pres->index_max = (53 * 8) * NUM_PIPE(unit); 1626 } 1627 1628 /* bcmBstStatIdPriGroupHeadroom */ 1629 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdPriGroupHeadroom); 1630 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1631 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1632 _BCM_BST_CMN_RES_F_PIPED | 1633 _BCM_BST_CMN_RES_F_RES_ING); 1634 1635 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_ALL(unit)); 1636 1637 _BCM_BST_PROFILE_INFO(pres, INVALIDm, THDI_BST_PG_HDRM_PROFILEr, 1638 BST_PG_HDRM_THRESHf); 1639 1640 _BCM_BST_THRESHOLD_INFO2(pres, THDI_PORT_PG_CONFIG_Xm, 1641 THDI_PORT_PG_CONFIG_Ym, INVALIDr, INVALIDr, PG_BST_PROFILE_HDRMf, 1); 1642 1643 _BCM_BST_STAT_INFO2(pres, THDI_PORT_PG_BST_Xm, THDI_PORT_PG_BST_Ym, 1644 INVALIDr, INVALIDr, PG_BST_STAT_HDRMf); 1645 1646 #if defined(BCM_APACHE_SUPPORT) 1647 #if defined(BCM_MONTEREY_SUPPORT) 1648 if (SOC_IS_MONTEREY(unit)) { 1649 /* Stat res -THDI_PORT_PG_BST_X : 68 (ports) * 8 (PGs) */ 1650 _BCM_BST_RESOURCE_STAT_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1651 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (68 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1652 pres->index_min = 0; 1653 pres->index_max = (68 * 8) * NUM_PIPE(unit); 1654 } else 1655 #endif 1656 if (SOC_IS_APACHE(unit)) { 1657 /* Stat res - THDI_PORT_PG_BST_X/_Y : 75(Ports) * 8(PGs) * 2(pipes) */ 1658 _BCM_BST_RESOURCE_STAT_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1659 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (75 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1660 pres->index_min = 0; 1661 pres->index_max = (75 * 8) * NUM_PIPE(unit); 1662 } else 1663 #endif 1664 { 1665 /* Stat res - THDI_PORT_PG_BST_X/_Y : 53(Ports) * 8(PGs) * 2(pipes) */ 1666 _BCM_BST_RESOURCE_STAT_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1667 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, (53 * 8) * NUM_PIPE(unit), "bst pg hdrm"); 1668 pres->index_min = 0; 1669 pres->index_max = (53 * 8) * NUM_PIPE(unit); 1670 } 1671 1672 /* bcmBstStatIdMcast */ 1673 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdMcast); 1674 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1675 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1676 _BCM_BST_CMN_RES_F_PIPED | 1677 _BCM_BST_CMN_RES_F_RES_EGR); 1678 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_CMIC(unit)); 1679 _BCM_BST_PROFILE_INFO(pres, INVALIDm, 1680 MMU_THDM_DB_QUEUE_MC_BST_THRESHOLD_PROFILEr, BST_STATf); 1681 1682 _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDM_DB_QUEUE_CONFIG_0m, 1683 MMU_THDM_DB_QUEUE_CONFIG_1m, INVALIDr, INVALIDr, 1684 BST_THRESHOLD_PROFILEf, 1); 1685 1686 idx_count = soc_mem_index_count(unit, MMU_THDM_DB_QUEUE_BST_0m); 1687 _BCM_BST_STAT_INFO2(pres, MMU_THDM_DB_QUEUE_BST_0m, MMU_THDM_DB_QUEUE_BST_1m, 1688 INVALIDr, INVALIDr, DATAf); 1689 _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit), 1690 "bst mcast"); 1691 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit), 1692 "bst mcast"); 1693 pres->index_min = 0; 1694 pres->index_max = idx_count * NUM_PIPE(unit); 1695 1696 /* bcmBstStatIdUcast */ 1697 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUcast); 1698 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1699 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1700 _BCM_BST_CMN_RES_F_PIPED | 1701 _BCM_BST_CMN_RES_F_RES_EGR); 1702 1703 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 1704 1705 _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_QUEUEm, 1706 MMU_THDU_YPIPE_CONFIG_QUEUEm, INVALIDr, INVALIDr, Q_WM_MAX_THRESHOLDf, 8); 1707 1708 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QUEUE_BST_THRESHOLDr, BST_STATf); 1709 1710 _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_QUEUEm, 1711 MMU_THDU_YPIPE_BST_QUEUEm, INVALIDr, INVALIDr, DATAf); 1712 1713 idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_QUEUEm) - 1; 1714 _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit), 1715 "bst ucast"); 1716 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit), 1717 "bst ucast"); 1718 pres->index_min = 0; 1719 pres->index_max = idx_count * NUM_PIPE(unit); 1720 1721 /* bcmBstStatIdEgrPortPoolSharedUcast */ 1722 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedUcast); 1723 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1724 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1725 _BCM_BST_CMN_RES_F_PIPED | 1726 _BCM_BST_CMN_RES_F_RES_EGR); 1727 1728 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 1729 1730 _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_PORTm, 1731 MMU_THDU_YPIPE_CONFIG_PORTm, INVALIDr, INVALIDr, WM_MAX_THRESHOLDf, 1732 8); 1733 1734 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_PORT_BST_THRESHOLDr, BST_STATf); 1735 1736 _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_PORTm, 1737 MMU_THDU_YPIPE_BST_PORTm, INVALIDr, INVALIDr, DATAf); 1738 idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_PORTm); 1739 _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit), 1740 "bst egr port pool shared ucast"); 1741 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit), 1742 "bst egr port pool shared ucast"); 1743 pres->index_min = 0; 1744 pres->index_max = idx_count * NUM_PIPE(unit); 1745 1746 /* bcmBstStatIdEgrPortPoolSharedMcast */ 1747 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdEgrPortPoolSharedMcast); 1748 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1749 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1750 _BCM_BST_CMN_RES_F_PIPED | 1751 _BCM_BST_CMN_RES_F_RES_EGR | 1752 _BCM_BST_CMN_RES_F_PORTED); 1753 1754 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 1755 1756 _BCM_BST_THRESHOLD_INFO2(pres, INVALIDm, INVALIDm, 1757 MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr, 1758 MMU_THDM_DB_PORTSP_THRESHOLD_PROFILE_SELr, 1759 BST_THRESHOLD_PROFILEf, 1); 1760 1761 _BCM_BST_PROFILE_INFO(pres, INVALIDm,MMU_THDM_DB_PORTSP_BST_THRESHOLDr, 1762 BST_STATf); 1763 1764 _BCM_BST_STAT_INFO2(pres, MMU_THDM_DB_PORTSP_BST_0m, 1765 MMU_THDM_DB_PORTSP_BST_1m, INVALIDr, INVALIDr, DATAf); 1766 idx_count = soc_mem_index_count(unit, MMU_THDM_DB_PORTSP_BST_0m); 1767 _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit), 1768 "bst egr port pool shared mcast"); 1769 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit), 1770 "bst egr port pool shared mcast"); 1771 pres->index_min = 0; 1772 pres->index_max = idx_count * NUM_PIPE(unit); 1773 1774 /* bcmBstStatIdRQEQueue */ 1775 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEQueue); 1776 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1777 pres->index_min = 0; 1778 pres->index_max = 10; 1779 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 1780 _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDR_DB_BST_STAT_PRIQr, BST_STATf); 1781 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 1782 MMU_THDR_DB_BST_THRESHOLD_PRIQr, BST_THRf, 1); 1783 _BCM_BST_RESOURCE_STAT_INIT(pres, 11, "bst RQE queue"); 1784 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 11, "bst RQE queue"); 1785 1786 /* bcmBstStatIdRQEPool */ 1787 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdRQEPool); 1788 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1789 pres->index_min = 0; 1790 pres->index_max = 3; 1791 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_RES_EGR); 1792 _BCM_BST_STAT_INFO(pres, INVALIDm, MMU_THDR_DB_BST_STAT_SPr, BST_STATf); 1793 _BCM_BST_THRESHOLD_INFO(pres, INVALIDm, 1794 MMU_THDR_DB_BST_THRESHOLD_SPr, BST_THRf, 1); 1795 _BCM_BST_RESOURCE_STAT_INIT(pres, 4, "bst RQE pool"); 1796 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, 4, "bst RQE pool"); 1797 1798 /* bcmBstStatIdUCQueueGroup */ 1799 pres = _BCM_BST_RESOURCE(unit, bcmBstStatIdUCQueueGroup); 1800 _BCM_BST_STAT_THRESHOLD_INFO_INIT(pres); 1801 _BCM_BST_RESOURCE_FLAG_SET(pres, _BCM_BST_CMN_RES_F_PROFILEID | 1802 _BCM_BST_CMN_RES_F_PIPED | 1803 _BCM_BST_CMN_RES_F_RES_EGR | 1804 _BCM_BST_CMN_RES_F_PORTED); 1805 _BCM_BST_RESOURCE_PBMP_SET(pres, PBMP_PORT_ALL(unit)); 1806 1807 _BCM_BST_THRESHOLD_INFO2(pres, MMU_THDU_XPIPE_CONFIG_QGROUPm, 1808 MMU_THDU_YPIPE_CONFIG_QGROUPm, INVALIDr, INVALIDr, Q_WM_MAX_THRESHOLDf, 8); 1809 1810 _BCM_BST_PROFILE_INFO(pres, INVALIDm, OP_UC_QGROUP_BST_THRESHOLDr, BST_STATf); 1811 1812 _BCM_BST_STAT_INFO2(pres, MMU_THDU_XPIPE_BST_QGROUPm, 1813 MMU_THDU_YPIPE_BST_QGROUPm, INVALIDr, INVALIDr, DATAf); 1814 1815 idx_count = soc_mem_index_count(unit, MMU_THDU_XPIPE_BST_QGROUPm); 1816 _BCM_BST_RESOURCE_STAT_INIT(pres, idx_count * NUM_PIPE(unit), 1817 "bst unicast queue group"); 1818 _BCM_BST_RESOURCE_THRESHOLD_INIT(pres, idx_count * NUM_PIPE(unit), 1819 "bst unicast queue group"); 1820 pres->index_min = 0; 1821 pres->index_max = idx_count * NUM_PIPE(unit); 1822 1823 return BCM_E_NONE; 1824 } 1825 1826 #endif /* BCM_TRIDENT2_SUPPORT || BCM_APACHE_SUPPORT*/ 1827 1828 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 1829 defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_APACHE_SUPPORT) 1830 STATIC int 1831 _bcm_bst_sync_thread_ok_to_run(int unit) 1832 { 1833 _bcm_bst_cmn_unit_info_t *bst_info; 1834 1835 bst_info = _BCM_UNIT_BST_INFO(unit); 1836 1837 if ((bst_info == NULL) || (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) || 1838 (bst_info->interval <= 0)) { 1839 return FALSE; 1840 } 1841 1842 return TRUE; 1843 } 1844 1845 int 1846 _bst_intr_enable_set(int unit, int enable) 1847 { 1848 uint64 rval64; 1849 uint32 rval; 1850 1851 if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) { 1852 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 1853 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_EN_64r(unit, &rval64)); 1854 soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64, 1855 BST_THDO_INT_ENf, enable); 1856 soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64, 1857 BST_THDI_INT_ENf, enable); 1858 soc_reg64_field32_set(unit, MEM_FAIL_INT_EN_64r, &rval64, 1859 BST_CFAP_INT_ENf, enable); 1860 BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_EN_64r(unit, rval64)); 1861 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 1862 if (!soc_property_get(unit, spn_POLLED_IRQ_MODE, 0)) { 1863 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_ENr(unit, &rval)); 1864 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1865 BST_THDO_INT_ENf, enable); 1866 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1867 BST_THDI_INT_ENf, enable); 1868 soc_reg_field_set(unit, MEM_FAIL_INT_ENr, &rval, 1869 BST_CFAP_INT_ENf, enable); 1870 BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_ENr(unit, rval)); 1871 } 1872 } 1873 } 1874 return 0; 1875 } 1876 1877 int 1878 _bst_intr_status_reset(int unit) 1879 { 1880 uint32 rval; 1881 uint64 rval64; 1882 1883 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_STAT_64r)) { 1884 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64)); 1885 soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r, 1886 &rval64, BST_CFAP_INTf, 0); 1887 soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r, 1888 &rval64, BST_THDO_INTf, 0); 1889 soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r, 1890 &rval64, BST_THDI_INTf, 0); 1891 BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64)); 1892 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_STATr)) { 1893 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 1894 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, 1895 BST_CFAP_INTf, 0); 1896 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, 1897 BST_THDO_INTf, 0); 1898 soc_reg_field_set(unit, MEM_FAIL_INT_STATr, &rval, 1899 BST_THDI_INTf, 0); 1900 BCM_IF_ERROR_RETURN(WRITE_MEM_FAIL_INT_STATr(unit, rval)); 1901 } 1902 1903 return BCM_E_NONE; 1904 } 1905 1906 int 1907 _bcm_bst_hw_event_cb(int unit) 1908 { 1909 1910 _bcm_bst_cmn_unit_info_t *bst_info; 1911 bst_info = _BCM_UNIT_BST_INFO(unit); 1912 1913 if ((!bst_info) || (bst_info->bst_trigger == NULL)) { 1914 return 0; 1915 } 1916 if (bst_info->intr_enable_set) { 1917 bst_info->intr_enable_set(unit, 0); 1918 } 1919 sal_sem_give(bst_info->bst_trigger); 1920 return 0; 1921 } 1922 1923 STATIC void 1924 _bcm_bst_sync_thread(void *cookie) 1925 { 1926 int unit; 1927 uint32 res_flags = 0; 1928 _bcm_bst_cmn_unit_info_t *bst_info; 1929 1930 unit = PTR_TO_INT(cookie); 1931 1932 bst_info = _BCM_UNIT_BST_INFO(unit); 1933 if (!bst_info) { 1934 sal_thread_exit(0); 1935 return; 1936 } 1937 1938 if (bst_info->hw_intr_cb) { 1939 bst_info->hw_intr_cb(unit); 1940 } 1941 1942 if (bst_info->intr_enable_set) { 1943 bst_info->intr_enable_set(unit, 1); 1944 } 1945 1946 /* When Thread VALID flag is disabled, loop should break, 1947 * thread must exit. 1948 */ 1949 while (_bcm_bst_sync_thread_ok_to_run(unit) == TRUE) { 1950 /* When Thread ENABLE flag is disabled, thread operations are paused 1951 * until ENABLE flag is enabled. 1952 */ 1953 if (_BCM_BST_SYNC_ENABLED(bst_info) == TRUE) { 1954 if (bst_info->bst_trigger) { 1955 1956 /* 1957 _bst_intr_enable_set(unit, 1); 1958 */ 1959 1960 if (sal_sem_take(bst_info->bst_trigger, bst_info->interval) < 0) { 1961 if (bst_info->interval <= 0) { 1962 break; 1963 } 1964 continue; 1965 } 1966 } else { 1967 sal_usleep(bst_info->interval); 1968 } 1969 1970 if (bst_info->interval <= 0) { 1971 break; 1972 } 1973 1974 res_flags = 0; 1975 if (bst_info->intr_to_resources) { 1976 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 1977 bst_info->intr_to_resources(unit, &res_flags); 1978 sal_mutex_give(bst_info->bst_reslock); 1979 } 1980 } else { 1981 sal_usleep(bst_info->interval); 1982 } 1983 } 1984 1985 if (bst_info->intr_enable_set) { 1986 bst_info->intr_enable_set(unit, 0); 1987 } 1988 bst_info->sync_flags &= ~_BCM_BST_SYNC_F_ENABLE; 1989 bst_info->sync_flags &= ~_BCM_BST_SYNC_F_THREAD_VALID; 1990 1991 sal_sem_give(bst_info->bst_thread); 1992 sal_thread_exit(0); 1993 return; 1994 } 1995 1996 int 1997 _bcm_bst_sync_thread_start(int unit) 1998 { 1999 _bcm_bst_cmn_unit_info_t *bst_info; 2000 int rv = BCM_E_NONE; 2001 2002 bst_info = _BCM_UNIT_BST_INFO(unit); 2003 if (!bst_info) { 2004 return BCM_E_INIT; 2005 } 2006 2007 if (_BCM_BST_SYNC_THREAD_VALID(bst_info)) { 2008 return BCM_E_NONE; 2009 } 2010 2011 if (bst_info->hw_sbusdma_desc_init) { 2012 rv = bst_info->hw_sbusdma_desc_init(unit); 2013 if (BCM_FAILURE(rv)) { 2014 BCM_IF_ERROR_RETURN(bst_info->hw_sbusdma_desc_deinit(unit)); 2015 LOG_ERROR(BSL_LS_SOC_COMMON, 2016 (BSL_META_U(unit, "hw_sbusdma_desc_init failed rv = %d\n"), rv)); 2017 return BCM_E_INIT; 2018 } 2019 } 2020 2021 bst_info->sync_flags |= _BCM_BST_SYNC_F_THREAD_VALID; 2022 bst_info->interval = 1000000; 2023 bst_info->bst_thread_id = sal_thread_create("bcm_bst_sync_thread", 2024 SAL_THREAD_STKSZ, 2025 soc_property_get(unit, spn_BST_SYNC_THREAD_PRI, 50), 2026 _bcm_bst_sync_thread, 2027 INT_TO_PTR(unit)); 2028 2029 _BCM_BST_SYNC_THREAD_ENABLE_SET(unit, TRUE); 2030 return rv; 2031 } 2032 2033 int 2034 _bcm_bst_sync_thread_stop(int unit) 2035 { 2036 _bcm_bst_cmn_unit_info_t *bst_info; 2037 2038 bst_info = _BCM_UNIT_BST_INFO(unit); 2039 if (!bst_info) { 2040 return BCM_E_INIT; 2041 } 2042 2043 if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) { 2044 return BCM_E_NONE; 2045 } 2046 2047 bst_info->sync_flags &= ~_BCM_BST_SYNC_F_ENABLE; 2048 bst_info->sync_flags &= ~_BCM_BST_SYNC_F_THREAD_VALID; 2049 2050 if (bst_info->bst_trigger) { 2051 sal_sem_give(bst_info->bst_trigger); 2052 } 2053 2054 /* If thread already running wait for it to be done before stopping */ 2055 (void)sal_sem_take(bst_info->bst_thread, sal_sem_FOREVER); 2056 2057 if (bst_info->hw_sbusdma_desc_deinit) { 2058 BCM_IF_ERROR_RETURN(bst_info->hw_sbusdma_desc_deinit(unit)); 2059 } 2060 2061 return BCM_E_NONE; 2062 } 2063 2064 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 2065 defined(BCM_APACHE_SUPPORT) 2066 STATIC int 2067 _bcm_bst_check_intr_status(int unit, bcm_bst_stat_id_t bid) 2068 { 2069 soc_field_t fld = INVALIDf; 2070 _bcm_bst_resource_info_t *resInfo; 2071 uint64 rval64; 2072 uint32 rval; 2073 uint32 fval = 0; 2074 2075 resInfo = _BCM_BST_RESOURCE(unit, bid); 2076 2077 if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_DEV) { 2078 fld = BST_CFAP_INTf; 2079 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_ING) { 2080 fld = BST_THDI_INTf; 2081 } else if (resInfo->flags & _BCM_BST_CMN_RES_F_RES_EGR) { 2082 fld = BST_THDO_INTf; 2083 } 2084 2085 if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_EN_64r)) { 2086 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STAT_64r(unit, &rval64)); 2087 fval = soc_reg64_field32_get(unit, MEM_FAIL_INT_STAT_64r, 2088 rval64, fld); 2089 } else if (SOC_REG_IS_VALID(unit, MEM_FAIL_INT_ENr)) { 2090 BCM_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &rval)); 2091 fval = soc_reg_field_get(unit, MEM_FAIL_INT_STATr, rval, 2092 fld); 2093 } 2094 return fval; 2095 } 2096 #endif 2097 #endif 2098 2099 int 2100 _bcm_bst_cmn_profile_delete_hw(int unit, bcm_bst_stat_id_t bid, 2101 int id, int profile_index) 2102 { 2103 _bcm_bst_resource_info_t *resInfo; 2104 2105 resInfo = _BCM_BST_RESOURCE(unit, bid); 2106 2107 if (resInfo->profile_r[id]) { 2108 SOC_IF_ERROR_RETURN 2109 (soc_profile_reg_delete(unit, resInfo->profile_r[id], profile_index)); 2110 } else if (resInfo->profile_m) { 2111 SOC_IF_ERROR_RETURN 2112 (soc_profile_mem_delete(unit, resInfo->profile_m, profile_index)); 2113 } else { 2114 return BCM_E_INIT; 2115 } 2116 2117 return BCM_E_NONE; 2118 } 2119 2120 STATIC int 2121 _bcm_bst_default_profile_init(int unit) 2122 { 2123 _bcm_bst_cmn_unit_info_t *bst_info; 2124 _bcm_bst_resource_info_t *resInfo; 2125 int ei, pipe, index_max = 0; 2126 bcm_bst_stat_id_t bid; 2127 int entry_size; 2128 bcm_cosq_bst_profile_t profile; 2129 int i, wb = 0; 2130 uint32 profile_index; 2131 2132 wb = SOC_WARM_BOOT(unit) ? 1 : 0; 2133 2134 bst_info = _BCM_UNIT_BST_INFO(unit); 2135 2136 if (bst_info->profile_init) { 2137 return bst_info->profile_init(unit); 2138 } 2139 2140 _BCM_BST_RESOURCE_ITER(bst_info, bid) { 2141 resInfo = _BCM_BST_RESOURCE(unit, bid); 2142 2143 if ((resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) == 0) { 2144 continue; 2145 } 2146 2147 for (i = 0; i < _BCM_MAX_PROFILES; i ++) { 2148 resInfo->profile_r[i] = NULL; 2149 } 2150 resInfo->profile_m = NULL; 2151 if (resInfo->profile_mem != INVALIDm) { 2152 soc_profile_mem_t_init(&resInfo->iprofile_m); 2153 entry_size = soc_mem_entry_bytes(unit, resInfo->profile_mem); 2154 SOC_IF_ERROR_RETURN( 2155 soc_profile_mem_create(unit, &resInfo->profile_mem, 2156 &entry_size, 1, &resInfo->iprofile_m)); 2157 resInfo->profile_m = &resInfo->iprofile_m; 2158 } else if (resInfo->profile_reg[0] != INVALIDr) { 2159 soc_profile_reg_t_init(&resInfo->iprofile_r[0]); 2160 SOC_IF_ERROR_RETURN 2161 (soc_profile_reg_create(unit, &resInfo->profile_reg[0], 2162 1, &resInfo->iprofile_r[0])); 2163 resInfo->profile_r[0] = &resInfo->iprofile_r[0]; 2164 } 2165 } 2166 2167 /* create default profiles. */ 2168 _BCM_BST_RESOURCE_ITER(bst_info, bid) { 2169 profile.byte = bst_info->max_bytes; 2170 resInfo = _BCM_BST_RESOURCE(unit, bid); 2171 if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) { 2172 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2173 if (SOC_IS_TD2_TT2(unit)) { 2174 if (resInfo->threshold_gran != 0) { 2175 profile.byte = bst_info->to_byte(unit, 2176 BST_THRESHOLD_MAX_HIGH - (resInfo->threshold_gran - 1)); 2177 } 2178 } 2179 #endif 2180 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 2181 if ((resInfo->threshold_mem[pipe] == INVALIDm) && 2182 (resInfo->threshold_reg[pipe] == INVALIDr)) { 2183 continue; 2184 } 2185 2186 if (!wb) { 2187 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw(unit, pipe, 2188 BCM_BST_DUP_XPE, -1, bid, &profile, &profile_index)); 2189 } 2190 if (SOC_IS_TOMAHAWKX(unit)) { 2191 /* TH has 4 MMU instances unlike previous devices 2192 where MMU instance is 1 */ 2193 index_max = resInfo->index_max / (NUM_PIPE(unit) * 2194 resInfo->num_instance); 2195 } else { 2196 index_max = resInfo->index_max / NUM_PIPE(unit); 2197 } 2198 for (ei = resInfo->index_min; ei < index_max; ei++) { 2199 if (wb) { 2200 SOC_IF_ERROR_RETURN( 2201 _bcm_bst_cmn_io_op(unit, 2202 BST_OP_GET | BST_OP_THD, 2203 pipe, ei, bid, 2204 resInfo->threshold_mem[pipe], 2205 resInfo->threshold_reg[pipe], 2206 resInfo->threshold_field, 2207 &profile_index)); 2208 } 2209 2210 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2211 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) && 2212 !SOC_IS_TRIDENT3X(unit)) { 2213 if (((bid == bcmBstStatIdPriGroupHeadroom) && 2214 (bst_info->mode == 1)) || 2215 ((bid == bcmBstStatIdPriGroupShared) && 2216 (bst_info->mode == 0))) { 2217 break; 2218 } 2219 } 2220 #endif 2221 if (resInfo->profile_r[0]) { 2222 BCM_IF_ERROR_RETURN(soc_profile_reg_reference(unit, 2223 resInfo->profile_r[0], profile_index, 1)); 2224 } else if (resInfo->profile_m) { 2225 BCM_IF_ERROR_RETURN(soc_profile_mem_reference(unit, 2226 resInfo->profile_m, profile_index, 1)); 2227 } 2228 } 2229 } 2230 } 2231 } 2232 2233 #if defined(BCM_TRIDENT2_SUPPORT) 2234 if (SOC_IS_TRIDENT2(unit)) { 2235 /* Set default threshold for bcmBstStatIdDevice and bcmBstStatIdIngPool 2236 * from zero to max to avoid unexpected trigger. 2237 */ 2238 int pool_num = 4; 2239 bcm_cosq_bst_profile_t_init(&profile); 2240 profile.byte = bst_info->max_bytes; 2241 for (ei = 0; ei < pool_num; ei++) { 2242 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_set_hw 2243 (unit, -1, BCM_BST_DUP_XPE, ei, 2244 bcmBstStatIdIngPool, &profile, NULL)); 2245 } 2246 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CFAPBSTTHRSr, 2247 REG_PORT_ANY, BST_THRESHOLDf, 2248 BST_THRESHOLD_MAX_HIGH)); 2249 } 2250 #endif 2251 2252 return BCM_E_NONE; 2253 } 2254 2255 int _bcm_bst_attach(int unit, _bcm_bst_device_handlers_t *cbs) 2256 { 2257 _bcm_bst_cmn_unit_info_t *bst_info; 2258 2259 (void)_bcm_bst_detach(unit); 2260 2261 bst_info = _BCM_UNIT_BST_INFO(unit); 2262 2263 if (NULL == bst_info) { 2264 bst_info = sal_alloc(sizeof(_bcm_bst_cmn_unit_info_t), "bst_dev_info"); 2265 if (!bst_info) { 2266 return BCM_E_MEMORY; 2267 } 2268 } 2269 2270 sal_memset(bst_info, 0, sizeof(_bcm_bst_cmn_unit_info_t)); 2271 2272 if (cbs) { 2273 sal_memcpy(&bst_info->handlers, cbs, sizeof(_bcm_bst_device_handlers_t)); 2274 } 2275 2276 _BCM_UNIT_BST_INFO(unit) = bst_info; 2277 2278 if (bst_info->bst_trigger == NULL) { 2279 bst_info->bst_trigger = sal_sem_create("bst_trigger", sal_sem_BINARY, 0); 2280 } 2281 2282 if (bst_info->bst_trigger == NULL) { 2283 (void)_bcm_bst_detach(unit); 2284 return BCM_E_MEMORY; 2285 } 2286 2287 if (bst_info->bst_thread == NULL) { 2288 bst_info->bst_thread = sal_sem_create("bst_thread", sal_sem_BINARY, 0); 2289 } 2290 2291 if (bst_info->bst_thread == NULL) { 2292 (void)_bcm_bst_detach(unit); 2293 return BCM_E_MEMORY; 2294 } 2295 2296 /* Create protection mutex. */ 2297 if (bst_info->bst_reslock == NULL) { 2298 bst_info->bst_reslock = sal_mutex_create("bst_resource_lock"); 2299 } 2300 2301 if (bst_info->bst_reslock == NULL) { 2302 (void)_bcm_bst_detach(unit); 2303 return BCM_E_MEMORY; 2304 } 2305 #if defined(BCM_TOMAHAWK3_SUPPORT) 2306 if (SOC_IS_TOMAHAWK3(unit)) { 2307 SOC_IF_ERROR_RETURN(bcm_bst_th3_init(unit)); 2308 } else 2309 #endif 2310 #if defined(BCM_TOMAHAWK_SUPPORT) 2311 if (SOC_IS_TOMAHAWKX(unit)) { 2312 SOC_IF_ERROR_RETURN(bcm_bst_th_init(unit)); 2313 } else 2314 #endif 2315 #if defined(BCM_HELIX5_SUPPORT) 2316 if (SOC_IS_HELIX5(unit)) { 2317 SOC_IF_ERROR_RETURN(bcm_bst_hx5_init(unit)); 2318 } else 2319 #endif 2320 #if defined(BCM_TRIDENT3_SUPPORT) 2321 if (SOC_IS_TRIDENT3X(unit)) { 2322 SOC_IF_ERROR_RETURN(bcm_bst_td3_init(unit)); 2323 } else 2324 #endif 2325 #if defined(BCM_TRIUMPH3_SUPPORT) 2326 if (SOC_IS_TRIUMPH3(unit)) { 2327 SOC_IF_ERROR_RETURN(_bcm_bst_triumph3_init(unit)); 2328 } else 2329 #endif 2330 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2331 if (SOC_IS_TD2_TT2(unit)) { 2332 SOC_IF_ERROR_RETURN(_bcm_bst_td2_init(unit)); 2333 } else 2334 #endif 2335 { 2336 return BCM_E_UNAVAIL; 2337 } 2338 2339 /* setup default profile. default profile is the max limit 2340 * of the buffer sizes and is equivalent of being disabled. 2341 */ 2342 2343 SOC_IF_ERROR_RETURN(_bcm_bst_default_profile_init(unit)); 2344 2345 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2346 if (SOC_WARM_BOOT(unit) && (SOC_IS_TRIDENT2(unit) || 2347 SOC_IS_APACHE(unit))) { 2348 BCM_IF_ERROR_RETURN(_bcm_td2_bst_info_restore(unit)); 2349 BCM_IF_ERROR_RETURN(_bcm_td2_bst_resource_threshold_restore(unit)); 2350 if (_bcm_td2_bst_sync_thread_restore(unit) == TRUE) { 2351 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_start(unit)); 2352 } 2353 } else 2354 #endif 2355 { 2356 /* Initialize the trigger and Snapshot regs */ 2357 if (bst_info->hw_trigger_reset) { 2358 bst_info->hw_trigger_reset(unit, -1); 2359 } 2360 } 2361 2362 return BCM_E_NONE; 2363 } 2364 2365 int _bcm_bst_detach(int unit) 2366 { 2367 _bcm_bst_cmn_unit_info_t *bst_info; 2368 _bcm_bst_resource_info_t *resInfo; 2369 bcm_bst_stat_id_t bid; 2370 int i; 2371 2372 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2373 return BCM_E_NONE; 2374 } 2375 2376 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 2377 defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \ 2378 defined(BCM_APACHE_SUPPORT) 2379 BCM_IF_ERROR_RETURN(_bcm_bst_sync_thread_stop(unit)); 2380 #endif /* BCM_TRIUMPH3_SUPPORT || BCM_TRIDENT2_SUPPORT || BCM_TOMAHAWK_SUPPORT 2381 * BCM_TRIDENT3_SUPPORT || BCM_APACHE_SUPPORT 2382 */ 2383 2384 _BCM_BST_RESOURCE_ITER(bst_info, bid) { 2385 resInfo = _BCM_BST_RESOURCE(unit, bid); 2386 if (resInfo->p_stat) { 2387 sal_free(resInfo->p_stat); 2388 resInfo->p_stat = NULL; 2389 } 2390 if (resInfo->p_threshold) { 2391 sal_free(resInfo->p_threshold); 2392 resInfo->p_threshold = NULL; 2393 } 2394 soc_profile_mem_destroy(unit, &resInfo->iprofile_m); 2395 for (i = 0; i < _BCM_MAX_PROFILES; i++) { 2396 soc_profile_reg_destroy(unit, &resInfo->iprofile_r[i]); 2397 resInfo->profile_r[i] = NULL; 2398 } 2399 resInfo->profile_m = NULL; 2400 } 2401 2402 sal_sem_destroy(bst_info->bst_trigger); 2403 sal_sem_destroy(bst_info->bst_thread); 2404 sal_mutex_destroy(bst_info->bst_reslock); 2405 bst_info->bst_trigger = NULL; 2406 bst_info->bst_thread = NULL; 2407 bst_info->bst_reslock = NULL; 2408 2409 sal_free(bst_info); 2410 2411 _BCM_UNIT_BST_INFO(unit) = NULL; 2412 2413 return BCM_E_NONE; 2414 } 2415 2416 int _bst_thd_reg_index_get(int unit, bcm_bst_stat_id_t bid, int pipe, 2417 int hw_index, int *inst, int *index) 2418 { 2419 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 2420 int phy_port, mmu_port, mmu_port_base; 2421 soc_info_t *si = &SOC_INFO(unit); 2422 2423 mmu_port_base = 64 * pipe; 2424 mmu_port = hw_index / 4; 2425 phy_port = si->port_m2p_mapping[mmu_port + mmu_port_base]; 2426 *inst = si->port_p2l_mapping[phy_port]; 2427 *index = hw_index % 4; 2428 } 2429 2430 return BCM_E_NONE; 2431 } 2432 2433 STATIC int 2434 _bcm_bst_cmn_io_op(int unit, int op, int pipe, int hw_index, 2435 bcm_bst_stat_id_t bid, soc_mem_t mem, soc_reg_t reg, 2436 soc_field_t field, uint32 *resval) 2437 { 2438 uint32 entry[SOC_MAX_MEM_WORDS], rval; 2439 int port = REG_PORT_ANY, reg_index = hw_index; 2440 _bcm_bst_resource_info_t *resInfo; 2441 #if defined(BCM_TOMAHAWK_SUPPORT) 2442 _bcm_bst_cmn_unit_info_t *bst_info = NULL; 2443 #endif 2444 2445 #if defined(BCM_TOMAHAWK_SUPPORT) 2446 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2447 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2448 return BCM_E_INIT; 2449 } 2450 2451 return bst_info->bst_cmn_io_op(unit, op, pipe, hw_index, bid, 2452 mem, reg, field, resval); 2453 } 2454 #endif 2455 resInfo = _BCM_BST_RESOURCE(unit, bid); 2456 if ((resInfo->flags & _BCM_BST_CMN_RES_F_PORTED) && 2457 (op & BST_OP_THD)) { 2458 BCM_IF_ERROR_RETURN( 2459 _bst_thd_reg_index_get(unit, bid, pipe, hw_index, 2460 &port, ®_index)); 2461 if ((bid == bcmBstStatIdEgrPortPoolSharedMcast) && (port == -1)) { 2462 port = REG_PORT_ANY; 2463 } 2464 } 2465 2466 if (mem != INVALIDm) { 2467 SOC_IF_ERROR_RETURN( 2468 soc_mem_read(unit, mem, MEM_BLOCK_ALL, reg_index, entry)); 2469 if (op & BST_OP_GET) { 2470 *resval = soc_mem_field32_get(unit, mem, entry, field); 2471 } else if (op & BST_OP_SET) { 2472 soc_mem_field32_set(unit, mem, entry, field, *resval); 2473 SOC_IF_ERROR_RETURN( 2474 soc_mem_write(unit, mem, MEM_BLOCK_ALL, reg_index, entry)); 2475 } 2476 } else if (reg != INVALIDr) { 2477 SOC_IF_ERROR_RETURN( 2478 soc_reg32_get(unit, reg, port, reg_index, &rval)); 2479 if (op & BST_OP_GET) { 2480 *resval = soc_reg_field_get(unit, reg, rval, field); 2481 } else if (op & BST_OP_SET) { 2482 if (*resval >= (1 << soc_reg_field_length(unit, reg, field))) { 2483 return BCM_E_PARAM; 2484 } 2485 soc_reg_field_set(unit, reg, &rval, field, *resval); 2486 SOC_IF_ERROR_RETURN( 2487 soc_reg32_set(unit, reg, port, reg_index, rval)); 2488 } 2489 } 2490 2491 return BCM_E_NONE; 2492 } 2493 2494 STATIC int 2495 _bcm_bst_cmn_profile_set_hw(int unit, int pipe, int xpe, int hw_index, 2496 bcm_bst_stat_id_t bid, 2497 bcm_cosq_bst_profile_t *profile, 2498 uint32 *p_profile) 2499 { 2500 uint32 cells; 2501 _bcm_bst_cmn_unit_info_t *bst_info; 2502 _bcm_bst_resource_info_t *resInfo; 2503 uint32 profile_index = 0xffffffff, old_profile_index = 0xffffffff; 2504 uint32 entry[SOC_MAX_MEM_WORDS]; 2505 uint64 rval, *rvals[1]; 2506 void *entries[1]; 2507 int pipe_factor = 1, pipe_offset = 0; 2508 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2509 _bcm_bst_resource_info_t *resInfo1 = NULL; 2510 int index = 0 , num_entries = 0; 2511 int start_idx = 0; 2512 #endif 2513 2514 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2515 return BCM_E_INIT; 2516 } 2517 2518 if ((bid >= bcmBstStatIdMaxCount) || (profile == NULL)) { 2519 return BCM_E_PARAM; 2520 } 2521 2522 if (p_profile) { 2523 *p_profile = -1; 2524 } 2525 2526 resInfo = _BCM_BST_RESOURCE(unit, bid); 2527 2528 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 2529 return BCM_E_UNAVAIL; 2530 } 2531 2532 if (bst_info->thd_set) { 2533 return bst_info->thd_set(unit, pipe, xpe, hw_index, bid, 2534 profile, p_profile); 2535 } 2536 2537 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 2538 pipe_factor = NUM_PIPE(unit); 2539 if (pipe) { 2540 if (resInfo->num_instance > 1) { 2541 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor / 2542 resInfo->num_instance); 2543 } else { 2544 pipe_offset = pipe * ((resInfo->index_max + 1) / pipe_factor); 2545 } 2546 } 2547 } else { 2548 pipe = 0; 2549 } 2550 2551 /* Taking granularity into count */ 2552 if (resInfo->threshold_gran != 0) { 2553 cells = (bst_info->to_cell(unit, profile->byte) + 2554 resInfo->threshold_adj + resInfo->threshold_gran - 1) / 2555 resInfo->threshold_gran; 2556 } else { 2557 cells = bst_info->to_cell(unit, profile->byte) + resInfo->threshold_adj; 2558 } 2559 2560 #if defined(BCM_APACHE_SUPPORT) 2561 if (SOC_IS_APACHE(unit)) { 2562 if ((bid == bcmBstStatIdDevice) && (cells < _BCM_AP_BST_MIN_THRESHOLD_CELLS)) { 2563 cells = _BCM_AP_BST_MIN_THRESHOLD_CELLS; 2564 } 2565 } 2566 #endif 2567 2568 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2569 if (SOC_IS_TD2_TT2(unit)) { 2570 if (hw_index >= 0) { 2571 if (BST_THRESHOLD_INVALID == profile->byte) { 2572 cells = BST_THRESHOLD_MAX_HIGH; 2573 } else { 2574 resInfo->p_threshold[hw_index + pipe_offset] = cells; 2575 } 2576 } 2577 } else 2578 #endif 2579 { 2580 if (hw_index >= 0) { 2581 resInfo->p_threshold[hw_index + pipe_offset] = cells; 2582 } 2583 } 2584 2585 if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) { 2586 if (hw_index >= 0) { 2587 SOC_IF_ERROR_RETURN( 2588 _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 2589 pipe, hw_index, bid, 2590 resInfo->threshold_mem[pipe], 2591 resInfo->threshold_reg[pipe], 2592 resInfo->threshold_field, 2593 &old_profile_index)); 2594 } 2595 2596 if (resInfo->profile_r[0]) { 2597 COMPILER_64_ZERO(rval); 2598 soc_reg64_field32_set(unit, resInfo->profile_reg[0], &rval, 2599 resInfo->profile_field, cells); 2600 rvals[0] = &rval; 2601 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2602 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) && 2603 !SOC_IS_TRIDENT3X(unit)) { 2604 if (((bid == bcmBstStatIdPriGroupHeadroom) && 2605 (bst_info->mode == 1) ) || 2606 ((bid == bcmBstStatIdPriGroupShared) && 2607 (bst_info->mode == 0))) { 2608 num_entries = SOC_REG_NUMELS(unit, 2609 resInfo->profile_reg[0]); 2610 /* 2611 * start_idx is 0 only in case hw_index = -1 2612 */ 2613 start_idx = hw_index < 0 ? 0: 1 ; 2614 for( index = start_idx; 2615 index < num_entries ; index++ ) { 2616 /* Insert the new entries into profile table */ 2617 SOC_IF_ERROR_RETURN(soc_reg_set(unit, 2618 resInfo->profile_reg[0], REG_PORT_ANY, 2619 index, 2620 rval)); 2621 } 2622 if ( hw_index >= 0) { 2623 old_profile_index = profile_index = 0xffffffff ; 2624 } else { 2625 profile_index = 0 ; 2626 } 2627 } else { 2628 SOC_IF_ERROR_RETURN(soc_profile_reg_add(unit, 2629 resInfo->profile_r[0], 2630 rvals, 1, 2631 &profile_index)); 2632 } 2633 } else 2634 #endif 2635 { 2636 SOC_IF_ERROR_RETURN(soc_profile_reg_add(unit, 2637 resInfo->profile_r[0], 2638 rvals, 1, 2639 &profile_index)); 2640 2641 } 2642 } else if (resInfo->profile_m) { 2643 sal_memset(entry, 0, sizeof(uint32)*SOC_MAX_MEM_WORDS); 2644 soc_mem_field32_set(unit, resInfo->profile_mem, &entry, 2645 resInfo->profile_field, cells); 2646 entries[0] = entry; 2647 SOC_IF_ERROR_RETURN(soc_profile_mem_add(unit, 2648 resInfo->profile_m, 2649 entries, 1, 2650 &profile_index)); 2651 } 2652 2653 /* attach the profile id for the resource */ 2654 if (profile_index != 0xffffffff) { 2655 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2656 if ((SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) 2657 || SOC_IS_APACHE(unit) || SOC_IS_TRIDENT3X(unit)) 2658 && (bid == bcmBstStatIdMcast)) { 2659 uint32 value = 0; 2660 soc_reg_field_set(unit, MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILEr, 2661 &value, THRESHOLDf, cells); 2662 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, 2663 MMU_THDM_DB_CPUQUEUE_BST_THRESHOLD_PROFILEr, 2664 REG_PORT_ANY, profile_index, value)); 2665 } 2666 #endif /* BCM_TRIDENT2_SUPPORT */ 2667 2668 if (hw_index >= 0) { 2669 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2670 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) && 2671 !SOC_IS_TRIDENT3X(unit)) { 2672 if (((bid == bcmBstStatIdPriGroupHeadroom) && 2673 (bst_info->mode == 0)) || 2674 ((bid == bcmBstStatIdPriGroupShared) && 2675 (bst_info->mode == 1))) { 2676 if ( bid == bcmBstStatIdPriGroupShared ) { 2677 resInfo1 = _BCM_BST_RESOURCE(unit, 2678 bcmBstStatIdPriGroupHeadroom); 2679 if (!_BCM_BST_RESOURCE_VALID(resInfo1)) { 2680 return BCM_E_UNAVAIL; 2681 } 2682 } else if ( bid == bcmBstStatIdPriGroupHeadroom) { 2683 resInfo1 = _BCM_BST_RESOURCE(unit, 2684 bcmBstStatIdPriGroupShared); 2685 if (!_BCM_BST_RESOURCE_VALID(resInfo1)) { 2686 return BCM_E_UNAVAIL; 2687 } 2688 } 2689 SOC_IF_ERROR_RETURN( 2690 _bcm_bst_cmn_io_op(unit, 2691 BST_OP_SET | BST_OP_THD, 2692 pipe, hw_index, bid, 2693 resInfo1->threshold_mem[pipe], 2694 resInfo1->threshold_reg[pipe], 2695 resInfo1->threshold_field, 2696 &profile_index)); 2697 2698 } 2699 } 2700 #endif 2701 SOC_IF_ERROR_RETURN( 2702 _bcm_bst_cmn_io_op(unit, BST_OP_SET | BST_OP_THD, 2703 pipe, hw_index, bid, 2704 resInfo->threshold_mem[pipe], 2705 resInfo->threshold_reg[pipe], 2706 resInfo->threshold_field, 2707 &profile_index)); 2708 } 2709 if (p_profile) { 2710 *p_profile = profile_index; 2711 } 2712 } 2713 2714 if (old_profile_index != 0xffffffff) { 2715 SOC_IF_ERROR_RETURN(_bcm_bst_cmn_profile_delete_hw(unit, bid, 2716 0, old_profile_index)); 2717 } 2718 } else { 2719 SOC_IF_ERROR_RETURN( 2720 _bcm_bst_cmn_io_op(unit, BST_OP_SET | BST_OP_THD, 2721 pipe, hw_index, bid, 2722 resInfo->threshold_mem[pipe], 2723 resInfo->threshold_reg[pipe], 2724 resInfo->threshold_field, 2725 &cells)); 2726 } 2727 2728 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 2729 if (SOC_IS_TD2_TT2(unit)) { 2730 if (bst_info->hw_trigger_set && cells && (BST_THRESHOLD_MAX_HIGH != cells)) { 2731 bst_info->hw_trigger_set(unit, bid); 2732 } 2733 } else 2734 #endif 2735 { 2736 if (bst_info->hw_trigger_set && cells) { 2737 bst_info->hw_trigger_set(unit, bid); 2738 } 2739 } 2740 return BCM_E_NONE; 2741 } 2742 2743 STATIC int 2744 _bcm_bst_cmn_profile_get_hw(int unit, int pipe, int xpe, int hw_index, 2745 bcm_bst_stat_id_t bid, 2746 bcm_cosq_bst_profile_t *profile) 2747 { 2748 _bcm_bst_cmn_unit_info_t *bst_info; 2749 _bcm_bst_resource_info_t *resInfo; 2750 uint32 profile_index; 2751 uint32 cells; 2752 2753 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2754 return BCM_E_INIT; 2755 } 2756 2757 if ((bid >= bcmBstStatIdMaxCount) || (profile == NULL)) { 2758 return BCM_E_PARAM; 2759 } 2760 2761 resInfo = _BCM_BST_RESOURCE(unit, bid); 2762 2763 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 2764 return BCM_E_UNAVAIL; 2765 } 2766 2767 if (bst_info->thd_get) { 2768 return bst_info->thd_get(unit, pipe, xpe, hw_index, bid, profile); 2769 } 2770 2771 if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) { 2772 /* Dont use Pipe info, if the resource is Not Pipe specific */ 2773 pipe = 0; 2774 } 2775 /* attach the profile id for the resource */ 2776 if (resInfo->flags & _BCM_BST_CMN_RES_F_PROFILEID) { 2777 SOC_IF_ERROR_RETURN( 2778 _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 2779 pipe, hw_index, bid, 2780 resInfo->threshold_mem[pipe], 2781 resInfo->threshold_reg[pipe], 2782 resInfo->threshold_field, 2783 &profile_index)); 2784 2785 SOC_IF_ERROR_RETURN( 2786 _bcm_bst_cmn_io_op(unit, BST_OP_GET, 2787 pipe, profile_index, bid, 2788 resInfo->profile_mem, 2789 resInfo->profile_reg[0], 2790 resInfo->profile_field, 2791 &cells)); 2792 } else { 2793 SOC_IF_ERROR_RETURN( 2794 _bcm_bst_cmn_io_op(unit, BST_OP_GET | BST_OP_THD, 2795 pipe, hw_index, bid, 2796 resInfo->threshold_mem[pipe], 2797 resInfo->threshold_reg[pipe], 2798 resInfo->threshold_field, 2799 &cells)); 2800 } 2801 2802 /* Taking granularity into count */ 2803 if (resInfo->threshold_gran != 0) { 2804 cells = cells * resInfo->threshold_gran - resInfo->threshold_adj; 2805 } else { 2806 cells -= resInfo->threshold_adj; 2807 } 2808 2809 profile->byte = bst_info->to_byte(unit, cells); 2810 2811 return BCM_E_NONE; 2812 } 2813 2814 typedef enum _bcm_bst_cmn_op_e { 2815 _BcmBstProfileGet = 0, 2816 _BcmBstProfileSet 2817 } _bcm_bst_cmn_op_t; 2818 2819 2820 STATIC int 2821 _bcm_bst_cmn_profile_op(int unit, _bcm_bst_cmn_op_t op, 2822 bcm_gport_t gport, bcm_cos_queue_t cosq, int xpe, 2823 bcm_bst_stat_id_t bid, bcm_cosq_bst_profile_t *profile) 2824 { 2825 _bcm_bst_cmn_unit_info_t *bst_info; 2826 _bcm_bst_cb_ret_t rv; 2827 void *cb_data = NULL; 2828 int bcm_rv, ii, rcb = 0, pipe; 2829 int start_hw_index = 0, end_hw_index = 0; 2830 _bcm_bst_resource_info_t *resInfo; 2831 2832 /* Parameter check */ 2833 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 2834 return BCM_E_PARAM; 2835 } 2836 2837 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2838 return BCM_E_INIT; 2839 } 2840 2841 resInfo = _BCM_BST_RESOURCE(unit, bid); 2842 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 2843 return BCM_E_PARAM; 2844 } 2845 2846 if (profile == NULL) { 2847 return BCM_E_PARAM; 2848 } 2849 2850 if (bst_info->handlers.resolve_index == NULL) { 2851 return BCM_E_UNAVAIL; 2852 } 2853 2854 do { 2855 rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 2856 &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv); 2857 if (bcm_rv) { 2858 return bcm_rv; 2859 } 2860 2861 if (op == _BcmBstProfileGet) { 2862 end_hw_index = start_hw_index; 2863 } 2864 2865 for (ii = start_hw_index; ii <= end_hw_index; ii++) { 2866 if (op == _BcmBstProfileGet) { 2867 SOC_IF_ERROR_RETURN( 2868 _bcm_bst_cmn_profile_get_hw(unit, pipe, xpe, ii, bid, profile)); 2869 } else { 2870 SOC_IF_ERROR_RETURN( 2871 _bcm_bst_cmn_profile_set_hw(unit, pipe, xpe, ii, bid, profile, NULL)); 2872 } 2873 } 2874 2875 if (op == _BcmBstProfileGet) { 2876 return BCM_E_NONE; 2877 } 2878 2879 } while (rv == _BCM_BST_RV_RETRY); 2880 2881 return BCM_E_NONE; 2882 } 2883 2884 int 2885 _bcm_bst_cmn_profile_set(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 2886 int xpe, bcm_bst_stat_id_t bid, 2887 bcm_cosq_bst_profile_t *profile) 2888 { 2889 BCM_IF_ERROR_RETURN( 2890 _bcm_bst_cmn_profile_op(unit, _BcmBstProfileSet, gport, cosq, xpe, 2891 bid, profile)); 2892 return BCM_E_NONE; 2893 } 2894 2895 int 2896 _bcm_bst_cmn_profile_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 2897 int xpe, bcm_bst_stat_id_t bid, 2898 bcm_cosq_bst_profile_t *profile) 2899 { 2900 BCM_IF_ERROR_RETURN( 2901 _bcm_bst_cmn_profile_op(unit, _BcmBstProfileGet, gport, cosq, xpe, 2902 bid, profile)); 2903 2904 return BCM_E_NONE; 2905 } 2906 2907 int 2908 _bcm_bst_cmn_stat_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 2909 bcm_cosq_buffer_id_t buffer_id, bcm_bst_stat_id_t bid, 2910 uint32 options, uint64 *pvalue) 2911 { 2912 _bcm_bst_cmn_unit_info_t *bst_info; 2913 _bcm_bst_resource_info_t *resInfo; 2914 _bcm_bst_cb_ret_t rv; 2915 void *cb_data = NULL; 2916 int bcm_rv, rcb = 0, ii, inst, entries_per_inst; 2917 int start_hw_index = 0, end_hw_index = 0, pipe_offset = 0, pipe; 2918 2919 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 2920 return BCM_E_PARAM; 2921 } 2922 2923 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 2924 return BCM_E_INIT; 2925 } 2926 2927 if (bst_info->handlers.resolve_index == NULL) { 2928 return BCM_E_UNAVAIL; 2929 } 2930 COMPILER_64_ZERO(*pvalue); 2931 2932 do { 2933 rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 2934 &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv); 2935 if (bcm_rv) { 2936 return bcm_rv; 2937 } 2938 2939 resInfo = _BCM_BST_RESOURCE(unit, bid); 2940 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 2941 return BCM_E_PARAM; 2942 } 2943 2944 if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) { 2945 pipe = 0; 2946 } 2947 2948 if (resInfo->num_instance > 1) { 2949 uint32 mmu_inst_map = 0; 2950 if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) { 2951 /* Dont use Pipe info, if the resource is Not Pipe specific */ 2952 pipe = 0; 2953 } 2954 pipe_offset = pipe * (((resInfo->index_max + 1) / NUM_PIPE(unit)) / 2955 resInfo->num_instance); 2956 entries_per_inst = (resInfo->index_max + 1) / resInfo->num_instance; 2957 if (bst_info->port_to_mmu_inst_map) { 2958 (void)bst_info->port_to_mmu_inst_map(unit, bid, gport, 2959 &mmu_inst_map); 2960 } 2961 /* When a resource has more than one instance, find the max value 2962 * of all applicable instances and return the Max value. 2963 */ 2964 for (ii = start_hw_index; ii <= end_hw_index; ii++) { 2965 int temp_stat = 0, max_stat = 0; 2966 if (buffer_id < 0 || buffer_id >= NUM_XPE(unit)) { 2967 for (inst = 0; inst < resInfo->num_instance; inst++) { 2968 if (mmu_inst_map & (1 << inst)) { 2969 temp_stat = resInfo->p_stat[pipe_offset + ii + 2970 (inst * entries_per_inst)]; 2971 if (temp_stat > max_stat) { 2972 max_stat = temp_stat; 2973 } 2974 } 2975 } 2976 } else { 2977 max_stat = resInfo->p_stat[pipe_offset + ii + 2978 (buffer_id * entries_per_inst)]; 2979 } 2980 COMPILER_64_ADD_32(*pvalue, max_stat); 2981 } 2982 } else { 2983 if ((resInfo->stat_mem[pipe] != INVALIDm) || 2984 (resInfo->stat_reg[pipe] != INVALIDr)) { 2985 pipe_offset = ((resInfo->index_max + 1) / NUM_PIPE(unit)) * pipe; 2986 } 2987 2988 for (ii = start_hw_index; ii <= end_hw_index; ii++) { 2989 COMPILER_64_ADD_32(*pvalue, resInfo->p_stat[ii + pipe_offset]); 2990 } 2991 } 2992 } while (rv == _BCM_BST_RV_RETRY); 2993 2994 bcm_rv = BCM_E_NONE; 2995 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 2996 defined(BCM_APACHE_SUPPORT) 2997 if (options & BCM_COSQ_STAT_CLEAR) { 2998 int need_hw_stat_clear = 1; 2999 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 3000 if ((bst_info->track_mode == 1) && 3001 (bst_info->hw_cor_in_max_use_count == 1)) { 3002 /* no need hw stat clear */ 3003 need_hw_stat_clear = 0; 3004 } 3005 if (bst_info->hw_stat_clear && (need_hw_stat_clear == 1)) { 3006 (void)bst_info->hw_stat_clear(unit, resInfo, bid, 3007 gport, start_hw_index); 3008 } 3009 bcm_rv = _bcm_bst_sw_stat_clear(unit, gport, cosq, bid); 3010 sal_mutex_give(bst_info->bst_reslock); 3011 } 3012 3013 if (_bcm_bst_check_intr_status(unit, bid)) { 3014 if (bst_info->intr_enable_set) { 3015 bst_info->intr_enable_set(unit, 1); 3016 } 3017 _bst_intr_status_reset(unit); 3018 } 3019 #endif 3020 3021 return bcm_rv; 3022 } 3023 3024 int _bcm_bst_cmn_stat_multi_get(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 3025 uint32 options, int max_values, bcm_bst_stat_id_t *id_list, uint64 *values) 3026 { 3027 int i; 3028 3029 for (i = 0; i < max_values; i++) { 3030 BCM_IF_ERROR_RETURN(_bcm_bst_cmn_stat_get(unit, gport, cosq, -1, id_list[i], 3031 options, &values[i])); 3032 } 3033 3034 return BCM_E_NONE; 3035 } 3036 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 3037 defined(BCM_APACHE_SUPPORT) 3038 int _bcm_bst_cmn_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 3039 bcm_bst_stat_id_t bid) 3040 { 3041 _bcm_bst_cmn_unit_info_t *bst_info; 3042 _bcm_bst_resource_info_t *resInfo; 3043 int bcm_rv = BCM_E_NONE; 3044 _bcm_bst_cb_ret_t rv; 3045 void *cb_data = NULL; 3046 int rcb = 0; 3047 int start_hw_index = 0, end_hw_index = 0, pipe; 3048 3049 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3050 return BCM_E_PARAM; 3051 } 3052 3053 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3054 return BCM_E_INIT; 3055 } 3056 3057 if (bst_info->handlers.resolve_index == NULL) { 3058 return BCM_E_UNAVAIL; 3059 } 3060 3061 /* sync all the stats */ 3062 resInfo = _BCM_BST_RESOURCE(unit, bid); 3063 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 3064 return BCM_E_PARAM; 3065 } 3066 3067 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 3068 if (bst_info->hw_stat_clear) { 3069 if (gport == -1) { 3070 /* Clear all stat counters */ 3071 (void)bst_info->hw_stat_clear(unit, resInfo, bid, -1, -1); 3072 } else { 3073 /* Clear stat counter for given port, cos */ 3074 rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 3075 &start_hw_index, &end_hw_index, &rcb, 3076 &cb_data, &bcm_rv); 3077 if (rv != _BCM_BST_RV_ERROR) { 3078 (void)bst_info->hw_stat_clear(unit, resInfo, bid, gport, 3079 start_hw_index); 3080 } 3081 } 3082 } 3083 3084 if (gport == -1) { 3085 bcm_port_t local_port; 3086 PBMP_PORT_ITER(unit, local_port) { 3087 bcm_rv = _bcm_bst_sw_stat_clear(unit, local_port, cosq, bid); 3088 if (BCM_FAILURE(bcm_rv)) { 3089 break; 3090 } 3091 } 3092 } else { 3093 bcm_rv = _bcm_bst_sw_stat_clear(unit, gport, cosq, bid); 3094 } 3095 sal_mutex_give(bst_info->bst_reslock); 3096 3097 return bcm_rv; 3098 3099 } 3100 #endif 3101 int 3102 _bcm_bst_cmn_stat_sync(int unit, bcm_bst_stat_id_t bid) 3103 { 3104 int rv = BCM_E_NONE; 3105 _bcm_bst_cmn_unit_info_t *bst_info; 3106 _bcm_bst_resource_info_t *resInfo; 3107 3108 if (((bid < 0) && (bid != bcmBstStatIdInvalid)) || 3109 (bid >= bcmBstStatIdMaxCount)) { 3110 return BCM_E_PARAM; 3111 } 3112 3113 bst_info = _BCM_UNIT_BST_INFO(unit); 3114 if (!bst_info) { 3115 return BCM_E_MEMORY; 3116 } 3117 if (bid == bcmBstStatIdInvalid) { 3118 if (bst_info->hw_sbusdma_desc_sync) { 3119 rv = bst_info->hw_sbusdma_desc_sync(unit); 3120 } else { 3121 return BCM_E_PARAM; 3122 } 3123 } else { 3124 #ifdef BCM_TOMAHAWK3_SUPPORT 3125 if (SOC_IS_TOMAHAWK3(unit)) { 3126 if (bid == bcmBstStatIdUcast || bid == bcmBstStatIdMcast) { 3127 bid = bcmBstStatIdQueueTotal; 3128 } 3129 } 3130 #endif 3131 resInfo = _BCM_BST_RESOURCE(unit, bid); 3132 if ((resInfo == NULL) || (!_BCM_BST_RESOURCE_VALID(resInfo))) { 3133 return BCM_E_PARAM; 3134 } 3135 3136 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 3137 if (bst_info->hw_stat_snapshot) { 3138 rv = bst_info->hw_stat_snapshot(unit, bid, -1, -1); 3139 } 3140 sal_mutex_give(bst_info->bst_reslock); 3141 } 3142 3143 return rv; 3144 } 3145 3146 int _bcm_bst_cmn_control_set(int unit, bcm_switch_control_t type, int arg) 3147 { 3148 _bcm_bst_cmn_unit_info_t *bst_info; 3149 3150 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3151 return BCM_E_INIT; 3152 } 3153 3154 if (bst_info->control_set == NULL) { 3155 return BCM_E_UNAVAIL; 3156 } 3157 3158 BCM_IF_ERROR_RETURN 3159 (bst_info->control_set(unit, type, arg, _bcmBstThreadOperExternal)); 3160 3161 return BCM_E_NONE; 3162 } 3163 3164 int _bcm_bst_cmn_control_get(int unit, bcm_switch_control_t type, int *arg) 3165 { 3166 _bcm_bst_cmn_unit_info_t *bst_info; 3167 3168 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3169 return BCM_E_INIT; 3170 } 3171 3172 if (bst_info->control_get == NULL) { 3173 return BCM_E_UNAVAIL; 3174 } 3175 3176 return bst_info->control_get(unit, type, arg); 3177 } 3178 3179 #if defined(BCM_TRIUMPH3_SUPPORT) 3180 3181 STATIC int 3182 _bcm_bst_hw_stat_sync(int unit, _bcm_bst_resource_info_t *resInfo, 3183 bcm_bst_stat_id_t bid, int port, int index) 3184 { 3185 _bcm_bst_cmn_unit_info_t *bst_info; 3186 int rv, pipe; 3187 uint32 rval; 3188 soc_mem_t mem; 3189 soc_reg_t reg; 3190 int min_hw_idx, max_hw_idx, idx; 3191 int pipe_factor = 1, pipe_offset = 0; 3192 int num_entries, mem_wsz; 3193 void *pentry; 3194 char *dmabuf; 3195 int sync_val = 0; 3196 3197 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3198 return BCM_E_PARAM; 3199 } 3200 3201 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3202 return BCM_E_INIT; 3203 } 3204 3205 if (bst_info->pre_sync) { 3206 bst_info->pre_sync(unit, bid, &sync_val); 3207 } 3208 3209 /* sync all the stats */ 3210 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 3211 pipe_factor = NUM_PIPE(unit); 3212 } 3213 if (index == -1) { 3214 min_hw_idx = resInfo->index_min; 3215 max_hw_idx = resInfo->index_max / pipe_factor; 3216 } else { 3217 min_hw_idx = max_hw_idx = index; 3218 } 3219 3220 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3221 if ((mem = resInfo->stat_mem[pipe]) != INVALIDm) { 3222 num_entries = soc_mem_index_count(unit, mem); 3223 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 3224 3225 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 3226 if (dmabuf == NULL) { 3227 return BCM_E_MEMORY; 3228 } 3229 3230 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 3231 soc_mem_index_min(unit, mem), 3232 soc_mem_index_max(unit, mem), 3233 dmabuf)) { 3234 soc_cm_sfree(unit, dmabuf); 3235 return BCM_E_INTERNAL; 3236 } 3237 3238 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 3239 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 3240 dmabuf, idx); 3241 resInfo->p_stat[idx + pipe_offset] = 3242 soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field); 3243 } 3244 3245 soc_cm_sfree(unit, dmabuf); 3246 } else if (resInfo->profile_r[0]) { 3247 pipe_offset += max_hw_idx; 3248 } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) { 3249 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 3250 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval); 3251 if (rv) { 3252 return BCM_E_INTERNAL; 3253 } 3254 resInfo->p_stat[idx] = soc_reg_field_get(unit, reg, 3255 rval, resInfo->stat_field); 3256 } 3257 } /* if valid reg */ 3258 } /* for each pipe */ 3259 3260 if (bst_info->post_sync) { 3261 bst_info->post_sync(unit, bid, sync_val); 3262 } 3263 3264 return BCM_E_NONE; 3265 } 3266 3267 STATIC int 3268 _bcm_bst_sw_stat_clear(int unit, bcm_gport_t gport, bcm_cos_queue_t cosq, 3269 bcm_bst_stat_id_t bid) 3270 { 3271 _bcm_bst_cmn_unit_info_t *bst_info; 3272 _bcm_bst_resource_info_t *resInfo; 3273 _bcm_bst_cb_ret_t rv; 3274 void *cb_data = NULL; 3275 int bcm_rv, rcb = 0, index; 3276 int start_hw_index = 0, end_hw_index = 0, pipe_offset = 0, pipe; 3277 3278 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3279 return BCM_E_PARAM; 3280 } 3281 3282 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3283 return BCM_E_INIT; 3284 } 3285 3286 if (bst_info->handlers.resolve_index == NULL) { 3287 return BCM_E_UNAVAIL; 3288 } 3289 3290 do { 3291 rv = bst_info->handlers.resolve_index(unit, gport, cosq, bid, &pipe, 3292 &start_hw_index, &end_hw_index, &rcb, &cb_data, &bcm_rv); 3293 if (bcm_rv) { 3294 return bcm_rv; 3295 } 3296 3297 resInfo = _BCM_BST_RESOURCE(unit, bid); 3298 if (resInfo == NULL) { 3299 return BCM_E_PARAM; 3300 } 3301 3302 if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) { 3303 pipe = 0; 3304 } 3305 3306 if (resInfo->num_instance > 1) { 3307 uint32 mmu_inst_map = 0; 3308 int entries_per_inst, inst_offset, inst; 3309 if (!(resInfo->flags & _BCM_BST_CMN_RES_F_PIPED)) { 3310 /* Dont use Pipe info, if the resource is Not Pipe specific */ 3311 pipe = 0; 3312 } 3313 pipe_offset = pipe * (((resInfo->index_max + 1) / NUM_PIPE(unit)) / 3314 resInfo->num_instance); 3315 entries_per_inst = (resInfo->index_max + 1) / resInfo->num_instance; 3316 if (bst_info->port_to_mmu_inst_map) { 3317 (void)bst_info->port_to_mmu_inst_map(unit, bid, gport, 3318 &mmu_inst_map); 3319 } 3320 /* When a resource has more than one instance, clear all 3321 * applicable instances. 3322 */ 3323 for (index = start_hw_index; index <= end_hw_index; index++) { 3324 for (inst = 0; inst < resInfo->num_instance; inst++) { 3325 if (mmu_inst_map & (1 << inst)) { 3326 inst_offset = inst * entries_per_inst; 3327 resInfo->p_stat[pipe_offset + index + inst_offset] = 0; 3328 } 3329 } 3330 } 3331 } else { 3332 if ((resInfo->stat_mem[pipe] != INVALIDm) || 3333 (resInfo->stat_reg[pipe] != INVALIDr)) { 3334 pipe_offset = ((resInfo->index_max + 1) / NUM_PIPE(unit)) * pipe; 3335 } 3336 3337 for (index = start_hw_index; index <= end_hw_index; index++) { 3338 resInfo->p_stat[index + pipe_offset] = 0; 3339 } 3340 } 3341 } while (rv == _BCM_BST_RV_RETRY); 3342 3343 return BCM_E_NONE; 3344 } 3345 3346 int 3347 _bcm_bst_hw_stat_clear(int unit, _bcm_bst_resource_info_t *resInfo, 3348 bcm_bst_stat_id_t bid, int port, int index) 3349 { 3350 _bcm_bst_cmn_unit_info_t *bst_info; 3351 int rv, pipe; 3352 uint32 rval; 3353 soc_mem_t mem; 3354 soc_reg_t reg; 3355 int min_hw_idx, max_hw_idx, idx; 3356 int pipe_factor = 1, pipe_offset = 0; 3357 int num_entries, mem_wsz; 3358 void *pentry; 3359 char *dmabuf; 3360 int enable = 0; 3361 int sync_val = 0; 3362 3363 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3364 return BCM_E_PARAM; 3365 } 3366 3367 /* The bcmBstStatIdIngPool stat register THDI_BST_SP_GLOBAL_SHARED_CNT 3368 is a readonly register */ 3369 if (SOC_IS_TRIDENT2(unit)) { 3370 if (bid == bcmBstStatIdIngPool && 3371 resInfo->stat_reg[0] == THDI_BST_SP_GLOBAL_SHARED_CNTr) { 3372 return BCM_E_PARAM; 3373 } 3374 } 3375 3376 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3377 return BCM_E_INIT; 3378 } 3379 3380 if (bst_info->pre_sync) { 3381 bst_info->pre_sync(unit, bid, &sync_val); 3382 } 3383 3384 /* sync all the stats */ 3385 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 3386 pipe_factor = NUM_PIPE(unit); 3387 } 3388 if (index == -1) { 3389 min_hw_idx = resInfo->index_min; 3390 max_hw_idx = resInfo->index_max / pipe_factor; 3391 } else { 3392 min_hw_idx = max_hw_idx = index; 3393 } 3394 3395 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3396 if ((mem = resInfo->stat_mem[pipe]) != INVALIDm) { 3397 if (index == -1) { 3398 BCM_IF_ERROR_RETURN(soc_mem_clear(unit, mem, COPYNO_ALL, TRUE)); 3399 continue; 3400 } 3401 3402 num_entries = soc_mem_index_count(unit, mem); 3403 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 3404 3405 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 3406 if (dmabuf == NULL) { 3407 return BCM_E_MEMORY; 3408 } 3409 3410 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 3411 soc_mem_index_min(unit, mem), 3412 soc_mem_index_max(unit, mem), 3413 dmabuf)) { 3414 soc_cm_sfree(unit, dmabuf); 3415 return BCM_E_INTERNAL; 3416 } 3417 3418 /* Clear stat counter if requested */ 3419 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 3420 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 3421 dmabuf, idx); 3422 soc_mem_field32_set(unit, mem, pentry, resInfo->stat_field, 0); 3423 } 3424 3425 if (soc_mem_write_range(unit, mem, MEM_BLOCK_ALL, 3426 soc_mem_index_min(unit, mem), 3427 soc_mem_index_max(unit, mem), 3428 dmabuf)) { 3429 soc_cm_sfree(unit, dmabuf); 3430 return BCM_E_INTERNAL; 3431 } 3432 3433 soc_cm_sfree(unit, dmabuf); 3434 } else if (resInfo->profile_r[0]) { 3435 pipe_offset += max_hw_idx; 3436 } else if ((reg = resInfo->stat_reg[pipe]) != INVALIDr) { 3437 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 3438 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval); 3439 if (rv) { 3440 return BCM_E_INTERNAL; 3441 } 3442 } 3443 3444 /* Clear stat counters */ 3445 if (bst_info->control_get) { 3446 bst_info->control_get(unit, bcmSwitchBstEnable, &enable); 3447 } 3448 if (enable && bst_info->control_set) { 3449 bst_info->control_set(unit, bcmSwitchBstEnable, 0, 3450 _bcmBstThreadOperInternal); 3451 } 3452 3453 for (idx = min_hw_idx; idx <= max_hw_idx; idx++) { 3454 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval); 3455 if (rv) { 3456 return BCM_E_INTERNAL; 3457 } 3458 soc_reg_field_set(unit, reg, &rval, resInfo->stat_field, 0); 3459 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, idx, rval)); 3460 } 3461 3462 if (enable && bst_info->control_set) { 3463 bst_info->control_set(unit, bcmSwitchBstEnable, enable, 3464 _bcmBstThreadOperInternal); 3465 } 3466 3467 } /* if valid reg */ 3468 } /* for each pipe */ 3469 3470 if (bst_info->post_sync) { 3471 bst_info->post_sync(unit, bid, sync_val); 3472 } 3473 3474 return BCM_E_NONE; 3475 } 3476 3477 int 3478 _bcm_bst_sync_hw_trigger(int unit, bcm_bst_stat_id_t bid, int port, int index) 3479 { 3480 _bcm_bst_cmn_unit_info_t *bst_info; 3481 _bcm_bst_resource_info_t *resInfo; 3482 bcm_gport_t gport; 3483 bcm_cos_t cosq; 3484 3485 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3486 return BCM_E_PARAM; 3487 } 3488 3489 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3490 return BCM_E_INIT; 3491 } 3492 3493 /* sync all the stats */ 3494 resInfo = _BCM_BST_RESOURCE(unit, bid); 3495 if (resInfo == NULL) { 3496 return BCM_E_PARAM; 3497 } 3498 3499 BCM_IF_ERROR_RETURN(_bcm_bst_hw_stat_sync(unit, resInfo, bid, port, index)); 3500 3501 if (bst_info->handlers.reverse_resolve_index) { 3502 /* reverse map the inedx to port/cos pair */ 3503 bst_info->handlers.reverse_resolve_index(unit, bid, port, index, &gport, &cosq); 3504 3505 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 3506 bid, gport, cosq); 3507 } 3508 3509 return BCM_E_NONE; 3510 } 3511 3512 int 3513 _bcm_bst_sync_hw_snapshot(int unit, bcm_bst_stat_id_t bid, int port, int index) 3514 { 3515 _bcm_bst_cmn_unit_info_t *bst_info; 3516 _bcm_bst_resource_info_t *resInfo; 3517 int num_entries, mem_wsz; 3518 int idx, idx_offset = 0, rv, pipe, pipe_offset = 0; 3519 void *pentry; 3520 char *dmabuf; 3521 uint32 rval, temp_val; 3522 soc_mem_t mem; 3523 soc_reg_t reg; 3524 int sync_val = 0; 3525 3526 if (bid < _BCM_BST_RESOURCE_MIN || bid >= _BCM_BST_RESOURCE_MAX) { 3527 return BCM_E_PARAM; 3528 } 3529 3530 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3531 return BCM_E_INIT; 3532 } 3533 3534 if (bst_info->pre_sync) { 3535 bst_info->pre_sync(unit, bid, &sync_val); 3536 } 3537 3538 /* sync all the stats */ 3539 resInfo = _BCM_BST_RESOURCE(unit, bid); 3540 if (resInfo == NULL) { 3541 return BCM_E_PARAM; 3542 } 3543 3544 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3545 bcm_gport_t gport = -1; 3546 bcm_cos_t cosq = -1; 3547 mem = resInfo->stat_mem[pipe]; 3548 reg = resInfo->stat_reg[pipe]; 3549 pipe_offset = 0; 3550 3551 if (pipe) { 3552 pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe; 3553 } 3554 if (mem != INVALIDm) { 3555 num_entries = soc_mem_index_count(unit, mem); 3556 mem_wsz = sizeof(uint32) * soc_mem_entry_words(unit, mem); 3557 3558 dmabuf = soc_cm_salloc(unit, num_entries * mem_wsz, "bst dmabuf"); 3559 if (dmabuf == NULL) { 3560 return BCM_E_MEMORY; 3561 } 3562 3563 if (soc_mem_read_range(unit, mem, MEM_BLOCK_ALL, 3564 soc_mem_index_min(unit, mem), 3565 soc_mem_index_max(unit, mem), 3566 dmabuf)) { 3567 soc_cm_sfree(unit, dmabuf); 3568 return BCM_E_INTERNAL; 3569 } 3570 3571 for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) { 3572 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 3573 if (bid == bcmBstStatIdEgrPortPoolSharedMcast) { 3574 /* 3575 * Reorder sw stat index 3576 * HW stat: index 0 - port 0 pool 0 3577 * index 1 - port 1 pool 0 3578 * index 2 - port 2 pool 0 3579 * ... 3580 * index n - port n%34 pool n/34 3581 * SW stat: index 0 - port 0 pool 0 3582 * index 1 - port 0 pool 1 3583 * index 2 - port 0 pool 2 3584 * ... 3585 * index n - port n/4 pool n%4 3586 */ 3587 int port_tmp = 0, pool = 0; 3588 #if defined(BCM_MONTEREY_SUPPORT) 3589 if (SOC_IS_MONTEREY(unit)) { 3590 port_tmp = idx % SOC_MONTEREY_NUM_MMU_PORTS_PER_PIPE; 3591 pool = idx / SOC_MONTEREY_NUM_MMU_PORTS_PER_PIPE; 3592 } else 3593 #endif 3594 #if defined(BCM_APACHE_SUPPORT) 3595 if (SOC_IS_APACHE(unit)) { 3596 port_tmp = idx % (SOC_APACHE_NUM_MMU_PORTS_PER_PIPE - 1); 3597 pool = idx / (SOC_APACHE_NUM_MMU_PORTS_PER_PIPE - 1); 3598 } else 3599 #endif 3600 #if defined(BCM_TRIDENT2_SUPPORT) 3601 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit) || 3602 SOC_IS_TD2P_TT2P(unit)) { 3603 port_tmp = idx % _TD2_MMU_PORTS_PER_PIPE; 3604 pool = idx / _TD2_MMU_PORTS_PER_PIPE; 3605 if (pipe) { 3606 /* TD2 uses specific port value to pass pipe info */ 3607 port = -2; 3608 } 3609 } else 3610 #endif 3611 { 3612 soc_cm_sfree(unit, dmabuf); 3613 return BCM_E_UNAVAIL; 3614 } 3615 idx_offset = port_tmp * 4 + pool + pipe_offset; 3616 } else 3617 #endif /* BCM_TRIDENT2_SUPPORT || BCM_APACHE_SUPPORT */ 3618 { 3619 idx_offset = idx + pipe_offset; 3620 } 3621 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 3622 dmabuf, idx); 3623 temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field); 3624 if (bst_info->track_mode) { 3625 if (resInfo->p_stat[idx_offset] < temp_val) { 3626 resInfo->p_stat[idx_offset] = temp_val; 3627 } 3628 } else { 3629 resInfo->p_stat[idx_offset] = temp_val; 3630 } 3631 3632 if (resInfo->p_threshold[idx_offset] && 3633 (resInfo->p_stat[idx_offset] >= 3634 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 3635 /* Generate SOC EVENT */ 3636 if (bst_info->handlers.reverse_resolve_index) { 3637 /* reverse map the inedx to port/cos pair */ 3638 bst_info->handlers.reverse_resolve_index(unit, bid, 3639 port, idx_offset, 3640 &gport, &cosq); 3641 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 3642 bid, gport, cosq); 3643 3644 } 3645 } 3646 } 3647 soc_cm_sfree(unit, dmabuf); 3648 } else if (reg != INVALIDr) { 3649 for (idx = 0; idx < resInfo->num_stat_pp; idx++) { 3650 idx_offset = idx + pipe_offset; 3651 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, idx, &rval); 3652 if (rv) { 3653 return BCM_E_INTERNAL; 3654 } 3655 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field); 3656 if (bst_info->track_mode) { 3657 if (resInfo->p_stat[idx_offset] < temp_val) { 3658 resInfo->p_stat[idx_offset] = temp_val; 3659 } 3660 } else { 3661 resInfo->p_stat[idx_offset] = temp_val; 3662 } 3663 3664 if (resInfo->p_threshold[idx_offset] && 3665 (resInfo->p_stat[idx_offset] >= 3666 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 3667 /* Generate SOC EVENT */ 3668 if (bst_info->handlers.reverse_resolve_index) { 3669 /* reverse map the inedx to port/cos pair */ 3670 bst_info->handlers.reverse_resolve_index(unit, bid, 3671 port, idx_offset, 3672 &gport, &cosq); 3673 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 3674 bid, gport, cosq); 3675 3676 } 3677 3678 } 3679 } 3680 } 3681 } 3682 3683 if (bst_info->post_sync) { 3684 bst_info->post_sync(unit, bid, sync_val); 3685 } 3686 3687 return BCM_E_NONE; 3688 } 3689 #endif 3690 3691 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 3692 STATIC int 3693 _bst_td2_sbusdma_desc_setup(int unit) 3694 { 3695 _bcm_bst_cmn_unit_info_t *bst_info; 3696 _bcm_bst_resource_info_t *resInfo; 3697 _bcm_bst_tbl_ctrl_t *tbl_ctrl; 3698 int blk, bid, pipe, mi, pipe_factor; 3699 uint8 acc_type; 3700 soc_mem_t mem; 3701 soc_reg_t reg; 3702 soc_reg_info_t *regp; 3703 uint32 size; 3704 uint8 *buff = NULL; 3705 _bcm_bst_tbl_desc_t *desc = NULL; 3706 3707 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3708 return BCM_E_INIT; 3709 } 3710 buff = bst_info->bst_tbl_buf; 3711 bst_tbl_ctrl[unit] = sal_alloc(bcmBstStatIdMaxCount * 3712 sizeof(_bcm_bst_tbl_ctrl_t *), 3713 "bst_tbl_ctrl_p"); 3714 if (bst_tbl_ctrl[unit] == NULL) { 3715 return BCM_E_MEMORY; 3716 } 3717 3718 bst_info->bst_tbl_desc = sal_alloc(bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t), 3719 "bst_tbl_desc_p"); 3720 if (bst_info->bst_tbl_desc == NULL) { 3721 return BCM_E_MEMORY; 3722 } 3723 sal_memset(bst_info->bst_tbl_desc, 0, bst_info->bst_tbl_num * sizeof(_bcm_bst_tbl_desc_t)); 3724 desc = bst_info->bst_tbl_desc; 3725 3726 mi = 0; 3727 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 3728 resInfo = _BCM_BST_RESOURCE(unit, bid); 3729 if (resInfo == NULL) { 3730 return BCM_E_PARAM; 3731 } 3732 3733 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 3734 continue; 3735 } 3736 3737 tbl_ctrl = sal_alloc(sizeof(_bcm_bst_tbl_ctrl_t), "bst_tbl_ctrl"); 3738 if (tbl_ctrl == NULL) { 3739 return BCM_E_MEMORY; 3740 } 3741 pipe_factor = 1; 3742 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 3743 pipe_factor = NUM_PIPE(unit); 3744 } 3745 size = 0; 3746 tbl_ctrl->tindex = bid; 3747 tbl_ctrl->entries = pipe_factor; 3748 tbl_ctrl->buff = buff; 3749 tbl_ctrl->size = 0; 3750 bst_tbl_ctrl[unit][bid] = tbl_ctrl; 3751 for (pipe = 0; pipe < pipe_factor; pipe++) { 3752 mem = resInfo->stat_mem[pipe]; 3753 reg = resInfo->stat_reg[pipe]; 3754 if (mem != INVALIDm) { 3755 desc[mi].mem = mem; 3756 desc[mi].flags = SOC_SBUSDMA_CFG_COUNTER_IS_MEM | SOC_SBUSDMA_CFG_USE_FLAGS; 3757 desc[mi].blk = SOC_MEM_BLOCK_ANY(unit, mem); 3758 desc[mi].addr = soc_mem_addr_get(unit, mem, 3759 0, desc[mi].blk, 0, &acc_type); 3760 desc[mi].acc_type = acc_type; 3761 desc[mi].blk = SOC_BLOCK2SCH(unit, desc[mi].blk); 3762 desc[mi].width = soc_mem_entry_words(unit, mem); 3763 desc[mi].entries = resInfo->num_stat_pp / pipe_factor; 3764 desc[mi].shift = 0; 3765 size += desc[mi].entries * desc[mi].width * 4; 3766 tbl_ctrl->blk = desc[mi].blk; 3767 mi++; 3768 }else if (reg != INVALIDr) { 3769 regp = SOC_REG_PTR(unit, reg); 3770 desc[mi].reg= reg; 3771 desc[mi].addr = soc_reg_addr_get(unit, reg, REG_PORT_ANY, 0, 3772 SOC_REG_ADDR_OPTION_NONE, &blk, 3773 &acc_type); 3774 desc[mi].flags = 0; 3775 desc[mi].acc_type = acc_type; 3776 desc[mi].blk = blk; 3777 desc[mi].width = BYTES2WORDS(soc_reg_bytes(unit, reg)) * regp->nFields; 3778 desc[mi].entries = resInfo->num_stat_pp / pipe_factor; 3779 desc[mi].shift = 8; 3780 size += desc[mi].entries * desc[mi].width * 4; 3781 tbl_ctrl->blk = desc[mi].blk; 3782 mi++; 3783 } 3784 } 3785 buff += size; 3786 tbl_ctrl->size += size; 3787 } 3788 3789 return BCM_E_NONE; 3790 } 3791 3792 STATIC int 3793 _bcm_bst_td2_sbusdma_desc_init(int unit) 3794 { 3795 _bcm_bst_cmn_unit_info_t *bst_info; 3796 _bcm_bst_resource_info_t *resInfo; 3797 int pipe, bid, mi, pipe_factor; 3798 soc_mem_t mem; 3799 soc_reg_t reg; 3800 soc_reg_info_t *regp; 3801 uint32 entries, width, size = 0; 3802 int rv = BCM_E_INIT; 3803 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3804 return BCM_E_INIT; 3805 } 3806 mi = 0; 3807 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 3808 resInfo = _BCM_BST_RESOURCE(unit, bid); 3809 if (resInfo == NULL) { 3810 return BCM_E_PARAM; 3811 } 3812 3813 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 3814 continue; 3815 } 3816 3817 pipe_factor = 1; 3818 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 3819 pipe_factor = NUM_PIPE(unit); 3820 } 3821 for (pipe = 0; pipe < pipe_factor; pipe++) { 3822 mem = resInfo->stat_mem[pipe]; 3823 reg = resInfo->stat_reg[pipe]; 3824 if (mem != INVALIDm) { 3825 entries = resInfo->num_stat_pp / pipe_factor; 3826 width = soc_mem_entry_words(unit, mem); 3827 size += entries * width * 4; 3828 mi++; 3829 } else if (reg != INVALIDr) { 3830 regp = SOC_REG_PTR(unit, reg); 3831 entries = resInfo->num_stat_pp; 3832 width = BYTES2WORDS(soc_reg_bytes(unit, reg)) * regp->nFields; 3833 size += entries * width * 4; 3834 mi++; 3835 } 3836 } 3837 } 3838 bst_info->bst_tbl_size = size; 3839 bst_info->bst_tbl_num = mi; 3840 LOG_VERBOSE(BSL_LS_SOC_COMMON, 3841 (BSL_META_U(unit, 3842 "Total bst tbls: %d, Total size: %d\n"), 3843 bcmBstStatIdMaxCount, size)); 3844 bst_tbl_handles[unit] = 0; 3845 if (bst_info->bst_tbl_buf == NULL) { 3846 bst_info->bst_tbl_buf = soc_cm_salloc(unit, size, "bst_tbl_buf"); 3847 if (bst_info->bst_tbl_buf == NULL) { 3848 goto error; 3849 } 3850 } 3851 sal_memset(bst_info->bst_tbl_buf, 0, size); 3852 rv =_bst_td2_sbusdma_desc_setup(unit); 3853 if (rv != SOC_E_NONE) { 3854 goto error; 3855 } 3856 3857 rv = soc_bst_sbusdma_desc_setup(unit); 3858 if (rv != SOC_E_NONE) { 3859 goto error; 3860 } 3861 return BCM_E_NONE; 3862 error: 3863 if (bst_info->bst_tbl_buf) { 3864 soc_cm_sfree(unit, bst_info->bst_tbl_buf); 3865 bst_info->bst_tbl_buf = NULL; 3866 } 3867 if (bst_info->bst_tbl_desc) { 3868 sal_free(bst_info->bst_tbl_desc); 3869 bst_info->bst_tbl_desc = NULL; 3870 } 3871 rv = soc_bst_sbusdma_desc_free(unit); 3872 return rv; 3873 } 3874 3875 STATIC int 3876 _bst_td2_sw_sbusdma_desc_sync(int unit, int bid) 3877 { 3878 _bcm_bst_cmn_unit_info_t *bst_info; 3879 _bcm_bst_resource_info_t *resInfo; 3880 _bcm_bst_tbl_ctrl_t *tbl_ctrl; 3881 int idx, idx_offset, pipe, pipe_offset = 0; 3882 void *pentry; 3883 uint32 rval, temp_val; 3884 uint8 *buff = NULL; 3885 soc_mem_t mem; 3886 soc_reg_t reg; 3887 uint32 width = 0; 3888 int pipe_factor; 3889 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3890 sal_mutex_give(bst_info->bst_reslock); 3891 return BCM_E_INIT; 3892 } 3893 if (!bst_tbl_ctrl[unit][bid]) { 3894 sal_mutex_give(bst_info->bst_reslock); 3895 return BCM_E_INIT; 3896 } 3897 tbl_ctrl = bst_tbl_ctrl[unit][bid]; 3898 buff = tbl_ctrl->buff; 3899 resInfo = _BCM_BST_RESOURCE(unit, bid); 3900 if (resInfo == NULL) { 3901 sal_mutex_give(bst_info->bst_reslock); 3902 return BCM_E_PARAM; 3903 } 3904 pipe_factor = 1; 3905 if (resInfo->flags & _BCM_BST_CMN_RES_F_PIPED) { 3906 pipe_factor = NUM_PIPE(unit); 3907 } 3908 for (pipe = 0; pipe < pipe_factor; pipe++) { 3909 bcm_gport_t gport = -1; 3910 bcm_cos_t cosq = -1; 3911 mem = resInfo->stat_mem[pipe]; 3912 reg = resInfo->stat_reg[pipe]; 3913 pipe_offset = 0; 3914 if (pipe) { 3915 pipe_offset = (resInfo->index_max / NUM_PIPE(unit)) * pipe; 3916 } 3917 if (mem != INVALIDm) { 3918 for (idx = 0; idx < (resInfo->num_stat_pp / NUM_PIPE(unit)); idx++) { 3919 idx_offset = idx + pipe_offset; 3920 pentry = soc_mem_table_idx_to_pointer(unit, mem, void*, 3921 buff, idx); 3922 temp_val = soc_mem_field32_get(unit, mem, pentry, resInfo->stat_field); 3923 if (bst_info->track_mode) { 3924 if (resInfo->p_stat[idx_offset] < temp_val) { 3925 resInfo->p_stat[idx_offset] = temp_val; 3926 } 3927 } else { 3928 resInfo->p_stat[idx_offset] = temp_val; 3929 } 3930 if (resInfo->p_threshold[idx_offset] && 3931 (resInfo->p_stat[idx_offset] >= 3932 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 3933 /* Generate SOC EVENT */ 3934 if (bst_info->handlers.reverse_resolve_index) { 3935 /* reverse map the inedx to port/cos pair */ 3936 bst_info->handlers.reverse_resolve_index(unit, bid, 3937 -1, idx_offset, 3938 &gport, &cosq); 3939 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 3940 bid, gport, cosq); 3941 } 3942 } 3943 } 3944 buff += tbl_ctrl->size / pipe_factor; 3945 } else if (reg != INVALIDr) { 3946 for (idx = 0; idx < resInfo->num_stat_pp; idx++) { 3947 width = BYTES2WORDS(soc_reg_bytes(unit, reg)); 3948 idx_offset = idx + pipe_offset; 3949 3950 sal_memcpy(&rval, buff, width * 4); 3951 temp_val = soc_reg_field_get(unit, reg, rval, resInfo->stat_field); 3952 if (bst_info->track_mode) { 3953 if (resInfo->p_stat[idx_offset] < temp_val) { 3954 resInfo->p_stat[idx_offset] = temp_val; 3955 } 3956 } else { 3957 resInfo->p_stat[idx_offset] = temp_val; 3958 } 3959 buff = buff + width * 4; 3960 3961 if (resInfo->p_threshold[idx_offset] && 3962 (resInfo->p_stat[idx_offset] >= 3963 (resInfo->p_threshold[idx_offset]) * resInfo->threshold_gran)) { 3964 /* Generate SOC EVENT */ 3965 if (bst_info->handlers.reverse_resolve_index) { 3966 /* reverse map the inedx to port/cos pair */ 3967 bst_info->handlers.reverse_resolve_index(unit, bid, 3968 -1, idx_offset, 3969 &gport, &cosq); 3970 soc_event_generate(unit, SOC_SWITCH_EVENT_MMU_BST_TRIGGER, 3971 bid, gport, cosq); 3972 } 3973 } 3974 } 3975 } 3976 } 3977 3978 return BCM_E_NONE; 3979 } 3980 3981 STATIC int 3982 _bcm_bst_td2_sbusdma_desc_sync(int unit) 3983 { 3984 _bcm_bst_cmn_unit_info_t *bst_info; 3985 _bcm_bst_resource_info_t *resInfo; 3986 bcm_bst_stat_id_t bid; 3987 int enable = 0; 3988 3989 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 3990 return BCM_E_INIT; 3991 } 3992 3993 if (!_BCM_BST_SYNC_THREAD_VALID(bst_info)) { 3994 return BCM_E_NONE; 3995 } 3996 3997 sal_mutex_take(bst_info->bst_reslock, sal_mutex_FOREVER); 3998 3999 if (bst_info->control_get) { 4000 bst_info->control_get(unit, bcmSwitchBstEnable, &enable); 4001 } 4002 4003 if (enable && bst_info->control_set) { 4004 bst_info->control_set(unit, bcmSwitchBstEnable, 0, 4005 _bcmBstThreadOperInternal); 4006 } 4007 4008 BCM_IF_ERROR_RETURN(soc_bst_hw_sbusdma_desc_sync(unit)); 4009 4010 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 4011 resInfo = _BCM_BST_RESOURCE(unit, bid); 4012 if (resInfo == NULL) { 4013 return BCM_E_PARAM; 4014 } 4015 4016 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 4017 continue; 4018 } 4019 4020 BCM_IF_ERROR_RETURN(_bst_td2_sw_sbusdma_desc_sync(unit, bid)); 4021 } 4022 4023 if (enable && bst_info->control_set) { 4024 bst_info->control_set(unit, bcmSwitchBstEnable, enable, 4025 _bcmBstThreadOperInternal); 4026 } 4027 4028 sal_mutex_give(bst_info->bst_reslock); 4029 return BCM_E_NONE; 4030 } 4031 4032 STATIC int 4033 _bcm_bst_td2_sbusdma_desc_deinit(int unit) 4034 { 4035 _bcm_bst_cmn_unit_info_t *bst_info; 4036 int rv = BCM_E_INIT; 4037 4038 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 4039 return BCM_E_INIT; 4040 } 4041 4042 if (bst_info->bst_tbl_buf) { 4043 soc_cm_sfree(unit, bst_info->bst_tbl_buf); 4044 bst_info->bst_tbl_buf = NULL; 4045 } 4046 if (bst_info->bst_tbl_desc) { 4047 sal_free(bst_info->bst_tbl_desc); 4048 bst_info->bst_tbl_desc = NULL; 4049 } 4050 4051 rv = soc_bst_sbusdma_desc_free(unit); 4052 if (rv != BCM_E_NONE) { 4053 return rv; 4054 } 4055 4056 return BCM_E_NONE; 4057 } 4058 #endif 4059 4060 STATIC void 4061 soc_sbusdma_bst_cb(int unit, int status, sbusdma_desc_handle_t handle, void *data) 4062 { 4063 _bcm_bst_tbl_ctrl_t *tbl_ctrl = bst_tbl_ctrl[unit][PTR_TO_INT(data)]; 4064 if (status != SOC_E_NONE) { 4065 LOG_ERROR(BSL_LS_SOC_COMMON, 4066 (BSL_META_U(unit, 4067 "bst sbusdma failed: blk: %d, bid: %d, entries: %d, size: %d.\n"), 4068 tbl_ctrl->blk, tbl_ctrl->tindex, tbl_ctrl->entries, tbl_ctrl->size)); 4069 } 4070 } 4071 4072 int 4073 soc_bst_sbusdma_desc_setup(int unit) 4074 { 4075 _bcm_bst_cmn_unit_info_t *bst_info; 4076 int mi; 4077 uint8 *buff = NULL; 4078 soc_sbusdma_desc_ctrl_t ctrl = {0}; 4079 soc_sbusdma_desc_cfg_t *cfg = NULL; 4080 _bcm_bst_tbl_desc_t *desc = NULL; 4081 int rv = BCM_E_INIT; 4082 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 4083 return BCM_E_INIT; 4084 } 4085 buff = bst_info->bst_tbl_buf; 4086 desc = bst_info->bst_tbl_desc; 4087 4088 ctrl.flags = SOC_SBUSDMA_CFG_USE_FLAGS; 4089 ctrl.pc = NULL; 4090 ctrl.pc_data = NULL; 4091 ctrl.cfg_count = bst_info->bst_tbl_num; 4092 ctrl.buff = buff; 4093 ctrl.cb = soc_sbusdma_bst_cb; 4094 ctrl.data = INT_TO_PTR(bcmBstStatIdDevice); 4095 #define BST_TBLS "BST TBLS" 4096 sal_strncpy(ctrl.name, BST_TBLS, sizeof(BST_TBLS)); 4097 cfg = sal_alloc(bst_info->bst_tbl_num * sizeof(soc_sbusdma_desc_cfg_t), 4098 "bst_sbusdma_desc_cfg"); 4099 if (cfg == NULL) { 4100 return BCM_E_MEMORY; 4101 } 4102 sal_memset(cfg, 0, bst_info->bst_tbl_num * sizeof(soc_sbusdma_desc_cfg_t)); 4103 mi = 0; 4104 for (mi = 0; mi < bst_info->bst_tbl_num; mi++) { 4105 cfg[mi].addr = desc[mi].addr; 4106 cfg[mi].flags = desc[mi].flags; 4107 cfg[mi].acc_type = desc[mi].acc_type; 4108 cfg[mi].blk = desc[mi].blk; 4109 cfg[mi].width = desc[mi].width; 4110 cfg[mi].count = desc[mi].entries; 4111 cfg[mi].addr_shift = desc[mi].shift; 4112 #ifdef BCM_TOMAHAWK3_SUPPORT 4113 if (SOC_IS_TOMAHAWK3(unit)) { 4114 cfg[mi].flags |= SOC_SBUSDMA_CFG_MOR; 4115 } 4116 #endif 4117 4118 } 4119 rv = soc_sbusdma_desc_create(unit, &ctrl, cfg, 4120 &bst_tbl_handles[unit]); 4121 sal_free(cfg); 4122 if (rv != SOC_E_NONE) { 4123 LOG_ERROR(BSL_LS_SOC_COMMON, 4124 (BSL_META_U(unit, 4125 "bst sbusdma desc creation error!\n"))); 4126 return rv; 4127 } 4128 return BCM_E_NONE; 4129 } 4130 4131 int 4132 soc_bst_sbusdma_desc_free(int unit) 4133 { 4134 int bid; 4135 _bcm_bst_resource_info_t *resInfo; 4136 int rv = BCM_E_INIT; 4137 if (bst_tbl_handles[unit]) { 4138 do { 4139 rv = soc_sbusdma_desc_delete(unit, bst_tbl_handles[unit]); 4140 if (rv == SOC_E_BUSY) { 4141 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 4142 } 4143 } while (rv == SOC_E_BUSY); 4144 if (rv != SOC_E_NONE) { 4145 LOG_ERROR(BSL_LS_SOC_COMMON, 4146 (BSL_META_U(unit, 4147 "bst sbusdma desc delete error!\n"))); 4148 return rv; 4149 } 4150 4151 bst_tbl_handles[unit] = 0; 4152 } 4153 4154 for (bid = _BCM_BST_RESOURCE_MIN; bid < _BCM_BST_RESOURCE_MAX; bid++) { 4155 resInfo = _BCM_BST_RESOURCE(unit, bid); 4156 if (resInfo == NULL) { 4157 return BCM_E_PARAM; 4158 } 4159 4160 if (!_BCM_BST_RESOURCE_VALID(resInfo)) { 4161 continue; 4162 } 4163 4164 if (bst_tbl_ctrl[unit][bid]) { 4165 sal_free(bst_tbl_ctrl[unit][bid]); 4166 bst_tbl_ctrl[unit][bid] = NULL; 4167 } 4168 } 4169 if (bst_tbl_ctrl[unit]) { 4170 sal_free(bst_tbl_ctrl[unit]); 4171 bst_tbl_ctrl[unit] = NULL; 4172 } 4173 4174 return BCM_E_NONE; 4175 } 4176 int 4177 soc_bst_hw_sbusdma_desc_sync(int unit) 4178 { 4179 sbusdma_desc_handle_t desc_handle; 4180 soc_timeout_t to; 4181 sal_usecs_t dma_timeout = 1000000; 4182 sal_usecs_t stime, etime; 4183 _bcm_bst_cmn_unit_info_t *bst_info; 4184 int rv = BCM_E_INIT; 4185 if ((bst_info = _BCM_UNIT_BST_INFO(unit)) == NULL) { 4186 return BCM_E_INIT; 4187 } 4188 if (!bst_tbl_ctrl[unit]) { 4189 return BCM_E_INIT; 4190 } 4191 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4192 (BSL_META_U(unit, "bst start sync.\n"))); 4193 desc_handle = bst_tbl_handles[unit]; 4194 if (bst_info->bst_tbl_buf && desc_handle) { 4195 soc_timeout_init(&to, 2 * dma_timeout, 0); 4196 do { 4197 stime = sal_time_usecs(); 4198 rv = soc_sbusdma_desc_start(unit, desc_handle); 4199 if (rv == SOC_E_NONE) { 4200 break; 4201 } else if (rv == SOC_E_BUSY) { 4202 sal_usleep(SAL_BOOT_QUICKTURN ? 10000 : 10); 4203 } else { 4204 sal_mutex_give(bst_info->bst_reslock); 4205 return SOC_E_INTERNAL; 4206 } 4207 if (soc_timeout_check(&to)) { 4208 LOG_WARN(BSL_LS_SOC_COMMON, 4209 (BSL_META_U(unit, 4210 "bst start dma timeout\n"))); 4211 sal_mutex_give(bst_info->bst_reslock); 4212 return SOC_E_TIMEOUT; 4213 } 4214 } while (rv == SOC_E_BUSY); 4215 etime = sal_time_usecs(); 4216 LOG_INFO(BSL_LS_SOC_MMU, 4217 (BSL_META_U(unit, 4218 "soc_bst_hw_sbusdma_desc_sync: unit=%d bst sync done in %d usec\n"), 4219 unit, 4220 SAL_USECS_SUB(etime, stime))); 4221 } 4222 return BCM_E_NONE; 4223 } 4224