tcb.c (40205B)
1 /* 2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 3 * 4 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 5 */ 6 7 #include <bcm/cosq.h> 8 9 #include <bcm_int/esw_dispatch.h> 10 #include <bcm_int/esw/trident3.h> 11 12 #include <soc/trident3.h> 13 14 #if defined (INCLUDE_TCB) && defined (BCM_TCB_SUPPORT) 15 #include <bcm_int/esw/tcb.h> 16 17 #define _BCM_TD3_TCB_MAX_NUM 1 18 #define _BCM_TD3_TCB_PROFILE_MAX_NUM 8 19 #define _BCM_TD3_TCB_THRESHOLD_MAX 0x3ffff 20 21 #define _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT 10 22 23 #define _TD3_NUM_PROFILE_COS 10 24 25 #define _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET 10 26 #define _TD3_TCB_UCQ_SCOPE_QUEUE_MASK 0x3ff 27 #define _TD3_TCB_PORT_SCOPE_PIPE_OFFSET 7 28 #define _TD3_TCB_PORT_SCOPE_PORT_MASK 0x7f 29 30 STATIC soc_field_t _bcm_td3_cosq_tcb_threshold_profile_map_fields[] = { 31 QUEUE_0f, 32 QUEUE_1f, 33 QUEUE_2f, 34 QUEUE_3f, 35 QUEUE_4f, 36 QUEUE_5f, 37 QUEUE_6f, 38 QUEUE_7f, 39 QUEUE_8f, 40 QUEUE_9f 41 }; 42 43 44 STATIC int 45 _bcm_td3_cosq_tcb_intr_enable_set(int unit, int enable) 46 { 47 uint32 rval; 48 49 if (SOC_REG_IS_VALID(unit, MMU_XCFG_XPE_CPU_INT_ENr)) { 50 BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_ENr(unit, &rval)); 51 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_ENr, &rval, 52 TCB_FREEZE_INT_ENf, enable); 53 BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_ENr(unit, rval)); 54 } 55 return BCM_E_NONE; 56 } 57 58 STATIC int 59 _bcm_td3_cosq_tcb_intr_status_reset(int unit) 60 { 61 uint32 rval; 62 63 BCM_IF_ERROR_RETURN(READ_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, &rval)); 64 soc_reg_field_set(unit, MMU_XCFG_XPE_CPU_INT_CLEARr, &rval, 65 TCB_FREEZE_INT_CLRf, 0); 66 BCM_IF_ERROR_RETURN(WRITE_MMU_XCFG_XPE_CPU_INT_CLEARr(unit, rval)); 67 68 return BCM_E_NONE; 69 } 70 71 /* 72 * Function: 73 * _bcm_td3_cosq_tcb_current_phase_get 74 * Purpose: 75 * Get tcb buffer running status. 76 * Parameters: 77 * unit - (IN) BCM device number. 78 * buffer_id - (IN) TCB buffer id. 79 * status - (OUT) TCB buffer status. 80 * Returns: 81 * BCM_E_XXX 82 */ 83 STATIC int 84 _bcm_td3_cosq_tcb_current_phase_get(int unit, int *status) 85 { 86 uint32 rval; 87 88 LOG_INFO(BSL_LS_BCM_COSQ, 89 (BSL_META_U(unit, 90 "tcb_current_phase_get: unit %d, buffer_id 0\n"), 91 unit)); 92 93 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_CURRENT_PHASEr, 0, 0, &rval)); 94 *status = soc_reg_field_get(unit,TCB_CURRENT_PHASEr, rval, CURRENT_PHASEf); 95 96 return BCM_E_NONE; 97 } 98 99 STATIC int 100 _bcm_td3_cosq_tcb_hw_event_cb(int unit) 101 { 102 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 103 bcm_cosq_buffer_id_t buffer_id; 104 int status; 105 106 tcb_unit_info = TCB_UNIT_CONTROL(unit); 107 if (!tcb_unit_info) { 108 return 0; 109 } 110 111 _bcm_td3_cosq_tcb_intr_enable_set(unit, 0); 112 _bcm_td3_cosq_tcb_intr_status_reset(unit); 113 114 buffer_id = 0; 115 /* Go over the enabled TCB to see which is freezed */ 116 if(tcb_unit_info->tcb_enabled_bmp & (1 << buffer_id)) { 117 BCM_IF_ERROR_RETURN( 118 _bcm_td3_cosq_tcb_current_phase_get(unit, &status)); 119 if (_TCB_FROZEN_PHASE == status) { 120 if (tcb_unit_info->tcb_evt_cb) { 121 tcb_unit_info->tcb_evt_cb(unit, buffer_id, 122 tcb_unit_info->tcb_evt_user_data); 123 } 124 } 125 } 126 127 _bcm_td3_cosq_tcb_intr_enable_set(unit, 1); 128 return BCM_E_NONE; 129 } 130 131 int 132 soc_td3_tcb_set_hw_intr_cb(int unit) 133 { 134 BCM_IF_ERROR_RETURN( 135 soc_td3_set_tcb_callback(unit, &_bcm_td3_cosq_tcb_hw_event_cb)); 136 return SOC_E_NONE; 137 } 138 139 STATIC int 140 _bcm_td3_cosq_tcb_buffer_ready_clear(int unit, bcm_cosq_buffer_id_t buffer_id) 141 { 142 uint32 rval; 143 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, TCB_BUFFER_READYr, buffer_id, 0, &rval)); 144 soc_reg_field_set(unit, TCB_BUFFER_READYr, &rval, BUFFER_READYf, 0); 145 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, TCB_BUFFER_READYr, buffer_id, 0, rval)); 146 147 return BCM_E_NONE; 148 } 149 150 STATIC int 151 _bcm_td3_cosq_tcb_ext_freeze_set(int unit, 152 bcm_cosq_buffer_id_t buffer_id, int enable) 153 { 154 uint32 rval; 155 156 LOG_INFO(BSL_LS_BCM_COSQ, 157 (BSL_META_U(unit, 158 "tcb_ext_freeze_set: unit %d, buffer_id %d, enable %d\n"), 159 unit, buffer_id, enable)); 160 161 BCM_IF_ERROR_RETURN(READ_MMU_GCFG_TCB_FREEZEr(unit, &rval)); 162 163 if(enable) { 164 soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, TCB_FREEZE_XPEf, 1); 165 } else { 166 soc_reg_field_set(unit,MMU_GCFG_TCB_FREEZEr, &rval, TCB_FREEZE_XPEf, 0); 167 } 168 169 BCM_IF_ERROR_RETURN(WRITE_MMU_GCFG_TCB_FREEZEr(unit, rval)); 170 171 return BCM_E_NONE; 172 } 173 174 int 175 bcm_td3_cosq_tcb_uc_queue_resolve(int unit, bcm_cosq_buffer_id_t buffer_id, int queue, 176 bcm_gport_t *uc_gport) 177 { 178 int pipe, id; 179 bcm_port_t mmu_port, local_port, phy_port, local_mmu_port; 180 soc_info_t *si; 181 182 si = &SOC_INFO(unit); 183 184 pipe = queue >> _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET; 185 id = (queue & _TD3_TCB_UCQ_SCOPE_QUEUE_MASK) % 186 _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT; 187 local_mmu_port = (queue & _TD3_TCB_UCQ_SCOPE_QUEUE_MASK) / 188 _BCM_TD3_NUM_UCAST_QUEUE_PER_PORT; 189 mmu_port = pipe * (SOC_TD3_MMU_PORT_STRIDE + 1) + local_mmu_port; 190 phy_port = si->port_m2p_mapping[mmu_port]; 191 local_port = si->port_p2l_mapping[phy_port]; 192 BCM_GPORT_UCAST_QUEUE_GROUP_SYSQID_SET(*uc_gport, local_port, id); 193 194 return BCM_E_NONE; 195 } 196 197 /* 198 * Function: 199 * bcm_td3_cosq_tcb_enable 200 * Purpose: 201 * Enable or disable a TCB buffer. 202 * Parameters: 203 * unit - (IN) BCM device number. 204 * buffer_id - (IN) TCB buffer id. 205 * enable - (IN) enable or disable. 206 * Returns: 207 * BCM_E_XXX 208 */ 209 int 210 bcm_td3_cosq_tcb_enable(int unit, bcm_cosq_buffer_id_t buffer_id, int enable) 211 { 212 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 213 int mask, rv = BCM_E_NONE; 214 uint64 rval64; 215 216 tcb_unit_info = TCB_UNIT_CONTROL(unit); 217 TCB_ID_CHECK(buffer_id); 218 mask = 1; 219 220 LOG_INFO(BSL_LS_BCM_COSQ, 221 (BSL_META_U(unit, 222 "tcb_enable: unit %d, buffer_id %d, enable %d\n"), 223 unit, buffer_id, enable)); 224 225 if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) { 226 LOG_INFO(BSL_LS_BCM_COSQ, 227 (BSL_META_U(unit, 228 "tcb config of buffer %d is not initialized\n"), 229 buffer_id)); 230 return BCM_E_DISABLED; 231 } 232 233 if (enable) { 234 if (tcb_unit_info->tcb_enabled_bmp & mask) { 235 /* tcb is already enabled */ 236 rv = BCM_E_BUSY; 237 } else { /* enable tcb */ 238 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, 239 &rval64)); 240 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 1); 241 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, 242 rval64)); 243 244 if (tcb_unit_info->tcb_enabled_bmp == 0) { 245 /* Enable interrupt */ 246 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_intr_enable_set(unit, 1)); 247 } 248 tcb_unit_info->tcb_enabled_bmp |= mask; 249 } 250 } else { 251 if (!(tcb_unit_info->tcb_enabled_bmp & mask)) { 252 /* tcb is already disabled */ 253 rv = BCM_E_PARAM; 254 } else { /* disable tcb */ 255 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 0)); 256 257 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, 258 &rval64)); 259 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TCB_ENABLEf, 0); 260 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, 261 rval64)); 262 263 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_buffer_ready_clear(unit, buffer_id)); 264 265 tcb_unit_info->tcb_enabled_bmp &= ~mask; 266 if (tcb_unit_info->tcb_enabled_bmp == 0) { 267 /* Disable interrupt */ 268 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_tcb_intr_enable_set(unit, 0)); 269 } 270 } 271 } 272 273 return rv; 274 275 } 276 277 /* 278 * Function: 279 * bcm_td3_cosq_tcb_freeze 280 * Purpose: 281 * External freeze a TCB buffer. 282 * Parameters: 283 * unit - (IN) BCM device number. 284 * buffer_id - (IN) TCB buffer id. 285 * enable - (IN) enable or disable. 286 * Returns: 287 * BCM_E_XXX 288 */ 289 int 290 bcm_td3_cosq_tcb_freeze(int unit, bcm_cosq_buffer_id_t buffer_id, int enable) 291 { 292 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 293 tcb_unit_info = TCB_UNIT_CONTROL(unit); 294 295 LOG_INFO(BSL_LS_BCM_COSQ, 296 (BSL_META_U(unit, 297 "tcb_freeze: unit %d, buffer_id %d, enable %d\n"), 298 unit, buffer_id, enable)); 299 300 if (buffer_id == -1) { 301 buffer_id = 0; 302 } 303 304 TCB_ID_CHECK(buffer_id); 305 306 if (!tcb_unit_info->tcb_enabled_bmp) { 307 LOG_INFO(BSL_LS_BCM_COSQ, 308 (BSL_META_U(unit, 309 "tcb buffer %d is disabled, can not freeze\n"), 310 buffer_id)); 311 return BCM_E_DISABLED; 312 } 313 314 if (0 != enable) { 315 BCM_IF_ERROR_RETURN( 316 _bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 1)); 317 } else { 318 BCM_IF_ERROR_RETURN( 319 _bcm_td3_cosq_tcb_ext_freeze_set(unit, buffer_id, 0)); 320 BCM_IF_ERROR_RETURN( 321 _bcm_td3_cosq_tcb_buffer_ready_clear(unit, buffer_id)); 322 } 323 324 return BCM_E_NONE; 325 } 326 327 /* 328 * Function: 329 * _bcm_td3_cosq_tcb_deinit 330 * Purpose: 331 * Deinitialize all TCB internal structure. 332 * Parameters: 333 * unit - (IN) BCM device number. 334 * Returns: 335 * BCM_E_XXX 336 */ 337 int 338 _bcm_td3_cosq_tcb_deinit(int unit) 339 { 340 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 341 _bcm_cosq_tcb_info_t *tcb_info; 342 int i = 0; 343 344 tcb_unit_info = TCB_UNIT_CONTROL(unit); 345 if (tcb_unit_info == NULL) { 346 return BCM_E_NONE; 347 } 348 349 if (NULL != tcb_unit_info->tcb_info[i]) { 350 tcb_info = tcb_unit_info->tcb_info[i]; 351 if (NULL != tcb_info->profile_bmp) { 352 sal_free(tcb_info->profile_bmp); 353 tcb_info->profile_bmp = NULL; 354 } 355 sal_free(tcb_unit_info->tcb_info[i]); 356 tcb_unit_info->tcb_info[i] = NULL; 357 } 358 359 if (NULL != tcb_unit_info->tcb_evt_cb) { 360 tcb_unit_info->tcb_evt_cb = NULL; 361 } 362 363 if (NULL != tcb_unit_info->tcb_evt_user_data) { 364 tcb_unit_info->tcb_evt_user_data = NULL; 365 } 366 367 if (NULL != tcb_unit_info->tcb_reslock) { 368 sal_mutex_destroy(tcb_unit_info->tcb_reslock); 369 tcb_unit_info->tcb_reslock = NULL; 370 } 371 372 sal_free(tcb_unit_info); 373 374 TCB_UNIT_CONTROL(unit) = NULL; 375 376 return BCM_E_NONE; 377 } 378 379 /* 380 * Function: 381 * bcm_td3_cosq_tcb_config_get 382 * Purpose: 383 * Get TCB instance control status. 384 * Parameters: 385 * unit - (IN) BCM device number. 386 * buffer_id - (IN) TCB buffer id. 387 * config - (OUT) TCB config information 388 * Returns: 389 * BCM_E_XXX 390 */ 391 int 392 bcm_td3_cosq_tcb_config_get(int unit, bcm_cosq_buffer_id_t buffer_id, 393 bcm_cosq_tcb_config_t *config) 394 { 395 uint64 rval64; 396 uint32 trigger, timer; 397 int type, entity_num, propability; 398 bcm_port_t mmu_port, local_port, phy_port; 399 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 400 soc_info_t *si; 401 tcb_unit_info = TCB_UNIT_CONTROL(unit); 402 403 LOG_INFO(BSL_LS_BCM_COSQ, 404 (BSL_META_U(unit, 405 "tcb_config_get: unit %d, buffer_id %d\n"), 406 unit, buffer_id)); 407 408 TCB_ID_CHECK(buffer_id); 409 if (NULL == config) { 410 LOG_ERROR(BSL_LS_BCM_COSQ, 411 (BSL_META_U(unit, "config is null!\n"))); 412 return BCM_E_PARAM; 413 } 414 415 si = &SOC_INFO(unit); 416 417 /* check TCB instance status */ 418 if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) { 419 config->scope_type = bcmCosqTcbScopeMaxCount; 420 config->gport = BCM_GPORT_INVALID; 421 config->cosq = -1; 422 config->trigger_reason = BCM_COSQ_TCB_INGRESS_ADMIN_DROP | 423 BCM_COSQ_TCB_EGRESS_ADMIN_DROP | 424 BCM_COSQ_TCB_CFAP_DROP | 425 BCM_COSQ_TCB_WRED_DROP; 426 config->pre_freeze_capture_num = _TCB_CAP_NUM_DEFAULT; 427 config->pre_freeze_capture_time = _TCB_CAP_TIM_DEFAULT * 10 / si->frequency; 428 config->pre_sample_probability = _TCB_PRE_SAMP_RATE_DEFAULT + 1; 429 config->post_sample_probability = _TCB_POST_SAMP_RATE_DEFAULT + 1; 430 431 return BCM_E_NONE; 432 } 433 434 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64)); 435 436 type = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, SCOPE_ENTITY_TYPEf); 437 438 switch(type) { 439 case _TCB_SCOPE_UCQ: 440 config->scope_type = bcmCosqTcbScopeUcastQueue; 441 entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 442 SCOPE_ENTITYf); 443 BCM_IF_ERROR_RETURN 444 (_bcm_cosq_tcb_uc_queue_resolve(unit, buffer_id, entity_num, 445 &config->gport)); 446 break; 447 case _TCB_SCOPE_ING_PORT: 448 config->scope_type = bcmCosqTcbScopeIngressPort; 449 entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 450 SCOPE_ENTITYf); 451 mmu_port = entity_num; 452 phy_port = si->port_m2p_mapping[mmu_port]; 453 local_port = si->port_p2l_mapping[phy_port]; 454 BCM_GPORT_LOCAL_SET(config->gport, local_port); 455 break; 456 case _TCB_SCOPE_EGR_PORT: 457 config->scope_type = bcmCosqTcbScopeEgressPort; 458 entity_num = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 459 SCOPE_ENTITYf); 460 mmu_port = entity_num; 461 phy_port = si->port_m2p_mapping[mmu_port]; 462 local_port = si->port_p2l_mapping[phy_port]; 463 BCM_GPORT_LOCAL_SET(config->gport, local_port); 464 break; 465 case _TCB_SCOPE_ING_PIPE: 466 config->scope_type = bcmCosqTcbScopeIngressPipe; 467 config->pipe_id = soc_reg64_field32_get( 468 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf); 469 break; 470 case _TCB_SCOPE_EGR_PIPE: 471 config->scope_type = bcmCosqTcbScopeEgressPipe; 472 config->pipe_id = soc_reg64_field32_get( 473 unit, TCB_CONFIGr, rval64, SCOPE_ENTITYf); 474 break; 475 default: 476 LOG_ERROR(BSL_LS_BCM_COSQ, 477 (BSL_META_U(unit, 478 "scope type %d is illegal\n"), 479 type)); 480 return BCM_E_PARAM; 481 } 482 483 trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_IADMN_DROPf); 484 config->trigger_reason = trigger << _SHR_TCB_TRACK_IADMN_DROP_SHIFT; 485 trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_EADMN_DROPf); 486 config->trigger_reason |= trigger << _SHR_TCB_TRACK_EADMN_DROP_SHIFT; 487 trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_CFAP_DROPf); 488 config->trigger_reason |= trigger << _SHR_TCB_TRACK_CFAP_DROP_SHIFT; 489 trigger = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TRACK_WRED_DROPf); 490 config->trigger_reason |= trigger << _SHR_TCB_TRACK_WRED_DROP_SHIFT; 491 492 config->pre_freeze_capture_num = soc_reg64_field32_get(unit, TCB_CONFIGr, 493 rval64, REV_COUNTERf); 494 timer = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 495 WD_TIMER_PRESETf); 496 config->pre_freeze_capture_time = timer * 10 / si->frequency; 497 propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 498 PRE_TRIGGER_SAMPLE_RATEf); 499 config->pre_sample_probability = propability + 1; 500 propability = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, 501 POST_TRIGGER_SAMPLE_RATEf); 502 config->post_sample_probability = propability + 1; 503 504 return BCM_E_NONE; 505 506 } 507 508 /* 509 * Function: 510 * bcm_td3_cosq_tcb_config_set 511 * Purpose: 512 * Set TCB instance config attributes. 513 * Parameters: 514 * unit - (IN) BCM device number. 515 * buffer_id - (IN) TCB buffer id. 516 * config - (IN) TCB config information 517 * Returns: 518 * BCM_E_XXX 519 */ 520 int 521 bcm_td3_cosq_tcb_config_set(int unit, bcm_cosq_buffer_id_t buffer_id, 522 bcm_cosq_tcb_config_t *config) 523 { 524 uint64 rval64 = COMPILER_64_INIT(0,0); 525 int timer; 526 bcm_port_t local_port; 527 bcm_gport_t gport; 528 int mmu_port, phy_port, q_num, pipe, arg = 0, cosq, modid, trunk_id; 529 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 530 soc_info_t *si; 531 tcb_unit_info = TCB_UNIT_CONTROL(unit); 532 533 LOG_INFO(BSL_LS_BCM_COSQ, 534 (BSL_META_U(unit, 535 "tcb_config_set: unit %d, buffer_id %d\n"), 536 unit, buffer_id)); 537 538 TCB_ID_CHECK(buffer_id); 539 if (NULL == config) { 540 LOG_ERROR(BSL_LS_BCM_COSQ, 541 (BSL_META_U(unit, "config is null!\n"))); 542 return BCM_E_PARAM; 543 } 544 545 if (tcb_unit_info->tcb_enabled_bmp) { 546 /* tcb can only be configured in idle state */ 547 LOG_INFO(BSL_LS_BCM_COSQ, 548 (BSL_META_U(unit, 549 "tcb buffer %d is enabled\n"), 550 buffer_id)); 551 return BCM_E_BUSY; 552 } 553 554 gport = config->gport; 555 si = &SOC_INFO(unit); 556 557 /* Reset default value */ 558 if ((config->scope_type == bcmCosqTcbScopeMaxCount) && 559 (config->gport == BCM_GPORT_INVALID) && 560 (config->cosq == -1) && 561 (config->trigger_reason == (BCM_COSQ_TCB_INGRESS_ADMIN_DROP | 562 BCM_COSQ_TCB_EGRESS_ADMIN_DROP | 563 BCM_COSQ_TCB_CFAP_DROP | 564 BCM_COSQ_TCB_WRED_DROP)) && 565 (config->pre_freeze_capture_num == _TCB_CAP_NUM_DEFAULT) && 566 (config->pre_freeze_capture_time == 567 _TCB_CAP_TIM_DEFAULT * 10 / si->frequency) && 568 (config->pre_sample_probability == _TCB_PRE_SAMP_RATE_DEFAULT + 1) && 569 (config->post_sample_probability == _TCB_POST_SAMP_RATE_DEFAULT + 1)) { 570 571 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64)); 572 /* update TCB instance status */ 573 if ((tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) { 574 tcb_unit_info->tcb_config_init_bmp &= ~(1 << buffer_id); 575 } 576 return BCM_E_NONE; 577 } 578 579 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, buffer_id, 0, &rval64)); 580 581 switch(config->scope_type) { 582 case bcmCosqTcbScopeUcastQueue: 583 if (!BCM_GPORT_IS_SET(gport)) { 584 LOG_INFO(BSL_LS_BCM_COSQ, 585 (BSL_META_U(unit, 586 "tcb config set, gport 0x%x is illegal\n"), 587 gport)); 588 return BCM_E_PARAM; 589 } 590 if (!BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 591 LOG_INFO(BSL_LS_BCM_COSQ, 592 (BSL_META_U(unit, 593 "tcb config set, gport 0x%x is illegal\n"), 594 gport)); 595 return BCM_E_PARAM; 596 } 597 598 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0, 599 _BCM_TD3_COSQ_INDEX_STYLE_UCAST_QUEUE, NULL, 600 &cosq, NULL)); 601 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_port_resolve(unit, gport, &modid, 602 &local_port, &trunk_id, NULL, NULL)); 603 604 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, local_port, &pipe)); 605 606 q_num = (pipe << _TD3_TCB_UCQ_SCOPE_PIPE_OFFSET) + cosq; 607 608 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf, 609 _TCB_SCOPE_UCQ); 610 arg = q_num; 611 break; 612 case bcmCosqTcbScopeIngressPort: 613 if (BCM_GPORT_IS_SET(gport)){ 614 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, 615 &local_port)); 616 } else if (SOC_PORT_VALID(unit, gport)) { 617 local_port = gport; 618 } else { 619 LOG_INFO(BSL_LS_BCM_COSQ, 620 (BSL_META_U(unit, 621 "tcb config set, gport 0x%x is illegal\n"), 622 gport)); 623 return BCM_E_PORT; 624 } 625 626 if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) { 627 LOG_INFO(BSL_LS_BCM_COSQ, 628 (BSL_META_U(unit, 629 "tcb config set, gport 0x%x is illegal\n"), 630 gport)); 631 return BCM_E_PORT; 632 } 633 634 phy_port = si->port_l2p_mapping[local_port]; 635 mmu_port = si->port_p2m_mapping[phy_port]; 636 637 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf, 638 _TCB_SCOPE_ING_PORT); 639 arg = mmu_port; 640 break; 641 case bcmCosqTcbScopeEgressPort: 642 if (BCM_GPORT_IS_SET(gport)){ 643 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, 644 &local_port)); 645 } else if (SOC_PORT_VALID(unit, gport)) { 646 local_port = gport; 647 } else { 648 LOG_INFO(BSL_LS_BCM_COSQ, 649 (BSL_META_U(unit, 650 "tcb config set, gport 0x%x is illegal\n"), 651 gport)); 652 return BCM_E_PORT; 653 } 654 655 if (IS_CPU_PORT(unit, local_port) || IS_LB_PORT(unit, local_port)) { 656 LOG_INFO(BSL_LS_BCM_COSQ, 657 (BSL_META_U(unit, 658 "tcb config set, gport 0x%x is illegal\n"), 659 gport)); 660 return BCM_E_PORT; 661 } 662 663 phy_port = si->port_l2p_mapping[local_port]; 664 mmu_port = si->port_p2m_mapping[phy_port]; 665 666 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf, 667 _TCB_SCOPE_EGR_PORT); 668 arg = mmu_port; 669 break; 670 case bcmCosqTcbScopeIngressPipe: 671 if ((config->pipe_id < 0) || (config->pipe_id >= si->num_pipe)) { 672 return BCM_E_PARAM; 673 } 674 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf, 675 _TCB_SCOPE_ING_PIPE); 676 arg = config->pipe_id; 677 break; 678 case bcmCosqTcbScopeEgressPipe: 679 if ((config->pipe_id < 0) || (config->pipe_id >= si->num_pipe)) { 680 return BCM_E_PARAM; 681 } 682 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITY_TYPEf, 683 _TCB_SCOPE_EGR_PIPE); 684 arg = config->pipe_id; 685 break; 686 default: 687 LOG_INFO(BSL_LS_BCM_COSQ, 688 (BSL_META_U(unit, 689 "tcb config set, scope type %d is illegal\n"), 690 config->scope_type)); 691 return BCM_E_PARAM; 692 } 693 694 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, SCOPE_ENTITYf, arg); 695 696 if (config->trigger_reason > _TCB_TRIGGER_MAX) { 697 LOG_INFO(BSL_LS_BCM_COSQ, 698 (BSL_META_U(unit, 699 "tcb config set, trigger reason %d is illegal\n"), 700 config->trigger_reason)); 701 return BCM_E_PARAM; 702 } 703 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_IADMN_DROPf, 704 (config->trigger_reason & BCM_COSQ_TCB_INGRESS_ADMIN_DROP) ? 1:0); 705 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_EADMN_DROPf, 706 (config->trigger_reason & BCM_COSQ_TCB_EGRESS_ADMIN_DROP) ? 1:0); 707 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_CFAP_DROPf, 708 (config->trigger_reason & BCM_COSQ_TCB_CFAP_DROP) ? 1:0); 709 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, TRACK_WRED_DROPf, 710 (config->trigger_reason & BCM_COSQ_TCB_WRED_DROP) ? 1:0); 711 712 /* rev_counter valid range is 2 - 1024 */ 713 if ((config->pre_freeze_capture_num < _TCB_CAP_NUM_MIN) || 714 (config->pre_freeze_capture_num > _TCB_CAP_NUM_MAX)) { 715 LOG_INFO(BSL_LS_BCM_COSQ, 716 (BSL_META_U(unit, 717 "tcb config set, pre freeze capture %d is illegal\n"), 718 config->pre_freeze_capture_num)); 719 return BCM_E_PARAM; 720 } 721 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, REV_COUNTERf, 722 config->pre_freeze_capture_num); 723 724 /* WD_TIMER_PRESET is a counter of clock cycles * 10, a value 1 means 10 clock cycles */ 725 timer = (config->pre_freeze_capture_time) * (si->frequency) / 10; 726 if (timer > _TCB_CAP_TIM_MAX) { 727 LOG_INFO(BSL_LS_BCM_COSQ, 728 (BSL_META_U(unit, 729 "tcb config set, pre freeze capture time %d is illegal\n"), 730 config->pre_freeze_capture_time)); 731 return BCM_E_PARAM; 732 } 733 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, WD_TIMER_PRESETf, 734 timer); 735 736 if (config->post_sample_probability > _TCB_POST_SAMP_RATE_MAX || 737 config->post_sample_probability <= 0) { 738 LOG_INFO(BSL_LS_BCM_COSQ, 739 (BSL_META_U(unit, 740 "tcb config set, post sample probability %d is illegal\n"), 741 config->post_sample_probability)); 742 return BCM_E_PARAM; 743 } 744 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, POST_TRIGGER_SAMPLE_RATEf, 745 config->post_sample_probability - 1); 746 747 if (config->pre_sample_probability > _TCB_PRE_SAMP_RATE_MAX || 748 config->pre_sample_probability <= 0) { 749 LOG_INFO(BSL_LS_BCM_COSQ, 750 (BSL_META_U(unit, 751 "tcb config set, pre sample probability %d is illegal\n"), 752 config->pre_sample_probability)); 753 return BCM_E_PARAM; 754 } 755 soc_reg64_field32_set(unit, TCB_CONFIGr, &rval64, PRE_TRIGGER_SAMPLE_RATEf, 756 config->pre_sample_probability - 1); 757 758 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, TCB_CONFIGr, buffer_id, 0, rval64)); 759 760 /* update TCB instance status */ 761 if (!(tcb_unit_info->tcb_config_init_bmp & (1 << buffer_id))) { 762 tcb_unit_info->tcb_config_init_bmp |= (1 << buffer_id); 763 } 764 return BCM_E_NONE; 765 } 766 767 /* 768 * Function: 769 * bcm_td3_cosq_tcb_gport_threshold_mapping_set 770 * Purpose: 771 * Set threshold profile for a UCQ or a port. 772 * Parameters: 773 * unit - (IN) unit number 774 * gport - (IN) Ucq or a port 775 * cosq - (IN) Reserved field 776 * buffer_id - (IN) TCB buffer id. 777 * index - (IN) Threshold profile index 778 * Returns: 779 * BCM_E_XXX 780 * Notes: 781 * When gport is a port, SDK will attach all Ucqs in this port to one threshold profile. 782 */ 783 int 784 bcm_td3_cosq_tcb_gport_threshold_mapping_set(int unit, 785 bcm_gport_t gport, bcm_cos_queue_t cosq, 786 bcm_cosq_buffer_id_t buffer_id, 787 int index) 788 { 789 soc_mem_t profile_mem; 790 soc_field_t field; 791 bcm_port_t local_port; 792 int mmu_port, phy_port, pipe, i, port_index, old_profile; 793 bcm_cos_t cos; 794 soc_info_t *si; 795 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 796 _bcm_cosq_tcb_info_t *tcb_config; 797 uint32 entry[SOC_MAX_MEM_WORDS]; 798 799 si = &SOC_INFO(unit); 800 tcb_unit_info = TCB_UNIT_CONTROL(unit); 801 TCB_ID_CHECK(buffer_id); 802 803 LOG_INFO(BSL_LS_BCM_COSQ, 804 (BSL_META_U(unit, 805 "tcb_threshold_mapping_set: unit %d, gport 0x%x, " 806 "cosq %d, buffer_id %d, index %d\n"), 807 unit, gport, cosq, buffer_id, index)); 808 809 if (tcb_unit_info->tcb_enabled_bmp) { 810 /* tcb can only be configured in idle state */ 811 LOG_INFO(BSL_LS_BCM_COSQ, 812 (BSL_META_U(unit, 813 "tcb buffer %d is enabled\n"), 814 buffer_id)); 815 return BCM_E_BUSY; 816 } 817 818 tcb_config = tcb_unit_info->tcb_info[buffer_id]; 819 profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id]; 820 821 if (BCM_GPORT_IS_SET(gport)) { 822 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 823 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0, 824 _BCM_TD3_COSQ_INDEX_STYLE_COS, &local_port, 825 &cos, NULL)); 826 } else if (BCM_GPORT_IS_LOCAL(gport)) { 827 local_port = BCM_GPORT_LOCAL_GET(gport); 828 cos = -1; 829 } else { 830 LOG_INFO(BSL_LS_BCM_COSQ, 831 (BSL_META_U(unit, 832 "tcb_threshold_mapping_set, gport 0x%x is illegal\n"), 833 gport)); 834 return BCM_E_PARAM; 835 } 836 } else { 837 local_port = gport; 838 cos = -1; 839 } 840 841 if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) || 842 IS_LB_PORT(unit, local_port)) { 843 LOG_INFO(BSL_LS_BCM_COSQ, 844 (BSL_META_U(unit, 845 "tcb_threshold_mapping_set, gport 0x%x is illegal\n"), 846 gport)); 847 return BCM_E_PORT; 848 } 849 850 phy_port = si->port_l2p_mapping[local_port]; 851 mmu_port = si->port_p2m_mapping[phy_port]; 852 pipe = si->port_pipe[local_port]; 853 port_index = mmu_port % 66 + pipe * 66; 854 855 856 if (!SHR_BITGET(tcb_config->profile_bmp, index)) { 857 LOG_ERROR(BSL_LS_BCM_COSQ, 858 (BSL_META_U(unit, 859 "profile %d is illegal\n"), 860 index)); 861 return BCM_E_NOT_FOUND; 862 } 863 864 if (-1 == cos) { 865 BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY, 866 port_index, entry)); 867 for (i = 0; i < _TD3_NUM_PROFILE_COS; i++) { 868 field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[i]; 869 old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm, 870 entry, field); 871 tcb_config->profile_ref_count[old_profile]--; 872 soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry, field, 873 index); 874 tcb_config->profile_ref_count[index]++; 875 } 876 BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL, 877 port_index, entry)); 878 } else { 879 field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[cos]; 880 BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY, 881 port_index, entry)); 882 old_profile = soc_mem_field32_get(unit, TCB_THRESHOLD_PROFILE_MAPm, 883 entry, field); 884 tcb_config->profile_ref_count[old_profile]--; 885 886 soc_mem_field32_set(unit, TCB_THRESHOLD_PROFILE_MAPm, entry, 887 field, index); 888 tcb_config->profile_ref_count[index]++; 889 BCM_IF_ERROR_RETURN (soc_mem_write(unit, profile_mem, MEM_BLOCK_ALL, 890 port_index, entry)); 891 } 892 893 return BCM_E_NONE; 894 } 895 896 /* 897 * Function: 898 * bcm_td3_cosq_tcb_gport_threshold_mapping_get 899 * Purpose: 900 * Set threshold profile for a UCQ or a port. 901 * Parameters: 902 * unit - (IN) unit number 903 * gport - (IN) Ucq or a port 904 * cosq - (IN) Reserved field 905 * buffer_id - (IN) TCB buffer id. 906 * index - (OUT) Threshold profile index 907 * Returns: 908 * BCM_E_XXX 909 * Notes: 910 * When gport is a port, SDK will return the threshold profile index of the first Ucq in this 911 * port. 912 */ 913 int 914 bcm_td3_cosq_tcb_gport_threshold_mapping_get(int unit, 915 bcm_gport_t gport, bcm_cos_queue_t cosq, 916 bcm_cosq_buffer_id_t buffer_id, int *index) 917 { 918 soc_mem_t profile_mem; 919 soc_field_t field; 920 bcm_port_t local_port; 921 int mmu_port, phy_port, pipe, port_index, cos; 922 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 923 _bcm_cosq_tcb_info_t *tcb_config; 924 soc_info_t *si; 925 uint32 entry[SOC_MAX_MEM_WORDS]; 926 927 LOG_INFO(BSL_LS_BCM_COSQ, 928 (BSL_META_U(unit, 929 "tcb_threshold_mapping_get: unit %d, gport 0x%x, " 930 "cosq %d, buffer_id %d\n"), 931 unit, gport, cosq, buffer_id)); 932 933 TCB_ID_CHECK(buffer_id); 934 if (NULL == index) { 935 LOG_ERROR(BSL_LS_BCM_COSQ, 936 (BSL_META_U(unit, "index is null!\n"))); 937 return BCM_E_PARAM; 938 } 939 940 tcb_unit_info = TCB_UNIT_CONTROL(unit); 941 si = &SOC_INFO(unit); 942 943 profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id]; 944 945 if (BCM_GPORT_IS_SET(gport)) { 946 if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) { 947 BCM_IF_ERROR_RETURN(_bcm_td3_cosq_index_resolve(unit, gport, 0, 948 _BCM_TD3_COSQ_INDEX_STYLE_COS, &local_port, 949 &cos, NULL)); 950 } else if (BCM_GPORT_IS_LOCAL(gport)) { 951 local_port = BCM_GPORT_LOCAL_GET(gport); 952 cos = 0; 953 } else { 954 LOG_INFO(BSL_LS_BCM_COSQ, 955 (BSL_META_U(unit, 956 "tcb_threshold_mapping_get, gport 0x%x is illegal\n"), 957 gport)); 958 return BCM_E_PARAM; 959 } 960 } else { 961 local_port = gport; 962 cos = 0; 963 } 964 965 if (!SOC_PORT_VALID(unit, local_port) || IS_CPU_PORT(unit, local_port) || 966 IS_LB_PORT(unit, local_port)) { 967 LOG_INFO(BSL_LS_BCM_COSQ, 968 (BSL_META_U(unit, 969 "tcb_threshold_mapping_get, gport 0x%x is illegal\n"), 970 gport)); 971 return BCM_E_PORT; 972 } 973 974 phy_port = si->port_l2p_mapping[local_port]; 975 mmu_port = si->port_p2m_mapping[phy_port]; 976 pipe = si->port_pipe[local_port]; 977 port_index = mmu_port % 66 + pipe * 66; 978 979 BCM_IF_ERROR_RETURN(soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY, 980 port_index, entry)); 981 982 field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[cos]; 983 *index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm, entry, field); 984 985 tcb_config = tcb_unit_info->tcb_info[buffer_id]; 986 if (!SHR_BITGET(tcb_config->profile_bmp, *index)) { 987 LOG_ERROR(BSL_LS_BCM_COSQ, 988 (BSL_META_U(unit, 989 "profile %d is illegal\n"), 990 *index)); 991 return BCM_E_NOT_FOUND; 992 } 993 994 return BCM_E_NONE; 995 996 } 997 998 #ifdef BCM_WARM_BOOT_SUPPORT 999 int 1000 bcm_td3_cosq_tcb_reinit(int unit) 1001 { 1002 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 1003 _bcm_cosq_tcb_info_t *tcb_config; 1004 int i = 0, j, k, n, enable, index, start_threshold, stop_threshold; 1005 uint64 rval64; 1006 soc_mem_t profile_mem; 1007 soc_field_t field; 1008 1009 tcb_unit_info = TCB_UNIT_CONTROL(unit); 1010 TCB_INIT(unit); 1011 1012 SOC_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_CONFIGr, i, 0, &rval64)); 1013 enable = soc_reg64_field32_get(unit, TCB_CONFIGr, rval64, TCB_ENABLEf); 1014 if (enable) { 1015 tcb_unit_info->tcb_enabled_bmp |= 1 << i; 1016 } 1017 1018 profile_mem = SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[i]; 1019 tcb_config = tcb_unit_info->tcb_info[i]; 1020 SHR_BITSET(tcb_config->profile_bmp, 0); 1021 1022 for (n = 1; n < _BCM_TD3_TCB_PROFILE_MAX_NUM; n++) { 1023 BCM_IF_ERROR_RETURN(soc_reg64_get(unit, TCB_THRESHOLD_PROFILEr, i, 1024 n, &rval64)); 1025 start_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr, 1026 rval64, CAPTURE_START_THRESHOLDf); 1027 stop_threshold = soc_reg_field_get(unit, TCB_THRESHOLD_PROFILEr, 1028 rval64, CAPTURE_END_THRESHOLDf); 1029 if (start_threshold != 0 || stop_threshold != 0) { 1030 SHR_BITSET(tcb_config->profile_bmp, n); 1031 } 1032 1033 } 1034 for (j = 0; j < soc_mem_index_count(unit, profile_mem); j++) { 1035 BCM_IF_ERROR_RETURN (soc_mem_read(unit, profile_mem, MEM_BLOCK_ANY, 1036 j, &rval64)); 1037 for (k = 0; k < _TD3_NUM_PROFILE_COS; k++) { 1038 field = _bcm_td3_cosq_tcb_threshold_profile_map_fields[k]; 1039 index = soc_mem_field32_get(unit,TCB_THRESHOLD_PROFILE_MAPm, 1040 &rval64, field); 1041 for (n = 0; n < _BCM_TD3_TCB_PROFILE_MAX_NUM; n++) { 1042 if (index == n) { 1043 if(SHR_BITGET(tcb_config->profile_bmp, n)) { 1044 tcb_config->profile_ref_count[n]++; 1045 } 1046 } 1047 } 1048 } 1049 } 1050 1051 return BCM_E_NONE; 1052 } 1053 #endif 1054 1055 /* 1056 * Function: 1057 * bcm_td3_cosq_tcb_init 1058 * Purpose: 1059 * Initialize (clear) all TCB internal structure. 1060 * Parameters: 1061 * unit - (IN) BCM device number. 1062 * Returns: 1063 * BCM_E_XXX 1064 */ 1065 int 1066 bcm_td3_cosq_tcb_init(int unit) 1067 { 1068 _bcm_cosq_tcb_unit_ctrl_t *tcb_unit_info; 1069 _bcm_cosq_tcb_info_t *tcb_info; 1070 bcm_cosq_buffer_id_t buffer_id = 0; 1071 soc_mem_t profile_mem; 1072 1073 (void)_bcm_td3_cosq_tcb_deinit(unit); 1074 1075 tcb_unit_info = TCB_UNIT_CONTROL(unit); 1076 if (NULL == tcb_unit_info) { 1077 tcb_unit_info = sal_alloc(sizeof(_bcm_cosq_tcb_unit_ctrl_t), "tcb_dev_info"); 1078 if (!tcb_unit_info) { 1079 return BCM_E_MEMORY; 1080 } 1081 } 1082 1083 sal_memset(tcb_unit_info, 0, sizeof(_bcm_cosq_tcb_unit_ctrl_t)); 1084 1085 TCB_UNIT_CONTROL(unit) = tcb_unit_info; 1086 1087 tcb_unit_info->tcb_num = _BCM_TD3_TCB_MAX_NUM; 1088 tcb_unit_info->cell_bytes = _TD3_MMU_BYTES_PER_CELL; 1089 tcb_unit_info->threshold_max = _BCM_TD3_TCB_THRESHOLD_MAX; 1090 1091 /* Create protection mutex. */ 1092 if (tcb_unit_info->tcb_reslock == NULL) { 1093 tcb_unit_info->tcb_reslock = sal_mutex_create("tcb_resource_lock"); 1094 } 1095 1096 if (tcb_unit_info->tcb_reslock == NULL) { 1097 (void)_bcm_td3_cosq_tcb_deinit(unit); 1098 return BCM_E_MEMORY; 1099 } 1100 1101 tcb_unit_info->tcb_info[buffer_id] = 1102 sal_alloc(sizeof(_bcm_cosq_tcb_info_t), "tcb info"); 1103 if (NULL == tcb_unit_info->tcb_info[buffer_id]) { 1104 (void)_bcm_td3_cosq_tcb_deinit(unit); 1105 return BCM_E_MEMORY; 1106 } 1107 1108 sal_memset(tcb_unit_info->tcb_info[buffer_id], 0, sizeof(_bcm_cosq_tcb_info_t)); 1109 1110 tcb_info = tcb_unit_info->tcb_info[buffer_id]; 1111 tcb_info->profile_bmp = 1112 sal_alloc(SHR_BITALLOCSIZE(_BCM_TD3_TCB_PROFILE_MAX_NUM), 1113 "profile_bitmap"); 1114 if (NULL == tcb_info->profile_bmp) { 1115 (void)_bcm_td3_cosq_tcb_deinit(unit); 1116 return BCM_E_MEMORY; 1117 } 1118 sal_memset(tcb_info->profile_bmp, 0, 1119 SHR_BITALLOCSIZE(_BCM_TD3_TCB_PROFILE_MAX_NUM)); 1120 1121 if (!SOC_WARM_BOOT(unit)) { 1122 SHR_BITSET(tcb_info->profile_bmp, 0); 1123 profile_mem = 1124 SOC_MEM_UNIQUE_ACC(unit, TCB_THRESHOLD_PROFILE_MAPm)[buffer_id]; 1125 tcb_info = tcb_unit_info->tcb_info[buffer_id]; 1126 tcb_info->profile_ref_count[0] = 1127 soc_mem_index_count(unit, profile_mem) * 10; 1128 } 1129 1130 soc_td3_tcb_set_hw_intr_cb(unit); 1131 1132 return BCM_E_NONE; 1133 } 1134 1135 #endif /* INCLUDE_TCB && BCM_TCB_SUPPORT */