ecn.c (55574B)
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 * ECN - Broadcom StrataSwitch ECN API. 8 */ 9 10 #include <sal/core/libc.h> 11 #include <soc/defs.h> 12 13 #include <soc/drv.h> 14 #include <soc/mem.h> 15 #include <bcm/error.h> 16 17 #include <bcm/ecn.h> 18 #include <bcm/debug.h> 19 #include <bcm/error.h> 20 #include <bcm/switch.h> 21 #include <bcm_int/esw/ecn.h> 22 #include <bcm_int/esw/xgs3.h> 23 #include <bcm_int/esw/xgs5.h> 24 #include <bcm_int/esw_dispatch.h> 25 26 27 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 28 29 int 30 _bcm_esw_ecn_init(int unit) 31 { 32 responsive_protocol_match_entry_t entry_res_protocol; 33 ip_to_int_cn_mapping_entry_t entry_ip_int_cn; 34 int_cn_to_mmuif_mapping_entry_t entry_int_cn_mmuif; 35 egr_int_cn_update_entry_t entry_egr_int_cn_update; 36 egr_int_cn_to_ip_mapping_entry_t entry_egr_int_cn_ip_mapping; 37 int count, i; 38 uint32 fld_val; 39 uint64 fld64_val; 40 soc_mem_t cfg_mem = RESPONSIVE_PROTOCOL_MATCHm; 41 int table_adj = 1; 42 43 if (!SOC_WARM_BOOT(unit)) { 44 /* Responsive Protocol Match table */ 45 /* Set TCP(0x6) to 1 */ 46 COMPILER_64_ZERO(fld64_val); 47 COMPILER_64_SET(fld64_val, 0x0, (0x1 << 6)); 48 sal_memset(&entry_res_protocol, 0, sizeof(entry_res_protocol)); 49 soc_mem_field64_set(unit, RESPONSIVE_PROTOCOL_MATCHm, 50 &entry_res_protocol, RESPONSIVEf, fld64_val); 51 soc_mem_write(unit, RESPONSIVE_PROTOCOL_MATCHm, MEM_BLOCK_ALL, 52 0, (void *)&entry_res_protocol); 53 54 /* 55 * IP_TO_INT_CN_MAPPING table 56 Address (ECN + responsive) : INT_CN 57 0 2'b01 58 1 2'b00 59 2 2'b10 60 3 2'b10 61 4 2'b10 62 5 2'b10 63 6 2'b11 64 7 2'b11 65 */ 66 #if defined(BCM_TRIDENT3_SUPPORT) 67 if(SOC_IS_TRIDENT3X(unit)) { 68 cfg_mem = PKT_ECN_TO_INT_CN_MAPPINGm; 69 table_adj = 8; 70 71 count = soc_mem_index_count(unit, cfg_mem); 72 count /= table_adj; 73 for (i = 0; i < count; i++) { 74 sal_memset(&entry_ip_int_cn, 0, sizeof(entry_ip_int_cn)); 75 switch (i) { 76 case 0: 77 fld_val = _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP; 78 break; 79 case 4: 80 fld_val = _BCM_ECN_INT_CN_RESPONSIVE_DROP; 81 break; 82 case 3: 83 case 7: 84 fld_val = _BCM_ECN_INT_CN_CONGESTION_MARK_ECN; 85 break; 86 default: 87 fld_val = _BCM_ECN_INT_CN_NON_CONGESTION_MARK_ECN; 88 break; 89 } 90 soc_mem_field32_set(unit, cfg_mem, 91 &entry_ip_int_cn, INT_CNf, fld_val); 92 soc_mem_write(unit, cfg_mem, MEM_BLOCK_ALL, 93 i, (void *)&entry_ip_int_cn); 94 } 95 } else 96 #endif 97 { 98 cfg_mem = IP_TO_INT_CN_MAPPINGm; 99 table_adj = 1; 100 101 count = soc_mem_index_count(unit, cfg_mem); 102 count /= table_adj; 103 for (i = 0; i < count; i++) { 104 sal_memset(&entry_ip_int_cn, 0, sizeof(entry_ip_int_cn)); 105 switch (i) { 106 case 0: 107 fld_val = _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP; 108 break; 109 case 1: 110 fld_val = _BCM_ECN_INT_CN_RESPONSIVE_DROP; 111 break; 112 case 6: 113 case 7: 114 fld_val = _BCM_ECN_INT_CN_CONGESTION_MARK_ECN; 115 break; 116 default: 117 fld_val = _BCM_ECN_INT_CN_NON_CONGESTION_MARK_ECN; 118 break; 119 } 120 soc_mem_field32_set(unit, cfg_mem, 121 &entry_ip_int_cn, INT_CNf, fld_val); 122 soc_mem_write(unit, cfg_mem, MEM_BLOCK_ALL, 123 i, (void *)&entry_ip_int_cn); 124 } 125 } 126 127 128 /* INT_CN_TO_MMUIF_MAPPING */ 129 count = soc_mem_index_count(unit, INT_CN_TO_MMUIF_MAPPINGm); 130 for (i = 0; i < count; i++) { 131 sal_memset(&entry_int_cn_mmuif, 0, sizeof(entry_int_cn_mmuif)); 132 switch (i) { 133 case _BCM_ECN_INT_CN_RESPONSIVE_DROP: 134 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 135 &entry_int_cn_mmuif, WRED_RESPONSIVEf, 1); 136 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 137 &entry_int_cn_mmuif, WRED_MARK_ELIGIBLEf, 0); 138 break; 139 case _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP: 140 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 141 &entry_int_cn_mmuif, WRED_RESPONSIVEf, 0); 142 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 143 &entry_int_cn_mmuif, WRED_MARK_ELIGIBLEf, 0); 144 break; 145 case _BCM_ECN_INT_CN_CONGESTION_MARK_ECN: 146 case _BCM_ECN_INT_CN_NON_CONGESTION_MARK_ECN: 147 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 148 &entry_int_cn_mmuif, WRED_RESPONSIVEf, 1); 149 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 150 &entry_int_cn_mmuif, WRED_MARK_ELIGIBLEf, 1); 151 break; 152 default: 153 break; 154 } 155 soc_mem_write(unit, INT_CN_TO_MMUIF_MAPPINGm, MEM_BLOCK_ALL, 156 i, (void *)&entry_int_cn_mmuif); 157 } 158 159 /* EGR_INT_CN_UPDATE */ 160 #if defined(BCM_TRIDENT3_SUPPORT) 161 if(SOC_IS_TRIDENT3X(unit)) { 162 /* In TD3, CE_R & CE_Y & CE_G is replaced by CE. */ 163 count = soc_mem_index_count(unit, EGR_INT_CN_UPDATEm); 164 for (i = 0; i < count; i++) { 165 sal_memset(&entry_egr_int_cn_update, 0, 166 sizeof(entry_egr_int_cn_update)); 167 if (i < 0x8) { 168 /* INT_CN == 0 */ 169 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 170 &entry_egr_int_cn_update, INT_CNf, 171 _BCM_ECN_INT_CN_RESPONSIVE_DROP); 172 } else if (i < 0x10) { 173 /* INT_CN == 1 */ 174 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 175 &entry_egr_int_cn_update, INT_CNf, 176 _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP); 177 } else if (i < 0x18) { 178 /* INT_CN == 2 */ 179 /* Change the INT_CN to 3 if local MMU is congested */ 180 if (i & (1 << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_OFFSET_TD3)) { 181 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 182 &entry_egr_int_cn_update, INT_CNf, 183 _BCM_ECN_INT_CN_CONGESTION_MARK_ECN); 184 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 185 &entry_egr_int_cn_update, CONGESTION_MARKEDf, 1); 186 } else { 187 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 188 &entry_egr_int_cn_update, INT_CNf, 189 _BCM_ECN_INT_CN_NON_CONGESTION_MARK_ECN); 190 } 191 } else { 192 /* INT_CN == 3 */ 193 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 194 &entry_egr_int_cn_update, INT_CNf, 195 _BCM_ECN_INT_CN_CONGESTION_MARK_ECN); 196 } 197 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 198 i, (void *)&entry_egr_int_cn_update); 199 } 200 }else 201 #endif 202 { 203 count = soc_mem_index_count(unit, EGR_INT_CN_UPDATEm); 204 for (i = 0; i < count; i++) { 205 sal_memset(&entry_egr_int_cn_update, 0, 206 sizeof(entry_egr_int_cn_update)); 207 if (i < 0x20) { 208 /* INT_CN == 0 */ 209 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 210 &entry_egr_int_cn_update, INT_CNf, 211 _BCM_ECN_INT_CN_RESPONSIVE_DROP); 212 } else if (i < 0x40) { 213 /* INT_CN == 1 */ 214 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 215 &entry_egr_int_cn_update, INT_CNf, 216 _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP); 217 } else if (i > 0x5f) { 218 /* INT_CN == 3 */ 219 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 220 &entry_egr_int_cn_update, INT_CNf, 221 _BCM_ECN_INT_CN_CONGESTION_MARK_ECN); 222 } else { 223 /* INT_CN == 2 */ 224 /* Change the INT_CN to 3 if local MMU is congested */ 225 switch (i) { 226 case 0x50: 227 case 0x54: 228 case 0x58: 229 case 0x5c: 230 case 0x4b: 231 case 0x4f: 232 case 0x5b: 233 case 0x5f: 234 case 0x45: 235 case 0x4d: 236 case 0x55: 237 case 0x5d: 238 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 239 &entry_egr_int_cn_update, INT_CNf, 240 _BCM_ECN_INT_CN_CONGESTION_MARK_ECN); 241 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 242 &entry_egr_int_cn_update, CONGESTION_MARKEDf, 1); 243 break; 244 default: 245 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 246 &entry_egr_int_cn_update, INT_CNf, 247 _BCM_ECN_INT_CN_NON_CONGESTION_MARK_ECN); 248 break; 249 } 250 } 251 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 252 i, (void *)&entry_egr_int_cn_update); 253 } 254 } 255 256 /* EGR_INT_CN_TO_IP_MAPPING */ 257 #if defined(BCM_TRIDENT3_SUPPORT) 258 if(SOC_IS_TRIDENT3X(unit)) { 259 cfg_mem = EGR_INT_CN_TO_PKT_ECN_MAPPINGm; 260 table_adj = 32; 261 } else 262 #endif 263 { 264 cfg_mem = EGR_INT_CN_TO_IP_MAPPINGm; 265 table_adj = 1; 266 } 267 count = soc_mem_index_count(unit, cfg_mem); 268 count /= table_adj; 269 for (i = 0; i < count; i++) { 270 sal_memset(&entry_egr_int_cn_ip_mapping, 0, 271 sizeof(entry_egr_int_cn_ip_mapping)); 272 273 /* Change the ECN value from 2'b01 or 2'b10 to 2'b11 for INT_CN is 3 */ 274 if ((i == 13) || (i == 14)) { 275 soc_mem_field32_set(unit, cfg_mem, 276 &entry_egr_int_cn_ip_mapping, CHANGE_PACKET_ECNf, 1); 277 soc_mem_field32_set(unit, cfg_mem, 278 &entry_egr_int_cn_ip_mapping, ECNf, 3); 279 soc_mem_field32_set(unit, cfg_mem, 280 &entry_egr_int_cn_ip_mapping, INCREMENT_ECN_COUNTERf, 1); 281 } 282 soc_mem_write(unit, cfg_mem, MEM_BLOCK_ALL, 283 i, (void *)&entry_egr_int_cn_ip_mapping); 284 } 285 /* 286 * Configure the int_cn of Non-IP packets to Non-Responsive Dropping. 287 */ 288 BCM_IF_ERROR_RETURN( 289 bcm_esw_switch_control_set(unit, 290 bcmSwitchEcnNonIpIntCongestionNotification, 291 _BCM_ECN_INT_CN_NON_RESPONSIVE_DROP)); 292 } 293 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(INCLUDE_L3) 294 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 295 BCM_IF_ERROR_RETURN(bcmi_xgs5_ecn_init(unit)); 296 } 297 #endif 298 return BCM_E_NONE; 299 } 300 301 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 302 303 /* 304 * Function: 305 * bcm_esw_ecn_responsive_protocol_get 306 * Purpose: 307 * To get the value of responsive indication based on the IP protocol value. 308 * Parameters: 309 * unit - (IN) Unit number. 310 * ip_proto - (IN) IP Protocol value. 311 * responsice - (OUT) Responsice indication. 312 * Returns: 313 * BCM_E_XXX 314 * Notes: 315 */ 316 int bcm_esw_ecn_responsive_protocol_get( 317 int unit, uint8 ip_proto, int *responsive) 318 { 319 320 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 321 uint64 fld64_val; 322 int mem_idx, field_offset; 323 responsive_protocol_match_entry_t entry_res_protocol; 324 325 if (!soc_feature(unit, soc_feature_ecn_wred)) { 326 return BCM_E_UNAVAIL; 327 } 328 329 COMPILER_64_ZERO(fld64_val); 330 mem_idx = ip_proto / 64; 331 field_offset = ip_proto % 64; 332 333 sal_memset(&entry_res_protocol, 0, sizeof(entry_res_protocol)); 334 BCM_IF_ERROR_RETURN( 335 soc_mem_read(unit, RESPONSIVE_PROTOCOL_MATCHm, MEM_BLOCK_ALL, 336 mem_idx, (void *)&entry_res_protocol)); 337 soc_mem_field64_get(unit, RESPONSIVE_PROTOCOL_MATCHm, 338 &entry_res_protocol, RESPONSIVEf, &fld64_val); 339 340 if (COMPILER_64_BITTEST(fld64_val, field_offset)) { 341 *responsive = TRUE; 342 } else { 343 *responsive = FALSE; 344 } 345 346 return BCM_E_NONE; 347 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 348 return BCM_E_UNAVAIL; 349 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 350 351 } 352 353 354 /* 355 * Function: 356 * bcm_esw_ecn_responsive_protocol_get 357 * Purpose: 358 * To configure the value of responsive indication based on the IP protocol value. 359 * Parameters: 360 * unit - (IN) Unit number. 361 * ip_proto - (IN) IP Protocol value. 362 * responsice - (IN) Responsice indication. 363 * Returns: 364 * BCM_E_XXX 365 * Notes: 366 */ 367 368 int bcm_esw_ecn_responsive_protocol_set( 369 int unit, uint8 ip_proto, int responsive) 370 { 371 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 372 uint64 fld64_val, val64; 373 int mem_idx, field_offset; 374 responsive_protocol_match_entry_t entry_res_protocol; 375 376 if (!soc_feature(unit, soc_feature_ecn_wred)) { 377 return BCM_E_UNAVAIL; 378 } 379 380 COMPILER_64_ZERO(fld64_val); 381 mem_idx = ip_proto / 64; 382 field_offset = ip_proto % 64; 383 384 sal_memset(&entry_res_protocol, 0, sizeof(entry_res_protocol)); 385 BCM_IF_ERROR_RETURN( 386 soc_mem_read(unit, RESPONSIVE_PROTOCOL_MATCHm, MEM_BLOCK_ALL, 387 mem_idx, (void *)&entry_res_protocol)); 388 soc_mem_field64_get(unit, RESPONSIVE_PROTOCOL_MATCHm, 389 &entry_res_protocol, RESPONSIVEf, &fld64_val); 390 391 COMPILER_64_ZERO(val64); 392 COMPILER_64_SET(val64, 0x0, 0x1); 393 COMPILER_64_SHL(val64, field_offset); 394 if (responsive) { 395 COMPILER_64_OR(fld64_val, val64); 396 } else { 397 COMPILER_64_NOT(val64); 398 COMPILER_64_AND(fld64_val, val64); 399 } 400 401 soc_mem_field64_set(unit, RESPONSIVE_PROTOCOL_MATCHm, 402 &entry_res_protocol, RESPONSIVEf, fld64_val); 403 BCM_IF_ERROR_RETURN( 404 soc_mem_write(unit, RESPONSIVE_PROTOCOL_MATCHm, MEM_BLOCK_ALL, 405 mem_idx, (void *)&entry_res_protocol)); 406 407 return BCM_E_NONE; 408 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 409 return BCM_E_UNAVAIL; 410 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 411 } 412 413 414 /* 415 * Function: 416 * bcm_esw_ecn_traffic_map_get 417 * Purpose: 418 * To get the mapped internal congestion notification (int_cn) value. 419 * Parameters: 420 * unit - (IN) Unit number. 421 * map - (INOUT) Internal congestion notification map. 422 * Returns: 423 * BCM_E_XXX 424 * Notes: 425 */ 426 427 int bcm_esw_ecn_traffic_map_get( 428 int unit, bcm_ecn_traffic_map_info_t *map) 429 { 430 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 431 int mem_idx; 432 ip_to_int_cn_mapping_entry_t entry_ip_int_cn; 433 uint32 fld_val; 434 soc_mem_t cfg_mem = 0; 435 436 if (!soc_feature(unit, soc_feature_ecn_wred)) { 437 return BCM_E_UNAVAIL; 438 } 439 440 if (map == NULL) { 441 return BCM_E_PARAM; 442 } 443 444 if (map->ecn > _BCM_ECN_VALUE_MAX) { 445 return BCM_E_PARAM; 446 } 447 448 /* Check supported flag */ 449 if ((map->flags & ~BCM_ECN_TRAFFIC_MAP_RESPONSIVE) != 0) { 450 return BCM_E_PARAM; 451 } 452 453 #if defined(BCM_TRIDENT3_SUPPORT) 454 if (SOC_IS_TRIDENT3X(unit)){ 455 cfg_mem = PKT_ECN_TO_INT_CN_MAPPINGm; 456 mem_idx = map->ecn; 457 if (map->flags & BCM_ECN_TRAFFIC_MAP_RESPONSIVE) { 458 /* mem_idx = (resp<<2) + ecn */ 459 mem_idx +=4; 460 } 461 } else 462 #endif 463 { 464 cfg_mem = IP_TO_INT_CN_MAPPINGm; 465 /* MEMORY INDEX : ECN + Responsive */ 466 mem_idx = (map->ecn << 1); 467 if (map->flags & BCM_ECN_TRAFFIC_MAP_RESPONSIVE) { 468 mem_idx++; 469 } 470 } 471 sal_memset(&entry_ip_int_cn, 0, sizeof(entry_ip_int_cn)); 472 473 BCM_IF_ERROR_RETURN( 474 soc_mem_read(unit, cfg_mem, MEM_BLOCK_ALL, 475 mem_idx, (void *)&entry_ip_int_cn)); 476 477 fld_val = soc_mem_field32_get(unit, cfg_mem, 478 &entry_ip_int_cn, INT_CNf); 479 480 map->int_cn = fld_val; 481 482 483 return BCM_E_NONE; 484 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 485 return BCM_E_UNAVAIL; 486 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 487 } 488 489 /* 490 * Function: 491 * bcm_esw_ecn_traffic_map_set 492 * Purpose: 493 * To set the mapped internal congestion notification (int_cn) value. 494 * Parameters: 495 * unit - (IN) Unit number. 496 * map - (INOUT) Internal congestion notification map. 497 * Returns: 498 * BCM_E_XXX 499 * Notes: 500 */ 501 int bcm_esw_ecn_traffic_map_set( 502 int unit, bcm_ecn_traffic_map_info_t *map) 503 { 504 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 505 int mem_idx; 506 ip_to_int_cn_mapping_entry_t entry_ip_int_cn; 507 uint32 fld_val; 508 soc_mem_t cfg_mem = 0; 509 510 if (!soc_feature(unit, soc_feature_ecn_wred)) { 511 return BCM_E_UNAVAIL; 512 } 513 514 if (map == NULL) { 515 return BCM_E_PARAM; 516 } 517 518 if (map->ecn > _BCM_ECN_VALUE_MAX) { 519 return BCM_E_PARAM; 520 } 521 522 if ((map->int_cn < 0) || (map->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 523 return BCM_E_PARAM; 524 } 525 526 #if defined(BCM_TRIDENT3_SUPPORT) 527 if (SOC_IS_TRIDENT3X(unit)){ 528 cfg_mem = PKT_ECN_TO_INT_CN_MAPPINGm; 529 mem_idx = map->ecn; 530 if (map->flags & BCM_ECN_TRAFFIC_MAP_RESPONSIVE) { 531 /* mem_idx = (resp<<2) + ecn */ 532 mem_idx += 4; 533 } 534 } else 535 #endif 536 { 537 /* MEMORY INDEX : ECN + Responsive */ 538 mem_idx = (map->ecn << 1); 539 if (map->flags & BCM_ECN_TRAFFIC_MAP_RESPONSIVE) { 540 mem_idx++; 541 } 542 543 cfg_mem = IP_TO_INT_CN_MAPPINGm; 544 } 545 546 sal_memset(&entry_ip_int_cn, 0, sizeof(entry_ip_int_cn)); 547 548 BCM_IF_ERROR_RETURN( 549 soc_mem_read(unit, cfg_mem, MEM_BLOCK_ALL, 550 mem_idx, (void *)&entry_ip_int_cn)); 551 552 fld_val = map->int_cn; 553 soc_mem_field32_set(unit, cfg_mem, 554 &entry_ip_int_cn, INT_CNf, fld_val); 555 556 BCM_IF_ERROR_RETURN( 557 soc_mem_write(unit, cfg_mem, MEM_BLOCK_ALL, 558 mem_idx, (void *)&entry_ip_int_cn)); 559 560 return BCM_E_NONE; 561 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 562 return BCM_E_UNAVAIL; 563 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 564 } 565 566 567 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 568 static int 569 _bcm_esw_ecn_action_enqueue_get(int unit, 570 bcm_ecn_traffic_action_config_t *ecn_config) 571 { 572 573 int_cn_to_mmuif_mapping_entry_t entry_int_cn_mmuif; 574 int mem_idx; 575 uint32 fld_val; 576 577 if ((ecn_config->int_cn < 0) || 578 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 579 return BCM_E_PARAM; 580 } 581 582 mem_idx = ecn_config->int_cn; 583 sal_memset(&entry_int_cn_mmuif, 0, sizeof(entry_int_cn_mmuif)); 584 585 BCM_IF_ERROR_RETURN( 586 soc_mem_read(unit, INT_CN_TO_MMUIF_MAPPINGm, MEM_BLOCK_ALL, 587 mem_idx, (void *)&entry_int_cn_mmuif)); 588 589 /* WRED RESPONSIVE */ 590 fld_val = soc_mem_field32_get(unit, INT_CN_TO_MMUIF_MAPPINGm, 591 &entry_int_cn_mmuif, WRED_RESPONSIVEf); 592 if (fld_val) { 593 ecn_config->action_flags |= 594 BCM_ECN_TRAFFIC_ACTION_ENQUEUE_WRED_RESPONSIVE; 595 } else { 596 ecn_config->action_flags &= 597 ~BCM_ECN_TRAFFIC_ACTION_ENQUEUE_WRED_RESPONSIVE; 598 } 599 600 /* MARK ELIGIBLE */ 601 fld_val = soc_mem_field32_get(unit, INT_CN_TO_MMUIF_MAPPINGm, 602 &entry_int_cn_mmuif, WRED_MARK_ELIGIBLEf); 603 if (fld_val) { 604 ecn_config->action_flags |= 605 BCM_ECN_TRAFFIC_ACTION_ENQUEUE_MARK_ELIGIBLE; 606 } else { 607 ecn_config->action_flags &= 608 ~BCM_ECN_TRAFFIC_ACTION_ENQUEUE_MARK_ELIGIBLE; 609 } 610 611 return BCM_E_NONE; 612 } 613 614 static int 615 _bcm_esw_ecn_action_enqueue_set(int unit, 616 bcm_ecn_traffic_action_config_t *ecn_config) 617 { 618 619 int_cn_to_mmuif_mapping_entry_t entry_int_cn_mmuif; 620 int mem_idx; 621 uint32 fld_val; 622 623 if ((ecn_config->int_cn < 0) || 624 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 625 return BCM_E_PARAM; 626 } 627 628 mem_idx = ecn_config->int_cn; 629 sal_memset(&entry_int_cn_mmuif, 0, sizeof(entry_int_cn_mmuif)); 630 631 BCM_IF_ERROR_RETURN( 632 soc_mem_read(unit, INT_CN_TO_MMUIF_MAPPINGm, MEM_BLOCK_ALL, 633 mem_idx, (void *)&entry_int_cn_mmuif)); 634 635 /* WRED RESPONSIVE */ 636 if (ecn_config->action_flags & 637 BCM_ECN_TRAFFIC_ACTION_ENQUEUE_WRED_RESPONSIVE) { 638 fld_val = 1; 639 } else { 640 fld_val = 0; 641 } 642 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 643 &entry_int_cn_mmuif, WRED_RESPONSIVEf, fld_val); 644 645 /* MARK ELIGIBLE */ 646 if (ecn_config->action_flags & 647 BCM_ECN_TRAFFIC_ACTION_ENQUEUE_MARK_ELIGIBLE) { 648 fld_val = 1; 649 } else { 650 fld_val = 0; 651 } 652 soc_mem_field32_set(unit, INT_CN_TO_MMUIF_MAPPINGm, 653 &entry_int_cn_mmuif, WRED_MARK_ELIGIBLEf, fld_val); 654 655 BCM_IF_ERROR_RETURN( 656 soc_mem_write(unit, INT_CN_TO_MMUIF_MAPPINGm, MEM_BLOCK_ALL, 657 mem_idx, (void *)&entry_int_cn_mmuif)); 658 659 return BCM_E_NONE; 660 } 661 662 static int 663 _bcm_esw_ecn_action_dequeue_get(int unit, 664 bcm_ecn_traffic_action_config_t *ecn_config) 665 { 666 int mem_idx, cng, ce_green, ce_yellow, ce_red, index_max; 667 egr_int_cn_update_entry_t entry_egr_int_cn_update; 668 uint32 fld_val; 669 #if defined(BCM_TRIDENT3_SUPPORT) 670 int ce = 0; 671 #endif 672 673 if ((ecn_config->color != bcmColorGreen) && 674 (ecn_config->color != bcmColorYellow) && 675 (ecn_config->color != bcmColorRed)) { 676 return BCM_E_PARAM; 677 } 678 679 if ((ecn_config->int_cn < 0) || 680 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 681 return BCM_E_PARAM; 682 } 683 684 /* 685 * Memory index : int_cn(2 bits)+ce_green+ce_yellow+ce_red+cng(2bit) 686 * Only the ce_[color] match the value of cng is meaningful. 687 */ 688 cng = _BCM_COLOR_ENCODING(unit, ecn_config->color); 689 index_max = soc_mem_index_max(unit, EGR_INT_CN_UPDATEm); 690 ce_green = 0; 691 ce_yellow = 0; 692 ce_red = 0; 693 694 #if defined(BCM_TRIDENT3_SUPPORT) 695 if(SOC_IS_TRIDENT3X(unit)) { 696 ce = 0; 697 mem_idx = 698 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET_TD3) 699 + (ce << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_OFFSET_TD3) 700 + (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 701 702 if (mem_idx > index_max) { 703 return BCM_E_PARAM; 704 } 705 706 sal_memset(&entry_egr_int_cn_update, 0, 707 sizeof(entry_egr_int_cn_update)); 708 /* Get the updated int_cn when congestion is not exprienced */ 709 BCM_IF_ERROR_RETURN( 710 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 711 mem_idx, (void *)&entry_egr_int_cn_update)); 712 fld_val = soc_mem_field32_get(unit, EGR_INT_CN_UPDATEm, 713 &entry_egr_int_cn_update, INT_CNf); 714 if (fld_val != ecn_config->int_cn) { 715 ecn_config->action_flags |= 716 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE; 717 ecn_config->non_congested_int_cn = fld_val; 718 } else { 719 ecn_config->action_flags &= 720 ~BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE; 721 } 722 723 /* Get the updated int_cn when congestion is exprienced */ 724 ce = 1; 725 mem_idx = 726 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET_TD3) 727 + (ce << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_OFFSET_TD3) 728 + (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 729 730 if (mem_idx > index_max) { 731 return BCM_E_PARAM; 732 } 733 sal_memset(&entry_egr_int_cn_update, 0, 734 sizeof(entry_egr_int_cn_update)); 735 BCM_IF_ERROR_RETURN( 736 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 737 mem_idx, (void *)&entry_egr_int_cn_update)); 738 fld_val = soc_mem_field32_get(unit, EGR_INT_CN_UPDATEm, 739 &entry_egr_int_cn_update, INT_CNf); 740 741 if (fld_val != ecn_config->int_cn) { 742 ecn_config->action_flags |= 743 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE; 744 ecn_config->congested_int_cn = fld_val; 745 } else { 746 ecn_config->action_flags &= 747 ~BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE; 748 } 749 } else 750 #endif 751 { 752 mem_idx = (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET) + 753 (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 754 755 if (mem_idx > index_max) { 756 return BCM_E_PARAM; 757 } 758 759 sal_memset(&entry_egr_int_cn_update, 0, 760 sizeof(entry_egr_int_cn_update)); 761 /* Get the updated int_cn when congestion is not exprienced */ 762 BCM_IF_ERROR_RETURN( 763 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 764 mem_idx, (void *)&entry_egr_int_cn_update)); 765 fld_val = soc_mem_field32_get(unit, EGR_INT_CN_UPDATEm, 766 &entry_egr_int_cn_update, INT_CNf); 767 if (fld_val != ecn_config->int_cn) { 768 ecn_config->action_flags |= 769 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE; 770 ecn_config->non_congested_int_cn = fld_val; 771 } else { 772 ecn_config->action_flags &= 773 ~BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE; 774 } 775 776 /* Get the updated int_cn when congestion is exprienced */ 777 if (ecn_config->color == bcmColorGreen) { 778 ce_green = 1; 779 } else if (ecn_config->color == bcmColorYellow) { 780 ce_yellow = 1; 781 } else { 782 /* Red */ 783 ce_red = 1; 784 } 785 786 mem_idx = (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET) + 787 (ce_green << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_GREEN_OFFSET) + 788 (ce_yellow << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_YELLOW_OFFSET) + 789 (ce_red << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_RED_OFFSET) + 790 (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 791 792 793 if (mem_idx > index_max) { 794 return BCM_E_PARAM; 795 } 796 sal_memset(&entry_egr_int_cn_update, 0, 797 sizeof(entry_egr_int_cn_update)); 798 799 BCM_IF_ERROR_RETURN( 800 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 801 mem_idx, (void *)&entry_egr_int_cn_update)); 802 fld_val = soc_mem_field32_get(unit, EGR_INT_CN_UPDATEm, 803 &entry_egr_int_cn_update, INT_CNf); 804 805 if (fld_val != ecn_config->int_cn) { 806 ecn_config->action_flags |= 807 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE; 808 ecn_config->congested_int_cn = fld_val; 809 } else { 810 ecn_config->action_flags &= 811 ~BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE; 812 } 813 } 814 ecn_config->responsive = soc_mem_field32_get(unit, EGR_INT_CN_UPDATEm, 815 &entry_egr_int_cn_update, 816 RESPONSIVEf); 817 return BCM_E_NONE; 818 819 } 820 821 822 static int 823 _bcm_esw_ecn_action_dequeue_set(int unit, 824 bcm_ecn_traffic_action_config_t *ecn_config) 825 { 826 int mem_idx, cng, ce_green, ce_yellow, ce_red, index_max; 827 egr_int_cn_update_entry_t entry_egr_int_cn_update; 828 uint32 fld_val; 829 #if defined(BCM_TRIDENT3_SUPPORT) 830 int ce = 0; 831 #endif 832 833 if ((ecn_config->color != bcmColorGreen) && 834 (ecn_config->color != bcmColorYellow) && 835 (ecn_config->color != bcmColorRed)) { 836 return BCM_E_PARAM; 837 } 838 839 if ((ecn_config->int_cn < 0) || 840 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 841 return BCM_E_PARAM; 842 } 843 844 /* 845 * Memory index : int_cn(2 bits)+ce_green+ce_yellow+ce_red+cng(2bit) 846 * Only the ce_[color] match the value of cng is meaningful. 847 */ 848 cng = _BCM_COLOR_ENCODING(unit, ecn_config->color); 849 index_max = soc_mem_index_max(unit, EGR_INT_CN_UPDATEm); 850 ce_green = 0; 851 ce_yellow = 0; 852 ce_red = 0; 853 854 #if defined(BCM_TRIDENT3_SUPPORT) 855 if(SOC_IS_TRIDENT3X(unit)) { 856 /* Update the int_cn value when congestion is not experienced */ 857 ce = 0; 858 mem_idx = 859 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET_TD3) 860 + (ce << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_OFFSET_TD3) 861 + (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 862 863 if (mem_idx > index_max) { 864 return BCM_E_PARAM; 865 } 866 sal_memset(&entry_egr_int_cn_update, 0, 867 sizeof(entry_egr_int_cn_update)); 868 BCM_IF_ERROR_RETURN( 869 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 870 mem_idx, (void *)&entry_egr_int_cn_update)); 871 if ((ecn_config->action_flags & 872 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE) && 873 (ecn_config->non_congested_int_cn != ecn_config->int_cn)) { 874 875 if ((ecn_config->non_congested_int_cn < 0) || 876 (ecn_config->non_congested_int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 877 return BCM_E_PARAM; 878 } 879 fld_val = ecn_config->non_congested_int_cn; 880 } else { 881 fld_val = ecn_config->int_cn; 882 } 883 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 884 &entry_egr_int_cn_update, INT_CNf, 885 fld_val); 886 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 887 &entry_egr_int_cn_update, RESPONSIVEf, 888 ecn_config->responsive ? 1 : 0); 889 890 BCM_IF_ERROR_RETURN( 891 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 892 mem_idx, (void *)&entry_egr_int_cn_update)); 893 894 895 /* Update the int_cn value when congestion is experienced */ 896 ce = 1; 897 mem_idx = 898 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET_TD3) 899 + (ce << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_OFFSET_TD3) 900 + (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 901 902 if (mem_idx > index_max) { 903 return BCM_E_PARAM; 904 } 905 sal_memset(&entry_egr_int_cn_update, 0, 906 sizeof(entry_egr_int_cn_update)); 907 908 BCM_IF_ERROR_RETURN( 909 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 910 mem_idx, (void *)&entry_egr_int_cn_update)); 911 if ((ecn_config->action_flags & 912 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE) && 913 (ecn_config->congested_int_cn != ecn_config->int_cn)) { 914 915 if ((ecn_config->congested_int_cn < 0) || 916 (ecn_config->congested_int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 917 return BCM_E_PARAM; 918 } 919 fld_val = ecn_config->congested_int_cn; 920 } else { 921 fld_val = ecn_config->int_cn; 922 } 923 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 924 &entry_egr_int_cn_update, INT_CNf, fld_val); 925 926 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 927 &entry_egr_int_cn_update, RESPONSIVEf, 928 ecn_config->responsive ? 1 : 0); 929 930 BCM_IF_ERROR_RETURN( 931 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 932 mem_idx, (void *)&entry_egr_int_cn_update)); 933 } else 934 #endif 935 { 936 /* Update the int_cn value when congestion is not experienced */ 937 for (ce_green = 0; ce_green < 2; ce_green++) { 938 if ((ecn_config->color == bcmColorGreen) && (ce_green == 1)) { 939 /* Bypass the congestion case */ 940 continue; 941 } 942 for (ce_yellow = 0; ce_yellow < 2; ce_yellow++) { 943 if ((ecn_config->color == bcmColorYellow) && (ce_yellow == 1)) { 944 /* Bypass the congestion case */ 945 continue; 946 } 947 for (ce_red = 0; ce_red < 2; ce_red++) { 948 if ((ecn_config->color == bcmColorRed) && (ce_red == 1)) { 949 /* Bypass the congestion case */ 950 continue; 951 } 952 mem_idx = 953 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET) + 954 (ce_green << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_GREEN_OFFSET) + 955 (ce_yellow << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_YELLOW_OFFSET) + 956 (ce_red << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_RED_OFFSET) + 957 (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 958 959 if (mem_idx > index_max) { 960 return BCM_E_PARAM; 961 } 962 sal_memset(&entry_egr_int_cn_update, 0, 963 sizeof(entry_egr_int_cn_update)); 964 BCM_IF_ERROR_RETURN( 965 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 966 mem_idx, (void *)&entry_egr_int_cn_update)); 967 if ((ecn_config->action_flags & 968 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE) && 969 (ecn_config->non_congested_int_cn != ecn_config->int_cn)) { 970 971 if ((ecn_config->non_congested_int_cn < 0) || 972 (ecn_config->non_congested_int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 973 return BCM_E_PARAM; 974 } 975 fld_val = ecn_config->non_congested_int_cn; 976 } else { 977 fld_val = ecn_config->int_cn; 978 } 979 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 980 &entry_egr_int_cn_update, INT_CNf, fld_val); 981 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 982 &entry_egr_int_cn_update, RESPONSIVEf, 983 ecn_config->responsive ? 1 : 0); 984 BCM_IF_ERROR_RETURN( 985 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 986 mem_idx, (void *)&entry_egr_int_cn_update)); 987 } 988 } 989 } 990 991 /* Update the int_cn value when congestion is experienced */ 992 for (ce_green = 0; ce_green < 2; ce_green++) { 993 if ((ecn_config->color == bcmColorGreen) && (ce_green == 0)) { 994 /* Bypass the non-congestion case */ 995 continue; 996 } 997 for (ce_yellow = 0; ce_yellow < 2; ce_yellow++) { 998 if ((ecn_config->color == bcmColorYellow) && (ce_yellow == 0)) { 999 /* Bypass the non-congestion case */ 1000 continue; 1001 } 1002 for (ce_red = 0; ce_red < 2; ce_red++) { 1003 if ((ecn_config->color == bcmColorRed) && (ce_red == 0)) { 1004 /* Bypass the non-congestion case */ 1005 continue; 1006 } 1007 mem_idx = 1008 (ecn_config->int_cn << _BCM_ECN_DEQUEUE_MEM_INDEX_INT_CN_OFFSET) + 1009 (ce_green << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_GREEN_OFFSET) + 1010 (ce_yellow << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_YELLOW_OFFSET) + 1011 (ce_red << _BCM_ECN_DEQUEUE_MEM_INDEX_CE_RED_OFFSET) + 1012 (cng << _BCM_ECN_DEQUEUE_MEM_INDEX_CNG_OFFSET); 1013 1014 if (mem_idx > index_max) { 1015 return BCM_E_PARAM; 1016 } 1017 sal_memset(&entry_egr_int_cn_update, 0, 1018 sizeof(entry_egr_int_cn_update)); 1019 1020 BCM_IF_ERROR_RETURN( 1021 soc_mem_read(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 1022 mem_idx, (void *)&entry_egr_int_cn_update)); 1023 if ((ecn_config->action_flags & 1024 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE) && 1025 (ecn_config->congested_int_cn != ecn_config->int_cn)) { 1026 1027 if ((ecn_config->congested_int_cn < 0) || 1028 (ecn_config->congested_int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 1029 return BCM_E_PARAM; 1030 } 1031 fld_val = ecn_config->congested_int_cn; 1032 } else { 1033 fld_val = ecn_config->int_cn; 1034 } 1035 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 1036 &entry_egr_int_cn_update, INT_CNf, fld_val); 1037 soc_mem_field32_set(unit, EGR_INT_CN_UPDATEm, 1038 &entry_egr_int_cn_update, RESPONSIVEf, 1039 ecn_config->responsive ? 1 : 0); 1040 BCM_IF_ERROR_RETURN( 1041 soc_mem_write(unit, EGR_INT_CN_UPDATEm, MEM_BLOCK_ALL, 1042 mem_idx, (void *)&entry_egr_int_cn_update)); 1043 } 1044 } 1045 } 1046 } 1047 return BCM_E_NONE; 1048 1049 } 1050 1051 1052 static int 1053 _bcm_esw_ecn_action_egress_get(int unit, 1054 bcm_ecn_traffic_action_config_t *ecn_config) 1055 { 1056 int mem_idx, index_max; 1057 egr_int_cn_to_ip_mapping_entry_t entry_egr_int_cn_ip_mapping; 1058 uint32 fld_val; 1059 soc_mem_t cfg_mem = 0; 1060 1061 if ((ecn_config->int_cn < 0) || 1062 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 1063 return BCM_E_PARAM; 1064 } 1065 1066 if (ecn_config->ecn > _BCM_ECN_VALUE_MAX) { 1067 return BCM_E_PARAM; 1068 } 1069 #if defined(BCM_TRIDENT3_SUPPORT) 1070 if(SOC_IS_TRIDENT3X(unit)){ 1071 cfg_mem = EGR_INT_CN_TO_PKT_ECN_MAPPINGm; 1072 } else 1073 #endif 1074 { 1075 cfg_mem = EGR_INT_CN_TO_IP_MAPPINGm; 1076 } 1077 1078 mem_idx = (ecn_config->int_cn << _BCM_ECN_EGRESS_MEM_INDEX_INT_CN_OFFSET) + 1079 (ecn_config->ecn << _BCM_ECN_EGRESS_MEM_INDEX_ECN_OFFSET); 1080 index_max = soc_mem_index_max(unit, cfg_mem); 1081 1082 if (mem_idx > index_max) { 1083 return BCM_E_PARAM; 1084 } 1085 sal_memset(&entry_egr_int_cn_ip_mapping, 0, 1086 sizeof(entry_egr_int_cn_ip_mapping)); 1087 1088 BCM_IF_ERROR_RETURN( 1089 soc_mem_read(unit, cfg_mem, MEM_BLOCK_ALL, 1090 mem_idx, (void *)&entry_egr_int_cn_ip_mapping)); 1091 1092 /* Check ECN MARKING action */ 1093 fld_val = soc_mem_field32_get(unit, cfg_mem, 1094 &entry_egr_int_cn_ip_mapping, 1095 CHANGE_PACKET_ECNf); 1096 1097 if (fld_val) { 1098 ecn_config->action_flags |= 1099 BCM_ECN_TRAFFIC_ACTION_EGRESS_ECN_MARKING; 1100 fld_val = soc_mem_field32_get(unit, cfg_mem, 1101 &entry_egr_int_cn_ip_mapping, ECNf); 1102 ecn_config->new_ecn = fld_val; 1103 } else { 1104 ecn_config->action_flags &= 1105 ~BCM_ECN_TRAFFIC_ACTION_EGRESS_ECN_MARKING; 1106 } 1107 1108 /* Check Drop action */ 1109 fld_val = soc_mem_field32_get(unit, cfg_mem, 1110 &entry_egr_int_cn_ip_mapping, DROPf); 1111 if (fld_val) { 1112 ecn_config->action_flags |= 1113 BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 1114 } else { 1115 ecn_config->action_flags &= 1116 ~BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 1117 } 1118 1119 1120 return BCM_E_NONE; 1121 } 1122 1123 1124 static int 1125 _bcm_esw_ecn_action_egress_set(int unit, 1126 bcm_ecn_traffic_action_config_t *ecn_config) 1127 { 1128 int mem_idx, index_max; 1129 egr_int_cn_to_ip_mapping_entry_t entry_egr_int_cn_ip_mapping; 1130 uint32 fld_val; 1131 soc_mem_t cfg_mem = 0; 1132 1133 if ((ecn_config->int_cn < 0) || 1134 (ecn_config->int_cn > _BCM_ECN_INT_CN_VALUE_MAX)) { 1135 return BCM_E_PARAM; 1136 } 1137 1138 if ((ecn_config->ecn > _BCM_ECN_VALUE_MAX) || 1139 (ecn_config->new_ecn > _BCM_ECN_VALUE_MAX)) { 1140 return BCM_E_PARAM; 1141 } 1142 1143 #if defined(BCM_TRIDENT3_SUPPORT) 1144 if(SOC_IS_TRIDENT3X(unit)){ 1145 cfg_mem = EGR_INT_CN_TO_PKT_ECN_MAPPINGm; 1146 } else 1147 #endif 1148 { 1149 cfg_mem = EGR_INT_CN_TO_IP_MAPPINGm; 1150 } 1151 1152 mem_idx = (ecn_config->int_cn << _BCM_ECN_EGRESS_MEM_INDEX_INT_CN_OFFSET) + 1153 (ecn_config->ecn << _BCM_ECN_EGRESS_MEM_INDEX_ECN_OFFSET); 1154 index_max = soc_mem_index_max(unit, cfg_mem); 1155 1156 if (mem_idx > index_max) { 1157 return BCM_E_PARAM; 1158 } 1159 sal_memset(&entry_egr_int_cn_ip_mapping, 0, 1160 sizeof(entry_egr_int_cn_ip_mapping)); 1161 1162 BCM_IF_ERROR_RETURN( 1163 soc_mem_read(unit, cfg_mem, MEM_BLOCK_ALL, 1164 mem_idx, (void *)&entry_egr_int_cn_ip_mapping)); 1165 1166 /* ECN Marking action */ 1167 if (ecn_config->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_ECN_MARKING) { 1168 1169 soc_mem_field32_set(unit, cfg_mem, 1170 &entry_egr_int_cn_ip_mapping, 1171 CHANGE_PACKET_ECNf, 1); 1172 soc_mem_field32_set(unit, cfg_mem, 1173 &entry_egr_int_cn_ip_mapping, 1174 INCREMENT_ECN_COUNTERf, 1); 1175 fld_val = ecn_config->new_ecn; 1176 soc_mem_field32_set(unit, cfg_mem, 1177 &entry_egr_int_cn_ip_mapping, 1178 ECNf, fld_val); 1179 } else { 1180 soc_mem_field32_set(unit, cfg_mem, 1181 &entry_egr_int_cn_ip_mapping, 1182 CHANGE_PACKET_ECNf, 0); 1183 soc_mem_field32_set(unit, cfg_mem, 1184 &entry_egr_int_cn_ip_mapping, 1185 INCREMENT_ECN_COUNTERf, 0); 1186 } 1187 1188 /* Drop action */ 1189 if (ecn_config->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP) { 1190 fld_val = 1; 1191 } else { 1192 fld_val = 0; 1193 } 1194 soc_mem_field32_set(unit, cfg_mem, 1195 &entry_egr_int_cn_ip_mapping, 1196 DROPf, fld_val); 1197 1198 BCM_IF_ERROR_RETURN( 1199 soc_mem_write(unit, cfg_mem, MEM_BLOCK_ALL, 1200 mem_idx, (void *)&entry_egr_int_cn_ip_mapping)); 1201 1202 1203 return BCM_E_NONE; 1204 } 1205 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 1206 1207 /* 1208 * Function: 1209 * bcm_esw_ecn_traffic_action_config_get 1210 * Purpose: 1211 * To get the actions of the specified ECN traffic. 1212 * Parameters: 1213 * unit - (IN) Unit number. 1214 * ecn_config - (INOUT) ECN traffic action configuration. 1215 * Returns: 1216 * BCM_E_XXX 1217 * Notes: 1218 */ 1219 1220 int 1221 bcm_esw_ecn_traffic_action_config_get( 1222 int unit, bcm_ecn_traffic_action_config_t *ecn_config) 1223 { 1224 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 1225 int rv = BCM_E_NONE; 1226 1227 if (!soc_feature(unit, soc_feature_ecn_wred)) { 1228 return BCM_E_UNAVAIL; 1229 } 1230 1231 if (ecn_config == NULL) { 1232 return BCM_E_PARAM; 1233 } 1234 1235 switch(ecn_config->action_type) { 1236 case BCM_ECN_TRAFFIC_ACTION_TYPE_ENQUEUE: 1237 rv = _bcm_esw_ecn_action_enqueue_get(unit, ecn_config); 1238 break; 1239 case BCM_ECN_TRAFFIC_ACTION_TYPE_DEQUEUE: 1240 rv = _bcm_esw_ecn_action_dequeue_get(unit, ecn_config); 1241 break; 1242 case BCM_ECN_TRAFFIC_ACTION_TYPE_EGRESS: 1243 rv = _bcm_esw_ecn_action_egress_get(unit, ecn_config); 1244 break; 1245 default: 1246 rv = BCM_E_PARAM; 1247 } 1248 1249 return rv; 1250 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 1251 return BCM_E_UNAVAIL; 1252 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 1253 } 1254 1255 1256 /* 1257 * Function: 1258 * bcm_esw_ecn_traffic_action_config_set 1259 * Purpose: 1260 * Assign the actions of the specified ECN traffic. 1261 * Parameters: 1262 * unit - (IN) Unit number. 1263 * ecn_config - (IN) ECN traffic action configuration. 1264 * Returns: 1265 * BCM_E_XXX 1266 * Notes: 1267 */ 1268 1269 int 1270 bcm_esw_ecn_traffic_action_config_set( 1271 int unit, bcm_ecn_traffic_action_config_t *ecn_config) 1272 { 1273 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 1274 int rv = BCM_E_NONE; 1275 1276 if (!soc_feature(unit, soc_feature_ecn_wred)) { 1277 return BCM_E_UNAVAIL; 1278 } 1279 1280 if (ecn_config == NULL) { 1281 return BCM_E_PARAM; 1282 } 1283 1284 if (ecn_config->action_flags & 1285 ~(BCM_ECN_TRAFFIC_ACTION_ENQUEUE_WRED_RESPONSIVE | 1286 BCM_ECN_TRAFFIC_ACTION_ENQUEUE_MARK_ELIGIBLE | 1287 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_CONGESTION_INT_CN_UPDATE | 1288 BCM_ECN_TRAFFIC_ACTION_DEQUEUE_NON_CONGESTION_INT_CN_UPDATE | 1289 BCM_ECN_TRAFFIC_ACTION_EGRESS_ECN_MARKING | 1290 BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP)) { 1291 return BCM_E_PARAM; 1292 } 1293 1294 switch(ecn_config->action_type) { 1295 case BCM_ECN_TRAFFIC_ACTION_TYPE_ENQUEUE: 1296 rv = _bcm_esw_ecn_action_enqueue_set(unit, ecn_config); 1297 break; 1298 case BCM_ECN_TRAFFIC_ACTION_TYPE_DEQUEUE: 1299 rv = _bcm_esw_ecn_action_dequeue_set(unit, ecn_config); 1300 break; 1301 case BCM_ECN_TRAFFIC_ACTION_TYPE_EGRESS: 1302 rv = _bcm_esw_ecn_action_egress_set(unit, ecn_config); 1303 break; 1304 default: 1305 rv = BCM_E_PARAM; 1306 } 1307 1308 return rv; 1309 #else /* !BCM_GREYHOUND_SUPPORT && !BCM_TOMAHAWK_SUPPORT */ 1310 return BCM_E_UNAVAIL; 1311 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 1312 } 1313 #if defined(INCLUDE_L3) 1314 /* 1315 * Function: 1316 * bcm_esw_ecn_map_create 1317 * Purpose: 1318 * To create an ECN mapping profile. 1319 * Parameters: 1320 * unit - (IN) Unit number. 1321 * flags - (IN) ECN flags. 1322 * ecn_map_id - (IN) ECN map id. 1323 * Returns: 1324 * BCM_E_XXX 1325 * Notes: 1326 */ 1327 1328 int 1329 bcm_esw_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 1330 { 1331 int rv = BCM_E_UNAVAIL; 1332 #if defined(BCM_TOMAHAWK_SUPPORT) 1333 if (soc_feature(unit, soc_feature_ecn_wred) && 1334 (flags & BCM_ECN_MAP_TUNNEL_TERM)) { 1335 rv = bcmi_xgs5_ecn_map_create(unit, flags, ecn_map_id); 1336 return rv; 1337 } 1338 #endif 1339 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1340 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1341 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1342 rv = bcmi_xgs5_mpls_ecn_map_create(unit, flags, ecn_map_id); 1343 return rv; 1344 } 1345 #endif 1346 return rv; 1347 1348 } 1349 1350 /* 1351 * Function: 1352 * bcm_esw_ecn_map_destroy 1353 * Purpose: 1354 * To destroy an ECN mapping profile. 1355 * Parameters: 1356 * unit - (IN) Unit number. 1357 * ecn_map_id - (IN) ECN map id. 1358 * Returns: 1359 * BCM_E_XXX 1360 * Notes: 1361 */ 1362 1363 int 1364 bcm_esw_ecn_map_destroy(int unit, int ecn_map_id) 1365 { 1366 int rv = BCM_E_UNAVAIL; 1367 #if defined(BCM_TOMAHAWK_SUPPORT) 1368 if (soc_feature(unit, soc_feature_ecn_wred) && 1369 (_BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM == 1370 (ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK))) { 1371 rv = bcmi_xgs5_ecn_map_destroy(unit, ecn_map_id); 1372 return rv; 1373 } 1374 #endif 1375 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1376 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1377 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1378 rv = bcmi_xgs5_mpls_ecn_map_destroy(unit, ecn_map_id); 1379 return rv; 1380 } 1381 #endif 1382 return rv; 1383 } 1384 1385 /* 1386 * Function: 1387 * bcm_esw_ecn_map_set 1388 * Purpose: 1389 * To set an ECN mapping entry in an ECN mapping profile. 1390 * Parameters: 1391 * unit - (IN) Unit number. 1392 * options - (IN) options, no used currently 1393 * ecn_map_id - (IN) ECN map id. 1394 * ecn_map - (IN) ECN mapping values 1395 * Returns: 1396 * BCM_E_XXX 1397 * Notes: 1398 */ 1399 1400 int 1401 bcm_esw_ecn_map_set(int unit, uint32 options, int ecn_map_id, 1402 bcm_ecn_map_t *ecn_map) 1403 { 1404 int rv = BCM_E_UNAVAIL; 1405 #if defined(BCM_TOMAHAWK_SUPPORT) 1406 if (soc_feature(unit, soc_feature_ecn_wred) && 1407 (_BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM == 1408 (ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK))) { 1409 rv = bcmi_xgs5_ecn_map_set(unit, ecn_map_id, ecn_map); 1410 return rv; 1411 } 1412 #endif 1413 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1414 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1415 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1416 rv = bcmi_xgs5_mpls_ecn_map_set(unit, ecn_map_id, ecn_map); 1417 return rv; 1418 } 1419 #endif 1420 return rv; 1421 } 1422 1423 1424 /* 1425 * Function: 1426 * bcm_esw_ecn_map_get 1427 * Purpose: 1428 * To get an ECN mapping entry from an ECN mapping profile. 1429 * Parameters: 1430 * unit - (IN) Unit number. 1431 * options - (IN) options, no used currently 1432 * ecn_map_id - (IN) ECN map id. 1433 * ecn_map - (IN/OUT) ECN mapping values 1434 * Returns: 1435 * BCM_E_XXX 1436 * Notes: 1437 */ 1438 1439 1440 int 1441 bcm_esw_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1442 { 1443 int rv = BCM_E_UNAVAIL; 1444 #if defined(BCM_TOMAHAWK_SUPPORT) 1445 if (soc_feature(unit, soc_feature_ecn_wred) && 1446 (_BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM == 1447 (ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK))) { 1448 rv = bcmi_xgs5_ecn_map_get(unit, ecn_map_id, ecn_map); 1449 return rv; 1450 } 1451 #endif 1452 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1453 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1454 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1455 rv = bcmi_xgs5_mpls_ecn_map_get(unit, ecn_map_id, ecn_map); 1456 return rv; 1457 } 1458 #endif 1459 return rv; 1460 } 1461 1462 /* 1463 * Function: 1464 * bcm_ecn_port_map_get 1465 * Purpose: 1466 * To get an ECN mapping info from a port. 1467 * Parameters: 1468 * unit - (IN) Unit number. 1469 * port - (IN) gport. 1470 * ecn_map - (IN/OUT) ECN mapping info 1471 * Returns: 1472 * BCM_E_XXX 1473 * Notes: 1474 */ 1475 1476 int 1477 bcm_esw_ecn_port_map_get(int unit, bcm_gport_t port, bcm_ecn_port_map_t *ecn_map) 1478 1479 { 1480 int rv = BCM_E_UNAVAIL; 1481 #if defined(BCM_TOMAHAWK_SUPPORT) 1482 if (soc_feature(unit, soc_feature_ecn_wred) && 1483 #if defined(BCM_TOMAHAWK3_SUPPORT) 1484 (!SOC_IS_TOMAHAWK3(unit)) && 1485 #endif 1486 (BCM_ECN_INGRESS_PORT_TUNNEL_TERM_MAP & ecn_map->flags)) { 1487 rv = bcmi_xgs5_ecn_port_map_get(unit, port, ecn_map); 1488 return rv; 1489 } 1490 #endif 1491 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1492 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1493 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1494 rv = bcmi_xgs5_mpls_ecn_port_map_get(unit, port, ecn_map); 1495 return rv; 1496 } 1497 #endif 1498 return rv; 1499 } 1500 1501 /* 1502 * Function: 1503 * bcm_ecn_port_map_set 1504 * Purpose: 1505 * To set an ECN mapping info from a port. 1506 * Parameters: 1507 * unit - (IN) Unit number. 1508 * port - (IN) gport. 1509 * ecn_map - (IN) ECN mapping info 1510 * Returns: 1511 * BCM_E_XXX 1512 * Notes: 1513 */ 1514 1515 int 1516 bcm_esw_ecn_port_map_set(int unit, bcm_gport_t port, bcm_ecn_port_map_t *ecn_map) 1517 1518 { 1519 int rv = BCM_E_UNAVAIL; 1520 #if defined(BCM_TOMAHAWK_SUPPORT) 1521 if (soc_feature(unit, soc_feature_ecn_wred) && 1522 #if defined(BCM_TOMAHAWK3_SUPPORT) 1523 (!SOC_IS_TOMAHAWK3(unit)) && 1524 #endif 1525 (BCM_ECN_INGRESS_PORT_TUNNEL_TERM_MAP & ecn_map->flags)) { 1526 rv = bcmi_xgs5_ecn_port_map_set(unit, port, ecn_map); 1527 return rv; 1528 } 1529 #endif 1530 #if (defined(BCM_MPLS_SUPPORT) && (defined(BCM_TOMAHAWK2_SUPPORT) || \ 1531 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT))) 1532 if (soc_feature(unit, soc_feature_mpls_ecn)) { 1533 rv = bcmi_xgs5_mpls_ecn_port_map_set(unit, port, ecn_map); 1534 return rv; 1535 } 1536 #endif 1537 return rv; 1538 } 1539 1540 /* 1541 * Function: 1542 * bcm_esw_ecn_map_mode_set 1543 * Purpose: 1544 * To set an ECN mapping mode. 1545 * Parameters: 1546 * unit - (IN) Unit number. 1547 * ecn_map_mode - (IN) ECN mapping mode info 1548 * Returns: 1549 * BCM_E_XXX 1550 * Notes: 1551 */ 1552 1553 int 1554 bcm_esw_ecn_map_mode_set(int unit, 1555 bcm_ecn_map_mode_t *ecn_map_mode) 1556 { 1557 int rv = BCM_E_UNAVAIL; 1558 #if defined(BCM_TRIDENT2_SUPPORT) 1559 soc_mem_t mem = EGR_DSCP_ECN_MAPm; 1560 soc_field_t field = ECN_MODEf; 1561 egr_dscp_ecn_map_entry_t map_entry; 1562 int idx_min, idx_max, idx; 1563 1564 if (soc_feature(unit, soc_feature_ecn_dscp_map_mode)) { 1565 if (ecn_map_mode == NULL) { 1566 rv = BCM_E_PARAM; 1567 return rv; 1568 } 1569 1570 if ((ecn_map_mode->dscp < -1) || (ecn_map_mode->dscp > 63)) { 1571 rv = BCM_E_PARAM; 1572 return rv; 1573 } 1574 1575 if (ecn_map_mode->dscp_map_mode >= bcmEcnDscpMapModeCount || 1576 ecn_map_mode->dscp_map_mode < 0) { 1577 rv = BCM_E_PARAM; 1578 return rv; 1579 } 1580 1581 if (ecn_map_mode->dscp == -1) { 1582 idx_min = 0; 1583 idx_max = 64; 1584 } else { 1585 idx_min = ecn_map_mode->dscp; 1586 idx_max = idx_min+1; 1587 } 1588 1589 for (idx = idx_min; idx < idx_max; idx++) { 1590 sal_memset(&map_entry, 0, sizeof(map_entry)); 1591 BCM_IF_ERROR_RETURN( 1592 soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, (void*)&map_entry)); 1593 soc_mem_field32_set(unit, mem, &map_entry, field, 1594 ecn_map_mode->dscp_map_mode); 1595 BCM_IF_ERROR_RETURN( 1596 soc_mem_write(unit, mem, MEM_BLOCK_ALL, idx, (void*)&map_entry)); 1597 } 1598 1599 rv = BCM_E_NONE; 1600 return rv; 1601 } 1602 #endif /* BCM_TRIDENT2_SUPPORT */ 1603 1604 return rv; 1605 } 1606 1607 /* 1608 * Function: 1609 * bcm_esw_ecn_map_mode_get 1610 * Purpose: 1611 * To get an ECN mapping mode info. 1612 * Parameters: 1613 * unit - (IN) Unit number. 1614 * ecn_map_mode - (IN/OUT) ECN mapping mode info 1615 * Returns: 1616 * BCM_E_XXX 1617 * Notes: 1618 */ 1619 1620 int 1621 bcm_esw_ecn_map_mode_get(int unit, 1622 bcm_ecn_map_mode_t *ecn_map_mode) 1623 { 1624 int rv = BCM_E_UNAVAIL; 1625 #if defined(BCM_TRIDENT2_SUPPORT) 1626 soc_mem_t mem = EGR_DSCP_ECN_MAPm; 1627 soc_field_t field = ECN_MODEf; 1628 egr_dscp_ecn_map_entry_t map_entry; 1629 int idx; 1630 uint32 fldval; 1631 1632 if (soc_feature(unit, soc_feature_ecn_dscp_map_mode)) { 1633 if (ecn_map_mode == NULL) { 1634 rv = BCM_E_PARAM; 1635 return rv; 1636 } 1637 if ((ecn_map_mode->dscp < 0) || (ecn_map_mode->dscp > 63)) { 1638 rv = BCM_E_PARAM; 1639 return rv; 1640 } 1641 1642 1643 idx = ecn_map_mode->dscp; 1644 sal_memset(&map_entry, 0, sizeof(map_entry)); 1645 BCM_IF_ERROR_RETURN( 1646 soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, (void*)&map_entry)); 1647 fldval = soc_mem_field32_get(unit, mem, (void*)&map_entry, field); 1648 ecn_map_mode->dscp_map_mode = fldval; 1649 1650 rv = BCM_E_NONE; 1651 return rv; 1652 } 1653 #endif /* BCM_TRIDENT2_SUPPORT */ 1654 1655 return rv; 1656 } 1657 1658 #endif /*INCLUDE_L3*/ 1659 1660 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 1661 void 1662 _bcm_esw_ecn_sw_dump(int unit) 1663 { 1664 #if defined(BCM_TOMAHAWK_SUPPORT) && defined(INCLUDE_L3) 1665 if (SOC_IS_TOMAHAWKX(unit)) { 1666 bcmi_xgs5_ecn_sw_dump(unit); 1667 } 1668 #endif 1669 } 1670 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 1671