port.c (78946B)
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 * File: port.c 8 * Purpose: Port function implementations 9 */ 10 11 12 #include <soc/defs.h> 13 14 #include <assert.h> 15 16 #include <sal/core/libc.h> 17 #if defined(BCM_TRX_SUPPORT) 18 19 #include <shared/util.h> 20 #include <soc/mem.h> 21 #include <soc/cm.h> 22 #include <soc/drv.h> 23 #include <soc/register.h> 24 #include <soc/memory.h> 25 #include <soc/lpm.h> 26 #include <soc/tnl_term.h> 27 28 #if defined(BCM_TOMAHAWK3_SUPPORT) 29 #include <soc/tomahawk3.h> 30 #endif 31 32 #include <bcm/port.h> 33 #include <bcm/error.h> 34 35 #include <bcm_int/esw/mbcm.h> 36 #include <bcm_int/esw/firebolt.h> 37 #include <bcm_int/esw/trx.h> 38 #include <bcm_int/esw/triumph.h> 39 #include <bcm_int/esw/port.h> 40 #include <bcm_int/esw/xgs3.h> 41 #include <bcm_int/esw/stack.h> 42 #include <bcm_int/esw/trill.h> 43 44 #include <bcm_int/esw_dispatch.h> 45 #if defined(BCM_KATANA2_SUPPORT) 46 #include <bcm_int/esw/katana2.h> 47 #endif 48 #if defined(BCM_HGPROXY_COE_SUPPORT) 49 #include <bcm_int/esw/subport.h> 50 #endif 51 #if defined(BCM_TRIUMPH_SUPPORT) 52 #include <bcm_int/esw/virtual.h> 53 #endif /* BCM_TRIUMPH_SUPPORT */ 54 55 /* 56 * Function: 57 * _bcm_trx_port_cml_hw2flags 58 * Description: 59 * Converts a HW value to CML flags 60 * Parameters: 61 * unit - (IN) Device number 62 * val - (IN) TRX HW value 63 * flags - (OUT) CML flags BCM_PORT_LEARN_* 64 * Return Value: 65 * BCM_E_XXX 66 */ 67 int _bcm_trx_port_cml_hw2flags(int unit, uint32 val, uint32 *flags) 68 { 69 uint32 lflags = 0; 70 71 if (NULL == flags) { 72 return BCM_E_PARAM; 73 } 74 75 if (!(val & (1 << 0))) { 76 lflags |= BCM_PORT_LEARN_FWD; 77 } 78 if (val & (1 << 1)) { 79 lflags |= BCM_PORT_LEARN_CPU; 80 } 81 if (val & (1 << 2)) { 82 lflags |= BCM_PORT_LEARN_PENDING; 83 } 84 if (val & (1 << 3)) { 85 lflags |= BCM_PORT_LEARN_ARL; 86 } 87 88 *flags = lflags; 89 return BCM_E_NONE; 90 } 91 92 93 /* 94 * Function: 95 * _bcm_trx_port_cml_flags2hw 96 * Description: 97 * Converts CML flags to a HW value. 98 * Parameters: 99 * unit - (IN) Device number 100 * flags - (IN) CML flags BCM_PORT_LEARN_* 101 * val - (OUT) TRX HW value 102 * Return Value: 103 * BCM_E_XXX 104 */ 105 int _bcm_trx_port_cml_flags2hw(int unit, uint32 flags, uint32 *val) 106 { 107 uint32 hw_val = 0; 108 109 if (NULL == val) { 110 return BCM_E_PARAM; 111 } 112 if (!(flags & BCM_PORT_LEARN_FWD)) { 113 hw_val |= (1 << 0); 114 } 115 if (flags & BCM_PORT_LEARN_CPU) { 116 hw_val |= (1 << 1); 117 } 118 if (flags & BCM_PORT_LEARN_PENDING) { 119 hw_val |= (1 << 2); 120 } 121 if (flags & BCM_PORT_LEARN_ARL) { 122 hw_val |= (1 << 3); 123 } 124 125 *val = hw_val; 126 return (BCM_E_NONE); 127 } 128 129 /* 130 * Function: 131 * _bcm_trx_vp_tpid_add 132 * Description: 133 * Add allowed TPID for a virtual port. 134 * Parameters: 135 * unit - (IN) Device number 136 * vport - (IN) Virtual Port identifier (MPLS ot MIM) 137 * tpid - (IN) Tag Protocol ID 138 * color_select - (IN) Color mode for TPID 139 * Return Value: 140 * BCM_E_XXX 141 */ 142 int _bcm_trx_vp_tpid_add(int unit, bcm_gport_t vport, uint16 tpid, int color_select) 143 { 144 int vp, rv, tpid_idx=0, tpid_enable=0, islocal; 145 source_vp_entry_t svp; 146 uint32 ena_f, cfi_cng, egr_vlan_ctrl; 147 bcm_port_t port; 148 bcm_module_t modid, mymodid; 149 bcm_trunk_t tgid; 150 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 151 egr_vlan_control_1_entry_t entry; 152 #endif 153 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 154 int vp_lag_vp; 155 #endif 156 #if defined(BCM_TRX_SUPPORT) 157 /* 158 * TRX devices only support OUTER_CFI to be mapped to CNG 159 */ 160 if (color_select == BCM_COLOR_INNER_CFI && SOC_IS_TRX(unit)) { 161 return BCM_E_UNAVAIL; 162 } 163 #endif 164 165 BCM_IF_ERROR_RETURN( 166 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 167 168 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 169 if (soc_feature(unit, soc_feature_vp_lag)) { 170 if (tgid != -1) { 171 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp); 172 if (BCM_SUCCESS(rv) && 173 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) { 174 vp = vp_lag_vp; 175 } 176 } 177 } 178 #endif 179 180 if (-1 == vp) { 181 return BCM_E_PORT; 182 } 183 if (tgid == -1) { 184 BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal)); 185 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 186 if (!islocal) { 187 if (soc_feature(unit, soc_feature_subtag_coe) || 188 soc_feature(unit, soc_feature_linkphy_coe)) { 189 #ifdef BCM_KATANA2_SUPPORT 190 if (SOC_IS_KATANA2(unit) && 191 (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) { 192 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 193 modid, port, &port)); 194 } else { 195 return BCM_E_PORT; 196 } 197 #endif 198 } 199 } else { 200 while (mymodid < modid) { 201 port += 32; 202 modid -= 1; 203 } 204 } 205 } 206 207 _bcm_fb2_outer_tpid_tab_lock(unit); 208 209 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 210 if (BCM_FAILURE(rv)) { 211 _bcm_fb2_outer_tpid_tab_unlock(unit); 212 return rv; 213 } 214 215 /* See if the entry already exist */ 216 rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_idx); 217 #if defined(BCM_TRIDENT3_SUPPORT) 218 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 219 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 220 uint32 tpid_enable = 0; 221 222 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 223 MEM_BLOCK_ANY, vp, svp_attrs_1)); 224 soc_SVP_ATTRS_1m_field_get(unit, 225 &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable); 226 227 ena_f = tpid_enable; 228 } else 229 #endif 230 { 231 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 232 } 233 234 if ((BCM_E_NOT_FOUND == rv) || !(ena_f & (1 << tpid_idx)) ) { 235 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx); 236 if (BCM_FAILURE(rv)) { 237 _bcm_fb2_outer_tpid_tab_unlock(unit); 238 return rv; 239 } 240 241 } 242 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 243 && defined(INCLUDE_L3) 244 /* Add TPID for Trill Virtual Port */ 245 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) 246 && (BCM_GPORT_IS_TRILL_PORT(vport)) 247 && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) { 248 rv = bcm_td_trill_tpid_add(unit, vport, tpid_idx); 249 if (BCM_FAILURE(rv)) { 250 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 251 _bcm_fb2_outer_tpid_tab_unlock(unit); 252 return (rv); 253 } 254 } else 255 #endif 256 { 257 tpid_enable = (1 << tpid_idx); 258 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1); 259 ena_f |= tpid_enable; 260 #if defined(BCM_TRIDENT3_SUPPORT) 261 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 262 rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m, 263 vp, TPID_ENABLEf, ena_f); 264 } else 265 #endif 266 { 267 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f); 268 } 269 270 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 271 272 if (BCM_FAILURE(rv)) { 273 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 274 _bcm_fb2_outer_tpid_tab_unlock(unit); 275 return rv; 276 } 277 } 278 279 if ((tgid == -1) && islocal && SOC_PORT_VALID(unit, port)) { 280 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 281 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 282 if (soc_feature(unit, soc_feature_egr_all_profile)) { 283 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit, 284 port, EGR_VLAN_CONTROL_1m, CFI_AS_CNGf, &cfi_cng)); 285 } else { 286 rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry); 287 cfi_cng = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry, 288 CFI_AS_CNGf); 289 } 290 } else 291 #endif 292 { 293 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &egr_vlan_ctrl); 294 cfi_cng = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 295 egr_vlan_ctrl, CFI_AS_CNGf); 296 } 297 if (BCM_FAILURE(rv)) { 298 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 299 _bcm_fb2_outer_tpid_tab_unlock(unit); 300 return rv; 301 } 302 303 /* Update color selection per TPID per port */ 304 switch (color_select) { 305 case BCM_COLOR_PRIORITY: 306 cfi_cng &= ~tpid_enable; 307 break; 308 case BCM_COLOR_INNER_CFI: 309 cfi_cng = 0x1; 310 break; 311 case BCM_COLOR_OUTER_CFI: 312 cfi_cng |= tpid_enable; 313 break; 314 default: 315 /* Already checked color_select param */ 316 /* Should never get here */ 317 break; 318 } 319 320 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 321 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 322 if (soc_feature(unit, soc_feature_egr_all_profile)) { 323 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 324 port, EGR_VLAN_CONTROL_1m, CFI_AS_CNGf, cfi_cng)); 325 } else { 326 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &entry, 327 CFI_AS_CNGf, cfi_cng); 328 rv = WRITE_EGR_VLAN_CONTROL_1m(unit, 329 MEM_BLOCK_ANY, port, &entry); 330 } 331 } else 332 #endif 333 { 334 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &egr_vlan_ctrl, 335 CFI_AS_CNGf, cfi_cng); 336 rv = WRITE_EGR_VLAN_CONTROL_1r(unit, port, egr_vlan_ctrl); 337 } 338 if (BCM_FAILURE(rv)) { 339 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 340 _bcm_fb2_outer_tpid_tab_unlock(unit); 341 return rv; 342 } 343 } 344 345 _bcm_fb2_outer_tpid_tab_unlock(unit); 346 return BCM_E_NONE; 347 } 348 349 /* 350 * Function: 351 * _bcm_trx_vp_tpid_get_all 352 * Description: 353 * Retrieve a list of TPIDs available for the given vport. 354 * Parameters: 355 * unit - (IN) Device number 356 * vport - (IN) Virtual Port identifier (MPLS ot MIM) 357 * size - (IN) size of the buffer arrays 358 * tpid_array - (OUT) tpid buffer array 359 * color_array - (OUT) color buffer array 360 * count - (OUT) actual number of tpids/colors retrieved 361 * Return Value: 362 * BCM_E_XXX 363 */ 364 int _bcm_trx_vp_tpid_get_all(int unit, bcm_gport_t vport, int size, 365 uint16 *tpid_array, int *color_array, int *count) 366 { 367 int vp, rv; 368 source_vp_entry_t svp; 369 uint32 tpid_enable=0; 370 bcm_port_t port; 371 bcm_module_t modid; 372 bcm_trunk_t tgid; 373 int cnt; 374 uint32 tpid; 375 int num_entries; 376 int index; 377 378 rv = BCM_E_NONE; 379 cnt = 0; 380 381 BCM_IF_ERROR_RETURN( 382 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 383 384 if (-1 == vp) { 385 return BCM_E_PORT; 386 } 387 388 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 389 if (BCM_FAILURE(rv)) { 390 return rv; 391 } 392 393 #if defined(BCM_TRIDENT3_SUPPORT) 394 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 395 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 396 397 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 398 MEM_BLOCK_ANY, vp, svp_attrs_1)); 399 soc_SVP_ATTRS_1m_field_get(unit, 400 &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable); 401 402 /* max tpid entries limited by width of this field */ 403 num_entries = soc_mem_field_length(unit,SVP_ATTRS_1m,TPID_ENABLEf); 404 } else 405 #endif 406 { 407 tpid_enable = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 408 /* max tpid entries limited by width of this field */ 409 num_entries = soc_mem_field_length(unit,SOURCE_VPm,TPID_ENABLEf); 410 } 411 412 if (size == 0) { 413 for (index = 0; index < num_entries; index++) { 414 if (tpid_enable & (1 << index)) { 415 cnt++; 416 } 417 } 418 *count = cnt; 419 return BCM_E_NONE; 420 } 421 422 for (index = 0; index < num_entries; index++) { 423 if (cnt < size) { 424 if (tpid_enable & (1 << index)) { 425 rv = READ_EGR_OUTER_TPIDr(unit, index, &tpid); 426 if (BCM_FAILURE(rv)) { 427 return (rv); 428 } 429 tpid_array[cnt] = (uint16)tpid; 430 cnt++; 431 } 432 } 433 } 434 *count = cnt; 435 436 return rv; 437 } 438 439 /* 440 * Function: 441 * _bcm_trx_vp_tpid_delete 442 * Description: 443 * Delete allowed TPID for a virtual port. 444 * Parameters: 445 * unit - (IN) Device number 446 * vport - (IN) Virtual Port identifier (WLAN or MIM) 447 * tpid - (IN) Tag Protocol ID 448 * Return Value: 449 * BCM_E_XXX 450 */ 451 int _bcm_trx_vp_tpid_delete(int unit, bcm_gport_t vport, uint16 tpid) 452 { 453 int vp, rv, tpid_idx; 454 source_vp_entry_t svp; 455 uint32 ena_f; 456 bcm_port_t port; 457 bcm_module_t modid; 458 bcm_trunk_t tgid; 459 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 460 int vp_lag_vp; 461 #endif 462 463 BCM_IF_ERROR_RETURN( 464 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 465 466 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 467 if (soc_feature(unit, soc_feature_vp_lag)) { 468 if (tgid != -1) { 469 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp); 470 if (BCM_SUCCESS(rv) && 471 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) { 472 vp = vp_lag_vp; 473 } 474 } 475 } 476 #endif 477 478 if (-1 == vp) { 479 return BCM_E_PORT; 480 } 481 482 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 483 #if defined(BCM_TRIDENT3_SUPPORT) 484 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 485 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 486 uint32 tpid_enable = 0; 487 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 488 MEM_BLOCK_ANY, vp, svp_attrs_1)); 489 tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf); 490 ena_f = tpid_enable; 491 } else 492 #endif 493 { 494 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 495 } 496 _bcm_fb2_outer_tpid_tab_lock(unit); 497 498 rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_idx); 499 if (BCM_FAILURE(rv)) { 500 _bcm_fb2_outer_tpid_tab_unlock(unit); 501 return (rv); 502 } 503 504 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 505 && defined(INCLUDE_L3) 506 /* Add TPID for Trill Virtual Port */ 507 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) 508 && (BCM_GPORT_IS_TRILL_PORT(vport)) 509 && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) { 510 rv = bcm_td_trill_tpid_delete(unit, vport, tpid_idx); 511 if (BCM_FAILURE(rv)) { 512 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 513 _bcm_fb2_outer_tpid_tab_unlock(unit); 514 return (rv); 515 } 516 } else 517 #endif 518 { 519 if (ena_f & (1 << tpid_idx)) { 520 ena_f &= ~(1 << tpid_idx); 521 #if defined(BCM_TRIDENT3_SUPPORT) 522 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 523 rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m, 524 vp, TPID_ENABLEf, ena_f); 525 } else 526 #endif 527 { 528 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f); 529 } 530 if (!ena_f) { 531 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0); 532 } 533 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 534 535 if (BCM_FAILURE(rv)) { 536 rv = _bcm_fb2_outer_tpid_entry_delete(unit,tpid_idx); 537 _bcm_fb2_outer_tpid_tab_unlock(unit); 538 return rv; 539 } 540 } else { 541 _bcm_fb2_outer_tpid_tab_unlock(unit); 542 return BCM_E_NOT_FOUND; 543 } 544 } 545 546 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 547 _bcm_fb2_outer_tpid_tab_unlock(unit); 548 return rv; 549 } 550 551 /* 552 * Function: 553 * _bcm_trx_vp_tpid_delete_all 554 * Description: 555 * Delete all allowed TPID for a virtual port. 556 * Parameters: 557 * unit - (IN) Device number 558 * vport - (IN) Virtual Port identifier 559 * Return Value: 560 * BCM_E_XXX 561 */ 562 int _bcm_trx_vp_tpid_delete_all(int unit, bcm_gport_t vport) 563 { 564 int vp, rv = BCM_E_NONE, tpid_idx; 565 source_vp_entry_t svp; 566 uint32 ena_f; 567 bcm_port_t port; 568 bcm_module_t modid; 569 bcm_trunk_t tgid; 570 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 571 int vp_lag_vp; 572 #endif 573 574 BCM_IF_ERROR_RETURN( 575 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 576 577 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 578 if (soc_feature(unit, soc_feature_vp_lag)) { 579 if (tgid != -1) { 580 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp); 581 if (BCM_SUCCESS(rv) && 582 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) { 583 vp = vp_lag_vp; 584 } 585 } 586 } 587 #endif 588 589 if (-1 == vp) { 590 return BCM_E_PORT; 591 } 592 593 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 594 #if defined(BCM_TRIDENT3_SUPPORT) 595 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 596 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 597 uint32 tpid_enable = 0; 598 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 599 MEM_BLOCK_ANY, vp, svp_attrs_1)); 600 tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf); 601 ena_f = tpid_enable; 602 } else 603 #endif 604 { 605 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 606 } 607 /* If was not set - do nothing */ 608 if (!ena_f) { 609 return BCM_E_NONE; 610 } 611 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 0); 612 #if defined(BCM_TRIDENT3_SUPPORT) 613 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 614 rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m, 615 vp, TPID_ENABLEf, ena_f); 616 } else 617 #endif 618 { 619 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, 0); 620 } 621 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp)); 622 623 /* Perform SW delition only after HW was updated */ 624 _bcm_fb2_outer_tpid_tab_lock(unit); 625 tpid_idx = 0; 626 while (ena_f) { 627 if (ena_f & 1) { 628 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 629 if (BCM_FAILURE(rv)) { 630 _bcm_fb2_outer_tpid_tab_unlock(unit); 631 return (rv); 632 } 633 } 634 ena_f = (ena_f >> 1); 635 tpid_idx++; 636 } 637 _bcm_fb2_outer_tpid_tab_unlock(unit); 638 return rv; 639 } 640 641 /* 642 * Function: 643 * _bcm_trx_vp_tpid_set 644 * Description: 645 * Set the default Tag Protocol ID for a virtual gport. 646 * Parameters: 647 * unit - Device number 648 * vport - Virtual Port identifier 649 * tpid - Tag Protocol ID 650 * Return Value: 651 * BCM_E_XXX 652 */ 653 int _bcm_trx_vp_tpid_set(int unit, bcm_gport_t vport, uint16 tpid) 654 { 655 int vp, rv, tpid_idx, old_idx, islocal; 656 source_vp_entry_t svp; 657 uint32 ena_f, evc; 658 bcm_port_t port; 659 bcm_module_t modid, mymodid; 660 bcm_trunk_t tgid; 661 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 662 egr_vlan_control_1_entry_t vlan_control; 663 #endif 664 int pp_port_flag = 0; 665 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 666 int vp_lag_vp; 667 #endif 668 BCM_IF_ERROR_RETURN( 669 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 670 671 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 672 if (soc_feature(unit, soc_feature_vp_lag)) { 673 if (tgid != -1) { 674 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp); 675 if (BCM_SUCCESS(rv) && 676 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) { 677 vp = vp_lag_vp; 678 } 679 } 680 } 681 #endif 682 683 if (-1 == vp) { 684 return BCM_E_PORT; 685 } 686 687 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 688 #if defined(BCM_TRIDENT3_SUPPORT) 689 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 690 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 691 uint32 tpid_enable = 0; 692 693 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 694 MEM_BLOCK_ANY, vp, svp_attrs_1)); 695 tpid_enable = soc_mem_field32_get(unit, SVP_ATTRS_1m, &svp_attrs_1, TPID_ENABLEf); 696 ena_f = tpid_enable; 697 } else 698 #endif 699 { 700 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 701 } 702 703 old_idx = 0; 704 if (tgid == -1) { 705 BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal)); 706 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 707 708 if (!islocal) { 709 if (soc_feature(unit, soc_feature_subtag_coe) || 710 soc_feature(unit, soc_feature_linkphy_coe)) { 711 #ifdef BCM_KATANA2_SUPPORT 712 if (SOC_IS_KATANA2(unit) && 713 (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) { 714 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 715 modid, port, &port)); 716 pp_port_flag = 1; 717 } else { 718 return BCM_E_PORT; 719 } 720 #endif 721 } 722 } else { 723 while (mymodid < modid) { 724 port += 32; 725 modid -= 1; 726 } 727 } 728 729 if (islocal || (!islocal && pp_port_flag)) { 730 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 731 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 732 if (soc_feature(unit, soc_feature_egr_all_profile)) { 733 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit, 734 port, EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf, 735 (void *)&old_idx)); 736 } else { 737 BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1m(unit, 738 MEM_BLOCK_ANY, port, &vlan_control)); 739 old_idx = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, 740 &vlan_control, OUTER_TPID_INDEXf); 741 } 742 } else 743 #endif 744 { 745 BCM_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1r(unit, port, &evc)); 746 old_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 747 evc, OUTER_TPID_INDEXf); 748 } 749 } 750 } 751 752 _bcm_fb2_outer_tpid_tab_lock(unit); 753 if (tgid == -1 && islocal) { 754 /* Delete the TPID referenced by EGR_VLAN_CONTROL_1r */ 755 rv = _bcm_fb2_outer_tpid_entry_delete(unit, old_idx); 756 if (BCM_FAILURE(rv)) { 757 _bcm_fb2_outer_tpid_tab_unlock(unit); 758 return (rv); 759 } 760 } 761 762 /* Delete the TPID referenced by SOURCE_VP table */ 763 tpid_idx = 0; 764 while (ena_f) { 765 if (ena_f & 1) { 766 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 767 if (BCM_FAILURE(rv)) { 768 _bcm_fb2_outer_tpid_tab_unlock(unit); 769 return (rv); 770 } 771 } 772 ena_f = ena_f >> 1; 773 tpid_idx++; 774 } 775 776 /* Add TPID */ 777 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx); 778 if (BCM_FAILURE(rv)) { 779 _bcm_fb2_outer_tpid_tab_unlock(unit); 780 return (rv); 781 } 782 783 if (tgid == -1 && islocal) { 784 /* Add TPID reference for EGR_VLAN_CONTROL_1. 785 * The first insertion and second insertion will return 786 * the same status because we are adding the same TPID value. 787 */ 788 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_idx); 789 if (BCM_FAILURE(rv)) { 790 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 791 _bcm_fb2_outer_tpid_tab_unlock(unit); 792 return (rv); 793 } 794 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 795 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 796 if (soc_feature(unit, soc_feature_egr_all_profile)) { 797 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 798 port, EGR_VLAN_CONTROL_1m, OUTER_TPID_INDEXf, tpid_idx)); 799 } else { 800 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &vlan_control, 801 OUTER_TPID_INDEXf, tpid_idx); 802 rv = WRITE_EGR_VLAN_CONTROL_1m(unit, 803 MEM_BLOCK_ANY, port, &vlan_control); 804 } 805 } else 806 #endif 807 { 808 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &evc, 809 OUTER_TPID_INDEXf, tpid_idx); 810 rv = WRITE_EGR_VLAN_CONTROL_1r(unit, port, evc); 811 } 812 if (BCM_FAILURE(rv)) { 813 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 814 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 815 _bcm_fb2_outer_tpid_tab_unlock(unit); 816 return (rv); 817 } 818 } 819 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 820 && defined(INCLUDE_L3) 821 /* Set TPID for Trill Virtual Port */ 822 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) 823 && (BCM_GPORT_IS_TRILL_PORT(vport)) 824 && (3 == soc_SOURCE_VPm_field32_get(unit, &svp, TPID_SOURCEf))) { 825 rv = bcm_td_trill_tpid_set(unit, vport, tpid_idx); 826 if (BCM_FAILURE(rv)) { 827 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 828 _bcm_fb2_outer_tpid_tab_unlock(unit); 829 return (rv); 830 } 831 } else 832 #endif 833 { 834 ena_f = 1 << tpid_idx; 835 #if defined(BCM_TRIDENT3_SUPPORT) 836 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 837 rv = soc_mem_field32_modify(unit, SVP_ATTRS_1m, 838 vp, TPID_ENABLEf, ena_f); 839 } else 840 #endif 841 { 842 soc_SOURCE_VPm_field32_set(unit, &svp, TPID_ENABLEf, ena_f); 843 } 844 soc_SOURCE_VPm_field32_set(unit, &svp, SD_TAG_MODEf, 1); 845 846 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 847 if (BCM_FAILURE(rv)) { 848 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_idx); 849 _bcm_fb2_outer_tpid_tab_unlock(unit); 850 return (rv); 851 } 852 } 853 854 _bcm_fb2_outer_tpid_tab_unlock(unit); 855 return BCM_E_NONE; 856 } 857 858 /* 859 * Function: 860 * _bcm_trx_vp_tpid_get 861 * Description: 862 * Get the default Tag Protocol ID for a virtual port. 863 * Parameters: 864 * unit - Device number 865 * vport - Virtual Port identifier 866 * tpid - Tag Protocol ID 867 * Return Value: 868 * BCM_E_XXX 869 */ 870 int _bcm_trx_vp_tpid_get(int unit, bcm_gport_t vport, uint16 *tpid) 871 { 872 int tpid_idx, vp, islocal; 873 uint32 evc; 874 bcm_port_t port; 875 bcm_module_t modid, mymodid; 876 bcm_trunk_t tgid; 877 source_vp_entry_t svp; 878 uint32 ena_f; 879 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 880 int rv; 881 int vp_lag_vp; 882 #endif 883 884 BCM_IF_ERROR_RETURN( 885 _bcm_esw_gport_resolve(unit, vport, &modid, &port, &tgid, &vp)); 886 887 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 888 if (soc_feature(unit, soc_feature_vp_lag)) { 889 if (tgid != -1) { 890 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, tgid, &vp_lag_vp); 891 if (BCM_SUCCESS(rv) && 892 _bcm_vp_used_get(unit, vp_lag_vp, _bcmVpTypeVpLag)) { 893 vp = vp_lag_vp; 894 } 895 } 896 } 897 #endif 898 899 if (-1 == vp) { 900 return BCM_E_PORT; 901 } 902 if (tgid == -1) { 903 BCM_IF_ERROR_RETURN( _bcm_esw_modid_is_local(unit, modid, &islocal)); 904 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 905 if (!islocal) { 906 if (soc_feature(unit, soc_feature_subtag_coe) || 907 soc_feature(unit, soc_feature_linkphy_coe)) { 908 #ifdef BCM_KATANA2_SUPPORT 909 if (SOC_IS_KATANA2(unit) && 910 (_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE)) { 911 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 912 modid, port, &port)); 913 } else { 914 return BCM_E_PORT; 915 } 916 #endif 917 } 918 } else { 919 while (mymodid < modid) { 920 port += 32; 921 modid -= 1; 922 } 923 } 924 } 925 926 #if (defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 927 && defined(INCLUDE_L3) 928 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) 929 && (BCM_GPORT_IS_TRILL_PORT(vport))) { 930 int rv; 931 rv = bcm_td_trill_tpid_get(unit, vport, &tpid_idx); 932 if (BCM_FAILURE(rv)) { 933 return (rv); 934 } 935 } else 936 #endif 937 { 938 if (tgid == -1 && islocal) { 939 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 940 if (soc_feature(unit, soc_feature_egr_all_profile)) { 941 BCM_IF_ERROR_RETURN( 942 bcm_esw_port_egr_lport_field_get( 943 unit, port, EGR_VLAN_CONTROL_1m, 944 OUTER_TPID_INDEXf, (uint32 *)&tpid_idx)); 945 } else { 946 egr_vlan_control_1_entry_t vlan_control; 947 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_VLAN_CONTROL_1m, 948 MEM_BLOCK_ANY, port, &vlan_control)); 949 soc_mem_field_get(unit, EGR_VLAN_CONTROL_1m, 950 (uint32*) &vlan_control, OUTER_TPID_INDEXf, 951 (uint32 *) &tpid_idx); 952 } 953 } else { 954 SOC_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1r(unit, port, &evc)); 955 tpid_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, 956 evc, OUTER_TPID_INDEXf); 957 } 958 } else { 959 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 960 #if defined(BCM_TRIDENT3_SUPPORT) 961 if (SOC_MEM_IS_VALID(unit, SVP_ATTRS_1m)) { 962 uint32 svp_attrs_1[SOC_MAX_MEM_WORDS]; 963 uint32 tpid_enable = 0; 964 965 BCM_IF_ERROR_RETURN(READ_SVP_ATTRS_1m(unit, 966 MEM_BLOCK_ANY, vp, svp_attrs_1)); 967 soc_SVP_ATTRS_1m_field_get(unit, 968 &svp_attrs_1, TPID_ENABLEf, (uint32 *)&tpid_enable); 969 970 ena_f = tpid_enable; 971 } else 972 #endif 973 { 974 ena_f = soc_SOURCE_VPm_field32_get(unit, &svp, TPID_ENABLEf); 975 } 976 tpid_idx = -1; 977 while (ena_f) { 978 tpid_idx++; 979 if (ena_f & 1) { 980 break; 981 } 982 ena_f = ena_f >> 1; 983 } 984 if (tpid_idx == -1) { 985 return BCM_E_NOT_FOUND; 986 } 987 } 988 } 989 _bcm_fb2_outer_tpid_entry_get(unit, tpid, tpid_idx); 990 991 return (BCM_E_NONE); 992 } 993 994 995 996 /* 997 * Function: 998 * _bcm_trx_egr_src_port_outer_tpid_set 999 * Description: 1000 * Enable/Disable outer tpid on all egress ports 1001 * Parameters: 1002 * unit - Device number 1003 * tpid_index - Tag Protocol ID 1004 * Return Value: 1005 * BCM_E_XXX 1006 */ 1007 int 1008 _bcm_trx_egr_src_port_outer_tpid_set(int unit, int tpid_index, int enable) 1009 { 1010 uint32 egr_src_port; 1011 uint32 tpid_enable; 1012 uint32 new_tpid_enable; 1013 bcm_port_t port; 1014 soc_reg_t reg; 1015 soc_pbmp_t temp_pbmp; 1016 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1017 egr_port_1_entry_t pe; 1018 #endif 1019 1020 if (SOC_IS_TD_TT(unit) || SOC_IS_HURRICANE(unit) || SOC_IS_TRIUMPH3(unit) 1021 || SOC_IS_KATANAX(unit) || SOC_IS_HURRICANE2(unit)) { 1022 reg = EGR_PORT_1r; 1023 } else { 1024 reg = EGR_SRC_PORTr; 1025 } 1026 1027 BCM_PBMP_CLEAR(temp_pbmp); 1028 BCM_PBMP_ASSIGN(temp_pbmp, PBMP_E_ALL(unit)); 1029 #ifdef BCM_KATANA2_SUPPORT 1030 if (soc_feature(unit, soc_feature_linkphy_coe) || 1031 soc_feature(unit, soc_feature_subtag_coe)) { 1032 _bcm_kt2_subport_pbmp_update (unit, &temp_pbmp); 1033 } 1034 #endif 1035 1036 PBMP_ITER(temp_pbmp, port) { 1037 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1038 if (soc_feature(unit, soc_feature_td2p_style_egr_outer_tpid)) { 1039 BCM_IF_ERROR_RETURN(READ_EGR_PORT_1m(unit, MEM_BLOCK_ANY, 1040 port, &pe)); 1041 tpid_enable = soc_mem_field32_get(unit, EGR_PORT_1m, &pe, 1042 OUTER_TPID_ENABLEf); 1043 } else 1044 #endif 1045 { 1046 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &egr_src_port)); 1047 tpid_enable = soc_reg_field_get(unit, reg, 1048 egr_src_port, OUTER_TPID_ENABLEf); 1049 } 1050 1051 if (enable) { 1052 new_tpid_enable = (tpid_enable | (1 << tpid_index)); 1053 } else { 1054 new_tpid_enable = (tpid_enable & ~(1 << tpid_index)); 1055 } 1056 1057 if (new_tpid_enable != tpid_enable) { 1058 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1059 if (soc_feature(unit, soc_feature_td2p_style_egr_outer_tpid)) { 1060 soc_mem_field32_set(unit, EGR_PORT_1m, &pe, 1061 OUTER_TPID_ENABLEf, new_tpid_enable); 1062 BCM_IF_ERROR_RETURN(WRITE_EGR_PORT_1m(unit, 1063 MEM_BLOCK_ANY, port, &pe)); 1064 } else 1065 #endif 1066 { 1067 soc_reg_field_set(unit, reg, &egr_src_port, 1068 OUTER_TPID_ENABLEf, new_tpid_enable); 1069 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, egr_src_port)); 1070 } 1071 } 1072 } 1073 return (BCM_E_NONE); 1074 } 1075 1076 /* 1077 * Function: 1078 * _bcm_esw_source_trunk_map_set 1079 * Description: 1080 * Helper funtion to modify fields in SOURCE_TRUNK_MAP memory. 1081 * Parameters: 1082 * unit - Device number 1083 * port - Port number 1084 * field - Field name within SOURCE_TRUNK_MAP table entry 1085 * value - new field value 1086 * Return Value: 1087 * BCM_E_XXX 1088 */ 1089 int 1090 _bcm_trx_source_trunk_map_set(int unit, bcm_port_t port, 1091 soc_field_t field, uint32 value) 1092 { 1093 bcm_module_t mod_out; 1094 bcm_port_t port_out; 1095 int index, trunk_id = -1, id = -1; 1096 1097 #if defined BCM_HGPROXY_COE_SUPPORT 1098 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1099 BCM_GPORT_IS_SET(port) && 1100 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 1101 /* Resolve the port */ 1102 SOC_IF_ERROR_RETURN( 1103 _bcm_esw_gport_resolve(unit, port, &mod_out, 1104 &port_out, &trunk_id, &id)); 1105 } else 1106 #endif 1107 { 1108 if (soc_feature(unit, soc_feature_shg_support_remote_port) && 1109 BCM_GPORT_IS_SET(port) && (field == CLASS_IDf)) { 1110 SOC_IF_ERROR_RETURN( 1111 _bcm_esw_gport_resolve(unit, port, &mod_out, 1112 &port_out, &trunk_id, &id)); 1113 } else { 1114 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 1115 /* Port sanity check. */ 1116 if (SOC_PORT_ADDRESSABLE(unit, port)) { 1117 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out)); 1118 port_out = port; 1119 } else { 1120 return (BCM_E_PORT); 1121 } 1122 } 1123 } 1124 /* Calculate table index. */ 1125 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 1126 mod_out, port_out, &index)); 1127 1128 return soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, 1129 index, field, value); 1130 } 1131 1132 /* 1133 * Function: 1134 * _bcm_esw_source_trunk_map_get 1135 * Description: 1136 * Helper funtion to get fields in SOURCE_TRUNK_MAP memory. 1137 * Parameters: 1138 * unit - Device number 1139 * port - Port number 1140 * field - Field name within SOURCE_TRUNK_MAP table entry 1141 * value - New field value 1142 * Return Value: 1143 * BCM_E_XXX 1144 */ 1145 int 1146 _bcm_trx_source_trunk_map_get(int unit, bcm_port_t port, 1147 soc_field_t field, uint32 *value) 1148 { 1149 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; 1150 bcm_module_t mod_out; 1151 bcm_port_t port_out; 1152 int index, trunk_id = -1, id = -1; 1153 1154 /* Input parameters check */ 1155 if (NULL == value) { 1156 return (BCM_E_PARAM); 1157 } 1158 1159 /* Memory field is valid check. */ 1160 if (!SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, field)) { 1161 return (BCM_E_UNAVAIL); 1162 } 1163 1164 #if defined BCM_HGPROXY_COE_SUPPORT 1165 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1166 BCM_GPORT_IS_SET(port) && 1167 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 1168 /* Resolve the port */ 1169 SOC_IF_ERROR_RETURN( 1170 _bcm_esw_gport_resolve(unit, port, &mod_out, 1171 &port_out, &trunk_id, &id)); 1172 } else 1173 #endif 1174 { 1175 if (soc_feature(unit, soc_feature_shg_support_remote_port) && 1176 BCM_GPORT_IS_SET(port) && (field == CLASS_IDf)) { 1177 SOC_IF_ERROR_RETURN( 1178 _bcm_esw_gport_resolve(unit, port, &mod_out, 1179 &port_out, &trunk_id, &id)); 1180 } else { 1181 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 1182 /* Port sanity check. */ 1183 if (SOC_PORT_ADDRESSABLE(unit, port)) { 1184 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out)); 1185 port_out = port; 1186 } else { 1187 return (BCM_E_PORT); 1188 } 1189 } 1190 } 1191 1192 1193 1194 /* Get table index. */ 1195 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 1196 mod_out, port_out, &index)); 1197 1198 if ((index > soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm)) || 1199 (index < soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm))) { 1200 return (BCM_E_INTERNAL); 1201 } 1202 1203 /* Read table entry. */ 1204 BCM_IF_ERROR_RETURN 1205 (soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, index, buf)); 1206 1207 /* Read requested field value. */ 1208 *value = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, buf, field); 1209 1210 return (BCM_E_NONE); 1211 } 1212 1213 /* 1214 * Function: 1215 * _bcm_trx_port_force_vlan_set 1216 * Description: 1217 * To set the force vlan attribute of a port 1218 * Parameters: 1219 * unit device number 1220 * port port number 1221 * vlan vlan identifier 1222 * (0 - 4095) - use this VLAN id if egress packet is tagged 1223 * pkt_prio egress packet priority (-1, 0..7) 1224 * any negative priority value disable the priority 1225 * override if the egress packet is tagged 1226 * flags bit fields 1227 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 1228 * port 1229 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 1230 * vlan is enabled on this port 1231 * 1232 * Return: 1233 * BCM_E_XXX 1234 */ 1235 int 1236 _bcm_trx_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan, 1237 int pkt_prio, uint32 flags) 1238 { 1239 bcm_port_cfg_t pcfg; 1240 uint32 reg_val; 1241 1242 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 1243 1244 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, 1245 &pcfg)); 1246 reg_val = 0; 1247 1248 if (flags & BCM_PORT_FORCE_VLAN_ENABLE) { 1249 if (!BCM_VLAN_VALID(vlan)) { 1250 return BCM_E_PARAM; 1251 } 1252 1253 if (pkt_prio > 7) { 1254 return BCM_E_PARAM; 1255 } 1256 1257 pcfg.pc_pvlan_enable = 1; 1258 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, ®_val, 1259 PVLAN_ENABLEf, 1); 1260 if (!(flags & BCM_PORT_FORCE_VLAN_UNTAG)) { 1261 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, ®_val, 1262 PVLAN_PVIDf, vlan); 1263 if (pkt_prio >= 0) { 1264 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, ®_val, 1265 PVLAN_PRIf, pkt_prio); 1266 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, ®_val, 1267 PVLAN_RPEf, 1); 1268 } 1269 } else { 1270 soc_reg_field_set(unit, EGR_PVLAN_EPORT_CONTROLr, ®_val, 1271 PVLAN_UNTAGf, 1); 1272 } 1273 } else { 1274 pcfg.pc_pvlan_enable = 0; 1275 } 1276 1277 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 1278 SOC_IF_ERROR_RETURN(WRITE_EGR_PVLAN_EPORT_CONTROLr(unit, port, reg_val)); 1279 1280 return BCM_E_NONE; 1281 } 1282 1283 /* 1284 * Function: 1285 * _bcm_trx_port_force_vlan_get 1286 * Description: 1287 * To get the force vlan attribute of a port 1288 * Parameters: 1289 * unit device number 1290 * port port number 1291 * vlan pointer to vlan identifier 1292 * (0 - 4095) - use this VLAN id if egress packet is tagged 1293 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 1294 * BCM_PORT_FORCE_VLAN_UNTAG is clear 1295 * pkt_prio egress packet priority (-1, 0 - 7) 1296 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 1297 * BCM_PORT_FORCE_VLAN_UNTAG is clear 1298 * flags bit fields 1299 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 1300 * port 1301 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 1302 * vlan is enabled on this port 1303 * 1304 * Return: 1305 * BCM_E_XXX 1306 */ 1307 int 1308 _bcm_trx_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan, 1309 int *pkt_prio, uint32 *flags) 1310 { 1311 bcm_port_cfg_t pcfg; 1312 uint32 reg_val; 1313 1314 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 1315 1316 if (!vlan || !pkt_prio || !flags) { 1317 return BCM_E_PARAM; 1318 } 1319 1320 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, 1321 &pcfg)); 1322 SOC_IF_ERROR_RETURN(READ_EGR_PVLAN_EPORT_CONTROLr(unit, port, 1323 ®_val)); 1324 1325 *flags = 0; 1326 if (pcfg.pc_pvlan_enable) { 1327 *flags |= BCM_PORT_FORCE_VLAN_ENABLE; 1328 if (!soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr, reg_val, 1329 PVLAN_UNTAGf)) { 1330 *vlan = soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr, 1331 reg_val, PVLAN_PVIDf); 1332 if (soc_reg_field_get(unit, EGR_PVLAN_EPORT_CONTROLr, reg_val, 1333 PVLAN_RPEf)) { 1334 *pkt_prio = soc_reg_field_get(unit, 1335 EGR_PVLAN_EPORT_CONTROLr, 1336 reg_val, PVLAN_PRIf); 1337 } else { 1338 *pkt_prio = -1; 1339 } 1340 } else { 1341 *flags |= BCM_PORT_FORCE_VLAN_UNTAG; 1342 } 1343 } 1344 1345 return BCM_E_NONE; 1346 } 1347 1348 /* 1349 * Function: 1350 * _bcm_trx_port_dtag_mode_set 1351 * Description: 1352 * Set the double-tagging mode of a port. 1353 * Parameters: 1354 * unit - Device number 1355 * port - Port number 1356 * mode - Double-tagging mode, one of: 1357 * BCM_PORT_DTAG_MODE_NONE No double tagging 1358 * BCM_PORT_DTAG_MODE_INTERNAL Service Provider port 1359 * BCM_PORT_DTAG_MODE_EXTERNAL Customer port 1360 * BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG Remove customer tag 1361 * BCM_PORT_DTAG_ADD_EXTERNAL_TAG Add customer tag 1362 * Return Value: 1363 * BCM_E_XXX 1364 * Notes: 1365 * BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports. 1366 * A tag will be added if the packet does not already 1367 * have the internal TPID (see bcm_port_tpid_set below). 1368 * Internally this sets DT_MODE and clears IGNORE_TAG. 1369 * BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports. 1370 * The service provider TPID will always be added 1371 * (see bcm_port_tpid_set below). 1372 * Internally this sets DT_MODE and sets IGNORE_TAG. 1373 */ 1374 1375 int 1376 _bcm_trx_port_dtag_mode_set(int unit, bcm_port_t port, int mode) 1377 { 1378 bcm_vlan_action_set_t action; 1379 _bcm_port_info_t *pinfo; 1380 int color_mode; 1381 #if defined(BCM_TRX_SUPPORT) 1382 int prev_mode; 1383 int index; 1384 #endif 1385 int rv; 1386 1387 if (!IS_HG_PORT(unit, port)) { 1388 /* Modify default ingress actions */ 1389 BCM_IF_ERROR_RETURN 1390 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 1391 action.dt_outer = bcmVlanActionNone; 1392 action.dt_outer_prio = bcmVlanActionReplace; 1393 action.dt_inner = bcmVlanActionNone; 1394 action.dt_inner_prio = bcmVlanActionNone; 1395 action.ot_outer = bcmVlanActionNone; 1396 action.ot_outer_prio = bcmVlanActionReplace; 1397 action.ot_inner = bcmVlanActionNone; 1398 action.it_outer = bcmVlanActionAdd; 1399 action.it_inner = bcmVlanActionNone; 1400 action.it_inner_prio = bcmVlanActionNone; 1401 action.ut_outer = bcmVlanActionAdd; 1402 if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG) { 1403 action.ut_inner = bcmVlanActionAdd; 1404 } else { 1405 action.ut_inner = bcmVlanActionNone; 1406 } 1407 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 1408 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1409 rv = _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action); 1410 } else 1411 #endif 1412 { 1413 rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action); 1414 } 1415 BCM_IF_ERROR_RETURN(rv); 1416 1417 /* Modify default egress actions */ 1418 rv = _bcm_trx_vlan_port_egress_default_action_get(unit, port, &action); 1419 BCM_IF_ERROR_RETURN(rv); 1420 1421 action.ot_inner = bcmVlanActionNone; 1422 if (mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) { 1423 action.dt_inner = bcmVlanActionDelete; 1424 action.dt_inner_prio = bcmVlanActionDelete; 1425 } else { 1426 action.dt_inner = bcmVlanActionNone; 1427 action.dt_inner_prio = bcmVlanActionNone; 1428 } 1429 action.dt_outer = bcmVlanActionNone; 1430 action.dt_outer_prio = bcmVlanActionNone; 1431 action.ot_outer = bcmVlanActionNone; 1432 action.ot_outer_prio = bcmVlanActionNone; 1433 rv = _bcm_trx_vlan_port_egress_default_action_set(unit, port, &action); 1434 BCM_IF_ERROR_RETURN(rv); 1435 } 1436 1437 rv = _bcm_port_info_get(unit, port, &pinfo); 1438 BCM_IF_ERROR_RETURN(rv); 1439 1440 #if defined(BCM_TRX_SUPPORT) 1441 prev_mode = pinfo->dtag_mode; 1442 #endif 1443 pinfo->dtag_mode = mode; 1444 mode &= BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL; 1445 1446 #if defined(BCM_TRX_SUPPORT) 1447 /* return if previous mode and current mode are same */ 1448 if(prev_mode & mode) { 1449 return BCM_E_NONE; 1450 } 1451 #endif 1452 if (mode == BCM_PORT_DTAG_MODE_NONE) { 1453 /* Set the default outer TPID. */ 1454 rv = bcm_esw_port_tpid_set(unit, port, 1455 _bcm_fb2_outer_tpid_default_get(unit)); 1456 BCM_IF_ERROR_RETURN(rv); 1457 } else if (mode == BCM_PORT_DTAG_MODE_INTERNAL) { 1458 /* Add the default outer TPID. */ 1459 rv = bcm_esw_switch_control_port_get(unit, port, 1460 bcmSwitchColorSelect, &color_mode); 1461 BCM_IF_ERROR_RETURN(rv); 1462 1463 rv = bcm_esw_port_tpid_add(unit, port, _bcm_fb2_outer_tpid_default_get(unit), 1464 color_mode); 1465 BCM_IF_ERROR_RETURN(rv); 1466 1467 } else if (mode == BCM_PORT_DTAG_MODE_EXTERNAL) { 1468 /* Disable all outer TPIDs. */ 1469 BCM_IF_ERROR_RETURN (bcm_esw_port_tpid_delete_all(unit, port)); 1470 } 1471 #if defined(BCM_TRX_SUPPORT) 1472 /* Increase the ref count of the default tpid if the mode 1473 * is changing to internal/none from external */ 1474 if (prev_mode & BCM_PORT_DTAG_MODE_EXTERNAL) { 1475 rv = _bcm_fb2_outer_tpid_lkup(unit, _bcm_fb2_outer_tpid_default_get(unit), 1476 &index); 1477 BCM_IF_ERROR_RETURN(rv); 1478 1479 rv = _bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1); 1480 BCM_IF_ERROR_RETURN(rv); 1481 } 1482 #endif 1483 return BCM_E_NONE; 1484 } 1485 1486 /* 1487 * Function: 1488 * _bcm_trx_port_control_egress_class_select_set 1489 * Description: 1490 * Helper funtion to modify fields in FP_I2E_CLASSID_SELECT/IFP_I2E_CLASSID_SELECTm memory. 1491 * Parameters: 1492 * unit - (IN) Device number 1493 * port - (IN) Port number 1494 * value - (IN) new field value 1495 * Return Value: 1496 * BCM_E_XXX 1497 */ 1498 int 1499 _bcm_trx_port_control_egress_class_select_set(int unit, bcm_port_t port, 1500 uint32 value) 1501 { 1502 int rv = BCM_E_NONE; 1503 soc_mem_t mem; 1504 1505 if (SOC_MEM_IS_VALID(unit, FP_I2E_CLASSID_SELECTm)) { 1506 mem = FP_I2E_CLASSID_SELECTm; 1507 } 1508 else if (SOC_MEM_IS_VALID(unit, IFP_I2E_CLASSID_SELECTm)) { 1509 /* For TOMAHAWK IFP_I2E_CLASSID_SELECTm is used */ 1510 mem = IFP_I2E_CLASSID_SELECTm; 1511 } 1512 else { 1513 return SOC_E_UNAVAIL; 1514 } 1515 1516 /* Check for valid input for I2E_CLASSID_SELECT*/ 1517 /* coverity[unsigned_compare] : FALSE */ 1518 if ((value < bcmPortEgressClassSelectNone) || 1519 (value >= bcmPortEgressClassSelectCount)) { 1520 return (BCM_E_PARAM); 1521 } 1522 1523 switch (value) { 1524 case bcmPortEgressClassSelectFieldIngress: 1525 #if defined(BCM_TRIDENT2_SUPPORT) 1526 if (SOC_IS_TRIDENT2(unit)) { 1527 value = 0xf; /* IFD_CLASS_ID bit */ 1528 } else 1529 #endif /* BCM_TRIDENT2_SUPPORT */ 1530 return BCM_E_UNAVAIL; 1531 break; 1532 default: 1533 break; 1534 } 1535 1536 /* Port sanity check. */ 1537 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 1538 return (BCM_E_PORT); 1539 } 1540 1541 #ifdef BCM_TRIDENT3_SUPPORT 1542 /* In TD3, IFP_I2E_CLASSID_SELECT is indexed by * 1543 * LPORT_PROFILE_TABLE.MISC_PORT_PROFILE_INDEX. * 1544 * * 1545 * The LPORT_PROFILE_TABLE is indexed from the * 1546 * SOURCE_TRUNK_MAP_TABLE Lport_profile_idx field. */ 1547 1548 if (SOC_IS_TRIDENT3X(unit) && (mem == IFP_I2E_CLASSID_SELECTm)) { 1549 int src_index; 1550 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 1551 int src_tbl_is_stm = 1; 1552 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 1553 1554 lport_tab_entry_t lport_entry; 1555 uint32 lport_index = 0; 1556 1557 BCM_IF_ERROR_RETURN 1558 (bcm_esw_port_lport_prof_src_check(unit, _BCM_ESW_PT_PORT, 1559 &src_tbl_is_stm)); 1560 1561 if (src_tbl_is_stm) { 1562 int modid = 0; 1563 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &modid)); 1564 BCM_IF_ERROR_RETURN 1565 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 1566 &src_index)); 1567 } else { 1568 src_mem = ING_DEVICE_PORTm; 1569 src_index = port; 1570 } 1571 1572 BCM_IF_ERROR_RETURN 1573 (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent)); 1574 lport_index = soc_mem_field32_get(unit, src_mem, 1575 src_ent, LPORT_PROFILE_IDXf); 1576 1577 BCM_IF_ERROR_RETURN(READ_LPORT_TABm(unit, MEM_BLOCK_ANY, 1578 lport_index, &lport_entry)); 1579 1580 soc_LPORT_TABm_field32_set(unit, &lport_entry, 1581 MISC_PORT_PROFILE_INDEXf, port); 1582 1583 BCM_IF_ERROR_RETURN(WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, 1584 lport_index, &lport_entry)); 1585 } 1586 #endif /* BCM_TRIDENT3_SUPPORT */ 1587 1588 /* Memory field is valid check. */ 1589 if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) { 1590 return (BCM_E_UNAVAIL); 1591 } 1592 1593 rv = soc_mem_field32_modify(unit, mem, port, PORT_SELf, value); 1594 1595 return rv; 1596 } 1597 1598 /* 1599 * Function: 1600 * _bcm_trx_port_control_egress_class_select_get 1601 * Description: 1602 * Helper funtion to get fields in FP_I2E_CLASSID_SELECT/IFP_I2E_CLASSID_SELECTm memory. 1603 * Parameters: 1604 * unit - (IN) Device number 1605 * port - (IN) Port number 1606 * value - (OUT) New field value 1607 * Return Value: 1608 * BCM_E_XXX 1609 */ 1610 int 1611 _bcm_trx_port_control_egress_class_select_get(int unit, bcm_port_t port, 1612 uint32 *value) 1613 { 1614 fp_i2e_classid_select_entry_t fp_ent; 1615 ifp_i2e_classid_select_entry_t ifp_ent; 1616 soc_mem_t mem; 1617 void *ptr_ent; 1618 1619 if (SOC_MEM_IS_VALID(unit, FP_I2E_CLASSID_SELECTm)) { 1620 mem = FP_I2E_CLASSID_SELECTm; 1621 ptr_ent = (void*) &fp_ent; 1622 } 1623 else if (SOC_MEM_IS_VALID(unit, IFP_I2E_CLASSID_SELECTm)) { 1624 /* For TOMAHAWK IFP_I2E_CLASSID_SELECTm is used */ 1625 mem = IFP_I2E_CLASSID_SELECTm; 1626 ptr_ent = (void*) &ifp_ent; 1627 } 1628 else { 1629 return SOC_E_UNAVAIL; 1630 } 1631 1632 /* Memory field is valid check. */ 1633 if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) { 1634 return (BCM_E_UNAVAIL); 1635 } 1636 1637 /* Port sanity check. */ 1638 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 1639 return (BCM_E_PORT); 1640 } 1641 1642 /* Read table entry. */ 1643 BCM_IF_ERROR_RETURN 1644 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, ptr_ent)); 1645 1646 /* Read requested field value. */ 1647 *value = soc_mem_field32_get(unit, mem, ptr_ent, PORT_SELf); 1648 return BCM_E_NONE; 1649 1650 } 1651 1652 /* 1653 * Function: 1654 * _bcm_trx_port_control_higig_class_select_set 1655 * Description: 1656 * Helper funtion to modify fields in FP_HG_CLASSID_SELECT memory. 1657 * Parameters: 1658 * unit - (IN) Device number 1659 * port - (IN) Port number 1660 * value - (IN) new field value 1661 * Return Value: 1662 * BCM_E_XXX 1663 */ 1664 int 1665 _bcm_trx_port_control_higig_class_select_set(int unit, bcm_port_t port, 1666 uint32 value) 1667 { 1668 int rv = BCM_E_NONE; 1669 soc_mem_t mem; 1670 1671 /* Check for valid input for I2E_CLASSID_SELECT*/ 1672 /* coverity[unsigned_compare] : FALSE */ 1673 if ((value < bcmPortFieldHiGigClassSelectNone) || 1674 (value >= bcmPortFieldHiGigClassSelectCount)) { 1675 return (BCM_E_PARAM); 1676 } 1677 1678 /* Value 2 and 3 are reserved for TD2/TD2+/TH/APACHE chips*/ 1679 #if defined(BCM_TRIDENT2_SUPPORT) 1680 if (SOC_IS_TD2_TT2(unit)) { 1681 if ((value == bcmPortFieldHiGigClassSelectL3Egress) || 1682 (value == bcmPortFieldHiGigClassSelectL3EgressIntf)) { 1683 return (BCM_E_PARAM); 1684 } 1685 } 1686 #endif 1687 1688 if (SOC_IS_TOMAHAWKX(unit)) { 1689 mem = IFP_HG_CLASSID_SELECTm; 1690 } else { 1691 mem = FP_HG_CLASSID_SELECTm; 1692 } 1693 1694 /* Memory field is valid check. */ 1695 if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) { 1696 return (BCM_E_UNAVAIL); 1697 } 1698 1699 /* Port sanity check. */ 1700 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 1701 return (BCM_E_PORT); 1702 } 1703 1704 rv = soc_mem_field32_modify(unit, mem, port, PORT_SELf, value); 1705 1706 return rv; 1707 } 1708 1709 /* 1710 * Function: 1711 * _bcm_trx_port_control_higig_class_select_get 1712 * Description: 1713 * Helper funtion to get fields in FP_HG_CLASSID_SELECT memory. 1714 * Parameters: 1715 * unit - (IN) Device number 1716 * port - (IN) Port number 1717 * value - (OUT) New field value 1718 * Return Value: 1719 * BCM_E_XXX 1720 */ 1721 int 1722 _bcm_trx_port_control_higig_class_select_get(int unit, bcm_port_t port, 1723 uint32 *value) 1724 { 1725 soc_mem_t mem; 1726 1727 #if defined(BCM_TOMAHAWK_SUPPORT) 1728 if (SOC_IS_TOMAHAWKX(unit)) { 1729 ifp_hg_classid_select_entry_t ent; 1730 mem = IFP_HG_CLASSID_SELECTm; 1731 1732 /* Memory field is valid check. */ 1733 if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) { 1734 return (BCM_E_UNAVAIL); 1735 } 1736 1737 /* Port sanity check. */ 1738 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 1739 return (BCM_E_PORT); 1740 } 1741 1742 /* Read table entry. */ 1743 BCM_IF_ERROR_RETURN 1744 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent)); 1745 1746 /* Read requested field value. */ 1747 *value = soc_mem_field32_get(unit, mem, &ent, PORT_SELf); 1748 } else 1749 #endif 1750 { 1751 fp_hg_classid_select_entry_t ent; 1752 mem = FP_HG_CLASSID_SELECTm; 1753 1754 /* Memory field is valid check. */ 1755 if (!SOC_MEM_FIELD_VALID(unit, mem, PORT_SELf)) { 1756 return (BCM_E_UNAVAIL); 1757 } 1758 1759 /* Port sanity check. */ 1760 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 1761 return (BCM_E_PORT); 1762 } 1763 1764 /* Read table entry. */ 1765 BCM_IF_ERROR_RETURN 1766 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent)); 1767 1768 /* Read requested field value. */ 1769 *value = soc_mem_field32_get(unit, mem, &ent, PORT_SELf); 1770 } 1771 1772 return BCM_E_NONE; 1773 } 1774 1775 /* 1776 * Function: 1777 * bcm_trx_source_trunk_map_lport_all_set 1778 * Purpose: 1779 * Set the LPORT profile index reference for all entries 1780 * in the Source Trunk Map Table. 1781 * Helper routine. 1782 * Parameters: 1783 * unit - (IN) Device number 1784 * lport_index - (IN) LPORT Index 1785 * stm_num_entries - (OUT) Returns number of entries in table 1786 * Returns: 1787 * BCM_E_XXX 1788 */ 1789 STATIC int 1790 bcm_trx_source_table_lport_all_set(int unit, uint32 lport_index, 1791 int *src_num_entries) 1792 { 1793 int rv = BCM_E_NONE; 1794 int i, m; 1795 #if defined(BCM_TOMAHAWK3_SUPPORT) 1796 int pipe; 1797 soc_info_t *si; 1798 source_trunk_map_table_entry_t stm_ent; 1799 int stm_entry_per_pipe; 1800 #endif 1801 soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm}; 1802 uint32 *src_entry; 1803 int index_min, index_max; 1804 uint32 *stm_buf; 1805 1806 #ifdef BCM_TOMAHAWK3_SUPPORT 1807 /* This code is added to support the non-contiguous pipes (0, 1, 6,7 half chip or 1808 bond option 0, 1, 4, 5) in TH3. Since this memory is addr_split in TH3, we cannot 1809 use mem_read/write_range as only certain blocks of entries are valid. With this 1810 check of checking if the pipe is active we make sure that only the entries which 1811 are valid are accessed 1812 */ 1813 if (SOC_IS_TOMAHAWK3(unit)) { 1814 1815 si = &SOC_INFO(unit); 1816 index_min = soc_mem_index_min(unit, src_mem[0]); 1817 index_max = soc_mem_index_max(unit, src_mem[0]); 1818 *src_num_entries = index_max - index_min + 1; 1819 stm_entry_per_pipe = *src_num_entries / _TH3_PIPES_PER_DEV; 1820 for (i = 0; i < *src_num_entries; i++) { 1821 pipe = i / stm_entry_per_pipe; 1822 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 1823 continue; 1824 } 1825 SOC_IF_ERROR_RETURN( 1826 READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 1827 i, &stm_ent)); 1828 1829 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_ent, 1830 LPORT_PROFILE_IDXf, 1831 lport_index); 1832 1833 SOC_IF_ERROR_RETURN(WRITE_SOURCE_TRUNK_MAP_TABLEm(unit,MEM_BLOCK_ALL, 1834 i, &stm_ent)); 1835 } 1836 return BCM_E_NONE; 1837 } 1838 else 1839 #endif 1840 { 1841 if (soc_mem_is_valid(unit, ING_DEVICE_PORTm)) { 1842 src_mem[1] = ING_DEVICE_PORTm; 1843 } 1844 1845 for (m = 0; m < 2; m++) { 1846 if (src_mem[m] == INVALIDm) { 1847 continue; 1848 } 1849 1850 index_min = soc_mem_index_min(unit, src_mem[m]); 1851 index_max = soc_mem_index_max(unit, src_mem[m]); 1852 *src_num_entries = index_max - index_min + 1; 1853 stm_buf = soc_cm_salloc(unit, 1854 (*src_num_entries) * 1855 (WORDS2BYTES(soc_mem_entry_words(unit, src_mem[m]))), 1856 "Source Trunk Map table buffer"); 1857 if (stm_buf == NULL) { 1858 return BCM_E_MEMORY; 1859 } 1860 1861 soc_mem_lock(unit, src_mem[m]); 1862 rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY, 1863 index_min, index_max, 1864 stm_buf); 1865 if (SOC_SUCCESS(rv)) { 1866 for (i = 0; i < *src_num_entries; i++) { 1867 src_entry = 1868 soc_mem_table_idx_to_pointer(unit, src_mem[m], void *, stm_buf, i); 1869 soc_mem_field32_set(unit, src_mem[m], src_entry, LPORT_PROFILE_IDXf, 1870 lport_index); 1871 } 1872 rv = soc_mem_write_range(unit, src_mem[m], MEM_BLOCK_ANY, 1873 index_min, index_max, 1874 stm_buf); 1875 } 1876 1877 soc_mem_unlock(unit, src_mem[m]); 1878 soc_cm_sfree(unit, stm_buf); 1879 1880 if (BCM_FAILURE(rv)) { 1881 break; 1882 } 1883 } 1884 1885 } 1886 return rv; 1887 } 1888 1889 /* 1890 * Function: 1891 * _bcm_trx_lport_tab_default_entry_index_get 1892 * Purpose: 1893 * Return the default LPORT profile entry index. 1894 * Parameters: 1895 * unit - (IN) Device number 1896 * Returns: 1897 * Default LPORT profile entry index. 1898 */ 1899 int 1900 _bcm_trx_lport_tab_default_entry_index_get(int unit) 1901 { 1902 return soc_mem_index_min(unit, LPORT_TABm); 1903 } 1904 1905 /* 1906 * Function: 1907 * _bcm_trx_egr_lport_tab_default_entry_index_get 1908 * Purpose: 1909 * Return the default LPORT profile entry index. 1910 * Parameters: 1911 * unit - (IN) Device number 1912 * Returns: 1913 * Default LPORT profile entry index. 1914 */ 1915 int 1916 _bcm_trx_egr_lport_tab_default_entry_index_get(int unit) 1917 { 1918 return soc_mem_index_min(unit, EGR_LPORT_PROFILEm); 1919 } 1920 1921 /* 1922 * Function: 1923 * _bcm_trx_rtag7_tab_default_entry_index_get 1924 * Purpose: 1925 * Return the default RTAG7 profile entry index. 1926 * Parameters: 1927 * unit - (IN) Device number 1928 * Returns: 1929 * Default LPORT profile entry index. 1930 */ 1931 int 1932 _bcm_trx_rtag7_tab_default_entry_index_get(int unit) 1933 { 1934 return soc_mem_index_min(unit, RTAG7_PORT_BASED_HASHm); 1935 } 1936 1937 /* 1938 * Function: 1939 * _bcm_trx_lport_tab_default_entry_add 1940 * Purpose: 1941 * Internal function for initializing common resource management 1942 * Shared by Virtual-port based modules 1943 * Parameters: 1944 * unit - (IN) Device number. 1945 * prof - (IN) LPORT memory profile. 1946 * Returns: 1947 * BCM_X_XXX 1948 */ 1949 int 1950 _bcm_trx_lport_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 1951 { 1952 int rv = BCM_E_NONE; 1953 soc_info_t *si; 1954 lport_tab_entry_t lport_entry; 1955 rtag7_port_based_hash_entry_t rtag7_entry; 1956 uint32 lport_index; 1957 void *entries[2]; 1958 bcm_module_t my_modid=0; 1959 int stab_num_entries = 0; 1960 int i; 1961 #ifdef BCM_TOMAHAWK3_SUPPORT 1962 int entries_per_pipe; 1963 #endif 1964 1965 /* Input parameters check. */ 1966 if (NULL == prof) { 1967 return (BCM_E_PARAM); 1968 } 1969 1970 si = &SOC_INFO(unit); 1971 1972 sal_memcpy(&lport_entry, soc_mem_entry_null(unit, LPORT_TABm), 1973 soc_mem_entry_words(unit, LPORT_TABm) * sizeof(uint32)); 1974 1975 if (SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 1976 sal_memcpy(&rtag7_entry, 1977 soc_mem_entry_null(unit, RTAG7_PORT_BASED_HASHm), 1978 soc_mem_entry_words(unit, RTAG7_PORT_BASED_HASHm) * 1979 sizeof(uint32)); 1980 } 1981 1982 /* Create a default LPORT profile entry */ 1983 rv = bcm_esw_stk_my_modid_get(unit, &my_modid); 1984 if (rv < 0) { 1985 return rv; 1986 } 1987 1988 /* Enable IFP. */ 1989 soc_LPORT_TABm_field32_set(unit, &lport_entry, FILTER_ENABLEf, 1); 1990 1991 /* Enable VFP. */ 1992 if (!(SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit))) { 1993 soc_LPORT_TABm_field32_set(unit, &lport_entry, VFP_ENABLEf, 1); 1994 } 1995 1996 /* Set port filed select index to PFS index max - 1. */ 1997 if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, FP_PORT_FIELD_SEL_INDEXf)) { 1998 soc_LPORT_TABm_field32_set(unit, &lport_entry, FP_PORT_FIELD_SEL_INDEXf, 1999 (soc_mem_index_max(unit, FP_PORT_FIELD_SELm) 2000 - 1)); 2001 } 2002 2003 /* Enable MPLS */ 2004 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MPLS_ENABLEf)) { 2005 soc_LPORT_TABm_field32_set(unit, &lport_entry, MPLS_ENABLEf, 1); 2006 } 2007 2008 /* Enable TRILL */ 2009 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, TRILL_ENABLEf)) { 2010 soc_LPORT_TABm_field32_set(unit, &lport_entry, TRILL_ENABLEf, 1); 2011 } 2012 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, ALLOW_TRILL_FRAMESf)) { 2013 soc_LPORT_TABm_field32_set(unit, &lport_entry, ALLOW_TRILL_FRAMESf, 1); 2014 } 2015 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, ALLOW_NON_TRILL_FRAMESf)) { 2016 soc_LPORT_TABm_field32_set(unit, &lport_entry, 2017 ALLOW_NON_TRILL_FRAMESf, 1); 2018 } 2019 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, COPY_CORE_IS_IS_TO_CPUf)) { 2020 soc_LPORT_TABm_field32_set(unit, &lport_entry, 2021 COPY_CORE_IS_IS_TO_CPUf, 1); 2022 } 2023 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) { 2024 soc_LPORT_TABm_field32_set(unit, &lport_entry, 2025 RTAG7_HASH_CFG_SEL_TRILL_ECMPf, 1); 2026 } 2027 2028 /* Enable OAM */ 2029 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OAM_ENABLEf)) { 2030 soc_LPORT_TABm_field32_set(unit, &lport_entry, OAM_ENABLEf, 1); 2031 } 2032 2033 /* Enable MIM */ 2034 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MIM_TERM_ENABLEf)) { 2035 soc_LPORT_TABm_field32_set(unit, &lport_entry, MIM_TERM_ENABLEf, 1); 2036 } 2037 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MIM_MC_TERM_ENABLEf)) { 2038 soc_LPORT_TABm_field32_set(unit, &lport_entry, MIM_MC_TERM_ENABLEf, 1); 2039 } 2040 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, SRC_SYS_PORT_IDf)) { 2041 soc_LPORT_TABm_field32_set(unit, &lport_entry, SRC_SYS_PORT_IDf, 2042 si->lb_port); 2043 } 2044 2045 if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MY_MODIDf)) { 2046 soc_LPORT_TABm_field32_set(unit, &lport_entry, MY_MODIDf, my_modid); 2047 } 2048 2049 #ifdef BCM_MONTEREY_SUPPORT 2050 if (SOC_IS_MONTEREY(unit) && soc_feature(unit, soc_feature_xflow_macsec)) { 2051 if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, PORT_VIDf)) { 2052 soc_LPORT_TABm_field32_set(unit, &lport_entry, PORT_VIDf, 2053 BCM_VLAN_DEFAULT); 2054 if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OUTER_TPID_ENABLEf)) { 2055 soc_LPORT_TABm_field32_set(unit, &lport_entry, 2056 OUTER_TPID_ENABLEf, 1); 2057 } 2058 } 2059 } 2060 #endif 2061 2062 /* Add LPORT default entry */ 2063 entries[0] = &lport_entry; 2064 entries[1] = &rtag7_entry; 2065 2066 /* Note that when 'soc_feature_separate_ing_lport_rtag7_profile' is TRUE 2067 we only set the LPORT index and not RTAG7, but this one call will suffice 2068 since the entries[0] will point to 'lport' entry, the entries[1] which 2069 points to RTAG7 will only be used in the case when the mentioned 2070 feature is FALSE, wherein the 'prof' passed in would be acting on an 2071 older profiling scheme */ 2072 2073 /* Tomahawk 3 made this memory on a per pipe unique, so we're going to add 2074 * a default entry into index 0 of each pipe 2075 */ 2076 #ifdef BCM_TOMAHAWK3_SUPPORT 2077 if (SOC_IS_TOMAHAWK3(unit) && SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 2078 for (i = 0; i < _TH3_PIPES_PER_DEV; i++) { 2079 rv = soc_profile_mem_add_unique(unit, prof, entries, 1, i, &lport_index); 2080 } 2081 } else 2082 #endif 2083 { 2084 rv = soc_profile_mem_add(unit, prof, entries, 1, &lport_index); 2085 } 2086 2087 if (lport_index != _bcm_trx_lport_tab_default_entry_index_get(unit)) { 2088 /* Something went horribly wrong. */ 2089 return (BCM_E_INTERNAL); 2090 } 2091 2092 /* Update all entries in SOURCE_TRUNK_MAP to use LPORT default entry */ 2093 BCM_IF_ERROR_RETURN 2094 (bcm_trx_source_table_lport_all_set(unit, lport_index, 2095 &stab_num_entries)); 2096 2097 /* Update reference count (keep 1 extra count) */ 2098 for (i = 0; i < stab_num_entries; i++) { 2099 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 2100 BCM_IF_ERROR_RETURN 2101 (_bcm_lport_ind_profile_mem_reference(unit, lport_index, 1)); 2102 } else { 2103 #ifdef BCM_TOMAHAWK3_SUPPORT 2104 /* This adds a reference count to the first index of the per pipe 2105 * memory: 2106 * example: 2107 * LPORT_TAB_PIPE0 index 0's ref_count == 21 2108 * LPORT_TAB_PIPE1 index 0's ref_count == 21 2109 */ 2110 if (SOC_IS_TOMAHAWK3(unit) && SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 2111 /* Fetches the # of entries per pipe. This is so that 2112 * the function call below will increase the ref_count on a per 2113 * pipe basis 2114 */ 2115 entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm); 2116 BCM_IF_ERROR_RETURN 2117 (_bcm_lport_profile_mem_reference_unique( 2118 unit, lport_index, 1, i/entries_per_pipe)); 2119 } else 2120 #endif 2121 { 2122 BCM_IF_ERROR_RETURN 2123 (_bcm_lport_profile_mem_reference(unit, lport_index, 1)); 2124 } 2125 } 2126 } 2127 2128 return rv; 2129 } 2130 2131 /* 2132 * Function: 2133 * _bcm_trx_egr_lport_tab_default_entry_add 2134 * Purpose: 2135 * Internal function for initializing common resource management 2136 * Shared by Virtual-port based modules 2137 * Parameters: 2138 * unit - (IN) Device number. 2139 * prof - (IN) LPORT memory profile. 2140 * Returns: 2141 * BCM_X_XXX 2142 */ 2143 int 2144 _bcm_trx_egr_lport_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 2145 { 2146 int rv = BCM_E_NONE; 2147 int index = 0; 2148 uint32 egr_lport_index; 2149 void *entries[9]; 2150 egr_lport_profile_entry_t egr_lport_profile_entry; 2151 egr_vlan_control_1_entry_t egr_vlan_control_1_entry; 2152 egr_vlan_control_2_entry_t egr_vlan_control_2_entry; 2153 egr_vlan_control_3_entry_t egr_vlan_control_3_entry; 2154 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2_entry; 2155 egr_mtu_entry_t egr_mtu_entry; 2156 egr_port_1_entry_t egr_port_1_entry; 2157 egr_counter_control_entry_t egr_counter_control_entry; 2158 egr_shaping_control_entry_t egr_shaping_control_entry; 2159 2160 /* Input parameters check. */ 2161 if (NULL == prof) { 2162 return (BCM_E_PARAM); 2163 } 2164 2165 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 2166 sal_memcpy(&egr_lport_profile_entry, 2167 soc_mem_entry_null(unit, EGR_LPORT_PROFILEm), 2168 soc_mem_entry_words(unit, EGR_LPORT_PROFILEm) * 2169 sizeof(uint32)); 2170 entries[index++] = &egr_lport_profile_entry; 2171 } 2172 2173 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 2174 sal_memcpy(&egr_vlan_control_1_entry, 2175 soc_mem_entry_null(unit, EGR_VLAN_CONTROL_1m), 2176 soc_mem_entry_words(unit, EGR_VLAN_CONTROL_1m) * 2177 sizeof(uint32)); 2178 entries[index++] = &egr_vlan_control_1_entry; 2179 } 2180 2181 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 2182 sal_memcpy(&egr_vlan_control_2_entry, 2183 soc_mem_entry_null(unit, EGR_VLAN_CONTROL_2m), 2184 soc_mem_entry_words(unit, EGR_VLAN_CONTROL_2m) * 2185 sizeof(uint32)); 2186 entries[index++] = &egr_vlan_control_2_entry; 2187 } 2188 2189 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 2190 sal_memcpy(&egr_vlan_control_3_entry, 2191 soc_mem_entry_null(unit, EGR_VLAN_CONTROL_3m), 2192 soc_mem_entry_words(unit, EGR_VLAN_CONTROL_3m) * 2193 sizeof(uint32)); 2194 entries[index++] = &egr_vlan_control_3_entry; 2195 } 2196 2197 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 2198 sal_memcpy(&egr_ipmc_cfg2_entry, 2199 soc_mem_entry_null(unit, EGR_IPMC_CFG2m), 2200 soc_mem_entry_words(unit, EGR_IPMC_CFG2m) * 2201 sizeof(uint32)); 2202 entries[index++] = &egr_ipmc_cfg2_entry; 2203 } 2204 2205 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 2206 sal_memcpy(&egr_mtu_entry, 2207 soc_mem_entry_null(unit, EGR_MTUm), 2208 soc_mem_entry_words(unit, EGR_MTUm) * 2209 sizeof(uint32)); 2210 entries[index++] = &egr_mtu_entry; 2211 } 2212 2213 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 2214 sal_memcpy(&egr_port_1_entry, 2215 soc_mem_entry_null(unit, EGR_PORT_1m), 2216 soc_mem_entry_words(unit, EGR_PORT_1m) * 2217 sizeof(uint32)); 2218 entries[index++] = &egr_port_1_entry; 2219 } 2220 2221 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 2222 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 2223 sal_memcpy(&egr_counter_control_entry, 2224 soc_mem_entry_null(unit, EGR_COUNTER_CONTROLm), 2225 soc_mem_entry_words(unit, EGR_COUNTER_CONTROLm) * 2226 sizeof(uint32)); 2227 entries[index++] = &egr_counter_control_entry; 2228 } 2229 2230 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 2231 sal_memcpy(&egr_shaping_control_entry, 2232 soc_mem_entry_null(unit, EGR_SHAPING_CONTROLm), 2233 soc_mem_entry_words(unit, EGR_SHAPING_CONTROLm) * 2234 sizeof(uint32)); 2235 entries[index++] = &egr_shaping_control_entry; 2236 } 2237 } 2238 2239 if (index > 0) { 2240 BCM_IF_ERROR_RETURN( 2241 soc_profile_mem_add(unit, prof, entries, 1, &egr_lport_index)); 2242 if (egr_lport_index != 2243 _bcm_trx_egr_lport_tab_default_entry_index_get(unit)) { 2244 /* Something went horribly wrong. */ 2245 rv = BCM_E_INTERNAL; 2246 } 2247 } 2248 2249 return rv; 2250 } 2251 2252 /* 2253 * Function: 2254 * _bcm_trx_rtag7_tab_default_entry_add 2255 * Purpose: 2256 * Internal function for initializing RTAG7 default 2257 * entry 2258 * Parameters: 2259 * unit - (IN) Device number. 2260 * prof - (IN) LPORT memory profile. 2261 * Returns: 2262 * BCM_X_XXX 2263 */ 2264 int 2265 _bcm_trx_rtag7_tab_default_entry_add(int unit, soc_profile_mem_t *prof) 2266 { 2267 rtag7_port_based_hash_entry_t rtag7_entry; 2268 void *entries[1]; 2269 uint32 rtag7_index; 2270 int stm_num_entries = 0, i; 2271 2272 /* Input parameters check. */ 2273 if (NULL == prof) { 2274 return (BCM_E_PARAM); 2275 } 2276 2277 if (SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 2278 sal_memcpy(&rtag7_entry, 2279 soc_mem_entry_null(unit, RTAG7_PORT_BASED_HASHm), 2280 soc_mem_entry_words(unit, RTAG7_PORT_BASED_HASHm) * 2281 sizeof(uint32)); 2282 } 2283 2284 entries[0] = &rtag7_entry; 2285 2286 BCM_IF_ERROR_RETURN( 2287 soc_profile_mem_add(unit, prof, entries, 1, &rtag7_index)); 2288 2289 if (rtag7_index != _bcm_trx_rtag7_tab_default_entry_index_get(unit)) { 2290 /* Something went horribly wrong. */ 2291 return (BCM_E_INTERNAL); 2292 } 2293 if (SOC_IS_TRIDENT3X(unit)) { 2294 /* Update reference count (keep 1 extra count) */ 2295 stm_num_entries = soc_mem_index_max(unit, 2296 SOURCE_TRUNK_MAP_TABLEm) - soc_mem_index_min(unit, 2297 SOURCE_TRUNK_MAP_TABLEm) + 1; 2298 for (i = 0; i < stm_num_entries; i++) { 2299 BCM_IF_ERROR_RETURN 2300 (_bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1)); 2301 } 2302 } 2303 return BCM_E_NONE; 2304 } 2305 2306 /* 2307 * Function: 2308 * _bcm_trx_gport_to_nhi_set 2309 * Purpose: 2310 * set EGR_PORT_TO_NHI_MAPPINGr or EGR_DGPP_TO_NHIm 2311 * Parameters: 2312 * unit - (IN) Device number. 2313 * gport - (IN) modport gport. 2314 * nh_index - (IN) nexthop index. 2315 * Returns: 2316 * BCM_E_XXX 2317 */ 2318 int 2319 _bcm_trx_gport_to_nhi_set(int unit, int gport, int nh_index) 2320 { 2321 int rv = 0; 2322 int port; 2323 #ifdef BCM_TRIDENT2PLUS_SUPPORT 2324 int modid; 2325 uint32 dgpp = 0; 2326 uint32 modbase = 0; 2327 egr_dgpp_to_nhi_modbase_entry_t mem_val; 2328 #endif 2329 if (nh_index < 0) { 2330 return BCM_E_PARAM; 2331 } 2332 if (!BCM_GPORT_IS_MODPORT(gport)) { 2333 return BCM_E_PARAM; 2334 } 2335 2336 port = BCM_GPORT_MODPORT_PORT_GET(gport); 2337 2338 if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 2339 rv = soc_reg_field32_modify(unit, EGR_PORT_TO_NHI_MAPPINGr, 2340 port, NEXT_HOP_INDEXf, nh_index); 2341 } 2342 #ifdef BCM_TRIDENT2PLUS_SUPPORT 2343 else { 2344 modid = BCM_GPORT_MODPORT_MODID_GET(gport); 2345 BCM_IF_ERROR_RETURN( 2346 READ_EGR_DGPP_TO_NHI_MODBASEm(unit, MEM_BLOCK_ANY, modid, &mem_val)); 2347 modbase = soc_mem_field32_get(unit, EGR_DGPP_TO_NHI_MODBASEm, 2348 &mem_val, BASEf); 2349 dgpp = modbase + port; 2350 rv = soc_mem_field32_modify(unit, EGR_DGPP_TO_NHIm, 2351 dgpp, NEXT_HOP_INDEXf, nh_index); 2352 } 2353 #endif 2354 return rv; 2355 } 2356 2357 /* 2358 * Function: 2359 * _bcm_trx_gport_to_nhi_get 2360 * Purpose: 2361 * get EGR_PORT_TO_NHI_MAPPINGr or EGR_DGPP_TO_NHIm 2362 * Parameters: 2363 * unit - (IN) Device number. 2364 * gport - (IN) modport gport. 2365 * nh_index - (OUT) nexthop index ptr. 2366 * Returns: 2367 * BCM_E_XXX 2368 */ 2369 2370 int 2371 _bcm_trx_gport_to_nhi_get(int unit, int gport, int* nh_index) 2372 { 2373 uint32 reg_val=0; 2374 int port; 2375 #ifdef BCM_TRIDENT2PLUS_SUPPORT 2376 int modid; 2377 uint32 modbase = 0; 2378 uint32 dgpp = 0; 2379 egr_dgpp_to_nhi_modbase_entry_t mem_val1; 2380 egr_dgpp_to_nhi_entry_t mem_val2; 2381 #endif 2382 if (!BCM_GPORT_IS_MODPORT(gport)) { 2383 return BCM_E_PARAM; 2384 } 2385 2386 port = BCM_GPORT_MODPORT_PORT_GET(gport); 2387 2388 if (!soc_feature(unit, soc_feature_egr_modport_to_nhi)) { 2389 BCM_IF_ERROR_RETURN( 2390 READ_EGR_PORT_TO_NHI_MAPPINGr(unit, port, ®_val)); 2391 *nh_index = soc_reg_field_get(unit, EGR_PORT_TO_NHI_MAPPINGr, reg_val, 2392 NEXT_HOP_INDEXf); 2393 } 2394 #ifdef BCM_TRIDENT2PLUS_SUPPORT 2395 else { 2396 /* TD2+ */ 2397 modid = BCM_GPORT_MODPORT_MODID_GET(gport); 2398 BCM_IF_ERROR_RETURN( 2399 READ_EGR_DGPP_TO_NHI_MODBASEm(unit, MEM_BLOCK_ANY, modid, &mem_val1)); 2400 modbase = soc_mem_field32_get(unit, EGR_DGPP_TO_NHI_MODBASEm, 2401 &mem_val1, BASEf); 2402 dgpp = modbase + port; 2403 BCM_IF_ERROR_RETURN( 2404 READ_EGR_DGPP_TO_NHIm(unit, MEM_BLOCK_ANY, dgpp, &mem_val2)); 2405 *nh_index = soc_mem_field32_get(unit, EGR_DGPP_TO_NHIm, &mem_val2, 2406 NEXT_HOP_INDEXf); 2407 } 2408 #endif 2409 return BCM_E_NONE; 2410 } 2411 #else /* BCM_TRX_SUPPORT */ 2412 int bcm_esw_trx_port_not_empty; 2413 #endif /* BCM_TRX_SUPPORT */ 2414