port.c (30508B)
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 #include <assert.h> 10 #include <sal/core/libc.h> 11 12 #ifdef BCM_HURRICANE3_SUPPORT 13 14 #include <shared/util.h> 15 #include <soc/mem.h> 16 #include <soc/cm.h> 17 #include <soc/drv.h> 18 #include <soc/register.h> 19 #include <soc/memory.h> 20 #include <soc/hash.h> 21 #include <bcm/port.h> 22 #include <bcm/error.h> 23 #include <bcm_int/esw/firebolt.h> 24 #include <bcm_int/esw/port.h> 25 #include <bcm_int/esw/triumph.h> 26 #include <bcm_int/esw/trx.h> 27 #include <bcm_int/esw/xgs3.h> 28 #include <bcm_int/esw/stack.h> 29 #include <bcm_int/esw/virtual.h> 30 #include <bcm_int/esw_dispatch.h> 31 32 #include <bcm_int/common/lock.h> 33 34 #define _HR3_ENTRIES_PER_PORFILE (64) 35 36 STATIC soc_profile_mem_t *_bcm_hr3_egr_mask_profile[BCM_MAX_NUM_UNITS]; 37 STATIC soc_profile_mem_t *_bcm_hr3_sys_cfg_profile[BCM_MAX_NUM_UNITS]; 38 39 int 40 bcm_hr3_port_reinit(int unit) 41 { 42 soc_profile_mem_t *profile; 43 uint32 entry[SOC_MAX_MEM_WORDS]; 44 uint32 profile_index; 45 bcm_module_t modid; 46 bcm_port_t port; 47 system_config_table_entry_t *sys_cfg_entry; 48 int tpid_enable, tpid_index; 49 int is_local; 50 51 /* EGR_MASK profile */ 52 profile = _bcm_hr3_egr_mask_profile[unit]; 53 for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) { 54 BCM_IF_ERROR_RETURN 55 (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, modid, 56 entry)); 57 profile_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, entry, 58 BASEf); 59 SOC_IF_ERROR_RETURN 60 (soc_profile_mem_reference(unit, profile, profile_index, 61 SOC_PORT_ADDR_MAX(unit) + 1)); 62 } 63 64 /* SYSTEM_CONFIG_TABLE profile */ 65 profile = _bcm_hr3_sys_cfg_profile[unit]; 66 for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) { 67 BCM_IF_ERROR_RETURN 68 (soc_mem_read(unit, SYSTEM_CONFIG_TABLE_MODBASEm, MEM_BLOCK_ALL, 69 modid, entry)); 70 profile_index = soc_mem_field32_get(unit, SYSTEM_CONFIG_TABLE_MODBASEm, 71 entry, BASEf); 72 SOC_IF_ERROR_RETURN 73 (soc_profile_mem_reference(unit, profile, profile_index, 74 SOC_PORT_ADDR_MAX(unit) + 1)); 75 76 BCM_IF_ERROR_RETURN 77 (_bcm_esw_modid_is_local(unit, modid, &is_local)); 78 if (is_local) { 79 continue; 80 } 81 82 /* Increment outer tpid reference count for non-local ports. 83 * The local ports' outer tpid reference count is taken care 84 * of by _bcm_fb2_outer_tpid_init. 85 */ 86 for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) { 87 sys_cfg_entry = 88 SOC_PROFILE_MEM_ENTRY(unit, profile, 89 system_config_table_entry_t *, 90 profile_index + port); 91 tpid_enable = 92 soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, sys_cfg_entry, 93 OUTER_TPID_ENABLEf); 94 for (tpid_index = 0; tpid_index < 4; tpid_index++) { 95 if (tpid_enable & (1 << tpid_index)) { 96 BCM_IF_ERROR_RETURN( 97 _bcm_fb2_outer_tpid_tab_ref_count_add(unit, 98 tpid_index, 1)); 99 } 100 } 101 } 102 } 103 104 return BCM_E_NONE; 105 } 106 107 int 108 bcm_hr3_port_init(int unit) 109 { 110 soc_mem_t mem; 111 int entry_words; 112 union { 113 #ifdef BCM_GREYHOUND2_SUPPORT 114 /* 115 * GH2 support max port_num=66 (HR3's max port_num=64). 116 * - change the array size below from 64 to 128 for related profile 117 * memory init. 118 */ 119 egr_mask_entry_t egr_mask[128]; 120 system_config_table_entry_t sys_cfg[128]; 121 #else 122 egr_mask_entry_t egr_mask[_HR3_ENTRIES_PER_PORFILE]; 123 system_config_table_entry_t sys_cfg[_HR3_ENTRIES_PER_PORFILE]; 124 #endif 125 uint32 w[1]; 126 } entry; 127 void *entries[1]; 128 int modid, port, index; 129 uint32 profile_index; 130 uint16 tpid; 131 bcm_vlan_action_set_t action; 132 133 /* Create profile for EGR_MASK table */ 134 if (_bcm_hr3_egr_mask_profile[unit] == NULL) { 135 _bcm_hr3_egr_mask_profile[unit] = 136 sal_alloc(sizeof(soc_profile_mem_t), "EGR_MASK profile"); 137 if (_bcm_hr3_egr_mask_profile[unit] == NULL) { 138 return BCM_E_MEMORY; 139 } 140 soc_profile_mem_t_init(_bcm_hr3_egr_mask_profile[unit]); 141 } 142 mem = EGR_MASKm; 143 entry_words = sizeof(egr_mask_entry_t) / sizeof(uint32); 144 BCM_IF_ERROR_RETURN 145 (soc_profile_mem_create(unit, &mem, &entry_words, 1, 146 _bcm_hr3_egr_mask_profile[unit])); 147 148 /* Create profile for SYSTEM_CONFIG_TABLE table */ 149 if (_bcm_hr3_sys_cfg_profile[unit] == NULL) { 150 _bcm_hr3_sys_cfg_profile[unit] = 151 sal_alloc(sizeof(soc_profile_mem_t), 152 "SYSTEM_CONFIG_TABLE profile"); 153 if (_bcm_hr3_sys_cfg_profile[unit] == NULL) { 154 return BCM_E_MEMORY; 155 } 156 soc_profile_mem_t_init(_bcm_hr3_sys_cfg_profile[unit]); 157 } 158 mem = SYSTEM_CONFIG_TABLEm; 159 entry_words = sizeof(system_config_table_entry_t) / sizeof(uint32); 160 BCM_IF_ERROR_RETURN 161 (soc_profile_mem_create(unit, &mem, &entry_words, 1, 162 _bcm_hr3_sys_cfg_profile[unit])); 163 164 #ifdef BCM_WARM_BOOT_SUPPORT 165 if (SOC_WARM_BOOT(unit)) { 166 return bcm_hr3_port_reinit(unit); 167 } 168 #endif /* BCM_WARM_BOOT_SUPPORT */ 169 170 entries[0] = &entry; 171 172 /* Add default entries for EGR_MASK profile */ 173 sal_memset(entry.egr_mask, 0, sizeof(entry.egr_mask)); 174 BCM_IF_ERROR_RETURN 175 (soc_profile_mem_add(unit, _bcm_hr3_egr_mask_profile[unit], entries, 176 SOC_PORT_ADDR_MAX(unit) + 1, &profile_index)); 177 for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) { 178 SOC_IF_ERROR_RETURN 179 (soc_profile_mem_reference(unit, _bcm_hr3_egr_mask_profile[unit], 180 profile_index, 181 SOC_PORT_ADDR_MAX(unit) + 1)); 182 } 183 /* EGR_MASK_MODBASE should be 0 for all modid which should match with the 184 * allocated default profile index */ 185 186 /* Add default entries for SYSTEM_CONFIG_TABLE profile */ 187 tpid = _bcm_fb2_outer_tpid_default_get(unit); 188 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &index)); 189 190 sal_memset(entry.sys_cfg, 0, sizeof(entry.sys_cfg)); 191 for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) { 192 soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm, &entry.sys_cfg[port], 193 OUTER_TPID_ENABLEf, 1 << index); 194 195 if (soc_feature(unit, soc_feature_inner_tpid_enable)) { 196 soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm, 197 &entry.sys_cfg[port], INNER_TPID_ENABLEf, 1); 198 } 199 } 200 201 BCM_IF_ERROR_RETURN 202 (soc_profile_mem_add(unit, _bcm_hr3_sys_cfg_profile[unit], entries, 203 SOC_PORT_ADDR_MAX(unit) + 1, &profile_index)); 204 for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) { 205 SOC_IF_ERROR_RETURN 206 (soc_profile_mem_reference(unit, _bcm_hr3_sys_cfg_profile[unit], 207 profile_index, 208 SOC_PORT_ADDR_MAX(unit) + 1)); 209 } 210 /* SYSTEM_CONFIG_TABLE_MODBASE should be 0 for all modid which should 211 * match with the allocated default profile index */ 212 213 /* Update the TPID index reference count for all (module, port) except 214 * for local (module, port). The TPID index reference count for 215 * local (module, port) will be updated during port module init, 216 * when default outer TPID will be set for each local port. 217 */ 218 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 219 (SOC_MODID_MAX(unit) + 1 - NUM_MODID(unit)) * 220 (SOC_PORT_ADDR_MAX(unit) + 1))); 221 222 if (soc_feature(unit, soc_feature_wh2)){ 223 /* 224 * The config "pbmp_gport_stack" specifies the hl bitmap only in 225 * soc_info_config. The rest settings on IP/EP and PGW are done here. 226 */ 227 228 PBMP_PORT_ITER(unit, port) { 229 if (IS_HL_PORT(unit, port)) { 230 BCM_IF_ERROR_RETURN( 231 _bcm_esw_port_higig2_mode_set(unit, port, 1)); 232 SOC_HG2_ENABLED_PORT_ADD(unit, port); 233 234 bcm_vlan_action_set_t_init(&action); 235 BCM_IF_ERROR_RETURN 236 (_bcm_trx_vlan_port_egress_default_action_get(unit, 237 port, &action)); 238 /* Backward compatible defaults */ 239 action.ot_outer = bcmVlanActionDelete; 240 action.dt_outer = bcmVlanActionDelete; 241 BCM_IF_ERROR_RETURN 242 (_bcm_trx_vlan_port_egress_default_action_set(unit, 243 port, &action)); 244 } 245 } 246 } 247 return BCM_E_NONE; 248 } 249 250 int 251 bcm_hr3_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp) 252 { 253 soc_profile_mem_t *profile; 254 egr_mask_modbase_entry_t base_entry; 255 egr_mask_entry_t *mask_entries = NULL; 256 int alloc_size = 0; 257 void *entries[1]; 258 uint32 old_index, index; 259 bcm_pbmp_t mask_pbmp; 260 bcm_module_t modid_min, modid_max, cur_modid; 261 bcm_port_t port_min, port_max, cur_port; 262 bcm_trunk_t tid; 263 int id, rv; 264 bcm_pbmp_t pbmp_all, temp_pbmp_all; 265 bcm_module_t my_modid; 266 int modid_is_local; 267 int egr_mask_modbase_index; 268 bcm_module_t hw_mod; 269 bcm_port_t hw_port; 270 int mod_port_map_done = 0; 271 272 profile = _bcm_hr3_egr_mask_profile[unit]; 273 274 BCM_PBMP_CLEAR(temp_pbmp_all); 275 BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_PORT_ALL(unit)); 276 277 BCM_PBMP_NEGATE(mask_pbmp, pbmp); 278 BCM_PBMP_ASSIGN(pbmp_all,PBMP_CMIC(unit)); /* CPU port */ 279 BCM_PBMP_OR(pbmp_all,temp_pbmp_all); 280 BCM_PBMP_AND(mask_pbmp, pbmp_all); 281 282 if (BCM_GPORT_IS_SET(port)) { 283 BCM_IF_ERROR_RETURN 284 (_bcm_esw_gport_resolve(unit, port, &modid_min, &port_min, &tid, 285 &id)); 286 287 if (-1 != id || -1 != tid) { 288 return BCM_E_PORT; 289 } 290 modid_max = modid_min; 291 port_max = port_min; 292 /* For devices with multiple module IDs, _bcm_esw_gport_resolve 293 * had already performed module and port mapping. 294 */ 295 mod_port_map_done = 1; 296 } else { 297 if (modid < -1 || modid > SOC_MODID_MAX(unit)) { 298 return BCM_E_PARAM; 299 } else if (modid == -1) { 300 modid_min = 0; 301 modid_max = SOC_MODID_MAX(unit); 302 } else { 303 modid_min = modid; 304 modid_max = modid; 305 } 306 if (port < -1 || port > SOC_PORT_ADDR_MAX(unit)) { 307 return BCM_E_PARAM; 308 } else if (port == -1) { 309 port_min = 0; 310 port_max = SOC_PORT_ADDR_MAX(unit); 311 } else { 312 port_min = port; 313 port_max = port; 314 } 315 } 316 317 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 318 319 alloc_size = sizeof(egr_mask_entry_t) * (SOC_PORT_ADDR_MAX(unit) + 1); 320 mask_entries = sal_alloc(alloc_size, "EGR_MASK entry buffer"); 321 sal_memset(mask_entries, 0, alloc_size); 322 if (mask_entries == NULL) { 323 return BCM_E_MEMORY; 324 } 325 entries[0] = mask_entries; 326 327 soc_mem_lock(unit, EGR_MASK_MODBASEm); 328 329 rv = BCM_E_NONE; 330 for (cur_modid = modid_min; cur_modid <= modid_max; cur_modid++) { 331 332 rv = _bcm_esw_modid_is_local(unit, cur_modid, &modid_is_local); 333 if (BCM_FAILURE(rv)) { 334 break; 335 } 336 if (modid_is_local) { 337 egr_mask_modbase_index = my_modid; 338 } else { 339 egr_mask_modbase_index = cur_modid; 340 } 341 342 rv = soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, 343 egr_mask_modbase_index, &base_entry); 344 if (BCM_FAILURE(rv)) { 345 break; 346 } 347 old_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry, 348 BASEf); 349 rv = soc_profile_mem_get(unit, profile, old_index, 350 SOC_PORT_ADDR_MAX(unit) + 1, entries); 351 if (BCM_FAILURE(rv)) { 352 break; 353 } 354 for (cur_port = port_min; cur_port <= port_max; cur_port++) { 355 if (modid_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) { 356 if (cur_port <= SOC_MODPORT_MAX(unit)) { 357 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 358 cur_modid, cur_port, &hw_mod, &hw_port); 359 if (BCM_FAILURE(rv)) { 360 break; 361 } 362 } else { 363 break; 364 } 365 } else { 366 hw_port = cur_port; 367 } 368 369 soc_mem_pbmp_field_set(unit, EGR_MASKm, 370 &mask_entries[hw_port], EGRESS_MASKf, &mask_pbmp); 371 } 372 if (BCM_FAILURE(rv)) { 373 break; 374 } 375 rv = soc_profile_mem_add(unit, profile, entries, 376 SOC_PORT_ADDR_MAX(unit) + 1, &index); 377 if (BCM_FAILURE(rv)) { 378 break; 379 } 380 rv = soc_mem_field32_modify(unit, EGR_MASK_MODBASEm, 381 egr_mask_modbase_index, BASEf, index); 382 if (BCM_FAILURE(rv)) { 383 break; 384 } 385 rv = soc_profile_mem_delete(unit, profile, old_index); 386 if (BCM_FAILURE(rv)) { 387 break; 388 } 389 } 390 391 soc_mem_unlock(unit, EGR_MASK_MODBASEm); 392 393 sal_free(mask_entries); 394 395 return rv; 396 } 397 398 int 399 bcm_hr3_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp) 400 { 401 soc_profile_mem_t *profile; 402 egr_mask_modbase_entry_t base_entry; 403 egr_mask_entry_t *mask_entries = NULL; 404 int alloc_size = 0; 405 int rv = BCM_E_NONE; 406 void *entries[1]; 407 uint32 index; 408 bcm_pbmp_t mask_pbmp, temp_pbmp_all; 409 bcm_module_t local_modid; 410 bcm_port_t local_port; 411 bcm_trunk_t tid; 412 int id; 413 414 profile = _bcm_hr3_egr_mask_profile[unit]; 415 416 if (BCM_GPORT_IS_SET(port)) { 417 BCM_IF_ERROR_RETURN 418 (_bcm_esw_gport_resolve(unit, port, &local_modid, &local_port, 419 &tid, &id)); 420 421 if (-1 != id || -1 != tid) { 422 return BCM_E_PORT; 423 } 424 } else { 425 if (modid < 0 || modid > SOC_MODID_MAX(unit) || 426 port < 0 || port > SOC_PORT_ADDR_MAX(unit)) { 427 return BCM_E_PARAM; 428 } else { 429 PORT_DUALMODID_VALID(unit, port); 430 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 431 modid, port, &local_modid, &local_port)); 432 } 433 } 434 435 BCM_IF_ERROR_RETURN 436 (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, local_modid, 437 &base_entry)); 438 index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry, BASEf); 439 alloc_size = sizeof(egr_mask_entry_t) * (SOC_PORT_ADDR_MAX(unit) + 1); 440 mask_entries = sal_alloc(alloc_size, "EGR_MASK entry buffer"); 441 if (mask_entries == NULL) { 442 return BCM_E_MEMORY; 443 } 444 sal_memset(mask_entries, 0, alloc_size); 445 entries[0] = mask_entries; 446 rv = soc_profile_mem_get(unit, 447 profile, index, SOC_PORT_ADDR_MAX(unit) + 1, entries); 448 449 if (BCM_FAILURE(rv)) { 450 sal_free(mask_entries); 451 return rv; 452 } 453 454 soc_mem_pbmp_field_get(unit, EGR_MASKm, &mask_entries[local_port], 455 EGRESS_MASKf, &mask_pbmp); 456 sal_free(mask_entries); 457 458 BCM_PBMP_CLEAR(temp_pbmp_all); 459 BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_ALL(unit)); 460 461 BCM_PBMP_NEGATE(*pbmp, mask_pbmp); 462 BCM_PBMP_AND(*pbmp, temp_pbmp_all); 463 BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit)); 464 465 return BCM_E_NONE; 466 } 467 468 /* 469 * Function: 470 * _bcm_hr3_mod_port_tpid_enable_set 471 * Description: 472 * Write the Tag Protocol ID enables for a (module, port). 473 * Parameters: 474 * unit - Device number 475 * mod - Module ID 476 * port - Port number 477 * is_outer - TRUE: outer, FALSE : inner 478 * tpid_enable - Tag Protocol ID enables 479 * Return Value: 480 * BCM_E_XXX 481 */ 482 STATIC int 483 _bcm_hr3_mod_port_tpid_enable_set(int unit, bcm_module_t mod, 484 bcm_port_t port, int is_outer, int tpid_enable) 485 { 486 int rv = BCM_E_NONE; 487 system_config_table_modbase_entry_t modbase_entry; 488 system_config_table_entry_t *entry_array; 489 void *entries; 490 uint32 old_profile_index, new_profile_index; 491 int i; 492 493 SOC_IF_ERROR_RETURN 494 (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod, 495 &modbase_entry)); 496 old_profile_index = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit, 497 &modbase_entry, BASEf); 498 499 entry_array = sal_alloc(sizeof(system_config_table_entry_t) * 500 (SOC_PORT_ADDR_MAX(unit) + 1), "system config table entry array"); 501 if (entry_array == NULL) { 502 return BCM_E_MEMORY; 503 } 504 505 for (i = 0; i <= SOC_PORT_ADDR_MAX(unit); i++) { 506 sal_memcpy(&entry_array[i], 507 SOC_PROFILE_MEM_ENTRY(unit, _bcm_hr3_sys_cfg_profile[unit], 508 void *, old_profile_index + i), 509 sizeof(system_config_table_entry_t)); 510 } 511 512 if (TRUE == is_outer) { 513 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &entry_array[port], 514 OUTER_TPID_ENABLEf, tpid_enable); 515 } else { 516 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &entry_array[port], 517 INNER_TPID_ENABLEf, tpid_enable); 518 } 519 520 entries = entry_array; 521 rv = soc_profile_mem_add(unit, _bcm_hr3_sys_cfg_profile[unit], &entries, 522 SOC_PORT_ADDR_MAX(unit) + 1, &new_profile_index); 523 if (BCM_FAILURE(rv)) { 524 sal_free(entry_array); 525 return rv; 526 } 527 528 soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_set(unit, &modbase_entry, 529 BASEf, new_profile_index); 530 rv = WRITE_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ALL, mod, 531 &modbase_entry); 532 if (BCM_FAILURE(rv)) { 533 sal_free(entry_array); 534 return rv; 535 } 536 537 rv = soc_profile_mem_delete(unit, _bcm_hr3_sys_cfg_profile[unit], 538 old_profile_index); 539 sal_free(entry_array); 540 return rv; 541 } 542 543 /* 544 * Function: 545 * _bcm_hr3_mod_port_tpid_enable_get 546 * Description: 547 * Get the Tag Protocol ID enables for a (module, port). 548 * Parameters: 549 * unit - Device number 550 * mod - Module ID 551 * port - Port number 552 * is_outer - TRUE: outer, FALSE : inner 553 * tpid_enable - (OUT) Tag Protocol ID enables 554 * Return Value: 555 * BCM_E_XXX 556 */ 557 STATIC int 558 _bcm_hr3_mod_port_tpid_enable_get(int unit, bcm_module_t mod, bcm_port_t port, 559 int is_outer, int *tpid_enable) 560 { 561 system_config_table_modbase_entry_t modbase_entry; 562 system_config_table_entry_t sys_cfg_entry; 563 int base; 564 565 SOC_IF_ERROR_RETURN 566 (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod, 567 &modbase_entry)); 568 base = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit, &modbase_entry, 569 BASEf); 570 571 SOC_IF_ERROR_RETURN 572 (READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, base + port, 573 &sys_cfg_entry)); 574 575 if (TRUE == is_outer) { 576 *tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, &sys_cfg_entry, 577 OUTER_TPID_ENABLEf); 578 } else { 579 *tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, &sys_cfg_entry, 580 INNER_TPID_ENABLEf); 581 } 582 583 return BCM_E_NONE; 584 } 585 586 /* 587 * Function: 588 * _bcm_hr3_mod_port_tpid_enable_write 589 * Description: 590 * Write the Tag Protocol ID enables for a (module, port). 591 * Parameters: 592 * unit - Device number 593 * mod - Module ID 594 * port - Port number 595 * tpid_enable - Tag Protocol ID enables 596 * Return Value: 597 * BCM_E_XXX 598 */ 599 int 600 _bcm_hr3_mod_port_tpid_enable_write(int unit, bcm_module_t mod, 601 bcm_port_t port, int tpid_enable) 602 { 603 return _bcm_hr3_mod_port_tpid_enable_set(unit, mod, port, TRUE, tpid_enable); 604 } 605 606 /* 607 * Function: 608 * _bcm_hr3_mod_port_tpid_enable_read 609 * Description: 610 * Get the Tag Protocol ID enables for a (module, port). 611 * Parameters: 612 * unit - Device number 613 * mod - Module ID 614 * port - Port number 615 * tpid_enable - (OUT) Tag Protocol ID enables 616 * Return Value: 617 * BCM_E_XXX 618 */ 619 int 620 _bcm_hr3_mod_port_tpid_enable_read(int unit, bcm_module_t mod, bcm_port_t port, 621 int *tpid_enable) 622 { 623 return _bcm_hr3_mod_port_tpid_enable_get(unit, mod, port, TRUE, tpid_enable); 624 } 625 626 /* 627 * Function: 628 * _bcm_hr3_mod_port_inner_tpid_enable_write 629 * Description: 630 * Write the Inner Tag Protocol ID enables for a (module, port). 631 * Parameters: 632 * unit - Device number 633 * mod - Module ID 634 * port - Port number 635 * tpid_enable - Inner Tag Protocol ID enables 636 * Return Value: 637 * BCM_E_XXX 638 */ 639 int 640 _bcm_hr3_mod_port_inner_tpid_enable_write(int unit, bcm_module_t mod, 641 bcm_port_t port, int tpid_enable) 642 { 643 return _bcm_hr3_mod_port_tpid_enable_set(unit, mod, port, FALSE, tpid_enable); 644 } 645 646 /* 647 * Function: 648 * _bcm_hr3_mod_port_inner_tpid_enable_read 649 * Description: 650 * Get the Inner Tag Protocol ID enables for a (module, port). 651 * Parameters: 652 * unit - Device number 653 * mod - Module ID 654 * port - Port number 655 * tpid_enable - (OUT) Inner Tag Protocol ID enables 656 * Return Value: 657 * BCM_E_XXX 658 */ 659 int 660 _bcm_hr3_mod_port_inner_tpid_enable_read(int unit, bcm_module_t mod, bcm_port_t port, 661 int *tpid_enable) 662 { 663 return _bcm_hr3_mod_port_tpid_enable_get(unit, mod, port, FALSE, tpid_enable); 664 } 665 666 /* 667 * Function: 668 * _bcm_hr3_mod_port_tpid_set 669 * Description: 670 * Set the Tag Protocol ID for a (module, port). 671 * Parameters: 672 * unit - Device number 673 * mod - Module ID 674 * port - Port number 675 * tpid - Tag Protocol ID 676 * Return Value: 677 * BCM_E_XXX 678 */ 679 int 680 _bcm_hr3_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port, 681 uint16 tpid) 682 { 683 int rv = BCM_E_NONE; 684 int tpid_enable, tpid_index; 685 686 _bcm_fb2_outer_tpid_tab_lock(unit); 687 688 rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable); 689 if (BCM_FAILURE(rv)) { 690 _bcm_fb2_outer_tpid_tab_unlock(unit); 691 return rv; 692 } 693 694 tpid_index = 0; 695 while (tpid_enable) { 696 if (tpid_enable & 1) { 697 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 698 if (BCM_FAILURE(rv)) { 699 _bcm_fb2_outer_tpid_tab_unlock(unit); 700 return rv; 701 } 702 } 703 tpid_enable = tpid_enable >> 1; 704 tpid_index++; 705 } 706 707 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index); 708 if (BCM_FAILURE(rv)) { 709 _bcm_fb2_outer_tpid_tab_unlock(unit); 710 return rv; 711 } 712 713 tpid_enable = 1 << tpid_index; 714 rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable); 715 if (BCM_FAILURE(rv)) { 716 _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 717 } 718 719 _bcm_fb2_outer_tpid_tab_unlock(unit); 720 return rv; 721 } 722 723 /* 724 * Function: 725 * _bcm_hr3_mod_port_tpid_get 726 * Description: 727 * Retrieve the Tag Protocol ID for a (module, port). 728 * Parameters: 729 * unit - Device number 730 * mod - Module ID 731 * port - Port number 732 * tpid - (OUT) Tag Protocol ID 733 * Return Value: 734 * BCM_E_XXX 735 */ 736 int 737 _bcm_hr3_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port, 738 uint16 *tpid) 739 { 740 int tpid_enable, tpid_index; 741 742 BCM_IF_ERROR_RETURN 743 (_bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable)); 744 745 tpid_index = 0; 746 while (tpid_enable) { 747 if (tpid_enable & 1) { 748 return _bcm_fb2_outer_tpid_entry_get(unit, tpid, tpid_index); 749 } 750 tpid_enable = tpid_enable >> 1; 751 tpid_index++; 752 } 753 754 return BCM_E_NOT_FOUND; 755 } 756 757 /* 758 * Function: 759 * _bcm_hr3_mod_port_tpid_add 760 * Description: 761 * Add TPID for a (module, port). 762 * Parameters: 763 * unit - (IN) Device number 764 * mod - (IN) Module ID 765 * port - (IN) Port number 766 * tpid - (IN) Tag Protocol ID 767 * Return Value: 768 * BCM_E_XXX 769 */ 770 int 771 _bcm_hr3_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 772 uint16 tpid) 773 { 774 int rv = BCM_E_NONE; 775 int remove_tpid = FALSE; 776 int tpid_enable, index; 777 778 _bcm_fb2_outer_tpid_tab_lock(unit); 779 780 rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable); 781 if (BCM_FAILURE(rv)) { 782 _bcm_fb2_outer_tpid_tab_unlock(unit); 783 return rv; 784 } 785 786 rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index); 787 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 788 _bcm_fb2_outer_tpid_tab_unlock(unit); 789 return rv; 790 } 791 792 if (rv == BCM_E_NOT_FOUND || !(tpid_enable & (1 << index))) { 793 rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &index); 794 if (BCM_FAILURE(rv)) { 795 _bcm_fb2_outer_tpid_tab_unlock(unit); 796 return rv; 797 } 798 remove_tpid = TRUE; 799 } 800 801 tpid_enable |= (1 << index); 802 rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable); 803 if (BCM_FAILURE(rv)) { 804 if (remove_tpid) { 805 _bcm_fb2_outer_tpid_entry_delete(unit, index); 806 } 807 } 808 809 _bcm_fb2_outer_tpid_tab_unlock(unit); 810 return rv; 811 } 812 813 /* 814 * Function: 815 * _bcm_hr3_mod_port_tpid_delete 816 * Description: 817 * Delete TPID for a (module, port). 818 * Parameters: 819 * unit - (IN) Device number 820 * mod - (IN) Module ID 821 * port - (IN) Port number 822 * tpid - (IN) Tag Protocol ID 823 * Return Value: 824 * BCM_E_XXX 825 */ 826 int 827 _bcm_hr3_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port, 828 uint16 tpid) 829 { 830 int rv = BCM_E_NONE; 831 int index, tpid_enable; 832 833 _bcm_fb2_outer_tpid_tab_lock(unit); 834 835 rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index); 836 if (BCM_FAILURE(rv)) { 837 _bcm_fb2_outer_tpid_tab_unlock(unit); 838 return rv; 839 } 840 841 rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable); 842 if (BCM_FAILURE(rv)) { 843 _bcm_fb2_outer_tpid_tab_unlock(unit); 844 return rv; 845 } 846 847 if (tpid_enable & (1 << index)) { 848 tpid_enable &= ~(1 << index); 849 rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable); 850 } else { 851 rv = BCM_E_NOT_FOUND; 852 } 853 if (BCM_FAILURE(rv)) { 854 _bcm_fb2_outer_tpid_tab_unlock(unit); 855 return rv; 856 } 857 858 rv = _bcm_fb2_outer_tpid_entry_delete(unit, index); 859 _bcm_fb2_outer_tpid_tab_unlock(unit); 860 return rv; 861 } 862 863 /* 864 * Function: 865 * _bcm_hr3_mod_port_tpid_delete_all 866 * Description: 867 * Delete all TPID for a (module, port). 868 * Parameters: 869 * unit - (IN) Device number 870 * mod - (IN) Module ID 871 * port - (IN) Port number 872 * Return Value: 873 * BCM_E_XXX 874 */ 875 int 876 _bcm_hr3_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port) 877 { 878 int rv = BCM_E_NONE; 879 int tpid_enable, tpid_index; 880 881 _bcm_fb2_outer_tpid_tab_lock(unit); 882 883 rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable); 884 if (BCM_FAILURE(rv)) { 885 _bcm_fb2_outer_tpid_tab_unlock(unit); 886 return rv; 887 } 888 889 rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, 0); 890 if (BCM_FAILURE(rv)) { 891 _bcm_fb2_outer_tpid_tab_unlock(unit); 892 return rv; 893 } 894 895 tpid_index = 0; 896 while (tpid_enable) { 897 if (tpid_enable & 1) { 898 rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index); 899 if (BCM_FAILURE(rv)) { 900 _bcm_fb2_outer_tpid_tab_unlock(unit); 901 return rv; 902 } 903 } 904 tpid_enable = tpid_enable >> 1; 905 tpid_index++; 906 } 907 908 _bcm_fb2_outer_tpid_tab_unlock(unit); 909 return rv; 910 } 911 912 /* 913 * Function: 914 * bcmi_wh2_port_encap_get 915 * Purpose: 916 * Get the port encapsulation mode 917 * For WH2, only support 918 * BCM_PORT_ENCAP_IEEE and BCM_PORT_ENCAP_HIGIG2_LITE 919 * Parameters: 920 * unit - unit # 921 * port - port # 922 * mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h) 923 * Returns: 924 * BCM_E_XXX 925 */ 926 int 927 bcmi_wh2_port_encap_get(int unit, bcm_port_t port, int *mode) 928 { 929 uint32 rval, higig2; 930 931 BCM_IF_ERROR_RETURN(READ_PGW_GE_CONFIGr(unit, port, &rval)); 932 higig2 = soc_reg_field_get(unit, PGW_GE_CONFIGr, rval, HIGIG2_MODEf); 933 if (higig2) { 934 *mode = BCM_PORT_ENCAP_HIGIG2_LITE; 935 } else { 936 *mode = BCM_PORT_ENCAP_IEEE; 937 } 938 return BCM_E_NONE; 939 } 940 941 /* 942 * Function: 943 * bcmi_wh2_port_encap_set 944 * Purpose: 945 * Set the port encapsulation mode 946 * For WH2, only support 947 * BCM_PORT_ENCAP_IEEE and BCM_PORT_ENCAP_HIGIG2_LITE 948 * Parameters: 949 * unit - unit # 950 * port - port # 951 * mode - One of BCM_PORT_ENCAP_xxx (see port.h) 952 * Returns: 953 * BCM_E_XXX 954 */ 955 int 956 bcmi_wh2_port_encap_set(int unit, bcm_port_t port, int mode) 957 { 958 int to_higig; 959 960 /* no encap change has been returned in bcmi_esw_port_encap_set */ 961 /* error check */ 962 if (mode == BCM_PORT_ENCAP_IEEE) { 963 if (!IS_HL_PORT(unit, port)) { 964 return BCM_E_UNAVAIL; 965 } 966 } else if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 967 if (!IS_E_PORT(unit, port)) { 968 return BCM_E_UNAVAIL; 969 } 970 } else { 971 return BCM_E_UNAVAIL; 972 } 973 974 to_higig = (mode != BCM_PORT_ENCAP_IEEE); 975 976 BCM_IF_ERROR_RETURN( 977 _bcm_port_encap_stport_set(unit, port, mode)); 978 BCM_IF_ERROR_RETURN( 979 _bcm_esw_port_higig2_mode_set(unit, port, to_higig)); 980 if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 981 SOC_HG2_ENABLED_PORT_ADD(unit, port); 982 } else { 983 SOC_HG2_ENABLED_PORT_REMOVE(unit, port); 984 } 985 soc_dport_map_update(unit); 986 987 return BCM_E_NONE; 988 } 989 990 #endif /* BCM_HURRICANE3_SUPPORT */