qos.c (22616B)
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 * All Rights Reserved.$ 7 * 8 * QoS module 9 */ 10 #include <soc/defs.h> 11 #include <shared/bsl.h> 12 #include <assert.h> 13 14 #include <sal/core/libc.h> 15 #include <shared/util.h> 16 #include <soc/cm.h> 17 #include <soc/drv.h> 18 #include <soc/scache.h> 19 #include <bcm/qos.h> 20 #include <bcm/error.h> 21 #include <bcm_int/esw/triumph2.h> 22 #include <bcm_int/esw/qos.h> 23 24 #if defined(BCM_TRIUMPH3_SUPPORT) 25 #include <bcm_int/esw/triumph3.h> 26 #endif /* BCM_TRIUMPH3_SUPPORT */ 27 28 #include <bcm_int/esw/triumph.h> 29 #include <bcm_int/esw/port.h> 30 #include <bcm_int/esw/firebolt.h> 31 #include <bcm_int/esw/trx.h> 32 #include <bcm_int/esw/virtual.h> 33 #include <bcm_int/esw/xgs3.h> 34 #include <bcm_int/esw_dispatch.h> 35 #include <bcm_int/esw/switch.h> 36 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 37 #include <bcm_int/esw/mpls.h> 38 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 39 40 #define TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE 8 41 #define EGR_MPLS_COMBO_MAP_ENTRY_TOTAL TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE 42 #define EGR_OUTER_ZONE_TABLE_OFFSET 2 43 #define EGR_INNER_ZONE_TABLE_OFFSET 1 44 #define EGR_MPLS_EXP_MEM_TABLE_OFFSET 5 45 46 #define EGR_MPLS_PRI_ENTRY_TOTAL 1 47 #define EGR_MPLS_ZONE_ENTRY_TOTAL 4 48 #define EGR_MPLS_EXP_ENTRY_TOTAL 3 49 50 #ifdef BCM_TRIDENT3_SUPPORT 51 #define _BCM_QOS_PROFILE_ENTRIES_PER_SET 64 52 53 soc_mem_t egr_mpls_combo_map_info[BCM_MAX_NUM_UNITS][EGR_MPLS_COMBO_MAP_ENTRY_TOTAL]; 54 int egr_mpls_combo_map_entry_total[BCM_MAX_NUM_UNITS]; 55 56 void bcm_td3_egr_mpls_combo_map_info_init(uint32 unit) 57 { 58 if (SOC_IS_TRIDENT3X(unit)) { 59 egr_mpls_combo_map_entry_total[unit] = TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE; 60 egr_mpls_combo_map_info[unit][0] = EGR_MPLS_PRI_MAPPINGm; 61 egr_mpls_combo_map_info[unit][1] = EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m; 62 egr_mpls_combo_map_info[unit][2] = EGR_ZONE_3_DOT1P_MAPPING_TABLE_4m; 63 egr_mpls_combo_map_info[unit][3] = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m; 64 egr_mpls_combo_map_info[unit][4] = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m; 65 egr_mpls_combo_map_info[unit][5] = EGR_MPLS_EXP_MAPPING_1m; 66 egr_mpls_combo_map_info[unit][6] = EGR_MPLS_EXP_MAPPING_2m; 67 egr_mpls_combo_map_info[unit][7] = EGR_MPLS_EXP_MAPPING_3m; 68 } 69 } 70 71 void bcm_td3_egr_mpls_combo_create_zone_entry(int unit, 72 soc_mem_t mem, 73 int mems_cnt, 74 int *mem_words, 75 soc_mem_t *mems) 76 { 77 if (SOC_MEM_IS_VALID(unit, mem)) { 78 *(mems + mems_cnt) = mem; 79 /* Since Zone memory are the same, we use first one as template */ 80 if (EGR_MPLS_PRI_MAPPINGm == mem) { 81 *(mem_words + mems_cnt) = sizeof(egr_mpls_pri_mapping_entry_t) / 82 sizeof(uint32); 83 } else if ((EGR_MPLS_EXP_MAPPING_1m == mem) || 84 (EGR_MPLS_EXP_MAPPING_2m == mem) || 85 (EGR_MPLS_EXP_MAPPING_3m == mem)) { 86 *(mem_words + mems_cnt) = sizeof(egr_mpls_exp_mapping_1_entry_t) / 87 sizeof(uint32); 88 } else { 89 /* Those entry share the same size */ 90 *(mem_words + mems_cnt) = sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t) / 91 sizeof(uint32); 92 } 93 } 94 } 95 96 int bcm_td3_combo_entry_size(int unit, 97 soc_mem_t mem) 98 { 99 int mem_size = 0; 100 101 if (SOC_MEM_IS_VALID(unit, mem)) { 102 /* Since Zone memory are the same, we use first one as template */ 103 if (EGR_MPLS_PRI_MAPPINGm == mem) { 104 mem_size = sizeof(egr_mpls_pri_mapping_entry_t); 105 } else if ((EGR_MPLS_EXP_MAPPING_1m == mem) || 106 (EGR_MPLS_EXP_MAPPING_2m == mem) || 107 (EGR_MPLS_EXP_MAPPING_3m == mem)) { 108 mem_size = sizeof(egr_mpls_exp_mapping_1_entry_t); 109 } else { 110 /* Those entry share the same size */ 111 mem_size = sizeof(egr_zone_3_dot1p_mapping_table_3_entry_t); 112 } 113 } 114 115 return mem_size; 116 } 117 118 void bcm_td3_egr_mpls_map_entry_default(int unit, soc_mem_t mem, uint32 *map_buf, uint32 entry_size) 119 { 120 int int_pri; 121 int cng; 122 uint32 *buf; 123 124 if ((EGR_MPLS_EXP_MAPPING_1m == mem) || 125 (EGR_MPLS_EXP_MAPPING_2m == mem) || 126 (EGR_MPLS_EXP_MAPPING_3m == mem)) { 127 /* Those 3 memory don't need default */ 128 return; 129 } 130 131 if (SOC_MEM_IS_VALID(unit, mem)) { 132 for (int_pri = 0; int_pri < 16; int_pri++) { 133 for (cng = 0; cng < 4; cng++) { 134 /* This loops altogher 6 bits - yet we only support up to 4 bits */ 135 buf = (uint32 *)((char *)map_buf + (((int_pri << 2) | cng) * entry_size)); 136 if (EGR_MPLS_PRI_MAPPINGm == mem) { 137 soc_mem_field32_set(unit, mem, buf, NEW_PRIf, int_pri > 7? 7: int_pri); 138 soc_mem_field32_set(unit, mem, buf, NEW_CFIf, cng > 1?1:cng); 139 } else { 140 soc_mem_field32_set(unit, mem, buf, PRIf, int_pri > 7? 7: int_pri); 141 soc_mem_field32_set(unit, mem, buf, CFIf, cng > 1?1:cng); 142 } 143 } 144 } 145 } 146 147 return; 148 } 149 150 int bcm_td3_egr_mpls_combo_map_create(uint32 unit, 151 int *egr_mpls_combo_map_created, 152 soc_profile_mem_t **egr_mpls_combo_map) 153 { 154 soc_mem_t mem; 155 soc_mem_t mems[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE]; 156 int mem_words[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE]; 157 int ix; 158 int rv = BCM_E_NONE; 159 160 if (NULL == *egr_mpls_combo_map) { 161 *egr_mpls_combo_map = sal_alloc(sizeof(soc_profile_mem_t), 162 "MPLS Combo Profile Mem"); 163 if (*egr_mpls_combo_map == NULL) { 164 return BCM_E_MEMORY; 165 } 166 soc_profile_mem_t_init(*egr_mpls_combo_map); 167 168 /* Prevent entries from moving around in the tables */ 169 (*egr_mpls_combo_map)->flags = SOC_PROFILE_MEM_F_NO_SHARE; 170 171 for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) { 172 /* First memory entry of the combo */ 173 mem = egr_mpls_combo_map_info[unit][ix]; /* Read out mem ID from book keeping info */ 174 bcm_td3_egr_mpls_combo_create_zone_entry(unit, mem, ix, mem_words, mems); 175 } 176 177 rv = soc_profile_mem_create(unit, mems, mem_words, egr_mpls_combo_map_entry_total[unit], 178 *egr_mpls_combo_map); 179 if (BCM_FAILURE(rv)) { 180 sal_free(*egr_mpls_combo_map); 181 return rv; 182 } 183 *egr_mpls_combo_map_created = TRUE; 184 } 185 186 return rv; 187 } 188 189 int bcm_td3_egr_mpls_combo_map_default(uint32 unit) 190 { 191 soc_mem_t mem; 192 int ix; 193 int rv = BCM_E_NONE; 194 void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE]; 195 uint32 index; 196 uint32 *map_buf[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE] = {NULL}; 197 uint32 alloc_size; 198 uint32 entry_size; 199 200 for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) { 201 /* First memory entry of the combo */ 202 mem = egr_mpls_combo_map_info[unit][ix]; /* Read out mem ID from book keeping info */ 203 entry_size = bcm_td3_combo_entry_size(unit, mem); 204 alloc_size = entry_size * _BCM_QOS_PROFILE_ENTRIES_PER_SET; 205 206 map_buf[ix] = sal_alloc(alloc_size, "TD3 EGR MPLS map"); 207 if (map_buf[ix] == NULL) { 208 rv = BCM_E_MEMORY; 209 goto cleanup; 210 } 211 sal_memset(map_buf[ix], 0, alloc_size); 212 bcm_td3_egr_mpls_map_entry_default(unit, mem, map_buf[ix], entry_size); 213 entries[ix] = (void *)map_buf[ix]; 214 } 215 216 rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries, 217 _BCM_QOS_PROFILE_ENTRIES_PER_SET, &index); 218 219 cleanup: 220 for (ix=0; ix < egr_mpls_combo_map_entry_total[unit]; ix++) { 221 if (map_buf[ix] != NULL) { 222 sal_free(map_buf[ix]); 223 } 224 } 225 226 return rv; 227 } 228 229 230 int bcm_td3_egr_mpls_combo_dump(int unit, soc_profile_mem_t *mpls_profile) 231 { 232 egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 233 egr_zone_1_dot1p_mapping_table_1_entry_t egr_mpls_zone_map[4][_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 234 egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map[3][_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 235 int ix, jx; 236 void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE]; 237 int pri, cfi, exp, new_pri, new_cfi; 238 soc_mem_t mem; 239 int num_entries; 240 int rv = BCM_E_NONE; 241 int entries_per_set; 242 int ref_count; 243 244 mem = EGR_MPLS_PRI_MAPPINGm; 245 num_entries = soc_mem_index_count(unit, mem); 246 247 LOG_CLI((BSL_META_U(unit, 248 " EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAP & EGR ZONE_1/3 PRI Combo Mem\n"))); 249 LOG_CLI((BSL_META_U(unit, 250 " Number of entries: %d\n"), num_entries)); 251 LOG_CLI((BSL_META_U(unit, 252 " Index RefCount EntriesPerSet - PRI CFI MPLS_EXP\n"))); 253 254 for (jx = 0; jx < num_entries; 255 jx += _BCM_QOS_PROFILE_ENTRIES_PER_SET) { 256 rv = soc_profile_mem_ref_count_get(unit, 257 mpls_profile, 258 jx, &ref_count); 259 if (SOC_FAILURE(rv)) { 260 LOG_CLI((BSL_META_U(unit, 261 " *** Error retrieving profile reference: %d ***\n"), rv)); 262 break; 263 } 264 265 if (ref_count <= 0) { 266 continue; 267 } 268 269 /* Add new chunk and store new HW index */ 270 entries[0] = &egr_mpls_pri_map; 271 /* 4 DOT1P zone entry */ 272 for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 273 entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = &egr_mpls_zone_map[ix]; 274 } 275 276 /* 3 MPLS EXP entry */ 277 for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 278 entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = &egr_mpls_exp_map[ix]; 279 } 280 281 rv = soc_profile_mem_get(unit, mpls_profile, 282 jx, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries); 283 if (SOC_FAILURE(rv)) { 284 LOG_CLI((BSL_META_U(unit, 285 " *** Error retrieving profile data: %d ***\n"), rv)); 286 break; 287 } 288 289 for (ix = 0; ix < _BCM_QOS_PROFILE_ENTRIES_PER_SET; ix++) { 290 entries_per_set = mpls_profile->tables[0].entries[jx+ix].entries_per_set; 291 292 new_pri = soc_mem_field32_get(unit, EGR_MPLS_PRI_MAPPINGm, 293 &(egr_mpls_pri_map[ix]), 294 NEW_PRIf); 295 new_cfi = soc_mem_field32_get(unit, EGR_MPLS_PRI_MAPPINGm, 296 &(egr_mpls_pri_map[ix]), 297 NEW_CFIf); 298 cfi = -1; 299 pri = -1; 300 exp = -1; 301 302 cfi = soc_mem_field32_get(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m, 303 &(egr_mpls_zone_map[0][ix]), 304 CFIf); 305 pri = soc_mem_field32_get(unit, EGR_ZONE_3_DOT1P_MAPPING_TABLE_3m, 306 &(egr_mpls_zone_map[0][ix]), 307 PRIf); 308 309 exp = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m, 310 &(egr_mpls_exp_map[0][ix]), 311 MPLS_EXPf); 312 LOG_CLI((BSL_META_U(unit, 313 " %5d %8d %13d %2d %2d %2d %2d %2d"), 314 ix + jx, ref_count, entries_per_set, 315 pri, cfi, new_pri, new_cfi, exp)); 316 LOG_CLI((BSL_META_U(unit, 317 "\n"))); 318 } 319 } 320 321 return rv; 322 } 323 324 325 int bcm_td3_l2_egr_combo_add(int unit, 326 uint32 flags, 327 bcm_qos_map_t *map, 328 int map_id, 329 uint32 *hw_idx, 330 uint32 entry_per_index) 331 { 332 egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map = NULL; 333 egr_zone_1_dot1p_mapping_table_1_entry_t *egr_mpls_zone_map[EGR_MPLS_ZONE_ENTRY_TOTAL]={NULL}; 334 egr_mpls_exp_mapping_1_entry_t *egr_mpls_exp_map[EGR_MPLS_EXP_ENTRY_TOTAL] = {NULL}; 335 int ix; 336 void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE], *entry; 337 int alloc_size, offset, cng, index; 338 int rv = BCM_E_NONE; 339 340 341 if (!((flags & BCM_QOS_MAP_L2) || 342 (flags & BCM_QOS_MAP_L2_INNER_TAG)|| 343 (flags & BCM_QOS_MAP_MPLS))|| 344 !(flags & BCM_QOS_MAP_EGRESS)) { 345 return BCM_E_PARAM; 346 } 347 348 if ((map->int_pri > 15) || (map->int_pri < 0) || 349 (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 350 ((map->color != bcmColorGreen) && 351 (map->color != bcmColorYellow) && 352 (map->color != bcmColorRed))) { 353 return BCM_E_PARAM; 354 } 355 356 if (flags & BCM_QOS_MAP_MPLS) { 357 if ((map->exp > 7) || (map->exp < 0)) { 358 return BCM_E_PARAM; 359 } 360 } 361 362 /* Base index of table in hardware */ 363 index = (*hw_idx * entry_per_index); 364 365 /* We total have 64 entries, based on the given CNG and PRI, 366 * Map to only one of them */ 367 /* Offset within table */ 368 cng = _BCM_COLOR_ENCODING(unit, map->color); 369 offset = (map->int_pri << 2) | cng; 370 371 /* Allocate memory for DMA */ 372 /* For table EGR_MPLS_PRI_MAP */ 373 alloc_size = (entry_per_index * sizeof(egr_mpls_pri_mapping_entry_t)); 374 egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size, 375 "TD3 egr mpls pri map"); 376 if (NULL == egr_mpls_pri_map) { 377 return (BCM_E_MEMORY); 378 } 379 380 sal_memset(egr_mpls_pri_map, 0, alloc_size); 381 382 /* Read the old profile chunk */ 383 rv = soc_mem_read_range(unit, EGR_MPLS_PRI_MAPPINGm, MEM_BLOCK_ANY, 384 index, 385 (index + (entry_per_index -1)), 386 egr_mpls_pri_map); 387 if (BCM_FAILURE(rv)) { 388 goto cleanup; 389 } 390 391 /* Modify what's needed for EGR_MPLS_PRI_MAPPINGm */ 392 entry = &egr_mpls_pri_map[offset]; 393 soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry, 394 NEW_PRIf, map->pkt_pri); 395 soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry, 396 NEW_CFIf, map->pkt_cfi); 397 398 399 /* For table 400 * EGR_ZONE_3_DOT1P_MAPPING_TABLE_3/4 401 * EGR_ZONE_1_DOT1P_MAPPING_TABLE_3/4 402 */ 403 for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 404 /* Allocate memory */ 405 alloc_size = (entry_per_index * 406 sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t)); 407 egr_mpls_zone_map[ix] = soc_cm_salloc(unit, alloc_size, 408 "TD3 egr mpls zone map"); 409 if (NULL == egr_mpls_zone_map[ix]) { 410 goto cleanup; 411 } 412 sal_memset(egr_mpls_zone_map[ix], 0, alloc_size); 413 414 /* Read out old entry */ 415 if (SOC_MEM_IS_VALID(unit, egr_mpls_combo_map_info[unit][ix+EGR_INNER_ZONE_TABLE_OFFSET])) { 416 rv = soc_mem_read_range(unit, egr_mpls_combo_map_info[unit][ix+EGR_INNER_ZONE_TABLE_OFFSET], 417 MEM_BLOCK_ANY, 418 index, 419 (index + (entry_per_index -1)), 420 egr_mpls_zone_map[ix]); 421 if (BCM_FAILURE(rv)) { 422 goto cleanup; 423 } 424 } 425 426 /* We combo inner and outer tag in one profile - so set them the same */ 427 entry = &egr_mpls_zone_map[ix][offset]; 428 soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+1], entry, 429 PRIf, map->pkt_pri); 430 soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+1], entry, 431 CFIf, map->pkt_cfi); 432 } 433 434 for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 435 /* Allocate memory */ 436 alloc_size = (entry_per_index * 437 sizeof(egr_mpls_exp_mapping_1_entry_t)); 438 egr_mpls_exp_map[ix] = soc_cm_salloc(unit, alloc_size, 439 "TD3 egr mpls exp map"); 440 if (NULL == egr_mpls_exp_map[ix]) { 441 goto cleanup; 442 } 443 sal_memset(egr_mpls_exp_map[ix], 0, alloc_size); 444 445 /* Read out old entry */ 446 if (SOC_MEM_IS_VALID(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET])) { 447 rv = soc_mem_read_range(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET], 448 MEM_BLOCK_ANY, 449 index, 450 (index + (entry_per_index -1)), 451 egr_mpls_exp_map[ix]); 452 if (BCM_FAILURE(rv)) { 453 goto cleanup; 454 } 455 } 456 457 /* Modify entry */ 458 entry = &egr_mpls_exp_map[ix][offset]; 459 if (flags & BCM_QOS_MAP_MPLS) { 460 soc_mem_field32_set(unit, egr_mpls_combo_map_info[unit][ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET], 461 entry, MPLS_EXPf, map->exp); 462 } 463 } 464 465 /* Delete the old profile chunk */ 466 rv = _bcm_egr_mpls_combo_map_entry_delete(unit, index); 467 if (BCM_FAILURE(rv)) { 468 goto cleanup; 469 } 470 471 /* Add new chunk and store new HW index */ 472 entries[0] = egr_mpls_pri_map; 473 for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 474 entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = egr_mpls_zone_map[ix]; 475 } 476 for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 477 entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = egr_mpls_exp_map[ix]; 478 } 479 rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries, 480 entry_per_index, 481 (uint32 *)&index); 482 if (BCM_FAILURE(rv)) { 483 goto cleanup; 484 } 485 486 *hw_idx = (index / entry_per_index); 487 488 cleanup: 489 /* Free the DMA memory */ 490 if (egr_mpls_pri_map != NULL) { 491 soc_cm_sfree(unit, egr_mpls_pri_map); 492 } 493 494 for (ix = 0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 495 if (egr_mpls_zone_map[ix] != NULL) { 496 soc_cm_sfree(unit, egr_mpls_zone_map[ix]); 497 } 498 } 499 for (ix = 0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 500 if (egr_mpls_exp_map[ix] != NULL) { 501 soc_cm_sfree(unit, egr_mpls_exp_map[ix]); 502 } 503 } 504 505 return rv; 506 } 507 508 int bcm_td3_qos_map_create(uint32 unit, uint32 *index, int entry_per_index) 509 { 510 egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map = NULL; 511 egr_zone_1_dot1p_mapping_table_1_entry_t *egr_mpls_zone_map[EGR_MPLS_ZONE_ENTRY_TOTAL] = {NULL}; 512 egr_mpls_exp_mapping_1_entry_t *egr_mpls_exp_map[EGR_MPLS_EXP_ENTRY_TOTAL]={NULL}; 513 int ix; 514 void *entries[TD3_EGR_MPLS_COMBO_MAP_ENTRY_SIZE]; 515 int rv = BCM_E_NONE; 516 int alloc_size; 517 518 /* Entries for EGR_MPLS_PRI_MAP */ 519 alloc_size = (entry_per_index * sizeof(egr_mpls_pri_mapping_entry_t)); 520 egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size, 521 "TD3 egr mpls pri map"); 522 if (NULL == egr_mpls_pri_map) { 523 return (BCM_E_MEMORY); 524 } 525 526 sal_memset(egr_mpls_pri_map, 0, alloc_size); 527 528 /* Entries for Zone 1 and Zone 3 table */ 529 for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 530 /* Allocate memory */ 531 alloc_size = (entry_per_index * 532 sizeof(egr_zone_1_dot1p_mapping_table_1_entry_t)); 533 egr_mpls_zone_map[ix] = soc_cm_salloc(unit, alloc_size, 534 "TD3 egr mpls zone map"); 535 if (NULL == egr_mpls_zone_map[ix]) { 536 goto cleanup; 537 } 538 sal_memset(egr_mpls_zone_map[ix], 0, alloc_size); 539 } 540 541 /* Entries for EGR_MPLS_EXP_MAPPING_1&2*/ 542 for (ix=0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 543 /* Allocate memory */ 544 alloc_size = (entry_per_index * 545 sizeof(egr_mpls_exp_mapping_1_entry_t)); 546 egr_mpls_exp_map[ix] = soc_cm_salloc(unit, alloc_size, 547 "TD3 egr mpls exp map"); 548 if (NULL == egr_mpls_exp_map[ix]) { 549 goto cleanup; 550 } 551 sal_memset(egr_mpls_exp_map[ix], 0, alloc_size); 552 } 553 554 /* Add new chunk and store new HW index */ 555 entries[0] = egr_mpls_pri_map; 556 for (ix=0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 557 entries[ix+EGR_INNER_ZONE_TABLE_OFFSET] = egr_mpls_zone_map[ix]; 558 } 559 for (ix=0; ix <EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 560 entries[ix+EGR_MPLS_EXP_MEM_TABLE_OFFSET] = egr_mpls_exp_map[ix]; 561 } 562 rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries, 563 entry_per_index, index); 564 if (BCM_FAILURE(rv)) { 565 goto cleanup; 566 } 567 return rv; 568 569 cleanup: 570 /* Free the DMA memory */ 571 if (egr_mpls_pri_map != NULL) { 572 soc_cm_sfree(unit, egr_mpls_pri_map); 573 } 574 575 for (ix = 0; ix < EGR_MPLS_ZONE_ENTRY_TOTAL; ix++) { 576 if (egr_mpls_zone_map[ix] != NULL) { 577 soc_cm_sfree(unit, egr_mpls_zone_map[ix]); 578 } 579 } 580 for (ix = 0; ix < EGR_MPLS_EXP_ENTRY_TOTAL; ix++) { 581 if (egr_mpls_exp_map[ix] != NULL) { 582 soc_cm_sfree(unit, egr_mpls_exp_map[ix]); 583 } 584 } 585 586 return rv; 587 } 588 589 /* 590 * Function: 591 * bcm_td3_qos_reinit 592 * Purpose: 593 * Initialize the TD2 QOS module for logics not covered by td2 and tr2. 594 * Parameters: 595 * unit - (IN) Unit being initialized 596 * Returns: 597 * BCM_E_XXX 598 */ 599 int bcm_td3_qos_reinit(int unit) 600 { 601 bcm_pbmp_t all_pbmp; 602 bcm_port_t port; 603 int index; 604 int rv = BCM_E_NONE; 605 606 /* Update reference counts for DSCP_TABLE profile, TD2 did it in cosq_reinit */ 607 BCM_PBMP_CLEAR(all_pbmp); 608 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 609 610 PBMP_ITER(all_pbmp, port) { 611 if (IS_LB_PORT(unit, port)) { 612 /* Loopback port base starts from 64 */ 613 continue; 614 } 615 616 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &index); 617 if (BCM_FAILURE(rv)) { 618 return rv; 619 } 620 621 SOC_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, index * 64, 622 64)); 623 } 624 625 return rv; 626 } 627 #endif /* End of BCM_TRIDENT3_SUPPORT */ 628