port.c (40934B)
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 8 #include <soc/defs.h> 9 10 #include <assert.h> 11 12 #include <sal/core/libc.h> 13 #if defined(BCM_TRIUMPH2_SUPPORT) 14 15 #include <shared/util.h> 16 #include <soc/mem.h> 17 #include <soc/cm.h> 18 #include <soc/drv.h> 19 #include <soc/register.h> 20 #include <soc/memory.h> 21 #include <bcm/port.h> 22 #include <bcm/error.h> 23 #include <bcm_int/esw/triumph2.h> 24 #include <bcm_int/esw/port.h> 25 #include <bcm_int/esw/firebolt.h> 26 #include <bcm_int/esw/trx.h> 27 #include <bcm_int/esw/virtual.h> 28 #include <bcm_int/esw/xgs3.h> 29 #include <bcm_int/esw/trident2.h> 30 31 STATIC SHR_BITDCL *vpd_bitmap[BCM_MAX_NUM_UNITS]; 32 #define _VLAN_PROTOCOL_DATA_PROF_USED_GET(_u_, _vpd_) \ 33 SHR_BITGET(vpd_bitmap[_u_], (_vpd_)) 34 #define _VLAN_PROTOCOL_DATA_PROF_USED_SET(_u_, _vpd_) \ 35 SHR_BITSET(vpd_bitmap[_u_], (_vpd_)) 36 #define _VLAN_PROTOCOL_DATA_PROF_USED_CLR(_u_, _vpd_) \ 37 SHR_BITCLR(vpd_bitmap[_u_], (_vpd_)) 38 39 int 40 _bcm_tr2_port_vpd_bitmap_alloc(int unit) 41 { 42 int num_profiles; 43 if (vpd_bitmap[unit]) { 44 sal_free(vpd_bitmap[unit]); 45 vpd_bitmap[unit] = NULL; 46 } 47 num_profiles = soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm) / 48 soc_mem_index_count(unit, VLAN_PROTOCOLm); 49 vpd_bitmap[unit] = sal_alloc(SHR_BITALLOCSIZE(num_profiles), 50 "vpd_bitmap"); 51 if (vpd_bitmap[unit] == NULL) { 52 return BCM_E_MEMORY; 53 } 54 sal_memset(vpd_bitmap[unit], 0, SHR_BITALLOCSIZE(num_profiles)); 55 return BCM_E_NONE; 56 } 57 58 void 59 _bcm_tr2_port_vpd_bitmap_free(int unit) 60 { 61 if (vpd_bitmap[unit]) { 62 sal_free(vpd_bitmap[unit]); 63 } 64 vpd_bitmap[unit] = NULL; 65 return; 66 } 67 68 int 69 _bcm_port_vlan_prot_index_alloc(int unit, int *prof_ptr) 70 { 71 int i, num_profiles; 72 num_profiles = soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm) / 73 soc_mem_index_count(unit, VLAN_PROTOCOLm); 74 for (i = 0; i < num_profiles; i++) { 75 if (!_VLAN_PROTOCOL_DATA_PROF_USED_GET(unit, i)) { 76 _VLAN_PROTOCOL_DATA_PROF_USED_SET(unit, i); 77 *prof_ptr = i * soc_mem_index_count(unit, VLAN_PROTOCOLm); 78 break; 79 } 80 } 81 if (i == num_profiles) { 82 #ifdef BCM_KATANA2_SUPPORT 83 84 if (SOC_IS_KATANA2(unit)) { 85 *prof_ptr = i * soc_mem_index_count(unit, VLAN_PROTOCOLm); 86 return BCM_E_NONE; 87 } 88 #endif 89 return BCM_E_RESOURCE; 90 } else { 91 return BCM_E_NONE; 92 } 93 } 94 95 /* 96 * Function: 97 * _bcm_port_vlan_prot_index_free 98 * Purpose: 99 * Free given VLAN protocol profile index. 100 * Parameters: 101 * unit - (IN) Unit number. 102 * prof_ptr - (IN) VLAN Protocol Profile index. 103 * Returns: 104 * BCM_E_XXX 105 * Notes: 106 */ 107 int 108 _bcm_port_vlan_prot_index_free(int unit, int prof_ptr) 109 { 110 int index; 111 int num_profiles; 112 113 num_profiles = soc_mem_index_count(unit, VLAN_PROTOCOL_DATAm) / 114 soc_mem_index_count(unit, VLAN_PROTOCOLm); 115 116 index = prof_ptr / soc_mem_index_count(unit, VLAN_PROTOCOLm); 117 118 if ((index < 0) || (index >= num_profiles)) { 119 return BCM_E_INTERNAL; 120 } 121 122 _VLAN_PROTOCOL_DATA_PROF_USED_CLR(unit, index); 123 124 return BCM_E_NONE; 125 } 126 127 int 128 _bcm_tr2_port_tab_get(int unit, bcm_port_t port, 129 soc_field_t field, int *value) 130 131 { 132 port_tab_entry_t pent; 133 soc_mem_t mem; 134 int rv = BCM_E_NONE; 135 136 mem = SOC_PORT_MEM_TAB(unit, port); 137 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 138 return (BCM_E_UNAVAIL); 139 } 140 sal_memset(&pent, 0, sizeof(port_tab_entry_t)); 141 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 142 SOC_PORT_MOD_OFFSET(unit, port), &pent); 143 144 if (BCM_SUCCESS(rv)) { 145 *value = soc_PORT_TABm_field32_get(unit, &pent, field); 146 } 147 return rv; 148 } 149 150 151 /* Port table field programming - assumes PORT_LOCK is taken */ 152 int 153 _bcm_tr2_port_tab_set(int unit, bcm_port_t port, 154 soc_field_t field, int value) 155 156 { 157 port_tab_entry_t pent; 158 soc_mem_t mem; 159 int rv, cur_val; 160 161 mem = SOC_PORT_MEM_TAB(unit, port); 162 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 163 return (BCM_E_UNAVAIL); 164 } 165 sal_memset(&pent, 0, sizeof(port_tab_entry_t)); 166 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 167 SOC_PORT_MOD_OFFSET(unit, port), &pent); 168 169 if (BCM_SUCCESS(rv)) { 170 cur_val = soc_PORT_TABm_field32_get(unit, &pent, field); 171 if (value != cur_val) { 172 soc_PORT_TABm_field32_set(unit, &pent, field, value); 173 rv = soc_mem_write(unit, mem, 174 MEM_BLOCK_ALL, port, &pent); 175 } 176 } 177 return rv; 178 } 179 180 /* Helper functions for bcmPortControlLanes 181 * Used for flex-port support 182 */ 183 int 184 _bcm_tr2_port_lanes_get(int unit, bcm_port_t port, int *value) 185 { 186 int rv = BCM_E_NONE; 187 uint32 rval, bitpos = 0; 188 /* coverity[new_values] */ 189 190 if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 191 return (BCM_E_PORT); 192 } 193 194 switch (port) { 195 case 30: 196 bitpos = 6; 197 break; 198 case 34: 199 bitpos = 7; 200 break; 201 case 38: 202 bitpos = 8; 203 break; 204 case 42: 205 bitpos = 9; 206 break; 207 case 46: 208 bitpos = 10; 209 break; 210 case 50: 211 bitpos = 11; 212 break; 213 214 /* Defensive Default */ 215 /* coverity[dead_error_begin] */ 216 default: 217 return (BCM_E_PORT); 218 } 219 220 BCM_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval)); 221 222 if (rval & (1 << bitpos)) { 223 *value = 4; 224 } else { 225 *value = 1; 226 } 227 return rv; 228 } 229 230 static const uint16 _soc_triumph2_int_phy_addr[] = { 231 0x00, /* Port 0 (cmic) N/A */ 232 0x99, /* Port 1 (9SERDES) IntBus=0 Addr=0x19 */ 233 0x81, /* Port 2 (8SERDES_0) IntBus=0 Addr=0x01 */ 234 0x82, /* Port 3 (8SERDES_0) IntBus=0 Addr=0x02 */ 235 0x83, /* Port 4 (8SERDES_0) IntBus=0 Addr=0x03 */ 236 0x84, /* Port 5 (8SERDES_0) IntBus=0 Addr=0x04 */ 237 0x85, /* Port 6 (8SERDES_0) IntBus=0 Addr=0x05 */ 238 0x86, /* Port 7 (8SERDES_0) IntBus=0 Addr=0x06 */ 239 0x87, /* Port 8 (8SERDES_0) IntBus=0 Addr=0x07 */ 240 0x88, /* Port 9 (8SERDES_0) IntBus=0 Addr=0x08 */ 241 0x89, /* Port 10 (8SERDES_1) IntBus=0 Addr=0x09 */ 242 0x8a, /* Port 11 (8SERDES_1) IntBus=0 Addr=0x0a */ 243 0x8b, /* Port 12 (8SERDES_1) IntBus=0 Addr=0x0b */ 244 0x8c, /* Port 13 (8SERDES_1) IntBus=0 Addr=0x0c */ 245 0x8d, /* Port 14 (8SERDES_1) IntBus=0 Addr=0x0d */ 246 0x8e, /* Port 15 (8SERDES_1) IntBus=0 Addr=0x0e */ 247 0x8f, /* Port 16 (8SERDES_1) IntBus=0 Addr=0x0f */ 248 0x90, /* Port 17 (8SERDES_1) IntBus=0 Addr=0x10 */ 249 0x91, /* Port 18 (9SERDES) IntBus=0 Addr=0x11 */ 250 0x92, /* Port 19 (9SERDES) IntBus=0 Addr=0x12 */ 251 0x93, /* Port 20 (9SERDES) IntBus=0 Addr=0x13 */ 252 0x94, /* Port 21 (9SERDES) IntBus=0 Addr=0x14 */ 253 0x95, /* Port 22 (9SERDES) IntBus=0 Addr=0x15 */ 254 0x96, /* Port 23 (9SERDES) IntBus=0 Addr=0x16 */ 255 0x97, /* Port 24 (9SERDES) IntBus=0 Addr=0x17 */ 256 0x98, /* Port 25 (9SERDES) IntBus=0 Addr=0x18 */ 257 0xd9, /* Port 26 (HC0) IntBus=2 Addr=0x19 */ 258 0xda, /* Port 27 (HC1) IntBus=2 Addr=0x1a */ 259 0xdb, /* Port 28 (HC2) IntBus=2 Addr=0x1b */ 260 0xdc, /* Port 29 (HC3) IntBus=2 Addr=0x1c */ 261 0xc1, /* Port 30 (HL0) IntBus=2 Addr=0x01 */ 262 0xc2, /* Port 31 (HL0) IntBus=2 Addr=0x02 */ 263 0xc3, /* Port 32 (HL0) IntBus=2 Addr=0x03 */ 264 0xc4, /* Port 33 (HL0) IntBus=2 Addr=0x04 */ 265 0xc5, /* Port 34 (HL1) IntBus=2 Addr=0x05 */ 266 0xc6, /* Port 35 (HL1) IntBus=2 Addr=0x06 */ 267 0xc7, /* Port 36 (HL1) IntBus=2 Addr=0x07 */ 268 0xc8, /* Port 37 (HL1) IntBus=2 Addr=0x08 */ 269 0xc9, /* Port 38 (HL2) IntBus=2 Addr=0x09 */ 270 0xca, /* Port 39 (HL2) IntBus=2 Addr=0x0a */ 271 0xcb, /* Port 40 (HL2) IntBus=2 Addr=0x0b */ 272 0xcc, /* Port 41 (HL2) IntBus=2 Addr=0x0c */ 273 0xcd, /* Port 42 (HL3) IntBus=2 Addr=0x0d */ 274 0xce, /* Port 43 (HL3) IntBus=2 Addr=0x0e */ 275 0xcf, /* Port 44 (HL3) IntBus=2 Addr=0x0f */ 276 0xd0, /* Port 45 (HL3) IntBus=2 Addr=0x10 */ 277 0xd1, /* Port 46 (HL4) IntBus=2 Addr=0x11 */ 278 0xd2, /* Port 47 (HL4) IntBus=2 Addr=0x12 */ 279 0xd3, /* Port 48 (HL4) IntBus=2 Addr=0x13 */ 280 0xd4, /* Port 49 (HL4) IntBus=2 Addr=0x14 */ 281 0xd5, /* Port 50 (HL5) IntBus=2 Addr=0x15 */ 282 0xd6, /* Port 51 (HL5) IntBus=2 Addr=0x16 */ 283 0xd7, /* Port 52 (HL5) IntBus=2 Addr=0x17 */ 284 0xd8, /* Port 53 (HL5) IntBus=2 Addr=0x18 */ 285 }; 286 287 int 288 _bcm_tr2_port_lanes_set(int unit, bcm_port_t port, int value) 289 { 290 uint16 dev_id; 291 uint8 rev_id; 292 int i, okay, old_value, count, rv = BCM_E_NONE; 293 uint32 rval, val2, to_usec, mode, flags, bitpos = 0; 294 uint64 rval64; 295 soc_info_t *si; 296 soc_field_t xq_rst2 = INVALIDf; 297 uint16 phy0, phy1, phy2, phy3; 298 bcm_port_t it_port; 299 iarb_tdm_table_entry_t iarb_tdm; 300 arb_tdm_table_entry_t arb_tdm; 301 mac_driver_t *macd; 302 303 si = &SOC_INFO(unit); 304 305 soc_cm_get_id(unit, &dev_id, &rev_id); 306 307 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 308 (10 * MILLISECOND_USEC); 309 310 if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 311 return BCM_E_PORT; 312 } 313 314 if ((value != 1) && (value != 4)) { 315 return BCM_E_PARAM; 316 } 317 BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value)); 318 319 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \ 320 si->ptype.num = 0; \ 321 si->ptype.min = si->ptype.max = -1; \ 322 PBMP_ITER(si->ptype.bitmap, it_port) { \ 323 si->ptype.port[si->ptype.num++] = it_port; \ 324 if (si->ptype.min < 0) { \ 325 si->ptype.min = it_port; \ 326 } \ 327 if (it_port > si->ptype.max) { \ 328 si->ptype.max = it_port; \ 329 } \ 330 } 331 332 /* Step 1: Change the SOC bitmaps */ 333 if ((value == 1) && (old_value == 4)) { 334 /* The block was originally a single high-speed port */ 335 SOC_CONTROL_LOCK(unit); 336 if (IS_HG_PORT(unit, port)) { 337 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 338 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 339 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 340 } else { 341 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 342 } 343 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 344 si->port_speed_max[port] = 1000; 345 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE); 346 for (i = port + 1; i < port + 4; i++) { 347 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i); 348 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i); 349 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i); 350 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i); 351 si->port_speed_max[i] = 1000; 352 soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE); 353 } 354 RECONFIGURE_PORT_TYPE_INFO(ether); 355 RECONFIGURE_PORT_TYPE_INFO(st); 356 RECONFIGURE_PORT_TYPE_INFO(hg); 357 RECONFIGURE_PORT_TYPE_INFO(xe); 358 RECONFIGURE_PORT_TYPE_INFO(ge); 359 SOC_CONTROL_UNLOCK(unit); 360 BCM_IF_ERROR_RETURN(_bcm_tr2_port_tab_set(unit, port, PORT_TYPEf, 0)); 361 BCM_IF_ERROR_RETURN 362 (soc_reg_field32_modify(unit, EGR_PORT_64r, port, PORT_TYPEf, 0)); 363 } else if ((value == 4) && (old_value == 1)) { 364 /* The block originally had 4 GE ports */ 365 SOC_CONTROL_LOCK(unit); 366 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 367 SOC_PBMP_PORT_ADD(si->hg.bitmap, port); 368 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 369 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 370 switch (dev_id) { 371 case BCM56526_DEVICE_ID: 372 si->port_speed_max[port] = 13000; 373 break; 374 case BCM56636_DEVICE_ID: 375 case BCM56638_DEVICE_ID: 376 si->port_speed_max[port] = 12000; 377 break; 378 default: 379 si->port_speed_max[port] = 10000; 380 } 381 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE); 382 for (i = port + 1; i < port + 4; i++) { 383 SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i); 384 SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i); 385 SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i); 386 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i); 387 } 388 RECONFIGURE_PORT_TYPE_INFO(ether); 389 RECONFIGURE_PORT_TYPE_INFO(st); 390 RECONFIGURE_PORT_TYPE_INFO(hg); 391 RECONFIGURE_PORT_TYPE_INFO(ge); 392 SOC_CONTROL_UNLOCK(unit); 393 BCM_IF_ERROR_RETURN(_bcm_tr2_port_tab_set(unit, port, PORT_TYPEf, 1)); 394 BCM_IF_ERROR_RETURN 395 (soc_reg_field32_modify(unit, EGR_PORT_64r, port, PORT_TYPEf, 1)); 396 } 397 #undef RECONFIGURE_PORT_TYPE_INFO 398 soc_dport_map_update(unit); 399 400 /* Step 2: Perform necessary block-level reset and initialization */ 401 /* Egress disable */ 402 rval = 0; 403 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 0); 404 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval)); 405 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 1, rval)); 406 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 2, rval)); 407 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 3, rval)); 408 409 /* Hold the XQPORT hotswap reset */ 410 switch (port) { 411 case 30: 412 bitpos = 6; 413 xq_rst2 = XQ0_HOTSWAP_RST_Lf; 414 break; 415 case 34: 416 bitpos = 7; 417 xq_rst2 = XQ1_HOTSWAP_RST_Lf; 418 break; 419 case 38: 420 bitpos = 8; 421 xq_rst2 = XQ2_HOTSWAP_RST_Lf; 422 break; 423 case 42: 424 bitpos = 9; 425 xq_rst2 = XQ3_HOTSWAP_RST_Lf; 426 break; 427 case 46: 428 bitpos = 10; 429 xq_rst2 = XQ4_HOTSWAP_RST_Lf; 430 break; 431 case 50: 432 bitpos = 11; 433 xq_rst2 = XQ5_HOTSWAP_RST_Lf; 434 break; 435 default: 436 break; 437 } 438 /* coverity[result_independent_of_operands] */ 439 BCM_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REG_2r(unit, &val2)); 440 soc_reg_field_set(unit, CMIC_SOFT_RESET_REG_2r, &val2, 441 xq_rst2, 0); 442 /* coverity[result_independent_of_operands] */ 443 BCM_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REG_2r(unit, val2)); 444 sal_usleep(to_usec); 445 446 /* Program the ingress and MMU TDMs */ 447 count = -1; 448 for (i = 0; i < soc_mem_index_count(unit, ARB_TDM_TABLEm); i++) { 449 BCM_IF_ERROR_RETURN 450 (READ_ARB_TDM_TABLEm(unit, MEM_BLOCK_ANY, i, &arb_tdm)); 451 BCM_IF_ERROR_RETURN 452 (READ_IARB_TDM_TABLEm(unit, MEM_BLOCK_ANY, i, &iarb_tdm)); 453 it_port = soc_ARB_TDM_TABLEm_field32_get(unit, &arb_tdm, PORT_NUMf); 454 /* First set to disabled - 63 */ 455 if (old_value == value) { 456 continue; 457 } else if (old_value == 4 && value == 1) { 458 if (port != it_port) { 459 continue; 460 } 461 } else { 462 if ((it_port != port) && (it_port != port + 1) && 463 (it_port != port + 2) && (it_port != port + 3)) { 464 continue; 465 } 466 } 467 soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 63); 468 soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 63); 469 BCM_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 470 &iarb_tdm)); 471 BCM_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 472 &arb_tdm)); 473 /* Then program the desired value */ 474 if (old_value == 4 && value == 1) { 475 count++; 476 soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, 477 port + (count % 4)); 478 soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, 479 port + (count % 4)); 480 } else { 481 soc_ARB_TDM_TABLEm_field32_set(unit, &arb_tdm, PORT_NUMf, port); 482 soc_IARB_TDM_TABLEm_field32_set(unit, &iarb_tdm, PORT_NUMf, port); 483 } 484 BCM_IF_ERROR_RETURN(WRITE_IARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 485 &iarb_tdm)); 486 BCM_IF_ERROR_RETURN(WRITE_ARB_TDM_TABLEm(unit, MEM_BLOCK_ALL, i, 487 &arb_tdm)); 488 if (soc_ARB_TDM_TABLEm_field32_get(unit, &arb_tdm, WRAP_ENf)) { 489 break; 490 } 491 } 492 493 /* Clear the ECRC register */ 494 for (i = port; i < port + 4; i++) { 495 BCM_IF_ERROR_RETURN(WRITE_TOQ_EP_CREDITr(unit, i, 0)); 496 } 497 498 /* Reset the EP */ 499 BCM_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval)); 500 rval |= (1 << (bitpos - 6)); 501 BCM_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval)); 502 sal_usleep(to_usec); 503 BCM_IF_ERROR_RETURN(READ_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, &rval)); 504 if (value == 4) { 505 rval |= (1 << bitpos); 506 } else { 507 rval &= ~(1 << bitpos); 508 } 509 /* coverity[BAD_SHIFT: FALSE] */ 510 rval &= ~(1 << (bitpos - 6)); 511 BCM_IF_ERROR_RETURN(WRITE_EDATABUF_XQP_FLEXPORT_CONFIGr(unit, rval)); 512 sal_usleep(to_usec); 513 514 /* Bring the XQPORT block out of reset */ 515 /* coverity[result_independent_of_operands] */ 516 BCM_IF_ERROR_RETURN(READ_CMIC_SOFT_RESET_REG_2r(unit, &val2)); 517 soc_reg_field_set(unit, CMIC_SOFT_RESET_REG_2r, &val2, 518 xq_rst2, 1); 519 /* coverity[result_independent_of_operands] */ 520 BCM_IF_ERROR_RETURN(WRITE_CMIC_SOFT_RESET_REG_2r(unit, val2)); 521 sal_usleep(to_usec); 522 523 /* Bring the hyperlite out of reset */ 524 soc_xgxs_reset(unit, port); 525 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XQPORT_XGXS_NEWCTL_REGr, 526 port, TXD1G_FIFO_RSTBf, 0xf)); 527 528 /* Change the XQPORT block mode */ 529 mode = (value == 4) ? 2 : 1; /* 2 = high-speed, 1 = GE */ 530 SOC_IF_ERROR_RETURN(READ_XQPORT_MODE_REGr(unit, port, &rval)); 531 soc_reg_field_set(unit, XQPORT_MODE_REGr, &rval, 532 XQPORT_MODE_BITSf, mode); 533 SOC_IF_ERROR_RETURN(WRITE_XQPORT_MODE_REGr(unit, port, rval)); 534 if (value == 4) { 535 rval = 0; 536 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, XPORT_ENf, 1); 537 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf, 1); 538 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, rval)); 539 } 540 541 /* Egress Enable */ 542 rval = 0; 543 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 1); 544 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port, rval)); 545 546 rval = 0; 547 soc_reg_field_set(unit, EGR_ENABLEr, &rval, PRT_ENABLEf, 548 (value == 1) ? 1 : 0); 549 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 1, rval)); 550 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 2, rval)); 551 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEr(unit, port + 3, rval)); 552 553 /* Step 3: Port probe and initialization */ 554 flags = 0; 555 if (value == 1) { 556 phy0 = soc_property_port_get(unit, port, spn_FLEX_PORT_PHY_ADDR, 0); 557 if (!phy0) { 558 phy0 = _soc_triumph2_int_phy_addr[port]; 559 flags = _SHR_PORT_PHY_INTERNAL; 560 } 561 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 562 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port, flags, phy0)); 563 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 564 if (!okay) { 565 return BCM_E_INTERNAL; 566 } 567 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE)); 568 phy1 = soc_property_port_get(unit, port + 1, spn_FLEX_PORT_PHY_ADDR, 0); 569 if (!phy1) { 570 phy1 = _soc_triumph2_int_phy_addr[port + 1]; 571 flags = _SHR_PORT_PHY_INTERNAL; 572 } 573 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 574 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 1, flags, phy1)); 575 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 1, &okay)); 576 if (!okay) { 577 return BCM_E_INTERNAL; 578 } 579 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 1, TRUE)); 580 phy2 = soc_property_port_get(unit, port + 2, spn_FLEX_PORT_PHY_ADDR, 0); 581 if (!phy2) { 582 phy2 = _soc_triumph2_int_phy_addr[port + 2]; 583 flags = _SHR_PORT_PHY_INTERNAL; 584 } 585 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 586 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 2, flags, phy2)); 587 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 2, &okay)); 588 if (!okay) { 589 return BCM_E_INTERNAL; 590 } 591 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 2, TRUE)); 592 phy3 = soc_property_port_get(unit, port + 3, spn_FLEX_PORT_PHY_ADDR, 0); 593 if (!phy3) { 594 phy3 = _soc_triumph2_int_phy_addr[port + 3]; 595 flags = _SHR_PORT_PHY_INTERNAL; 596 } 597 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 598 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + 3, flags, phy3)); 599 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + 3, &okay)); 600 if (!okay) { 601 return BCM_E_INTERNAL; 602 } 603 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + 3, TRUE)); 604 } else { 605 phy0 = soc_property_port_get(unit, port, spn_FLEX_PORT_PHY_ADDR, 0); 606 if (!phy0) { 607 phy0 = _soc_triumph2_int_phy_addr[port]; 608 flags = _SHR_PORT_PHY_INTERNAL; 609 } 610 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 611 if (old_value == 1) { 612 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 613 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 614 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 615 } 616 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port, flags, phy0)); 617 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 618 if (!okay) { 619 return BCM_E_INTERNAL; 620 } 621 622 /* Need to reset the Bigmac to make registers accessible */ 623 SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd)); 624 625 SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64)); 626 soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, TXRESETf, 1); 627 soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, RXRESETf, 1); 628 SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64)); 629 630 SOC_IF_ERROR_RETURN(READ_MAC_CTRLr(unit, port, &rval64)); 631 soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, TXRESETf, 0); 632 soc_reg64_field32_set(unit, MAC_CTRLr, &rval64, RXRESETf, 0); 633 SOC_IF_ERROR_RETURN(WRITE_MAC_CTRLr(unit, port, rval64)); 634 635 SOC_IF_ERROR_RETURN(MAC_INIT(macd, unit, port)); 636 637 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE)); 638 } 639 return rv; 640 } 641 642 int _bcm_tr2_ing_pri_cng_map_default_entry_add(int unit, 643 soc_profile_mem_t *prof) 644 { 645 ing_pri_cng_map_entry_t pri_map[16]; 646 phb_mapping_tbl_1_entry_t phb_pri_map[16]; 647 ing_untagged_phb_entry_t phb; 648 int index, pkt_pri, cfi, base = 0; 649 void *entries[2]; 650 651 sal_memset(pri_map, 0, sizeof(ing_pri_cng_map_entry_t) * 16); 652 sal_memset(&phb, 0, sizeof(phb)); 653 654 for (cfi = 0; cfi <= 1; cfi++) { 655 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) { 656 index = (pkt_pri << 1) | cfi; 657 if (SOC_IS_TRIDENT3X(unit)) { 658 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_pri_map[index], PRIf, 659 pkt_pri); 660 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_pri_map[index], 661 CNGf, cfi); 662 } else { 663 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index], PRIf, 664 pkt_pri); 665 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index], 666 CNGf, cfi); 667 } 668 } 669 } 670 if (SOC_IS_TRIDENT3X(unit)) { 671 entries[0] = &phb_pri_map; 672 } else { 673 entries[0] = &pri_map; 674 } 675 676 /** Revisit ---- No ING_UNTAGGED_PHB found in Trident3 */ 677 entries[1] = &phb; 678 BCM_IF_ERROR_RETURN 679 (soc_profile_mem_add(unit, prof, entries, 16, (uint32 *)&base)); 680 681 if (SOC_IS_TRIDENT3X(unit)) { 682 if (base != soc_mem_index_min(unit, PHB_MAPPING_TBL_1m)) { 683 return BCM_E_INTERNAL; 684 } 685 } else { 686 if (base != soc_mem_index_min(unit, ING_PRI_CNG_MAPm)) { 687 return BCM_E_INTERNAL; 688 } 689 } 690 691 return BCM_E_NONE; 692 } 693 694 /* 695 * Function: 696 * _bcm_tr2_port_vlan_priority_map_get 697 * Description: 698 * Get the mapping of incomming port, packet priority, and cfi bit to 699 * switch internal priority and color. 700 * Parameters: 701 * unit - (IN) Device number 702 * port - (IN) Port number 703 * pkt_pri - (IN) Packet priority 704 * cfi - (IN) Packet CFI 705 * internal_pri - (OUT) Internal priority 706 * color - (OUT) color 707 * Return Value: 708 * BCM_E_XXX 709 * Note: 710 * This API programs only the mapping table. 711 */ 712 int 713 _bcm_tr2_port_vlan_priority_map_get(int unit, bcm_port_t port, int pkt_pri, 714 int cfi, int *internal_pri, 715 bcm_color_t *color) 716 { 717 port_tab_entry_t pent; 718 ing_pri_cng_map_entry_t pri_cng_entry; 719 phb_mapping_tbl_1_entry_t phb_pri_map; 720 int rv; 721 int index; 722 int hw_color; 723 int ptr; 724 725 sal_memset(&pent, 0, sizeof(port_tab_entry_t)); 726 sal_memset(&pri_cng_entry, 0, sizeof(ing_pri_cng_map_entry_t)); 727 728 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 729 SOC_PORT_MOD_OFFSET(unit, port), &pent); 730 BCM_IF_ERROR_RETURN(rv); 731 732 ptr = soc_PORT_TABm_field32_get(unit, &pent, TRUST_DOT1P_PTRf); 733 734 index = ((pkt_pri << 1) | cfi) + (ptr * _BCM_TR2_PRI_CNG_MAP_SIZE); 735 736 if (SOC_IS_TRIDENT3X(unit)) { 737 rv = soc_mem_read(unit, PHB_MAPPING_TBL_1m, MEM_BLOCK_ANY, 738 index, &phb_pri_map); 739 740 *internal_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, 741 (uint32 *)&phb_pri_map, PRIf); 742 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, 743 (uint32 *)&phb_pri_map, CNGf); 744 } else { 745 rv = soc_mem_read(unit, ING_PRI_CNG_MAPm, MEM_BLOCK_ANY, 746 index, &pri_cng_entry); 747 748 *internal_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, 749 (uint32 *)&pri_cng_entry, PRIf); 750 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, 751 (uint32 *)&pri_cng_entry, CNGf); 752 } 753 754 *color = _BCM_COLOR_DECODING(unit, hw_color); 755 return (rv); 756 } 757 758 /* 759 * Function: 760 * _bcm_tr2_port_vlan_priority_map_set 761 * Description: 762 * Define the mapping of incomming port, packet priority, and cfi bit to 763 * switch internal priority and color. 764 * Parameters: 765 * unit - (IN) Device number 766 * port - (IN) Port number 767 * pkt_pri - (IN) Packet priority 768 * cfi - (IN) Packet CFI 769 * internal_pri - (IN) Internal priority 770 * color - (IN) color 771 * Return Value: 772 * BCM_E_XXX 773 * Note: 774 * This API programs only the mapping table. 775 */ 776 int 777 _bcm_tr2_port_vlan_priority_map_set(int unit, bcm_port_t port, int pkt_pri, 778 int cfi, int internal_pri, bcm_color_t color) 779 { 780 ing_pri_cng_map_entry_t pri_cng_map[_BCM_TR2_PRI_CNG_MAP_SIZE]; 781 phb_mapping_tbl_1_entry_t phb_pri_cng_map[_BCM_TR2_PRI_CNG_MAP_SIZE]; 782 void *entries[1]; 783 port_tab_entry_t pent; 784 int index; 785 int rv; 786 int new_ptr; 787 int old_ptr; 788 char *pri_map; 789 int alloc_size; 790 791 /* Allocate buffer for dma read. */ 792 alloc_size = _BCM_TR2_PRI_CNG_MAP_SIZE * sizeof (ing_pri_cng_map_entry_t); 793 pri_map = soc_cm_salloc(unit, alloc_size, "TR2 pri cng map"); 794 if (NULL == pri_map) { 795 return (BCM_E_MEMORY); 796 } 797 sal_memset(pri_map, 0, alloc_size); 798 sal_memset(pri_cng_map, 0, alloc_size); 799 800 /* Get man id from port table. */ 801 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 802 SOC_PORT_MOD_OFFSET(unit, port), &pent); 803 if (BCM_FAILURE(rv)) { 804 soc_cm_sfree(unit, pri_map); 805 return (rv); 806 } 807 old_ptr = soc_PORT_TABm_field32_get(unit, &pent, TRUST_DOT1P_PTRf); 808 809 if (SOC_IS_TRIDENT3X(unit)) { 810 /* Get the existing profile chunk */ 811 index = old_ptr * _BCM_TR2_PRI_CNG_MAP_SIZE; 812 rv = soc_mem_read_range(unit, PHB_MAPPING_TBL_1m, MEM_BLOCK_ANY, 813 index, index + _BCM_TR2_PRI_CNG_MAP_SIZE - 1, 814 pri_map); 815 if (BCM_FAILURE(rv)) { 816 soc_cm_sfree(unit, pri_map); 817 return (rv); 818 } 819 for (index = 0; index < _BCM_TR2_PRI_CNG_MAP_SIZE; index++) { 820 entries[0] = soc_mem_table_idx_to_pointer(unit, PHB_MAPPING_TBL_1m, 821 void *, pri_map, index); 822 sal_memcpy(phb_pri_cng_map + index, entries[0], 823 sizeof(phb_mapping_tbl_1_entry_t)); 824 } 825 } else { 826 /* Get the existing profile chunk */ 827 index = old_ptr * _BCM_TR2_PRI_CNG_MAP_SIZE; 828 rv = soc_mem_read_range(unit, ING_PRI_CNG_MAPm, MEM_BLOCK_ANY, 829 index, index + _BCM_TR2_PRI_CNG_MAP_SIZE - 1, 830 pri_map); 831 if (BCM_FAILURE(rv)) { 832 soc_cm_sfree(unit, pri_map); 833 return (rv); 834 } 835 for (index = 0; index < _BCM_TR2_PRI_CNG_MAP_SIZE; index++) { 836 entries[0] = soc_mem_table_idx_to_pointer(unit, ING_PRI_CNG_MAPm, 837 void *, pri_map, index); 838 sal_memcpy(pri_cng_map + index, entries[0], 839 sizeof(ing_pri_cng_map_entry_t)); 840 } 841 842 } 843 844 /* When invoked from bcm_port_cfi_color_set, color for a particular 845 * cfi and port needs to be programmed for all priorities. 846 * To identify this special case, 847 * both pkt_pri and internal_pri are set to -1. 848 */ 849 if (pkt_pri < 0 && internal_pri < 0) { 850 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) { 851 index = (pkt_pri << 1) | cfi; 852 if (SOC_IS_TRIDENT3X(unit)) { 853 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, (uint32 *)&phb_pri_cng_map[index], 854 PRIf, pkt_pri); 855 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, (uint32 *)&phb_pri_cng_map[index], 856 CNGf, _BCM_COLOR_ENCODING(unit, color)); 857 } else { 858 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index], 859 PRIf, pkt_pri); 860 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index], 861 CNGf, _BCM_COLOR_ENCODING(unit, color)); 862 } 863 } 864 } else { 865 /* Modify what's needed */ 866 index = (pkt_pri << 1) | cfi; 867 868 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index], 869 PRIf, internal_pri); 870 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index], 871 CNGf, _BCM_COLOR_ENCODING(unit, color)); 872 } 873 874 /* Delete the old profile chunk */ 875 if (old_ptr != 0) { 876 index = _BCM_TR2_PRI_CNG_MAP_SIZE * old_ptr; 877 rv = _bcm_ing_pri_cng_map_entry_delete(unit, index); 878 if (BCM_FAILURE(rv)) { 879 soc_cm_sfree(unit, pri_map); 880 return (rv); 881 } 882 } 883 884 /* Add and point to the new profile chunk */ 885 entries[0] = pri_cng_map; 886 rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 887 _BCM_TR2_PRI_CNG_MAP_SIZE, 888 (uint32 *)&new_ptr); 889 if (BCM_FAILURE(rv)) { 890 soc_cm_sfree(unit, pri_map); 891 return (rv); 892 } 893 /* 894 * COVERITY 895 * 896 * The variable new_ptr is passed by reference and will have a 897 * deterministic value if _bcm_ing_pri_cng_map_entry_add does 898 * not return an error 899 */ 900 /* coverity[uninit_use : FALSE] */ 901 new_ptr /= _BCM_TR2_PRI_CNG_MAP_SIZE; 902 soc_PORT_TABm_field32_set(unit, &pent, TRUST_DOT1P_PTRf, new_ptr); 903 rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, 904 SOC_PORT_MOD_OFFSET(unit, port), &pent); 905 soc_cm_sfree(unit, pri_map); 906 return rv; 907 } 908 909 910 static soc_field_t _bcm_xgs3_priority_fields[] = { 911 PRIORITY0_CNGf, 912 PRIORITY1_CNGf, 913 PRIORITY2_CNGf, 914 PRIORITY3_CNGf, 915 PRIORITY4_CNGf, 916 PRIORITY5_CNGf, 917 PRIORITY6_CNGf, 918 PRIORITY7_CNGf, 919 }; 920 921 /* 922 * Function: 923 * _bcm_tr2_port_priority_color_set 924 * Purpose: 925 * Specify the color selection for the given priority. 926 * Parameters: 927 * unit - StrataSwitch PCI device unit number (driver internal). 928 * port - Port to configure 929 * prio - priority (aka 802.1p CoS) 930 * color - color assigned to packets with indicated priority. 931 * Returns: 932 * BCM_E_NONE - Success. 933 * BCM_E_XXX 934 */ 935 int 936 _bcm_tr2_port_priority_color_set(int unit, bcm_port_t port, 937 int prio, bcm_color_t color) 938 { 939 /* In order to set color based on port and priority, both the 940 * ING_PRI_CNG_MAP and CNG_MAP tables have to be configured. 941 * Hardware derives color from the ING_PRI_CNG_MAP table if 942 * incoming packet is tagged and PORT_TAB.TRUST_OUTER_DOT1P = 1. 943 * If PORT_TAB.TRUST_OUTER_DOT1P = 0, or if packet is untagged, 944 * harware derives color from CNG_MAP. 945 */ 946 947 ing_pri_cng_map_entry_t pri_cng_map[_BCM_TR2_PRI_CNG_MAP_SIZE]; 948 cng_map_entry_t cng_map_entry; 949 void *entries[1]; 950 port_tab_entry_t pent; 951 int index; 952 int rv = BCM_E_NONE; 953 int new_ptr = 0; 954 int old_ptr; 955 char *pri_map; 956 int alloc_size; 957 uint32 val; 958 959 /* Allocate buffer for dma read. */ 960 alloc_size = _BCM_TR2_PRI_CNG_MAP_SIZE * sizeof (ing_pri_cng_map_entry_t); 961 pri_map = soc_cm_salloc(unit, alloc_size, "TR2 pri cng map"); 962 if (NULL == pri_map) { 963 return (BCM_E_MEMORY); 964 } 965 sal_memset(pri_map, 0, alloc_size); 966 sal_memset(pri_cng_map, 0, alloc_size); 967 968 /* Lock the port table */ 969 soc_mem_lock(unit, PORT_TABm); 970 971 /* Get man id from port table. */ 972 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 973 SOC_PORT_MOD_OFFSET(unit, port), &pent); 974 if (BCM_FAILURE(rv)) { 975 goto _cleanup_bcm_tr2_port_priority_color_set; 976 } 977 old_ptr = soc_PORT_TABm_field32_get(unit, &pent, TRUST_DOT1P_PTRf); 978 979 /* Get the existing profile chunk, even if old_ptr == 0, in order 980 * to retain the PRI field of ING_PRI_CNG_MAP. 981 */ 982 index = old_ptr * _BCM_TR2_PRI_CNG_MAP_SIZE; 983 rv = soc_mem_read_range(unit, ING_PRI_CNG_MAPm, MEM_BLOCK_ANY, 984 index, index + _BCM_TR2_PRI_CNG_MAP_SIZE - 1, 985 pri_map); 986 if (BCM_FAILURE(rv)) { 987 goto _cleanup_bcm_tr2_port_priority_color_set; 988 } 989 990 for (index = 0; index < _BCM_TR2_PRI_CNG_MAP_SIZE; index++) { 991 entries[0] = soc_mem_table_idx_to_pointer(unit, ING_PRI_CNG_MAPm, 992 void *, pri_map, index); 993 sal_memcpy(pri_cng_map + index, entries[0], 994 sizeof(ing_pri_cng_map_entry_t)); 995 } 996 997 /* Set the CNG fields in 2 consecutive entries, whose indices are given by 998 * (priority << 1) | cfi, where cfi = 0 or 1. 999 */ 1000 index = prio << 1; 1001 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index], 1002 CNGf, _BCM_COLOR_ENCODING(unit, color)); 1003 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, (uint32 *)&pri_cng_map[index+1], 1004 CNGf, _BCM_COLOR_ENCODING(unit, color)); 1005 1006 /* Add and point to the new profile chunk */ 1007 entries[0] = pri_cng_map; 1008 rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 1009 _BCM_TR2_PRI_CNG_MAP_SIZE, 1010 (uint32 *)&new_ptr); 1011 if (BCM_FAILURE(rv)) { 1012 goto _cleanup_bcm_tr2_port_priority_color_set; 1013 } 1014 1015 new_ptr /= _BCM_TR2_PRI_CNG_MAP_SIZE; 1016 soc_PORT_TABm_field32_set(unit, &pent, TRUST_DOT1P_PTRf, new_ptr); 1017 rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, 1018 SOC_PORT_MOD_OFFSET(unit, port), &pent); 1019 if (BCM_FAILURE(rv)) { 1020 goto _cleanup_bcm_tr2_port_priority_color_set; 1021 } 1022 1023 soc_cm_sfree(unit, pri_map); 1024 /* Release port table lock */ 1025 soc_mem_unlock(unit, PORT_TABm); 1026 1027 if (old_ptr != 0) { 1028 /* Delete the old profile chunk */ 1029 index = _BCM_TR2_PRI_CNG_MAP_SIZE * old_ptr; 1030 BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_delete(unit, index)); 1031 } 1032 1033 /* Configure CNG_MAP */ 1034 if (SOC_REG_IS_VALID(unit, CNG_MAPr)) { 1035 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, old_ptr, &val)); 1036 soc_reg_field_set(unit, CNG_MAPr, &val, 1037 _bcm_xgs3_priority_fields[prio], 1038 _BCM_COLOR_ENCODING(unit, color)); 1039 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, new_ptr, val)); 1040 if (old_ptr != new_ptr) { 1041 /* Clear Old CNG_MAP profile */ 1042 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, old_ptr, 0)); 1043 } 1044 } else if (SOC_MEM_IS_VALID(unit, CNG_MAPm)) { 1045 SOC_IF_ERROR_RETURN(READ_CNG_MAPm(unit, MEM_BLOCK_ANY, 1046 old_ptr, &cng_map_entry)); 1047 soc_CNG_MAPm_field32_set(unit, &cng_map_entry, 1048 _bcm_xgs3_priority_fields[prio], 1049 _BCM_COLOR_ENCODING(unit, color)); 1050 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPm(unit, MEM_BLOCK_ALL, 1051 new_ptr, &cng_map_entry)); 1052 if (old_ptr != new_ptr) { 1053 /* Clear Old CNG_MAP profile */ 1054 sal_memset(&cng_map_entry, 0, sizeof(cng_map_entry)); 1055 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPm(unit, MEM_BLOCK_ALL, 1056 old_ptr, &cng_map_entry)); 1057 } 1058 } 1059 1060 return (rv); 1061 1062 _cleanup_bcm_tr2_port_priority_color_set: 1063 /* Release port table lock */ 1064 soc_mem_unlock(unit, PORT_TABm); 1065 soc_cm_sfree(unit, pri_map); 1066 return (rv); 1067 } 1068 1069 #ifdef INCLUDE_L3 1070 int 1071 _bcm_tr2_svp_field_set(int unit, bcm_gport_t port_id, 1072 soc_field_t field, int value) 1073 { 1074 int vp, rv = BCM_E_NONE; 1075 1076 /* Get the VP index from the gport */ 1077 if (BCM_GPORT_IS_MIM_PORT(port_id)) { 1078 vp = BCM_GPORT_MIM_PORT_ID_GET(port_id); 1079 } else if (BCM_GPORT_IS_MPLS_PORT(port_id)) { 1080 vp = BCM_GPORT_MPLS_PORT_ID_GET(port_id); 1081 } else if (BCM_GPORT_IS_VXLAN_PORT(port_id)) { 1082 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port_id); 1083 } else { 1084 return BCM_E_BADID; 1085 } 1086 1087 /* Be sure the entry is used and is set for MIM/MPLS */ 1088 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim) && 1089 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls) && 1090 !_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1091 return BCM_E_BADID; 1092 } 1093 1094 if (BCM_GPORT_IS_MIM_PORT(port_id)) { 1095 rv = _bcm_tr2_mim_svp_field_set(unit, vp, field, value); 1096 } else if (BCM_GPORT_IS_MPLS_PORT(port_id)) { 1097 #if defined(BCM_MPLS_SUPPORT) 1098 rv = _bcm_tr2_mpls_svp_field_set(unit, vp, field, value); 1099 #endif 1100 } else if (BCM_GPORT_IS_VXLAN_PORT(port_id)) { 1101 #if defined(BCM_TRIDENT2_SUPPORT) 1102 rv = _bcm_td2_vxlan_svp_field_set(unit, vp, field, value); 1103 #endif 1104 } 1105 return rv; 1106 } 1107 1108 int 1109 _bcm_tr2_svp_field_get(int unit, bcm_gport_t port_id, 1110 soc_field_t field, int *value) 1111 { 1112 int vp, rv = BCM_E_NONE; 1113 source_vp_entry_t svp; 1114 1115 /* Get the VP index from the gport */ 1116 if (BCM_GPORT_IS_MIM_PORT(port_id)) { 1117 vp = BCM_GPORT_MIM_PORT_ID_GET(port_id); 1118 } else if (BCM_GPORT_IS_MPLS_PORT(port_id)) { 1119 vp = BCM_GPORT_MPLS_PORT_ID_GET(port_id); 1120 } else if (BCM_GPORT_IS_VXLAN_PORT(port_id)) { 1121 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port_id); 1122 } else { 1123 return BCM_E_BADID; 1124 } 1125 1126 /* Be sure the entry is used and is set for MIM/MPLS */ 1127 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim) && 1128 !_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls) && 1129 !_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 1130 return BCM_E_BADID; 1131 } 1132 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 1133 1134 *value = soc_SOURCE_VPm_field32_get(unit, &svp, field); 1135 return rv; 1136 } 1137 1138 #endif /* INCLUDE_L3 */ 1139 #endif