cosq.c (19995B)
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 * MMU/Cosq soc routines 8 */ 9 10 #include <sal/core/libc.h> 11 12 #include <soc/debug.h> 13 #include <soc/util.h> 14 #include <soc/mem.h> 15 #include <soc/trident2.h> 16 #include <soc/tomahawk.h> 17 #include <shared/bsl.h> 18 #if defined(BCM_TOMAHAWK2_SUPPORT) 19 #include <soc/tomahawk2.h> 20 #endif 21 #include <soc/mmu_config.h> 22 #if defined(BCM_TOMAHAWK_SUPPORT) 23 24 #define TH_MMU_PER_PIPE_PORT_OFFSET 64 25 #define TH_MMU_GP_UCQ_NUM 320 /* Generl ports UC Queue Num in per Pipe Queue Number Space */ 26 #define TH_MMU_MGMT_UCQ_NUM 10 /* Management port UC Queues Num in Pipe Queue Number */ 27 #define TH_MMU_GP_MCQ_NUM 320 /* Generl ports MC Queue Num in per Pipe Queue Number Space */ 28 #define TH_MMU_LB_MCQ_NUM 10 /* Loopback port MC Queue Num in per Pipe Queue Number Space */ 29 #define TH_MMU_LB_MCQ_OFFSET ((TH_MMU_GP_UCQ_NUM) + (TH_MMU_MGMT_UCQ_NUM) + \ 30 (TH_MMU_GP_MCQ_NUM)) 31 #define TH_MMU_CPU_MCQ_OFFSET (TH_MMU_LB_MCQ_OFFSET + TH_MMU_LB_MCQ_NUM) 32 #define TH_MMU_MGMT_UCQ_OFFSET (TH_MMU_GP_UCQ_NUM) 33 #define TH_MMU_MGMT_MCQ_OFFSET (TH_MMU_LB_MCQ_OFFSET + TH_MMU_LB_MCQ_NUM) 34 35 int 36 soc_th_sched_weight_set(int unit, int port, int level, 37 int index, int weight, int mc) 38 { 39 soc_info_t *si; 40 soc_mem_t mem = INVALIDm; 41 uint32 entry[SOC_MAX_MEM_WORDS]; 42 int phy_port, mmu_port, pipe; 43 44 si = &SOC_INFO(unit); 45 46 pipe = si->port_pipe[port]; 47 phy_port = si->port_l2p_mapping[port]; 48 mmu_port = si->port_p2m_mapping[phy_port]; 49 50 if (level == SOC_TH_NODE_LVL_L0) { 51 mem = Q_SCHED_L0_WEIGHT_MEMm; 52 index = ((mmu_port % TH_MMU_PER_PIPE_PORT_OFFSET) * 10) + index 53 + (mc ? SOC_TH_NUM_UC_QUEUES_PER_PIPE : 0); 54 } else if (level == SOC_TH_NODE_LVL_L1) { 55 mem = Q_SCHED_L1_WEIGHT_MEMm; 56 57 if (IS_CPU_PORT(unit, port)) { 58 index = TH_MMU_CPU_MCQ_OFFSET + index; 59 } else if (IS_LB_PORT(unit, port)) { 60 index = TH_MMU_LB_MCQ_OFFSET + index; 61 } else if (SOC_PBMP_MEMBER(si->management_pbm, port)) { 62 index = (mc ? TH_MMU_MGMT_MCQ_OFFSET : TH_MMU_MGMT_UCQ_OFFSET) + index; 63 } else { 64 index = ((mmu_port % TH_MMU_PER_PIPE_PORT_OFFSET) * 10) + index 65 + (mc ? SOC_TH_NUM_UC_QUEUES_PER_PIPE : 0); 66 } 67 } else { 68 return SOC_E_PARAM; 69 } 70 71 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 72 73 SOC_IF_ERROR_RETURN 74 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 75 soc_mem_field32_set(unit, mem, &entry, WEIGHTf, weight); 76 SOC_IF_ERROR_RETURN 77 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &entry)); 78 79 return SOC_E_NONE; 80 } 81 82 int 83 soc_th_sched_weight_get(int unit, int port, int level, 84 int index, int *weight, int mc) 85 { 86 soc_info_t *si; 87 soc_mem_t mem = INVALIDm; 88 uint32 entry[SOC_MAX_MEM_WORDS]; 89 int phy_port, mmu_port, pipe; 90 91 si = &SOC_INFO(unit); 92 93 pipe = si->port_pipe[port]; 94 phy_port = si->port_l2p_mapping[port]; 95 mmu_port = si->port_p2m_mapping[phy_port]; 96 97 if (level == SOC_TH_NODE_LVL_L0) { 98 mem = Q_SCHED_L0_WEIGHT_MEMm; 99 index = ((mmu_port % TH_MMU_PER_PIPE_PORT_OFFSET) * 10) + index 100 + (mc ? SOC_TH_NUM_UC_QUEUES_PER_PIPE : 0); 101 } else if (level == SOC_TH_NODE_LVL_L1) { 102 mem = Q_SCHED_L1_WEIGHT_MEMm; 103 104 if (IS_CPU_PORT(unit, port)) { 105 index = TH_MMU_CPU_MCQ_OFFSET + index; 106 } else if (IS_LB_PORT(unit, port)) { 107 index = TH_MMU_LB_MCQ_OFFSET + index; 108 } else if (SOC_PBMP_MEMBER(si->management_pbm, port)) { 109 index = (mc ? TH_MMU_MGMT_MCQ_OFFSET : TH_MMU_MGMT_UCQ_OFFSET) + index; 110 } else { 111 index = ((mmu_port % TH_MMU_PER_PIPE_PORT_OFFSET) * 10) + index 112 + (mc ? SOC_TH_NUM_UC_QUEUES_PER_PIPE : 0); 113 } 114 } else { 115 return SOC_E_PARAM; 116 } 117 118 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 119 SOC_IF_ERROR_RETURN 120 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 121 *weight = soc_mem_field32_get(unit, mem, &entry, WEIGHTf); 122 123 return SOC_E_NONE; 124 } 125 126 int 127 soc_th_cosq_sched_mode_set(int unit, soc_port_t port, int level, int index, 128 soc_th_sched_mode_e mode, int weight, int mc) 129 { 130 soc_reg_t reg, reg2 = INVALIDr; 131 uint32 fval, rval, wrr_mask; 132 soc_info_t *si = &SOC_INFO(unit); 133 134 LOG_INFO(BSL_LS_SOC_COSQ, 135 (BSL_META_U(unit, 136 "Port:%d L%s%d config : index=%d MODE=%d WT=%d\n"), 137 port, (level == 0) ? "r" : "", level - 1, 138 index, mode, weight)); 139 140 /* selection between SP and WxRR is based on weight property. */ 141 SOC_IF_ERROR_RETURN(soc_th_sched_weight_set(unit, port, 142 level, index, weight, mc)); 143 144 if (level == SOC_TH_NODE_LVL_L0) { 145 if (IS_CPU_PORT(unit, port)) { 146 reg = Q_SCHED_CPU_PORT_CONFIGr; 147 reg2 = Q_SCHED_PORT_CONFIGr; 148 } else { 149 reg = Q_SCHED_PORT_CONFIGr; 150 } 151 index = 0; 152 } else if (level == SOC_TH_NODE_LVL_L1) { 153 if (IS_CPU_PORT(unit, port)) { 154 int parent_index = 0; 155 reg = Q_SCHED_CPU_L0_NODE_CONFIGr; 156 reg2 = Q_SCHED_L0_NODE_CONFIGr; 157 SOC_IF_ERROR_RETURN 158 (soc_th_cosq_cpu_parent_get(unit, index, SOC_TH_NODE_LVL_L1, 159 &parent_index)); 160 index = parent_index; 161 } else { 162 reg = Q_SCHED_L0_NODE_CONFIGr; 163 index %= si->port_num_cosq[port]; 164 } 165 } else { 166 return SOC_E_PARAM; 167 } 168 169 if (mode == SOC_TH_SCHED_MODE_WRR) { 170 fval = 1; 171 } else if (mode == SOC_TH_SCHED_MODE_WERR) { 172 fval = 0; 173 } else { 174 return SOC_E_NONE; 175 } 176 177 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 178 wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf); 179 wrr_mask &= ~(1 << index); 180 wrr_mask |= (fval << index); 181 soc_reg_field_set(unit, reg, &rval, ENABLE_WRRf, wrr_mask); 182 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 183 184 /* WAR: set port 32 besides CPU reg, 185 as CPU WRED takes some info from port 32. */ 186 if (reg2 != INVALIDr) { 187 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg2, port, 0, &rval)); 188 wrr_mask = soc_reg_field_get(unit, reg2, rval, ENABLE_WRRf); 189 wrr_mask &= ~(1 << index); 190 wrr_mask |= (fval << index); 191 soc_reg_field_set(unit, reg2, &rval, ENABLE_WRRf, wrr_mask); 192 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg2, port, 0, rval)); 193 } 194 195 return SOC_E_NONE; 196 } 197 198 int 199 soc_th_cosq_sched_mode_get(int unit, soc_port_t port, int level, int index, 200 soc_th_sched_mode_e *mode, int *weight, int mc) 201 { 202 soc_reg_t reg; 203 uint32 rval, wrr_mask; 204 soc_info_t *si = &SOC_INFO(unit); 205 206 /* selection between SP and WxRR is based on weight property. */ 207 SOC_IF_ERROR_RETURN(soc_th_sched_weight_get(unit, port, 208 level, index, weight, mc)); 209 210 if (level == SOC_TH_NODE_LVL_L0) { 211 if (IS_CPU_PORT(unit, port)) { 212 reg = Q_SCHED_CPU_PORT_CONFIGr; 213 } else { 214 reg = Q_SCHED_PORT_CONFIGr; 215 } 216 index = 0; 217 } else if (level == SOC_TH_NODE_LVL_L1) { 218 if (IS_CPU_PORT(unit, port)) { 219 int parent_index = 0; 220 reg = Q_SCHED_CPU_L0_NODE_CONFIGr; 221 SOC_IF_ERROR_RETURN 222 (soc_th_cosq_cpu_parent_get(unit, index, SOC_TH_NODE_LVL_L1, 223 &parent_index)); 224 index = parent_index; 225 } else { 226 reg = Q_SCHED_L0_NODE_CONFIGr; 227 index %= si->port_num_cosq[port]; 228 } 229 } else { 230 return SOC_E_PARAM; 231 } 232 233 if (*weight == 0) { 234 *mode = SOC_TH_SCHED_MODE_STRICT; 235 } else { 236 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 237 wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf); 238 if (wrr_mask & (1 << index)) { 239 *mode = SOC_TH_SCHED_MODE_WRR; 240 } else { 241 *mode = SOC_TH_SCHED_MODE_WERR; 242 } 243 } 244 245 return SOC_E_NONE; 246 } 247 248 /* 249 * Function to Set Parent(L0) for a given L1 queue of the CPU port 250 * Note: Only child @ L1 level is supported. 251 * Because only L1 level queues can be attached to different parent (L0.0-L0.9) 252 * of the CPU port. 253 */ 254 int 255 soc_th_cosq_cpu_parent_set(int unit, int child_index, int child_level, 256 int parent_index) 257 { 258 soc_reg_t reg = Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr; 259 uint32 rval = 0; 260 261 if (child_level != SOC_TH_NODE_LVL_L1) { 262 /* Only child at L1 are allowed to move */ 263 return SOC_E_PARAM; 264 } 265 /* Set the L1 queue's parent to the given L0 node */ 266 SOC_IF_ERROR_RETURN 267 (soc_reg32_get(unit, reg, 0, child_index, &rval)); 268 soc_reg_field_set(unit, reg, &rval, SELECTf, parent_index); 269 SOC_IF_ERROR_RETURN 270 (soc_reg32_set(unit, reg, 0, child_index, rval)); 271 272 return SOC_E_NONE; 273 } 274 275 /* 276 * Function to Get Parent(L0) for a given L1 queue of the CPU port 277 * Note: Only child @ L1 level is supported. 278 * Because only L1 level queues can be attached to different parent (L0.0-L0.9) 279 * of the CPU port. 280 */ 281 int 282 soc_th_cosq_cpu_parent_get(int unit, int child_index, int child_level, 283 int *parent_index) 284 { 285 soc_reg_t reg = Q_SCHED_CPU_L1_MC_QUEUE_L0_MAPPINGr; 286 uint32 rval = 0; 287 288 if (child_level != SOC_TH_NODE_LVL_L1) { 289 /* Only child at L1 are allowed to move */ 290 return SOC_E_PARAM; 291 } 292 /* Set the L1 queue's parent to the given L0 node */ 293 SOC_IF_ERROR_RETURN 294 (soc_reg32_get(unit, reg, 0, child_index, &rval)); 295 *parent_index = soc_reg_field_get(unit, reg, rval, SELECTf); 296 297 return SOC_E_NONE; 298 } 299 300 int 301 soc_th_mmu_get_shared_size(int unit, int *thdi_shared, 302 int *thdo_db_shared, int *thdo_qe_shared) 303 { 304 int xpe, xpe_map; 305 int granularity; 306 uint32 rval = 0; 307 308 xpe_map = SOC_INFO(unit).ipipe_xpe_map[0]|SOC_INFO(unit).ipipe_xpe_map[1]; 309 310 for (xpe = 0; xpe < NUM_XPE(unit); xpe ++) { 311 /* unavailable XPEs */ 312 if (!(xpe_map & (1 << xpe))) { 313 thdi_shared[xpe] = thdo_db_shared[xpe] = thdo_qe_shared[xpe] = -1; 314 continue; 315 } 316 317 /* available XPEs */ 318 /* Read shared size from Service pool 0 */ 319 /* THDI */ 320 rval = 0; 321 granularity = 1; 322 SOC_IF_ERROR_RETURN 323 (soc_tomahawk_xpe_reg32_get(unit, THDI_BUFFER_CELL_LIMIT_SPr, 324 xpe, -1, 0, &rval)); 325 thdi_shared[xpe] = soc_reg_field_get(unit, THDI_BUFFER_CELL_LIMIT_SPr, 326 rval, LIMITf) * granularity; 327 /* THDO - DB */ 328 rval = 0; 329 granularity = 1; 330 SOC_IF_ERROR_RETURN 331 (soc_tomahawk_xpe_reg32_get(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, 332 xpe, -1, 0, &rval)); 333 thdo_db_shared[xpe] = soc_reg_field_get(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, 334 rval, SHARED_LIMITf) * granularity; 335 336 /* THDO - QE */ 337 rval = 0; 338 granularity = 4; 339 SOC_IF_ERROR_RETURN 340 (soc_tomahawk_xpe_reg32_get(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 341 xpe, -1, 0, &rval)); 342 thdo_qe_shared[xpe] = soc_reg_field_get(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 343 rval, SHARED_LIMITf) * granularity; 344 345 LOG_VERBOSE(BSL_LS_SOC_MMU, 346 (BSL_META_U(unit, 347 "XPE[%d] Shared cell allocation: ING: %d, " 348 "EGR: DB %d, QE %d (unit of cells)\n"), xpe, 349 *thdi_shared, *thdo_db_shared, *thdo_qe_shared)); 350 } 351 352 return SOC_E_NONE; 353 } 354 355 int soc_th_mmu_config_res_limits_update(int unit, int res, int *ing_shd, 356 int *egr_db_shd, int *egr_qe_shd, 357 int post_update) 358 { 359 if (SOC_IS_TOMAHAWK(unit)) { 360 return soc_th_mmu_config_shared_buf_recalc(unit, res, ing_shd, 361 egr_db_shd, egr_qe_shd, 362 post_update); 363 } 364 #if defined(BCM_TOMAHAWK2_SUPPORT) 365 else if (SOC_IS_TOMAHAWK2(unit)) { 366 return soc_th2_mmu_config_shared_buf_set_hw(unit, res, ing_shd, 367 egr_db_shd, egr_qe_shd, 368 post_update); 369 } 370 #endif 371 return SOC_E_INTERNAL; 372 } 373 374 /* 375 * Function to calculate reserved memory in Egress buffer 376 */ 377 int 378 soc_th_mmu_get_egr_rsvd (int unit, int pipe, int *egr_rsvd) 379 { 380 int port, phy_port, mmu_port, new_pipe, local_mmu_port; 381 int startq, to_cos, cos, count; 382 int qg_valid, use_qg_min; 383 soc_mem_t mem1 = INVALIDm, base_mem1 = INVALIDm; 384 soc_mem_t mem2 = INVALIDm, base_mem2 = INVALIDm; 385 soc_mem_t mem3 = INVALIDm, base_mem3 = INVALIDm; 386 soc_mem_t mem4 = INVALIDm, base_mem4 = INVALIDm; 387 mmu_thdo_q_to_qgrp_map_entry_t entry1; 388 mmu_thdu_config_qgroup_entry_t entry2; 389 mmu_thdu_config_queue_entry_t entry3; 390 mmu_thdm_db_queue_config_entry_t entry4; 391 soc_info_t *si= &SOC_INFO(unit); 392 soc_field_t qg_min_field = USE_QGROUP_MINf; 393 *egr_rsvd = 0; 394 if (pipe >= NUM_PIPE(unit)) { 395 return SOC_E_PARAM; 396 } 397 base_mem1 = MMU_THDU_Q_TO_QGRP_MAPm; 398 mem1 = SOC_MEM_UNIQUE_ACC(unit, base_mem1)[pipe]; 399 base_mem2 = MMU_THDU_CONFIG_QGROUPm; 400 mem2 = SOC_MEM_UNIQUE_ACC(unit, base_mem2)[pipe]; 401 base_mem3 = MMU_THDU_CONFIG_QUEUEm; 402 mem3 = SOC_MEM_UNIQUE_ACC(unit, base_mem3)[pipe]; 403 base_mem4 = MMU_THDM_DB_QUEUE_CONFIGm; 404 mem4 = SOC_MEM_UNIQUE_ACC(unit, base_mem4)[pipe]; 405 /*Loop for UC queue/qgroup Mins, excluding CPU and LB ports*/ 406 PBMP_ALL_ITER(unit, port) { 407 if (!(IS_CPU_PORT(unit, port)) && !(IS_LB_PORT(unit, port))) { 408 new_pipe = si->port_pipe[port]; 409 if (pipe == new_pipe) { 410 /*Calculate qmin+qgroup_min for each port in the pipe*/ 411 phy_port = si->port_l2p_mapping[port]; 412 mmu_port = si->port_p2m_mapping[phy_port]; 413 local_mmu_port = mmu_port & (SOC_TH_MMU_PORT_STRIDE - 1); 414 startq = si->port_uc_cosq_base[port]; 415 count = si->port_num_cosq[port]; 416 to_cos = startq + count; 417 /*Loop for qgroup min; add if atleast one queue uses 418 *qgroup min and break 419 */ 420 for (cos = startq; cos < to_cos; cos++) { 421 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem1, 422 MEM_BLOCK_ALL, cos, &entry1)); 423 qg_valid = soc_mem_field32_get(unit, mem1, &entry1, 424 QGROUP_VALIDf); 425 use_qg_min = soc_mem_field32_get(unit, mem1, &entry1, 426 qg_min_field); 427 if ((qg_valid == 1) && (use_qg_min ==1)) { 428 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem2, MEM_BLOCK_ALL, 429 local_mmu_port, &entry2)); 430 *egr_rsvd += soc_mem_field32_get(unit, mem2, &entry2, 431 Q_MIN_LIMIT_CELLf); 432 break; 433 } 434 } 435 /*loop for qmin; check all queues and add queue mins*/ 436 for (cos = startq; cos < to_cos; cos++) { 437 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem1, MEM_BLOCK_ALL, 438 cos, &entry1)); 439 qg_valid = soc_mem_field32_get(unit, mem1, &entry1, 440 QGROUP_VALIDf); 441 use_qg_min = soc_mem_field32_get(unit, mem1, &entry1, 442 qg_min_field); 443 if ((qg_valid == 0) || (use_qg_min ==0)) { 444 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem3, 445 MEM_BLOCK_ALL,cos, &entry3)); 446 *egr_rsvd += soc_mem_field32_get(unit, mem3, 447 &entry3, Q_MIN_LIMIT_CELLf); 448 } 449 } 450 } 451 } 452 } 453 /*Loop for MC queue Mins, including CPU and LB ports*/ 454 PBMP_ALL_ITER(unit, port) { 455 new_pipe = si->port_pipe[port]; 456 if (pipe == new_pipe) { 457 /*Calculate qmin+qgroup_min for each port in the pipe*/ 458 phy_port = si->port_l2p_mapping[port]; 459 mmu_port = si->port_p2m_mapping[phy_port]; 460 local_mmu_port = mmu_port & (SOC_TH_MMU_PORT_STRIDE - 1); 461 startq = si->port_cosq_base[port]; 462 count = si->port_num_cosq[port]; 463 to_cos = startq + count; 464 /*loop for MC qmin; check all queues and add queue mins*/ 465 for (cos = startq; cos < to_cos; cos++) { 466 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem4, MEM_BLOCK_ALL, 467 cos, &entry4)); 468 *egr_rsvd += soc_mem_field32_get(unit, mem4, &entry4, 469 Q_MIN_LIMITf); 470 } 471 } 472 } 473 return SOC_E_NONE; 474 } 475 476 /* 477 * Function to calculate the new value of egress shared limit 478 */ 479 int 480 soc_th_recalc_new_egress_shared_limit (int unit, int pipe, 481 int *new_shared_limit) 482 { 483 soc_info_t *si; 484 int lossless, asf_profile; 485 _soc_mmu_rsvd_buffer_t rsvd_buffer; 486 int asf_rsvd1 = 0, asf_rsvd2 = 0; 487 int egr_rsvd1 = 0, egr_rsvd2 = 0 ; 488 int xpe, pipe2 = 0, count, temp_val; 489 uint32 pipe_map; 490 si = &SOC_INFO(unit); 491 *new_shared_limit = 0; 492 /*Getting the second egress pipe which is part of same xpe as this pipe*/ 493 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 494 pipe_map = si->xpe_epipe_map[xpe]; 495 if (pipe_map & (1 << pipe)) { 496 count = 0; 497 while(pipe_map) { 498 temp_val = (pipe_map >> 1); 499 if ((temp_val != 0) && (count != pipe)) { 500 pipe2=count; 501 break; 502 } 503 count++; 504 } 505 } 506 } 507 508 if (SOC_IS_TOMAHAWKPLUS(unit)) { 509 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 510 SOC_TH_MMU_LOSSLESS_DEFAULT_DISABLE); 511 } else { 512 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 513 SOC_TH_MMU_LOSSLESS_DEFAULT_ENABLE); 514 } 515 516 asf_profile = soc_property_get(unit, spn_ASF_MEM_PROFILE, 517 _SOC_TH_ASF_MEM_PROFILE_SIMILAR); 518 soc_th_mmu_additional_buffer_reserve(unit, pipe, si->flex_eligible, 519 lossless, asf_profile, 520 &rsvd_buffer); 521 asf_rsvd1 = rsvd_buffer.asf_rsvd_cells; 522 soc_th_mmu_additional_buffer_reserve(unit, pipe2, si->flex_eligible, 523 lossless, asf_profile, 524 &rsvd_buffer); 525 asf_rsvd2 = rsvd_buffer.asf_rsvd_cells; 526 soc_th_mmu_get_egr_rsvd (unit, pipe, &egr_rsvd1); 527 soc_th_mmu_get_egr_rsvd (unit, pipe2, &egr_rsvd2); 528 *new_shared_limit = _TH_MMU_TOTAL_CELLS_PER_XPE - asf_rsvd1 - 529 egr_rsvd1 -egr_rsvd2 - asf_rsvd2 - (_TH_MMU_NUM_RQE_QUEUES * 8); 530 LOG_INFO(BSL_LS_SOC_MMU, 531 (BSL_META_U(unit, 532 "MMU buffer recal: asf_rsvd1: %d egr_rsvd1: %d new_shared_limit: %d\n"), 533 asf_rsvd1, egr_rsvd1, *new_shared_limit)); 534 return SOC_E_NONE; 535 } 536 537 #endif /* BCM_TOMAHAWK_SUPPORT */